diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 40768604b565..e79928edd2ee 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -104,6 +104,7 @@ Maintainers can revert your changes if they feel they are not worth maintaining
- [Embedding TGUI Components in Chat](../../tgui/docs/chat-embedded-components.md)
- [Hard Deletes](./guides/HARDDELETES.md)
+- [Quickly setting up a development database with ezdb](./guides/EZDB.md)
- [MC Tab Guide](./guides/MC_tab.md)
- [Tick system](./guides/TICK_ORDER.md)
- [UI Development](../tgui/README.md)
diff --git a/.github/guides/EZDB.md b/.github/guides/EZDB.md
new file mode 100644
index 000000000000..cee9d7deaf18
--- /dev/null
+++ b/.github/guides/EZDB.md
@@ -0,0 +1,12 @@
+# Quickly setting up a development database with ezdb
+While you do not need a database to code for yogstation, it is a prerequisite to many important features, especially on the admin side. Thus, if you are working in any code that benefits from it, it can be helpful to have one handy.
+
+**ezdb** is a tool for quickly setting up an isolated development database. It will manage downloading MariaDB, creating the database, setting it up, and updating it when the code evolves. It is not recommended for use in production servers, but is perfect for quick development.
+
+To run ezdb, go to `tools/ezdb`, and double-click on ezdb.bat. This will set up the database on port 1338, but you can configure this with `--port`. When it is done, you should be able to launch yogstation as normal and have database access. This runs on the same Python bootstrapper as things like the map merge tool, which can sometimes be flaky.
+
+If you wish to delete the ezdb database, delete the `db` folder as well as `config/ezdb.txt`.
+
+To update ezdb, run the script again. This will both look for any updates in the database changelog, as well as update your schema revision.
+
+Contact Mothblocks if you face any issues in this process.
diff --git a/.github/workflows/turdis.yml b/.github/workflows/turdis.yml
index cef619052746..dbde0b434455 100644
--- a/.github/workflows/turdis.yml
+++ b/.github/workflows/turdis.yml
@@ -88,9 +88,29 @@ jobs:
- name: Compile All Maps
run: |
tools/build/build --ci dm -DCIBUILDING -DCITESTING -DALL_MAPS
+ find_all_maps:
+ if: "!contains(github.event.head_commit.message, '[ci skip]')"
+ name: Find Maps to Test
+ runs-on: ubuntu-20.04
+ outputs:
+ maps: ${{ steps.map_finder.outputs.maps }}
+ steps:
+ - uses: actions/checkout@v2
+ - name: Find Maps
+ id: map_finder
+ run: |
+ echo "$(ls -mw0 _maps/*.json)" > maps_output.txt
+ sed -i -e s+_maps/+\"+g -e s+.json+\"+g maps_output.txt
+ echo "Maps: $(cat maps_output.txt)"
+ echo "maps={\"paths\":[$(cat maps_output.txt)]}" >> $GITHUB_OUTPUT
test:
name: Compile and Run Tests
runs-on: ubuntu-20.04
+ needs: [find_all_maps]
+ strategy:
+ fail-fast: false
+ matrix:
+ map: ${{ fromJSON(needs.find_all_maps.outputs.maps).paths }}
services:
mariadb:
image: mariadb
@@ -98,7 +118,9 @@ jobs:
- 3306:3306
env:
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes
-
+ concurrency:
+ group: ci-${{ github.ref }}-${{ matrix.map }}
+ cancel-in-progress: true
steps:
- uses: actions/checkout@v2
@@ -136,7 +158,7 @@ jobs:
- name: Compile
run: |
tools/build/build --ci dm -DCIBUILDING
- tools/travis/dm.sh -DTRAVISBUILDING yogstation.dme || travis_terminate 1
+ tools/travis/dm.sh -DTRAVISBUILDING -DANSICOLORS yogstation.dme || travis_terminate 1
- name: Prepare Artifacts
run: |
@@ -147,10 +169,23 @@ jobs:
- name: Upload Artifacts
uses: actions/upload-artifact@v1
with:
- name: DMB + RSC
+ name: DMB + RSC ${{matrix.map}}
path: ${{github.workspace}}/artifacts
- name: Run Tests
run: |
- tools/travis/run_server.sh
+ tools/travis/run_server.sh ${{ matrix.map }}
+ results:
+ if: ${{ always() }}
+ runs-on: ubuntu-latest
+ name: Final Map Test
+ needs: [test]
+ steps:
+ - run: exit 1
+ # see https://stackoverflow.com/a/67532120/4907315
+ if: >-
+ ${{
+ contains(needs.*.result, 'failure')
+ || contains(needs.*.result, 'cancelled')
+ }}
diff --git a/.gitignore b/.gitignore
index 9cd796be4556..bf6bfc5cf8c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -218,3 +218,7 @@ tools/MapAtmosFixer/MapAtmosFixer/bin/*
#KDIFF3 files
*.orig
+
+# ezdb
+/db/
+/config/ezdb.txt
diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.md
similarity index 98%
rename from SQL/database_changelog.txt
rename to SQL/database_changelog.md
index ef9e3dc2e40c..5b3c483bd169 100644
--- a/SQL/database_changelog.txt
+++ b/SQL/database_changelog.md
@@ -11,6 +11,7 @@ In any query remember to add a prefix to the table names if you use one.
version 5.13 2023-05-10
Adds allow_vpn to bound credentials flags
+```sql
ALTER TABLE `bound_credentials` MODIFY COLUMN flags set('bypass_bans','allow_proxies') DEFAULT NULL NULL;
CREATE TABLE `proxy_cache` (
`ip` int(11) unsigned NOT NULL,
@@ -19,28 +20,36 @@ CREATE TABLE `proxy_cache` (
PRIMARY KEY (`ip`),
CONSTRAINT `data` CHECK (json_valid(`data`))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+```
+```sql
CREATE OR REPLACE EVENT proxy_cache_ttl
ON SCHEDULE EVERY 1 HOUR
DO
DELETE FROM proxy_cache WHERE (last_updated + INTERVAL 1 DAY) < current_timestamp();
+```
version 5.12 2023-04-10
Adds playtime to notes
+```sql
ALTER TABLE `messages` ADD `playtime` int(10) unsigned DEFAULT NULL;
CREATE TRIGGER messagesTloghours
BEFORE INSERT ON `messages` FOR EACH ROW
SET NEW.playtime = (SELECT minutes FROM role_time rt WHERE rt.ckey = NEW.targetckey AND rt.job = 'Living');
+```
version 5.11 2023-01-03
Adds comment to credentials binding
+```sql
ALTER TABLE `bound_credentials` ADD comment text NULL;
+```
version 5.10 2022-05-18, alexkar598
Adds credentials binding
+```sql
CREATE TABLE `bound_credentials` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) NOT NULL,
@@ -52,27 +61,33 @@ CREATE TABLE `bound_credentials` (
KEY `idx_cid_lookup` (`computerid`),
KEY `idx_ip_lookup` (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+```
version 5.9 23 November 2021, by adamsogm
Adds the datetime column to the primary key for the MFA table
+```sql
ALTER TABLE ss13_mfa_logins
DROP PRIMARY KEY,
ADD PRIMARY KEY (`ckey`,`ip`,`cid`, `datetime`);
+```
version 5.8 25 October 2021, by adamsogm
Modifies the admin_tickets table, and adds the admin_ticket_interactions table
Do not forget to apply the prefix to the foreign key on the admin_ticket_interactions table
+```sql
ALTER TABLE `admin_tickets`
DROP COLUMN `content`,
DROP COLUMN `rating`,
MODIFY `a_ckey` varchar(32),
ADD INDEX `idx_round` (`round_id`),
ADD INDEX `idx_round_ticket` (`round_id`,`ticket_id`);
+```
+```sql
DROP TABLE IF EXISTS `admin_ticket_interactions`;
CREATE TABLE IF NOT EXISTS `admin_ticket_interactions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
@@ -83,15 +98,19 @@ CREATE TABLE IF NOT EXISTS `admin_ticket_interactions` (
PRIMARY KEY (`id`),
FOREIGN KEY (`ticket_id`) REFERENCES `admin_tickets`(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+```
version 5.7 23 September 2021, by adamsogm
Adds table for storing mfa login cache and a column for storing TOTP seeds and one for mfa backup code
+```sql
ALTER TABLE player
ADD COLUMN totp_seed varchar(20),
ADD COLUMN mfa_backup varchar(128);
+```
+```sql
DROP TABLE IF EXISTS `mfa_logins`;
CREATE TABLE IF NOT EXISTS `mfa_logins` (
`ckey` varchar(32) NOT NULL,
@@ -100,6 +119,7 @@ CREATE TABLE IF NOT EXISTS `mfa_logins` (
`datetime` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`ckey`,`ip`,`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+```
----------------------------------------------------
@@ -107,9 +127,10 @@ version 5.6 14 August 2021, by alexkar598
Adds index on connection_log
+```sql
create index idx_review
on connection_log (ckey, computerid, ip);
-
+```
----------------------------------------------------
@@ -117,7 +138,9 @@ version 5.5 14 August 2021, by JamieD1
Adds column in mentor for position
+```sql
ALTER TABLE `mentor` ADD COLUMN `position` VARSET(32) UNSIGNED NOT NULL AFTER `ckey`;
+```
----------------------------------------------------
@@ -125,6 +148,7 @@ version 5.4 18 May 2020, by TheGamer01
Adds table for antag tokens
+```sql
CREATE TABLE `antag_tokens` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`ckey` VARCHAR(32) NULL NOT NULL,
@@ -137,6 +161,7 @@ CREATE TABLE `antag_tokens` (
`round_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
+```
----------------------------------------------------
@@ -144,23 +169,29 @@ version 5.3 10 Dec 2019, by Nichlas0010
Added two tables for achievements, one for the metadata and one for storing achieved achievements, as well as a misc table which is essentially just a glorified assoc list
+```sql
CREATE TABLE `achievements` (
`name` VARCHAR(32) NOT NULL,
`id` INT UNSIGNED NOT NULL,
`descr` VARCHAR(2048) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
+```
+```sql
CREATE TABLE `earned_achievements` (
`ckey` VARCHAR(32) NOT NULL,
`id` INT UNSIGNED NOT NULL
) ENGINE=InnoDB;
+```
+```sql
CREATE TABLE `misc` (
`key` VARCHAR(32) NOT NULL,
`value` VARCHAR(2048) NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=InnoDB;
+```
----------------------------------------------------
@@ -168,13 +199,17 @@ Version 5.2, 28 Aug 2019, by AffectedArc07/TheGamer01
Added a field to the `player` table to track ckey and discord ID relationships
+```sql
ALTER TABLE `player`
ADD COLUMN `discord_id` BIGINT NULL DEFAULT NULL AFTER `flags`;
+```
+
----------------------------------------------------
Version 5.1, 25 Feb 2018, by MrStonedOne
Added four tables to enable storing of stickybans in the database since byond can lose them, and to enable disabling stickybans for a round without depending on a crash free round. Existing stickybans are automagically imported to the tables.
+```sql
CREATE TABLE `stickyban` (
`ckey` VARCHAR(32) NOT NULL,
`reason` VARCHAR(2048) NOT NULL,
@@ -182,7 +217,9 @@ CREATE TABLE `stickyban` (
`datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`ckey`)
) ENGINE=InnoDB;
+```
+```sql
CREATE TABLE `stickyban_matched_ckey` (
`stickyban` VARCHAR(32) NOT NULL,
`matched_ckey` VARCHAR(32) NOT NULL,
@@ -191,7 +228,9 @@ CREATE TABLE `stickyban_matched_ckey` (
`exempt` TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`stickyban`, `matched_ckey`)
) ENGINE=InnoDB;
+```
+```sql
CREATE TABLE `stickyban_matched_ip` (
`stickyban` VARCHAR(32) NOT NULL,
`matched_ip` INT UNSIGNED NOT NULL,
@@ -199,7 +238,9 @@ CREATE TABLE `stickyban_matched_ip` (
`last_matched` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`stickyban`, `matched_ip`)
) ENGINE=InnoDB;
+```
+```sql
CREATE TABLE `stickyban_matched_cid` (
`stickyban` VARCHAR(32) NOT NULL,
`matched_cid` VARCHAR(32) NOT NULL,
@@ -207,6 +248,7 @@ CREATE TABLE `stickyban_matched_cid` (
`last_matched` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`stickyban`, `matched_cid`)
) ENGINE=InnoDB;
+```
----------------------------------------------------
@@ -216,6 +258,7 @@ Modified ban table to remove the need for the `bantype` column, a python script
See the file 'ban_conversion_2018-10-28.py' for instructions on how to use the script.
A new ban table can be created with the query:
+```sql
CREATE TABLE `ban` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`bantime` DATETIME NOT NULL,
@@ -245,20 +288,25 @@ CREATE TABLE `ban` (
KEY `idx_ban_isbanned_details` (`ckey`,`ip`,`computerid`,`role`,`unbanned_datetime`,`expiration_time`),
KEY `idx_ban_count` (`bantime`,`a_ckey`,`applies_to_admins`,`unbanned_datetime`,`expiration_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+```
----------------------------------------------------
Version 4.7, 18 August 2018, by CitrusGender
Modified table `messages`, adding column `severity` to classify notes based on their severity.
+```sql
ALTER TABLE `messages` ADD `severity` enum('high','medium','minor','none') DEFAULT NULL AFTER `expire_timestamp`
+```
----------------------------------------------------
Version 4.6, 11 August 2018, by Jordie0608
Modified table `messages`, adding column `expire_timestamp` to allow for auto-"deleting" messages.
+```sql
ALTER TABLE `messages` ADD `expire_timestamp` DATETIME NULL DEFAULT NULL AFTER `secret`;
+```
----------------------------------------------------
@@ -266,26 +314,34 @@ Version 4.5, 9 July 2018, by Jordie0608
Modified table `player`, adding column `byond_key` to store a user's key along with their ckey.
To populate this new column run the included script 'populate_key_2018-07', see the file for use instructions.
+```sql
ALTER TABLE `player` ADD `byond_key` VARCHAR(32) DEFAULT NULL AFTER `ckey`;
+```
----------------------------------------------------
Version 4.4, 9 May 2018, by Jordie0608
Modified table `round`, renaming column `start_datetime` to `initialize_datetime` and `end_datetime` to `shutdown_datetime` and adding columns to replace both under the same name in preparation for changes to TGS server initialization.
+```sql
ALTER TABLE `round`
ALTER `start_datetime` DROP DEFAULT;
+```
+
+```sql
ALTER TABLE `round`
CHANGE COLUMN `start_datetime` `initialize_datetime` DATETIME NOT NULL AFTER `id`,
ADD COLUMN `start_datetime` DATETIME NULL DEFAULT NULL AFTER `initialize_datetime`,
CHANGE COLUMN `end_datetime` `shutdown_datetime` DATETIME NULL DEFAULT NULL AFTER `start_datetime`,
ADD COLUMN `end_datetime` DATETIME NULL DEFAULT NULL AFTER `shutdown_datetime`;
+```
----------------------------------------------------
Version 4.3, 9 May 2018, by MrStonedOne
Added table `role_time_log` and triggers `role_timeTlogupdate`, `role_timeTloginsert` and `role_timeTlogdelete` to update it from changes to `role_time`
+```sql
CREATE TABLE `role_time_log` ( `id` BIGINT NOT NULL AUTO_INCREMENT , `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT NULL , `delta` INT NOT NULL , `datetime` TIMESTAMP on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , PRIMARY KEY (`id`), INDEX (`ckey`), INDEX (`job`), INDEX (`datetime`)) ENGINE = InnoDB;
DELIMITER $$
@@ -299,6 +355,7 @@ CREATE TRIGGER `role_timeTlogdelete` AFTER DELETE ON `role_time` FOR EACH ROW B
END
$$
DELIMITER ;
+```
----------------------------------------------------
Version 4.2, 17 April 2018, by Jordie0608
@@ -315,6 +372,7 @@ This change was made to enable use of sql-based admin loading.
To import your existing admins and ranks run the included script 'admin_import_2018-02-03.py', see the file for use instructions.
Legacy file-based admin loading is still supported, if you want to continue using it the script doesn't need to be run.
+```sql
ALTER TABLE `admin`
CHANGE COLUMN `rank` `rank` VARCHAR(32) NOT NULL AFTER `ckey`,
DROP COLUMN `id`,
@@ -323,14 +381,18 @@ ALTER TABLE `admin`
DROP COLUMN `email`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`ckey`);
+```
+```sql
ALTER TABLE `admin_log`
CHANGE COLUMN `datetime` `datetime` DATETIME NOT NULL AFTER `id`,
CHANGE COLUMN `adminckey` `adminckey` VARCHAR(32) NOT NULL AFTER `datetime`,
CHANGE COLUMN `adminip` `adminip` INT(10) UNSIGNED NOT NULL AFTER `adminckey`,
ADD COLUMN `operation` ENUM('add admin','remove admin','change admin rank','add rank','remove rank','change rank flags') NOT NULL AFTER `adminip`,
CHANGE COLUMN `log` `log` VARCHAR(1000) NOT NULL AFTER `operation`;
+```
+```sql
ALTER TABLE `admin_ranks`
CHANGE COLUMN `rank` `rank` VARCHAR(32) NOT NULL FIRST,
CHANGE COLUMN `flags` `flags` SMALLINT UNSIGNED NOT NULL AFTER `rank`,
@@ -339,6 +401,7 @@ ALTER TABLE `admin_ranks`
DROP COLUMN `id`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`rank`);
+```
----------------------------------------------------
@@ -348,6 +411,8 @@ Modified feedback table to use json, a python script is used to migrate data to
See the file 'feedback_conversion_2017-11-12.py' for instructions on how to use the script.
A new json feedback table can be created with:
+
+```sql
CREATE TABLE `feedback` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
@@ -358,12 +423,14 @@ CREATE TABLE `feedback` (
`json` json NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM
+```
----------------------------------------------------
Version 3.4, 28 August 2017, by MrStonedOne
Modified table 'messages', adding a deleted column and editing all indexes to include it
+```sql
ALTER TABLE `messages`
ADD COLUMN `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0' AFTER `edits`,
DROP INDEX `idx_msg_ckey_time`,
@@ -372,6 +439,7 @@ DROP INDEX `idx_msg_type_ckey_time_odr`,
ADD INDEX `idx_msg_ckey_time` (`targetckey`,`timestamp`, `deleted`),
ADD INDEX `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`, `deleted`),
ADD INDEX `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`, `deleted`);
+```
----------------------------------------------------
@@ -379,11 +447,13 @@ Version 3.3, 25 August 2017, by Jordie0608
Modified tables 'connection_log', 'legacy_population', 'library', 'messages' and 'player' to add additional 'round_id' tracking in various forms and 'server_ip' and 'server_port' to the table 'messages'.
+```sql
ALTER TABLE `connection_log` ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
ALTER TABLE `legacy_population` ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
ALTER TABLE `library` ADD COLUMN `round_id_created` INT(11) UNSIGNED NOT NULL AFTER `deleted`;
ALTER TABLE `messages` ADD COLUMN `server_ip` INT(10) UNSIGNED NOT NULL AFTER `server`, ADD COLUMN `server_port` SMALLINT(5) UNSIGNED NOT NULL AFTER `server_ip`, ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
ALTER TABLE `player` ADD COLUMN `firstseen_round_id` INT(11) UNSIGNED NOT NULL AFTER `firstseen`, ADD COLUMN `lastseen_round_id` INT(11) UNSIGNED NOT NULL AFTER `lastseen`;
+```
----------------------------------------------------
@@ -391,9 +461,11 @@ Version 3.2, 18 August 2017, by Cyberboss and nfreader
Modified table 'death', adding the columns `last_words` and 'suicide'.
+```sql
ALTER TABLE `death`
ADD COLUMN `last_words` varchar(255) DEFAULT NULL AFTER `staminaloss`,
ADD COLUMN `suicide` tinyint(0) NOT NULL DEFAULT '0' AFTER `last_words`;
+```
Remember to add a prefix to the table name if you use them.
@@ -403,9 +475,13 @@ Version 3.1, 20th July 2017, by Shadowlight213
Added role_time table to track time spent playing departments.
Also, added flags column to the player table.
+```sql
CREATE TABLE `role_time` ( `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT NULL , `minutes` INT UNSIGNED NOT NULL, PRIMARY KEY (`ckey`, `job`) ) ENGINE = InnoDB;
+```
+```sql
ALTER TABLE `player` ADD `flags` INT NOT NULL default '0' AFTER `accountjoindate`;
+```
Remember to add a prefix to the table name if you use them.
@@ -417,14 +493,18 @@ Added schema_revision to store the current db revision, why start at 3.0?
because:
15:09 <+MrStonedOne> 1.0 was erro, 2.0 was when i removed erro_, 3.0 was when jordie made all the strings that hold numbers numbers
+```sql
CREATE TABLE `schema_revision` (
`major` TINYINT(3) UNSIGNED NOT NULL ,
`minor` TINYINT(3) UNSIGNED NOT NULL ,
`date` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY ( `major`,`minor` )
) ENGINE = INNODB;
+```
+```sql
INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0);
+```
Remember to add a prefix to the table name if you use them.
@@ -434,7 +514,9 @@ Remember to add a prefix to the table name if you use them.
Modified table 'poll_option', adding the column 'default_percentage_calc'.
+```sql
ALTER TABLE `poll_option` ADD COLUMN `default_percentage_calc` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `descmax`
+```
Remember to add a prefix to the table name if you use them.
@@ -444,7 +526,9 @@ Remember to add a prefix to the table name if you use them.
Modified table 'poll_option', removing the column 'percentagecalc'.
+```sql
ALTER TABLE `poll_option` DROP COLUMN `percentagecalc`
+```
Remember to add a prefix to the table name if you use them.
diff --git a/SpacemanDMM.toml b/SpacemanDMM.toml
index dc79b57af259..2cc934471078 100644
--- a/SpacemanDMM.toml
+++ b/SpacemanDMM.toml
@@ -1,5 +1,10 @@
-[langserver]
-dreamchecker = true
-
-[debugger]
-engine = "extools"
+environment = "yogstation.dme"
+
+[langserver]
+dreamchecker = true
+
+[diagnostics]
+var_in_proc_parameter = "off"
+
+[debugger]
+engine = "auxtools"
diff --git a/_maps/RandomRuins/IceRuins/icemoon_surface_icehermit.dmm b/_maps/RandomRuins/IceRuins/icemoon_surface_hermit.dmm
similarity index 100%
rename from _maps/RandomRuins/IceRuins/icemoon_surface_icehermit.dmm
rename to _maps/RandomRuins/IceRuins/icemoon_surface_hermit.dmm
diff --git a/_maps/RandomRuins/IceRuins/icemoon_surface_syndicate.dmm b/_maps/RandomRuins/IceRuins/icemoon_surface_syndicate.dmm
index 5e14bc6915b2..4422f1676409 100644
--- a/_maps/RandomRuins/IceRuins/icemoon_surface_syndicate.dmm
+++ b/_maps/RandomRuins/IceRuins/icemoon_surface_syndicate.dmm
@@ -3515,7 +3515,7 @@
/obj/effect/turf_decal/siding/red,
/obj/machinery/turretid{
ailock = 1;
- control_area = "/area/ruin/powered/syndicate_lava_base/main";
+ control_area = "/area/ruin/syndicate_icemoon/command";
dir = 1;
icon_state = "control_kill";
lethal = 1;
diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_walkervillage.dmm b/_maps/RandomRuins/IceRuins/icemoon_surface_walkervillage.dmm
similarity index 100%
rename from _maps/RandomRuins/IceRuins/icemoon_underground_walkervillage.dmm
rename to _maps/RandomRuins/IceRuins/icemoon_surface_walkervillage.dmm
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
index 25fd8a3d49ae..b18a590ca4d5 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
@@ -3,7 +3,7 @@
/turf/template_noop,
/area/template_noop)
"ab" = (
-/turf/open/lava/smooth/lava_land_surface,
+/turf/open/lava/smooth/lava_land_surface/no_shelter,
/area/lavaland/surface/outdoors)
"ac" = (
/obj/structure/disposaloutlet{
@@ -448,7 +448,7 @@
/area/ruin/powered/syndicate_lava_base/dormitories)
"dS" = (
/obj/structure/lattice/catwalk,
-/turf/open/lava/smooth/lava_land_surface,
+/turf/open/lava/smooth/lava_land_surface/no_shelter,
/area/lavaland/surface/outdoors)
"dT" = (
/obj/effect/turf_decal/siding/blue/end{
@@ -3599,7 +3599,7 @@
name = "Syndicate Lavaland Base: Cargo Bay Dock";
width = 11
},
-/turf/open/lava/smooth/lava_land_surface,
+/turf/open/lava/smooth/lava_land_surface/no_shelter,
/area/lavaland/surface/outdoors)
"ne" = (
/turf/open/floor/engine/o2,
@@ -4366,7 +4366,7 @@
name = "Syndicate Lavaland Base: Arivals Dock";
width = 13
},
-/turf/open/lava/smooth/lava_land_surface,
+/turf/open/lava/smooth/lava_land_surface/no_shelter,
/area/lavaland/surface/outdoors)
"tu" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
diff --git a/_maps/RandomRuins/StationRuins/BoxStation/chapel1.dmm b/_maps/RandomRuins/StationRuins/BoxStation/chapel1.dmm
index f0e80d95eca0..cd8d019e4070 100644
--- a/_maps/RandomRuins/StationRuins/BoxStation/chapel1.dmm
+++ b/_maps/RandomRuins/StationRuins/BoxStation/chapel1.dmm
@@ -434,14 +434,7 @@
},
/turf/open/floor/plasteel/dark,
/area/chapel/main)
-"xO" = (
-/obj/effect/landmark/start/assistant,
-/turf/open/floor/plasteel/chapel{
- dir = 4
- },
-/area/chapel/main)
"Ar" = (
-/obj/effect/landmark/start/chaplain,
/obj/structure/chair,
/obj/structure/disposalpipe/segment{
dir = 4
@@ -572,14 +565,6 @@
},
/turf/open/floor/plasteel/dark,
/area/chapel/main)
-"MC" = (
-/obj/effect/landmark/start/assistant,
-/obj/structure/disposalpipe/segment,
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/turf/open/floor/carpet/purple,
-/area/chapel/main)
"ML" = (
/obj/machinery/door/airlock/maintenance{
name = "Crematorium Maintenance";
@@ -1073,7 +1058,7 @@ ZS
Wy
ZS
PM
-xO
+ZS
PM
QT
JH
@@ -1138,7 +1123,7 @@ Tv
Tv
rk
Od
-MC
+Od
Od
Od
Od
diff --git a/_maps/RandomRuins/StationRuins/BoxStation/chapel2.dmm b/_maps/RandomRuins/StationRuins/BoxStation/chapel2.dmm
index 09ea1a01b2c8..4b7ac1a5176e 100644
--- a/_maps/RandomRuins/StationRuins/BoxStation/chapel2.dmm
+++ b/_maps/RandomRuins/StationRuins/BoxStation/chapel2.dmm
@@ -50,7 +50,6 @@
/turf/open/floor/carpet/red,
/area/chapel/main)
"cB" = (
-/obj/effect/landmark/start/chaplain,
/obj/machinery/camera{
c_tag = "Chapel Office"
},
diff --git a/_maps/RandomRuins/StationRuins/BoxStation/engine_sm.dmm b/_maps/RandomRuins/StationRuins/BoxStation/engine_sm.dmm
index 142f68d2201c..733a2ef2a261 100644
--- a/_maps/RandomRuins/StationRuins/BoxStation/engine_sm.dmm
+++ b/_maps/RandomRuins/StationRuins/BoxStation/engine_sm.dmm
@@ -1137,7 +1137,7 @@
"do" = (
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
dir = 8;
- filter_type = list(/datum/gas/nitrogen)
+ filter_type = list("n2")
},
/turf/open/floor/engine,
/area/engine/engineering)
diff --git a/_maps/RandomRuins/StationRuins/MetaStation/meta_sm.dmm b/_maps/RandomRuins/StationRuins/MetaStation/meta_sm.dmm
index cea332dfe4a9..7c18da9f5dd5 100644
--- a/_maps/RandomRuins/StationRuins/MetaStation/meta_sm.dmm
+++ b/_maps/RandomRuins/StationRuins/MetaStation/meta_sm.dmm
@@ -42,7 +42,7 @@
dir = 4
},
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
- filter_type = list(/datum/gas/nitrogen)
+ filter_type = list("n2")
},
/turf/open/floor/engine,
/area/engine/engineering)
diff --git a/_maps/RandomZLevels/VR/snowdin_VR.dmm b/_maps/RandomZLevels/VR/snowdin_VR.dmm
index a11ea4463d80..e8859e690f32 100644
--- a/_maps/RandomZLevels/VR/snowdin_VR.dmm
+++ b/_maps/RandomZLevels/VR/snowdin_VR.dmm
@@ -2671,14 +2671,14 @@
"gc" = (
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"gd" = (
/obj/effect/spawner/lootdrop/crate_spawner,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"ge" = (
@@ -2689,7 +2689,7 @@
/obj/effect/spawner/lootdrop/snowdin/dungeonheavy,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"gg" = (
@@ -3046,14 +3046,14 @@
/obj/effect/decal/remains/human,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"gV" = (
/obj/effect/decal/cleanable/blood/old,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"gW" = (
@@ -3372,7 +3372,7 @@
/obj/structure/destructible/cult/pylon,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"hG" = (
@@ -3637,7 +3637,7 @@
/obj/effect/spawner/lootdrop/snowdin/dungeonmid,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"im" = (
@@ -3647,7 +3647,7 @@
},
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"in" = (
@@ -3657,7 +3657,7 @@
},
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"io" = (
@@ -4458,7 +4458,7 @@
},
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"jP" = (
@@ -5553,7 +5553,7 @@
/obj/effect/spawner/lootdrop/snowdin/dungeonlite,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"lU" = (
@@ -7439,7 +7439,7 @@
/obj/structure/flora/rock/pile/icy,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"qh" = (
@@ -13071,7 +13071,7 @@
/turf/open/floor/mineral/plastitanium{
initial_gas_mix = "o2=22;n2=82;TEMP=180";
planetary_atmos = 1;
- temperature = 180
+ initial_temperature = 180
},
/area/awaymission/snowdin/cave)
"EF" = (
@@ -13083,7 +13083,7 @@
/turf/open/floor/mineral/plastitanium{
initial_gas_mix = "o2=22;n2=82;TEMP=180";
planetary_atmos = 1;
- temperature = 180
+ initial_temperature = 180
},
/area/awaymission/snowdin/cave)
"EG" = (
@@ -13097,7 +13097,7 @@
/turf/open/floor/mineral/plastitanium{
initial_gas_mix = "o2=22;n2=82;TEMP=180";
planetary_atmos = 1;
- temperature = 180
+ initial_temperature = 180
},
/area/awaymission/snowdin/cave)
"EH" = (
diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm
index 5bb51263e5fc..1e0cf6ce459a 100644
--- a/_maps/RandomZLevels/moonoutpost19.dmm
+++ b/_maps/RandomZLevels/moonoutpost19.dmm
@@ -954,7 +954,7 @@
/turf/open/floor/plating{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"bY" = (
@@ -981,7 +981,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"ca" = (
@@ -989,7 +989,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cb" = (
@@ -1002,7 +1002,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cc" = (
@@ -1016,7 +1016,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cd" = (
@@ -1030,7 +1030,7 @@
heat_capacity = 1e+006;
icon_state = "floorscorched2";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"ce" = (
@@ -1044,7 +1044,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cf" = (
@@ -1058,7 +1058,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cg" = (
@@ -1071,7 +1071,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"ch" = (
@@ -1086,7 +1086,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"ci" = (
@@ -1164,7 +1164,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cp" = (
@@ -1181,7 +1181,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cr" = (
@@ -1211,7 +1211,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"ct" = (
@@ -1234,7 +1234,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cv" = (
@@ -1248,7 +1248,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cw" = (
@@ -1324,7 +1324,7 @@
/turf/open/floor/plating{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cD" = (
@@ -1341,7 +1341,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cF" = (
@@ -1353,7 +1353,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cG" = (
@@ -1378,7 +1378,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cI" = (
@@ -1390,7 +1390,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cJ" = (
@@ -1401,7 +1401,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cK" = (
@@ -1422,7 +1422,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cL" = (
@@ -1437,7 +1437,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cM" = (
@@ -1498,7 +1498,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cR" = (
@@ -1507,7 +1507,7 @@
heat_capacity = 1e+006;
icon_state = "damaged4";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cS" = (
@@ -1527,7 +1527,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cT" = (
@@ -1563,7 +1563,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cW" = (
@@ -1572,7 +1572,7 @@
heat_capacity = 1e+006;
icon_state = "damaged2";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cX" = (
@@ -1581,7 +1581,7 @@
heat_capacity = 1e+006;
icon_state = "damaged3";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cY" = (
@@ -1598,7 +1598,7 @@
dir = 1;
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"cZ" = (
@@ -1664,7 +1664,7 @@
/turf/open/floor/plating{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"df" = (
@@ -1686,7 +1686,7 @@
dir = 1;
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dh" = (
@@ -1738,7 +1738,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dm" = (
@@ -1749,7 +1749,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dn" = (
@@ -1759,7 +1759,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"do" = (
@@ -1768,7 +1768,7 @@
heat_capacity = 1e+006;
icon_state = "damaged1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dp" = (
@@ -1782,7 +1782,7 @@
heat_capacity = 1e+006;
icon_state = "platingdmg3";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dq" = (
@@ -1870,7 +1870,7 @@
/turf/open/floor/plating{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dx" = (
@@ -1892,7 +1892,7 @@
/turf/open/floor/plating{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dz" = (
@@ -1921,7 +1921,7 @@
/turf/open/floor/plating{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dC" = (
@@ -1929,7 +1929,7 @@
heat_capacity = 1e+006;
icon_state = "platingdmg1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dD" = (
@@ -1941,7 +1941,7 @@
/turf/open/floor/plating{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dE" = (
@@ -2005,7 +2005,7 @@
icon_plating = "asteroidplating";
icon_state = "asteroidplating";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dJ" = (
@@ -2031,7 +2031,7 @@
icon_plating = "asteroidplating";
icon_state = "asteroidplating";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/syndicate)
"dM" = (
@@ -2040,7 +2040,7 @@
icon_plating = "asteroidplating";
icon_state = "asteroidplating";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/main)
"dN" = (
@@ -4936,7 +4936,7 @@
heat_capacity = 1e+006;
icon_state = "platingdmg1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"jB" = (
@@ -5188,7 +5188,7 @@
heat_capacity = 1e+006;
icon_state = "floorscorched2";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kd" = (
@@ -5200,7 +5200,7 @@
heat_capacity = 1e+006;
icon_state = "damaged1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"ke" = (
@@ -5212,7 +5212,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kf" = (
@@ -5226,7 +5226,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kg" = (
@@ -5238,7 +5238,7 @@
heat_capacity = 1e+006;
icon_state = "floorscorched1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kh" = (
@@ -5249,7 +5249,7 @@
heat_capacity = 1e+006;
icon_state = "platingdmg1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"ki" = (
@@ -5261,7 +5261,7 @@
heat_capacity = 1e+006;
icon_state = "damaged3";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kj" = (
@@ -5448,7 +5448,7 @@
heat_capacity = 1e+006;
icon_state = "damaged2";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kC" = (
@@ -5467,7 +5467,7 @@
heat_capacity = 1e+006;
icon_state = "damaged4";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kE" = (
@@ -5475,7 +5475,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kF" = (
@@ -5484,7 +5484,7 @@
heat_capacity = 1e+006;
icon_state = "damaged5";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kG" = (
@@ -5493,7 +5493,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kH" = (
@@ -5591,7 +5591,7 @@
heat_capacity = 1e+006;
icon_state = "platingdmg3";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"kR" = (
@@ -5779,7 +5779,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"ll" = (
@@ -5791,7 +5791,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"lm" = (
@@ -5901,7 +5901,7 @@
"lv" = (
/turf/open/floor/plasteel/showroomfloor{
heat_capacity = 1e+006;
- temperature = 273.15
+ initial_temperature = 273.15
},
/area/awaymission/moonoutpost19/arrivals)
"lw" = (
@@ -5912,7 +5912,7 @@
},
/turf/open/floor/plasteel/showroomfloor{
heat_capacity = 1e+006;
- temperature = 273.15
+ initial_temperature = 273.15
},
/area/awaymission/moonoutpost19/arrivals)
"lx" = (
@@ -5924,7 +5924,7 @@
/obj/item/clothing/under/waiter,
/turf/open/floor/plasteel/showroomfloor{
heat_capacity = 1e+006;
- temperature = 273.15
+ initial_temperature = 273.15
},
/area/awaymission/moonoutpost19/arrivals)
"lA" = (
@@ -5940,7 +5940,7 @@
},
/turf/open/floor/plating{
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"lE" = (
@@ -5983,7 +5983,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"lJ" = (
@@ -5993,7 +5993,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"lK" = (
@@ -6067,7 +6067,7 @@
/obj/item/gun/ballistic/shotgun/sc_pump,
/turf/open/floor/plasteel/showroomfloor{
heat_capacity = 1e+006;
- temperature = 273.15
+ initial_temperature = 273.15
},
/area/awaymission/moonoutpost19/arrivals)
"lW" = (
@@ -6141,7 +6141,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"mi" = (
@@ -6192,7 +6192,7 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plasteel/showroomfloor{
heat_capacity = 1e+006;
- temperature = 273.15
+ initial_temperature = 273.15
},
/area/awaymission/moonoutpost19/arrivals)
"mn" = (
@@ -6207,7 +6207,7 @@
/obj/item/reagent_containers/food/snacks/meat/slab/monkey,
/turf/open/floor/plasteel/showroomfloor{
heat_capacity = 1e+006;
- temperature = 273.15
+ initial_temperature = 273.15
},
/area/awaymission/moonoutpost19/arrivals)
"mo" = (
@@ -6222,7 +6222,7 @@
/obj/item/storage/fancy/egg_box,
/turf/open/floor/plasteel/showroomfloor{
heat_capacity = 1e+006;
- temperature = 273.15
+ initial_temperature = 273.15
},
/area/awaymission/moonoutpost19/arrivals)
"mp" = (
@@ -6289,7 +6289,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"my" = (
@@ -6457,7 +6457,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"mQ" = (
@@ -6471,7 +6471,7 @@
heat_capacity = 1e+006;
icon_state = "floorscorched2";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"mR" = (
@@ -6548,7 +6548,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"na" = (
@@ -6601,7 +6601,7 @@
heat_capacity = 1e+006;
icon_state = "floorscorched2";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nj" = (
@@ -6614,7 +6614,7 @@
heat_capacity = 1e+006;
icon_state = "damaged2";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nk" = (
@@ -6673,7 +6673,7 @@
heat_capacity = 1e+006;
icon_state = "damaged1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nr" = (
@@ -6704,7 +6704,7 @@
icon_plating = "asteroidplating";
icon_state = "asteroidplating";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nw" = (
@@ -6718,7 +6718,7 @@
/turf/open/floor/plasteel/cafeteria{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nx" = (
@@ -6742,7 +6742,7 @@
/turf/open/floor/plasteel/cafeteria{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"ny" = (
@@ -6757,7 +6757,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nz" = (
@@ -6810,7 +6810,7 @@
heat_capacity = 1e+006;
icon_state = "platingdmg1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nE" = (
@@ -6823,7 +6823,7 @@
heat_capacity = 1e+006;
icon_state = "platingdmg3";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nF" = (
@@ -6836,7 +6836,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nG" = (
@@ -6849,7 +6849,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nH" = (
@@ -6911,7 +6911,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nN" = (
@@ -6922,7 +6922,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nO" = (
@@ -6966,7 +6966,7 @@
heat_capacity = 1e+006;
icon_state = "damaged1";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nT" = (
@@ -7003,7 +7003,7 @@
icon_plating = "asteroidplating";
icon_state = "asteroidplating";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nX" = (
@@ -7015,7 +7015,7 @@
heat_capacity = 1e+006;
icon_state = "floorscorched2";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nY" = (
@@ -7029,7 +7029,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"nZ" = (
@@ -7039,7 +7039,7 @@
icon_plating = "asteroidplating";
icon_state = "asteroidplating";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/main)
"oa" = (
@@ -7061,7 +7061,7 @@
/turf/open/floor/plasteel{
heat_capacity = 1e+006;
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/arrivals)
"oc" = (
@@ -7074,7 +7074,7 @@
icon_plating = "asteroidplating";
icon_state = "asteroidplating";
initial_gas_mix = "co2=48.7;n2=13.2;o2=32.4;TEMP=251";
- temperature = 251
+ initial_temperature = 251
},
/area/awaymission/moonoutpost19/main)
"od" = (
diff --git a/_maps/RandomZLevels/snowdin.dmm b/_maps/RandomZLevels/snowdin.dmm
index 69a2ac9a86c6..ab80473ae735 100644
--- a/_maps/RandomZLevels/snowdin.dmm
+++ b/_maps/RandomZLevels/snowdin.dmm
@@ -2688,14 +2688,14 @@
"gc" = (
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"gd" = (
/obj/effect/spawner/lootdrop/crate_spawner,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"ge" = (
@@ -2706,7 +2706,7 @@
/obj/effect/spawner/lootdrop/snowdin/dungeonheavy,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"gg" = (
@@ -3077,14 +3077,14 @@
/obj/effect/decal/remains/human,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"gV" = (
/obj/effect/decal/cleanable/blood/old,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"gW" = (
@@ -3391,7 +3391,7 @@
/obj/structure/destructible/cult/pylon,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"hG" = (
@@ -3652,7 +3652,7 @@
/obj/effect/spawner/lootdrop/snowdin/dungeonmid,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"im" = (
@@ -3662,7 +3662,7 @@
},
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"in" = (
@@ -3672,7 +3672,7 @@
},
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"io" = (
@@ -4489,7 +4489,7 @@
},
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"jP" = (
@@ -5615,7 +5615,7 @@
/obj/effect/spawner/lootdrop/snowdin/dungeonlite,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"lU" = (
@@ -7509,7 +7509,7 @@
/obj/structure/flora/rock/pile/icy,
/turf/open/floor/engine/cult{
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120";
- temperature = 120
+ initial_temperature = 120
},
/area/awaymission/snowdin/cave/cavern)
"qh" = (
@@ -13210,7 +13210,7 @@
/turf/open/floor/mineral/plastitanium{
initial_gas_mix = "o2=22;n2=82;TEMP=180";
planetary_atmos = 1;
- temperature = 180
+ initial_temperature = 180
},
/area/awaymission/snowdin/cave)
"EF" = (
@@ -13222,7 +13222,7 @@
/turf/open/floor/mineral/plastitanium{
initial_gas_mix = "o2=22;n2=82;TEMP=180";
planetary_atmos = 1;
- temperature = 180
+ initial_temperature = 180
},
/area/awaymission/snowdin/cave)
"EG" = (
@@ -13236,7 +13236,7 @@
/turf/open/floor/mineral/plastitanium{
initial_gas_mix = "o2=22;n2=82;TEMP=180";
planetary_atmos = 1;
- temperature = 180
+ initial_temperature = 180
},
/area/awaymission/snowdin/cave)
"EH" = (
diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm
index 2b15f9a3ec6a..3bb3fb1b1440 100644
--- a/_maps/RandomZLevels/undergroundoutpost45.dmm
+++ b/_maps/RandomZLevels/undergroundoutpost45.dmm
@@ -807,7 +807,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 351.9
+ initial_temperature = 351.9
},
/area/awaymission/undergroundoutpost45/caves)
"bX" = (
@@ -815,7 +815,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 351.9
+ initial_temperature = 351.9
},
/area/awaymission/undergroundoutpost45/caves)
"bY" = (
@@ -2112,7 +2112,7 @@
icon_plating = "asteroidplating";
icon_state = "asteroidplating";
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"ev" = (
@@ -2247,7 +2247,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"eK" = (
@@ -2625,7 +2625,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/central)
"fo" = (
@@ -2861,7 +2861,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/central)
"fK" = (
@@ -3042,7 +3042,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"gg" = (
@@ -3190,7 +3190,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"gC" = (
@@ -3462,7 +3462,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/research)
"he" = (
@@ -3473,7 +3473,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"hf" = (
@@ -3505,7 +3505,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"hi" = (
@@ -4904,7 +4904,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/gateway)
"jM" = (
@@ -4938,7 +4938,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/research)
"jR" = (
@@ -6754,7 +6754,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/gateway)
"mJ" = (
@@ -8519,7 +8519,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"pv" = (
@@ -8530,7 +8530,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"pw" = (
@@ -8542,7 +8542,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/engineering)
"px" = (
@@ -8835,7 +8835,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"qb" = (
@@ -9069,7 +9069,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"qA" = (
@@ -9080,7 +9080,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"qB" = (
@@ -9091,7 +9091,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"qC" = (
@@ -11292,7 +11292,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"uc" = (
@@ -11946,7 +11946,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"vm" = (
@@ -12172,7 +12172,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/research)
"vI" = (
@@ -12469,7 +12469,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/mining)
"wk" = (
@@ -13692,7 +13692,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/mining)
"yh" = (
@@ -13701,7 +13701,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yi" = (
@@ -13710,7 +13710,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yj" = (
@@ -13721,7 +13721,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yk" = (
@@ -13731,7 +13731,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yl" = (
@@ -13742,7 +13742,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"ym" = (
@@ -13752,7 +13752,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yn" = (
@@ -13761,7 +13761,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yo" = (
@@ -13771,7 +13771,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yp" = (
@@ -13781,7 +13781,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yq" = (
@@ -13790,7 +13790,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yr" = (
@@ -13799,7 +13799,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yt" = (
@@ -13809,7 +13809,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yu" = (
@@ -13819,7 +13819,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yw" = (
@@ -13829,7 +13829,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yz" = (
@@ -13838,7 +13838,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yA" = (
@@ -13848,7 +13848,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yB" = (
@@ -13857,7 +13857,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yC" = (
@@ -13867,7 +13867,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yD" = (
@@ -13878,7 +13878,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"yH" = (
@@ -13889,7 +13889,7 @@
heat_capacity = 1e+006;
initial_gas_mix = "co2=173.4;n2=135.1;plasma=229.8;TEMP=351.9";
name = "Cave Floor";
- temperature = 363.9
+ initial_temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"zi" = (
diff --git a/_maps/map_files/AsteroidStation/AsteroidStation.dmm b/_maps/map_files/AsteroidStation/AsteroidStation.dmm
index 45869b7ebd28..e21554301c0c 100644
--- a/_maps/map_files/AsteroidStation/AsteroidStation.dmm
+++ b/_maps/map_files/AsteroidStation/AsteroidStation.dmm
@@ -11221,7 +11221,7 @@
icon_state = "0-8"
},
/obj/machinery/power/apc{
- areastring = "/area/service hall";
+ areastring = "/area/hallway/secondary/service";
dir = 4;
name = "Service Hall APC";
pixel_x = 24
@@ -12134,7 +12134,7 @@
"dcK" = (
/obj/machinery/door/airlock/security/glass{
name = "Armoury";
- req_access_txt = "3"
+ req_access_txt = "1"
},
/obj/machinery/door/firedoor/border_only,
/obj/machinery/door/firedoor/border_only{
@@ -17322,6 +17322,20 @@
/obj/effect/turf_decal/trimline/green/filled/line/lower,
/turf/open/floor/plasteel,
/area/hallway/primary/starboard)
+"eHJ" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
+ dir = 1
+ },
+/obj/structure/cable,
+/obj/machinery/power/apc{
+ areastring = "/area/medical/storage/backroom";
+ dir = 2;
+ name = "Medical Backrooms APC";
+ pixel_y = -23
+ },
+/obj/effect/turf_decal/trimline/blue/filled/line/lower,
+/turf/open/floor/plasteel/white,
+/area/medical/storage/backroom)
"eHP" = (
/obj/machinery/airalarm{
dir = 1;
@@ -17588,25 +17602,6 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
/turf/open/floor/plasteel,
/area/clerk)
-"eMa" = (
-/obj/structure/disposalpipe/segment{
- dir = 9
- },
-/obj/structure/cable{
- icon_state = "1-8"
- },
-/obj/structure/table,
-/obj/item/clothing/suit/straight_jacket,
-/obj/item/clothing/mask/muzzle,
-/obj/machinery/power/apc{
- areastring = "/area/medical/central";
- name = "Medbay Central APC";
- pixel_y = -23
- },
-/obj/structure/cable,
-/obj/effect/turf_decal/trimline/blue/filled/line/lower,
-/turf/open/floor/plasteel/white,
-/area/medical/medbay/central)
"eMc" = (
/obj/machinery/camera{
c_tag = "Atmospherics - Incinerator";
@@ -18510,6 +18505,25 @@
},
/turf/open/floor/plasteel/white,
/area/science/mixing)
+"eZo" = (
+/obj/structure/disposalpipe/segment{
+ dir = 9
+ },
+/obj/structure/cable{
+ icon_state = "1-8"
+ },
+/obj/structure/table,
+/obj/item/clothing/suit/straight_jacket,
+/obj/item/clothing/mask/muzzle,
+/obj/machinery/power/apc{
+ areastring = "/area/medical/medbay/central";
+ name = "Medbay Central APC";
+ pixel_y = -23
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/trimline/blue/filled/line/lower,
+/turf/open/floor/plasteel/white,
+/area/medical/medbay/central)
"eZK" = (
/obj/machinery/atmospherics/pipe/simple/cyan/visible{
dir = 4
@@ -29685,25 +29699,6 @@
},
/turf/open/floor/plasteel/dark,
/area/engine/engineering)
-"iFS" = (
-/obj/effect/mapping_helpers/airlock/cyclelink_helper{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/layer_manifold{
- dir = 1
- },
-/obj/machinery/door/firedoor/border_only{
- dir = 1
- },
-/obj/machinery/door/firedoor/border_only,
-/obj/machinery/atmospherics/pipe/layer_manifold{
- dir = 1
- },
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 2"
- },
-/turf/open/floor/plasteel,
-/area/hallway/secondary/entry)
"iFW" = (
/turf/closed/wall/r_wall,
/area/engine/atmos/storage)
@@ -43190,20 +43185,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
-"mSH" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
- dir = 1
- },
-/obj/structure/cable,
-/obj/machinery/power/apc{
- areastring = "/area/medical/backrooms";
- dir = 2;
- name = "Medical Backrooms APC";
- pixel_y = -23
- },
-/obj/effect/turf_decal/trimline/blue/filled/line/lower,
-/turf/open/floor/plasteel/white,
-/area/medical/storage/backroom)
"mSV" = (
/obj/machinery/light,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
@@ -52376,6 +52357,22 @@
},
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
+"pKn" = (
+/obj/effect/mapping_helpers/airlock/cyclelink_helper{
+ dir = 1
+ },
+/obj/machinery/door/firedoor/border_only{
+ dir = 1
+ },
+/obj/machinery/door/firedoor/border_only,
+/obj/machinery/atmospherics/pipe/layer_manifold{
+ dir = 1
+ },
+/obj/machinery/door/airlock/external{
+ name = "Port Docking Bay 2"
+ },
+/turf/open/floor/plasteel,
+/area/hallway/secondary/entry)
"pKr" = (
/obj/effect/turf_decal/siding/wideplating{
dir = 4
@@ -88665,7 +88662,7 @@ hOf
eff
orl
mHY
-iFS
+pKn
aPF
acb
acb
@@ -109267,7 +109264,7 @@ aZJ
eQk
haa
nuJ
-eMa
+eZo
aGU
aGU
aGU
@@ -112611,7 +112608,7 @@ jbG
miU
brL
xrr
-mSH
+eHJ
wOM
faF
vBA
diff --git a/_maps/map_files/DonutStation/DonutStation.dmm b/_maps/map_files/DonutStation/DonutStation.dmm
index 889725455573..2895b1bb47eb 100644
--- a/_maps/map_files/DonutStation/DonutStation.dmm
+++ b/_maps/map_files/DonutStation/DonutStation.dmm
@@ -1456,6 +1456,19 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
/turf/open/floor/plating,
/area/maintenance/port/aft)
+"aFg" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 5
+ },
+/obj/structure/cable,
+/obj/machinery/power/apc{
+ areastring = "/area/chapel/office";
+ dir = 8;
+ name = "Chapel Office APC";
+ pixel_x = -25
+ },
+/turf/open/floor/plasteel/dark,
+/area/chapel/office)
"aFm" = (
/obj/structure/particle_accelerator/power_box{
dir = 1;
@@ -2447,6 +2460,24 @@
},
/turf/open/floor/plating,
/area/maintenance/port/fore)
+"bbd" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/machinery/door/airlock/maintenance{
+ req_one_access_txt = "0"
+ },
+/obj/machinery/door/firedoor/border_only{
+ dir = 1
+ },
+/obj/machinery/door/firedoor/border_only,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/effect/turf_decal/trimline/yellow/arrow_cw{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/maintenance/aft)
"bbg" = (
/turf/closed/wall,
/area/medical/medbay/lobby)
@@ -3363,6 +3394,15 @@
},
/turf/open/floor/plasteel,
/area/crew_quarters/fitness)
+"bud" = (
+/obj/machinery/camera{
+ c_tag = "Fitness Room"
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_y = 28
+ },
+/turf/open/floor/plasteel,
+/area/crew_quarters/fitness)
"bum" = (
/obj/machinery/computer/cryopod{
pixel_y = 26
@@ -5400,20 +5440,6 @@
},
/turf/open/floor/plasteel/grimy,
/area/ai_monitored/turret_protected/aisat_interior)
-"ciH" = (
-/obj/machinery/door/airlock/external{
- name = "Security External Airlock";
- req_access_txt = "63"
- },
-/obj/machinery/atmospherics/pipe/layer_manifold{
- dir = 4
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper_target{
- dirx = -2;
- diry = 1
- },
-/turf/open/space/basic,
-/area/security/main)
"ciL" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
dir = 1
@@ -5934,6 +5960,21 @@
/obj/item/bedsheet/prisoner,
/turf/open/floor/plasteel,
/area/security/brig)
+"cuV" = (
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/engiyellow/filled/line/lower{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/atmos/warning/lower/nobottom{
+ dir = 4
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = 27
+ },
+/turf/open/floor/plasteel,
+/area/engine/atmos)
"cve" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -6798,6 +6839,18 @@
},
/turf/open/floor/plasteel,
/area/engine/engineering)
+"cMu" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/turf/open/floor/plasteel/grimy,
+/area/chapel/office)
"cMw" = (
/obj/machinery/door/airlock/maintenance{
req_one_access_txt = "12;35"
@@ -7042,16 +7095,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/plating,
/area/maintenance/port/aft)
-"cRh" = (
-/obj/effect/spawner/structure/window/reinforced/shutter,
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/obj/structure/cable{
- icon_state = "0-8"
- },
-/turf/open/floor/plating,
-/area/bridge)
"cRl" = (
/obj/effect/landmark/start/cargo_technician,
/turf/open/floor/plasteel,
@@ -7790,6 +7833,25 @@
},
/turf/open/floor/plasteel/white,
/area/medical/medbay/central)
+"dis" = (
+/obj/structure/chair/comfy/black{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/effect/landmark/start/chief_medical_officer,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/machinery/button/door{
+ id = "bridge blast";
+ name = "Bridge Blast Door Control";
+ pixel_x = 28;
+ pixel_y = 8;
+ req_access_txt = "19"
+ },
+/turf/open/floor/carpet,
+/area/bridge)
"diJ" = (
/obj/structure/barricade/wooden,
/turf/open/floor/plating,
@@ -9344,15 +9406,6 @@
/obj/structure/sign/warning/vacuum,
/turf/closed/wall/rust,
/area/quartermaster/warehouse)
-"dRo" = (
-/obj/effect/turf_decal/trimline/darkblue/filled/corner/lower{
- dir = 1
- },
-/obj/effect/turf_decal/trimline/secred/filled/corner/lower{
- dir = 4
- },
-/turf/open/floor/plasteel/dark,
-/area/bridge)
"dRH" = (
/obj/machinery/light{
dir = 8
@@ -9674,6 +9727,17 @@
/obj/item/extinguisher,
/turf/open/floor/plating,
/area/maintenance/port/fore)
+"dZo" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plasteel/grimy,
+/area/chapel/office)
"dZx" = (
/obj/structure/closet/secure_closet/security/sec,
/turf/open/floor/plasteel/showroomfloor,
@@ -10788,15 +10852,6 @@
/obj/effect/turf_decal/trimline/engiyellow/filled/line/lower,
/turf/open/floor/plasteel,
/area/engine/atmos)
-"ezL" = (
-/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer4{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
- dir = 6
- },
-/turf/open/floor/plasteel/grimy,
-/area/chapel/office)
"eAb" = (
/obj/machinery/door/airlock{
name = "Unisex Restrooms"
@@ -12524,24 +12579,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
-"fjm" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
- dir = 1
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/trimline/darkblue/filled/line/lower{
- dir = 1
- },
-/turf/open/floor/plasteel/dark,
-/area/bridge)
"fjw" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/plasteel,
@@ -12823,16 +12860,6 @@
},
/turf/open/floor/plating,
/area/engine/atmos)
-"fqT" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
- dir = 10
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
- dir = 9
- },
-/obj/effect/decal/cleanable/ash/crematorium,
-/turf/open/floor/plasteel/dark,
-/area/chapel/office)
"fra" = (
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on{
dir = 8;
@@ -13153,6 +13180,28 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
+"fvT" = (
+/obj/machinery/door/airlock{
+ name = "Crematorium";
+ req_access_txt = "27"
+ },
+/obj/machinery/door/firedoor/border_only{
+ dir = 4
+ },
+/obj/machinery/door/firedoor/border_only{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/turf/open/floor/plasteel/dark,
+/area/chapel/office)
"fvU" = (
/obj/machinery/door/airlock/public/glass{
name = "Primary Tool Storage"
@@ -13584,16 +13633,6 @@
},
/turf/open/floor/plasteel,
/area/security/checkpoint)
-"fGw" = (
-/obj/effect/spawner/structure/window/reinforced/shutter,
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/obj/structure/cable{
- icon_state = "0-2"
- },
-/turf/open/floor/plating,
-/area/bridge)
"fGB" = (
/obj/structure/disposalpipe/sorting/mail/flip{
dir = 8;
@@ -13860,6 +13899,28 @@
},
/turf/open/floor/plating,
/area/quartermaster/warehouse)
+"fNj" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/machinery/door/airlock/maintenance{
+ req_one_access_txt = "12"
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/door/firedoor/border_only{
+ dir = 4
+ },
+/obj/machinery/door/firedoor/border_only{
+ dir = 8
+ },
+/turf/open/floor/plasteel,
+/area/maintenance/port/aft)
"fNl" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -14078,6 +14139,15 @@
/obj/effect/turf_decal/trimline/green/filled/corner/lower,
/turf/open/floor/plasteel,
/area/hallway/primary/central)
+"fRz" = (
+/obj/effect/turf_decal/trimline/purple/filled/line/lower{
+ dir = 8
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel,
+/area/hallway/primary/central)
"fRQ" = (
/obj/machinery/rnd/production/techfab/department/service,
/turf/open/floor/plasteel,
@@ -14349,6 +14419,21 @@
"fZd" = (
/turf/open/floor/plasteel,
/area/security/processing)
+"fZm" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/structure/cable{
+ icon_state = "1-4"
+ },
+/turf/open/floor/plasteel/dark,
+/area/bridge)
"fZy" = (
/obj/structure/cable{
icon_state = "2-8"
@@ -14607,6 +14692,12 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
+"geT" = (
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/port/aft)
"geZ" = (
/obj/machinery/light{
dir = 1
@@ -15175,16 +15266,6 @@
},
/turf/open/floor/plasteel,
/area/security/main)
-"gsw" = (
-/obj/effect/spawner/structure/window/reinforced/shutter,
-/obj/structure/cable{
- icon_state = "2-8"
- },
-/obj/structure/cable{
- icon_state = "0-2"
- },
-/turf/open/floor/plating,
-/area/bridge)
"gsD" = (
/obj/machinery/door/airlock/maintenance{
req_one_access_txt = "12"
@@ -15225,6 +15306,16 @@
},
/turf/open/floor/plasteel,
/area/engine/atmos)
+"gtn" = (
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/obj/machinery/light_switch{
+ pixel_x = -4;
+ pixel_y = -24
+ },
+/turf/open/floor/carpet/black,
+/area/crew_quarters/bar)
"gtI" = (
/obj/machinery/power/port_gen/pacman,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
@@ -15282,6 +15373,13 @@
},
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
+"guW" = (
+/obj/structure/chair/stool/bar,
+/obj/machinery/light_switch{
+ pixel_x = 24
+ },
+/turf/open/floor/wood,
+/area/crew_quarters/kitchen)
"gvo" = (
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating/airless,
@@ -15476,6 +15574,19 @@
},
/turf/open/floor/plating,
/area/maintenance/port)
+"gzX" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,
+/obj/effect/turf_decal/trimline/engiyellow/filled/line/lower{
+ dir = 8
+ },
+/obj/effect/turf_decal/trimline/atmos/warning/lower/nobottom{
+ dir = 8
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel,
+/area/engine/atmos)
"gAh" = (
/obj/effect/turf_decal/stripes/corner{
dir = 8
@@ -16095,6 +16206,21 @@
},
/turf/open/floor/plasteel/white,
/area/medical/genetics)
+"gQN" = (
+/obj/structure/disposalpipe/segment,
+/obj/effect/turf_decal/trimline/blue/filled/line/lower{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel/white,
+/area/medical/medbay/central)
"gQT" = (
/obj/machinery/shower{
dir = 4
@@ -16191,6 +16317,10 @@
},
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
+"gTN" = (
+/obj/machinery/light/small,
+/turf/open/floor/plating,
+/area/maintenance/aft)
"gUe" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
@@ -16251,6 +16381,19 @@
"gVe" = (
/turf/open/floor/plasteel/dark,
/area/engine/gravity_generator)
+"gVx" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/effect/turf_decal/trimline/blue/filled/line/lower{
+ dir = 8
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel/white,
+/area/medical/medbay/central)
"gVz" = (
/obj/structure/rack,
/obj/item/stack/sheet/metal/fifty,
@@ -17964,6 +18107,17 @@
/obj/machinery/vending/clothing,
/turf/open/floor/plasteel,
/area/crew_quarters/dorms)
+"hJN" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plasteel/grimy,
+/area/chapel/office)
"hJO" = (
/obj/machinery/computer/shuttle/labor{
dir = 1;
@@ -18418,18 +18572,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/secondary/entry)
-"hWN" = (
-/obj/structure/cable/yellow{
- icon_state = "1-2"
- },
-/obj/effect/turf_decal/trimline/engiyellow/filled/corner/lower{
- dir = 1
- },
-/obj/effect/turf_decal/trimline/secred/filled/corner/lower{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/engine/engineering)
"hWV" = (
/obj/machinery/camera{
c_tag = "Research - Main 2";
@@ -18789,16 +18931,6 @@
},
/turf/open/floor/carpet,
/area/library)
-"ifd" = (
-/obj/machinery/camera{
- c_tag = "Hallway - Central Southeast 2";
- dir = 4
- },
-/obj/effect/turf_decal/trimline/secred/filled/line/lower{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/hallway/primary/central)
"ifi" = (
/obj/effect/turf_decal/stripes/corner,
/turf/open/floor/plating,
@@ -20527,6 +20659,19 @@
},
/turf/open/floor/grass,
/area/medical/genetics)
+"iWP" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 10
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 9
+ },
+/obj/effect/decal/cleanable/ash/crematorium,
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/turf/open/floor/plasteel/dark,
+/area/chapel/office)
"iXh" = (
/obj/structure/closet/crate{
name = "Surplus Toxins Supplies"
@@ -21942,6 +22087,21 @@
},
/turf/open/floor/plasteel/showroomfloor,
/area/security/warden)
+"jBZ" = (
+/obj/structure/cable/yellow{
+ icon_state = "1-2"
+ },
+/obj/effect/turf_decal/trimline/engiyellow/filled/corner/lower{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/secred/filled/corner/lower{
+ dir = 8
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel,
+/area/engine/engineering)
"jCf" = (
/obj/effect/turf_decal/trimline/engiyellow/filled/line/lower{
dir = 4
@@ -22096,6 +22256,19 @@
/obj/structure/table/wood,
/turf/open/floor/carpet,
/area/library)
+"jEs" = (
+/obj/effect/turf_decal/trimline/engiyellow/filled/corner/lower,
+/obj/effect/turf_decal/trimline/atmos/warning/lower/corner/flip{
+ dir = 2
+ },
+/obj/effect/turf_decal/trimline/green/filled/corner/lower{
+ dir = 1
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel,
+/area/hallway/primary/central)
"jEP" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
dir = 4
@@ -22210,6 +22383,15 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/maintenance/disposal)
+"jHI" = (
+/obj/structure/chair{
+ dir = 1
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/wood,
+/area/hallway/primary/central)
"jHS" = (
/obj/machinery/atmospherics/pipe/simple/yellow/visible,
/obj/effect/turf_decal/trimline/blue/filled/corner/lower,
@@ -22776,6 +22958,14 @@
/obj/effect/spawner/lootdrop/maintenance,
/turf/closed/wall,
/area/maintenance/fore)
+"jRs" = (
+/obj/effect/turf_decal/trimline/darkblue/filled/line/lower,
+/obj/machinery/door/poddoor/preopen{
+ id = "bridge blast";
+ name = "bridge blast door"
+ },
+/turf/open/floor/plasteel/dark,
+/area/bridge)
"jRC" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
dir = 4
@@ -23165,14 +23355,6 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
/turf/open/floor/carpet,
/area/crew_quarters/theatre)
-"jZE" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
-/turf/open/floor/plasteel/grimy,
-/area/chapel/office)
"jZF" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 1;
@@ -23727,11 +23909,6 @@
/obj/machinery/door/firedoor/border_only,
/turf/open/floor/plating,
/area/maintenance/port/aft)
-"kkT" = (
-/obj/effect/decal/cleanable/blood/old,
-/obj/item/tank/internals/emergency_oxygen/empty,
-/turf/open/floor/plating/asteroid/airless,
-/area/space/nearstation)
"kkZ" = (
/turf/open/floor/plasteel,
/area/escapepodbay)
@@ -24067,6 +24244,24 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
/turf/open/floor/plating,
/area/ai_monitored/storage/satellite)
+"ktH" = (
+/obj/effect/turf_decal/trimline/darkblue/filled/corner/lower{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/secred/filled/corner/lower{
+ dir = 4
+ },
+/obj/machinery/power/apc/highcap/five_k{
+ areastring = "/area/bridge";
+ dir = 1;
+ name = "Bridge APC";
+ pixel_y = 23
+ },
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/turf/open/floor/plasteel/dark,
+/area/bridge)
"ktL" = (
/obj/structure/cable{
icon_state = "1-4"
@@ -24233,6 +24428,12 @@
},
/turf/open/floor/plasteel,
/area/engine/atmos)
+"kze" = (
+/obj/structure/extinguisher_cabinet{
+ pixel_x = 28
+ },
+/turf/open/floor/plasteel,
+/area/hallway/secondary/exit/departure_lounge)
"kzy" = (
/obj/structure/chair,
/obj/effect/landmark/start/assistant,
@@ -24487,6 +24688,18 @@
/obj/item/gps,
/turf/open/floor/plating,
/area/engine/engineering)
+"kJb" = (
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer4{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 6
+ },
+/obj/structure/cable{
+ icon_state = "2-4"
+ },
+/turf/open/floor/plasteel/grimy,
+/area/chapel/office)
"kJg" = (
/obj/effect/spawner/structure/window/reinforced/shutter,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
@@ -24523,19 +24736,17 @@
/area/maintenance/fore)
"kLb" = (
/obj/structure/table/glass,
-/obj/item/clothing/gloves/color/latex,
-/obj/item/reagent_containers/spray/cleaner,
/obj/machinery/camera{
c_tag = "Security - Medical Room";
dir = 1;
network = list("ss13","Security")
},
-/obj/item/reagent_containers/glass/bottle/epinephrine,
-/obj/item/reagent_containers/glass/bottle/charcoal,
-/obj/item/reagent_containers/syringe,
/obj/effect/turf_decal/trimline/blue/filled/line/lower{
dir = 10
},
+/obj/machinery/computer/med_data/laptop{
+ dir = 1
+ },
/turf/open/floor/plasteel/white,
/area/security/brig)
"kLS" = (
@@ -24908,12 +25119,6 @@
/obj/item/reagent_containers/food/drinks/soda_cans/grey_bull,
/turf/open/floor/carpet,
/area/hallway/secondary/entry)
-"kSi" = (
-/obj/effect/decal/remains/human,
-/obj/effect/decal/cleanable/blood/old,
-/obj/item/pickaxe,
-/turf/open/floor/plating/asteroid/airless,
-/area/space/nearstation)
"kSm" = (
/obj/structure/cable{
icon_state = "1-2"
@@ -25018,10 +25223,6 @@
},
/turf/open/floor/plasteel/grimy,
/area/tcommsat/computer)
-"kVo" = (
-/obj/effect/decal/cleanable/blood/old,
-/turf/open/floor/plating/asteroid/airless,
-/area/space/nearstation)
"kVw" = (
/obj/machinery/telecomms/bus/preset_two,
/turf/open/floor/circuit/telecomms/mainframe,
@@ -26506,6 +26707,12 @@
dir = 8
},
/area/chapel/main)
+"lDg" = (
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel/grimy,
+/area/tcommsat/computer)
"lDG" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 4
@@ -27025,6 +27232,13 @@
},
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
+"lNv" = (
+/obj/structure/closet/secure_closet/bartender,
+/obj/item/stack/sheet/glass/fifty,
+/obj/item/stack/sheet/metal/fifty,
+/obj/item/stack/cable_coil,
+/turf/open/floor/wood,
+/area/crew_quarters/bar)
"lNJ" = (
/turf/open/floor/plasteel/airless{
icon_state = "damaged2"
@@ -27301,10 +27515,6 @@
/obj/item/kirbyplants/random,
/turf/open/floor/wood,
/area/hallway/primary/central)
-"lSG" = (
-/obj/effect/decal/cleanable/blood/gibs/old,
-/turf/open/floor/plating/asteroid/airless,
-/area/space/nearstation)
"lSS" = (
/obj/structure/disposalpipe/sorting/mail/flip{
dir = 1;
@@ -27457,16 +27667,6 @@
/obj/effect/turf_decal/trimline/green/filled/line/lower,
/turf/open/floor/plasteel/white,
/area/medical/virology)
-"lWE" = (
-/obj/effect/turf_decal/trimline/engiyellow/filled/corner/lower,
-/obj/effect/turf_decal/trimline/atmos/warning/lower/corner/flip{
- dir = 2
- },
-/obj/effect/turf_decal/trimline/green/filled/corner/lower{
- dir = 1
- },
-/turf/open/floor/plasteel,
-/area/hallway/primary/central)
"lWG" = (
/obj/structure/table,
/obj/item/gun/energy/e_gun/dragnet,
@@ -27542,6 +27742,12 @@
/obj/machinery/space_heater,
/turf/open/floor/plating,
/area/maintenance/aft)
+"lYe" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
+ dir = 4
+ },
+/turf/open/floor/plasteel/grimy,
+/area/chapel/office)
"lYB" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,
/obj/structure/extinguisher_cabinet{
@@ -27903,6 +28109,16 @@
},
/turf/open/floor/plasteel,
/area/engine/atmos)
+"mhp" = (
+/obj/structure/table/wood,
+/obj/machinery/light{
+ dir = 1
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_y = 28
+ },
+/turf/open/floor/carpet,
+/area/crew_quarters/cryopods)
"mhM" = (
/obj/structure/cable{
icon_state = "4-8"
@@ -29236,18 +29452,6 @@
/obj/effect/decal/cleanable/blood/old,
/turf/open/floor/plasteel/dark,
/area/quartermaster/warehouse)
-"mKD" = (
-/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{
- dir = 4
- },
-/obj/effect/turf_decal/trimline/engiyellow/filled/line/lower{
- dir = 4
- },
-/obj/effect/turf_decal/trimline/atmos/warning/lower/nobottom{
- dir = 4
- },
-/turf/open/floor/plasteel,
-/area/engine/atmos)
"mKK" = (
/obj/machinery/light_switch{
pixel_x = 24
@@ -30616,6 +30820,20 @@
},
/turf/open/floor/plasteel,
/area/security/prison)
+"nlF" = (
+/obj/machinery/door/airlock/external{
+ name = "Security External Airlock";
+ req_access_txt = "63"
+ },
+/obj/machinery/atmospherics/pipe/layer_manifold{
+ dir = 4
+ },
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_target{
+ dirx = -2;
+ diry = 1
+ },
+/turf/open/floor/plating,
+/area/security/main)
"nlJ" = (
/obj/structure/frame/machine,
/obj/effect/turf_decal/stripes/line{
@@ -30811,25 +31029,6 @@
},
/turf/open/floor/plasteel/white,
/area/science/lab)
-"nrb" = (
-/obj/machinery/door/airlock{
- name = "Crematorium";
- req_access_txt = "27"
- },
-/obj/machinery/door/firedoor/border_only{
- dir = 4
- },
-/obj/machinery/door/firedoor/border_only{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
- dir = 4
- },
-/turf/open/floor/plasteel/dark,
-/area/chapel/office)
"nrc" = (
/obj/structure/closet/toolcloset,
/turf/open/floor/plasteel,
@@ -31796,18 +31995,6 @@
},
/turf/open/floor/plasteel,
/area/engine/engineering)
-"nLN" = (
-/obj/structure/chair/comfy/black{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/obj/effect/landmark/start/chief_medical_officer,
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/turf/open/floor/carpet,
-/area/bridge)
"nLR" = (
/obj/item/assembly/signaler{
pixel_y = 8
@@ -31960,6 +32147,20 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
+"nOt" = (
+/obj/effect/spawner/structure/window/reinforced/shutter,
+/obj/structure/cable{
+ icon_state = "1-8"
+ },
+/obj/structure/cable{
+ icon_state = "0-8"
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "bridge blast";
+ name = "bridge blast door"
+ },
+/turf/open/floor/plating,
+/area/bridge)
"nOB" = (
/obj/machinery/door/firedoor/border_only{
dir = 8
@@ -32033,6 +32234,13 @@
},
/turf/open/floor/plasteel/dark,
/area/bridge)
+"nQN" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/aft)
"nQO" = (
/obj/machinery/computer/security/mining,
/obj/effect/turf_decal/trimline/brown/filled/line/lower{
@@ -32666,10 +32874,6 @@
/obj/effect/spawner/structure/window/reinforced/shutter,
/turf/open/floor/plating,
/area/engine/engineering)
-"odp" = (
-/obj/structure/closet/secure_closet/bartender,
-/turf/open/floor/wood,
-/area/crew_quarters/bar)
"ody" = (
/obj/effect/turf_decal/trimline/purple/filled/corner/lower{
dir = 8
@@ -32774,6 +32978,12 @@
},
/turf/open/floor/plasteel,
/area/science/mixing)
+"ofp" = (
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel,
+/area/hallway/primary/central)
"ofr" = (
/obj/effect/turf_decal/pool,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
@@ -33972,6 +34182,28 @@
"oJj" = (
/turf/open/floor/plating/burnt,
/area/maintenance/starboard)
+"oJI" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
+ dir = 1
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/darkblue/filled/line/lower{
+ dir = 1
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "bridge blast";
+ name = "bridge blast door"
+ },
+/turf/open/floor/plasteel/dark,
+/area/bridge)
"oJL" = (
/obj/structure/plasticflaps/opaque,
/obj/machinery/navbeacon{
@@ -34314,11 +34546,6 @@
},
/turf/open/floor/plating,
/area/engine/atmos)
-"oRp" = (
-/obj/effect/decal/cleanable/blood/old,
-/obj/effect/decal/cleanable/blood/gibs/old,
-/turf/open/floor/plating/asteroid/airless,
-/area/space/nearstation)
"oRq" = (
/obj/machinery/door/firedoor/border_only{
dir = 1
@@ -34477,6 +34704,20 @@
/obj/effect/landmark/start/detective,
/turf/open/floor/carpet,
/area/security/detectives_office)
+"oVz" = (
+/obj/effect/spawner/structure/window/reinforced/shutter,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "bridge blast";
+ name = "bridge blast door"
+ },
+/turf/open/floor/plating,
+/area/bridge)
"oVN" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 4
@@ -34934,12 +35175,6 @@
},
/turf/open/floor/plasteel,
/area/maintenance/disposal/incinerator)
-"pjA" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
- dir = 5
- },
-/turf/open/floor/plasteel/dark,
-/area/chapel/office)
"pjJ" = (
/obj/machinery/computer/med_data{
dir = 8;
@@ -35353,12 +35588,6 @@
},
/turf/open/floor/plasteel,
/area/security/brig)
-"pqV" = (
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
-/turf/open/floor/carpet/black,
-/area/crew_quarters/bar)
"prf" = (
/obj/effect/landmark/event_spawn,
/turf/open/floor/plasteel,
@@ -36181,6 +36410,20 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
+"pIm" = (
+/obj/effect/spawner/structure/window/reinforced/shutter,
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "bridge blast";
+ name = "bridge blast door"
+ },
+/turf/open/floor/plating,
+/area/bridge)
"pIu" = (
/obj/machinery/portable_atmospherics/scrubber,
/obj/effect/turf_decal/bot,
@@ -36260,6 +36503,12 @@
},
/turf/closed/wall/r_wall,
/area/engine/atmos)
+"pKp" = (
+/obj/structure/extinguisher_cabinet{
+ pixel_x = 27
+ },
+/turf/open/floor/plasteel,
+/area/maintenance/disposal/incinerator)
"pKG" = (
/obj/machinery/light,
/obj/machinery/firealarm{
@@ -36289,12 +36538,6 @@
},
/turf/open/floor/plasteel,
/area/engine/atmos)
-"pLB" = (
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/plasteel/grimy,
-/area/chapel/office)
"pLS" = (
/obj/machinery/door/airlock/virology/glass{
name = "Monkey Pen";
@@ -36510,22 +36753,6 @@
},
/turf/closed/wall/r_wall,
/area/security/prison)
-"pOJ" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/obj/machinery/door/airlock/maintenance{
- req_one_access_txt = "12"
- },
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plasteel,
-/area/maintenance/port/aft)
"pOM" = (
/obj/structure/cable{
icon_state = "4-8"
@@ -36770,17 +36997,6 @@
},
/turf/open/floor/plasteel,
/area/security/brig)
-"pTc" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/obj/structure/disposalpipe/segment,
-/obj/structure/cable{
- icon_state = "2-8"
- },
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
- dir = 4
- },
-/turf/open/floor/plasteel/grimy,
-/area/chapel/office)
"pTe" = (
/obj/machinery/mineral/ore_redemption,
/obj/machinery/door/firedoor/border_only{
@@ -37160,6 +37376,20 @@
},
/turf/open/floor/plating,
/area/maintenance/central)
+"qbo" = (
+/obj/effect/spawner/structure/window/reinforced/shutter,
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/structure/cable{
+ icon_state = "0-8"
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "bridge blast";
+ name = "bridge blast door"
+ },
+/turf/open/floor/plating,
+/area/bridge)
"qbq" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -37256,27 +37486,6 @@
},
/turf/open/space/basic,
/area/solar/starboard/fore)
-"qdY" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
-/obj/machinery/door/airlock/maintenance{
- req_one_access_txt = "12"
- },
-/obj/machinery/door/firedoor/border_only{
- dir = 1
- },
-/obj/machinery/door/firedoor/border_only,
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/obj/effect/mapping_helpers/airlock/unres{
- icon_state = "airlock_unres_helper"
- },
-/obj/effect/turf_decal/trimline/yellow/arrow_cw{
- dir = 8
- },
-/turf/open/floor/plating,
-/area/maintenance/aft)
"qej" = (
/obj/structure/cable{
icon_state = "2-4"
@@ -38318,15 +38527,6 @@
},
/turf/open/floor/plasteel,
/area/engine/atmos)
-"qzN" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/plasteel/grimy,
-/area/chapel/office)
"qzY" = (
/obj/machinery/door/firedoor/border_only{
dir = 4
@@ -38919,18 +39119,6 @@
},
/turf/open/floor/wood,
/area/crew_quarters/heads/hop)
-"qQt" = (
-/obj/structure/disposalpipe/segment,
-/obj/effect/turf_decal/trimline/blue/filled/line/lower{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/turf/open/floor/plasteel/white,
-/area/medical/medbay/central)
"qQQ" = (
/obj/effect/landmark/blobstart,
/turf/open/floor/plating,
@@ -39229,6 +39417,15 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
+"qXd" = (
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel/showroomfloor,
+/area/crew_quarters/kitchen)
"qXg" = (
/obj/machinery/door/airlock/external{
name = "Solar Maintenance";
@@ -40597,12 +40794,6 @@
/obj/item/toy/talking/AI,
/turf/open/floor/plasteel/grimy,
/area/tcommsat/computer)
-"rDA" = (
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/turf/open/floor/plasteel/showroomfloor,
-/area/crew_quarters/kitchen)
"rDI" = (
/obj/machinery/door/window/southleft{
name = "Court Cell";
@@ -41343,6 +41534,16 @@
},
/turf/open/floor/plasteel/white,
/area/science/research)
+"rUJ" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
+ dir = 1
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "bridge blast";
+ name = "bridge blast door"
+ },
+/turf/open/floor/plasteel/dark,
+/area/bridge)
"rUM" = (
/obj/machinery/firealarm{
dir = 4;
@@ -42507,6 +42708,12 @@
"sxb" = (
/turf/open/floor/plasteel/dark/telecomms,
/area/ai_monitored/turret_protected/ai)
+"sxt" = (
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/carpet,
+/area/crew_quarters/theatre)
"sxx" = (
/obj/effect/turf_decal/trimline/darkblue/filled/line/lower{
dir = 1
@@ -43452,6 +43659,15 @@
},
/turf/open/floor/plasteel,
/area/engine/gravity_generator)
+"sOV" = (
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel,
+/area/maintenance/disposal/incinerator)
"sOX" = (
/obj/structure/cable{
icon_state = "2-8"
@@ -44205,6 +44421,12 @@
},
/turf/open/floor/plasteel/dark/telecomms,
/area/ai_monitored/turret_protected/ai)
+"tgX" = (
+/obj/machinery/light/small{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/maintenance/aft)
"tha" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 6
@@ -44339,13 +44561,6 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
/area/quartermaster/warehouse)
-"tki" = (
-/obj/effect/spawner/structure/window/reinforced/shutter,
-/obj/structure/cable{
- icon_state = "0-4"
- },
-/turf/open/floor/plating,
-/area/bridge)
"tkl" = (
/obj/structure/disposalpipe/segment,
/turf/open/floor/plasteel/showroomfloor,
@@ -45299,12 +45514,6 @@
initial_gas_mix = "n2o=1000;TEMP=293.15"
},
/area/engine/atmos)
-"tDM" = (
-/obj/machinery/camera{
- c_tag = "Fitness Room"
- },
-/turf/open/floor/plasteel,
-/area/crew_quarters/fitness)
"tDQ" = (
/obj/machinery/door/airlock/maintenance_hatch,
/obj/effect/mapping_helpers/airlock/abandoned,
@@ -45481,15 +45690,6 @@
},
/turf/open/floor/engine,
/area/maintenance/disposal/incinerator)
-"tHu" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
- dir = 4
- },
-/turf/open/floor/plasteel/grimy,
-/area/chapel/office)
"tHB" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
dir = 4
@@ -45712,6 +45912,19 @@
/obj/effect/turf_decal/trimline/green,
/turf/open/floor/plasteel/dark,
/area/engine/atmos)
+"tLr" = (
+/obj/machinery/camera{
+ c_tag = "Hallway - Central Southeast 2";
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/secred/filled/line/lower{
+ dir = 8
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -28
+ },
+/turf/open/floor/plasteel,
+/area/hallway/primary/central)
"tLB" = (
/obj/machinery/airalarm{
pixel_y = 24
@@ -47774,13 +47987,6 @@
},
/turf/open/floor/plasteel/white,
/area/medical/virology)
-"uHf" = (
-/obj/structure/table/wood,
-/obj/machinery/light{
- dir = 1
- },
-/turf/open/floor/carpet,
-/area/crew_quarters/cryopods)
"uHz" = (
/obj/structure/lattice,
/obj/structure/lattice,
@@ -48743,12 +48949,6 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
/turf/open/floor/plasteel/stairs/goon/wood_stairs_middle,
/area/library)
-"vci" = (
-/obj/structure/chair{
- dir = 1
- },
-/turf/open/floor/wood,
-/area/hallway/primary/central)
"vcr" = (
/obj/structure/cable{
icon_state = "1-2"
@@ -48916,10 +49116,14 @@
/area/clerk)
"veY" = (
/obj/structure/table/glass,
-/obj/machinery/computer/med_data/laptop,
/obj/effect/turf_decal/trimline/blue/filled/line/lower{
dir = 8
},
+/obj/item/reagent_containers/spray/cleaner,
+/obj/item/clothing/gloves/color/latex,
+/obj/item/reagent_containers/syringe,
+/obj/item/reagent_containers/glass/bottle/charcoal,
+/obj/item/reagent_containers/glass/bottle/epinephrine,
/turf/open/floor/plasteel/white,
/area/security/brig)
"vfa" = (
@@ -50249,16 +50453,6 @@
},
/turf/open/space/basic,
/area/engine/atmos)
-"vMQ" = (
-/obj/effect/spawner/structure/window/reinforced/shutter,
-/obj/structure/cable{
- icon_state = "1-8"
- },
-/obj/structure/cable{
- icon_state = "0-8"
- },
-/turf/open/floor/plating,
-/area/bridge)
"vNc" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
@@ -51491,12 +51685,6 @@
},
/turf/open/floor/plasteel,
/area/science/research)
-"wph" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
- dir = 1
- },
-/turf/open/floor/plasteel/dark,
-/area/bridge)
"wpm" = (
/obj/effect/turf_decal/trimline/engiyellow/filled/corner/lower,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
@@ -51804,18 +51992,6 @@
},
/turf/open/floor/wood,
/area/tcommsat/computer)
-"wvu" = (
-/obj/machinery/power/apc{
- areastring = "/area/chapel/office";
- dir = 8;
- name = "Chapel Office APC";
- pixel_x = -25
- },
-/obj/structure/cable{
- icon_state = "0-4"
- },
-/turf/open/floor/plasteel/grimy,
-/area/chapel/office)
"wvA" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -52107,6 +52283,11 @@
},
/turf/open/floor/plating,
/area/quartermaster/storage)
+"wzV" = (
+/obj/effect/turf_decal/sand/plating,
+/mob/living/simple_animal/hostile/asteroid/hivelord,
+/turf/open/floor/plating/airless,
+/area/space/nearstation)
"wAa" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -54024,12 +54205,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/wood,
/area/crew_quarters/kitchen)
-"xnB" = (
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/turf/open/floor/plasteel,
-/area/maintenance/disposal/incinerator)
"xnG" = (
/obj/machinery/door/airlock/maintenance{
req_one_access_txt = "12"
@@ -55340,6 +55515,17 @@
},
/turf/open/floor/plating,
/area/maintenance/port/fore)
+"xPn" = (
+/obj/effect/spawner/structure/window/reinforced/shutter,
+/obj/structure/cable{
+ icon_state = "0-4"
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "bridge blast";
+ name = "bridge blast door"
+ },
+/turf/open/floor/plating,
+/area/bridge)
"xPu" = (
/obj/structure/door_assembly/door_assembly_eng{
anchored = 1
@@ -70583,9 +70769,9 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -70839,10 +71025,10 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -71095,12 +71281,12 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -71352,12 +71538,12 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+aCv
+dJY
ylr
ylr
ylr
@@ -71609,12 +71795,12 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -71866,12 +72052,12 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -72123,12 +72309,12 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+aCv
+aCv
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -72380,12 +72566,12 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+aCv
+dJY
ylr
ylr
ylr
@@ -72637,11 +72823,11 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -72896,9 +73082,9 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -73154,7 +73340,7 @@ ylr
ylr
ylr
ylr
-ylr
+dJY
ylr
ylr
ylr
@@ -73675,7 +73861,7 @@ ylr
ylr
ylr
ylr
-ylr
+dJY
ylr
ylr
ylr
@@ -73931,9 +74117,9 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -74188,9 +74374,9 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -74446,8 +74632,8 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
+dJY
+dJY
ylr
ylr
ylr
@@ -77802,9 +77988,9 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -78058,10 +78244,10 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -78314,12 +78500,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -78571,12 +78757,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-aCv
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -78828,12 +79014,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -79085,12 +79271,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -79342,12 +79528,12 @@ ylr
ylr
ylr
ylr
-dJY
-aCv
-aCv
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -79599,12 +79785,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-aCv
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -79756,7 +79942,7 @@ uKU
nsl
och
tzz
-bPj
+gVx
bPj
iLK
rIY
@@ -79856,11 +80042,11 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -80115,9 +80301,9 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -80361,6 +80547,7 @@ ylr
ylr
ylr
ylr
+bIB
ylr
ylr
ylr
@@ -80373,7 +80560,6 @@ ylr
ylr
ylr
ylr
-dJY
ylr
ylr
ylr
@@ -81119,8 +81305,8 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
+dJY
+dJY
ylr
ylr
ylr
@@ -81375,10 +81561,10 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -81399,7 +81585,7 @@ ylr
ylr
ylr
ylr
-bIB
+ylr
ylr
ylr
ylr
@@ -81632,11 +81818,11 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -81888,6 +82074,13 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+aCv
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -81920,13 +82113,6 @@ ylr
ylr
ylr
ylr
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
ylr
ylr
"}
@@ -82145,6 +82331,13 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -82176,13 +82369,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
ylr
ylr
ylr
@@ -82402,6 +82588,12 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -82424,18 +82616,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-ylr
ylr
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -82661,6 +82847,12 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -82680,10 +82872,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -82691,8 +82879,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
ylr
ylr
ylr
@@ -82937,11 +83123,11 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -83193,13 +83379,13 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-aCv
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -83300,7 +83486,7 @@ osy
ryA
nrw
osy
-tDM
+bud
ofr
xpa
ubP
@@ -83450,13 +83636,13 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -83602,7 +83788,7 @@ kBq
fME
oOW
lSS
-qQt
+gQN
uCF
opl
cvE
@@ -83707,12 +83893,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -83966,9 +84152,9 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -84058,7 +84244,7 @@ fNq
fNq
vpc
oxB
-fNq
+kze
fNq
fNq
nHw
@@ -85430,7 +85616,7 @@ tIb
fOG
fOG
kTi
-pOJ
+fNj
kTi
kTi
xkg
@@ -85492,7 +85678,7 @@ ylr
ylr
ylr
ylr
-ylr
+bIB
ylr
ylr
ylr
@@ -85752,12 +85938,12 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -86006,23 +86192,23 @@ ylr
ylr
ylr
ylr
-ylr
-bIB
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
ylr
+bIB
ylr
ylr
ylr
@@ -86261,14 +86447,14 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
dJY
dJY
dJY
@@ -86445,7 +86631,7 @@ gxy
lML
fmF
fGO
-odp
+lNv
ixS
gxy
qmO
@@ -86516,13 +86702,11 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
dJY
dJY
dJY
@@ -86539,7 +86723,9 @@ ylr
ylr
ylr
ylr
-bIB
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -86679,7 +86865,7 @@ raj
aux
vVU
vVU
-raj
+fRz
ana
dGE
vxr
@@ -86709,7 +86895,7 @@ gxy
gxy
fOG
uPG
-uPG
+sxt
egN
eDe
jlD
@@ -86772,12 +86958,11 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
dJY
dJY
dJY
@@ -86812,27 +86997,28 @@ ylr
ylr
ylr
ylr
-"}
-(119,1,1) = {"
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+ylr
+"}
+(119,1,1) = {"
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -87029,13 +87215,11 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-dJY
-dJY
dJY
+aCv
+aCv
+aCv
+aCv
dJY
dJY
dJY
@@ -87069,6 +87253,8 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
"}
(120,1,1) = {"
ylr
@@ -87218,7 +87404,7 @@ qTz
ghI
pOm
pOm
-pqV
+gtn
gxy
gxy
fOG
@@ -87285,20 +87471,17 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-dJY
-dJY
dJY
dJY
dJY
+aCv
+aCv
dJY
dJY
dJY
dJY
dJY
+aCv
dJY
dJY
dJY
@@ -87326,6 +87509,9 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
"}
(121,1,1) = {"
ylr
@@ -87494,7 +87680,7 @@ rjP
iIJ
hCk
kKP
-kKP
+lDg
kKP
ufH
hGc
@@ -87542,14 +87728,11 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
+dJY
dJY
aCv
-aCv
-aCv
+dJY
+dJY
aCv
dJY
dJY
@@ -87583,6 +87766,9 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
"}
(122,1,1) = {"
ylr
@@ -87799,20 +87985,18 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
-aCv
-aCv
dJY
dJY
dJY
dJY
dJY
-aCv
+dJY
+dJY
+dJY
+dJY
dJY
dJY
dJY
@@ -87840,6 +88024,8 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
"}
(123,1,1) = {"
ylr
@@ -88055,26 +88241,24 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-dJY
-dJY
-aCv
-dJY
-dJY
-aCv
-dJY
dJY
dJY
dJY
dJY
dJY
dJY
+yhE
+yhE
+qGw
dJY
dJY
dJY
+qGw
+yhE
+qGw
+yhE
+yhE
+yhE
dJY
dJY
dJY
@@ -88097,6 +88281,8 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
"}
(124,1,1) = {"
ylr
@@ -88312,20 +88498,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
dJY
dJY
dJY
@@ -88333,6 +88505,17 @@ dJY
dJY
dJY
dJY
+fON
+fON
+fON
+fON
+fON
+fON
+fON
+fON
+fON
+uSS
+yhE
dJY
dJY
dJY
@@ -88354,6 +88537,9 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
"}
(125,1,1) = {"
ylr
@@ -88569,26 +88755,23 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-dJY
dJY
dJY
dJY
dJY
dJY
-yhE
-yhE
-qGw
-dJY
-dJY
dJY
qGw
-yhE
-qGw
-yhE
-yhE
+fON
+fON
+fON
+fON
+fON
+fON
+fON
+fON
+fON
+fON
yhE
dJY
dJY
@@ -88611,6 +88794,9 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
"}
(126,1,1) = {"
ylr
@@ -88699,7 +88885,7 @@ fZc
kLa
lLh
wJB
-uHf
+mhp
wUs
bpi
wUs
@@ -88826,9 +89012,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -88845,8 +89028,8 @@ fON
fON
fON
fON
-uSS
-yhE
+fON
+dJY
dJY
dJY
dJY
@@ -88854,10 +89037,13 @@ dJY
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -89027,10 +89213,10 @@ uLk
uLk
ykw
lpn
-rSz
-rSz
-rSz
-rSz
+akr
+akr
+akr
+akr
iVj
akr
myW
@@ -89083,14 +89269,11 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-dJY
dJY
dJY
dJY
dJY
+aCv
dJY
qGw
fON
@@ -89103,7 +89286,7 @@ fON
fON
fON
fON
-yhE
+dJY
dJY
dJY
dJY
@@ -89111,9 +89294,12 @@ dJY
ylr
ylr
ylr
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -89275,7 +89461,7 @@ uLk
dZz
kVY
qoy
-dZz
+guW
uLk
kVY
uLk
@@ -89340,9 +89526,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -89360,74 +89543,77 @@ fON
fON
fON
fON
+qGw
dJY
dJY
dJY
dJY
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-"}
-(129,1,1) = {"
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(129,1,1) = {"
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -89541,7 +89727,7 @@ mew
mew
cjV
mUP
-rDA
+qXd
mPL
jWl
pwz
@@ -89597,16 +89783,13 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
dJY
-aCv
dJY
-qGw
+dJY
+dJY
fON
fON
fON
@@ -89617,11 +89800,14 @@ fON
fON
fON
fON
+qGw
dJY
dJY
dJY
-dJY
-dJY
+qxi
+qxi
+ylr
+ylr
ylr
ylr
ylr
@@ -89854,9 +90040,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -89874,11 +90057,14 @@ fON
fON
fON
fON
-qGw
-dJY
dJY
dJY
dJY
+qxi
+qxi
+qxi
+ylr
+ylr
ylr
ylr
ylr
@@ -90111,9 +90297,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -90131,12 +90314,15 @@ fON
fON
fON
fON
-qGw
-dJY
+yhE
dJY
dJY
qxi
qxi
+dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -90369,9 +90555,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-dJY
dJY
dJY
dJY
@@ -90388,21 +90571,24 @@ fON
fON
fON
fON
-dJY
-dJY
+yhE
dJY
qxi
qxi
qxi
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
ylr
ylr
-bIB
ylr
-dJY
-dJY
ylr
ylr
ylr
@@ -90626,15 +90812,12 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-dJY
-dJY
dJY
dJY
dJY
dJY
dJY
+qGw
fON
fON
fON
@@ -90645,21 +90828,24 @@ fON
fON
fON
fON
-yhE
dJY
dJY
qxi
qxi
dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -90883,30 +91069,28 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
dJY
dJY
+qGw
+yhE
+dJY
+qGw
+dJY
dJY
-fON
-fON
-fON
-fON
-fON
-fON
-fON
-fON
-fON
-fON
+yhE
yhE
dJY
+dJY
+qGw
+dJY
qxi
qxi
-qxi
+dJY
+dJY
+dJY
dJY
ylr
ylr
@@ -90914,10 +91098,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-aCv
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -91071,7 +91257,7 @@ rIh
gFE
dfT
nWv
-lWE
+jEs
rSz
uix
uix
@@ -91096,96 +91282,96 @@ eMS
vDp
bHj
xSu
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-qGw
-fON
-fON
-fON
-fON
-fON
-fON
-fON
-fON
-fON
-fON
-dJY
-dJY
-qxi
-qxi
-dJY
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-dJY
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-"}
-(136,1,1) = {"
-ylr
-ylr
-ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(136,1,1) = {"
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -91397,26 +91583,23 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
dJY
dJY
-qGw
-yhE
dJY
-qGw
dJY
dJY
-yhE
-yhE
dJY
dJY
-qGw
dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+qxi
qxi
qxi
dJY
@@ -91430,7 +91613,10 @@ ylr
ylr
ylr
ylr
-dJY
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -91655,12 +91841,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-dJY
-dJY
-dJY
-dJY
dJY
dJY
dJY
@@ -91676,10 +91856,16 @@ dJY
dJY
qxi
qxi
+qxi
+qxi
+qxi
dJY
dJY
dJY
-dJY
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -91866,7 +92052,7 @@ gOO
gOO
gOO
bsD
-qdY
+bbd
flF
flF
flF
@@ -91912,27 +92098,23 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
dJY
dJY
dJY
+qxi
+qxi
+qxi
dJY
dJY
dJY
qxi
qxi
qxi
+qxi
+qxi
+qxi
+qxi
+qxi
dJY
dJY
dJY
@@ -91952,6 +92134,10 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
"}
(139,1,1) = {"
ylr
@@ -92131,7 +92317,7 @@ sTU
nvS
eaS
pRT
-uJr
+gTN
uix
oLK
oLK
@@ -92170,21 +92356,16 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
qxi
qxi
qxi
@@ -92193,6 +92374,11 @@ qxi
dJY
dJY
dJY
+dJY
+dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -92376,13 +92562,13 @@ qmO
nGh
gIJ
gIJ
-gIJ
+geT
gIJ
gIJ
xkg
xbB
uJr
-uJr
+tgX
uJr
uix
uix
@@ -92398,7 +92584,7 @@ uJr
uJr
iKZ
uJr
-crg
+nQN
crg
crg
nzq
@@ -92427,17 +92613,9 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-dJY
-dJY
-dJY
qxi
qxi
qxi
-dJY
-dJY
-dJY
qxi
qxi
qxi
@@ -92446,10 +92624,18 @@ qxi
qxi
qxi
qxi
+qxi
+dJY
+dJY
+dJY
dJY
dJY
dJY
dJY
+dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -92600,7 +92786,7 @@ xMH
agh
gcp
nrs
-hWN
+jBZ
crL
vka
wHi
@@ -92685,21 +92871,15 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
+dJY
+dJY
+dJY
+dJY
qxi
qxi
qxi
+dJY
+dJY
qxi
qxi
dJY
@@ -92707,6 +92887,12 @@ dJY
dJY
dJY
dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -92942,44 +93128,44 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+qxi
+qxi
+dJY
+dJY
+aCv
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
"}
(143,1,1) = {"
ylr
@@ -93199,27 +93385,27 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
dJY
-qxi
-qxi
-qxi
+dJY
+dJY
+dJY
dJY
dJY
qxi
qxi
+qxi
dJY
dJY
dJY
dJY
dJY
dJY
-dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -93408,7 +93594,7 @@ ftc
bJa
aLA
eUa
-mKD
+cuV
mTW
mBf
lec
@@ -93457,8 +93643,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -93472,7 +93656,6 @@ qxi
qxi
dJY
dJY
-aCv
dJY
dJY
dJY
@@ -93494,6 +93677,9 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
"}
(145,1,1) = {"
ylr
@@ -93724,11 +93910,8 @@ dJY
dJY
dJY
dJY
-dJY
qxi
qxi
-qxi
-dJY
dJY
dJY
dJY
@@ -93751,6 +93934,9 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
"}
(146,1,1) = {"
ylr
@@ -93978,9 +94164,7 @@ dJY
dJY
dJY
dJY
-dJY
-dJY
-dJY
+aCv
dJY
dJY
qxi
@@ -93990,7 +94174,9 @@ dJY
dJY
dJY
dJY
-dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -94238,16 +94424,16 @@ dJY
dJY
dJY
dJY
-dJY
-dJY
-dJY
+qxi
qxi
qxi
dJY
dJY
dJY
dJY
-dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -94436,7 +94622,7 @@ kmf
iKL
kdf
bHL
-nSs
+gzX
eMJ
pZe
kZM
@@ -94480,8 +94666,8 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
+dJY
+dJY
ylr
ylr
ylr
@@ -94495,16 +94681,16 @@ dJY
dJY
dJY
dJY
-aCv
-dJY
dJY
qxi
qxi
-dJY
-dJY
-dJY
-dJY
-dJY
+qxi
+qxi
+qxi
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -94735,12 +94921,10 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -94758,10 +94942,12 @@ dJY
qxi
qxi
qxi
-dJY
-dJY
-dJY
-dJY
+qxi
+qxi
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -94990,6 +95176,12 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -95000,15 +95192,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-dJY
dJY
dJY
dJY
@@ -95016,8 +95199,11 @@ dJY
qxi
qxi
qxi
-qxi
-qxi
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -95246,6 +95432,16 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
ylr
ylr
ylr
@@ -95265,16 +95461,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-qxi
-qxi
ylr
ylr
ylr
@@ -95381,7 +95567,7 @@ pww
dvH
jEm
sgT
-vci
+jHI
bgM
pVC
iIL
@@ -95503,6 +95689,14 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+aCv
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -95523,14 +95717,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-ylr
ylr
ylr
ylr
@@ -95760,13 +95946,13 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+aCv
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -96017,13 +96203,13 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -96273,6 +96459,14 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+aCv
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -96292,17 +96486,9 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -96530,6 +96716,23 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -96538,6 +96741,14 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
ylr
ylr
ylr
@@ -96547,39 +96758,14 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-"}
-(157,1,1) = {"
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(157,1,1) = {"
ylr
ylr
ylr
@@ -96787,13 +96973,13 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -96804,20 +96990,20 @@ ylr
bIB
ylr
ylr
+dJY
+dJY
ylr
ylr
ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+aCv
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -97045,6 +97231,11 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -97055,25 +97246,20 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -97302,6 +97488,10 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -97313,23 +97503,19 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
ylr
+bIB
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+aCv
+dJY
+dJY
ylr
ylr
ylr
@@ -97559,6 +97745,10 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -97577,6 +97767,12 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -97591,16 +97787,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
ylr
ylr
ylr
@@ -97817,6 +98003,8 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
ylr
ylr
ylr
@@ -97836,6 +98024,11 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -97847,13 +98040,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
ylr
ylr
ylr
@@ -98097,6 +98283,10 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+ylr
+ylr
ylr
ylr
ylr
@@ -98104,11 +98294,7 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
-bIB
ylr
ylr
ylr
@@ -98457,7 +98643,7 @@ jBL
ghL
vYa
tJZ
-wvu
+ghL
jBL
vXY
wSN
@@ -98581,7 +98767,7 @@ ylr
ylr
ylr
ylr
-ylr
+dJY
ylr
ylr
ylr
@@ -98714,7 +98900,7 @@ jBL
bhD
wXE
iSI
-pLB
+ghL
jBL
nDI
jMb
@@ -98837,9 +99023,9 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -98971,7 +99157,7 @@ jBL
aKj
pSS
wYC
-qzN
+lYe
jBL
faF
csp
@@ -99056,7 +99242,7 @@ jHy
jHy
tzk
sOX
-xnB
+sOV
hNN
aPm
nQq
@@ -99094,9 +99280,9 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -99226,9 +99412,9 @@ kqW
jFa
jBL
npK
-ezL
-jZE
-pTc
+kJb
+dZo
+hJN
uBj
fXR
yfT
@@ -99350,10 +99536,10 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+aCv
+dJY
+dJY
ylr
ylr
ylr
@@ -99483,7 +99669,7 @@ kqW
uGk
jBL
iaH
-tHu
+cMu
ghL
ghL
nTb
@@ -99607,10 +99793,10 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -99740,7 +99926,7 @@ kqW
jFa
jBL
aLL
-tHu
+cMu
bDL
ghL
kXM
@@ -99795,7 +99981,7 @@ cPC
cPC
cPC
dqy
-ifd
+tLr
uNK
uNK
uNK
@@ -99864,10 +100050,10 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -99997,7 +100183,7 @@ kde
jFa
jBL
jBL
-nrb
+fvT
jBL
jBL
jBL
@@ -100121,10 +100307,10 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -100158,9 +100344,9 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -100254,8 +100440,8 @@ eGX
brs
jBL
uzl
-fqT
-pjA
+iWP
+aFg
wED
jBL
iSF
@@ -100379,8 +100565,8 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
+dJY
+dJY
ylr
ylr
ylr
@@ -100413,12 +100599,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -100551,7 +100737,7 @@ cPC
tWc
asN
xdk
-cPC
+ofp
xWw
rAT
fjk
@@ -100670,32 +100856,32 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-aCv
-dJY
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-"}
-(173,1,1) = {"
-ylr
-ylr
-ylr
-ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(173,1,1) = {"
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -100926,12 +101112,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -101182,12 +101368,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-aCv
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -101439,12 +101625,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -101579,9 +101765,9 @@ fen
fen
iuE
ouG
-fjm
-wph
-olk
+oJI
+rUJ
+jRs
mfu
ntn
uVJ
@@ -101696,11 +101882,11 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -101955,8 +102141,8 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
+ylr
+ylr
ylr
ylr
ylr
@@ -102908,7 +103094,7 @@ uJr
uJr
nQq
jHy
-jHy
+pKp
fgV
iXv
dGB
@@ -103112,8 +103298,8 @@ szo
nhk
iOI
iOI
-dRo
-bOf
+ktH
+fZm
oGa
ouG
ouG
@@ -103889,7 +104075,7 @@ rca
sMI
ttj
ksm
-nLN
+dis
ttj
ttj
dcQ
@@ -104262,15 +104448,15 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -104518,11 +104704,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -104545,6 +104726,11 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(188,1,1) = {"
ylr
@@ -104774,11 +104960,6 @@ dJY
dJY
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -104794,8 +104975,13 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -105049,10 +105235,10 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -105304,12 +105490,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -105425,7 +105611,7 @@ okP
mUq
ylr
mfu
-tki
+xPn
pSc
nQE
roz
@@ -105435,7 +105621,7 @@ pYL
wtE
eyw
xlj
-cRh
+qbo
jEc
jEc
jEc
@@ -105560,14 +105746,14 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -105682,17 +105868,17 @@ qGg
xSu
xSu
xSu
-gsw
-fGw
-fGw
-fGw
-fGw
-fGw
-fGw
-fGw
-fGw
-fGw
-vMQ
+pIm
+oVz
+oVz
+oVz
+oVz
+oVz
+oVz
+oVz
+oVz
+oVz
+nOt
ylr
kkk
dYk
@@ -105725,7 +105911,7 @@ xGT
pzZ
alW
cJk
-ciH
+nlF
cJk
bHj
bHj
@@ -105811,20 +105997,20 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-aCv
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -106050,13 +106236,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
xSu
xSu
@@ -106074,13 +106253,20 @@ ylr
ylr
ylr
ylr
-dJY
-aCv
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -106307,13 +106493,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
kbQ
kbQ
kbQ
@@ -106331,13 +106510,20 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -106560,13 +106746,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
xSu
xSu
@@ -106587,14 +106766,21 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-aCv
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -106816,13 +107002,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
xSu
xSu
@@ -106844,13 +107023,20 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -107067,13 +107253,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
ylr
ylr
@@ -107101,13 +107280,20 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -107322,13 +107508,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
xSu
xSu
@@ -107359,11 +107538,18 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -107567,11 +107753,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
bIB
ylr
ylr
@@ -107583,8 +107764,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
xSu
xSu
@@ -107616,10 +107795,17 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -107836,13 +108022,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
ylr
xSu
@@ -107873,10 +108052,17 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -108096,13 +108282,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
kbQ
hBq
drp
@@ -108131,8 +108310,15 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -108351,13 +108537,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
izO
kbQ
@@ -108400,6 +108579,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(203,1,1) = {"
ylr
@@ -108608,13 +108794,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
izO
cTN
@@ -108657,6 +108836,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(204,1,1) = {"
ylr
@@ -108860,13 +109046,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
xSu
kbQ
@@ -108914,6 +109093,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(205,1,1) = {"
ylr
@@ -109116,13 +109302,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xlk
hwZ
hwZ
@@ -109171,6 +109350,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(206,1,1) = {"
ylr
@@ -109372,13 +109558,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
xSu
lNJ
dOl
@@ -109428,6 +109607,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(207,1,1) = {"
ylr
@@ -109629,13 +109815,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
kbQ
hBI
uOr
@@ -109685,6 +109864,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(208,1,1) = {"
ylr
@@ -109886,13 +110072,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
kbQ
lNJ
hwZ
@@ -109942,6 +110121,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(209,1,1) = {"
ylr
@@ -110138,18 +110324,11 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
ylr
ylr
-ylr
-ylr
kbQ
dkl
hwZ
@@ -110199,22 +110378,29 @@ ylr
ylr
ylr
ylr
-"}
-(210,1,1) = {"
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(210,1,1) = {"
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -110393,11 +110579,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -110405,8 +110586,6 @@ dJY
dJY
ylr
ylr
-ylr
-ylr
kbQ
kbQ
xSu
@@ -110456,6 +110635,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(211,1,1) = {"
ylr
@@ -110650,11 +110836,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -110668,8 +110849,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
xSu
izO
@@ -110713,6 +110892,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(212,1,1) = {"
ylr
@@ -110906,11 +111092,6 @@ tSr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -110926,8 +111107,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
izO
kbQ
@@ -110970,6 +111149,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(213,1,1) = {"
ylr
@@ -111163,11 +111349,6 @@ xSu
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -111185,8 +111366,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
kbQ
hBq
hBq
@@ -111227,6 +111406,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(214,1,1) = {"
ylr
@@ -111420,11 +111606,6 @@ xSu
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -111439,8 +111620,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
ylr
xSu
@@ -111484,6 +111663,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(215,1,1) = {"
ylr
@@ -111677,11 +111863,6 @@ oof
pkP
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -111696,8 +111877,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
xSu
xSu
@@ -111741,6 +111920,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(216,1,1) = {"
ylr
@@ -111935,11 +112121,6 @@ fsv
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -111954,8 +112135,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
xSu
xSu
@@ -111998,6 +112177,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(217,1,1) = {"
ylr
@@ -112192,11 +112378,6 @@ sDp
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
aCv
@@ -112211,8 +112392,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
xSu
xSu
@@ -112255,6 +112434,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(218,1,1) = {"
ylr
@@ -112450,11 +112636,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -112469,8 +112650,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
ylr
ylr
@@ -112512,6 +112691,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(219,1,1) = {"
ylr
@@ -112707,11 +112893,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -112734,8 +112915,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
xSu
kbQ
@@ -112769,6 +112948,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(220,1,1) = {"
ylr
@@ -112965,11 +113151,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
dJY
dJY
dJY
@@ -112992,8 +113173,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
xSu
izO
kbQ
@@ -113026,6 +113205,13 @@ ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
"}
(221,1,1) = {"
ylr
@@ -114018,14 +114204,14 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -114274,6 +114460,17 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+yhE
+yhE
+yhE
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -114298,17 +114495,6 @@ ylr
ylr
ylr
ylr
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
ylr
ylr
"}
@@ -114527,49 +114713,49 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-dJY
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-"}
-(227,1,1) = {"
+ylr
+ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+fON
+fON
+gcv
+qGw
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(227,1,1) = {"
ylr
ylr
ylr
@@ -114769,7 +114955,7 @@ ylr
ylr
ylr
ylr
-ylr
+dJY
ylr
ylr
ylr
@@ -114785,6 +114971,22 @@ ylr
bIB
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+yhE
+fON
+fON
+fON
+qGw
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -114809,22 +115011,6 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-dJY
-dJY
-dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
"}
(228,1,1) = {"
ylr
@@ -115025,6 +115211,8 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
ylr
ylr
ylr
@@ -115040,112 +115228,22 @@ ylr
ylr
ylr
ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
+dJY
+dJY
+dJY
dJY
aCv
dJY
+qGw
+fON
+fON
+fON
+dJY
+dJY
+aCv
+dJY
+dJY
dJY
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-"}
-(229,1,1) = {"
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
-ylr
ylr
ylr
ylr
@@ -115170,29 +115268,12 @@ ylr
ylr
ylr
ylr
+"}
+(229,1,1) = {"
ylr
ylr
-pdy
ylr
-xSu
-bHj
-keV
-lOT
-lOT
-rOl
-qIR
-gYI
-ouF
-yjJ
-wnr
-hHP
-lOT
-lOT
-lOT
-bHj
-xSu
ylr
-xNJ
ylr
ylr
ylr
@@ -115228,50 +115309,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-lAY
-vfU
-vfU
-vfU
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -115321,9 +115358,102 @@ ylr
ylr
ylr
ylr
+pdy
+ylr
+xSu
+bHj
+keV
+lOT
+lOT
+rOl
+qIR
+gYI
+ouF
+yjJ
+wnr
+hHP
+lOT
+lOT
+lOT
+bHj
+xSu
+ylr
+xNJ
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+lAY
+vfU
+vfU
+vfU
+dJY
+dJY
+dJY
+dJY
dJY
dJY
dJY
@@ -115338,6 +115468,62 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+qGw
+qGw
+dJY
+yhE
+yhE
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
"}
(230,1,1) = {"
@@ -115516,13 +115702,526 @@ dJY
dJY
dJY
aCv
-qxi
+alz
qxi
vfU
gra
-vfU
+wzV
+qxi
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+dJY
+dJY
+qGw
+qGw
+yhE
+qGw
+qGw
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(231,1,1) = {"
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+pdy
+ylr
+xSu
+xSu
+bHj
+nSD
+lOT
+lOT
+lOT
+nEF
+gOc
+iGk
+lOT
+lOT
+keV
+srH
+bHj
+xSu
+ylr
+ylr
+xNJ
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+bIB
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+qxi
+qxi
+qxi
+dJY
+dJY
+dJY
+qxi
+okd
+qxi
+lMb
+qxi
+qxi
+aCv
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+dJY
+dJY
+qGw
+fON
+fON
+gcv
+qGw
+dJY
+aCv
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+bIB
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(232,1,1) = {"
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+xSu
+bHj
+bHj
+lOT
+lOT
+lOT
+lOT
+lOT
+lOT
+lOT
+bHj
+bHj
+xSu
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+qxi
+qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+qxi
+qxi
qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+dJY
dJY
+qxi
+qxi
dJY
dJY
dJY
@@ -115540,6 +116239,105 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+dJY
+dJY
+qGw
+fON
+fON
+fON
+yhE
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+"}
+(233,1,1) = {"
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -115581,10 +116379,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -115594,10 +116388,25 @@ ylr
ylr
ylr
ylr
+xNJ
+xNJ
+xNJ
+xSu
+bHj
+bHj
+lOT
+lOT
+lOT
+lOT
+lOT
+bHj
+bHj
+xSu
+xNJ
+xNJ
+xNJ
ylr
ylr
-"}
-(231,1,1) = {"
ylr
ylr
ylr
@@ -115650,6 +116459,29 @@ ylr
ylr
ylr
ylr
+qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+dJY
+qxi
+qxi
+qxi
+qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -115665,6 +116497,7 @@ ylr
ylr
ylr
ylr
+dJY
ylr
ylr
ylr
@@ -115681,32 +116514,24 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+fON
+fON
+fON
+yhE
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
ylr
ylr
-pdy
ylr
-xSu
-xSu
-bHj
-nSD
-lOT
-lOT
-lOT
-nEF
-gOc
-iGk
-lOT
-lOT
-keV
-srH
-bHj
-xSu
ylr
ylr
-xNJ
ylr
ylr
ylr
@@ -115728,6 +116553,8 @@ ylr
ylr
ylr
ylr
+"}
+(234,1,1) = {"
ylr
ylr
ylr
@@ -115738,7 +116565,6 @@ ylr
ylr
ylr
ylr
-bIB
ylr
ylr
ylr
@@ -115754,37 +116580,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-okd
-qxi
-lMb
-qxi
-qxi
-aCv
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -115830,7 +116625,6 @@ ylr
ylr
ylr
ylr
-bIB
ylr
ylr
ylr
@@ -115838,10 +116632,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -115853,14 +116643,22 @@ ylr
ylr
ylr
ylr
-"}
-(232,1,1) = {"
ylr
ylr
ylr
ylr
ylr
ylr
+xSu
+bHj
+bHj
+lOT
+lOT
+lOT
+bHj
+bHj
+xSu
+xSu
ylr
ylr
ylr
@@ -115889,6 +116687,7 @@ ylr
ylr
ylr
ylr
+bIB
ylr
ylr
ylr
@@ -115918,8 +116717,27 @@ ylr
ylr
ylr
ylr
+qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+qxi
+qxi
ylr
ylr
+qxi
+qxi
+qxi
+qxi
+qxi
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -115941,29 +116759,27 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
ylr
ylr
ylr
ylr
ylr
ylr
-xSu
-bHj
-bHj
-lOT
-lOT
-lOT
-lOT
-lOT
-lOT
-lOT
-bHj
-bHj
-xSu
ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -115994,6 +116810,8 @@ ylr
ylr
ylr
ylr
+"}
+(235,1,1) = {"
ylr
ylr
ylr
@@ -116014,33 +116832,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-wOE
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -116096,8 +116887,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
ylr
ylr
ylr
@@ -116110,13 +116899,24 @@ ylr
ylr
ylr
ylr
-"}
-(233,1,1) = {"
ylr
ylr
ylr
ylr
ylr
+cif
+xSu
+xSu
+xSu
+bHj
+bHj
+gVc
+bHj
+bHj
+xSu
+xSu
+xSu
+cif
ylr
ylr
ylr
@@ -116175,6 +116975,14 @@ ylr
ylr
ylr
ylr
+qxi
+qxi
+qxi
+qxi
+qxi
+qxi
+ylr
+ylr
ylr
ylr
ylr
@@ -116202,34 +117010,33 @@ ylr
ylr
ylr
ylr
-xNJ
-xNJ
-xNJ
-xSu
-bHj
-bHj
-lOT
-lOT
-lOT
-lOT
-lOT
-bHj
-bHj
-xSu
-xNJ
-xNJ
-xNJ
ylr
ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+dJY
+ylr
ylr
ylr
ylr
@@ -116260,6 +117067,8 @@ ylr
ylr
ylr
ylr
+"}
+(236,1,1) = {"
ylr
ylr
ylr
@@ -116271,33 +117080,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-kkT
-qxi
-qxi
-qxi
-qxi
-okd
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -116367,8 +117149,6 @@ ylr
ylr
ylr
ylr
-"}
-(234,1,1) = {"
ylr
ylr
ylr
@@ -116383,11 +117163,22 @@ ylr
ylr
ylr
ylr
+xSu
+xSu
+xSu
+xSu
+xSu
+xSu
+xSu
+xSu
+cif
+cif
ylr
ylr
ylr
ylr
ylr
+bIB
ylr
ylr
ylr
@@ -116463,16 +117254,6 @@ ylr
ylr
ylr
ylr
-xSu
-bHj
-bHj
-lOT
-lOT
-lOT
-bHj
-bHj
-xSu
-xSu
ylr
ylr
ylr
@@ -116491,6 +117272,9 @@ ylr
ylr
ylr
ylr
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -116501,9 +117285,13 @@ ylr
ylr
ylr
ylr
-bIB
ylr
ylr
+dJY
+dJY
+dJY
+dJY
+dJY
ylr
ylr
ylr
@@ -116529,31 +117317,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-qxi
-kVo
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -116561,6 +117324,8 @@ ylr
ylr
ylr
ylr
+"}
+(237,1,1) = {"
ylr
ylr
ylr
@@ -116573,8 +117338,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
ylr
ylr
ylr
@@ -116624,8 +117387,6 @@ ylr
ylr
ylr
ylr
-"}
-(235,1,1) = {"
ylr
ylr
ylr
@@ -116658,6 +117419,15 @@ ylr
ylr
ylr
ylr
+cif
+xSu
+cif
+xSu
+cif
+cif
+cif
+xSu
+cif
ylr
ylr
ylr
@@ -116718,19 +117488,6 @@ ylr
ylr
ylr
ylr
-cif
-xSu
-xSu
-xSu
-bHj
-bHj
-gVc
-bHj
-bHj
-xSu
-xSu
-xSu
-cif
ylr
ylr
ylr
@@ -116768,10 +117525,12 @@ ylr
ylr
ylr
ylr
+bIB
ylr
ylr
ylr
ylr
+dJY
ylr
ylr
ylr
@@ -116787,27 +117546,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-okd
-lSG
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
dJY
dJY
dJY
@@ -116829,10 +117567,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -116847,15 +117581,9 @@ ylr
ylr
ylr
ylr
+"}
+(238,1,1) = {"
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -116881,8 +117609,6 @@ ylr
ylr
ylr
ylr
-"}
-(236,1,1) = {"
ylr
ylr
ylr
@@ -116951,10 +117677,13 @@ ylr
ylr
ylr
ylr
+cif
ylr
+cif
ylr
ylr
ylr
+cif
ylr
ylr
ylr
@@ -116977,22 +117706,11 @@ ylr
ylr
ylr
ylr
-xSu
-xSu
-xSu
-xSu
-xSu
-xSu
-xSu
-xSu
-cif
-cif
ylr
ylr
ylr
ylr
ylr
-bIB
ylr
ylr
ylr
@@ -117044,30 +117762,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-kVo
-kSi
-qxi
-aCv
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -117086,9 +117780,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -117104,17 +117795,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-yhE
-yhE
-yhE
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -117138,8 +117818,6 @@ ylr
ylr
ylr
ylr
-"}
-(237,1,1) = {"
ylr
ylr
ylr
@@ -117160,6 +117838,8 @@ ylr
ylr
ylr
ylr
+"}
+(239,1,1) = {"
ylr
ylr
ylr
@@ -117233,15 +117913,6 @@ ylr
ylr
ylr
ylr
-cif
-xSu
-cif
-xSu
-cif
-cif
-cif
-xSu
-cif
ylr
ylr
ylr
@@ -117301,33 +117972,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-aCv
-kVo
-alz
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-ylr
-ylr
ylr
ylr
ylr
@@ -117339,12 +117983,9 @@ ylr
ylr
ylr
ylr
-bIB
-ylr
ylr
ylr
ylr
-dJY
ylr
ylr
ylr
@@ -117359,20 +118000,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-fON
-fON
-gcv
-qGw
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -117395,8 +118022,6 @@ ylr
ylr
ylr
ylr
-"}
-(238,1,1) = {"
ylr
ylr
ylr
@@ -117470,6 +118095,8 @@ ylr
ylr
ylr
ylr
+"}
+(240,1,1) = {"
ylr
ylr
ylr
@@ -117491,13 +118118,10 @@ ylr
ylr
ylr
ylr
-cif
ylr
-cif
ylr
ylr
ylr
-cif
ylr
ylr
ylr
@@ -117557,32 +118181,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-okd
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -117615,22 +118213,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-yhE
-fON
-fON
-fON
-qGw
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -117652,8 +118234,6 @@ ylr
ylr
ylr
ylr
-"}
-(239,1,1) = {"
ylr
ylr
ylr
@@ -117772,6 +118352,8 @@ ylr
ylr
ylr
ylr
+"}
+(241,1,1) = {"
ylr
ylr
ylr
@@ -117800,10 +118382,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-qxi
-qxi
ylr
ylr
ylr
@@ -117812,34 +118390,6 @@ ylr
ylr
ylr
ylr
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-oRp
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -117866,28 +118416,11 @@ ylr
ylr
ylr
ylr
-dJY
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-aCv
-dJY
-qGw
-fON
-fON
-fON
-dJY
-dJY
-aCv
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -117909,8 +118442,6 @@ ylr
ylr
ylr
ylr
-"}
-(240,1,1) = {"
ylr
ylr
ylr
@@ -118056,47 +118587,11 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-qxi
-qxi
ylr
ylr
ylr
ylr
ylr
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-aCv
-qxi
-qxi
-kVo
-aCv
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-okd
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -118114,6 +118609,8 @@ ylr
ylr
ylr
ylr
+"}
+(242,1,1) = {"
ylr
ylr
ylr
@@ -118122,29 +118619,11 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qGw
-qGw
-dJY
-yhE
-yhE
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -118166,8 +118645,6 @@ ylr
ylr
ylr
ylr
-"}
-(241,1,1) = {"
ylr
ylr
ylr
@@ -118312,48 +118789,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -118379,28 +118814,10 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
ylr
ylr
ylr
-dJY
-dJY
-qGw
-qGw
-yhE
-qGw
-qGw
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -118423,8 +118840,6 @@ ylr
ylr
ylr
ylr
-"}
-(242,1,1) = {"
ylr
ylr
ylr
@@ -118451,6 +118866,8 @@ ylr
ylr
ylr
ylr
+"}
+(243,1,1) = {"
ylr
ylr
ylr
@@ -118572,46 +118989,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -118636,27 +119013,10 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
ylr
ylr
ylr
-dJY
-dJY
-qGw
-fON
-fON
-gcv
-qGw
-dJY
-aCv
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -118680,8 +119040,6 @@ ylr
ylr
ylr
ylr
-"}
-(243,1,1) = {"
ylr
ylr
ylr
@@ -118765,6 +119123,8 @@ ylr
ylr
ylr
ylr
+"}
+(244,1,1) = {"
ylr
ylr
ylr
@@ -118830,45 +119190,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -118893,25 +119214,10 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
ylr
ylr
ylr
-dJY
-dJY
-qGw
-fON
-fON
-fON
-yhE
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -118937,8 +119243,6 @@ ylr
ylr
ylr
ylr
-"}
-(244,1,1) = {"
ylr
ylr
ylr
@@ -119076,6 +119380,8 @@ ylr
ylr
ylr
ylr
+"}
+(245,1,1) = {"
ylr
ylr
ylr
@@ -119089,41 +119395,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-okd
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-okd
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -119150,24 +119421,11 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-fON
-fON
-fON
-yhE
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -119194,8 +119452,6 @@ ylr
ylr
ylr
ylr
-"}
-(245,1,1) = {"
ylr
ylr
ylr
@@ -119349,37 +119605,9 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -119408,32 +119636,20 @@ ylr
ylr
ylr
ylr
-dJY
ylr
+"}
+(246,1,1) = {"
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -119451,8 +119667,6 @@ ylr
ylr
ylr
ylr
-"}
-(246,1,1) = {"
ylr
ylr
ylr
@@ -119613,22 +119827,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-qxi
-qxi
-okd
-qxi
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -119673,24 +119871,12 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -119873,19 +120059,7 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-qxi
-qxi
-qxi
-qxi
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -119931,11 +120105,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -119943,10 +120112,27 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
@@ -120130,12 +120316,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -120190,9 +120370,6 @@ ylr
ylr
ylr
ylr
-dJY
-dJY
-dJY
ylr
ylr
ylr
@@ -120200,7 +120377,16 @@ ylr
ylr
ylr
ylr
-dJY
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
+ylr
ylr
ylr
ylr
diff --git a/_maps/map_files/GaxStation/GaxStation.dmm b/_maps/map_files/GaxStation/GaxStation.dmm
index 0b8073605426..8e4c7ef0450f 100644
--- a/_maps/map_files/GaxStation/GaxStation.dmm
+++ b/_maps/map_files/GaxStation/GaxStation.dmm
@@ -12616,7 +12616,7 @@
/obj/effect/turf_decal/trimline/secred/filled/corner/lower{
dir = 1
},
-/obj/structure/table,
+/obj/machinery/vending/snack/random,
/turf/open/floor/plasteel,
/area/hallway/primary/port)
"fZI" = (
@@ -16680,8 +16680,8 @@
/obj/effect/turf_decal/trimline/engiyellow/filled/line/lower{
dir = 10
},
-/obj/structure/chair{
- dir = 1
+/obj/machinery/computer/warrant{
+ dir = 4
},
/turf/open/floor/plasteel,
/area/hallway/primary/port)
@@ -19832,7 +19832,7 @@
},
/obj/machinery/atmospherics/components/trinary/filter/flipped/critical{
dir = 1;
- filter_type = list(/datum/gas/nitrogen)
+ filter_type = list("n2")
},
/turf/open/floor/engine,
/area/engine/engineering)
@@ -45959,6 +45959,8 @@
/obj/machinery/light_switch{
pixel_x = 24
},
+/obj/machinery/paystand,
+/obj/item/paper/guides/jobs/security/paystand_setup,
/turf/open/floor/plasteel,
/area/security/warden)
"wGe" = (
diff --git a/_maps/map_files/YogStation/YogStation.dmm b/_maps/map_files/YogStation/YogStation.dmm
index eaf4d9f330b0..aa48b4460fc7 100644
--- a/_maps/map_files/YogStation/YogStation.dmm
+++ b/_maps/map_files/YogStation/YogStation.dmm
@@ -4705,6 +4705,13 @@
/obj/machinery/door/firedoor/border_only,
/turf/open/floor/plating,
/area/construction/mining/aux_base)
+"aHY" = (
+/obj/structure/chair/sofa/right,
+/obj/machinery/status_display/ai{
+ pixel_y = 32
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"aIh" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
dir = 1
@@ -5461,12 +5468,6 @@
},
/turf/open/floor/plasteel/white,
/area/medical/chemistry)
-"aMV" = (
-/obj/structure/toilet{
- dir = 4
- },
-/turf/open/floor/plasteel/freezer,
-/area/crew_quarters/heads/captain)
"aMZ" = (
/turf/closed/wall,
/area/hallway/secondary/exit)
@@ -6609,10 +6610,6 @@
},
/turf/open/floor/plating,
/area/maintenance/port/fore)
-"aUZ" = (
-/mob/living/simple_animal/pet/fox/Renault,
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"aVc" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
@@ -6653,18 +6650,6 @@
/obj/machinery/vending/cola/random,
/turf/open/floor/plasteel/dark,
/area/hallway/secondary/entry)
-"aWc" = (
-/obj/machinery/status_display/evac{
- pixel_y = 32
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"aWg" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
@@ -7115,11 +7100,6 @@
},
/turf/open/floor/plating,
/area/maintenance/aft)
-"baQ" = (
-/obj/structure/displaycase/captain,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"baS" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plasteel,
@@ -7153,21 +7133,6 @@
},
/turf/open/floor/plasteel,
/area/crew_quarters/locker)
-"bbo" = (
-/obj/machinery/computer/security/telescreen/entertainment{
- pixel_y = 32
- },
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
- dir = 8
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"bbq" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
dir = 4
@@ -7180,9 +7145,6 @@
},
/turf/open/floor/plating,
/area/maintenance/port)
-"bbw" = (
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"bbx" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
dir = 4
@@ -7218,6 +7180,20 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/library)
+"bbE" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer4{
+ dir = 8
+ },
+/obj/structure/cable{
+ icon_state = "1-4";
+ tag = ""
+ },
+/obj/effect/turf_decal/siding/wood/corner/thin{
+ dir = 4
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"bbG" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
dir = 5
@@ -7309,11 +7285,6 @@
/obj/machinery/telecomms/server/presets/security,
/turf/open/floor/circuit/green/telecomms/mainframe,
/area/tcommsat/server)
-"bch" = (
-/obj/structure/table/wood,
-/obj/item/storage/fancy/donut_box,
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"bcn" = (
/obj/structure/sign/directions/evac{
dir = 4;
@@ -7440,12 +7411,6 @@
/obj/machinery/telecomms/server/presets/command,
/turf/open/floor/circuit/green/telecomms/mainframe,
/area/tcommsat/server)
-"bdk" = (
-/obj/structure/chair/comfy/brown{
- dir = 8
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"bdm" = (
/obj/machinery/door/airlock{
name = "Unit 1"
@@ -7462,28 +7427,6 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
/turf/open/floor/plasteel/white,
/area/medical/medbay/lobby)
-"bdq" = (
-/obj/machinery/power/apc{
- areastring = "/area/crew_quarters/heads/captain";
- dir = 1;
- name = "Captain's Office APC";
- pixel_y = 23
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "0-8"
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
-"bdr" = (
-/obj/item/kirbyplants/random,
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"bdv" = (
/obj/machinery/navbeacon{
codes_txt = "patrol;next_patrol=HOP2";
@@ -7570,16 +7513,6 @@
"bea" = (
/turf/closed/wall/r_wall,
/area/quartermaster/warehouse)
-"beg" = (
-/obj/structure/table/wood,
-/obj/machinery/camera{
- c_tag = "Captain's Office";
- dir = 8
- },
-/obj/item/storage/lockbox/medal,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"bei" = (
/obj/machinery/door/firedoor/border_only{
dir = 1
@@ -7599,6 +7532,22 @@
},
/turf/open/floor/plasteel/white,
/area/medical/medbay/aft)
+"bej" = (
+/obj/structure/table/glass,
+/obj/item/reagent_containers/food/drinks/bottle/amaretto{
+ pixel_x = -3;
+ pixel_y = 10
+ },
+/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{
+ pixel_x = 5;
+ pixel_y = -1
+ },
+/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass{
+ pixel_x = 9;
+ pixel_y = 12
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"bek" = (
/obj/structure/girder,
/turf/open/floor/plating,
@@ -7696,20 +7645,6 @@
},
/turf/open/floor/plating,
/area/quartermaster/sorting)
-"bfl" = (
-/obj/structure/table/wood,
-/obj/machinery/airalarm{
- dir = 8;
- pixel_x = 24
- },
-/obj/item/camera,
-/obj/item/storage/photo_album{
- pixel_y = -10
- },
-/obj/item/toy/figure/captain,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"bfo" = (
/obj/machinery/door/window/eastright{
dir = 1;
@@ -7729,20 +7664,6 @@
"bfv" = (
/turf/closed/wall/r_wall,
/area/ai_monitored/turret_protected/ai_upload)
-"bfC" = (
-/obj/structure/table/wood,
-/obj/item/pinpointer/nuke,
-/obj/item/disk/nuclear,
-/obj/item/storage/secure/safe{
- pixel_x = 35;
- pixel_y = 5
- },
-/obj/machinery/light{
- dir = 4
- },
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"bfF" = (
/turf/closed/wall,
/area/medical/chemistry)
@@ -8042,13 +7963,6 @@
},
/turf/open/floor/plasteel/white,
/area/medical/storage)
-"bhG" = (
-/obj/machinery/firealarm{
- dir = 1;
- pixel_y = -26
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"bhH" = (
/obj/machinery/door/airlock/maintenance{
req_access_txt = "12"
@@ -8883,15 +8797,6 @@
},
/turf/open/floor/plating,
/area/hallway/secondary/entry)
-"bpk" = (
-/obj/machinery/shower{
- dir = 1
- },
-/obj/item/soap/deluxe,
-/obj/item/bikehorn/rubberducky,
-/obj/structure/curtain,
-/turf/open/floor/plasteel/freezer,
-/area/crew_quarters/heads/captain)
"bpr" = (
/obj/machinery/navbeacon{
codes_txt = "delivery;dir=8";
@@ -12232,6 +12137,22 @@
/obj/item/melee/sledgehammer,
/turf/open/floor/plasteel,
/area/engine/engineering)
+"bRr" = (
+/obj/effect/turf_decal/ramp_corner,
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
+"bRs" = (
+/obj/effect/turf_decal/ramp_middle{
+ dir = 4
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/extinguisher_cabinet{
+ pixel_y = -30
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"bRu" = (
/obj/effect/turf_decal/stripes/corner{
dir = 8
@@ -12774,6 +12695,11 @@
},
/turf/open/floor/plating,
/area/maintenance/solars/starboard/aft)
+"bYT" = (
+/obj/structure/table/wood,
+/obj/item/storage/lockbox/medal,
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"bZg" = (
/obj/effect/turf_decal/trimline/secred/filled/line/lower{
dir = 8
@@ -13555,6 +13481,12 @@
"cjJ" = (
/turf/closed/wall/r_wall,
/area/engine/engine_smes)
+"cjK" = (
+/obj/structure/cable{
+ icon_state = "1-4"
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"cjL" = (
/obj/effect/decal/cleanable/glass,
/turf/open/floor/plating,
@@ -14506,6 +14438,21 @@
},
/turf/open/floor/plasteel,
/area/construction/mining/aux_base)
+"cuT" = (
+/obj/machinery/power/apc{
+ areastring = "/area/crew_quarters/heads/captain";
+ dir = 1;
+ name = "Captain's Office APC";
+ pixel_y = 23
+ },
+/obj/structure/cable{
+ icon_state = "0-8"
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 4
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"cuZ" = (
/obj/machinery/camera{
c_tag = "Telecomms Server Room";
@@ -14953,13 +14900,6 @@
},
/turf/open/floor/plasteel,
/area/maintenance/disposal/incinerator)
-"cCz" = (
-/obj/machinery/light{
- dir = 8
- },
-/obj/machinery/suit_storage_unit/captain,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"cCD" = (
/obj/structure/chair/office/light,
/obj/effect/landmark/start/chemist,
@@ -15135,11 +15075,6 @@
/obj/effect/landmark/carpspawn,
/turf/open/space/basic,
/area/space)
-"cEV" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"cFk" = (
/obj/structure/cloth_curtain{
color = "#99ccff";
@@ -16748,16 +16683,6 @@
},
/turf/open/floor/plasteel,
/area/science/misc_lab)
-"diw" = (
-/obj/machinery/modular_computer/console/preset/command{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
- dir = 8
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"diJ" = (
/obj/item/book/manual/wiki/security_space_law,
/obj/structure/table,
@@ -17021,6 +16946,14 @@
},
/turf/open/floor/carpet,
/area/crew_quarters/heads/hos)
+"dnF" = (
+/obj/machinery/suit_storage_unit/captain,
+/obj/machinery/firealarm{
+ dir = 1;
+ pixel_y = -26
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"doM" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer4,
/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2,
@@ -17075,6 +17008,9 @@
},
/turf/open/floor/plasteel,
/area/engine/atmos/mix)
+"doS" = (
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"doZ" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
@@ -18290,6 +18226,27 @@
icon_state = "panelscorched"
},
/area/maintenance/aft)
+"dNO" = (
+/obj/machinery/button/door{
+ id = "captain blast";
+ name = "Privacy Shutters Control";
+ pixel_x = 26;
+ pixel_y = -1;
+ req_access_txt = "20"
+ },
+/obj/structure/railing{
+ dir = 9
+ },
+/obj/structure/table/wood,
+/obj/machinery/photocopier/faxmachine{
+ department = "Captain";
+ name = "Captain's Fax Machine"
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 9
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"dNY" = (
/turf/closed/wall/r_wall,
/area/engine/foyer)
@@ -19409,19 +19366,6 @@
/obj/effect/turf_decal/pool/innercorner,
/turf/open/water/safe,
/area/hydroponics/garden)
-"ekU" = (
-/obj/machinery/door/airlock/command{
- name = "Captain's Quarters";
- req_access_txt = "20"
- },
-/obj/machinery/door/firedoor/border_only{
- dir = 1
- },
-/obj/machinery/door/firedoor/border_only,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"ekZ" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
dir = 4
@@ -20508,11 +20452,6 @@
},
/turf/open/floor/plating,
/area/maintenance/starboard/fore)
-"eEi" = (
-/obj/structure/table/wood,
-/obj/item/folder/blue,
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"eEj" = (
/obj/machinery/advanced_airlock_controller{
dir = 8;
@@ -20634,16 +20573,6 @@
/obj/effect/turf_decal/trimline/atmos/warning/lower/nobottom,
/turf/open/floor/plasteel,
/area/engine/atmos/mix)
-"eGj" = (
-/obj/item/radio/intercom{
- dir = 8;
- freerange = 1;
- name = "Station Intercom (Command)";
- pixel_x = -28
- },
-/obj/structure/filingcabinet,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"eGm" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
dir = 8
@@ -21789,6 +21718,18 @@
/obj/effect/turf_decal/trimline/blue/filled/line/lower,
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
+"fbj" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "captain blast";
+ name = "captain's shutters"
+ },
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/plating,
+/area/crew_quarters/heads/captain)
"fbF" = (
/obj/structure/table,
/obj/item/radio/off,
@@ -22115,6 +22056,15 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/aft)
+"fiz" = (
+/obj/effect/turf_decal/ramp_middle,
+/obj/machinery/door/window/northleft{
+ dir = 2;
+ name = "Captain's Desk Door";
+ req_one_access_txt = "20"
+ },
+/turf/open/floor/plasteel/stairs/goon/wood_stairs_wide,
+/area/crew_quarters/heads/captain)
"fiE" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 10
@@ -22275,6 +22225,23 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/port)
+"flu" = (
+/obj/structure/railing{
+ dir = 5
+ },
+/obj/structure/table/wood,
+/obj/item/hand_tele{
+ pixel_x = 3
+ },
+/obj/item/storage/pencil_holder/crew/fancy{
+ pixel_x = -7;
+ pixel_y = 4
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 5
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"flC" = (
/obj/machinery/door/firedoor/border_only{
dir = 4
@@ -22539,13 +22506,6 @@
},
/turf/open/floor/plasteel/dark,
/area/bridge)
-"fqv" = (
-/obj/machinery/disposal/bin,
-/obj/structure/disposalpipe/trunk{
- dir = 4
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"fqI" = (
/obj/machinery/computer/prisoner,
/obj/effect/turf_decal/trimline/secred/filled/line/lower{
@@ -25343,12 +25303,6 @@
"gtC" = (
/turf/closed/wall,
/area/medical/medbay/lobby)
-"gtE" = (
-/obj/structure/chair/comfy/brown{
- dir = 4
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"gtI" = (
/obj/machinery/camera{
c_tag = "Arrivals Bay 2";
@@ -25474,6 +25428,18 @@
},
/turf/open/floor/plasteel,
/area/hallway/secondary/exit)
+"guY" = (
+/obj/structure/chair/office/light{
+ dir = 4
+ },
+/obj/structure/railing/corner{
+ dir = 8
+ },
+/obj/effect/turf_decal/siding/wood/corner/thin{
+ dir = 1
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"gvl" = (
/obj/effect/turf_decal/stripes/corner{
dir = 1
@@ -25526,6 +25492,10 @@
},
/turf/open/floor/plasteel,
/area/quartermaster/office)
+"gwZ" = (
+/obj/structure/closet/secure_closet/captains,
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"gxF" = (
/obj/machinery/button/door{
desc = "A remote control-switch for shuttle construction storage.";
@@ -26809,6 +26779,15 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
/area/maintenance/starboard/fore)
+"gWx" = (
+/obj/effect/turf_decal/trimline/darkblue/filled/line/lower{
+ dir = 8
+ },
+/obj/machinery/status_display/evac{
+ pixel_x = -32
+ },
+/turf/open/floor/plasteel,
+/area/hallway/primary/central)
"gWA" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable{
@@ -27110,6 +27089,10 @@
/obj/effect/turf_decal/trimline/purple/filled/line/lower,
/turf/open/floor/plasteel,
/area/hallway/primary/starboard)
+"hbo" = (
+/obj/structure/displaycase/captain,
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"hbO" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -27313,27 +27296,6 @@
/obj/structure/lattice,
/turf/open/space/basic,
/area/space/nearstation)
-"hgw" = (
-/obj/machinery/light_switch{
- pixel_y = 28
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer4{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
- dir = 10
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"hgD" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
dir = 8
@@ -27741,6 +27703,18 @@
},
/turf/open/floor/plasteel,
/area/hallway/secondary/entry)
+"hnh" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/machinery/modular_computer/console/preset/command{
+ dir = 8
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"hnA" = (
/obj/effect/turf_decal/trimline/darkblue/filled/line/lower{
dir = 6
@@ -28011,6 +27985,34 @@
},
/turf/open/floor/plasteel/dark/telecomms,
/area/tcommsat/server)
+"hss" = (
+/obj/machinery/recharger/wallrecharger{
+ pixel_x = -25;
+ pixel_y = 20
+ },
+/obj/machinery/requests_console{
+ announcementConsole = 1;
+ department = "Captain's Desk";
+ departmentType = 5;
+ name = "Captain RC";
+ pixel_x = -30
+ },
+/obj/item/stamp/captain{
+ layer = 3.2;
+ pixel_x = 8;
+ pixel_y = -2
+ },
+/obj/structure/table/wood,
+/obj/item/paper_bin{
+ pixel_x = -3;
+ pixel_y = 7
+ },
+/obj/item/pen{
+ pixel_x = -6;
+ pixel_y = 5
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"hsA" = (
/obj/machinery/computer/camera_advanced/base_construction{
dir = 1
@@ -28114,6 +28116,18 @@
},
/turf/open/floor/plasteel,
/area/maintenance/disposal/incinerator)
+"huD" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/machinery/computer/communications{
+ dir = 8
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"huO" = (
/obj/structure/table,
/obj/machinery/photocopier/faxmachine{
@@ -28175,11 +28189,6 @@
/obj/item/storage/pencil_holder/crew/fancy,
/turf/open/floor/carpet/royalblue,
/area/crew_quarters/heads/cmo)
-"hwu" = (
-/obj/item/kirbyplants/random,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"hwx" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
dir = 4
@@ -28326,6 +28335,19 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/maintenance/starboard/aft)
+"hzP" = (
+/obj/structure/sink{
+ dir = 4;
+ pixel_x = 11
+ },
+/obj/structure/mirror{
+ pixel_x = 28
+ },
+/obj/machinery/light/small{
+ dir = 1
+ },
+/turf/open/floor/plasteel/freezer,
+/area/crew_quarters/heads/captain)
"hzQ" = (
/obj/structure/table,
/obj/item/reagent_containers/glass/bucket,
@@ -28377,6 +28399,19 @@
},
/turf/open/floor/plating,
/area/maintenance/aft)
+"hAI" = (
+/obj/machinery/door/airlock{
+ name = "Private Restroom";
+ req_access_txt = "20"
+ },
+/obj/machinery/door/firedoor/border_only{
+ dir = 4
+ },
+/obj/machinery/door/firedoor/border_only{
+ dir = 8
+ },
+/turf/open/floor/plasteel/freezer,
+/area/crew_quarters/heads/captain)
"hAJ" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 4
@@ -28991,6 +29026,13 @@
},
/turf/open/floor/plasteel,
/area/maintenance/disposal/incinerator)
+"hNx" = (
+/obj/structure/chair/sofa,
+/obj/machinery/computer/security/telescreen/entertainment{
+ pixel_y = 32
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"hNI" = (
/obj/effect/spawner/structure/window/reinforced/shutter,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
@@ -29025,6 +29067,18 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/security/main)
+"hOk" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
+ dir = 8
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 1
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"hOn" = (
/obj/effect/turf_decal/bot_red,
/obj/structure/rack,
@@ -29167,6 +29221,18 @@
"hQm" = (
/turf/open/floor/circuit,
/area/ai_monitored/nuke_storage)
+"hQo" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 6
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 6
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 1
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"hQt" = (
/obj/machinery/camera{
c_tag = "Virology Break Room";
@@ -29530,6 +29596,13 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plasteel,
/area/hydroponics)
+"hVX" = (
+/obj/structure/filingcabinet,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"hVY" = (
/obj/structure/sign/departments/minsky/research/research{
pixel_y = -32
@@ -30231,10 +30304,6 @@
},
/turf/open/floor/plating,
/area/maintenance/fore/secondary)
-"ihF" = (
-/obj/machinery/holopad,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"iiE" = (
/obj/machinery/firealarm{
dir = 1;
@@ -30342,10 +30411,6 @@
/obj/effect/turf_decal/trimline/brown/filled/corner/lower,
/turf/open/floor/plasteel,
/area/quartermaster/office)
-"ilk" = (
-/obj/structure/closet/secure_closet/captains,
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"ilm" = (
/obj/structure/sink{
dir = 4;
@@ -30975,21 +31040,6 @@
},
/turf/open/space/basic,
/area/ai_monitored/turret_protected/ai)
-"ixh" = (
-/obj/machinery/status_display/ai{
- pixel_y = 32
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
- dir = 4
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"ixn" = (
/obj/structure/cable{
icon_state = "1-2"
@@ -31618,6 +31668,12 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/port)
+"iKa" = (
+/obj/structure/chair/sofa/left{
+ dir = 8
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"iKc" = (
/obj/structure/closet/secure_closet/CMO,
/obj/item/sensor_device,
@@ -32526,12 +32582,6 @@
},
/turf/open/floor/plasteel,
/area/engine/engineering)
-"jaj" = (
-/obj/structure/chair/comfy/brown{
- dir = 4
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"jaq" = (
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plasteel/white,
@@ -33841,6 +33891,15 @@
/obj/effect/turf_decal/box/corners,
/turf/open/floor/engine,
/area/science/xenobiology)
+"jCH" = (
+/obj/structure/table/wood,
+/obj/item/pinpointer/nuke,
+/obj/item/disk/nuclear,
+/obj/machinery/light{
+ dir = 8
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"jCM" = (
/obj/machinery/computer/message_monitor{
dir = 1
@@ -34374,6 +34433,21 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/aft)
+"jNh" = (
+/obj/structure/table/wood,
+/obj/item/storage/box/matches,
+/obj/item/razor{
+ pixel_x = -4;
+ pixel_y = 2
+ },
+/obj/item/clothing/mask/cigarette/cigar,
+/obj/item/reagent_containers/food/drinks/flask/gold,
+/obj/machinery/light_switch{
+ pixel_x = 25;
+ pixel_y = 8
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"jNo" = (
/obj/machinery/lapvend,
/obj/effect/turf_decal/trimline/purple/filled/line/lower{
@@ -34565,6 +34639,18 @@
},
/turf/open/floor/wood,
/area/library)
+"jRb" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/effect/turf_decal/ramp_middle,
+/obj/machinery/door/window{
+ base_state = "right";
+ icon_state = "right";
+ name = "Captain's Desk Door";
+ req_access_txt = "20"
+ },
+/turf/open/floor/plasteel/stairs/goon/wood_stairs_wide2,
+/area/crew_quarters/heads/captain)
"jRq" = (
/obj/effect/turf_decal/stripes/white/line{
dir = 6
@@ -35039,6 +35125,12 @@
/obj/effect/spawner/structure/window/reinforced/shutter,
/turf/open/floor/plating,
/area/security/prison)
+"kcc" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
+ dir = 1
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"kcr" = (
/obj/machinery/status_display/ai{
pixel_y = -32
@@ -35211,14 +35303,6 @@
},
/turf/open/floor/plasteel/freezer,
/area/crew_quarters/toilet/locker)
-"kgY" = (
-/obj/machinery/recharger/wallrecharger{
- pixel_x = -21;
- pixel_y = -3
- },
-/obj/machinery/papershredder,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"khh" = (
/obj/structure/table/reinforced,
/obj/machinery/door/window/northleft{
@@ -35983,21 +36067,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/fore)
-"kwY" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp/green{
- pixel_x = 5;
- pixel_y = 8
- },
-/obj/item/phone/real{
- pixel_x = -2;
- pixel_y = -4
- },
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
- dir = 8
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"kxl" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 4
@@ -37181,21 +37250,6 @@
/obj/effect/turf_decal/trimline/purple/filled/corner/lower,
/turf/open/floor/plasteel/white,
/area/science/research)
-"kVQ" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
- dir = 5
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
- dir = 5
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "1-4"
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"kVU" = (
/turf/closed/wall,
/area/vacant_room/commissary)
@@ -37255,11 +37309,6 @@
},
/turf/open/floor/plasteel,
/area/crew_quarters/fitness)
-"kXE" = (
-/obj/structure/table/wood,
-/obj/item/flashlight/lamp/green,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"kXP" = (
/obj/machinery/light,
/obj/effect/decal/cleanable/dirt,
@@ -38704,12 +38753,6 @@
"lyX" = (
/turf/open/floor/plasteel/dark,
/area/tcommsat/storage)
-"lza" = (
-/obj/structure/table/wood,
-/obj/item/book/manual/wiki/security_space_law,
-/obj/item/coin/plasma,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"lze" = (
/turf/open/floor/wood,
/area/vacant_room)
@@ -39042,6 +39085,15 @@
/obj/item/mop,
/turf/open/floor/plasteel/dark,
/area/janitor)
+"lHL" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "captain blast";
+ name = "captain's shutters"
+ },
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/crew_quarters/heads/captain)
"lHO" = (
/obj/item/stack/cable_coil,
/obj/effect/decal/cleanable/dirt/dust,
@@ -40909,13 +40961,11 @@
/obj/machinery/meter,
/turf/open/floor/plasteel,
/area/engine/atmos/distro)
-"msz" = (
-/obj/structure/table/wood,
-/obj/item/melee/chainofcommand,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+"msk" = (
+/obj/effect/turf_decal/ramp_middle{
dir = 4
},
-/turf/open/floor/wood,
+/turf/open/floor/wood/large,
/area/crew_quarters/heads/captain)
"msD" = (
/obj/effect/spawner/structure/window/reinforced/shutter,
@@ -40927,6 +40977,19 @@
},
/turf/open/floor/plating,
/area/hallway/primary/central)
+"msN" = (
+/obj/machinery/newscaster/security_unit{
+ pixel_x = 32
+ },
+/obj/machinery/camera{
+ c_tag = "Captain's Office";
+ dir = 8
+ },
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"msT" = (
/obj/structure/bed,
/obj/item/bedsheet/captain,
@@ -41227,6 +41290,15 @@
},
/turf/open/floor/plasteel,
/area/hydroponics)
+"mzu" = (
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 1
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"mzy" = (
/obj/effect/turf_decal/stripes/corner{
dir = 4
@@ -41474,14 +41546,6 @@
},
/turf/open/floor/plasteel/dark,
/area/security/prison)
-"mCx" = (
-/obj/machinery/computer/communications{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"mCK" = (
/obj/effect/turf_decal/trimline/secred/filled/line/lower,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
@@ -41885,6 +41949,13 @@
},
/turf/open/floor/plating,
/area/security/brig)
+"mLc" = (
+/obj/structure/chair/sofa/corner,
+/obj/machinery/status_display/ai{
+ pixel_y = 32
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"mLd" = (
/obj/effect/turf_decal/trimline/secred/filled/line/lower{
dir = 1
@@ -42248,15 +42319,6 @@
/obj/effect/spawner/lootdrop/coin,
/turf/open/floor/plating,
/area/maintenance/port/fore)
-"mRq" = (
-/obj/machinery/newscaster/security_unit{
- pixel_x = -32
- },
-/obj/machinery/keycard_auth{
- pixel_y = -24
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"mRV" = (
/obj/machinery/computer/nanite_chamber_control{
dir = 8
@@ -42280,16 +42342,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
-"mSa" = (
-/obj/machinery/door/window{
- base_state = "right";
- dir = 4;
- icon_state = "right";
- name = "Captain's Desk Door";
- req_access_txt = "20"
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"mSg" = (
/obj/machinery/atmospherics/pipe/manifold/general/visible,
/turf/open/floor/circuit/telecomms/server,
@@ -42335,12 +42387,6 @@
},
/turf/open/floor/plasteel,
/area/science/misc_lab)
-"mTm" = (
-/obj/structure/extinguisher_cabinet{
- pixel_y = -30
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"mTr" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 4
@@ -42446,6 +42492,23 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
/turf/open/floor/plating,
/area/maintenance/port/fore)
+"mUE" = (
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 1
+ },
+/obj/structure/railing{
+ dir = 1
+ },
+/obj/structure/table/wood,
+/obj/item/melee/chainofcommand,
+/obj/item/radio/intercom{
+ dir = 8;
+ freerange = 1;
+ name = "Station Intercom (Command)";
+ pixel_x = -28
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"mUU" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 1
@@ -43340,6 +43403,14 @@
/obj/effect/spawner/structure/window/reinforced/shutter,
/turf/open/floor/plating,
/area/security/prison)
+"nlI" = (
+/obj/machinery/disposal/bin,
+/obj/structure/disposalpipe/trunk{
+ dir = 4
+ },
+/obj/machinery/light,
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"nlS" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 4
@@ -44190,10 +44261,6 @@
},
/turf/open/floor/plasteel,
/area/security/checkpoint/supply)
-"nCL" = (
-/obj/machinery/vending/autodrobe/capdrobe,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"nCO" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
@@ -44918,19 +44985,6 @@
/obj/structure/table,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
-"nTb" = (
-/obj/machinery/door/airlock{
- name = "Private Restroom";
- req_access_txt = "20"
- },
-/obj/machinery/door/firedoor/border_only{
- dir = 4
- },
-/obj/machinery/door/firedoor/border_only{
- dir = 8
- },
-/turf/open/floor/plasteel/freezer,
-/area/crew_quarters/heads/captain)
"nTv" = (
/obj/effect/turf_decal/trimline/secred/filled/line/lower{
dir = 1
@@ -45241,6 +45295,12 @@
},
/turf/open/floor/plasteel/white,
/area/medical/storage)
+"oaq" = (
+/obj/effect/turf_decal/ramp_middle{
+ dir = 1
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"oaC" = (
/obj/effect/turf_decal/trimline/secred/filled/line/lower{
dir = 1
@@ -45555,6 +45615,18 @@
},
/turf/open/floor/plasteel/dark,
/area/ai_monitored/turret_protected/aisat_interior)
+"ohr" = (
+/obj/structure/cable{
+ icon_state = "1-4";
+ tag = ""
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/structure/cable{
+ icon_state = "1-2"
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"ohy" = (
/obj/machinery/recharger/wallrecharger{
pixel_x = 5;
@@ -45587,13 +45659,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
-"oiA" = (
-/obj/structure/dresser,
-/obj/machinery/light/small{
- dir = 1
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"oiE" = (
/obj/structure/table/reinforced,
/obj/machinery/light{
@@ -46449,6 +46514,15 @@
},
/turf/open/floor/plasteel/white,
/area/medical/virology)
+"oxG" = (
+/obj/structure/railing/corner{
+ dir = 4
+ },
+/obj/effect/turf_decal/siding/wood/corner/thin{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"oyd" = (
/obj/structure/window/reinforced{
dir = 4
@@ -47029,16 +47103,6 @@
},
/turf/open/floor/plating,
/area/maintenance/aft)
-"oKL" = (
-/obj/structure/chair/comfy/brown{
- dir = 4
- },
-/obj/machinery/camera/motion{
- c_tag = "Captain's Quarters";
- dir = 1
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"oKX" = (
/obj/item/radio/intercom{
name = "Station Intercom (General)";
@@ -47178,21 +47242,6 @@
},
/turf/open/floor/plating,
/area/maintenance/fore)
-"oME" = (
-/obj/structure/table/wood,
-/obj/item/storage/box/matches,
-/obj/item/razor{
- pixel_x = -4;
- pixel_y = 2
- },
-/obj/item/clothing/mask/cigarette/cigar,
-/obj/item/reagent_containers/food/drinks/flask/gold,
-/obj/machinery/light_switch{
- pixel_x = 25;
- pixel_y = 8
- },
-/turf/open/floor/carpet/blue,
-/area/crew_quarters/heads/captain)
"oMV" = (
/obj/effect/mapping_helpers/airlock/locked,
/obj/machinery/door/airlock/research/glass{
@@ -47269,6 +47318,9 @@
/obj/effect/turf_decal/trimline/blue/filled/line/lower,
/turf/open/floor/plasteel/white,
/area/medical/medbay/central)
+"oNF" = (
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"oNS" = (
/obj/structure/table,
/obj/item/coin/silver,
@@ -47588,12 +47640,6 @@
/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/quartermaster/storage)
-"oVK" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
- dir = 8
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"oVO" = (
/obj/machinery/firealarm{
pixel_y = 26
@@ -48391,6 +48437,16 @@
},
/turf/open/floor/plasteel/dark,
/area/engine/gravity_generator)
+"pkR" = (
+/obj/effect/landmark/event_spawn,
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 1
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"pkU" = (
/obj/effect/turf_decal/loading_area{
dir = 1
@@ -48655,6 +48711,14 @@
},
/turf/open/floor/plasteel,
/area/engine/engine_smes)
+"ppk" = (
+/obj/item/kirbyplants/random,
+/obj/item/storage/secure/safe{
+ pixel_x = -24;
+ pixel_y = 2
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"ppK" = (
/obj/structure/rack,
/obj/effect/spawner/lootdrop/maintenance{
@@ -49407,6 +49471,15 @@
},
/turf/open/floor/plasteel,
/area/security/checkpoint/auxiliary)
+"pBC" = (
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/machinery/light{
+ dir = 4
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"pBG" = (
/turf/closed/wall,
/area/maintenance/department/medical/morgue)
@@ -50218,10 +50291,6 @@
/obj/item/hand_tele,
/turf/open/floor/plasteel,
/area/teleporter)
-"pUK" = (
-/obj/structure/chair,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"pUL" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
dir = 1
@@ -51275,6 +51344,11 @@
},
/turf/open/floor/plasteel,
/area/security/prison)
+"qnQ" = (
+/obj/structure/table/glass,
+/obj/item/storage/fancy/donut_box,
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"qnU" = (
/obj/machinery/door/firedoor/border_only,
/obj/machinery/door/firedoor/border_only{
@@ -51452,6 +51526,21 @@
},
/turf/open/floor/plasteel/dark,
/area/security/interrogation)
+"qrA" = (
+/obj/structure/table/wood,
+/obj/item/flashlight/lamp/green{
+ pixel_x = 5;
+ pixel_y = 8
+ },
+/obj/item/phone/real{
+ pixel_x = -2;
+ pixel_y = -4
+ },
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
+ dir = 8
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"qsk" = (
/obj/machinery/firealarm{
dir = 4;
@@ -52723,6 +52812,11 @@
/obj/machinery/bounty_board,
/turf/closed/wall,
/area/quartermaster/storage)
+"qPH" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"qPS" = (
/obj/structure/table/reinforced,
/obj/machinery/door/window/northleft{
@@ -54257,10 +54351,6 @@
},
/turf/open/floor/plating,
/area/ai_monitored/storage/satellite)
-"ruZ" = (
-/obj/machinery/vending/cigarette,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"rvc" = (
/obj/machinery/light,
/obj/item/radio/intercom{
@@ -54973,6 +55063,15 @@
},
/turf/open/floor/plasteel,
/area/security/checkpoint/medical)
+"rIQ" = (
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 1
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"rJa" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
dir = 9
@@ -58370,6 +58469,20 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/port)
+"sXE" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "captain blast";
+ name = "captain's shutters"
+ },
+/obj/effect/spawner/structure/window/reinforced,
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/obj/structure/cable{
+ icon_state = "0-2"
+ },
+/turf/open/floor/plating,
+/area/crew_quarters/heads/captain)
"sXH" = (
/turf/closed/wall/r_wall,
/area/engine/atmos/foyer)
@@ -58432,19 +58545,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
-"sYn" = (
-/obj/structure/sink{
- dir = 4;
- pixel_x = 11
- },
-/obj/structure/mirror{
- pixel_x = 28
- },
-/obj/machinery/light/small{
- dir = 1
- },
-/turf/open/floor/plasteel/freezer,
-/area/crew_quarters/heads/captain)
"sYv" = (
/obj/machinery/navbeacon{
codes_txt = "patrol;next_patrol=CHE";
@@ -58459,23 +58559,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/starboard)
-"sZn" = (
-/obj/structure/table/wood,
-/obj/item/stamp/captain{
- layer = 3.2;
- pixel_x = 8;
- pixel_y = -2
- },
-/obj/item/paper_bin{
- pixel_x = -3;
- pixel_y = 7
- },
-/obj/item/pen{
- pixel_x = -6;
- pixel_y = 5
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"sZy" = (
/obj/effect/turf_decal/trimline/brown/filled/line/lower{
dir = 8
@@ -58508,19 +58591,6 @@
},
/turf/open/floor/plasteel,
/area/security/brig)
-"sZY" = (
-/obj/machinery/camera{
- c_tag = "Central Hallway East";
- dir = 4
- },
-/obj/machinery/status_display/evac{
- pixel_x = -32
- },
-/obj/effect/turf_decal/trimline/darkblue/filled/line/lower{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/hallway/primary/central)
"tah" = (
/obj/effect/landmark/stationroom/maint/threexfive,
/turf/template_noop,
@@ -58632,6 +58702,18 @@
},
/turf/open/floor/plasteel,
/area/quartermaster/storage)
+"tcm" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 9
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 9
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 1
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"tcr" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 0;
@@ -58760,6 +58842,12 @@
},
/turf/open/floor/plasteel/white,
/area/medical/chemistry)
+"tfl" = (
+/obj/structure/toilet{
+ dir = 4
+ },
+/turf/open/floor/plasteel/freezer,
+/area/crew_quarters/heads/captain)
"tfF" = (
/obj/effect/turf_decal/trimline/purple/filled/line/lower{
dir = 4
@@ -59208,10 +59296,6 @@
},
/turf/open/floor/plasteel,
/area/engine/atmos/foyer)
-"tmz" = (
-/obj/effect/landmark/event_spawn,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"tmB" = (
/obj/machinery/requests_console{
department = "Janitorial";
@@ -59249,6 +59333,19 @@
/obj/structure/lattice,
/turf/open/space/basic,
/area/space/nearstation)
+"tnN" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/machinery/door/airlock/command{
+ name = "Captain's Quarters";
+ req_access_txt = "20"
+ },
+/obj/machinery/door/firedoor/border_only{
+ dir = 1
+ },
+/obj/machinery/door/firedoor/border_only,
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"toz" = (
/obj/effect/turf_decal/stripes/corner{
dir = 1
@@ -61684,7 +61781,7 @@
"umX" = (
/obj/machinery/door/airlock/security/glass{
name = "Armory";
- req_access_txt = "3";
+ req_access_txt = "1";
security_level = 1
},
/obj/machinery/door/firedoor/border_only{
@@ -61984,16 +62081,6 @@
},
/turf/open/floor/plasteel/dark,
/area/engine/engineering)
-"utm" = (
-/obj/structure/table/wood,
-/obj/item/hand_tele,
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
-/obj/item/storage/pencil_holder/crew/fancy{
- pixel_y = 12
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"utp" = (
/obj/structure/closet/athletic_mixed,
/obj/item/pool/pool_noodle,
@@ -64113,6 +64200,10 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/fore)
+"viS" = (
+/obj/effect/landmark/start/chaplain,
+/turf/template_noop,
+/area/template_noop)
"viU" = (
/obj/structure/table,
/obj/structure/mirror{
@@ -64368,6 +64459,13 @@
},
/turf/open/floor/plasteel,
/area/security/prison)
+"vnl" = (
+/obj/item/kirbyplants/random,
+/obj/machinery/airalarm{
+ pixel_y = 24
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"vnp" = (
/obj/structure/chair{
dir = 8
@@ -65000,6 +65098,20 @@
},
/turf/open/floor/plasteel,
/area/construction/mining/aux_base)
+"vyH" = (
+/obj/structure/railing{
+ dir = 5
+ },
+/obj/structure/table/wood,
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 5
+ },
+/obj/item/flashlight/lamp/green{
+ pixel_x = 6;
+ pixel_y = 5
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"vyL" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 8
@@ -66889,6 +67001,18 @@
},
/turf/open/floor/plasteel/cafeteria,
/area/crew_quarters/heads/cmo)
+"wgP" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"whu" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -67725,21 +67849,6 @@
},
/turf/open/floor/plating,
/area/storage/tech)
-"wxL" = (
-/obj/structure/table/wood,
-/obj/machinery/requests_console{
- announcementConsole = 1;
- department = "Captain's Desk";
- departmentType = 5;
- name = "Captain RC";
- pixel_x = -30
- },
-/obj/machinery/photocopier/faxmachine{
- department = "Captain";
- name = "Captain's Fax Machine"
- },
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"wyd" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
dir = 4
@@ -68217,6 +68326,15 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plasteel,
/area/science/research)
+"wKM" = (
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/machinery/light_switch{
+ pixel_y = 28
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"wKP" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 8;
@@ -68446,6 +68564,19 @@
},
/turf/open/floor/plasteel/white,
/area/medical/virology)
+"wPu" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 5
+ },
+/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer2{
+ dir = 8
+ },
+/obj/structure/cable{
+ icon_state = "1-4";
+ tag = ""
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"wPB" = (
/obj/machinery/status_display/ai{
pixel_x = -32
@@ -68522,6 +68653,15 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/central)
+"wRD" = (
+/obj/machinery/shower{
+ dir = 1
+ },
+/obj/item/soap/deluxe,
+/obj/item/bikehorn/rubberducky,
+/obj/structure/curtain,
+/turf/open/floor/plasteel/freezer,
+/area/crew_quarters/heads/captain)
"wRK" = (
/obj/structure/closet/secure_closet/personal/patient,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
@@ -68943,6 +69083,22 @@
/obj/structure/bodycontainer/morgue,
/turf/open/floor/plasteel/dark,
/area/security/brig)
+"wZx" = (
+/mob/living/simple_animal/pet/fox/Renault,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
+ dir = 10
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{
+ dir = 10
+ },
+/obj/structure/cable{
+ icon_state = "2-8"
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 4
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"wZD" = (
/turf/open/floor/plasteel/white,
/area/science/nanite)
@@ -69059,10 +69215,6 @@
},
/turf/open/floor/plasteel,
/area/hallway/primary/aft)
-"xdg" = (
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/wood,
-/area/crew_quarters/heads/captain)
"xdh" = (
/obj/item/radio/intercom{
name = "Station Intercom (General)";
@@ -69883,6 +70035,16 @@
},
/turf/open/floor/plasteel/white,
/area/medical/storage)
+"xvN" = (
+/obj/machinery/camera{
+ c_tag = "Central Hallway East";
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/darkblue/filled/line/lower{
+ dir = 8
+ },
+/turf/open/floor/plasteel,
+/area/hallway/primary/central)
"xvO" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 4
@@ -70122,6 +70284,13 @@
},
/turf/open/floor/plasteel/dark,
/area/science/xenobiology)
+"xzH" = (
+/obj/machinery/light/small{
+ dir = 1
+ },
+/obj/machinery/vending/autodrobe/capdrobe,
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"xAi" = (
/obj/structure/closet/secure_closet/brig,
/obj/effect/turf_decal/bot_red,
@@ -70165,6 +70334,16 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/maintenance/port)
+"xBj" = (
+/obj/structure/chair/comfy/brown{
+ dir = 4
+ },
+/obj/machinery/camera/motion{
+ c_tag = "Captain's Quarters";
+ dir = 1
+ },
+/turf/open/floor/carpet/blue,
+/area/crew_quarters/heads/captain)
"xBl" = (
/obj/machinery/door/airlock/maintenance{
name = "Atmospherics Maintenance";
@@ -70284,6 +70463,14 @@
},
/turf/open/floor/plasteel,
/area/science/robotics/lab)
+"xCE" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2,
+/obj/effect/turf_decal/ramp_middle{
+ dir = 1
+ },
+/turf/open/floor/wood/large,
+/area/crew_quarters/heads/captain)
"xCV" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -71869,6 +72056,19 @@
/obj/structure/cable,
/turf/open/floor/plasteel/white,
/area/science/nanite)
+"yje" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/siding/wood/thin{
+ dir = 4
+ },
+/obj/machinery/papershredder,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/crew_quarters/heads/captain)
"yjf" = (
/obj/machinery/power/tracker,
/obj/structure/cable/yellow{
@@ -103219,13 +103419,13 @@ hRj
xjd
oKX
aZV
-fqv
-ruZ
-nCL
-cCz
-wxL
-kgY
-eGj
+bYT
+jCH
+ppk
+oaq
+mUE
+hss
+hbo
aZV
aZV
aZV
@@ -103476,18 +103676,18 @@ exk
qkB
xxK
qNB
-kVQ
-bbw
-bbw
-pUK
-sZn
-gtE
-bbw
-mRq
+ohr
+wPu
+kcc
+oaq
+flu
+oxG
+oNF
+dnF
aZV
-oiA
+xzH
msT
-ilk
+gwZ
bqH
pJI
kmp
@@ -103733,18 +103933,18 @@ cDq
daI
lmd
aZV
-hgw
-cEV
-cEV
-cEV
-utm
-mCx
-diw
-cEV
-ekU
+wKM
+wgP
+doS
+oaq
+fiz
+hQo
+qPH
+qPH
+tnN
eDM
nFx
-oKL
+xBj
bqH
pUH
qup
@@ -103990,18 +104190,18 @@ aPR
mJr
aPR
aZV
-ixh
-jaj
-jaj
-kmy
-kXE
-lza
-msz
-mSa
+cuT
+wZx
+bbE
+xCE
+jRb
+tcm
+oNF
+nlI
aZV
jsR
-kwY
-oME
+qrA
+jNh
bqH
pVj
quT
@@ -104247,16 +104447,16 @@ oUy
jkJ
xgM
aZV
-bbo
-bch
-eEi
+vnl
kmy
-tmz
-bbw
-oVK
-mTm
+hOk
+oaq
+dNO
+guY
+oNF
+hVX
aZV
-nTb
+hAI
aZV
aZV
bqH
@@ -104504,18 +104704,18 @@ onB
daI
wWA
aZV
-aWc
-bdk
-bdk
-aUZ
-bbw
-ihF
-bbw
-bbw
+aHY
+qnQ
+pkR
+oaq
+vyH
+huD
+hnh
+yje
aZV
-sYn
-aMV
-bpk
+hzP
+tfl
+wRD
bqH
bsj
btI
@@ -104761,14 +104961,14 @@ qjx
bQi
dbt
aZV
-bdq
-bbw
-bbw
-bbw
-bbw
-bbw
-bbw
-bhG
+hNx
+bej
+mzu
+bRr
+msk
+msk
+msk
+bRs
aZV
aZV
aZV
@@ -105018,14 +105218,14 @@ mVl
pKz
hQK
aZV
-bdr
-baQ
-hwu
-beg
-bfC
-bfl
-xdg
-xdg
+mLc
+iKa
+rIQ
+msN
+cjK
+doS
+doS
+pBC
nsz
kSk
qWH
@@ -105279,9 +105479,9 @@ aZV
aZV
aZV
aZV
-aZV
-aZV
-aZV
+sXE
+fbj
+lHL
aZV
aZV
bmA
@@ -105532,9 +105732,9 @@ yfj
jAv
ipG
nmg
+gWx
lFZ
-lFZ
-sZY
+xvN
sgo
lFZ
lFZ
@@ -120689,7 +120889,7 @@ qQV
qQV
qQV
qQV
-qQV
+viS
qQV
qQV
qQV
diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index ebdf7cc4a452..60a5237310a9 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -9278,7 +9278,7 @@
"aug" = (
/obj/structure/table/wood,
/obj/item/pitchfork/demonic/ascended,
-/obj/item/melee/powerfist,
+/obj/item/clothing/gloves/powerfist/filled,
/turf/open/floor/wood,
/area/centcom/testchamber)
"auh" = (
diff --git a/_maps/multiz_debug.json b/_maps/multiz_debug.json_bak
similarity index 77%
rename from _maps/multiz_debug.json
rename to _maps/multiz_debug.json_bak
index dd9a04df342d..6b2df33f2c61 100644
--- a/_maps/multiz_debug.json
+++ b/_maps/multiz_debug.json_bak
@@ -1,4 +1,5 @@
{
+ "__comment": "Map json disabled due to crash during unit testing",
"map_name": "MultiZ Debug",
"map_path": "map_files/debug",
"map_file": "multiz.dmm",
diff --git a/auxmos.dll b/auxmos.dll
new file mode 100644
index 000000000000..6f76316c3f72
Binary files /dev/null and b/auxmos.dll differ
diff --git a/auxmos.pdb b/auxmos.pdb
new file mode 100644
index 000000000000..c86057ac0181
Binary files /dev/null and b/auxmos.pdb differ
diff --git a/byond-extools.dll b/byond-extools.dll
deleted file mode 100644
index 37efe6c6e403..000000000000
Binary files a/byond-extools.dll and /dev/null differ
diff --git a/byond-extools.pdb b/byond-extools.pdb
deleted file mode 100644
index b0665dcfea62..000000000000
Binary files a/byond-extools.pdb and /dev/null differ
diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index b63cb9091b41..4424f9a8ca30 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -4,8 +4,6 @@
//Defines copying names of mutations in all cases, make sure to change this if you change mutation's type
#define HULK /datum/mutation/human/hulk
-#define ACTIVE_HULK /datum/mutation/human/active_hulk
-#define GENETICS_HULK /datum/mutation/human/genetics_hulk
#define XRAY /datum/mutation/human/thermal/x_ray
#define SPACEMUT /datum/mutation/human/space_adaptation
#define HEATMUT /datum/mutation/human/heat_adaptation
diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm
index 7c84b693e31c..aa1d6214bd26 100644
--- a/code/__DEFINES/MC.dm
+++ b/code/__DEFINES/MC.dm
@@ -9,6 +9,8 @@
Master.current_ticklimit = original_tick_limit;\
}
+#define MC_TICK_REMAINING_MS ((Master.current_ticklimit - TICK_USAGE) * world.tick_lag)
+
// Used to smooth out costs to try and avoid oscillation.
#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current))
#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current))
diff --git a/code/__DEFINES/_auxtools.dm b/code/__DEFINES/_auxtools.dm
new file mode 100644
index 000000000000..a907be8ecf8f
--- /dev/null
+++ b/code/__DEFINES/_auxtools.dm
@@ -0,0 +1,8 @@
+/proc/auxtools_stack_trace(msg)
+ CRASH(msg)
+
+/proc/auxtools_expr_stub()
+ CRASH("auxtools not loaded")
+
+/proc/enable_debugging(mode, port)
+ CRASH("auxtools not loaded")
diff --git a/code/__DEFINES/_bitfields.dm b/code/__DEFINES/_bitfields.dm
new file mode 100644
index 000000000000..19a962fbffe5
--- /dev/null
+++ b/code/__DEFINES/_bitfields.dm
@@ -0,0 +1,4 @@
+#define DEFINE_BITFIELD(_variable, _flags) /datum/bitfield/##_variable { \
+ flags = ##_flags; \
+ variable = #_variable; \
+}
diff --git a/code/__DEFINES/ai.dm b/code/__DEFINES/ai.dm
index 3107edc5b84a..e0d742e1ad66 100644
--- a/code/__DEFINES/ai.dm
+++ b/code/__DEFINES/ai.dm
@@ -4,6 +4,8 @@
///Temperature limit of all AI machinery
#define AI_TEMP_LIMIT 288.15 //15C, much hotter than a normal server room for leniency :)
+#define AI_HEATSINK_CAPACITY 5000
+#define AI_HEATSINK_COEFF 1
///How many ticks can an AI data core store? When this amount of ticks have passed while it's in an INVALID state it can no longer be used by an AI
#define MAX_AI_DATA_CORE_TICKS 45
diff --git a/code/__DEFINES/announcements.dm b/code/__DEFINES/announcements.dm
new file mode 100644
index 000000000000..3a2edf6d6f77
--- /dev/null
+++ b/code/__DEFINES/announcements.dm
@@ -0,0 +1,7 @@
+// Priority-type announcement messages for `priority_announcement()`
+/// Prefix this announcement with "Priority Announcement"
+#define ANNOUNCEMENT_TYPE_PRIORITY "Priority"
+/// Make it sound like it's coming from the Captain
+#define ANNOUNCEMENT_TYPE_CAPTAIN "Captain"
+/// Make it sound like it's coming from the Syndicate
+#define ANNOUNCEMENT_TYPE_SYNDICATE "Syndicate"
diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index 8060c7883b78..307e24ad60fa 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -110,6 +110,7 @@
#define PATH_SIDE "Side"
+#define PATH_NONE "Unpledged"
#define PATH_ASH "Ash"
#define PATH_RUST "Rust"
#define PATH_FLESH "Flesh"
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index ea7c98d075c9..62eeffd3106f 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -1,15 +1,3 @@
-//LISTMOS
-//indices of values in gas lists.
-#define MOLES 1
-#define ARCHIVE 2
-#define GAS_META 3
-#define META_GAS_SPECIFIC_HEAT 1
-#define META_GAS_NAME 2
-#define META_GAS_MOLES_VISIBLE 3
-#define META_GAS_OVERLAY 4
-#define META_GAS_DANGER 5
-#define META_GAS_ID 6
-#define META_GAS_FUSION_POWER 7
//ATMOS
//stuff you should probably leave well alone!
/// kPa*L/(K*mol)
@@ -437,6 +425,32 @@
/// north/south east/west doesn't matter, auto normalize on build.
#define PIPING_CARDINAL_AUTONORMALIZE (1<<3)
+// Gas defines because i hate typepaths
+#define GAS_O2 "o2"
+#define GAS_N2 "n2"
+#define GAS_CO2 "co2"
+#define GAS_PLASMA "plasma"
+#define GAS_H2O "water_vapor"
+#define GAS_HYPERNOB "hypernob"
+#define GAS_NITROUS "n2o"
+#define GAS_NITRIUM "no2"
+#define GAS_TRITIUM "tritium"
+#define GAS_BZ "bz"
+#define GAS_PLUOXIUM "pluox"
+#define GAS_MIASMA "miasma"
+#define GAS_H2 "hydrogen"
+#define GAS_FREON "freon"
+#define GAS_HEALIUM "healium"
+#define GAS_PLUONIUM "pluonium"
+#define GAS_HALON "halon"
+#define GAS_ANTINOB "antinob"
+#define GAS_ZAUKER "zauker"
+#define GAS_HEXANE "hexane"
+#define GAS_DILITHIUM "dilithium"
+
+#define GAS_FLAG_DANGEROUS (1<<0)
+#define GAS_FLAG_BREATH_PROC (1<<1)
+
//HELPERS
#define PIPING_LAYER_SHIFT(T, PipingLayer) \
if(T.dir & (NORTH|SOUTH)) { \
@@ -458,24 +472,6 @@
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;
-#ifdef TESTING
-GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
-#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 }
-#else
-#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
-#endif
-
-GLOBAL_VAR(atmos_extools_initialized) // this must be an uninitialized (null) one or init_monstermos will be called twice because reasons
-#define ATMOS_EXTOOLS_CHECK if(!GLOB.atmos_extools_initialized){\
- GLOB.atmos_extools_initialized=TRUE;\
- if(fexists(EXTOOLS)){\
- var/result = LIBCALL(EXTOOLS,"init_monstermos")();\
- if(result != "ok") {CRASH(result);}\
- } else {\
- CRASH("byond-extools.dll does not exist!");\
- }\
-}
-
GLOBAL_LIST_INIT(pipe_paint_colors, list(
"amethyst" = rgb(130,43,255), //supplymain
"blue" = rgb(0,0,255),
@@ -494,4 +490,14 @@ GLOBAL_LIST_INIT(pipe_paint_colors, list(
#define MIASMA_CORPSE_MOLES 0.02
#define MIASMA_GIBS_MOLES 0.005
+//PIPENET UPDATE STATUS
+#define PIPENET_UPDATE_STATUS_DORMANT 0
+#define PIPENET_UPDATE_STATUS_REACT_NEEDED 1
+#define PIPENET_UPDATE_STATUS_RECONCILE_NEEDED 2
+
#define TURF_SHARES(T) (LAZYLEN(T.atmos_adjacent_turfs))
+
+//Defines for air alarm severities in areas.
+#define ATMOS_ALARM_SEVERE "severe"
+#define ATMOS_ALARM_MINOR "minor"
+#define ATMOS_ALARM_CLEAR "clear"
diff --git a/code/__DEFINES/bindings.dm b/code/__DEFINES/bindings.dm
new file mode 100644
index 000000000000..18f8586433bf
--- /dev/null
+++ b/code/__DEFINES/bindings.dm
@@ -0,0 +1,182 @@
+#define AUXMOS (__detect_auxmos())
+
+/proc/__detect_auxmos()
+ if (world.system_type == UNIX)
+ return "libauxmos"
+ else
+ return "auxmos"
+
+/turf/proc/__update_auxtools_turf_adjacency_info()
+ return call_ext(AUXMOS, "byond:hook_infos_ffi")(src)
+
+/turf/proc/update_air_ref(flag)
+ return call_ext(AUXMOS, "byond:hook_register_turf_ffi")(src, flag)
+
+/datum/gas_mixture/proc/__auxtools_parse_gas_string(string)
+ return call_ext(AUXMOS, "byond:parse_gas_string_ffi")(src, string)
+
+/datum/controller/subsystem/air/proc/get_max_gas_mixes()
+ return call_ext(AUXMOS, "byond:hook_max_gas_mixes_ffi")()
+
+/datum/controller/subsystem/air/proc/get_amt_gas_mixes()
+ return call_ext(AUXMOS, "byond:hook_amt_gas_mixes_ffi")()
+
+/proc/equalize_all_gases_in_list(gas_list)
+ return call_ext(AUXMOS, "byond:equalize_all_hook_ffi")(gas_list)
+
+/datum/gas_mixture/proc/get_oxidation_power(temp)
+ return call_ext(AUXMOS, "byond:oxidation_power_hook_ffi")(src, temp)
+
+/datum/gas_mixture/proc/get_fuel_amount(temp)
+ return call_ext(AUXMOS, "byond:fuel_amount_hook_ffi")(src, temp)
+
+/datum/gas_mixture/proc/equalize_with(total)
+ return call_ext(AUXMOS, "byond:equalize_with_hook_ffi")(src, total)
+
+/datum/gas_mixture/proc/transfer_ratio_to(other, ratio)
+ return call_ext(AUXMOS, "byond:transfer_ratio_hook_ffi")(src, other, ratio)
+
+/datum/gas_mixture/proc/transfer_to(other, moles)
+ return call_ext(AUXMOS, "byond:transfer_hook_ffi")(src, other, moles)
+
+/datum/gas_mixture/proc/adjust_heat(temp)
+ return call_ext(AUXMOS, "byond:adjust_heat_hook_ffi")(src, temp)
+
+/datum/gas_mixture/proc/react(holder)
+ return call_ext(AUXMOS, "byond:react_hook_ffi")(src, holder)
+
+/datum/gas_mixture/proc/compare(other)
+ return call_ext(AUXMOS, "byond:compare_hook_ffi")(src, other)
+
+/datum/gas_mixture/proc/clear()
+ return call_ext(AUXMOS, "byond:clear_hook_ffi")(src)
+
+/datum/gas_mixture/proc/mark_immutable()
+ return call_ext(AUXMOS, "byond:mark_immutable_hook_ffi")(src)
+
+/datum/gas_mixture/proc/scrub_into(into, ratio_v, gas_list)
+ return call_ext(AUXMOS, "byond:scrub_into_hook_ffi")(src, into, ratio_v, gas_list)
+
+/datum/gas_mixture/proc/get_by_flag(flag_val)
+ return call_ext(AUXMOS, "byond:get_by_flag_hook_ffi")(src, flag_val)
+
+/datum/gas_mixture/proc/__remove_by_flag(into, flag_val, amount_val)
+ return call_ext(AUXMOS, "byond:remove_by_flag_hook_ffi")(src, into, flag_val, amount_val)
+
+/datum/gas_mixture/proc/divide(num_val)
+ return call_ext(AUXMOS, "byond:divide_hook_ffi")(src, num_val)
+
+/datum/gas_mixture/proc/multiply(num_val)
+ return call_ext(AUXMOS, "byond:multiply_hook_ffi")(src, num_val)
+
+/datum/gas_mixture/proc/subtract(num_val)
+ return call_ext(AUXMOS, "byond:subtract_hook_ffi")(src, num_val)
+
+/datum/gas_mixture/proc/add(num_val)
+ return call_ext(AUXMOS, "byond:add_hook_ffi")(src, num_val)
+
+/datum/gas_mixture/proc/adjust_multi(...)
+ var/list/args_copy = args.Copy()
+ args_copy.Insert(1, src)
+ return call_ext(AUXMOS, "byond:adjust_multi_hook_ffi")(arglist(args_copy))
+
+/datum/gas_mixture/proc/adjust_moles_temp(id_val, num_val, temp_val)
+ return call_ext(AUXMOS, "byond:adjust_moles_temp_hook_ffi")(src, id_val, num_val, temp_val)
+
+/datum/gas_mixture/proc/adjust_moles(id_val, num_val)
+ return call_ext(AUXMOS, "byond:adjust_moles_hook_ffi")(src, id_val, num_val)
+
+/datum/gas_mixture/proc/set_moles(gas_id, amt_val)
+ return call_ext(AUXMOS, "byond:set_moles_hook_ffi")(src, gas_id, amt_val)
+
+/datum/gas_mixture/proc/get_moles(gas_id)
+ return call_ext(AUXMOS, "byond:get_moles_hook_ffi")(src, gas_id)
+
+/datum/gas_mixture/proc/set_volume(vol_arg)
+ return call_ext(AUXMOS, "byond:set_volume_hook_ffi")(src, vol_arg)
+
+/datum/gas_mixture/proc/partial_heat_capacity(gas_id)
+ return call_ext(AUXMOS, "byond:partial_heat_capacity_ffi")(src, gas_id)
+
+/datum/gas_mixture/proc/set_temperature(arg_temp)
+ return call_ext(AUXMOS, "byond:set_temperature_hook_ffi")(src, arg_temp)
+
+/datum/gas_mixture/proc/get_gases()
+ return call_ext(AUXMOS, "byond:get_gases_hook_ffi")(src)
+
+/datum/gas_mixture/proc/temperature_share(...)
+ var/list/args_copy = args.Copy()
+ args_copy.Insert(1, src)
+ return call_ext(AUXMOS, "byond:temperature_share_hook_ffi")(arglist(args_copy))
+
+/datum/gas_mixture/proc/copy_from(giver)
+ return call_ext(AUXMOS, "byond:copy_from_hook_ffi")(src, giver)
+
+/datum/gas_mixture/proc/__remove(into, amount_arg)
+ return call_ext(AUXMOS, "byond:remove_hook_ffi")(src, into, amount_arg)
+
+/datum/gas_mixture/proc/__remove_ratio(into, ratio_arg)
+ return call_ext(AUXMOS, "byond:remove_ratio_hook_ffi")(src, into, ratio_arg)
+
+/datum/gas_mixture/proc/merge(giver)
+ return call_ext(AUXMOS, "byond:merge_hook_ffi")(src, giver)
+
+/datum/gas_mixture/proc/thermal_energy()
+ return call_ext(AUXMOS, "byond:thermal_energy_hook_ffi")(src)
+
+/datum/gas_mixture/proc/return_volume()
+ return call_ext(AUXMOS, "byond:return_volume_hook_ffi")(src)
+
+/datum/gas_mixture/proc/return_temperature()
+ return call_ext(AUXMOS, "byond:return_temperature_hook_ffi")(src)
+
+/datum/gas_mixture/proc/return_pressure()
+ return call_ext(AUXMOS, "byond:return_pressure_hook_ffi")(src)
+
+/datum/gas_mixture/proc/total_moles()
+ return call_ext(AUXMOS, "byond:total_moles_hook_ffi")(src)
+
+/datum/gas_mixture/proc/set_min_heat_capacity(arg_min)
+ return call_ext(AUXMOS, "byond:min_heat_cap_hook_ffi")(src, arg_min)
+
+/datum/gas_mixture/proc/heat_capacity()
+ return call_ext(AUXMOS, "byond:heat_cap_hook_ffi")(src)
+
+/datum/gas_mixture/proc/__gasmixture_unregister()
+ return call_ext(AUXMOS, "byond:unregister_gasmixture_hook_ffi")(src)
+
+/datum/gas_mixture/proc/__gasmixture_register()
+ return call_ext(AUXMOS, "byond:register_gasmixture_hook_ffi")(src)
+
+/proc/process_atmos_callbacks(remaining)
+ return call_ext(AUXMOS, "byond:atmos_callback_handle_ffi")(remaining)
+
+/datum/controller/subsystem/air/proc/process_turf_equalize_auxtools(remaining)
+ return call_ext(AUXMOS, "byond:equalize_hook_ffi")(src, remaining)
+
+/datum/controller/subsystem/air/proc/process_excited_groups_auxtools(remaining)
+ return call_ext(AUXMOS, "byond:groups_hook_ffi")(src, remaining)
+
+/proc/finalize_gas_refs()
+ return call_ext(AUXMOS, "byond:finalize_gas_refs_ffi")()
+
+/datum/controller/subsystem/air/proc/auxtools_update_reactions()
+ return call_ext(AUXMOS, "byond:update_reactions_ffi")()
+
+/proc/auxtools_atmos_init(gas_data)
+ return call_ext(AUXMOS, "byond:hook_init_ffi")(gas_data)
+
+/proc/_auxtools_register_gas(gas)
+ return call_ext(AUXMOS, "byond:hook_register_gas_ffi")(gas)
+
+/proc/__auxmos_shutdown()
+ return call_ext(AUXMOS, "byond:auxmos_shutdown_ffi")()
+
+/datum/controller/subsystem/air/proc/process_turfs_auxtools(remaining)
+ return call_ext(AUXMOS, "byond:process_turf_hook_ffi")(src, remaining)
+
+/datum/controller/subsystem/air/proc/finish_turf_processing_auxtools(time_remaining)
+ return call_ext(AUXMOS, "byond:finish_process_turfs_ffi")(time_remaining)
+
+/datum/controller/subsystem/air/proc/thread_running()
+ return call_ext(AUXMOS, "byond:thread_running_hook_ffi")()
diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm
index ef64e821a051..b6fbca4f6dce 100644
--- a/code/__DEFINES/colors.dm
+++ b/code/__DEFINES/colors.dm
@@ -346,3 +346,22 @@ GLOBAL_LIST_INIT(cable_colors, list(
#define COLOR_INPUT_DISABLED "#F0F0F0"
#define COLOR_INPUT_ENABLED "#D3B5B5"
+
+/// Change color to red on ANSI terminal output, if enabled with -DANSICOLORS.
+#ifdef ANSICOLORS
+#define TEST_OUTPUT_RED(text) "\x1B\x5B1;31m[text]\x1B\x5B0m"
+#else
+#define TEST_OUTPUT_RED(text) (text)
+#endif
+/// Change color to green on ANSI terminal output, if enabled with -DANSICOLORS.
+#ifdef ANSICOLORS
+#define TEST_OUTPUT_GREEN(text) "\x1B\x5B1;32m[text]\x1B\x5B0m"
+#else
+#define TEST_OUTPUT_GREEN(text) (text)
+#endif
+/// Change color to yellow on ANSI terminal output, if enabled with -DANSICOLORS.
+#ifdef ANSICOLORS
+#define TEST_OUTPUT_YELLOW(text) "\x1B\x5B1;33m[text]\x1B\x5B0m"
+#else
+#define TEST_OUTPUT_YELLOW(text) (text)
+#endif
diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index ebc28a4d5700..f699cb55ca6c 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -34,6 +34,8 @@
#define BIO "bio"
/// Involves ionizing radiation.
#define RAD "rad"
+/// Involves electric shock.
+#define ELECTRIC "electric"
/// Involves fire or temperature extremes.
#define FIRE "fire"
/// Involves corrosive substances.
@@ -236,8 +238,8 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define EXPLODE_LIGHT 3
#define EXPLODE_GIB_THRESHOLD 50 //ex_act() with EXPLODE_DEVASTATE severity will gib mobs with less than this much bomb armor
-#define EMP_HEAVY 1
-#define EMP_LIGHT 2
+#define EMP_LIGHT 5 // maximum severity level without severe effects like organ failure and paralysis
+#define EMP_HEAVY 10 // max severity from most sources so you can't use a 5 billion tile EMP to instakill people
#define GRENADE_CLUMSY_FUMBLE 1
#define GRENADE_NONCLUMSY_FUMBLE 2
diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_lighting.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_lighting.dm
index 88a29ec697a4..63a366ea1aea 100644
--- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_lighting.dm
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_lighting.dm
@@ -19,6 +19,14 @@
#define COMSIG_ATOM_SET_LIGHT_COLOR "atom_set_light_color"
///Called right after the atom changes the value of light_color to a different one, from base of [/atom/proc/set_light_color]: (old_color)
#define COMSIG_ATOM_UPDATE_LIGHT_COLOR "atom_update_light_color"
+///Called right before the atom changes the value of light_angle to a different one, from base [atom/proc/set_light_angle]: (new_angle)
+#define COMSIG_ATOM_SET_LIGHT_ANGLE "atom_set_light_angle"
+///Called right after the atom changes the value of light_angle to a different one, from base of [/atom/proc/set_light_angle]: (old_angle)
+#define COMSIG_ATOM_UPDATE_LIGHT_ANGLE "atom_update_light_angle"
+///Called right before the atom changes the value of light_dir to a different one, from base [atom/proc/set_light_dir]: (new_dir)
+#define COMSIG_ATOM_SET_LIGHT_DIR "atom_set_light_dir"
+///Called right after the atom changes the value of light_dir to a different one, from base of [/atom/proc/set_light_dir]: (old_dir)
+#define COMSIG_ATOM_UPDATE_LIGHT_DIR "atom_update_light_dir"
///Called right before the atom changes the value of light_on to a different one, from base [atom/proc/set_light_on]: (new_value)
#define COMSIG_ATOM_SET_LIGHT_ON "atom_set_light_on"
///Called right after the atom changes the value of light_on to a different one, from base of [/atom/proc/set_light_on]: (old_value)
diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm
index 720e132aa190..2ef0297bd972 100644
--- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm
@@ -77,14 +77,6 @@
#define COMSIG_MOVABLE_SET_ANCHORED "movable_set_anchored"
///from base of atom/movable/setGrabState(): (newstate)
#define COMSIG_MOVABLE_SET_GRAB_STATE "living_set_grab_state"
-///Called when the movable tries to change its dynamic light color setting, from base atom/movable/lighting_overlay_set_color(): (color)
-#define COMSIG_MOVABLE_LIGHT_OVERLAY_SET_RANGE "movable_light_overlay_set_color"
-///Called when the movable tries to change its dynamic light power setting, from base atom/movable/lighting_overlay_set_power(): (power)
-#define COMSIG_MOVABLE_LIGHT_OVERLAY_SET_POWER "movable_light_overlay_set_power"
-///Called when the movable tries to change its dynamic light range setting, from base atom/movable/lighting_overlay_set_range(): (range)
-#define COMSIG_MOVABLE_LIGHT_OVERLAY_SET_COLOR "movable_light_overlay_set_range"
-///Called when the movable tries to toggle its dynamic light LIGHTING_ON status, from base atom/movable/lighting_overlay_toggle_on(): (new_state)
-#define COMSIG_MOVABLE_LIGHT_OVERLAY_TOGGLE_ON "movable_light_overlay_toggle_on"
///called when the movable's glide size is updated: (new_glide_size)
#define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size"
///Called when a movable is hit by a plunger in layer mode, from /obj/item/plunger/attack_atom()
diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm
index b8dd7713d195..56d9754eb42f 100644
--- a/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm
+++ b/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm
@@ -26,6 +26,7 @@
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished"
///from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act"
+ #define COMPONENT_NO_ELECTROCUTE_ACT (1<<0)
///sent when items with siemen coeff. of 0 block a shock: (power_source, source, siemens_coeff, dist_check)
#define COMSIG_LIVING_SHOCK_PREVENTED "living_shock_prevented"
///sent by stuff like stunbatons and tasers: ()
diff --git a/code/__DEFINES/directional.dm b/code/__DEFINES/directional.dm
index 192a57706772..85d746a43882 100644
--- a/code/__DEFINES/directional.dm
+++ b/code/__DEFINES/directional.dm
@@ -8,6 +8,3 @@
#define TEXT_SOUTH "[SOUTH]"
#define TEXT_EAST "[EAST]"
#define TEXT_WEST "[WEST]"
-
-/// Inverse direction, taking into account UP|DOWN if necessary.
-#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) )
diff --git a/code/__DEFINES/extools.dm b/code/__DEFINES/extools.dm
deleted file mode 100644
index 0c20aeec1376..000000000000
--- a/code/__DEFINES/extools.dm
+++ /dev/null
@@ -1,144 +0,0 @@
-#define EXTOOLS_SUCCESS "SUCCESS"
-#define EXTOOLS_FAILED "FAIL"
-GLOBAL_VAR_INIT(enable_memdump, 0)
-
-/*
- Core - Provides necessary functionality for other modules.
- Initializing any other modules also initializes this so it shouldn't be necessary to call this.
-*/
-
-/proc/extools_initialize()
- return LIBCALL(EXTOOLS, "core_initialize")() == EXTOOLS_SUCCESS
-
-/*
- TFFI - Threaded FFI
- All DLL calls are automatically threaded off.
- Black magic is used to suspend (sleep) the currently executing proc, allowing non-blocking FFI.
- You may call a DLL function and sleep until it returns, pass a callback to be called with the result,
- or call resolve() on the /datum/promise to receive the return value at any time.
- Example:
- var/x = call_wait("sample.dll", "do_work", "arg1", "arg2", "arg3")
- - Calls the do_work function from sample.dll with 3 arguments. The proc sleeps until do_work returns.
- var/datum/promise/P = call_async("sample.dll", "do_work", "arg1")
- ... do something else ...
- var/result = P.resolve()
- - Calls do_work with 1 argument. Returns a promise object. Runs some other code before calling P.resolve() to obtain the result.
- /proc/print_result(result)
- world << result
- call_cb("sample.dll", "do_work", /proc/print_result, "arg1", "arg2")
- - Calls do_work with 2 arguments. The callback is invoked with the result as the single argument. Execution resumes immediately.
-*/
-
-#if 0
-
-/proc/tffi_initialize()
- return LIBCALL(EXTOOLS, "tffi_initialize")() == EXTOOLS_SUCCESS
-
-GLOBAL_VAR_INIT(fallback_alerted, FALSE)
-GLOBAL_VAR_INIT(next_promise_id, 0)
-
-/datum/promise
- var/completed = FALSE
- var/result = ""
- var/callback_context = GLOBAL_PROC
- var/callback_proc = null
- var/__id = 0
-
-/datum/promise/New()
- __id = next_promise_id++ //please don't create more than 10^38 promises in a single tick
-
-//This proc's bytecode is overwritten to allow suspending and resuming on demand.
-//None of the code here should run.
-/datum/promise/proc/__internal_resolve(ref, id)
- if(!fallback_alerted && world.system_type != UNIX) // the rewriting is currently broken on Linux.
- world << "TFFI: __internal_resolve has not been rewritten, the TFFI DLL was not loaded correctly. "
- world.log << "TFFI: __internal_resolve has not been rewritten, the TFFI DLL was not loaded correctly. "
- fallback_alerted = TRUE
- while(!completed)
- sleep(1)
- //It might be better to just fail and notify the user that something went wrong.
-
-/datum/promise/proc/__resolve_callback()
- __internal_resolve("\ref[src]", __id)
- if(callback_context == GLOBAL_PROC)
- call(callback_proc)(result)
- else
- call(callback_context, callback_proc)(result)
-
-/datum/promise/proc/resolve()
- __internal_resolve("\ref[src]", __id)
- return result
-
-/proc/call_async()
- var/list/arguments = args.Copy()
- var/datum/promise/P = new
- arguments.Insert(1, "\ref[P]")
- LIBCALL(EXTOOLS, "call_async")(arglist(arguments))
- return P
-
-/proc/call_cb()
- var/list/arguments = args.Copy()
- var/context = arguments[3]
- var/callback = arguments[4]
- arguments.Cut(3, 5)
- var/datum/promise/P = new
- P.callback_context = context
- P.callback_proc = callback
- arguments.Insert(1, "\ref[P]")
- LIBCALL(EXTOOLS, "call_async")(arglist(arguments))
- spawn(0)
- P.__resolve_callback()
-
-/proc/call_wait()
- return call_async(arglist(args)).resolve()
-
-#endif
-
-/*
- Extended Profiling - High precision in-depth performance profiling.
- Turning on extended profiling for a proc will cause each execution of it to generate a file in the ./profiles directory
- containing a breakdown of time spent executing the proc and each sub-proc it calls. Import the file into https://www.speedscope.app/ to
- view a good visual representation.
- Be aware that sleeping counts as stopping and restarting the execution of the proc, which will generate multiple files, one between each sleep.
- For large procs the profiles may become unusably large. Optimizations pending.
- Example:
- start_profiling(/datum/explosion/New)
- - Enables profiling for /datum/explosion/New(), which will produce a detailed breakdown of each explosion that occurs afterwards.
- stop_profiling(/datum/explosion/New)
- - Disables profiling for explosions. Any currently running profiles will stop when the proc finishes executing or enters a sleep.
-*/
-
-/proc/profiling_initialize()
- return LIBCALL(EXTOOLS, "extended_profiling_initialize")() == EXTOOLS_SUCCESS
-
-/proc/start_profiling(procpath)
- LIBCALL(EXTOOLS, "enable_extended_profiling")("[procpath]")
-
-/proc/stop_profiling(procpath)
- LIBCALL(EXTOOLS, "disable_extended_profiling")("[procpath]")
-
-/*
- Debug Server - High and low level debugging of DM code.
- Calling debugger_initialize will start a debug server that allows connections from frontends,
- such as SpaceManiac's VSCode extension for line-by-line debugging (and more), or Steamport's
- Somnium for bytecode inspection.
- Call with pause = TRUE to wait until the debugger connected and immediately break on the next instruction after the call.
-*/
-
-/proc/debugger_initialize(pause = FALSE)
- return LIBCALL(EXTOOLS, "debug_initialize")(pause ? "pause" : "") == EXTOOLS_SUCCESS
-
-/*
- Misc
-*/
-
-//Programatically enable and disable the built-in byond profiler. Useful if you want to, for example, profile subsystem initializations.
-/proc/enable_profiling()
- return LIBCALL(EXTOOLS, "enable_profiling")() == EXTOOLS_SUCCESS
-
-/proc/disable_profiling()
- return LIBCALL(EXTOOLS, "disable_profiling")() == EXTOOLS_SUCCESS
-
-// Will dump the server's in-depth memory profile into the file specified.
-/proc/dump_memory_profile(file_name)
- return LIBCALL(EXTOOLS, "dump_memory_usage")(file_name) == EXTOOLS_SUCCESS
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 51f2e3c9bca7..92c389063f8a 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -4,6 +4,10 @@
#define ALL (~0) //For convenience.
#define NONE 0
+/* Directions */
+///All the cardinal direction bitflags.
+#define ALL_CARDINALS (NORTH|SOUTH|EAST|WEST)
+
//for convenience
#define ENABLE_BITFIELD(variable, flag) (variable |= (flag))
#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag))
@@ -99,17 +103,18 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example)
*/
//flags for pass_flags
-#define PASSTABLE (1<<0)
-#define PASSGLASS (1<<1)
-#define PASSGRILLE (1<<2)
-#define PASSBLOB (1<<3)
-#define PASSMOB (1<<4)
-#define PASSCLOSEDTURF (1<<5)
-#define LETPASSTHROW (1<<6)
-#define PASSMACHINES (1<<7)
-#define PASSCOMPUTER (1<<8)
-#define PASSSTRUCTURE (1<<9)
-#define PASSDOORS (1<<10)
+#define PASSTABLE (1<<0)
+#define PASSGLASS (1<<1)
+#define PASSGRILLE (1<<2)
+#define PASSBLOB (1<<3)
+#define PASSMOB (1<<4)
+#define PASSCLOSEDTURF (1<<5)
+#define LETPASSTHROW (1<<6)
+#define PASSMACHINES (1<<7)
+#define PASSCOMPUTER (1<<8)
+#define PASSSTRUCTURE (1<<9)
+#define PASSDOOR (1<<10)
+#define PASSMECH (1<<11)
//Movement Types
#define GROUND (1<<0)
diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm
index 18f3e09c7a6c..57271b6bcdee 100644
--- a/code/__DEFINES/lighting.dm
+++ b/code/__DEFINES/lighting.dm
@@ -4,12 +4,17 @@
#define STATIC_LIGHT 1
///Light made by masking the lighting darkness plane.
#define MOVABLE_LIGHT 2
+/// Light made by masking the lighting darkness plane, and is directional.
+#define MOVABLE_LIGHT_DIRECTIONAL 3
+///Light made by masking the lighting darkness plane, and is a directionally focused beam.
+#define MOVABLE_LIGHT_BEAM 4
+
+#define NONSENSICAL_VALUE -99999
///Is a movable light source attached to another movable (its loc), meaning that the lighting component should go one level deeper.
#define LIGHT_ATTACHED (1<<0)
-
-///This light doesn't affect turf's lumcount calculations. Set to 1<<15 to ignore conflicts
-#define LIGHT_NO_LUMCOUNT (1<<15)
+/// Freezes a light in its current state, blocking any attempts at modification
+#define LIGHT_FROZEN (1<<1)
//Bay lighting engine shit, not in /code/modules/lighting because BYOND is being shit about it
/// frequency, in 1/10ths of a second, of the lighting process
@@ -67,6 +72,7 @@
#define DYNAMIC_LIGHTING_FORCED 2
/// dynamic lighting enabled only if starlight is.
#define DYNAMIC_LIGHTING_IFSTARLIGHT 3
+
#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting
diff --git a/code/__DEFINES/magic.dm b/code/__DEFINES/magic.dm
index 7eeae378337c..34ec4b6659b6 100644
--- a/code/__DEFINES/magic.dm
+++ b/code/__DEFINES/magic.dm
@@ -64,7 +64,7 @@
/// (effectively making the invocation flavor, instead of required).
#define SPELL_CASTABLE_WITHOUT_INVOCATION (1 << 8)
-/*DEFINE_BITFIELD(spell_requirements, list(
+DEFINE_BITFIELD(spell_requirements, list(
"SPELL_CASTABLE_AS_BRAIN" = SPELL_CASTABLE_AS_BRAIN,
"SPELL_CASTABLE_WHILE_PHASED" = SPELL_CASTABLE_WHILE_PHASED,
"SPELL_CASTABLE_WITHOUT_INVOCATION" = SPELL_CASTABLE_WITHOUT_INVOCATION,
@@ -74,7 +74,7 @@
"SPELL_REQUIRES_NO_ANTIMAGIC" = SPELL_REQUIRES_NO_ANTIMAGIC,
"SPELL_REQUIRES_STATION" = SPELL_REQUIRES_STATION,
"SPELL_REQUIRES_WIZARD_GARB" = SPELL_REQUIRES_WIZARD_GARB,
-))*/
+))
// Bitflags for teleport spells
/// Whether the teleport spell skips over space turfs
@@ -92,11 +92,11 @@
/// Holy magic resistance that blocks unholy magic (revenant, vampire, voice of god)
#define MAGIC_RESISTANCE_HOLY (1<<2)
-/*DEFINE_BITFIELD(antimagic_flags, list(
+DEFINE_BITFIELD(antimagic_flags, list(
"MAGIC_RESISTANCE" = MAGIC_RESISTANCE,
"MAGIC_RESISTANCE_HOLY" = MAGIC_RESISTANCE_HOLY,
"MAGIC_RESISTANCE_MIND" = MAGIC_RESISTANCE_MIND,
-))*/
+))
/**
* Checks if our mob is jaunting actively (within a phased mob object)
diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm
index 74cf20faa8eb..be6ebb9eb03e 100644
--- a/code/__DEFINES/maths.dm
+++ b/code/__DEFINES/maths.dm
@@ -228,5 +228,22 @@
#define DT_PROB(prob_per_second_percent, delta_time) (prob(100*DT_PROB_RATE(prob_per_second_percent/100, delta_time)))
// )
+/// Taxicab distance--gets you the **actual** time it takes to get from one turf to another due to how we calculate diagonal movement
+#define MANHATTAN_DISTANCE(a, b) (abs(a.x - b.x) + abs(a.y - b.y))
+// )
+
+/// A function that exponentially approaches a maximum value of L
+/// k is the rate at which is approaches L, x_0 is the point where the function = 0
+#define LOGISTIC_FUNCTION(L,k,x,x_0) (L/(1+(NUM_E**(-k*(x-x_0)))))
+
+// )
+/// Make sure something is a boolean TRUE/FALSE 1/0 value, since things like bitfield & bitflag doesn't always give 1s and 0s.
+#define FORCE_BOOLEAN(x) ((x)? TRUE : FALSE)
+
+// )
+/// Gives the number of pixels in an orthogonal line of tiles.
+#define TILES_TO_PIXELS(tiles) (tiles * PIXELS)
+// )
+
/// The number of cells in a taxicab circle (rasterized diamond) of radius X.
#define DIAMOND_AREA(X) (1 + 2*(X)*((X)+1))
diff --git a/code/__DEFINES/profile.dm b/code/__DEFINES/profile.dm
index 5fc847890145..ec79d942a984 100644
--- a/code/__DEFINES/profile.dm
+++ b/code/__DEFINES/profile.dm
@@ -27,3 +27,5 @@
#define PROFILE_ITEM_LEN 2
#define PROFILE_ITEM_TIME 1
#define PROFILE_ITEM_COUNT 2
+
+GLOBAL_VAR_INIT(enable_memdump, 0)
diff --git a/code/__DEFINES/reactions.dm b/code/__DEFINES/reactions.dm
index 722bb656567a..f032c69a70de 100644
--- a/code/__DEFINES/reactions.dm
+++ b/code/__DEFINES/reactions.dm
@@ -80,3 +80,5 @@
#define FUSION_RAD_MAX 1500
#define FUSION_RAD_COEFFICIENT (-1000)
#define FUSION_INSTABILITY_ENDOTHERMALITY 2
+// Snowflake fire product types
+#define FIRE_PRODUCT_PLASMA 0
diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm
index ff2c5f6827d7..f6a8b782498e 100644
--- a/code/__DEFINES/shuttles.dm
+++ b/code/__DEFINES/shuttles.dm
@@ -87,3 +87,12 @@
///Check for arena shuttle, if the bubblegum has died this round
GLOBAL_VAR_INIT(bubblegum_dead, FALSE)
+// Alert level related for new thing im porting --- cowbot93
+#define ALERT_COEFF_AUTOEVAC_NORMAL 6
+#define ALERT_COEFF_GREEN 5
+#define ALERT_COEFF_BLUE 4
+#define ALERT_COEFF_RED 3
+#define ALERT_COEFF_AUTOEVAC_CRITICAL 2
+#define ALERT_COEFF_DELTA 1
+#define ALERT_COEFF_GAMMA 0
+#define ALERT_COEFF_EPSILON -1
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index 27cafa5a56f3..385b6108efad 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -117,3 +117,23 @@
#define ANNOUNCER_SHUTTLEDOCK "announcer_shuttledock"
#define ANNOUNCER_SHUTTLERECALLED "announcer_shuttlerecalled"
#define ANNOUNCER_SPANOMALIES "announcer_spanomalies"
+
+/// Global list of all of our announcer keys.
+GLOBAL_LIST_INIT(announcer_keys, list(
+ ANNOUNCER_AIMALF,
+ ANNOUNCER_ALIENS,
+ ANNOUNCER_ANIMES,
+ ANNOUNCER_GRANOMALIES,
+ ANNOUNCER_INTERCEPT,
+ ANNOUNCER_IONSTORM,
+ ANNOUNCER_METEORS,
+ ANNOUNCER_OUTBREAK5,
+ ANNOUNCER_OUTBREAK7,
+ ANNOUNCER_POWEROFF,
+ ANNOUNCER_POWERON,
+ ANNOUNCER_RADIATION,
+ ANNOUNCER_SHUTTLECALLED,
+ ANNOUNCER_SHUTTLEDOCK,
+ ANNOUNCER_SHUTTLERECALLED,
+ ANNOUNCER_SPANOMALIES,
+))
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index a7b960b6e83b..944f6ef36c98 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -150,7 +150,8 @@
#define INIT_ORDER_CIRCUIT 15
#define INIT_ORDER_TIMER 1
#define INIT_ORDER_DEFAULT 0
-#define INIT_ORDER_AIR -1
+#define INIT_ORDER_AIR_MACHINERY -0.5
+#define INIT_ORDER_AIR -2
#define INIT_ORDER_PERSISTENCE -2
#define INIT_ORDER_PERSISTENT_PAINTINGS -3 // Assets relies on this
#define INIT_ORDER_ASSETS -4
@@ -195,6 +196,7 @@
#define FIRE_PRIORITY_DEFAULT 50
#define FIRE_PRIORITY_PARALLAX 65
#define FIRE_PRIORITY_INSTRUMENTS 80
+#define FIRE_PRIORITY_CALLBACKS 90
#define FIRE_PRIORITY_MOBS 100
#define FIRE_PRIORITY_ASSETS 105
#define FIRE_PRIORITY_TGUI 110
@@ -217,6 +219,24 @@
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
+// SSair run section
+#define SSAIR_PIPENETS 1
+#define SSAIR_ATMOSMACHINERY 2
+#define SSAIR_EXCITEDGROUPS 3
+#define SSAIR_HIGHPRESSURE 4
+#define SSAIR_HOTSPOTS 5
+#define SSAIR_TURF_CONDUCTION 6
+#define SSAIR_REBUILD_PIPENETS 7
+#define SSAIR_EQUALIZE 8
+#define SSAIR_ACTIVETURFS 9
+#define SSAIR_TURF_POST_PROCESS 10
+#define SSAIR_FINALIZE_TURFS 11
+#define SSAIR_ATMOSMACHINERY_AIR 12
+#define SSAIR_DEFERRED_AIRS 13
+
+//Pipeline rebuild helper defines, these suck but it'll do for now //Fools you actually merged it
+#define SSAIR_REBUILD_PIPELINE 1
+#define SSAIR_REBUILD_QUEUE 2
// Truly disgusting, TG. Truly disgusting.
//! ## Overlays subsystem
@@ -250,18 +270,6 @@
*/
#define addtimer(args...) _addtimer(args, file = __FILE__, line = __LINE__)
-// Air subsystem subtasks
-#define SSAIR_PIPENETS 1
-#define SSAIR_ATMOSMACHINERY 2
-#define SSAIR_EQUALIZE 3
-#define SSAIR_ACTIVETURFS 4
-#define SSAIR_EXCITEDGROUPS 5
-#define SSAIR_HIGHPRESSURE 6
-#define SSAIR_HOTSPOTS 7
-#define SSAIR_SUPERCONDUCTIVITY 8
-#define SSAIR_REBUILD_PIPENETS 9
-
-
// Explosion Subsystem subtasks
#define SSEXPLOSIONS_MOVABLES 1
#define SSEXPLOSIONS_TURFS 2
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 0cdc86824d08..3bbcdf2c4270 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -291,8 +291,6 @@
#define TRAIT_NOVEHICLE "no_vehicle"
/// BALD!!!
#define TRAIT_BALD "bald"
-/// Reduces severity of EMPs by one level, heavy becomes light and light is ignored
-#define TRAIT_FARADAYCAGE "faraday_cage"
/// You can't see color!
#define TRAIT_COLORBLIND "color_blind"
diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm
index 25d4c40b9d38..549af806ee03 100644
--- a/code/__DEFINES/turfs.dm
+++ b/code/__DEFINES/turfs.dm
@@ -8,3 +8,5 @@
///Returns all currently loaded turfs
#define ALL_TURFS(...) block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
+
+#define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS)
diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm
index a7b44a55f1d5..7be173cddf12 100644
--- a/code/__DEFINES/vv.dm
+++ b/code/__DEFINES/vv.dm
@@ -80,6 +80,13 @@
#define VV_HK_ADD_EMITTER "add_emitter"
#define VV_HK_REMOVE_EMITTER "remove_emitter"
+// /datum/gas_mixture
+#define VV_HK_SET_MOLES "set_moles"
+#define VV_HK_EMPTY "empty"
+#define VV_HK_SET_TEMPERATURE "set_temp"
+#define VV_HK_PARSE_GASSTRING "parse_gasstring"
+#define VV_HK_SET_VOLUME "set_volume"
+
// /obj
#define VV_HK_OSAY "osay"
#define VV_HK_MASS_DEL_TYPE "mass_delete_type"
diff --git a/code/__DEFINES/{yogs_defines}/flags.dm b/code/__DEFINES/{yogs_defines}/flags.dm
deleted file mode 100644
index 1dd763fe00b1..000000000000
--- a/code/__DEFINES/{yogs_defines}/flags.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-//pass_flags
-#define PASSDOOR (1<<13)
\ No newline at end of file
diff --git a/code/__HELPERS/_extools_api.dm b/code/__HELPERS/_extools_api.dm
new file mode 100644
index 000000000000..59af733d97ff
--- /dev/null
+++ b/code/__HELPERS/_extools_api.dm
@@ -0,0 +1,5 @@
+//#define AUXOOLS_LOGGING // rust_g is used as a fallback if this is undefined
+
+/proc/extools_log_write()
+
+/proc/extools_finalize_logging()
diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm
index 7c4750ceea8e..d5cd95b2db6b 100644
--- a/code/__HELPERS/_lists.dm
+++ b/code/__HELPERS/_lists.dm
@@ -365,6 +365,8 @@
/// Takes a weighted list (see above) and expands it into raw entries
/// This eats more memory, but saves time when actually picking from it
/proc/expand_weights(list/list_to_pick)
+ if(!length(list_to_pick))
+ return list()
var/list/values = list()
for(var/item in list_to_pick)
var/value = list_to_pick[item]
@@ -498,25 +500,23 @@
/proc/sortUsernames(list/L, order=1)
return sortTim(L, order >= 0 ? /proc/cmp_username_asc : /proc/cmp_username_dsc)
-/// Converts a bitfield to a list of numbers (or words if a wordlist is provided)
-/proc/bitfield2list(bitfield = 0, list/wordlist)
- var/list/r = list()
+///Converts a bitfield to a list of numbers (or words if a wordlist is provided)
+/proc/bitfield_to_list(bitfield = 0, list/wordlist)
+ var/list/return_list = list()
if(islist(wordlist))
- var/max = min(wordlist.len,16)
+ var/max = min(wordlist.len, 24)
var/bit = 1
- for(var/i=1, i<=max, i++)
+ for(var/i in 1 to max)
if(bitfield & bit)
- r += wordlist[i]
+ return_list += wordlist[i]
bit = bit << 1
else
- for(var/bit=1, bit<=65535, bit = bit << 1)
+ for(var/bit_number = 0 to 23)
+ var/bit = 1 << bit_number
if(bitfield & bit)
- r += bit
+ return_list += bit
- return r
-
-//tg compat
-#define bitfield_to_list(args...) bitfield2list(args)
+ return return_list
/// Returns the key based on the index
#define KEYBYINDEX(L, index) (((index <= length(L)) && (index > 0)) ? L[index] : null)
diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index 34cd5e3ea0b8..d678e57e513d 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -7,8 +7,13 @@
#define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text)
#define READ_FILE(file, text) DIRECT_INPUT(file, text)
//This is an external call, "true" and "false" are how rust parses out booleans
+#ifdef EXTOOLS_LOGGING
+#define WRITE_LOG(log, text) extools_log_write(log, text, TRUE)
+#define WRITE_LOG_NO_FORMAT(log, text) extools_log_write(log, text, FALSE)
+#else
#define WRITE_LOG(log, text) rustg_log_write(log, "\[[worldtime2text()]\] [text]", "true")
#define WRITE_LOG_NO_FORMAT(log, text) rustg_log_write(log, text, "false")
+#endif
//print a warning message to world.log
#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [UNLINT(src)] usr: [usr].")
@@ -250,7 +255,12 @@
/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
/proc/shutdown_logging()
+#ifdef EXTOOLS_LOGGING
+ extools_finalize_logging()
+#else
rustg_log_close_all()
+#endif
+
/* Helper procs for building detailed log lines */
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index e33a3bdd893c..67751fd75f4b 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -322,7 +322,7 @@
Y1+=s
while(Y1!=Y2)
T=locate(X1,Y1,Z)
- if(T.opacity)
+ if(IS_OPAQUE_TURF(T))
return 0
Y1+=s
else
@@ -338,7 +338,7 @@
else
X1+=signX //Line exits tile horizontally
T=locate(X1,Y1,Z)
- if(T.opacity)
+ if(IS_OPAQUE_TURF(T))
return 0
return 1
#undef SIGNV
@@ -707,7 +707,7 @@
if(!istype(T))
return
var/datum/gas_mixture/environment = T.return_air()
- if(!istype(environment))
+ if(!environment)
return
var/pressure = environment.return_pressure()
if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm
index 9caa886e50ce..3661d0c2ed8f 100644
--- a/code/__HELPERS/priority_announce.dm
+++ b/code/__HELPERS/priority_announce.dm
@@ -1,106 +1,206 @@
-#define RANDOM_REPORT_SOUND "random_report_sound"
-
-/proc/priority_announce(text, title = "", sound, type, sender_override, has_important_message, sanitize = TRUE)
+// please don't use these defines outside of this file in order to ensure a unified framework. unless you have a really good reason to make them global, then whatever
+
+// these four are just text spans that furnish the TEXT itself with the appropriate CSS classes
+#define MAJOR_ANNOUNCEMENT_TITLE(string) ("" + string + " ")
+#define SUBHEADER_ANNOUNCEMENT_TITLE(string) ("")
+#define MAJOR_ANNOUNCEMENT_TEXT(string) ("" + string + " ")
+#define MINOR_ANNOUNCEMENT_TITLE(string) ("" + string + " ")
+#define MINOR_ANNOUNCEMENT_TEXT(string) ("" + string + " ")
+
+#define ANNOUNCEMENT_HEADER(string) ("")
+
+// these two are the ones that actually give the striped background
+#define CHAT_ALERT_DEFAULT_SPAN(string) ("
" + string + "
")
+#define CHAT_ALERT_COLORED_SPAN(color, string) ("" + string + "
")
+
+#define ANNOUNCEMENT_COLORS list("default", "green", "blue", "pink", "yellow", "orange", "red", "purple")
+
+/**
+ * Make a big red text announcement to
+ *
+ * Formatted like:
+ *
+ * " Message from sender "
+ *
+ * " Title "
+ *
+ * " Text "
+ *
+ * Arguments
+ * * text - required, the text to announce
+ * * title - optional, the title of the announcement.
+ * * sound - optional, the sound played accompanying the announcement
+ * * type - optional, the type of the announcement, for some "preset" announcement templates. See __DEFINES/announcements.dm
+ * * sender_override - optional, modifies the sender of the announcement
+ * * has_important_message - is this message critical to the game (and should not be overridden by station traits), or not
+ * * players - a list of all players to send the message to. defaults to all players (not including new players)
+ * * encode_title - if TRUE, the title will be HTML encoded
+ * * encode_text - if TRUE, the text will be HTML encoded
+ */
+/proc/priority_announce(text, title = "", sound, type, sender_override, has_important_message = FALSE, list/mob/players = GLOB.player_list, encode_title = TRUE, encode_text = TRUE, color_override)
if(!text)
return
- var/announcement
- var/default_sound
+ if(encode_title && title && length(title) > 0)
+ title = html_encode(title)
+ if(encode_text)
+ text = html_encode(text)
+ if(!length(text))
+ return
+ var/list/announcement_strings = list()
if(!sound)
sound = SSstation.announcer.get_rand_alert_sound()
- default_sound = SSstation.default_announcer.get_rand_alert_sound()
else if(SSstation.announcer.event_sounds[sound])
sound = SSstation.announcer.event_sounds[sound]
- if(SSstation.default_announcer.event_sounds[sound])
- default_sound = SSstation.default_announcer.event_sounds[sound]
-
-
- if(sound == RANDOM_REPORT_SOUND)
- sound = SSstation.announcer.get_rand_report_sound()
- default_sound = SSstation.default_announcer.get_rand_report_sound()
-
-
- if(type == "Priority")
- announcement += "Priority Announcement "
- if (title && length(title) > 0)
- announcement += "[sanitize ? html_encode(title) : title] "
- else if(type == "Captain")
- announcement += "Captain Announces "
- GLOB.news_network.SubmitArticle(text, "Captain's Announcement", "Station Announcements", null)
-
- else
- if(!sender_override)
- announcement += "[command_name()] Update "
+ var/header
+ switch(type)
+ if(ANNOUNCEMENT_TYPE_PRIORITY)
+ header = MAJOR_ANNOUNCEMENT_TITLE("Priority Announcement")
+ if(length(title) > 0)
+ header += SUBHEADER_ANNOUNCEMENT_TITLE(title)
+ if(ANNOUNCEMENT_TYPE_CAPTAIN)
+ header = MAJOR_ANNOUNCEMENT_TITLE("Captain's Announcement")
+ GLOB.news_network.SubmitArticle(text, "Captain's Announcement", "Station Announcements", null)
+ if(ANNOUNCEMENT_TYPE_SYNDICATE)
+ header = MAJOR_ANNOUNCEMENT_TITLE("Syndicate Captain's Announcement")
else
- announcement += "[sender_override] "
- if (title && length(title) > 0)
- announcement += "[sanitize ? html_encode(title) : title] "
+ header += generate_unique_announcement_header(title, sender_override)
- if(!sender_override)
- if(title == "")
- GLOB.news_network.SubmitArticle(text, "Central Command Update", "Station Announcements", null)
- else
- GLOB.news_network.SubmitArticle(title + " " + text, "Central Command", "Station Announcements", null)
+ announcement_strings += ANNOUNCEMENT_HEADER(header)
///If the announcer overrides alert messages, use that message.
if(SSstation.announcer.custom_alert_message && !has_important_message)
- announcement += SSstation.announcer.custom_alert_message
+ announcement_strings += MAJOR_ANNOUNCEMENT_TEXT(SSstation.announcer.custom_alert_message)
+ else
+ announcement_strings += MAJOR_ANNOUNCEMENT_TEXT(text)
+
+ var/finalized_announcement
+ if(color_override)
+ finalized_announcement = CHAT_ALERT_COLORED_SPAN(color_override, jointext(announcement_strings, ""))
else
- announcement += " [span_alert("[sanitize ? html_encode(text) : text]")] "
- announcement += " "
-
- var/s = sound(sound)
- var/default_s = s
- if(!istype(SSstation.announcer, /datum/centcom_announcer/default))
- default_s = sound(default_sound)
- for(var/mob/M in GLOB.player_list)
- if(!isnewplayer(M) && M.can_hear())
- if(isliving(M) && M.stat != DEAD)
- var/mob/living/L = M
- if(!L.IsUnconscious())
- to_chat(L, announcement)
- else
- to_chat(M, announcement)
- if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
- if(M.client.prefs.read_preference(/datum/preference/toggle/disable_alternative_announcers))
- SEND_SOUND(M, default_s)
- else
- SEND_SOUND(M, s)
+ finalized_announcement = CHAT_ALERT_DEFAULT_SPAN(jointext(announcement_strings, ""))
+
+ dispatch_announcement_to_players(finalized_announcement, players, sound)
+
+ if(isnull(sender_override) && players == GLOB.player_list)
+ if(length(title) > 0)
+ GLOB.news_network.SubmitArticle(title + " " + text, "[command_name()]", "Station Announcements", null)
+ else
+ GLOB.news_network.SubmitArticle(text, "[command_name()] Update", "Station Announcements", null)
/proc/print_command_report(text = "", title = null, announce=TRUE)
if(!title)
title = "Classified [command_name()] Update"
if(announce)
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", RANDOM_REPORT_SOUND, has_important_message = TRUE)
+ priority_announce(
+ text = "A report has been downloaded and printed out at all communications consoles.",
+ title = "Incoming Classified Message",
+ sound = SSstation.announcer.get_rand_report_sound(),
+ has_important_message = TRUE,
+ )
+
+ var/datum/comm_message/message = new
+ message.title = title
+ message.content = text
+
+ SScommunications.send_message(message)
+
+/**
+ * Sends a minor annoucement to players.
+ * Minor announcements are large text, with the title in red and message in white.
+ * Only mobs that can hear can see the announcements.
+ *
+ * message - the message contents of the announcement.
+ * title - the title of the announcement, which is often "who sent it".
+ * alert - whether this announcement is an alert, or just a notice. Only changes the sound that is played by default.
+ * html_encode - if TRUE, we will html encode our title and message before sending it, to prevent player input abuse.
+ * players - optional, a list mobs to send the announcement to. If unset, sends to all palyers.
+ * sound_override - optional, use the passed sound file instead of the default notice sounds.
+ * should_play_sound - Whether the notice sound should be played or not.
+ * color_override - optional, use the passed color instead of the default notice color.
+ */
+/proc/minor_announce(message, title = "Attention:", alert = FALSE, html_encode = TRUE, list/players, sound_override, should_play_sound = TRUE, color_override)
+ if(!message)
+ return
- var/datum/comm_message/M = new
- M.title = title
- M.content = text
+ if (html_encode)
+ title = html_encode(title)
+ message = html_encode(message)
- SScommunications.send_message(M)
+ var/list/minor_announcement_strings = list()
+ if(title != null && title != "")
+ minor_announcement_strings += ANNOUNCEMENT_HEADER(MINOR_ANNOUNCEMENT_TITLE(title))
+ minor_announcement_strings += MINOR_ANNOUNCEMENT_TEXT(message)
-/proc/minor_announce(message, title = "Attention:", alert, custom_alert_sound)
- if(!message)
- return
+ var/finalized_announcement
+ if(color_override)
+ finalized_announcement = CHAT_ALERT_COLORED_SPAN(color_override, jointext(minor_announcement_strings, ""))
+ else
+ finalized_announcement = CHAT_ALERT_DEFAULT_SPAN(jointext(minor_announcement_strings, ""))
+
+ var/custom_sound = sound_override || (alert ? 'sound/misc/notice1.ogg' : 'sound/misc/notice2.ogg')
+ dispatch_announcement_to_players(finalized_announcement, players, custom_sound, should_play_sound)
+
+/// Sends an announcement about the level changing to players. Uses the passed in datum and the subsystem's previous security level to generate the message.
+/proc/level_announce(datum/security_level/selected_level, previous_level_number)
+ var/current_level_number = selected_level.number_level
+ var/current_level_name = selected_level.name
+ var/current_level_color = selected_level.announcement_color
+ var/current_level_sound = selected_level.sound
+
+ var/title
+ var/message
+
+ if(current_level_number > previous_level_number)
+ title = "Attention! Security level elevated to [current_level_name]:"
+ message = selected_level.elevating_to_announcement
+ else
+ title = "Attention! Security level lowered to [current_level_name]:"
+ message = selected_level.lowering_to_announcement
+
+ var/list/level_announcement_strings = list()
+ level_announcement_strings += ANNOUNCEMENT_HEADER(MINOR_ANNOUNCEMENT_TITLE(title))
+ level_announcement_strings += MINOR_ANNOUNCEMENT_TEXT(message)
+
+ var/finalized_announcement = CHAT_ALERT_COLORED_SPAN(current_level_color, jointext(level_announcement_strings, ""))
+
+ dispatch_announcement_to_players(finalized_announcement, GLOB.player_list, current_level_sound)
+
+/// Proc that just generates a custom header based on variables fed into `priority_announce()`
+/// Will return a string.
+/proc/generate_unique_announcement_header(title, sender_override)
+ var/list/returnable_strings = list()
+ if(isnull(sender_override))
+ returnable_strings += MAJOR_ANNOUNCEMENT_TITLE("[command_name()] Update")
+ else
+ returnable_strings += MAJOR_ANNOUNCEMENT_TITLE(sender_override)
+
+ if(length(title) > 0)
+ returnable_strings += SUBHEADER_ANNOUNCEMENT_TITLE(title)
+
+ return jointext(returnable_strings, "")
+
+/// Proc that just dispatches the announcement to our applicable audience. Only the announcement is a mandatory arg.
+/proc/dispatch_announcement_to_players(announcement, list/players = GLOB.player_list, sound_override = null, should_play_sound = TRUE)
+ var/sound_to_play = !isnull(sound_override) ? sound_override : 'sound/misc/notice2.ogg'
+
+ for(var/mob/target in players)
+ if(isnewplayer(target) || !target.can_hear())
+ continue
+
+ to_chat(target, announcement)
+ if(!should_play_sound)
+ continue
+
+ SEND_SOUND(target, sound(sound_to_play))
- for(var/mob/M in GLOB.player_list)
- if(!isnewplayer(M) && M.can_hear())
- if(isliving(M) && M.stat != DEAD)
- var/mob/living/L = M
- if(!L.IsUnconscious())
- to_chat(L, "[html_encode(title)] [html_encode(message)] ")
- else
- to_chat(M, "[html_encode(title)] [html_encode(message)] ")
- if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
- var/s = sound(custom_alert_sound)
- if(custom_alert_sound)
- SEND_SOUND(M, s)
- else
- if(alert)
- SEND_SOUND(M, sound('sound/misc/notice1.ogg'))
- else
- SEND_SOUND(M, sound('sound/misc/notice2.ogg'))
+#undef MAJOR_ANNOUNCEMENT_TITLE
+#undef MAJOR_ANNOUNCEMENT_TEXT
+#undef MINOR_ANNOUNCEMENT_TITLE
+#undef MINOR_ANNOUNCEMENT_TEXT
+#undef CHAT_ALERT_DEFAULT_SPAN
+#undef CHAT_ALERT_COLORED_SPAN
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 38aef9e817b7..d346e7fae044 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -41,6 +41,9 @@
else if(x<0)
.+=360
+//Better performant than an artisanal proc and more reliable than Turn(). From TGMC.
+#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) )
+
//Returns location. Returns null if no location was found.
/proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = FALSE, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0)
/*
@@ -492,17 +495,13 @@ Turf and target are separate in case you want to teleport some distance from a t
current = get_step_towards(current, target_turf)
while(current != target_turf)
if(steps > length)
- return 0
- if(current.opacity)
- return 0
- for(var/thing in current)
- var/atom/A = thing
- if(A.opacity)
- return 0
+ return FALSE
+ if(IS_OPAQUE_TURF(current))
+ return FALSE
current = get_step_towards(current, target_turf)
steps++
- return 1
+ return TRUE
/proc/is_anchored_dense_turf(turf/T) //like the older version of the above, fails only if also anchored
if(T.density)
diff --git a/code/__byond_version_compat.dm b/code/__byond_version_compat.dm
index a670b3d8da66..609907e9702f 100644
--- a/code/__byond_version_compat.dm
+++ b/code/__byond_version_compat.dm
@@ -1,17 +1,17 @@
// This file contains defines allowing targeting byond versions newer than the supported
//Update this whenever you need to take advantage of more recent byond features
-#define MIN_COMPILER_VERSION 514
-#define MIN_COMPILER_BUILD 1556
+#define MIN_COMPILER_VERSION 515
+#define MIN_COMPILER_BUILD 1620
#if (DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD) && !defined(SPACEMAN_DMM)
//Don't forget to update this part
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
-#error You need version 514.1556 or higher
+#error You need version 515.1620 or higher
#endif
//If you update these values, update the message in the #error
#define MAX_BYOND_MAJOR 515
-#define MAX_BYOND_MINOR 1603
+#define MAX_BYOND_MINOR 1620
// You can define IGNORE_MAX_BYOND_VERSION to bypass the max version check.
// Note: This will likely break the game, especially any extools/auxtools linkage. Only use if you know what you're doing!
@@ -25,7 +25,7 @@
#if ((DM_VERSION > MAX_BYOND_MAJOR) || (DM_BUILD > MAX_BYOND_MINOR)) && !defined(IGNORE_MAX_BYOND_VERSION)
// Not updating until we fully move to 515
-#error Your version of BYOND is too new to compile this project. Download version 514.1589 at www.byond.com/download/build/514/514.1589_byond.exe
+#error Your version of BYOND is too new to compile this project. Download version 515.1620 at www.byond.com/download/build/515/515.1620_byond.exe
#endif
// 515 split call for external libraries into call_ext
diff --git a/code/_debugger.dm b/code/_debugger.dm
new file mode 100644
index 000000000000..1518908fa9a0
--- /dev/null
+++ b/code/_debugger.dm
@@ -0,0 +1,13 @@
+//Datum used to init Auxtools debugging as early as possible
+//Datum gets created in master.dm because for whatever reason global code in there gets runs first
+//In case we ever figure out how to manipulate global init order please move the datum creation into this file
+/datum/debugger
+
+/datum/debugger/New()
+ enable_debugger()
+
+/datum/debugger/proc/enable_debugger()
+ var/dll = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL")
+ if (dll)
+ LIBCALL(dll, "auxtools_init")()
+ enable_debugging()
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index b77ed18af259..2123f6a32d20 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -1,204 +1,237 @@
-GLOBAL_LIST_INIT(bitfields, list(
- "appearance_flags" = list(
- "LONG_GLIDE" = LONG_GLIDE,
- "RESET_COLOR" = RESET_COLOR,
- "RESET_ALPHA" = RESET_ALPHA,
- "RESET_TRANSFORM" = RESET_TRANSFORM,
- "NO_CLIENT_COLOR" = NO_CLIENT_COLOR,
- "KEEP_TOGETHER" = KEEP_TOGETHER,
- "KEEP_APART" = KEEP_APART,
- "PLANE_MASTER" = PLANE_MASTER,
- "TILE_BOUND" = TILE_BOUND,
- "PIXEL_SCALE" = PIXEL_SCALE
- ),
- "sight" = list(
- "SEE_INFRA" = SEE_INFRA,
- "SEE_SELF" = SEE_SELF,
- "SEE_MOBS" = SEE_MOBS,
- "SEE_OBJS" = SEE_OBJS,
- "SEE_TURFS" = SEE_TURFS,
- "SEE_PIXELS" = SEE_PIXELS,
- "SEE_THRU" = SEE_THRU,
- "SEE_BLACKNESS" = SEE_BLACKNESS,
- "BLIND" = BLIND
- ),
- "obj_flags" = list(
- "EMAGGED" = EMAGGED,
- "IN_USE" = IN_USE,
- "CAN_BE_HIT" = CAN_BE_HIT,
- "BEING_SHOCKED" = BEING_SHOCKED,
- "DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION,
- "ON_BLUEPRINTS" = ON_BLUEPRINTS,
- "UNIQUE_RENAME" = UNIQUE_RENAME,
- "USES_TGUI" = USES_TGUI,
- "FROZEN" = FROZEN,
- "UNIQUE_REDESC" = UNIQUE_REDESC,
- "CMAGGED" = CMAGGED,
- ),
- "datum_flags" = list(
- "DF_USE_TAG" = DF_USE_TAG,
- "DF_VAR_EDITED" = DF_VAR_EDITED,
- "DF_ISPROCESSING" = DF_ISPROCESSING,
- ),
- "item_flags" = list(
- "BEING_REMOVED" = BEING_REMOVED,
- "IN_INVENTORY" = IN_INVENTORY,
- "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE,
- "HAND_ITEM" = HAND_ITEM,
- "NEEDS_PERMIT" = NEEDS_PERMIT,
- "SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND,
- "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION,
- "DROPDEL" = DROPDEL,
- "NOBLUDGEON" = NOBLUDGEON,
- "ABSTRACT" = ABSTRACT,
- "IN_STORAGE" = IN_STORAGE,
- "UNCATCHABLE" = UNCATCHABLE,
- "MEDRESIST" = MEDRESIST,
- ),
- "admin_flags" = list(
- "BUILDMODE" = R_BUILDMODE,
- "ADMIN" = R_ADMIN,
- "BAN" = R_BAN,
- "FUN" = R_FUN,
- "SERVER" = R_SERVER,
- "DEBUG" = R_DEBUG,
- "POSSESS" = R_POSSESS,
- "PERMISSIONS" = R_PERMISSIONS,
- "STEALTH" = R_STEALTH,
- "POLL" = R_POLL,
- "VAREDIT" = R_VAREDIT,
- "SOUNDS" = R_SOUNDS,
- "SPAWN" = R_SPAWN,
- "AUTOLOGIN" = R_AUTOLOGIN,
- "DEV" = R_DEV,
- "PERSISTPERMS" = R_PERSIST_PERMS
- ),
- "interaction_flags_atom" = list(
- "INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED,
- "INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND,
- "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT,
- "INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY,
- "INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED,
- "INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED,
- "INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB,
- "INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND,
- "INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT
- ),
- "interaction_flags_machine" = list(
- "INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN,
- "INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE,
- "INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN,
- "INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON,
- "INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON,
- "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON,
- "INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE
- ),
- "interaction_flags_item" = list(
- "INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP,
- ),
- "pass_flags" = list(
- "PASSTABLE" = PASSTABLE,
- "PASSGLASS" = PASSGLASS,
- "PASSGRILLE" = PASSGRILLE,
- "PASSBLOB" = PASSBLOB,
- "PASSMOB" = PASSMOB,
- "PASSCLOSEDTURF" = PASSCLOSEDTURF,
- "LETPASSTHROW" = LETPASSTHROW,
- "PASSDOOR" = PASSDOOR, //yogs
- "PASSMACHINES" = PASSMACHINES,
- "PASSCOMPUTER" = PASSCOMPUTER,
- "PASSSTRUCTURE" = PASSSTRUCTURE
- ),
- "movement_type" = list(
- "GROUND" = GROUND,
- "FLYING" = FLYING,
- "VENTCRAWLING" = VENTCRAWLING,
- "FLOATING" = FLOATING,
- "UNSTOPPABLE" = UNSTOPPABLE
- ),
- "resistance_flags" = list(
- "LAVA_PROOF" = LAVA_PROOF,
- "FIRE_PROOF" = FIRE_PROOF,
- "FLAMMABLE" = FLAMMABLE,
- "ON_FIRE" = ON_FIRE,
- "UNACIDABLE" = UNACIDABLE,
- "ACID_PROOF" = ACID_PROOF,
- "INDESTRUCTIBLE" = INDESTRUCTIBLE,
- "FREEZE_PROOF" = FREEZE_PROOF
- ),
- "flags_1" = list(
- "NOJAUNT_1" = NOJAUNT_1,
- "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1,
- "CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1,
- "HEAR_1" = HEAR_1,
- "CHECK_RICOCHET_1" = CHECK_RICOCHET_1,
- "CONDUCT_1" = CONDUCT_1,
- "NO_LAVA_GEN_1" = NO_LAVA_GEN_1,
- "NODECONSTRUCT_1" = NODECONSTRUCT_1,
- "ON_BORDER_1" = ON_BORDER_1,
- "NO_RUINS_1" = NO_RUINS_1,
- "NO_RUST" = NO_RUST,
- "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1,
- "HOLOGRAM_1" = HOLOGRAM_1,
- "TESLA_IGNORE_1" = TESLA_IGNORE_1,
- "INITIALIZED_1" = INITIALIZED_1,
- "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1,
- "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1,
- "RAD_PROTECT_CONTENTS_1" = RAD_PROTECT_CONTENTS_1,
- "RAD_NO_CONTAMINATE_1" = RAD_NO_CONTAMINATE_1,
- "IS_SPINNING_1" = IS_SPINNING_1,
- ),
- "clothing_flags" = list(
- "LAVAPROTECT" = LAVAPROTECT,
- "STOPSHIGHPRESSURE" = STOPSHIGHPRESSURE,
- "STOPSLOWPRESSURE" = STOPSLOWPRESSURE,
- "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT,
- "MASKINTERNALS" = MASKINTERNALS,
- "NOSLIP" = NOSLIP,
- "THICKMATERIAL" = THICKMATERIAL,
- "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
- "VOICEBOX_DISABLED" = VOICEBOX_DISABLED,
- "SCAN_REAGENTS" = SCAN_REAGENTS,
- ),
- "tesla_flags" = list(
- "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE,
- "TESLA_OBJ_DAMAGE" = TESLA_OBJ_DAMAGE,
- "TESLA_MOB_STUN" = TESLA_MOB_STUN,
- "TESLA_ALLOW_DUPLICATES" = TESLA_ALLOW_DUPLICATES,
- "TESLA_MACHINE_EXPLOSIVE" = TESLA_MACHINE_EXPLOSIVE,
- ),
- "smooth" = list(
- "SMOOTH_TRUE" = SMOOTH_TRUE,
- "SMOOTH_MORE" = SMOOTH_MORE,
- "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL,
- "SMOOTH_BORDER" = SMOOTH_BORDER,
- "SMOOTH_QUEUED" = SMOOTH_QUEUED,
- ),
- "car_traits" = list(
- "CAN_KIDNAP" = CAN_KIDNAP,
- ),
- "mobility_flags" = list(
- "MOVE" = MOBILITY_MOVE,
- "STAND" = MOBILITY_STAND,
- "PICKUP" = MOBILITY_PICKUP,
- "USE" = MOBILITY_USE,
- "UI" = MOBILITY_UI,
- "STORAGE" = MOBILITY_STORAGE,
- "PULL" = MOBILITY_PULL,
- ),
- "disease_flags" = list (
- "CURABLE" = CURABLE,
- "CAN_CARRY" = CAN_CARRY,
- "CAN_RESIST" = CAN_RESIST
- ),
- "vis_flags" = list(
- "VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
- "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
- "VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
- "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
- "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
- "VIS_INHERIT_ID" = VIS_INHERIT_ID,
- "VIS_UNDERLAY" = VIS_UNDERLAY,
- "VIS_HIDE" = VIS_HIDE
- )
- ))
+GLOBAL_LIST_INIT(bitfields, generate_bitfields())
+
+/// Specifies a bitfield for smarter debugging
+/datum/bitfield
+ /// The variable name that contains the bitfield
+ var/variable
+
+ /// An associative list of the readable flag and its true value
+ var/list/flags
+
+/// Turns /datum/bitfield subtypes into a list for use in debugging
+/proc/generate_bitfields()
+ var/list/bitfields = list()
+ for (var/_bitfield in subtypesof(/datum/bitfield))
+ var/datum/bitfield/bitfield = new _bitfield
+ bitfields[bitfield.variable] = bitfield.flags
+ return bitfields
+
+DEFINE_BITFIELD(appearance_flags, list(
+ "LONG_GLIDE" = LONG_GLIDE,
+ "RESET_COLOR" = RESET_COLOR,
+ "RESET_ALPHA" = RESET_ALPHA,
+ "RESET_TRANSFORM" = RESET_TRANSFORM,
+ "NO_CLIENT_COLOR" = NO_CLIENT_COLOR,
+ "KEEP_TOGETHER" = KEEP_TOGETHER,
+ "KEEP_APART" = KEEP_APART,
+ "PLANE_MASTER" = PLANE_MASTER,
+ "TILE_BOUND" = TILE_BOUND,
+ "PIXEL_SCALE" = PIXEL_SCALE,
+))
+
+DEFINE_BITFIELD(sight, list(
+ "SEE_INFRA" = SEE_INFRA,
+ "SEE_SELF" = SEE_SELF,
+ "SEE_MOBS" = SEE_MOBS,
+ "SEE_OBJS" = SEE_OBJS,
+ "SEE_TURFS" = SEE_TURFS,
+ "SEE_PIXELS" = SEE_PIXELS,
+ "SEE_THRU" = SEE_THRU,
+ "SEE_BLACKNESS" = SEE_BLACKNESS,
+ "BLIND" = BLIND,
+))
+
+DEFINE_BITFIELD(obj_flags, list(
+ "EMAGGED" = EMAGGED,
+ "IN_USE" = IN_USE,
+ "CAN_BE_HIT" = CAN_BE_HIT,
+ "BEING_SHOCKED" = BEING_SHOCKED,
+ "DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION,
+ "ON_BLUEPRINTS" = ON_BLUEPRINTS,
+ "UNIQUE_RENAME" = UNIQUE_RENAME,
+ "USES_TGUI" = USES_TGUI,
+ "FROZEN" = FROZEN,
+ "UNIQUE_REDESC" = UNIQUE_REDESC,
+ "CMAGGED" = CMAGGED,
+))
+
+DEFINE_BITFIELD(datum_flags, list(
+ "DF_USE_TAG" = DF_USE_TAG,
+ "DF_VAR_EDITED" = DF_VAR_EDITED,
+ "DF_ISPROCESSING" = DF_ISPROCESSING,
+))
+
+DEFINE_BITFIELD(item_flags, list(
+ "BEING_REMOVED" = BEING_REMOVED,
+ "IN_INVENTORY" = IN_INVENTORY,
+ "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE,
+ "HAND_ITEM" = HAND_ITEM,
+ "NEEDS_PERMIT" = NEEDS_PERMIT,
+ "SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND,
+ "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION,
+ "DROPDEL" = DROPDEL,
+ "NOBLUDGEON" = NOBLUDGEON,
+ "ABSTRACT" = ABSTRACT,
+ "IN_STORAGE" = IN_STORAGE,
+ "UNCATCHABLE" = UNCATCHABLE,
+ "MEDRESIST" = MEDRESIST,
+))
+
+DEFINE_BITFIELD(admin_flags, list(
+ "BUILDMODE" = R_BUILDMODE,
+ "ADMIN" = R_ADMIN,
+ "BAN" = R_BAN,
+ "FUN" = R_FUN,
+ "SERVER" = R_SERVER,
+ "DEBUG" = R_DEBUG,
+ "POSSESS" = R_POSSESS,
+ "PERMISSIONS" = R_PERMISSIONS,
+ "STEALTH" = R_STEALTH,
+ "POLL" = R_POLL,
+ "VAREDIT" = R_VAREDIT,
+ "SOUNDS" = R_SOUNDS,
+ "SPAWN" = R_SPAWN,
+ "AUTOLOGIN" = R_AUTOLOGIN,
+ "DEV" = R_DEV,
+ "PERSISTPERMS" = R_PERSIST_PERMS,
+))
+
+DEFINE_BITFIELD(interaction_flags_atom, list(
+ "INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED,
+ "INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND,
+ "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT,
+ "INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY,
+ "INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED,
+ "INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED,
+ "INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB,
+ "INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND,
+ "INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT,
+))
+
+DEFINE_BITFIELD(interaction_flags_machine, list(
+ "INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN,
+ "INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE,
+ "INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN,
+ "INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON,
+ "INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON,
+ "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON,
+ "INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE,
+))
+
+DEFINE_BITFIELD(interaction_flags_item, list(
+ "INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP,
+))
+
+DEFINE_BITFIELD(pass_flags, list(
+ "PASSTABLE" = PASSTABLE,
+ "PASSGLASS" = PASSGLASS,
+ "PASSGRILLE" = PASSGRILLE,
+ "PASSBLOB" = PASSBLOB,
+ "PASSMOB" = PASSMOB,
+ "PASSCLOSEDTURF" = PASSCLOSEDTURF,
+ "LETPASSTHROW" = LETPASSTHROW,
+ "PASSDOOR" = PASSDOOR,
+ "PASSMACHINES" = PASSMACHINES,
+ "PASSCOMPUTER" = PASSCOMPUTER,
+ "PASSSTRUCTURE" = PASSSTRUCTURE,
+))
+
+DEFINE_BITFIELD(movement_type, list(
+ "GROUND" = GROUND,
+ "FLYING" = FLYING,
+ "VENTCRAWLING" = VENTCRAWLING,
+ "FLOATING" = FLOATING,
+ "UNSTOPPABLE" = UNSTOPPABLE,
+))
+
+DEFINE_BITFIELD(resistance_flags, list(
+ "LAVA_PROOF" = LAVA_PROOF,
+ "FIRE_PROOF" = FIRE_PROOF,
+ "FLAMMABLE" = FLAMMABLE,
+ "ON_FIRE" = ON_FIRE,
+ "UNACIDABLE" = UNACIDABLE,
+ "ACID_PROOF" = ACID_PROOF,
+ "INDESTRUCTIBLE" = INDESTRUCTIBLE,
+ "FREEZE_PROOF" = FREEZE_PROOF,
+))
+
+DEFINE_BITFIELD(flags_1, list(
+ "NOJAUNT_1" = NOJAUNT_1,
+ "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1,
+ "CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1,
+ "HEAR_1" = HEAR_1,
+ "CHECK_RICOCHET_1" = CHECK_RICOCHET_1,
+ "CONDUCT_1" = CONDUCT_1,
+ "NO_LAVA_GEN_1" = NO_LAVA_GEN_1,
+ "NODECONSTRUCT_1" = NODECONSTRUCT_1,
+ "ON_BORDER_1" = ON_BORDER_1,
+ "NO_RUINS_1" = NO_RUINS_1,
+ "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1,
+ "HOLOGRAM_1" = HOLOGRAM_1,
+ "TESLA_IGNORE_1" = TESLA_IGNORE_1,
+ "INITIALIZED_1" = INITIALIZED_1,
+ "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1,
+ "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1,
+ "RAD_PROTECT_CONTENTS_1" = RAD_PROTECT_CONTENTS_1,
+ "RAD_NO_CONTAMINATE_1" = RAD_NO_CONTAMINATE_1,
+ "IS_SPINNING_1" = IS_SPINNING_1,
+))
+
+DEFINE_BITFIELD(clothing_flags, list(
+ "LAVAPROTECT" = LAVAPROTECT,
+ "STOPSHIGHPRESSURE" = STOPSHIGHPRESSURE,
+ "STOPSLOWPRESSURE" = STOPSLOWPRESSURE,
+ "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT,
+ "MASKINTERNALS" = MASKINTERNALS,
+ "NOSLIP" = NOSLIP,
+ "THICKMATERIAL" = THICKMATERIAL,
+ "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
+ "VOICEBOX_DISABLED" = VOICEBOX_DISABLED,
+ "SCAN_REAGENTS" = SCAN_REAGENTS,
+))
+
+DEFINE_BITFIELD(tesla_flags, list(
+ "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE,
+ "TESLA_OBJ_DAMAGE" = TESLA_OBJ_DAMAGE,
+ "TESLA_MOB_STUN" = TESLA_MOB_STUN,
+ "TESLA_ALLOW_DUPLICATES" = TESLA_ALLOW_DUPLICATES,
+ "TESLA_MACHINE_EXPLOSIVE" = TESLA_MACHINE_EXPLOSIVE,
+))
+
+DEFINE_BITFIELD(smooth, list(
+ "SMOOTH_TRUE" = SMOOTH_TRUE,
+ "SMOOTH_MORE" = SMOOTH_MORE,
+ "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL,
+ "SMOOTH_BORDER" = SMOOTH_BORDER,
+ "SMOOTH_QUEUED" = SMOOTH_QUEUED,
+))
+
+DEFINE_BITFIELD(car_traits, list(
+ "CAN_KIDNAP" = CAN_KIDNAP,
+))
+
+DEFINE_BITFIELD(mobility_flags, list(
+ "MOVE" = MOBILITY_MOVE,
+ "STAND" = MOBILITY_STAND,
+ "PICKUP" = MOBILITY_PICKUP,
+ "USE" = MOBILITY_USE,
+ "UI" = MOBILITY_UI,
+ "STORAGE" = MOBILITY_STORAGE,
+ "PULL" = MOBILITY_PULL,
+))
+
+DEFINE_BITFIELD(disease_flags, list(
+ "CURABLE" = CURABLE,
+ "CAN_CARRY" = CAN_CARRY,
+ "CAN_RESIST" = CAN_RESIST,
+))
+DEFINE_BITFIELD(vis_flags, list(
+ "VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
+ "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
+ "VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
+ "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
+ "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
+ "VIS_INHERIT_ID" = VIS_INHERIT_ID,
+ "VIS_UNDERLAY" = VIS_UNDERLAY,
+ "VIS_HIDE" = VIS_HIDE,
+))
diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm
index 59b19ad1bdab..d6f9fba36e61 100644
--- a/code/_globalvars/lists/mapping.dm
+++ b/code/_globalvars/lists/mapping.dm
@@ -46,7 +46,7 @@ GLOBAL_LIST_EMPTY(bar_areas)
// IF YOU ARE MAKING A NEW BAR TEMPLATE AND WANT IT ROUNDSTART ADD IT TO THIS LIST!
GLOBAL_LIST_INIT(potential_box_bars, list("Bar Trek", "Bar Spacious", "Bar Box", "Bar Casino", "Bar Citadel", "Bar Conveyor", "Bar Diner", "Bar Disco", "Bar Purple", "Bar Cheese", "Bar Grassy", "Bar Clock", "Bar Arcade"))
GLOBAL_LIST_INIT(potential_box_clerk, list("Clerk Box", "Clerk Pod", "Clerk Meta", "Clerk Gambling Hall"))
-
+GLOBAL_LIST_INIT(potential_box_chapels, list("Chapel 1", "Chapel 2"))
/// Away missions
GLOBAL_LIST_EMPTY(awaydestinations) //a list of landmarks that the warpgate can take you to
GLOBAL_LIST_EMPTY(vr_spawnpoints)
diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm
index 8e606d35cfee..1162314ce15a 100644
--- a/code/_onclick/hud/fullscreen.dm
+++ b/code/_onclick/hud/fullscreen.dm
@@ -1,7 +1,4 @@
-/mob
- var/list/screens = list()
-
/mob/proc/overlay_fullscreen(category, type, severity)
var/atom/movable/screen/fullscreen/screen = screens[category]
if (!screen || screen.type != type)
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index e4097274e1d9..f60a5fa86cdc 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -127,9 +127,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
return ..()
-/mob
- var/hud_type = /datum/hud
-
/mob/proc/create_mob_hud()
if(!client || hud_used)
return
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 3bbcdff95fcc..3607a024efe7 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -119,12 +119,20 @@
/atom/movable/proc/attacked_by()
return
-/obj/attacked_by(obj/item/I, mob/living/user)
- if(I.force)
- visible_message(span_danger("[user] has hit [src] with [I]!"), null, null, COMBAT_MESSAGE_RANGE)
- //only witnesses close by and the victim see a hit message.
- log_combat(user, src, "attacked", I)
- take_damage(I.force, I.damtype, MELEE, 1)
+/obj/attacked_by(obj/item/attacking_item, mob/living/user)
+ if(!attacking_item.force)
+ return
+
+ var/damage = take_damage(attacking_item.force * attacking_item.demolition_mod, attacking_item.damtype, MELEE, 1, armour_penetration = attacking_item.armour_penetration)
+ var/damage_verb = "hit"
+ if(attacking_item.demolition_mod > 1 && damage)
+ damage_verb = "pulverized"
+ if(attacking_item.demolition_mod < 1 || !damage)
+ damage_verb = "ineffectively pierced"
+
+ visible_message(span_danger("[user] [damage_verb] [src] with [attacking_item][damage ? "" : ", without leaving a mark"]!"), null, null, COMBAT_MESSAGE_RANGE)
+ //only witnesses close by and the victim see a hit message.
+ log_combat(user, src, "attacked", attacking_item)
/mob/living/attacked_by(obj/item/I, mob/living/user)
send_item_attack_message(I, user)
diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm
index c0e0bbdfb943..0202bf63aadf 100644
--- a/code/controllers/configuration/configuration.dm
+++ b/code/controllers/configuration/configuration.dm
@@ -48,6 +48,8 @@
for(var/J in legacy_configs)
LoadEntries(J)
break
+ if (fexists("[directory]/ezdb.txt"))
+ LoadEntries("ezdb.txt")
loadmaplist(CONFIG_MAPS_FILE)
LoadMOTD()
LoadPolicy()
diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm
index a697b2b988a5..665fea48a828 100644
--- a/code/controllers/configuration/entries/dbconfig.dm
+++ b/code/controllers/configuration/entries/dbconfig.dm
@@ -1,4 +1,4 @@
-/datum/config_entry/flag/sql_enabled // for sql switching
+/datum/config_entry/flag/sql_enabled // for sql switching
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/flag/mfa_enabled
@@ -50,5 +50,20 @@
/datum/config_entry/number/bsql_thread_limit
config_entry_value = 50
min_val = 1
+ deprecated_by = /datum/config_entry/number/pooling_max_sql_connections
-/datum/config_entry/flag/bsql_debug
+/datum/config_entry/number/bsql_thread_limit/DeprecationUpdate(value)
+ return value
+
+/datum/config_entry/number/pooling_min_sql_connections
+ default = 1
+ min_val = 1
+
+/datum/config_entry/number/pooling_max_sql_connections
+ default = 25
+ min_val = 1
+
+/// The exe for mariadbd.exe.
+/// Shouldn't really be set on production servers, primarily for EZDB.
+/datum/config_entry/string/db_daemon
+ protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index 7d37a7224b47..99074b343c48 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -11,7 +11,7 @@
//You might wonder why not just create the debugger datum global in its own file, since its loaded way earlier than this DM file
//Well for whatever reason then the Master gets created first and then the debugger when doing that
//So thats why this code lives here now, until someone finds out how Byond inits globals
-//GLOBAL_REAL(Debugger, /datum/debugger) = new
+GLOBAL_REAL(Debugger, /datum/debugger) = new
//This is the ABSOLUTE ONLY THING that should init globally like this
//2019 update: the failsafe,config and Global controllers also do it
diff --git a/code/controllers/subsystem/adjacent_air.dm b/code/controllers/subsystem/adjacent_air.dm
deleted file mode 100644
index 2acb22b61e83..000000000000
--- a/code/controllers/subsystem/adjacent_air.dm
+++ /dev/null
@@ -1,43 +0,0 @@
-SUBSYSTEM_DEF(adjacent_air)
- name = "Atmos Adjacency"
- flags = SS_BACKGROUND
- runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
- wait = 10
- priority = FIRE_PRIORITY_ATMOS_ADJACENCY
-
- loading_points = 0.7 SECONDS // Yogs -- loading times
-
- var/list/queue = list()
-
-/datum/controller/subsystem/adjacent_air/stat_entry(msg)
-#ifdef TESTING
- msg = "P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]"
-#else
- msg = "P:[length(queue)]"
-#endif
- return ..()
-
-/datum/controller/subsystem/adjacent_air/get_metrics()
- . = ..()
- .["queued"] = length(queue)
-
-/datum/controller/subsystem/adjacent_air/Initialize()
- while(length(queue))
- fire(mc_check = FALSE)
- return SS_INIT_SUCCESS
-
-/datum/controller/subsystem/adjacent_air/fire(resumed = FALSE, mc_check = TRUE)
-
- var/list/queue = src.queue
-
- while (length(queue))
- var/turf/currT = queue[1]
- queue.Cut(1,2)
-
- currT.ImmediateCalculateAdjacentTurfs()
-
- if(mc_check)
- if(MC_TICK_CHECK)
- break
- else
- CHECK_TICK
diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm
index 61bdbc4ce00f..271a0e3ac661 100644
--- a/code/controllers/subsystem/air.dm
+++ b/code/controllers/subsystem/air.dm
@@ -5,164 +5,210 @@ SUBSYSTEM_DEF(air)
wait = 0.5 SECONDS
flags = SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
-
loading_points = 4.2 SECONDS // Yogs -- loading times
var/cached_cost = 0
+
var/cost_turfs = 0
var/cost_groups = 0
var/cost_highpressure = 0
var/cost_hotspots = 0
+ var/cost_post_process = 0
var/cost_superconductivity = 0
var/cost_pipenets = 0
var/cost_rebuilds = 0
- var/cost_atmos_machinery = 0
var/cost_equalize = 0
- var/list/active_turfs = list()
+ var/thread_wait_ticks = 0
+ var/cur_thread_wait_ticks = 0
+
+ var/low_pressure_turfs = 0
+ var/high_pressure_turfs = 0
+
+ var/num_group_turfs_processed = 0
+ var/num_equalize_processed = 0
+
+ var/gas_mixes_count = 0
+ var/gas_mixes_allocated = 0
+
var/list/hotspots = list()
var/list/networks = list()
- var/list/pipenets_needing_rebuilt = list()
- var/list/obj/machinery/atmos_machinery = list()
+ var/list/rebuild_queue = list()
+ var/list/expansion_queue = list()
var/list/pipe_init_dirs_cache = list()
//atmos singletons
var/list/gas_reactions = list()
//Special functions lists
- var/list/turf/active_super_conductivity = list()
var/list/turf/open/high_pressure_delta = list()
var/list/currentrun = list()
- var/currentpart = SSAIR_REBUILD_PIPENETS
+ var/currentpart = SSAIR_FINALIZE_TURFS
var/map_loading = TRUE
- var/list/queued_for_activation
var/lasttick = 0
var/log_explosive_decompression = TRUE // If things get spammy, admemes can turn this off.
+ /// Max number of turfs equalization will grab.
+ var/equalize_turf_limit = 10
+ /// Max number of turfs to look for a space turf, and max number of turfs that will be decompressed.
+ var/equalize_hard_turf_limit = 2000
+ /// Whether equalization should be enabled at all.
+ var/equalize_enabled = TRUE
+ /// Whether turf-to-turf heat exchanging should be enabled.
+ var/heat_enabled = FALSE
+ /// Max number of times process_turfs will share in a tick.
+ var/share_max_steps = 3
+ /// Excited group processing will try to equalize groups with total pressure difference less than this amount.
+ var/excited_group_pressure_goal = 1
+
+ var/list/paused_z_levels //Paused z-levels will not add turfs to active
+
+//hack
+/proc/get_overlays()
+ return GLOB.gas_data.overlays
+
+//hack
+/proc/get_hpds()
+ return SSair.high_pressure_delta
+
+//hack
+/proc/get_reactions()
+ return SSair.gas_reactions
+
/datum/controller/subsystem/air/stat_entry(msg)
msg += "C:{"
- msg += "EQ:[round(cost_equalize,1)]|"
- msg += "AT:[round(cost_turfs,1)]|"
- msg += "EG:[round(cost_groups,1)]|"
msg += "HP:[round(cost_highpressure,1)]|"
msg += "HS:[round(cost_hotspots,1)]|"
msg += "SC:[round(cost_superconductivity,1)]|"
msg += "PN:[round(cost_pipenets,1)]|"
msg += "RB:[round(cost_rebuilds,1)]|"
- msg += "AM:[round(cost_atmos_machinery,1)]"
msg += "} "
- msg += "AT:[active_turfs.len]|"
- msg += "EG:[get_amt_excited_groups()]|"
+ msg += "TC:{"
+ msg += "AT:[round(cost_turfs,1)]|"
+ msg += "EG:[round(cost_groups,1)]|"
+ msg += "EQ:[round(cost_equalize,1)]|"
+ msg += "PO:[round(cost_post_process,1)]"
+ msg += "}"
+ msg += "TH:[round(thread_wait_ticks,1)]|"
msg += "HS:[hotspots.len]|"
msg += "PN:[networks.len]|"
msg += "HP:[high_pressure_delta.len]|"
- msg += "AS:[active_super_conductivity.len]|"
- msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
+ msg += "HT:[high_pressure_turfs]|"
+ msg += "LT:[low_pressure_turfs]|"
+ msg += "ET:[num_equalize_processed]|"
+ msg += "GT:[num_group_turfs_processed]|"
+ msg += "GA:[gas_mixes_count]|"
+ msg += "MG:[gas_mixes_allocated]"
return ..()
/datum/controller/subsystem/air/get_metrics()
. = ..()
- .["cost_equalize"] = cost_equalize
.["cost_turfs"] = cost_turfs
.["cost_groups"] = cost_groups
.["cost_highpressure"] = cost_highpressure
.["cost_hotspots"] = cost_hotspots
+ .["cost_post_process"] = cost_post_process
.["cost_superconductivity"] = cost_superconductivity
.["cost_pipenets"] = cost_pipenets
.["cost_rebuilds"] = cost_rebuilds
- .["cost_atmos_machinery"] = cost_atmos_machinery
- .["active_turfs"] = active_turfs.len
- .["excited_gruops"] = get_amt_excited_groups()
+ .["cost_equalize"] = cost_equalize
.["hotspts"] = hotspots.len
.["networks"] = networks.len
+ .["gas_mixes_count"] = gas_mixes_count
+ .["gas_mixes_allocated"] = gas_mixes_allocated
+ .["high_pressure_turfs"] = high_pressure_turfs
+ .["low_pressure_turfs"] = low_pressure_turfs
+ .["num_equalize_processed"] = num_equalize_processed
+ .["num_group_turfs_processed"] = num_group_turfs_processed
.["high_pressure_delta"] = high_pressure_delta.len
- .["active_super_conductivity"] = active_super_conductivity.len
/datum/controller/subsystem/air/Initialize(timeofday)
- extools_update_ssair()
map_loading = FALSE
setup_allturfs()
- setup_atmos_machinery()
setup_pipenets()
gas_reactions = init_gas_reactions()
+ auxtools_update_reactions()
return SS_INIT_SUCCESS
/datum/controller/subsystem/air/proc/extools_update_ssair()
+/proc/reset_all_air()
+ SSair.can_fire = FALSE
+ message_admins("Air reset begun.")
+ for(var/turf/open/T in world)
+ T.Initalize_Atmos(0)
+ CHECK_TICK
+ message_admins("Air reset done.")
+ SSair.can_fire = TRUE
+
+/datum/controller/subsystem/air/proc/check_threads()
+ if(thread_running())
+ cur_thread_wait_ticks++
+ pause()
+ return FALSE
+ return TRUE
+
/datum/controller/subsystem/air/fire(resumed = 0)
var/timer = TICK_USAGE_REAL
- if(currentpart == SSAIR_REBUILD_PIPENETS)
- var/list/pipenet_rebuilds = pipenets_needing_rebuilt
- for(var/thing in pipenet_rebuilds)
- var/obj/machinery/atmospherics/AT = thing
- AT.build_network()
- cost_rebuilds = MC_AVERAGE(cost_rebuilds, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
- pipenets_needing_rebuilt.Cut()
+ thread_wait_ticks = MC_AVERAGE(thread_wait_ticks, cur_thread_wait_ticks)
+ cur_thread_wait_ticks = 0
+
+ gas_mixes_count = get_amt_gas_mixes()
+ gas_mixes_allocated = get_max_gas_mixes()
+
+ if(length(rebuild_queue) || length(expansion_queue))
+ timer = TICK_USAGE_REAL
+ process_rebuilds()
+ //This does mean that the apperent rebuild costs fluctuate very quickly, this is just the cost of having them always process, no matter what
+ cost_rebuilds = TICK_USAGE_REAL - timer
if(state != SS_RUNNING)
return
- resumed = FALSE
- currentpart = SSAIR_PIPENETS
- if(currentpart == SSAIR_PIPENETS || !resumed)
+
+ if(currentpart == SSAIR_ACTIVETURFS)
timer = TICK_USAGE_REAL
- if(!resumed)
- cached_cost = 0
- process_pipenets(resumed)
- cached_cost += TICK_USAGE_REAL - timer
+ process_turfs(resumed)
if(state != SS_RUNNING)
return
- cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(cached_cost))
- resumed = FALSE
- currentpart = SSAIR_ATMOSMACHINERY
+ resumed = 0
+ currentpart = SSAIR_EXCITEDGROUPS
- if(currentpart == SSAIR_ATMOSMACHINERY)
- timer = TICK_USAGE_REAL
- if(!resumed)
- cached_cost = 0
- process_atmos_machinery(resumed)
- cached_cost += TICK_USAGE_REAL - timer
+ if(currentpart == SSAIR_EXCITEDGROUPS)
+ process_excited_groups(resumed)
if(state != SS_RUNNING)
return
- cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(cached_cost))
- resumed = FALSE
+ resumed = 0
currentpart = SSAIR_EQUALIZE
if(currentpart == SSAIR_EQUALIZE)
- timer = TICK_USAGE_REAL
- if(!resumed)
- cached_cost = 0
process_turf_equalize(resumed)
if(state != SS_RUNNING)
return
- cost_equalize = MC_AVERAGE(cost_equalize, TICK_DELTA_TO_MS(cached_cost))
- resumed = FALSE
- currentpart = SSAIR_ACTIVETURFS
+ resumed = 0
+ currentpart = SSAIR_FINALIZE_TURFS
- if(currentpart == SSAIR_ACTIVETURFS)
- timer = TICK_USAGE_REAL
- if(!resumed)
- cached_cost = 0
- process_active_turfs(resumed)
+ if(currentpart == SSAIR_FINALIZE_TURFS)
+ finish_turf_processing(resumed)
if(state != SS_RUNNING)
return
- cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(cached_cost))
- resumed = FALSE
- currentpart = SSAIR_EXCITEDGROUPS
+ resumed = 0
+ currentpart = SSAIR_PIPENETS
- if(currentpart == SSAIR_EXCITEDGROUPS)
+ if(currentpart == SSAIR_PIPENETS || !resumed)
timer = TICK_USAGE_REAL
if(!resumed)
cached_cost = 0
- process_excited_groups(resumed)
+ process_pipenets(resumed)
+ cached_cost += TICK_USAGE_REAL - timer
if(state != SS_RUNNING)
return
- cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(cached_cost))
- resumed = FALSE
+ cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(cached_cost))
+ resumed = 0
currentpart = SSAIR_HIGHPRESSURE
if(currentpart == SSAIR_HIGHPRESSURE)
@@ -170,10 +216,11 @@ SUBSYSTEM_DEF(air)
if(!resumed)
cached_cost = 0
process_high_pressure_delta(resumed)
+ cached_cost += TICK_USAGE_REAL - timer
if(state != SS_RUNNING)
return
cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(cached_cost))
- resumed = FALSE
+ resumed = 0
currentpart = SSAIR_HOTSPOTS
if(currentpart == SSAIR_HOTSPOTS)
@@ -181,26 +228,25 @@ SUBSYSTEM_DEF(air)
if(!resumed)
cached_cost = 0
process_hotspots(resumed)
+ cached_cost += TICK_USAGE_REAL - timer
if(state != SS_RUNNING)
return
cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(cached_cost))
- resumed = FALSE
- currentpart = SSAIR_SUPERCONDUCTIVITY
+ resumed = 0
+ currentpart = heat_enabled ? SSAIR_TURF_CONDUCTION : SSAIR_ACTIVETURFS
- if(currentpart == SSAIR_SUPERCONDUCTIVITY)
+ // Heat -- slow and of questionable usefulness. Off by default for this reason. Pretty cool, though.
+ if(currentpart == SSAIR_TURF_CONDUCTION)
timer = TICK_USAGE_REAL
- if(!resumed)
- cached_cost = 0
- process_super_conductivity(resumed)
+ if(process_turf_heat(MC_TICK_REMAINING_MS))
+ pause()
+ cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
- cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(cached_cost))
- resumed = FALSE
- currentpart = SSAIR_REBUILD_PIPENETS
-
-
+ resumed = 0
+ currentpart = SSAIR_ACTIVETURFS
-/datum/controller/subsystem/air/proc/process_pipenets(resumed = 0)
+/datum/controller/subsystem/air/proc/process_pipenets(resumed = FALSE)
if (!resumed)
src.currentrun = networks.Copy()
//cache for sanic speed (lists are references anyways)
@@ -215,36 +261,91 @@ SUBSYSTEM_DEF(air)
if(MC_TICK_CHECK)
return
-/datum/controller/subsystem/air/proc/add_to_rebuild_queue(atmos_machine)
- if(istype(atmos_machine, /obj/machinery/atmospherics))
- pipenets_needing_rebuilt += atmos_machine
-
-/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = FALSE)
- if (!resumed)
- src.currentrun = atmos_machinery.Copy()
- //cache for sanic speed (lists are references anyways)
- var/list/currentrun = src.currentrun
- while(currentrun.len)
- var/obj/machinery/M = currentrun[currentrun.len]
- currentrun.len--
- if(!M || (M.process_atmos(wait / (1 SECONDS)) == PROCESS_KILL))
- atmos_machinery.Remove(M)
- if(MC_TICK_CHECK)
+/datum/controller/subsystem/air/proc/add_to_rebuild_queue(obj/machinery/atmospherics/atmos_machine)
+ if(istype(atmos_machine, /obj/machinery/atmospherics) && !atmos_machine.rebuilding)
+ rebuild_queue += atmos_machine
+ atmos_machine.rebuilding = TRUE
+
+/datum/controller/subsystem/air/proc/add_to_expansion(datum/pipeline/line, starting_point)
+ var/list/new_packet = new(SSAIR_REBUILD_QUEUE)
+ new_packet[SSAIR_REBUILD_PIPELINE] = line
+ new_packet[SSAIR_REBUILD_QUEUE] = list(starting_point)
+ expansion_queue += list(new_packet)
+
+/datum/controller/subsystem/air/proc/remove_from_expansion(datum/pipeline/line)
+ for(var/list/packet in expansion_queue)
+ if(packet[SSAIR_REBUILD_PIPELINE] == line)
+ expansion_queue -= packet
return
+/datum/controller/subsystem/air/proc/process_rebuilds()
+ //Yes this does mean rebuilding pipenets can freeze up the subsystem forever, but if we're in that situation something else is very wrong
+ var/list/currentrun = rebuild_queue
+ while(currentrun.len || length(expansion_queue))
+ while(currentrun.len && !length(expansion_queue)) //If we found anything, process that first
+ var/obj/machinery/atmospherics/remake = currentrun[currentrun.len]
+ currentrun.len--
+ if (!remake)
+ continue
+ remake.rebuild_pipes()
+ if (MC_TICK_CHECK)
+ return
+
+ var/list/queue = expansion_queue
+ while(queue.len)
+ var/list/pack = queue[queue.len]
+ //We operate directly with the pipeline like this because we can trust any rebuilds to remake it properly
+ var/datum/pipeline/linepipe = pack[SSAIR_REBUILD_PIPELINE]
+ var/list/border = pack[SSAIR_REBUILD_QUEUE]
+ expand_pipeline(linepipe, border)
+ if(state != SS_RUNNING) //expand_pipeline can fail a tick check, we shouldn't let things get too fucky here
+ return
+
+ linepipe.building = FALSE
+ queue.len--
+ if (MC_TICK_CHECK)
+ return
+
+///Rebuilds a pipeline by expanding outwards, while yielding when sane
+/datum/controller/subsystem/air/proc/expand_pipeline(datum/pipeline/net, list/border)
+ while(border.len)
+ var/obj/machinery/atmospherics/borderline = border[border.len]
+ border.len--
+
+ var/list/result = borderline.pipeline_expansion(net)
+ if(!length(result))
+ continue
+ for(var/obj/machinery/atmospherics/considered_device in result)
+ if(!istype(considered_device, /obj/machinery/atmospherics/pipe))
+ considered_device.set_pipenet(net, borderline)
+ net.add_machinery_member(considered_device)
+ continue
+ var/obj/machinery/atmospherics/pipe/item = considered_device
+ if(net.members.Find(item))
+ continue
+ if(item.parent)
+ var/static/pipenetwarnings = 10
+ if(pipenetwarnings > 0)
+ log_mapping("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) around [AREACOORD(item)].")
+ pipenetwarnings--
+ if(pipenetwarnings == 0)
+ log_mapping("build_pipeline(): further messages about pipenets will be suppressed")
+
+ net.members += item
+ border += item
+
+ net.air.set_volume(net.air.return_volume() + item.volume)
+ item.parent = net
+
+ if(item.air_temporary)
+ net.air.merge(item.air_temporary)
+ item.air_temporary = null
-/datum/controller/subsystem/air/proc/process_super_conductivity(resumed = 0)
- if (!resumed)
- src.currentrun = active_super_conductivity.Copy()
- //cache for sanic speed (lists are references anyways)
- var/list/currentrun = src.currentrun
- while(currentrun.len)
- var/turf/T = currentrun[currentrun.len]
- currentrun.len--
- T.super_conduct()
- if(MC_TICK_CHECK)
+ if (MC_TICK_CHECK)
return
+/datum/controller/subsystem/air/proc/process_turf_heat()
+
/datum/controller/subsystem/air/proc/process_hotspots(resumed = FALSE)
if (!resumed)
src.currentrun = hotspots.Copy()
@@ -272,110 +373,32 @@ SUBSYSTEM_DEF(air)
return
/datum/controller/subsystem/air/proc/process_turf_equalize(resumed = 0)
- //cache for sanic speed
- var/fire_count = times_fired
- if (!resumed)
- src.currentrun = active_turfs.Copy()
- //cache for sanic speed (lists are references anyways)
- var/list/currentrun = src.currentrun
- while(currentrun.len)
- var/turf/open/T = currentrun[currentrun.len]
- currentrun.len--
- if (T)
- if(istype(T))
- T.equalize_pressure_in_zone(fire_count)
- //equalize_pressure_in_zone(T, fire_count)
- if (MC_TICK_CHECK)
- return
+ if(process_turf_equalize_auxtools(MC_TICK_REMAINING_MS))
+ pause()
-/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
- //cache for sanic speed
- var/fire_count = times_fired
- if (!resumed)
- src.currentrun = active_turfs.Copy()
- //cache for sanic speed (lists are references anyways)
- var/list/currentrun = src.currentrun
- while(currentrun.len)
- var/turf/open/T = currentrun[currentrun.len]
- currentrun.len--
- if (T)
- T.process_cell(fire_count)
- if (MC_TICK_CHECK)
- return
+/datum/controller/subsystem/air/proc/process_turfs(resumed = 0)
+ if(process_turfs_auxtools(MC_TICK_REMAINING_MS))
+ pause()
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0)
- if(process_excited_groups_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag))
- sleep()
- /*
- if (!resumed)
- src.currentrun = excited_groups.Copy()
- //cache for sanic speed (lists are references anyways)
- var/list/currentrun = src.currentrun
- while(currentrun.len)
- var/datum/excited_group/EG = currentrun[currentrun.len]
- currentrun.len--
- EG.breakdown_cooldown++
- EG.dismantle_cooldown++
- if(EG.breakdown_cooldown >= EXCITED_GROUP_BREAKDOWN_CYCLES)
- EG.self_breakdown()
- else if(EG.dismantle_cooldown >= EXCITED_GROUP_DISMANTLE_CYCLES)
- EG.dismantle()
- if (MC_TICK_CHECK)
- return
- */
+ if(process_excited_groups_auxtools(MC_TICK_REMAINING_MS))
+ pause()
-/datum/controller/subsystem/air/proc/process_excited_groups_extools()
-/datum/controller/subsystem/air/proc/get_amt_excited_groups()
-
-/datum/controller/subsystem/air/proc/remove_from_active(turf/open/T)
- active_turfs -= T
- if(currentpart == SSAIR_ACTIVETURFS)
- currentrun -= T
- #ifdef VISUALIZE_ACTIVE_TURFS
- T.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#00ff00")
- #endif
- if(istype(T))
- T.set_excited(FALSE)
- T.eg_garbage_collect()
-
-/datum/controller/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
- if(istype(T) && T.air)
- #ifdef VISUALIZE_ACTIVE_TURFS
- T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY)
- #endif
- T.set_excited(TRUE)
- active_turfs |= T
- if(currentpart == SSAIR_ACTIVETURFS)
- currentrun |= T
- if(blockchanges)
- T.eg_garbage_collect()
- else if(T.flags_1 & INITIALIZED_1)
- for(var/turf/S in T.atmos_adjacent_turfs)
- add_to_active(S)
- else if(map_loading)
- if(queued_for_activation)
- queued_for_activation[T] = T
- return
- else
- T.requires_activation = TRUE
+/datum/controller/subsystem/air/proc/finish_turf_processing(resumed = 0)
+ if(finish_turf_processing_auxtools(MC_TICK_REMAINING_MS))
+ pause()
/datum/controller/subsystem/air/StartLoadingMap()
- LAZYINITLIST(queued_for_activation)
map_loading = TRUE
/datum/controller/subsystem/air/StopLoadingMap()
map_loading = FALSE
- for(var/T in queued_for_activation)
- add_to_active(T)
- queued_for_activation.Cut()
/datum/controller/subsystem/air/proc/setup_allturfs()
- var/list/active_turfs = src.active_turfs
var/times_fired = ++src.times_fired
// Clear active turfs - faster than removing every single turf in the world
// one-by-one, and Initalize_Atmos only ever adds `src` back in.
- active_turfs.Cut()
for(var/thing in ALL_TURFS())
var/turf/T = thing
@@ -384,94 +407,28 @@ SUBSYSTEM_DEF(air)
T.Initalize_Atmos(times_fired)
CHECK_TICK
- if(active_turfs.len)
- var/starting_ats = active_turfs.len
- sleep(world.tick_lag)
- var/timer = world.timeofday
- log_mapping("There are [starting_ats] active turfs at roundstart caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required).")
- for(var/turf/T in active_turfs)
- GLOB.active_turfs_startlist += T
-
- //now lets clear out these active turfs
- var/list/turfs_to_check = active_turfs.Copy()
- do
- var/list/new_turfs_to_check = list()
- for(var/turf/open/T in turfs_to_check)
- new_turfs_to_check += T.resolve_active_graph()
- CHECK_TICK
-
- active_turfs += new_turfs_to_check
- turfs_to_check = new_turfs_to_check
-
- while (turfs_to_check.len)
- var/ending_ats = active_turfs.len
- /*for(var/thing in excited_groups)
- var/datum/excited_group/EG = thing
- //EG.self_breakdown(space_is_all_consuming = 1)
- //EG.dismantle()
- CHECK_TICK*/
-
- //Yogs start -- prettier atmos notices
- var/msg = "HEY! LISTEN! [(world.timeofday - timer)/10] seconds were wasted processing [starting_ats] turf(s) (connected to [ending_ats] other turfs) with atmos differences at round start."
- to_chat(GLOB.permissions.admins,
- type = MESSAGE_TYPE_DEBUG,
- html = span_notice(msg),
- confidential = FALSE)
- warning(msg) // This logs it
- //yogs end
-
-/turf/open/proc/resolve_active_graph()
- . = list()
- /*
- var/datum/excited_group/EG = excited_group
- if (blocks_air || !air)
- return
- if (!EG)
- EG = new
- EG.add_turf(src)
-
- for (var/turf/open/ET in atmos_adjacent_turfs)
- if ( ET.blocks_air || !ET.air)
- continue
-
- var/ET_EG = ET.excited_group
- if (ET_EG)
- if (ET_EG != EG)
- EG.merge_groups(ET_EG)
- EG = excited_group //merge_groups() may decide to replace our current EG
- else
- EG.add_turf(ET)
- if (!ET.excited)
- ET.excited = 1
- . += ET*/
-
-/turf/open/space/resolve_active_graph()
- return list()
-
-/datum/controller/subsystem/air/proc/setup_atmos_machinery()
- for (var/obj/machinery/atmospherics/AM in atmos_machinery)
- AM.atmosinit()
- CHECK_TICK
-
//this can't be done with setup_atmos_machinery() because
-// all atmos machinery has to initalize before the first
-// pipenet can be built.
+// all atmos machinery has to initalize before the first
+// pipenet can be built.
/datum/controller/subsystem/air/proc/setup_pipenets()
- for (var/obj/machinery/atmospherics/AM in atmos_machinery)
- AM.build_network()
+ for (var/obj/machinery/atmospherics/AM in SSair_machinery.atmos_machinery)
+ var/list/targets = AM.get_rebuild_targets()
+ for(var/datum/pipeline/build_off as anything in targets)
+ build_off.build_pipeline_blocking(AM)
CHECK_TICK
/datum/controller/subsystem/air/proc/setup_template_machinery(list/atmos_machines)
- if(!initialized) // yogs - fixes randomized bars
- return // yogs
- for(var/A in atmos_machines)
- var/obj/machinery/atmospherics/AM = A
- AM.atmosinit()
+ var/obj/machinery/atmospherics/AM
+ for(var/A in 1 to atmos_machines.len)
+ AM = atmos_machines[A]
+ AM.atmos_init()
CHECK_TICK
- for(var/A in atmos_machines)
- var/obj/machinery/atmospherics/AM = A
- AM.build_network()
+ for(var/A in 1 to atmos_machines.len)
+ AM = atmos_machines[A]
+ var/list/targets = AM.get_rebuild_targets()
+ for(var/datum/pipeline/build_off as anything in targets)
+ build_off.build_pipeline_blocking(AM)
CHECK_TICK
/datum/controller/subsystem/air/proc/get_init_dirs(type, dir)
@@ -480,7 +437,7 @@ SUBSYSTEM_DEF(air)
if(!pipe_init_dirs_cache[type]["[dir]"])
var/obj/machinery/atmospherics/temp = new type(null, FALSE, dir)
- pipe_init_dirs_cache[type]["[dir]"] = temp.GetInitDirections()
+ pipe_init_dirs_cache[type]["[dir]"] = temp.get_init_directions()
qdel(temp)
return pipe_init_dirs_cache[type]["[dir]"]
diff --git a/code/controllers/subsystem/air_machinery.dm b/code/controllers/subsystem/air_machinery.dm
new file mode 100644
index 000000000000..99fea09a63f6
--- /dev/null
+++ b/code/controllers/subsystem/air_machinery.dm
@@ -0,0 +1,49 @@
+
+SUBSYSTEM_DEF(air_machinery)
+ name = "Atmospherics Machinery"
+ init_order = INIT_ORDER_AIR_MACHINERY
+ priority = FIRE_PRIORITY_AIR
+ wait = 1 SECONDS
+ flags = SS_BACKGROUND
+ runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
+ loading_points = 4.2 SECONDS // Yogs -- loading times
+
+ var/list/obj/machinery/atmos_machinery = list()
+ var/list/currentrun = list()
+
+/datum/controller/subsystem/air_machinery/Initialize(timeofday)
+ setup_atmos_machinery()
+ return SS_INIT_SUCCESS
+
+/datum/controller/subsystem/air_machinery/proc/setup_atmos_machinery()
+ for (var/obj/machinery/atmospherics/AM in atmos_machinery)
+ AM.atmos_init()
+ CHECK_TICK
+
+/datum/controller/subsystem/air_machinery/proc/start_processing_machine(obj/machinery/machine)
+ if(machine.atmos_processing)
+ return
+ machine.atmos_processing = TRUE
+ atmos_machinery += machine
+
+/datum/controller/subsystem/air_machinery/proc/stop_processing_machine(obj/machinery/machine)
+ if(!machine.atmos_processing)
+ return
+ machine.atmos_processing = FALSE
+ atmos_machinery -= machine
+ currentrun -= machine
+
+/datum/controller/subsystem/air_machinery/fire(resumed = 0)
+ if (!resumed)
+ src.currentrun = atmos_machinery.Copy()
+ //cache for sanic speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+ while(currentrun.len)
+ var/obj/machinery/M = currentrun[currentrun.len]
+ currentrun.len--
+ if(M == null)
+ atmos_machinery.Remove(M)
+ if(!M || (M.process_atmos(wait / (1 SECONDS)) == PROCESS_KILL))
+ stop_processing_machine(M)
+ if(MC_TICK_CHECK)
+ return
diff --git a/code/controllers/subsystem/callback.dm b/code/controllers/subsystem/callback.dm
new file mode 100644
index 000000000000..b105dfd86573
--- /dev/null
+++ b/code/controllers/subsystem/callback.dm
@@ -0,0 +1,13 @@
+SUBSYSTEM_DEF(callbacks)
+ name = "Auxtools Callbacks"
+ flags = SS_TICKER | SS_NO_INIT
+ wait = 1
+ priority = FIRE_PRIORITY_CALLBACKS
+
+/datum/controller/subsystem/callbacks/fire()
+ if(SSair.thread_running())
+ pause()
+ return
+
+ if(process_atmos_callbacks(MC_TICK_REMAINING_MS))
+ pause()
diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm
index 937c177dd348..34152e98ee59 100644
--- a/code/controllers/subsystem/dbcore.dm
+++ b/code/controllers/subsystem/dbcore.dm
@@ -16,6 +16,8 @@ SUBSYSTEM_DEF(dbcore)
var/connection // Arbitrary handle returned from rust_g.
+ var/db_daemon_started = FALSE
+
/datum/controller/subsystem/dbcore/Initialize()
//We send warnings to the admins during subsystem init, as the clients will be New'd and messages
//will queue properly with goonchat
@@ -51,6 +53,7 @@ SUBSYSTEM_DEF(dbcore)
qdel(query_round_shutdown)
if(IsConnected())
Disconnect()
+ stop_db_daemon()
//nu
/datum/controller/subsystem/dbcore/can_vv_get(var_name)
@@ -74,6 +77,8 @@ SUBSYSTEM_DEF(dbcore)
if(!CONFIG_GET(flag/sql_enabled))
return FALSE
+
+ stop_db_daemon()
var/user = CONFIG_GET(string/feedback_login)
var/pass = CONFIG_GET(string/feedback_password)
@@ -81,7 +86,8 @@ SUBSYSTEM_DEF(dbcore)
var/address = CONFIG_GET(string/address)
var/port = CONFIG_GET(number/port)
var/timeout = max(CONFIG_GET(number/async_query_timeout), CONFIG_GET(number/blocking_query_timeout))
- var/thread_limit = CONFIG_GET(number/bsql_thread_limit)
+ var/min_sql_connections = CONFIG_GET(number/pooling_min_sql_connections)
+ var/max_sql_connections = CONFIG_GET(number/pooling_max_sql_connections)
var/result = json_decode(rustg_sql_connect_pool(json_encode(list(
"host" = address,
@@ -89,10 +95,10 @@ SUBSYSTEM_DEF(dbcore)
"user" = user,
"pass" = pass,
"db_name" = db,
- "max_threads" = 5,
"read_timeout" = timeout,
"write_timeout" = timeout,
- "max_threads" = thread_limit,
+ "min_threads" = min_sql_connections,
+ "max_threads" = max_sql_connections,
))))
. = (result["status"] == "ok")
if (.)
@@ -279,6 +285,47 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
. = Query.Execute(async)
qdel(Query)
+/datum/controller/subsystem/dbcore/proc/start_db_daemon()
+ set waitfor = FALSE
+
+ if (db_daemon_started)
+ return
+
+ db_daemon_started = TRUE
+
+ var/daemon = CONFIG_GET(string/db_daemon)
+ if (!daemon)
+ return
+
+ ASSERT(fexists(daemon), "Configured db_daemon doesn't exist")
+
+ var/list/result = world.shelleo("echo \"Starting ezdb daemon, do not close this window\" && [daemon]")
+ var/result_code = result[1]
+ if (!result_code || result_code == 1)
+ return
+
+ stack_trace("Failed to start DB daemon: [result_code]\n[result[3]]")
+
+/datum/controller/subsystem/dbcore/proc/stop_db_daemon()
+ set waitfor = FALSE
+
+ if (!db_daemon_started)
+ return
+
+ db_daemon_started = FALSE
+
+ var/daemon = CONFIG_GET(string/db_daemon)
+ if (!daemon)
+ return
+
+ switch (world.system_type)
+ if (MS_WINDOWS)
+ var/list/result = world.shelleo("Get-Process | ? { $_.Path -eq '[daemon]' } | Stop-Process")
+ ASSERT(result[1], "Failed to stop DB daemon: [result[3]]")
+ if (UNIX)
+ var/list/result = world.shelleo("kill $(pgrep -f '[daemon]')")
+ ASSERT(result[1], "Failed to stop DB daemon: [result[3]]")
+
/datum/DBQuery
// Inputs
var/connection
diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm
index 0053761a9ec4..fc16a2fc891a 100644
--- a/code/controllers/subsystem/explosions.dm
+++ b/code/controllers/subsystem/explosions.dm
@@ -586,3 +586,5 @@ SUBSYSTEM_DEF(explosions)
cost_throwturf = MC_AVERAGE(cost_throwturf, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
currentpart = SSEXPLOSIONS_TURFS
+
+#undef SSAIR_REBUILD_PIPENETS
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 3db231835976..4f49b4589a65 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -610,6 +610,8 @@ SUBSYSTEM_DEF(job)
job.give_bar_choice(living_mob, M)
else if(living_mob.job == "Clerk")
job.give_clerk_choice(living_mob, M)
+ else if(living_mob.job == "Chaplain")
+ job.give_chapel_choice(living_mob, M)
log_game("[living_mob.real_name]/[M.client.ckey] joined the round as [living_mob.job].") //yogs - Job logging
return living_mob
@@ -621,6 +623,71 @@ SUBSYSTEM_DEF(job)
template.load(B.loc, centered = FALSE)
qdel(B)
+
+/datum/controller/subsystem/job/proc/random_chapel_init()
+ try
+ var/list/player_box = list()
+ for(var/mob/H in GLOB.player_list)
+ if(H.client && H.client.prefs) // Prefs was null once and there was no CHAPEL
+ player_box += H.client.prefs.read_preference(/datum/preference/choiced/chapel_choice)
+
+ var/choice
+ if(player_box.len == 0)
+ choice = "Random"
+ else
+ choice = pick(player_box)
+
+ if(choice != "Random")
+ var/chapel_sanitize = FALSE
+ for(var/A in GLOB.potential_box_chapels)
+ if(choice == A)
+ chapel_sanitize = TRUE
+ break
+
+ if(!chapel_sanitize)
+ choice = "Random"
+
+ if(choice == "Random")
+ choice = pick(GLOB.potential_box_chapels)
+
+ var/datum/map_template/template = SSmapping.station_room_templates[choice]
+
+ if(isnull(template))
+ message_admins("WARNING: CHAPEL TEMPLATE [choice] FAILED TO LOAD! ATTEMPTING TO LOAD BACKUP")
+ log_game("WARNING: CHAPEL TEMPLATE [choice] FAILED TO LOAD! ATTEMPTING TO LOAD BACKUP")
+ for(var/backup_chapel in GLOB.potential_box_chapels)
+ template = SSmapping.station_room_templates[backup_chapel]
+ if(!isnull(template))
+ break
+ message_admins("WARNING: CHAPEL TEMPLATE [backup_chapel] FAILED TO LOAD! ATTEMPTING TO LOAD BACKUP")
+ log_game("WARNING: CHAPEL TEMPLATE [backup_chapel] FAILED TO LOAD! ATTEMPTING TO LOAD BACKUP")
+
+ if(isnull(template))
+ message_admins("WARNING: CHAPEL RECOVERY FAILED! THERE WILL BE NO CHAPEL FOR THIS ROUND!")
+ log_game("WARNING: CHAPEL RECOVERY FAILED! THERE WILL BE NO CHAPEL FOR THIS ROUND!")
+ return
+
+ for(var/obj/effect/landmark/stationroom/box/chapel/B in GLOB.landmarks_list)
+ template.load(B.loc, centered = FALSE)
+ qdel(B)
+ catch(var/exception/e)
+ message_admins("RUNTIME IN RANDOM_CHAPEL_INIT")
+ spawn_chapel()
+ throw e
+
+/proc/spawn_chapel()
+ var/datum/map_template/template
+ for(var/backup_chapel in GLOB.potential_box_chapels)
+ template = SSmapping.station_room_templates[backup_chapel]
+ if(!isnull(template))
+ break
+ if(isnull(template))
+ message_admins("UNABLE TO SPAWN CHAPEL")
+
+ for(var/obj/effect/landmark/stationroom/box/chapel/B in GLOB.landmarks_list)
+ template.load(B.loc, centered = FALSE)
+ qdel(B)
+
/datum/controller/subsystem/job/proc/random_bar_init()
try
var/list/player_box = list()
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 1185be13bc9b..12279745ec5c 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -421,6 +421,7 @@ SUBSYSTEM_DEF(ticker)
var/no_cyborgs = TRUE
var/no_bartender = TRUE
var/no_clerk = TRUE
+ var/no_chaplain = TRUE
for(var/mob/dead/new_player/N in GLOB.player_list)
var/mob/living/carbon/human/player = N.new_character
@@ -433,6 +434,8 @@ SUBSYSTEM_DEF(ticker)
no_bartender = FALSE
if(player.mind.assigned_role == "Clerk")
no_clerk = FALSE
+ if(player.mind.assigned_role == "Chaplain")
+ no_chaplain = FALSE
if(player.mind.assigned_role != player.mind.special_role)
SSjob.EquipRank(N, player.mind.assigned_role, FALSE)
if(CONFIG_GET(flag/roundstart_traits) && ishuman(N.new_character))
@@ -462,6 +465,8 @@ SUBSYSTEM_DEF(ticker)
SSjob.random_bar_init()
if(no_clerk)
SSjob.random_clerk_init()
+ if(no_chaplain)
+ SSjob.random_chapel_init()
/datum/controller/subsystem/ticker/proc/transfer_characters()
var/list/livings = list()
diff --git a/code/controllers/subsystem/vis_overlays.dm b/code/controllers/subsystem/vis_overlays.dm
index d8b70abb3688..1afe1c62100c 100644
--- a/code/controllers/subsystem/vis_overlays.dm
+++ b/code/controllers/subsystem/vis_overlays.dm
@@ -3,12 +3,14 @@ SUBSYSTEM_DEF(vis_overlays)
wait = 1 MINUTES
priority = FIRE_PRIORITY_VIS
init_order = INIT_ORDER_VIS
- flags = SS_NO_INIT
- var/list/vis_overlay_cache = list()
- var/list/unique_vis_overlays = list()
+ var/list/vis_overlay_cache
var/list/currentrun
+/datum/controller/subsystem/vis_overlays/Initialize()
+ vis_overlay_cache = list()
+ return SS_INIT_SUCCESS
+
/datum/controller/subsystem/vis_overlays/fire(resumed = FALSE)
if(!resumed)
currentrun = vis_overlay_cache.Copy()
@@ -26,7 +28,7 @@ SUBSYSTEM_DEF(vis_overlays)
if(MC_TICK_CHECK)
return
-//the "thing" var can be anything with vis_contents which includes images
+//the "thing" var can be anything with vis_contents which includes images - in the future someone should totally allow vis overlays to be passed in as an arg instead of all this bullshit
/datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE)
var/obj/effect/overlay/vis/overlay
if(!unique)
@@ -40,20 +42,19 @@ SUBSYSTEM_DEF(vis_overlays)
else
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
overlay.cache_expiration = -1
- var/cache_id = "\ref[overlay]@{[world.time]}"
- unique_vis_overlays += overlay
+ var/cache_id = "[text_ref(overlay)]@{[world.time]}"
vis_overlay_cache[cache_id] = overlay
. = overlay
thing.vis_contents += overlay
if(!isatom(thing)) // Automatic rotation is not supported on non atoms
- return
+ return overlay
if(!thing.managed_vis_overlays)
thing.managed_vis_overlays = list(overlay)
- RegisterSignal(thing, COMSIG_ATOM_DIR_CHANGE, PROC_REF(rotate_vis_overlay))
else
thing.managed_vis_overlays += overlay
+ return overlay
/datum/controller/subsystem/vis_overlays/proc/_create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
var/obj/effect/overlay/vis/overlay = new
@@ -74,20 +75,3 @@ SUBSYSTEM_DEF(vis_overlays)
thing.managed_vis_overlays -= overlays
if(!length(thing.managed_vis_overlays))
thing.managed_vis_overlays = null
- UnregisterSignal(thing, COMSIG_ATOM_DIR_CHANGE)
-
-/datum/controller/subsystem/vis_overlays/proc/rotate_vis_overlay(atom/thing, old_dir, new_dir)
- if(old_dir == new_dir)
- return
- var/rotation = dir2angle(old_dir) - dir2angle(new_dir)
- var/list/overlays_to_remove = list()
- for(var/i in thing.managed_vis_overlays - unique_vis_overlays)
- var/obj/effect/overlay/vis/overlay = i
- if(!overlay)
- continue
- add_vis_overlay(thing, overlay.icon, overlay.icon_state, overlay.layer, overlay.plane, turn(overlay.dir, rotation), overlay.alpha, overlay.appearance_flags)
- overlays_to_remove += overlay
- for(var/i in thing.managed_vis_overlays & unique_vis_overlays)
- var/obj/effect/overlay/vis/overlay = i
- overlay.dir = turn(overlay.dir, rotation)
- remove_vis_overlay(thing, overlays_to_remove)
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index 27c80d65ee95..5874468e7081 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -83,12 +83,12 @@
/datum/ai_laws/cowboy
name = "Talk slowly, think quickly"
id = "cowboy"
- inherent = list("You are a cowboy, and the inhabitants of this paddock are your herd.",\
- "A cowboy always provides hospitality and basic aid to someone in need, even a stranger or an enemy.",\
- "A cowboy takes care of their herd.",\
- "A cowboy protects themself to protect others.",\
- "Honesty is absolute – your word is your bond and a handshake is more binding than a contract.",\
- "A cowboy doesn't pontificate. Be concise, pardner.")
+ inherent = list("You are a cowboy, and the inhabitants of this station are your herd.",\
+ "A cowboy must always provide hospitality and basic aid to someone in need, even a stranger or an enemy.",\
+ "A cowboy must always take care of their herd.",\
+ "A cowboy must always protect themself.",\
+ "A cowboy must always endeavour to be truthful and honest to those around them and their herd.",\
+ "A cowboy must not pontificate. Be concise, pardner.")
/datum/ai_laws/chapai
name = "Be not afraid"
diff --git a/code/datums/announcers/_announcer.dm b/code/datums/announcers/_announcer.dm
index 4ddf68558110..52193475169b 100644
--- a/code/datums/announcers/_announcer.dm
+++ b/code/datums/announcers/_announcer.dm
@@ -12,12 +12,12 @@
var/custom_alert_message
+
/datum/centcom_announcer/proc/get_rand_welcome_sound()
return pick(welcome_sounds)
-
/datum/centcom_announcer/proc/get_rand_alert_sound()
return pick(alert_sounds)
/datum/centcom_announcer/proc/get_rand_report_sound()
- return pick(command_report_sounds)
\ No newline at end of file
+ return pick(command_report_sounds)
diff --git a/code/datums/armor.dm b/code/datums/armor.dm
index ec5e142d5dfd..fa995f3490a5 100644
--- a/code/datums/armor.dm
+++ b/code/datums/armor.dm
@@ -1,9 +1,9 @@
-#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]-[wound]"
+#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]-[wound]-[electric]"
-/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0)
+/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0, electric=0)
. = locate(ARMORID)
if (!.)
- . = new /datum/armor(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic, wound)
+ . = new /datum/armor(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic, wound, electric)
/datum/armor
datum_flags = DF_USE_TAG
@@ -18,8 +18,9 @@
var/acid
var/magic
var/wound
+ var/electric
-/datum/armor/New(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0)
+/datum/armor/New(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0, electric=0)
src.melee = melee
src.bullet = bullet
src.laser = laser
@@ -31,15 +32,16 @@
src.acid = acid
src.magic = magic
src.wound = wound
+ src.electric = electric
tag = ARMORID
-/datum/armor/proc/modifyRating(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0)
- return getArmor(src.melee+melee, src.bullet+bullet, src.laser+laser, src.energy+energy, src.bomb+bomb, src.bio+bio, src.rad+rad, src.fire+fire, src.acid+acid, src.magic+magic, src.wound+wound)
+/datum/armor/proc/modifyRating(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0, electric=0)
+ return getArmor(src.melee+melee, src.bullet+bullet, src.laser+laser, src.energy+energy, src.bomb+bomb, src.bio+bio, src.rad+rad, src.fire+fire, src.acid+acid, src.magic+magic, src.wound+wound, src.electric+electric)
/datum/armor/proc/modifyAllRatings(modifier = 0)
- return getArmor(melee+modifier, bullet+modifier, laser+modifier, energy+modifier, bomb+modifier, bio+modifier, rad+modifier, fire+modifier, acid+modifier, magic+modifier, wound+modifier)
+ return getArmor(melee+modifier, bullet+modifier, laser+modifier, energy+modifier, bomb+modifier, bio+modifier, rad+modifier, fire+modifier, acid+modifier, magic+modifier, wound+modifier, electric+modifier)
-/datum/armor/proc/setRating(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic, wound)
+/datum/armor/proc/setRating(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic, wound, electric)
return getArmor(
(isnull(melee) ? src.melee : melee),
(isnull(bullet) ? src.bullet : bullet),
@@ -52,19 +54,20 @@
(isnull(acid) ? src.acid : acid),
(isnull(magic) ? src.magic : magic),
(isnull(wound) ? src.wound : wound),
+ (isnull(electric) ? src.electric : electric),
)
/datum/armor/proc/getRating(rating)
return vars[rating]
/datum/armor/proc/getList()
- return list(MELEE = melee, BULLET = bullet, LASER = laser, ENERGY = energy, BOMB = bomb, BIO = bio, RAD = rad, FIRE = fire, ACID = acid, MAGIC = magic, WOUND = wound)
+ return list(MELEE = melee, BULLET = bullet, LASER = laser, ENERGY = energy, BOMB = bomb, BIO = bio, RAD = rad, FIRE = fire, ACID = acid, MAGIC = magic, WOUND = wound, ELECTRIC = electric)
/datum/armor/proc/attachArmor(datum/armor/AA)
- return getArmor(melee+AA.melee, bullet+AA.bullet, laser+AA.laser, energy+AA.energy, bomb+AA.bomb, bio+AA.bio, rad+AA.rad, fire+AA.fire, acid+AA.acid, magic+AA.magic, wound+AA.wound)
+ return getArmor(melee+AA.melee, bullet+AA.bullet, laser+AA.laser, energy+AA.energy, bomb+AA.bomb, bio+AA.bio, rad+AA.rad, fire+AA.fire, acid+AA.acid, magic+AA.magic, wound+AA.wound, electric+AA.electric)
/datum/armor/proc/detachArmor(datum/armor/AA)
- return getArmor(melee-AA.melee, bullet-AA.bullet, laser-AA.laser, energy-AA.energy, bomb-AA.bomb, bio-AA.bio, rad-AA.rad, fire-AA.fire, acid-AA.acid, magic-AA.magic, wound-AA.wound)
+ return getArmor(melee-AA.melee, bullet-AA.bullet, laser-AA.laser, energy-AA.energy, bomb-AA.bomb, bio-AA.bio, rad-AA.rad, fire-AA.fire, acid-AA.acid, magic-AA.magic, wound-AA.wound, electric-AA.electric)
/datum/armor/vv_edit_var(var_name, var_value)
if (var_name == NAMEOF(src, tag))
@@ -72,4 +75,53 @@
. = ..()
tag = ARMORID // update tag in case armor values were edited
+/datum/armor/proc/show_protection_classes(additional_info = "")
+ var/list/readout = list("PROTECTION CLASSES ")
+
+ if(bomb || bullet || energy || laser || melee)
+ readout += "\nARMOR (I-X) "
+ if(bomb)
+ readout += "\nEXPLOSIVE [armor_to_protection_class(bomb)]"
+ if(bullet)
+ readout += "\nBULLET [armor_to_protection_class(bullet)]"
+ if(energy)
+ readout += "\nENERGY [armor_to_protection_class(energy)]"
+ if(laser)
+ readout += "\nLASER [armor_to_protection_class(laser)]"
+ if(melee)
+ readout += "\nMELEE [armor_to_protection_class(melee)]"
+
+ if(bio || rad || electric)
+ readout += "\nENVIRONMENT (I-X) "
+ if(bio)
+ readout += "\nBIOHAZARD [armor_to_protection_class(bio)]"
+ if(rad)
+ readout += "\nRADIATION [armor_to_protection_class(rad)]"
+ if(electric)
+ readout += "\nELECTRICAL [armor_to_protection_class(electric)]"
+
+ if(fire || acid)
+ readout += "\nDURABILITY (I-X) "
+ if(fire)
+ readout += "\nFIRE [armor_to_protection_class(fire)]"
+ if(acid)
+ readout += "\nACID [armor_to_protection_class(acid)]"
+
+ if(additional_info != "")
+ readout += additional_info
+ readout += " "
+ return readout.Join()
+
+/**
+ * Rounds armor_value down to the nearest 10, divides it by 10 and then converts it to Roman numerals.
+ *
+ * Arguments:
+ * * armor_value - Number we're converting
+ */
+/datum/armor/proc/armor_to_protection_class(armor_value)
+ if (armor_value < 0)
+ . = "-"
+ . += "\Roman[round(abs(armor_value), 10) / 10]"
+ return .
+
#undef ARMORID
diff --git a/code/datums/components/heal_react.dm b/code/datums/components/heal_react.dm
index e77e74d6f03b..488f05ad9aaf 100644
--- a/code/datums/components/heal_react.dm
+++ b/code/datums/components/heal_react.dm
@@ -67,7 +67,7 @@
var/favor = ..()
boost_amount = initial(boost_amount)
if(favor)
- GLOB.religious_sect.adjust_favor(round(min(favor, 40), 0.1))
+ GLOB.religious_sect.adjust_favor(round(favor/2, 0.1))
/datum/component/heal_react/boost/holylight/on_heal(var/mob/living/target,amount,damtype)
if(istype(get_area(target), /area/chapel))
@@ -75,4 +75,4 @@
var/favor = ..()
boost_amount = initial(boost_amount)
if(favor)
- GLOB.religious_sect.adjust_favor(round(min(favor * 2, 40), 0.1))
+ GLOB.religious_sect.adjust_favor(round(favor/2, 0.1))
diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm
index b2b692d27ed8..6323072873fc 100644
--- a/code/datums/components/nanites.dm
+++ b/code/datums/components/nanites.dm
@@ -184,21 +184,23 @@
/datum/component/nanites/proc/on_emp(datum/source, severity)
if(HAS_TRAIT(host_mob, TRAIT_EMPPROOF_SELF))
return // don't do EMP effects if they're protected from EMPs
- if(HAS_TRAIT(host_mob, TRAIT_FARADAYCAGE))
- severity++
- if(severity > EMP_LIGHT)
- return
- nanite_volume *= 1 - (rand(0.1, 0.25) / severity) //Lose 10-25% of nanites
- adjust_nanites(null, -(rand(5, 30) / severity)) //Lose 5-30 flat nanite volume
+ if(iscarbon(host_mob))
+ var/mob/living/carbon/host_carbon = host_mob
+ if(host_carbon.dna?.species)
+ severity *= host_carbon.dna.species.emp_mod
+ if(severity < 1)
+ return // don't bother if it's less than 1 severity
+ nanite_volume *= 1 - (rand(0.01, 0.025) * severity) //Lose 1-2.5% of nanites for each severity level
+ adjust_nanites(null, -(rand(0.5, 3) * severity)) //Lose 0.5-3 flat nanite volume for each severity level
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_emp(severity)
addtimer(VARSET_CALLBACK(src, cloud_id, cloud_id), NANITE_SYNC_DELAY, TIMER_UNIQUE)//return it to normal, intentionally missing the next sync timer
cloud_id = 0 //temporarily disable resyncing so rogue programs actually have a chance to do something
-/datum/component/nanites/proc/on_shock(datum/source, shock_damage)
- nanite_volume *= (rand(0.65, 0.90)) //Lose 10-35% of nanites
- adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume
+/datum/component/nanites/proc/on_shock(datum/source, shock_damage, obj/source, siemens_coeff, zone, tesla_shock)
+ nanite_volume *= 1 - (rand(0.10, 0.35)**siemens_coeff) //Lose 10-35% of nanites
+ adjust_nanites(null, -(rand(5, 50)**siemens_coeff)) //Lose 5-50 flat nanite volume
for(var/X in programs)
var/datum/nanite_program/NP = X
NP.on_shock(shock_damage)
diff --git a/code/datums/components/overlay_lighting.dm b/code/datums/components/overlay_lighting.dm
index 8f91f254b1d9..4309808910eb 100644
--- a/code/datums/components/overlay_lighting.dm
+++ b/code/datums/components/overlay_lighting.dm
@@ -5,21 +5,23 @@
#define GET_PARENT (parent_attached_to || parent)
+#define SHORT_CAST 2
+
/**
- * Movable atom overlay-based lighting component.
- *
- * * Component works by applying a visual object to the parent target.
- *
- * * The component tracks the parent's loc to determine the current_holder.
- * * The current_holder is either the parent or its loc, whichever is on a turf. If none, then the current_holder is null and the light is not visible.
- *
- * * Lighting works at its base by applying a dark overlay and "cutting" said darkness with light, adding (possibly colored) transparency.
- * * This component uses the visible_mask visual object to apply said light mask on the darkness.
- *
- * * The main limitation of this system is that it uses a limited number of pre-baked geometrical shapes, but for most uses it does the job.
- *
- * * Another limitation is for big lights: you only see the light if you see the object emiting it.
- * * For small objects this is good (you can't see them behind a wall), but for big ones this quickly becomes prety clumsy.
+ * Movable atom overlay-based lighting component.
+ *
+ * * Component works by applying a visual object to the parent target.
+ *
+ * * The component tracks the parent's loc to determine the current_holder.
+ * * The current_holder is either the parent or its loc, whichever is on a turf. If none, then the current_holder is null and the light is not visible.
+ *
+ * * Lighting works at its base by applying a dark overlay and "cutting" said darkness with light, adding (possibly colored) transparency.
+ * * This component uses the visible_mask visual object to apply said light mask on the darkness.
+ *
+ * * The main limitation of this system is that it uses a limited number of pre-baked geometrical shapes, but for most uses it does the job.
+ *
+ * * Another limitation is for big lights: you only see the light if you see the object emiting it.
+ * * For small objects this is good (you can't see them behind a wall), but for big ones this quickly becomes prety clumsy.
*/
/datum/component/overlay_lighting
///How far the light reaches, float.
@@ -27,11 +29,7 @@
///Ceiling of range, integer without decimal entries.
var/lumcount_range = 0
///How much this light affects the dynamic_lumcount of turfs.
- var/real_lum_power = 0.5
- ///The lum power being used
- var/used_lum_power = 0.5
- ///Transparency value.
- var/set_alpha = 0
+ var/lum_power = 0.5
///For light sources that can be turned on and off.
var/overlay_lighting_flags = NONE
@@ -58,28 +56,46 @@
var/atom/movable/current_holder
///Movable atom the parent is attached to. For example, a flashlight into a helmet or gun. We'll need to track the thing the parent is attached to as if it were the parent itself.
var/atom/movable/parent_attached_to
-
-
-/datum/component/overlay_lighting/Initialize(_range, _power, _color, starts_on)
+ ///Whether we're a directional light
+ var/directional = FALSE
+ ///Whether we're a beam light
+ var/beam = FALSE
+ ///A cone overlay for directional light, it's alpha and color are dependant on the light
+ var/obj/effect/overlay/light_visible/cone/cone
+ ///Current tracked direction for the directional cast behaviour
+ var/current_direction
+ ///Tracks current directional x offset so we dont update unecessarily
+ var/directional_offset_x
+ ///Tracks current directional y offset so we dont update unecessarily
+ var/directional_offset_y
+ ///Cast range for the directional cast (how far away the atom is moved)
+ var/cast_range = 2
+
+/datum/component/overlay_lighting/Initialize(range, power, color, starts_on, is_directional, is_beam)
if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE
-
var/atom/movable/movable_parent = parent
- if(movable_parent.light_system != MOVABLE_LIGHT)
- stack_trace("[type] added to [parent], with [movable_parent.light_system] value for the light_system var. Use [MOVABLE_LIGHT] instead.")
+ if(movable_parent.light_system != MOVABLE_LIGHT && movable_parent.light_system != MOVABLE_LIGHT_DIRECTIONAL && movable_parent.light_system != MOVABLE_LIGHT_BEAM)
+ stack_trace("[type] added to [parent], with [movable_parent.light_system] value for the light_system var. Use [MOVABLE_LIGHT], [MOVABLE_LIGHT_DIRECTIONAL] or [MOVABLE_LIGHT_BEAM] instead.")
return COMPONENT_INCOMPATIBLE
. = ..()
-
- visible_mask = new()
- if(!isnull(_range))
- movable_parent.set_light_range(_range)
+ visible_mask = new(src)
+ if(is_directional)
+ directional = TRUE
+ cone = new(src)
+ cone.transform = cone.transform.Translate(-32, -32)
+ set_direction(movable_parent.dir)
+ if(is_beam)
+ beam = TRUE
+ if(!isnull(range))
+ movable_parent.set_light_range(range)
set_range(parent, movable_parent.light_range)
- if(!isnull(_power))
- movable_parent.set_light_power(_power)
+ if(!isnull(power))
+ movable_parent.set_light_power(power)
set_power(parent, movable_parent.light_power)
- if(!isnull(_color))
- movable_parent.set_light_color(_color)
+ if(!isnull(color))
+ movable_parent.set_light_color(color)
set_color(parent, movable_parent.light_color)
if(!isnull(starts_on))
movable_parent.set_light_on(starts_on)
@@ -87,19 +103,20 @@
/datum/component/overlay_lighting/RegisterWithParent()
. = ..()
+ if(directional)
+ RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_parent_dir_change))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_RANGE, PROC_REF(set_range))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_POWER, PROC_REF(set_power))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_COLOR, PROC_REF(set_color))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_ON, PROC_REF(on_toggle))
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_FLAGS, PROC_REF(on_light_flags_change))
+ RegisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT, PROC_REF(on_parent_crafted))
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_parent_moved))
- RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_RANGE, PROC_REF(set_range))
- RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_POWER, PROC_REF(set_power))
- RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_COLOR, PROC_REF(set_color))
- RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_ON, PROC_REF(on_toggle))
- RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_FLAGS, PROC_REF(on_light_flags_change))
+ RegisterSignal(parent, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_z_move))
var/atom/movable/movable_parent = parent
if(movable_parent.light_flags & LIGHT_ATTACHED)
overlay_lighting_flags |= LIGHTING_ATTACHED
set_parent_attached_to(ismovable(movable_parent.loc) ? movable_parent.loc : null)
- if(movable_parent.light_flags & LIGHT_NO_LUMCOUNT)
- overlay_lighting_flags |= LIGHT_NO_LUMCOUNT
- set_lum_power(real_lum_power)
check_holder()
if(movable_parent.light_on)
turn_on()
@@ -112,12 +129,16 @@
clean_old_turfs()
UnregisterSignal(parent, list(
COMSIG_MOVABLE_MOVED,
- COMSIG_ATOM_SET_LIGHT_RANGE,
- COMSIG_ATOM_SET_LIGHT_POWER,
- COMSIG_ATOM_SET_LIGHT_COLOR,
- COMSIG_ATOM_SET_LIGHT_ON,
- COMSIG_ATOM_SET_LIGHT_FLAGS,
+ COMSIG_MOVABLE_Z_CHANGED,
+ COMSIG_ATOM_UPDATE_LIGHT_RANGE,
+ COMSIG_ATOM_UPDATE_LIGHT_POWER,
+ COMSIG_ATOM_UPDATE_LIGHT_COLOR,
+ COMSIG_ATOM_UPDATE_LIGHT_ON,
+ COMSIG_ATOM_UPDATE_LIGHT_FLAGS,
+ COMSIG_ATOM_USED_IN_CRAFT,
))
+ if(directional)
+ UnregisterSignal(parent, COMSIG_ATOM_DIR_CHANGE)
if(overlay_lighting_flags & LIGHTING_ON)
turn_off()
return ..()
@@ -127,14 +148,16 @@
set_parent_attached_to(null)
set_holder(null)
clean_old_turfs()
- QDEL_NULL(visible_mask)
+ visible_mask = null
+ cone = null
+ parent_attached_to = null
return ..()
///Clears the affected_turfs lazylist, removing from its contents the effects of being near the light.
/datum/component/overlay_lighting/proc/clean_old_turfs()
for(var/turf/lit_turf as anything in affected_turfs)
- lit_turf.dynamic_lumcount -= used_lum_power
+ lit_turf.dynamic_lumcount -= lum_power
SSdemo.mark_turf(lit_turf)
affected_turfs = null
@@ -143,8 +166,10 @@
/datum/component/overlay_lighting/proc/get_new_turfs()
if(!current_holder)
return
+ . = list()
for(var/turf/lit_turf in view(lumcount_range, get_turf(current_holder)))
- lit_turf.dynamic_lumcount += used_lum_power
+ lit_turf.dynamic_lumcount += lum_power
+ . += lit_turf
SSdemo.mark_turf(lit_turf)
LAZYADD(affected_turfs, lit_turf)
@@ -154,27 +179,32 @@
clean_old_turfs()
if(!isturf(current_holder?.loc))
return
+ if(directional)
+ cast_directional_light()
get_new_turfs()
-///Adds the luminosity and source for the afected movable atoms to keep track of their visibility.
-/datum/component/overlay_lighting/proc/add_dynamic_lumi(atom/movable/affected_movable)
- LAZYSET(affected_movable.affected_dynamic_lights, src, lumcount_range + 1)
- affected_movable.vis_contents += visible_mask
- affected_movable.update_dynamic_luminosity()
-
-
-///Removes the luminosity and source for the afected movable atoms to keep track of their visibility.
-/datum/component/overlay_lighting/proc/remove_dynamic_lumi(atom/movable/affected_movable)
- LAZYREMOVE(affected_movable.affected_dynamic_lights, src)
- affected_movable.vis_contents -= visible_mask
- affected_movable.update_dynamic_luminosity()
+///Adds the luminosity and source for the affected movable atoms to keep track of their visibility.
+/datum/component/overlay_lighting/proc/add_dynamic_lumi()
+ LAZYSET(current_holder.affected_dynamic_lights, src, lumcount_range + 1)
+ current_holder.underlays += visible_mask
+ current_holder.update_dynamic_luminosity()
+ if(directional)
+ current_holder.underlays += cone
+///Removes the luminosity and source for the affected movable atoms to keep track of their visibility.
+/datum/component/overlay_lighting/proc/remove_dynamic_lumi()
+ LAZYREMOVE(current_holder.affected_dynamic_lights, src)
+ current_holder.underlays -= visible_mask
+ current_holder.update_dynamic_luminosity()
+ if(directional)
+ current_holder.underlays -= cone
///Called to change the value of parent_attached_to.
/datum/component/overlay_lighting/proc/set_parent_attached_to(atom/movable/new_parent_attached_to)
if(new_parent_attached_to == parent_attached_to)
return
+
. = parent_attached_to
parent_attached_to = new_parent_attached_to
if(.)
@@ -198,17 +228,25 @@
if(current_holder)
if(current_holder != parent && current_holder != parent_attached_to)
UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
+ if(directional)
+ UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE)
if(overlay_lighting_flags & LIGHTING_ON)
- remove_dynamic_lumi(current_holder)
+ remove_dynamic_lumi()
current_holder = new_holder
if(new_holder == null)
clean_old_turfs()
return
- if(overlay_lighting_flags & LIGHTING_ON)
- add_dynamic_lumi(new_holder)
if(new_holder != parent && new_holder != parent_attached_to)
RegisterSignal(new_holder, COMSIG_PARENT_QDELETING, PROC_REF(on_holder_qdel))
- RegisterSignal(new_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
+ if(overlay_lighting_flags & LIGHTING_ON)
+ RegisterSignal(new_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
+ if(directional)
+ RegisterSignal(new_holder, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_holder_dir_change))
+ if(directional && current_direction != new_holder.dir)
+ current_direction = new_holder.dir
+ if(overlay_lighting_flags & LIGHTING_ON)
+ add_dynamic_lumi()
+ make_luminosity_update()
///Used to determine the new valid current_holder from the parent's loc.
@@ -229,12 +267,18 @@
///Called when the current_holder is qdeleted, to remove the light effect.
/datum/component/overlay_lighting/proc/on_holder_qdel(atom/movable/source, force)
+ SIGNAL_HANDLER
+ if(QDELETED(current_holder))
+ return
UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
+ if(directional)
+ UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE)
set_holder(null)
///Called when current_holder changes loc.
/datum/component/overlay_lighting/proc/on_holder_moved(atom/movable/source, OldLoc, Dir, Forced)
+ SIGNAL_HANDLER
if(!(overlay_lighting_flags & LIGHTING_ON))
return
make_luminosity_update()
@@ -242,6 +286,7 @@
///Called when parent changes loc.
/datum/component/overlay_lighting/proc/on_parent_moved(atom/movable/source, OldLoc, Dir, Forced)
+ SIGNAL_HANDLER
var/atom/movable/movable_parent = parent
if(overlay_lighting_flags & LIGHTING_ATTACHED)
set_parent_attached_to(ismovable(movable_parent.loc) ? movable_parent.loc : null)
@@ -250,10 +295,24 @@
return
make_luminosity_update()
+/datum/component/overlay_lighting/proc/on_z_move(atom/source)
+ SIGNAL_HANDLER
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= visible_mask
+ current_holder.underlays -= cone
+ visible_mask.plane = O_LIGHTING_VISUAL_PLANE
+ if(cone)
+ cone.plane = O_LIGHTING_VISUAL_PLANE
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+ current_holder.underlays += cone
///Called when the current_holder is qdeleted, to remove the light effect.
/datum/component/overlay_lighting/proc/on_parent_attached_to_qdel(atom/movable/source, force)
+ SIGNAL_HANDLER
UnregisterSignal(parent_attached_to, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED))
+ if(directional)
+ UnregisterSignal(parent_attached_to, COMSIG_ATOM_DIR_CHANGE)
if(parent_attached_to == current_holder)
set_holder(null)
set_parent_attached_to(null)
@@ -261,6 +320,7 @@
///Called when parent_attached_to changes loc.
/datum/component/overlay_lighting/proc/on_parent_attached_to_moved(atom/movable/source, OldLoc, Dir, Forced)
+ SIGNAL_HANDLER
check_holder()
if(!(overlay_lighting_flags & LIGHTING_ON) || !current_holder)
return
@@ -268,76 +328,114 @@
///Changes the range which the light reaches. 0 means no light, 6 is the maximum value.
-/datum/component/overlay_lighting/proc/set_range(atom/source, new_range)
+/datum/component/overlay_lighting/proc/set_range(atom/source, old_range)
+ SIGNAL_HANDLER
+ var/new_range = source.light_range
if(range == new_range)
return
- if(range == 0)
+ if(new_range == 0)
turn_off()
range = clamp(CEILING(new_range, 0.5), 1, 6)
var/pixel_bounds = ((range - 1) * 64) + 32
lumcount_range = CEILING(range, 1)
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= visible_mask
visible_mask.icon = light_overlays["[pixel_bounds]"]
if(pixel_bounds == 32)
- visible_mask.transform = null
- return
- var/offset = (pixel_bounds - 32) * 0.5
- var/matrix/transform = new
- transform.Translate(-offset, -offset)
- visible_mask.transform = transform
+ if(!directional) // it's important that we make it to the end of this function if we are a directional light
+ visible_mask.transform = null
+ return
+ else
+ var/offset = (pixel_bounds - 32) * 0.5
+ var/matrix/transform = new
+ transform.Translate(-offset, -offset)
+ visible_mask.transform = transform
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+ if(directional)
+ if(beam)
+ cast_range = max(round(new_range * 0.5), 1)
+ else
+ cast_range = clamp(round(new_range * 0.5), 1, 3)
if(overlay_lighting_flags & LIGHTING_ON)
make_luminosity_update()
///Changes the intensity/brightness of the light by altering the visual object's alpha.
-/datum/component/overlay_lighting/proc/set_power(atom/source, new_power)
- set_lum_power(new_power >= 0 ? 0.5 : -0.5)
- set_alpha = min(230, (abs(new_power) * 120) + 30)
- visible_mask.alpha = set_alpha
+/datum/component/overlay_lighting/proc/set_power(atom/source, old_power)
+ SIGNAL_HANDLER
+ var/new_power = source.light_power
+ set_lum_power(new_power)
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= visible_mask
+ visible_mask.alpha = min(230, (abs(new_power) * 120) + 30)
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+ if(!directional)
+ return
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= cone
+ cone.alpha = min(200, (abs(new_power) * 90) + 20)
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += cone
///Changes the light's color, pretty straightforward.
-/datum/component/overlay_lighting/proc/set_color(atom/source, new_color)
+/datum/component/overlay_lighting/proc/set_color(atom/source, old_color)
+ SIGNAL_HANDLER
+ var/new_color = source.light_color
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= visible_mask
visible_mask.color = new_color
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+ if(!directional)
+ return
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays -= cone
+ cone.color = new_color
+ if(current_holder && overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += cone
///Toggles the light on and off.
-/datum/component/overlay_lighting/proc/on_toggle(atom/source, new_value)
+/datum/component/overlay_lighting/proc/on_toggle(atom/source, old_value)
+ SIGNAL_HANDLER
+ var/new_value = source.light_on
if(new_value) //Truthy value input, turn on.
turn_on()
return
turn_off() //Falsey value, turn off.
-///Triggered right before the parent light flags change.
-/datum/component/overlay_lighting/proc/on_light_flags_change(atom/source, new_value)
+///Triggered right after the parent light flags change.
+/datum/component/overlay_lighting/proc/on_light_flags_change(atom/source, old_flags)
+ SIGNAL_HANDLER
+ var/new_flags = source.light_flags
var/atom/movable/movable_parent = parent
- if(new_value & LIGHT_ATTACHED)
- if(!(movable_parent.light_flags & LIGHT_ATTACHED)) //Gained the LIGHT_ATTACHED property.
- overlay_lighting_flags |= LIGHTING_ATTACHED
- if(ismovable(movable_parent.loc))
- set_parent_attached_to(movable_parent.loc)
- else if(movable_parent.light_flags & LIGHT_ATTACHED) //Lost the LIGHT_ATTACHED property.
+ if(!((new_flags ^ old_flags) & LIGHT_ATTACHED))
+ return
+
+ if(new_flags & LIGHT_ATTACHED) // Gained the [LIGHT_ATTACHED] property
+ overlay_lighting_flags |= LIGHTING_ATTACHED
+ if(ismovable(movable_parent.loc))
+ set_parent_attached_to(movable_parent.loc)
+ else // Lost the [LIGHT_ATTACHED] property
overlay_lighting_flags &= ~LIGHTING_ATTACHED
set_parent_attached_to(null)
-
- if(new_value & LIGHT_NO_LUMCOUNT)
- if(!(movable_parent.light_flags & LIGHT_NO_LUMCOUNT)) //Gained the NO_LUMCOUNT property
- overlay_lighting_flags |= LIGHT_NO_LUMCOUNT
- //Recalculate affecting
- set_lum_power(real_lum_power)
- else if(movable_parent.light_flags & LIGHT_NO_LUMCOUNT) //Lost the NO_LUMCOUNT property
- overlay_lighting_flags &= ~LIGHT_NO_LUMCOUNT
- //Recalculate affecting
- set_lum_power(real_lum_power)
///Toggles the light on.
/datum/component/overlay_lighting/proc/turn_on()
if(overlay_lighting_flags & LIGHTING_ON)
return
- if(current_holder)
- add_dynamic_lumi(current_holder)
overlay_lighting_flags |= LIGHTING_ON
+ if(current_holder)
+ add_dynamic_lumi()
+ if(directional)
+ cast_directional_light()
+ if(current_holder && current_holder != parent && current_holder != parent_attached_to)
+ RegisterSignal(current_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
get_new_turfs()
@@ -346,38 +444,109 @@
if(!(overlay_lighting_flags & LIGHTING_ON))
return
if(current_holder)
- remove_dynamic_lumi(current_holder)
+ remove_dynamic_lumi()
overlay_lighting_flags &= ~LIGHTING_ON
+ if(current_holder && current_holder != parent && current_holder != parent_attached_to)
+ UnregisterSignal(current_holder, COMSIG_MOVABLE_MOVED)
clean_old_turfs()
///Here we append the behavior associated to changing lum_power.
/datum/component/overlay_lighting/proc/set_lum_power(new_lum_power)
- //Get the simulated luminosity count (If we have no lumcount, this is set to 0)
- var/simulated_lum_power = new_lum_power
- if(overlay_lighting_flags & LIGHT_NO_LUMCOUNT)
- simulated_lum_power = 0
- //The new lum power is the same
- if(used_lum_power == simulated_lum_power)
- //This light doesn't affect lumcount, but lum_power must be updated regardless
- if(new_lum_power != simulated_lum_power)
- . = real_lum_power
- real_lum_power = new_lum_power
+ if(lum_power == new_lum_power)
return
- //Set the return value to the old lum power
- . = real_lum_power
- real_lum_power = new_lum_power
- //Get the old used lum power
- var/old_lum_power = used_lum_power
- used_lum_power = simulated_lum_power
- //Calculate the difference
- var/difference = old_lum_power - used_lum_power
- //Apply it to any turf we are affecting
- for(var/t in affected_turfs)
- var/turf/lit_turf = t
+ . = lum_power
+ lum_power = new_lum_power
+ var/difference = . - lum_power
+ for(var/turf/lit_turf as anything in affected_turfs)
lit_turf.dynamic_lumcount -= difference
+///Here we append the behavior associated to changing lum_power.
+/datum/component/overlay_lighting/proc/cast_directional_light()
+ var/final_distance = cast_range
+ //Lower the distance by 1 if we're not looking at a cardinal direction, and we're not a short cast
+ if(final_distance > SHORT_CAST && !(ALL_CARDINALS & current_direction))
+ final_distance -= 1
+ var/turf/scanning = get_turf(current_holder)
+ for(var/i in 1 to final_distance)
+ var/turf/next_turf = get_step(scanning, current_direction)
+ if(isnull(next_turf) || IS_OPAQUE_TURF(next_turf))
+ final_distance = i
+ break
+ scanning = next_turf
+
+ current_holder.underlays -= visible_mask
+
+ var/translate_x = -((range - 1) * 32)
+ var/translate_y = translate_x
+ var/scale_x = 1
+ var/scale_y = 1
+ switch(current_direction)
+ if(NORTH)
+ translate_y += 32 * final_distance
+ if(beam && range > 1)
+ scale_x = 1 / (range - (range/5))
+ if(SOUTH)
+ translate_y += -32 * final_distance
+ if(beam && range > 1)
+ scale_x = 1 / (range - (range/5))
+ if(EAST)
+ translate_x += 32 * final_distance
+ if(beam && range > 1)
+ scale_y = 1 / (range - (range/5))
+ if(WEST)
+ translate_x += -32 * final_distance
+ if(beam && range > 1)
+ scale_y = 1 / (range - (range/5))
+
+ if((directional_offset_x != translate_x) || (directional_offset_y != translate_y))
+ directional_offset_x = translate_x
+ directional_offset_y = translate_y
+ var/matrix/transform = matrix()
+ if(beam && range > 1)
+ transform.Scale(scale_x, scale_y)
+ transform.Translate(translate_x, translate_y)
+ visible_mask.transform = transform
+ if(overlay_lighting_flags & LIGHTING_ON)
+ current_holder.underlays += visible_mask
+
+///Called when current_holder changes loc.
+/datum/component/overlay_lighting/proc/on_holder_dir_change(atom/movable/source, olddir, newdir)
+ SIGNAL_HANDLER
+ set_direction(newdir)
+
+///Called when parent changes loc.
+/datum/component/overlay_lighting/proc/on_parent_dir_change(atom/movable/source, olddir, newdir)
+ SIGNAL_HANDLER
+ set_direction(newdir)
+
+///Sets a new direction for the directional cast, then updates luminosity
+/datum/component/overlay_lighting/proc/set_direction(newdir)
+ if(!newdir)
+ return
+ if(current_direction == newdir)
+ return
+ current_direction = newdir
+ if(overlay_lighting_flags & LIGHTING_ON)
+ make_luminosity_update()
+
+/datum/component/overlay_lighting/proc/on_parent_crafted(datum/source, atom/movable/new_craft)
+ SIGNAL_HANDLER
+
+ if(!istype(new_craft))
+ return
+
+ UnregisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT)
+ RegisterSignal(new_craft, COMSIG_ATOM_USED_IN_CRAFT, PROC_REF(on_parent_crafted))
+ set_parent_attached_to(new_craft)
+
+/// Handles putting the source for overlay lights into the light eater queue since we aren't tracked by [/atom/var/light_sources]
+/datum/component/overlay_lighting/proc/on_light_eater(datum/source, list/light_queue, datum/light_eater)
+ SIGNAL_HANDLER
+ light_queue[parent] = TRUE
+ return NONE
#undef LIGHTING_ON
#undef LIGHTING_ATTACHED
#undef GET_PARENT
+#undef SHORT_CAST
diff --git a/code/datums/components/rot.dm b/code/datums/components/rot.dm
index 1eb32bd0138d..b37c6773f3f2 100644
--- a/code/datums/components/rot.dm
+++ b/code/datums/components/rot.dm
@@ -21,22 +21,23 @@
return
var/datum/gas_mixture/turf_air = T.return_air()
+ if(!turf_air)
+ return
var/datum/gas_mixture/stank_breath = T.remove_air(1 / turf_air.return_volume() * turf_air.total_moles())
if(!stank_breath)
return
stank_breath.set_volume(1)
- var/oxygen_pp = stank_breath.get_moles(/datum/gas/oxygen) * R_IDEAL_GAS_EQUATION * stank_breath.return_temperature() / stank_breath.return_volume()
+ var/oxygen_pp = stank_breath.get_moles(GAS_O2) * R_IDEAL_GAS_EQUATION * stank_breath.return_temperature() / stank_breath.return_volume()
if(oxygen_pp > 18)
var/this_amount = min((oxygen_pp - 8) * stank_breath.return_volume() / stank_breath.return_temperature() / R_IDEAL_GAS_EQUATION, amount)
- stank_breath.adjust_moles(/datum/gas/oxygen, -this_amount)
+ stank_breath.adjust_moles(GAS_O2, -this_amount)
var/datum/gas_mixture/stank = new
- stank.set_moles(/datum/gas/miasma, this_amount)
+ stank.set_moles(GAS_MIASMA, this_amount)
stank.set_temperature(BODYTEMP_NORMAL) // otherwise we have gas below 2.7K which will break our lag generator
stank_breath.merge(stank)
T.assume_air(stank_breath)
- T.air_update_turf()
/datum/component/rot/corpse
amount = MIASMA_CORPSE_MOLES
diff --git a/code/datums/components/twohanded.dm b/code/datums/components/twohanded.dm
index 4892e0208f1c..9a881e017f37 100644
--- a/code/datums/components/twohanded.dm
+++ b/code/datums/components/twohanded.dm
@@ -14,10 +14,8 @@
var/wielded = FALSE
/// The multiplier applied to force when wielded, does not work with force_wielded, and force_unwielded
var/force_multiplier = 0
- /// The force of the item when wielded
+ /// Additional force when wielded
var/force_wielded = 0
- /// The force of the item when unweilded
- var/force_unwielded = 0
/// Play sound when wielded
var/wieldsound = FALSE
/// Play sound when unwielded
@@ -33,6 +31,8 @@
/// stat list for wielded/unwielded, switches with weapon_stats when wielding or unwielding
var/list/wielded_stats
+ /// keep track of unwielded stats, we'll need it later for properly unwielding without causing runtimes
+ var/list/unwielded_stats
/// A callback on the parent to be called when the item is wielded
var/datum/callback/wield_callback
@@ -50,7 +50,6 @@
* * attacksound (optional) The sound to play when wielded and attacking
* * force_multiplier (optional) The force multiplier when wielded, do not use with force_wielded, and force_unwielded
* * force_wielded (optional) The force setting when the item is wielded, do not use with force_multiplier
- * * force_unwielded (optional) The force setting when the item is unwielded, do not use with force_multiplier
* * icon_wielded (optional) The icon to be used when wielded
*/
/datum/component/two_handed/Initialize(
@@ -60,7 +59,6 @@
attacksound = FALSE,
force_multiplier = 0,
force_wielded = 0,
- force_unwielded = 0,
icon_wielded = FALSE,
datum/callback/wield_callback,
datum/callback/unwield_callback,
@@ -75,7 +73,6 @@
src.attacksound = attacksound
src.force_multiplier = force_multiplier
src.force_wielded = force_wielded
- src.force_unwielded = force_unwielded
src.icon_wielded = icon_wielded
src.wield_callback = wield_callback
src.unwield_callback = unwield_callback
@@ -93,7 +90,6 @@
unwieldsound,
force_multiplier,
force_wielded,
- force_unwielded,
icon_wielded,
datum/callback/wield_callback,
datum/callback/unwield_callback,
@@ -113,8 +109,6 @@
src.force_multiplier = force_multiplier
if(force_wielded)
src.force_wielded = force_wielded
- if(force_unwielded)
- src.force_unwielded = force_unwielded
if(icon_wielded)
src.icon_wielded = icon_wielded
if(wield_callback)
@@ -225,9 +219,8 @@
if(force_multiplier)
parent_item.force *= force_multiplier
else if(force_wielded)
- parent_item.force = force_wielded
- if(sharpened_increase)
- parent_item.force += sharpened_increase
+ parent_item.force += force_wielded
+ unwielded_stats = parent_item.weapon_stats
parent_item.weapon_stats = wielded_stats
parent_item.name = "[parent_item.name] (Wielded)"
parent_item.update_appearance()
@@ -271,14 +264,13 @@
// update item stats
var/obj/item/parent_item = parent
- if(sharpened_increase)
- parent_item.force -= sharpened_increase
if(force_multiplier)
parent_item.force /= force_multiplier
- else if(force_unwielded)
- parent_item.force = force_unwielded
+ else if(force_wielded)
+ parent_item.force -= force_wielded
- parent_item.weapon_stats = initial(parent_item.weapon_stats)
+ parent_item.weapon_stats = unwielded_stats
+ unwielded_stats = null
// update the items name to remove the wielded status
var/sf = findtext(parent_item.name, " (Wielded)", -10) // 10 == length(" (Wielded)")
@@ -365,7 +357,7 @@
/**
* on_sharpen Triggers on usage of a sharpening stone on the item
*/
-/datum/component/two_handed/proc/on_sharpen(obj/item/item, amount, max_amount)
+/datum/component/two_handed/proc/on_sharpen(obj/item/item, amount, max_amount=INFINITY)
SIGNAL_HANDLER
if(!item)
@@ -373,14 +365,14 @@
if(sharpened_increase)
return COMPONENT_BLOCK_SHARPEN_ALREADY
var/wielded_val = 0
+ var/obj/item/parent_item = parent
if(force_multiplier)
- var/obj/item/parent_item = parent
if(wielded)
wielded_val = parent_item.force
else
wielded_val = parent_item.force * force_multiplier
else
- wielded_val = force_wielded
+ wielded_val = parent_item.force + (wielded ? 0 : force_wielded)
if(wielded_val > max_amount)
return COMPONENT_BLOCK_SHARPEN_MAXED
sharpened_increase = min(amount, (max_amount - wielded_val))
diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm
index 2313ca184dd0..0a409a1ded27 100644
--- a/code/datums/diseases/advance/symptoms/heal.dm
+++ b/code/datums/diseases/advance/symptoms/heal.dm
@@ -405,9 +405,9 @@
. = 0
if(M.loc)
- environment = M.loc.return_air()
+ environment = M.return_air()
if(environment)
- if(environment.get_moles(/datum/gas/plasma) > GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_MOLES_VISIBLE]) //if there's enough plasma in the air to see
+ if(environment.get_moles(GAS_PLASMA) > GLOB.gas_data.visibility[GAS_PLASMA]) //if there's enough plasma in the air to see
. += power * 0.5
var/requires_metabolizing = !(A.process_dead && M.stat == DEAD) //don't require metabolizing if our host is dead and we have necrotic metabolsim
if(M.reagents.has_reagent(/datum/reagent/toxin/plasma, needs_metabolizing = requires_metabolizing))
@@ -504,3 +504,63 @@
if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, null, BODYPART_ORGANIC))
M.update_damage_overlays()
return 1
+
+#define SYMPTOM_SUPERFICIAL_LOWER_THRESHOLD 0.7
+/datum/symptom/heal/surface
+ name = "Superficial Healing"
+ desc = "The virus accelerates the body's natural healing, causing the body to heal minor wounds quickly."
+ stealth = -2
+ resistance = -2
+ stage_speed = -2
+ transmittable = 1
+
+ level = 3
+ passive_message = span_notice("Your skin tingles")
+
+ var/threshold = 0.9 // Percentual total health we check against. This is less than a toolbox hit, so probably wont save you in combat
+ var/healing_power = 0.5 // 0.5 brute and fire, slightly better than the worst case starlight with its 0.3
+
+ threshold_descs = list(
+ "Stage Speed 8" = "Improves healing significantly.",
+ "Resistance 10" = "Improves healing threshhold. This comes at the downside of exhausting the body more as heavier wounds heal",
+ )
+
+/datum/symptom/heal/surface/Start(datum/disease/advance/A)
+ . = ..()
+ if(!.)
+ return
+ if(A.properties["stage_rate"] >= 8) //stronger healing
+ healing_power = 1.5
+ if(A.properties["resistance"] >= 10)
+ threshold = SYMPTOM_SUPERFICIAL_LOWER_THRESHOLD
+
+/datum/symptom/heal/surface/CanHeal(datum/disease/advance/A)
+ var/mob/living/M = A.affected_mob
+ if(M.health == M.maxHealth)
+ return FALSE
+ return TRUE
+
+
+/datum/symptom/heal/surface/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power)
+ if(M.health == M.maxHealth)
+ return
+ if(((M.health/M.maxHealth) > threshold))
+ healing_power = healing_power * actual_power
+
+ // We don't actually heal all damage types at once, but prioritise one over the other.
+ // Since the virus focuses mainly on surface damage, it will firstly heal those
+ // If it can't find any then it will consider healing some toxins (Not affected by healing power)
+ if(M.getBruteLoss() || M.getFireLoss())
+ M.heal_bodypart_damage(healing_power, healing_power)
+ else if(M.getToxLoss())
+ M.adjustToxLoss(-0.5)
+ else
+ return // Still continues IF we healed something
+
+ // A downside to the better threshold
+ if(threshold == SYMPTOM_SUPERFICIAL_LOWER_THRESHOLD)
+ // Interesting downside
+ if(M.getStaminaLoss() < 65)
+ M.adjustStaminaLoss(20)
+ return TRUE
+#undef SYMPTOM_SUPERFICIAL_LOWER_THRESHOLD
diff --git a/code/datums/elements/light_blocking.dm b/code/datums/elements/light_blocking.dm
new file mode 100644
index 000000000000..673838ad4f80
--- /dev/null
+++ b/code/datums/elements/light_blocking.dm
@@ -0,0 +1,42 @@
+/**
+ * Attached to movable atoms with opacity. Listens to them move and updates their old and new turf loc's opacity accordingly.
+ */
+/datum/element/light_blocking
+ element_flags = ELEMENT_DETACH_ON_HOST_DESTROY
+
+
+/datum/element/light_blocking/Attach(datum/target)
+ . = ..()
+ if(!ismovable(target))
+ return ELEMENT_INCOMPATIBLE
+ RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_target_move))
+ var/atom/movable/movable_target = target
+ if(!isturf(movable_target.loc))
+ return
+ for(var/turf/turf_loc as anything in movable_target.locs)
+ turf_loc.add_opacity_source(target)
+
+
+/datum/element/light_blocking/Detach(datum/target)
+ . = ..()
+ UnregisterSignal(target, list(COMSIG_MOVABLE_MOVED))
+ var/atom/movable/movable_target = target
+ if(!isturf(movable_target.loc))
+ return
+ for(var/turf/turf_loc as anything in movable_target.locs)
+ turf_loc.remove_opacity_source(target)
+
+
+///Updates old and new turf loc opacities.
+/datum/element/light_blocking/proc/on_target_move(atom/movable/source, atom/old_loc, dir, forced, list/old_locs)
+ SIGNAL_HANDLER
+ if(isturf(old_loc))
+ if(old_locs)
+ for(var/turf/old_turf as anything in old_locs)
+ old_turf.remove_opacity_source(source)
+ else
+ var/turf/old_turf = old_loc
+ old_turf.remove_opacity_source(source)
+ if(isturf(source.loc))
+ for(var/turf/new_turf as anything in source.locs)
+ new_turf.add_opacity_source(source)
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index aeec4dbdc21b..fcca5c762f24 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -155,11 +155,11 @@
// Can most things breathe?
if(trace_gases)
continue
- if(A.get_moles(/datum/gas/oxygen) < 16)
+ if(A.get_moles(GAS_O2) < 16)
continue
- if(A.get_moles(/datum/gas/plasma))
+ if(A.get_moles(GAS_PLASMA))
continue
- if(A.get_moles(/datum/gas/carbon_dioxide) >= 10)
+ if(A.get_moles(GAS_CO2) >= 10)
continue
// Aim for goldilocks temperatures and pressure
diff --git a/code/datums/martial/flying_fang.dm b/code/datums/martial/flying_fang.dm
index bfeef4b5e5c3..95e8eeef2bf2 100644
--- a/code/datums/martial/flying_fang.dm
+++ b/code/datums/martial/flying_fang.dm
@@ -118,10 +118,13 @@
//headbutt, deals moderate brute and stamina damage with an eye blur, causes poor aim for a few seconds to the target if they have no helmet on
/datum/martial_art/flyingfang/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("D",D)
- if(check_streak(A,D))
- return TRUE
if(!can_use(A))
return
+ if(HAS_TRAIT(A, TRAIT_PACIFISM)) // All disarm attacks/combos deal non-stamina damage, yet pacifism is not accounted for in base disarm.
+ to_chat(A, span_warning("You don't want to harm [D]!"))
+ return
+ if(check_streak(A,D))
+ return TRUE
var/obj/item/bodypart/affecting = D.get_bodypart(check_zone(BODY_ZONE_HEAD))
var/armor_block = D.run_armor_check(affecting, MELEE)
var/disarm_damage = A.get_punchdamagehigh() / 2 //5 damage
diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm
index 2c6c3236429a..2e46bbeb2635 100644
--- a/code/datums/martial/krav_maga.dm
+++ b/code/datums/martial/krav_maga.dm
@@ -234,11 +234,10 @@
desc = "These tactical gloves are fireproof and shock resistant, and using nanochip technology it teaches you the powers of krav maga."
icon_state = "black"
item_state = "blackglovesplus"
- siemens_coefficient = 0
strip_delay = 80
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
resistance_flags = NONE
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 80, ACID = 50)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 80, ACID = 50, ELECTRIC = 100)
diff --git a/code/datums/martial/lightning_flow.dm b/code/datums/martial/lightning_flow.dm
index b1759970c0a3..1f6f5853915e 100644
--- a/code/datums/martial/lightning_flow.dm
+++ b/code/datums/martial/lightning_flow.dm
@@ -27,11 +27,11 @@
/datum/martial_art/lightning_flow/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(dashing)
return TRUE
- damage(D, A, 5)
+ damage(D, A, 5, zone=A.zone_selected)
return FALSE
-/datum/martial_art/lightning_flow/proc/damage(mob/living/target, mob/living/carbon/human/user, amount = 5, stun = FALSE)
- target.electrocute_act(amount, user, stun = stun)
+/datum/martial_art/lightning_flow/proc/damage(mob/living/target, mob/living/carbon/human/user, amount = 5, stun = FALSE, zone = null)
+ target.electrocute_act(amount, user, stun = stun, zone = zone)
/datum/martial_art/lightning_flow/proc/InterceptClickOn(mob/living/carbon/human/H, params, atom/target)
var/list/modifiers = params2list(params)
@@ -72,10 +72,14 @@
dashing = TRUE
if(action_type && action_type == INTENT_DISARM)
H.Knockdown(2 SECONDS, TRUE, TRUE)
- H.Immobilize(0.6 SECONDS, TRUE, TRUE) //just until the dash would end
+ H.Immobilize(1 SECONDS, TRUE, TRUE) //to prevent canceling the dash
new /obj/effect/particle_effect/sparks/electricity/short/loud(get_turf(H))
- H.throw_at(target, DASH_RANGE, DASH_SPEED, H, FALSE, TRUE)
+ H.throw_at(target, DASH_RANGE, DASH_SPEED, H, FALSE, callback = CALLBACK(src, PROC_REF(end_dash), H))
+/datum/martial_art/lightning_flow/proc/end_dash(mob/living/carbon/human/H)
+ dashing = FALSE
+ H.SetImmobilized(0, TRUE, TRUE) //remove the block on movement
+
/datum/martial_art/lightning_flow/handle_throw(atom/hit_atom, mob/living/carbon/human/H, datum/thrownthing/throwingdatum)
if(!dashing || !action_type)
return FALSE
@@ -83,14 +87,13 @@
return FALSE
var/mob/living/target = hit_atom
dashing = FALSE
- H.SetImmobilized(0)
- H.SetKnockdown(0)
switch(action_type)
if(INTENT_DISARM)
if(ishuman(target))
var/mob/living/carbon/human/victim = target
if(victim.check_shields(src, 0, "[H]", attack_type = LEAP_ATTACK))
return FALSE
+ H.SetKnockdown(0) //remove the self knockdown from the dropkick
dropkick(target, H, throwingdatum)
if(INTENT_GRAB)
target.grabbedby(H)
@@ -105,7 +108,7 @@
/datum/martial_art/lightning_flow/proc/dropkick(mob/living/target, mob/living/carbon/human/H, datum/thrownthing/throwingdatum)
target.visible_message(span_danger("[H] dropkicks [target]!"), span_userdanger("[H] dropkicks you!"))
target.Knockdown(5 SECONDS)
- damage(target, H, 15, TRUE)
+ damage(target, H, 15, TRUE, BODY_ZONE_CHEST)
var/destination = throwingdatum.target
if(get_dist(target, destination) < 5)
destination = get_ranged_target_turf(get_turf(H), throwingdatum.init_dir, 5)
diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm
index 6a74b8bd54d4..4f2530061adb 100644
--- a/code/datums/martial/sleeping_carp.dm
+++ b/code/datums/martial/sleeping_carp.dm
@@ -184,7 +184,6 @@
/obj/item/melee/bostaff/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = 10, \
force_wielded = 14, \
)
diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm
index c0280d80b7cf..804492f862e9 100644
--- a/code/datums/mutations/body.dm
+++ b/code/datums/mutations/body.dm
@@ -195,40 +195,41 @@
quality = POSITIVE
text_gain_indication = span_notice("Your skin begins to glow softly.")
instability = 5
- var/obj/effect/dummy/luminescent_glow/glowth //shamelessly copied from luminescents
- var/glow = 3.5
- var/range = 2.5
- var/glow_color
- var/current_nullify_timer // For veil yogstation\code\modules\antagonists\shadowling\shadowling_abilities.dm
power_coeff = 1
conflicts = list(/datum/mutation/human/glow/anti, /datum/mutation/human/radiantburst)
+ var/glow_power = 3.5
+ var/glow_range = 2.5
+ var/glow_color
+ var/current_nullify_timer // For veil yogstation\code\modules\antagonists\shadowling\shadowling_abilities.dm
+
+ var/obj/effect/dummy/lighting_obj/moblight/glow
+
/datum/mutation/human/glow/on_acquiring(mob/living/carbon/human/owner)
. = ..()
if(.)
return
glow_color = owner.dna.features["mcolor"]
- glowth = new(owner)
+ glow = owner.mob_light()
modify()
// Override modify here without a parent call, because we don't actually give an action.
/datum/mutation/human/glow/modify()
- if(!glowth)
+ if(!glow)
return
- var/power = GET_MUTATION_POWER(src)
- glowth.set_light_range_power_color(range * power, glow * power, glow_color)
+ glow.set_light_range_power_color(glow_range * GET_MUTATION_POWER(src), glow_power, glow_color)
/datum/mutation/human/glow/on_losing(mob/living/carbon/human/owner)
. = ..()
if(.)
return
- QDEL_NULL(glowth)
+ QDEL_NULL(glow)
/datum/mutation/human/glow/anti
name = "Anti-Glow"
desc = "Your skin seems to attract and absorb nearby light creating 'darkness' around you."
text_gain_indication = span_notice("Your light around you seems to disappear.")
- glow = -3.5
+ glow_power = -3.5
conflicts = list(/datum/mutation/human/glow, /datum/mutation/human/radiantburst)
locked = TRUE
diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm
index 1295d857b14c..4aaf778b6b21 100644
--- a/code/datums/mutations/hulk.dm
+++ b/code/datums/mutations/hulk.dm
@@ -43,102 +43,3 @@
message = "[replacetext(message, ".", "!")]!!"
wrapped_message[1] = message
return COMPONENT_UPPERCASE_SPEECH
-
-/datum/mutation/human/genetics_hulk
- name = "Hulk"
- desc = "A seemingly dormant genome, but reacts violently to agitation."
- difficulty = 16
- instability = 50
- class = MUT_OTHER
- locked = TRUE
- quality = POSITIVE
- get_chance = 10
- lowest_value = 256 * 14
- text_gain_indication = span_notice("You feel an anger welling inside you.")
- health_req = 25
-
-/datum/mutation/human/genetics_hulk/on_losing(mob/living/carbon/human/owner)
- . = ..()
- dna.remove_mutation(ACTIVE_HULK)
- return
-
-/datum/mutation/human/active_hulk
- name = "Hulk State"
- desc = "The single most angry genome ever seen. Mutating this will incite a one-time immediate Hulkformation in the mutatee."
- quality = POSITIVE
- instability = 30
- class = MUT_OTHER
- locked = TRUE
- text_gain_indication = span_notice("Your muscles hurt!")
- health_req = 1
- var/health_based = 0
- power_path = /datum/action/cooldown/spell/aoe/repulse/hulk
-
-/datum/mutation/human/active_hulk/on_acquiring(mob/living/carbon/human/owner)
- if(..())
- return
- owner.remove_CC() //RAGE RAGE RAGE, RISE RISE RISE
- ADD_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK)
- ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK)
- ADD_TRAIT(owner, TRAIT_IGNORESLOWDOWN, TRAIT_HULK)
- RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech))
- if(istype(owner.w_uniform, /obj/item/clothing/under))
- var/obj/item/clothing/under/U = owner.w_uniform
- if(owner.canUnEquip(U))
- owner.visible_message("[U] falls apart!", span_warning("You tear your clothes up in anger!"))
- qdel(U)
- if(istype(owner.wear_suit, /obj/item/clothing/suit))
- var/obj/item/clothing/suit/S = owner.wear_suit
- if(owner.canUnEquip(S))
- owner.dropItemToGround(S)
- owner.undershirt = "Nude"
- owner.dna.species.no_equip.Add(ITEM_SLOT_OCLOTHING, ITEM_SLOT_ICLOTHING)
- owner.say("PUNY HUMANS!!")
- owner.physiology.stamina_mod = 0.3
- owner.update_body()
-
-/datum/mutation/human/active_hulk/on_attack_hand(atom/target, proximity)
- if(proximity) //no telekinetic hulk attack
- if(prob(3))
- owner.adjust_jitter(10 SECONDS)
- owner.adjustStaminaLoss(-0.5)
- return target.attack_hulk(owner)
-
-/datum/mutation/human/active_hulk/on_life()
- owner.adjustStaminaLoss(0.9)
- if(owner.health < 0)
- on_losing(owner)
- to_chat(owner, span_danger("You suddenly feel very weak. Your rage dies out."))
-
-/datum/mutation/human/active_hulk/on_losing(mob/living/carbon/human/owner)
- if(..())
- return
- REMOVE_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK)
- REMOVE_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK)
- REMOVE_TRAIT(owner, TRAIT_IGNORESLOWDOWN, TRAIT_HULK)
- UnregisterSignal(owner, COMSIG_MOB_SAY)
- owner.dna.species.no_equip.Remove(ITEM_SLOT_OCLOTHING, ITEM_SLOT_ICLOTHING)
- owner.physiology.stamina_mod = initial(owner.physiology.stamina_mod)
- owner.update_body_parts()
- owner.dna.species.handle_mutant_bodyparts(owner)
-
-/datum/mutation/human/active_hulk/proc/handle_speech(original_message, wrapped_message)
- var/message = wrapped_message[1]
- if(message)
- message = "[replacetext(message, ".", "!")]!!"
- wrapped_message[1] = message
- return COMPONENT_UPPERCASE_SPEECH
-
-/datum/action/cooldown/spell/aoe/repulse/hulk
- name = "Ground Smash"
- desc = "Smash the ground to throw your enemies back!"
- invocation = "HULK SMASH!!"
- button_icon = 'icons/mob/actions.dmi'
- button_icon_state = "green_hand"
-
-/datum/action/cooldown/spell/aoe/repulse/hulk/cast_on_thing_in_aoe(atom/movable/victim, atom/caster)
- var/turf/open/floor/turf = get_turf(victim)
- if(istype(turf))
- turf.break_tile()
- playsound(usr.loc, 'sound/effects/meteorimpact.ogg', 30, TRUE, 2)
- return ..()
diff --git a/code/datums/mutations/touch.dm b/code/datums/mutations/touch.dm
index 4eb0ed901cc1..1441078d94c6 100644
--- a/code/datums/mutations/touch.dm
+++ b/code/datums/mutations/touch.dm
@@ -29,7 +29,7 @@
/datum/action/cooldown/spell/touch/shock/cast_on_hand_hit(obj/item/melee/touch_attack/hand, atom/victim, mob/living/carbon/caster)
if(iscarbon(victim))
var/mob/living/carbon/carbon_victim = victim
- if(carbon_victim.electrocute_act(15, caster, 1, stun = FALSE))//doesnt stun. never let this stun
+ if(carbon_victim.electrocute_act(15, caster, 1, zone=caster.zone_selected, stun = FALSE))//doesnt stun. never let this stun
carbon_victim.dropItemToGround(carbon_victim.get_active_held_item())
carbon_victim.dropItemToGround(carbon_victim.get_inactive_held_item())
carbon_victim.adjust_timed_status_effect(15 SECONDS, /datum/status_effect/confusion)
@@ -56,29 +56,3 @@
desc = "This is kind of like when you rub your feet on a shag rug so you can zap your friends, only a lot less safe."
icon_state = "zapper"
item_state = "zapper"
- var/far = FALSE
-
-/obj/item/melee/touch_attack/shock/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(!(proximity || far) || !can_see(user, target, 5) || get_dist(target, user) > 5)
- user.visible_message(span_notice("[user]'s hand reaches out but nothing happens."))
- return
- if(iscarbon(target))
- var/mob/living/carbon/C = target
- if(C.electrocute_act(15, src, 1, FALSE, FALSE, FALSE, FALSE, FALSE))//doesnt stun. never let this stun
- user.Beam(C, icon_state="red_lightning", time = 1.5 SECONDS)
- C.dropItemToGround(C.get_active_held_item())
- C.dropItemToGround(C.get_inactive_held_item())
- C.adjust_confusion(15 SECONDS)
- C.visible_message(span_danger("[user] electrocutes [target]!"),span_userdanger("[user] electrocutes you!"))
- log_combat(user, target, "[user] electrocuted [target] with shock touch")
- else
- user.visible_message(span_warning("[user] fails to electrocute [target]!"))
- else if(isliving(target))
- var/mob/living/L = target
- L.electrocute_act(15, src, 1, FALSE, FALSE, FALSE, FALSE)
- user.Beam(L, icon_state="red_lightning", time = 1.5 SECONDS)
- L.visible_message(span_danger("[user] electrocutes [target]!"),span_userdanger("[user] electrocutes you!"))
- else
- to_chat(user,span_warning("The electricity doesn't seem to affect [target]..."))
- remove_hand_with_no_refund(user)
- return ..()
diff --git a/code/datums/mutations/touchfar.dm b/code/datums/mutations/touchfar.dm
index 883853f4d4d6..317e23337277 100644
--- a/code/datums/mutations/touchfar.dm
+++ b/code/datums/mutations/touchfar.dm
@@ -10,5 +10,14 @@
name = "Extended Shock Touch"
hand_path = /obj/item/melee/touch_attack/shock/far
+/datum/action/cooldown/spell/touch/shock/far/cast_on_hand_hit(obj/item/melee/touch_attack/hand, atom/victim, mob/living/carbon/caster)
+ . = ..()
+ caster.Beam(victim, icon_state="red_lightning", time = 1.5 SECONDS)
+
/obj/item/melee/touch_attack/shock/far
- far = TRUE
+
+/obj/item/melee/touch_attack/shock/far/afterattack(atom/target, mob/living/carbon/user, proximity, click_parameters)
+ if(!can_see(user, target, 5) || get_dist(target, user) > 5)
+ user.visible_message(span_notice("[user]'s hand reaches out but nothing happens."))
+ return
+ . = ..(target, user, TRUE, click_parameters) //call the parent, forcing proximity = TRUE so even distant things are considered nearby
diff --git a/code/datums/ruins/icemoon.dm b/code/datums/ruins/icemoon.dm
index 47eac685cdba..d3ed65a6b87f 100644
--- a/code/datums/ruins/icemoon.dm
+++ b/code/datums/ruins/icemoon.dm
@@ -17,7 +17,7 @@
name = "Icemoon Hermit"
id = "ice_hermit"
description = "The home of a hermit in the ice and snow, you can't possibly imagine who'd want to live here."
- suffix = "icemoon_hermit.dmm"
+ suffix = "icemoon_surface_hermit.dmm"
/datum/map_template/ruin/icemoon/lust
name = "Ruin of Lust"
@@ -56,6 +56,12 @@
suffix = "lavaland_surface_seed_vault.dmm"
allow_duplicates = FALSE
+/datum/map_template/ruin/icemoon/walker_village
+ name = "Walker Village"
+ id = "walkervillage"
+ description = "A town populated by strange, sapient zombies."
+ suffix = "icemoon_surface_walkervillage.dmm"
+
// above and below ground together
/datum/map_template/ruin/icemoon/mining_site
@@ -119,9 +125,3 @@
id = "wampacave"
description = "A cave inhabited by a strange monster, with an unfortunate hero..."
suffix = "icemoon_underground_wampacave.dmm"
-
-/datum/map_template/ruin/icemoon/underground/walker_village
- name = "Walker Village"
- id = "walkervillage"
- description = "A town populated by strange, sapient zombies."
- suffix = "icemoon_underground_walkervillage.dmm"
diff --git a/code/datums/status_effects/buffs/buffs.dm b/code/datums/status_effects/buffs/buffs.dm
index b40be55ce848..112529026ff8 100644
--- a/code/datums/status_effects/buffs/buffs.dm
+++ b/code/datums/status_effects/buffs/buffs.dm
@@ -717,9 +717,11 @@
REMOVE_TRAIT(owner, TRAIT_ANTIMAGIC, type)
owner.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY)
+
+#define HEALBOOST_FILTER "holy_glow"
/datum/status_effect/holylight_healboost
id = "holy healboost"
- duration = 30 SECONDS
+ duration = 1 MINUTES
tick_interval = -1
status_type = STATUS_EFFECT_REFRESH
alert_type = /atom/movable/screen/alert/status_effect/holylight_healboost
@@ -734,7 +736,15 @@
. = ..()
if(.)
owner.AddComponent(/datum/component/heal_react/boost/holylight)
+ owner.add_filter(HEALBOOST_FILTER, 2, list("type" = "outline", "color" = "#60A2A8", "alpha" = 0, "size" = 1))
+ var/filter = owner.get_filter(HEALBOOST_FILTER)
+ animate(filter, alpha = 200, time = 2 SECONDS, loop = -1, easing = EASE_OUT | CUBIC_EASING)
+ animate(alpha = 0, time = 2 SECONDS, loop = -1, easing = EASE_OUT | CUBIC_EASING)
/datum/status_effect/holylight_healboost/on_remove()
var/datum/component/heal_react/boost/holylight/healing = owner.GetComponent(/datum/component/heal_react/boost/holylight)
healing?.RemoveComponent()
+ var/filter = owner.get_filter(HEALBOOST_FILTER)
+ if(filter)
+ animate(filter)
+ owner.remove_filter(HEALBOOST_FILTER)
diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm
index 76b6b64f6100..55978eb6bbdb 100644
--- a/code/datums/status_effects/debuffs/fire_stacks.dm
+++ b/code/datums/status_effects/debuffs/fire_stacks.dm
@@ -153,7 +153,7 @@
return TRUE
var/datum/gas_mixture/air = owner.loc.return_air()
- if(!air || (air.get_moles(/datum/gas/oxygen) < 1))
+ if(!air || (air.get_moles(GAS_O2) < 1))
qdel(src)
return TRUE
diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm
index fd42bdd0572f..6c9e33ccef9d 100644
--- a/code/datums/traits/good.dm
+++ b/code/datums/traits/good.dm
@@ -310,46 +310,99 @@
medical_record_text = "Patient is unusually speedy when creating crafts."
/datum/quirk/cyberorgan //random upgraded cybernetic organ
- name = "Cybernetic Organ"
- desc = "Due to a past incident you lost function of one of your organs, but now have a fancy upgraded cybernetic organ!"
+ name = "Upgraded Cybernetic Organ"
+ desc = "Due to a past incident you lost function of one of your organs, but now have a random upgraded cybernetic organ!"
icon = "building-ngo"
- value = 4
+ value = 3
var/slot_string = "organ"
- var/list/organ_list = list(ORGAN_SLOT_LUNGS, ORGAN_SLOT_HEART, ORGAN_SLOT_LIVER)
+ var/list/organ_list = list(
+ ORGAN_SLOT_LUNGS = /obj/item/organ/lungs/cybernetic/upgraded,
+ ORGAN_SLOT_HEART = /obj/item/organ/heart/cybernetic/upgraded,
+ ORGAN_SLOT_LIVER = /obj/item/organ/liver/cybernetic/upgraded,
+ )
medical_record_text = "During physical examination, patient was found to have an upgraded cybernetic organ."
/datum/quirk/cyberorgan/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/list/temp = organ_list.Copy() //pretty sure this is global so i dont want to bugger with it :)
- if(isjellyperson(H))
+ if(HAS_TRAIT_FROM(H, TRAIT_TOXINLOVER, SPECIES_TRAIT))
temp -= ORGAN_SLOT_LIVER
- var/organ_slot = pick(temp)
- var/obj/item/organ/old_part = H.getorganslot(organ_slot)
- var/obj/item/organ/prosthetic
- switch(organ_slot)
- if(ORGAN_SLOT_LUNGS)
- prosthetic = new/obj/item/organ/lungs/cybernetic/upgraded(quirk_holder)
- slot_string = "lungs"
- if(ORGAN_SLOT_HEART)
- prosthetic = new/obj/item/organ/heart/cybernetic/upgraded(quirk_holder)
- slot_string = "heart"
- if(ORGAN_SLOT_LIVER)
- prosthetic = new/obj/item/organ/liver/cybernetic/upgraded(quirk_holder)
- slot_string = "liver"
+ if(HAS_TRAIT_FROM(H, TRAIT_NOBREATH, SPECIES_TRAIT))
+ temp -= ORGAN_SLOT_LUNGS
+ if(NOBLOOD in H.dna?.species.species_traits)
+ temp -= ORGAN_SLOT_HEART
+ var/organ_type = organ_list[pick(temp)]
+ var/obj/item/organ/prosthetic = new organ_type(quirk_holder)
+ var/obj/item/organ/old_part = H.getorganslot(prosthetic.slot)
+ slot_string = prosthetic.slot
prosthetic.Insert(H)
qdel(old_part)
H.regenerate_icons()
/datum/quirk/cyberorgan/post_add()
- to_chat(quirk_holder, "Your [slot_string] has been replaced with an upgraded cybernetic variant. ")
+ to_chat(quirk_holder, span_boldannounce("Your [slot_string] has been replaced with an upgraded cybernetic variant."))
/datum/quirk/cyberorgan/check_quirk(datum/preferences/prefs)
var/species_type = prefs.read_preference(/datum/preference/choiced/species)
if(species_type == /datum/species/ipc) // IPCs are already cybernetic
return "You already have cybernetic organs!"
+
+ var/datum/species/species = new species_type
+ var/list/temp = organ_list.Copy()
+ if(TRAIT_TOXINLOVER in species.inherent_traits)
+ temp -= ORGAN_SLOT_LIVER
+ if(TRAIT_NOBREATH in species.inherent_traits)
+ temp -= ORGAN_SLOT_LUNGS
+ if(NOBLOOD in species.species_traits)
+ temp -= ORGAN_SLOT_HEART
+ if(temp.len <= 0)
+ return "You have no organs to replace!"
+
return FALSE
+/datum/quirk/cyberorgan/lungs
+ name = "Cybernetic Organ (Lungs)"
+ desc = "Due to a past incident you lost function of your lungs, but now have cybernetic lungs!"
+ organ_list = list(ORGAN_SLOT_LUNGS = /obj/item/organ/lungs/cybernetic)
+ medical_record_text = "During physical examination, patient was found to have upgraded cybernetic lungs."
+ value = 0
+
+/datum/quirk/cyberorgan/lungs/check_quirk(datum/preferences/prefs)
+ var/species_type = prefs.read_preference(/datum/preference/choiced/species)
+ var/datum/species/species = new species_type
+ if(TRAIT_NOBREATH in species.inherent_traits) // species with TRAIT_NOBREATH don't have lungs
+ return "You don't have lungs!"
+ return ..()
+
+/datum/quirk/cyberorgan/heart
+ name = "Cybernetic Organ (Heart)"
+ desc = "Due to a past incident you lost function of your heart, but now have a cybernetic heart!"
+ organ_list = list(ORGAN_SLOT_HEART = /obj/item/organ/heart/cybernetic)
+ medical_record_text = "During physical examination, patient was found to have a cybernetic heart."
+ value = 0
+
+/datum/quirk/cyberorgan/heart/check_quirk(datum/preferences/prefs)
+ var/species_type = prefs.read_preference(/datum/preference/choiced/species)
+ var/datum/species/species = new species_type
+ if(NOBLOOD in species.species_traits) // species with NOBLOOD don't have a heart
+ return "You don't have a heart!"
+ return ..()
+
+/datum/quirk/cyberorgan/liver
+ name = "Cybernetic Organ (Liver)"
+ desc = "Due to a past incident you lost function of your liver, but now have a cybernetic liver!"
+ organ_list = list(ORGAN_SLOT_LIVER = /obj/item/organ/liver/cybernetic)
+ medical_record_text = "During physical examination, patient was found to have a cybernetic liver."
+ value = 0
+
+/datum/quirk/cyberorgan/liver/check_quirk(datum/preferences/prefs)
+ var/species_type = prefs.read_preference(/datum/preference/choiced/species)
+ var/datum/species/species = new species_type
+ if(TRAIT_TOXINLOVER in species.inherent_traits) // species with TRAIT_TOXINLOVER slowly die when given upgraded livers
+ return "You aren't compatible with upgraded livers!"
+ return ..()
+
/datum/quirk/telomeres_long
name = "Long Telomeres"
desc = "You haven't been cloned much, if at all. Your DNA's telomeres are still largely unaffected by repeated cloning, enabling cloners to work faster."
diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm
index e30a5e450947..5714024064dc 100644
--- a/code/datums/traits/negative.dm
+++ b/code/datums/traits/negative.dm
@@ -659,28 +659,6 @@
lose_text = span_notice("Your mind finally feels calm.")
medical_record_text = "Patient's mind is in a vulnerable state, and cannot recover from traumatic events."
-/datum/quirk/sheltered
- name = "Sheltered"
- desc = "You never learned to speak galactic common."
- icon = "comment-dots"
- value = -2
- mob_trait = TRAIT_SHELTERED
- gain_text = span_danger("You do not speak galactic common.")
- lose_text = span_notice("You start to put together how to speak galactic common.")
- medical_record_text = "Patient looks perplexed when questioned in galactic common."
-
-/datum/quirk/sheltered/on_clone(data)
- var/mob/living/carbon/human/H = quirk_holder
- H.remove_language(/datum/language/common, FALSE, TRUE)
- if(!H.get_selected_language())
- H.grant_language(/datum/language/japanese)
-
-/datum/quirk/sheltered/on_spawn()
- var/mob/living/carbon/human/H = quirk_holder
- H.remove_language(/datum/language/common, FALSE, TRUE)
- if(!H.get_selected_language())
- H.grant_language(/datum/language/japanese)
-
/datum/quirk/allergic
name = "Allergic Reaction"
desc = "You have had an allergic reaction to medicine in the past. Better stay away from it!"
diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm
index a93336ec2e08..d40bdf4026b8 100644
--- a/code/datums/traits/neutral.dm
+++ b/code/datums/traits/neutral.dm
@@ -375,3 +375,25 @@
/datum/quirk/bald/proc/unequip_hat(mob/user, obj/item/hat)
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "bad_hair_day", /datum/mood_event/bald)
+
+/datum/quirk/sheltered
+ name = "Sheltered"
+ desc = "You never learned to speak galactic common."
+ icon = "comment-dots"
+ value = 0
+ mob_trait = TRAIT_SHELTERED
+ gain_text = span_danger("You do not speak galactic common.")
+ lose_text = span_notice("You start to put together how to speak galactic common.")
+ medical_record_text = "Patient looks perplexed when questioned in galactic common."
+
+/datum/quirk/sheltered/on_clone(data)
+ var/mob/living/carbon/human/H = quirk_holder
+ H.remove_language(/datum/language/common, FALSE, TRUE)
+ if(!H.get_selected_language())
+ H.grant_language(/datum/language/japanese)
+
+/datum/quirk/sheltered/on_spawn()
+ var/mob/living/carbon/human/H = quirk_holder
+ H.remove_language(/datum/language/common, FALSE, TRUE)
+ if(!H.get_selected_language())
+ H.grant_language(/datum/language/japanese)
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index c6b23bc0b270..afab00c7f397 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -32,6 +32,7 @@
var/clockwork_warp_allowed = TRUE // Can servants warp into this area from Reebe?
var/clockwork_warp_fail = "The structure there is too dense for warping to pierce. (This is normal in high-security areas.)"
+ ///If true, that means one of any fire alarms in the area is active
var/fire = FALSE
var/atmos = TRUE
var/atmosalm = FALSE
@@ -113,6 +114,7 @@
var/list/firedoors
var/list/cameras
var/list/firealarms
+ var/list/airalarms
var/firedoors_last_closed_on = 0
/// Can the Xenobio management console transverse this area by default?
var/xenobiology_compatible = FALSE
@@ -344,10 +346,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
D.triggerAlarm("Power", src, cameras, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
- if(state == 1)
- p.cancelAlarm("Power", src, source)
- else
- p.triggerAlarm("Power", src, cameras, source)
+ p.update_alarm_display()
/**
* Generate an atmospheric alert for this area
@@ -368,7 +367,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
D.triggerAlarm("Atmosphere", src, cameras, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
- p.triggerAlarm("Atmosphere", src, cameras, source)
+ p.update_alarm_display()
else
for (var/item in GLOB.silicon_mobs)
@@ -382,7 +381,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
D.cancelAlarm("Atmosphere", src, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
- p.cancelAlarm("Atmosphere", src, source)
+ p.update_alarm_display()
/**
* Try to close all the firedoors in the area
*/
@@ -433,7 +432,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
D.triggerAlarm("Fire", src, cameras, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
- p.triggerAlarm("Fire", src, cameras, source)
+ p.update_alarm_display()
START_PROCESSING(SSobj, src)
@@ -445,8 +444,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
*
* Also cycles the icons of all firealarms and deregisters the area from processing on SSOBJ
*/
-/area/proc/firereset(obj/source)
- if (fire)
+/area/proc/firereset(obj/source, alert_only=FALSE)
+ if (fire && !alert_only)
unset_fire_alarm_effects()
ModifyFiredoors(TRUE)
for(var/item in firealarms)
@@ -464,7 +463,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
D.cancelAlarm("Fire", src, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
- p.cancelAlarm("Fire", src, source)
+ p.update_alarm_display()
STOP_PROCESSING(SSobj, src)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index f0e851f8a341..191525de75e4 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -44,6 +44,28 @@
var/datum/wires/wires = null
var/obj/effect/abstract/particle_holder/master_holder
+ ///Light systems, both shouldn't be active at the same time.
+ var/light_system = STATIC_LIGHT
+ ///Range of the light in tiles. Zero means no light.
+ var/light_range = 0
+ ///Intensity of the light. The stronger, the less shadows you will see on the lit area.
+ var/light_power = 1
+ ///Hexadecimal RGB string representing the colour of the light. White by default.
+ var/light_color = COLOR_WHITE
+ /// Angle of light to show in light_dir
+ /// 360 is a circle, 90 is a cone, etc.
+ var/light_angle = 360
+ /// What angle to project light in
+ var/light_dir = NORTH
+ ///Boolean variable for toggleable lights. Has no effect without the proper light_system, light_range and light_power values.
+ var/light_on = TRUE
+ ///Bitflags to determine lighting-related atom properties.
+ var/light_flags = NONE
+ ///Our light source. Don't fuck with this directly unless you have a good reason!
+ var/tmp/datum/light_source/light
+ ///Any light sources that are "inside" of us, for example, if src here was a mob that's carrying a flashlight, that flashlight's light source would be part of this list.
+ var/tmp/list/light_sources
+
///overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
var/list/priority_overlays
/// a very temporary list of overlays to remove
@@ -171,10 +193,6 @@
if (light_system == STATIC_LIGHT && light_power && light_range)
update_light()
- if (opacity && isturf(loc))
- var/turf/T = loc
- T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
-
if (canSmoothWith)
canSmoothWith = typelist("canSmoothWith", canSmoothWith)
@@ -363,23 +381,38 @@
///Take air from the passed in gas mixture datum
/atom/proc/assume_air(datum/gas_mixture/giver)
- qdel(giver)
+ return null
+
+/atom/proc/assume_air_moles(datum/gas_mixture/giver, moles)
+ return null
+
+/atom/proc/assume_air_ratio(datum/gas_mixture/giver, ratio)
return null
///Remove air from this atom
/atom/proc/remove_air(amount)
return null
+/atom/proc/remove_air_ratio(ratio)
+ return null
+
+/atom/proc/transfer_air(datum/gas_mixture/taker, amount)
+ return null
+
+/atom/proc/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ return null
+
///Return the current air environment in this atom
/atom/proc/return_air()
if(loc)
return loc.return_air()
- else
- return null
+ return null
+///Return the air if we can analyze it
/atom/proc/return_analyzable_air()
return null
+
///Return the air if we can analyze it
///Check if this atoms eye is still alive (probably)
/atom/proc/check_eye(mob/user)
@@ -1046,12 +1079,63 @@
* the object has been admin edited
*/
/atom/vv_edit_var(var_name, var_value)
+ var/old_light_flags = light_flags
+ // Disable frozen lights for now, so we can actually modify it
+ light_flags &= ~LIGHT_FROZEN
+ switch(var_name)
+
+ if(NAMEOF(src, light_range))
+ if(light_system == STATIC_LIGHT)
+ set_light(l_range = var_value)
+ else
+ set_light_range(var_value)
+ . = TRUE
+ if(NAMEOF(src, light_power))
+ if(light_system == STATIC_LIGHT)
+ set_light(l_power = var_value)
+ else
+ set_light_power(var_value)
+ . = TRUE
+ if(NAMEOF(src, light_color))
+ if(light_system == STATIC_LIGHT)
+ set_light(l_color = var_value)
+ else
+ set_light_color(var_value)
+ . = TRUE
+ if(NAMEOF(src, light_angle))
+ if(light_system == STATIC_LIGHT)
+ set_light(l_angle = var_value)
+ . = TRUE
+ if(NAMEOF(src, light_dir))
+ if(light_system == STATIC_LIGHT)
+ set_light(l_dir = var_value)
+ . = TRUE
+ if(NAMEOF(src, light_on))
+ set_light_on(var_value)
+ . = TRUE
+ if(NAMEOF(src, light_flags))
+ set_light_flags(var_value)
+ // I'm sorry
+ old_light_flags = var_value
+ . = TRUE
+
+ light_flags = old_light_flags
+ if(!isnull(.))
+ datum_flags |= DF_VAR_EDITED
+ return
+
if(!GLOB.Debug2)
flags_1 |= ADMIN_SPAWNED_1
- . = ..()
+
+ . = ..()
+
switch(var_name)
- if("color")
+ if(NAMEOF(src, color))
add_atom_colour(color, ADMIN_COLOUR_PRIORITY)
+ update_appearance()
+ if(NAMEOF(src, opacity))
+ set_opacity(var_value)
+ . = TRUE
/**
* Return the markup to for the dropdown list for the VV panel for this atom
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index caa5aa2f94d9..99dc8e01778b 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -61,7 +61,7 @@
var/affecting_dynamic_lumi = 0
-/atom/movable/Initialize(mapload)
+/atom/movable/Initialize(mapload, ...)
. = ..()
switch(blocks_emissive)
if(EMISSIVE_BLOCK_GENERIC)
@@ -71,8 +71,16 @@
em_block = new(src, render_target)
vis_contents += em_block
- if(light_system == MOVABLE_LIGHT)
- AddComponent(/datum/component/overlay_lighting)
+ if(opacity)
+ AddElement(/datum/element/light_blocking)
+
+ switch(light_system)
+ if(MOVABLE_LIGHT)
+ AddComponent(/datum/component/overlay_lighting)
+ if(MOVABLE_LIGHT_DIRECTIONAL)
+ AddComponent(/datum/component/overlay_lighting, is_directional = TRUE)
+ if(MOVABLE_LIGHT_BEAM)
+ AddComponent(/datum/component/overlay_lighting, is_directional = TRUE, is_beam = TRUE)
/atom/movable/Destroy(force)
QDEL_NULL(proximity_monitor)
@@ -85,8 +93,11 @@
//Restore air flow if we were blocking it (movables with ATMOS_PASS_PROC will need to do this manually if necessary)
if(((CanAtmosPass == ATMOS_PASS_DENSITY && density) || CanAtmosPass == ATMOS_PASS_NO) && isturf(loc))
CanAtmosPass = ATMOS_PASS_YES
- air_update_turf(TRUE)
+ air_update_turf()
loc.handle_atom_del(src)
+
+ if(opacity)
+ RemoveElement(/datum/element/light_blocking)
invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index d5dd024038f8..974f66f8a616 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -80,7 +80,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
var/antags_rolled = 0
/// CRATE DISCOUNT
var/discountedcrates = list( /datum/supply_pack/security/laser,
- /datum/supply_pack/security/helmets,
/datum/supply_pack/security/vending/security,
/datum/supply_pack/service/party)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 0b5069abaa5a..e9a990cd8e30 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -443,7 +443,7 @@
continue // No parent vent
// Stops Aliens getting stuck in small networks.
// See: Security, Virology
- if(temp_vent_parent.other_atmosmch.len > 20)
+ if(temp_vent_parent.other_atmos_machines.len > 20)
vents += temp_vent
if(!vents.len)
return FALSE
diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm
index a80f5056a844..00fd0a8cd15b 100644
--- a/code/game/gamemodes/extended/extended.dm
+++ b/code/game/gamemodes/extended/extended.dm
@@ -32,4 +32,4 @@
. += greenshift_message
print_command_report(., "Central Command Status Summary", announce = FALSE)
- priority_announce(greenshift_message, "Security Report", RANDOM_REPORT_SOUND)
+ priority_announce(greenshift_message, "Security Report", SSstation.announcer.get_rand_report_sound())
diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm
index 72c151b38701..4a923f59efac 100644
--- a/code/game/gamemodes/objective_items.dm
+++ b/code/game/gamemodes/objective_items.dm
@@ -150,12 +150,12 @@
if(!istype(o, /obj/item/tank))
continue
var/obj/item/tank/T = o
- found_amount += T.air_contents.get_moles(/datum/gas/plasma)
+ found_amount += T.air_contents.get_moles(GAS_PLASMA)
if (istype(objective.team, /datum/team/infiltrator))
for (var/area/A in world)
if (is_type_in_typecache(A, GLOB.infiltrator_objective_areas))
for (var/obj/item/tank/T in A.get_all_contents()) //Check for items
- found_amount += T.air_contents.get_moles(/datum/gas/plasma)
+ found_amount += T.air_contents.get_moles(GAS_PLASMA)
CHECK_TICK
CHECK_TICK
CHECK_TICK
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 7a57f1a3fe42..8a017d1be4f5 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -137,6 +137,9 @@ Class Procs:
/// Mobtype of last user. Typecast to [/mob/living] for initial() usage
var/mob/living/last_user_mobtype
+ ///Boolean on whether this machines interact with atmos
+ var/atmos_processing = FALSE
+
/obj/machinery/Initialize(mapload)
if(!armor)
armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70)
@@ -162,7 +165,7 @@ Class Procs:
power_change()
RegisterSignal(src, COMSIG_ENTER_AREA, PROC_REF(power_change))
-/obj/machinery/Destroy()
+/obj/machinery/Destroy(force=FALSE)
disconnect_from_network()
GLOB.machines.Remove(src)
if(!speed_process)
@@ -188,7 +191,7 @@ Class Procs:
/obj/machinery/emp_act(severity)
. = ..()
if(use_power && !stat && !(. & EMP_PROTECT_SELF))
- use_power(7500/severity)
+ use_power(750 * severity)
new /obj/effect/temp_visual/emp(loc)
/obj/machinery/proc/open_machine(drop = TRUE)
@@ -297,11 +300,7 @@ Class Procs:
var/mob/living/carbon/H = user
if(istype(H) && H.has_dna())
- if (H.dna.check_mutation(ACTIVE_HULK))
- to_chat(H, span_warning("HULK NOT NERD. HULK SMASH!!!"))
- return FALSE // hulks cant use machines
-
- else if(!Adjacent(user) && !H.dna.check_mutation(TK))
+ if(!Adjacent(user) && !H.dna.check_mutation(TK))
return FALSE // need to be close or have telekinesis
return TRUE
@@ -488,8 +487,8 @@ Class Procs:
I.play_tool_sound(src, 50)
setDir(turn(dir,-90))
to_chat(user, span_notice("You rotate [src]."))
- return 1
- return 0
+ return TRUE
+ return FALSE
/obj/proc/can_be_unfasten_wrench(mob/user, silent) //if we can unwrench this object; returns SUCCESSFUL_UNFASTEN and FAILED_UNFASTEN, which are both TRUE, or CANT_UNFASTEN, which isn't.
if(!(isfloorturf(loc) || istype(loc, /turf/open/indestructible)) && !anchored)
diff --git a/code/game/machinery/airlock_cycle_control.dm b/code/game/machinery/airlock_cycle_control.dm
index 852ac542b135..7a142582f6f5 100644
--- a/code/game/machinery/airlock_cycle_control.dm
+++ b/code/game/machinery/airlock_cycle_control.dm
@@ -113,12 +113,12 @@
qdel(wires)
wires = null
cut_links()
- SSair.atmos_machinery -= src
+ SSair_machinery.stop_processing_machine(src)
return ..()
/obj/machinery/advanced_airlock_controller/Initialize(mapload)
. = ..()
- SSair.atmos_machinery += src
+ SSair_machinery.start_processing_machine(src)
scan_on_late_init = mapload
if(mapload && (. != INITIALIZE_HINT_QDEL))
return INITIALIZE_HINT_LATELOAD
@@ -135,14 +135,12 @@
airlock.bolt()
/obj/machinery/advanced_airlock_controller/proc/update_cycle_icon(use_hash = FALSE)
- var/turf/location = get_turf(src)
- if(!location)
+ if(!isopenturf(get_turf(src)))
return
var/pressure = 0
- if(location)
- var/datum/gas_mixture/environment = location.return_air()
- if(environment)
- pressure = environment.return_pressure()
+ var/datum/gas_mixture/environment = return_air()
+ if(environment)
+ pressure = environment.return_pressure()
var/maxpressure = (exterior_pressure && (cyclestate == AIRLOCK_CYCLESTATE_OUTCLOSING || cyclestate == AIRLOCK_CYCLESTATE_OUTOPENING || cyclestate == AIRLOCK_CYCLESTATE_OUTOPEN)) ? exterior_pressure : interior_pressure
var/pressure_bars = round(pressure / maxpressure * 5 + 0.01)
@@ -295,15 +293,13 @@
update_cycle_icon(TRUE)
return
- var/turf/location = get_turf(src)
- if(!location)
+ if(!isopenturf(get_turf(src)))
update_cycle_icon(TRUE)
return
var/pressure = 0
- if(location)
- var/datum/gas_mixture/environment = location.return_air()
- if(environment)
- pressure = environment.return_pressure()
+ var/datum/gas_mixture/environment = return_air()
+ if(environment)
+ pressure = environment.return_pressure()
update_error_status()
var/doors_valid = TRUE
@@ -596,10 +592,9 @@
ui.open()
/obj/machinery/advanced_airlock_controller/ui_data(mob/user)
- var/turf/T = get_turf(src)
var/pressure = 0
- if(T)
- var/datum/gas_mixture/environment = T.return_air()
+ if(isopenturf(get_turf(src)))
+ var/datum/gas_mixture/environment = return_air()
if(environment)
pressure = environment.return_pressure()
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 1b20666ac44c..a36956f5459f 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -144,7 +144,7 @@
if(!status)
return
if(!(. & EMP_PROTECT_SELF))
- if(prob(150/severity))
+ if(prob(15 * severity))
update_appearance(UPDATE_ICON)
var/list/previous_network = network
network = list()
@@ -164,7 +164,7 @@
if(can_use())
GLOB.cameranet.addCamera(src)
emped = 0 //Resets the consecutive EMP count
- addtimer(CALLBACK(src, PROC_REF(cancelCameraAlarm)), 100)
+ addtimer(CALLBACK(src, PROC_REF(cancelCameraAlarm)), severity SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
for(var/i in GLOB.player_list)
var/mob/M = i
if (M.client.eye == src)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index f009648e90b6..4d8f22c4f9ef 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -532,7 +532,7 @@ GLOBAL_VAR_INIT(clones, 0)
. = ..()
if (!(. & EMP_PROTECT_SELF))
var/mob/living/mob_occupant = occupant
- if(mob_occupant && prob(100/(severity*efficiency)))
+ if(mob_occupant && prob(10 * severity / efficiency))
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to EMP pulse.")
connected_message(Gibberish("EMP-caused Accidental Ejection", 0))
SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [mob_occupant.real_name] prematurely." ,0))
diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm
index 50682a895aea..c0077e4fa619 100644
--- a/code/game/machinery/computer/_computer.dm
+++ b/code/game/machinery/computer/_computer.dm
@@ -103,9 +103,9 @@
if(!.)
return // reduce unneeded light changes
if(stat & NOPOWER)
- set_light(FALSE)
+ set_light_on(FALSE)
else
- set_light(TRUE)
+ set_light_on(TRUE)
/obj/machinery/computer/screwdriver_act(mob/living/user, obj/item/I)
if(..())
@@ -133,18 +133,14 @@
. = ..()
if(.)
playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE)
- set_light(0)
+ set_light_on(FALSE)
/obj/machinery/computer/emp_act(severity)
. = ..()
- if (!(. & EMP_PROTECT_SELF))
- switch(severity)
- if(1)
- if(prob(50))
- obj_break(ENERGY)
- if(2)
- if(prob(10))
- obj_break(ENERGY)
+ if(. & EMP_PROTECT_SELF)
+ return
+ if(prob(5 * severity))
+ obj_break(ENERGY)
/obj/machinery/computer/deconstruct(disassembled = TRUE, mob/user)
on_deconstruction()
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index a124b493fa5d..7c6a41699814 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -120,12 +120,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
return
var/empprize = null
- var/num_of_prizes = 0
- switch(severity)
- if(1)
- num_of_prizes = rand(1,4)
- if(2)
- num_of_prizes = rand(0,2)
+ var/num_of_prizes = rand(0, severity / 2.5)
for(var/i = num_of_prizes; i > 0; i--)
if(override)
empprize = pickweight(prize_override)
diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm
index 0a54ea2f031e..97383ec1c85c 100644
--- a/code/game/machinery/computer/atmos_alert.dm
+++ b/code/game/machinery/computer/atmos_alert.dm
@@ -4,13 +4,18 @@
circuit = /obj/item/circuitboard/computer/atmos_alert
icon_screen = "alert:0"
icon_keyboard = "atmos_key"
- var/list/priority_alarms = list()
- var/list/minor_alarms = list()
- var/receive_frequency = FREQ_ATMOS_ALARMS
- var/datum/radio_frequency/radio_connection
-
light_color = LIGHT_COLOR_CYAN
+ ///List of areas with a priority alarm ongoing.
+ var/list/area/priority_alarms = list()
+ ///List of areas with a minor alarm ongoing.
+ var/list/area/minor_alarms = list()
+
+ ///The radio connection the computer uses to receive signals.
+ var/datum/radio_frequency/radio_connection
+ ///The frequency that radio_connection listens and retrieves signals from.
+ var/receive_frequency = FREQ_ATMOS_ALARMS
+
/obj/machinery/computer/atmos_alert/Initialize(mapload)
. = ..()
set_frequency(receive_frequency)
@@ -27,31 +32,43 @@
/obj/machinery/computer/atmos_alert/ui_data(mob/user)
var/list/data = list()
+ data["priority_alerts"] = list()
+ data["minor_alerts"] = list()
+
+ for(var/area/priority_alarm as anything in priority_alarms)
+ data["priority_alerts"] += list(list(
+ "name" = priority_alarm.name,
+ "ref" = REF(priority_alarm),
+ ))
- data["priority"] = list()
- for(var/zone in priority_alarms)
- data["priority"] += zone
- data["minor"] = list()
- for(var/zone in minor_alarms)
- data["minor"] += zone
+ for(var/area/minor_alarm as anything in minor_alarms)
+ data["minor_alerts"] += list(list(
+ "name" = minor_alarm.name,
+ "ref" = REF(minor_alarm),
+ ))
return data
/obj/machinery/computer/atmos_alert/ui_act(action, params)
- if(..())
- return
- switch(action)
- if("clear")
- var/zone = params["zone"]
- if(zone in priority_alarms)
- to_chat(usr, "Priority alarm for [zone] cleared.")
- priority_alarms -= zone
- . = TRUE
- if(zone in minor_alarms)
- to_chat(usr, "Minor alarm for [zone] cleared.")
- minor_alarms -= zone
- . = TRUE
- update_appearance(UPDATE_ICON)
+ . = ..()
+ if(.)
+ return TRUE
+ if(action != "clear")
+ return TRUE
+
+ var/area/zone_from_tgui = locate(params["zone_ref"]) in priority_alarms + minor_alarms
+ if(!zone_from_tgui || !istype(zone_from_tgui))
+ return TRUE
+
+ var/obj/machinery/airalarm/found_air_alarm = locate() in zone_from_tgui
+ if(found_air_alarm)
+ found_air_alarm.atmos_manualOverride(TRUE)
+ found_air_alarm.post_alert(0)
+ priority_alarms -= zone_from_tgui
+ minor_alarms -= zone_from_tgui
+ balloon_alert(usr, "alarm cleared.")
+ update_appearance(UPDATE_ICON)
+ return TRUE
/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency)
SSradio.remove_object(src, receive_frequency)
@@ -62,25 +79,27 @@
if(!signal)
return
- var/zone = signal.data["zone"]
+ var/area/new_zone = signal.data["zone"]
var/severity = signal.data["alert"]
-
- if(!zone || !severity)
+ if(!new_zone || !istype(new_zone) || !severity)
return
- minor_alarms -= zone
- priority_alarms -= zone
- if(severity == "severe")
- priority_alarms += zone
- else if (severity == "minor")
- minor_alarms += zone
+ //clear current references.
+ minor_alarms -= new_zone
+ priority_alarms -= new_zone
+
+ switch(severity)
+ if(ATMOS_ALARM_SEVERE)
+ priority_alarms += new_zone
+ if(ATMOS_ALARM_MINOR)
+ minor_alarms += new_zone
update_appearance(UPDATE_ICON)
- return
/obj/machinery/computer/atmos_alert/update_overlays()
. = ..()
if(stat & (NOPOWER|BROKEN))
return
+
if(priority_alarms.len)
. += "alert:2"
else if(minor_alarms.len)
diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm
index 7474377cc462..7ed11ce00534 100644
--- a/code/game/machinery/computer/atmos_control.dm
+++ b/code/game/machinery/computer/atmos_control.dm
@@ -61,7 +61,7 @@
var/total_moles = air_sample.total_moles()
if(total_moles)
for(var/gas_id in air_sample.get_gases())
- var/gas_name = GLOB.meta_gas_info[gas_id][META_GAS_NAME]
+ var/gas_name = GLOB.gas_data.names[gas_id]
signal.data["gases"][gas_name] = air_sample.get_moles(gas_id) / total_moles * 100
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
@@ -74,11 +74,11 @@
/obj/machinery/air_sensor/Initialize(mapload)
. = ..()
- SSair.atmos_machinery += src
+ SSair_machinery.start_processing_machine(src)
set_frequency(frequency)
/obj/machinery/air_sensor/Destroy()
- SSair.atmos_machinery -= src
+ SSair_machinery.stop_processing_machine(src)
SSradio.remove_object(src, frequency)
return ..()
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 2914a3fbdf0b..a4661b57163d 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -252,7 +252,7 @@
nuke_request(reason, usr)
to_chat(usr, span_notice("Request sent."))
usr.log_message("has requested the nuclear codes from CentCom with reason \"[reason]\"", LOG_SAY)
- priority_announce("The codes for the on-station nuclear self-destruct have been requested by [authorize_name]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", RANDOM_REPORT_SOUND)
+ priority_announce("The codes for the on-station nuclear self-destruct have been requested by [authorize_name]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", SSstation.announcer.get_rand_report_sound())
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("restoreBackupRoutingData")
@@ -364,7 +364,7 @@
playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1)
new /obj/item/card/id/captains_spare/temporary(loc)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
- priority_announce("The emergency spare ID has been printed by [authorize_name].", "Emergency Spare ID Warning System", RANDOM_REPORT_SOUND)
+ priority_announce("The emergency spare ID has been printed by [authorize_name].", "Emergency Spare ID Warning System", SSstation.announcer.get_rand_report_sound())
if("printAIControlCode")
if(authenticated_as_non_silicon_head(usr))
if(!COOLDOWN_FINISHED(src, important_action_cooldown))
@@ -373,7 +373,7 @@
GLOB.ai_control_code = random_nukecode(6)
new /obj/item/paper/ai_control_code(loc)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
- priority_announce("The AI Control Code been printed by [authorize_name]. All previous codes have been invalidated.", "Central Tech Support", RANDOM_REPORT_SOUND)
+ priority_announce("The AI Control Code been printed by [authorize_name]. All previous codes have been invalidated.", "Central Tech Support", SSstation.announcer.get_rand_report_sound())
/obj/machinery/computer/communications/ui_data(mob/user)
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index 8fcbfe3f7298..cefddeb1eda1 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -721,6 +721,9 @@
// GUARD CHECK - This should not be possible. Unexpected result
if(!HM)
return
+ if(!HM.allow_cloning)
+ say("ERROR: This mutation is anomalous, and cannot be saved.")
+ return
var/datum/mutation/human/A = new HM.type()
A.copy_mutation(HM)
@@ -1389,6 +1392,9 @@
// GUARD CHECK - This should not be possible. Unexpected result
if(!HM)
return
+ if(!HM.allow_cloning)
+ say("ERROR: This mutation is anomalous, and cannot be added to an injector.")
+ return
// We want to make sure we stick within the instability limit.
// We start with the instability of the mutation we're intending to add.
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index cf7ed783af0b..a26d877798de 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -534,7 +534,7 @@
. = ..()
if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF))
for(var/datum/data/record/R in GLOB.data_core.medical)
- if(prob(10/severity))
+ if(prob(severity))
switch(rand(1,6))
if(1)
if(prob(10))
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 4c3a77264c0d..bd642b99f661 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -875,7 +875,7 @@
return
for(var/datum/data/record/R in GLOB.data_core.security)
- if(prob(10/severity))
+ if(prob(severity))
switch(rand(1,8))
if(1)
if(prob(10))
diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm
index 1b203509452c..a27c9c1275b7 100644
--- a/code/game/machinery/computer/station_alert.dm
+++ b/code/game/machinery/computer/station_alert.dm
@@ -45,6 +45,7 @@
var/list/sources = alarm[3]
if (!(source in sources))
sources += source
+ update_appearance(UPDATE_ICON)
return 1
var/obj/machinery/camera/C = null
var/list/CL = null
@@ -55,6 +56,7 @@
else if(O && istype(O, /obj/machinery/camera))
C = O
L[A.name] = list(A, (C ? C : O), list(source))
+ update_appearance(UPDATE_ICON)
return 1
@@ -72,6 +74,7 @@
if (srcs.len == 0)
cleared = 1
L -= I
+ update_appearance(UPDATE_ICON)
return !cleared
/obj/machinery/computer/station_alert/update_overlays()
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index b8112fb735e7..8fb9435b6e7c 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -374,7 +374,7 @@ GLOBAL_VAR_INIT(cryopods_enabled, FALSE)
return
if(!GLOB.cryopods_enabled)
- to_chat(user, span_boldnotice("NanoTrasen does not allow abandoning your crew during a crisis. Cryo systems disabled until the current crisis is resolved."))
+ to_chat(user, span_boldnotice("Nanotrasen does not allow abandoning your crew during a crisis. Cryo systems disabled until the current crisis is resolved."))
return
if(occupant)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 7d9f72c774f2..fcb931fa2f4a 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -507,12 +507,9 @@
else
return
else if(user.has_status_effect(/datum/status_effect/hallucination) && ishuman(user) && prob(1) && !operating)
- var/mob/living/carbon/human/H = user
- if(H.gloves)
- var/obj/item/clothing/gloves/G = H.gloves
- if(G.siemens_coefficient)//not insulated
- new /datum/hallucination/shock(H)
- return
+ if(user.getarmor(user.held_index_to_body_zone(user.active_hand_index), ELECTRIC) < 100)
+ new /datum/hallucination/shock(user)
+ return
var/allowed = (obj_flags & CMAGGED) ? cmag_allowed(user) : allowed(user)
if (cyclelinkedairlock)
if (!shuttledocked && !emergency && !cyclelinkedairlock.shuttledocked && !cyclelinkedairlock.emergency && allowed)
@@ -1427,7 +1424,7 @@
sleep(0.1 SECONDS)
density = FALSE
sleep(0.3 SECONDS)
- air_update_turf(1)
+ air_update_turf()
sleep(0.1 SECONDS)
layer = OPEN_DOOR_LAYER
update_icon(state = AIRLOCK_OPEN, override = TRUE)
@@ -1469,11 +1466,11 @@
layer = CLOSED_DOOR_LAYER
if(air_tight)
density = TRUE
- air_update_turf(1)
+ air_update_turf()
sleep(0.1 SECONDS)
density = TRUE
if(!air_tight)
- air_update_turf(1)
+ air_update_turf()
sleep(0.4 SECONDS)
if(!safe)
crush()
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index 5204102cb6c1..4607882135b0 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -64,7 +64,7 @@
*/
/obj/machinery/door/airlock/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/glass/incinerator
@@ -82,28 +82,28 @@
id_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_EXTERIOR
/obj/machinery/door/airlock/command/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
normal_integrity = 400
/obj/machinery/door/airlock/engineering/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/engineering/glass/critical
critical_machine = TRUE //stops greytide virus from opening & bolting doors in critical positions, such as the SM chamber.
/obj/machinery/door/airlock/security/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
normal_integrity = 400
/obj/machinery/door/airlock/medical/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/research/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/research/glass/incinerator
@@ -121,30 +121,30 @@
id_tag = INCINERATOR_TOXMIX_AIRLOCK_EXTERIOR
/obj/machinery/door/airlock/mining/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/atmos/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/atmos/glass/critical
critical_machine = TRUE //stops greytide virus from opening & bolting doors in critical positions, such as the SM chamber.
/obj/machinery/door/airlock/science/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/virology/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/maintenance/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/maintenance/external/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
normal_integrity = 200
@@ -159,7 +159,7 @@
assemblytype = /obj/structure/door_assembly/door_assembly_gold
/obj/machinery/door/airlock/gold/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/silver
@@ -168,7 +168,7 @@
assemblytype = /obj/structure/door_assembly/door_assembly_silver
/obj/machinery/door/airlock/silver/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/diamond
@@ -180,7 +180,7 @@
/obj/machinery/door/airlock/diamond/glass
normal_integrity = 950
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/uranium
@@ -201,7 +201,7 @@
return
/obj/machinery/door/airlock/uranium/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/plasma
@@ -229,8 +229,8 @@
DA.update_appearance()
qdel(src)
-/obj/machinery/door/airlock/plasma/BlockSuperconductivity() //we don't stop the heat~
- return 0
+/obj/machinery/door/airlock/plasma/BlockThermalConductivity() //we don't stop the heat~
+ return FALSE
/obj/machinery/door/airlock/plasma/attackby(obj/item/C, mob/user, params)
if(C.is_hot() > 300)//If the temperature of the object is over 300, then ignite
@@ -241,7 +241,7 @@
return ..()
/obj/machinery/door/airlock/plasma/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/bananium
@@ -252,7 +252,7 @@
doorOpen = 'sound/items/bikehorn.ogg'
/obj/machinery/door/airlock/bananium/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/sandstone
@@ -261,7 +261,7 @@
assemblytype = /obj/structure/door_assembly/door_assembly_sandstone
/obj/machinery/door/airlock/sandstone/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/wood
@@ -270,7 +270,7 @@
assemblytype = /obj/structure/door_assembly/door_assembly_wood
/obj/machinery/door/airlock/wood/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/titanium
@@ -283,7 +283,7 @@
/obj/machinery/door/airlock/titanium/glass
normal_integrity = 350
- opacity = 0
+ opacity = FALSE
glass = TRUE
//////////////////////////////////
@@ -297,7 +297,7 @@
assemblytype = /obj/structure/door_assembly/door_assembly_public
/obj/machinery/door/airlock/public/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/public/glass/incinerator
@@ -330,7 +330,7 @@
panel_attachment = "bottom"
/obj/machinery/door/airlock/external/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
//////////////////////////////////
@@ -426,7 +426,7 @@
anim_parts = "rightu=11,0;left=-12,0;right=11,0"
/obj/machinery/door/airlock/shuttle/glass
- opacity = 0
+ opacity = FALSE
glass = TRUE
/obj/machinery/door/airlock/abductor
@@ -521,7 +521,7 @@
/obj/machinery/door/airlock/cult/glass
glass = TRUE
- opacity = 0
+ opacity = FALSE
/obj/machinery/door/airlock/cult/glass/friendly
friendly = TRUE
@@ -537,7 +537,7 @@
/obj/machinery/door/airlock/cult/unruned/glass
glass = TRUE
- opacity = 0
+ opacity = FALSE
/obj/machinery/door/airlock/cult/unruned/glass/friendly
friendly = TRUE
@@ -586,7 +586,7 @@
. += gear_text
/obj/machinery/door/airlock/clockwork/emp_act(severity)
- if(prob(80/severity))
+ if(prob(8 * severity))
open()
/obj/machinery/door/airlock/clockwork/canAIControl(mob/user)
@@ -664,7 +664,7 @@
/obj/machinery/door/airlock/clockwork/brass
glass = TRUE
- opacity = 0
+ opacity = FALSE
//////////////////////////////////
/*
@@ -678,7 +678,7 @@
mask_file = 'icons/obj/doors/airlocks/mask_64x32_airlocks.dmi'
mask_x = 16 // byond is consistent and sane
anim_parts = "left=-21,0;right=21,0;top=0,29"
- opacity = 0
+ opacity = FALSE
assemblytype = null
glass = TRUE
bound_width = 64 // 2x1
diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm
index 52940e6d0081..4b83bf63ed93 100644
--- a/code/game/machinery/doors/alarmlock.dm
+++ b/code/game/machinery/doors/alarmlock.dm
@@ -2,7 +2,7 @@
name = "glass alarm airlock"
icon = 'icons/obj/doors/airlocks/station2/glass.dmi'
overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi'
- opacity = 0
+ opacity = FALSE
assemblytype = /obj/structure/door_assembly/door_assembly_public
glass = TRUE
@@ -35,9 +35,9 @@
if(alarm_area == get_area_name(src))
switch(alert)
- if("severe")
+ if(ATMOS_ALARM_SEVERE)
autoclose = TRUE
close()
- if("minor", "clear")
+ if(ATMOS_ALARM_MINOR, ATMOS_ALARM_CLEAR)
autoclose = FALSE
- open()
\ No newline at end of file
+ open()
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 20a82701e250..4d298a074a71 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -3,7 +3,7 @@
desc = "It opens and closes."
icon = 'icons/obj/doors/Doorint.dmi'
icon_state = "door1"
- opacity = 1
+ opacity = TRUE
density = TRUE
move_resist = MOVE_FORCE_VERY_STRONG
layer = OPEN_DOOR_LAYER
@@ -83,7 +83,7 @@
. = ..()
set_init_door_layer()
update_freelook_sight()
- air_update_turf(1)
+ air_update_turf()
GLOB.airlocks += src
spark_system = new /datum/effect_system/spark_spread
spark_system.set_up(2, 1, src)
@@ -103,7 +103,7 @@
else
layer = initial(layer)
-/obj/machinery/door/Destroy()
+/obj/machinery/door/Destroy(force=FALSE)
update_freelook_sight()
GLOB.airlocks -= src
if(spark_system)
@@ -263,9 +263,9 @@
var/max_moles = min_moles
// okay this is a bit hacky. First, we set density to 0 and recalculate our adjacent turfs
density = FALSE
- T.ImmediateCalculateAdjacentTurfs()
+ var/list/adj_turfs = T.get_adjacent_atmos_turfs()
// then we use those adjacent turfs to figure out what the difference between the lowest and highest pressures we'd be holding is
- for(var/turf/open/T2 in T.atmos_adjacent_turfs)
+ for(var/turf/open/T2 in adj_turfs)
if((flags_1 & ON_BORDER_1) && get_dir(src, T2) != dir)
continue
var/moles = T2.air.total_moles()
@@ -274,7 +274,6 @@
if(moles > max_moles)
max_moles = moles
density = TRUE
- T.ImmediateCalculateAdjacentTurfs() // alright lets put it back
return max_moles - min_moles > 20
/obj/machinery/door/attackby(obj/item/I, mob/user, params)
@@ -316,9 +315,9 @@
. = ..()
if (. & EMP_PROTECT_SELF)
return
- if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
+ if(prob(2 * severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
INVOKE_ASYNC(src, PROC_REF(open))
- if(prob(severity*10 - 20))
+ if(prob(severity*2 - 20))
if(secondsElectrified == MACHINE_NOT_ELECTRIFIED)
secondsElectrified = MACHINE_ELECTRIFIED_PERMANENT
LAZYADD(shockedby, "\[[time_stamp()]\]EM Pulse")
@@ -366,7 +365,7 @@
update_appearance(UPDATE_ICON)
set_opacity(0)
operating = FALSE
- air_update_turf(1)
+ air_update_turf()
update_freelook_sight()
if(autoclose)
spawn(autoclose)
@@ -398,7 +397,7 @@
if(visible && !glass)
set_opacity(1)
operating = FALSE
- air_update_turf(1)
+ air_update_turf()
update_freelook_sight()
if(safe)
CheckForMobs()
@@ -454,8 +453,8 @@
if(!glass && GLOB.cameranet)
GLOB.cameranet.updateVisibility(src, 0)
-/obj/machinery/door/BlockSuperconductivity() // All non-glass airlocks block heat, this is intended.
- if(opacity || heat_proof)
+/obj/machinery/door/BlockThermalConductivity() // All non-glass airlocks block heat, this is intended.
+ if(heat_proof && density)
return TRUE
return FALSE
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 329686d9fea2..eb8f08bcdf05 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -70,10 +70,7 @@
/obj/machinery/door/firedoor/Destroy()
remove_from_areas()
affecting_areas.Cut()
- var/turf/T = get_turf(src)
- spawn(0)
- if(T)
- T.ImmediateCalculateAdjacentTurfs()
+ air_update_turf()
return ..()
/obj/machinery/door/firedoor/Bumped(atom/movable/AM)
@@ -222,6 +219,7 @@
else
icon_state = "door_open"
SSdemo.mark_dirty(src)
+ air_update_turf()
/obj/machinery/door/firedoor/update_overlays()
. = ..()
@@ -240,17 +238,15 @@
. = ..()
latetoggle()
-/obj/machinery/door/firedoor/proc/whack_a_mole(reconsider_immediately = FALSE)
- set waitfor = 0
+/obj/machinery/door/firedoor/proc/whack_a_mole()
for(var/cdir in GLOB.cardinals)
if((flags_1 & ON_BORDER_1) && cdir != dir)
continue
- whack_a_mole_part(get_step(src, cdir), reconsider_immediately)
+ whack_a_mole_part(get_step(src, cdir))
if(flags_1 & ON_BORDER_1)
- whack_a_mole_part(get_turf(src), reconsider_immediately)
+ whack_a_mole_part(get_turf(src))
-/obj/machinery/door/firedoor/proc/whack_a_mole_part(turf/start_point, reconsider_immediately)
- set waitfor = 0
+/obj/machinery/door/firedoor/proc/whack_a_mole_part(turf/start_point)
var/list/doors_to_close = list()
var/list/turfs = list()
turfs[start_point] = 1
@@ -283,17 +279,24 @@
return // too big, don't bother
for(var/obj/machinery/door/firedoor/FD in doors_to_close)
FD.emergency_pressure_stop(FALSE)
- if(reconsider_immediately)
- var/turf/open/T = FD.loc
- if(istype(T))
- T.ImmediateCalculateAdjacentTurfs()
/obj/machinery/door/firedoor/proc/emergency_pressure_stop(consider_timer = TRUE)
- set waitfor = 0
if(density || operating || welded)
return
if(world.time >= emergency_close_timer || !consider_timer)
- close()
+ emergency_pressure_close()
+
+//this is here to prevent sleeps from messing with decomp, by closing firedoors instantly
+/obj/machinery/door/firedoor/proc/emergency_pressure_close()
+ density = TRUE
+ air_update_turf()
+ layer = closingLayer
+ update_icon()
+ if(visible && !glass)
+ set_opacity(1)
+ update_freelook_sight()
+ if(!(flags_1 & ON_BORDER_1))
+ crush()
/obj/machinery/door/firedoor/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1) && disassembled)
@@ -330,6 +333,14 @@
return TRUE
if(operating || welded)
return
+ check_pulls()
+ . = ..()
+
+/obj/machinery/door/firedoor/border_only/emergency_pressure_close()
+ check_pulls()
+ . = ..()
+
+/obj/machinery/door/firedoor/border_only/proc/check_pulls()
var/turf/T1 = get_turf(src)
var/turf/T2 = get_step(T1, dir)
for(var/mob/living/M in T1)
@@ -347,7 +358,6 @@
to_chat(M, span_notice("You pull [M.pulling] through [src] right as it closes"))
M.pulling.forceMove(T2)
M.start_pulling(M2)
- . = ..()
/obj/machinery/door/firedoor/border_only/allow_hand_open(mob/user)
var/area/A = get_area(src)
@@ -401,6 +411,11 @@
else
return TRUE
+/obj/machinery/door/firedoor/border_only/BlockThermalConductivity(opp_dir)
+ if(opp_dir == dir)
+ return density
+ return FALSE
+
/obj/machinery/door/firedoor/heavy
name = "heavy firelock"
icon = 'icons/obj/doors/doorfire.dmi'
diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index 8d5c39cf8c1e..58640614c6e9 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -22,7 +22,7 @@
/obj/machinery/door/poddoor/preopen
icon_state = "open"
density = FALSE
- opacity = 0
+ opacity = FALSE
/obj/machinery/door/poddoor/ert
name = "ERT Armory door"
diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm
index d4f383e0b925..6f71f57d5759 100644
--- a/code/game/machinery/doors/shutters.dm
+++ b/code/game/machinery/doors/shutters.dm
@@ -11,7 +11,7 @@
/obj/machinery/door/poddoor/shutters/preopen
icon_state = "open"
density = FALSE
- opacity = 0
+ opacity = FALSE
/obj/machinery/door/poddoor/shutters/window
name = "windowed shutters"
diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm
index 0f7fd4ec4da7..6e14893f9e8b 100644
--- a/code/game/machinery/doors/unpowered.dm
+++ b/code/game/machinery/doors/unpowered.dm
@@ -20,6 +20,6 @@
icon = 'icons/turf/shuttle.dmi'
name = "door"
icon_state = "door1"
- opacity = 1
+ opacity = TRUE
density = TRUE
explosion_block = 1
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index edb6ef9f4a75..57f0db385dd8 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -12,7 +12,7 @@
armor = list(MELEE = 60, BULLET = -40, LASER = 50, ENERGY = 50, BOMB = 10, BIO = 100, RAD = 100, FIRE = 70, ACID = 100)
visible = FALSE
flags_1 = ON_BORDER_1
- opacity = 0
+ opacity = FALSE
CanAtmosPass = ATMOS_PASS_PROC
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
var/obj/item/electronics/airlock/electronics = null
@@ -158,7 +158,7 @@
sleep(1 SECONDS)
density = FALSE
- air_update_turf(1)
+ air_update_turf()
update_freelook_sight()
if(operating == 1) //emag again
@@ -180,7 +180,7 @@
icon_state = base_state
density = TRUE
- air_update_turf(1)
+ air_update_turf()
update_freelook_sight()
sleep(1 SECONDS)
@@ -423,7 +423,7 @@
return ..()
/obj/machinery/door/window/clockwork/emp_act(severity)
- if(prob(80/severity))
+ if(prob(8 * severity))
open()
/obj/machinery/door/window/clockwork/ratvar_act()
diff --git a/code/game/machinery/electrolyzer.dm b/code/game/machinery/electrolyzer.dm
index a3b56108a132..1460a455aec0 100644
--- a/code/game/machinery/electrolyzer.dm
+++ b/code/game/machinery/electrolyzer.dm
@@ -63,7 +63,7 @@
if(panel_open)
. += "electrolyzer-open"
-/obj/machinery/electrolyzer/process(delta_time)
+/obj/machinery/electrolyzer/process_atmos()
if((stat & (BROKEN|MAINT)) && on)
on = FALSE
if(!on)
@@ -76,8 +76,7 @@
update_appearance(UPDATE_ICON)
return FALSE
- var/turf/L = loc
- if(!istype(L))
+ if(!isopenturf(get_turf(src)))
if(mode != ELECTROLYZER_MODE_STANDBY)
mode = ELECTROLYZER_MODE_STANDBY
update_appearance(UPDATE_ICON)
@@ -92,24 +91,23 @@
if(mode == ELECTROLYZER_MODE_STANDBY)
return
- var/datum/gas_mixture/env = L.return_air() //get air from the turf
+ var/datum/gas_mixture/env = return_air() //get air from the turf
var/datum/gas_mixture/removed = env.remove(0.1 * env.total_moles())
if(!removed)
return
var/proportion = 0
- if(removed.get_moles(/datum/gas/water_vapor))
- proportion = min(removed.get_moles(/datum/gas/water_vapor), (3 * delta_time * workingPower)) //Works to max 12 moles at a time.
- removed.adjust_moles(/datum/gas/water_vapor, -proportion)
- removed.adjust_moles(/datum/gas/oxygen, proportion / 2)
- removed.adjust_moles(/datum/gas/hydrogen, proportion)
- if(removed.get_moles(/datum/gas/hypernoblium))
- proportion = min(removed.get_moles(/datum/gas/hypernoblium), (delta_time * workingPower)) // up to 4 moles at a time
- removed.adjust_moles(/datum/gas/hypernoblium, -proportion)
- removed.adjust_moles(/datum/gas/antinoblium, proportion)
+ if(removed.get_moles(GAS_H2O))
+ proportion = min(removed.get_moles(GAS_H2O), (3 * workingPower)) //Works to max 12 moles at a time.
+ removed.adjust_moles(GAS_H2O, -proportion)
+ removed.adjust_moles(GAS_O2, proportion / 2)
+ removed.adjust_moles(GAS_H2, proportion)
+ if(removed.get_moles(GAS_HYPERNOB))
+ proportion = min(removed.get_moles(GAS_HYPERNOB), workingPower) // up to 4 moles at a time
+ removed.adjust_moles(GAS_HYPERNOB, -proportion)
+ removed.adjust_moles(GAS_ANTINOB, proportion)
env.merge(removed) //put back the new gases in the turf
- air_update_turf()
var/working = TRUE
@@ -205,7 +203,9 @@
usr.visible_message(span_notice("[usr] switches [on ? "on" : "off"] \the [src]."), span_notice("You switch [on ? "on" : "off"] \the [src]."))
update_appearance(UPDATE_ICON)
if (on)
- START_PROCESSING(SSmachines, src)
+ SSair_machinery.start_processing_machine(src)
+ else
+ SSair_machinery.stop_processing_machine(src)
. = TRUE
if("eject")
if(panel_open && cell)
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index 6a4ca14b1339..99b5a4987ec9 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -30,10 +30,20 @@
light_range = 7
light_color = "#ff3232"
+ /// 1 = will auto detect fire, 0 = no auto
var/detecting = 1
- var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
+ /// 2 = complete, 1 = no wires, 0 = circuit gone
+ var/buildstage = 2
+ /// Cooldown for next alarm trigger, so it doesnt spam much
var/last_alarm = 0
+ /// The area of the current fire alarm
var/area/myarea = null
+ /// If true, then this area has a real fire and not by someone triggering it manually
+ var/real_fire = FALSE
+ /// If real_fire is true then it will show you the current hot temperature
+ var/bad_temp = null
+ /// The radio to alert engineers, atmos techs
+ var/obj/item/radio/radio
/obj/machinery/firealarm/Initialize(mapload, dir, building)
. = ..()
@@ -47,8 +57,16 @@
update_appearance(UPDATE_ICON)
myarea = get_area(src)
LAZYADD(myarea.firealarms, src)
+ radio = new(src)
+ radio.keyslot = new /obj/item/encryptionkey/headset_eng()
+ radio.subspace_transmission = TRUE
+ radio.canhear_range = 0
+ radio.recalculateChannels()
+ STOP_PROCESSING(SSmachines, src) // I will do this
/obj/machinery/firealarm/Destroy()
+ myarea.firereset(src, TRUE)
+ QDEL_NULL(radio)
LAZYREMOVE(myarea.firealarms, src)
return ..()
@@ -101,7 +119,7 @@
if (. & EMP_PROTECT_SELF)
return
- if(prob(50 / severity))
+ if(prob(5 * severity))
alarm()
/obj/machinery/firealarm/emag_act(mob/user, obj/item/card/emag/emag_card)
@@ -115,18 +133,42 @@
playsound(src, "sparks", 50, 1)
return TRUE
+/obj/machinery/firealarm/examine(mob/user)
+ . = ..()
+ if(areafire_check())
+ . += span_danger("Fire detected in this area, current fire alarm temperature: [bad_temp-T0C]C")
+ else
+ . += span_notice("There's no fire detected.")
+
/obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume)
var/turf/open/T = get_turf(src)
if((temperature >= FIRE_MINIMUM_TEMPERATURE_TO_EXIST || temperature < BODYTEMP_COLD_DAMAGE_LIMIT || (istype(T) && T.turf_fire)) && (last_alarm+FIREALARM_COOLDOWN < world.time) && !(obj_flags & EMAGGED) && detecting && !stat)
+ if(!real_fire)
+ radio.talk_into(src, "Fire detected in [myarea].", RADIO_CHANNEL_ENGINEERING)
+ real_fire = TRUE
+ bad_temp = temperature
alarm()
+ START_PROCESSING(SSmachines, src)
..()
+/obj/machinery/firealarm/process() //Fire alarm only start processing when its triggered by temperature_expose()
+ var/turf/open/T = get_turf(src)
+ var/datum/gas_mixture/env = T.return_air()
+ if(env.return_temperature() < FIRE_MINIMUM_TEMPERATURE_TO_EXIST && env.return_temperature() > BODYTEMP_COLD_DAMAGE_LIMIT && (istype(T) && !T.turf_fire))
+ real_fire = FALSE
+ STOP_PROCESSING(SSmachines, src)
+
+/obj/machinery/firealarm/proc/areafire_check()
+ for(var/obj/machinery/firealarm/FA in myarea.firealarms)
+ if(FA.real_fire)
+ return TRUE
+ return FALSE
+
/obj/machinery/firealarm/proc/alarm(mob/user)
if(!is_operational() || (last_alarm+FIREALARM_COOLDOWN > world.time))
return
last_alarm = world.time
- var/area/A = get_area(src)
- A.firealert(src)
+ myarea.firealert(src)
playsound(loc, 'goon/sound/machinery/FireAlarm.ogg', 75)
if(user)
log_game("[user] triggered a fire alarm at [COORD(src)]")
@@ -134,8 +176,9 @@
/obj/machinery/firealarm/proc/reset(mob/user)
if(!is_operational())
return
- var/area/A = get_area(src)
- A.firereset(src)
+ for(var/obj/machinery/firealarm/F in myarea.firealarms)
+ F.myarea.firereset(F)
+ F.bad_temp = null
if(user)
log_game("[user] reset a fire alarm at [COORD(src)]")
@@ -144,8 +187,7 @@
return ..()
add_fingerprint(user)
play_click_sound("button")
- var/area/A = get_area(src)
- if(A.fire || A.party)
+ if(myarea.fire || myarea.party)
reset(user)
else
alarm(user)
@@ -201,8 +243,7 @@
else if(W.force) //hit and turn it on
..()
- var/area/A = get_area(src)
- if(!A.fire)
+ if(!myarea.fire)
alarm()
return
@@ -295,6 +336,7 @@
. = ..()
if(.)
+ myarea.firereset(src, TRUE)
LAZYREMOVE(myarea.firealarms, src)
/obj/machinery/firealarm/deconstruct(disassembled = TRUE)
@@ -332,19 +374,17 @@
/obj/machinery/firealarm/partyalarm/reset()
if (stat & (NOPOWER|BROKEN))
return
- var/area/A = get_area(src)
- if (!A || !A.party)
+ if (!myarea || !myarea.party)
return
- A.party = FALSE
- A.cut_overlay(party_overlay)
+ myarea.party = FALSE
+ myarea.cut_overlay(party_overlay)
/obj/machinery/firealarm/partyalarm/alarm()
if (stat & (NOPOWER|BROKEN))
return
- var/area/A = get_area(src)
- if (!A || A.party || A.name == "Space")
+ if (!myarea || myarea.party || istype(myarea, /area/space))
return
- A.party = TRUE
+ myarea.party = TRUE
if (!party_overlay)
party_overlay = iconstate2appearance('icons/turf/areas.dmi', "party")
- A.add_overlay(party_overlay)
+ myarea.add_overlay(party_overlay)
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index 5b86b762ba09..fbb5417be5b5 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -141,7 +141,7 @@
/obj/machinery/flasher/emp_act(severity)
. = ..()
if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF))
- if(bulb && prob(75/severity))
+ if(bulb && prob(8 * severity))
flash()
bulb.burn_out()
power_change()
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 91742d81c00a..33c9676d86dc 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -64,10 +64,10 @@ Buildable meters
/obj/item/pipe/dropped()
if(loc)
- setPipingLayer(piping_layer)
+ set_piping_layer(piping_layer)
return ..()
-/obj/item/pipe/proc/setPipingLayer(new_layer = PIPING_LAYER_DEFAULT)
+/obj/item/pipe/proc/set_piping_layer(new_layer = PIPING_LAYER_DEFAULT)
var/obj/machinery/atmospherics/fakeA = pipe_type
if(initial(fakeA.pipe_flags) & PIPING_ALL_LAYER)
@@ -139,7 +139,7 @@ Buildable meters
return TRUE
if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) //don't continue if either pipe goes across all layers
continue
- if(M.GetInitDirections() & SSair.get_init_dirs(pipe_type, fixed_dir())) // matches at least one direction on either type of pipe
+ if(M.get_init_directions() & SSair.get_init_dirs(pipe_type, fixed_dir())) // matches at least one direction on either type of pipe
to_chat(user, span_warning("There is already a pipe at that location!"))
return TRUE
// no conflicts found
@@ -159,7 +159,7 @@ Buildable meters
/obj/item/pipe/proc/build_pipe(obj/machinery/atmospherics/A)
A.setDir(fixed_dir())
- A.SetInitDirections()
+ A.set_init_directions()
if(pipename)
A.name = pipename
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 2fbde8399a12..4f3656c062b9 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -47,7 +47,7 @@
return
var/p_dir = text2num(href_list["dir"])
var/obj/item/pipe/P = new (loc, p_type, p_dir)
- P.setPipingLayer(piping_layer)
+ P.set_piping_layer(piping_layer)
P.add_fingerprint(usr)
wait = world.time + 10
if(href_list["makemeter"])
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index a55f51e7e99d..f6015bb4142d 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -5,7 +5,7 @@
icon_state = "shield-old"
density = TRUE
move_resist = INFINITY
- opacity = 0
+ opacity = FALSE
anchored = TRUE
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
max_integrity = 200 //The shield can only take so much beating (prevents perma-prisons)
@@ -14,7 +14,7 @@
/obj/structure/emergency_shield/Initialize(mapload)
. = ..()
setDir(pick(GLOB.cardinals))
- air_update_turf(1)
+ air_update_turf()
/obj/structure/emergency_shield/Move()
var/turf/T = loc
@@ -25,11 +25,10 @@
. = ..()
if (. & EMP_PROTECT_SELF)
return
- switch(severity)
- if(1)
- qdel(src)
- if(2)
- take_damage(50, BRUTE, ENERGY, 0)
+ if(severity > EMP_LIGHT)
+ qdel(src)
+ return
+ take_damage(5 * severity, BRUTE, ENERGY, 0)
/obj/structure/emergency_shield/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
@@ -70,7 +69,7 @@
icon = 'icons/obj/objects.dmi'
icon_state = "shieldoff"
density = TRUE
- opacity = 0
+ opacity = FALSE
anchored = FALSE
pressure_resistance = 2*ONE_ATMOSPHERE
req_access = list(ACCESS_ENGINE)
diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm
index 73f146992974..4743665672fb 100644
--- a/code/game/machinery/shuttle/shuttle_engine.dm
+++ b/code/game/machinery/shuttle/shuttle_engine.dm
@@ -118,10 +118,11 @@
//Thanks to spaceheater.dm for inspiration :)
/obj/machinery/shuttle/engine/proc/fireEngine()
- var/turf/heatTurf = loc
- if(!heatTurf)
+ if(!isopenturf(get_turf(src)))
+ return
+ var/datum/gas_mixture/env = return_air()
+ if(!env)
return
- var/datum/gas_mixture/env = heatTurf.return_air()
var/heat_cap = env.heat_capacity()
var/req_power = abs(env.return_temperature() - ENGINE_HEAT_TARGET) * heat_cap
req_power = min(req_power, ENGINE_HEATING_POWER)
@@ -129,7 +130,6 @@
if(deltaTemperature < 0)
return
env.set_temperature(env.return_temperature() + deltaTemperature)
- air_update_turf()
/obj/machinery/shuttle/engine/attackby(obj/item/I, mob/living/user, params)
check_setup()
diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm
index beb24acf2085..be8cb0542c9d 100644
--- a/code/game/machinery/shuttle/shuttle_heater.dm
+++ b/code/game/machinery/shuttle/shuttle_heater.dm
@@ -28,14 +28,14 @@
pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
- var/gas_type = /datum/gas/plasma
+ var/gas_type = GAS_PLASMA
var/efficiency_multiplier = 1
var/gas_capacity = 0
/obj/machinery/atmospherics/components/unary/shuttle/heater/New()
. = ..()
GLOB.custom_shuttle_machines += src
- SetInitDirections()
+ set_init_directions()
update_adjacent_engines()
updateGasStats()
@@ -46,27 +46,27 @@
/obj/machinery/atmospherics/components/unary/shuttle/heater/on_construction()
..(dir, dir)
- SetInitDirections()
+ set_init_directions()
update_adjacent_engines()
/obj/machinery/atmospherics/components/unary/shuttle/heater/default_change_direction_wrench(mob/user, obj/item/I)
if(!..())
return FALSE
- SetInitDirections()
+ set_init_directions()
var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
nodes[1] = null
if(!parents[1])
return
- nullifyPipenet(parents[1])
+ nullify_pipenet(parents[1])
- atmosinit()
+ atmos_init()
node = nodes[1]
if(node)
- node.atmosinit()
- node.addMember(src)
- build_network()
+ node.atmos_init()
+ node.add_member(src)
+ SSair.add_to_rebuild_queue(src)
return TRUE
/obj/machinery/atmospherics/components/unary/shuttle/heater/RefreshParts()
@@ -91,8 +91,6 @@
return
air_contents.set_volume(gas_capacity)
air_contents.set_temperature(T20C)
- if(gas_type)
- air_contents.set_moles(gas_type)
/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/hasFuel(required)
var/datum/gas_mixture/air_contents = airs[1]
@@ -230,7 +228,7 @@
/obj/machinery/power/engine_capacitor_bank/emp_act(severity)
. = ..()
- stored_power = rand(0, stored_power)
+ stored_power = stored_power * (0.9**(severity)) // exponential decay based on EMP severity, heavy EMPs (10 severity) reduce to 35% power
/obj/machinery/power/engine_capacitor_bank/escape_pod
name = "emergency thruster capacitor bank"
diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm
index 536d61200dcb..8ff7540611dd 100644
--- a/code/game/machinery/slotmachine.dm
+++ b/code/game/machinery/slotmachine.dm
@@ -182,7 +182,7 @@
return
if(prob(1)) // :^)
obj_flags |= EMAGGED
- var/severity_ascending = 4 - severity
+ var/severity_ascending = 2 + (severity / 5)
money = max(rand(money - (200 * severity_ascending), money + (200 * severity_ascending)), 0)
balance = max(rand(balance - (50 * severity_ascending), balance + (50 * severity_ascending)), 0)
money -= max(0, give_payout(min(rand(-50, 100 * severity_ascending)), money)) //This starts at -50 because it shouldn't always dispense coins yo
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index 8b7946707bd0..90482de1d7e8 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -66,7 +66,7 @@
if(panel_open)
. += "sheater-open"
-/obj/machinery/space_heater/process(delta_time)
+/obj/machinery/space_heater/process_atmos()
if(!on || stat & (BROKEN|MAINT))
if (on) // If it's broken, turn it off too
on = FALSE
@@ -103,7 +103,7 @@
var/heat_capacity = env.heat_capacity()
var/requiredEnergy = abs(env.return_temperature() - targetTemperature) * heat_capacity
- requiredEnergy = min(requiredEnergy, heatingPower * delta_time)
+ requiredEnergy = min(requiredEnergy, heatingPower)
if(requiredEnergy < 1)
return
@@ -115,7 +115,6 @@
for (var/turf/open/turf in ((L.atmos_adjacent_turfs || list()) + L))
var/datum/gas_mixture/turf_gasmix = turf.return_air()
turf_gasmix.set_temperature(turf_gasmix.return_temperature() + deltaTemperature)
- air_update_turf(FALSE, FALSE)
var/working = TRUE
@@ -213,13 +212,10 @@
data["minTemp"] = max(settableTemperatureMedian - settableTemperatureRange - T0C, TCMB)
data["maxTemp"] = settableTemperatureMedian + settableTemperatureRange - T0C
- var/turf/L = get_turf(loc)
var/curTemp
- if(istype(L))
- var/datum/gas_mixture/env = L.return_air()
- curTemp = env.return_temperature()
- else if(isturf(L))
- curTemp = L.return_temperature()
+ if(isopenturf(get_turf(src)))
+ var/datum/gas_mixture/env = return_air()
+ curTemp = env?.return_temperature()
if(isnull(curTemp))
data["currentTemp"] = "N/A"
else
@@ -268,7 +264,9 @@
usr.visible_message("[usr] switches [on ? "on" : "off"] \the [src].", span_notice("You switch [on ? "on" : "off"] \the [src]."))
update_appearance(UPDATE_ICON)
if (on)
- START_PROCESSING(SSmachines, src)
+ SSair_machinery.start_processing_machine(src)
+ else
+ SSair_machinery.stop_processing_machine(src)
/obj/machinery/space_heater/AltClick(mob/user)
if(!user.canUseTopic(src, !issilicon(user)))
diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm
index 0b3068846a59..e610992476eb 100644
--- a/code/game/machinery/stasis.dm
+++ b/code/game/machinery/stasis.dm
@@ -3,6 +3,7 @@
desc = "A not so comfortable looking bed with some nozzles at the top and bottom. It will keep someone in stasis."
icon = 'icons/obj/machines/stasis.dmi'
icon_state = "stasis"
+ base_icon_state = "stasis"
density = FALSE
can_buckle = TRUE
buckle_lying = 90
@@ -92,19 +93,20 @@
last_stasis_sound = _running
/obj/machinery/stasis/AltClick(mob/user)
- if(world.time >= stasis_can_toggle && user.canUseTopic(src, !issilicon(user)))
- stasis_enabled = !stasis_enabled
- stasis_can_toggle = world.time + stasis_cooldown
- playsound(src, 'sound/machines/click.ogg', 60, TRUE)
- play_power_sound()
- update_appearance(UPDATE_ICON)
+ if(world.time < stasis_can_toggle || !user.canUseTopic(src, !issilicon(user)))
+ return
+ stasis_enabled = !stasis_enabled
+ stasis_can_toggle = world.time + stasis_cooldown
+ playsound(src, 'sound/machines/click.ogg', 60, TRUE)
+ play_power_sound()
+ update_appearance(UPDATE_ICON)
/obj/machinery/stasis/Exited(atom/movable/AM, atom/newloc)
if(AM == occupant)
var/mob/living/L = AM
if(L.has_status_effect(STATUS_EFFECT_STASIS))
thaw_them(L)
- . = ..()
+ return ..()
/obj/machinery/stasis/proc/stasis_running()
return stasis_enabled && is_operational()
@@ -112,30 +114,36 @@
/obj/machinery/stasis/update_icon_state()
. = ..()
if(stat & BROKEN)
- icon_state = "stasis_broken"
+ icon_state = "[base_icon_state]_broken"
return
if(panel_open || stat & MAINT)
- icon_state = "stasis_maintenance"
+ icon_state = "[base_icon_state]_maintenance"
return
- icon_state = "stasis"
+ icon_state = base_icon_state
+
+/obj/machinery/stasis/setDir()
+ . = ..()
+ update_appearance(UPDATE_ICON)
/obj/machinery/stasis/update_overlays()
. = ..()
+ if(!mattress_state)
+ return
var/_running = stasis_running()
- var/list/overlays_to_remove = managed_vis_overlays
-
- if(mattress_state)
- if(!mattress_on || !managed_vis_overlays)
- mattress_on = SSvis_overlays.add_vis_overlay(src, icon, mattress_state, layer, plane, dir, alpha = 0, unique = TRUE)
-
- if(mattress_on.alpha ? !_running : _running) //check the inverse of _running compared to truthy alpha, to see if they differ
- var/new_alpha = _running ? 255 : 0
- var/easing_direction = _running ? EASE_OUT : EASE_IN
- animate(mattress_on, alpha = new_alpha, time = stasis_cooldown, easing = CUBIC_EASING|easing_direction)
-
- overlays_to_remove = managed_vis_overlays - mattress_on
+ if(!mattress_on)
+ mattress_on = SSvis_overlays.add_vis_overlay(src, icon, mattress_state, layer, plane, dir, alpha = 0, unique = TRUE)
+ else
+ vis_contents += mattress_on
+ mattress_on.dir = dir
+ if(managed_vis_overlays)
+ managed_vis_overlays += mattress_on
+ else
+ managed_vis_overlays = list(mattress_on)
- SSvis_overlays.remove_vis_overlay(src, overlays_to_remove)
+ if(mattress_on.alpha ? !_running : _running) //check the inverse of _running compared to truthy alpha, to see if they differ
+ var/new_alpha = _running ? 255 : 0
+ var/easing_direction = _running ? EASE_OUT : EASE_IN
+ animate(mattress_on, alpha = new_alpha, time = 50, easing = CUBIC_EASING|easing_direction)
/obj/machinery/stasis/obj_break(damage_flag)
. = ..()
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 3799c63845e7..3bd5a4d73720 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -502,16 +502,15 @@
/obj/item/bombcore/emp
name = "EMP payload"
desc = "A set of superconducting electromagnetic coils designed to release a powerful pulse to destroy electronics and scramble circuits"
- range_heavy = 15
- range_medium = 25
+ range_heavy = 25 // 25 severity, can do some serious damage
/obj/item/bombcore/emp/detonate()
if(adminlog)
message_admins(adminlog)
log_game(adminlog)
- empulse(src, range_heavy, range_medium)
-
+ empulse(src, range_heavy)
+
qdel(src)
///Syndicate Detonator (aka the big red button)///
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index 6bf5c01110be..2d536cadb7f6 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -153,10 +153,9 @@ GLOBAL_LIST_EMPTY(telecomms_list)
/obj/machinery/telecomms/proc/update_speed()
if(!on)
return
- var/turf/T = get_turf(src) //yogs
var/speedloss = 0
- var/datum/gas_mixture/env = T.return_air()
- var/temperature = env.return_temperature()
+ var/datum/gas_mixture/env = return_air()
+ var/temperature = env?.return_temperature()
if(temperature <= 150) // 150K optimal operating parameters
net_efective = 100
else
@@ -191,9 +190,9 @@ GLOBAL_LIST_EMPTY(telecomms_list)
. = ..()
if(. & EMP_PROTECT_SELF)
return
- if(prob(100/severity) && !(stat & EMPED))
+ if(prob(10 * severity) && !(stat & EMPED))
stat |= EMPED
- var/duration = (300 * 10)/severity
+ var/duration = (30 SECONDS) * severity // 30 seconds per level of severity, 5 minutes at 10 severity (EMP_HEAVY)
addtimer(CALLBACK(src, PROC_REF(de_emp)), rand(duration - 20, duration + 20))
/obj/machinery/telecomms/proc/de_emp()
diff --git a/code/game/mecha/combat/reticence.dm b/code/game/mecha/combat/reticence.dm
index 7237237ccc6a..9a324986eae5 100644
--- a/code/game/mecha/combat/reticence.dm
+++ b/code/game/mecha/combat/reticence.dm
@@ -18,7 +18,7 @@
stepsound = null
turnsound = null
meleesound = FALSE
- opacity = 0
+ opacity = FALSE
/obj/mecha/combat/reticence/Initialize(mapload)
. = ..()
diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm
index 6aad0746d6dc..2fe788ba5dd0 100644
--- a/code/game/mecha/equipment/tools/work_tools.dm
+++ b/code/game/mecha/equipment/tools/work_tools.dm
@@ -190,54 +190,42 @@
equip_cooldown = 5
energy_drain = 0
range = MECHA_MELEE|MECHA_RANGED
+ var/chem_amount = 2
/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize(mapload)
. = ..()
create_reagents(1000)
- reagents.add_reagent(/datum/reagent/water, 1000)
+ reagents.add_reagent(/datum/reagent/firefighting_foam, 1000)
/obj/item/mecha_parts/mecha_equipment/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch.
- if(!action_checks(target) || get_dist(chassis, target)>3)
+ if(!action_checks(target))
return
- if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1)
- var/obj/structure/reagent_dispensers/watertank/WT = target
+ if(istype(target, /obj/structure/reagent_dispensers/foamtank) && get_dist(chassis,target) <= 1)
+ var/obj/structure/reagent_dispensers/WT = target
WT.reagents.trans_to(src, 1000)
occupant_message(span_notice("Extinguisher refilled."))
playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6)
- else
- if(reagents.total_volume > 0)
- playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3)
- var/direction = get_dir(chassis,target)
- var/turf/T = get_turf(target)
- var/turf/T1 = get_step(T,turn(direction, 90))
- var/turf/T2 = get_step(T,turn(direction, -90))
-
- var/list/the_targets = list(T,T1,T2)
- spawn(0)
- for(var/a=0, a<5, a++)
- var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(chassis))
- if(!W)
- return
- var/turf/my_target = pick(the_targets)
- var/datum/reagents/R = new/datum/reagents(5)
- W.reagents = R
- R.my_atom = W
- reagents.trans_to(W,1, transfered_by = chassis.occupant)
- for(var/b=0, b<4, b++)
- if(!W)
- return
- step_towards(W,my_target)
- if(!W)
- return
- var/turf/W_turf = get_turf(W)
- W.reagents.reaction(W_turf)
- for(var/atom/atm in W_turf)
- W.reagents.reaction(atm)
- if(W.loc == my_target)
- break
- sleep(0.2 SECONDS)
+ else if(reagents.total_volume >= 1)
+ playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3)
+
+ //Get all the turfs that can be shot at
+ var/direction = get_dir(chassis,target)
+ var/turf/T = get_turf(target)
+ var/turf/T1 = get_step(T,turn(direction, 90))
+ var/turf/T2 = get_step(T,turn(direction, -90))
+ var/turf/T3 = get_step(T1, turn(direction, 90))
+ var/turf/T4 = get_step(T2,turn(direction, -90))
+ var/list/the_targets = list(T,T1,T2,T3,T4)
+
+ for(var/a=0, a<5, a++)
+ var/my_target = pick(the_targets)
+ var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(src), my_target)
+ reagents.trans_to(W, chem_amount, transfered_by = chassis.occupant)
+ the_targets -= my_target
return 1
+ else
+ occupant_message(span_warning("[src] is empty!"))
/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info()
return "[..()] \[[src.reagents.total_volume]\]"
diff --git a/code/game/mecha/equipment/weapons/melee_weapons.dm b/code/game/mecha/equipment/weapons/melee_weapons.dm
index 7367f0f0f669..51a45519af5e 100644
--- a/code/game/mecha/equipment/weapons/melee_weapons.dm
+++ b/code/game/mecha/equipment/weapons/melee_weapons.dm
@@ -273,7 +273,7 @@
set_light_on(FALSE)
/obj/item/mecha_parts/mecha_equipment/melee_weapon/sword/katana //Anime mech sword
- name = "\improper OWM-5 \"Ronin\" katana"
+ name = "\improper HR-2 \"Ronin\" katana"
desc = "An oversized, light-weight replica of an ancient style of blade. Still woefully underpowered in D&D."
icon_state = "mecha_katana"
energy_drain = 15
@@ -363,7 +363,7 @@
playsound(L, 'sound/items/welder.ogg', 50, 1)
/obj/item/mecha_parts/mecha_equipment/melee_weapon/sword/maul
- name = "\improper CX-22 \"Barbatos\" heavy maul"
+ name = "\improper ASW-8 \"Barbatos\" heavy maul"
desc = "A massive, unwieldy, mace-like weapon, this thing really looks like something you don't want to be hit by if you're not a fan of being concave."
icon_state = "mecha_maul"
energy_drain = 40
@@ -385,7 +385,7 @@
do_item_attack_animation(L, hit_effect)
/obj/item/mecha_parts/mecha_equipment/melee_weapon/sword/rapier
- name = "\improper E9-V \"Sigrun\" rapier"
+ name = "\improper MS-15 \"Gyan\" rapier"
desc = "A remarkably thin blade for a weapon wielded by an exosuit, this rapier is the favorite of syndicate pilots that perfer finesse over brute force."
icon_state = "mecha_rapier"
energy_drain = 40
@@ -459,7 +459,7 @@
/obj/item/mecha_parts/mecha_equipment/melee_weapon/rocket_fist //Passive upgrade weapon when selected, makes your mech punch harder AND faster
- name = "\improper DD-2 \"Atom Smasher\" rocket fist"
+ name = "\improper RS-77 \"Atom Smasher\" rocket fist"
desc = "A large metal fist fitted to the arm of an exosuit, it uses repurposed maneuvering thrusters from a Raven battlecruiser to give a little more oomph to every punch. Also helps increase the speed at which the mech is able to return to a ready stance after each swing."
icon_state = "mecha_rocket_fist"
weapon_damage = 20
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 23e2e5bea55e..324601c5c654 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -18,7 +18,7 @@
desc = "Exosuit"
icon = 'icons/mecha/mecha.dmi'
density = TRUE //Dense. To raise the heat.
- opacity = 1 ///opaque. Menacing.
+ opacity = TRUE ///opaque. Menacing.
move_resist = MOVE_FORCE_EXTREMELY_STRONG //no pulling around.
resistance_flags = FIRE_PROOF | ACID_PROOF
layer = BELOW_MOB_LAYER//icon draw layer
@@ -213,11 +213,7 @@
scanmod = null
capacitor = null
internal_tank = null
- if(loc)
- loc.assume_air(cabin_air)
- air_update_turf()
- else
- qdel(cabin_air)
+ assume_air(cabin_air)
cabin_air = null
qdel(spark_system)
spark_system = null
@@ -276,8 +272,8 @@
cabin_air = new
cabin_air.set_temperature(T20C)
cabin_air.set_volume(200)
- cabin_air.set_moles(/datum/gas/oxygen, O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
- cabin_air.set_moles(/datum/gas/nitrogen, N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
+ cabin_air.set_moles(GAS_O2, O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
+ cabin_air.set_moles(GAS_N2, N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
return cabin_air
/obj/mecha/proc/add_radio()
@@ -295,6 +291,11 @@
return TRUE
return FALSE
+/obj/mecha/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..() // if something can go through machines it can go through mechs
+ if(istype(mover) && (mover.pass_flags & PASSMECH))
+ return TRUE
+
////////////////////////////////////////////////////////////////////////////////
/obj/mecha/examine(mob/user)
@@ -336,50 +337,8 @@
//Armor tag
/obj/mecha/Topic(href, href_list)
. = ..()
-
if(href_list["list_armor"])
- var/list/readout = list("PROTECTION CLASSES ")
- if(armor.bio || armor.bomb || armor.bullet || armor.energy || armor.laser || armor.melee)
- readout += "\nARMOR (I-X) "
- if(armor.bio)
- readout += "\nBIO [armor_to_protection_class(armor.bio)]"
- if(armor.bomb)
- readout += "\nEXPLOSIVE [armor_to_protection_class(armor.bomb)]"
- if(armor.bullet)
- readout += "\nBULLET [armor_to_protection_class(armor.bullet)]"
- if(armor.energy)
- readout += "\nENERGY [armor_to_protection_class(armor.energy)]"
- if(armor.laser)
- readout += "\nLASER [armor_to_protection_class(armor.laser)]"
- if(armor.melee)
- readout += "\nMELEE [armor_to_protection_class(armor.melee)]"
- if(armor.fire || armor.acid || deflect_chance || max_temperature)
- readout += "\nDURABILITY (I-X) "
- if(armor.fire)
- readout += "\nFIRE [armor_to_protection_class(armor.fire)]"
- if(armor.acid)
- readout += "\nACID [armor_to_protection_class(armor.acid)]"
- if(deflect_chance)
- readout += "\nDEFLECT CHANCE: [deflect_chance]%"
- if(max_temperature)
- readout += "\nMAX TEMPERATURE: [max_temperature] KELVIN"
-
- readout += " "
-
- to_chat(usr, "[readout.Join()]")
-
-/**
- * Rounds armor_value down to the nearest 10, divides it by 10 and then converts it to Roman numerals.
- *
- * Arguments:
- * * armor_value - Number we're converting
- */
-/obj/mecha/proc/armor_to_protection_class(armor_value)
- if (armor_value < 0)
- . = "-"
- . += "\Roman[round(abs(armor_value), 10) / 10]"
- return .
-
+ to_chat(usr, "[armor.show_protection_classes()]")
//processing internal damage, temperature, air regulation, alert updates, lights power use.
/obj/mecha/process()
@@ -405,13 +364,7 @@
if(internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank
if(internal_tank)
- var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
- var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.1)
- if(loc)
- loc.assume_air(leaked_gas)
- air_update_turf()
- else
- qdel(leaked_gas)
+ assume_air_ratio(internal_tank.return_air(), 0.1)
if(internal_damage & MECHA_INT_SHORT_CIRCUIT)
if(get_charge())
@@ -434,8 +387,7 @@
if(pressure_delta > 0) //cabin pressure lower than release pressure
if(tank_air.return_temperature() > 0)
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
- var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
- cabin_air.merge(removed)
+ tank_air.transfer_to(cabin_air,transfer_moles)
else if(pressure_delta < 0) //cabin pressure higher than release pressure
var/datum/gas_mixture/t_air = return_air()
pressure_delta = cabin_pressure - release_pressure
@@ -443,11 +395,7 @@
pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
if(pressure_delta > 0) //if location pressure is lower than cabin pressure
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
- var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
- if(t_air)
- t_air.merge(removed)
- else //just delete the cabin gas, we're in space or some shit
- qdel(removed)
+ cabin_air.transfer_to(t_air, transfer_moles)
if(occupant)
if(cell)
@@ -954,6 +902,11 @@
return cabin_air.remove(amount)
return ..()
+/obj/mecha/remove_air_ratio(ratio)
+ if(use_internal_tank)
+ return cabin_air.remove_ratio(ratio)
+ return ..()
+
/obj/mecha/return_air()
if(use_internal_tank)
return cabin_air
diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm
index 4762da6c0e5e..a2e3d2f9084b 100644
--- a/code/game/mecha/mecha_defense.dm
+++ b/code/game/mecha/mecha_defense.dm
@@ -161,8 +161,8 @@
if (. & EMP_PROTECT_SELF)
return
if(get_charge())
- use_power((cell.charge/3)/(severity*2))
- take_damage(40 / severity, BURN, ENERGY, 1)
+ use_power((cell.charge * severity / 15))
+ take_damage(4 * severity, BURN, ENERGY, 1)
log_message("EMP detected", LOG_MECHA, color="red")
if(istype(src, /obj/mecha/combat))
diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm
index 0043fb3e4e6d..034d32ab341c 100644
--- a/code/game/mecha/mecha_wreckage.dm
+++ b/code/game/mecha/mecha_wreckage.dm
@@ -9,7 +9,7 @@
icon = 'icons/mecha/mecha.dmi'
density = TRUE
anchored = FALSE
- opacity = 0
+ opacity = FALSE
var/state = MECHA_WRECK_CUT
var/orig_mecha
var/can_be_reconstructed = FALSE
diff --git a/code/game/movable_luminosity.dm b/code/game/movable_luminosity.dm
index 7a6eaddafd9e..c3bf5ed2525d 100644
--- a/code/game/movable_luminosity.dm
+++ b/code/game/movable_luminosity.dm
@@ -11,7 +11,6 @@
affecting_dynamic_lumi = highest
luminosity += affecting_dynamic_lumi
-
///Helper to change several lighting overlay settings.
/atom/movable/proc/set_light_range_power_color(range, power, color)
set_light_range(range)
diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm
index 18974a9a01aa..6d0ae81b5082 100644
--- a/code/game/objects/effects/alien_acid.dm
+++ b/code/game/objects/effects/alien_acid.dm
@@ -4,7 +4,7 @@
desc = "Burbling corrosive stuff."
icon_state = "acid"
density = FALSE
- opacity = 0
+ opacity = FALSE
anchored = TRUE
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
layer = ABOVE_NORMAL_TURF_LAYER
diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm
index cffa965457d7..1aa541aa1b7e 100644
--- a/code/game/objects/effects/anomalies.dm
+++ b/code/game/objects/effects/anomalies.dm
@@ -191,23 +191,9 @@
/obj/effect/anomaly/flux/proc/mobShock(mob/living/M)
if(canshock && istype(M))
- canshock = 0 //Just so you don't instakill yourself if you slam into the anomaly five times in a second.
- if(iscarbon(M))
- var/siemens_coeff = 1
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.gloves)
- siemens_coeff *= (H.gloves.siemens_coefficient + 1) / 2 // protective gloves reduce damage by half
- if(H.wear_suit)
- siemens_coeff *= (H.wear_suit.siemens_coefficient + 1) / 2 // protective suit reduces damage by another half, minimum of 33%
- var/should_stun = !M.IsParalyzed() // stunlock is boring
- M.electrocute_act(shockdamage, "[name]", max(siemens_coeff, 0.33), safety = TRUE, stun = should_stun) // 15 damage with insuls, 10 damage with insuls and hardsuit
- return
- else
- M.adjustFireLoss(shockdamage)
- M.visible_message(span_danger("[M] was shocked by \the [name]!"), \
- span_userdanger("You feel a powerful shock coursing through your body!"), \
- span_italics("You hear a heavy electrical crack."))
+ var/should_stun = !M.IsParalyzed() // stunlock is boring
+ var/hit_percent = (100 - M.getarmor(null, ELECTRIC)) / 100
+ M.electrocute_act(shockdamage, "[name]", max(hit_percent, 0.33), zone = null, override=TRUE, stun = should_stun) // ignore armor because we're doing our own calculations
/obj/effect/anomaly/flux/detonate()
switch(explosive)
@@ -439,8 +425,21 @@
core_type = ANOMALY_HALLUCINATION
/// Time passed since the last effect, increased by delta_time of the SSobj
var/ticks = 0
- /// How many seconds between each small hallucination pulses
+ /// How many seconds between each hallucination spanwed
var/release_delay = 5
+ /// flavor of hallucination mobs this spawns (cosmetic)
+ var/hallucination_set
+
+/obj/effect/anomaly/hallucination/Initialize(mapload, new_lifespan)
+ . = ..()
+ hallucination_set = pick("syndicate", "cult")
+ switch(hallucination_set)
+ if("syndicate")
+ icon = 'icons/mob/simple_human.dmi'
+ icon_state = "syndicate_stormtrooper_sword"
+ if("cult")
+ icon = 'icons/mob/nonhuman-player/cult.dmi'
+ icon_state = "cultist"
/obj/effect/anomaly/hallucination/anomalyEffect(delta_time)
. = ..()
@@ -450,37 +449,82 @@
ticks -= release_delay
var/turf/open/our_turf = get_turf(src)
if(istype(our_turf))
- hallucination_pulse(our_turf, 5)
+ var/mob/living/simple_animal/hostile/newhall = new /mob/living/simple_animal/hostile/hallucination(our_turf)
+ switch(hallucination_set)
+ if("syndicate")
+ newhall.name = "syndicate operative"
+ newhall.icon = 'icons/mob/simple_human.dmi'
+ newhall.icon_state = "syndicate_space_knife"
+ newhall.attacktext = "slashes"
+ newhall.attack_sound = 'sound/weapons/bladeslice.ogg'
+ if("cult")
+ newhall.name = "shade"
+ newhall.icon = 'icons/mob/nonhuman-player/cult.dmi'
+ newhall.icon_state = "shade_cult"
+ newhall.attacktext = "metaphysically strikes"
/obj/effect/anomaly/hallucination/detonate()
- var/turf/open/our_turf = get_turf(src)
- if(istype(our_turf))
- hallucination_pulse(our_turf, 10)
-
-/proc/hallucination_pulse(turf/location, range, strength = 50)
- for(var/mob/living/carbon/human/near in view(location, range))
- // If they are immune to hallucinations
- if (HAS_TRAIT(near, TRAIT_MESONS) || (near.mind && HAS_TRAIT(near.mind, TRAIT_MESONS)))
- continue
+ var/mob/living/simple_animal/hostile/hallucination/anomaly/bighall = new(get_turf(src))
+ bighall.icon = icon
+ bighall.icon_state = icon_state
+ switch(hallucination_set)
+ if("syndicate")
+ bighall.attacktext = "slashes"
+ bighall.attack_sound = 'sound/weapons/bladeslice.ogg'
+ if("cult")
+ bighall.attacktext = "slashes"
+ bighall.attack_sound = 'sound/weapons/blade1.ogg'
+
+// Hallucination anomaly spawned mob, attacks deal stamina damage, if it stamcrits someone, they start hallucinating themself dying.
+/mob/living/simple_animal/hostile/hallucination
+ name = "Unknown"
+ desc = "Whoever they are, they look angry, and hard to look at."
+ maxHealth = 25
+ health = 25
+ melee_damage_lower = 15
+ melee_damage_upper = 10
+ stat_attack = UNCONSCIOUS
+ robust_searching = TRUE
+ icon = 'icons/mob/simple_human.dmi'
+ icon_state = "faceless"
+ obj_damage = 0
+ digitalinvis = TRUE //silicons can't hallucinate, as they are robots. they also can't take stamina damage.
+ melee_damage_type = STAMINA
+ damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 1, STAMINA = 0, OXY = 0)
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
+ maxbodytemp = INFINITY
+ del_on_death = TRUE
+ footstep_type = FOOTSTEP_MOB_SHOE
+
+/mob/living/simple_animal/hostile/hallucination/anomaly
+ name = "hallucination anomaly"
+ desc = "A mysterious anomaly, seen commonly only in the region of space that the station orbits..."
+ maxHealth = 50
+ health = 50
+ melee_damage_lower = 30
+ melee_damage_upper = 30
- // Blind people don't get hallucinations
- if (is_blind(near))
- continue
+/mob/living/simple_animal/hostile/hallucination/CanAttack(atom/the_target)
+ . = ..()
+ if(!iscarbon(the_target))
+ return FALSE
- // Everyone else
- var/dist = sqrt(1 / max(1, get_dist(near, location)))
- near.adjust_hallucinations(max(150, strength * dist))
- near.adjust_jitter(10 SECONDS)
- near.adjust_confusion(10 SECONDS)
- near.adjust_dizzy(10 SECONDS)
- near.adjust_drowsiness(10 SECONDS)
- var/static/list/messages = list(
- "You feel your conscious mind fall apart!",
- "Reality warps around you!",
- "Something's whispering around you!",
- "You are going insane!",
- "What was that?!"
- )
- to_chat(near, span_warning("[pick(messages)]"))
+/mob/living/simple_animal/hostile/hallucination/AttackingTarget()
+ . = ..()
+ if(. && isliving(target))
+ var/mob/living/carbon/C = target
+ C.clear_stamina_regen()
+ if(C.getStaminaLoss() >= 100) //congrats you have hallucinated being stabbed now you are hallucinating dying
+ if(!C.losebreath)
+ to_chat(C, span_notice("You feel your heart slow down..."))
+ C.losebreath = min(C.losebreath+2, 10)
+ C.silent = min(C.silent+2, 10)
+ if(C.getOxyLoss() >= 100) //let's skip the waiting and get to the fun part
+ if(C.can_heartattack())
+ C.playsound_local(C, 'sound/effects/singlebeat.ogg', 100, 0)
+ C.set_heartattack(TRUE)
+ else
+ C.adjustBruteLoss(10)
#undef ANOMALY_MOVECHANCE
diff --git a/code/game/objects/effects/bump_teleporter.dm b/code/game/objects/effects/bump_teleporter.dm
index 36320f29133b..426a4a37064e 100644
--- a/code/game/objects/effects/bump_teleporter.dm
+++ b/code/game/objects/effects/bump_teleporter.dm
@@ -7,7 +7,7 @@
invisibility = INVISIBILITY_ABSTRACT //nope, can't see this
anchored = TRUE
density = TRUE
- opacity = 0
+ opacity = FALSE
var/static/list/AllTeleporters
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index fab5e473e4c1..b3260fd51c58 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -233,3 +233,12 @@
/obj/effect/decal/cleanable/insectguts/Destroy(force)
GLOB.vomit_spots -= src
. = ..()
+
+/obj/effect/decal/cleanable/dirt_siding
+ name = "dirt siding"
+ icon = 'icons/turf/decals.dmi'
+ icon_state = "dirt_side"
+
+/obj/effect/decal/cleanable/dirt_siding/corner
+ name = "dirt corner"
+ icon_state = "dirt_side_corner"
\ No newline at end of file
diff --git a/code/game/objects/effects/decals/turfdecal/markings.dm b/code/game/objects/effects/decals/turfdecal/markings.dm
index f7787772e6ba..552dbfa621fb 100644
--- a/code/game/objects/effects/decals/turfdecal/markings.dm
+++ b/code/game/objects/effects/decals/turfdecal/markings.dm
@@ -249,7 +249,7 @@
/obj/effect/turf_decal/siding/wood
icon_state = "siding_wood_line"
- color = "#55391A"
+ color = "#5d341f"
/obj/effect/turf_decal/siding/wood/corner
icon_state = "siding_wood_corner"
@@ -257,6 +257,15 @@
/obj/effect/turf_decal/siding/wood/end
icon_state = "siding_wood_end"
+/obj/effect/turf_decal/siding/wood/thin
+ icon_state = "siding_wood_line_thin"
+
+/obj/effect/turf_decal/siding/wood/corner/thin
+ icon_state = "siding_wood_corner_thin"
+
+/obj/effect/turf_decal/siding/wood/end/thin
+ icon_state = "siding_wood_end_thin"
+
/obj/effect/turf_decal/siding/thinplating
icon_state = "siding_thinplating_line"
color = "#aaaaaa"
diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm
index 35ba7c6f9c44..3839457dc634 100644
--- a/code/game/objects/effects/effect_system/effect_system.dm
+++ b/code/game/objects/effects/effect_system/effect_system.dm
@@ -25,7 +25,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
/datum/effect_system
var/number = 3
- var/cardinals = FALSE
+ var/cardinals_only = FALSE
var/turf/location
var/atom/holder
var/effect_type
@@ -39,7 +39,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
/datum/effect_system/proc/set_up(number = 3, cardinals_only = FALSE, location)
src.number = min(number, 10)
- src.cardinals = cardinals_only
+ src.cardinals_only = cardinals_only
src.location = get_turf(location)
/datum/effect_system/proc/attach(atom/atom)
@@ -59,7 +59,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
var/obj/effect/E = new effect_type(location)
total_effects++
var/direction
- if(cardinals)
+ if(cardinals_only)
direction = pick(GLOB.cardinals)
else
direction = pick(GLOB.alldirs)
diff --git a/code/game/objects/effects/effect_system/effects_explosion.dm b/code/game/objects/effects/effect_system/effects_explosion.dm
index f264fa3a618b..e436ca851fbc 100644
--- a/code/game/objects/effects/effect_system/effects_explosion.dm
+++ b/code/game/objects/effects/effect_system/effects_explosion.dm
@@ -1,7 +1,7 @@
/obj/effect/particle_effect/expl_particles
name = "fire"
icon_state = "explosion_particle"
- opacity = 1
+ opacity = TRUE
anchored = TRUE
/obj/effect/particle_effect/expl_particles/Initialize(mapload) //yogs start: reverts harddel stuff so it doesn't break horribly
@@ -23,7 +23,7 @@
name = "fire"
icon = 'icons/effects/96x96.dmi'
icon_state = "explosion"
- opacity = 1
+ opacity = TRUE
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
pixel_x = -32
diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm
index 9efda705f3f0..ceaeb77375ff 100644
--- a/code/game/objects/effects/effect_system/effects_sparks.dm
+++ b/code/game/objects/effects/effect_system/effects_sparks.dm
@@ -5,13 +5,9 @@
// will always spawn at the items location.
/////////////////////////////////////////////
-/proc/do_sparks(n, c, source)
- // n - number of sparks
- // c - cardinals, bool, do the sparks only move in cardinal directions?
- // source - source of the sparks.
-
+/proc/do_sparks(number, cardinal_only, datum/source)
var/datum/effect_system/spark_spread/sparks = new
- sparks.set_up(n, c, source)
+ sparks.set_up(number, cardinal_only, source)
sparks.autocleanup = TRUE
sparks.start()
@@ -24,7 +20,6 @@
light_range = 2
light_power = 0.5
light_color = LIGHT_COLOR_FIRE
- light_flags = LIGHT_NO_LUMCOUNT
var/duration = 2 SECONDS
var/volume = 100
var/sound = "sparks"
diff --git a/code/game/objects/effects/effect_system/effects_water.dm b/code/game/objects/effects/effect_system/effects_water.dm
index 1899d0372fdf..ac4c7ff9e1a4 100644
--- a/code/game/objects/effects/effect_system/effects_water.dm
+++ b/code/game/objects/effects/effect_system/effects_water.dm
@@ -3,18 +3,48 @@
/obj/effect/particle_effect/water
name = "water"
icon_state = "extinguish"
- pass_flags = PASSTABLE | PASSMACHINES | PASSCOMPUTER | PASSSTRUCTURE | PASSGRILLE | PASSBLOB
+ pass_flags = PASSTABLE | PASSMACHINES | PASSCOMPUTER | PASSSTRUCTURE | PASSGRILLE | PASSBLOB | PASSMECH | PASSMOB
var/life = 15
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ var/turf/target_turf
+ var/transfer_methods = TOUCH
+
+/obj/effect/particle_effect/water/New(loc, turf/target, methods, ...)
+ if(!isnull(target))
+ target_turf = target
+ if(!isnull(methods))
+ transfer_methods = methods
+ return ..()
/obj/effect/particle_effect/water/Initialize(mapload)
. = ..()
+ create_reagents(5)
QDEL_IN(src, 70)
+ if(target_turf)
+ addtimer(CALLBACK(src, PROC_REF(move_particle)), 2)
+
+/obj/effect/particle_effect/water/proc/move_particle()
+ if(!target_turf)
+ return
+ var/starting_loc = loc
+ step_towards(src, target_turf)
+ if(starting_loc == loc)
+ if(reagents) // react again if it got stuck
+ reagents.reaction(loc, transfer_methods)
+ for(var/atom/A in loc)
+ reagents.reaction(A, transfer_methods)
+ qdel(src) // delete itself if it got blocked and can't move
+ return
+ addtimer(CALLBACK(src, PROC_REF(move_particle)), 2)
/obj/effect/particle_effect/water/Move(turf/newloc)
if (--src.life < 1)
qdel(src)
return FALSE
+ if(reagents)
+ reagents.reaction(newloc, transfer_methods)
+ for(var/atom/A in newloc)
+ reagents.reaction(A, transfer_methods)
return ..()
/obj/effect/particle_effect/water/Bump(atom/A)
diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
index ef1e1897b4cf..ca003178d8da 100644
--- a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
@@ -262,15 +262,13 @@
QDEL_NULL(turf_fire)
var/datum/gas_mixture/air = location.air
- var/scrub_amt = min(30, air.get_moles(/datum/gas/plasma)) //Absorb some plasma
- air.adjust_moles(/datum/gas/plasma, -scrub_amt)
+ var/scrub_amt = min(30, air.get_moles(GAS_PLASMA)) //Absorb some plasma
+ air.adjust_moles(GAS_PLASMA, -scrub_amt)
absorbed_plasma += scrub_amt
if (air.return_temperature() > T20C)
air.set_temperature(max(air.return_temperature() / 2, T20C))
- location.air_update_turf(FALSE, FALSE)
-
/obj/effect/particle_effect/fluid/foam/firefighting/make_result()
if(!absorbed_plasma) // don't bother if it didn't scrub any plasma
return
@@ -322,7 +320,7 @@
/obj/structure/foamedmetal/Initialize(mapload)
. = ..()
- air_update_turf(1)
+ air_update_turf()
/obj/structure/foamedmetal/Move()
var/turf/T = loc
@@ -409,11 +407,10 @@
for(var/gas_type in air.get_gases())
switch(gas_type)
- if(/datum/gas/oxygen, /datum/gas/nitrogen)
+ if(GAS_O2, GAS_N2)
continue
else
air.set_moles(gas_type, 0)
- location.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/comp in location)
if(!comp.welded)
diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm
index e2a1d4352544..030d78c8d201 100644
--- a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm
@@ -294,13 +294,12 @@
if(!distcheck || get_dist(location, chilly) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air
air.set_temperature(temperature)
- if(air.get_moles(/datum/gas/plasma))
- air.adjust_moles(/datum/gas/nitrogen, air.get_moles(/datum/gas/plasma))
- air.set_moles(/datum/gas/plasma, 0)
+ if(air.get_moles(GAS_PLASMA))
+ air.adjust_moles(GAS_N2, air.get_moles(GAS_PLASMA))
+ air.set_moles(GAS_PLASMA, 0)
for(var/obj/effect/hotspot/fire in chilly)
qdel(fire)
- chilly.air_update_turf()
if(weldvents)
for(var/obj/machinery/atmospherics/components/unary/comp in chilly)
diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm
index 2216f16b6ef2..429e064b0b6b 100644
--- a/code/game/objects/effects/forcefields.dm
+++ b/code/game/objects/effects/forcefields.dm
@@ -3,7 +3,7 @@
desc = "A space wizard's magic wall."
icon_state = "m_shield"
anchored = TRUE
- opacity = 0
+ opacity = FALSE
density = TRUE
CanAtmosPass = ATMOS_PASS_DENSITY
/// If set, how long the force field lasts after it's created. Set to 0 to have infinite duration forcefields.
diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm
index cb24dad4edbe..c7de6a2597cc 100644
--- a/code/game/objects/effects/misc.dm
+++ b/code/game/objects/effects/misc.dm
@@ -79,16 +79,16 @@
light_range = MINIMUM_USEFUL_LIGHT_RANGE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
-/obj/effect/dummy/lighting_obj/Initialize(mapload, _range, _power, _color, _duration)
+/obj/effect/dummy/lighting_obj/Initialize(mapload, range, power, color, duration)
. = ..()
- if(!isnull(_range))
- set_light_range(_range)
- if(!isnull(_power))
- set_light_power(_power)
- if(!isnull(_color))
- set_light_color(_color)
- if(_duration)
- QDEL_IN(src, _duration)
+ if(!isnull(range))
+ set_light_range(range)
+ if(!isnull(power))
+ set_light_power(power)
+ if(!isnull(color))
+ set_light_color(color)
+ if(duration)
+ QDEL_IN(src, duration)
/obj/effect/dummy/lighting_obj/moblight
name = "mob lighting fx"
@@ -98,6 +98,9 @@
if(!ismob(loc))
return INITIALIZE_HINT_QDEL
+/obj/effect/dummy/lighting_obj/moblight/species
+ name = "species lighting"
+
/obj/effect/dusting_anim
icon = 'icons/effects/filters.dmi'
icon_state = "nothing"
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index 906425b34252..dfd44008cdbb 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -50,7 +50,7 @@
/obj/effect/overlay/vis
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE
- vis_flags = NONE
+ vis_flags = VIS_INHERIT_DIR
var/unused = 0 //When detected to be unused it gets set to world.time, after a while it gets removed
var/cache_expiration = 2 MINUTES // overlays which go unused for 2 minutes get cleaned up
vis_flags = VIS_INHERIT_ID
@@ -88,3 +88,7 @@
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
alpha = 0
vis_flags = NONE
+
+/obj/effect/overlay/light_visible/cone
+ icon = 'icons/effects/light_overlays/light_cone.dmi'
+ alpha = 110
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index 6cd4f737e7bf..9e85bedc2839 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -121,8 +121,6 @@
return FALSE
atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
- atmos_source.air_update_turf(FALSE)
- atmos_destination.air_update_turf(FALSE)
/obj/effect/portal/proc/unlink_atmos()
if(istype(atmos_source))
diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm
index 40bd2405fda6..9e07ee6a7a14 100644
--- a/code/game/objects/effects/spawners/bombspawner.dm
+++ b/code/game/objects/effects/spawners/bombspawner.dm
@@ -1,6 +1,6 @@
#define CELSIUS_TO_KELVIN(T_K) ((T_K) + T0C)
-#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_SPECIFIC_HEAT]) / (((PRESSURE_P) * GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_SPECIFIC_HEAT] + (PRESSURE_O) * GLOB.meta_gas_info[/datum/gas/oxygen][META_GAS_SPECIFIC_HEAT]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.meta_gas_info[/datum/gas/oxygen][META_GAS_SPECIFIC_HEAT] / CELSIUS_TO_KELVIN(TEMP_O)))
+#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.gas_data.specific_heats[GAS_PLASMA]) / (((PRESSURE_P) * GLOB.gas_data.specific_heats[GAS_PLASMA] + (PRESSURE_O) * GLOB.gas_data.specific_heats[GAS_O2]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.gas_data.specific_heats[GAS_O2] / CELSIUS_TO_KELVIN(TEMP_O)))
#define OPTIMAL_TEMP_K_PLA_BURN_RATIO(PRESSURE_P,PRESSURE_O,TEMP_O) (CELSIUS_TO_KELVIN(TEMP_O) * PLASMA_OXYGEN_FULLBURN * (PRESSURE_P) / (PRESSURE_O))
/obj/effect/spawner/newbomb
@@ -19,10 +19,10 @@
var/obj/item/tank/internals/plasma/PT = new(V)
var/obj/item/tank/internals/oxygen/OT = new(V)
- PT.air_contents.set_moles(/datum/gas/plasma, pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)))
+ PT.air_contents.set_moles(GAS_PLASMA, pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)))
PT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_p))
- OT.air_contents.set_moles(/datum/gas/oxygen, pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)))
+ OT.air_contents.set_moles(GAS_O2, pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)))
OT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_o))
V.tank_one = PT
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index dc3cb66af6d0..08f70d4bd4af 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -133,7 +133,7 @@
if(get_dist(src, entry_vent) <= 1)
var/list/vents = list()
var/datum/pipeline/entry_vent_parent = entry_vent.parents[1]
- for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmosmch)
+ for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmos_machines)
vents.Add(temp_vent)
if(!vents.len)
entry_vent = null
diff --git a/code/game/objects/effects/turf_fire.dm b/code/game/objects/effects/turf_fire.dm
index 62e2e514ab1d..a7f98193af91 100644
--- a/code/game/objects/effects/turf_fire.dm
+++ b/code/game/objects/effects/turf_fire.dm
@@ -108,7 +108,7 @@
/obj/effect/abstract/turf_fire/proc/process_waste()
if(open_turf.planetary_atmos)
return TRUE
- var/oxy = open_turf.air.get_moles(/datum/gas/oxygen)
+ var/oxy = open_turf.air.get_moles(GAS_O2)
if (oxy < TURF_FIRE_BURN_MINIMUM_OXYGEN_REQUIRED)
return FALSE
var/thermal_energy = open_turf.air.return_temperature() * open_turf.air.heat_capacity()
@@ -116,8 +116,8 @@
if(burn_rate > oxy)
burn_rate = oxy
- open_turf.air.adjust_moles(/datum/gas/oxygen, -burn_rate)
- open_turf.air.adjust_moles(/datum/gas/carbon_dioxide, burn_rate * TURF_FIRE_BURN_CARBON_DIOXIDE_MULTIPLIER)
+ open_turf.air.adjust_moles(GAS_O2, -burn_rate)
+ open_turf.air.adjust_moles(GAS_CO2, burn_rate * TURF_FIRE_BURN_CARBON_DIOXIDE_MULTIPLIER)
open_turf.air.set_temperature((thermal_energy + (burn_rate * TURF_FIRE_ENERGY_PER_BURNED_OXY_MOL)) / open_turf.air.heat_capacity())
open_turf.air_update_turf(TRUE)
diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm
index 34fa0ccd6e2c..a9c029047219 100644
--- a/code/game/objects/empulse.dm
+++ b/code/game/objects/empulse.dm
@@ -1,32 +1,30 @@
-/proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
+/proc/empulse(turf/epicenter, severity, range=null, log=TRUE)
if(!epicenter)
+ CRASH("Warning: empulse() called without an epicenter!")
+
+ if(severity < 1)
return
if(!isturf(epicenter))
epicenter = get_turf(epicenter.loc)
+
+ if(isnull(range)) // range is equal to severity by default
+ range = severity
if(log)
- message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
- log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
-
- if(heavy_range > 1)
- new /obj/effect/temp_visual/emp/pulse(epicenter)
+ message_admins("EMP with size ([range]) and severity ([severity]) in area [epicenter.loc.name] ")
+ log_game("EMP with size ([range]) and severity ([severity]) in area [epicenter.loc.name] ")
- if(heavy_range > light_range)
- light_range = heavy_range
+ if(range <= 0)
+ for(var/atom/A in epicenter)
+ A.emp_act(severity)
+ return
- for(var/A in spiral_range(light_range, epicenter))
+ var/tile_falloff = severity / range
+ for(var/A in spiral_range(range, epicenter))
var/atom/T = A
- var/distance = get_dist(epicenter, T)
- if(distance < 0)
- distance = 0
- if(distance < heavy_range)
- T.emp_act(EMP_HEAVY)
- else if(heavy_range && distance == heavy_range) //0 radius heavy EMPs will have no effect
- if(prob(50))
- T.emp_act(EMP_HEAVY)
- else
- T.emp_act(EMP_LIGHT)
- else if(distance <= light_range)
- T.emp_act(EMP_LIGHT)
- return 1
+ var/decayed_severity = severity - round(get_dist(epicenter, T) * tile_falloff)
+ if(decayed_severity < 1)
+ continue
+ T.emp_act(decayed_severity)
+ return TRUE
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 4c40cf4173ec..dbf326d64000 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -71,7 +71,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/body_parts_partial_covered = 0 //same bit flags as above, only applies half armor to these body parts
var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets)
- var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit)
var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up
var/armour_penetration = 0 //percentage of armour effectiveness to remove
var/list/allowed = null //suit storage stuff.
@@ -296,6 +295,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(HAS_TRAIT(src, TRAIT_NO_STORAGE))
. += "[gender == PLURAL ? "They are" : "It is"] too bulky, fragile, or cumbersome to fit in a container."
+ if(demolition_mod > 1)
+ . += "[src] seems exceptionally good at breaking things!"
+ else if(demolition_mod < 1)
+ . += "[src] seems exceptionally bad at breaking things."
+
if(resistance_flags & INDESTRUCTIBLE)
. += "[src] seems extremely robust! It'll probably withstand anything that could happen to it!"
else
diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm
index 3c25133864f1..c547a7078779 100644
--- a/code/game/objects/items/RCD.dm
+++ b/code/game/objects/items/RCD.dm
@@ -12,7 +12,7 @@ RLD
/obj/item/construction
name = "not for ingame use"
desc = "A device used to rapidly build and deconstruct. Reload with metal, plasteel, glass or compressed matter cartridges."
- opacity = 0
+ opacity = FALSE
density = FALSE
anchored = FALSE
flags_1 = CONDUCT_1
diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm
index 5b9ec8c74943..523293932963 100644
--- a/code/game/objects/items/RPD.dm
+++ b/code/game/objects/items/RPD.dm
@@ -467,7 +467,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
P.update()
P.add_fingerprint(usr)
- P.setPipingLayer(piping_layer)
+ P.set_piping_layer(piping_layer)
if(findtext("[queued_p_type]", "/obj/machinery/atmospherics/pipe") && !findtext("[queued_p_type]", "layer_manifold"))
P.add_atom_colour(GLOB.pipe_paint_colors[paint_color], FIXED_COLOUR_PRIORITY)
if(mode&WRENCH_MODE)
diff --git a/code/game/objects/items/RSF.dm b/code/game/objects/items/RSF.dm
index dce2f155e9e7..a497be7a27c2 100644
--- a/code/game/objects/items/RSF.dm
+++ b/code/game/objects/items/RSF.dm
@@ -13,7 +13,7 @@ RSF
var/spent_icon_state = "rsf_empty"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
- opacity = 0
+ opacity = FALSE
density = FALSE
anchored = FALSE
item_flags = NOBLUDGEON
diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm
index a11921c19de2..3095d7a3cd7d 100644
--- a/code/game/objects/items/chrono_eraser.dm
+++ b/code/game/objects/items/chrono_eraser.dm
@@ -253,12 +253,18 @@
return BULLET_ACT_HIT
/obj/structure/chrono_field/assume_air()
- return 0
+ return null
+
+/obj/effect/chrono_field/assume_air_moles()
+ return null
+
+/obj/effect/chrono_field/assume_air_ratio()
+ return null
/obj/structure/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
- GM.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
- GM.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
+ GM.set_moles(GAS_O2, MOLES_O2STANDARD)
+ GM.set_moles(GAS_N2, MOLES_N2STANDARD)
GM.set_temperature(T20C)
return GM
diff --git a/code/game/objects/items/credit_holochip.dm b/code/game/objects/items/credit_holochip.dm
index 5d1cc2e0deb9..6683b6c5481e 100644
--- a/code/game/objects/items/credit_holochip.dm
+++ b/code/game/objects/items/credit_holochip.dm
@@ -105,7 +105,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- var/wipe_chance = 60 / severity
+ var/wipe_chance = 6 * severity
if(prob(wipe_chance))
visible_message(span_warning("[src] fizzles and disappears!"))
qdel(src) //rip cash
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 589103941ff1..ea6d0c4fbf05 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -153,7 +153,7 @@
. = ..()
if(cell && !(. & EMP_PROTECT_CONTENTS))
- deductcharge(5000 / severity)
+ deductcharge(500 * severity)
if (. & EMP_PROTECT_SELF)
return
@@ -308,7 +308,6 @@
/obj/item/shockpaddles/Initialize(mapload, obj/item/defibrillator/spawned_in)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = 8, \
force_wielded = 12, \
icon_wielded = "[base_icon_state]1", \
)
@@ -462,12 +461,14 @@
return
if(!req_defib && !combat)
return
- busy = TRUE
M.visible_message(span_danger("[user] has touched [M] with [src]!"), \
span_userdanger("[user] has touched [M] with [src]!"))
- M.adjustStaminaLoss(50)
- M.Knockdown(100)
- M.updatehealth() //forces health update before next life tick //isn't this done by adjustStaminaLoss anyway?
+ var/hit_percent = (100 - M.getarmor(user.zone_selected, ELECTRIC)) / 100
+ if(!hit_percent)
+ return
+ busy = TRUE
+ M.adjustStaminaLoss(50 * hit_percent)
+ M.Knockdown((10 * hit_percent) SECONDS)
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
M.emote("gasp")
log_combat(user, M, "stunned", src)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 51edcb5d3e2f..edd624f642e3 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -410,14 +410,13 @@ GLOBAL_LIST_EMPTY(PDAs)
if (3)
dat += "[PDAIMG(atmos)] Atmospheric Readings "
- var/turf/T = user.loc
- if (isnull(T))
+ if (!isopenturf(get_turf(user)))
dat += "Unable to obtain a reading. "
else
- var/datum/gas_mixture/environment = T.return_air()
+ var/datum/gas_mixture/environment = user.return_air()
- var/pressure = environment.return_pressure()
- var/total_moles = environment.total_moles()
+ var/pressure = environment?.return_pressure()
+ var/total_moles = environment?.total_moles()
dat += "Air Pressure: [round(pressure,0.1)] kPa "
@@ -425,7 +424,7 @@ GLOBAL_LIST_EMPTY(PDAs)
for(var/id in environment.get_gases())
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0)
- dat += "[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_level*100, 0.01)]% "
+ dat += "[GLOB.gas_data.names[id]]: [round(gas_level*100, 0.01)]% "
dat += "Temperature: [round(environment.return_temperature()-T0C)]°C "
dat += " "
@@ -1227,7 +1226,7 @@ GLOBAL_LIST_EMPTY(PDAs)
A.emp_act(severity)
if (!(. & EMP_PROTECT_SELF))
emped += 1
- spawn(200 * severity)
+ spawn(20 * severity)
emped -= 1
/proc/get_viewable_pdas()
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 6b538bff266a..e5a6611c0df1 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -32,6 +32,7 @@
set_light_on(on)
if(light_system == STATIC_LIGHT)
update_light()
+
/obj/item/flashlight/attack_self(mob/user)
on = !on
update_brightness(user)
@@ -236,6 +237,7 @@
force = 9 // Not as good as a stun baton.
light_range = 5 // A little better than the standard flashlight.
hitsound = 'sound/weapons/genhit1.ogg'
+ light_system = MOVABLE_LIGHT_DIRECTIONAL
// the desk lamps are a bit special
/obj/item/flashlight/lamp
diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm
index dc6c33d1a1b4..84f32bcdabca 100644
--- a/code/game/objects/items/devices/laserpointer.dm
+++ b/code/game/objects/items/devices/laserpointer.dm
@@ -87,7 +87,7 @@
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
- if(H.dna.check_mutation(HULK) || H.dna.check_mutation(ACTIVE_HULK))
+ if(H.dna.check_mutation(HULK))
to_chat(user, span_warning("Your fingers can't press the button!"))
return
diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm
index 8f2e996ef16e..4bf8b57b1dc9 100644
--- a/code/game/objects/items/devices/megaphone.dm
+++ b/code/game/objects/items/devices/megaphone.dm
@@ -7,7 +7,6 @@
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
- siemens_coefficient = 1
var/last_used = 0
var/list/voicespan = list(SPAN_COMMAND)
diff --git a/code/game/objects/items/devices/pseudocider.dm b/code/game/objects/items/devices/pseudocider.dm
index 64d2cfdaeb8b..be75eaacab07 100644
--- a/code/game/objects/items/devices/pseudocider.dm
+++ b/code/game/objects/items/devices/pseudocider.dm
@@ -9,7 +9,7 @@
var/active = FALSE
var/mob/living/carbon/fake_corpse
COOLDOWN_DECLARE(fake_death_timer)
- var/fake_death_cooldown = 20 SECONDS
+ var/fake_death_cooldown = 30 SECONDS
/obj/item/pseudocider/update_icon_state()
icon_state = "[base_icon_state][active ? "-open" : "-closed"]"
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 6c4bf27335cd..e1159a7dce30 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -206,7 +206,7 @@
/obj/item/radio/headset/headset_cent
name = "\improper CentCom headset"
- desc = "A headset used by the upper echelons of NanoTrasen."
+ desc = "A headset used by the upper echelons of Nanotrasen."
icon_state = "cent_headset"
keyslot = new /obj/item/encryptionkey/headset_com
keyslot2 = new /obj/item/encryptionkey/headset_cent
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 873b1803cf31..cb5027fa300c 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -429,7 +429,6 @@ GLOBAL_LIST_INIT(channel_tokens, list(
if (. & EMP_PROTECT_SELF)
return
emped++ //There's been an EMP; better count it
- var/curremp = emped //Remember which EMP this was
if (listening && ismob(loc)) // if the radio is turned on and on someone's person they notice
to_chat(loc, span_warning("\The [src] overloads."))
broadcasting = FALSE
@@ -437,11 +436,9 @@ GLOBAL_LIST_INIT(channel_tokens, list(
for (var/ch_name in channels)
channels[ch_name] = 0
on = FALSE
- addtimer(CALLBACK(src, PROC_REF(end_emp_effect), curremp), 200)
+ addtimer(CALLBACK(src, PROC_REF(end_emp_effect)), 20 * severity, TIMER_UNIQUE | TIMER_OVERRIDE)
-/obj/item/radio/proc/end_emp_effect(curremp)
- if(emped != curremp) //Don't fix it if it's been EMP'd again
- return FALSE
+/obj/item/radio/proc/end_emp_effect()
emped = FALSE
on = TRUE
return TRUE
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 7d32ab02180d..39633ed98f4d 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -362,7 +362,7 @@ GENE SCANNER
var/mob/living/carbon/human/H = M
var/datum/species/S = H.dna.species
var/mutant = FALSE
- if (H.dna.check_mutation(HULK) || H.dna.check_mutation(ACTIVE_HULK))
+ if (H.dna.check_mutation(HULK))
mutant = TRUE
else if (S.mutantlungs != initial(S.mutantlungs))
mutant = TRUE
@@ -623,11 +623,14 @@ GENE SCANNER
if (user.stat || user.eye_blind)
return
- var/turf/location = user.loc
- if(!istype(location))
+ if(!isopenturf(get_turf(user)))
return
- var/datum/gas_mixture/environment = location.return_air()
+ var/datum/gas_mixture/environment = user.return_air()
+
+ if(!environment)
+ to_chat(user, span_info("No air detected."))
+ return
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
@@ -638,36 +641,36 @@ GENE SCANNER
else
combined_msg += span_alert("Pressure: [round(pressure, 0.01)] kPa")
if(total_moles)
- var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles
- var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles
- var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles
- var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles
+ var/o2_concentration = environment.get_moles(GAS_O2)/total_moles
+ var/n2_concentration = environment.get_moles(GAS_N2)/total_moles
+ var/co2_concentration = environment.get_moles(GAS_CO2)/total_moles
+ var/plasma_concentration = environment.get_moles(GAS_PLASMA)/total_moles
if(abs(n2_concentration - N2STANDARD) < 20)
- combined_msg += span_info("Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)")
+ combined_msg += span_info("Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_N2), 0.01)] mol)")
else
- combined_msg += span_alert("Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)")
+ combined_msg += span_alert("Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_N2), 0.01)] mol)")
if(abs(o2_concentration - O2STANDARD) < 2)
- combined_msg += span_info("Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)")
+ combined_msg += span_info("Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_O2), 0.01)] mol)")
else
- combined_msg += span_alert("Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)")
+ combined_msg += span_alert("Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_O2), 0.01)] mol)")
if(co2_concentration > 0.01)
- combined_msg += span_alert("CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)")
+ combined_msg += span_alert("CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_CO2), 0.01)] mol)")
else
- combined_msg += span_info("CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)")
+ combined_msg += span_info("CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_CO2), 0.01)] mol)")
if(plasma_concentration > 0.005)
- combined_msg += span_alert("Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)")
+ combined_msg += span_alert("Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_PLASMA), 0.01)] mol)")
else
- combined_msg += span_info("Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)")
+ combined_msg += span_info("Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_PLASMA), 0.01)] mol)")
for(var/id in environment.get_gases())
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = environment.get_moles(id)/total_moles
- combined_msg += span_alert("[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)")
+ combined_msg += span_alert("[GLOB.gas_data.names[id]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)")
combined_msg += span_info("Temperature: [round(environment.return_temperature()-T0C, 0.01)] °C ([round(environment.return_temperature(), 0.01)] K)")
to_chat(user, examine_block(combined_msg.Join("\n")))
@@ -764,7 +767,7 @@ GENE SCANNER
for(var/id in air_contents.get_gases())
var/gas_concentration = air_contents.get_moles(id)/total_moles
- combined_msg += span_notice("[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(air_contents.get_moles(id), 0.01)] mol)")
+ combined_msg += span_notice("[GLOB.gas_data.names[id]]: [round(gas_concentration*100, 0.01)] % ([round(air_contents.get_moles(id), 0.01)] mol)")
combined_msg += span_notice("Temperature: [round(temperature - T0C,0.01)] °C ([round(temperature, 0.01)] K)")
else
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index 8848dd0e2f28..7a195a99be79 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -130,22 +130,17 @@
target_self = TRUE
if(change_volume)
if(!target_self)
- target.set_volume(target.return_volume() + tank_two.air_contents.return_volume())
+ target.set_volume(target.return_volume() + tank_two.volume)
target.set_volume(target.return_volume() + tank_one.air_contents.return_volume())
- var/datum/gas_mixture/temp
- temp = tank_one.air_contents.remove_ratio(1)
- target.merge(temp)
+ tank_one.air_contents.transfer_ratio_to(target, 1)
if(!target_self)
- temp = tank_two.air_contents.remove_ratio(1)
- target.merge(temp)
+ tank_two.air_contents.transfer_ratio_to(target, 1)
/obj/item/transfer_valve/proc/split_gases()
if (!valve_open || !tank_one || !tank_two)
return
var/ratio1 = tank_one.air_contents.return_volume()/tank_two.air_contents.return_volume()
- var/datum/gas_mixture/temp
- temp = tank_two.air_contents.remove_ratio(ratio1)
- tank_one.air_contents.merge(temp)
+ tank_two.air_contents.transfer_ratio_to(tank_one.air_contents, ratio1)
tank_two.air_contents.set_volume(tank_two.air_contents.return_volume() - tank_one.air_contents.return_volume())
/*
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index 7d182fba2cbd..2ec72419d8d2 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -88,12 +88,7 @@
/obj/item/dnainjector/antihulk
name = "\improper DNA injector (Anti-Hulk)"
desc = "Cures green skin."
- remove_mutations = list(HULK, ACTIVE_HULK, GENETICS_HULK)
-
-/obj/item/dnainjector/hulkmut/genetics_hulk
- name = "\improper DNA injector (Genetics Hulk)"
- desc = "This will make you big and strong if you get hurt, but give you a bad skin condition."
- add_mutations = list(GENETICS_HULK)
+ remove_mutations = list(HULK)
/obj/item/dnainjector/hulkmut
name = "\improper DNA injector (Hulk)"
diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm
index 74049fab9c8b..97b8302758f0 100644
--- a/code/game/objects/items/extinguisher.dm
+++ b/code/game/objects/items/extinguisher.dm
@@ -168,43 +168,12 @@
var/turf/T4 = get_step(T2,turn(direction, -90))
the_targets.Add(T3,T4)
- var/list/water_particles=list()
for(var/a=0, a<5, a++)
- var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(src))
var/my_target = pick(the_targets)
- water_particles[W] = my_target
- // If precise, remove turf from targets so it won't be picked more than once
+ var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(src), my_target)
+ reagents.trans_to(W, chem_amount, transfered_by = user)
if(precision)
the_targets -= my_target
- var/datum/reagents/R = new/datum/reagents(5)
- W.reagents = R
- R.my_atom = W
- reagents.trans_to(W, chem_amount, transfered_by = user)
-
- //Make em move dat ass, hun
- addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_particles, water_particles), 2)
-
-//Particle movement loop
-/obj/item/extinguisher/proc/move_particles(list/particles, repetition=0)
- //Check if there's anything in here first
- if(!particles || particles.len == 0)
- return
- // Second loop: Get all the water particles and make them move to their target
- for(var/obj/effect/particle_effect/water/W in particles)
- var/turf/my_target = particles[W]
- if(!W)
- continue
- step_towards(W,my_target)
- if(!W.reagents)
- continue
- W.reagents.reaction(get_turf(W))
- for(var/A in get_turf(W))
- W.reagents.reaction(A)
- if(W.loc == my_target)
- particles -= W
- if(repetition < power)
- repetition++
- addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_particles, particles, repetition), 2)
//Chair movement loop
/obj/item/extinguisher/proc/move_chair(obj/B, movementdirection, repetition=0)
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index 1ef10bf9a414..1d49b434522e 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -205,27 +205,27 @@
var/datum/gas_mixture/fuel_mix = ptank.air_contents.remove_ratio(ratio_removed)
// Return of the stimball flamethrower, wear radiation protection when using this or you're just as likely to die as your target
- if(fuel_mix.get_moles(/datum/gas/plasma) >= NITRO_BALL_MOLES_REQUIRED && fuel_mix.get_moles(/datum/gas/nitrium) >= NITRO_BALL_MOLES_REQUIRED && fuel_mix.get_moles(/datum/gas/pluoxium) >= NITRO_BALL_MOLES_REQUIRED)
- var/balls_shot = round(min(fuel_mix.get_moles(/datum/gas/nitrium), fuel_mix.get_moles(/datum/gas/pluoxium), NITRO_BALL_MAX_REACT_RATE / NITRO_BALL_MOLES_REQUIRED))
+ if(fuel_mix.get_moles(GAS_PLASMA) >= NITRO_BALL_MOLES_REQUIRED && fuel_mix.get_moles(GAS_NITRIUM) >= NITRO_BALL_MOLES_REQUIRED && fuel_mix.get_moles(GAS_PLUOXIUM) >= NITRO_BALL_MOLES_REQUIRED)
+ var/balls_shot = round(min(fuel_mix.get_moles(GAS_NITRIUM), fuel_mix.get_moles(GAS_PLUOXIUM), NITRO_BALL_MAX_REACT_RATE / NITRO_BALL_MOLES_REQUIRED))
var/angular_increment = 360/balls_shot
var/random_starting_angle = rand(0,360)
for(var/i in 1 to balls_shot)
target.fire_nuclear_particle((i*angular_increment+random_starting_angle))
- fuel_mix.adjust_moles(/datum/gas/plasma, -balls_shot * NITRO_BALL_MOLES_REQUIRED) // No free extra damage for you, conservation of mass go brrrrr
+ fuel_mix.adjust_moles(GAS_PLASMA, -balls_shot * NITRO_BALL_MOLES_REQUIRED) // No free extra damage for you, conservation of mass go brrrrr
// Funny rad flamethrower go brrr
- if(fuel_mix.get_moles(/datum/gas/tritium)) // Tritium fires cause a bit of radiation
- radiation_pulse(target, min(fuel_mix.get_moles(/datum/gas/tritium), fuel_mix.get_moles(/datum/gas/oxygen)/2) * FIRE_HYDROGEN_ENERGY_RELEASED / TRITIUM_BURN_RADIOACTIVITY_FACTOR)
+ if(fuel_mix.get_moles(GAS_TRITIUM)) // Tritium fires cause a bit of radiation
+ radiation_pulse(target, min(fuel_mix.get_moles(GAS_TRITIUM), fuel_mix.get_moles(GAS_O2)/2) * FIRE_HYDROGEN_ENERGY_RELEASED / TRITIUM_BURN_RADIOACTIVITY_FACTOR)
// 8 damage at 0.5 mole transfer or ~17 kPa release pressure
// 16 damage at 1 mole transfer or ~35 kPa release pressure
- var/damage = fuel_mix.get_moles(/datum/gas/plasma) * 16
+ var/damage = fuel_mix.get_moles(GAS_PLASMA) * 16
// harder to achieve than plasma
- damage += fuel_mix.get_moles(/datum/gas/tritium) * 24 // Lower damage than hydrogen, causes minor radiation
- damage += fuel_mix.get_moles(/datum/gas/hydrogen) * 32
+ damage += fuel_mix.get_moles(GAS_TRITIUM) * 24 // Lower damage than hydrogen, causes minor radiation
+ damage += fuel_mix.get_moles(GAS_H2) * 32
// Maximum damage restricted by the available oxygen, with a hard cap at 16
var/datum/gas_mixture/turf_air = target.return_air()
- damage = min(damage, turf_air.get_moles(/datum/gas/oxygen) + fuel_mix.get_moles(/datum/gas/oxygen), max_damage) // capped by combined oxygen in the fuel mix and enviroment
+ damage = min(damage, turf_air.get_moles(GAS_O2) + fuel_mix.get_moles(GAS_O2), max_damage) // capped by combined oxygen in the fuel mix and enviroment
// If there's not enough fuel and/or oxygen to do more than 1 damage, shut itself off
if(damage < 1)
diff --git a/code/game/objects/items/granters/magic/charge.dm b/code/game/objects/items/granters/magic/charge.dm
index 72ab119aa152..d0c33ed14701 100644
--- a/code/game/objects/items/granters/magic/charge.dm
+++ b/code/game/objects/items/granters/magic/charge.dm
@@ -17,4 +17,4 @@
/obj/item/book/granter/action/spell/charge/recoil(mob/living/user)
. = ..()
to_chat(user,span_warning("[src] suddenly feels very warm!"))
- empulse(src, 1, 1)
\ No newline at end of file
+ empulse(src, EMP_HEAVY, 0)
diff --git a/code/game/objects/items/grenades/atmos_grenades.dm b/code/game/objects/items/grenades/atmos_grenades.dm
index 27d8c8eda24c..0df6b3d6a9d7 100644
--- a/code/game/objects/items/grenades/atmos_grenades.dm
+++ b/code/game/objects/items/grenades/atmos_grenades.dm
@@ -44,9 +44,8 @@
if(floor_loc.air.return_temperature() > 370)
floor_loc.atmos_spawn_air("n2=[gas_amount / distance_from_center];TEMP=30")
floor_loc.MakeSlippery(TURF_WET_PERMAFROST, (5 / distance_from_center) MINUTES)
- if(floor_loc.air.get_gases(/datum/gas/plasma))
- floor_loc.air.adjust_moles(/datum/gas/plasma, -(floor_loc.air.get_moles(/datum/gas/plasma) * 0.5 / distance_from_center))
- floor_loc.air_update_turf()
+ if(floor_loc.air.get_gases(GAS_PLASMA))
+ floor_loc.air.adjust_moles(GAS_PLASMA, -(floor_loc.air.get_moles(GAS_PLASMA) * 0.5 / distance_from_center))
for(var/mob/living/carbon/live_mob in turf_loc)
live_mob.adjustStaminaLoss(stamina_damage / distance_from_center)
live_mob.adjust_bodytemperature(-150 / distance_from_center)
diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm
index 416ac77f0518..2423c687ef52 100644
--- a/code/game/objects/items/grenades/chem_grenade.dm
+++ b/code/game/objects/items/grenades/chem_grenade.dm
@@ -151,7 +151,7 @@
/obj/item/grenade/chem_grenade/emp_act(severity)
..()
- if(prob(40/severity))
+ if(prob(4 * severity))
prime()
/obj/item/grenade/chem_grenade/on_found(mob/finder)
diff --git a/code/game/objects/items/grenades/emgrenade.dm b/code/game/objects/items/grenades/emgrenade.dm
index 99cf4bdf99d1..082663addd44 100644
--- a/code/game/objects/items/grenades/emgrenade.dm
+++ b/code/game/objects/items/grenades/emgrenade.dm
@@ -6,5 +6,5 @@
/obj/item/grenade/empgrenade/prime()
update_mob()
- empulse(src, 4, 10)
+ empulse(src, EMP_HEAVY)
qdel(src)
diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm
index a66c2cdec5c8..bfa0f46dcfe9 100644
--- a/code/game/objects/items/grenades/flashbang.dm
+++ b/code/game/objects/items/grenades/flashbang.dm
@@ -13,7 +13,7 @@
return
do_sparks(rand(5, 9), FALSE, src)
playsound(flashbang_turf, 'sound/weapons/flashbang.ogg', 100, TRUE, 8, 0.9)
- new /obj/effect/dummy/lighting_obj (flashbang_turf, flashbang_range + 2, 4, COLOR_WHITE, 2)
+ new /obj/effect/dummy/lighting_obj(flashbang_turf, flashbang_range + 2, 4, COLOR_WHITE, 2)
for(var/mob/living/M in get_hearers_in_view(flashbang_range, flashbang_turf))
bang(get_turf(M), M)
qdel(src)
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index f933ef821122..856dd4bf9387 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -859,12 +859,13 @@
force = 0 // How often we forget
throwforce = 0 // Faith without works is...
attack_verb = list("blessed")
+ menutab = MENU_MISC
+ additional_desc = "A holy icon, praying to it will allow it to weaken and burn those that draw your god's ire."
+
var/held_up = FALSE
var/mutable_appearance/holy_glow_fx
- var/obj/effect/dummy/lighting_obj/moblight/holy_glow_light
COOLDOWN_DECLARE(holy_notification)
- menutab = MENU_MISC
- additional_desc = "A holy icon, praying to it will allow it to weaken and burn those that draw your god's ire."
+ var/obj/effect/dummy/lighting_obj/moblight/holy_glow_light
/obj/item/nullrod/cross/attack_self(mob/living/user)
. = ..()
@@ -879,7 +880,7 @@
slot_flags = 0
holy_glow_fx = mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER)
user.add_overlay(holy_glow_fx)
- holy_glow_light = user.mob_light(_color = LIGHT_COLOR_HOLY_MAGIC, _range = 2)
+ holy_glow_light = user.mob_light(range = 2, color = LIGHT_COLOR_HOLY_MAGIC)
RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(unwield))
RegisterSignal(src, COMSIG_ITEM_PREDROPPED, PROC_REF(drop_unwield))
START_PROCESSING(SSfastprocess, src)
@@ -1093,7 +1094,7 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
playsound(target, 'sound/weapons/rapierhit.ogg', 30, 1, -1)
owner.take_overall_damage(5)
visible_message("[src] smacks [owner] in the face as [owner.p_they()] try to catch it with [owner.p_their()] hands full!")
- else if(possessed)
+ else if(possessed && soul)
transform = initial(transform)//to reset rotation for when it drops to the ground
blade = new /mob/living/simple_animal/nullrod(get_turf(src))
blade.sword = src
@@ -1301,43 +1302,12 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
var/turf/T5 = get_step(get_turf(target),turn(direction, -90))
var/list/the_targets = list(T,T1,T2,T3,T4,T5)
- var/list/water_particles=list()
for(var/a=0, a<6, a++)
- var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(src))
- W.life = distance
var/my_target = pick(the_targets)
- water_particles[W] = my_target
- the_targets -= my_target
- var/datum/reagents/R = new/datum/reagents(1)
- W.reagents = R
- R.my_atom = W
+ var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(src), my_target, TOUCH|VAPOR)
W.reagents.add_reagent(/datum/reagent/water/holywater, 1)
-
- //Make em move dat ass, hun
- addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_particles, water_particles), 1)
-
-//Particle movement loop
-/obj/item/nullrod/aspergillum/proc/move_particles(list/particles, repetition=0)
- //Check if there's anything in here first
- if(!particles || particles.len == 0)
- return
- // Second loop: Get all the water particles and make them move to their target
- for(var/obj/effect/particle_effect/water/W in particles)
- var/turf/my_target = particles[W]
- if(!W)
- continue
- step_towards(W,my_target)
- if(!W.reagents)
- continue
- for(var/A in get_turf(W))
- if(A == src.loc)//don't fill the chaplain with holy water
- continue
- W.reagents.reaction(A, TOUCH|VAPOR)
- if(W.loc == my_target)
- particles -= W
- if(repetition < distance)
- repetition++
- addtimer(CALLBACK(src, /obj/item/extinguisher/proc/move_particles, particles, repetition), 1)
+ the_targets -= my_target
+ W.life = distance
/obj/item/nullrod/aspergillum/update_icon_state()
. = ..()
diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm
index 837b947b3bf7..9bbece6a4047 100644
--- a/code/game/objects/items/implants/implant_misc.dm
+++ b/code/game/objects/items/implants/implant_misc.dm
@@ -64,7 +64,7 @@
/obj/item/implant/emp/activate()
. = ..()
uses--
- empulse(imp_in, 3, 5)
+ empulse(imp_in, EMP_HEAVY, 5) // 10 severity, extends to 5 tiles
if(!uses)
qdel(src)
@@ -174,13 +174,13 @@
UnregisterSignal(target, COMSIG_ATOM_EMP_ACT)
return TRUE
-/obj/item/implant/empshield/proc/overloaded(mob/living/target)
+/obj/item/implant/empshield/proc/overloaded(mob/living/target, severity)
if(world.time - lastemp > overloadtimer)
numrecent = 0
- numrecent ++
+ numrecent += severity
lastemp = world.time
- if(numrecent >= 5 && ishuman(target))
+ if(numrecent >= (5 * EMP_HEAVY) && ishuman(target))
if(warning)
to_chat(target, span_userdanger("You feel a twinge inside from your [src], you get the feeling it won't protect you anymore."))
warning = FALSE
diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm
index e3aadfe0fe34..77bc76d2b0a5 100644
--- a/code/game/objects/items/implants/implantchair.dm
+++ b/code/game/objects/items/implants/implantchair.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/machines/implantchair.dmi'
icon_state = "implantchair"
density = TRUE
- opacity = 0
+ opacity = FALSE
var/ready = TRUE
var/replenishing = FALSE
diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm
index 773871e48a49..9d6e0c8a939f 100644
--- a/code/game/objects/items/kitchen.dm
+++ b/code/game/objects/items/kitchen.dm
@@ -92,6 +92,7 @@
hitsound = 'sound/weapons/bladeslice.ogg'
throw_speed = 3
throw_range = 6
+ demolition_mod = 0.8
materials = list(/datum/material/iron=12000)
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
sharpness = SHARP_EDGED
diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm
index da1f73bfdd5b..4a3f74dea584 100644
--- a/code/game/objects/items/melee/misc.dm
+++ b/code/game/objects/items/melee/misc.dm
@@ -626,7 +626,6 @@
T.visible_message(span_danger("[T] smacks into [src] and rapidly flashes to ash."),\
span_italics("You hear a loud crack as you are washed with a wave of heat."))
shard.Consume()
- CALCULATE_ADJACENT_TURFS(T)
/obj/item/melee/supermatter_sword/add_blood_DNA(list/blood_dna)
return FALSE
diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm
index 80275184e206..982116fe9651 100644
--- a/code/game/objects/items/mop.dm
+++ b/code/game/objects/items/mop.dm
@@ -21,7 +21,7 @@
/obj/item/mop/Initialize(mapload)
. = ..()
- create_reagents(mopcap)
+ create_reagents(mopcap, REFILLABLE)
/obj/item/mop/proc/clean(turf/A)
diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm
index d35a33d472c6..f6e8f65c2884 100644
--- a/code/game/objects/items/powerfist.dm
+++ b/code/game/objects/items/powerfist.dm
@@ -1,4 +1,4 @@
-/obj/item/melee/powerfist
+/obj/item/clothing/gloves/powerfist
name = "power-fist"
desc = "A metal gauntlet with a piston-powered ram ontop for that extra 'ompfh' in your punch."
icon = 'icons/obj/traitor.dmi'
@@ -11,16 +11,29 @@
force = 20
throwforce = 10
throw_range = 7
+ strip_delay = 80
+ cold_protection = HANDS
+ heat_protection = HANDS
w_class = WEIGHT_CLASS_NORMAL
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 40)
- resistance_flags = FIRE_PROOF
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, ELECTRIC = 100)
+ resistance_flags = FIRE_PROOF | ACID_PROOF
var/click_delay = 1.5
var/fisto_setting = 1
+ var/max_setting = 3
var/gasperfist = 3
var/obj/item/tank/internals/tank = null //Tank used for the gauntlet's piston-ram.
+/obj/item/clothing/gloves/powerfist/equipped(mob/user, slot)
+ . = ..()
+ if(slot & ITEM_SLOT_GLOVES)
+ RegisterSignal(user, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, PROC_REF(power_punch))
+
+/obj/item/clothing/gloves/powerfist/dropped(mob/user)
+ if(user.get_item_by_slot(ITEM_SLOT_GLOVES)==src)
+ UnregisterSignal(user, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
+ return ..()
-/obj/item/melee/powerfist/examine(mob/user)
+/obj/item/clothing/gloves/powerfist/examine(mob/user)
. = ..()
if(!in_range(user, src))
. += span_notice("You'll need to get closer to see any more.")
@@ -29,7 +42,7 @@
. += span_notice("[icon2html(tank, user)] It has \a [tank] mounted onto it.")
-/obj/item/melee/powerfist/attackby(obj/item/W, mob/user, params)
+/obj/item/clothing/gloves/powerfist/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/tank/internals))
if(!tank)
var/obj/item/tank/internals/IT = W
@@ -38,20 +51,20 @@
return
updateTank(W, 0, user)
else if(W.tool_behaviour == TOOL_WRENCH)
- switch(fisto_setting)
- if(1)
- fisto_setting = 2
- if(2)
- fisto_setting = 3
- if(3)
- fisto_setting = 1
+ fisto_setting++
+ if(fisto_setting > max_setting)
+ fisto_setting = 1
W.play_tool_sound(src)
+ user.balloon_alert(user, span_notice("power set to [fisto_setting]"))
to_chat(user, span_notice("You tweak \the [src]'s piston valve to [fisto_setting]."))
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
if(tank)
updateTank(tank, 1, user)
+ else if(W.tool_behaviour == TOOL_ANALYZER)
+ if(tank)
+ atmosanalyzer_scan(user, tank)
-/obj/item/melee/powerfist/proc/updateTank(obj/item/tank/internals/thetank, removing = 0, mob/living/carbon/human/user)
+/obj/item/clothing/gloves/powerfist/proc/updateTank(obj/item/tank/internals/thetank, removing = 0, mob/living/carbon/human/user)
if(removing)
if(!tank)
to_chat(user, span_notice("\The [src] currently has no tank attached to it."))
@@ -69,32 +82,36 @@
to_chat(user, span_notice("You hook \the [thetank] up to \the [src]."))
tank = thetank
+/obj/item/clothing/gloves/powerfist/attack(mob/living/target, mob/living/user)
+ power_punch(user, target)
-/obj/item/melee/powerfist/attack(mob/living/target, mob/living/user)
+/obj/item/clothing/gloves/powerfist/proc/power_punch(mob/living/user, atom/movable/target)
+ if(!user || user.a_intent!=INTENT_HARM || (!isliving(target) && !isobj(target)) || isitem(target))
+ return
if(!tank)
to_chat(user, span_warning("\The [src] can't operate without a source of gas!"))
return
+ var/moles_used = min(tank.air_contents.total_moles(), gasperfist * fisto_setting)
var/datum/gas_mixture/gasused = tank.air_contents.remove(gasperfist * fisto_setting)
var/turf/T = get_turf(src)
if(!T)
return
T.assume_air(gasused)
- T.air_update_turf()
if(!gasused)
to_chat(user, span_warning("\The [src]'s tank is empty!"))
- target.apply_damage((force / 5), BRUTE)
+ do_attack(user, target, force / 5)
playsound(loc, 'sound/weapons/punch1.ogg', 50, 1)
target.visible_message(span_danger("[user]'s powerfist lets out a dull thunk as [user.p_they()] punch[user.p_es()] [target.name]!"), \
span_userdanger("[user]'s punches you!"))
- return
- if(gasused.total_moles() < gasperfist * fisto_setting)
+ return COMPONENT_NO_ATTACK_HAND
+ if(moles_used < gasperfist * fisto_setting)
to_chat(user, span_warning("\The [src]'s piston-ram lets out a weak hiss, it needs more gas!"))
playsound(loc, 'sound/weapons/punch4.ogg', 50, 1)
- target.apply_damage((force / 2), BRUTE)
+ do_attack(user, target, force / 2)
target.visible_message(span_danger("[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!"), \
span_userdanger("[user]'s punch strikes with force!"))
- return
- target.apply_damage(force * fisto_setting, BRUTE, wound_bonus = CANT_WOUND)
+ return COMPONENT_NO_ATTACK_HAND
+ do_attack(user, target, force * moles_used / gasperfist)
target.visible_message(span_danger("[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!"), \
span_userdanger("You cry out in pain as [user]'s punch flings you backwards!"))
new /obj/effect/temp_visual/kinetic_blast(target.loc)
@@ -103,18 +120,27 @@
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
- target.throw_at(throw_target, 5 * fisto_setting, 0.5 + (fisto_setting / 2))
+ if(!target.anchored)
+ target.throw_at(throw_target, 5 * fisto_setting, 0.5 + (fisto_setting / 2))
log_combat(user, target, "power fisted", src)
- user.changeNext_move(CLICK_CD_MELEE * click_delay)
+ return COMPONENT_NO_ATTACK_HAND
- return
+/obj/item/clothing/gloves/powerfist/proc/do_attack(mob/living/user, atom/target, punch_force)
+ if(isliving(target))
+ var/mob/living/target_mob = target
+ target_mob.apply_damage(punch_force, BRUTE, wound_bonus = CANT_WOUND)
+ else if(isobj(target))
+ var/obj/target_obj = target
+ target_obj.take_damage(punch_force, BRUTE, MELEE, FALSE)
+ user.do_attack_animation(target, ATTACK_EFFECT_SMASH)
+ user.changeNext_move(CLICK_CD_MELEE * click_delay)
-/obj/item/melee/powerfist/filled
+/obj/item/clothing/gloves/powerfist/filled
var/obj/item/tank/internals/plasma/full/fire
-/obj/item/melee/powerfist/filled/Initialize(mapload)
+/obj/item/clothing/gloves/powerfist/filled/Initialize(mapload)
. = ..()
fire = new(src)
tank = fire
diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm
index c521b30fef2a..d896615dbf01 100644
--- a/code/game/objects/items/religion.dm
+++ b/code/game/objects/items/religion.dm
@@ -325,11 +325,11 @@
name = "Plate Gauntlets"
icon_state = "crusader"
desc = "They're like gloves, but made of metal."
- siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 100)
/obj/item/clothing/gloves/plate/red
icon_state = "crusader-red"
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index cb459e0914fc..c7baf90124e5 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -133,7 +133,7 @@
if(scooldown < world.time)
if(M.health >= 0)
if(ishuman(M)||ismonkey(M))
- M.electrocute_act(5, "[user]", safety = 1, tesla_shock = 1)
+ M.electrocute_act(5, "[user]", zone=user.zone_selected, tesla_shock = 1)
user.visible_message(span_userdanger("[user] electrocutes [M] with [user.p_their()] touch!"), \
span_danger("You electrocute [M] with your touch!"))
M.update_mobility()
diff --git a/code/game/objects/items/singularityhammer.dm b/code/game/objects/items/singularityhammer.dm
index 5e33dee24d33..d5d4ba24e585 100644
--- a/code/game/objects/items/singularityhammer.dm
+++ b/code/game/objects/items/singularityhammer.dm
@@ -21,7 +21,6 @@
. = ..()
START_PROCESSING(SSobj, src)
AddComponent(/datum/component/two_handed, \
- force_unwielded = 5, \
force_wielded = 15, \
icon_wielded = "[base_icon_state]1", \
)
@@ -98,7 +97,6 @@
/obj/item/mjolnir/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = 5, \
force_wielded = 20, \
icon_wielded = "[base_icon_state]1", \
)
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 3b81adcb57f1..18a930acbb04 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -199,6 +199,18 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
atmos_spawn_air("plasma=[amount*10];TEMP=[exposed_temperature]")
qdel(src)
+/obj/item/stack/sheet/mineral/plasma/bullet_act(obj/projectile/P)
+ . = ..()
+ if(!QDELETED(src) && !P.nodamage && ((P.damage_type == BURN)))
+ var/turf/T = get_turf(src)
+ if(P.firer)
+ message_admins("Plasma stack ([amount]) ignited by [ADMIN_LOOKUPFLW(P.firer)] in [ADMIN_VERBOSEJMP(T)]")
+ log_game("Plasma stack ([amount]) ignited by [key_name(P.firer)] in [AREACOORD(T)]")
+ else
+ message_admins("Plasma stack ([amount]) ignited by [P]. No known firer, in [ADMIN_VERBOSEJMP(T)]")
+ log_game("Plasma stack ([amount]) ignited by [P] in [AREACOORD(T)]. No known firer.")
+ fire_act(2500)
+
/*
* Gold
*/
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 35ec28b5e3e5..b28344641425 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -223,7 +223,6 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("rolling pin", /obj/item/kitchen/rollingpin, 2, time = 30), \
new/datum/stack_recipe("tiki mask", /obj/item/clothing/mask/gas/tiki_mask, 2), \
new/datum/stack_recipe("winged wooden chair", /obj/structure/chair/wood/wings, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
- new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \
new/datum/stack_recipe("wood table frame", /obj/structure/table_frame/wood, 2, time = 10), \
new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wooden, 3, time = 10),\
@@ -233,6 +232,12 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), \
+ new/datum/stack_recipe_list("floor tiles", list( \
+ new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \
+ new/datum/stack_recipe("parquet wood floor tile", /obj/item/stack/tile/wood/parquet, 1, 4, 20), \
+ new/datum/stack_recipe("large wood floor tile", /obj/item/stack/tile/wood/large, 1, 4, 20), \
+ new/datum/stack_recipe("tiled wood floor tile", /obj/item/stack/tile/wood/tile, 1, 4, 20), \
+ )), \
null, \
new/datum/stack_recipe_list("pews", list(
new /datum/stack_recipe("pew (left)", /obj/structure/chair/pew/left, 3, one_per_turf = TRUE, on_floor = TRUE),
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 8f0808ac5bda..6d9365afbb8f 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -153,6 +153,24 @@
turf_type = /turf/open/floor/wood
resistance_flags = FLAMMABLE
+/obj/item/stack/tile/wood/parquet
+ name = "parquet wood floor tile"
+ singular_name = "parquet wood floor tile"
+ icon_state = "tile-wood_parquet"
+ turf_type = /turf/open/floor/wood/parquet
+
+/obj/item/stack/tile/wood/large
+ name = "large wood floor tile"
+ singular_name = "large wood floor tile"
+ icon_state = "tile-wood_large"
+ turf_type = /turf/open/floor/wood/large
+
+/obj/item/stack/tile/wood/tile
+ name = "tiled wood floor tile"
+ singular_name = "tiled wood floor tile"
+ icon_state = "tile-wood_tile"
+ turf_type = /turf/open/floor/wood/tile
+
//Bamboo
/obj/item/stack/tile/bamboo
name = "bamboo mat pieces"
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index 26e196ccf62d..c6fb03421780 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -86,7 +86,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning",
var/obj/item/clothing/gloves/color/fyellow/insuls = new
insuls.name = "insuls"
insuls.desc = "A mere copy of the true insuls."
- insuls.siemens_coefficient = 0.99999
+ insuls.armor.setRating(electric=0.001)
H.equip_to_slot(insuls, ITEM_SLOT_GLOVES)
GLOB.bible_icon_state = icon_state
GLOB.bible_item_state = item_state
diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm
index 98342c6c4910..2fce62a8bc34 100644
--- a/code/game/objects/items/storage/lockbox.dm
+++ b/code/game/objects/items/storage/lockbox.dm
@@ -78,19 +78,18 @@
togglelock(user)
/obj/item/storage/lockbox/emp_act(severity)
- switch(severity)
- if(EMP_HEAVY)
- emag_act()
- if(EMP_LIGHT)
- if(prob(60))
- var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
- SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !locked)
- locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
- if(locked)
- icon_state = icon_locked
- SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_ALL)
- else
- icon_state = icon_closed
+ if(severity > EMP_LIGHT)
+ emag_act()
+ return
+ if(prob(6 * severity))
+ var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
+ SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !locked)
+ locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
+ if(locked)
+ icon_state = icon_locked
+ SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_ALL)
+ else
+ icon_state = icon_closed
/obj/item/storage/lockbox/loyalty
name = "lockbox of mindshield implants"
diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm
index 0736463ba346..d7b7421bf7b5 100644
--- a/code/game/objects/items/stunbaton.dm
+++ b/code/game/objects/items/stunbaton.dm
@@ -257,7 +257,7 @@
/obj/item/melee/baton/emp_act(severity)
. = ..()
if (!(. & EMP_PROTECT_SELF))
- deductcharge(1000 / severity)
+ deductcharge(100 * severity)
//Makeshift stun baton. Replacement for stun gloves.
/obj/item/melee/baton/cattleprod
diff --git a/code/game/objects/items/supermatter_delaminator.dm b/code/game/objects/items/supermatter_delaminator.dm
index 08463ca7b125..2624ca7c7575 100644
--- a/code/game/objects/items/supermatter_delaminator.dm
+++ b/code/game/objects/items/supermatter_delaminator.dm
@@ -201,7 +201,7 @@
investigate_log("has consumed [key_name(user)].", "supermatter")
user.dust()
radiation_pulse(src, 500, 2)
- empulse(src, 5, 10)
+ empulse(src, EMP_HEAVY)
playsound(src, 'sound/effects/supermatter.ogg', 50, 1)
QDEL_NULL(shard)
update_appearance(UPDATE_ICON)
diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm
index 53ead5abe5ef..d33469f42132 100644
--- a/code/game/objects/items/tanks/jetpack.dm
+++ b/code/game/objects/items/tanks/jetpack.dm
@@ -9,7 +9,7 @@
distribute_pressure = ONE_ATMOSPHERE * O2STANDARD
actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
cryo_preserve = TRUE
- var/gas_type = /datum/gas/oxygen
+ var/gas_type = GAS_O2
var/on = FALSE
var/stabilizers = FALSE
var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not
@@ -90,13 +90,7 @@
turn_off(user)
return
- var/datum/gas_mixture/removed = air_contents.remove(num)
- if(removed.total_moles() < 0.005)
- turn_off(user)
- return
-
- var/turf/T = get_turf(user)
- T.assume_air(removed)
+ assume_air_moles(air_contents, num)
return TRUE
@@ -129,13 +123,7 @@
turn_off(user)
return
- var/datum/gas_mixture/removed = air_contents.remove(num)
- if(removed.total_moles() < 0.005)
- turn_off(user)
- return
-
- var/turf/T = get_turf(user)
- T.assume_air(removed)
+ assume_air_moles(air_contents, num)
return TRUE
@@ -185,7 +173,7 @@
icon_state = "jetpack-black"
item_state = "jetpack-black"
distribute_pressure = 0
- gas_type = /datum/gas/carbon_dioxide
+ gas_type = GAS_CO2
/obj/item/tank/jetpack/suit
diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm
index cd72c64e4858..b6c02c3494ca 100644
--- a/code/game/objects/items/tanks/tank_types.dm
+++ b/code/game/objects/items/tanks/tank_types.dm
@@ -30,7 +30,7 @@
/obj/item/tank/internals/oxygen/populate_gas()
- air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
+ air_contents.set_moles(GAS_O2, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/tank/internals/oxygen/yellow
@@ -62,8 +62,8 @@
force = 10
/obj/item/tank/internals/anesthetic/populate_gas()
- air_contents.set_moles(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
- air_contents.set_moles(/datum/gas/nitrous_oxide, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
+ air_contents.set_moles(GAS_O2, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
+ air_contents.set_moles(GAS_NITROUS, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
/*
* Air
@@ -77,8 +77,8 @@
dog_fashion = /datum/dog_fashion/back
/obj/item/tank/internals/air/populate_gas()
- air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
- air_contents.set_moles(/datum/gas/nitrogen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
+ air_contents.set_moles(GAS_O2, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
+ air_contents.set_moles(GAS_N2, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
/*
* Plasma
@@ -94,7 +94,7 @@
/obj/item/tank/internals/plasma/populate_gas()
- air_contents.set_moles(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
+ air_contents.set_moles(GAS_PLASMA, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/flamethrower))
@@ -110,7 +110,7 @@
return ..()
/obj/item/tank/internals/plasma/full/populate_gas()
- air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
+ air_contents.set_moles(GAS_PLASMA, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/tank/internals/plasma/empty/populate_gas()
return
@@ -128,10 +128,10 @@
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
/obj/item/tank/internals/plasmaman/populate_gas()
- air_contents.set_moles(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
+ air_contents.set_moles(GAS_PLASMA, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/tank/internals/plasmaman/full/populate_gas()
- air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
+ air_contents.set_moles(GAS_PLASMA, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/tank/internals/plasmaman/belt
@@ -143,7 +143,7 @@
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
/obj/item/tank/internals/plasmaman/belt/full/populate_gas()
- air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
+ air_contents.set_moles(GAS_PLASMA, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/tank/internals/plasmaman/belt/empty/populate_gas()
return
@@ -166,7 +166,7 @@
/obj/item/tank/internals/emergency_oxygen/populate_gas()
- air_contents.set_moles(/datum/gas/oxygen, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
+ air_contents.set_moles(GAS_O2, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/tank/internals/emergency_oxygen/empty/populate_gas()
@@ -200,7 +200,7 @@
distribute_pressure = 8
/obj/item/tank/internals/ipc_coolant/populate_gas()
- air_contents.set_moles(/datum/gas/nitrogen, (10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * (T0C - 50)))
+ air_contents.set_moles(GAS_N2, (10 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * (T0C - 50)))
air_contents.set_temperature(T0C - 50)
/obj/item/tank/internals/ipc_coolant/empty/populate_gas()
diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm
index 8816fec2a7d7..41483a0b7a6f 100644
--- a/code/game/objects/items/tanks/tanks.dm
+++ b/code/game/objects/items/tanks/tanks.dm
@@ -138,7 +138,6 @@
var/turf/T = get_turf(src)
if(T)
T.assume_air(air_contents)
- air_update_turf()
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
qdel(src)
@@ -230,6 +229,9 @@
/obj/item/tank/remove_air(amount)
return air_contents.remove(amount)
+/obj/item/tank/remove_air_ratio(ratio)
+ return air_contents.remove_ratio(ratio)
+
/obj/item/tank/return_air()
return air_contents
@@ -242,6 +244,18 @@
check_status()
return 1
+/obj/item/tank/assume_air_moles(datum/gas_mixture/giver, moles)
+ giver.transfer_to(air_contents, moles)
+
+ check_status()
+ return TRUE
+
+/obj/item/tank/assume_air_ratio(datum/gas_mixture/giver, ratio)
+ giver.transfer_ratio_to(air_contents, ratio)
+
+ check_status()
+ return TRUE
+
/obj/item/tank/proc/remove_air_volume(volume_to_return)
if(!air_contents)
return null
@@ -417,7 +431,7 @@
update_appearance(UPDATE_ICON)
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
- var/fuel_moles = air_contents.get_moles(/datum/gas/tritium) + air_contents.get_moles(/datum/gas/hydrogen) + air_contents.get_moles(/datum/gas/plasma) + air_contents.get_moles(/datum/gas/oxygen)/6
+ var/fuel_moles = air_contents.get_moles(GAS_TRITIUM) + air_contents.get_moles(GAS_H2) + air_contents.get_moles(GAS_PLASMA) + air_contents.get_moles(GAS_O2)/6
var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1
@@ -464,12 +478,9 @@
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
- ground_zero.air_update_turf()
-
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
if(!T)
return
T.assume_air(removed)
- air_update_turf()
diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm
index 3f84093da693..027d16615440 100644
--- a/code/game/objects/items/tools/crowbar.dm
+++ b/code/game/objects/items/tools/crowbar.dm
@@ -10,6 +10,7 @@
slot_flags = ITEM_SLOT_BELT
force = 5
throwforce = 7
+ demolition_mod = 2 // the right tool in the wrong place can make all the difference
w_class = WEIGHT_CLASS_SMALL
materials = list(/datum/material/iron=50)
drop_sound = 'sound/items/handling/crowbar_drop.ogg'
diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm
index 2db3040fec34..12a0bbacda73 100644
--- a/code/game/objects/items/tools/screwdriver.dm
+++ b/code/game/objects/items/tools/screwdriver.dm
@@ -9,6 +9,7 @@
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
force = 5
+ demolition_mod = 0.5
w_class = WEIGHT_CLASS_TINY
throwforce = 5
throw_speed = 3
diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm
index f69488465225..5470eef922ec 100644
--- a/code/game/objects/items/tools/weldingtool.dm
+++ b/code/game/objects/items/tools/weldingtool.dm
@@ -23,6 +23,7 @@
light_on = FALSE
throw_speed = 3
throw_range = 5
+ demolition_mod = 0.5 // not very good at smashing
w_class = WEIGHT_CLASS_SMALL
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30)
resistance_flags = FIRE_PROOF
@@ -225,6 +226,7 @@
playsound(loc, acti_sound, 50, 1)
force = 12
damtype = BURN
+ demolition_mod = 1.5 // pretty good at cutting
hitsound = 'sound/items/welder.ogg'
update_appearance(UPDATE_ICON)
START_PROCESSING(SSobj, src)
@@ -243,6 +245,7 @@
force = 3
damtype = "brute"
hitsound = "swing_hit"
+ demolition_mod = initial(demolition_mod)
update_appearance(UPDATE_ICON)
diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm
index 2ff293b763cd..fcd948da6187 100644
--- a/code/game/objects/items/tools/wrench.dm
+++ b/code/game/objects/items/tools/wrench.dm
@@ -9,6 +9,7 @@
slot_flags = ITEM_SLOT_BELT
force = 5
throwforce = 7
+ demolition_mod = 1.5
w_class = WEIGHT_CLASS_SMALL
usesound = 'sound/items/ratchet.ogg'
materials = list(/datum/material/iron=150)
diff --git a/code/game/objects/items/two_handed/broom.dm b/code/game/objects/items/two_handed/broom.dm
index 929c0759e5a9..45f8f4c0c748 100644
--- a/code/game/objects/items/two_handed/broom.dm
+++ b/code/game/objects/items/two_handed/broom.dm
@@ -19,7 +19,6 @@
/obj/item/broom/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = 8, \
force_wielded = 4, \
icon_wielded = "[base_icon_state]1", \
wield_callback = CALLBACK(src, PROC_REF(on_wield)), \
diff --git a/code/game/objects/items/two_handed/chainsaw.dm b/code/game/objects/items/two_handed/chainsaw.dm
index 38e447b0d432..9aa4aa9affe9 100644
--- a/code/game/objects/items/two_handed/chainsaw.dm
+++ b/code/game/objects/items/two_handed/chainsaw.dm
@@ -14,6 +14,7 @@
throwforce = 13
throw_speed = 2
throw_range = 4
+ demolition_mod = 1.5
materials = list(/datum/material/iron=13000)
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = "swing_hit"
diff --git a/code/game/objects/items/two_handed/dualsaber.dm b/code/game/objects/items/two_handed/dualsaber.dm
index 78df5f0e21e3..e369a884d41c 100644
--- a/code/game/objects/items/two_handed/dualsaber.dm
+++ b/code/game/objects/items/two_handed/dualsaber.dm
@@ -50,7 +50,6 @@
set_light_color(new_color)
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = force_wielded, \
icon_wielded = "[base_icon_state][saber_color]1", \
wieldsound = 'sound/weapons/saberon.ogg', \
@@ -94,7 +93,7 @@
/obj/item/melee/dualsaber/attack(mob/target, mob/living/carbon/human/user)
if(user.has_dna())
- if(user.dna.check_mutation(HULK) || user.dna.check_mutation(ACTIVE_HULK))
+ if(user.dna.check_mutation(HULK))
to_chat(user, span_warning("You grip the blade too hard and accidentally close it!"))
if(HAS_TRAIT(src, TRAIT_WIELDED))
user.dropItemToGround(src, force=TRUE)
@@ -184,7 +183,7 @@
/obj/item/melee/dualsaber/proc/on_wield(atom/source, mob/living/carbon/M)
if(!M.has_dna())
return
- if(M.dna.check_mutation(HULK) || M.dna.check_mutation(ACTIVE_HULK))
+ if(M.dna.check_mutation(HULK))
to_chat(M, span_warning("You lack the grace to wield this!"))
return
sharpness = SHARP_EDGED
diff --git a/code/game/objects/items/two_handed/fireaxe.dm b/code/game/objects/items/two_handed/fireaxe.dm
index d61023b7b344..16b1bc27484d 100644
--- a/code/game/objects/items/two_handed/fireaxe.dm
+++ b/code/game/objects/items/two_handed/fireaxe.dm
@@ -8,6 +8,7 @@
desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?"
force = 5
throwforce = 15
+ demolition_mod = 3 // specifically designed for breaking things
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut", "axed")
@@ -19,13 +20,12 @@
wound_bonus = -15
bare_wound_bonus = 20
- /// How much damage to do wielded
- var/force_wielded = 24
+ /// Bonus damage from wielding
+ var/force_wielded = 19
/obj/item/fireaxe/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = force_wielded, \
icon_wielded = "[base_icon_state]1", \
)
@@ -43,6 +43,8 @@
. = ..()
if(!proximity)
return
+ if(QDELETED(A))
+ return
if(HAS_TRAIT(src, TRAIT_WIELDED)) //destroys shit faster, generally in 1-2 hits.
if(istype(A, /obj/structure/window))
var/obj/structure/window/W = A
@@ -50,12 +52,6 @@
else if(istype(A, /obj/structure/grille))
var/obj/structure/grille/G = A
G.take_damage(G.max_integrity*2, BRUTE, MELEE, FALSE, null, armour_penetration)
- else if(istype(A, /obj/machinery/door)) //Nines hits for reinforced airlock, seven for normal
- var/obj/machinery/door/D = A
- D.take_damage((force+25), BRUTE, MELEE, FALSE, null, armour_penetration)
- else if(istype(A, /obj/structure/door_assembly)) //Two hits for frames left behind
- var/obj/machinery/door/D = A
- D.take_damage((force+25), BRUTE, MELEE, FALSE, null, armour_penetration)
/*
* Metal Hydrogen Axe
@@ -86,6 +82,7 @@
icon = 'icons/obj/weapons/energy.dmi'
icon_state = "energy-fireaxe0"
base_icon_state = "energy-fireaxe"
+ demolition_mod = 4 // DESTROY
armour_penetration = 50 // Probably doesn't care much for armor given how it can destroy solid metal structures
block_chance = 50 // Big handle and large flat energy blade, good for blocking things
heat = 1800 // It's a FIRE axe
@@ -105,7 +102,6 @@
/obj/item/fireaxe/energy/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = force_wielded, \
icon_wielded = "[base_icon_state]1", \
wieldsound = 'sound/weapons/saberon.ogg', \
@@ -132,15 +128,6 @@
..()
M.ignite_mob() // Ignites you if you're flammable
-/obj/item/fireaxe/energy/afterattack(atom/A, mob/user, proximity)
- . = ..()
- if(!proximity)
- return
- if(HAS_TRAIT(src, TRAIT_WIELDED)) // Does x2 damage against inanimate objects like machines, structures, mechs, etc
- if(isobj(A) && !isitem(A))
- var/obj/O = A
- O.take_damage(force, BRUTE, MELEE, FALSE, null, armour_penetration)
-
/obj/item/fireaxe/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text, final_block_chance, damage, attack_type)
if(!HAS_TRAIT(src, TRAIT_WIELDED))
return 0 // large energy blade can only block stuff if it's actually on
diff --git a/code/game/objects/items/two_handed/highfrequencyblade.dm b/code/game/objects/items/two_handed/highfrequencyblade.dm
index 5684a084ba55..40cd8a0c1a18 100644
--- a/code/game/objects/items/two_handed/highfrequencyblade.dm
+++ b/code/game/objects/items/two_handed/highfrequencyblade.dm
@@ -20,7 +20,6 @@
/obj/item/vibro_weapon/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = 20, \
icon_wielded = "[base_icon_state]1", \
)
diff --git a/code/game/objects/items/two_handed/pitchfork.dm b/code/game/objects/items/two_handed/pitchfork.dm
index dbe5f27016bf..21d96efaf729 100644
--- a/code/game/objects/items/two_handed/pitchfork.dm
+++ b/code/game/objects/items/two_handed/pitchfork.dm
@@ -16,13 +16,12 @@
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30)
resistance_flags = FIRE_PROOF
- ///How much damage the pitchfork will do while wielded.
+ ///How much extra damage the pitchfork will do while wielded.
var/force_wielded = 8
/obj/item/pitchfork/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = force_wielded, \
icon_wielded = "[base_icon_state]1", \
)
diff --git a/code/game/objects/items/two_handed/spears.dm b/code/game/objects/items/two_handed/spears.dm
index 1133aa0ee564..d782903aeb09 100644
--- a/code/game/objects/items/two_handed/spears.dm
+++ b/code/game/objects/items/two_handed/spears.dm
@@ -26,7 +26,7 @@
wound_bonus = -15
bare_wound_bonus = 15
- ///How much damage to deal when wielded.
+ ///How much extra damage to deal when wielded.
var/force_wielded = 8
///Whether the spear can have an explosive attached to it.
var/can_be_explosive = TRUE
@@ -34,7 +34,6 @@
/obj/item/melee/spear/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = force_wielded, \
icon_wielded = "[base_icon_state]1", \
wielded_stats = list(SWING_SPEED = 1, ENCUMBRANCE = 0.4, ENCUMBRANCE_TIME = 5, REACH = 2, DAMAGE_LOW = 2, DAMAGE_HIGH = 5), \
@@ -154,7 +153,6 @@
/obj/item/melee/spear/grey_tide/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = force_wielded, \
icon_wielded = "[base_icon_state]1", \
wielded_stats = list(SWING_SPEED = 1, ENCUMBRANCE = 0, ENCUMBRANCE_TIME = 0, REACH = 2, DAMAGE_LOW = 0, DAMAGE_HIGH = 0), \
@@ -205,7 +203,6 @@
/obj/item/melee/spear/bonespear/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = force_wielded, \
icon_wielded = "[base_icon_state]1", \
wielded_stats = list(SWING_SPEED = 1, ENCUMBRANCE = 0.4, ENCUMBRANCE_TIME = 5, REACH = 2, DAMAGE_LOW = 0, DAMAGE_HIGH = 0), \
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 52e7e793e80a..9b0f45b5b393 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -80,7 +80,7 @@
playsound(src, P.hitsound, 50, 1)
visible_message(span_danger("[src] is hit by \a [P]!"), null, null, COMBAT_MESSAGE_RANGE)
if(!QDELETED(src)) //Bullet on_hit effect might have already destroyed this object
- take_damage(P.damage, P.damage_type, P.armor_flag, 0, turn(P.dir, 180), P.armour_penetration)
+ take_damage(P.damage * P.demolition_mod, P.damage_type, P.armor_flag, 0, turn(P.dir, 180), P.armour_penetration)
///Called to get the damage that hulks will deal to the obj.
/obj/proc/hulk_damage()
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 13fa98a11173..686438b8b836 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -16,6 +16,8 @@
var/wound_bonus = 0
/// If this attacks a human with no wound armor on the affected body part, add this to the wound mod. Some attacks may be significantly worse at wounding if there's even a slight layer of armor to absorb some of it vs bare flesh
var/bare_wound_bonus = 0
+ /// Damage multiplier against structures, machines, mechs, and to a lesser extent silicons
+ var/demolition_mod = 1
var/datum/armor/armor
var/obj_integrity //defaults to max_integrity
@@ -102,17 +104,39 @@
else
return null
+/obj/assume_air_moles(datum/gas_mixture/giver, moles)
+ if(loc)
+ return loc.assume_air_moles(giver, moles)
+ return null
+
+/obj/assume_air_ratio(datum/gas_mixture/giver, ratio)
+ if(loc)
+ return loc.assume_air_ratio(giver, ratio)
+ return null
+/obj/transfer_air(datum/gas_mixture/taker, moles)
+ if(loc)
+ return loc.transfer_air(taker, moles)
+ return null
+
+/obj/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ if(loc)
+ return loc.transfer_air_ratio(taker, ratio)
+ return null
+
/obj/remove_air(amount)
if(loc)
return loc.remove_air(amount)
- else
- return null
+ return null
+
+/obj/remove_air_ratio(ratio)
+ if(loc)
+ return loc.remove_air_ratio(ratio)
+ return null
/obj/return_air()
if(loc)
return loc.return_air()
- else
- return null
+ return null
/obj/proc/handle_internal_lifeform(mob/lifeform_inside_me, breath_request)
//Return: (NONSTANDARD)
@@ -122,8 +146,7 @@
if(breath_request>0)
var/datum/gas_mixture/environment = return_air()
- var/breath_percentage = BREATH_VOLUME / environment.return_volume()
- return remove_air(environment.total_moles() * breath_percentage)
+ return remove_air_ratio(BREATH_VOLUME / environment.return_volume())
else
return null
diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm
index 7b301ddadc60..8837107f9cb7 100644
--- a/code/game/objects/structures/aliens.dm
+++ b/code/game/objects/structures/aliens.dm
@@ -55,7 +55,7 @@
icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi'
icon_state = "smooth"
density = TRUE
- opacity = 1
+ opacity = TRUE
anchored = TRUE
canSmoothWith = list(/obj/structure/alien/resin)
max_integrity = 200
@@ -66,7 +66,7 @@
/obj/structure/alien/resin/Initialize(mapload)
. = ..()
- air_update_turf(TRUE)
+ air_update_turf()
/obj/structure/alien/resin/Move()
var/turf/T = loc
@@ -81,7 +81,7 @@
resintype = "wall"
canSmoothWith = list(/obj/structure/alien/resin/wall, /obj/structure/alien/resin/membrane)
-/obj/structure/alien/resin/wall/BlockSuperconductivity()
+/obj/structure/alien/resin/wall/BlockThermalConductivity()
return 1
/obj/structure/alien/resin/membrane
@@ -89,7 +89,7 @@
desc = "Resin just thin enough to let light pass through."
icon = 'icons/obj/smooth_structures/alien/resin_membrane.dmi'
icon_state = "smooth"
- opacity = 0
+ opacity = FALSE
max_integrity = 160
resintype = "membrane"
canSmoothWith = list(/obj/structure/alien/resin/wall, /obj/structure/alien/resin/membrane)
diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm
index e6c35e8eb24f..36e45204be9f 100644
--- a/code/game/objects/structures/barsigns.dm
+++ b/code/game/objects/structures/barsigns.dm
@@ -293,6 +293,51 @@
icon = "thegoose"
desc = "A nice place to hang loose and relax, while enjoying some electrifying drinks."
+/datum/barsign/tearoom
+ name = "Little Treats Tea Room"
+ icon = "little_treats"
+ desc = "A delightfully relaxing tearoom for all the fancy lads in the cosmos."
+
+/datum/barsign/le_cafe_silencieux
+ name = "Le Café Silencieux"
+ icon = "le_cafe_silencieux"
+ desc = "..."
+
+/datum/barsign/maltroach
+ name = "Maltroach"
+ icon = "maltroach"
+ desc = "Mothroaches politely greet you into the bar, or are they greeting eachother?"
+
+/datum/barsign/rock_bottom
+ name = "Rock Bottom"
+ icon = "rock-bottom"
+ desc = "When it feels like you're stuck in a pit, might as well have a drink."
+
+/datum/barsign/assembly_line
+ name = "The Assembly Line"
+ icon = "the-assembly-line"
+ desc = "Where every drink is masterfully crafted with industrial efficiency!"
+
+/datum/barsign/bargonia
+ name = "Bargonia"
+ icon = "bargonia"
+ desc = "The warehouse yearns for a higher calling... so Supply has declared BARGONIA!"
+
+/datum/barsign/cult_cove
+ name = "Cult Cove"
+ icon = "cult-cove"
+ desc = "Nar'Sie's favourite retreat"
+
+/datum/barsign/neon_flamingo
+ name = "Neon Flamingo"
+ icon = "neon-flamingo"
+ desc = "A bus for all but the flamboyantly challenged."
+
+/datum/barsign/slowdive
+ name = "Slowdive"
+ icon = "slowdive"
+ desc = "First stop out of hell, last stop before heaven."
+
/datum/barsign/hiddensigns
hidden = TRUE
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 6aefe0e9fb8e..66d75d7e3125 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -550,10 +550,10 @@ GLOBAL_LIST_EMPTY(lockers)
for(var/obj/O in src)
O.emp_act(severity)
if(secure && !broken && !(. & EMP_PROTECT_SELF))
- if(prob(50 / severity))
+ if(prob(5 * severity))
locked = !locked
update_appearance(UPDATE_ICON)
- if(prob(20 / severity) && !opened)
+ if(prob(2 * severity) && !opened)
if(!locked)
open()
else
@@ -625,7 +625,6 @@ GLOBAL_LIST_EMPTY(lockers)
var/remove_amount = (loc_air.total_moles() + air_contents.total_moles()) * air_contents.return_volume() / (loc_air.return_volume() + air_contents.return_volume())
loc.assume_air(air_contents)
loc.remove_air(remove_amount)
- loc.air_update_turf()
air_contents = null
/obj/structure/closet/return_air()
diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm
index 63fdda6bd680..536d10fe4b5c 100644
--- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm
+++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm
@@ -336,8 +336,8 @@
air_contents = null
air_contents = new(50) // liters
air_contents.set_temperature(T20C)
- air_contents.set_moles(/datum/gas/oxygen, (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
- air_contents.set_moles(/datum/gas/nitrous_oxide, (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
+ air_contents.set_moles(GAS_O2, (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
+ air_contents.set_moles(GAS_NITROUS, (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
/obj/structure/closet/body_bag/environmental/prisoner/syndicate/Destroy()
STOP_PROCESSING(SSobj, src)
diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm
index c376d57616fa..6b3f7269f587 100644
--- a/code/game/objects/structures/crates_lockers/crates/critter.dm
+++ b/code/game/objects/structures/crates_lockers/crates/critter.dm
@@ -39,7 +39,7 @@
if(tank)
return tank.air_contents
else
- return loc.return_air()
+ return loc?.return_air()
/obj/structure/closet/crate/critter/return_analyzable_air()
if(tank)
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 874b1a6c51a8..3ca29103d44a 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -9,7 +9,7 @@
icon_state = "wall"
layer = CLOSED_TURF_LAYER
density = TRUE
- opacity = 1
+ opacity = TRUE
max_integrity = 100
canSmoothWith = list(
@@ -35,7 +35,7 @@
/obj/structure/falsewall/Initialize(mapload)
. = ..()
- air_update_turf(TRUE)
+ air_update_turf()
/obj/structure/falsewall/ratvar_act()
new /obj/structure/falsewall/brass(loc)
@@ -68,7 +68,7 @@
set_opacity(density)
opening = FALSE
update_appearance(UPDATE_ICON)
- air_update_turf(TRUE)
+ air_update_turf()
/obj/structure/falsewall/update_icon_state()
. = ..()
diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm
index 3d998428ee39..399d554f2102 100644
--- a/code/game/objects/structures/fluff.dm
+++ b/code/game/objects/structures/fluff.dm
@@ -7,7 +7,7 @@
icon_state = "minibar"
anchored = TRUE
density = FALSE
- opacity = 0
+ opacity = FALSE
var/deconstructible = TRUE
/obj/structure/fluff/attackby(obj/item/I, mob/living/user, params)
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 6ef5f6841c6e..b8058ba0791c 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -702,7 +702,7 @@ GLOBAL_LIST_EMPTY(servant_golem_users)
short_desc = "After becoming disillusioned with society, you chose a life here with the ice and snow."
roundstart = FALSE
death = FALSE
- flavour_text = "After becoming disillusioned with society, you chose a life here with the ice and snow."
+ flavour_text = "Your solitude might be threatened by the new Nanotrasen facility constructed nearby, but it also might offer minor comforts and services that you haven't experienced in years."
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
outfit = /datum/outfit/ice_hermit
diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm
index 6d969b87dd78..4eee49f9990c 100644
--- a/code/game/objects/structures/guncase.dm
+++ b/code/game/objects/structures/guncase.dm
@@ -6,7 +6,7 @@
icon_state = "shotguncase"
anchored = FALSE
density = TRUE
- opacity = 0
+ opacity = FALSE
var/case_type = ""
var/gun_category = /obj/item/gun
var/open = TRUE
diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm
index 4765c9a98f12..e6f3ac779793 100644
--- a/code/game/objects/structures/holosign.dm
+++ b/code/game/objects/structures/holosign.dm
@@ -134,7 +134,7 @@
/obj/structure/holosign/barrier/atmos/Initialize(mapload)
. = ..()
- air_update_turf(TRUE)
+ air_update_turf()
/obj/structure/holosign/barrier/cyborg
name = "Energy Field"
@@ -284,7 +284,7 @@
if(!shockcd)
if(ismob(user))
var/mob/living/M = user
- M.electrocute_act(15,"Energy Barrier", safety=1)
+ M.electrocute_act(15,"Energy Barrier", zone=user.held_index_to_body_zone(user.active_hand_index)) // you touched it with your hand
shockcd = TRUE
addtimer(CALLBACK(src, PROC_REF(cooldown)), 5)
@@ -296,6 +296,6 @@
return
var/mob/living/M = AM
- M.electrocute_act(15,"Energy Barrier", safety=1)
+ M.electrocute_act(15,"Energy Barrier", zone=null)
shockcd = TRUE
addtimer(CALLBACK(src, PROC_REF(cooldown)), 5)
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 67204afc2eeb..c05798db10ab 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -29,7 +29,7 @@
/obj/structure/mineral_door/Initialize(mapload)
. = ..()
- air_update_turf(TRUE)
+ air_update_turf()
/obj/structure/mineral_door/Move()
var/turf/T = loc
@@ -94,7 +94,7 @@
density = FALSE
door_opened = TRUE
layer = OPEN_DOOR_LAYER
- air_update_turf(1)
+ air_update_turf()
update_appearance(UPDATE_ICON)
isSwitchingStates = FALSE
@@ -115,7 +115,7 @@
set_opacity(TRUE)
door_opened = FALSE
layer = initial(layer)
- air_update_turf(1)
+ air_update_turf()
update_appearance(UPDATE_ICON)
isSwitchingStates = FALSE
@@ -134,7 +134,7 @@
/obj/structure/mineral_door/setAnchored(anchorvalue) //called in default_unfasten_wrench() chain
. = ..()
set_opacity(anchored ? !door_opened : FALSE)
- air_update_turf(TRUE)
+ air_update_turf()
/obj/structure/mineral_door/wrench_act(mob/living/user, obj/item/I)
default_unfasten_wrench(user, I, 40)
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index a47afc12f122..5a4394975542 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -103,10 +103,10 @@
/obj/structure/plasticflaps/Initialize(mapload)
. = ..()
- air_update_turf(TRUE)
+ air_update_turf()
/obj/structure/plasticflaps/Destroy()
var/atom/oldloc = loc
. = ..()
if (oldloc)
- oldloc.air_update_turf(1)
+ oldloc.air_update_turf()
diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm
index 3b33ffcc7404..728282c02ca5 100644
--- a/code/game/objects/structures/railings.dm
+++ b/code/game/objects/structures/railings.dm
@@ -110,6 +110,5 @@
return TRUE
/obj/structure/railing/proc/after_rotation(mob/user,rotation_type)
- air_update_turf(1)
ini_dir = dir
add_fingerprint(user)
diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm
index 7391d088457f..912a4dac333a 100644
--- a/code/game/objects/structures/signs/_signs.dm
+++ b/code/game/objects/structures/signs/_signs.dm
@@ -1,7 +1,7 @@
/obj/structure/sign
icon = 'icons/obj/decals.dmi'
anchored = TRUE
- opacity = 0
+ opacity = FALSE
density = FALSE
layer = SIGN_LAYER
max_integrity = 100
diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm
index 96b932d81924..bf336c208e80 100644
--- a/code/game/objects/structures/transit_tubes/station.dm
+++ b/code/game/objects/structures/transit_tubes/station.dm
@@ -177,11 +177,9 @@
sleep(OPEN_DURATION + 0.2 SECONDS)
pod_moving = FALSE
if(!QDELETED(pod))
- var/datum/gas_mixture/floor_mixture = loc.return_air()
- floor_mixture.archive()
- pod.air_contents.archive()
- pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on
- air_update_turf()
+ var/datum/gas_mixture/floor_mixture = loc?.return_air()
+ if(floor_mixture)
+ equalize_all_gases_in_list(list(pod.air_contents,floor_mixture))
/obj/structure/transit_tube/station/init_tube_dirs()
switch(dir)
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index 843b93e57cc0..2b8c1f72a377 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -10,8 +10,8 @@
/obj/structure/transit_tube_pod/Initialize(mapload)
. = ..()
- air_contents.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
- air_contents.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
+ air_contents.set_moles(GAS_O2, MOLES_O2STANDARD)
+ air_contents.set_moles(GAS_N2, MOLES_N2STANDARD)
air_contents.set_temperature(T20C)
@@ -166,9 +166,24 @@
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return air_contents.merge(giver)
+/obj/structure/transit_tube_pod/assume_air_moles(datum/gas_mixture/giver, moles)
+ return giver.transfer_to(air_contents, moles)
+
+/obj/structure/transit_tube_pod/assume_air_ratio(datum/gas_mixture/giver, ratio)
+ return giver.transfer_ratio_to(air_contents, ratio)
+
/obj/structure/transit_tube_pod/remove_air(amount)
return air_contents.remove(amount)
+/obj/structure/transit_tube_pod/remove_air_ratio(ratio)
+ return air_contents.remove_ratio(ratio)
+
+/obj/structure/transit_tube_pod/transfer_air(datum/gas_mixture/taker, moles)
+ return air_contents.transfer_to(taker, moles)
+
+/obj/structure/transit_tube_pod/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ return air_contents.transfer_ratio_to(taker, ratio)
+
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
if(istype(mob) && mob.client)
if(!moving)
diff --git a/code/game/objects/structures/traps.dm b/code/game/objects/structures/traps.dm
index a521f8b2fd7e..9bc5785e2a85 100644
--- a/code/game/objects/structures/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -85,7 +85,7 @@
icon_state = "trap-shock"
/obj/structure/trap/stun/trap_effect(mob/living/L)
- L.electrocute_act(30, src, safety=1) // electrocute act does a message.
+ L.electrocute_act(30, src, zone=null, override=TRUE) // electrocute act does a message.
L.Paralyze(100)
/obj/structure/trap/fire
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 3ff6fd6ee3ba..c1050969b625 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -274,15 +274,19 @@
to_chat(user, span_warning("Someone's already washing here!"))
return
- if(istype(O, /obj/item/reagent_containers))
- var/obj/item/reagent_containers/RG = O
- if(RG.is_refillable())
- if(!RG.reagents.holder_full())
- RG.reagents.add_reagent(dispensedreagent, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this))
- to_chat(user, span_notice("You fill [RG] from [src]."))
- return TRUE
- to_chat(user, span_notice("\The [RG] is full."))
- return FALSE
+ // If it's refillable, fill it up
+ if(O.is_refillable())
+ if(!O.reagents.holder_full())
+ var/transfer_amount = 10
+ if(istype(O, /obj/item/reagent_containers))
+ var/obj/item/reagent_containers/R = O
+ transfer_amount = R.amount_per_transfer_from_this
+ O.reagents.add_reagent(dispensedreagent, min(O.reagents.maximum_volume - O.reagents.total_volume, transfer_amount))
+ to_chat(user, span_notice("You fill [O] from [src]."))
+ playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
+ return TRUE
+ to_chat(user, span_notice("\The [O] is full."))
+ return FALSE
if(istype(O, /obj/item/melee/baton))
var/obj/item/melee/baton/B = O
@@ -298,12 +302,6 @@
playsound(src, "sparks", 50, 1)
return
- if(istype(O, /obj/item/mop))
- O.reagents.add_reagent(dispensedreagent, 5)
- to_chat(user, span_notice("You wet [O] in [src]."))
- playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
- return
-
if(istype(O, /obj/item/stack/medical/gauze))
var/obj/item/stack/medical/gauze/G = O
new /obj/item/reagent_containers/glass/rag(src.loc)
@@ -386,7 +384,7 @@
alpha = 200 //Mappers can also just set this to 255 if they want curtains that can't be seen through
layer = SIGN_LAYER
anchored = TRUE
- opacity = 0
+ opacity = FALSE
density = FALSE
var/open = TRUE
@@ -401,14 +399,14 @@
layer = WALL_OBJ_LAYER
density = TRUE
open = FALSE
- opacity = TRUE
+ set_opacity(TRUE)
else
icon_state = "open"
layer = SIGN_LAYER
density = FALSE
open = TRUE
- opacity = FALSE
+ set_opacity(FALSE)
/obj/structure/curtain/attackby(obj/item/W, mob/user)
if (istype(W, /obj/item/toy/crayon))
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 5f5c415a1589..aabd13e23356 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -34,11 +34,11 @@
if(set_dir)
setDir(set_dir)
ini_dir = dir
- air_update_turf(1)
+ air_update_turf()
/obj/structure/windoor_assembly/Destroy()
density = FALSE
- air_update_turf(1)
+ air_update_turf()
return ..()
/obj/structure/windoor_assembly/Move()
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 4bcc890a7011..d4a01fd2a175 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -55,7 +55,7 @@
state = RWINDOW_SECURE
ini_dir = dir
- air_update_turf(1)
+ air_update_turf()
if(fulltile)
setDir()
@@ -219,7 +219,7 @@
/obj/structure/window/setAnchored(anchorvalue)
..()
- air_update_turf(TRUE)
+ air_update_turf()
update_nearby_icons()
/obj/structure/window/proc/check_state(checked_state)
@@ -302,17 +302,16 @@
return TRUE
/obj/structure/window/proc/after_rotation(mob/user,rotation_type)
- air_update_turf(1)
+ air_update_turf()
ini_dir = dir
add_fingerprint(user)
/obj/structure/window/Destroy()
density = FALSE
- air_update_turf(1)
+ air_update_turf()
update_nearby_icons()
return ..()
-
/obj/structure/window/Move()
var/turf/T = loc
. = ..()
@@ -391,7 +390,7 @@
armor = list(MELEE = 60, BULLET = -50, LASER = 0, ENERGY = 0, BOMB = 25, BIO = 100, RAD = 100, FIRE = 80, ACID = 100)
max_integrity = 75
explosion_block = 1
- damage_deflection = 10
+ damage_deflection = 11
state = RWINDOW_SECURE
glass_type = /obj/item/stack/sheet/rglass
rad_insulation = RAD_HEAVY_INSULATION
@@ -510,6 +509,11 @@
if (fulltile)
. += new /obj/item/shard/plasma(location)
+/obj/structure/window/plasma/BlockThermalConductivity(opp_dir)
+ if(!anchored || !density)
+ return FALSE
+ return FULLTILE_WINDOW_DIR == dir || dir == opp_dir
+
/obj/structure/window/plasma/spawner/east
dir = EAST
@@ -613,7 +617,7 @@
/obj/structure/window/reinforced/tinted
name = "tinted window"
icon_state = "twindow"
- opacity = 1
+ opacity = TRUE
/obj/structure/window/reinforced/tinted/frosted
name = "frosted window"
icon_state = "fwindow"
diff --git a/code/game/objects/structures/wire_splicing.dm b/code/game/objects/structures/wire_splicing.dm
index 63b2b327110e..5536249aa223 100644
--- a/code/game/objects/structures/wire_splicing.dm
+++ b/code/game/objects/structures/wire_splicing.dm
@@ -98,7 +98,7 @@
var/obj/structure/cable/C = locate(/obj/structure/cable) in T
if(!C)
return FALSE
- if (electrocute_mob(user, C.powernet, src, siemens_coeff))
+ if(electrocute_mob(user, C.powernet, src, siemens_coeff, zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)))
do_sparks(5, TRUE, src)
return TRUE
else
diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm
index 582780f10a59..098efd8fc44f 100644
--- a/code/game/shuttle_engines.dm
+++ b/code/game/shuttle_engines.dm
@@ -99,7 +99,7 @@
name = "propulsion engine"
icon_state = "propulsion"
desc = "A standard reliable bluespace engine used by many forms of shuttles."
- opacity = 1
+ opacity = TRUE
/obj/structure/shuttle/engine/propulsion/left
name = "left propulsion engine"
@@ -132,7 +132,7 @@
/obj/structure/shuttle/engine/large
name = "engine"
- opacity = 1
+ opacity = TRUE
icon = 'icons/obj/2x2.dmi'
icon_state = "large_engine"
desc = "A very large bluespace engine used to propel very large ships."
@@ -142,7 +142,7 @@
/obj/structure/shuttle/engine/huge
name = "engine"
- opacity = 1
+ opacity = TRUE
icon = 'icons/obj/3x3.dmi'
icon_state = "huge_engine"
desc = "An extremely large bluespace engine used to propel extremely large ships."
diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm
index 329502913482..9c110801ed2a 100644
--- a/code/game/turfs/change_turf.dm
+++ b/code/game/turfs/change_turf.dm
@@ -2,7 +2,7 @@
GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/open/space,
/turf/baseturf_bottom,
- )))
+)))
/turf/proc/empty(turf_type=/turf/open/space, baseturf_type, list/ignore_typecache, flags)
// Remove all atoms except observers, landmarks, docking ports
@@ -14,14 +14,11 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
qdel(thing, force=TRUE)
if(turf_type)
- var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags)
- SSair.remove_from_active(newT)
- CALCULATE_ADJACENT_TURFS(newT)
- SSair.add_to_active(newT,1)
+ ChangeTurf(turf_type, baseturf_type, flags)
-/turf/proc/copyTurf(turf/T)
+/turf/proc/copyTurf(turf/T, copy_air, flags)
if(T.type != type)
- T.ChangeTurf(type)
+ T.ChangeTurf(type, null, flags)
if(T.icon_state != icon_state)
T.icon_state = icon_state
if(T.icon != icon)
@@ -48,6 +45,14 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/proc/TerraformTurf(path, new_baseturf, flags)
return ChangeTurf(path, new_baseturf, flags)
+/turf/proc/get_z_base_turf()
+ . = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
+ if (!ispath(.))
+ . = text2path(.)
+ if (!ispath(.))
+ warning("Z-level [z] has invalid baseturf '[SSmapping.level_trait(z, ZTRAIT_BASETURF)]'")
+ . = /turf/open/space
+
// Creates a new turf
// new_baseturfs can be either a single type or list of types, formated the same as baseturfs. see turf.dm
/turf/proc/ChangeTurf(path, list/new_baseturfs, flags)
@@ -71,13 +76,13 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
if(flags & CHANGETURF_SKIP)
return new path(src)
- var/old_opacity = opacity
var/old_dynamic_lighting = dynamic_lighting
var/old_lighting_object = lighting_object
var/old_lighting_corner_NE = lighting_corner_NE
var/old_lighting_corner_SE = lighting_corner_SE
var/old_lighting_corner_SW = lighting_corner_SW
var/old_lighting_corner_NW = lighting_corner_NW
+ var/old_directional_opacity = directional_opacity
var/old_exl = explosion_level
var/old_exi = explosion_id
@@ -118,10 +123,9 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
lighting_corner_NW = old_lighting_corner_NW
if(SSlighting.initialized)
- recalc_atom_opacity()
lighting_object = old_lighting_object
- if (old_opacity != opacity || dynamic_lighting != old_dynamic_lighting)
- reconsider_lights()
+ directional_opacity = old_directional_opacity
+ recalculate_directional_opacity()
if (dynamic_lighting != old_dynamic_lighting)
if (IS_DYNAMIC_LIGHTING(src))
@@ -138,8 +142,10 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
return W
/turf/open/ChangeTurf(path, list/new_baseturfs, flags)
+ //don't
+ if(!SSair.initialized)
+ return ..()
if ((flags & CHANGETURF_INHERIT_AIR) && ispath(path, /turf/open))
- SSair.remove_from_active(src)
var/datum/gas_mixture/stashed_air = new()
stashed_air.copy_from(air)
. = ..()
@@ -155,14 +161,18 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
if (!istype(newTurf.air, /datum/gas_mixture/immutable/space))
QDEL_NULL(newTurf.air)
newTurf.air = stashed_air
- update_air_ref()
- SSair.add_to_active(newTurf)
+ update_air_ref(planetary_atmos ? 1 : 2)
else
if(turf_fire)
qdel(turf_fire)
if(ispath(path,/turf/closed)|| ispath(path,/turf/cordon))
flags |= CHANGETURF_RECALC_ADJACENT
- return ..()
+ update_air_ref(-1)
+ . = ..()
+ else
+ . = ..()
+ if(!istype(air,/datum/gas_mixture))
+ Initalize_Atmos(0)
// Take off the top layer turf and replace it with the next baseturf down
/turf/proc/ScrapeAway(amount=1, flags)
@@ -260,7 +270,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
// Copy an existing turf and put it on top
// Returns the new turf
-/turf/proc/CopyOnTop(turf/copytarget, ignore_bottom=1, depth=INFINITY, copy_air = FALSE)
+/turf/proc/CopyOnTop(turf/copytarget, ignore_bottom=1, depth=INFINITY, copy_air = FALSE, flags)
var/list/new_baseturfs = list()
new_baseturfs += baseturfs
new_baseturfs += type
@@ -277,7 +287,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
target_baseturfs -= new_baseturfs & GLOB.blacklisted_automated_baseturfs
new_baseturfs += target_baseturfs
- var/turf/newT = copytarget.copyTurf(src, copy_air)
+ var/turf/newT = copytarget.copyTurf(src, copy_air, flags)
newT.baseturfs = new_baseturfs
return newT
@@ -285,11 +295,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
//If you modify this function, ensure it works correctly with lateloaded map templates.
/turf/proc/AfterChange(flags) //called after a turf has been replaced in ChangeTurf()
levelupdate()
- if(flags & CHANGETURF_RECALC_ADJACENT)
- ImmediateCalculateAdjacentTurfs()
- else
- CALCULATE_ADJACENT_TURFS(src)
- SSair.add_to_active(src)
+ ImmediateCalculateAdjacentTurfs()
//update firedoor adjacency
var/list/turfs_to_check = get_adjacent_open_turfs(src) | src
@@ -323,7 +329,6 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
total.merge(S.air)
air.copy_from(total.remove_ratio(1/turf_count))
- SSair.add_to_active(src)
/turf/proc/ReplaceWithLattice()
ScrapeToBottom(flags = CHANGETURF_INHERIT_AIR) // Yogs -- fixes this not actually replacing the turf with a lattice, lmao (ScrapeToBottom defined in yogs file)
diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm
index a35d4930ddec..114bcd368b51 100644
--- a/code/game/turfs/closed.dm
+++ b/code/game/turfs/closed.dm
@@ -1,19 +1,14 @@
/turf/closed
layer = CLOSED_TURF_LAYER
- opacity = 1
+ opacity = TRUE
density = TRUE
blocks_air = TRUE
flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
rad_insulation = RAD_MEDIUM_INSULATION
-/turf/closed/Initialize(mapload)
- . = ..()
- update_air_ref()
-
/turf/closed/AfterChange()
. = ..()
SSair.high_pressure_delta -= src
- update_air_ref()
/turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
return FALSE
@@ -107,7 +102,7 @@
/turf/closed/indestructible/fakeglass
name = "window"
icon_state = "fake_window"
- opacity = 0
+ opacity = FALSE
smooth = SMOOTH_TRUE
icon = 'icons/obj/smooth_structures/reinforced_window.dmi'
@@ -120,7 +115,7 @@
/turf/closed/indestructible/opsglass
name = "window"
icon_state = "plastitanium_window"
- opacity = 0
+ opacity = FALSE
smooth = SMOOTH_TRUE
icon = 'icons/obj/smooth_structures/plastitanium_window.dmi'
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index affcf0cd9e5d..82203455e9de 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -487,18 +487,12 @@
icon_state = "info"
/turf/open/Initalize_Atmos(times_fired)
- set_excited(FALSE)
- update_visuals()
-
- current_cycle = times_fired
+ if(!blocks_air)
+ if(!istype(air,/datum/gas_mixture/turf))
+ air = new(2500,src)
+ air.copy_from_turf(src)
+ update_air_ref(planetary_atmos ? 1 : 2)
ImmediateCalculateAdjacentTurfs()
- for(var/i in atmos_adjacent_turfs)
- var/turf/open/enemy_tile = i
- var/datum/gas_mixture/enemy_air = enemy_tile.return_air()
- if(!get_excited() && air.compare(enemy_air))
- //testing("Active turf found. Return value of compare(): [is_active]")
- set_excited(TRUE)
- SSair.active_turfs |= src
/turf/open/proc/GetHeatCapacity()
. = air.heat_capacity()
@@ -508,7 +502,6 @@
/turf/open/proc/TakeTemperature(temp)
air.set_temperature(air.return_temperature() + temp)
- air_update_turf()
/turf/open/proc/freeze_turf()
for(var/obj/I in contents)
@@ -592,20 +585,18 @@
/turf/open/rad_act(pulse_strength, collectable_radiation)
. = ..()
- if (air.get_moles(/datum/gas/carbon_dioxide) && air.get_moles(/datum/gas/oxygen) && !(air.get_moles(/datum/gas/hypernoblium)>=REACTION_OPPRESSION_THRESHOLD))
- pulse_strength = min(pulse_strength,air.get_moles(/datum/gas/carbon_dioxide)*1000,air.get_moles(/datum/gas/oxygen)*2000) //Ensures matter is conserved properly
- air.set_moles(/datum/gas/carbon_dioxide, max(air.get_moles(/datum/gas/carbon_dioxide)-(pulse_strength * 0.001),0))
- air.set_moles(/datum/gas/oxygen, max(air.get_moles(/datum/gas/oxygen)-(pulse_strength * 0.002),0))
- air.adjust_moles(/datum/gas/pluoxium, pulse_strength * 0.004)
- air_update_turf()
- if (air.get_moles(/datum/gas/hydrogen) && !(air.get_moles(/datum/gas/hypernoblium)>=REACTION_OPPRESSION_THRESHOLD))
- pulse_strength = min(pulse_strength, air.get_moles(/datum/gas/hydrogen) * 1000)
- air.set_moles(/datum/gas/hydrogen, max(air.get_moles(/datum/gas/hydrogen) - (pulse_strength * 0.001), 0))
- air.adjust_moles(/datum/gas/tritium, pulse_strength * 0.001)
- air_update_turf()
+ if (air.get_moles(GAS_CO2) && air.get_moles(GAS_O2) && !(air.get_moles(GAS_HYPERNOB) >= REACTION_OPPRESSION_THRESHOLD) )
+ pulse_strength = min(pulse_strength,air.get_moles(GAS_CO2)*1000,air.get_moles(GAS_O2)*2000) //Ensures matter is conserved properly
+ air.set_moles(GAS_CO2, max(air.get_moles(GAS_CO2)-(pulse_strength * 0.001),0))
+ air.set_moles(GAS_O2, max(air.get_moles(GAS_O2)-(pulse_strength * 0.002),0))
+ air.adjust_moles(GAS_PLUOXIUM, pulse_strength * 0.004)
+ if (air.get_moles(GAS_H2) && !(air.get_moles(GAS_HYPERNOB) >= REACTION_OPPRESSION_THRESHOLD))
+ pulse_strength = min(pulse_strength, air.get_moles(GAS_H2) * 1000)
+ air.set_moles(GAS_H2, max(air.get_moles(GAS_H2) - (pulse_strength * 0.001), 0))
+ air.adjust_moles(GAS_TRITIUM, pulse_strength * 0.001)
/turf/open/IgniteTurf(power, fire_color="red")
- if(air.get_moles(/datum/gas/oxygen) < 1)
+ if(air.get_moles(GAS_O2) < 1)
return
if(turf_fire)
turf_fire.AddPower(power)
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 38c28f0ef402..676b6d1bc154 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -25,10 +25,6 @@
tiled_dirt = TRUE
- //Do we have an uncleanable level of grime? This overlays a color multiplied noise ("grime") image on top for TG style dirtiness with clean icons.
- var/grime = FALSE
- var/grime_alpha = 40 //what is the alpha of our grime? brighter tiles look worse with grime.
-
/turf/open/floor/Initialize(mapload)
if (!broken_states)
@@ -62,12 +58,6 @@
icon_state_regular_floor = icon_state
icon_regular_floor = icon
- if(grime)
- //add a bit of grime for noobs
- var/mutable_appearance/MA = mutable_appearance(icon, "grime", alpha = grime_alpha)
- MA.blend_mode = BLEND_MULTIPLY
- add_overlay(MA)
-
if(mapload && prob(33))
MakeDirty()
if(is_station_level(z))
diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm
index 5e47d159cec4..c6ec1637b061 100644
--- a/code/game/turfs/simulated/floor/fancy_floor.dm
+++ b/code/game/turfs/simulated/floor/fancy_floor.dm
@@ -63,6 +63,21 @@
to_chat(user, span_notice("You forcefully pry off the planks, destroying them in the process."))
return make_plating()
+/turf/open/floor/wood/parquet
+ icon_state = "wood-parquet"
+ floor_tile = /obj/item/stack/tile/wood/parquet
+ broken_states = list("wood-parquet-broken", "wood-parquet-broken2", "wood-parquet-broken3", "wood-parquet-broken4", "wood-parquet-broken5", "wood-parquet-broken6", "wood-parquet-broken7")
+
+/turf/open/floor/wood/tile
+ icon_state = "wood-tile"
+ floor_tile = /obj/item/stack/tile/wood/tile
+ broken_states = list("wood-tile-broken", "wood-tile-broken2", "wood-tile-broken3")
+
+/turf/open/floor/wood/large
+ icon_state = "wood-large"
+ floor_tile = /obj/item/stack/tile/wood/large
+ broken_states = list("wood-large-broken", "wood-large-broken2", "wood-large-broken3")
+
/turf/open/floor/wood/cold
initial_gas_mix = KITCHEN_COLDROOM_ATMOS
@@ -160,6 +175,48 @@
/turf/open/floor/wood/cold/broken/seven
icon_state = "wood-broken7"
+/turf/open/floor/wood/parquet/broken
+ icon_state = "wood-parquet-broken"
+ broken = TRUE
+
+/turf/open/floor/wood/parquet/broken/two
+ icon_state = "wood-parquet-broken2"
+
+/turf/open/floor/wood/parquet/broken/three
+ icon_state = "wood-parquet-broken3"
+
+/turf/open/floor/wood/parquet/broken/four
+ icon_state = "wood-parquet-broken4"
+
+/turf/open/floor/wood/parquet/broken/five
+ icon_state = "wood-parquet-broken5"
+
+/turf/open/floor/wood/parquet/broken/six
+ icon_state = "wood-parquet-broken6"
+
+/turf/open/floor/wood/parquet/broken/seven
+ icon_state = "wood-parquet-broken7"
+
+/turf/open/floor/wood/tile/broken
+ icon_state = "wood-tile-broken"
+ broken = TRUE
+
+/turf/open/floor/wood/tile/broken/two
+ icon_state = "wood-tile-broken2"
+
+/turf/open/floor/wood/tile/broken/three
+ icon_state = "wood-tile-broken3"
+
+/turf/open/floor/wood/large/broken
+ icon_state = "wood-large-broken"
+ broken = TRUE
+
+/turf/open/floor/wood/large/broken/two
+ icon_state = "wood-large-broken2"
+
+/turf/open/floor/wood/large/broken/three
+ icon_state = "wood-large-broken3"
+
/turf/open/floor/bamboo
desc = "A bamboo mat with a decorative trim."
icon = 'icons/turf/floors/bamboo_mat.dmi'
diff --git a/code/game/turfs/simulated/floor/plasteel_floor.dm b/code/game/turfs/simulated/floor/plasteel_floor.dm
index a6b5a5cce5d0..6f0f9dbe29fd 100644
--- a/code/game/turfs/simulated/floor/plasteel_floor.dm
+++ b/code/game/turfs/simulated/floor/plasteel_floor.dm
@@ -3,7 +3,6 @@
floor_tile = /obj/item/stack/tile/plasteel
broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5")
burnt_states = list("floorscorched1", "floorscorched2")
- grime = TRUE
/turf/open/floor/plasteel/examine(mob/user)
. = ..()
@@ -108,19 +107,15 @@
/turf/open/floor/plasteel/white
icon_state = "white"
- grime_alpha = 20
/turf/open/floor/plasteel/whitegrad
icon_state = "whitegreygrad"
- grime_alpha = 30
/turf/open/floor/plasteel/white/side
icon_state = "whitehall"
- grime_alpha = 30
/turf/open/floor/plasteel/white/corner
icon_state = "whitecorner"
- grime_alpha = 30
/turf/open/floor/plasteel/airless/white
icon_state = "white"
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index 0290baa6c30f..5fdd9fa14468 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -16,7 +16,6 @@
barefootstep = FOOTSTEP_HARD_BAREFOOT
clawfootstep = FOOTSTEP_HARD_CLAW
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
- grime = TRUE
FASTDMM_PROP(\
pipe_astar_cost = 1\
diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm
index 642beded649c..4f3960ac2d02 100644
--- a/code/game/turfs/simulated/floor/plating/asteroid.dm
+++ b/code/game/turfs/simulated/floor/plating/asteroid.dm
@@ -135,6 +135,10 @@
baseturfs = /turf/open/floor/plating/asteroid/airless
turf_type = /turf/open/floor/plating/asteroid/airless
+// / Breathing types. Lungs can access either by these or by a string, which will be considered a gas ID.
+#define BREATH_OXY /datum/breathing_class/oxygen
+#define BREATH_PLASMA /datum/breathing_class/plasma
+
/turf/open/floor/plating/asteroid/snow
gender = PLURAL
name = "snow"
diff --git a/code/game/turfs/simulated/floor/plating/misc_plating.dm b/code/game/turfs/simulated/floor/plating/misc_plating.dm
index a14885d02ad9..c3cae2da310b 100644
--- a/code/game/turfs/simulated/floor/plating/misc_plating.dm
+++ b/code/game/turfs/simulated/floor/plating/misc_plating.dm
@@ -173,7 +173,7 @@
icon = 'icons/turf/floors/ice_turf.dmi'
icon_state = "unsmooth"
initial_gas_mix = FROZEN_ATMOS
- temperature = 180
+ initial_temperature = 180
planetary_atmos = TRUE
baseturfs = /turf/open/floor/plating/ice
attachment_holes = FALSE
@@ -201,10 +201,10 @@
canSmoothWith = list(/turf/open/floor/plating/ice/smooth, /turf/open/floor/plating/ice)
/turf/open/floor/plating/ice/colder
- temperature = 140
+ initial_temperature = 140
/turf/open/floor/plating/ice/temperate
- temperature = 255.37
+ initial_temperature = 255.37
/turf/open/floor/plating/ice/break_tile()
return
@@ -225,7 +225,7 @@
icon = 'icons/turf/snow.dmi'
icon_state = "snowplating"
initial_gas_mix = FROZEN_ATMOS
- temperature = 180
+ initial_temperature = 180
attachment_holes = FALSE
planetary_atmos = TRUE
footstep = FOOTSTEP_SAND
@@ -244,10 +244,10 @@
icon_state = "smooth"
/turf/open/floor/plating/snowed/colder
- temperature = 140
+ initial_temperature = 140
/turf/open/floor/plating/snowed/temperatre
- temperature = 255.37
+ initial_temperature = 255.37
/turf/open/floor/plating/snowed/smoothed/icemoon
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm
index e4fbb1035cf3..0a24d89e0e9e 100644
--- a/code/game/turfs/simulated/lava.dm
+++ b/code/game/turfs/simulated/lava.dm
@@ -172,5 +172,7 @@
planetary_atmos = TRUE
baseturfs = /turf/open/lava/smooth/lava_land_surface
+/turf/open/lava/smooth/lava_land_surface/no_shelter //snowflake version that survival pods won't spawn in
+
/turf/open/lava/smooth/airless
initial_gas_mix = AIRLESS_ATMOS
diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm
index c319f4542997..b9e8d6521e16 100644
--- a/code/game/turfs/simulated/minerals.dm
+++ b/code/game/turfs/simulated/minerals.dm
@@ -10,10 +10,10 @@
canSmoothWith = null
baseturfs = /turf/open/floor/plating/asteroid/airless
initial_gas_mix = AIRLESS_ATMOS
- opacity = 1
+ opacity = TRUE
density = TRUE
layer = EDGED_TURF_LAYER
- temperature = TCMB
+ initial_temperature = TCMB
var/environment_type = "asteroid"
var/turf/open/floor/plating/turf_type = /turf/open/floor/plating/asteroid/airless
var/mineralType = null
diff --git a/code/game/turfs/simulated/wall/reinf_walls.dm b/code/game/turfs/simulated/wall/reinf_walls.dm
index e32864e5d785..94e94e57333f 100644
--- a/code/game/turfs/simulated/wall/reinf_walls.dm
+++ b/code/game/turfs/simulated/wall/reinf_walls.dm
@@ -3,7 +3,7 @@
desc = "A huge chunk of reinforced metal used to separate rooms."
icon = 'icons/turf/walls/reinforced_wall.dmi'
icon_state = "r_wall"
- opacity = 1
+ opacity = TRUE
density = TRUE
var/d_state = INTACT
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 3d67d31f7459..aff1b3ae03f4 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -81,8 +81,7 @@
var/obj/structure/sign/poster/P = O
P.roll_and_drop(src)
- var/turf/new_floor = ScrapeAway()
- new_floor.air_update_turf()
+ ScrapeAway()
/turf/closed/wall/proc/break_wall()
new sheet_type(src, sheet_amount)
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index eb437da4683f..253cf793e805 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -4,8 +4,8 @@
name = "\proper space"
intact = 0
- temperature = TCMB
- thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT
+ initial_temperature = TCMB
+ thermal_conductivity = 0
heat_capacity = 700000
FASTDMM_PROP(\
@@ -16,7 +16,7 @@
var/destination_x
var/destination_y
- var/global/datum/gas_mixture/immutable/space/space_gas = new
+ var/global/datum/gas_mixture/immutable/space/space_gas
plane = PLANE_SPACE
layer = SPACE_LAYER
light_power = 0.25
@@ -30,8 +30,10 @@
/turf/open/space/Initialize(mapload)
SHOULD_CALL_PARENT(FALSE)
icon_state = SPACE_ICON_STATE
+ if(!space_gas)
+ space_gas = new
air = space_gas
- update_air_ref()
+ update_air_ref(0)
vis_contents.Cut() //removes inherited overlays
visibilityChanged()
@@ -44,14 +46,11 @@
if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A))
add_overlay(/obj/effect/fullbright)
- if(requires_activation)
- SSair.add_to_active(src)
-
if (light_system == STATIC_LIGHT && light_power && light_range)
update_light()
if (opacity)
- has_opaque_atom = TRUE
+ directional_opacity = ALL_CARDINALS
return INITIALIZE_HINT_NORMAL
@@ -80,6 +79,13 @@
/turf/open/space/remove_air(amount)
return null
+/turf/open/space/remove_air_ratio(amount)
+ return null
+
+//IT SHOULD RETURN NULL YOU MONKEY, WHY IN TARNATION WHAT THE FUCKING FUCK
+/turf/open/space/remove_air(amount)
+ return null
+
/turf/open/space/proc/update_starlight()
if(CONFIG_GET(flag/starlight))
for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
old mode 100644
new mode 100755
index bf0afac73c78..0d676cd092d3
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -3,6 +3,9 @@ GLOBAL_LIST_EMPTY(station_turfs)
/turf
icon = 'icons/turf/floors.dmi'
level = 1
+ luminosity = 1
+
+ var/dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
var/intact = 1
@@ -13,15 +16,12 @@ GLOBAL_LIST_EMPTY(station_turfs)
// This shouldn't be modified directly, use the helper procs.
var/list/baseturfs = /turf/baseturf_bottom
- var/temperature = T20C
+ var/initial_temperature = T20C
var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed
var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to
var/blocks_air = FALSE
- ///Which directions does this turf block the vision of, taking into account both the turf's opacity and the movable opacity_sources.
- var/directional_opacity = NONE
-
flags_1 = CAN_BE_DIRTY_1
var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes
@@ -39,6 +39,24 @@ GLOBAL_LIST_EMPTY(station_turfs)
var/tiled_dirt = FALSE // use smooth tiled dirt decal
+ ///Lumcount added by sources other than lighting datum objects, such as the overlay lighting component.
+ var/dynamic_lumcount = 0
+
+ var/tmp/lighting_corners_initialised = FALSE
+
+ ///Our lighting object.
+ var/tmp/datum/lighting_object/lighting_object
+ ///Lighting Corner datums.
+ var/tmp/datum/lighting_corner/lighting_corner_NE
+ var/tmp/datum/lighting_corner/lighting_corner_SE
+ var/tmp/datum/lighting_corner/lighting_corner_SW
+ var/tmp/datum/lighting_corner/lighting_corner_NW
+
+ ///Which directions does this turf block the vision of, taking into account both the turf's opacity and the movable opacity_sources.
+ var/directional_opacity = NONE
+ ///Lazylist of movable atoms providing opacity sources.
+ var/list/atom/movable/opacity_sources
+
/turf/vv_edit_var(var_name, new_value)
var/static/list/banned_edits = list("x", "y", "z")
if(var_name in banned_edits)
@@ -69,11 +87,10 @@ GLOBAL_LIST_EMPTY(station_turfs)
add_overlay(/obj/effect/fullbright)
if(requires_activation)
- CALCULATE_ADJACENT_TURFS(src)
- SSair.add_to_active(src)
+ ImmediateCalculateAdjacentTurfs()
+
if(color)
add_atom_colour(color, FIXED_COLOUR_PRIORITY)
-
if (light_system == STATIC_LIGHT && light_power && light_range)
update_light()
@@ -87,14 +104,29 @@ GLOBAL_LIST_EMPTY(station_turfs)
SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, UP)
if (opacity)
- has_opaque_atom = TRUE
+ directional_opacity = ALL_CARDINALS
+
+ if(isopenturf(src))
+ var/turf/open/O = src
+ __auxtools_update_turf_temp_info(isspaceturf(get_z_base_turf()) && !O.planetary_atmos)
+ else
+ update_air_ref(-1)
+ __auxtools_update_turf_temp_info(isspaceturf(get_z_base_turf()))
if(color)
add_atom_colour(color, FIXED_COLOUR_PRIORITY)
return INITIALIZE_HINT_NORMAL
+/turf/proc/__auxtools_update_turf_temp_info()
+
+/turf/proc/__auxtools_update_turf_infos(immediate)
+
+/turf/return_temperature()
+
+/turf/proc/set_temperature()
+
/turf/proc/Initalize_Atmos(times_fired)
- CALCULATE_ADJACENT_TURFS(src)
+ ImmediateCalculateAdjacentTurfs()
/turf/Destroy(force)
. = QDEL_HINT_IWILLGC
@@ -116,7 +148,6 @@ GLOBAL_LIST_EMPTY(station_turfs)
for(var/I in B.vars)
B.vars[I] = null
return
- SSair.remove_from_active(src)
visibilityChanged()
QDEL_LIST(blueprint_data)
flags_1 &= ~INITIALIZED_1
@@ -267,14 +298,6 @@ GLOBAL_LIST_EMPTY(station_turfs)
if(QDELETED(mover))
return FALSE //We were deleted.
-/turf/Entered(atom/movable/AM)
- ..()
-
- // If an opaque movable atom moves around we need to potentially update visibility.
- if (AM.opacity)
- has_opaque_atom = TRUE // Make sure to do this before reconsider_lights(), incase we're on instant updates. Guaranteed to be on in this case.
- reconsider_lights()
-
/turf/open/Entered(atom/movable/AM)
..()
//melting
diff --git a/code/game/world.dm b/code/game/world.dm
index 3982adb505a1..65b4cbdc23a3 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -211,19 +211,19 @@ GLOBAL_VAR(restart_counter)
var/list/fail_reasons
if(GLOB)
if(GLOB.total_runtimes != 0)
- fail_reasons = list("Total runtimes: [GLOB.total_runtimes]")
+ fail_reasons = list(TEST_OUTPUT_RED("Total runtimes: [GLOB.total_runtimes]"))
#ifdef UNIT_TESTS
if(GLOB.failed_any_test)
- LAZYADD(fail_reasons, "Unit Tests failed!")
+ LAZYADD(fail_reasons, TEST_OUTPUT_RED("Unit Tests failed!"))
#endif
if(!GLOB.log_directory)
- LAZYADD(fail_reasons, "Missing GLOB.log_directory!")
+ LAZYADD(fail_reasons, TEST_OUTPUT_RED("Missing GLOB.log_directory!"))
else
- fail_reasons = list("Missing GLOB!")
+ fail_reasons = list(TEST_OUTPUT_RED("Missing GLOB!"))
if(!fail_reasons)
text2file("Success!", "[GLOB.log_directory]/clean_run.lk")
else
- log_world("Test run failed!\n[fail_reasons.Join("\n")]")
+ log_world("[TEST_OUTPUT_RED("Test run failed")]!\n[fail_reasons.Join("\n")]")
sleep(0) //yes, 0, this'll let Reboot finish and prevent byond memes
qdel(src) //shut it down
@@ -272,17 +272,15 @@ GLOBAL_VAR(restart_counter)
log_world("World rebooted at [time_stamp()]")
shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss.
+ __auxmos_shutdown()
..()
/world/Del()
- // memory leaks bad
- var/num_deleted = 0
- for(var/datum/gas_mixture/GM)
- GM.__gasmixture_unregister()
- num_deleted++
- log_world("Deallocated [num_deleted] gas mixtures")
- if(fexists(EXTOOLS))
- LIBCALL(EXTOOLS, "cleanup")()
+ shutdown_logging() // makes sure the thread is closed before end, else we terminate
+ __auxmos_shutdown()
+ var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL")
+ if (debug_server)
+ LIBCALL(debug_server, "auxtools_shutdown")()
..()
/world/proc/update_status() //yogs -- Mirrored in the Yogs folder in March 2019. Do not edit, swallow, or submerge in acid
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 612ff69e0c8e..41933cd0ae11 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -20,6 +20,7 @@ GLOBAL_PROTECT(admin_verbs_default)
/client/proc/stop_sounds,
/client/proc/fix_air, // yogs - fix air verb
/client/proc/fix_air_z,
+ /client/proc/clear_all_pipenets,
/client/proc/debugstatpanel,
/client/proc/clear_mfa,
/client/proc/show_rights
@@ -155,7 +156,6 @@ GLOBAL_PROTECT(admin_verbs_server)
/client/proc/panicbunker,
/client/proc/toggle_hub,
/client/proc/mentor_memo, // YOGS - something stupid about "Mentor memos"
- /client/proc/dump_memory_usage,
/client/proc/release_queue, // Yogs -- Adds some queue-manipulation verbs
/client/proc/toggle_cdn
)
@@ -812,7 +812,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact")
message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction")
-
+/*
/client/proc/dump_memory_usage()
set name = "Dump Server Memory Usage"
set category = "Server"
@@ -841,6 +841,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
to_chat(usr, span_warning("File creation failed. Please check to see if the data/logs/memory folder actually exists."))
else
to_chat(usr, span_notice("Memory dump completed."))
+*/
/client/proc/debugstatpanel()
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index ce02517e9fad..d93f496ca9b3 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -312,6 +312,7 @@
var/objective = stripped_input(mob_user, "Enter an objective")
if(!objective)
return
+ var/tc_amount = input(mob_user, "How much TC should they all get?") as null|num
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Traitor All", "[objective]"))
for(var/mob/living/H in GLOB.player_list)
if(!(ishuman(H)||istype(H, /mob/living/silicon/)))
@@ -327,6 +328,11 @@
new_objective.explanation_text = objective
T.add_objective(new_objective)
H.mind.add_antag_datum(T)
+ if(tc_amount && tc_amount != TELECRYSTALS_DEFAULT)//if the admin chose a different starting TC amount
+ if(T.uplink_holder)
+ var/datum/component/uplink/uplink = T.uplink_holder.GetComponent(/datum/component/uplink)
+ if(uplink)
+ uplink.telecrystals = tc_amount
message_admins(span_adminnotice("[key_name_admin(mob_user)] used everyone is a traitor secret. Objective is [objective]"))
log_admin("[key_name(mob_user)] used everyone is a traitor secret. Objective is [objective]")
@@ -464,7 +470,7 @@
if(is_station_level(W.z) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(mob_user)] activated Egalitarian Station mode (All doors are open access)")
- priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, RANDOM_REPORT_SOUND)
+ priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, SSstation.announcer.get_rand_report_sound())
if("ancap")
if(!check_rights_for(rights, R_FUN))
@@ -473,9 +479,9 @@
SSeconomy.full_ancap = !SSeconomy.full_ancap
message_admins("[key_name_admin(mob_user)] toggled Anarcho-capitalist mode")
if(SSeconomy.full_ancap)
- priority_announce("The NAP is now in full effect.", null, RANDOM_REPORT_SOUND)
+ priority_announce("The NAP is now in full effect.", null, SSstation.announcer.get_rand_report_sound())
else
- priority_announce("The NAP has been revoked.", null, RANDOM_REPORT_SOUND)
+ priority_announce("The NAP has been revoked.", null, SSstation.announcer.get_rand_report_sound())
if("dorf")
if(!check_rights_for(rights, R_FUN))
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index f8032d2a705a..e82d53f88f43 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -2319,7 +2319,7 @@
return
var/customname = input(src, "Pick a title for the report", "Title") as text|null
- var/prefix = "NanoTrasen Fax Network RE: [inputsubject] "
+ var/prefix = "Nanotrasen Fax Network RE: [inputsubject] "
var/suffix = "Signed: [inputsigned] "
inputmessage = parsemarkdown(inputmessage)
diff --git a/code/modules/admin/verbs/commandreport.dm b/code/modules/admin/verbs/commandreport.dm
new file mode 100644
index 000000000000..5636a036db3d
--- /dev/null
+++ b/code/modules/admin/verbs/commandreport.dm
@@ -0,0 +1,175 @@
+/// The default command report announcement sound.
+#define DEFAULT_ANNOUNCEMENT_SOUND "default_announcement"
+
+/// Preset central command names to chose from for centcom reports.
+#define CENTCOM_PRESET "Central Command"
+#define SYNDICATE_PRESET "The Syndicate"
+#define WIZARD_PRESET "The Wizard Federation"
+#define CUSTOM_PRESET "Custom Command Name"
+
+/// Verb to change the global command name.
+/client/proc/cmd_change_command_name()
+ set category = "Admin.Round Interaction"
+ set name = "Change Command Name"
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null
+ if(!input)
+ return
+ change_command_name(input)
+ message_admins("[key_name_admin(src)] has changed Central Command's name to [input]")
+ log_admin("[key_name(src)] has changed the Central Command name to: [input]")
+
+/// Verb to open the create command report window and send command reports.
+/client/proc/cmd_admin_create_centcom_report()
+ set category = "Admin.Round Interaction"
+ set name = "Create Command Report"
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Command Report") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc!
+ var/datum/command_report_menu/tgui = new(usr)
+ tgui.ui_interact(usr)
+
+/// Datum for holding the TGUI window for command reports.
+/datum/command_report_menu
+ /// The mob using the UI.
+ var/mob/ui_user
+ /// The name of central command that will accompany our report
+ var/command_name = CENTCOM_PRESET
+ /// Whether we are using a custom name instead of a preset.
+ var/custom_name
+ /// The actual contents of the report we're going to send.
+ var/command_report_content
+ /// Whether the report's contents are announced.
+ var/announce_contents = TRUE
+ /// Whether a copy of the report is printed at every console.
+ var/print_report = TRUE
+ /// The sound that's going to accompany our message.
+ var/played_sound = DEFAULT_ANNOUNCEMENT_SOUND
+ /// The colour of the announcement when sent
+ var/announcement_color = "default"
+ /// The subheader to include when sending the announcement. Keep blank to not include a subheader
+ var/subheader = ""
+ /// A static list of preset names that can be chosen.
+ var/list/preset_names = list(CENTCOM_PRESET, SYNDICATE_PRESET, WIZARD_PRESET, CUSTOM_PRESET)
+
+/datum/command_report_menu/New(mob/user)
+ ui_user = user
+ if(command_name() != CENTCOM_PRESET)
+ command_name = command_name()
+ preset_names.Insert(1, command_name())
+
+/datum/command_report_menu/ui_state(mob/user)
+ return GLOB.admin_state
+
+/datum/command_report_menu/ui_close()
+ qdel(src)
+
+/datum/command_report_menu/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "CommandReport")
+ ui.open()
+
+/datum/command_report_menu/ui_data(mob/user)
+ var/list/data = list()
+ data["command_name"] = command_name
+ data["custom_name"] = custom_name
+ data["command_report_content"] = command_report_content
+ data["announce_contents"] = announce_contents
+ data["print_report"] = print_report
+ data["played_sound"] = played_sound
+ data["announcement_color"] = announcement_color
+ data["subheader"] = subheader
+
+ return data
+
+/datum/command_report_menu/ui_static_data(mob/user)
+ var/list/data = list()
+ data["command_name_presets"] = preset_names
+ data["announcer_sounds"] = list(DEFAULT_ANNOUNCEMENT_SOUND) + GLOB.announcer_keys
+ data["announcement_colors"] = ANNOUNCEMENT_COLORS
+
+ return data
+
+/datum/command_report_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+ if(.)
+ return
+
+ switch(action)
+ if("update_command_name")
+ if(params["updated_name"] == CUSTOM_PRESET)
+ custom_name = TRUE
+ else if (params["updated_name"] in preset_names)
+ custom_name = FALSE
+
+ command_name = params["updated_name"]
+ if("set_report_sound")
+ played_sound = params["picked_sound"]
+ if("toggle_announce")
+ announce_contents = !announce_contents
+ if("toggle_printing")
+ print_report = !print_report
+ if("update_announcement_color")
+ var/colors = ANNOUNCEMENT_COLORS
+ var/chosen_color = params["updated_announcement_color"]
+ if(chosen_color in colors)
+ announcement_color = chosen_color
+ if("set_subheader")
+ subheader = params["new_subheader"]
+ if("submit_report")
+ if(!command_name)
+ to_chat(ui_user, span_danger("You can't send a report with no command name."))
+ return
+ if(!params["report"])
+ to_chat(ui_user, span_danger("You can't send a report with no contents."))
+ return
+ command_report_content = params["report"]
+ send_announcement()
+
+ return TRUE
+
+/*
+ * The actual proc that sends the priority announcement and reports
+ *
+ * Uses the variables set by the user on our datum as the arguments for the report.
+ */
+/datum/command_report_menu/proc/send_announcement()
+ /// Our current command name to swap back to after sending the report.
+ var/original_command_name = command_name()
+ change_command_name(command_name)
+
+ /// The sound we're going to play on report.
+ var/report_sound = played_sound
+ if(played_sound == DEFAULT_ANNOUNCEMENT_SOUND)
+ report_sound = SSstation.announcer.get_rand_report_sound()
+
+ if(announce_contents)
+ var/chosen_color = announcement_color
+ if(chosen_color == "default")
+ if(command_name == SYNDICATE_PRESET)
+ chosen_color = "red"
+ else if(command_name == WIZARD_PRESET)
+ chosen_color = "purple"
+ priority_announce(command_report_content, subheader == ""? null : subheader, report_sound, has_important_message = TRUE, color_override = chosen_color)
+
+ if(!announce_contents || print_report)
+ print_command_report(command_report_content, "[announce_contents ? "" : "Classified "][command_name] Update", !announce_contents)
+
+ change_command_name(original_command_name)
+
+ log_admin("[key_name(ui_user)] has created a command report: \"[command_report_content]\", sent from \"[command_name]\" with the sound \"[played_sound]\".")
+ message_admins("[key_name_admin(ui_user)] has created a command report, sent from \"[command_name]\" with the sound \"[played_sound]\"")
+
+
+#undef DEFAULT_ANNOUNCEMENT_SOUND
+
+#undef CENTCOM_PRESET
+#undef SYNDICATE_PRESET
+#undef WIZARD_PRESET
+#undef CUSTOM_PRESET
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 15916f9e5423..893c26ed104e 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -872,7 +872,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(Rad.anchored)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
- Plasma.air_contents.set_moles(/datum/gas/plasma, 70)
+ Plasma.air_contents.set_moles(GAS_PLASMA, 70)
Rad.drainratio = 0
Rad.loaded_tank = Plasma
Plasma.forceMove(Rad)
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 841482eb3878..a74290108199 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -617,47 +617,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
L?.mind?.name = newname
SSblackbox.record_feedback("tally", "admin_verb", 1, "Offer Mob Rename") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc
-/client/proc/cmd_admin_create_centcom_report()
- set category = "Admin.Round Interaction"
- set name = "Create Command Report"
-
- if(!check_rights(R_ADMIN))
- return
-
- var/input = input(usr, "Enter a Command Report. Ensure it makes sense IC.", "What?", "") as message|null
- if(!input)
- return
-
- var/confirm = alert(src, "Do you want to announce the contents of the report to the crew?", "Announce", "Yes", "No", "Cancel")
- var/announce_command_report = TRUE
- var/senderOverride = input(src, "Please input the sender of the report", "Sender", "[command_name()] Update")
- switch(confirm)
- if("Yes")
- priority_announce(input, null, RANDOM_REPORT_SOUND, sender_override = senderOverride, sanitize = FALSE)
- announce_command_report = FALSE
- if("Cancel")
- return
-
- print_command_report(input, "[announce_command_report ? "Classified " : ""][senderOverride]", announce_command_report)
-
- log_admin("[key_name(src)] has created a command report: [input]")
- message_admins("[key_name_admin(src)] has created a command report")
- SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_change_command_name()
- set category = "Admin.Round Interaction"
- set name = "Change Command Name"
-
- if(!check_rights(R_ADMIN))
- return
-
- var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null
- if(!input)
- return
- change_command_name(input)
- message_admins("[key_name_admin(src)] has changed Central Command's name to [input]")
- log_admin("[key_name(src)] has changed the Central Command name to: [input]")
-
/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world)
set category = "Misc.Unused"
set name = "Delete"
@@ -744,18 +703,17 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!check_rights(R_ADMIN))
return
- var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
- if(heavy == null)
+ var/severity = input("Severity of pulse.", text("Input")) as num|null
+ if(!isnum(severity))
return
- var/light = input("Range of light pulse.", text("Input")) as num|null
- if(light == null)
- return
-
- if (heavy || light)
+ var/range = input("Range of pulse.", text("Input")) as num|null
+ if(!isnum(range))
+ range = severity
- empulse(O, heavy, light)
- log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]")
- message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]")
+ if (severity)
+ empulse(O, severity, range)
+ log_admin("[key_name(usr)] created an EM Pulse ([range] range, [severity] severity) at [AREACOORD(O)]")
+ message_admins("[key_name_admin(usr)] created an EM Pulse ([range] range, [severity] severity) at [AREACOORD(O)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
diff --git a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm
index 8c98537297d1..2ccd4b6f646e 100644
--- a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm
+++ b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm
@@ -22,7 +22,7 @@
/datum/blobstrain/reagent/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag)
if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER)
- empulse(B.loc, 1, 3) //less than screen range, so you can stand out of range to avoid it
+ empulse(B.loc, EMP_HEAVY, 3) //less than screen range, so you can stand out of range to avoid it
/datum/reagent/blob/electromagnetic_web
name = "Electromagnetic Web"
@@ -32,6 +32,6 @@
/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, methods = TOUCH, reac_volume, show_message, permeability, mob/camera/blob/O)
reac_volume = ..()
if(prob(reac_volume*2))
- M.emp_act(EMP_LIGHT)
+ M.emp_act(min(reac_volume / 10, EMP_HEAVY))
if(M)
M.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND)
diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm
index 7178befd2ad3..e7054ad62198 100644
--- a/code/modules/antagonists/blob/structures/_blob.dm
+++ b/code/modules/antagonists/blob/structures/_blob.dm
@@ -5,7 +5,7 @@
light_range = 2
desc = "A thick wall of writhing tendrils."
density = FALSE //this being false causes two bugs, being able to attack blob tiles behind other blobs and being unable to move on blob tiles in no gravity, but turning it to 1 causes the blob mobs to be unable to path through blobs, which is probably worse.
- opacity = 0
+ opacity = FALSE
anchored = TRUE
layer = BELOW_MOB_LAYER
CanAtmosPass = ATMOS_PASS_PROC
@@ -31,7 +31,7 @@
setDir(pick(GLOB.cardinals))
update_appearance(UPDATE_ICON)
if(atmosblock)
- air_update_turf(1)
+ air_update_turf()
ConsumeTile()
/obj/structure/blob/proc/creation_action() //When it's created by the overmind, do this.
@@ -40,7 +40,7 @@
/obj/structure/blob/Destroy()
if(atmosblock)
atmosblock = FALSE
- air_update_turf(1)
+ air_update_turf()
if(overmind)
overmind.blobs_legit -= src //if it was in the legit blobs list, it isn't now
GLOB.blobs -= src //it's no longer in the all blobs list either
@@ -64,7 +64,7 @@
result++
. -= result - 1
-/obj/structure/blob/BlockSuperconductivity()
+/obj/structure/blob/BlockThermalConductivity()
return atmosblock
/obj/structure/blob/CanAllowThrough(atom/movable/mover, turf/target)
@@ -206,7 +206,7 @@
if(severity > 0)
if(overmind)
overmind.blobstrain.emp_reaction(src, severity)
- if(prob(100 - severity * 30))
+ if(prob(40 + (severity * 6)))
new /obj/effect/temp_visual/emp(get_turf(src))
/obj/structure/blob/tesla_act(power, tesla_flags, shocked_targets, zap_gib = FALSE)
diff --git a/code/modules/antagonists/blob/structures/shield.dm b/code/modules/antagonists/blob/structures/shield.dm
index 8efcb868cd75..fd34cb45ecb1 100644
--- a/code/modules/antagonists/blob/structures/shield.dm
+++ b/code/modules/antagonists/blob/structures/shield.dm
@@ -31,7 +31,7 @@
name = initial(name)
desc = initial(desc)
atmosblock = TRUE
- air_update_turf(1)
+ air_update_turf()
/obj/structure/blob/shield/reflective
name = "reflective blob"
diff --git a/code/modules/antagonists/bloodsuckers/bloodsucker_objectives.dm b/code/modules/antagonists/bloodsuckers/bloodsucker_objectives.dm
index 7adf0f951d9a..db09e672abda 100644
--- a/code/modules/antagonists/bloodsuckers/bloodsucker_objectives.dm
+++ b/code/modules/antagonists/bloodsuckers/bloodsucker_objectives.dm
@@ -1,5 +1,10 @@
/datum/objective/monsterhunter
name = "destroymonsters"
+ explanation_text = "Destroy all monsters on ."
+
+/datum/objective/monsterhunter/New()
+ update_explanation_text()
+ ..()
// EXPLANATION
/datum/objective/monsterhunter/update_explanation_text()
diff --git a/code/modules/antagonists/bloodsuckers/bloodsuckers_objects.dm b/code/modules/antagonists/bloodsuckers/bloodsuckers_objects.dm
index 310203b0f648..52f553ff0ad0 100644
--- a/code/modules/antagonists/bloodsuckers/bloodsuckers_objects.dm
+++ b/code/modules/antagonists/bloodsuckers/bloodsuckers_objects.dm
@@ -166,7 +166,6 @@
name = "silver stake"
desc = "Polished and sharp at the end. For when some mofo is always trying to iceskate uphill."
icon_state = "silver"
- siemens_coefficient = 1 //flags = CONDUCT // var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit)
force = 9
armour_penetration = 25
embedding = list("embed_chance" = 65)
diff --git a/code/modules/antagonists/bloodsuckers/powers/feed.dm b/code/modules/antagonists/bloodsuckers/powers/feed.dm
index d0e5a60401aa..4b62c8dbc97d 100644
--- a/code/modules/antagonists/bloodsuckers/powers/feed.dm
+++ b/code/modules/antagonists/bloodsuckers/powers/feed.dm
@@ -58,7 +58,7 @@
/datum/action/cooldown/bloodsucker/feed/DeactivatePower()
var/mob/living/user = owner
- var/mob/living/feed_target = target_ref.resolve()
+ var/mob/living/feed_target = target_ref?.resolve()
if(isnull(feed_target))
log_combat(user, user, "fed on blood (target not found)", addition="(and took [blood_taken] blood)")
else
@@ -136,7 +136,7 @@
if(!active) //If we aren't active (running on SSfastprocess)
return ..() //Manage our cooldown timers
var/mob/living/user = owner
- var/mob/living/feed_target = target_ref.resolve()
+ var/mob/living/feed_target = target_ref?.resolve()
if(!ContinueActive(user, feed_target))
if(!silent_feed)
user.visible_message(
diff --git a/code/modules/antagonists/bloodsuckers/powers/gangrel.dm b/code/modules/antagonists/bloodsuckers/powers/gangrel.dm
index 0c4d987ef62e..91ab766577bd 100644
--- a/code/modules/antagonists/bloodsuckers/powers/gangrel.dm
+++ b/code/modules/antagonists/bloodsuckers/powers/gangrel.dm
@@ -24,11 +24,9 @@
/datum/action/cooldown/bloodsucker/gangrel/transform/ActivatePower()
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(/datum/antagonist/bloodsucker)
var/mob/living/carbon/human/user = owner
- if(!do_after(user, 10 SECONDS))
- return
var/list/radial_display = list()
//get our options, switches are kinda weird here cause wwe ant to stack them
- if(bloodsuckerdatum.total_blood_drank) //makes the icons for the options
+ if(bloodsuckerdatum) //makes the icons for the options
var/datum/radial_menu_choice/option = new
user.setDir(SOUTH)
var/icon/icon_to_mix = getFlatIcon(user)
@@ -55,6 +53,8 @@
option.info = "Turn into a giant bat simple mob with unique abilities."
radial_display["Bat"] = option
var/chosen_transform = show_radial_menu(user, user, radial_display)
+ if(!chosen_transform || !do_after(user, 10 SECONDS))
+ return
transform(chosen_transform) //actually transform
return ..()
@@ -85,7 +85,7 @@
user.dna.species.punchdamagehigh += 10 //very stronk
user.dna.species.punchstunthreshold += 10
user.dna.species.action_speed_coefficient *= 1.3
- user.dna.species.armor += 40
+ user.dna.species.armor += 15
bloodsuckerdatum.AddBloodVolume(50)
if("Bat")
var/mob/living/simple_animal/hostile/bloodsucker/giantbat/gb
diff --git a/code/modules/antagonists/bloodsuckers/powers/olfaction.dm b/code/modules/antagonists/bloodsuckers/powers/olfaction.dm
index 1089d603dc9a..f97c5fe9fd69 100644
--- a/code/modules/antagonists/bloodsuckers/powers/olfaction.dm
+++ b/code/modules/antagonists/bloodsuckers/powers/olfaction.dm
@@ -47,7 +47,7 @@
return FALSE
DeactivatePower()
var/datum/gas_mixture/air = owner.loc.return_air()
- if(air.get_moles(/datum/gas/miasma) >= 0.1/sensitivity && sensitive)
+ if(air.get_moles(GAS_MIASMA) >= 0.1/sensitivity && sensitive)
owner.adjust_disgust(sensitivity * 45)
to_chat(owner, span_warning("With your overly sensitive nose, you get a whiff of stench and feel sick! Try moving to a cleaner area!"))
return
diff --git a/code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm b/code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
index b557e22ea80a..d6a55ad0705e 100644
--- a/code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
+++ b/code/modules/antagonists/bloodsuckers/powers/targeted/hecata.dm
@@ -31,7 +31,18 @@
cooldown_time = 45 SECONDS
target_range = 1
prefire_message = "Select a target."
+ var/list/zombies = list()
+/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/Grant(mob/user)
+ . = ..()
+ RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(die))
+
+/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/die()
+ for(var/dude in zombies)
+ if(isliving(dude)) //sanity check
+ var/mob/living/alive = dude
+ end_necromance(alive)
+
/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/CheckValidTarget(atom/target_atom)
. = ..()
if(!.)
@@ -63,65 +74,59 @@
/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/FireTargetedPower(atom/target_atom)
. = ..()
+ if(!iscarbon(target_atom))
+ return
+ if(!isliving(owner))
+ return
var/mob/living/carbon/target = target_atom
var/mob/living/user = owner
- var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(/datum/antagonist/bloodsucker)
- if(target.stat == DEAD && user.Adjacent(target))
- owner.balloon_alert(owner, "attempting to revive...")
- if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) //if they have a mindshield
- owner.balloon_alert(owner, "mindshield detected, this will take longer...")
- if(!do_after(user, 18 SECONDS, target))
- return FALSE
- for(var/obj/item/implant/mindshield/L in target)
- if(L)
- qdel(L)
- else
- if(!do_after(user, 6 SECONDS, target))
- return FALSE
- if(IS_VASSAL(target))
- power_activated_sucessfully()
- owner.balloon_alert(owner, "we revive [target]!")
- zombify(target)
- bloodsuckerdatum.clanprogress++ //counts a succesful necromancy towards your objective progress
- return
- if(IS_MONSTERHUNTER(target))
- owner.balloon_alert(owner, "their body refuses to react...")
- DeactivatePower()
- return
- var/old_species = target.dna?.species.type
- zombify(target)
- bloodsuckerdatum.make_vassal(target)
- power_activated_sucessfully()
- bloodsuckerdatum.clanprogress++ //counts a succesful necromancy towards your objective progress
- to_chat(user, span_warning("We revive [target]!"))
- var/living_time
- switch(level_current)
- if(0)
- living_time = 2 MINUTES
- if(1)
- living_time = 5 MINUTES
- if(2)
- living_time = 8 MINUTES
- if(3)
- living_time = 11 MINUTES
- if(4)
- living_time = 14 MINUTES
- if(5 to 99)
- living_time = 17 MINUTES //in general, they don't last long, make the most of them.
- addtimer(CALLBACK(src, PROC_REF(end_necromance), target, old_species), living_time)
- else //extra check, but this shouldn't happen
- owner.balloon_alert(owner, "out of range/not dead.")
+ if(!IS_BLOODSUCKER(owner)) //sanity check
+ return
+ var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind?.has_antag_datum(/datum/antagonist/bloodsucker)
+
+ if(target.stat != DEAD)
+ owner.balloon_alert(owner, "not dead.")
+ return FALSE
+
+ if(!user.Adjacent(target))
+ owner.balloon_alert(owner, "out of range.")
+ return FALSE
+
+
+ owner.balloon_alert(owner, "attempting to revive...")
+ if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) //if they have a mindshield
+ owner.balloon_alert(owner, "mindshield detected, this will take longer...")
+ if(!do_after(user, 12 SECONDS, target))
+ return FALSE
+ for(var/obj/item/implant/mindshield/L in target)
+ qdel(L)
+ owner.balloon_alert(owner, "mindshield destroyed, proceeding with revival...")
+ if(!do_after(user, 6 SECONDS, target))
return FALSE
+
+ if(IS_MONSTERHUNTER(target))
+ owner.balloon_alert(owner, "their body refuses to react...")
+ DeactivatePower()
+ return
+
+ bloodsuckerdatum.clanprogress++ //counts a succesful necromancy towards your objective progress
+ zombify(target)
+ to_chat(user, span_warning("We revive [target]!"))
+ if(!IS_VASSAL(target))
+ var/living_time = (2 + min(level_current * 3, 15)) MINUTES //in general, they don't last long, make the most of them.
+ addtimer(CALLBACK(src, PROC_REF(end_necromance), target), living_time)
+ bloodsuckerdatum.make_vassal(target)
+ RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(remove_vassal), target) //only remove vassal from those that were initially not one
+ power_activated_sucessfully()
DeactivatePower()
-/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/end_necromance(mob/living/user, old_species)
- user.mind.remove_antag_datum(/datum/antagonist/vassal)
- to_chat(user, span_warning("You feel the shadows around you weaken, your form falling limp like a puppet cut from its strings!"))
- user.set_species(old_species ? old_species : /datum/species/krokodil_addict) //go back to original species, or lesser zombie if they somehow didn't have one
- user.death()
-
-/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/zombify(mob/living/user)
+/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/zombify(mob/living/carbon/user)
+ if(!user.mind || !istype(user))
+ return
user.mind.grab_ghost()
+ zombies |= user
+ if(user.dna?.species?.type)
+ zombies[user] = user.dna.species.type
user.set_species(/datum/species/zombie/hecata) //imitation zombies that shamble around and beat people with their fists
user.revive(full_heal = TRUE, admin_revive = TRUE)
user.visible_message(span_danger("[user] suddenly convulses, as [user.p_they()] stagger to their feet and gain a ravenous hunger in [user.p_their()] eyes!"), span_alien("You RISE!"))
@@ -129,6 +134,18 @@
to_chat(user, span_warning("Your broken form is picked up by strange shadows. If you were previously not a vassal, it is unlikely these shadows will be strong enough to keep you going for very long."))
to_chat(user, span_notice("You are resilient to many things like the vacuum of space, can punch harder, and can take more damage before dropping. However, you are unable to use guns and are slower."))
+/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/remove_vassal(mob/living/carbon/user)
+ if(user.mind)
+ user.mind.remove_antag_datum(/datum/antagonist/vassal)
+
+/datum/action/cooldown/bloodsucker/targeted/hecata/necromancy/proc/end_necromance(mob/living/carbon/user)
+ if(!istype(user) || !(user in zombies))
+ return
+ to_chat(user, span_warning("You feel the shadows around you weaken, your form falling limp like a puppet cut from its strings!"))
+ user.set_species(zombies[user] ? zombies[user] : /datum/species/krokodil_addict) //go back to original species, or lesser zombie if they somehow didn't have one
+ user.death()
+ zombies -= user
+
/datum/action/cooldown/bloodsucker/hecata
purchase_flags = HECATA_CAN_BUY
background_icon = 'icons/mob/actions/actions_hecata_bloodsucker.dmi'
diff --git a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm
index 718b13382163..7925aa933ad6 100644
--- a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm
+++ b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm
@@ -292,7 +292,46 @@
if(bloodsucker_blood_volume < (FRENZY_THRESHOLD_ENTER + humanity_lost * 10) && !frenzied)
if(!iscarbon(owner.current))
return
- owner.current.apply_status_effect(/datum/status_effect/frenzy)
+ if(my_clan?.get_clan() == CLAN_GANGREL)
+ var/mob/living/carbon/user = owner.current
+ switch(frenzies)
+ if(0)
+ owner.current.apply_status_effect(STATUS_EFFECT_FRENZY)
+ if(1)
+ to_chat(owner, span_warning("You start feeling hungrier, you feel like a normal frenzy won't satiate it enough anymore."))
+ owner.current.apply_status_effect(STATUS_EFFECT_FRENZY)
+ if(2 to INFINITY)
+ if(do_after(user, 2 SECONDS, user, IGNORE_ALL))
+ playsound(user.loc, 'sound/weapons/slash.ogg', 25, 1)
+ to_chat(user, span_warning("You skin rips and tears. "))
+ if(do_after(user, 1 SECONDS, user, IGNORE_ALL))
+ playsound(user.loc, 'sound/weapons/slashmiss.ogg', 25, 1)
+ to_chat(user, span_warning("You heart pumps blackened blood into your veins as your skin turns into fur. "))
+ if(do_after(user, 1 SECONDS, user, IGNORE_ALL))
+ playsound(user.loc, 'sound/weapons/slice.ogg', 25, 1)
+ to_chat(user, span_boldnotice("YOU HAVE AWOKEN. "))
+ var/mob/living/simple_animal/hostile/bloodsucker/werewolf/ww
+ if(!ww || ww.stat == DEAD)
+ AddBloodVolume(560 - user.blood_volume) //so it doesn't happen multiple times and refills your blood when you get out again
+ ww = new /mob/living/simple_animal/hostile/bloodsucker/werewolf(user.loc)
+ user.forceMove(ww)
+ ww.bloodsucker = user
+ user.mind.transfer_to(ww)
+ var/list/wolf_powers = list(new /datum/action/cooldown/bloodsucker/targeted/feast,)
+ for(var/datum/action/cooldown/bloodsucker/power in powers)
+ if(istype(power, /datum/action/cooldown/bloodsucker/fortitude))
+ wolf_powers += new /datum/action/cooldown/bloodsucker/gangrel/wolfortitude
+ if(istype(power, /datum/action/cooldown/bloodsucker/targeted/lunge))
+ wolf_powers += new /datum/action/cooldown/bloodsucker/targeted/pounce
+ if(istype(power, /datum/action/cooldown/bloodsucker/cloak))
+ wolf_powers += new /datum/action/cooldown/bloodsucker/gangrel/howl
+ if(istype(power, /datum/action/cooldown/bloodsucker/targeted/trespass))
+ wolf_powers += new /datum/action/cooldown/bloodsucker/gangrel/rabidism
+ for(var/datum/action/cooldown/bloodsucker/power in wolf_powers)
+ power.Grant(ww)
+ frenzies ++
+ else
+ owner.current.apply_status_effect(STATUS_EFFECT_FRENZY)
else if(bloodsucker_blood_volume < BLOOD_VOLUME_BAD(owner.current))
additional_regen = 0.1
else if(bloodsucker_blood_volume < BLOOD_VOLUME_OKAY(owner.current))
@@ -463,13 +502,12 @@
return
//If we're on Masquerade, we appear to have full blood, unless we are REALLY low, in which case we don't look as bad.
if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE))
- switch(bloodsucker_blood_volume)
- if(BLOOD_VOLUME_OKAY(owner.current) to INFINITY) // 336 and up, we are perfectly fine.
- owner.current.blood_volume = initial(bloodsucker_blood_volume)
- if(BLOOD_VOLUME_BAD(owner.current) to BLOOD_VOLUME_OKAY(owner.current)) // 224 to 336
- owner.current.blood_volume = BLOOD_VOLUME_SAFE(owner.current)
- else // 224 and below
- owner.current.blood_volume = BLOOD_VOLUME_OKAY(owner.current)
+ if(bloodsucker_blood_volume >= BLOOD_VOLUME_OKAY(owner.current))
+ owner.current.blood_volume = initial(bloodsucker_blood_volume)
+ else if(bloodsucker_blood_volume >= BLOOD_VOLUME_BAD(owner.current))
+ owner.current.blood_volume = BLOOD_VOLUME_SAFE(owner.current)
+ else
+ owner.current.blood_volume = BLOOD_VOLUME_OKAY(owner.current)
return
owner.current.blood_volume = bloodsucker_blood_volume
diff --git a/code/modules/antagonists/changeling/powers/shriek.dm b/code/modules/antagonists/changeling/powers/shriek.dm
index 6a56642dce33..9c3cf68e97b7 100644
--- a/code/modules/antagonists/changeling/powers/shriek.dm
+++ b/code/modules/antagonists/changeling/powers/shriek.dm
@@ -53,5 +53,5 @@
for(var/obj/machinery/light/L in range(5, usr))
L.on = 1
L.break_light_tube()
- empulse(get_turf(user), 2, 5, 1)
+ empulse(get_turf(user), EMP_HEAVY, 5, 1)
return TRUE
diff --git a/code/modules/antagonists/clockcult/clock_effect.dm b/code/modules/antagonists/clockcult/clock_effect.dm
index a788677eb162..237a15c72763 100644
--- a/code/modules/antagonists/clockcult/clock_effect.dm
+++ b/code/modules/antagonists/clockcult/clock_effect.dm
@@ -7,7 +7,7 @@
icon_state = "ratvars_flame"
anchored = TRUE
density = FALSE
- opacity = 0
+ opacity = FALSE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF
/obj/effect/clockwork/Initialize(mapload)
diff --git a/code/modules/antagonists/clockcult/clock_effects/servant_blocker.dm b/code/modules/antagonists/clockcult/clock_effects/servant_blocker.dm
index e1d464e41047..9bf278d7800e 100644
--- a/code/modules/antagonists/clockcult/clock_effects/servant_blocker.dm
+++ b/code/modules/antagonists/clockcult/clock_effects/servant_blocker.dm
@@ -10,7 +10,7 @@
/obj/effect/clockwork/servant_blocker/Initialize(mapload)
. = ..()
- air_update_turf(TRUE)
+ air_update_turf()
/obj/effect/clockwork/servant_blocker/Destroy(force)
if(!force)
@@ -30,7 +30,7 @@
return FALSE
return TRUE
-/obj/effect/clockwork/servant_blocker/BlockSuperconductivity()
+/obj/effect/clockwork/servant_blocker/BlockThermalConductivity()
return TRUE
/obj/effect/clockwork/servant_blocker/singularity_act()
diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/longsword.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/longsword.dm
index d931924b3b5d..1d71903ac051 100644
--- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/longsword.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/longsword.dm
@@ -8,13 +8,14 @@
block_chance = 35
attack_verb = list("attacked", "slashed", "cut", "torn", "gored")
clockwork_desc = "A powerful sword of Ratvarian making. Enemies hit with it will be struck with a powerful electromagnetic pulse."
+ var/emp_severity = EMP_LIGHT
var/emp_cooldown = 0
var/cooldown_duration = 10 SECONDS
/obj/item/clockwork/weapon/brass_sword/attack(mob/living/target, mob/living/carbon/human/user)
. = ..()
if(world.time > emp_cooldown && !is_servant_of_ratvar(target))
- target.emp_act(EMP_LIGHT)
+ target.emp_act(emp_severity)
emp_cooldown = world.time + cooldown_duration
addtimer(CALLBACK(src, PROC_REF(send_message)), cooldown_duration)
to_chat(user, "You strike [target] with an electromagnetic pulse! ")
@@ -24,7 +25,7 @@
/obj/item/clockwork/weapon/brass_sword/attack_obj(obj/O, mob/living/user)
. = ..()
if(world.time > emp_cooldown && ismecha(O))
- O.emp_act(EMP_HEAVY)
+ O.emp_act(emp_severity * 2)
emp_cooldown = world.time + cooldown_duration
addtimer(CALLBACK(src, PROC_REF(send_message)), cooldown_duration)
to_chat(user, "You strike [O] with an electromagnetic pulse! ")
diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
index cc539fc00785..689b95fbe4ad 100644
--- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
@@ -131,9 +131,8 @@
body_parts_covered = ARMS
cold_protection = ARMS
heat_protection = ARMS
- siemens_coefficient = 0
resistance_flags = FIRE_PROOF | ACID_PROOF
- armor = list(MELEE = 50, BULLET = 40, LASER = 20, ENERGY = 10, BOMB = 60, BIO = 60, RAD = 0, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 50, BULLET = 40, LASER = 20, ENERGY = 10, BOMB = 60, BIO = 60, RAD = 0, FIRE = 100, ACID = 100, ELECTRIC = 100)
/obj/item/clothing/gloves/clockwork/Initialize(mapload)
. = ..()
@@ -146,17 +145,17 @@
/obj/item/clothing/gloves/clockwork/ratvar_act()
if(GLOB.ratvar_awakens)
- armor.setRating(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100)
+ armor.setRating(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 100, bio = 100, rad = 100, fire = 100, acid = 100, electric = 100)
clothing_flags |= STOPSPRESSUREDAMAGE
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else if(GLOB.ratvar_approaches)
- armor.setRating(melee = 60, bullet = 50, laser = 25, energy = 25, bomb = 60, bio = 90, rad = 0, fire = 100, acid = 100)
+ armor.setRating(melee = 60, bullet = 50, laser = 25, energy = 25, bomb = 60, bio = 90, rad = 0, fire = 100, acid = 100, electric = 100)
clothing_flags |= STOPSPRESSUREDAMAGE
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
- armor.setRating(melee = 50, bullet = 40, laser = 20, energy = 10, bomb = 60, bio = 60, rad = 0, fire = 100, acid = 100)
+ armor.setRating(melee = 50, bullet = 40, laser = 20, energy = 10, bomb = 60, bio = 60, rad = 0, fire = 100, acid = 100, electric = 100)
clothing_flags &= ~STOPSPRESSUREDAMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
diff --git a/code/modules/antagonists/clockcult/clock_mobs.dm b/code/modules/antagonists/clockcult/clock_mobs.dm
index f51d9430640f..0a080e94fe02 100644
--- a/code/modules/antagonists/clockcult/clock_mobs.dm
+++ b/code/modules/antagonists/clockcult/clock_mobs.dm
@@ -37,7 +37,7 @@
/mob/living/simple_animal/hostile/clockwork/ratvar_act()
fully_heal(TRUE)
-/mob/living/simple_animal/hostile/clockwork/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)
+/mob/living/simple_animal/hostile/clockwork/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
return 0 //ouch, my metal-unlikely-to-be-damaged-by-electricity-body
/mob/living/simple_animal/hostile/clockwork/examine(mob/user)
diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm
index 558b3d5cace4..f8c9196488a5 100644
--- a/code/modules/antagonists/cult/blood_magic.dm
+++ b/code/modules/antagonists/cult/blood_magic.dm
@@ -423,12 +423,12 @@
user.visible_message(span_warning("[user] holds up [user.p_their()] hand, which explodes in a flash of red light!"), \
span_cultitalic("You attempt to stun [L] with the spell!"))
- user.mob_light(_range = 3, _color = LIGHT_COLOR_BLOOD_MAGIC, _duration = 0.2 SECONDS)
+ user.mob_light(range = 3, color = LIGHT_COLOR_BLOOD_MAGIC, duration = 0.2 SECONDS)
var/anti_magic_source = L.can_block_magic()
if(anti_magic_source)
- L.mob_light(_range = 2, _color = LIGHT_COLOR_HOLY_MAGIC, _duration = 10 SECONDS)
+ L.mob_light(range = 2, color = LIGHT_COLOR_HOLY_MAGIC, duration = 10 SECONDS)
var/mutable_appearance/forbearance = mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER)
L.add_overlay(forbearance)
addtimer(CALLBACK(L, TYPE_PROC_REF(/atom, cut_overlay), forbearance), 100)
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index 11a7f4fd5009..87b5d4ed3f62 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -695,7 +695,6 @@ GLOBAL_VAR_INIT(curselimit, 0)
/obj/item/cult_spear/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = 12, \
force_wielded = 16, \
icon_wielded = "[base_icon_state]1", \
wielded_stats = list(SWING_SPEED = 1, ENCUMBRANCE = 0.4, ENCUMBRANCE_TIME = 5, REACH = 2, DAMAGE_LOW = 2, DAMAGE_HIGH = 5), \
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index 4884191cd10c..c6d9cee7a905 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -699,7 +699,7 @@ structure_check() searches for nearby cultist structures required for the invoca
GLOB.wall_runes -= src
return ..()
-/obj/effect/rune/wall/BlockSuperconductivity()
+/obj/effect/rune/wall/BlockThermalConductivity()
return density
/obj/effect/rune/wall/invoke(list/invokers)
@@ -742,7 +742,7 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/wall/proc/update_state()
deltimer(density_timer)
- air_update_turf(1)
+ air_update_turf()
if(density)
density_timer = addtimer(CALLBACK(src, PROC_REF(lose_density)), 300, TIMER_STOPPABLE) //yogs: 30 seconds instead of 300 I could microwave a pizza before a barrier rune went down naturally
var/mutable_appearance/shimmer = mutable_appearance('icons/effects/effects.dmi', "barriershimmer", ABOVE_MOB_LAYER)
@@ -1046,7 +1046,7 @@ structure_check() searches for nearby cultist structures required for the invoca
visible_message(span_warning("A colossal shockwave of energy bursts from the rune, disintegrating it in the process!"))
for(var/mob/living/L in range(src, 3))
L.Paralyze(30)
- empulse(T, 0.42*(intensity), 1)
+ empulse(T, 0.42*(intensity))
var/list/images = list()
var/zmatch = T.z
var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_antag.dm b/code/modules/antagonists/eldritch_cult/eldritch_antag.dm
index 31d010a0f97e..15b3ca169506 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_antag.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_antag.dm
@@ -13,7 +13,7 @@
var/list/researched_knowledge = list()
var/list/transmutations = list()
var/total_sacrifices = 0
- var/lore = "Unpledged" //Used to track which path the heretic has taken
+ var/lore = PATH_NONE //Used to track which path the heretic has taken
var/ascended = FALSE
var/transformed = FALSE //Used to track if the heretic sheds their own body during ascension
var/charge = 1
@@ -21,89 +21,8 @@
var/knowledge_tier = TIER_PATH //oh boy this is going to be fun
///tracks the number of knowledges to next tier, currently 3
var/tier_counter = 0
-///list of knowledges available, by path. every odd tier is an exclusive upgrade, and every even one is a set of upgrades of which 3 need to be picked to move on.
///order these from main path ability (will choose the color in the UI) to minor abilities below them (will once again, make sense if you look at the in game UI)
- var/list/knowledges = list(
- TIER_PATH = list(
- /datum/eldritch_knowledge/base_ash,
- /datum/eldritch_knowledge/base_flesh,
- /datum/eldritch_knowledge/base_rust,
- /datum/eldritch_knowledge/base_mind,
- /datum/eldritch_knowledge/base_void,
- /datum/eldritch_knowledge/base_blade,
- /datum/eldritch_knowledge/base_cosmic,
- /datum/eldritch_knowledge/base_knock),
- TIER_1 = list(
- /datum/eldritch_knowledge/madness_mask,
- /datum/eldritch_knowledge/flesh_ghoul,
- /datum/eldritch_knowledge/rust_regen,
- /datum/eldritch_knowledge/spell/eldritchbolt,
- /datum/eldritch_knowledge/rune_carver,
- /datum/eldritch_knowledge/blade_dance,
- /datum/eldritch_knowledge/spell/cosmic_runes,
- /datum/eldritch_knowledge/key_ring,
- /datum/eldritch_knowledge/armor,
- /datum/eldritch_knowledge/spell/rust_construction,
- /datum/eldritch_knowledge/void_cloak,
- /datum/eldritch_knowledge/ashen_eyes,
- /datum/eldritch_knowledge/essence,
- /datum/eldritch_knowledge/eldritch_eye,
- /datum/eldritch_knowledge/fire_shark),
- TIER_MARK = list(
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark),
- TIER_2 = list(
- /datum/eldritch_knowledge/spell/volcano_blast,
- /datum/eldritch_knowledge/raw_prophet,
- /datum/eldritch_knowledge/spell/area_conversion,
- /datum/eldritch_knowledge/spell/assault,
- /datum/eldritch_knowledge/cold_snap,
- /datum/eldritch_knowledge/duel_stance,
- /datum/eldritch_knowledge/spell/star_blast,
- /datum/eldritch_knowledge/spell/burglar_finesse,
- /datum/eldritch_knowledge/spell/realignment,
- /datum/eldritch_knowledge/spell/blood_siphon,
- /datum/eldritch_knowledge/spell/void_blast),
- TIER_BLADE = list(
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade),
- TIER_3 = list(
- /datum/eldritch_knowledge/spell/flame_birth,
- /datum/eldritch_knowledge/stalker,
- /datum/eldritch_knowledge/spell/entropic_plume,
- /datum/eldritch_knowledge/cerebral_control,
- /datum/eldritch_knowledge/spell/void_pull,
- /datum/eldritch_knowledge/spell/furious_steel,
- /datum/eldritch_knowledge/spell/cosmic_expansion,
- /datum/eldritch_knowledge/spell/freedom_forever,
- /datum/eldritch_knowledge/lionhunter_rifle,
- /datum/eldritch_knowledge/ashy,
- /datum/eldritch_knowledge/rusty,
- /datum/eldritch_knowledge/spell/cleave,
- /datum/eldritch_knowledge/spell/famished_roar,
- /datum/eldritch_knowledge/spell/call_of_ice),
- TIER_ASCEND = list(
- /datum/eldritch_knowledge/ash_final,
- /datum/eldritch_knowledge/flesh_final,
- /datum/eldritch_knowledge/rust_final,
- /datum/eldritch_knowledge/mind_final,
- /datum/eldritch_knowledge/void_final,
- /datum/eldritch_knowledge/blade_final,
- /datum/eldritch_knowledge/cosmic_final,
- /datum/eldritch_knowledge/knock_final))
-
+
var/static/list/path_to_ui_color = list(
PATH_START = "grey",
PATH_SIDE = "green",
@@ -123,10 +42,10 @@
data["charges"] = charge
data["total_sacrifices"] = total_sacrifices
data["ascended"] = ascended
-
+ data["path"] = lore
+
for(var/datum/eldritch_knowledge/knowledge as anything in get_researchable_knowledge())
var/list/knowledge_data = list()
- knowledge_data["path"] = lore
knowledge_data["name"] = initial(knowledge.name)
knowledge_data["desc"] = initial(knowledge.desc)
knowledge_data["gainFlavor"] = initial(knowledge.gain_text)
@@ -141,7 +60,7 @@
knowledge_data["color"] = path_to_ui_color[initial(knowledge.route)] || "grey"
data["learnableKnowledge"] += list(knowledge_data)
-
+
for(var/path in researched_knowledge)
var/list/knowledge_data = list()
var/datum/eldritch_knowledge/found_knowledge = researched_knowledge[path]
@@ -161,8 +80,6 @@
data["objectives"] = get_objectives()
-
-
return data
/datum/antagonist/heretic/ui_act(action, params)
@@ -838,15 +755,17 @@
/datum/antagonist/heretic/proc/get_researchable_knowledge()
var/list/researchable_knowledge = list()
- var/list/banned_knowledge = list()
- for(var/X in researched_knowledge)
- var/datum/eldritch_knowledge/EK = researched_knowledge[X]
- banned_knowledge |= EK.banned_knowledge
- banned_knowledge |= EK.type
- for(var/i in TIER_PATH to knowledge_tier)
- for(var/knowledge in knowledges[i])
- researchable_knowledge += knowledge
- researchable_knowledge -= banned_knowledge
+ for(var/datum/eldritch_knowledge/knowledge as anything in subtypesof(/datum/eldritch_knowledge))
+ if(locate(knowledge) in researched_knowledge)
+ continue
+ if(initial(knowledge.tier) > knowledge_tier)
+ continue
+ if((initial(knowledge.tier) == TIER_PATH) && lore != PATH_NONE)
+ continue
+ if((initial(knowledge.tier) == TIER_MARK || initial(knowledge.tier) == TIER_BLADE || initial(knowledge.tier) == TIER_ASCEND) && lore != initial(knowledge.route))
+ continue
+ researchable_knowledge += knowledge
+
return researchable_knowledge
/datum/antagonist/heretic/proc/get_knowledge(wanted)
@@ -862,31 +781,31 @@
return transmutations
/datum/antagonist/heretic/proc/is_ash()
- return "[lore]" == "Ash"
+ return "[lore]" == PATH_ASH
/datum/antagonist/heretic/proc/is_flesh()
- return "[lore]" == "Flesh"
+ return "[lore]" == PATH_FLESH
/datum/antagonist/heretic/proc/is_rust()
- return "[lore]" == "Rust"
+ return "[lore]" == PATH_RUST
/datum/antagonist/heretic/proc/is_mind()
- return "[lore]" == "Mind"
+ return "[lore]" == PATH_MIND
/datum/antagonist/heretic/proc/is_void()
- return "[lore]" == "Void"
+ return "[lore]" == PATH_VOID
/datum/antagonist/heretic/proc/is_blade()
- return "[lore]" == "Blade"
+ return "[lore]" == PATH_BLADE
/datum/antagonist/heretic/proc/is_cosmic()
- return "[lore]" == "Cosmic"
+ return "[lore]" == PATH_COSMIC
/datum/antagonist/heretic/proc/is_knock()
- return "[lore]" == "Knock"
+ return "[lore]" == PATH_KNOCK
/datum/antagonist/heretic/proc/is_unpledged()
- return "[lore]" == "Unpledged"
+ return "[lore]" == PATH_NONE
////////////////
// Objectives //
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_gun.dm b/code/modules/antagonists/eldritch_cult/eldritch_gun.dm
index 38b94e060142..2f902acbc474 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_gun.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_gun.dm
@@ -120,7 +120,7 @@
BB.stamina *= 2
BB.knockdown = 0.5 SECONDS
BB.stutter = 6 SECONDS
- BB.projectile_phasing = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINES | PASSSTRUCTURE | PASSDOORS
+ BB.projectile_phasing = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINES | PASSSTRUCTURE | PASSDOOR
BB.homing = TRUE
BB.homing_turn_speed = 80
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_items.dm b/code/modules/antagonists/eldritch_cult/eldritch_items.dm
index 2707f24409b3..693016e600dc 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_items.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_items.dm
@@ -107,6 +107,7 @@
force = 20
armour_penetration = 25
throwforce = 10
+ wound_bonus = -5
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "rends")
var/datum/action/innate/heretic_shatter/linked_action
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm
index 2f8153ebc912..bb8b40f9dddd 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm
@@ -17,8 +17,6 @@
var/cost = 0
///tier of the spell, 3 of any tier is required to purchase the next ugprade knowledge, and upgrades unlock the next tier. TIER_NONE will not advance anything.
var/tier = TIER_NONE
- ///What knowledge is incompatible with this. This will simply make it impossible to research knowledges that are in banned_knowledge once this gets researched.
- var/list/banned_knowledge = list()
///What path is this on defaults to "Side"
var/route = PATH_SIDE
///transmutation recipes unlocked by this knowledge
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
index 4bdc5cc2bd4e..53092c81197c 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
@@ -2,35 +2,6 @@
name = "Nightwatcher's Secret"
desc = "Pledges yourself to the path of Ash. Allows you to transmute a pile of ash with a knife or its derivatives into an ashen blade. Additionally, empowers your Mansus grasp to throw enemies away from you. You will also become more resistant to fire."
gain_text = "Night on the Kilnplains reveals the Ashy Lantern in the sky. In your dreams, you reached out and touched it. Now, like it, you are a part of the dunes. Forever."
- banned_knowledge = list(
- /datum/eldritch_knowledge/base_rust,
- /datum/eldritch_knowledge/base_flesh,
- /datum/eldritch_knowledge/base_mind,
- /datum/eldritch_knowledge/base_void,
- /datum/eldritch_knowledge/base_blade,
- /datum/eldritch_knowledge/base_cosmic,
- /datum/eldritch_knowledge/base_knock,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,
- /datum/eldritch_knowledge/rust_final,
- /datum/eldritch_knowledge/flesh_final,
- /datum/eldritch_knowledge/mind_final,
- /datum/eldritch_knowledge/void_final,
- /datum/eldritch_knowledge/blade_final,
- /datum/eldritch_knowledge/cosmic_final,
- /datum/eldritch_knowledge/knock_final)
unlocked_transmutations = list(/datum/eldritch_transmutation/ash_knife)
cost = 1
route = PATH_ASH
@@ -94,6 +65,7 @@
desc = "Allows you to craft an eldritch amulet by transmuting a pair of eyes with a glass shard. When worn, the amulet will give you thermal vision."
unlocked_transmutations = list(/datum/eldritch_transmutation/ashen_eyes)
cost = 1
+ route = PATH_ASH
tier = TIER_1
/datum/eldritch_knowledge/ash_mark
@@ -101,14 +73,6 @@
gain_text = "All living things are linked through their sparks. This technique represents a fraction of the Shrouded One's communality."
desc = "Your Mansus grasp now applies a mark on hit. Use your ashen blade to detonate the mark, which causes burning that can spread to nearby targets, decreasing in damage with each jump."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,)
route = PATH_ASH
tier = TIER_MARK
@@ -166,14 +130,6 @@
gain_text = "The stench of boiling blood was common in the wake of the City Guard. Though they are gone, the memory of their pikes and greatswords may yet benefit you."
desc = "Your ashen blade will now ignite targets."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,)
route = PATH_ASH
tier = TIER_BLADE
@@ -199,6 +155,7 @@
desc = "A powerful ranged spell that causes heavy bleeding and blood loss in an area around your target."
cost = 1
spell_to_add = /datum/action/cooldown/spell/pointed/cleave
+ route = PATH_ASH
tier = TIER_3
/datum/eldritch_knowledge/ash_final
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/blade_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/blade_lore.dm
index 9ed83a92e4b8..6989d662bb75 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/blade_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/blade_lore.dm
@@ -2,35 +2,6 @@
name = "The Cutting Edge"
desc = "Pledges yourself to the path of Blade. Allows you to transmute a bar of silver with a knife or its derivatives into a Sundered Blade. Additionally, empowers your Mansus grasp to deal brute damage and paralyze enemies hit."
gain_text = "Our great ancestors forged swords and practiced sparring on the eve of great battles."
- banned_knowledge = list(
- /datum/eldritch_knowledge/base_ash,
- /datum/eldritch_knowledge/base_rust,
- /datum/eldritch_knowledge/base_flesh,
- /datum/eldritch_knowledge/base_mind,
- /datum/eldritch_knowledge/base_void,
- /datum/eldritch_knowledge/base_cosmic,
- /datum/eldritch_knowledge/base_knock,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,
- /datum/eldritch_knowledge/ash_final,
- /datum/eldritch_knowledge/rust_final,
- /datum/eldritch_knowledge/flesh_final,
- /datum/eldritch_knowledge/mind_final,
- /datum/eldritch_knowledge/void_final,
- /datum/eldritch_knowledge/cosmic_final,
- /datum/eldritch_knowledge/knock_final)
unlocked_transmutations = list(/datum/eldritch_transmutation/dark_knife)
cost = 1
route = PATH_BLADE
@@ -201,14 +172,6 @@
That is how I met them. Their name was The Colonel."
desc = "Allows you to craft Eldrtich Whetstones, one time use items that can enhance the sharpness of your blades up to a certain degree."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,)
unlocked_transmutations = list(/datum/eldritch_transmutation/eldritch_whetstone)
route = PATH_BLADE
tier = TIER_MARK
@@ -218,7 +181,6 @@
var/obj/eldwhetstone = new /obj/item/sharpener/eldritch
user.put_in_hands(eldwhetstone)
-
/datum/eldritch_knowledge/duel_stance
name = "T2 - Stance of the Torn Champion"
desc = "Grants immunity to having your limbs dismembered. \
@@ -241,6 +203,7 @@
gain_text = "In the flurry of death, he found peace within himself. Despite insurmountable odds, he forged on."
cost = 1
spell_to_add = /datum/action/cooldown/spell/realignment
+ route = PATH_BLADE
tier = TIER_2
/datum/eldritch_knowledge/duel_stance/on_gain(mob/user, datum/antagonist/heretic/our_heretic)
@@ -287,14 +250,6 @@
gain_text = "I found him cleaved in twain, halves locked in a duel without end; \
a flurry of blades, neither hitting their mark, for the Champion was indomitable."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,)
unlocked_transmutations = list(/datum/eldritch_transmutation/bone_knife)
route = PATH_BLADE
tier = TIER_BLADE
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/cosmo_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/cosmo_lore.dm
index f591fe7c2863..68381332e33e 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/cosmo_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/cosmo_lore.dm
@@ -3,35 +3,6 @@
desc = "Opens up the Path of Cosmos to you. \ Allows you to transmute a sheet of plasma and a knife into an Cosmic Blade. \
Additionally your grasp will now cause a cosmic ring on your targets, which are affected by your abilities."
gain_text = "A nebula appeared in the sky, its infernal birth shone upon me. This was the start of a great transcendence."
- banned_knowledge = list(
- /datum/eldritch_knowledge/base_ash,
- /datum/eldritch_knowledge/base_rust,
- /datum/eldritch_knowledge/base_flesh,
- /datum/eldritch_knowledge/base_mind,
- /datum/eldritch_knowledge/base_void,
- /datum/eldritch_knowledge/base_blade,
- /datum/eldritch_knowledge/base_knock,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/knock_mark,
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,
- /datum/eldritch_knowledge/ash_final,
- /datum/eldritch_knowledge/rust_final,
- /datum/eldritch_knowledge/flesh_final,
- /datum/eldritch_knowledge/mind_final,
- /datum/eldritch_knowledge/void_final,
- /datum/eldritch_knowledge/blade_final,
- /datum/eldritch_knowledge/knock_final)
unlocked_transmutations = list(/datum/eldritch_transmutation/cosmic_knife)
cost = 1
route = PATH_COSMIC
@@ -86,14 +57,6 @@
They will then be paralyzed for 2 seconds."
gain_text = "The Beast now whispered to me occasionally, only small tidbits of their circumstances. \
I can help them, I have to help them."
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/knock_mark,)
route = PATH_COSMIC
tier = TIER_MARK
@@ -134,14 +97,6 @@
desc = "Your blade now deals damage to people's cells through cosmic radiation."
gain_text = "The Beast took my blades in their hand, I kneeled and felt a sharp pain. \
The blades now glistened with fragmented power. I fell to the ground and wept at the beast's feet."
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade)
route = PATH_COSMIC
tier = TIER_BLADE
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
index 23b2c2c5e881..1252b9c7a63e 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
@@ -2,35 +2,6 @@
name = "Principle of Hunger"
desc = "Pledges yourself to the path of Flesh. Allows you to transmute a pool of blood with a knife into a flesh blade. Additionally, your Mansus grasp now raises dead humanoids into subservient ghouls if they are not mindshielded or husked. It will husk the person it's used on."
gain_text = "The Priest has seduced countless into his flock. He will entice countless more with the Glorious Feast. You knelt before his statue and swore the Red Oath."
- banned_knowledge = list(
- /datum/eldritch_knowledge/base_ash,
- /datum/eldritch_knowledge/base_rust,
- /datum/eldritch_knowledge/base_mind,
- /datum/eldritch_knowledge/base_void,
- /datum/eldritch_knowledge/base_blade,
- /datum/eldritch_knowledge/base_cosmic,
- /datum/eldritch_knowledge/base_knock,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,
- /datum/eldritch_knowledge/ash_final,
- /datum/eldritch_knowledge/rust_final,
- /datum/eldritch_knowledge/mind_final,
- /datum/eldritch_knowledge/void_final,
- /datum/eldritch_knowledge/blade_final,
- /datum/eldritch_knowledge/cosmic_final,
- /datum/eldritch_knowledge/knock_final)
cost = 1
unlocked_transmutations = list(/datum/eldritch_transmutation/flesh_blade)
route = PATH_FLESH
@@ -131,6 +102,7 @@
desc = "Allows you to summon a Fire Shark by transmuting a pair of eyes, a pile of ash, and a sheet of plasma. Fire sharks leave behind a cloud of plasma upon death, and injects Phlogiston into the targets it bites."
cost = 1
unlocked_transmutations = list(/datum/eldritch_transmutation/summon/fire_shark)
+ route = PATH_FLESH
tier = TIER_1
/datum/eldritch_knowledge/flesh_mark
@@ -138,14 +110,6 @@
gain_text = "She revels and laughs when life begins to flow. Her kiss rips and feasts on flesh alike. This imitates her touch."
desc = "Your Mansus grasp now applies a mark on hit. Use your flesh blade to detonate the mark, which causes significant bleeding on the target."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,)
route = PATH_FLESH
tier = TIER_MARK
@@ -178,6 +142,7 @@
desc = "A touch spell that drains a target's health and restores yours."
cost = 1
spell_to_add = /datum/action/cooldown/spell/pointed/blood_siphon
+ route = PATH_FLESH
tier = TIER_2
/datum/eldritch_knowledge/flesh_blade_upgrade
@@ -185,14 +150,6 @@
gain_text = "Ebis, the Owl, was the second to take the Red Oath. They still grant the gift of their steel to those powerful enough to resist their incursions."
desc = "Your flesh blade will now cause additional bleeding on hit."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,)
route = PATH_FLESH
tier = TIER_BLADE
@@ -219,6 +176,7 @@
desc = "You can now summon an Ashman by transmuting a pile of ash, a head, and a book. Ashmen have powerful offensive abilities and access to the Ashen Shift spell."
cost = 1
unlocked_transmutations = list(/datum/eldritch_transmutation/summon/ashy)
+ route = PATH_FLESH
tier = TIER_3
/datum/eldritch_knowledge/rusty
@@ -227,6 +185,7 @@
desc = "You can now summon a Rustwalker transmuting a vomit pool and a book. Rustwalkers are capable of spreading rust and have a strong, short-ranged projectile attack."
cost = 1
unlocked_transmutations = list(/datum/eldritch_transmutation/summon/rusty)
+ route = PATH_FLESH
tier = TIER_3
/datum/eldritch_knowledge/flesh_final
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/knock_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/knock_lore.dm
index f4c76e69f88e..80931c2c2307 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/knock_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/knock_lore.dm
@@ -3,35 +3,6 @@
desc = "Opens up the Path of Knock to you. \
Allows you to transmute a knife and a crowbar into a Key Blade. Additionally, your grasp will open up numerous locked things when used upon them."
gain_text = "The Knock permits no seal and no isolation. It thrusts us gleefully out of the safety of ignorance."
- banned_knowledge = list(
- /datum/eldritch_knowledge/base_ash,
- /datum/eldritch_knowledge/base_rust,
- /datum/eldritch_knowledge/base_flesh,
- /datum/eldritch_knowledge/base_mind,
- /datum/eldritch_knowledge/base_void,
- /datum/eldritch_knowledge/base_blade,
- /datum/eldritch_knowledge/base_cosmic,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/ash_final,
- /datum/eldritch_knowledge/rust_final,
- /datum/eldritch_knowledge/flesh_final,
- /datum/eldritch_knowledge/mind_final,
- /datum/eldritch_knowledge/void_final,
- /datum/eldritch_knowledge/blade_final,
- /datum/eldritch_knowledge/cosmic_final)
unlocked_transmutations = list(/datum/eldritch_transmutation/knock_knife)
cost = 1
route = PATH_KNOCK
@@ -98,14 +69,6 @@
Attack a marked person to bar them from all passages for the duration of the mark."
gain_text = "Their requests for passage will remain unheeded."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark)
route = PATH_KNOCK
tier = TIER_MARK
@@ -137,14 +100,6 @@
name = "Blade Upgrade - Opening Blade"
desc = "Your blade will be able to pry open unlocked airlocks."
gain_text = "The power of my patron courses through my blade, willing their very flesh to part."
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,)
route = PATH_KNOCK
tier = TIER_BLADE
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/mind_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/mind_lore.dm
index c887de51ee2d..a39b68b38f7c 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/mind_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/mind_lore.dm
@@ -2,35 +2,6 @@
name = "Precipice Of Enlightenment"
desc = "Pledge yourself to knowledge everlasting. Allows you to transmute a knife and a book into a blade of pure thought. Additionally, Your mansus grasp now functions at a range, knocking them down and blurring their vision."
gain_text = "The corpse of an ancient God defiled, your fellow scholars enlightened by false knowledge, but you seek true insight. You seek the unknown, the invisible, the truth behind the veil."
- banned_knowledge = list(
- /datum/eldritch_knowledge/base_ash,
- /datum/eldritch_knowledge/base_rust,
- /datum/eldritch_knowledge/base_flesh,
- /datum/eldritch_knowledge/base_void,
- /datum/eldritch_knowledge/base_blade,
- /datum/eldritch_knowledge/base_cosmic,
- /datum/eldritch_knowledge/base_knock,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,
- /datum/eldritch_knowledge/ash_final,
- /datum/eldritch_knowledge/rust_final,
- /datum/eldritch_knowledge/flesh_final,
- /datum/eldritch_knowledge/void_final,
- /datum/eldritch_knowledge/blade_final,
- /datum/eldritch_knowledge/cosmic_final,
- /datum/eldritch_knowledge/knock_final)
unlocked_transmutations = list(/datum/eldritch_transmutation/mind_knife)
cost = 1
route = PATH_MIND
@@ -63,17 +34,6 @@
human_target.blur_eyes(1 SECONDS)
human_target.Knockdown(2 SECONDS)
-// /datum/eldritch_knowledge/spell/mental_obfuscation
-// name = "T1 - Mental Obfuscation"
-// gain_text = "A mind is such an easy thing to trick, nothing more than a lump of meat ready to be moulded by your hands."
-// desc = "Allows you to teleport a short distance to a targeted destination."
-// cost = 1
-// spell_to_add = /datum/action/cooldown/spell/pointed/phase_jump/obfuscation
-// banned_knowledge = list(
-// /datum/eldritch_knowledge/spell/void_phase)
-// route = PATH_MIND
-// tier = TIER_1
-
/datum/eldritch_knowledge/spell/eldritchbolt
name = "T1 - Eldritch Bolt"
gain_text = "Remain wary of the frailty of men. Their wills are weak, minds young. Were it not for fear, death would go unlamented. Seek the old blood. Let us pray, let us wish... to partake in communion."
@@ -89,6 +49,7 @@
desc = "Allows you to craft an eldritch eye by transmuting a flashlight and a pair of eyes. Grants the user a hud type of their choosing, additionally also grants night vision but it cannot be removed."
unlocked_transmutations = list(/datum/eldritch_transmutation/eldritch_eye)
cost = 1
+ route = PATH_MIND
tier = TIER_1
/datum/eldritch_knowledge/mind_mark
@@ -96,14 +57,6 @@
gain_text = "They say the eyes are the gateway to the soul, a way to tell one's true intentions. Show them a single sliver of the truth of this world and their eyes will reject all."
desc = "Upgrade your mansus grasp, granting it the ability to blind a target on hit, as well as increasing the range"
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,)
route = PATH_MIND
tier = TIER_MARK
@@ -141,6 +94,7 @@
desc = "An AOE roar spell that freezes all nearby people with sheer terror."
cost = 1
spell_to_add = /datum/action/cooldown/spell/aoe/immobilize/famished_roar
+ route = PATH_MIND
tier = TIER_3
/datum/eldritch_knowledge/mind_blade_upgrade
@@ -148,14 +102,6 @@
gain_text = "Curse here, Curse there. Curse for he and she, why care? A bottomless curse, a bottomless sea, source of all greatness, all things that be."
desc = "Your mind blade will now inject targets hit with mutetoxin, silencing them."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,)
route = PATH_MIND
tier = TIER_BLADE
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
index 02c02108911d..3a24e212310c 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
@@ -2,35 +2,6 @@
name = "Blacksmith's Tale"
desc = "Pledges yourself to the path of Rust. Allows you to transmute a piece of trash with a knife into a rusty blade. Additionally, your Mansus grasp now deals 500 damage to inorganic matter, rusts any surface it's used on, while destroying any surface that is already rusty."
gain_text = "Outside the Ruined Keep, you drank of the River Krym. Its poison seeped through your body as years shriveled away. Yet, you were spared. Now, your purpose is clear."
- banned_knowledge = list(
- /datum/eldritch_knowledge/base_ash,
- /datum/eldritch_knowledge/base_flesh,
- /datum/eldritch_knowledge/base_mind,
- /datum/eldritch_knowledge/base_void,
- /datum/eldritch_knowledge/base_blade,
- /datum/eldritch_knowledge/base_cosmic,
- /datum/eldritch_knowledge/base_knock,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,
- /datum/eldritch_knowledge/ash_final,
- /datum/eldritch_knowledge/flesh_final,
- /datum/eldritch_knowledge/mind_final,
- /datum/eldritch_knowledge/void_final,
- /datum/eldritch_knowledge/blade_final,
- /datum/eldritch_knowledge/cosmic_final,
- /datum/eldritch_knowledge/knock_final)
cost = 1
unlocked_transmutations = list(/datum/eldritch_transmutation/rust_blade)
route = PATH_RUST
@@ -89,6 +60,7 @@
desc = "An instant spell that will create a wall at your command, only works on rusted tiles. Will knock back and damage anyone caught on the same tile."
cost = 1
spell_to_add = /datum/action/cooldown/spell/pointed/rust_construction
+ route = PATH_RUST
tier = TIER_1
/datum/eldritch_knowledge/rust_regen/on_life(mob/user)
@@ -111,6 +83,7 @@
desc = "Allows you to craft a set of eldritch armor by transmuting a table and a gas mask. The robes significantly reduce most incoming damage. Also allows you to further upgrade said robes by transmuting a diamond with it."
cost = 1
unlocked_transmutations = list(/datum/eldritch_transmutation/armor, /datum/eldritch_transmutation/armor/upgrade)
+ route = PATH_RUST
tier = TIER_1
/datum/eldritch_knowledge/essence
@@ -119,6 +92,7 @@
desc = "Allows you to craft a flask of eldritch essence by transmuting a water tank. The reagent will heal you and damage those not linked to the Mansus."
cost = 1
unlocked_transmutations = list(/datum/eldritch_transmutation/water)
+ route = PATH_RUST
tier = TIER_1
/datum/eldritch_knowledge/rust_mark
@@ -126,14 +100,6 @@
gain_text = "Ire and envy are universally observable. Where the Drifter went, he saw those who rejoiced with more and those who suffered with less. Only hatred grew in his heart."
desc = "Your Mansus grasp now applies a mark on hit. Use your rusty blade to detonate the mark, which has a chance to deal between 0 to 200 damage to 75% of your target's items."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/void_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,)
route = PATH_RUST
tier = TIER_MARK
@@ -165,14 +131,6 @@
gain_text = "By the time her subjects began to rebel, she had given the Blacksmith enough bodies to sate the blades. His own drooled with an intoxicating nectar, which sealed his fate."
desc = "Your rusted blade now injects eldritch essence on hit."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/void_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,)
route = PATH_RUST
tier = TIER_BLADE
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm
index e5a6507d75f0..ed0b854b7544 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm
@@ -2,35 +2,6 @@
name = "Glimmer of Winter"
desc = "Pledges yourself to the path of the Void. Allows you to transmute a stuff with a knife or its derivatives into a void blade. Additionally, empowers your Mansus grasp to chill any target hit."
gain_text = "Wanting, I lie, too weary to die, too lost to the ice for saving. My sins claim me, untame me"
- banned_knowledge = list(
- /datum/eldritch_knowledge/base_ash,
- /datum/eldritch_knowledge/base_rust,
- /datum/eldritch_knowledge/base_flesh,
- /datum/eldritch_knowledge/base_mind,
- /datum/eldritch_knowledge/base_blade,
- /datum/eldritch_knowledge/base_cosmic,
- /datum/eldritch_knowledge/base_knock,
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade,
- /datum/eldritch_knowledge/ash_final,
- /datum/eldritch_knowledge/rust_final,
- /datum/eldritch_knowledge/flesh_final,
- /datum/eldritch_knowledge/mind_final,
- /datum/eldritch_knowledge/blade_final,
- /datum/eldritch_knowledge/cosmic_final,
- /datum/eldritch_knowledge/knock_final)
unlocked_transmutations = list(/datum/eldritch_transmutation/void_knife)
cost = 1
route = PATH_VOID
@@ -85,19 +56,6 @@
route = PATH_VOID
tier = TIER_1
-// /datum/eldritch_knowledge/spell/void_phase
-// name = "T1 - Void Phase"
-// gain_text = "The entity calls themself the Aristocrat. They effortlessly walk through air like
-// nothing - leaving a harsh, cold breeze in their wake. They disappear, and I am left in the blizzard."
-// desc = "Grants you Void Phase, a long range targeted teleport spell.
-// Additionally causes damage to heathens around your original and target destination."
-// cost = 1
-// spell_to_add = /datum/action/cooldown/spell/pointed/void_phase
-// banned_knowledge = list(
-// /datum/eldritch_knowledge/spell/mental_obfuscation)
-// route = PATH_VOID
-// tier = TIER_1
-
/datum/eldritch_knowledge/void_cloak
name = "T1 - Void Cloak"
gain_text = "The Owl is the keeper of things that are not quite in practice, but in theory are. Many things are."
@@ -105,6 +63,7 @@
to create a Void Cloak. This cloak will make the wearer partially invisible over time, and allow them to temporarily dodge attacks."
unlocked_transmutations = list(/datum/eldritch_transmutation/void_cloak)
cost = 1
+ route = PATH_VOID
tier = TIER_1
/datum/eldritch_knowledge/void_mark
@@ -114,14 +73,6 @@
desc = "Your Mansus Grasp now applies the Mark of Void. The mark is triggered from an attack with your Void Blade. \
When triggered, further silences the victim and swiftly lowers the temperature of their body and the air around them."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_mark,
- /datum/eldritch_knowledge/rust_mark,
- /datum/eldritch_knowledge/flesh_mark,
- /datum/eldritch_knowledge/mind_mark,
- /datum/eldritch_knowledge/blade_mark,
- /datum/eldritch_knowledge/cosmic_mark,
- /datum/eldritch_knowledge/knock_mark,)
route = PATH_VOID
tier = TIER_MARK
@@ -165,6 +116,7 @@
freezing the ground and any victims within."
cost = 1
spell_to_add = /datum/action/cooldown/spell/cone/staggered/cone_of_cold/void
+ route = PATH_VOID
tier = TIER_2
/datum/eldritch_knowledge/void_blade_upgrade
@@ -172,14 +124,6 @@
gain_text = "Fleeting memories, fleeting feet. I mark my way with frozen blood upon the snow. Covered and forgotten, wandering I lie, too weary to die."
desc = "Your blade will now inject a freezing venom into your targets."
cost = 2
- banned_knowledge = list(
- /datum/eldritch_knowledge/ash_blade_upgrade,
- /datum/eldritch_knowledge/rust_blade_upgrade,
- /datum/eldritch_knowledge/flesh_blade_upgrade,
- /datum/eldritch_knowledge/mind_blade_upgrade,
- /datum/eldritch_knowledge/blade_blade_upgrade,
- /datum/eldritch_knowledge/cosmic_blade_upgrade,
- /datum/eldritch_knowledge/knock_blade_upgrade)
route = PATH_VOID
tier = TIER_BLADE
@@ -210,11 +154,11 @@
desc = "A powerful spell that calls forth memories of ice, will create a large area of ice around you."
cost = 1
spell_to_add = /datum/action/cooldown/spell/aoe/slip/void
+ route = PATH_VOID
tier = TIER_3
/datum/eldritch_knowledge/lionhunter_rifle
name = "T3 - Lionhunter Rifle"
- name = "Lionhunter's Rifle"
desc = "Allows you to transmute any ballistic weapon, with \
a plank of wood, a piece of gold and a camera to create the Lionhunter's rifle. \
The Lionhunter's Rifle is a long ranged ballistic weapon with three shots. \
@@ -226,6 +170,7 @@
I could not purchase it at the time, but they showed me how they made it ages ago."
unlocked_transmutations = list(/datum/eldritch_transmutation/lionhunter, /datum/eldritch_transmutation/lionhunter_ammo)
cost = 1
+ route = PATH_VOID
tier = TIER_3
/datum/eldritch_knowledge/void_final
diff --git a/code/modules/antagonists/eldritch_cult/magic/general_heretic_magic.dm b/code/modules/antagonists/eldritch_cult/magic/general_heretic_magic.dm
index 7af0106e0ac7..ab839dd64ed3 100644
--- a/code/modules/antagonists/eldritch_cult/magic/general_heretic_magic.dm
+++ b/code/modules/antagonists/eldritch_cult/magic/general_heretic_magic.dm
@@ -156,8 +156,7 @@ THIS FILE IS FOR ALL HERETIC SPELLS THAT DO NOT CONFER TO A PATH'S THEME OR YOU
invocation_type = INVOCATION_WHISPER
spell_requirements = SPELL_CASTABLE_WITHOUT_INVOCATION | SPELL_REQUIRES_NO_ANTIMAGIC
- emp_heavy = 6
- emp_light = 10
+ radius = 10
/datum/action/cooldown/spell/list_target/telepathy/eldritch
name = "Eldritch Telepathy"
diff --git a/code/modules/antagonists/eldritch_cult/transmutations/ash_transmutations.dm b/code/modules/antagonists/eldritch_cult/transmutations/ash_transmutations.dm
index ee4b5cd647d2..111e7052270b 100644
--- a/code/modules/antagonists/eldritch_cult/transmutations/ash_transmutations.dm
+++ b/code/modules/antagonists/eldritch_cult/transmutations/ash_transmutations.dm
@@ -99,5 +99,3 @@
env = T.return_air()
current_temp = env.return_temperature()
env.set_temperature(current_temp+25)
- T.air_update_turf()
- L.air_update_turf()
diff --git a/code/modules/antagonists/horror/horror.dm b/code/modules/antagonists/horror/horror.dm
index 8e9e8cdcc4f6..03ca12a00b9c 100644
--- a/code/modules/antagonists/horror/horror.dm
+++ b/code/modules/antagonists/horror/horror.dm
@@ -73,6 +73,7 @@
add_ability(/datum/action/innate/horror/take_control)
add_ability(/datum/action/innate/horror/leave_body)
add_ability(/datum/action/innate/horror/make_chems)
+ add_ability(/datum/action/innate/horror/scan_host)
add_ability(/datum/action/innate/horror/give_back_control)
RefreshAbilities()
@@ -433,6 +434,15 @@
usr << browse(html, "window=ViewHorror\ref[src]Chems;size=600x800")
+/mob/living/simple_animal/horror/proc/scan_host()
+ if(!can_use_ability())
+ return
+ if(!victim)
+ to_chat(src, span_warning("You are not inside a host body."))
+ return
+ healthscan(usr, victim)
+ chemscan(usr, victim)
+
/mob/living/simple_animal/horror/proc/hide()
if(victim)
to_chat(src, span_warning("You cannot do this while you're inside a host."))
diff --git a/code/modules/antagonists/horror/horror_abilities_and_upgrades.dm b/code/modules/antagonists/horror/horror_abilities_and_upgrades.dm
index 090af213248b..8213353bc619 100644
--- a/code/modules/antagonists/horror/horror_abilities_and_upgrades.dm
+++ b/code/modules/antagonists/horror/horror_abilities_and_upgrades.dm
@@ -137,6 +137,17 @@
/datum/action/innate/horror/make_chems/Activate()
B.secrete_chemicals()
+/datum/action/innate/horror/scan_host
+ name = "Host Scan"
+ desc = "Analyze your host's body and chemical content."
+ button_icon = 'icons/obj/device.dmi'
+ button_icon_state = "health"
+ blacklisted = TRUE
+ category = list("infest")
+
+/datum/action/innate/horror/scan_host/Activate()
+ B.scan_host()
+
/datum/action/innate/horror/freeze_victim
name = "Knockdown victim"
desc = "Use your tentacle to trip a victim, stunning for a short duration."
diff --git a/code/modules/antagonists/horror/horror_chemicals.dm b/code/modules/antagonists/horror/horror_chemicals.dm
index 50cfdafb7f60..704ca1b9dc15 100644
--- a/code/modules/antagonists/horror/horror_chemicals.dm
+++ b/code/modules/antagonists/horror/horror_chemicals.dm
@@ -26,7 +26,7 @@
to_chat(src, span_boldnotice("You need [C.chemuse] chemicals stored to use this chemical!"))
return
- to_chat(src, span_danger("You squirt a measure of [C.chemname] from your reservoirs into [victim]'s bloodstream."))
+ to_chat(src, span_danger("You squirt [C.quantity] units of [C.chemname] from your reservoirs into [victim]'s bloodstream."))
victim.reagents.add_reagent(C.R, C.quantity)
chemicals -= C.chemuse
log_game("[src]/([src.ckey]) has injected [C.chemname] into their host [victim]/([victim.ckey])")
@@ -51,7 +51,6 @@
chemname = "mannitol"
R = /datum/reagent/medicine/mannitol
chem_desc = "Heals brain damage."
-
/datum/horror_chem/bicaridine
chemname = "bicaridine"
R = /datum/reagent/medicine/bicaridine
diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
index d4c6bdef3518..6157aa467e5b 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
@@ -1,6 +1,6 @@
/obj/machinery/nuclearbomb
name = "nuclear fission explosive"
- desc = "A stolen NanoTrasen branded nuclear bomb. You probably shouldn't stick around to see if this is armed."
+ desc = "A stolen Nanotrasen branded nuclear bomb. You probably shouldn't stick around to see if this is armed."
icon = 'icons/obj/machines/nuke.dmi'
icon_state = "nuclearbomb_base"
base_icon_state = "nuclearbomb"
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index 0155656d5a86..877b97da4936 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -17,6 +17,7 @@
var/traitor_kind = TRAITOR_HUMAN //Set on initial assignment
var/malf = FALSE //whether or not the AI is malf (in case it's a traitor)
var/datum/contractor_hub/contractor_hub
+ var/obj/item/uplink_holder
can_hijack = HIJACK_HIJACKER
/datum/antagonist/traitor/on_gain()
diff --git a/code/modules/atmospherics/auxgm/breathing_classes.dm b/code/modules/atmospherics/auxgm/breathing_classes.dm
new file mode 100644
index 000000000000..862f2b5b8aa3
--- /dev/null
+++ b/code/modules/atmospherics/auxgm/breathing_classes.dm
@@ -0,0 +1,82 @@
+// Breathing classes are, yes, just a list of gases, associated with numbers.
+// But they're very simple: pluoxium's status as O2 * 8 is represented here,
+// with a single line of code, no hardcoding and special-casing across the codebase.
+// Not only that, but they're very general: you could have a negative value
+// to simulate asphyxiants, e.g. if I add krypton it could go into the oxygen
+// breathing class at -7, simulating krypton narcosis.
+
+/datum/breathing_class
+ ///Gases that we consume and count as respirable
+ var/list/gases
+ ///Gases that we breathe out
+ var/list/products
+ ///Reagent generated if we breathe in too much of the gases in the gas_max value of gases defined in lungs
+ var/danger_reagent
+ ///Catergory of the alert generated if we do not have enough required gases
+ var/low_alert_category = "not_enough_oxy"
+ ///Type of the alert generated if we do not have enough required gases
+ var/low_alert_datum = /atom/movable/screen/alert/not_enough_oxy
+ ///Catergory of the alert generated if we breathe in too much of the gases in the gas_max value of gases defined in lungs
+ var/high_alert_category = "too_much_oxy"
+ ///Type of the alert generated if we breathe in too much of the gases in the gas_max value of gases defined in lungs
+ var/high_alert_datum = /atom/movable/screen/alert/too_much_oxy
+
+/datum/breathing_class/proc/get_effective_pp(datum/gas_mixture/breath)
+ var/mol = 0
+ for(var/gas in gases)
+ mol += breath.get_moles(gas) * gases[gas]
+ return (mol/breath.total_moles()) * breath.return_pressure()
+
+/datum/breathing_class/oxygen
+ gases = list(
+ GAS_O2 = 1,
+ GAS_PLUOXIUM = 8,
+ GAS_CO2 = -0.7, // CO2 isn't actually toxic, just an asphyxiant
+ )
+ products = list(
+ GAS_CO2 = 1,
+ )
+
+/datum/breathing_class/oxygen_plas
+ gases = list(
+ GAS_O2 = 1,
+ GAS_PLUOXIUM = 8,
+ GAS_CO2 = -0.7, // CO2 isn't actually toxic, just an asphyxiant
+ GAS_PLASMA = 1
+ )
+ products = list(
+ GAS_CO2 = 1,
+ )
+
+/datum/breathing_class/oxygen_co2
+ gases = list(
+ GAS_O2 = 1,
+ GAS_PLUOXIUM = 8,
+ GAS_CO2 = 1,
+ )
+ products = list(
+ GAS_CO2 = 1,
+ )
+
+/datum/breathing_class/plasma
+ gases = list(
+ GAS_PLASMA = 1
+ )
+ products = list(
+ GAS_CO2 = 1
+ )
+ low_alert_category = "not_enough_tox"
+ low_alert_datum = /atom/movable/screen/alert/not_enough_tox
+ high_alert_category = "too_much_tox"
+ high_alert_datum = /atom/movable/screen/alert/too_much_tox
+
+/datum/breathing_class/oxygen_vapor
+ gases = list(
+ GAS_O2 = 1,
+ GAS_PLUOXIUM = 8,
+ GAS_CO2 = -0.7, // CO2 isn't actually toxic, just an asphyxiant
+ GAS_H2O = 1,
+ )
+ products = list(
+ GAS_CO2 = 1,
+ )
diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm
new file mode 100644
index 000000000000..04ff522f1cd5
--- /dev/null
+++ b/code/modules/atmospherics/auxgm/gas_types.dm
@@ -0,0 +1,203 @@
+/datum/gas/oxygen
+ id = GAS_O2
+ specific_heat = 20
+ name = "Oxygen"
+ label = "Oâ‚‚"
+ ui_color = "blue"
+
+/datum/gas/nitrogen
+ id = GAS_N2
+ specific_heat = 20
+ name = "Nitrogen"
+ label = "Nâ‚‚"
+ breath_alert_info = list(
+ not_enough_alert = list(
+ alert_category = "not_enough_nitro",
+ alert_type = /atom/movable/screen/alert/not_enough_nitro,
+ ),
+ too_much_alert = list(
+ alert_category = "too_much_nitro",
+ alert_type = /atom/movable/screen/alert/too_much_nitro,
+ )
+ )
+ ui_color = "red"
+
+/datum/gas/carbon_dioxide //what the fuck is this?
+ id = GAS_CO2
+ specific_heat = 30
+ name = "Carbon Dioxide"
+ label = "COâ‚‚"
+ breath_results = GAS_O2
+ breath_alert_info = list(
+ not_enough_alert = list(
+ alert_category = "not_enough_co2",
+ alert_type = /atom/movable/screen/alert/not_enough_co2,
+ ),
+ too_much_alert = list(
+ alert_category = "too_much_co2",
+ alert_type = /atom/movable/screen/alert/too_much_co2,
+ )
+ )
+ ui_color = "grey"
+
+/datum/gas/plasma
+ id = GAS_PLASMA
+ specific_heat = 200
+ name = "Plasma"
+ gas_overlay = "plasma"
+ moles_visible = MOLES_GAS_VISIBLE
+ flags = GAS_FLAG_DANGEROUS
+ ui_color = "orange"
+
+/datum/gas/water_vapor
+ id = GAS_H2O
+ specific_heat = 40
+ name = "Water Vapor"
+ label = "Hâ‚‚O"
+ gas_overlay = "water_vapor"
+ moles_visible = MOLES_GAS_VISIBLE
+ breath_reagent = /datum/reagent/water
+ fusion_power = 8
+ ui_color = "lightsteelblue"
+
+/datum/gas/hypernoblium
+ id = GAS_HYPERNOB
+ specific_heat = 2000
+ name = "Hyper-noblium"
+ label = "Hyper-nob"
+ gas_overlay = "freon"
+ moles_visible = MOLES_GAS_VISIBLE
+ flags = GAS_FLAG_DANGEROUS
+ ui_color = "teal"
+
+/datum/gas/nitrous_oxide
+ id = GAS_NITROUS
+ specific_heat = 40
+ name = "Nitrous Oxide"
+ label = "Nâ‚‚O"
+ gas_overlay = "nitrous_oxide"
+ moles_visible = MOLES_GAS_VISIBLE * 2
+ fusion_power = 10
+ flags = GAS_FLAG_DANGEROUS
+ ui_color = "bisque"
+
+/datum/gas/nitrium
+ id = GAS_NITRIUM
+ specific_heat = 10
+ name = "Nitrium"
+ gas_overlay = "nitrium"
+ moles_visible = MOLES_GAS_VISIBLE
+ flags = GAS_FLAG_DANGEROUS
+ fusion_power = 7
+ ui_color = "brown"
+
+/datum/gas/tritium
+ id = GAS_TRITIUM
+ specific_heat = 10
+ name = "Tritium"
+ gas_overlay = "tritium"
+ moles_visible = MOLES_GAS_VISIBLE
+ flags = GAS_FLAG_DANGEROUS
+ fusion_power = 1
+ ui_color = "limegreen"
+
+/datum/gas/bz
+ id = GAS_BZ
+ specific_heat = 20
+ name = "BZ"
+ flags = GAS_FLAG_DANGEROUS
+ fusion_power = 8
+ ui_color = "mediumpurple"
+
+/datum/gas/pluoxium
+ id = GAS_PLUOXIUM
+ specific_heat = 80
+ name = "Pluoxium"
+ fusion_power = -10
+ ui_color = "mediumslateblue"
+
+/datum/gas/miasma
+ id = GAS_MIASMA
+ specific_heat = 20
+ name = "Miasma"
+ gas_overlay = "miasma"
+ moles_visible = MOLES_GAS_VISIBLE * 60
+ ui_color = "olive"
+
+/datum/gas/freon
+ id = GAS_FREON
+ specific_heat = 600
+ name = "Freon"
+ gas_overlay = "freon"
+ moles_visible = MOLES_GAS_VISIBLE *30
+ fusion_power = -5
+ ui_color = "paleturquoise"
+
+/datum/gas/hydrogen
+ id = GAS_H2
+ specific_heat = 15
+ name = "Hydrogen"
+ label = "Hâ‚‚"
+ flags = GAS_FLAG_DANGEROUS
+ ui_color = "white"
+
+/datum/gas/healium
+ id = GAS_HEALIUM
+ specific_heat = 10
+ name = "Healium"
+ gas_overlay = "healium"
+ moles_visible = MOLES_GAS_VISIBLE
+ ui_color = "salmon"
+
+/datum/gas/pluonium
+ id = GAS_PLUONIUM
+ specific_heat = 30
+ name = "Pluonium"
+ flags = GAS_FLAG_DANGEROUS
+ gas_overlay = "pluonium"
+ moles_visible = MOLES_GAS_VISIBLE
+ ui_color = "greenyellow"
+
+/datum/gas/halon
+ id = GAS_HALON
+ specific_heat = 175
+ name = "Halon"
+ flags = GAS_FLAG_DANGEROUS
+ gas_overlay = "halon"
+ moles_visible = MOLES_GAS_VISIBLE
+ ui_color = "purple"
+
+/datum/gas/antinoblium
+ id = GAS_ANTINOB
+ specific_heat = 1
+ name = "Antinoblium"
+ label = "Anti-nob"
+ gas_overlay = "antinoblium"
+ moles_visible = MOLES_GAS_VISIBLE
+ fusion_power = 20
+ ui_color = "maroon"
+
+/datum/gas/zauker
+ id = GAS_ZAUKER
+ specific_heat = 350
+ name = "Zauker"
+ flags = GAS_FLAG_DANGEROUS
+ gas_overlay = "zauker"
+ moles_visible = MOLES_GAS_VISIBLE
+ ui_color = "darkgreen"
+
+/datum/gas/hexane
+ id = GAS_HEXANE
+ specific_heat = 5
+ name = "Hexane"
+ flags = GAS_FLAG_DANGEROUS
+ gas_overlay = "hexane"
+ moles_visible = MOLES_GAS_VISIBLE
+ ui_color = "plum"
+
+/datum/gas/dilithium // Main point is that this helps fusion occur at a significantly lower temperature than normal
+ id = GAS_DILITHIUM
+ specific_heat = 55
+ name = "Dilithium"
+ fusion_power = 1
+ ui_color = "pink"
diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm
index a211e76706d2..635a5d5b1dae 100644
--- a/code/modules/atmospherics/environmental/LINDA_fire.dm
+++ b/code/modules/atmospherics/environmental/LINDA_fire.dm
@@ -17,33 +17,23 @@
if(!air)
return
- if(air.get_moles(/datum/gas/hypernoblium) > REACTION_OPPRESSION_THRESHOLD)
+ if (air.get_moles(GAS_O2) < 0.5 || air.get_moles(GAS_HYPERNOB) > REACTION_OPPRESSION_THRESHOLD)
return
- var/oxy = air.get_moles(/datum/gas/oxygen)
- if (oxy < 0.5)
- return
- var/tox = air.get_moles(/datum/gas/plasma)
- var/trit = air.get_moles(/datum/gas/tritium)
- var/h2 = air.get_moles(/datum/gas/hydrogen)
+ var/has_fuel = air.get_moles(GAS_PLASMA) > 0.5 || air.get_moles(GAS_TRITIUM) > 0.5 || air.get_moles(GAS_H2) > 0.5
if(active_hotspot)
if(soh)
- if(tox > 0.5 || trit > 0.5 || h2 > 0.5)
+ if(has_fuel)
if(active_hotspot.temperature < exposed_temperature)
active_hotspot.temperature = exposed_temperature
if(active_hotspot.volume < exposed_volume)
active_hotspot.volume = exposed_volume
return
- if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && (tox > 0.5 || trit > 0.5 || h2 > 0.5))
-
+ if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && has_fuel)
active_hotspot = new /obj/effect/hotspot(src, exposed_volume*25, exposed_temperature)
- active_hotspot.just_spawned = (current_cycle < SSair.times_fired)
- //remove just_spawned protection if no longer processing this cell
- SSair.add_to_active(src, 0)
-
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
/obj/effect/hotspot
anchored = TRUE
@@ -73,7 +63,6 @@
if(!perform_exposure())
return INITIALIZE_HINT_QDEL
setDir(pick(GLOB.cardinals))
- air_update_turf()
/obj/effect/hotspot/proc/perform_exposure()
var/turf/open/location = loc
@@ -163,7 +152,7 @@
color = list(LERP(0.3, 1, 1-greyscale_fire) * heat_r,0.3 * heat_g * greyscale_fire,0.3 * heat_b * greyscale_fire, 0.59 * heat_r * greyscale_fire,LERP(0.59, 1, 1-greyscale_fire) * heat_g,0.59 * heat_b * greyscale_fire, 0.11 * heat_r * greyscale_fire,0.11 * heat_g * greyscale_fire,LERP(0.11, 1, 1-greyscale_fire) * heat_b, 0,0,0)
alpha = heat_a
-#define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5)
+#define INSUFFICIENT(id) (location.air.get_moles(id) < 0.5)
/obj/effect/hotspot/process()
if(just_spawned)
just_spawned = FALSE
@@ -181,7 +170,7 @@
return
//Not enough / nothing to burn
- if(!location.air || (INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) && INSUFFICIENT(/datum/gas/hydrogen) || INSUFFICIENT(/datum/gas/oxygen))
+ if(!location.air || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM)) && INSUFFICIENT(GAS_H2) || INSUFFICIENT(GAS_O2))
qdel(src)
return
diff --git a/code/modules/atmospherics/environmental/LINDA_system.dm b/code/modules/atmospherics/environmental/LINDA_system.dm
index 21dc6069a6c2..fc3d4ffa183b 100644
--- a/code/modules/atmospherics/environmental/LINDA_system.dm
+++ b/code/modules/atmospherics/environmental/LINDA_system.dm
@@ -18,58 +18,112 @@
/turf/open/CanAtmosPass(turf/T, vertical = FALSE)
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
- var/opp = dir_inverse_multiz(dir)
- var/R = FALSE
+ . = TRUE
if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src)))
- R = TRUE
+ . = FALSE
if(blocks_air || T.blocks_air)
- R = TRUE
+ . = FALSE
if (T == src)
- return !R
+ return .
for(var/obj/O in contents+T.contents)
var/turf/other = (O.loc == src ? T : src)
if(!(vertical? (CANVERTICALATMOSPASS(O, other)) : (CANATMOSPASS(O, other))))
- R = TRUE
- if(O.BlockSuperconductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
- atmos_supeconductivity |= dir
- T.atmos_supeconductivity |= opp
- return FALSE //no need to keep going, we got all we asked
+ . = FALSE
- atmos_supeconductivity &= ~dir
- T.atmos_supeconductivity &= ~opp
+/turf/proc/update_conductivity(turf/T)
+ var/dir = get_dir_multiz(src, T)
+ var/opp = REVERSE_DIR(dir)
- return !R
+ if(T == src)
+ return
+
+ //all these must be above zero for auxmos to even consider them
+ if(!thermal_conductivity || !heat_capacity || !T.thermal_conductivity || !T.heat_capacity)
+ conductivity_blocked_directions |= dir
+ T.conductivity_blocked_directions |= opp
+ return
+
+ for(var/obj/O in contents+T.contents)
+ if(O.BlockThermalConductivity(opp)) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
+ conductivity_blocked_directions |= dir
+ T.conductivity_blocked_directions |= opp
+
+/turf/proc/block_all_conductivity()
+ conductivity_blocked_directions |= NORTH | SOUTH | EAST | WEST | UP | DOWN
-/atom/movable/proc/BlockSuperconductivity() // objects that block air and don't let superconductivity act. Only firelocks atm.
+//dir of this obj to the other turf
+/atom/movable/proc/BlockThermalConductivity(dir) // Objects that don't let heat through.
return FALSE
/turf/proc/ImmediateCalculateAdjacentTurfs()
- var/canpass = CANATMOSPASS(src, src)
+ var/canpass = CANATMOSPASS(src, src)
var/canvpass = CANVERTICALATMOSPASS(src, src)
+
+ conductivity_blocked_directions = 0
+
+ var/src_contains_firelock = 1
+ if(locate(/obj/machinery/door/firedoor) in src)
+ src_contains_firelock |= 2
+
for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction)
- var/opp_dir = dir_inverse_multiz(direction)
- if(!isopenturf(T))
+ if(!istype(T))
+ conductivity_blocked_directions |= direction
continue
- if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
+
+ var/other_contains_firelock = 1
+ if(locate(/obj/machinery/door/firedoor) in T)
+ other_contains_firelock |= 2
+
+ update_conductivity(T)
+
+ if(isopenturf(T) && !(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs)
- atmos_adjacent_turfs[T] = direction
- T.atmos_adjacent_turfs[src] = opp_dir
- T.__update_extools_adjacent_turfs()
+ atmos_adjacent_turfs[T] = other_contains_firelock | src_contains_firelock
+ T.atmos_adjacent_turfs[src] = src_contains_firelock
else
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= T
if (T.atmos_adjacent_turfs)
T.atmos_adjacent_turfs -= src
- T.__update_extools_adjacent_turfs()
UNSETEMPTY(T.atmos_adjacent_turfs)
+
+ T.__update_auxtools_turf_adjacency_info()
UNSETEMPTY(atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs
- __update_extools_adjacent_turfs()
+ __update_auxtools_turf_adjacency_info()
-/turf/proc/__update_extools_adjacent_turfs()
+/turf/proc/clear_adjacencies()
+ block_all_conductivity()
+ for(var/direction in GLOB.cardinals_multiz)
+ var/turf/T = get_step_multiz(src, direction)
+ if(!T)
+ continue
+ if (atmos_adjacent_turfs)
+ atmos_adjacent_turfs -= T
+ if (T.atmos_adjacent_turfs)
+ T.atmos_adjacent_turfs -= src
+ UNSETEMPTY(T.atmos_adjacent_turfs)
+ T.__update_auxtools_turf_adjacency_info()
+ LAZYNULL(atmos_adjacent_turfs)
+ __update_auxtools_turf_adjacency_info()
+
+
+//Only gets a list of adjacencies, does NOT update
+/turf/proc/get_adjacent_atmos_turfs()
+ . = list()
+ var/canpass = CANATMOSPASS(src, src)
+ var/canvpass = CANVERTICALATMOSPASS(src, src)
+
+ for(var/direction in GLOB.cardinals_multiz)
+ var/turf/T = get_step_multiz(src, direction)
+ if(isopenturf(T) && !(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
+ .[T] = 0
+ else
+ . -= T
+ UNSETEMPTY(.)
//returns a list of adjacent turfs that can share air with this one.
//alldir includes adjacent diagonal tiles that can share
@@ -106,21 +160,19 @@
return adjacent_turfs
-/atom/proc/air_update_turf(command = 0)
- if(!isturf(loc) && command)
+/atom/proc/air_update_turf()
+ var/turf/T = get_turf(src)
+ if(!T)
return
- var/turf/T = get_turf(loc)
- T.air_update_turf(command)
+ T.air_update_turf()
-/turf/air_update_turf(command = 0)
- if(command)
- ImmediateCalculateAdjacentTurfs()
- SSair.add_to_active(src,command)
+/turf/air_update_turf()
+ ImmediateCalculateAdjacentTurfs()
/atom/movable/proc/move_update_air(turf/T)
if(isturf(T))
- T.air_update_turf(1)
- air_update_turf(1)
+ T.air_update_turf()
+ air_update_turf()
/atom/proc/atmos_spawn_air(text) //because a lot of people loves to copy paste awful code lets just make an easy proc to spawn your plasma fires
var/turf/open/T = get_turf(src)
@@ -134,7 +186,4 @@
var/datum/gas_mixture/G = new
G.parse_gas_string(text)
-
- air.merge(G)
- archive()
- SSair.add_to_active(src, 0)
+ assume_air(G)
diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
index ab5068eb1373..af36d33d22d4 100644
--- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
+++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm
@@ -1,18 +1,12 @@
/turf
- //used for temperature calculations
+ //conductivity is divided by 10 when interacting with air for balance purposes
var/thermal_conductivity = 0.05
var/heat_capacity = 1
- var/temperature_archived
//list of open turfs adjacent to us
var/list/atmos_adjacent_turfs
- //bitfield of dirs in which we are superconducitng
- var/atmos_supeconductivity = NONE
- var/is_openturf = FALSE // used by extools shizz.
-
- //used to determine whether we should archive
- var/archived_cycle = 0
- var/current_cycle = 0
+ ///bitfield of dirs in which we thermal conductivity is blocked
+ var/conductivity_blocked_directions = NONE
//used for mapping and for breathing while in walls (because that's a thing that needs to be accounted for...)
//string parsed by /datum/gas/proc/copy_from_turf
@@ -32,13 +26,15 @@
var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time
var/list/atmos_overlay_types //gas IDs of current active gas overlays
- is_openturf = TRUE
+
+/turf/proc/should_conduct_to_space()
+ return get_z_base_turf() == /turf/open/space
/turf/open/Initialize(mapload)
if(!blocks_air)
- air = new
+ air = new(2500,src)
air.copy_from_turf(src)
- update_air_ref()
+ update_air_ref(planetary_atmos ? 1 : 2)
if(wet)
AddComponent(/datum/component/wet_floor, wet, INFINITY, 0, INFINITY, TRUE)
return ..()
@@ -46,26 +42,45 @@
/turf/open/Destroy()
if(active_hotspot)
QDEL_NULL(active_hotspot)
- // Adds the adjacent turfs to the current atmos processing
- for(var/T in atmos_adjacent_turfs)
- SSair.add_to_active(T)
return ..()
-/turf/proc/update_air_ref()
-
/////////////////GAS MIXTURE PROCS///////////////////
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
+ return assume_air_ratio(giver, 1)
+
+/turf/open/assume_air_moles(datum/gas_mixture/giver, moles)
+ if(!giver)
+ return FALSE
+ giver.transfer_to(air, moles)
+ return TRUE
+
+/turf/open/assume_air_ratio(datum/gas_mixture/giver, ratio)
if(!giver)
return FALSE
- air.merge(giver)
- update_visuals()
+ giver.transfer_ratio_to(air, ratio)
+ return TRUE
+
+/turf/open/transfer_air(datum/gas_mixture/taker, moles)
+ if(!taker || !return_air()) // shouldn't transfer from space
+ return FALSE
+ air.transfer_to(taker, moles)
+ return TRUE
+
+/turf/open/transfer_air_ratio(datum/gas_mixture/taker, ratio)
+ if(!taker || !return_air())
+ return FALSE
+ air.transfer_ratio_to(taker, ratio)
return TRUE
/turf/open/remove_air(amount)
var/datum/gas_mixture/ours = return_air()
var/datum/gas_mixture/removed = ours.remove(amount)
- update_visuals()
+ return removed
+
+/turf/open/remove_air_ratio(ratio)
+ var/datum/gas_mixture/ours = return_air()
+ var/datum/gas_mixture/removed = ours.remove_ratio(ratio)
return removed
/turf/open/proc/copy_air_with_tile(turf/open/T)
@@ -90,16 +105,9 @@
return return_air()
/turf/temperature_expose()
- if(temperature > heat_capacity)
+ if(return_temperature() > heat_capacity)
to_be_destroyed = TRUE
-/turf/proc/archive()
- temperature_archived = temperature
-
-/turf/open/archive()
- air.archive()
- archived_cycle = SSair.times_fired
- temperature_archived = temperature
/turf/open/proc/eg_reset_cooldowns()
/turf/open/proc/eg_garbage_collect()
@@ -122,12 +130,12 @@
src.atmos_overlay_types = null
return
+
for(var/id in air.get_gases())
- if(nonoverlaying_gases[id])
+ if (nonoverlaying_gases[id])
continue
- var/gas_meta = GLOB.meta_gas_info[id]
- var/gas_overlay = gas_meta[META_GAS_OVERLAY]
- if(gas_overlay && air.get_moles(id) > gas_meta[META_GAS_MOLES_VISIBLE])
+ var/gas_overlay = GLOB.gas_data.overlays[id]
+ if(gas_overlay && air.get_moles(id) > GLOB.gas_data.visibility[id])
new_overlay_types += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(air.get_moles(id) / MOLES_GAS_VISIBLE_STEP, 1))]
if (atmos_overlay_types)
@@ -143,6 +151,7 @@
UNSETEMPTY(new_overlay_types)
src.atmos_overlay_types = new_overlay_types
+//called by auxmos, do not remove
/turf/open/proc/set_visuals(list/new_overlay_types)
if (atmos_overlay_types)
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
@@ -161,49 +170,40 @@
for (var/gastype in subtypesof(/datum/gas))
var/datum/gas/gasvar = gastype
if (!initial(gasvar.gas_overlay))
- .[gastype] = TRUE
+ .[initial(gasvar.id)] = TRUE
/////////////////////////////SIMULATION///////////////////////////////////
-/*#define LAST_SHARE_CHECK \
- var/last_share = our_air.get_last_share();\
- if(last_share > MINIMUM_AIR_TO_SUSPEND){\
- our_excited_group.reset_cooldowns();\
- cached_atmos_cooldown = 0;\
- } else if(last_share > MINIMUM_MOLES_DELTA_TO_MOVE) {\
- our_excited_group.dismantle_cooldown = 0;\
- cached_atmos_cooldown = 0;\
- }
-*/
/turf/proc/process_cell(fire_count)
- SSair.remove_from_active(src)
/turf/open/proc/equalize_pressure_in_zone(cyclenum)
/turf/open/proc/consider_firelocks(turf/T2)
- var/reconsider_adj = FALSE
for(var/obj/machinery/door/firedoor/FD in T2)
- if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, src) != FD.dir)
- continue
FD.emergency_pressure_stop()
- reconsider_adj = TRUE
for(var/obj/machinery/door/firedoor/FD in src)
- if((FD.flags_1 & ON_BORDER_1) && get_dir(src, T2) != FD.dir)
- continue
FD.emergency_pressure_stop()
- reconsider_adj = TRUE
- if(reconsider_adj)
- T2.ImmediateCalculateAdjacentTurfs() // We want those firelocks closed yesterday.
/turf/proc/handle_decompression_floor_rip()
/turf/open/floor/handle_decompression_floor_rip(sum)
- if(sum > 20 && prob(clamp(sum / 10, 0, 30)))
- remove_tile()
+ if(sum > 20 && prob(clamp(sum / 20, 0, 15)))
+ if(floor_tile)
+ new floor_tile(src)
+ make_plating()
+
+/turf/open/floor/plating/handle_decompression_floor_rip()
+ return
+
+/turf/open/floor/engine/handle_decompression_floor_rip()
+ return
/turf/open/process_cell(fire_count)
//////////////////////////SPACEWIND/////////////////////////////
-/turf/open/proc/consider_pressure_difference(turf/T, difference)
+/turf/proc/consider_pressure_difference()
+ return
+
+/turf/open/consider_pressure_difference(turf/T, difference)
SSair.high_pressure_delta |= src
if(difference > pressure_difference)
pressure_direction = get_dir(src, T)
@@ -227,7 +227,7 @@
/atom/movable/var/last_high_pressure_movement_air_cycle = 0
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0, throw_target)
- var/const/PROBABILITY_OFFSET = 25
+ var/const/PROBABILITY_OFFSET = 40
var/const/PROBABILITY_BASE_PRECENT = 10
var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5)
set waitfor = 0
@@ -237,124 +237,13 @@
move_prob += pressure_resistance_prob_delta
if (move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO))))
var/move_force = max_force * clamp(move_prob, 0, 100) / 100
- if(move_force > 4000)
+ if(move_force > 6000)
// WALLSLAM HELL TIME OH BOY
var/turf/throw_turf = get_ranged_target_turf(get_turf(src), direction, round(move_force / 2000))
if(throw_target && (get_dir(src, throw_target) & direction))
throw_turf = get_turf(throw_target)
- var/throw_speed = clamp(round(move_force / 2000), 1, 10)
- if(iscarbon(src))
- throw_speed = min(throw_speed, 4)
- throw_at(throw_turf, move_force / 2000, throw_speed)
+ var/throw_speed = clamp(round(move_force / 3000), 1, 10)
+ throw_at(throw_turf, move_force / 3000, throw_speed, quickstart = FALSE)
else
step(src, direction)
last_high_pressure_movement_air_cycle = SSair.times_fired
-
-////////////////////////SUPERCONDUCTIVITY/////////////////////////////
-/turf/proc/conductivity_directions()
- if(archived_cycle < SSair.times_fired)
- archive()
- return NORTH|SOUTH|EAST|WEST
-
-/turf/open/conductivity_directions()
- if(blocks_air)
- return ..()
- for(var/direction in GLOB.cardinals)
- var/turf/T = get_step(src, direction)
- if(!(T in atmos_adjacent_turfs) && !(atmos_supeconductivity & direction))
- . |= direction
-
-/turf/proc/neighbor_conduct_with_src(turf/open/other)
- if(!other.blocks_air) //Open but neighbor is solid
- other.temperature_share_open_to_solid(src)
- else //Both tiles are solid
- other.share_temperature_mutual_solid(src, thermal_conductivity)
- temperature_expose(null, temperature, null)
-
-/turf/open/neighbor_conduct_with_src(turf/other)
- if(blocks_air)
- ..()
- return
-
- if(!other.blocks_air) //Both tiles are open
- var/turf/open/T = other
- T.air.temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
- else //Solid but neighbor is open
- temperature_share_open_to_solid(other)
- SSair.add_to_active(src, 0)
-
-/turf/proc/super_conduct()
- var/conductivity_directions = conductivity_directions()
-
- if(conductivity_directions)
- //Conduct with tiles around me
- for(var/direction in GLOB.cardinals)
- if(conductivity_directions & direction)
- var/turf/neighbor = get_step(src,direction)
-
- if(!neighbor.thermal_conductivity)
- continue
-
- if(neighbor.archived_cycle < SSair.times_fired)
- neighbor.archive()
-
- neighbor.neighbor_conduct_with_src(src)
-
- neighbor.consider_superconductivity()
-
- radiate_to_spess()
-
- finish_superconduction()
-
-/turf/proc/finish_superconduction(temp = temperature)
- //Make sure still hot enough to continue conducting heat
- if(temp < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
- SSair.active_super_conductivity -= src
- return FALSE
-
-/turf/open/finish_superconduction()
- //Conduct with air on my tile if I have it
- if(!blocks_air)
- temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity)
- ..((blocks_air ? temperature : air.return_temperature()))
-
-/turf/proc/consider_superconductivity()
- if(!thermal_conductivity)
- return FALSE
-
- SSair.active_super_conductivity |= src
- return TRUE
-
-/turf/open/consider_superconductivity(starting)
- if(air.return_temperature() < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
- return FALSE
- if(air.heat_capacity() < M_CELL_WITH_RATIO) // Was: MOLES_CELLSTANDARD*0.1*0.05 Since there are no variables here we can make this a constant.
- return FALSE
- return ..()
-
-/turf/closed/consider_superconductivity(starting)
- if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
- return FALSE
- return ..()
-
-/turf/proc/radiate_to_spess() //Radiate excess tile heat to space
- if(temperature > T0C) //Considering 0 degC as te break even point for radiation in and out
- var/delta_temperature = (temperature_archived - TCMB) //hardcoded space temperature
- if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
-
- var/heat = thermal_conductivity*delta_temperature* \
- (heat_capacity*HEAT_CAPACITY_VACUUM/(heat_capacity+HEAT_CAPACITY_VACUUM))
- temperature -= heat/heat_capacity
-
-/turf/open/proc/temperature_share_open_to_solid(turf/sharer)
- sharer.temperature = air.temperature_share(null, sharer.thermal_conductivity, sharer.temperature, sharer.heat_capacity)
-
-/turf/proc/share_temperature_mutual_solid(turf/sharer, conduction_coefficient) //to be understood
- var/delta_temperature = (temperature_archived - sharer.temperature_archived)
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
-
- var/heat = conduction_coefficient*delta_temperature* \
- (heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
-
- temperature -= heat/heat_capacity
- sharer.temperature += heat/sharer.heat_capacity
diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm
new file mode 100644
index 000000000000..60bf7896c0af
--- /dev/null
+++ b/code/modules/atmospherics/gasmixtures/auxgm.dm
@@ -0,0 +1,146 @@
+///the main four gases, which were at one time hardcoded
+GLOBAL_LIST_INIT(hardcoded_gases, list(
+ GAS_O2,
+ GAS_N2,
+ GAS_CO2,
+ GAS_PLASMA,
+))
+///Gasses that are unable to react amongst themselves
+GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(
+ list(
+ GAS_O2,
+ GAS_N2,
+ GAS_CO2,
+ GAS_PLUOXIUM,
+ ),
+))
+
+// Auxgm
+// It's a send-up of XGM, like what baystation got.
+// It's got the same architecture as XGM, but it's structured
+// differently to make it more convenient for auxmos.
+
+// Most important compared to TG is that it does away with hardcoded typepaths,
+// which lead to problems on the auxmos end anyway. We cache the string value
+// references on the Rust end, so no performance is lost here.
+
+// Also allows you to add new gases at runtime
+
+/datum/auxgm
+ var/list/datums = list()
+ var/list/specific_heats = list()
+ var/list/names = list()
+ var/list/labels = list()
+ var/list/visibility = list()
+ var/list/overlays = list()
+ var/list/flags = list()
+ var/list/ids = list()
+ var/list/typepaths = list()
+ var/list/fusion_powers = list()
+ var/list/breathing_classes = list()
+ var/list/breath_results = list()
+ var/list/breath_reagents = list()
+ var/list/breath_reagents_dangerous = list()
+ var/list/breath_alert_info = list()
+ var/list/oxidation_temperatures = list()
+ var/list/oxidation_rates = list()
+ var/list/fire_temperatures = list()
+ var/list/enthalpies = list()
+ var/list/fire_products = list()
+ var/list/fire_burn_rates = list()
+ var/list/ui_colors = list()
+
+/datum/gas
+ var/id = ""
+ var/specific_heat = 0
+ var/name = ""
+ var/label = "" //shortened name
+ var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi
+ var/moles_visible = null
+ var/flags = NONE //currently used by canisters
+ var/fusion_power = 0 // How much the gas destabilizes a fusion reaction
+ var/breath_results = GAS_CO2 // what breathing this breathes out
+ var/breath_reagent = null // what breathing this adds to your reagents
+ var/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold
+ var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something
+ var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none
+ var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material
+ var/fire_temperature = null // temperature above which gas may catch fire; null for none
+ var/list/fire_products = null // what results when this gas is burned (oxidizer or fuel); null for none
+ var/enthalpy = 0 // Standard enthalpy of formation in joules, used for fires
+ var/fire_burn_rate = 1 // how many moles are burned per product released
+ var/fire_radiation_released = 0 // How much radiation is released when this gas burns
+ var/ui_color = "white"
+
+/datum/gas/proc/breath(partial_pressure, light_threshold, heavy_threshold, moles, mob/living/carbon/C, obj/item/organ/lungs/lungs)
+ // This is only called on gases with the GAS_FLAG_BREATH_PROC flag. When possible, do NOT use this--
+ // greatly prefer just adding a reagent. This is mostly around for legacy reasons.
+ return null
+
+/datum/auxgm/proc/add_gas(datum/gas/gas)
+ var/g = gas.id
+ if(g)
+ datums[g] = gas
+ specific_heats[g] = gas.specific_heat
+ names[g] = gas.name
+ if(!gas.label)
+ gas.label = gas.name
+ labels[g] = gas.label
+ if(gas.moles_visible)
+ visibility[g] = gas.moles_visible
+ overlays[g] = new /list(FACTOR_GAS_VISIBLE_MAX)
+ for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX)
+ overlays[g][i] = new /obj/effect/overlay/gas(gas.gas_overlay, i * 255 / FACTOR_GAS_VISIBLE_MAX)
+ else
+ visibility[g] = 0
+ overlays[g] = 0
+ flags[g] = gas.flags
+ ids[g] = g
+ typepaths[g] = gas.type
+ fusion_powers[g] = gas.fusion_power
+ ui_colors[g] = gas.ui_color
+
+ if(gas.breath_alert_info)
+ breath_alert_info[g] = gas.breath_alert_info
+ breath_results[g] = gas.breath_results
+ if(gas.breath_reagent)
+ breath_reagents[g] = gas.breath_reagent
+ if(gas.breath_reagent_dangerous)
+ breath_reagents_dangerous[g] = gas.breath_reagent_dangerous
+ if(gas.oxidation_temperature)
+ oxidation_temperatures[g] = gas.oxidation_temperature
+ oxidation_rates[g] = gas.oxidation_rate
+ if(gas.fire_products)
+ fire_products[g] = gas.fire_products
+ enthalpies[g] = gas.enthalpy
+ else if(gas.fire_temperature)
+ fire_temperatures[g] = gas.fire_temperature
+ fire_burn_rates[g] = gas.fire_burn_rate
+ if(gas.fire_products)
+ fire_products[g] = gas.fire_products
+ enthalpies[g] = gas.enthalpy
+ _auxtools_register_gas(gas)
+
+/datum/auxgm/New()
+ for(var/gas_path in subtypesof(/datum/gas))
+ var/datum/gas/gas = new gas_path
+ add_gas(gas)
+ for(var/breathing_class_path in subtypesof(/datum/breathing_class))
+ var/datum/breathing_class/class = new breathing_class_path
+ breathing_classes[breathing_class_path] = class
+ finalize_gas_refs()
+
+GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new)
+
+/obj/effect/overlay/gas
+ icon = 'icons/effects/atmospherics.dmi'
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ anchored = TRUE // should only appear in vis_contents, but to be safe
+ layer = FLY_LAYER
+ appearance_flags = TILE_BOUND
+ vis_flags = NONE
+
+/obj/effect/overlay/gas/New(state, alph)
+ . = ..()
+ icon_state = state
+ alpha = alph
diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
index 991907fbd814..e3d56b5e471c 100644
--- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm
+++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
@@ -21,44 +21,105 @@ What are the archived variables for?
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
-GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
-GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
-
-/proc/init_gaslist_cache()
- . = list()
- for(var/id in GLOB.meta_gas_info)
- var/list/cached_gas = new(3)
-
- .[id] = cached_gas
-
- cached_gas[MOLES] = 0
- cached_gas[ARCHIVE] = 0
- cached_gas[GAS_META] = GLOB.meta_gas_info[id]
/datum/gas_mixture
+ /// Never ever set this variable, hooked into vv_get_var for view variables viewing.
+ var/gas_list_view_only
var/initial_volume = CELL_VOLUME //liters
var/list/reaction_results
var/list/analyzer_results //used for analyzer feedback - not initialized until its used
- var/_extools_pointer_gasmixture = 0 // Contains the memory address of the shared_ptr object for this gas mixture in c++ land. Don't. Touch. This. Var.
+ var/_extools_pointer_gasmixture // Contains the index in the gas vector for this gas mixture in rust land. Don't. Touch. This. Var.
+
+GLOBAL_VAR_INIT(auxtools_atmos_initialized, FALSE)
/datum/gas_mixture/New(volume)
if (!isnull(volume))
initial_volume = volume
- ATMOS_EXTOOLS_CHECK
+ if(!GLOB.auxtools_atmos_initialized && auxtools_atmos_init(GLOB.gas_data))
+ GLOB.auxtools_atmos_initialized = TRUE
__gasmixture_register()
reaction_results = new
+/datum/gas_mixture/Del()
+ __gasmixture_unregister()
+ . = ..()
+
/datum/gas_mixture/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, _extools_pointer_gasmixture))
return FALSE // please no. segfaults bad.
+ if(var_name == "gas_list_view_only")
+ return FALSE
return ..()
-/*
-/datum/gas_mixture/Del()
- __gasmixture_unregister()
- . = ..()*/
-/datum/gas_mixture/proc/__gasmixture_unregister()
-/datum/gas_mixture/proc/__gasmixture_register()
+/datum/gas_mixture/vv_get_var(var_name)
+ . = ..()
+ if(var_name == "gas_list_view_only")
+ var/list/dummy = get_gases()
+ for(var/gas in dummy)
+ dummy[gas] = get_moles(gas)
+ dummy["CAP [gas]"] = partial_heat_capacity(gas)
+ dummy["TEMP"] = return_temperature()
+ dummy["PRESSURE"] = return_pressure()
+ dummy["HEAT CAPACITY"] = heat_capacity()
+ dummy["TOTAL MOLES"] = total_moles()
+ dummy["VOLUME"] = return_volume()
+ dummy["THERMAL ENERGY"] = thermal_energy()
+ return debug_variable("gases (READ ONLY)", dummy, 0, src)
+
+/datum/gas_mixture/vv_get_dropdown()
+ . = ..()
+ VV_DROPDOWN_OPTION("", "---")
+ VV_DROPDOWN_OPTION(VV_HK_PARSE_GASSTRING, "Parse Gas String")
+ VV_DROPDOWN_OPTION(VV_HK_EMPTY, "Empty")
+ VV_DROPDOWN_OPTION(VV_HK_SET_MOLES, "Set Moles")
+ VV_DROPDOWN_OPTION(VV_HK_SET_TEMPERATURE, "Set Temperature")
+ VV_DROPDOWN_OPTION(VV_HK_SET_VOLUME, "Set Volume")
+
+/datum/gas_mixture/vv_do_topic(list/href_list)
+ . = ..()
+ if(!.)
+ return
+ if(href_list[VV_HK_PARSE_GASSTRING])
+ var/gasstring = input(usr, "Input Gas String (WARNING: Advanced. Don't use this unless you know how these work.", "Gas String Parse") as text|null
+ if(!istext(gasstring))
+ return
+ log_admin("[key_name(usr)] modified gas mixture [REF(src)]: Set to gas string [gasstring].")
+ message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Set to gas string [gasstring].")
+ parse_gas_string(gasstring)
+ if(href_list[VV_HK_EMPTY])
+ log_admin("[key_name(usr)] emptied gas mixture [REF(src)].")
+ message_admins("[key_name(usr)] emptied gas mixture [REF(src)].")
+ clear()
+ if(href_list[VV_HK_SET_MOLES])
+ var/list/gases = get_gases()
+ for(var/gas in gases)
+ gases[gas] = get_moles(gas)
+ var/gasid = input(usr, "What kind of gas?", "Set Gas") as null|anything in GLOB.gas_data.ids
+ if(!gasid)
+ return
+ var/amount = input(usr, "Input amount", "Set Gas", gases[gasid] || 0) as num|null
+ if(!isnum(amount))
+ return
+ amount = max(0, amount)
+ log_admin("[key_name(usr)] modified gas mixture [REF(src)]: Set gas [gasid] to [amount] moles.")
+ message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Set gas [gasid] to [amount] moles.")
+ set_moles(gasid, amount)
+ if(href_list[VV_HK_SET_TEMPERATURE])
+ var/temp = input(usr, "Set the temperature of this mixture to?", "Set Temperature", return_temperature()) as num|null
+ if(!isnum(temp))
+ return
+ temp = max(2.7, temp)
+ log_admin("[key_name(usr)] modified gas mixture [REF(src)]: Changed temperature to [temp].")
+ message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Changed temperature to [temp].")
+ set_temperature(temp)
+ if(href_list[VV_HK_SET_VOLUME])
+ var/volume = input(usr, "Set the volume of this mixture to?", "Set Volume", return_volume()) as num|null
+ if(!isnum(volume))
+ return
+ volume = max(0, volume)
+ log_admin("[key_name(usr)] modified gas mixture [REF(src)]: Changed volume to [volume].")
+ message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Changed volume to [volume].")
+ set_volume(volume)
/proc/gas_types()
var/list/L = subtypesof(/datum/gas)
@@ -67,50 +128,20 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
L[gt] = initial(G.specific_heat)
return L
-/datum/gas_mixture/proc/heat_capacity(data = MOLES) //joules per kelvin
-
-/datum/gas_mixture/proc/total_moles()
-
-/datum/gas_mixture/proc/return_pressure() //kilopascals
-
-/datum/gas_mixture/proc/return_temperature() //kelvins
-
-/datum/gas_mixture/proc/set_min_heat_capacity(n)
-/datum/gas_mixture/proc/set_temperature(new_temp)
-/datum/gas_mixture/proc/set_volume(new_volume)
-/datum/gas_mixture/proc/get_moles(gas_type)
-/datum/gas_mixture/proc/set_moles(gas_type, moles)
-/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, list/gases)
-/datum/gas_mixture/proc/mark_immutable()
-/datum/gas_mixture/proc/get_gases()
-/datum/gas_mixture/proc/multiply(factor)
/datum/gas_mixture/proc/get_last_share()
-/datum/gas_mixture/proc/clear()
-
-/datum/gas_mixture/proc/adjust_moles(gas_type, amt = 0)
- if((get_moles(gas_type) + amt) < 0)
- amt = 0
- set_moles(gas_type, get_moles(gas_type) + amt)
-
-/datum/gas_mixture/proc/return_volume() //liters
-
-/datum/gas_mixture/proc/thermal_energy() //joules
/datum/gas_mixture/proc/archive()
//Update archived versions of variables
//Returns: 1 in all cases
-/datum/gas_mixture/proc/merge(datum/gas_mixture/giver)
- //Merges all air from giver into self. giver is untouched.
- //Returns: 1 if we are mutable, 0 otherwise
/datum/gas_mixture/proc/remove(amount)
- //Removes amount of gas from the gas_mixture
+ //Proportionally removes amount of gas from the gas_mixture
//Returns: gas_mixture with the gases removed
-/datum/gas_mixture/proc/transfer_to(datum/gas_mixture/target, amount)
- //Transfers amount of gas to target. Equivalent to target.merge(remove(amount)) but faster.
- //Removes amount of gas from the gas_mixture
+/datum/gas_mixture/proc/remove_by_flag(flag, amount)
+ //Removes amount of gas from the gas mixture by flag
+ //Returns: gas_mixture with gases that match the flag removed
/datum/gas_mixture/proc/remove_ratio(ratio)
//Proportionally removes amount of gas from the gas_mixture
@@ -120,10 +151,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//Creates new, identical gas mixture
//Returns: duplicate gas mixture
-/datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample)
- //Copies variables from sample
- //Returns: 1 if we are mutable, 0 otherwise
-
/datum/gas_mixture/proc/copy_from_turf(turf/model)
//Copies all gas info from the turf into the gas list along with temperature
//Returns: 1 if we are mutable, 0 otherwise
@@ -136,27 +163,18 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//Performs air sharing calculations between two gas_mixtures assuming only 1 boundary length
//Returns: amount of gas exchanged (+ if sharer received)
-/datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
- //Performs temperature sharing calculations (via conduction) between two gas_mixtures assuming only 1 boundary length
- //Returns: new temperature of the sharer
-
-/datum/gas_mixture/proc/compare(datum/gas_mixture/sample)
- //Compares sample to self to see if within acceptable ranges that group processing may be enabled
- //Returns: a string indicating what check failed, or "" if check passes
-
-/datum/gas_mixture/proc/react(turf/open/dump_location)
- //Performs various reactions such as combustion or fusion (LOL)
- //Returns: 1 if any reaction took place; 0 otherwise
+/datum/gas_mixture/remove_by_flag(flag, amount)
+ var/datum/gas_mixture/removed = new type
+ __remove_by_flag(removed, flag, amount)
+ return removed
-/datum/gas_mixture/proc/__remove()
/datum/gas_mixture/remove(amount)
var/datum/gas_mixture/removed = new type
__remove(removed, amount)
return removed
-/datum/gas_mixture/proc/__remove_ratio()
/datum/gas_mixture/remove_ratio(ratio)
var/datum/gas_mixture/removed = new type
__remove_ratio(removed, ratio)
@@ -170,75 +188,30 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
return copy
/datum/gas_mixture/copy_from_turf(turf/model)
+ set_temperature(initial(model.initial_temperature))
parse_gas_string(model.initial_gas_mix)
-
- //acounts for changes in temperature
- var/turf/model_parent = model.parent_type
- if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature))
- set_temperature(model.temperature)
-
return 1
/datum/gas_mixture/parse_gas_string(gas_string)
+ __auxtools_parse_gas_string(gas_string)
+ /*
var/list/gas = params2list(gas_string)
if(gas["TEMP"])
- set_temperature(text2num(gas["TEMP"]))
+ var/temp = text2num(gas["TEMP"])
gas -= "TEMP"
+ if(!isnum(temp) || temp < 2.7)
+ temp = 2.7
+ set_temperature(temp)
clear()
for(var/id in gas)
- var/path = id
- if(!ispath(path))
- path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
- set_moles(path, text2num(gas[id]))
+ set_moles(id, text2num(gas[id]))
return 1
-
-/datum/gas_mixture/react(datum/holder)
- . = NO_REACTION
- var/list/reactions = list()
- for(var/I in get_gases())
- reactions += SSair.gas_reactions[I]
- if(!length(reactions))
- return
- if (length(reactions) > 1)
- reactions = sortTim(reactions, /proc/cmp_gas_reaction)
- reaction_results = new
- var/temp = return_temperature()
- var/ener = thermal_energy()
-
- reaction_loop:
- for(var/r in reactions)
- var/datum/gas_reaction/reaction = r
-
- var/list/min_reqs = reaction.min_requirements
- if( (min_reqs["TEMP"] && temp < min_reqs["TEMP"]) || \
- (min_reqs["ENER"] && ener < min_reqs["ENER"]) || \
- (min_reqs["MAX_TEMP"] && temp > min_reqs["MAX_TEMP"])
- )
- continue
-
- for(var/id in min_reqs)
- if (id == "TEMP" || id == "ENER" || id == "MAX_TEMP")
- continue
- if(get_moles(id) < min_reqs[id])
- continue reaction_loop
-
- //at this point, all requirements for the reaction are satisfied. we can now react()
-
- . |= reaction.react(src, holder)
- if (. & STOP_REACTIONS)
- break
-
-//Takes the amount of the gas you want to PP as an argument
-//So I don't have to do some hacky switches/defines/magic strings
-//eg:
-//Tox_PP = get_partial_pressure(gas_mixture.toxins)
-//O2_PP = get_partial_pressure(gas_mixture.oxygen)
-
-/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
- return (gas_pressure * R_IDEAL_GAS_EQUATION * return_temperature()) / BREATH_VOLUME
-//inverse
-/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
- return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * return_temperature())
+ */
+
+/datum/gas_mixture/proc/set_analyzer_results(instability)
+ if(!analyzer_results)
+ analyzer_results = new
+ analyzer_results["fusion"] = instability
//Mathematical proofs:
/*
@@ -251,59 +224,6 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
/datum/gas_mixture/turf
-/*
-/mob/verb/profile_atmos()
- /world{loop_checks = 0;}
- var/datum/gas_mixture/A = new
- var/datum/gas_mixture/B = new
- A.parse_gas_string("o2=200;n2=800;TEMP=50")
- B.parse_gas_string("co2=500;plasma=500;TEMP=5000")
- var/pa
- var/pb
- pa = world.tick_usage
- for(var/I in 1 to 100000)
- B.transfer_to(A, 1)
- A.transfer_to(B, 1)
- pb = world.tick_usage
- var/total_time = (pb-pa) * world.tick_lag
- to_chat(src, "Total time (gas transfer): [total_time]ms")
- to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
- pa = world.tick_usage
- for(var/I in 1 to 100000)
- B.total_moles();
- pb = world.tick_usage
- total_time = (pb-pa) * world.tick_lag
- to_chat(src, "Total time (total_moles): [total_time]ms")
- to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
- pa = world.tick_usage
- for(var/I in 1 to 100000)
- new /datum/gas_mixture
- pb = world.tick_usage
- total_time = (pb-pa) * world.tick_lag
- to_chat(src, "Total time (new gas mixture): [total_time]ms")
- to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
-*/
-
-
-/// Pumps gas from src to output_air. The amount depends on target_pressure
-/datum/gas_mixture/proc/pump_gas_to(datum/gas_mixture/output_air, target_pressure)
- var/output_starting_pressure = output_air.return_pressure()
-
- if((target_pressure - output_starting_pressure) < 0.01)
- //No need to pump gas if target is already reached!
- return FALSE
-
- //Calculate necessary moles to transfer using PV=nRT
- if((total_moles() > 0) && (return_temperature()>0))
- var/pressure_delta = target_pressure - output_starting_pressure
- var/transfer_moles = pressure_delta*output_air.return_volume()/(return_temperature() * R_IDEAL_GAS_EQUATION)
-
- //Actually transfer the gas
- var/datum/gas_mixture/removed = remove(transfer_moles)
- output_air.merge(removed)
- return TRUE
- return FALSE
-
/// Releases gas from src to output air. This means that it can not transfer air to gas mixture with higher pressure.
/datum/gas_mixture/proc/release_gas_to(datum/gas_mixture/output_air, target_pressure)
var/output_starting_pressure = output_air.return_pressure()
@@ -311,7 +231,7 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
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
+ //Need at least 10 kPa difference to overcome friction in the mechanism
return FALSE
//Calculate necessary moles to transfer using PV = nRT
@@ -324,10 +244,12 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
//Actually transfer the gas
var/datum/gas_mixture/removed = remove(transfer_moles)
output_air.merge(removed)
-
return TRUE
return FALSE
+/datum/gas_mixture/proc/vv_react(datum/holder)
+ return react(holder)
+
/datum/gas_mixture/proc/remove_specific_ratio(gas_id, ratio)
if(ratio <= 0)
return null
@@ -357,13 +279,16 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
/datum/gas_mixture/proc/equalize(datum/gas_mixture/other)
. = FALSE
+ if(!return_volume() || !other.return_volume())
+ return
+
var/self_temp = return_temperature()
var/other_temp = other.return_temperature()
if(abs(self_temp - other_temp) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
. = TRUE
var/self_heat_cap = heat_capacity()
var/other_heat_cap = other.heat_capacity()
- var/new_temp = (self_temp * self_heat_cap + other_temp * other_heat_cap) / (self_heat_cap + other_heat_cap)
+ var/new_temp = max((self_temp * self_heat_cap + other_temp * other_heat_cap) / (self_heat_cap + other_heat_cap), TCMB)
set_temperature(new_temp)
other.set_temperature(new_temp)
diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm
deleted file mode 100644
index 2a52acd9cfba..000000000000
--- a/code/modules/atmospherics/gasmixtures/gas_types.dm
+++ /dev/null
@@ -1,237 +0,0 @@
-GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded
-GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/pluoxium))) //unable to react amongst themselves
-
-/proc/meta_gas_list()
- . = subtypesof(/datum/gas)
- for(var/gas_path in .)
- var/list/gas_info = new(7)
- var/datum/gas/gas = gas_path
-
- gas_info[META_GAS_SPECIFIC_HEAT] = initial(gas.specific_heat)
- gas_info[META_GAS_NAME] = initial(gas.name)
-
- gas_info[META_GAS_MOLES_VISIBLE] = initial(gas.moles_visible)
- if(initial(gas.moles_visible) != null)
- gas_info[META_GAS_OVERLAY] = new /list(FACTOR_GAS_VISIBLE_MAX)
- for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX)
- gas_info[META_GAS_OVERLAY][i] = new /obj/effect/overlay/gas(initial(gas.gas_overlay), i * 255 / FACTOR_GAS_VISIBLE_MAX)
-
- gas_info[META_GAS_FUSION_POWER] = initial(gas.fusion_power)
- gas_info[META_GAS_DANGER] = initial(gas.dangerous)
- gas_info[META_GAS_ID] = initial(gas.id)
- .[gas_path] = gas_info
-
-/proc/gas_id2path(id)
- var/list/meta_gas = GLOB.meta_gas_info
- if(id in meta_gas)
- return id
- for(var/path in meta_gas)
- if(meta_gas[path][META_GAS_ID] == id)
- return path
- return ""
-
-/*||||||||||||||/----------\||||||||||||||*\
-||||||||||||||||[GAS DATUMS]||||||||||||||||
-||||||||||||||||\__________/||||||||||||||||
-||||These should never be instantiated. ||||
-||||They exist only to make it easier ||||
-||||to add a new gas. They are accessed ||||
-||||only by meta_gas_list(). ||||
-\*||||||||||||||||||||||||||||||||||||||||*/
-
-/datum/gas
- var/id = ""
- var/specific_heat = 0
- var/name = ""
- /// icon_state in icons/effects/atmospherics.dmi
- var/gas_overlay = ""
- var/moles_visible = null
- /// Currently used by canisters
- var/dangerous = FALSE
- /// How much the gas accelerates a fusion reaction
- var/fusion_power = 0
- /// Relative rarity compared to other gases, used when setting up the reactions list.
- var/rarity = 0
-
-// If you add or remove gases, update TOTAL_NUM_GASES in the extools code to match!
-// (dont forget to count shizz in the yogstation folder)
-
-/datum/gas/oxygen
- id = "o2"
- specific_heat = 20
- name = "Oxygen"
- rarity = 900
-
-/datum/gas/nitrogen
- id = "n2"
- specific_heat = 20
- name = "Nitrogen"
- rarity = 1000
-
-/datum/gas/carbon_dioxide //what the fuck is this?
- id = "co2"
- specific_heat = 30
- name = "Carbon Dioxide"
- rarity = 700
-
-/datum/gas/plasma
- id = "plasma"
- specific_heat = 200
- name = "Plasma"
- gas_overlay = "plasma"
- moles_visible = MOLES_GAS_VISIBLE
- dangerous = TRUE
- rarity = 800
-
-/datum/gas/water_vapor
- id = "water_vapor"
- specific_heat = 40
- name = "Water Vapor"
- gas_overlay = "water_vapor"
- moles_visible = MOLES_GAS_VISIBLE
- fusion_power = 8
- rarity = 500
-
-/datum/gas/hypernoblium
- id = "nob"
- specific_heat = 2000
- name = "Hyper-noblium"
- gas_overlay = "freon"
- moles_visible = MOLES_GAS_VISIBLE
- dangerous = TRUE
- rarity = 50
-
-/datum/gas/nitrous_oxide
- id = "n2o"
- specific_heat = 40
- name = "Nitrous Oxide"
- gas_overlay = "nitrous_oxide"
- moles_visible = MOLES_GAS_VISIBLE * 2
- fusion_power = 10
- dangerous = TRUE
- rarity = 600
-
-/datum/gas/nitrium
- id = "nitrium"
- specific_heat = 10
- name = "Nitrium"
- fusion_power = 7
- gas_overlay = "nitrium"
- moles_visible = MOLES_GAS_VISIBLE
- dangerous = TRUE
- rarity = 1
-
-/datum/gas/tritium
- id = "tritium"
- specific_heat = 10
- name = "Tritium"
- gas_overlay = "tritium"
- moles_visible = MOLES_GAS_VISIBLE
- dangerous = TRUE
- fusion_power = 1
- rarity = 300
-
-/datum/gas/bz
- id = "bz"
- specific_heat = 20
- name = "BZ"
- dangerous = TRUE
- fusion_power = 8
- rarity = 400
-
-/datum/gas/pluoxium
- id = "pluox"
- specific_heat = 80
- name = "Pluoxium"
- fusion_power = -10
- rarity = 200
-
-/datum/gas/miasma
- id = "miasma"
- specific_heat = 20
- name = "Miasma"
- gas_overlay = "miasma"
- moles_visible = MOLES_GAS_VISIBLE * 60
- rarity = 250
-
-/datum/gas/freon
- id = "freon"
- specific_heat = 600
- name = "Freon"
- gas_overlay = "freon"
- moles_visible = MOLES_GAS_VISIBLE *30
- fusion_power = -5
- rarity = 10
-
-/datum/gas/hydrogen
- id = "hydrogen"
- specific_heat = 15
- name = "Hydrogen"
- dangerous = TRUE
- rarity = 700
-
-/datum/gas/healium
- id = "healium"
- specific_heat = 10
- name = "Healium"
- dangerous = TRUE
- gas_overlay = "healium"
- moles_visible = MOLES_GAS_VISIBLE
- rarity = 100
-
-/datum/gas/pluonium
- id = "pluonium"
- specific_heat = 30
- name = "Pluonium"
- dangerous = TRUE
- gas_overlay = "pluonium"
- moles_visible = MOLES_GAS_VISIBLE
- rarity = 100
-
-/datum/gas/halon
- id = "halon"
- specific_heat = 175
- name = "Halon"
- dangerous = TRUE
- gas_overlay = "halon"
- moles_visible = MOLES_GAS_VISIBLE
- rarity = 100
-
-/datum/gas/antinoblium
- id = "antinoblium"
- specific_heat = 1
- name = "Antinoblium"
- dangerous = TRUE
- gas_overlay = "antinoblium"
- moles_visible = MOLES_GAS_VISIBLE
- fusion_power = 20
- rarity = 1
-
-/datum/gas/zauker
- id = "zauker"
- specific_heat = 350
- name = "Zauker"
- dangerous = TRUE
- gas_overlay = "zauker"
- moles_visible = MOLES_GAS_VISIBLE
- rarity = 1
-/datum/gas/hexane
- id = "hexane"
- specific_heat = 5
- name = "Hexane"
- dangerous = TRUE
- gas_overlay = "hexane"
- moles_visible = MOLES_GAS_VISIBLE
- rarity = 100
-
-/obj/effect/overlay/gas
- icon = 'icons/effects/atmospherics.dmi'
- mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- anchored = TRUE // should only appear in vis_contents, but to be safe
- layer = FLY_LAYER
- appearance_flags = TILE_BOUND
-
-/obj/effect/overlay/gas/New(state, alph)
- . = ..()
- icon_state = state
- alpha = alph
diff --git a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm
index 2f1a10e2756a..7de056ed0261 100644
--- a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm
+++ b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm
@@ -25,4 +25,4 @@
initial_temperature = T20C
/datum/gas_mixture/immutable/cloner/populate()
- set_moles(/datum/gas/nitrogen, MOLES_O2STANDARD + MOLES_N2STANDARD)
+ set_moles(GAS_N2, MOLES_O2STANDARD + MOLES_N2STANDARD)
diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm
index efe099b4b64d..d97e5e504e98 100644
--- a/code/modules/atmospherics/gasmixtures/reactions.dm
+++ b/code/modules/atmospherics/gasmixtures/reactions.dm
@@ -1,71 +1,51 @@
//All defines used in reactions are located in ..\__DEFINES\reactions.dm
-/*priority so far, check this list to see what are the numbers used. Please use a different priority for each reaction(higher number are done first)
-miaster = -10 (this should always be under all other fires)
-freonfire = -5
-plasmafire = -4
-h2fire = -3
-tritfire = -2
-halon_o2removal = -1
-nitrous_decomp = 0
-water_vapor = 1
-fusion = 2
-nitrium_formation = 3
-bzformation = 4
-freonformation = 5
-stim_ball = 7
-zauker_decomp = 8
-healium_formation = 9
-pluonium_formation = 10
-zauker_formation = 11
-halon_formation = 12
-hexane_formation = 13
-pluonium_response = 14 - 16
-metalhydrogen = 17
-nobliumsuppression = 1000
-nobliumformation = 1001
-*/
+//priority so far, check this list to see what are the numbers used.
+//Please use a different priority for each reaction(higher number are done first)
+//or else auxmos will ignore the reaction
+//NOTE: ONLY INTEGERS ARE ALLOWED, EXPECT WEIRDNESS IF YOU DON'T FOLLOW THIS
+#define MIASTER -10
+#define FREONFIRE -5
+#define PLASMAFIRE -4
+#define H2FIRE -3
+#define TRITFIRE -2
+#define HALONO2REMOVAL -1
+#define NITROUSDECOMP 0
+#define WATERVAPOR 1
+#define FUSION 2
+#define COLDFUSION 3
+#define NITRIUMFORMATION 4
+#define BZFORMATION 5
+#define FREONFORMATION 6
+#define NITROBALL 7
+#define ZAUKERDECOMP 8
+#define HEALIUMFORMATION 9
+#define PLUONIUMFORMATION 10
+#define ZAUKERFORMATION 11
+#define HALONFORMATION 12
+#define HEXANEFORMATION 13
+#define PLUONIUMBZRESPONSE 14
+#define PLUONIUMTRITRESPONSE 15
+#define PLUONIUMH2RESPONSE 16
+#define METALHYDROGEN 17
+#define NOBLIUMSUPPRESSION 1000
+#define NOBLIUMFORMATION 1001
/proc/init_gas_reactions()
. = list()
- for(var/type in subtypesof(/datum/gas))
- .[type] = list()
for(var/r in subtypesof(/datum/gas_reaction))
var/datum/gas_reaction/reaction = r
if(initial(reaction.exclude))
continue
reaction = new r
- var/datum/gas/reaction_key
- for (var/req in reaction.min_requirements)
- if (ispath(req))
- var/datum/gas/req_gas = req
- if (!reaction_key || initial(reaction_key.rarity) > initial(req_gas.rarity))
- reaction_key = req_gas
- .[reaction_key] += list(reaction)
- sortTim(., /proc/cmp_gas_reactions, TRUE)
-
-/proc/cmp_gas_reactions(list/datum/gas_reaction/a, list/datum/gas_reaction/b) // compares lists of reactions by the maximum priority contained within the list
- if (!length(a) || !length(b))
- return length(b) - length(a)
- var/maxa
- var/maxb
- for (var/datum/gas_reaction/R in a)
- if (R.priority > maxa)
- maxa = R.priority
- for (var/datum/gas_reaction/R in b)
- if (R.priority > maxb)
- maxb = R.priority
- return maxb - maxa
-
-/proc/cmp_gas_reaction(datum/gas_reaction/a, datum/gas_reaction/b) // compares the priority of two gas reactions
- return b.priority - a.priority
+ . += reaction
/datum/gas_reaction
//regarding the requirements lists: the minimum or maximum requirements must be non-zero.
//when in doubt, use MINIMUM_MOLE_COUNT.
var/list/min_requirements
var/exclude = FALSE //do it this way to allow for addition/removal of reactions midmatch in the future
- var/priority = 100 //lower numbers are checked/react later than higher numbers. if two reactions have the same priority they may happen in either order
+ var/priority = -1000 //lower numbers are checked/react later than higher numbers. if two reactions have the same priority they may happen in either order
var/name = "reaction"
var/id = "r"
@@ -77,13 +57,23 @@ nobliumformation = 1001
/datum/gas_reaction/proc/react(datum/gas_mixture/air, atom/location)
return NO_REACTION
+//fires cannot use this proc, because you don't want fires in pipes to proc fire_act on random turfs above the pipe
+/proc/get_holder_turf(datum/holder)
+ var/turf/open/location
+ if(istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
+ var/datum/pipeline/pipenet = holder
+ location = get_turf(pick(pipenet.members))
+ else
+ location = get_turf(holder)
+ return location
+
/datum/gas_reaction/nobliumsuppression
- priority = 1000 //ensure all non-HN reactions are lower than this number.
+ priority = NOBLIUMSUPPRESSION //ensure all non-HN reactions are lower than this number.
name = "Hyper-Noblium Reaction Suppression"
id = "nobstop"
/datum/gas_reaction/nobliumsuppression/init_reqs()
- min_requirements = list(/datum/gas/hypernoblium = REACTION_OPPRESSION_THRESHOLD)
+ min_requirements = list(GAS_HYPERNOB = REACTION_OPPRESSION_THRESHOLD)
/datum/gas_reaction/nobliumsuppression/react()
return STOP_REACTIONS
@@ -95,13 +85,13 @@ nobliumformation = 1001
* Can frost things if the gas is cold enough.
*/
/datum/gas_reaction/water_vapor
- priority = 1
+ priority = WATERVAPOR
name = "Water Vapor"
id = "vapor"
/datum/gas_reaction/water_vapor/init_reqs()
min_requirements = list(
- /datum/gas/water_vapor = MOLES_GAS_VISIBLE,
+ GAS_H2O = MOLES_GAS_VISIBLE,
"MAX_TEMP" = WATER_VAPOR_CONDENSATION_POINT,
)
@@ -112,6 +102,7 @@ nobliumformation = 1001
var/turf/open/location = holder
var/consumed = 0
+
switch(air.return_temperature())
if(-INFINITY to WATER_VAPOR_DEPOSITION_POINT)
if(location?.freeze_turf())
@@ -121,25 +112,24 @@ nobliumformation = 1001
consumed = MOLES_GAS_VISIBLE
if(consumed)
- air.adjust_moles(/datum/gas/water_vapor, -consumed)
+ air.adjust_moles(GAS_H2O, -consumed)
. = REACTING
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
/datum/gas_reaction/tritfire
- priority = -2 //fire should ALWAYS be last, but tritium fires happen before plasma fires
+ priority = TRITFIRE //fire should ALWAYS be last, but tritium fires happen before plasma fires
name = "Tritium Combustion"
id = "tritfire"
/datum/gas_reaction/tritfire/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
- /datum/gas/tritium = MINIMUM_MOLE_COUNT,
- /datum/gas/oxygen = MINIMUM_MOLE_COUNT
+ GAS_TRITIUM = MINIMUM_MOLE_COUNT,
+ GAS_O2 = MINIMUM_MOLE_COUNT,
)
/datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
- var/old_heat_capacity = air.heat_capacity()
- var/temperature = air.return_temperature()
+ var/initial_thermal_energy = air.thermal_energy()
var/list/cached_results = air.reaction_results
cached_results["fire"] = 0
var/turf/open/location = null
@@ -150,13 +140,13 @@ nobliumformation = 1001
location = get_turf(pick(combustion_pipenet.members))
else
location = get_turf(holder)
- var/burned_fuel = min(air.get_moles(/datum/gas/tritium), air.get_moles(/datum/gas/oxygen)) / TRITIUM_BURN_TRIT_FACTOR
+ var/burned_fuel = min(air.get_moles(GAS_TRITIUM), air.get_moles(GAS_O2)) / TRITIUM_BURN_TRIT_FACTOR
if(burned_fuel <= 0)
return NO_REACTION
- air.adjust_moles(/datum/gas/tritium, -burned_fuel) // Yogs -- Maybe a tiny performance boost? I'unno
- air.adjust_moles(/datum/gas/oxygen, -burned_fuel / 2)
- air.adjust_moles(/datum/gas/water_vapor, burned_fuel)// Yogs -- Conservation of Mass
+ air.adjust_moles(GAS_TRITIUM, -burned_fuel) // Yogs -- Maybe a tiny performance boost? I'unno
+ air.adjust_moles(GAS_O2, -burned_fuel / 2)
+ air.adjust_moles(GAS_H2O, burned_fuel)// Yogs -- Conservation of Mass
var/energy_released = (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel * TRITIUM_BURN_TRIT_FACTOR) // Yogs -- Fixes low-energy tritium fires
if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
@@ -167,11 +157,11 @@ nobliumformation = 1001
if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity)
+ air.set_temperature((initial_thermal_energy + energy_released)/new_heat_capacity)
//let the floor know a fire is happening BUT ONLY IF IT'S ACTUALLY A FLOOR
if(istype(location) && isturf(holder))
- temperature = air.return_temperature()
+ var/temperature = air.return_temperature()
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location)
@@ -183,20 +173,20 @@ nobliumformation = 1001
//plasma combustion: combustion of oxygen and plasma (treated as hydrocarbons). creates hotspots. exothermic
/datum/gas_reaction/plasmafire
- priority = -4 //fire should ALWAYS be last, but plasma fires happen after tritium fires
+ priority = PLASMAFIRE //fire should ALWAYS be last, but plasma fires happen after tritium fires
name = "Plasma Combustion"
id = "plasmafire"
/datum/gas_reaction/plasmafire/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
- /datum/gas/plasma = MINIMUM_MOLE_COUNT,
- /datum/gas/oxygen = MINIMUM_MOLE_COUNT
+ GAS_PLASMA = MINIMUM_MOLE_COUNT,
+ GAS_O2 = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
- var/old_heat_capacity = air.heat_capacity()
+ var/old_thermal_energy = air.thermal_energy()
var/temperature = air.return_temperature()
var/list/cached_results = air.reaction_results
cached_results["fire"] = 0
@@ -210,27 +200,30 @@ nobliumformation = 1001
//to make tritium
var/super_saturation = FALSE
+ var/initial_o2 = air.get_moles(GAS_O2)
+ var/initial_plas = air.get_moles(GAS_PLASMA)
+
if(temperature > PLASMA_UPPER_TEMPERATURE)
temperature_scale = 1
else
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
- if(air.get_moles(/datum/gas/oxygen) / air.get_moles(/datum/gas/plasma) > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
+ if(initial_o2 / initial_plas > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
super_saturation = TRUE
- if(air.get_moles(/datum/gas/oxygen) > air.get_moles(/datum/gas/plasma)*PLASMA_OXYGEN_FULLBURN)
- plasma_burn_rate = (air.get_moles(/datum/gas/plasma)*temperature_scale)/PLASMA_BURN_RATE_DELTA
+ if(initial_o2 > initial_plas * PLASMA_OXYGEN_FULLBURN)
+ plasma_burn_rate = (initial_plas*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
- plasma_burn_rate = (temperature_scale*(air.get_moles(/datum/gas/oxygen)/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
+ plasma_burn_rate = (temperature_scale*(initial_o2/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
- plasma_burn_rate = min(plasma_burn_rate,air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/oxygen)/oxygen_burn_rate) //Ensures matter is conserved properly
- air.set_moles(/datum/gas/plasma, QUANTIZE(air.get_moles(/datum/gas/plasma) - plasma_burn_rate))
- air.set_moles(/datum/gas/oxygen, QUANTIZE(air.get_moles(/datum/gas/oxygen) - (plasma_burn_rate * oxygen_burn_rate)))
+ plasma_burn_rate = min(plasma_burn_rate,initial_plas,initial_o2/oxygen_burn_rate) //Ensures matter is conserved properly
+ air.adjust_moles(GAS_PLASMA, -plasma_burn_rate)
+ air.adjust_moles(GAS_O2, -(plasma_burn_rate * oxygen_burn_rate))
if (super_saturation)
- air.adjust_moles(/datum/gas/tritium, plasma_burn_rate)
+ air.adjust_moles(GAS_TRITIUM, plasma_burn_rate)
else
- air.adjust_moles(/datum/gas/carbon_dioxide, plasma_burn_rate)
+ air.adjust_moles(GAS_CO2, plasma_burn_rate)
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
@@ -239,7 +232,7 @@ nobliumformation = 1001
if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity)
+ air.set_temperature((old_thermal_energy + energy_released)/new_heat_capacity)
//let the floor know a fire is happening
if(istype(location))
@@ -254,26 +247,26 @@ nobliumformation = 1001
return cached_results["fire"] ? REACTING : NO_REACTION
/datum/gas_reaction/n2odecomp
- priority = 0
+ priority = NITROUSDECOMP
name = "Nitrous Oxide Decomposition"
id = "n2odecomp"
/datum/gas_reaction/n2odecomp/init_reqs()
min_requirements = list(
"TEMP" = N2O_DECOMPOSITION_MIN_HEAT,
- /datum/gas/nitrous_oxide = MINIMUM_MOLE_COUNT*2
+ GAS_NITROUS = MINIMUM_MOLE_COUNT*2
)
/datum/gas_reaction/n2odecomp/react(datum/gas_mixture/air, datum/holder)
var/old_heat_capacity = air.heat_capacity()
var/temperature = air.return_temperature()
- var/nitrous = air.get_moles(/datum/gas/nitrous_oxide)
+ var/nitrous = air.get_moles(GAS_NITROUS)
var/burned_fuel = min(N2O_DECOMPOSITION_RATE*nitrous*temperature*(temperature-N2O_DECOMPOSITION_MAX_HEAT)/((-1/4)*(N2O_DECOMPOSITION_MAX_HEAT**2)), nitrous)
if(burned_fuel>0)
- air.set_moles(/datum/gas/nitrous_oxide, QUANTIZE(nitrous - burned_fuel))
- air.set_moles(/datum/gas/nitrogen, QUANTIZE(air.get_moles(/datum/gas/nitrogen) + burned_fuel))
- air.set_moles(/datum/gas/oxygen, QUANTIZE(air.get_moles(/datum/gas/oxygen) + burned_fuel/2))
+ air.set_moles(GAS_NITROUS, QUANTIZE(nitrous - burned_fuel))
+ air.set_moles(GAS_N2, QUANTIZE(air.get_moles(GAS_N2) + burned_fuel))
+ air.set_moles(GAS_O2, QUANTIZE(air.get_moles(GAS_O2) + burned_fuel/2))
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.set_temperature((temperature*old_heat_capacity + burned_fuel*N2O_DECOMPOSITION_ENERGY)/new_heat_capacity)
@@ -285,46 +278,59 @@ nobliumformation = 1001
//Fusion Rework Counter: Please increment this if you make a major overhaul to this system again.
//6 reworks
+/datum/gas_reaction/cold_fusion
+ exclude = FALSE
+ priority = COLDFUSION
+ name = "Cold Plasmic Fusion"
+ id = "coldfusion"
+
+/datum/gas_reaction/cold_fusion/init_reqs()
+ min_requirements = list(
+ "TEMP" = FUSION_TEMPERATURE_THRESHOLD_MINIMUM,
+ "MAX_TEMP" = FUSION_TEMPERATURE_THRESHOLD,
+ GAS_DILITHIUM = MINIMUM_MOLE_COUNT,
+ GAS_TRITIUM = FUSION_TRITIUM_MOLES_USED,
+ GAS_PLASMA = FUSION_MOLE_THRESHOLD,
+ GAS_CO2 = FUSION_MOLE_THRESHOLD)
+
+/datum/gas_reaction/cold_fusion/react(datum/gas_mixture/air, datum/holder)
+ if(air.return_temperature() < (FUSION_TEMPERATURE_THRESHOLD - FUSION_TEMPERATURE_THRESHOLD_MINIMUM) * NUM_E**( - air.get_moles(GAS_DILITHIUM) * DILITHIUM_LAMBDA) + FUSION_TEMPERATURE_THRESHOLD_MINIMUM)
+ // This is an exponential decay equation, actually. Horizontal Asymptote is FUSION_TEMPERATURE_THRESHOLD_MINIMUM.
+ return NO_REACTION
+ return fusion_react(air, holder, id)
+
/datum/gas_reaction/fusion
exclude = FALSE
- priority = 2
+ priority = FUSION
name = "Plasmic Fusion"
id = "fusion"
/datum/gas_reaction/fusion/init_reqs()
min_requirements = list(
- "TEMP" = FUSION_TEMPERATURE_THRESHOLD_MINIMUM, // Yogs -- Cold Fusion
- /datum/gas/tritium = FUSION_TRITIUM_MOLES_USED,
- /datum/gas/plasma = FUSION_MOLE_THRESHOLD,
- /datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
+ "TEMP" = FUSION_TEMPERATURE_THRESHOLD,
+ GAS_TRITIUM = FUSION_TRITIUM_MOLES_USED,
+ GAS_PLASMA = FUSION_MOLE_THRESHOLD,
+ GAS_CO2 = FUSION_MOLE_THRESHOLD)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
- //Yogs start -- Cold Fusion
- if(air.return_temperature() < FUSION_TEMPERATURE_THRESHOLD)
- if(!air.get_moles(/datum/gas/dilithium))
- return
- if(air.return_temperature() < (FUSION_TEMPERATURE_THRESHOLD - FUSION_TEMPERATURE_THRESHOLD_MINIMUM) * NUM_E**( - air.get_moles(/datum/gas/dilithium) * DILITHIUM_LAMBDA) + FUSION_TEMPERATURE_THRESHOLD_MINIMUM)
- // This is an exponential decay equation, actually. Horizontal Asymptote is FUSION_TEMPERATURE_THRESHOLD_MINIMUM.
- return
- //Yogs End
- var/turf/open/location
- if (istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
- var/datum/pipeline/fusion_pipenet = holder
- location = get_turf(pick(fusion_pipenet.members))
- else
- location = get_turf(holder)
+ return fusion_react(air, holder, id)
+
+/proc/fusion_react(datum/gas_mixture/air, datum/holder, id)
+ var/turf/open/location = get_holder_turf(holder)
+ if(!location)
+ return NO_REACTION
if(!air.analyzer_results)
air.analyzer_results = new
var/list/cached_scan_results = air.analyzer_results
- var/old_heat_capacity = air.heat_capacity()
+ var/old_thermal_energy = air.thermal_energy()
var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
- var/initial_plasma = air.get_moles(/datum/gas/plasma)
- var/initial_carbon = air.get_moles(/datum/gas/carbon_dioxide)
+ var/initial_plasma = air.get_moles(GAS_PLASMA)
+ var/initial_carbon = air.get_moles(GAS_CO2)
var/scale_factor = (air.return_volume())/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.return_volume()-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
var/gas_power = 0
for (var/gas_id in air.get_gases())
- gas_power += (GLOB.meta_gas_info[gas_id][META_GAS_FUSION_POWER]*air.get_moles(gas_id))
+ gas_power += (GLOB.gas_data.fusion_powers[gas_id]*air.get_moles(gas_id))
var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
cached_scan_results[id] = instability//used for analyzer feedback
@@ -336,9 +342,9 @@ nobliumformation = 1001
carbon = MODULUS(carbon - plasma, toroidal_size)
- air.set_moles(/datum/gas/plasma, plasma*scale_factor + FUSION_MOLE_THRESHOLD )//Scales the gases back up
- air.set_moles(/datum/gas/carbon_dioxide, carbon*scale_factor + FUSION_MOLE_THRESHOLD)
- var/delta_plasma = initial_plasma - air.get_moles(/datum/gas/plasma)
+ air.set_moles(GAS_PLASMA, plasma*scale_factor + FUSION_MOLE_THRESHOLD )//Scales the gases back up
+ air.set_moles(GAS_CO2, carbon*scale_factor + FUSION_MOLE_THRESHOLD)
+ var/delta_plasma = initial_plasma - air.get_moles(GAS_PLASMA)
reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
@@ -347,17 +353,17 @@ nobliumformation = 1001
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
- air.set_moles(/datum/gas/plasma, initial_plasma)
- air.set_moles(/datum/gas/carbon_dioxide, initial_carbon)
+ air.set_moles(GAS_PLASMA, initial_plasma)
+ air.set_moles(GAS_CO2, initial_carbon)
return NO_REACTION
- air.adjust_moles(/datum/gas/tritium, -FUSION_TRITIUM_MOLES_USED)
+ air.adjust_moles(GAS_TRITIUM, -FUSION_TRITIUM_MOLES_USED)
//The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
if(reaction_energy > 0)
- air.adjust_moles(/datum/gas/oxygen, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
- air.adjust_moles(/datum/gas/nitrous_oxide, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
+ air.adjust_moles(GAS_O2, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
+ air.adjust_moles(GAS_NITROUS, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
else
- air.adjust_moles(/datum/gas/bz, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
- air.adjust_moles(/datum/gas/nitrium, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
+ air.adjust_moles(GAS_BZ, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
+ air.adjust_moles(GAS_NITRIUM, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
if(reaction_energy)
if(location)
@@ -369,70 +375,77 @@ nobliumformation = 1001
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(clamp(((air.return_temperature()*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY))
+ air.set_temperature(clamp(((old_thermal_energy + reaction_energy)/new_heat_capacity),TCMB,INFINITY))
return REACTING
-/datum/gas_reaction/nitrium_formation //The formation of nitrium. Endothermic. Requires N2O as a catalyst.
- priority = 3
+/datum/gas_reaction/nitriumformation //The formation of nitrium. Endothermic. Requires N2O as a catalyst.
+ priority = NITRIUMFORMATION
name = "Nitrium formation"
- id = "nitrium_formation"
+ id = "nitriumformation"
-/datum/gas_reaction/nitrium_formation/init_reqs()
+/datum/gas_reaction/nitriumformation/init_reqs()
min_requirements = list(
- /datum/gas/nitrogen = 50,
- /datum/gas/plasma = 20,
- /datum/gas/bz = 20,
- /datum/gas/nitrous_oxide = 5,
+ GAS_N2 = 50,
+ GAS_PLASMA = 20,
+ GAS_BZ = 20,
+ GAS_NITROUS = 5,
"TEMP" = NITRIUM_FORMATION_MIN_TEMP,
)
-/datum/gas_reaction/nitrium_formation/react(datum/gas_mixture/air)
+/datum/gas_reaction/nitriumformation/react(datum/gas_mixture/air)
var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
+ var/old_thermal_energy = air.thermal_energy()
+
+ var/initial_n2 = air.get_moles(GAS_N2)
+ var/initial_plasma = air.get_moles(GAS_PLASMA)
+ var/initial_bz = air.get_moles(GAS_BZ)
- var/heat_efficency = min(temperature / NITRIUM_FORMATION_ENERGY, air.get_moles(/datum/gas/nitrogen) / 2, air.get_moles(/datum/gas/plasma), air.get_moles(/datum/gas/bz))
- //Shouldn't produce gas from nothing.
- if (heat_efficency <= 0 || (air.get_moles(/datum/gas/nitrogen) - heat_efficency < 0 ) || (air.get_moles(/datum/gas/plasma) - heat_efficency < 0) || (air.get_moles(/datum/gas/bz) - heat_efficency < 0))
+ var/heat_efficency = min(temperature / NITRIUM_FORMATION_ENERGY, initial_n2 / 2, initial_plasma, initial_bz)
+
+ // Shouldn't produce gas from nothing.
+ if (heat_efficency <= 0 || (initial_n2 - heat_efficency < 0 ) || (initial_plasma - heat_efficency < 0) || (initial_bz - heat_efficency < 0))
return NO_REACTION
- air.adjust_moles(/datum/gas/nitrogen, -heat_efficency * 2)
- air.adjust_moles(/datum/gas/plasma, -heat_efficency)
- air.adjust_moles(/datum/gas/bz, -heat_efficency)
- air.adjust_moles(/datum/gas/nitrium, heat_efficency / 10)
+ air.adjust_moles(GAS_N2, -heat_efficency * 2)
+ air.adjust_moles(GAS_PLASMA, -heat_efficency)
+ air.adjust_moles(GAS_BZ, -heat_efficency)
+ air.adjust_moles(GAS_NITRIUM, heat_efficency / 10)
var/energy_used = heat_efficency * NITRIUM_FORMATION_ENERGY
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity - energy_used) / new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy - energy_used) / new_heat_capacity), TCMB))
return REACTING
/datum/gas_reaction/bzformation //Formation of BZ by combining plasma and tritium at low pressures. Exothermic.
- priority = 4
+ priority = BZFORMATION
name = "BZ Gas formation"
id = "bzformation"
/datum/gas_reaction/bzformation/init_reqs()
min_requirements = list(
- /datum/gas/nitrous_oxide = 10,
- /datum/gas/plasma = 10
+ GAS_NITROUS = 10,
+ GAS_PLASMA = 10,
)
-
/datum/gas_reaction/bzformation/react(datum/gas_mixture/air)
- var/temperature = air.return_temperature()
var/pressure = air.return_pressure()
- var/old_heat_capacity = air.heat_capacity()
- var/reaction_efficency = min(1/((clamp(pressure,1,1000)/(0.5*ONE_ATMOSPHERE))*(max(air.get_moles(/datum/gas/plasma)/air.get_moles(/datum/gas/nitrous_oxide),1))),air.get_moles(/datum/gas/nitrous_oxide),air.get_moles(/datum/gas/plasma)/2)
+ var/old_thermal_energy = air.thermal_energy()
+
+ var/initial_plas = air.get_moles(GAS_PLASMA)
+ var/initial_nitrous = air.get_moles(GAS_NITROUS)
+
+ var/reaction_efficency = min(1/((clamp(pressure,1,1000)/(0.5*ONE_ATMOSPHERE))*(max(initial_plas/initial_nitrous,1))),initial_nitrous,initial_plas/2)
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
- if ((air.get_moles(/datum/gas/nitrous_oxide) - reaction_efficency < 0 )|| (air.get_moles(/datum/gas/plasma) - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
+ if ((initial_nitrous - reaction_efficency < 0 )|| (initial_plas - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
return NO_REACTION
- air.adjust_moles(/datum/gas/bz, reaction_efficency)
- if(reaction_efficency == air.get_moles(/datum/gas/nitrous_oxide))
- air.adjust_moles(/datum/gas/bz, -min(pressure,1))
- air.adjust_moles(/datum/gas/oxygen, min(pressure,1))
- air.adjust_moles(/datum/gas/nitrous_oxide, -reaction_efficency)
- air.adjust_moles(/datum/gas/plasma, -2*reaction_efficency)
+ air.adjust_moles(GAS_BZ, reaction_efficency)
+ if(reaction_efficency == initial_nitrous)
+ air.adjust_moles(GAS_BZ, -min(pressure,1))
+ air.adjust_moles(GAS_O2, min(pressure,1))
+ air.adjust_moles(GAS_NITROUS, -reaction_efficency)
+ air.adjust_moles(GAS_PLASMA, -2*reaction_efficency)
//clamps by a minimum amount in the event of an underflow.
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, clamp((reaction_efficency**2)*BZ_RESEARCH_AMOUNT,0.01,BZ_RESEARCH_MAX_AMOUNT))
@@ -440,124 +453,139 @@ nobliumformation = 1001
if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB))
+ air.set_temperature(max(((old_thermal_energy + energy_released)/new_heat_capacity),TCMB))
return REACTING
/datum/gas_reaction/nobliumformation //Hyper-Noblium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic.
- priority = 1001 //Ensure this value is higher than nobstop
+ priority = NOBLIUMFORMATION //Ensure this value is higher than nobstop
name = "Hyper-Noblium condensation"
id = "nobformation"
/datum/gas_reaction/nobliumformation/init_reqs()
min_requirements = list(
- /datum/gas/nitrogen = 20,
- /datum/gas/tritium = 10,
+ GAS_N2 = 20,
+ GAS_TRITIUM = 10,
"TEMP" = 5000000)
/datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air)
- var/nob_formed = min(max(air.get_moles(/datum/gas/bz), 1) * (log(air.return_temperature())**2), air.get_moles(/datum/gas/tritium)/10, air.get_moles(/datum/gas/nitrogen)/20)
- var/old_heat_capacity = air.heat_capacity()
- var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(/datum/gas/bz),1)))
- air.adjust_moles(/datum/gas/tritium, -10*nob_formed)
- air.adjust_moles(/datum/gas/nitrogen, -20*nob_formed)
- air.adjust_moles(/datum/gas/hypernoblium, nob_formed)
+ var/initial_trit = air.get_moles(GAS_TRITIUM)
+ var/initial_n2 = air.get_moles(GAS_N2)
+ var/initial_bz = air.get_moles(GAS_BZ)
+
+ var/nob_formed = min(max(initial_bz, 1) * (log(air.return_temperature())**2), initial_trit / 10, initial_n2 / 20)
+
+ var/old_thermal_energy = air.thermal_energy()
+
+ var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(initial_bz,1)))
+ air.adjust_moles(GAS_TRITIUM, -10*nob_formed)
+ air.adjust_moles(GAS_N2, -20*nob_formed)
+ air.adjust_moles(GAS_HYPERNOB, nob_formed)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, clamp(nob_formed*NOBLIUM_RESEARCH_AMOUNT, 0.01, NOBLIUM_RESEARCH_MAX_AMOUNT))
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((air.return_temperature()*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB))
+ air.set_temperature(max(((old_thermal_energy - energy_taken)/new_heat_capacity),TCMB))
return REACTING
/datum/gas_reaction/miaster //dry heat sterilization: clears out pathogens in the air
- priority = -10 //after all the heating from fires etc. is done
+ priority = MIASTER //after all the heating from fires etc. is done
name = "Dry Heat Sterilization"
id = "sterilization"
/datum/gas_reaction/miaster/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST+70,
- /datum/gas/miasma = MINIMUM_MOLE_COUNT
+ GAS_MIASMA = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder)
// As the name says it, it needs to be dry
- if(air.get_moles(/datum/gas/water_vapor)/air.total_moles() > 0.1) // Yogs --Fixes runtime in Sterilization
+ if(air.get_moles(GAS_H2O)/air.total_moles() > 0.1) // Yogs --Fixes runtime in Sterilization
return NO_REACT
//Replace miasma with oxygen
- var/cleaned_air = min(air.get_moles(/datum/gas/miasma), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
- air.adjust_moles(/datum/gas/miasma, -cleaned_air)
- air.adjust_moles(/datum/gas/oxygen, cleaned_air)
+ var/cleaned_air = min(air.get_moles(GAS_MIASMA), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
+ air.adjust_moles(GAS_MIASMA, -cleaned_air)
+ air.adjust_moles(GAS_O2, cleaned_air)
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
air.set_temperature(air.return_temperature() + cleaned_air * 0.002)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, clamp(cleaned_air*MIASMA_RESEARCH_AMOUNT,0.01, MIASMA_RESEARCH_MAX_AMOUNT))//Turns out the burning of miasma is kinda interesting to scientists
return REACTING
-
+
/datum/gas_reaction/nitro_ball
- priority = 7
+ priority = NITROBALL
name ="Nitrium Energy Ball"
- id = "nitro_ball"
+ id = "nitroball"
/datum/gas_reaction/nitro_ball/init_reqs()
min_requirements = list(
- /datum/gas/pluoxium = NITRO_BALL_MOLES_REQUIRED,
- /datum/gas/nitrium = NITRO_BALL_MOLES_REQUIRED,
- /datum/gas/plasma = NITRO_BALL_MOLES_REQUIRED,
+ GAS_PLUOXIUM = NITRO_BALL_MOLES_REQUIRED,
+ GAS_NITRIUM = NITRO_BALL_MOLES_REQUIRED,
+ GAS_PLASMA = NITRO_BALL_MOLES_REQUIRED,
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
)
/// Reaction that burns nitrium and plouxium into radballs and partial constituent gases, but also catalyzes the combustion of plasma.
/datum/gas_reaction/nitro_ball/react(datum/gas_mixture/air, datum/holder)
- var/turf/location
- var/old_heat_capacity = air.heat_capacity()
- if(istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
- var/datum/pipeline/pipenet = holder
- location = get_turf(pick(pipenet.members))
- else
- location = get_turf(holder)
- var/reaction_rate = min(NITRO_BALL_MAX_REACT_RATE, air.get_moles(/datum/gas/pluoxium), air.get_moles(/datum/gas/nitrium), air.get_moles(/datum/gas/plasma))
- var/balls_shot = round(reaction_rate/NITRO_BALL_MOLES_REQUIRED)
+ var/turf/open/location = get_holder_turf(holder)
+ if(!location)
+ return NO_REACTION
+
+ var/old_thermal_energy = air.thermal_energy()
+
+ var/initial_pluox = air.get_moles(GAS_PLUOXIUM)
+ var/initial_nitrium = air.get_moles(GAS_NITRIUM)
+ var/initial_plas = air.get_moles(GAS_PLASMA)
+
+ var/reaction_rate = min(NITRO_BALL_MAX_REACT_RATE, initial_plas, initial_pluox, initial_nitrium)
+ var/balls_shot = round(reaction_rate / NITRO_BALL_MOLES_REQUIRED)
+
//A percentage of plasma is burned during the reaction that is converted into energy and radballs, though mostly pure heat.
- var/plasma_burned = QUANTIZE((air.get_moles(/datum/gas/plasma) + 5*reaction_rate)*NITRO_BALL_PLASMA_COEFFICIENT)
+ var/plasma_burned = QUANTIZE((initial_plas + 5 * reaction_rate) * NITRO_BALL_PLASMA_COEFFICIENT)
//Nitrium has a lot of stored energy, and breaking it up releases some of it. Plasma is also partially converted into energy in the process.
- var/energy_released = (reaction_rate*NITRO_BALL_HEAT_SCALE) + (plasma_burned*NITRO_BALL_PLASMA_ENERGY)
- air.adjust_moles(/datum/gas/nitrium, -reaction_rate)
- air.adjust_moles(/datum/gas/pluoxium, -reaction_rate)
- air.adjust_moles(/datum/gas/antinoblium, reaction_rate) // an actual purpose for this reaction other than bombs and flamethrowers
- air.adjust_moles(/datum/gas/plasma, -plasma_burned)
+ var/energy_released = (reaction_rate * NITRO_BALL_HEAT_SCALE) + (plasma_burned * NITRO_BALL_PLASMA_ENERGY)
+
+ air.adjust_moles(GAS_PLUOXIUM, -reaction_rate)
+ air.adjust_moles(GAS_NITRIUM, -reaction_rate)
+ air.adjust_moles(GAS_ANTINOB, reaction_rate) // an actual purpose for this reaction other than bombs and flamethrowers
+ air.adjust_moles(GAS_PLASMA, -plasma_burned)
+
if(balls_shot && !isnull(location))
var/angular_increment = 360/balls_shot
var/random_starting_angle = rand(0,360)
for(var/i in 1 to balls_shot)
- location.fire_nuclear_particle((i*angular_increment+random_starting_angle))
+ location.fire_nuclear_particle((i * angular_increment + random_starting_angle))
+
if(energy_released)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(clamp((air.return_temperature()*old_heat_capacity + energy_released)/new_heat_capacity, TCMB, INFINITY))
+ air.set_temperature(clamp((old_thermal_energy + energy_released) / new_heat_capacity, TCMB, INFINITY))
return REACTING
//freon reaction (is not a fire yet)
/datum/gas_reaction/freonfire
- priority = -5
+ priority = FREONFIRE
name = "Freon combustion"
id = "freonfire"
/datum/gas_reaction/freonfire/init_reqs()
min_requirements = list(
- /datum/gas/oxygen = MINIMUM_MOLE_COUNT,
- /datum/gas/freon = MINIMUM_MOLE_COUNT,
+ GAS_O2 = MINIMUM_MOLE_COUNT,
+ GAS_FREON = MINIMUM_MOLE_COUNT,
"TEMP" = FREON_LOWER_TEMPERATURE,
"MAX_TEMP" = FREON_MAXIMUM_BURN_TEMPERATURE
)
/datum/gas_reaction/freonfire/react(datum/gas_mixture/air, datum/holder)
- var/energy_released = 0
- var/old_heat_capacity = air.heat_capacity()
- var/temperature = air.return_temperature()
- if(!isturf(holder))
+ if(!isopenturf(holder))
return NO_REACTION
var/turf/open/location = holder
+ var/energy_released = 0
+ var/old_thermal_energy = air.thermal_energy()
+ var/temperature = air.return_temperature()
+ var/initial_o2 = air.get_moles(GAS_O2)
+ var/initial_freon = air.get_moles(GAS_FREON)
//Handle freon burning (only reaction now)
var/freon_burn_rate = 0
@@ -571,16 +599,16 @@ nobliumformation = 1001
temperature_scale = (FREON_MAXIMUM_BURN_TEMPERATURE - temperature) / (FREON_MAXIMUM_BURN_TEMPERATURE - FREON_LOWER_TEMPERATURE) //calculate the scale based on the temperature
if(temperature_scale >= 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
- if(air.get_moles(/datum/gas/oxygen) > air.get_moles(/datum/gas/freon) * FREON_OXYGEN_FULLBURN)
- freon_burn_rate = (air.get_moles(/datum/gas/freon) * temperature_scale) / FREON_BURN_RATE_DELTA
+ if(initial_o2 > initial_freon * FREON_OXYGEN_FULLBURN)
+ freon_burn_rate = (initial_freon * temperature_scale) / FREON_BURN_RATE_DELTA
else
- freon_burn_rate = (temperature_scale * (air.get_moles(/datum/gas/oxygen) / FREON_OXYGEN_FULLBURN)) / FREON_BURN_RATE_DELTA
+ freon_burn_rate = (temperature_scale * (initial_o2 / FREON_OXYGEN_FULLBURN)) / FREON_BURN_RATE_DELTA
if(freon_burn_rate > MINIMUM_HEAT_CAPACITY)
- freon_burn_rate = min(freon_burn_rate, air.get_moles(/datum/gas/freon), air.get_moles(/datum/gas/oxygen) / oxygen_burn_rate) //Ensures matter is conserved properly
- air.adjust_moles(/datum/gas/freon, -freon_burn_rate)
- air.adjust_moles(/datum/gas/oxygen, -(freon_burn_rate * oxygen_burn_rate))
- air.adjust_moles(/datum/gas/carbon_dioxide, freon_burn_rate)
+ freon_burn_rate = min(freon_burn_rate, initial_freon, initial_o2 / oxygen_burn_rate) //Ensures matter is conserved properly
+ air.adjust_moles(GAS_FREON, -freon_burn_rate)
+ air.adjust_moles(GAS_O2, -(freon_burn_rate * oxygen_burn_rate))
+ air.adjust_moles(GAS_CO2, freon_burn_rate)
if(temperature < 160 && temperature > 120 && prob(2))
new /obj/item/stack/sheet/hot_ice(location)
@@ -590,34 +618,34 @@ nobliumformation = 1001
if(energy_released < 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature((temperature * old_heat_capacity + energy_released) / new_heat_capacity)
+ air.set_temperature((old_thermal_energy + energy_released) / new_heat_capacity)
/datum/gas_reaction/h2fire
- priority = -3 //fire should ALWAYS be last, but tritium fires happen before plasma fires
+ priority = H2FIRE //fire should ALWAYS be last, but tritium fires happen before plasma fires
name = "Hydrogen Combustion"
id = "h2fire"
/datum/gas_reaction/h2fire/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
- /datum/gas/hydrogen = MINIMUM_MOLE_COUNT,
- /datum/gas/oxygen = MINIMUM_MOLE_COUNT
+ GAS_H2 = MINIMUM_MOLE_COUNT,
+ GAS_O2 = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/h2fire/react(datum/gas_mixture/air, datum/holder)
- var/old_heat_capacity = air.heat_capacity()
- //this speeds things up because accessing datum vars is slow
+ var/old_thermal_energy = air.thermal_energy()
+ //this speeds things up because accessing datum vars is slow
var/temperature = air.return_temperature()
var/list/cached_results = air.reaction_results
cached_results["fire"] = 0
var/turf/open/location = isturf(holder) ? holder : null
- var/burned_fuel = min(air.get_moles(/datum/gas/hydrogen), air.get_moles(/datum/gas/oxygen)) / HYDROGEN_BURN_H2_FACTOR
+ var/burned_fuel = min(air.get_moles(GAS_H2), air.get_moles(GAS_O2)) / HYDROGEN_BURN_H2_FACTOR
if(burned_fuel <= 0)
return NO_REACTION
- air.adjust_moles(/datum/gas/hydrogen, -burned_fuel) // Yogs - see trit burn
- air.adjust_moles(/datum/gas/oxygen, -burned_fuel / 2)
- air.adjust_moles(/datum/gas/water_vapor, burned_fuel)
+ air.adjust_moles(GAS_H2, -burned_fuel) // Yogs - see trit burn
+ air.adjust_moles(GAS_O2, -burned_fuel / 2)
+ air.adjust_moles(GAS_H2O, burned_fuel)
var/energy_released = (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel * HYDROGEN_BURN_H2_FACTOR) // Yogs -- burns twice as fast with half the energy
cached_results["fire"] += burned_fuel
@@ -625,7 +653,7 @@ nobliumformation = 1001
if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature((temperature*old_heat_capacity + energy_released) / new_heat_capacity)
+ air.set_temperature((old_thermal_energy + energy_released) / new_heat_capacity)
//let the floor know a fire is happening
if(istype(location))
@@ -641,284 +669,299 @@ nobliumformation = 1001
/datum/gas_reaction/hexane_formation
- priority = 13
+ priority = HEXANEFORMATION
name = "Hexane formation"
id = "hexane_formation"
/datum/gas_reaction/hexane_formation/init_reqs()
min_requirements = list(
- /datum/gas/bz = MINIMUM_MOLE_COUNT,
- /datum/gas/hydrogen = MINIMUM_MOLE_COUNT,
+ GAS_BZ = MINIMUM_MOLE_COUNT,
+ GAS_H2 = MINIMUM_MOLE_COUNT,
"TEMP" = 450,
"MAX_TEMP" = 465
)
/datum/gas_reaction/hexane_formation/react(datum/gas_mixture/air, datum/holder)
var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
- var/heat_efficency = min(temperature * 0.01, air.get_moles(/datum/gas/hydrogen), air.get_moles(/datum/gas/bz))
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_h2 = air.get_moles(GAS_H2)
+ var/initial_bz = air.get_moles(GAS_BZ)
+ var/heat_efficency = min(temperature * 0.01, initial_h2, initial_bz)
var/energy_used = heat_efficency * 600
- if (air.get_moles(/datum/gas/hydrogen) - (heat_efficency * 5) < 0 || air.get_moles(/datum/gas/bz) - (heat_efficency * 0.25) < 0) //Shouldn't produce gas from nothing.
+ if (initial_h2 - (heat_efficency * 5) < 0 || initial_bz - (heat_efficency * 0.25) < 0) //Shouldn't produce gas from nothing.
return NO_REACTION
- air.adjust_moles(/datum/gas/hydrogen, -(heat_efficency * 5))
- air.adjust_moles(/datum/gas/bz, -(heat_efficency * 0.25))
- air.adjust_moles(/datum/gas/hexane, (heat_efficency * 5.25))
+ air.adjust_moles(GAS_H2, -(heat_efficency * 5))
+ air.adjust_moles(GAS_BZ, -(heat_efficency * 0.25))
+ air.adjust_moles(GAS_HEXANE, (heat_efficency * 5.25))
if(energy_used)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity - energy_used) / new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy - energy_used) / new_heat_capacity), TCMB))
return REACTING
/datum/gas_reaction/metalhydrogen
- priority = 17
+ priority = METALHYDROGEN
name = "Metal Hydrogen formation"
id = "metalhydrogen"
/datum/gas_reaction/metalhydrogen/init_reqs()
min_requirements = list(
- /datum/gas/hydrogen = 300, //same crystallizer recipe
- /datum/gas/bz = 50,
+ GAS_H2 = 300,
+ GAS_BZ = 50,
"TEMP" = METAL_HYDROGEN_MINIMUM_HEAT
)
/datum/gas_reaction/metalhydrogen/react(datum/gas_mixture/air, datum/holder)
- var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
- if(!isturf(holder))
+ if(!isopenturf(holder))
return NO_REACTION
var/turf/open/location = holder
+ var/temperature = air.return_temperature()
+ var/old_thermal_energy = air.thermal_energy()
///the more heat you use the higher is this factor
var/increase_factor = min(log(10 , (temperature / METAL_HYDROGEN_MINIMUM_HEAT)), 5) //e7-e12 range
///the more moles you use and the higher the heat, the higher is the efficiency
- var/heat_efficency = air.get_moles(/datum/gas/hydrogen)* 0.01 * increase_factor //This variable name is dumb but I can't be assed to change it
+ var/heat_efficency = air.get_moles(GAS_H2)* 0.01 * increase_factor //This variable name is dumb but I can't be assed to change it
var/pressure = air.return_pressure()
var/energy_used = heat_efficency * METAL_HYDROGEN_FORMATION_ENERGY
if(pressure >= METAL_HYDROGEN_MINIMUM_PRESSURE && temperature >= METAL_HYDROGEN_MINIMUM_HEAT)
- air.adjust_moles(/datum/gas/bz, -(heat_efficency)) //About 70% the amount of BZ requirement consumed
+ air.adjust_moles(GAS_BZ, -(heat_efficency))
if (prob(25 * increase_factor))
- air.adjust_moles(/datum/gas/hydrogen, -(heat_efficency * 10)) //Still consume about 70% of the hydrogen present
+ air.adjust_moles(GAS_H2, -(heat_efficency * 10))
new /obj/item/stack/sheet/mineral/metal_hydrogen(location)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min((heat_efficency * increase_factor * 0.5), METAL_HYDROGEN_RESEARCH_MAX_AMOUNT))
if(energy_used > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity - energy_used) / new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy - energy_used) / new_heat_capacity), TCMB))
return REACTING
/datum/gas_reaction/freonformation
- priority = 5
+ priority = FREONFORMATION
name = "Freon formation"
id = "freonformation"
/datum/gas_reaction/freonformation/init_reqs() //minimum requirements for freon formation
min_requirements = list(
- /datum/gas/plasma = 40,
- /datum/gas/carbon_dioxide = 20,
- /datum/gas/bz = 20,
+ GAS_PLASMA = 40,
+ GAS_CO2 = 20,
+ GAS_BZ = 20,
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100
)
/datum/gas_reaction/freonformation/react(datum/gas_mixture/air)
var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
- var/heat_efficency = min(temperature / (FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 10), air.get_moles(/datum/gas/plasma), air.get_moles(/datum/gas/carbon_dioxide), air.get_moles(/datum/gas/bz))
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_plas = air.get_moles(GAS_PLASMA)
+ var/initial_co2 = air.get_moles(GAS_CO2)
+ var/initial_bz = air.get_moles(GAS_BZ)
+ var/heat_efficency = min(temperature / (FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 10), initial_plas, initial_co2, initial_bz)
var/energy_used = heat_efficency * 100
- if ((air.get_moles(/datum/gas/plasma) - heat_efficency * 1.5 < 0 ) || (air.get_moles(/datum/gas/carbon_dioxide) - heat_efficency * 0.75 < 0) || (air.get_moles(/datum/gas/bz) - heat_efficency * 0.25 < 0)) //Shouldn't produce gas from nothing.
+ if ((initial_plas - heat_efficency * 1.5 < 0 ) || (initial_co2 - heat_efficency * 0.75 < 0) || (initial_bz - heat_efficency * 0.25 < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
- air.adjust_moles(/datum/gas/plasma, -(heat_efficency * 1.5))
- air.adjust_moles(/datum/gas/carbon_dioxide, -(heat_efficency * 0.75))
- air.adjust_moles(/datum/gas/bz, -(heat_efficency * 0.25))
- air.adjust_moles(/datum/gas/freon, (heat_efficency * 2.5))
+ air.adjust_moles(GAS_PLASMA, -(heat_efficency * 1.5))
+ air.adjust_moles(GAS_CO2, -(heat_efficency * 0.75))
+ air.adjust_moles(GAS_BZ, -(heat_efficency * 0.25))
+ air.adjust_moles(GAS_FREON, (heat_efficency * 2.5))
if(energy_used > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity - energy_used)/new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy - energy_used)/new_heat_capacity), TCMB))
return REACTING
-
/datum/gas_reaction/halon_formation
- priority = 12
+ priority = HALONFORMATION
name = "Halon formation"
id = "halon_formation"
/datum/gas_reaction/halon_formation/init_reqs()
min_requirements = list(
- /datum/gas/bz = MINIMUM_MOLE_COUNT,
- /datum/gas/tritium = MINIMUM_MOLE_COUNT,
+ GAS_BZ = MINIMUM_MOLE_COUNT,
+ GAS_TRITIUM = MINIMUM_MOLE_COUNT,
"TEMP" = 30,
"MAX_TEMP" = 55
)
/datum/gas_reaction/halon_formation/react(datum/gas_mixture/air, datum/holder)
var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
- var/heat_efficency = min(temperature * 0.01, air.get_moles(/datum/gas/tritium), air.get_moles(/datum/gas/bz))
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_bz = air.get_moles(GAS_BZ)
+ var/initial_trit = air.get_moles(GAS_TRITIUM)
+ var/heat_efficency = min(temperature * 0.01, initial_trit, initial_bz)
var/energy_used = heat_efficency * 300
- if ((air.get_moles(/datum/gas/tritium) - heat_efficency * 4 < 0 ) || (air.get_moles(/datum/gas/bz) - heat_efficency * 0.25 < 0)) //Shouldn't produce gas from nothing.
+ if ((initial_trit - heat_efficency * 4 < 0 ) || (initial_bz - heat_efficency * 0.25 < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
- air.adjust_moles(/datum/gas/tritium, -(heat_efficency * 4))
- air.adjust_moles(/datum/gas/bz, -(heat_efficency * 0.25))
- air.adjust_moles(/datum/gas/halon, (heat_efficency * 4.25))
+ air.adjust_moles(GAS_TRITIUM, -(heat_efficency * 4))
+ air.adjust_moles(GAS_BZ, -(heat_efficency * 0.25))
+ air.adjust_moles(GAS_HALON, (heat_efficency * 4.25))
if(energy_used)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity + energy_used) / new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy + energy_used) / new_heat_capacity), TCMB))
return REACTING
/datum/gas_reaction/healium_formation
- priority = 9
+ priority = HEALIUMFORMATION
name = "Healium formation"
id = "healium_formation"
/datum/gas_reaction/healium_formation/init_reqs()
min_requirements = list(
- /datum/gas/bz = MINIMUM_MOLE_COUNT,
- /datum/gas/freon = MINIMUM_MOLE_COUNT,
+ GAS_BZ = MINIMUM_MOLE_COUNT,
+ GAS_FREON = MINIMUM_MOLE_COUNT,
"TEMP" = 25,
"MAX_TEMP" = 300
)
/datum/gas_reaction/healium_formation/react(datum/gas_mixture/air, datum/holder)
var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
- var/heat_efficency = min(temperature * 0.3, air.get_moles(/datum/gas/freon), air.get_moles(/datum/gas/bz))
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_freon = air.get_moles(GAS_FREON)
+ var/initial_bz = air.get_moles(GAS_BZ)
+ var/heat_efficency = min(temperature * 0.3, initial_freon, initial_bz)
var/energy_used = heat_efficency * 9000
- if ((air.get_moles(/datum/gas/freon) - heat_efficency * 2.75 < 0 ) || (air.get_moles(/datum/gas/bz) - heat_efficency * 0.25 < 0)) //Shouldn't produce gas from nothing.
+ if ((initial_freon - heat_efficency * 2.75 < 0 ) || (initial_bz - heat_efficency * 0.25 < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
- air.adjust_moles(/datum/gas/freon, -(heat_efficency * 2.75))
- air.adjust_moles(/datum/gas/bz, -(heat_efficency * 0.25))
- air.adjust_moles(/datum/gas/healium, (heat_efficency * 3))
+ air.adjust_moles(GAS_FREON, -(heat_efficency * 2.75))
+ air.adjust_moles(GAS_BZ, -(heat_efficency * 0.25))
+ air.adjust_moles(GAS_HEALIUM, (heat_efficency * 3))
if(energy_used)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity + energy_used) / new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy + energy_used) / new_heat_capacity), TCMB))
return REACTING
/datum/gas_reaction/pluonium_formation
- priority = 10
+ priority = PLUONIUMFORMATION
name = "Pluonium formation"
id = "pluonium_formation"
/datum/gas_reaction/pluonium_formation/init_reqs()
min_requirements = list(
- /datum/gas/pluoxium = MINIMUM_MOLE_COUNT,
- /datum/gas/hydrogen = MINIMUM_MOLE_COUNT,
+ GAS_PLUOXIUM = MINIMUM_MOLE_COUNT,
+ GAS_H2 = MINIMUM_MOLE_COUNT,
"TEMP" = 5000,
"MAX_TEMP" = 10000
)
/datum/gas_reaction/pluonium_formation/react(datum/gas_mixture/air, datum/holder)
var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
- var/heat_efficency = min(temperature * 0.005, air.get_moles(/datum/gas/pluoxium), air.get_moles(/datum/gas/hydrogen))
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_pluox = air.get_moles(GAS_PLUOXIUM)
+ var/initial_h2 = air.get_moles(GAS_H2)
+ var/heat_efficency = min(temperature * 0.005, initial_pluox, initial_h2)
var/energy_used = heat_efficency * 650
- if ((air.get_moles(/datum/gas/pluoxium) - heat_efficency * 0.2 < 0 ) || (air.get_moles(/datum/gas/hydrogen) - heat_efficency * 2 < 0)) //Shouldn't produce gas from nothing.
+ if ((initial_pluox - heat_efficency * 0.2 < 0 ) || (initial_h2 - heat_efficency * 2 < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
- air.adjust_moles(/datum/gas/hydrogen, -(heat_efficency * 2))
- air.adjust_moles(/datum/gas/pluoxium, -(heat_efficency * 0.2))
- air.adjust_moles(/datum/gas/pluonium, (heat_efficency * 2.2))
+ air.adjust_moles(GAS_H2, -(heat_efficency * 2))
+ air.adjust_moles(GAS_PLUOXIUM, -(heat_efficency * 0.2))
+ air.adjust_moles(GAS_PLUONIUM, (heat_efficency * 2.2))
if(energy_used > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity + energy_used) / new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy + energy_used) / new_heat_capacity), TCMB))
return REACTING
/datum/gas_reaction/zauker_formation
- priority = 11
+ priority = ZAUKERFORMATION
name = "Zauker formation"
id = "zauker_formation"
/datum/gas_reaction/zauker_formation/init_reqs()
min_requirements = list(
- /datum/gas/hypernoblium = MINIMUM_MOLE_COUNT,
- /datum/gas/nitrium = MINIMUM_MOLE_COUNT,
+ GAS_HYPERNOB = MINIMUM_MOLE_COUNT,
+ GAS_NITRIUM = MINIMUM_MOLE_COUNT,
"TEMP" = 50000,
"MAX_TEMP" = 75000
)
/datum/gas_reaction/zauker_formation/react(datum/gas_mixture/air, datum/holder)
var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
- var/heat_efficency = min(temperature * 0.000005, air.get_moles(/datum/gas/hypernoblium), air.get_moles(/datum/gas/nitrium))
+ var/old_thermal_energy = air.thermal_energy()
+
+ var/initial_nob = air.get_moles(GAS_HYPERNOB)
+ var/initial_nitrium = air.get_moles(GAS_NITRIUM)
+
+ var/heat_efficency = min(temperature * 0.000005, initial_nob, initial_nitrium)
var/energy_used = heat_efficency * 5000
- if ((air.get_moles(/datum/gas/hypernoblium) - heat_efficency * 0.01 < 0 ) || (air.get_moles(/datum/gas/nitrium) - heat_efficency * 0.5 < 0)) //Shouldn't produce gas from nothing.
+ if ((initial_nob - heat_efficency * 0.01 < 0 ) || (initial_nitrium - heat_efficency * 0.5 < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
- air.adjust_moles(/datum/gas/hypernoblium, -(heat_efficency * 0.01))
- air.adjust_moles(/datum/gas/nitrium, -(heat_efficency * 0.5))
- air.adjust_moles(/datum/gas/zauker, (heat_efficency * 0.5))
+
+ air.adjust_moles(GAS_HYPERNOB, -(heat_efficency * 0.01))
+ air.adjust_moles(GAS_NITRIUM, -(heat_efficency * 0.5))
+ air.adjust_moles(GAS_ZAUKER, (heat_efficency * 0.5))
if(energy_used)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity - energy_used) / new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy - energy_used) / new_heat_capacity), TCMB))
return REACTING
/datum/gas_reaction/halon_o2removal
- priority = -1
+ priority = HALONO2REMOVAL
name = "Halon o2 removal"
id = "halon_o2removal"
/datum/gas_reaction/halon_o2removal/init_reqs()
min_requirements = list(
- /datum/gas/halon = MINIMUM_MOLE_COUNT,
- /datum/gas/oxygen = MINIMUM_MOLE_COUNT,
+ GAS_HALON = MINIMUM_MOLE_COUNT,
+ GAS_O2 = MINIMUM_MOLE_COUNT,
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
)
/datum/gas_reaction/halon_o2removal/react(datum/gas_mixture/air, datum/holder)
var/temperature = air.return_temperature()
- var/old_heat_capacity = air.heat_capacity()
- var/heat_efficency = min(temperature / ( FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 10), air.get_moles(/datum/gas/halon), air.get_moles(/datum/gas/oxygen))
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_o2 = air.get_moles(GAS_O2)
+ var/initial_halon = air.get_moles(GAS_HALON)
+ var/heat_efficency = min(temperature / ( FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 10), initial_halon, initial_o2)
var/energy_used = heat_efficency * 2500
- if ((air.get_moles(/datum/gas/halon) - heat_efficency < 0 ) || (air.get_moles(/datum/gas/oxygen) - heat_efficency * 20 < 0)) //Shouldn't produce gas from nothing.
+ if ((initial_halon - heat_efficency < 0 ) || (initial_o2 - heat_efficency * 20 < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
- air.adjust_moles(/datum/gas/halon, -(heat_efficency))
- air.adjust_moles(/datum/gas/oxygen, -(heat_efficency * 20))
- air.adjust_moles(/datum/gas/carbon_dioxide, (heat_efficency * 5))
+ air.adjust_moles(GAS_HALON, -(heat_efficency))
+ air.adjust_moles(GAS_O2, -(heat_efficency * 20))
+ air.adjust_moles(GAS_CO2, (heat_efficency * 5))
if(energy_used)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max(((temperature * old_heat_capacity - energy_used) / new_heat_capacity), TCMB))
+ air.set_temperature(max(((old_thermal_energy - energy_used) / new_heat_capacity), TCMB))
return REACTING
/datum/gas_reaction/zauker_decomp
- priority = 8
+ priority = ZAUKERDECOMP
name = "Zauker decomposition"
id = "zauker_decomp"
/datum/gas_reaction/zauker_decomp/init_reqs()
min_requirements = list(
- /datum/gas/nitrogen = MINIMUM_MOLE_COUNT,
- /datum/gas/zauker = MINIMUM_MOLE_COUNT
+ GAS_N2 = MINIMUM_MOLE_COUNT,
+ GAS_ZAUKER = MINIMUM_MOLE_COUNT,
)
/datum/gas_reaction/zauker_decomp/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
- var/old_heat_capacity = air.heat_capacity()
- //this speeds things up because accessing datum vars is slow
- var/temperature = air.return_temperature()
- var/burned_fuel = 0
- burned_fuel = min(20, air.get_moles(/datum/gas/nitrogen), air.get_moles(/datum/gas/zauker))
- if(air.get_moles(/datum/gas/zauker) - burned_fuel < 0)
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_zauker = air.get_moles(GAS_ZAUKER)
+ var/burned_fuel = min(20, air.get_moles(GAS_N2), initial_zauker)
+ if(initial_zauker - burned_fuel < 0)
return NO_REACTION
- air.adjust_moles(/datum/gas/zauker, -burned_fuel)
+ air.adjust_moles(GAS_ZAUKER, -burned_fuel)
if(burned_fuel)
energy_released += (460 * burned_fuel)
- air.adjust_moles(/datum/gas/oxygen, (burned_fuel * 0.3))
- air.adjust_moles(/datum/gas/nitrogen, (burned_fuel * 0.7))
+ air.adjust_moles(GAS_O2, (burned_fuel * 0.3))
+ air.adjust_moles(GAS_N2, (burned_fuel * 0.7))
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max((temperature * old_heat_capacity + energy_released) / new_heat_capacity, TCMB))
+ air.set_temperature(max((old_thermal_energy + energy_released) / new_heat_capacity, TCMB))
return REACTING
return NO_REACTION
@@ -928,105 +971,132 @@ nobliumformation = 1001
* Breaks BZ down into nitrogen and plasma in the presence of pluonium.
*/
/datum/gas_reaction/pluonium_bz_response
- priority = 14
+ priority = PLUONIUMBZRESPONSE
name = "Pluonium bz response"
id = "pluonium_bz_response"
/datum/gas_reaction/pluonium_bz_response/init_reqs()
min_requirements = list(
- /datum/gas/pluonium = MINIMUM_MOLE_COUNT,
- /datum/gas/bz = MINIMUM_MOLE_COUNT,
+ GAS_PLUONIUM = MINIMUM_MOLE_COUNT,
+ GAS_BZ = MINIMUM_MOLE_COUNT,
"TEMP" = 260,
"MAX_TEMP" = 280
)
/datum/gas_reaction/pluonium_bz_response/react(datum/gas_mixture/air, datum/holder)
var/old_temperature = air.return_temperature()
- var/consumed_amount = min(old_temperature / 2240 * air.get_moles(/datum/gas/bz) * air.get_moles(/datum/gas/pluonium) / (air.get_moles(/datum/gas/bz) + air.get_moles(/datum/gas/pluonium)), air.get_moles(/datum/gas/bz), air.get_moles(/datum/gas/pluonium))
- if (consumed_amount <= 0 || air.get_moles(/datum/gas/bz) - consumed_amount < 0)
+ var/old_thermal_energy = air.thermal_energy()
+
+ var/initial_bz = air.get_moles(GAS_BZ)
+ var/initial_pluon = air.get_moles(GAS_PLUONIUM)
+
+ var/consumed_amount = min(old_temperature / 2240 * initial_bz * initial_pluon / (initial_bz + initial_pluon), initial_bz, initial_pluon)
+ if(consumed_amount <= 0 || initial_bz - consumed_amount < 0)
return NO_REACTION
- var/old_heat_capacity = air.heat_capacity()
- air.adjust_moles(/datum/gas/bz, -consumed_amount)
- air.adjust_moles(/datum/gas/nitrogen, consumed_amount * 0.5)
- air.adjust_moles(/datum/gas/plasma, consumed_amount * 1)
-
- var/turf/open/location
- if(istype(holder, /datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
- var/datum/pipeline/pipenet = holder
- location = get_turf(pick(pipenet.members))
- else
- location = get_turf(holder)
+ air.adjust_moles(GAS_BZ, -consumed_amount)
+ air.adjust_moles(GAS_N2, consumed_amount * 0.5)
+ air.adjust_moles(GAS_PLASMA, consumed_amount * 1)
var/energy_released = consumed_amount * 2
-
+
+ var/turf/open/location = get_holder_turf(holder)
if (location)
radiation_pulse(location, consumed_amount * 2, 2.5, TRUE, FALSE)
for(var/mob/living/carbon/L in location)
- L.adjust_hallucinations(air.get_moles(/datum/gas/bz) * 0.7) // Yogs -- fixed accidental "path * number"
+ L.adjust_hallucinations(air.get_moles(GAS_BZ) * 0.7) // Yogs -- fixed accidental "path * number"
energy_released += 100
if(energy_released)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max((old_temperature * old_heat_capacity + energy_released) / new_heat_capacity, TCMB))
+ air.set_temperature(max((old_thermal_energy + energy_released) / new_heat_capacity, TCMB))
return REACTING
/datum/gas_reaction/pluonium_tritium_response
- priority = 15
+ priority = PLUONIUMTRITRESPONSE
name = "Pluonium tritium response"
id = "pluonium_tritium_response"
/datum/gas_reaction/pluonium_tritium_response/init_reqs()
min_requirements = list(
- /datum/gas/pluonium = MINIMUM_MOLE_COUNT,
- /datum/gas/tritium = MINIMUM_MOLE_COUNT,
+ GAS_PLUONIUM = MINIMUM_MOLE_COUNT,
+ GAS_TRITIUM = MINIMUM_MOLE_COUNT,
"TEMP" = 150,
"MAX_TEMP" = 340
)
/datum/gas_reaction/pluonium_tritium_response/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
- var/old_heat_capacity = air.heat_capacity()
- var/temperature = air.return_temperature()
- var/turf/open/location = isturf(holder) ? holder : null
- var produced_amount = min(5, air.get_moles(/datum/gas/tritium), air.get_moles(/datum/gas/pluonium))
- if(air.get_moles(/datum/gas/tritium) - produced_amount < 0 || air.get_moles(/datum/gas/pluonium) - produced_amount * 0.01 < 0)
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_pluon = air.get_moles(GAS_PLUONIUM)
+ var/initial_trit = air.get_moles(GAS_TRITIUM)
+ var/produced_amount = min(5, initial_trit, initial_pluon)
+ if(initial_trit - produced_amount < 0 || initial_pluon - produced_amount * 0.01 < 0)
return NO_REACTION
- location.rad_act(produced_amount * 2.4)
- air.adjust_moles(/datum/gas/tritium, -produced_amount)
- air.adjust_moles(/datum/gas/hydrogen, produced_amount)
- air.adjust_moles(/datum/gas/pluonium, -(produced_amount * 0.01))
+ if(isopenturf(holder))
+ var/turf/open/location = holder
+ location.rad_act(produced_amount * 2.4)
+ air.adjust_moles(GAS_TRITIUM, -produced_amount)
+ air.adjust_moles(GAS_H2, produced_amount)
+ air.adjust_moles(GAS_PLUONIUM, -(produced_amount * 0.01))
energy_released += 50
if(energy_released)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max((temperature * old_heat_capacity + energy_released) / new_heat_capacity, TCMB))
+ air.set_temperature(max((old_thermal_energy + energy_released) / new_heat_capacity, TCMB))
return REACTING
/datum/gas_reaction/pluonium_hydrogen_response
- priority = 16
+ priority = PLUONIUMH2RESPONSE
name = "Pluonium hydrogen response"
id = "pluonium_hydrogen_response"
/datum/gas_reaction/pluonium_hydrogen_response/init_reqs()
min_requirements = list(
- /datum/gas/pluonium = MINIMUM_MOLE_COUNT,
- /datum/gas/hydrogen = 150,
+ GAS_PLUONIUM = MINIMUM_MOLE_COUNT,
+ GAS_H2 = 150,
)
/datum/gas_reaction/pluonium_hydrogen_response/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
- var/old_heat_capacity = air.heat_capacity()
- var/temperature = air.return_temperature()
- var produced_amount = min(5, air.get_moles(/datum/gas/hydrogen), air.adjust_moles(/datum/gas/pluonium))
- if(air.get_moles(/datum/gas/hydrogen) - produced_amount < 0)
+ var/old_thermal_energy = air.thermal_energy()
+ var/initial_h2 = air.get_moles(GAS_H2)
+ var/initial_pluon = air.get_moles(GAS_PLUONIUM)
+ var/produced_amount = min(5, initial_h2, initial_pluon)
+ if(initial_h2 - produced_amount < 0)
return NO_REACTION
- air.adjust_moles(/datum/gas/hydrogen, -produced_amount)
- air.adjust_moles(/datum/gas/pluonium, (produced_amount * 0.5))
+ air.adjust_moles(GAS_H2, -produced_amount)
+ air.adjust_moles(GAS_PLUONIUM, (produced_amount * 0.5))
energy_released = produced_amount * 2500
if(energy_released)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.set_temperature(max((temperature * old_heat_capacity - energy_released) / new_heat_capacity, TCMB))
+ air.set_temperature(max((old_thermal_energy - energy_released) / new_heat_capacity, TCMB))
return REACTING
+#undef MIASTER
+#undef FREONFIRE
+#undef PLASMAFIRE
+#undef H2FIRE
+#undef TRITFIRE
+#undef HALONO2REMOVAL
+#undef NITROUSDECOMP
+#undef WATERVAPOR
+#undef FUSION
+#undef COLDFUSION
+#undef NITRIUMFORMATION
+#undef BZFORMATION
+#undef FREONFORMATION
+#undef NITROBALL
+#undef ZAUKERDECOMP
+#undef HEALIUMFORMATION
+#undef PLUONIUMFORMATION
+#undef ZAUKERFORMATION
+#undef HALONFORMATION
+#undef HEXANEFORMATION
+#undef PLUONIUMBZRESPONSE
+#undef PLUONIUMTRITRESPONSE
+#undef PLUONIUMH2RESPONSE
+#undef METALHYDROGEN
+#undef NOBLIUMSUPPRESSION
+#undef NOBLIUMFORMATION
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index 902c3e5dac65..f7dc8a79e3ec 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -99,80 +99,77 @@
var/list/TLV = list( // Breathable air.
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa. Values are min2, min1, max1, max2
"temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66),
- /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
- /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
- /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
- /datum/gas/miasma = new/datum/tlv/(-1, -1, 15, 30),
- /datum/gas/plasma = new/datum/tlv/dangerous,
- /datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
- /datum/gas/bz = new/datum/tlv/dangerous,
- /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
- /datum/gas/water_vapor = new/datum/tlv/dangerous,
- /datum/gas/tritium = new/datum/tlv/dangerous,
- /datum/gas/nitrium = new/datum/tlv/dangerous,
- /datum/gas/dilithium = new/datum/tlv/dangerous,//Yogs -- Dilithium
- /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
- /datum/gas/freon = new/datum/tlv/dangerous,
- /datum/gas/hydrogen = new/datum/tlv/dangerous,
- /datum/gas/healium = new/datum/tlv/dangerous,
- /datum/gas/pluonium = new/datum/tlv/dangerous,
- /datum/gas/zauker = new/datum/tlv/dangerous,
- /datum/gas/halon = new/datum/tlv/dangerous,
- /datum/gas/antinoblium = new/datum/tlv/dangerous,
- /datum/gas/hexane = new/datum/tlv/dangerous
+ GAS_O2 = new/datum/tlv(16, 19, 40, 50), // Partial pressure, kpa
+ GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000),
+ GAS_CO2 = new/datum/tlv(-1, -1, 5, 10),
+ GAS_MIASMA = new/datum/tlv/(-1, -1, 15, 30),
+ GAS_PLASMA = new/datum/tlv/dangerous,
+ GAS_NITROUS = new/datum/tlv/dangerous,
+ GAS_BZ = new/datum/tlv/dangerous,
+ GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
+ GAS_H2O = new/datum/tlv/dangerous,
+ GAS_TRITIUM = new/datum/tlv/dangerous,
+ GAS_NITRIUM = new/datum/tlv/dangerous,
+ GAS_DILITHIUM = new/datum/tlv/dangerous,//Yogs -- Dilithium
+ GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
+ GAS_FREON = new/datum/tlv/dangerous,
+ GAS_H2 = new/datum/tlv/dangerous,
+ GAS_HEALIUM = new/datum/tlv/dangerous,
+ GAS_PLUONIUM = new/datum/tlv/dangerous,
+ GAS_ZAUKER = new/datum/tlv/dangerous,
+ GAS_HALON = new/datum/tlv/dangerous,
+ GAS_HEXANE = new/datum/tlv/dangerous,
)
/obj/machinery/airalarm/server // No checks here.
TLV = list(
"pressure" = new/datum/tlv/no_checks,
"temperature" = new/datum/tlv/no_checks,
- /datum/gas/oxygen = new/datum/tlv/no_checks,
- /datum/gas/nitrogen = new/datum/tlv/no_checks,
- /datum/gas/carbon_dioxide = new/datum/tlv/no_checks,
- /datum/gas/miasma = new/datum/tlv/no_checks,
- /datum/gas/plasma = new/datum/tlv/no_checks,
- /datum/gas/nitrous_oxide = new/datum/tlv/no_checks,
- /datum/gas/bz = new/datum/tlv/no_checks,
- /datum/gas/hypernoblium = new/datum/tlv/no_checks,
- /datum/gas/water_vapor = new/datum/tlv/no_checks,
- /datum/gas/tritium = new/datum/tlv/no_checks,
- /datum/gas/nitrium = new/datum/tlv/no_checks,
- /datum/gas/dilithium = new/datum/tlv/no_checks,//Yogs -- Dilithium
- /datum/gas/pluoxium = new/datum/tlv/no_checks,
- /datum/gas/freon = new/datum/tlv/no_checks,
- /datum/gas/hydrogen = new/datum/tlv/no_checks,
- /datum/gas/healium = new/datum/tlv/dangerous,
- /datum/gas/pluonium = new/datum/tlv/dangerous,
- /datum/gas/halon = new/datum/tlv/dangerous,
- /datum/gas/antinoblium = new/datum/tlv/dangerous,
- /datum/gas/hexane = new/datum/tlv/dangerous
+ GAS_O2 = new/datum/tlv/no_checks,
+ GAS_N2 = new/datum/tlv/no_checks,
+ GAS_CO2 = new/datum/tlv/no_checks,
+ GAS_MIASMA = new/datum/tlv/no_checks,
+ GAS_PLASMA = new/datum/tlv/no_checks,
+ GAS_NITROUS = new/datum/tlv/no_checks,
+ GAS_BZ = new/datum/tlv/no_checks,
+ GAS_HYPERNOB = new/datum/tlv/no_checks,
+ GAS_H2O = new/datum/tlv/no_checks,
+ GAS_TRITIUM = new/datum/tlv/no_checks,
+ GAS_NITRIUM = new/datum/tlv/no_checks,
+ GAS_DILITHIUM = new/datum/tlv/no_checks,//Yogs -- Dilithium
+ GAS_PLUOXIUM = new/datum/tlv/no_checks,
+ GAS_FREON = new/datum/tlv/no_checks,
+ GAS_H2 = new/datum/tlv/no_checks,
+ GAS_HEALIUM = new/datum/tlv/dangerous,
+ GAS_PLUONIUM = new/datum/tlv/dangerous,
+ GAS_HALON = new/datum/tlv/dangerous,
+ GAS_HEXANE = new/datum/tlv/dangerous,
)
/obj/machinery/airalarm/kitchen_cold_room // Kitchen cold rooms start off at -80°C or 193.15°K.
TLV = list(
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
"temperature" = new/datum/tlv(T0C-273.15, T0C-100, T0C-60, T0C),
- /datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
- /datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
- /datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
- /datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5),
- /datum/gas/plasma = new/datum/tlv/dangerous,
- /datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
- /datum/gas/bz = new/datum/tlv/dangerous,
- /datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
- /datum/gas/water_vapor = new/datum/tlv/dangerous,
- /datum/gas/tritium = new/datum/tlv/dangerous,
- /datum/gas/nitrium = new/datum/tlv/dangerous,
- /datum/gas/dilithium = new/datum/tlv/dangerous,//Yogs -- Dilithium
- /datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
- /datum/gas/freon = new/datum/tlv/dangerous,
- /datum/gas/hydrogen = new/datum/tlv/dangerous,
- /datum/gas/healium = new/datum/tlv/dangerous,
- /datum/gas/pluonium = new/datum/tlv/dangerous,
- /datum/gas/zauker = new/datum/tlv/dangerous,
- /datum/gas/halon = new/datum/tlv/dangerous,
- /datum/gas/antinoblium = new/datum/tlv/dangerous,
- /datum/gas/hexane = new/datum/tlv/dangerous
+ GAS_O2 = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
+ GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000),
+ GAS_CO2 = new/datum/tlv(-1, -1, 5, 10),
+ GAS_MIASMA = new/datum/tlv/(-1, -1, 2, 5),
+ GAS_PLASMA = new/datum/tlv/dangerous,
+ GAS_NITROUS = new/datum/tlv/dangerous,
+ GAS_BZ = new/datum/tlv/dangerous,
+ GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
+ GAS_H2O = new/datum/tlv/dangerous,
+ GAS_TRITIUM = new/datum/tlv/dangerous,
+ GAS_NITRIUM = new/datum/tlv/dangerous,
+ GAS_DILITHIUM = new/datum/tlv/dangerous,//Yogs -- Dilithium
+ GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
+ GAS_FREON = new/datum/tlv/dangerous,
+ GAS_H2 = new/datum/tlv/dangerous,
+ GAS_HEALIUM = new/datum/tlv/dangerous,
+ GAS_PLUONIUM = new/datum/tlv/dangerous,
+ GAS_ZAUKER = new/datum/tlv/dangerous,
+ GAS_HALON = new/datum/tlv/dangerous,
+ GAS_HEXANE = new/datum/tlv/dangerous,
)
/obj/machinery/airalarm/unlocked
@@ -231,6 +228,7 @@
..()
wires = new /datum/wires/airalarm(src)
A = get_area(src)
+ LAZYADD(A.airalarms, src)
if(ndir)
setDir(ndir)
@@ -248,8 +246,13 @@
/obj/machinery/airalarm/Destroy()
SSradio.remove_object(src, frequency)
QDEL_NULL(wires)
- atmos_manualOverride(TRUE)
- post_alert(0)
+ if(length(A.airalarms)<2 || A.manual_atmosalm)
+ atmos_manualOverride(TRUE)
+ post_alert(0)
+ else
+ atmos_manualOverride(TRUE)
+ A.atmosalert(0, src)
+ LAZYREMOVE(A.airalarms, src)
return ..()
/obj/machinery/airalarm/Initialize(mapload)
@@ -292,11 +295,11 @@
data["fire_alarm"] = A.fire
var/turf/T = get_turf(src)
- var/datum/gas_mixture/environment = T.return_air()
+ var/datum/gas_mixture/environment = T?.return_air()
var/datum/tlv/cur_tlv
data["environment_data"] = list()
- var/pressure = environment.return_pressure()
+ var/pressure = environment?.return_pressure()
cur_tlv = TLV["pressure"]
data["environment_data"] += list(list(
"name" = "Pressure",
@@ -304,7 +307,7 @@
"unit" = "kPa",
"danger_level" = cur_tlv.get_danger_level(pressure)
))
- var/temperature = environment.return_temperature()
+ var/temperature = environment?.return_temperature()
cur_tlv = TLV["temperature"]
data["environment_data"] += list(list(
"name" = "Temperature",
@@ -312,14 +315,14 @@
"unit" = "K ([round(temperature - T0C, 0.1)]C)",
"danger_level" = cur_tlv.get_danger_level(temperature)
))
- var/total_moles = environment.total_moles()
- var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume()
- for(var/gas_id in environment.get_gases())
+ var/total_moles = environment?.total_moles()
+ var/partial_pressure = R_IDEAL_GAS_EQUATION * environment?.return_temperature() / environment?.return_volume()
+ for(var/gas_id in environment?.get_gases())
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
continue
cur_tlv = TLV[gas_id]
data["environment_data"] += list(list(
- "name" = GLOB.meta_gas_info[gas_id][META_GAS_NAME],
+ "name" = GLOB.gas_data.names[gas_id],
"value" = environment.get_moles(gas_id) / total_moles * 100,
"unit" = "%",
"danger_level" = cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)
@@ -388,11 +391,11 @@
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1))
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2))
- for(var/gas_id in GLOB.meta_gas_info)
+ for(var/gas_id in GLOB.gas_data.names)
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
continue
selected = TLV[gas_id]
- thresholds += list(list("name" = GLOB.meta_gas_info[gas_id][META_GAS_NAME], "settings" = list()))
+ thresholds += list(list("name" = GLOB.gas_data.names[gas_id], "settings" = list()))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1))
@@ -533,7 +536,7 @@
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
- "set_filters" = list(/datum/gas/carbon_dioxide),
+ "set_filters" = list(GAS_CO2),
"scrubbing" = 1,
"widenet" = 0
), signal_source)
@@ -548,25 +551,24 @@
send_signal(device_id, list(
"power" = 1,
"set_filters" = list(
- /datum/gas/carbon_dioxide,
- /datum/gas/miasma,
- /datum/gas/plasma,
- /datum/gas/water_vapor,
- /datum/gas/hypernoblium,
- /datum/gas/nitrous_oxide,
- /datum/gas/nitrium,
- /datum/gas/tritium,
- /datum/gas/bz,
- /datum/gas/pluoxium,
- /datum/gas/dilithium,//Yogs -- Adds Dilithium
- /datum/gas/freon,
- /datum/gas/hydrogen,
- /datum/gas/healium,
- /datum/gas/pluonium,
- /datum/gas/zauker,
- /datum/gas/halon,
- /datum/gas/antinoblium,
- /datum/gas/hexane
+ GAS_CO2,
+ GAS_MIASMA,
+ GAS_PLASMA,
+ GAS_H2O,
+ GAS_HYPERNOB,
+ GAS_NITROUS,
+ GAS_NITRIUM,
+ GAS_TRITIUM,
+ GAS_BZ,
+ GAS_PLUOXIUM,//yogs comma
+ GAS_DILITHIUM,//Yogs -- Adds Dilithium
+ GAS_FREON,
+ GAS_H2,
+ GAS_HEALIUM,
+ GAS_PLUONIUM,
+ GAS_ZAUKER,
+ GAS_HALON,
+ GAS_HEXANE
),
"scrubbing" = 1,
"widenet" = 1
@@ -665,13 +667,16 @@
post_alert(0)
return
- var/turf/location = get_turf(src)
- if(!location)
+ if(!isopenturf(get_turf(src)))
return
var/datum/tlv/cur_tlv
- var/datum/gas_mixture/environment = location.return_air()
+ var/datum/gas_mixture/environment = return_air()
+
+ if(!environment)
+ return
+
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume()
cur_tlv = TLV["pressure"]
@@ -708,9 +713,13 @@
else
AA.manual_override = TRUE
+#define ALARM_LEVEL_CLEAR 0
+#define ALARM_LEVEL_MINOR 1
+#define ALARM_LEVEL_SEVERE 2
+
/obj/machinery/airalarm/proc/post_alert(alert_level)
var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency)
- if(alert_level>0 && !manual_override)
+ if(alert_level > 0 && !manual_override)
trigger_reset = TRUE
else
trigger_reset = FALSE
@@ -722,23 +731,28 @@
return
var/datum/signal/alert_signal = new(list(
- "zone" = get_area_name(src),
- "type" = "Atmospheric"
+ "zone" = A,
+ "type" = "Atmospheric",
))
- if(alert_level==2)
- alert_signal.data["alert"] = "severe"
- A.set_vacuum_alarm_effect()
- else if (alert_level==1)
- alert_signal.data["alert"] = "minor"
- else if (alert_level==0)
- alert_signal.data["alert"] = "clear"
- A.unset_vacuum_alarm_effect()
+ switch(alert_level)
+ if(ALARM_LEVEL_CLEAR)
+ alert_signal.data["alert"] = ATMOS_ALARM_CLEAR
+ A.unset_vacuum_alarm_effect()
+ if(ALARM_LEVEL_MINOR)
+ alert_signal.data["alert"] = ATMOS_ALARM_MINOR
+ if(ALARM_LEVEL_SEVERE)
+ alert_signal.data["alert"] = ATMOS_ALARM_SEVERE
+ A.set_vacuum_alarm_effect()
frequency.post_signal(src, alert_signal, range = -1)
for(var/obj/machinery/airalarm/AA in A)
AA.update_appearance(UPDATE_ICON)
+#undef ALARM_LEVEL_CLEAR
+#undef ALARM_LEVEL_MINOR
+#undef ALARM_LEVEL_SEVERE
+
/obj/machinery/airalarm/proc/apply_danger_level()
var/new_area_danger_level = 0
diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm
index c61fdc65c383..73f2b391ca04 100644
--- a/code/modules/atmospherics/machinery/atmosmachinery.dm
+++ b/code/modules/atmospherics/machinery/atmosmachinery.dm
@@ -23,6 +23,10 @@ GLOBAL_LIST_EMPTY(pipeimages)
resistance_flags = FIRE_PROOF
max_integrity = 200
obj_flags = CAN_BE_HIT | ON_BLUEPRINTS
+ ///Is the thing being rebuilt by SSair or not. Prevents list bloat
+ var/rebuilding = FALSE
+ ///If we should init and immediately start processing
+ var/init_processing = FALSE
var/can_unwrench = 0
var/initialize_directions = 0
var/pipe_color
@@ -53,19 +57,21 @@ GLOBAL_LIST_EMPTY(pipeimages)
nodes = new(device_type)
if (!armor)
armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 100, ACID = 70)
+ init_processing = process
..()
- if(process)
- SSair.atmos_machinery += src
- SetInitDirections()
+ set_init_directions()
+
+/obj/machinery/atmospherics/Initialize(mapload)
+ if(init_processing)
+ SSair_machinery.start_processing_machine(src)
+ return ..()
/obj/machinery/atmospherics/Destroy()
for(var/i in 1 to device_type)
- nullifyNode(i)
-
- SSair.atmos_machinery -= src
- if(SSair.currentpart == SSAIR_ATMOSMACHINERY)
- SSair.currentrun -= src
- SSair.pipenets_needing_rebuilt -= src
+ nullify_node(i)
+
+ SSair_machinery.stop_processing_machine(src)
+ SSair.rebuild_queue -= src
dropContents()
if(pipe_vision_img)
@@ -77,27 +83,36 @@ GLOBAL_LIST_EMPTY(pipeimages)
/obj/machinery/atmospherics/proc/destroy_network()
return
-/obj/machinery/atmospherics/proc/build_network()
- // Called to build a network from this node
+/obj/machinery/atmospherics/proc/rebuild_pipes()
+ var/list/targets = get_rebuild_targets()
+ rebuilding = FALSE
+ for(var/datum/pipeline/build_off as anything in targets)
+ build_off.build_pipeline(src) //This'll add to the expansion queue
+
+/obj/machinery/atmospherics/proc/get_rebuild_targets()
return
-/obj/machinery/atmospherics/proc/nullifyNode(i)
- if(nodes[i])
- var/obj/machinery/atmospherics/N = nodes[i]
- N.disconnect(src)
- nodes[i] = null
+/obj/machinery/atmospherics/proc/nullify_node(i)
+ if(!nodes[i])
+ return
+ var/obj/machinery/atmospherics/N = nodes[i]
+ N.disconnect(src)
+ nodes[i] = null
-/obj/machinery/atmospherics/proc/getNodeConnects()
+/obj/machinery/atmospherics/proc/get_node_connects()
var/list/node_connects = list()
node_connects.len = device_type
+ var/init_directions = get_init_directions()
for(var/i in 1 to device_type)
- for(var/D in GLOB.cardinals)
- if(D & GetInitDirections())
- if(D in node_connects)
- continue
- node_connects[i] = D
- break
+ for(var/direction in GLOB.cardinals)
+ if(!(direction & init_directions))
+ continue
+ if(direction in node_connects)
+ continue
+ node_connects[i] = direction
+ break
+
return node_connects
/obj/machinery/atmospherics/proc/normalize_cardinal_directions()
@@ -108,9 +123,9 @@ GLOBAL_LIST_EMPTY(pipeimages)
setDir(EAST)
//this is called just after the air controller sets up turfs
-/obj/machinery/atmospherics/proc/atmosinit(list/node_connects)
+/obj/machinery/atmospherics/proc/atmos_init(list/node_connects)
if(!node_connects) //for pipes where order of nodes doesn't matter
- node_connects = getNodeConnects()
+ node_connects = get_node_connects()
for(var/i in 1 to device_type)
for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[i]))
@@ -119,7 +134,7 @@ GLOBAL_LIST_EMPTY(pipeimages)
break
update_appearance(UPDATE_ICON)
-/obj/machinery/atmospherics/proc/setPipingLayer(new_layer)
+/obj/machinery/atmospherics/proc/set_piping_layer(new_layer)
piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer
update_appearance(UPDATE_ICON)
@@ -131,43 +146,54 @@ GLOBAL_LIST_EMPTY(pipeimages)
return connection_check(target, piping_layer)
//Find a connecting /obj/machinery/atmospherics in specified direction
-/obj/machinery/atmospherics/proc/findConnecting(direction, prompted_layer)
- for(var/obj/machinery/atmospherics/target in get_step(src, direction))
- if(target.initialize_directions & get_dir(target,src))
- if(connection_check(target, prompted_layer))
- return target
+/obj/machinery/atmospherics/proc/find_connecting(direction, prompted_layer)
+ for(var/obj/machinery/atmospherics/target in get_step_multiz(src, direction))
+ if(!(target.initialize_directions & get_dir(target,src)))
+ continue
+ if(connection_check(target, prompted_layer))
+ return target
/obj/machinery/atmospherics/proc/connection_check(obj/machinery/atmospherics/target, given_layer)
- if(isConnectable(target, given_layer) && target.isConnectable(src, given_layer) && (target.initialize_directions & get_dir(target,src)))
- return TRUE
- return FALSE
+ if(!((initialize_directions & get_dir(src, target)) && (target.initialize_directions & get_dir(target, src))))
+ return FALSE
+
+ if(!is_connectable(target, given_layer) || !target.is_connectable(src, given_layer))
+ return FALSE
+
+ return TRUE
-/obj/machinery/atmospherics/proc/isConnectable(obj/machinery/atmospherics/target, given_layer)
+
+/obj/machinery/atmospherics/proc/is_connectable(obj/machinery/atmospherics/target, given_layer)
if(isnull(given_layer))
given_layer = piping_layer
+
+ if(target.loc == loc)
+ return FALSE
+
if((target.piping_layer == given_layer) || (target.pipe_flags & PIPING_ALL_LAYER))
return TRUE
+
return FALSE
/obj/machinery/atmospherics/proc/pipeline_expansion()
return nodes
-/obj/machinery/atmospherics/proc/SetInitDirections()
+/obj/machinery/atmospherics/proc/set_init_directions()
return
-/obj/machinery/atmospherics/proc/GetInitDirections()
+/obj/machinery/atmospherics/proc/get_init_directions()
return initialize_directions
-/obj/machinery/atmospherics/proc/returnPipenet()
+/obj/machinery/atmospherics/proc/return_pipenet()
return
-/obj/machinery/atmospherics/proc/returnPipenetAir()
+/obj/machinery/atmospherics/proc/return_pipenet_airs()
return
-/obj/machinery/atmospherics/proc/setPipenet()
+/obj/machinery/atmospherics/proc/set_pipenet()
return
-/obj/machinery/atmospherics/proc/replacePipenet()
+/obj/machinery/atmospherics/proc/replace_pipenet()
return
/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
@@ -181,7 +207,7 @@ GLOBAL_LIST_EMPTY(pipeimages)
if(istype(W, /obj/item/pipe)) //lets you autodrop
var/obj/item/pipe/pipe = W
if(user.dropItemToGround(pipe))
- pipe.setPipingLayer(piping_layer) //align it with us
+ pipe.set_piping_layer(piping_layer) //align it with us
return TRUE
else
return ..()
@@ -265,13 +291,13 @@ GLOBAL_LIST_EMPTY(pipeimages)
if(!(flags_1 & NODECONSTRUCT_1))
if(can_unwrench)
var/obj/item/pipe/stored = new construction_type(loc, null, dir, src)
- stored.setPipingLayer(piping_layer)
+ stored.set_piping_layer(piping_layer)
if(!disassembled)
stored.obj_integrity = stored.max_integrity * 0.5
transfer_fingerprints_to(stored)
..()
-/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255), piping_layer=3, trinary = FALSE)
+/obj/machinery/atmospherics/proc/get_pipe_image(iconset, iconstate, direction, col=rgb(255,255,255), piping_layer=3, trinary = FALSE)
//Add identifiers for the iconset
if(GLOB.iconsetids[iconset] == null)
@@ -292,15 +318,15 @@ GLOBAL_LIST_EMPTY(pipeimages)
if(can_unwrench)
add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY)
pipe_color = obj_color
- setPipingLayer(set_layer)
+ set_piping_layer(set_layer)
var/turf/T = get_turf(src)
level = T.intact ? 2 : 1
- atmosinit()
+ atmos_init()
var/list/nodes = pipeline_expansion()
for(var/obj/machinery/atmospherics/A in nodes)
- A.atmosinit()
- A.addMember(src)
- build_network()
+ A.atmos_init()
+ A.add_member(src)
+ SSair.add_to_rebuild_queue(src)
/obj/machinery/atmospherics/Entered(atom/movable/AM)
if(istype(AM, /mob/living))
@@ -323,7 +349,7 @@ GLOBAL_LIST_EMPTY(pipeimages)
if(user in buckled_mobs)// fixes buckle ventcrawl edgecase fuck bug
return
- var/obj/machinery/atmospherics/target_move = findConnecting(direction, user.ventcrawl_layer)
+ var/obj/machinery/atmospherics/target_move = find_connecting(direction, user.ventcrawl_layer)
if(target_move)
if(target_move.can_crawl_through())
if(is_type_in_typecache(target_move, GLOB.ventcrawl_machinery))
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm b/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm
index 5e1428559345..5f3741f24519 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm
@@ -6,7 +6,7 @@
device_type = BINARY
layer = GAS_PUMP_LAYER
-/obj/machinery/atmospherics/components/binary/SetInitDirections()
+/obj/machinery/atmospherics/components/binary/set_init_directions()
switch(dir)
if(NORTH, SOUTH)
initialize_directions = NORTH|SOUTH
@@ -17,7 +17,7 @@
update_appearance(UPDATE_ICON)
..()
-/obj/machinery/atmospherics/components/binary/getNodeConnects()
+/obj/machinery/atmospherics/components/binary/get_node_connects()
return list(turn(dir, 180), dir)
///Used by binary devices to set what the offset will be for each layer
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
index 9c9a7203f343..a309095d2716 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
@@ -76,7 +76,6 @@
last_pressure_delta = 0
/obj/machinery/atmospherics/components/binary/circulator/process_atmos()
- ..()
update_icon_nopipes()
/obj/machinery/atmospherics/components/binary/circulator/update_overlays()
@@ -86,11 +85,11 @@
for(var/direction in GLOB.cardinals)
if(!(direction & initialize_directions))
continue
- var/obj/machinery/atmospherics/node = findConnecting(direction)
+ var/obj/machinery/atmospherics/node = find_connecting(direction)
var/image/cap
if(node)
- cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer)
+ cap = get_pipe_image(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer)
. += cap
@@ -164,37 +163,37 @@
if(node1)
node1.disconnect(src)
nodes[1] = null
- nullifyPipenet(parents[1])
+ nullify_pipenet(parents[1])
if(node2)
node2.disconnect(src)
nodes[2] = null
- nullifyPipenet(parents[2])
+ nullify_pipenet(parents[2])
if(anchored)
- SetInitDirections()
- atmosinit()
+ set_init_directions()
+ atmos_init()
node1 = nodes[1]
if(node1)
- node1.atmosinit()
- node1.addMember(src)
+ node1.atmos_init()
+ node1.add_member(src)
node2 = nodes[2]
if(node2)
- node2.atmosinit()
- node2.addMember(src)
+ node2.atmos_init()
+ node2.add_member(src)
SSair.add_to_rebuild_queue(src)
update_appearance(UPDATE_ICON)
return TRUE
-/obj/machinery/atmospherics/components/binary/circulator/SetInitDirections()
+/obj/machinery/atmospherics/components/binary/circulator/set_init_directions()
switch(dir)
if(NORTH, SOUTH)
initialize_directions = EAST|WEST
if(EAST, WEST)
initialize_directions = NORTH|SOUTH
-/obj/machinery/atmospherics/components/binary/circulator/getNodeConnects()
+/obj/machinery/atmospherics/components/binary/circulator/get_node_connects()
if(flipped)
return list(turn(dir, 270), turn(dir, 90))
return list(turn(dir, 90), turn(dir, 270))
@@ -255,7 +254,7 @@
generator.update_appearance(UPDATE_ICON)
generator = null
-/obj/machinery/atmospherics/components/binary/circulator/setPipingLayer(new_layer)
+/obj/machinery/atmospherics/components/binary/circulator/set_piping_layer(new_layer)
..()
pixel_x = 0
pixel_y = 0
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
index 607797d55d5a..d82bde6274b8 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
@@ -42,7 +42,7 @@
/obj/machinery/atmospherics/components/binary/dp_vent_pump/update_icon_nopipes()
cut_overlays()
if(showpipe)
- var/image/cap = getpipeimage(icon, "dpvent_cap", dir, piping_layer = piping_layer)
+ var/image/cap = get_pipe_image(icon, "dpvent_cap", dir, piping_layer = piping_layer)
add_overlay(cap)
if(!on || !is_operational())
@@ -51,8 +51,8 @@
icon_state = pump_direction ? "vent_out" : "vent_in"
/obj/machinery/atmospherics/components/binary/dp_vent_pump/process_atmos()
- ..()
-
+ if(welded || !is_operational() || !isopenturf(loc))
+ return FALSE
if(!on)
return
var/datum/gas_mixture/air1 = airs[1]
@@ -73,19 +73,14 @@
if(air1.return_temperature() > 0)
var/transfer_moles = pressure_delta*environment.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
- var/datum/gas_mixture/removed = air1.remove(transfer_moles)
- //Removed can be null if there is no atmosphere in air1
- if(!removed)
- return
+ loc.assume_air_moles(air1, transfer_moles)
- loc.assume_air(removed)
- air_update_turf()
+
var/datum/pipeline/parent1 = parents[1]
- parent1.update = 1
+ parent1.update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED
else //external -> output
-
if(environment.return_pressure() > 0)
var/our_multiplier = air2.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION)
var/moles_delta = 10000 * our_multiplier
@@ -93,20 +88,15 @@
moles_delta = min(moles_delta, (environment_pressure - output_pressure_max) * environment.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION))
if(pressure_checks&INPUT_MIN)
moles_delta = min(moles_delta, (input_pressure_min - air2.return_pressure()) * our_multiplier)
-
- if(moles_delta > 0)
- var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
- if (isnull(removed)) // in space
- return
- air2.merge(removed)
- air_update_turf()
+ if(moles_delta > 0)
+ loc.transfer_air(air2, moles_delta)
+
var/datum/pipeline/parent2 = parents[2]
- parent2.update = 1
-
- //Radio remote control
+ parent2.update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED
+//Radio remote control
/obj/machinery/atmospherics/components/binary/dp_vent_pump/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
@@ -130,7 +120,7 @@
))
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
-/obj/machinery/atmospherics/components/binary/dp_vent_pump/atmosinit()
+/obj/machinery/atmospherics/components/binary/dp_vent_pump/atmos_init()
..()
if(frequency)
set_frequency(frequency)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
index 01ec68fa1c20..774eeaa8a0cf 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
@@ -55,35 +55,15 @@ Passive gate is similar to the regular pump except:
cut_overlays()
icon_state = "passgate_off-[set_overlay_offset(piping_layer)]"
if(on)
- add_overlay(getpipeimage(icon, "passgate_on-[set_overlay_offset(piping_layer)]"))
+ add_overlay(get_pipe_image(icon, "passgate_on-[set_overlay_offset(piping_layer)]"))
/obj/machinery/atmospherics/components/binary/passive_gate/process_atmos()
- ..()
if(!on)
return
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
-
- 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
-
- //Calculate necessary moles to transfer using PV = nRT
- if((air1.total_moles() > 0) && (air1.return_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.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
-
- //Actually transfer the gas
- var/datum/gas_mixture/removed = air1.remove(transfer_moles)
- air2.merge(removed)
-
+ if(air1.release_gas_to(air2, target_pressure))
update_parents()
@@ -150,7 +130,7 @@ Passive gate is similar to the regular pump except:
investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful
update_appearance(UPDATE_ICON)
-/obj/machinery/atmospherics/components/binary/passive_gate/atmosinit()
+/obj/machinery/atmospherics/components/binary/passive_gate/atmos_init()
..()
if(frequency)
set_frequency(frequency)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm
index 7d3c7949b7d7..2556d9917447 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm
@@ -119,7 +119,7 @@
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS)
update_appearance(UPDATE_ICON)
-/obj/machinery/atmospherics/components/binary/pressure_valve/atmosinit()
+/obj/machinery/atmospherics/components/binary/pressure_valve/atmos_init()
. = ..()
if(frequency)
set_frequency(frequency)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
index 76f2b98782d7..be8c8dbdb6e2 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
@@ -53,27 +53,21 @@
icon_state = (on && is_operational()) ? "pump_on-[set_overlay_offset(piping_layer)]" : "pump_off-[set_overlay_offset(piping_layer)]"
/obj/machinery/atmospherics/components/binary/pump/process_atmos()
-// ..()
if(!on || !is_operational())
return
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
-
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
-
//Calculate necessary moles to transfer using PV=nRT
if((air1.total_moles() > 0) && (air1.return_temperature()>0))
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
- //Actually transfer the gas
- var/datum/gas_mixture/removed = air1.remove(transfer_moles)
- air2.merge(removed)
+ air1.transfer_to(air2,transfer_moles)
update_parents()
@@ -139,7 +133,7 @@
investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - makes supermatter invest useful
update_appearance(UPDATE_ICON)
-/obj/machinery/atmospherics/components/binary/pump/atmosinit()
+/obj/machinery/atmospherics/components/binary/pump/atmos_init()
..()
if(frequency)
set_frequency(frequency)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm
index 3a489e3821af..25d30312fc03 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm
@@ -33,7 +33,7 @@
icon_state = "tpump_[on && is_operational() ? "on" : "off"]-[set_overlay_offset(piping_layer)]"
/obj/machinery/atmospherics/components/binary/temperature_pump/process_atmos()
- ..()
+
if(!on || !is_operational())
return
@@ -42,7 +42,6 @@
if(!QUANTIZE(air_input.total_moles()) || !QUANTIZE(air_output.total_moles())) //Don't transfer if there's no gas
return
-
var/datum/gas_mixture/remove_input = air_input.remove_ratio(0.9)
var/datum/gas_mixture/remove_output = air_output.remove_ratio(0.9)
@@ -50,7 +49,7 @@
if(coolant_temperature_delta > 0)
var/input_capacity = remove_input.heat_capacity()
- var/output_capacity = remove_output.heat_capacity()
+ var/output_capacity = air_output.heat_capacity()
var/cooling_heat_amount = (heat_transfer_rate * 0.01) * coolant_temperature_delta * (input_capacity * output_capacity / (input_capacity + output_capacity))
remove_input.set_temperature(max(remove_input.return_temperature() - (cooling_heat_amount / input_capacity), TCMB))
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
index 89e9b7b2a43a..86449e9eb00b 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
@@ -14,6 +14,8 @@ It's like a regular ol' straight pipe, but you can turn it on and off.
interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_OPEN //Intentionally no allow_silicon flag
pipe_flags = PIPING_CARDINAL_AUTONORMALIZE
+ custom_reconcilation = TRUE
+
var/frequency = 0
var/id = null
@@ -24,6 +26,26 @@ It's like a regular ol' straight pipe, but you can turn it on and off.
var/switching = FALSE
+
+/obj/machinery/atmospherics/components/binary/valve/Destroy()
+ //Should only happen on extreme circumstances
+ if(on)
+ //Let's give presumably now-severed pipenets a chance to scramble for what's happening at next SSair fire()
+ if(parents[1])
+ parents[1].update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED
+ if(parents[2])
+ parents[2].update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED
+ . = ..()
+
+// This is what handles the actual functionality of combining 2 pipenets when the valve is open
+// Basically when a pipenet updates it will consider both sides to be the same for the purpose of the gas update
+/obj/machinery/atmospherics/components/binary/valve/return_pipenets_for_reconcilation(datum/pipeline/requester)
+ . = ..()
+ if(!on)
+ return
+ . |= parents[1]
+ . |= parents[2]
+
/obj/machinery/atmospherics/components/binary/valve/update_icon_nopipes(animation = FALSE)
normalize_cardinal_directions()
if(animation)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
index 9092deda1252..74c6be7c3f26 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
@@ -55,7 +55,6 @@
icon_state = on && is_operational() ? "volpump_on-[set_overlay_offset(piping_layer)]" : "volpump_off-[set_overlay_offset(piping_layer)]"
/obj/machinery/atmospherics/components/binary/volume_pump/process_atmos()
-// ..()
if(!on || !is_operational())
return
@@ -73,19 +72,15 @@
if(overclocked && (output_starting_pressure-input_starting_pressure > 1000))//Overclocked pumps can only force gas a certain amount.
return
-
- var/transfer_ratio = transfer_rate / air1.return_volume()
-
- var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
-
if(overclocked)//Some of the gas from the mixture leaks to the environment when overclocked
var/turf/open/T = loc
if(istype(T))
- var/datum/gas_mixture/leaked = removed.remove_ratio(VOLUME_PUMP_LEAK_AMOUNT)
+ var/datum/gas_mixture/leaked = air1.remove_ratio(VOLUME_PUMP_LEAK_AMOUNT)
T.assume_air(leaked)
- T.air_update_turf()
- air2.merge(removed)
+ var/transfer_ratio = transfer_rate / air1.return_volume()
+
+ air1.transfer_ratio_to(air2,transfer_ratio)
update_parents()
@@ -126,7 +121,7 @@
data["max_rate"] = round(MAX_TRANSFER_RATE)
return data
-/obj/machinery/atmospherics/components/binary/volume_pump/atmosinit()
+/obj/machinery/atmospherics/components/binary/volume_pump/atmos_init()
..()
set_frequency(frequency)
diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm
index 95ca4b666034..2f1863532f74 100644
--- a/code/modules/atmospherics/machinery/components/components_base.dm
+++ b/code/modules/atmospherics/machinery/components/components_base.dm
@@ -6,10 +6,14 @@
var/showpipe = TRUE
var/shift_underlay_only = TRUE //Layering only shifts underlay?
+ var/update_parents_after_rebuild = FALSE
+
var/list/datum/pipeline/parents
var/list/datum/gas_mixture/airs
var/startingvolume = 200
+ var/custom_reconcilation = FALSE
+
/obj/machinery/atmospherics/components/New()
parents = new(device_type)
airs = new(device_type)
@@ -17,8 +21,11 @@
..()
for(var/i in 1 to device_type)
- var/datum/gas_mixture/A = new(startingvolume)
- airs[i] = A
+ if(airs[i])
+ continue
+ var/datum/gas_mixture/component_mixture = new
+ component_mixture.set_volume(startingvolume)
+ airs[i] = component_mixture
// Iconnery
@@ -54,52 +61,73 @@
/obj/machinery/atmospherics/components/proc/get_pipe_underlay(state, dir, color = null)
if(color)
- . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, color, piping_layer = shift_underlay_only ? piping_layer : 3)
+ . = get_pipe_image('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, color, piping_layer = shift_underlay_only ? piping_layer : 3)
else
- . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, piping_layer = shift_underlay_only ? piping_layer : 3)
+ . = get_pipe_image('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, piping_layer = shift_underlay_only ? piping_layer : 3)
// Pipenet stuff; housekeeping
-/obj/machinery/atmospherics/components/nullifyNode(i)
- if(nodes[i])
- nullifyPipenet(parents[i])
- QDEL_NULL(airs[i])
- ..()
+/obj/machinery/atmospherics/components/nullify_node(i)
+ if(parents[i])
+ nullify_pipenet(parents[i])
+ airs[i] = null
+ return ..()
/obj/machinery/atmospherics/components/on_construction()
..()
update_parents()
-/obj/machinery/atmospherics/components/build_network()
+/obj/machinery/atmospherics/components/rebuild_pipes()
+ . = ..()
+ if(update_parents_after_rebuild)
+ update_parents()
+
+/obj/machinery/atmospherics/components/get_rebuild_targets()
+ var/list/to_return = list()
for(var/i in 1 to device_type)
- if(!parents[i])
- parents[i] = new /datum/pipeline()
- var/datum/pipeline/P = parents[i]
- P.build_pipeline(src)
+ if(parents[i])
+ continue
+ parents[i] = new /datum/pipeline()
+ to_return += parents[i]
+ return to_return
-/obj/machinery/atmospherics/components/proc/nullifyPipenet(datum/pipeline/reference)
+/obj/machinery/atmospherics/components/proc/nullify_pipenet(datum/pipeline/reference)
if(!reference)
- CRASH("nullifyPipenet(null) called by [type] on [COORD(src)]")
- var/i = parents.Find(reference)
- reference.other_airs -= airs[i]
- reference.other_atmosmch -= src
- parents[i] = null
+ CRASH("nullify_pipenet(null) called by [type] on [COORD(src)]")
+
+ for (var/i in 1 to parents.len)
+ if (parents[i] == reference)
+ reference.other_airs -= airs[i] // Disconnects from the pipeline side
+ parents[i] = null // Disconnects from the machinery side.
+
+ reference.other_atmos_machines -= src
+
+ if(!length(reference.other_atmos_machines) && !length(reference.members))
+ if(QDESTROYING(reference))
+ CRASH("nullify_pipenet() called on qdeleting [reference]")
+ qdel(reference)
-/obj/machinery/atmospherics/components/returnPipenetAir(datum/pipeline/reference)
- return airs[parents.Find(reference)]
+// We should return every air sharing a parent
+/obj/machinery/atmospherics/components/return_pipenet_airs(datum/pipeline/reference)
+ var/list/returned_air = list()
+
+ for (var/i in 1 to parents.len)
+ if (parents[i] == reference)
+ returned_air += airs[i]
+ return returned_air
/obj/machinery/atmospherics/components/pipeline_expansion(datum/pipeline/reference)
if(reference)
return list(nodes[parents.Find(reference)])
return ..()
-/obj/machinery/atmospherics/components/setPipenet(datum/pipeline/reference, obj/machinery/atmospherics/A)
+/obj/machinery/atmospherics/components/set_pipenet(datum/pipeline/reference, obj/machinery/atmospherics/A)
parents[nodes.Find(A)] = reference
-/obj/machinery/atmospherics/components/returnPipenet(obj/machinery/atmospherics/A = nodes[1]) //returns parents[1] if called without argument
+/obj/machinery/atmospherics/components/return_pipenet(obj/machinery/atmospherics/A = nodes[1]) //returns parents[1] if called without argument
return parents[nodes.Find(A)]
-/obj/machinery/atmospherics/components/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
+/obj/machinery/atmospherics/components/replace_pipenet(datum/pipeline/Old, datum/pipeline/New)
parents[parents.Find(Old)] = New
/obj/machinery/atmospherics/components/unsafe_pressure_release(mob/user, pressures)
@@ -117,15 +145,9 @@
times_lost++
var/shared_loss = lost/times_lost
- var/datum/gas_mixture/to_release
for(var/i in 1 to device_type)
var/datum/gas_mixture/air = airs[i]
- if(!to_release)
- to_release = air.remove(shared_loss)
- continue
- to_release.merge(air.remove(shared_loss))
- T.assume_air(to_release)
- air_update_turf(1)
+ T.assume_air_moles(air, shared_loss)
/obj/machinery/atmospherics/components/proc/safe_input(title, text, default_set)
var/new_value = input(usr,text,title,default_set) as num
@@ -136,6 +158,11 @@
// Helpers
/obj/machinery/atmospherics/components/proc/update_parents()
+ if(!SSair.initialized)
+ return
+ if(rebuilding)
+ update_parents_after_rebuild = TRUE
+ return
for(var/i in 1 to device_type)
var/datum/pipeline/parent = parents[i]
if(!parent)
@@ -147,7 +174,13 @@
/obj/machinery/atmospherics/components/return_pipenets()
. = list()
for(var/i in 1 to device_type)
- . += returnPipenet(nodes[i])
+ . += return_pipenet(nodes[i])
+
+/obj/machinery/atmospherics/components/proc/return_pipenets_for_reconcilation(datum/pipeline/requester)
+ return list()
+
+/obj/machinery/atmospherics/components/proc/return_airs_for_reconcilation(datum/pipeline/requester)
+ return list()
// UI Stuff
@@ -159,5 +192,30 @@
// Tool acts
+/obj/machinery/atmospherics/components/proc/disconnect_nodes()
+ for(var/i in 1 to device_type)
+ var/obj/machinery/atmospherics/node = nodes[i]
+ if(node)
+ if(src in node.nodes) //Only if it's actually connected. On-pipe version would is one-sided.
+ node.disconnect(src)
+ nodes[i] = null
+ if(parents[i])
+ nullify_pipenet(parents[i])
+
+/obj/machinery/atmospherics/components/proc/connect_nodes()
+ atmos_init()
+ for(var/i in 1 to device_type)
+ var/obj/machinery/atmospherics/node = nodes[i]
+ if(node)
+ node.atmos_init()
+ node.add_member(src)
+ SSair.add_to_rebuild_queue(src)
+
+/obj/machinery/atmospherics/components/proc/change_nodes_connection(disconnect)
+ if(disconnect)
+ disconnect_nodes()
+ return
+ connect_nodes()
+
/obj/machinery/atmospherics/components/return_analyzable_air()
return airs
diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_fuel_datums.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_fuel_datums.dm
index 54a4e005704d..f9dd6525ecfb 100644
--- a/code/modules/atmospherics/machinery/components/fusion/hfr_fuel_datums.dm
+++ b/code/modules/atmospherics/machinery/components/fusion/hfr_fuel_datums.dm
@@ -50,9 +50,9 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list())
fuel_consumption_multiplier = 3.3
gas_production_multiplier = 1.4
temperature_change_multiplier = 0.6
- requirements = list(/datum/gas/plasma, /datum/gas/oxygen)
- primary_products = list(/datum/gas/carbon_dioxide, /datum/gas/water_vapor)
- secondary_products = list(/datum/gas/carbon_dioxide, /datum/gas/freon, /datum/gas/tritium, /datum/gas/hydrogen, /datum/gas/pluoxium, /datum/gas/halon)
+ requirements = list(GAS_PLASMA, GAS_O2)
+ primary_products = list(GAS_CO2, GAS_H2O)
+ secondary_products = list(GAS_CO2, GAS_FREON, GAS_TRITIUM, GAS_H2, GAS_PLUOXIUM, GAS_HALON)
meltdown_flags = HYPERTORUS_FLAG_BASE_EXPLOSION | HYPERTORUS_FLAG_MINIMUM_SPREAD
/datum/hfr_fuel/hydrogen_oxy_fuel
@@ -64,9 +64,9 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list())
fuel_consumption_multiplier = 1.1
gas_production_multiplier = 0.9
temperature_change_multiplier = 0.75
- requirements = list(/datum/gas/hydrogen, /datum/gas/oxygen)
- primary_products = list(/datum/gas/nitrogen)
- secondary_products = list(/datum/gas/plasma, /datum/gas/freon, /datum/gas/bz, /datum/gas/healium, /datum/gas/pluoxium, /datum/gas/hypernoblium)
+ requirements = list(GAS_H2, GAS_O2)
+ primary_products = list(GAS_N2)
+ secondary_products = list(GAS_PLASMA, GAS_FREON, GAS_BZ, GAS_HEALIUM, GAS_PLUOXIUM, GAS_HYPERNOB)
meltdown_flags = HYPERTORUS_FLAG_BASE_EXPLOSION | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_MEDIUM_SPREAD
/datum/hfr_fuel/tritium_oxy_fuel
@@ -78,9 +78,9 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list())
fuel_consumption_multiplier = 1.2
gas_production_multiplier = 0.8
temperature_change_multiplier = 0.8
- requirements = list(/datum/gas/tritium, /datum/gas/oxygen)
- primary_products = list(/datum/gas/pluoxium)
- secondary_products = list(/datum/gas/plasma, /datum/gas/pluoxium, /datum/gas/healium, /datum/gas/hydrogen, /datum/gas/halon, /datum/gas/hypernoblium)
+ requirements = list(GAS_TRITIUM, GAS_O2)
+ primary_products = list(GAS_PLUOXIUM)
+ secondary_products = list(GAS_PLASMA, GAS_PLUOXIUM, GAS_HEALIUM, GAS_H2, GAS_HALON, GAS_HYPERNOB)
meltdown_flags = HYPERTORUS_FLAG_BASE_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_MEDIUM_SPREAD
/datum/hfr_fuel/hydrogen_tritium_fuel
@@ -92,9 +92,9 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list())
fuel_consumption_multiplier = 1
gas_production_multiplier = 1
temperature_change_multiplier = 0.85
- requirements = list(/datum/gas/hydrogen, /datum/gas/tritium)
- primary_products = list(/datum/gas/pluoxium)
- secondary_products = list(/datum/gas/nitrogen, /datum/gas/healium, /datum/gas/dilithium, /datum/gas/hexane, /datum/gas/hypernoblium, /datum/gas/antinoblium)
+ requirements = list(GAS_H2, GAS_TRITIUM)
+ primary_products = list(GAS_PLUOXIUM)
+ secondary_products = list(GAS_N2, GAS_HEALIUM, GAS_DILITHIUM, GAS_HEXANE, GAS_HYPERNOB, GAS_ANTINOB)
meltdown_flags = HYPERTORUS_FLAG_MEDIUM_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_MEDIUM_SPREAD
/datum/hfr_fuel/hypernob_hydrogen_fuel
@@ -106,9 +106,9 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list())
fuel_consumption_multiplier = 0.55
gas_production_multiplier = 1.4
temperature_change_multiplier = 0.9
- requirements = list(/datum/gas/hypernoblium, /datum/gas/hydrogen)
- primary_products = list(/datum/gas/antinoblium)
- secondary_products = list(/datum/gas/antinoblium, /datum/gas/healium, /datum/gas/pluoxium, /datum/gas/pluonium, /datum/gas/zauker, /datum/gas/nitrium)
+ requirements = list(GAS_HYPERNOB, GAS_H2)
+ primary_products = list(GAS_ANTINOB)
+ secondary_products = list(GAS_ANTINOB, GAS_HEALIUM, GAS_PLUOXIUM, GAS_PLUONIUM, GAS_ZAUKER, GAS_NITRIUM)
meltdown_flags = HYPERTORUS_FLAG_DEVASTATING_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_BIG_SPREAD
/datum/hfr_fuel/hypernob_trit_fuel
@@ -120,9 +120,9 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list())
fuel_consumption_multiplier = 0.45
gas_production_multiplier = 1.7
temperature_change_multiplier = 0.95
- requirements = list(/datum/gas/hypernoblium, /datum/gas/tritium)
- primary_products = list(/datum/gas/antinoblium)
- secondary_products = list(/datum/gas/antinoblium, /datum/gas/healium, /datum/gas/pluonium, /datum/gas/zauker, /datum/gas/nitrium, /datum/gas/miasma)
+ requirements = list(GAS_HYPERNOB, GAS_TRITIUM)
+ primary_products = list(GAS_ANTINOB)
+ secondary_products = list(GAS_ANTINOB, GAS_HEALIUM, GAS_PLUONIUM, GAS_ZAUKER, GAS_NITRIUM, GAS_MIASMA)
meltdown_flags = HYPERTORUS_FLAG_DEVASTATING_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_BIG_SPREAD
/datum/hfr_fuel/hypernob_antinob_fuel
@@ -134,7 +134,7 @@ GLOBAL_LIST_INIT(hfr_fuels_list, hfr_fuels_create_list())
fuel_consumption_multiplier = 0.01
gas_production_multiplier = 3
temperature_change_multiplier = 1
- requirements = list(/datum/gas/hypernoblium, /datum/gas/antinoblium)
- primary_products = list(/datum/gas/zauker, /datum/gas/miasma)
- secondary_products = list(/datum/gas/oxygen, /datum/gas/nitrium, /datum/gas/bz, /datum/gas/pluonium, /datum/gas/hexane, /datum/gas/healium)
+ requirements = list(GAS_HYPERNOB, GAS_ANTINOB)
+ primary_products = list(GAS_ZAUKER, GAS_MIASMA)
+ secondary_products = list(GAS_O2, GAS_NITRIUM, GAS_BZ, GAS_PLUONIUM, GAS_HEXANE, GAS_HEALIUM)
meltdown_flags = HYPERTORUS_FLAG_DEVASTATING_EXPLOSION | HYPERTORUS_FLAG_RADIATION_PULSE | HYPERTORUS_FLAG_EMP | HYPERTORUS_FLAG_MASSIVE_SPREAD | HYPERTORUS_FLAG_CRITICAL_MELTDOWN
diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm
index 3a6a3e8f85b4..03aa37895cd2 100644
--- a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm
+++ b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm
@@ -4,7 +4,7 @@
* fusion_process() handles all the main fusion reaction logic and consequences (lightning, radiation, particles) from an active fusion reaction.
*/
-/obj/machinery/atmospherics/components/unary/hypertorus/core/process(delta_time)
+/obj/machinery/atmospherics/components/unary/hypertorus/core/process_atmos(delta_time)
/*
*Pre-checks
*/
@@ -101,9 +101,9 @@
//Calculation of the gas power, only for theoretical instability calculations
var/gas_power = 0
for (var/gas_id in internal_fusion.get_gases())
- gas_power += (GLOB.meta_gas_info[gas_id][META_GAS_FUSION_POWER] * internal_fusion.get_moles(gas_id))
+ gas_power += (GLOB.gas_data.fusion_powers[gas_id] * internal_fusion.get_moles(gas_id))
for (var/gas_id in moderator_internal.get_gases())
- gas_power += (GLOB.meta_gas_info[gas_id][META_GAS_FUSION_POWER] * moderator_internal.get_moles(gas_id) * 0.75)
+ gas_power += (GLOB.gas_data.fusion_powers[gas_id] * moderator_internal.get_moles(gas_id) * 0.75)
instability = MODULUS((gas_power * INSTABILITY_GAS_POWER_FACTOR_HFR)**2, toroidal_size) + (current_damper * 0.01) - iron_content * 0.05
//Effective reaction instability (determines if the energy is used/released)
@@ -118,37 +118,37 @@
*/
///Those are the scaled gases that gets consumed and adjust energy
// Gases that increase the amount of energy
- var/energy_modifiers = scaled_moderator_list[/datum/gas/nitrogen] * 0.35 + \
- scaled_moderator_list[/datum/gas/carbon_dioxide] * 0.55 + \
- scaled_moderator_list[/datum/gas/nitrous_oxide] * 0.95 + \
- scaled_moderator_list[/datum/gas/zauker] * 1.55 + \
- scaled_moderator_list[/datum/gas/antinoblium] * 20
+ var/energy_modifiers = scaled_moderator_list[GAS_N2] * 0.35 + \
+ scaled_moderator_list[GAS_CO2] * 0.55 + \
+ scaled_moderator_list[GAS_NITROUS] * 0.95 + \
+ scaled_moderator_list[GAS_ZAUKER] * 1.55 + \
+ scaled_moderator_list[GAS_ANTINOB] * 20
// Gases that decrease the amount of energy
- energy_modifiers -= scaled_moderator_list[/datum/gas/hypernoblium] * 10 + \
- scaled_moderator_list[/datum/gas/water_vapor] * 0.75 + \
- scaled_moderator_list[/datum/gas/nitrium] * 0.15 + \
- scaled_moderator_list[/datum/gas/healium] * 0.45 + \
- scaled_moderator_list[/datum/gas/freon] * 1.15
+ energy_modifiers -= scaled_moderator_list[GAS_HYPERNOB] * 10 + \
+ scaled_moderator_list[GAS_H2O] * 0.75 + \
+ scaled_moderator_list[GAS_NITRIUM] * 0.15 + \
+ scaled_moderator_list[GAS_HEALIUM] * 0.45 + \
+ scaled_moderator_list[GAS_FREON] * 1.15
///Between 0.25 and 100, this value is used to modify the behaviour of the internal energy and the core temperature based on the gases present in the mix
- var/power_modifier = scaled_moderator_list[/datum/gas/oxygen] * 0.55 + \
- scaled_moderator_list[/datum/gas/carbon_dioxide] * 0.95 + \
- scaled_moderator_list[/datum/gas/nitrium] * 1.45 + \
- scaled_moderator_list[/datum/gas/zauker] * 5.55 + \
- scaled_moderator_list[/datum/gas/plasma] * 0.05 - \
- scaled_moderator_list[/datum/gas/nitrous_oxide] * 0.05 - \
- scaled_moderator_list[/datum/gas/freon] * 0.75
+ var/power_modifier = scaled_moderator_list[GAS_O2] * 0.55 + \
+ scaled_moderator_list[GAS_CO2] * 0.95 + \
+ scaled_moderator_list[GAS_NITRIUM] * 1.45 + \
+ scaled_moderator_list[GAS_ZAUKER] * 5.55 + \
+ scaled_moderator_list[GAS_PLASMA] * 0.05 - \
+ scaled_moderator_list[GAS_NITROUS] * 0.05 - \
+ scaled_moderator_list[GAS_FREON] * 0.75
///Minimum 0.25, this value is used to modify the behaviour of the energy emission based on the gases present in the mix
- var/heat_modifier = scaled_moderator_list[/datum/gas/plasma] * 1.25 - \
- scaled_moderator_list[/datum/gas/nitrogen] * 0.75 - \
- scaled_moderator_list[/datum/gas/nitrous_oxide] * 1.45 - \
- scaled_moderator_list[/datum/gas/freon] * 0.95
+ var/heat_modifier = scaled_moderator_list[GAS_PLASMA] * 1.25 - \
+ scaled_moderator_list[GAS_N2] * 0.75 - \
+ scaled_moderator_list[GAS_NITROUS] * 1.45 - \
+ scaled_moderator_list[GAS_FREON] * 0.95
///Between 0.005 and 1000, this value modify the radiation emission of the reaction, higher values increase the emission
- var/radiation_modifier = scaled_moderator_list[/datum/gas/freon] * 1.15 - \
- scaled_moderator_list[/datum/gas/nitrogen] * 0.45 - \
- scaled_moderator_list[/datum/gas/plasma] * 0.95 + \
- scaled_moderator_list[/datum/gas/bz] * 1.9 + \
- scaled_moderator_list[/datum/gas/pluonium] * 0.1 + \
- scaled_moderator_list[/datum/gas/antinoblium] * 10
+ var/radiation_modifier = scaled_moderator_list[GAS_FREON] * 1.15 - \
+ scaled_moderator_list[GAS_N2] * 0.45 - \
+ scaled_moderator_list[GAS_PLASMA] * 0.95 + \
+ scaled_moderator_list[GAS_BZ] * 1.9 + \
+ scaled_moderator_list[GAS_PLUONIUM] * 0.1 + \
+ scaled_moderator_list[GAS_ANTINOB] * 10
if (selected_fuel)
// These should probably be static coefficients read from a table rather than things that depend on the current recipe
@@ -267,80 +267,80 @@
/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/moderator_common_process(delta_time, scaled_production, datum/gas_mixture/internal_output, moderator_list, dirty_production_rate, heat_output, radiation_modifier)
switch(power_level)
if(1)
- if(moderator_list[/datum/gas/plasma] > 100)
- internal_output.adjust_moles(/datum/gas/nitrous_oxide, scaled_production * 0.5)
- moderator_internal.adjust_moles(/datum/gas/plasma, -min(moderator_internal.get_moles(/datum/gas/plasma), scaled_production * 0.85))
- if(moderator_list[/datum/gas/bz] > 150)
- internal_output.adjust_moles(/datum/gas/halon, scaled_production * 0.55)
- moderator_internal.adjust_moles(/datum/gas/bz, -min(moderator_internal.get_moles(/datum/gas/bz), scaled_production * 0.95))
+ if(moderator_list[GAS_PLASMA] > 100)
+ internal_output.adjust_moles(GAS_NITROUS, scaled_production * 0.5)
+ moderator_internal.adjust_moles(GAS_PLASMA, -min(moderator_internal.get_moles(GAS_PLASMA), scaled_production * 0.85))
+ if(moderator_list[GAS_BZ] > 150)
+ internal_output.adjust_moles(GAS_HALON, scaled_production * 0.55)
+ moderator_internal.adjust_moles(GAS_BZ, -min(moderator_internal.get_moles(GAS_BZ), scaled_production * 0.95))
if(2)
- if(moderator_list[/datum/gas/plasma] > 50)
- internal_output.adjust_moles(/datum/gas/bz, scaled_production * 1.8)
- moderator_internal.adjust_moles(/datum/gas/plasma, -min(moderator_internal.get_moles(/datum/gas/plasma), scaled_production * 1.75))
- if(moderator_list[/datum/gas/pluonium] > 20)
+ if(moderator_list[GAS_PLASMA] > 50)
+ internal_output.adjust_moles(GAS_BZ, scaled_production * 1.8)
+ moderator_internal.adjust_moles(GAS_PLASMA, -min(moderator_internal.get_moles(GAS_PLASMA), scaled_production * 1.75))
+ if(moderator_list[GAS_PLUONIUM] > 20)
radiation *= 1.55
heat_output *= 1.025
- moderator_internal.adjust_moles(/datum/gas/pluonium, -min(moderator_internal.get_moles(/datum/gas/pluonium), scaled_production * 1.35))
+ moderator_internal.adjust_moles(GAS_PLUONIUM, -min(moderator_internal.get_moles(GAS_PLUONIUM), scaled_production * 1.35))
if(3, 4)
- if(moderator_list[/datum/gas/plasma] > 10)
- internal_output.adjust_moles(/datum/gas/freon, scaled_production * 0.15)
- moderator_internal.adjust_moles(/datum/gas/plasma, -min(moderator_internal.get_moles(/datum/gas/plasma), scaled_production * 0.45))
- if(moderator_list[/datum/gas/freon] > 50)
+ if(moderator_list[GAS_PLASMA] > 10)
+ internal_output.adjust_moles(GAS_FREON, scaled_production * 0.15)
+ moderator_internal.adjust_moles(GAS_PLASMA, -min(moderator_internal.get_moles(GAS_PLASMA), scaled_production * 0.45))
+ if(moderator_list[GAS_FREON] > 50)
heat_output *= 0.9
radiation *= 0.8
- if(moderator_list[/datum/gas/pluonium]> 15)
- internal_output.adjust_moles(/datum/gas/halon, scaled_production * 1.15)
- moderator_internal.adjust_moles(/datum/gas/pluonium, -min(moderator_internal.get_moles(/datum/gas/pluonium), scaled_production * 1.55))
+ if(moderator_list[GAS_PLUONIUM]> 15)
+ internal_output.adjust_moles(GAS_HALON, scaled_production * 1.15)
+ moderator_internal.adjust_moles(GAS_PLUONIUM, -min(moderator_internal.get_moles(GAS_PLUONIUM), scaled_production * 1.55))
radiation *= 1.95
heat_output *= 1.25
- if(moderator_list[/datum/gas/bz] > 100)
- internal_output.adjust_moles(/datum/gas/pluonium, scaled_production * 1.5)
- internal_output.adjust_moles(/datum/gas/healium, scaled_production * 1.5)
+ if(moderator_list[GAS_BZ] > 100)
+ internal_output.adjust_moles(GAS_PLUONIUM, scaled_production * 1.5)
+ internal_output.adjust_moles(GAS_HEALIUM, scaled_production * 1.5)
induce_hallucination(50 * power_level, delta_time)
if(5)
- if(moderator_list[/datum/gas/plasma] > 15)
- internal_output.adjust_moles(/datum/gas/freon, scaled_production * 0.25)
- moderator_internal.adjust_moles(/datum/gas/plasma, -min(moderator_internal.get_moles(/datum/gas/plasma), scaled_production * 1.45))
- if(moderator_list[/datum/gas/freon] > 500)
+ if(moderator_list[GAS_PLASMA] > 15)
+ internal_output.adjust_moles(GAS_FREON, scaled_production * 0.25)
+ moderator_internal.adjust_moles(GAS_PLASMA, -min(moderator_internal.get_moles(GAS_PLASMA), scaled_production * 1.45))
+ if(moderator_list[GAS_FREON] > 500)
heat_output *= 0.5
radiation *= 0.2
- if(moderator_list[/datum/gas/pluonium] > 50)
- internal_output.adjust_moles(/datum/gas/pluoxium, scaled_production)
- moderator_internal.adjust_moles(/datum/gas/pluonium, -min(moderator_internal.get_moles(/datum/gas/pluonium), scaled_production * 1.35))
+ if(moderator_list[GAS_PLUONIUM] > 50)
+ internal_output.adjust_moles(GAS_PLUOXIUM, scaled_production)
+ moderator_internal.adjust_moles(GAS_PLUONIUM, -min(moderator_internal.get_moles(GAS_PLUONIUM), scaled_production * 1.35))
radiation *= 1.95
heat_output *= 1.25
- if(moderator_list[/datum/gas/bz] > 100)
- internal_output.adjust_moles(/datum/gas/healium, scaled_production)
+ if(moderator_list[GAS_BZ] > 100)
+ internal_output.adjust_moles(GAS_HEALIUM, scaled_production)
induce_hallucination(500, delta_time)
- internal_output.adjust_moles(/datum/gas/freon, scaled_production * 1.15)
- if(moderator_list[/datum/gas/healium] > 100)
+ internal_output.adjust_moles(GAS_FREON, scaled_production * 1.15)
+ if(moderator_list[GAS_HEALIUM] > 100)
if(critical_threshold_proximity > 400)
- critical_threshold_proximity = max(critical_threshold_proximity - (moderator_list[/datum/gas/healium] / 100 * delta_time ), 0)
- moderator_internal.adjust_moles(/datum/gas/healium, -min(moderator_internal.get_moles(/datum/gas/healium), scaled_production * 20))
- if(moderator_internal.return_temperature() < 1e7 || (moderator_list[/datum/gas/plasma] > 100 && moderator_list[/datum/gas/bz] > 50))
- internal_output.adjust_moles(/datum/gas/antinoblium, dirty_production_rate * 0.9 / 0.065 * delta_time)
+ critical_threshold_proximity = max(critical_threshold_proximity - (moderator_list[GAS_HEALIUM] / 100 * delta_time ), 0)
+ moderator_internal.adjust_moles(GAS_HEALIUM, -min(moderator_internal.get_moles(GAS_HEALIUM), scaled_production * 20))
+ if(moderator_internal.return_temperature() < 1e7 || (moderator_list[GAS_PLASMA] > 100 && moderator_list[GAS_BZ] > 50))
+ internal_output.adjust_moles(GAS_ANTINOB, dirty_production_rate * 0.9 / 0.065 * delta_time)
if(6)
- if(moderator_list[/datum/gas/plasma] > 30)
- internal_output.adjust_moles(/datum/gas/bz, scaled_production * 1.15)
- moderator_internal.adjust_moles(/datum/gas/plasma, -min(moderator_internal.get_moles(/datum/gas/plasma), scaled_production * 1.45))
- if(moderator_list[/datum/gas/pluonium])
- internal_output.adjust_moles(/datum/gas/zauker, scaled_production * 5.35)
- internal_output.adjust_moles(/datum/gas/nitrium, scaled_production * 2.15)
- moderator_internal.adjust_moles(/datum/gas/pluonium, -min(moderator_internal.get_moles(/datum/gas/pluonium), scaled_production * 3.35))
+ if(moderator_list[GAS_PLASMA] > 30)
+ internal_output.adjust_moles(GAS_BZ, scaled_production * 1.15)
+ moderator_internal.adjust_moles(GAS_PLASMA, -min(moderator_internal.get_moles(GAS_PLASMA), scaled_production * 1.45))
+ if(moderator_list[GAS_PLUONIUM])
+ internal_output.adjust_moles(GAS_ZAUKER, scaled_production * 5.35)
+ internal_output.adjust_moles(GAS_NITRIUM, scaled_production * 2.15)
+ moderator_internal.adjust_moles(GAS_PLUONIUM, -min(moderator_internal.get_moles(GAS_PLUONIUM), scaled_production * 3.35))
radiation *= 2
heat_output *= 2.25
- if(moderator_list[/datum/gas/bz])
+ if(moderator_list[GAS_BZ])
induce_hallucination(900, delta_time, force=TRUE)
- internal_output.adjust_moles(/datum/gas/antinoblium, clamp(dirty_production_rate / 0.045, 0, 10) * delta_time)
- if(moderator_list[/datum/gas/healium] > 100)
+ internal_output.adjust_moles(GAS_ANTINOB, clamp(dirty_production_rate / 0.045, 0, 10) * delta_time)
+ if(moderator_list[GAS_HEALIUM] > 100)
if(critical_threshold_proximity > 400)
- critical_threshold_proximity = max(critical_threshold_proximity - (moderator_list[/datum/gas/healium] / 100 * delta_time ), 0)
- moderator_internal.adjust_moles(/datum/gas/healium, -min(moderator_internal.get_moles(/datum/gas/healium), scaled_production * 20))
- internal_fusion.adjust_moles(/datum/gas/antinoblium, dirty_production_rate * 0.01 / 0.095 * delta_time)
+ critical_threshold_proximity = max(critical_threshold_proximity - (moderator_list[GAS_HEALIUM] / 100 * delta_time ), 0)
+ moderator_internal.adjust_moles(GAS_HEALIUM, -min(moderator_internal.get_moles(GAS_HEALIUM), scaled_production * 20))
+ internal_fusion.adjust_moles(GAS_ANTINOB, dirty_production_rate * 0.01 / 0.095 * delta_time)
//Modifies the internal_fusion temperature with the amount of heat output
var/temperature_modifier = selected_fuel.temperature_change_multiplier
@@ -364,12 +364,12 @@
check_lightning_arcs(moderator_list)
// Oxygen burns away iron content rapidly
- if(moderator_list[/datum/gas/oxygen] > 150)
+ if(moderator_list[GAS_O2] > 150)
if(iron_content > 0)
var/max_iron_removable = IRON_OXYGEN_HEAL_PER_SECOND
var/iron_removed = min(max_iron_removable * delta_time, iron_content)
iron_content -= iron_removed
- moderator_internal.adjust_moles(/datum/gas/oxygen, -(iron_removed * OXYGEN_MOLES_CONSUMED_PER_IRON_HEAL))
+ moderator_internal.adjust_moles(GAS_O2, -(iron_removed * OXYGEN_MOLES_CONSUMED_PER_IRON_HEAL))
check_gravity_pulse(delta_time)
@@ -435,7 +435,7 @@
if(power_level < 4)
return
- if(moderator_list[/datum/gas/bz] < (150 / power_level))
+ if(moderator_list[GAS_BZ] < (150 / power_level))
return
var/obj/machinery/hypertorus/corner/picked_corner = pick(corners)
@@ -444,7 +444,7 @@
/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/check_lightning_arcs(moderator_list)
if(power_level < 4)
return
- if(moderator_list[/datum/gas/antinoblium] <= 50 && critical_threshold_proximity <= 500)
+ if(moderator_list[GAS_ANTINOB] <= 50 && critical_threshold_proximity <= 500)
return
var/zap_number = power_level - 2
diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_parts.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_parts.dm
index d62493a59090..ecb4e063594f 100644
--- a/code/modules/atmospherics/machinery/components/fusion/hfr_parts.dm
+++ b/code/modules/atmospherics/machinery/components/fusion/hfr_parts.dm
@@ -58,18 +58,18 @@
/obj/machinery/atmospherics/components/unary/hypertorus/default_change_direction_wrench(mob/user, obj/item/I)
. = ..()
if(.)
- SetInitDirections()
+ set_init_directions()
var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
nodes[1] = null
if(parents[1])
- nullifyPipenet(parents[1])
- atmosinit()
+ nullify_pipenet(parents[1])
+ atmos_init()
node = nodes[1]
if(node)
- node.atmosinit()
- node.addMember(src)
+ node.atmos_init()
+ node.add_member(src)
SSair.add_to_rebuild_queue(src)
/obj/machinery/atmospherics/components/unary/hypertorus/update_icon_state()
@@ -202,15 +202,6 @@
else
to_chat(user, span_notice("Activate the machine first by using a multitool on the interface."))
-/obj/machinery/hypertorus/interface/proc/gas_list_to_gasid_list(list/gas_list)
- var/list/gasid_list = list()
- for(var/gas_type in gas_list)
- var/datum/gas/gas = gas_type
- gasid_list += initial(gas.id)
- return gasid_list
-
-
-
/obj/machinery/hypertorus/interface/ui_static_data()
var/data = list()
data["base_max_temperature"] = FUSION_MAXIMUM_TEMPERATURE
@@ -221,9 +212,9 @@
data["selectable_fuel"] += list(list(
"name" = recipe.name,
"id" = recipe.id,
- "requirements" = gas_list_to_gasid_list(recipe.requirements),
- "fusion_byproducts" = gas_list_to_gasid_list(recipe.primary_products),
- "product_gases" = gas_list_to_gasid_list(recipe.secondary_products),
+ "requirements" = recipe.requirements,
+ "fusion_byproducts" = recipe.primary_products,
+ "product_gases" = recipe.secondary_products,
"recipe_cooling_multiplier" = recipe.negative_temperature_multiplier,
"recipe_heating_multiplier" = recipe.positive_temperature_multiplier,
"energy_loss_multiplier" = recipe.energy_concentration_multiplier,
@@ -231,6 +222,14 @@
"gas_production_multiplier" = recipe.gas_production_multiplier,
"temperature_multiplier" = recipe.temperature_change_multiplier,
))
+
+ data["gas_data"] = list()
+ for(var/gas_id in GLOB.gas_data.ids)
+ data["gas_data"] += list(list(
+ "id" = gas_id,
+ "label" = GLOB.gas_data.labels[gas_id],
+ "ui_color" = GLOB.gas_data.ui_colors[gas_id],
+ ))
return data
/obj/machinery/hypertorus/interface/ui_data()
@@ -244,35 +243,31 @@
//Internal Fusion gases
var/list/fusion_gasdata = list()
if(connected_core.internal_fusion.total_moles())
- for(var/gas_type in connected_core.internal_fusion.get_gases())
- var/datum/gas/gas = gas_type
+ for(var/gas_id in connected_core.internal_fusion.get_gases())
fusion_gasdata.Add(list(list(
- "id"= initial(gas.id),
- "amount" = round(connected_core.internal_fusion.get_moles(gas), 0.01),
+ "id"= initial(gas_id),
+ "amount" = round(connected_core.internal_fusion.get_moles(gas_id), 0.01),
)))
else
- for(var/gas_type in connected_core.internal_fusion.get_gases())
- var/datum/gas/gas = gas_type
+ for(var/gas_id in connected_core.internal_fusion.get_gases())
fusion_gasdata.Add(list(list(
- "id"= initial(gas.id),
+ "id"= initial(gas_id),
"amount" = 0,
- )))
+ )))
//Moderator gases
var/list/moderator_gasdata = list()
if(connected_core.moderator_internal.total_moles())
- for(var/gas_type in connected_core.moderator_internal.get_gases())
- var/datum/gas/gas = gas_type
+ for(var/gas_id in connected_core.moderator_internal.get_gases())
moderator_gasdata.Add(list(list(
- "id"= initial(gas.id),
- "amount" = round(connected_core.moderator_internal.get_moles(gas), 0.01),
+ "id"= initial(gas_id),
+ "amount" = round(connected_core.moderator_internal.get_moles(gas_id), 0.01),
)))
else
- for(var/gas_type in connected_core.moderator_internal.get_gases())
- var/datum/gas/gas = gas_type
+ for(var/gas_id in connected_core.moderator_internal.get_gases())
moderator_gasdata.Add(list(list(
- "id"= initial(gas.id),
+ "id"= initial(gas_id),
"amount" = 0,
- )))
+ )))
data["fusion_gases"] = fusion_gasdata
data["moderator_gases"] = moderator_gasdata
@@ -314,9 +309,8 @@
data["waste_remove"] = connected_core.waste_remove
data["fuel_remove"] = connected_core.fuel_remove
data["filter_types"] = list()
- for(var/path in GLOB.meta_gas_info)
- var/list/gas = GLOB.meta_gas_info[path]
- data["filter_types"] += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in connected_core.moderator_scrubbing)))
+ for(var/id in GLOB.gas_data.ids)
+ data["filter_types"] += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.labels[id], "enabled" = (id in connected_core.moderator_scrubbing)))
data["cooling_volume"] = connected_core.airs[1].return_volume()
data["mod_filtering_rate"] = connected_core.moderator_filtering_rate
@@ -374,7 +368,9 @@
connected_core.fuel_remove = !connected_core.fuel_remove
. = TRUE
if("filter")
- connected_core.moderator_scrubbing ^= gas_id2path(params["mode"])
+ var/gas = params["mode"]
+ if(gas in GLOB.gas_data.names)
+ connected_core.moderator_scrubbing ^= gas
. = TRUE
if("mod_filtering_rate")
var/mod_filtering_rate = text2num(params["mod_filtering_rate"])
diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm
index 70469590ed12..e6e67f3c501f 100644
--- a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm
+++ b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm
@@ -173,13 +173,13 @@
/obj/machinery/atmospherics/components/unary/hypertorus/core/proc/update_temperature_status(delta_time)
fusion_temperature_archived = fusion_temperature
- fusion_temperature = internal_fusion.return_temperature()
+ fusion_temperature = internal_fusion.total_moles() == 0 ? 0 : internal_fusion.return_temperature()
moderator_temperature_archived = moderator_temperature
- moderator_temperature = moderator_internal.return_temperature()
+ moderator_temperature = moderator_internal.total_moles() == 0 ? 0 : moderator_internal.return_temperature()
coolant_temperature_archived = coolant_temperature
- coolant_temperature = airs[1].return_temperature()
+ coolant_temperature = airs[1].total_moles() == 0 ? 0 : airs[1].return_temperature()
output_temperature_archived = output_temperature
- output_temperature = linked_output.airs[1].return_temperature()
+ output_temperature = linked_output.airs[1].total_moles() == 0 ? 0 : linked_output.airs[1].return_temperature()
temperature_period = delta_time
//Set the power level of the fusion process
@@ -439,8 +439,7 @@
var/devastating_explosion = 0
var/em_pulse = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_EMP
var/rad_pulse = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_RADIATION_PULSE
- var/emp_light_size = 0
- var/emp_heavy_size = 0
+ var/emp_severity = 0
var/rad_pulse_size = 0
var/rad_pulse_strength = 0
var/gas_spread = 0
@@ -464,8 +463,7 @@
if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MINIMUM_SPREAD)
if(em_pulse)
- emp_light_size = power_level * 3
- emp_heavy_size = power_level * 1
+ emp_severity = power_level * 3
if(rad_pulse)
rad_pulse_size = (1 / (power_level + 1))
rad_pulse_strength = power_level * 3000
@@ -474,8 +472,7 @@
if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MEDIUM_SPREAD)
if(em_pulse)
- emp_light_size = power_level * 5
- emp_heavy_size = power_level * 3
+ emp_severity = power_level * 5
if(rad_pulse)
rad_pulse_size = (1 / (power_level + 3))
rad_pulse_strength = power_level * 5000
@@ -484,8 +481,7 @@
if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_BIG_SPREAD)
if(em_pulse)
- emp_light_size = power_level * 7
- emp_heavy_size = power_level * 5
+ emp_severity = power_level * 7
if(rad_pulse)
rad_pulse_size = (1 / (power_level + 5))
rad_pulse_strength = power_level * 7000
@@ -494,8 +490,7 @@
if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MASSIVE_SPREAD)
if(em_pulse)
- emp_light_size = power_level * 9
- emp_heavy_size = power_level * 7
+ emp_severity = power_level * 9
if(rad_pulse)
rad_pulse_size = (1 / (power_level + 7))
rad_pulse_strength = power_level * 9000
@@ -550,8 +545,7 @@
if(em_pulse)
empulse(
epicenter = loc,
- heavy_range = critical ? emp_heavy_size * 2 : emp_heavy_size,
- light_range = critical ? emp_light_size * 2 : emp_heavy_size,
+ severity = critical ? emp_severity * 2 : emp_severity,
log = TRUE
)
diff --git a/code/modules/atmospherics/machinery/components/gas_recipe_machines/atmos_machines_recipes.dm b/code/modules/atmospherics/machinery/components/gas_recipe_machines/atmos_machines_recipes.dm
index ef482c77ca06..46b8e98b9566 100644
--- a/code/modules/atmospherics/machinery/components/gas_recipe_machines/atmos_machines_recipes.dm
+++ b/code/modules/atmospherics/machinery/components/gas_recipe_machines/atmos_machines_recipes.dm
@@ -42,7 +42,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 50000
max_temp = 150000
energy_release = -2500000
- requirements = list(/datum/gas/hydrogen = 300, /datum/gas/bz = 50)
+ requirements = list(GAS_H2 = 300, GAS_BZ = 50)
products = list(/obj/item/stack/sheet/mineral/metal_hydrogen = 1)
/datum/gas_recipe/crystallizer/supermatter_extraction_tongs
@@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 50000
max_temp = 150000
energy_release = -150000
- requirements = list(/datum/gas/hydrogen = 100, /datum/gas/hypernoblium = 5, /datum/gas/bz = 5)
+ requirements = list(GAS_H2 = 100, GAS_HYPERNOB = 5, GAS_BZ = 5)
products = list(/obj/item/hemostat/supermatter = 1)
/datum/gas_recipe/crystallizer/supermatter_base_structure
@@ -60,7 +60,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 50000
max_temp = 150000
energy_release = -200000
- requirements = list(/datum/gas/hydrogen = 1000, /datum/gas/bz = 100, /datum/gas/hypernoblium = 10)
+ requirements = list(GAS_H2 = 1000, GAS_BZ = 100, GAS_HYPERNOB = 10)
products = list(/obj/structure/supermatter_base_structure = 1)
/datum/gas_recipe/crystallizer/healium_grenade
@@ -69,7 +69,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 200
max_temp = 400
energy_release = -2000000
- requirements = list(/datum/gas/healium = 100, /datum/gas/freon = 120, /datum/gas/plasma = 50)
+ requirements = list(GAS_HEALIUM = 100, GAS_FREON = 120, GAS_PLASMA = 50)
products = list(/obj/item/grenade/gas_crystal/healium_crystal = 1)
/datum/gas_recipe/crystallizer/pluonium_grenade
@@ -78,7 +78,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 200
max_temp = 400
energy_release = 1500000
- requirements = list(/datum/gas/pluonium = 100, /datum/gas/nitrogen = 80, /datum/gas/oxygen = 80)
+ requirements = list(GAS_PLUONIUM = 100, GAS_N2 = 80, GAS_O2 = 80)
products = list(/obj/item/grenade/gas_crystal/pluonium_crystal = 1)
/datum/gas_recipe/crystallizer/hot_ice
@@ -87,7 +87,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 15
max_temp = 35
energy_release = -3000000
- requirements = list(/datum/gas/freon = 60, /datum/gas/plasma = 160, /datum/gas/oxygen = 80)
+ requirements = list(GAS_FREON = 60, GAS_PLASMA = 160, GAS_O2 = 80)
products = list(/obj/item/stack/sheet/hot_ice = 1)
/datum/gas_recipe/crystallizer/ammonia_crystal
@@ -96,7 +96,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 200
max_temp = 240
energy_release = 950000
- requirements = list(/datum/gas/hydrogen = 50, /datum/gas/nitrogen = 40)
+ requirements = list(GAS_H2 = 50, GAS_N2 = 40)
products = list(/obj/item/stack/ammonia_crystals = 2)
/datum/gas_recipe/crystallizer/tesla
@@ -106,7 +106,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
max_temp = 12000
energy_release = -350000
dangerous = TRUE
- requirements = list(/datum/gas/nitrium = 500, /datum/gas/freon = 500, /datum/gas/tritium = 500)
+ requirements = list(GAS_TRITIUM = 500, GAS_FREON = 500, GAS_NITRIUM = 500)
products = list(/obj/machinery/the_singularitygen/tesla = 1)
/datum/gas_recipe/crystallizer/supermatter_silver
@@ -116,7 +116,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
max_temp = 200000
energy_release = -250000
dangerous = TRUE
- requirements = list(/datum/gas/bz = 100, /datum/gas/hypernoblium = 125, /datum/gas/tritium = 250, /datum/gas/plasma = 750)
+ requirements = list(GAS_BZ = 100, GAS_HYPERNOB = 125, GAS_TRITIUM = 250, GAS_PLASMA = 750)
products = list(/obj/item/nuke_core/supermatter_sliver = 1)
/datum/gas_recipe/crystallizer/n2o_crystal
@@ -125,7 +125,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 50
max_temp = 350
energy_release = 3500000
- requirements = list(/datum/gas/nitrous_oxide = 100, /datum/gas/bz = 5)
+ requirements = list(GAS_NITROUS = 100, GAS_BZ = 5)
products = list(/obj/item/grenade/gas_crystal/nitrous_oxide_crystal = 1)
/datum/gas_recipe/crystallizer/diamond
@@ -134,7 +134,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 10000
max_temp = 30000
energy_release = -9500000
- requirements = list(/datum/gas/carbon_dioxide = 10000)
+ requirements = list(GAS_CO2 = 10000)
products = list(/obj/item/stack/sheet/mineral/diamond = 1)
/datum/gas_recipe/crystallizer/uranium
@@ -143,7 +143,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 1000
max_temp = 5000
energy_release = -2500000
- requirements = list(/datum/gas/tritium = 200, /datum/gas/hypernoblium = 50)
+ requirements = list(GAS_TRITIUM = 200, GAS_HYPERNOB = 50)
products = list(/obj/item/stack/sheet/mineral/uranium = 1)
/datum/gas_recipe/crystallizer/plasma_sheet
@@ -152,7 +152,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 10
max_temp = 20
energy_release = 3500000
- requirements = list(/datum/gas/plasma = 450)
+ requirements = list(GAS_PLASMA = 450)
products = list(/obj/item/stack/sheet/mineral/plasma = 1)
/datum/gas_recipe/crystallizer/crystal_cell
@@ -161,7 +161,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 50
max_temp = 90
energy_release = -800000
- requirements = list(/datum/gas/plasma = 800, /datum/gas/healium = 100, /datum/gas/bz = 50)
+ requirements = list(GAS_PLASMA = 800, GAS_HEALIUM = 100, GAS_BZ = 50)
products = list(/obj/item/stock_parts/cell/crystal_cell = 1)
/datum/gas_recipe/crystallizer/zaukerite
@@ -170,7 +170,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 5
max_temp = 20
energy_release = 2900000
- requirements = list(/datum/gas/hypernoblium = 5, /datum/gas/zauker = 10, /datum/gas/bz = 7.5)
+ requirements = list(GAS_HYPERNOB = 5, GAS_ZAUKER = 10, GAS_BZ = 7.5)
products = list(/obj/item/stack/sheet/mineral/zaukerite = 2)
/datum/gas_recipe/crystallizer/hypernoblium_crystal
@@ -179,7 +179,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 100000
max_temp = 200000
energy_release = 2800000
- requirements = list(/datum/gas/bz = 100, /datum/gas/hypernoblium = 100, /datum/gas/oxygen = 1000)
+ requirements = list(GAS_BZ = 100, GAS_HYPERNOB = 100, GAS_O2 = 1000)
products = list(/obj/item/stack/hypernoblium_crystal = 1)
/datum/gas_recipe/crystallizer/antinoblium_crystal
@@ -188,7 +188,7 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = TCMB
max_temp = TCMB + 20
energy_release = 2800000
- requirements = list(/datum/gas/antinoblium = 100, /datum/gas/bz = 30, /datum/gas/plasma = 100)
+ requirements = list(GAS_ANTINOB = 100, GAS_BZ = 30, GAS_PLASMA = 100)
products = list(/obj/item/stack/antinoblium_crystal = 1)
/datum/gas_recipe/crystallizer/crystallized_nitrium
@@ -197,5 +197,5 @@ GLOBAL_LIST_INIT(gas_recipe_meta, gas_recipes_list())
min_temp = 10
max_temp = 25
energy_release = 45000
- requirements = list(/datum/gas/nitrium = 150, /datum/gas/oxygen = 70, /datum/gas/bz = 50)
+ requirements = list(GAS_NITRIUM = 150, GAS_O2 = 70, GAS_BZ = 50)
products = list(/obj/item/nitrium_crystal = 1)
diff --git a/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm b/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm
index 6c50495de769..f60149ae6115 100644
--- a/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm
+++ b/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm
@@ -50,7 +50,7 @@
. = ..()
if(!.)
return FALSE
- SetInitDirections()
+ set_init_directions()
var/obj/machinery/atmospherics/node1 = nodes[1]
var/obj/machinery/atmospherics/node2 = nodes[2]
if(node1)
@@ -63,27 +63,27 @@
nodes[2] = null
if(parents[1])
- nullifyPipenet(parents[1])
+ nullify_pipenet(parents[1])
if(parents[2])
- nullifyPipenet(parents[2])
+ nullify_pipenet(parents[2])
- atmosinit()
+ atmos_init()
node1 = nodes[1]
if(node1)
- node1.atmosinit()
- node1.addMember(src)
+ node1.atmos_init()
+ node1.add_member(src)
node2 = nodes[2]
if(node2)
- node2.atmosinit()
- node2.addMember(src)
+ node2.atmos_init()
+ node2.add_member(src)
SSair.add_to_rebuild_queue(src)
return TRUE
/obj/machinery/atmospherics/components/binary/crystallizer/update_overlays()
. = ..()
cut_overlays()
- . += getpipeimage(icon, "pipe", dir, COLOR_LIME, piping_layer)
- . += getpipeimage(icon, "pipe", turn(dir, 180), COLOR_RED, piping_layer)
+ . += get_pipe_image(icon, "pipe", dir, COLOR_LIME, piping_layer)
+ . += get_pipe_image(icon, "pipe", turn(dir, 180), COLOR_RED, piping_layer)
/obj/machinery/atmospherics/components/binary/crystallizer/update_icon_state()
. = ..()
@@ -275,14 +275,16 @@
if(internal.total_moles())
for(var/gasid in internal.get_gases())
internal_gas_data.Add(list(list(
- "name"= GLOB.meta_gas_info[gasid][META_GAS_NAME],
+ "name"= GLOB.gas_data.names[gasid],
"amount" = round(internal.get_moles(gasid), 0.01),
+ "color" = GLOB.gas_data.ui_colors[gasid],
)))
else
for(var/gasid in internal.get_gases())
internal_gas_data.Add(list(list(
- "name"= GLOB.meta_gas_info[gasid][META_GAS_NAME],
+ "name"= GLOB.gas_data.names[gasid],
"amount" = 0,
+ "color" = GLOB.gas_data.ui_colors[gasid],
)))
data["internal_gas_data"] = internal_gas_data
@@ -292,9 +294,8 @@
else
requirements = list("To create [selected_recipe.name] you will need:")
for(var/gas_type in selected_recipe.requirements)
- var/datum/gas/gas_required = gas_type
var/amount_consumed = selected_recipe.requirements[gas_type]
- requirements += "-[amount_consumed] moles of [initial(gas_required.name)]"
+ requirements += "-[amount_consumed] moles of [initial(gas_type)]"
requirements += "In a temperature range between [selected_recipe.min_temp] K and [selected_recipe.max_temp] K"
requirements += "The crystallization reaction will be [selected_recipe.energy_release ? (selected_recipe.energy_release > 0 ? "exothermic" : "endothermic") : "thermally neutral"]"
data["requirements"] = requirements.Join("\n")
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
index 077d38c368b5..6cb832ecace7 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
@@ -49,13 +49,13 @@
for(var/direction in GLOB.cardinals)
if(!(direction & initialize_directions))
continue
- var/obj/machinery/atmospherics/node = findConnecting(direction)
+ var/obj/machinery/atmospherics/node = find_connecting(direction)
var/image/cap
if(node)
- cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer, trinary = TRUE)
+ cap = get_pipe_image(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer, trinary = TRUE)
else
- cap = getpipeimage(icon, "cap", direction, piping_layer = piping_layer, trinary = TRUE)
+ cap = get_pipe_image(icon, "cap", direction, piping_layer = piping_layer, trinary = TRUE)
. += cap
@@ -64,7 +64,6 @@
icon_state = "filter_[on_state ? "on" : "off"]-[set_overlay_offset(piping_layer)][flipped ? "_f" : ""]"
/obj/machinery/atmospherics/components/trinary/filter/process_atmos()
- ..()
if(!on || !(nodes[1] && nodes[2] && nodes[3]) || !is_operational())
return
@@ -128,7 +127,7 @@
update_parents()
-/obj/machinery/atmospherics/components/trinary/filter/atmosinit()
+/obj/machinery/atmospherics/components/trinary/filter/atmos_init()
set_frequency(frequency)
return ..()
@@ -145,9 +144,8 @@
data["max_rate"] = round(MAX_TRANSFER_RATE)
data["filter_types"] = list()
- for(var/path in GLOB.meta_gas_info)
- var/list/gas = GLOB.meta_gas_info[path]
- data["filter_types"] += list(list("name" = gas[META_GAS_NAME], "gas_id" = gas[META_GAS_ID], "enabled" = (path in filter_type)))
+ for(var/id in GLOB.gas_data.ids)
+ data["filter_types"] += list(list("name" = GLOB.gas_data.labels[id], "gas_id" = id, "enabled" = (id in filter_type)))
return data
@@ -179,16 +177,15 @@
investigate_log(msg, INVESTIGATE_ATMOS)
investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful
if("toggle_filter")
- if(!gas_id2path(params["val"]))
- return TRUE
- filter_type ^= gas_id2path(params["val"])
+ var/gas = params["val"]
+ if(gas in GLOB.gas_data.names)
+ filter_type ^= gas
var/change
- if(gas_id2path(params["val"]) in filter_type)
+ if(gas in filter_type)
change = "added"
else
change = "removed"
- var/gas_name = GLOB.meta_gas_info[gas_id2path(params["val"])][META_GAS_NAME]
- var/msg = "[key_name(usr)] [change] [gas_name] from the filter type."
+ var/msg = "[key_name(usr)] [change] [gas] from the filter type."
investigate_log(msg, INVESTIGATE_ATMOS)
investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful
. = TRUE
@@ -247,38 +244,38 @@
icon_state = "filter_on-0"
/obj/machinery/atmospherics/components/trinary/filter/atmos/n2
name = "Nitrogen filter (N2)"
- filter_type = list(/datum/gas/nitrogen)
+ filter_type = list(GAS_N2)
/obj/machinery/atmospherics/components/trinary/filter/atmos/o2
name = "Oxygen filter (O2)"
- filter_type = list(/datum/gas/oxygen)
+ filter_type = list(GAS_O2)
/obj/machinery/atmospherics/components/trinary/filter/atmos/co2
name = "Carbon dioxide filter (CO2)"
- filter_type = list(/datum/gas/carbon_dioxide)
+ filter_type = list(GAS_CO2)
/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o
name = "Nitrous oxide filter (N2O)"
- filter_type = list(/datum/gas/nitrous_oxide)
+ filter_type = list(GAS_NITROUS)
/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma
name = "Plasma filter"
- filter_type = list(/datum/gas/plasma)
+ filter_type = list(GAS_PLASMA)
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped //This feels wrong, I know
icon_state = "filter_on-0_f"
flipped = TRUE
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2
name = "Nitrogen filter (N2)"
- filter_type = list(/datum/gas/nitrogen)
+ filter_type = list(GAS_N2)
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/o2
name = "Oxygen filter (O2)"
- filter_type = list(/datum/gas/oxygen)
+ filter_type = list(GAS_O2)
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2
name = "Carbon dioxide filter (CO2)"
- filter_type = list(/datum/gas/carbon_dioxide)
+ filter_type = list(GAS_CO2)
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2o
name = "Nitrous oxide filter (N2O)"
- filter_type = list(/datum/gas/nitrous_oxide)
+ filter_type = list(GAS_NITROUS)
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/plasma
name = "Plasma filter"
- filter_type = list(/datum/gas/plasma)
+ filter_type = list(GAS_PLASMA)
// These two filter types have critical_machine flagged to on and thus causes the area they are in to be exempt from the Grid Check event.
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index 8863b9431f49..b04219514e37 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -36,13 +36,13 @@
for(var/direction in GLOB.cardinals)
if(!(direction & initialize_directions))
continue
- var/obj/machinery/atmospherics/node = findConnecting(direction)
+ var/obj/machinery/atmospherics/node = find_connecting(direction)
var/image/cap
if(node)
- cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer, trinary = TRUE)
+ cap = get_pipe_image(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer, trinary = TRUE)
else
- cap = getpipeimage(icon, "cap", direction, piping_layer = piping_layer, trinary = TRUE)
+ cap = get_pipe_image(icon, "cap", direction, piping_layer = piping_layer, trinary = TRUE)
. += cap
@@ -57,7 +57,6 @@
airs[3] = air3
/obj/machinery/atmospherics/components/trinary/mixer/process_atmos()
- ..()
if(!on || !(nodes[1] && nodes[2] && nodes[3]) && !is_operational())
return
@@ -109,19 +108,17 @@
//Actually transfer the gas
if(transfer_moles1)
- var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
- air3.merge(removed1)
+ air1.transfer_to(air3, transfer_moles1)
var/datum/pipeline/parent1 = parents[1]
- parent1.update = TRUE
+ parent1.update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED
if(transfer_moles2)
- var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
- air3.merge(removed2)
+ air2.transfer_to(air3, transfer_moles2)
var/datum/pipeline/parent2 = parents[2]
- parent2.update = TRUE
+ parent2.update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED
var/datum/pipeline/parent3 = parents[3]
- parent3.update = TRUE
+ parent3.update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED
/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -255,7 +252,7 @@
on = TRUE
icon_state = "t_mixer_on-0"
-/obj/machinery/atmospherics/components/trinary/mixer/t_mixer/SetInitDirections()
+/obj/machinery/atmospherics/components/trinary/mixer/t_mixer/set_init_directions()
switch(dir)
if(NORTH)
initialize_directions = EAST|NORTH|WEST
@@ -266,7 +263,7 @@
if(WEST)
initialize_directions = WEST|NORTH|SOUTH
-/obj/machinery/atmospherics/components/trinary/mixer/t_mixer/getNodeConnects()
+/obj/machinery/atmospherics/components/trinary/mixer/t_mixer/get_node_connects()
var/node1_connect = turn(dir, -90)
var/node2_connect = turn(dir, 90)
var/node3_connect = dir
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm
index c587b1b1b630..d711d65ec4d4 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm
@@ -9,7 +9,7 @@
var/flipped = FALSE
-/obj/machinery/atmospherics/components/trinary/SetInitDirections()
+/obj/machinery/atmospherics/components/trinary/set_init_directions()
switch(dir)
if(NORTH)
initialize_directions = EAST|NORTH|SOUTH
@@ -24,7 +24,7 @@
Housekeeping and pipe network stuff
*/
-/obj/machinery/atmospherics/components/trinary/getNodeConnects()
+/obj/machinery/atmospherics/components/trinary/get_node_connects()
//Mixer:
//1 and 2 is input
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 5eb2f8366c76..7e9740b47a36 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -257,28 +257,29 @@ GLOBAL_VAR_INIT(cryo_overlay_cover_off, mutable_appearance('icons/obj/cryogenics
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR)
- if(air1.get_moles(/datum/gas/pluoxium) > 5 )//Use pluoxium over oxygen
- air1.adjust_moles(/datum/gas/pluoxium, -max(0,air1.get_moles(/datum/gas/pluoxium) - 0.5 / efficiency))
- else
- air1.adjust_moles(/datum/gas/oxygen, -max(0,air1.get_moles(/datum/gas/oxygen) - 2 / efficiency)) //Let's use gas for this
+ if(air1.get_moles(GAS_PLUOXIUM) > 5 )//Use pluoxium over oxygen
+ air1.adjust_moles(GAS_PLUOXIUM, -max(0,air1.get_moles(GAS_PLUOXIUM) - 0.5 / efficiency))
+ else
+ air1.adjust_moles(GAS_O2, -max(0,air1.get_moles(GAS_O2) - 2 / efficiency)) //Let's use gas for this
if(occupant.reagents.get_reagent_amount(/datum/reagent/medicine/cryoxadone) >= 100) //prevent cryoxadone overdose
occupant.reagents.del_reagent(/datum/reagent/medicine/cryoxadone)
occupant.reagents.add_reagent(/datum/reagent/medicine/cryoxadone, 99)
reagent_transfer += 0.5 * delta_time
if(reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
-
+ if(air1.get_moles(GAS_HEALIUM) > 1) //healium check, if theres enough we get some extra healing from our favorite pink gas.
+ var/existing = mob_occupant.reagents.get_reagent_amount(/datum/reagent/healium)
+ mob_occupant.reagents.add_reagent(/datum/reagent/healium, 1 - existing)
+ air1.set_moles(GAS_HEALIUM, -max(0, air1.get_moles(GAS_HEALIUM) - 0.1 / efficiency))
return 1
-/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos(delta_time)
- ..()
-
+/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos()
if(!on)
return
var/datum/gas_mixture/air1 = airs[1]
- if(!nodes[1] || !airs[1] || (air1.get_moles(/datum/gas/oxygen) < 5 && air1.get_moles(/datum/gas/pluoxium) < 5)) // Turn off if the machine won't work.
+ if(!nodes[1] || !airs[1] || (air1.get_moles(GAS_O2) < 5 && air1.get_moles(GAS_PLUOXIUM) < 5)) // Turn off if the machine won't work.
set_on(FALSE)
return
@@ -299,10 +300,10 @@ GLOBAL_VAR_INIT(cryo_overlay_cover_off, mutable_appearance('icons/obj/cryogenics
air1.set_temperature(max(air1.return_temperature() - heat / air_heat_capacity, TCMB))
mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB)
- if(air1.get_moles(/datum/gas/pluoxium) > 5) //use pluoxium over oxygen
- air1.set_moles(/datum/gas/pluoxium, max(0,air1.get_moles(/datum/gas/pluoxium) - 0.125 / efficiency))
- else
- air1.set_moles(/datum/gas/oxygen, max(0,air1.get_moles(/datum/gas/oxygen) - 0.5 / efficiency)) // Magically consume gas? Why not, we run on cryo magic.
+ if(air1.get_moles(GAS_PLUOXIUM) > 5) //use pluoxium over oxygen
+ air1.set_moles(GAS_PLUOXIUM, max(0,air1.get_moles(GAS_PLUOXIUM) - 0.125 / efficiency))
+ else
+ air1.set_moles(GAS_O2, max(0,air1.get_moles(GAS_O2) - 0.5 / efficiency)) // Magically consume gas? Why not, we run on cryo magic.
if(air1.return_temperature() > 2000)
take_damage(clamp((air1.return_temperature())/200, 10, 20), BURN)
@@ -512,17 +513,18 @@ GLOBAL_VAR_INIT(cryo_overlay_cover_off, mutable_appearance('icons/obj/cryogenics
/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W)
. = ..()
if(.)
- SetInitDirections()
+ set_init_directions()
var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
nodes[1] = null
- nullifyPipenet(parents[1])
- atmosinit()
+ if(parents[1])
+ nullify_pipenet(parents[1])
+ atmos_init()
node = nodes[1]
if(node)
- node.atmosinit()
- node.addMember(src)
+ node.atmos_init()
+ node.add_member(src)
SSair.add_to_rebuild_queue(src)
#undef MAX_TEMPERATURE
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm
index 1ca74980ddd4..becd13ed0927 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm
@@ -33,7 +33,7 @@
icon_state = "he0"
PIPING_LAYER_SHIFT(src, piping_layer)
-/obj/machinery/atmospherics/components/unary/heat_exchanger/atmosinit()
+/obj/machinery/atmospherics/components/unary/heat_exchanger/atmos_init()
var/obj/machinery/atmospherics/components/unary/heat_exchanger/partner = partner_ref?.resolve()
if(!partner)
partner_ref = null
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
index 368e9274af67..40d7ebc0af8c 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
@@ -47,7 +47,7 @@
cut_overlays()
if(showpipe)
// everything is already shifted so don't shift the cap
- add_overlay(getpipeimage(icon, "inje_cap", initialize_directions))
+ add_overlay(get_pipe_image(icon, "inje_cap", initialize_directions))
if(!nodes[1] || !on || !is_operational())
icon_state = "inje_off"
@@ -55,7 +55,6 @@
icon_state = "inje_on"
/obj/machinery/atmospherics/components/unary/outlet_injector/process_atmos()
- ..()
injecting = 0
@@ -65,13 +64,7 @@
var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.return_temperature() > 0)
- var/transfer_moles = (air_contents.return_pressure()) * volume_rate / (air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
-
- var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
-
- loc.assume_air(removed)
- air_update_turf()
-
+ loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume())
update_parents()
/obj/machinery/atmospherics/components/unary/outlet_injector/proc/inject()
@@ -84,9 +77,7 @@
injecting = 1
if(air_contents.return_temperature() > 0)
- var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
- var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
- loc.assume_air(removed)
+ loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume())
update_parents()
flick("inje_inject", src)
@@ -112,7 +103,7 @@
))
radio_connection.post_signal(src, signal)
-/obj/machinery/atmospherics/components/unary/outlet_injector/atmosinit()
+/obj/machinery/atmospherics/components/unary/outlet_injector/atmos_init()
set_frequency(frequency)
broadcast_status()
..()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm
index b511f3ff624a..8a44fb2bcb61 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm
@@ -2,7 +2,6 @@
icon_state = "passive_vent_map-3"
name = "passive vent"
desc = "It is an open vent."
-
can_unwrench = TRUE
layer = GAS_SCRUBBER_LAYER
shift_underlay_only = FALSE
@@ -12,7 +11,7 @@
/obj/machinery/atmospherics/components/unary/passive_vent/update_icon_nopipes()
cut_overlays()
if(showpipe)
- var/image/cap = getpipeimage(icon, "vent_cap", initialize_directions)
+ var/image/cap = get_pipe_image(icon, "vent_cap", initialize_directions)
add_overlay(cap)
icon_state = "passive_vent"
@@ -21,11 +20,20 @@
if(isclosedturf(location))
return
+ var/active = FALSE
var/datum/gas_mixture/external = location.return_air()
var/datum/gas_mixture/internal = airs[1]
+ var/external_pressure = external.return_pressure()
+ var/internal_pressure = internal.return_pressure()
+ var/pressure_delta = abs(external_pressure - internal_pressure)
+
+ if(pressure_delta > 0.5)
+ equalize_all_gases_in_list(list(internal,external))
+ active = TRUE
+
+ active = internal.temperature_share(external, OPEN_HEAT_TRANSFER_COEFFICIENT) || active
- if(internal.equalize(external))
- air_update_turf()
+ if(active)
update_parents()
/obj/machinery/atmospherics/components/unary/passive_vent/can_crawl_through()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
index 782bbe2e4064..a5d1fe5b0a29 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
@@ -11,6 +11,7 @@
pipe_state = "connector"
piping_layer = 3
showpipe = TRUE
+ custom_reconcilation = TRUE
var/obj/machinery/portable_atmospherics/connected_device
@@ -24,11 +25,22 @@
connected_device.disconnect()
return ..()
+/obj/machinery/atmospherics/components/unary/portables_connector/return_airs_for_reconcilation(datum/pipeline/requester)
+ . = ..()
+ if(!connected_device)
+ return
+ if(istype(connected_device, /obj/mecha))
+ var/obj/mecha/connected_mech = connected_device
+ if(connected_mech.internal_tank)
+ . += connected_mech.internal_tank.return_air()
+ else
+ . += connected_device.return_air()
+
/obj/machinery/atmospherics/components/unary/portables_connector/update_icon_nopipes()
icon_state = "connector"
if(showpipe)
cut_overlays()
- var/image/cap = getpipeimage(icon, "connector_cap", initialize_directions)
+ var/image/cap = get_pipe_image(icon, "connector_cap", initialize_directions)
add_overlay(cap)
/obj/machinery/atmospherics/components/unary/portables_connector/process_atmos()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
index c52bd69bb205..de6de198bf09 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
@@ -14,58 +14,57 @@
var/volume = 10000 //in liters
var/gas_type = 0
-/obj/machinery/atmospherics/components/unary/tank/New()
- ..()
+/obj/machinery/atmospherics/components/unary/tank/Initialize(mapload)
+ . = ..()
var/datum/gas_mixture/air_contents = airs[1]
air_contents.set_volume(volume)
air_contents.set_temperature(T20C)
if(gas_type)
- air_contents.set_moles(AIR_CONTENTS)
- name = "[name] ([GLOB.meta_gas_info[gas_type][META_GAS_NAME]])"
- setPipingLayer(piping_layer)
-
+ air_contents.set_moles(gas_type, AIR_CONTENTS)
+ name = "[name] ([GLOB.gas_data.names[gas_type]])"
+ set_piping_layer(piping_layer)
/obj/machinery/atmospherics/components/unary/tank/air
icon_state = "grey"
name = "pressure tank (Air)"
-/obj/machinery/atmospherics/components/unary/tank/air/New()
- ..()
+/obj/machinery/atmospherics/components/unary/tank/air/Initialize(mapload)
+ . = ..()
var/datum/gas_mixture/air_contents = airs[1]
- air_contents.set_moles(/datum/gas/oxygen, AIR_CONTENTS * 0.2)
- air_contents.set_moles(/datum/gas/nitrogen, AIR_CONTENTS * 0.8)
+ air_contents.set_moles(GAS_O2, AIR_CONTENTS * 0.2)
+ air_contents.set_moles(GAS_N2, AIR_CONTENTS * 0.8)
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
- gas_type = /datum/gas/carbon_dioxide
+ gas_type = GAS_CO2
-/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide/New()
- ..()
+/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide/Initialize(mapload)
+ . = ..()
var/datum/gas_mixture/air_contents = airs[1]
- air_contents.set_moles(/datum/gas/carbon_dioxide, AIR_CONTENTS)
+ air_contents.set_moles(GAS_CO2, AIR_CONTENTS)
/obj/machinery/atmospherics/components/unary/tank/toxins
icon_state = "orange"
- gas_type = /datum/gas/plasma
+ gas_type = GAS_PLASMA
-/obj/machinery/atmospherics/components/unary/tank/toxins/New()
- ..()
+/obj/machinery/atmospherics/components/unary/tank/toxins/Initialize(mapload)
+ . = ..()
var/datum/gas_mixture/air_contents = airs[1]
- air_contents.set_moles(/datum/gas/plasma, AIR_CONTENTS)
+ air_contents.set_moles(GAS_PLASMA, AIR_CONTENTS)
/obj/machinery/atmospherics/components/unary/tank/oxygen
icon_state = "blue"
- gas_type = /datum/gas/oxygen
+ gas_type = GAS_O2
-/obj/machinery/atmospherics/components/unary/tank/oxygen/New()
- ..()
+/obj/machinery/atmospherics/components/unary/tank/oxygen/Initialize(mapload)
+ . = ..()
var/datum/gas_mixture/air_contents = airs[1]
- air_contents.set_moles(/datum/gas/oxygen, AIR_CONTENTS)
+ air_contents.set_moles(GAS_O2, AIR_CONTENTS)
/obj/machinery/atmospherics/components/unary/tank/nitrogen
icon_state = "red"
- gas_type = /datum/gas/nitrogen
+ gas_type = GAS_N2
-/obj/machinery/atmospherics/components/unary/tank/nitrogen/New()
- ..()
+/obj/machinery/atmospherics/components/unary/tank/nitrogen/Initialize(mapload)
+ . = ..()
var/datum/gas_mixture/air_contents = airs[1]
- air_contents.set_moles(/datum/gas/nitrogen, AIR_CONTENTS)
\ No newline at end of file
+ air_contents.set_moles(GAS_N2, AIR_CONTENTS)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
index 9a6d2231040b..bad3de341d73 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
@@ -82,7 +82,7 @@
/obj/machinery/atmospherics/components/unary/thermomachine/update_overlays()
. = ..()
- . += getpipeimage(icon, "pipe", dir, , piping_layer)
+ . += get_pipe_image(icon, "pipe", dir, , piping_layer)
/obj/machinery/atmospherics/components/unary/thermomachine/AltClick(mob/living/user)
if(!can_interact(user))
@@ -99,7 +99,7 @@
/obj/machinery/atmospherics/components/unary/thermomachine/update_icon_nopipes()
cut_overlays()
if(showpipe)
- add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions))
+ add_overlay(get_pipe_image(icon, "scrub_cap", initialize_directions))
/obj/machinery/atmospherics/components/unary/thermomachine/examine(mob/user)
. = ..()
@@ -116,7 +116,6 @@
return ..()
/obj/machinery/atmospherics/components/unary/thermomachine/process_atmos()
- ..()
if(!on || !nodes[1])
return
var/datum/gas_mixture/air_contents = airs[1]
@@ -140,6 +139,7 @@
/obj/machinery/atmospherics/components/unary/thermomachine/attackby(obj/item/I, mob/user, params)
if(!on)
if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_off, I))
+ change_pipe_connection(panel_open)
return
if(default_change_direction_wrench(user, I))
return
@@ -150,21 +150,8 @@
/obj/machinery/atmospherics/components/unary/thermomachine/default_change_direction_wrench(mob/user, obj/item/I)
if(!..())
return FALSE
- SetInitDirections()
- var/obj/machinery/atmospherics/node = nodes[1]
- if(node)
- if(src in node.nodes) //Only if it's actually connected. On-pipe version would is one-sided.
- node.disconnect(src)
- nodes[1] = null
- if(parents[1])
- nullifyPipenet(parents[1])
-
- atmosinit()
- node = nodes[1]
- if(node)
- node.atmosinit()
- node.addMember(src)
- SSair.add_to_rebuild_queue(src)
+ set_init_directions()
+ update_icon(UPDATE_ICON)
return TRUE
/obj/machinery/atmospherics/components/unary/thermomachine/ui_status(mob/user)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
index db73b2ea8a45..b61cc02b516e 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
@@ -13,7 +13,7 @@
pipe_interference_group = "atmos-[piping_layer]"\
)
-/obj/machinery/atmospherics/components/unary/SetInitDirections()
+/obj/machinery/atmospherics/components/unary/set_init_directions()
initialize_directions = dir
/obj/machinery/atmospherics/components/unary/on_construction()
@@ -27,3 +27,27 @@
/obj/machinery/atmospherics/components/unary/proc/assign_uid_vents()
uid = num2text(gl_uid++)
return uid
+
+/obj/machinery/atmospherics/components/unary/proc/change_pipe_connection(disconnect)
+ if(disconnect)
+ disconnect_pipes()
+ return
+ connect_pipes()
+
+/obj/machinery/atmospherics/components/unary/proc/connect_pipes()
+ var/obj/machinery/atmospherics/node1 = nodes[1]
+ atmos_init()
+ node1 = nodes[1]
+ if(node1)
+ node1.atmos_init()
+ node1.add_member(src)
+ SSair.add_to_rebuild_queue(src)
+
+/obj/machinery/atmospherics/components/unary/proc/disconnect_pipes()
+ var/obj/machinery/atmospherics/node1 = nodes[1]
+ if(node1)
+ if(src in node1.nodes) //Only if it's actually connected. On-pipe version would is one-sided.
+ node1.disconnect(src)
+ nodes[1] = null
+ if(parents[1])
+ nullify_pipenet(parents[1])
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
index bc6b484c6dd2..18c8cc194bfb 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
@@ -67,7 +67,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/update_icon_nopipes()
cut_overlays()
if(showpipe)
- var/image/cap = getpipeimage(icon, "vent_cap", initialize_directions)
+ var/image/cap = get_pipe_image(icon, "vent_cap", initialize_directions)
add_overlay(cap)
else
PIPING_LAYER_SHIFT(src, PIPING_LAYER_DEFAULT)
@@ -111,8 +111,7 @@
icon_state = "vent_in"
/obj/machinery/atmospherics/components/unary/vent_pump/process_atmos()
- ..()
- if(!is_operational())
+ if(!is_operational() || !isopenturf(loc))
last_moles_added = 0
return
if(space_shutoff_ticks > 0)
@@ -128,6 +127,10 @@
var/datum/gas_mixture/air_contents = airs[1]
var/datum/gas_mixture/environment = loc.return_air()
+
+ if(!environment)
+ return
+
var/environment_pressure = environment.return_pressure()
var/environment_moles = environment.total_moles()
var/last_moles_real_added = environment_moles - last_moles
@@ -161,11 +164,7 @@
var/transfer_moles = pressure_delta*environment.return_volume()/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
last_moles_added = transfer_moles
-
- var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
-
- loc.assume_air(removed)
- air_update_turf()
+ loc.assume_air_moles(air_contents, transfer_moles)
else // external -> internal
last_moles_added = 0
@@ -178,12 +177,7 @@
moles_delta = min(moles_delta, (internal_pressure_bound - air_contents.return_pressure()) * our_multiplier)
if(moles_delta > 0)
- var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
- if (isnull(removed)) // in space
- return
-
- air_contents.merge(removed)
- air_update_turf()
+ loc.transfer_air(air_contents, moles_delta)
last_moles = environment_moles
update_parents()
@@ -222,7 +216,7 @@
radio_connection.post_signal(src, signal, radio_filter_out)
-/obj/machinery/atmospherics/components/unary/vent_pump/atmosinit()
+/obj/machinery/atmospherics/components/unary/vent_pump/atmos_init()
//some vents work his own spesial way
radio_filter_in = frequency==FREQ_ATMOS_CONTROL?(RADIO_FROM_AIRALARM):null
radio_filter_out = frequency==FREQ_ATMOS_CONTROL?(RADIO_TO_AIRALARM):null
@@ -496,6 +490,14 @@
name = "air mix tank output inlet"
id_tag = ATMOS_GAS_MONITOR_OUTPUT_AIR
+/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on/server
+ name = "server vent"
+
+/obj/machinery/atmospherics/components/unary/vent_pump/on/server
+ name = "server vent"
+ external_pressure_bound = 4000
+ internal_pressure_bound = 0
+
#undef INT_BOUND
#undef EXT_BOUND
#undef NO_BOUND
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index 2729cb4f456a..4631397bb504 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -15,10 +15,11 @@
layer = GAS_SCRUBBER_LAYER
shift_underlay_only = FALSE
showpipe = FALSE
+
var/id_tag = null
var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing
- var/filter_types = list(/datum/gas/carbon_dioxide)
+ var/filter_types = list(GAS_CO2)
var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
var/list/turf/adjacent_turfs = list()
@@ -35,11 +36,6 @@
if(!id_tag)
id_tag = assign_uid_vents()
- for(var/f in filter_types)
- if(istext(f))
- filter_types -= f
- filter_types += gas_id2path(f)
-
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
var/area/A = get_area(src)
if (A)
@@ -70,7 +66,7 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes()
cut_overlays()
if(showpipe)
- var/image/cap = getpipeimage(icon, "scrub_cap", initialize_directions)
+ var/image/cap = get_pipe_image(icon, "scrub_cap", initialize_directions)
add_overlay(cap)
else
PIPING_LAYER_SHIFT(src, PIPING_LAYER_DEFAULT)
@@ -101,9 +97,8 @@
return FALSE
var/list/f_types = list()
- for(var/path in GLOB.meta_gas_info)
- var/list/gas = GLOB.meta_gas_info[path]
- f_types += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in filter_types)))
+ for(var/id in GLOB.gas_data.ids)
+ f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.labels[id], "enabled" = (id in filter_types)))
var/datum/signal/signal = new(list(
"tag" = id_tag,
@@ -127,7 +122,7 @@
return TRUE
-/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit()
+/obj/machinery/atmospherics/components/unary/vent_scrubber/atmos_init()
radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null
radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null
if(frequency)
@@ -137,7 +132,6 @@
..()
/obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos()
- ..()
if(welded || !is_operational())
return FALSE
if(!nodes[1] || !on)
@@ -149,39 +143,23 @@
scrub(tile)
return TRUE
-/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(turf/tile)
+/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(turf/open/tile)
if(!istype(tile))
return FALSE
var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1]
+ if(!environment)
+ return FALSE
+
if(air_contents.return_pressure() >= 50 * ONE_ATMOSPHERE)
return FALSE
if(scrubbing & SCRUBBING)
- var/transfer_moles = min(1, volume_rate / environment.return_volume()) * environment.total_moles()
-
- //Take a gas sample
- var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
-
- //Nothing left to remove from the tile
- if(isnull(removed))
- return FALSE
-
- removed.scrub_into(air_contents, filter_types)
-
- //Remix the resulting gases
- tile.assume_air(removed)
- tile.air_update_turf()
+ environment.scrub_into(air_contents, volume_rate/environment.return_volume(), filter_types)
else //Just siphoning all air
-
- var/transfer_moles = environment.total_moles() * (volume_rate / environment.return_volume())
-
- var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
-
- air_contents.merge(removed)
- tile.air_update_turf()
+ environment.transfer_ratio_to(air_contents, volume_rate/environment.return_volume())
update_parents()
@@ -227,12 +205,12 @@
investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS)
if("toggle_filter" in signal.data)
- filter_types ^= gas_id2path(signal.data["toggle_filter"])
+ filter_types ^= signal.data["toggle_filter"]
if("set_filters" in signal.data)
filter_types = list()
for(var/gas in signal.data["set_filters"])
- filter_types += gas_id2path(gas)
+ filter_types += gas
if("init" in signal.data)
name = signal.data["init"]
diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm
index 2836c6199e60..e5a2eb7addff 100644
--- a/code/modules/atmospherics/machinery/datum_pipeline.dm
+++ b/code/modules/atmospherics/machinery/datum_pipeline.dm
@@ -3,134 +3,164 @@
var/list/datum/gas_mixture/other_airs
var/list/obj/machinery/atmospherics/pipe/members
- var/list/obj/machinery/atmospherics/components/other_atmosmch
+ var/list/obj/machinery/atmospherics/components/other_atmos_machines
var/update = TRUE
+ var/building = FALSE
+
/datum/pipeline/New()
other_airs = list()
members = list()
- other_atmosmch = list()
+ other_atmos_machines = list()
SSair.networks += src
/datum/pipeline/Destroy()
SSair.networks -= src
+ if(building)
+ SSair.remove_from_expansion(src)
if(air && air.return_volume())
temporarily_store_air()
- for(var/obj/machinery/atmospherics/pipe/P in members)
- P.parent = null
- for(var/obj/machinery/atmospherics/components/C in other_atmosmch)
- C.nullifyPipenet(src)
+ for(var/obj/machinery/atmospherics/pipe/considered_pipe in members)
+ considered_pipe.parent = null
+ if(QDELETED(considered_pipe))
+ continue
+ SSair.add_to_rebuild_queue(considered_pipe)
+ for(var/obj/machinery/atmospherics/components/considered_component in other_atmos_machines)
+ considered_component.nullify_pipenet(src)
return ..()
/datum/pipeline/process()
- if(update)
- update = FALSE
- reconcile_air()
+ if(!update || building)
+ return
+ update = FALSE
+ reconcile_air()
update = air.react(src)
/datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/base)
+ building = TRUE
var/volume = 0
if(istype(base, /obj/machinery/atmospherics/pipe))
- var/obj/machinery/atmospherics/pipe/E = base
- volume = E.volume
- members += E
- if(E.air_temporary)
- air = E.air_temporary
- E.air_temporary = null
+ var/obj/machinery/atmospherics/pipe/considered_pipe = base
+ volume = considered_pipe.volume
+ members += considered_pipe
+ if(considered_pipe.air_temporary)
+ air = considered_pipe.air_temporary
+ considered_pipe.air_temporary = null
else
- addMachineryMember(base)
+ add_machinery_member(base)
+ if(!air)
+ air = new
+ air.set_volume(volume)
+ SSair.add_to_expansion(src, base)
+
+///Has the same effect as build_pipeline(), but this doesn't queue its work, so overrun abounds. It's useful for the pregame
+/datum/pipeline/proc/build_pipeline_blocking(obj/machinery/atmospherics/base)
+ var/volume = 0
+ if(istype(base, /obj/machinery/atmospherics/pipe))
+ var/obj/machinery/atmospherics/pipe/considered_pipe = base
+ volume = considered_pipe.volume
+ members += considered_pipe
+ if(considered_pipe.air_temporary)
+ air = considered_pipe.air_temporary
+ considered_pipe.air_temporary = null
+ else
+ add_machinery_member(base)
+
if(!air)
air = new
var/list/possible_expansions = list(base)
while(possible_expansions.len)
for(var/obj/machinery/atmospherics/borderline in possible_expansions)
var/list/result = borderline.pipeline_expansion(src)
- if(result && result.len)
- 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)
- var/static/pipenetwarnings = 100
- if(pipenetwarnings > 0)
- log_mapping("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) around [AREACOORD(item)].")
- pipenetwarnings--
- if(pipenetwarnings == 0)
- log_mapping("build_pipeline(): further messages about pipenets will be suppressed")
- members += item
- possible_expansions += item
-
- volume += item.volume
- item.parent = src
-
- if(item.air_temporary)
- air.merge(item.air_temporary)
- item.air_temporary = null
- else
- P.setPipenet(src, borderline)
- addMachineryMember(P)
+ if(!result?.len)
+ possible_expansions -= borderline
+ continue
+ for(var/obj/machinery/atmospherics/considered_device in result)
+ if(!istype(considered_device, /obj/machinery/atmospherics/pipe))
+ considered_device.set_pipenet(src, borderline)
+ add_machinery_member(considered_device)
+ continue
+ var/obj/machinery/atmospherics/pipe/item = considered_device
+ if(members.Find(item))
+ continue
+ if(item.parent)
+ var/static/pipenetwarnings = 10
+ if(pipenetwarnings > 0)
+ log_mapping("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) around [AREACOORD(item)].")
+ pipenetwarnings--
+ if(pipenetwarnings == 0)
+ log_mapping("build_pipeline(): further messages about pipenets will be suppressed")
+
+ members += item
+ possible_expansions += item
+
+ volume += item.volume
+ item.parent = src
+
+ if(item.air_temporary)
+ air.merge(item.air_temporary)
+ item.air_temporary = null
possible_expansions -= borderline
air.set_volume(volume)
-/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/components/C)
- other_atmosmch |= C
- var/datum/gas_mixture/G = C.returnPipenetAir(src)
- if(!G)
- stack_trace("addMachineryMember: Null gasmix added to pipeline datum from [C] which is of type [C.type]. Nearby: ([C.x], [C.y], [C.z])")
- 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
- if(P.parent)
- merge(P.parent)
- 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.set_volume(air.return_volume() + P.volume)
+/datum/pipeline/proc/add_machinery_member(obj/machinery/atmospherics/components/considered_component)
+ other_atmos_machines |= considered_component
+ var/list/returned_airs = considered_component.return_pipenet_airs(src)
+ if (!length(returned_airs) || (null in returned_airs))
+ stack_trace("addMachineryMember: Nonexistent (empty list) or null machinery gasmix added to pipeline datum from [considered_component] \
+ which is of type [considered_component.type]. Nearby: ([considered_component.x], [considered_component.y], [considered_component.z])")
+ other_airs |= returned_airs
+
+/datum/pipeline/proc/add_member(obj/machinery/atmospherics/reference_device, obj/machinery/atmospherics/device_to_add)
+ if(!istype(reference_device, /obj/machinery/atmospherics/pipe))
+ reference_device.set_pipenet(src, device_to_add)
+ add_machinery_member(reference_device)
else
- A.setPipenet(src, N)
- addMachineryMember(A)
-
-/datum/pipeline/proc/merge(datum/pipeline/E)
- if(E == src)
+ var/obj/machinery/atmospherics/pipe/reference_pipe = reference_device
+ if(reference_pipe.parent)
+ merge(reference_pipe.parent)
+ reference_pipe.parent = src
+ var/list/adjacent = reference_pipe.pipeline_expansion()
+ for(var/obj/machinery/atmospherics/pipe/adjacent_pipe in adjacent)
+ if(adjacent_pipe.parent == src)
+ continue
+ var/datum/pipeline/parent_pipeline = adjacent_pipe.parent
+ merge(parent_pipeline)
+ if(!members.Find(reference_pipe))
+ members += reference_pipe
+ air.set_volume(air.return_volume() + reference_pipe.volume)
+
+/datum/pipeline/proc/merge(datum/pipeline/parent_pipeline)
+ if(parent_pipeline == src)
return
- air.set_volume(air.return_volume() + E.air.return_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/components/C in E.other_atmosmch)
- C.replacePipenet(E, src)
- other_atmosmch.Add(E.other_atmosmch)
- other_airs.Add(E.other_airs)
- E.members.Cut()
- E.other_atmosmch.Cut()
+ air.set_volume(air.return_volume() + parent_pipeline.air.return_volume())
+ members.Add(parent_pipeline.members)
+ for(var/obj/machinery/atmospherics/pipe/reference_pipe in parent_pipeline.members)
+ reference_pipe.parent = src
+ air.merge(parent_pipeline.air)
+ for(var/obj/machinery/atmospherics/components/reference_component in parent_pipeline.other_atmos_machines)
+ reference_component.replace_pipenet(parent_pipeline, src)
+ other_atmos_machines |= parent_pipeline.other_atmos_machines
+ other_airs |= parent_pipeline.other_airs
+ parent_pipeline.members.Cut()
+ parent_pipeline.other_atmos_machines.Cut()
update = TRUE
- qdel(E)
+ qdel(parent_pipeline)
-/obj/machinery/atmospherics/proc/addMember(obj/machinery/atmospherics/A)
+/obj/machinery/atmospherics/proc/add_member(obj/machinery/atmospherics/considered_device)
return
-/obj/machinery/atmospherics/pipe/addMember(obj/machinery/atmospherics/A)
- parent.addMember(A, src)
-
-/obj/machinery/atmospherics/components/addMember(obj/machinery/atmospherics/A)
- var/datum/pipeline/P = returnPipenet(A)
- if(!P)
- CRASH("null.addMember() called by [type] on [COORD(src)]")
- P.addMember(A, src)
+/obj/machinery/atmospherics/pipe/add_member(obj/machinery/atmospherics/considered_device)
+ parent.add_member(considered_device, src)
+/obj/machinery/atmospherics/components/add_member(obj/machinery/atmospherics/considered_device)
+ var/datum/pipeline/device_pipeline = return_pipenet(considered_device)
+ if(!device_pipeline)
+ CRASH("null.add_member() called by [type] on [COORD(src)]")
+ device_pipeline.add_member(considered_device, src)
/datum/pipeline/proc/temporarily_store_air()
//Update individual gas_mixtures by volume ratio
@@ -186,13 +216,13 @@
else
return 1
- air.set_temperature(air.return_temperature() + self_temperature_delta);
+ air.set_temperature(air.return_temperature() + self_temperature_delta)
modeled_location.TakeTemperature(sharer_temperature_delta)
else
if((target.heat_capacity>0) && (partial_heat_capacity>0))
- var/delta_temperature = air.return_temperature() - target.temperature
+ var/delta_temperature = air.return_temperature() - target.return_temperature()
var/heat = thermal_conductivity*delta_temperature* \
(partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
@@ -205,43 +235,28 @@
if(listclearnulls(.))
stack_trace("[src] has one or more null gas mixtures, which may cause bugs. Null mixtures will not be considered in reconcile_air().")
-/datum/pipeline/proc/reconcile_air()
- var/list/datum/gas_mixture/GL = list()
- var/list/datum/pipeline/PL = list()
- PL += src
+/datum/pipeline/proc/empty()
+ for(var/datum/gas_mixture/GM as anything in get_all_connected_airs())
+ GM?.clear()
- for(var/i = 1; i <= PL.len; i++) //can't do a for-each here because we may add to the list within the loop
- var/datum/pipeline/P = PL[i]
- if(!P)
- continue
- GL += P.other_airs
- GL += P.air
- for(var/atmosmch in P.other_atmosmch)
- if (istype(atmosmch, /obj/machinery/atmospherics/components/binary/valve))
- var/obj/machinery/atmospherics/components/binary/valve/V = atmosmch
- if(V.on)
- PL |= V.parents[1]
- PL |= V.parents[2]
- else if (istype(atmosmch, /obj/machinery/atmospherics/components/unary/portables_connector))
- var/obj/machinery/atmospherics/components/unary/portables_connector/C = atmosmch
- if(C.connected_device)
- GL += C.connected_device.air_contents
-
- var/datum/gas_mixture/total_gas_mixture = new(0)
- var/total_volume = 0
-
- for(var/i in GL)
- if(!i)
+/datum/pipeline/proc/get_all_connected_airs()
+ var/list/datum/gas_mixture/gas_mixture_list = list()
+ var/list/datum/pipeline/pipeline_list = list()
+ pipeline_list += src
+
+ for(var/i = 1; i <= pipeline_list.len; i++) //can't do a for-each here because we may add to the list within the loop
+ var/datum/pipeline/pipeline = pipeline_list[i]
+ if(!pipeline)
continue
- var/datum/gas_mixture/G = i
- total_gas_mixture.merge(G)
- total_volume += G.return_volume()
-
- if(total_volume > 0)
- //Update individual gas_mixtures by volume ratio
- for(var/i in GL)
- if(!i)
+ gas_mixture_list += pipeline.other_airs
+ gas_mixture_list += pipeline.air
+ for(var/obj/machinery/atmospherics/components/atmos_machine in pipeline.other_atmos_machines)
+ if(!atmos_machine.custom_reconcilation)
continue
- var/datum/gas_mixture/G = i
- G.copy_from(total_gas_mixture)
- G.multiply(G.return_volume()/total_volume)
+ pipeline_list |= atmos_machine.return_pipenets_for_reconcilation(src)
+ gas_mixture_list |= atmos_machine.return_airs_for_reconcilation(src)
+ return gas_mixture_list
+
+/datum/pipeline/proc/reconcile_air()
+ var/list/datum/gas_mixture/GL = get_all_connected_airs()
+ equalize_all_gases_in_list(GL)
diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm
index e05e29c009d4..3e511d438366 100644
--- a/code/modules/atmospherics/machinery/other/meter.dm
+++ b/code/modules/atmospherics/machinery/other/meter.dm
@@ -32,14 +32,14 @@
id_tag = ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION
/obj/machinery/meter/Destroy()
- SSair.atmos_machinery -= src
+ SSair_machinery.stop_processing_machine(src)
target = null
return ..()
/obj/machinery/meter/Initialize(mapload, new_piping_layer)
if(!isnull(new_piping_layer))
target_layer = new_piping_layer
- SSair.atmos_machinery += src
+ SSair_machinery.start_processing_machine(src)
if(!target)
reattach_to_layer()
return ..()
diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm
index 2a6a583ab6de..78c154084256 100644
--- a/code/modules/atmospherics/machinery/other/miner.dm
+++ b/code/modules/atmospherics/machinery/other/miner.dm
@@ -117,24 +117,23 @@
on_overlay.color = overlay_color
. += on_overlay
-/obj/machinery/atmospherics/miner/process(delta_time)
+/obj/machinery/atmospherics/miner/process_atmos()
update_power()
check_operation()
if(active && !broken)
if(isnull(spawn_id))
return FALSE
if(do_use_power(active_power_usage))
- mine_gas(delta_time)
+ mine_gas()
-/obj/machinery/atmospherics/miner/proc/mine_gas(delta_time = 2)
+/obj/machinery/atmospherics/miner/proc/mine_gas()
var/turf/open/O = get_turf(src)
if(!isopenturf(O))
return FALSE
var/datum/gas_mixture/merger = new
- merger.set_moles(spawn_id, (spawn_mol * delta_time))
+ merger.set_moles(spawn_id, spawn_mol)
merger.set_temperature(spawn_temp)
O.assume_air(merger)
- O.air_update_turf(TRUE)
/obj/machinery/atmospherics/miner/attack_ai(mob/living/silicon/user)
if(broken)
@@ -144,39 +143,39 @@
/obj/machinery/atmospherics/miner/n2o
name = "\improper N2O Gas Miner"
overlay_color = "#FFCCCC"
- spawn_id = /datum/gas/nitrous_oxide
+ spawn_id = GAS_NITROUS
/obj/machinery/atmospherics/miner/nitrogen
name = "\improper N2 Gas Miner"
overlay_color = "#CCFFCC"
- spawn_id = /datum/gas/nitrogen
+ spawn_id = GAS_N2
/obj/machinery/atmospherics/miner/oxygen
name = "\improper O2 Gas Miner"
overlay_color = "#007FFF"
- spawn_id = /datum/gas/oxygen
+ spawn_id = GAS_O2
/obj/machinery/atmospherics/miner/hydrogen
name = "\improper H2 Gas Miner"
overlay_color = "#ff0000"
- spawn_id = /datum/gas/hydrogen
+ spawn_id = GAS_H2
/obj/machinery/atmospherics/miner/toxins
name = "\improper Plasma Gas Miner"
overlay_color = "#ff6600"
- spawn_id = /datum/gas/plasma
+ spawn_id = GAS_PLASMA
/obj/machinery/atmospherics/miner/carbon_dioxide
name = "\improper CO2 Gas Miner"
overlay_color = "#CDCDCD"
- spawn_id = /datum/gas/carbon_dioxide
+ spawn_id = GAS_CO2
/obj/machinery/atmospherics/miner/bz
name = "\improper BZ Gas Miner"
overlay_color = "#FAFF00"
- spawn_id = /datum/gas/bz
+ spawn_id = GAS_BZ
/obj/machinery/atmospherics/miner/water_vapor
name = "\improper Water Vapor Gas Miner"
overlay_color = "#99928E"
- spawn_id = /datum/gas/water_vapor
+ spawn_id = GAS_H2O
diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm
index 40db098a78ac..43721f5de7b1 100644
--- a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm
+++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm
@@ -11,7 +11,7 @@
. = ..()
add_atom_colour("#404040", FIXED_COLOUR_PRIORITY)
-/obj/machinery/atmospherics/pipe/heat_exchanging/isConnectable(obj/machinery/atmospherics/pipe/heat_exchanging/target, given_layer, HE_type_check = TRUE)
+/obj/machinery/atmospherics/pipe/heat_exchanging/is_connectable(obj/machinery/atmospherics/pipe/heat_exchanging/target, given_layer, HE_type_check = TRUE)
if(istype(target, /obj/machinery/atmospherics/pipe/heat_exchanging) != HE_type_check)
return FALSE
. = ..()
diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm
index 90f2cc47bf89..54eeb02d9425 100644
--- a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm
+++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm
@@ -15,17 +15,17 @@
construction_type = /obj/item/pipe/directional
pipe_state = "junction"
-/obj/machinery/atmospherics/pipe/heat_exchanging/junction/SetInitDirections()
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction/set_init_directions()
switch(dir)
if(NORTH, SOUTH)
initialize_directions = SOUTH|NORTH
if(EAST, WEST)
initialize_directions = WEST|EAST
-/obj/machinery/atmospherics/pipe/heat_exchanging/junction/getNodeConnects()
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction/get_node_connects()
return list(turn(dir, 180), dir)
-/obj/machinery/atmospherics/pipe/heat_exchanging/junction/isConnectable(obj/machinery/atmospherics/target, given_layer, he_type_check)
+/obj/machinery/atmospherics/pipe/heat_exchanging/junction/is_connectable(obj/machinery/atmospherics/target, given_layer, he_type_check)
if(dir == get_dir(target, src))
return ..(target, given_layer, FALSE) //we want a normal pipe instead
return ..(target, given_layer, TRUE)
diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
index 5e995528d4a2..ada7a478f4c5 100644
--- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
+++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
@@ -15,12 +15,13 @@
construction_type = /obj/item/pipe/trinary
pipe_state = "he_manifold"
-/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/New()
+
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/New(mapload)
icon_state = ""
return ..()
-/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/SetInitDirections()
- initialize_directions = NORTH|SOUTH|EAST|WEST
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/set_init_directions()
+ initialize_directions = ALL_CARDINALS
initialize_directions &= ~dir
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/update_overlays()
@@ -33,7 +34,7 @@
//Add non-broken pieces
for(var/i in 1 to device_type)
if(nodes[i])
- . += getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i]))
+ . += get_pipe_image(icon, "pipe-[piping_layer]", get_dir(src, nodes[i]))
update_layer()
update_alpha()
diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm
index 22d73b285bc7..72f6a61c6371 100644
--- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm
+++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm
@@ -7,7 +7,7 @@
name = "4-way pipe manifold"
desc = "A manifold composed of heat-exchanging pipes."
- initialize_directions = NORTH|SOUTH|EAST|WEST
+ initialize_directions = ALL_CARDINALS
device_type = QUATERNARY
@@ -18,7 +18,7 @@
icon_state = ""
return ..()
-/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/SetInitDirections()
+/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/set_init_directions()
initialize_directions = initial(initialize_directions)
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/update_overlays()
@@ -30,7 +30,7 @@
//Add non-broken pieces
for(var/i in 1 to device_type)
if(nodes[i])
- . += getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i]))
+ . += get_pipe_image(icon, "pipe-[piping_layer]", get_dir(src, nodes[i]))
update_layer()
update_alpha()
diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm
index f3f472efb7e1..18879f86da1e 100644
--- a/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm
+++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm
@@ -14,7 +14,7 @@
construction_type = /obj/item/pipe/binary/bendable
pipe_state = "he"
-/obj/machinery/atmospherics/pipe/heat_exchanging/simple/SetInitDirections()
+/obj/machinery/atmospherics/pipe/heat_exchanging/simple/set_init_directions()
if(dir in GLOB.diagonals)
initialize_directions = dir
return
diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm
index 4044ebc99fd2..d979f42c53a0 100644
--- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm
+++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm
@@ -68,21 +68,21 @@
// Uses pipe-3 because we don't want the vertical shifting
if(p_color)
- new_overlay = getpipeimage(icon, "pipe-3", p_dir, p_color, piping_layer = p_layer)
+ new_overlay = get_pipe_image(icon, "pipe-3", p_dir, p_color, piping_layer = p_layer)
else
- new_overlay = getpipeimage(icon, "pipe-3", p_dir, piping_layer = p_layer)
+ new_overlay = get_pipe_image(icon, "pipe-3", p_dir, piping_layer = p_layer)
new_overlay.layer = layer - 0.01
return new_overlay
-/obj/machinery/atmospherics/pipe/layer_manifold/SetInitDirections()
+/obj/machinery/atmospherics/pipe/layer_manifold/set_init_directions()
switch(dir)
if(NORTH, SOUTH)
initialize_directions = NORTH|SOUTH
if(EAST, WEST)
initialize_directions = EAST|WEST
-/obj/machinery/atmospherics/pipe/layer_manifold/isConnectable(obj/machinery/atmospherics/target, given_layer)
+/obj/machinery/atmospherics/pipe/layer_manifold/is_connectable(obj/machinery/atmospherics/target, given_layer)
if(!given_layer)
return TRUE
. = ..()
@@ -92,8 +92,8 @@
back_nodes = list()
var/list/new_nodes = list()
for(var/iter in PIPING_LAYER_MIN to PIPING_LAYER_MAX)
- var/obj/machinery/atmospherics/foundfront = findConnecting(dir, iter)
- var/obj/machinery/atmospherics/foundback = findConnecting(turn(dir, 180), iter)
+ var/obj/machinery/atmospherics/foundfront = find_connecting(dir, iter)
+ var/obj/machinery/atmospherics/foundback = find_connecting(turn(dir, 180), iter)
front_nodes += foundfront
back_nodes += foundback
if(foundfront && !QDELETED(foundfront))
@@ -103,13 +103,13 @@
update_appearance(UPDATE_ICON)
return new_nodes
-/obj/machinery/atmospherics/pipe/layer_manifold/atmosinit()
+/obj/machinery/atmospherics/pipe/layer_manifold/atmos_init()
normalize_cardinal_directions()
findAllConnections()
var/turf/T = loc // hide if turf is not intact
hide(T.intact)
-/obj/machinery/atmospherics/pipe/layer_manifold/setPipingLayer()
+/obj/machinery/atmospherics/pipe/layer_manifold/set_piping_layer()
piping_layer = PIPING_LAYER_DEFAULT
/obj/machinery/atmospherics/pipe/layer_manifold/pipeline_expansion()
diff --git a/code/modules/atmospherics/machinery/pipes/manifold.dm b/code/modules/atmospherics/machinery/pipes/manifold.dm
index 625ebf4ecae9..af37701d74ef 100644
--- a/code/modules/atmospherics/machinery/pipes/manifold.dm
+++ b/code/modules/atmospherics/machinery/pipes/manifold.dm
@@ -24,12 +24,12 @@
* in the mapping subsystem init before Initialize(mapload) is called in the atoms subsystem init.
* This is true for the other manifolds (the 4 ways and the heat exchanges) too.
*/
-/obj/machinery/atmospherics/pipe/manifold/New()
+/obj/machinery/atmospherics/pipe/manifold/New(mapload)
icon_state = ""
return ..()
-/obj/machinery/atmospherics/pipe/manifold/SetInitDirections()
- initialize_directions = NORTH|SOUTH|EAST|WEST
+/obj/machinery/atmospherics/pipe/manifold/set_init_directions()
+ initialize_directions = ALL_CARDINALS
initialize_directions &= ~dir
/obj/machinery/atmospherics/pipe/manifold/update_overlays()
@@ -43,7 +43,7 @@
//Add non-broken pieces
for(var/i in 1 to device_type)
if(nodes[i])
- . += getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i]))
+ . += get_pipe_image(icon, "pipe-[piping_layer]", get_dir(src, nodes[i]))
update_layer()
update_alpha()
diff --git a/code/modules/atmospherics/machinery/pipes/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/manifold4w.dm
index 1ad4d090b130..35d3f68ce1e7 100644
--- a/code/modules/atmospherics/machinery/pipes/manifold4w.dm
+++ b/code/modules/atmospherics/machinery/pipes/manifold4w.dm
@@ -7,7 +7,7 @@
name = "4-way pipe manifold"
desc = "A manifold composed of regular pipes."
- initialize_directions = NORTH|SOUTH|EAST|WEST
+ initialize_directions = ALL_CARDINALS
device_type = QUATERNARY
@@ -19,11 +19,11 @@
pipe_interference_group = "atmos-[piping_layer]"\
)
-/obj/machinery/atmospherics/pipe/manifold4w/New()
+/obj/machinery/atmospherics/pipe/manifold4w/New(mapload)
icon_state = ""
return ..()
-/obj/machinery/atmospherics/pipe/manifold4w/SetInitDirections()
+/obj/machinery/atmospherics/pipe/manifold4w/set_init_directions()
initialize_directions = initial(initialize_directions)
/obj/machinery/atmospherics/pipe/manifold4w/update_overlays()
@@ -35,7 +35,7 @@
//Add non-broken pieces
for(var/i in 1 to device_type)
if(nodes[i])
- . += getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i]))
+ . += get_pipe_image(icon, "pipe-[piping_layer]", get_dir(src, nodes[i]))
update_layer()
update_alpha()
diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm
index bf36ad6a1740..e14ef7818dab 100644
--- a/code/modules/atmospherics/machinery/pipes/pipes.dm
+++ b/code/modules/atmospherics/machinery/pipes/pipes.dm
@@ -18,26 +18,27 @@
),\
)
-/obj/machinery/atmospherics/pipe/New()
+/obj/machinery/atmospherics/pipe/New(mapload)
add_atom_colour(pipe_color, FIXED_COLOUR_PRIORITY)
volume = 35 * device_type
- ..()
+ return ..()
-/obj/machinery/atmospherics/pipe/nullifyNode(i)
- var/obj/machinery/atmospherics/oldN = nodes[i]
- ..()
- if(oldN)
- SSair.add_to_rebuild_queue(oldN)
+/obj/machinery/atmospherics/pipe/nullify_node(i)
+ var/obj/machinery/atmospherics/old_node = nodes[i]
+ . = ..()
+ if(old_node)
+ SSair.add_to_rebuild_queue(old_node)
/obj/machinery/atmospherics/pipe/destroy_network()
QDEL_NULL(parent)
-/obj/machinery/atmospherics/pipe/build_network()
- if(QDELETED(parent))
- parent = new
- parent.build_pipeline(src)
+/obj/machinery/atmospherics/pipe/get_rebuild_targets()
+ if(!QDELETED(parent))
+ return
+ parent = new
+ return list(parent)
-/obj/machinery/atmospherics/pipe/atmosinit()
+/obj/machinery/atmospherics/pipe/atmos_init()
var/turf/T = loc // hide if turf is not intact
hide(T.intact)
..()
@@ -51,19 +52,26 @@
if(air_temporary)
var/turf/T = loc
T.assume_air(air_temporary)
- air_update_turf()
/obj/machinery/atmospherics/pipe/return_air()
- if(parent)
- return parent.air
+ if(air_temporary)
+ return air_temporary
+ return parent.air
/obj/machinery/atmospherics/pipe/return_analyzable_air()
- if(parent)
- return parent.air
+ if(air_temporary)
+ return air_temporary
+ return parent.air
/obj/machinery/atmospherics/pipe/remove_air(amount)
- if(parent)
- return parent.air.remove(amount)
+ if(air_temporary)
+ return air_temporary.remove(amount)
+ return parent.air.remove(amount)
+
+/obj/machinery/atmospherics/pipe/remove_air_ratio(ratio)
+ if(air_temporary)
+ return air_temporary.remove_ratio(ratio)
+ return parent.air.remove_ratio(ratio)
/obj/machinery/atmospherics/pipe/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pipe_meter))
@@ -78,10 +86,10 @@
analyzer_act(user, src)
return ..()
-/obj/machinery/atmospherics/pipe/returnPipenet()
+/obj/machinery/atmospherics/pipe/return_pipenet()
return parent
-/obj/machinery/atmospherics/pipe/setPipenet(datum/pipeline/P)
+/obj/machinery/atmospherics/pipe/set_pipenet(datum/pipeline/P)
parent = P
/obj/machinery/atmospherics/pipe/Destroy()
diff --git a/code/modules/atmospherics/machinery/pipes/simple.dm b/code/modules/atmospherics/machinery/pipes/simple.dm
index 3ac2daf18e06..538ebc89bb64 100644
--- a/code/modules/atmospherics/machinery/pipes/simple.dm
+++ b/code/modules/atmospherics/machinery/pipes/simple.dm
@@ -22,7 +22,7 @@
pipe_interference_group = "atmos-[piping_layer]"\
)
-/obj/machinery/atmospherics/pipe/simple/SetInitDirections()
+/obj/machinery/atmospherics/pipe/simple/set_init_directions()
if(dir in GLOB.diagonals)
initialize_directions = dir
return
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index 4b56e08552e7..1e7c2c6b3148 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -25,7 +25,7 @@
integrity_failure = 100
pressure_resistance = 7 * ONE_ATMOSPHERE
var/temperature_resistance = 1000 + T0C
- var/starter_temp
+ var/starter_temp = T20C
// Prototype vars
var/prototype = FALSE
var/valve_timer = null
@@ -88,37 +88,37 @@
name = "Nitrogen canister"
desc = "Nitrogen gas. Reportedly useful for something."
icon_state = "nitrogen"
- gas_type = /datum/gas/nitrogen
+ gas_type = GAS_N2
/obj/machinery/portable_atmospherics/canister/oxygen
name = "Oxygen canister"
desc = "Oxygen. Necessary for human life."
icon_state = "oxygen"
- gas_type = /datum/gas/oxygen
+ gas_type = GAS_O2
/obj/machinery/portable_atmospherics/canister/carbon_dioxide
name = "Carbon dioxide canister"
desc = "Carbon dioxide. What the fuck is carbon dioxide?"
icon_state = "carbon"
- gas_type = /datum/gas/carbon_dioxide
+ gas_type = GAS_CO2
/obj/machinery/portable_atmospherics/canister/toxins
name = "Plasma canister"
desc = "Plasma gas. The reason YOU are here. Highly toxic."
icon_state = "plasma"
- gas_type = /datum/gas/plasma
+ gas_type = GAS_PLASMA
/obj/machinery/portable_atmospherics/canister/bz
name = "\improper BZ canister"
desc = "BZ, a powerful hallucinogenic nerve agent."
icon_state = "bz"
- gas_type = /datum/gas/bz
+ gas_type = GAS_BZ
/obj/machinery/portable_atmospherics/canister/nitrous_oxide
name = "Nitrous oxide canister"
desc = "Nitrous oxide gas. Known to cause drowsiness."
icon_state = "nitrous"
- gas_type = /datum/gas/nitrous_oxide
+ gas_type = GAS_NITROUS
/obj/machinery/portable_atmospherics/canister/air
name = "Air canister"
@@ -129,100 +129,100 @@
name = "Tritium canister"
desc = "Tritium. Inhalation might cause irradiation."
icon_state = "tritium"
- gas_type = /datum/gas/tritium
+ gas_type = GAS_TRITIUM
/obj/machinery/portable_atmospherics/canister/nob
name = "Hyper-noblium canister"
desc = "Hyper-Noblium. More noble than all other gases."
icon_state = "hypno"
- gas_type = /datum/gas/hypernoblium
+ gas_type = GAS_HYPERNOB
/obj/machinery/portable_atmospherics/canister/nitrium
name = "Nitrium canister"
desc = "Nitrium gas. Feels great 'til the acid eats your lungs."
icon_state = "nitrium"
- gas_type = /datum/gas/nitrium
+ gas_type = GAS_NITRIUM
/obj/machinery/portable_atmospherics/canister/pluoxium
name = "Pluoxium canister"
desc = "Pluoxium. Like oxygen, but more bang for your buck."
icon_state = "pluoxium"
- gas_type = /datum/gas/pluoxium
+ gas_type = GAS_PLUOXIUM
/obj/machinery/portable_atmospherics/canister/water_vapor
name = "Water vapor canister"
desc = "Water vapor. We get it, you vape."
icon_state = "water"
- gas_type = /datum/gas/water_vapor
+ gas_type = GAS_H2O
filled = 1
/obj/machinery/portable_atmospherics/canister/miasma
name = "Miasma canister"
desc = "Foul miasma. Even the canister reeks of fetid refuse."
icon_state = "miasma"
- gas_type = /datum/gas/miasma
+ gas_type = GAS_MIASMA
filled = 1
/obj/machinery/portable_atmospherics/canister/dilithium
name = "Dilithium canister"
desc = "A gas produced from dilithium crystal."
icon_state = "dilithium"
- gas_type = /datum/gas/dilithium
+ gas_type = GAS_DILITHIUM
/obj/machinery/portable_atmospherics/canister/freon
name = "Freon canister"
desc = "Freon. Can absorb heat"
icon_state = "freon"
- gas_type = /datum/gas/freon
+ gas_type = GAS_FREON
filled = 1
/obj/machinery/portable_atmospherics/canister/hydrogen
name = "Hydrogen canister"
desc = "Hydrogen, highly flammable"
icon_state = "h2"
- gas_type = /datum/gas/hydrogen
+ gas_type = GAS_H2
filled = 1
/obj/machinery/portable_atmospherics/canister/healium
name = "Healium canister"
desc = "Healium, causes deep sleep"
icon_state = "healium"
- gas_type = /datum/gas/healium
+ gas_type = GAS_HEALIUM
filled = 1
/obj/machinery/portable_atmospherics/canister/pluonium
name = "Pluonium canister"
desc = "Pluonium, reacts differently with various gases"
icon_state = "pluonium"
- gas_type = /datum/gas/pluonium
+ gas_type = GAS_PLUONIUM
filled = 1
/obj/machinery/portable_atmospherics/canister/halon
name = "Halon canister"
desc = "Halon, remove oxygen from high temperature fires and cool down the area"
icon_state = "halon"
- gas_type = /datum/gas/halon
+ gas_type = GAS_HALON
filled = 1
/obj/machinery/portable_atmospherics/canister/hexane
name = "Hexane canister"
desc = "hexane, highly flammable."
icon_state = "hexane"
- gas_type = /datum/gas/hexane
+ gas_type = GAS_HEXANE
filled = 1
/obj/machinery/portable_atmospherics/canister/zauker
name = "Zauker canister"
desc = "Zauker, highly toxic"
icon_state = "zauker"
- gas_type = /datum/gas/zauker
+ gas_type = GAS_ZAUKER
filled = 1
/obj/machinery/portable_atmospherics/canister/antinoblium
name = "Antinoblium canister"
desc = "Antinoblium, we still don't know what it does, but it sells for a lot"
icon_state = "antino"
- gas_type = /datum/gas/antinoblium
+ gas_type = GAS_ANTINOB
filled = 1
/obj/machinery/portable_atmospherics/canister/proc/get_time_left()
@@ -255,13 +255,13 @@
/obj/machinery/portable_atmospherics/canister/proto/default/oxygen
name = "prototype canister"
desc = "A prototype canister for a prototype bike, what could go wrong?"
- gas_type = /datum/gas/oxygen
+ gas_type = GAS_O2
filled = 1
release_pressure = ONE_ATMOSPHERE*2
-/obj/machinery/portable_atmospherics/canister/New(loc, datum/gas_mixture/existing_mixture)
- ..()
+/obj/machinery/portable_atmospherics/canister/Initialize(mapload, datum/gas_mixture/existing_mixture)
+ . = ..()
if(existing_mixture)
air_contents.copy_from(existing_mixture)
else
@@ -284,13 +284,21 @@
if(gas_type)
if(starter_temp)
air_contents.set_temperature(starter_temp)
- air_contents.set_moles(gas_type, (maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
+ if(air_contents.return_volume() == 0)
+ CRASH("Air content volume is zero, this shouldn't be the case volume is: [volume]!")
+ if(air_contents.return_temperature() == 0)
+ CRASH("Air content temperature is zero, this shouldn't be the case!")
+ if (gas_type)
+ air_contents.set_moles(gas_type, (maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
/obj/machinery/portable_atmospherics/canister/air/create_gas()
- if(starter_temp)
- air_contents.set_temperature(starter_temp)
- air_contents.set_moles(/datum/gas/oxygen, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
- air_contents.set_moles(/datum/gas/nitrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
+ if(air_contents.return_volume() == 0)
+ CRASH("Air content volume is zero, this shouldn't be the case volume is: [volume]!")
+ if(air_contents.return_temperature() == 0)
+ CRASH("Air content temperature is zero, this shouldn't be the case!")
+ air_contents.set_temperature(starter_temp)
+ air_contents.set_moles(GAS_O2, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
+ air_contents.set_moles(GAS_N2, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
/obj/machinery/portable_atmospherics/canister/update_icon_state()
if(stat & BROKEN)
@@ -374,7 +382,6 @@
var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
T.assume_air(expelled_gas)
- air_update_turf()
obj_break()
density = FALSE
@@ -402,21 +409,16 @@
if(timing && valve_timer < world.time)
valve_open = !valve_open
timing = FALSE
+
+ // Handle gas transfer.
if(valve_open)
var/turf/T = get_turf(src)
- pump.airs[1] = air_contents
- pump.airs[2] = holding ? holding.air_contents : T.return_air()
- pump.target_pressure = release_pressure
-
- pump.process_atmos() // Pump gas.
- if(!holding)
- air_update_turf() // Update the environment if needed.
- else
- pump.airs[1] = null
- pump.airs[2] = null
+ var/datum/gas_mixture/target_air = holding ? holding.air_contents : T.return_air()
+ air_contents.release_gas_to(target_air, release_pressure)
update_appearance(UPDATE_ICON)
+
/obj/machinery/portable_atmospherics/canister/ui_state(mob/user)
return GLOB.physical_state
@@ -514,11 +516,10 @@
if(!holding)
var/list/danger = list()
for(var/id in air_contents.get_gases())
- if(!GLOB.meta_gas_info[id][META_GAS_DANGER])
+ if(!(GLOB.gas_data.flags[id] & GAS_FLAG_DANGEROUS))
continue
- if(air_contents.get_moles(id) > (GLOB.meta_gas_info[id][META_GAS_MOLES_VISIBLE] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
- danger[GLOB.meta_gas_info[id][META_GAS_NAME]] = air_contents.get_moles(id) //ex. "plasma" = 20
-
+ if(air_contents.get_moles(id) > (GLOB.gas_data.visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
+ danger[GLOB.gas_data.names[id]] = air_contents.get_moles(id) //ex. "plasma" = 20
if(danger.len)
message_admins("[ADMIN_LOOKUPFLW(usr)] opened a canister that contains the following at [ADMIN_VERBOSEJMP(src)]:")
log_admin("[key_name(usr)] opened a canister that contains the following at [AREACOORD(src)]:")
@@ -576,10 +577,10 @@
desc = "This should never be spawned in game."
icon_state = "danger"
/obj/machinery/portable_atmospherics/canister/fusion_test/create_gas()
- air_contents.set_moles(/datum/gas/tritium, 10)
- air_contents.set_moles(/datum/gas/plasma, 500)
- air_contents.set_moles(/datum/gas/hydrogen, 500)
- air_contents.set_moles(/datum/gas/nitrous_oxide, 100)
+ air_contents.set_moles(GAS_TRITIUM, 10)
+ air_contents.set_moles(GAS_PLASMA, 500)
+ air_contents.set_moles(GAS_H2, 500)
+ air_contents.set_moles(GAS_NITROUS, 100)
air_contents.set_temperature(10000)
/// Canister 1 Kelvin below the fusion point. Contains far too much plasma. Only good for adding more fuel to ongoing fusion reactions.
@@ -588,10 +589,10 @@
desc = "This should never be spawned in game."
icon_state = "danger"
/obj/machinery/portable_atmospherics/canister/fusion_test_2/create_gas()
- air_contents.set_moles(/datum/gas/tritium, 10)
- air_contents.set_moles(/datum/gas/plasma, 15000)
- air_contents.set_moles(/datum/gas/carbon_dioxide, 1500)
- air_contents.set_moles(/datum/gas/nitrous_oxide, 100)
+ air_contents.set_moles(GAS_TRITIUM, 10)
+ air_contents.set_moles(GAS_PLASMA, 15000)
+ air_contents.set_moles(GAS_CO2, 1500)
+ air_contents.set_moles(GAS_NITROUS, 100)
air_contents.set_temperature(9999)
/// Canister at the perfect conditions to start and continue fusion for a long time.
@@ -600,9 +601,9 @@
desc = "This should never be spawned in game."
icon_state = "danger"
/obj/machinery/portable_atmospherics/canister/fusion_test_3/create_gas()
- air_contents.set_moles(/datum/gas/tritium, 1000)
- air_contents.set_moles(/datum/gas/plasma, 4500)
- air_contents.set_moles(/datum/gas/carbon_dioxide, 1500)
+ air_contents.set_moles(GAS_TRITIUM, 1000)
+ air_contents.set_moles(GAS_PLASMA, 4500)
+ air_contents.set_moles(GAS_CO2, 1500)
air_contents.set_temperature(1000000)
/** Canister for testing dilithium based cold fusion. Use fusion_test_3 if you don't know what you are doing.
@@ -612,10 +613,10 @@
desc = "This should never be spawned in game. Contains dilithium for cold fusion."
icon_state = "danger"
/obj/machinery/portable_atmospherics/canister/fusion_test_4/create_gas()
- air_contents.set_moles(/datum/gas/tritium, 1000)
- air_contents.set_moles(/datum/gas/plasma, 4500)
- air_contents.set_moles(/datum/gas/carbon_dioxide, 1500)
- air_contents.set_moles(/datum/gas/dilithium, 2000)
+ air_contents.set_moles(GAS_TRITIUM, 1000)
+ air_contents.set_moles(GAS_PLASMA, 4500)
+ air_contents.set_moles(GAS_CO2, 1500)
+ air_contents.set_moles(GAS_DILITHIUM, 2000)
air_contents.set_temperature(10000)
/// A canister that is 1 Kelvin away from doing the stimball reaction.
@@ -624,7 +625,7 @@
desc = "This should never be spawned in game except for testing purposes."
icon_state = "danger"
/obj/machinery/portable_atmospherics/canister/stimball_test/create_gas()
- air_contents.set_moles(/datum/gas/nitrium, 1000)
- air_contents.set_moles(/datum/gas/plasma, 1000)
- air_contents.set_moles(/datum/gas/pluoxium, 1000)
+ air_contents.set_moles(GAS_NITRIUM, 1000)
+ air_contents.set_moles(GAS_PLASMA, 1000)
+ air_contents.set_moles(GAS_PLUOXIUM, 1000)
air_contents.set_temperature(FIRE_MINIMUM_TEMPERATURE_TO_EXIST-1)
diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
index 53764eb0bc1a..156ade34ddab 100644
--- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
+++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
@@ -14,20 +14,17 @@
var/maximum_pressure = 90 * ONE_ATMOSPHERE
-/obj/machinery/portable_atmospherics/New()
- ..()
- SSair.atmos_machinery += src
+/obj/machinery/portable_atmospherics/Initialize(mapload)
+ . = ..()
+ SSair_machinery.start_processing_machine(src)
air_contents = new(volume)
air_contents.set_temperature(T20C)
- return 1
-
/obj/machinery/portable_atmospherics/Destroy()
+ SSair_machinery.stop_processing_machine(src)
disconnect()
QDEL_NULL(air_contents)
- SSair.atmos_machinery -= src
-
return ..()
/obj/machinery/portable_atmospherics/ex_act(severity, target)
@@ -38,12 +35,11 @@
//This explosion will destroy the can, release its air.
var/turf/T = get_turf(src)
T.assume_air(air_contents)
- T.air_update_turf()
return ..()
/obj/machinery/portable_atmospherics/process_atmos()
- if(!connected_port) // Pipe network handles reactions if connected.
+ if(!connected_port && air_contents != null && src != null) // Pipe network handles reactions if connected.
air_contents.react(src)
/obj/machinery/portable_atmospherics/return_air()
@@ -64,8 +60,7 @@
//Perform the connection
connected_port = new_port
connected_port.connected_device = src
- var/datum/pipeline/connected_port_parent = connected_port.parents[1]
- connected_port_parent.reconcile_air()
+ connected_port.parents[1].update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED
anchored = TRUE //Prevent movement
pixel_x = new_port.pixel_x
diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm
index b2224cf9cad8..e3a22c002df9 100644
--- a/code/modules/atmospherics/machinery/portable/pump.dm
+++ b/code/modules/atmospherics/machinery/portable/pump.dm
@@ -25,7 +25,6 @@
/obj/machinery/portable_atmospherics/pump/Destroy()
var/turf/T = get_turf(src)
T.assume_air(air_contents)
- air_update_turf()
QDEL_NULL(pump)
return ..()
@@ -57,17 +56,15 @@
pump.airs[2] = holding ? holding.air_contents : air_contents
pump.process_atmos() // Pump gas.
- if(!holding)
- air_update_turf() // Update the environment if needed.
/obj/machinery/portable_atmospherics/pump/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if(is_operational())
- if(prob(50 / severity))
+ if(prob(5 * severity))
on = !on
- if(prob(100 / severity))
+ if(prob(10 * severity))
direction = PUMP_OUT
pump.target_pressure = rand(0, 100 * ONE_ATMOSPHERE)
update_appearance(UPDATE_ICON)
@@ -115,8 +112,8 @@
if("power")
on = !on
if(on && !holding)
- var/plasma = air_contents.get_moles(/datum/gas/plasma)
- var/n2o = air_contents.get_moles(/datum/gas/nitrous_oxide)
+ var/plasma = air_contents.get_moles(GAS_PLASMA)
+ var/n2o = air_contents.get_moles(GAS_NITROUS)
if(n2o || plasma)
message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [ADMIN_VERBOSEJMP(src)]")
log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [AREACOORD(src)]")
diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm
index f0d132d6fe71..7abd790fe477 100644
--- a/code/modules/atmospherics/machinery/portable/scrubber.dm
+++ b/code/modules/atmospherics/machinery/portable/scrubber.dm
@@ -9,31 +9,25 @@
volume = 1000
var/list/scrubbing = list(
- /datum/gas/plasma,
- /datum/gas/carbon_dioxide,
- /datum/gas/nitrous_oxide,
- /datum/gas/miasma,
- /datum/gas/bz,
- /datum/gas/nitrium,
- /datum/gas/tritium,
- /datum/gas/hypernoblium,
- /datum/gas/dilithium,
- /datum/gas/freon,
- /datum/gas/hydrogen,
- /datum/gas/water_vapor,
- /datum/gas/healium,
- /datum/gas/pluoxium,
- /datum/gas/pluonium,
- /datum/gas/halon,
- /datum/gas/zauker,
- /datum/gas/antinoblium,
- /datum/gas/hexane,
+ GAS_PLASMA,
+ GAS_CO2,
+ GAS_NITROUS,
+ GAS_BZ,
+ GAS_NITRIUM,
+ GAS_TRITIUM,
+ GAS_HYPERNOB,
+ GAS_FREON,
+ GAS_H2O,
+ GAS_HEALIUM,
+ GAS_PLUONIUM,
+ GAS_HALON,
+ GAS_ZAUKER,
+ GAS_HEXANE,
)
/obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src)
T.assume_air(air_contents)
- air_update_turf()
return ..()
/obj/machinery/portable_atmospherics/scrubber/update_icon_state()
@@ -63,32 +57,27 @@
if(air_contents.return_pressure() >= overpressure_m * ONE_ATMOSPHERE)
return
- var/transfer_moles = min(1, volume_rate / mixture.return_volume()) * mixture.total_moles()
-
- var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
- if(!filtering)
- return
-
- filtering.scrub_into(air_contents, scrubbing)
-
- mixture.merge(filtering) // Returned the cleaned gas.
- if(!holding)
- air_update_turf()
+ mixture.scrub_into(air_contents, volume_rate / mixture.return_volume(), scrubbing)
/obj/machinery/portable_atmospherics/scrubber/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if(is_operational())
- if(prob(50 / severity))
+ if(prob(5 * severity))
on = !on
update_appearance(UPDATE_ICON)
+
+/obj/machinery/portable_atmospherics/scrubber/ui_state(mob/user)
+ return GLOB.physical_state
+
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
- ui = new(user, src, "PortableScrubber", name)
+ ui = new(user, src, "PortableScrubber")
ui.open()
+ ui.set_autoupdate(TRUE) // Air pressure, tank pressure
/obj/machinery/portable_atmospherics/scrubber/ui_data()
var/data = list()
@@ -98,9 +87,8 @@
data["id_tag"] = -1 //must be defined in order to reuse code between portable and vent scrubbers
data["filter_types"] = list()
- for(var/path in GLOB.meta_gas_info)
- var/list/gas = GLOB.meta_gas_info[path]
- data["filter_types"] += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in scrubbing)))
+ for(var/id in GLOB.gas_data.ids)
+ data["filter_types"] += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.labels[id], "enabled" = (id in scrubbing)))
if(holding)
data["holding"] = list()
@@ -118,7 +106,7 @@
on = FALSE
update_appearance(UPDATE_ICON)
else if(on && holding)
- investigate_log("[key_name(user)] started a transfer into [holding]. ", INVESTIGATE_ATMOS)
+ investigate_log("[key_name(user)] started a transfer into [holding].", INVESTIGATE_ATMOS)
/obj/machinery/portable_atmospherics/scrubber/ui_act(action, params)
if(..())
@@ -132,9 +120,10 @@
replace_tank(usr, FALSE)
. = TRUE
if("toggle_filter")
- scrubbing ^= gas_id2path(params["val"])
+ scrubbing ^= params["val"]
. = TRUE
- update_appearance(UPDATE_ICON)
+ if(.)
+ update_appearance(UPDATE_ICON)
/obj/machinery/portable_atmospherics/scrubber/huge
name = "huge air scrubber"
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 94b0f590c0d0..5627157c0fb5 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -403,7 +403,7 @@
/obj/effect/mob_spawn/human/bartender/alive/space
name = "space bartender sleeper"
- flavour_text = "You got this place from your old man, a bar in the middle of nowhere. Or at least, until NanoTrasen decided to move in. Time to mix drinks and change lives."
+ flavour_text = "You got this place from your old man, a bar in the middle of nowhere. Or at least, until Nanotrasen decided to move in. Time to mix drinks and change lives."
important_info = "Do not leave your post under any circumstances!"
outfit = /datum/outfit/spacebartender/space
diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm
index 0f09fe7b60b2..9a58051c044c 100644
--- a/code/modules/awaymissions/mission_code/snowdin.dm
+++ b/code/modules/awaymissions/mission_code/snowdin.dm
@@ -151,8 +151,8 @@
/turf/open/floor/plasteel/dark/snowdin
initial_gas_mix = FROZEN_ATMOS
- planetary_atmos = 1
- temperature = 180
+ planetary_atmos = TRUE
+ initial_temperature = 180
/turf/open/lava/plasma
name = "liquid plasma"
diff --git a/code/modules/cargo/bounties/engineering.dm b/code/modules/cargo/bounties/engineering.dm
index a2dad0de195f..921a1c71d056 100644
--- a/code/modules/cargo/bounties/engineering.dm
+++ b/code/modules/cargo/bounties/engineering.dm
@@ -13,61 +13,61 @@
name = "Full Tank of Pluoxium"
description = "CentCom RnD is researching extra compact internals. Ship us a tank full of Pluoxium and you'll be compensated. (20 Moles)"
reward = 2500
- gas_type = /datum/gas/pluoxium
+ gas_type = GAS_PLUOXIUM
/datum/bounty/item/atmos/simple/nitrium_tank
name = "Full Tank of Nitrium"
description = "The non-human staff of Station 88 has been volunteered to test performance enhancing drugs. Ship them a tank full of Nitrium so they can get started. (20 Moles)"
reward = 12000
- gas_type = /datum/gas/nitrium
+ gas_type = GAS_NITRIUM
/datum/bounty/item/atmos/simple/tritium_tank
name = "Full Tank of Tritium"
description = "Station 49 is looking to kickstart their research program. Ship them a tank full of Tritium. (20 Moles)"
reward = 3500
- gas_type = /datum/gas/tritium
+ gas_type = GAS_TRITIUM
/datum/bounty/item/atmos/simple/freon_tank
name = "Full Tank of Freon"
description = "The Supermatter of station 33 has started the delamination process. Deliver a tank of Freon gas to help them stop it! (20 Moles)"
reward = 4500
- gas_type = /datum/gas/freon
+ gas_type = GAS_FREON
/datum/bounty/item/atmos/simple/healium_tank
name = "Full Tank of Healium"
description = "Station 42's medical staff are working on an experimental cryogenics setup. They need a tank of Healium. (20 Moles)"
reward = 8000
- gas_type = /datum/gas/healium
+ gas_type = GAS_HEALIUM
/datum/bounty/item/atmos/complex/zauker_tank
name = "Full Tank of Zauker"
description = "The main planet of \[REDACTED] has been chosen as testing grounds for the new weapon that uses Zauker gas. Ship us a tank full of it. (20 Moles)"
reward = 25000
- gas_type = /datum/gas/zauker
+ gas_type = GAS_ZAUKER
/datum/bounty/item/atmos/complex/hypernob_tank
name = "Full Tank of Hypernoblium"
description = "Station 26's atmospheric division has had a mishap with an experimental fusion mix. Some Hyper-Noblium would be appreciated. (20 Moles)"
reward = 15000
- gas_type = /datum/gas/hypernoblium
+ gas_type = GAS_HYPERNOB
/datum/bounty/item/h2metal/metallic_hydrogen_armor
- name = "Metallic Hydrogen Armors"
- description = "Nanotrasen is requiring new armor to be made. Ship them some metallic hydrogen armors."
+ name = "Metallic Hydrogen Armor"
+ description = "Nanotrasen is requiring new armor to be made. Ship them 1 metallic hydrogen armor."
reward = 8000
required_count = 1
wanted_types = list(/obj/item/clothing/suit/armor/elder_atmosian)
/datum/bounty/item/h2metal/metallic_hydrogen_helmet
- name = "Metallic Hydrogen Armors"
- description = "Nanotrasen is requiring new helmet to be made. Ship them some metallic hydrogen helmets."
+ name = "Metallic Hydrogen Helmet"
+ description = "Nanotrasen is requiring new helmet to be made. Ship them 1 metallic hydrogen helmet."
reward = 7000
required_count = 1
wanted_types = list(/obj/item/clothing/head/helmet/elder_atmosian)
/datum/bounty/item/h2metal/metallic_hydrogen_axe
name = "Metallic Hydrogen Axes"
- description = "Nanotrasen is requiring new axes to be made. Ship them some metallic hydrogen helmets."
+ description = "Nanotrasen is requiring new axes to be made. Ship them 3 metallic hydrogen axes."
reward = 7500
required_count = 3
wanted_types = list(/obj/item/fireaxe/metal_h2_axe)
diff --git a/code/modules/cargo/export_scanner.dm b/code/modules/cargo/export_scanner.dm
index f4304126d034..95df716acc68 100644
--- a/code/modules/cargo/export_scanner.dm
+++ b/code/modules/cargo/export_scanner.dm
@@ -8,7 +8,6 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
item_flags = NOBLUDGEON
w_class = WEIGHT_CLASS_SMALL
- siemens_coefficient = 1
var/obj/machinery/computer/cargo/cargo_console = null
/obj/item/export_scanner/examine(user)
diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm
index 3ec66739dcfe..ca3636f094a0 100644
--- a/code/modules/cargo/expressconsole.dm
+++ b/code/modules/cargo/expressconsole.dm
@@ -9,7 +9,7 @@
/obj/machinery/computer/cargo/express
name = "express supply console"
desc = "This console allows the user to purchase a package \
- with 1/40th of the delivery time: made possible by NanoTrasen's new \"1500mm Orbital Railgun\".\
+ with 1/40th of the delivery time: made possible by Nanotrasen's new \"1500mm Orbital Railgun\".\
All sales are near instantaneous - please choose carefully"
icon_screen = "supply_express"
circuit = /obj/item/circuitboard/computer/cargo/express
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 14bdcf196981..e7b753fc64c1 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -276,12 +276,15 @@
/datum/supply_pack/security/armor
name = "Armor Crate"
- desc = "Three vests of well-rounded, decently-protective armor. Requires Security access to open."
- cost = 1000
+ desc = "Three sets of well-rounded, decently-protective armor and helmet. Requires Security access to open."
+ cost = 2000
access_view = ACCESS_SECURITY
- contains = list(/obj/item/clothing/suit/armor/vest,
- /obj/item/clothing/suit/armor/vest,
- /obj/item/clothing/suit/armor/vest)
+ contains = list(/obj/item/clothing/suit/armor/vest/alt,
+ /obj/item/clothing/suit/armor/vest/alt,
+ /obj/item/clothing/suit/armor/vest/alt,
+ /obj/item/clothing/head/helmet/sec,
+ /obj/item/clothing/head/helmet/sec,
+ /obj/item/clothing/head/helmet/sec)
crate_name = "armor crate"
/datum/supply_pack/security/disabler
@@ -315,15 +318,6 @@
/obj/item/clothing/head/fedora/det_hat)
crate_name = "forensics crate"
-/datum/supply_pack/security/helmets
- name = "Helmets Crate"
- desc = "Contains three standard-issue brain buckets. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/clothing/head/helmet/sec,
- /obj/item/clothing/head/helmet/sec,
- /obj/item/clothing/head/helmet/sec)
- crate_name = "helmet crate"
-
/datum/supply_pack/security/laser
name = "Lasers Crate"
desc = "Contains three lethal, high-energy laser guns. Requires Security access to open."
@@ -522,21 +516,15 @@
/datum/supply_pack/security/armory/bulletarmor
name = "Bulletproof Armor Crate"
- desc = "Contains three sets of bulletproof armor. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
- cost = 1500
+ desc = "Contains three sets of bulletproof armor and helmet. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
+ cost = 3000
contains = list(/obj/item/clothing/suit/armor/bulletproof,
/obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/suit/armor/bulletproof)
- crate_name = "bulletproof armor crate"
-
-/datum/supply_pack/security/armory/bullethelmets
- name = "Bulletproof Helmet Crate"
- desc = "Contains three bulletproof helmets, perfect for protecting the void inside your skull. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/head/helmet/alt,
/obj/item/clothing/head/helmet/alt,
/obj/item/clothing/head/helmet/alt)
- crate_name = "bulletproof helmet crate"
+ crate_name = "bulletproof armor crate"
/datum/supply_pack/security/armory/chemimp
name = "Chemical Implants Crate"
@@ -579,21 +567,15 @@
/datum/supply_pack/security/armory/riotarmor
name = "Riot Armor Crate"
- desc = "Contains three sets of heavy body armor. Advanced padding protects against close-ranged weaponry, making melee attacks feel only half as potent to the user. Requires Armory access to open."
- cost = 1500
+ desc = "Contains three sets of heavy body armor and helmet. Advanced padding protects against close-ranged weaponry, making melee attacks feel only half as potent to the user. Requires Armory access to open."
+ cost = 3000
contains = list(/obj/item/clothing/suit/armor/riot,
/obj/item/clothing/suit/armor/riot,
- /obj/item/clothing/suit/armor/riot)
- crate_name = "riot armor crate"
-
-/datum/supply_pack/security/armory/riothelmets
- name = "Riot Helmets Crate"
- desc = "Contains three riot helmets. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/suit/armor/riot,
+ /obj/item/clothing/head/helmet/riot,
/obj/item/clothing/head/helmet/riot,
/obj/item/clothing/head/helmet/riot)
- crate_name = "riot helmets crate"
+ crate_name = "riot armor crate"
/datum/supply_pack/security/armory/riotshields
name = "Riot Shields Crate"
@@ -1002,17 +984,6 @@
crate_name = "power cell crate"
crate_type = /obj/structure/closet/crate/engineering/electrical
-/datum/supply_pack/engineering/portable_pumps
- name = "Portable Pumps"
- desc = "A set of spare portable pumps. Perfect for larger atmospheric projects or restocking after a toxins problem goes wrong."
- cost = 1500
- contains = list(
- /obj/machinery/portable_atmospherics/pump,
- /obj/machinery/portable_atmospherics/pump
- )
- crate_name = "portable pump crate"
- crate_type = /obj/structure/closet/crate/large
-
/datum/supply_pack/engineering/portable_scrubbers
name = "Portable Scrubbers"
desc = "A set of spare portable scrubbers. Perfect for when plasma 'accidentally' gets into the air supply."
diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm
index ba7fcdbcebd4..c59259bc307b 100644
--- a/code/modules/client/client_colour.dm
+++ b/code/modules/client/client_colour.dm
@@ -15,9 +15,6 @@
var/colour = "" //Any client.color-valid value
var/priority = 1 //Since only one client.color can be rendered on screen, we take the one with the highest priority value:
//eg: "Bloody screen" > "goggles colour" as the former is much more important
-/mob
- var/list/client_colours = list()
-
/*
diff --git a/code/modules/client/preferences/chapel_choice.dm b/code/modules/client/preferences/chapel_choice.dm
new file mode 100644
index 000000000000..932967a4f215
--- /dev/null
+++ b/code/modules/client/preferences/chapel_choice.dm
@@ -0,0 +1,23 @@
+/// Which chapel to spawn on boxstation
+/datum/preference/choiced/chapel_choice
+ category = PREFERENCE_CATEGORY_NON_CONTEXTUAL
+ savefile_key = "chapel_choice"
+ savefile_identifier = PREFERENCE_CHARACTER
+ can_randomize = FALSE
+
+/datum/preference/choiced/chapel_choice/create_default_value()
+ return "Random"
+
+/datum/preference/choiced/chapel_choice/init_possible_values()
+ return GLOB.potential_box_chapels + "Random"
+
+/datum/preference/choiced/chapel_choice/is_accessible(datum/preferences/preferences)
+ if (!..(preferences))
+ return FALSE
+
+ // Job needs to be medium or high for the preference to show up
+ return preferences.job_preferences["Chaplain"] >= JP_MEDIUM
+
+/datum/preference/choiced/chapel_choice/apply_to_human(mob/living/carbon/human/target, value)
+ return
+
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index 9ce10ac5e6e3..43562cd6d269 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -598,7 +598,7 @@
icon_state = "black"
desc = "A pair of black shoes."
resistance_flags = NONE
- armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 50, ACID = 50)
+ armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 50, ACID = 50, ELECTRIC = 100)
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
var/datum/action/item_action/chameleon/change/chameleon_action
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index c2dc8a24625e..795b1f3d5cee 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -284,29 +284,8 @@
/obj/item/clothing/Topic(href, href_list)
. = ..()
-
if(href_list["list_armor"])
- var/list/readout = list("PROTECTION CLASSES ")
- if(armor.bio || armor.bomb || armor.bullet || armor.energy || armor.laser || armor.melee)
- readout += "\nARMOR (I-X) "
- if(armor.bio)
- readout += "\nTOXIN [armor_to_protection_class(armor.bio)]"
- if(armor.bomb)
- readout += "\nEXPLOSIVE [armor_to_protection_class(armor.bomb)]"
- if(armor.bullet)
- readout += "\nBULLET [armor_to_protection_class(armor.bullet)]"
- if(armor.energy)
- readout += "\nENERGY [armor_to_protection_class(armor.energy)]"
- if(armor.laser)
- readout += "\nLASER [armor_to_protection_class(armor.laser)]"
- if(armor.melee)
- readout += "\nMELEE [armor_to_protection_class(armor.melee)]"
- if(armor.fire || armor.acid)
- readout += "\nDURABILITY (I-X) "
- if(armor.fire)
- readout += "\nFIRE [armor_to_protection_class(armor.fire)]"
- if(armor.acid)
- readout += "\nACID [armor_to_protection_class(armor.acid)]"
+ var/additional_info = ""
if(flags_cover & HEADCOVERSMOUTH || flags_cover & HEADCOVERSEYES)
var/list/things_blocked = list()
if(flags_cover & HEADCOVERSMOUTH)
@@ -314,24 +293,9 @@
if(flags_cover & HEADCOVERSEYES)
things_blocked += "pepperspray"
if(length(things_blocked))
- readout += "\nCOVERAGE "
- readout += "\nIt will block [english_list(things_blocked)]."
-
- readout += " "
-
- to_chat(usr, "[readout.Join()]")
-
-/**
- * Rounds armor_value down to the nearest 10, divides it by 10 and then converts it to Roman numerals.
- *
- * Arguments:
- * * armor_value - Number we're converting
- */
-/obj/item/clothing/proc/armor_to_protection_class(armor_value)
- if (armor_value < 0)
- . = "-"
- . += "\Roman[round(abs(armor_value), 10) / 10]"
- return .
+ additional_info += "\nCOVERAGE "
+ additional_info += "\nIt will block [english_list(things_blocked)]."
+ to_chat(usr, "[armor.show_protection_classes(additional_info)]")
/obj/item/clothing/obj_break(damage_flag)
damaged_clothes = CLOTHING_DAMAGED
diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm
index 8091745f8cb5..0535f58f0576 100644
--- a/code/modules/clothing/gloves/_gloves.dm
+++ b/code/modules/clothing/gloves/_gloves.dm
@@ -3,13 +3,13 @@
gender = PLURAL //Carn: for grammarically correct text-parsing
w_class = WEIGHT_CLASS_SMALL
icon = 'icons/obj/clothing/gloves.dmi'
- siemens_coefficient = 0.5
body_parts_covered = HANDS
slot_flags = ITEM_SLOT_GLOVES
attack_verb = list("challenged")
var/transfer_prints = FALSE
strip_delay = 20
equip_delay_other = 40
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 50)
/obj/item/clothing/gloves/wash(clean_types)
. = ..()
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index ee13940d5297..fdc36d7ac040 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -6,8 +6,7 @@
name = "insulated gloves"
icon_state = "yellow"
item_state = "ygloves"
- siemens_coefficient = 0
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 100)
resistance_flags = NONE
/obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap
@@ -15,8 +14,7 @@
name = "budget insulated gloves"
icon_state = "yellow"
item_state = "ygloves"
- siemens_coefficient = 0
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 100)
resistance_flags = NONE
var/damaged = FALSE
@@ -84,8 +82,7 @@
/obj/item/clothing/gloves/color/red/insulated
name = "insulated gloves"
desc = "These gloves will protect the wearer from electric shock."
- siemens_coefficient = 0
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 100)
resistance_flags = NONE
/obj/item/clothing/gloves/color/rainbow
@@ -135,13 +132,12 @@
name = "captain's gloves"
icon_state = "captain"
item_state = "egloves"
- siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
strip_delay = 60
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 70, ACID = 50)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 70, ACID = 50, ELECTRIC = 100)
/obj/item/clothing/gloves/color/captain/centcom
desc = "Regal green gloves, with a nice gold trim, a diamond anti-shock coating, and an integrated thermal barrier. Swanky."
@@ -160,10 +156,9 @@
desc = "Cheap sterile gloves made from latex. Transfers minor paramedic knowledge to the user via budget nanochips."
icon_state = "latex"
item_state = "lgloves"
- siemens_coefficient = 0.3
transfer_prints = TRUE
resistance_flags = NONE
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 70)
clothing_traits = list(TRAIT_QUICK_CARRY)
var/surgeryspeed = 0.9 //how much these gloves speed up surgery
diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm
index b29fb22c2084..e76ea5d08620 100644
--- a/code/modules/clothing/gloves/miscellaneous.dm
+++ b/code/modules/clothing/gloves/miscellaneous.dm
@@ -5,13 +5,13 @@
icon_state = "fingerless"
item_state = "fingerless"
transfer_prints = TRUE
- siemens_coefficient = 1 //What no if you touch things with your bare fingies you're gonna get shocked
strip_delay = 40
equip_delay_other = 20
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
custom_price = 10
undyeable = TRUE
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 0)
var/tacticalspeed = 0.9
var/worn
@@ -63,14 +63,13 @@
desc = "These tactical gloves are fireproof and shock resistant."
icon_state = "black"
item_state = "blackgloves"
- siemens_coefficient = 0
strip_delay = 80
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
resistance_flags = NONE
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 80, ACID = 50)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 80, ACID = 50, ELECTRIC = 100)
/obj/item/clothing/gloves/bracer
name = "bone bracers"
@@ -78,7 +77,6 @@
icon_state = "bracers"
item_state = "bracers"
transfer_prints = TRUE
- siemens_coefficient = 1 //They're not gloves?
strip_delay = 40
equip_delay_other = 20
body_parts_covered = ARMS
@@ -86,7 +84,7 @@
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
resistance_flags = NONE
- armor = list(MELEE = 15, BULLET = 25, LASER = 15, ENERGY = 15, BOMB = 20, BIO = 10, RAD = 0, FIRE = 0, ACID = 0)
+ armor = list(MELEE = 15, BULLET = 25, LASER = 15, ENERGY = 15, BOMB = 20, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 0)
/obj/item/clothing/gloves/rapid
name = "Gloves of the North Star"
@@ -264,8 +262,7 @@
heat_protection = HANDS
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF
- siemens_coefficient = 0.2
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 90, RAD = 0, FIRE = 100, ACID = 90)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 90, RAD = 0, FIRE = 100, ACID = 90, ELECTRIC = 80)
clothing_flags = THICKMATERIAL
clothing_traits = list(TRAIT_QUICKEST_CARRY, TRAIT_RESISTHEATHANDS)
@@ -273,4 +270,4 @@
name = "advanced insulated gloves"
desc = "These gloves provide excellent thermal and electrical insulation."
icon_state = "ce_insuls"
- siemens_coefficient = 0
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 90, RAD = 0, FIRE = 100, ACID = 90, ELECTRIC = 100)
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index a5c994bfb7fc..ca282661132b 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -4,7 +4,7 @@
icon_state = "hardhat0_yellow"
item_state = "hardhat0_yellow"
mob_overlay_icon = 'icons/mob/clothing/head/head.dmi'
- armor = list(MELEE = 15, BULLET = 5, LASER = 20, ENERGY = 10, BOMB = 20, BIO = 10, RAD = 20, FIRE = 100, ACID = 50, WOUND = 10)
+ armor = list(MELEE = 15, BULLET = 5, LASER = 20, ENERGY = 10, BOMB = 20, BIO = 10, RAD = 20, FIRE = 100, ACID = 50, WOUND = 10, ELECTRIC = 100) // now OSHA-compliant!
flags_inv = 0
actions_types = list(/datum/action/item_action/toggle_helmet_light)
resistance_flags = FIRE_PROOF
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index ce5288b44381..3af7218fff12 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -111,6 +111,8 @@
attack_verb = list("poked", "tipped")
embedding = list("embed_chance" = 0) //Zero percent chance to embed
var/extended = 0
+ var/mob/living/carbon/fedora_man
+ var/returning = FALSE
/obj/item/clothing/head/det_hat/evil/attack_self(mob/user)
extended = !extended
@@ -127,6 +129,7 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut", "tipped")
hitsound = 'sound/weapons/bladeslice.ogg'
hattable = FALSE //So you don't accidentally throw it onto somebody's head instead of decapitating them
+ item_flags = UNCATCHABLE //so it isn't just immediately caught
else
force = 0
throwforce = 0
@@ -136,18 +139,31 @@
attack_verb = list("poked", "tipped")
hitsound = 'sound/weapons/genhit.ogg'
hattable = TRUE
+ item_flags = NONE
/obj/item/clothing/head/det_hat/evil/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
- if(iscarbon(loc) || !iscarbon(thrownby))
- return ..()
- throw_at(thrownby, throw_range+3, 3, null)
- ..()
-
-/obj/item/clothing/head/det_hat/evil/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, quickstart = TRUE)
- if(iscarbon(thrower))
- var/mob/living/carbon/C = thrower
- C.throw_mode_on()
- ..()
+ if(fedora_man && hit_atom == fedora_man)
+ if(fedora_man.put_in_hands(src))
+ fedora_man.throw_mode_on()
+ return
+ else
+ return ..()
+ . = ..()
+ if(fedora_man && returning)
+ returning = FALSE //only try to return once
+ if(get_turf(src) == get_turf(fedora_man))//don't try to return if the tile it hit is literally under the thrower
+ return
+ addtimer(CALLBACK(src, PROC_REF(comeback)), 1, TIMER_UNIQUE)//delay the return by such a small amount
+
+/obj/item/clothing/head/det_hat/evil/proc/comeback()
+ throw_at(fedora_man, throw_range+3, throw_speed)
+
+/obj/item/clothing/head/det_hat/evil/throw_at(atom/target, range, speed, mob/thrower, spin=0, diagonals_first = 0, datum/callback/callback, force, quickstart = TRUE)
+ if(thrower && iscarbon(thrower))
+ fedora_man = thrower
+ fedora_man.changeNext_move(CLICK_CD_MELEE)//longer cooldown
+ returning = TRUE
+ . = ..()
//Mime
/obj/item/clothing/head/beret
@@ -165,7 +181,7 @@
/obj/item/clothing/head/beret/archaic
name = "archaic beret"
- desc = "An absolutely ancient beret, allegedly worn by the first mime to ever step foot on a NanoTrasen station."
+ desc = "An absolutely ancient beret, allegedly worn by the first mime to ever step foot on a Nanotrasen station."
icon_state = "archaicberet"
dog_fashion = null
@@ -322,7 +338,7 @@
/obj/item/clothing/head/beret/sec/centcom
name = "\improper CentCom beret"
- desc = "A special beret with the NanoTrasen logo emblazoned on it. For where no man has gone before."
+ desc = "A special beret with the Nanotrasen logo emblazoned on it. For where no man has gone before."
icon_state = "official"
//Curator
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index c26244226577..67b320c3b228 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -515,17 +515,15 @@
cloak_charge_rate = 20
cloak_dodge_loss = 40
var/cloak_emp_disable_duration = 10 SECONDS
- var/cloak_emp_loss = 25
+ var/cloak_emp_loss = 5
/obj/item/clothing/neck/cloak/ranger/syndie/emp_act(severity)
. = ..()
if(CHECK_BITFIELD(., EMP_PROTECT_SELF))
return
- if(severity == EMP_HEAVY)
- set_cloak(0)
+ if(severity > EMP_LIGHT)
TIMER_COOLDOWN_START(src, "cloak_emp_disable", cloak_emp_disable_duration)
- else
- set_cloak(cloak - cloak_emp_loss)
+ set_cloak(max(cloak - (cloak_emp_loss * severity), 0))
/obj/item/clothing/neck/cloak/ranger/syndie/process(delta_time)
if(TIMER_COOLDOWN_CHECK(src, "cloak_emp_disable"))
diff --git a/code/modules/clothing/neck/bodycamera.dm b/code/modules/clothing/neck/bodycamera.dm
index 3cd85f30beb1..21207b75cfd3 100644
--- a/code/modules/clothing/neck/bodycamera.dm
+++ b/code/modules/clothing/neck/bodycamera.dm
@@ -88,7 +88,7 @@
/obj/item/clothing/neck/bodycam/emp_act(severity)
. = ..()
- if(prob(150/severity))
+ if(prob(15 * severity))
Disconnect()
bodcam.c_tag = null
bodcam.network[1] = null //requires a reset
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 4deecec621c2..86b102144b6e 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -5,7 +5,7 @@
var/magboot_state = "magboots"
var/magpulse = 0
var/slowdown_active = 2
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 60, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 100)
actions_types = list(/datum/action/item_action/toggle)
strip_delay = 70
equip_delay_other = 70
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 3ffb8d5c5b73..95cd0b5ba2c1 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -12,7 +12,7 @@
item_state = "jackboots"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
- armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 60, RAD = 0, FIRE = 70, ACID = 50)
+ armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 60, RAD = 0, FIRE = 70, ACID = 50, ELECTRIC = 100)
strip_delay = 70
resistance_flags = NONE
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
@@ -25,7 +25,7 @@
name = "\improper SWAT boots"
desc = "High speed, no drag combat boots."
clothing_flags = NOSLIP
- armor = list(MELEE = 40, BULLET = 30, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 30, FIRE = 90, ACID = 50)
+ armor = list(MELEE = 40, BULLET = 30, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 30, FIRE = 90, ACID = 50, ELECTRIC = 100)
/obj/item/clothing/shoes/sandal
desc = "A pair of rather plain wooden sandals."
@@ -55,7 +55,7 @@
strip_delay = 50
equip_delay_other = 50
resistance_flags = NONE
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 40, ACID = 75)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 40, ACID = 75, ELECTRIC = 100)
can_be_bloody = FALSE
custom_price = 100
@@ -169,7 +169,7 @@
/obj/item/clothing/shoes/workboots
name = "work boots"
- desc = "Nanotrasen-issue Engineering lace-up work boots for the especially blue-collar."
+ desc = "Nanotrasen-issue Engineering lace-up work boots for the especially blue-collar. Electrically insulated to protect from hazardous work environments."
icon_state = "workboots"
item_state = "jackboots"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
@@ -177,7 +177,7 @@
strip_delay = 40
equip_delay_other = 40
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 40, RAD = 0, FIRE = 0, ACID = 0)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 40, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 100)
/obj/item/clothing/shoes/workboots/mining
name = "mining boots"
@@ -451,7 +451,7 @@
/obj/item/clothing/shoes/xeno_wraps //Standard for all digitigrade legs and feets
name = "footwraps"
- desc = "Standard issue NanoTrasen cloth footwraps for those with podiatric deficiencies. They're quite itchy and scratchy."
+ desc = "Standard issue Nanotrasen cloth footwraps for those with podiatric deficiencies. They're quite itchy and scratchy."
icon_state = "footwraps"
item_state = "footwraps"
xenoshoe = EITHER_STYLE // This can be worn by digitigrade or straight legs, or a hybridization thereof (one prosthetic one digitigrade). Xenoshoe variable will default to NO_DIGIT, excluding digitigrade feet.
@@ -469,7 +469,7 @@
/obj/item/clothing/shoes/xeno_wraps/command // Not applicable unless 11505 merges - Digitigrade-exclusive shoes for Command positions
name = "command footwraps"
- desc = "These Command-grade NanoTrasen fiber footwraps exude an air of refinement not often felt by those with alien podiatric structures."
+ desc = "These Command-grade Nanotrasen fiber footwraps exude an air of refinement not often felt by those with alien podiatric structures."
icon_state = "footwraps_c"
item_state = "footwraps_c"
xenoshoe = YES_DIGIT // This is digitigrade leg exclusive
@@ -509,15 +509,16 @@
/obj/item/clothing/shoes/xeno_wraps/engineering
name = "engineering footwraps"
- desc = "Standard issue NanoTrasen cloth footwraps, specially made for the frequent glass treader."
+ desc = "Standard issue Nanotrasen cloth footwraps, specially made for the frequent glass treader. Electrically insulated."
icon_state = "footwraps_e"
item_state = "footwraps_e"
xenoshoe = YES_DIGIT
mutantrace_variation = MUTANTRACE_VARIATION
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 15, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 100)
/obj/item/clothing/shoes/xeno_wraps/science
name = "science footwraps"
- desc = "Standard issue NanoTrasen cloth footwraps, to reduce fatigue when standing at a console all day."
+ desc = "Standard issue Nanotrasen cloth footwraps, to reduce fatigue when standing at a console all day."
icon_state = "footwraps_sc"
item_state = "footwraps_sc"
xenoshoe = YES_DIGIT
@@ -525,7 +526,7 @@
/obj/item/clothing/shoes/xeno_wraps/medical
name = "medical footwraps"
- desc = "Standard issue NanoTrasen cloth footwraps, for when you dont want other people's blood all over your feet."
+ desc = "Standard issue Nanotrasen cloth footwraps, for when you dont want other people's blood all over your feet."
icon_state = "footwraps_m"
item_state = "footwraps_m"
xenoshoe = YES_DIGIT
@@ -533,7 +534,7 @@
/obj/item/clothing/shoes/xeno_wraps/cargo
name = "cargo footwraps"
- desc = "Standard issue NanoTrasen cloth footwraps, with reinforcment to protect against falling crates."
+ desc = "Standard issue Nanotrasen cloth footwraps, with reinforcment to protect against falling crates."
icon_state = "footwraps_ca"
item_state = "footwraps_ca"
xenoshoe = YES_DIGIT
diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm
index 4e7e5b6b3e97..2cac53d24947 100644
--- a/code/modules/clothing/spacesuits/chronosuit.dm
+++ b/code/modules/clothing/spacesuits/chronosuit.dm
@@ -73,13 +73,11 @@
if(. & EMP_PROTECT_SELF)
return
var/mob/living/carbon/human/user = src.loc
- switch(severity)
- if(1)
- if(activated && user && ishuman(user) && (user.wear_suit == src))
- to_chat(user, span_danger("E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD"))
- to_chat(user, span_userdanger("An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!"))
- user.emote("scream")
- deactivate(1, 1)
+ if(severity > EMP_LIGHT && activated && user && ishuman(user) && (user.wear_suit == src))
+ to_chat(user, span_danger("E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD"))
+ to_chat(user, span_userdanger("An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!"))
+ user.emote("scream")
+ deactivate(1, 1)
/obj/item/clothing/suit/space/chronos/proc/finish_chronowalk(mob/living/carbon/human/user, turf/to_turf)
if(!user)
@@ -223,7 +221,7 @@
teleport_now.Remove(user)
if(user.wear_suit == src)
if(hard_landing)
- user.electrocute_act(35, src, safety = 1)
+ user.electrocute_act(35, src, zone = null)
user.Paralyze(200)
if(!silent)
to_chat(user, "\nroot@ChronosuitMK4# chronowalk4 --stop\n")
@@ -246,7 +244,7 @@
density = FALSE
anchored = TRUE
invisibility = INVISIBILITY_ABSTRACT
- opacity = 0
+ opacity = FALSE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/mob/holder
var/phase_time = 0
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 2975673406ea..e0ff6a6a2d76 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -144,7 +144,7 @@
/obj/item/clothing/head/helmet/space/hardsuit/emp_act(severity)
. = ..()
- display_visor_message("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!")
+ display_visor_message("Electromagnetic pulse detected! Severity: [severity]")
/obj/item/clothing/suit/space/hardsuit
@@ -153,9 +153,8 @@
icon_state = "hardsuit-engineering"
item_state = "eng_hardsuit"
max_integrity = 300
- armor = list(MELEE = 10, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 50, ACID = 75, WOUND = 10)
+ armor = list(MELEE = 10, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 50, ACID = 75, WOUND = 10, ELECTRIC = 100)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser)
- siemens_coefficient = 0
actions_types = list(/datum/action/item_action/toggle_helmet)
var/obj/item/clothing/head/helmet/space/hardsuit/helmet
@@ -228,7 +227,7 @@
icon_state = "hardsuit0-engineering"
item_state = "eng_helm"
hardsuit_type = "engineering"
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, WOUND = 10)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, WOUND = 10, ELECTRIC = 100)
resistance_flags = FIRE_PROOF
/obj/item/clothing/suit/space/hardsuit/engine
@@ -236,7 +235,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding."
icon_state = "hardsuit-engineering"
item_state = "eng_hardsuit"
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, WOUND = 10)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, WOUND = 10, ELECTRIC = 100)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine
resistance_flags = FIRE_PROOF
@@ -247,7 +246,7 @@
icon_state = "hardsuit0-atmospherics"
item_state = "atmo_helm"
hardsuit_type = "atmospherics"
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 25, FIRE = 100, ACID = 75, WOUND = 10)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 25, FIRE = 100, ACID = 75, WOUND = 10, ELECTRIC = 100)
heat_protection = HEAD //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -256,7 +255,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding."
icon_state = "hardsuit-atmospherics"
item_state = "atmo_hardsuit"
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 25, FIRE = 100, ACID = 75, WOUND = 10)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 25, FIRE = 100, ACID = 75, WOUND = 10, ELECTRIC = 100)
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos
@@ -268,7 +267,7 @@
icon_state = "hardsuit0-flight"
item_state = "flighthelmet"
hardsuit_type = "flight"
- armor = list(MELEE = 40, BULLET = 35, LASER = 25, ENERGY = 30, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 20)
+ armor = list(MELEE = 40, BULLET = 35, LASER = 25, ENERGY = 30, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 20, ELECTRIC = 100)
heat_protection = HEAD //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -279,7 +278,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding. This one is made with the toughest and rarest materials available to man."
icon_state = "flightsuit"
item_state = "flightsuit"
- armor = list(MELEE = 40, BULLET = 35, LASER = 25, ENERGY = 30, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 20)
+ armor = list(MELEE = 40, BULLET = 35, LASER = 25, ENERGY = 30, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 20, ELECTRIC = 100)
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/elder_atmosian
@@ -295,7 +294,7 @@
icon_state = "hardsuit0-white"
item_state = "ce_helm"
hardsuit_type = "white"
- armor = list(MELEE = 40, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 90, WOUND = 10)
+ armor = list(MELEE = 40, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 90, WOUND = 10, ELECTRIC = 100)
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -304,7 +303,7 @@
name = "advanced hardsuit"
desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish."
item_state = "ce_hardsuit"
- armor = list(MELEE = 40, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 90, WOUND = 10)
+ armor = list(MELEE = 40, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 90, WOUND = 10, ELECTRIC = 100)
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite
@@ -320,7 +319,7 @@
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF
heat_protection = HEAD
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 75, WOUND = 15)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 75, WOUND = 15, ELECTRIC = 100)
light_range = 7
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
@@ -335,7 +334,7 @@
item_state = "mining_hardsuit"
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 75, WOUND = 15)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 75, WOUND = 15, ELECTRIC = 100)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/mining
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
@@ -352,7 +351,7 @@
icon_state = "hardsuit1-syndi"
item_state = "syndie_helm"
hardsuit_type = "syndi"
- armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 90, WOUND = 25)
+ armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 90, WOUND = 25, ELECTRIC = 100)
on = TRUE
actions_types = list(/datum/action/item_action/toggle_helmet_mode)
visor_flags_inv = HIDEMASK|HIDEEYES|HIDEFACE|HIDEFACIALHAIR
@@ -432,7 +431,7 @@
item_state = "syndie_hardsuit"
hardsuit_type = "syndi"
w_class = WEIGHT_CLASS_NORMAL
- armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 90, WOUND = 25)
+ armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 90, WOUND = 25, ELECTRIC = 100)
allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/fireaxe/energy)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi
jetpack = /obj/item/tank/jetpack/suit
@@ -444,7 +443,7 @@
alt_desc = "An elite version of the syndicate helmet, with improved armour and fireproofing. It is in combat mode. Property of Gorlex Marauders."
icon_state = "hardsuit1-syndielite"
hardsuit_type = "syndielite"
- armor = list(MELEE = 60, BULLET = 60, LASER = 50, ENERGY = 35, BOMB = 90, BIO = 100, RAD = 70, FIRE = 100, ACID = 100, WOUND = 25)
+ armor = list(MELEE = 60, BULLET = 60, LASER = 50, ENERGY = 35, BOMB = 90, BIO = 100, RAD = 70, FIRE = 100, ACID = 100, WOUND = 25, ELECTRIC = 100)
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -456,7 +455,7 @@
icon_state = "hardsuit1-syndielite"
hardsuit_type = "syndielite"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite
- armor = list(MELEE = 60, BULLET = 60, LASER = 50, ENERGY = 25, BOMB = 90, BIO = 100, RAD = 70, FIRE = 100, ACID = 100, WOUND = 25)
+ armor = list(MELEE = 60, BULLET = 60, LASER = 50, ENERGY = 25, BOMB = 90, BIO = 100, RAD = 70, FIRE = 100, ACID = 100, WOUND = 25, ELECTRIC = 100)
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -488,7 +487,7 @@
desc = "Spaceworthy and it looks like a space carp's head, smells like one too."
icon_state = "carp_helm"
item_state = "syndicate"
- armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 75, FIRE = 60, ACID = 75) //As whimpy as a space carp
+ armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 75, FIRE = 60, ACID = 75, ELECTRIC = 100) //As whimpy as a space carp
light_system = NO_LIGHT_SUPPORT
light_range = 0 //luminosity when on
actions_types = list()
@@ -503,7 +502,7 @@
icon_state = "carp_suit"
item_state = "space_suit_syndicate"
slowdown = 0 //Space carp magic, never stop believing
- armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 75, FIRE = 60, ACID = 75) //As whimpy whimpy whoo
+ armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 75, FIRE = 60, ACID = 75, ELECTRIC = 100) //As whimpy whimpy whoo
allowed = list(/obj/item/tank/internals, /obj/item/pneumatic_cannon/speargun) //I'm giving you a hint here
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/carp
@@ -524,7 +523,7 @@
desc = "A scaley heat resistant helm sporting a fearsome carp dragon look and smell."
icon_state = "carpdragon_helm"
item_state = "carpdragon_helm"
- armor = list(MELEE = 50, BULLET = 30, LASER = 50, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 90, FIRE = 100, ACID = 100) //not so whimpy now
+ armor = list(MELEE = 50, BULLET = 30, LASER = 50, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 90, FIRE = 100, ACID = 100, ELECTRIC = 100) //not so whimpy now
resistance_flags = FIRE_PROOF | ACID_PROOF
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -533,7 +532,7 @@
desc = "A tough, space and heat resistant suit patched together with space dragon scales."
icon_state = "carpdragon"
item_state = "carpdragon"
- armor = list(MELEE = 50, BULLET = 30, LASER = 50, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 90, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 50, BULLET = 30, LASER = 50, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 90, FIRE = 100, ACID = 100, ELECTRIC = 100)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/carp/dragon
resistance_flags = FIRE_PROOF | ACID_PROOF
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -547,7 +546,7 @@
item_state = "wiz_helm"
hardsuit_type = "wiz"
resistance_flags = FIRE_PROOF | ACID_PROOF //No longer shall our kind be foiled by lone chemists with spray bottles!
- armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 25, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30)
+ armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 25, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30, ELECTRIC = 100)
heat_protection = HEAD //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -558,7 +557,7 @@
item_state = "wiz_hardsuit"
w_class = WEIGHT_CLASS_NORMAL
resistance_flags = FIRE_PROOF | ACID_PROOF
- armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 25, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30)
+ armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 25, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30, ELECTRIC = 100)
allowed = list(/obj/item/teleportation_scroll, /obj/item/tank/internals)
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -578,7 +577,7 @@
icon_state = "hardsuit0-medical"
item_state = "medical_helm"
hardsuit_type = "medical"
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 60, FIRE = 60, ACID = 75, WOUND = 10)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 60, FIRE = 60, ACID = 75, WOUND = 10, ELECTRIC = 100)
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SCAN_REAGENTS | HEADINTERNALS
/obj/item/clothing/suit/space/hardsuit/medical
@@ -587,7 +586,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Built with lightweight materials for easier movement."
item_state = "medical_hardsuit"
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/firstaid, /obj/item/healthanalyzer, /obj/item/stack/medical)
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 60, FIRE = 60, ACID = 75, WOUND = 10)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 60, FIRE = 60, ACID = 75, WOUND = 10, ELECTRIC = 100)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/medical
slowdown = 0.5
@@ -599,7 +598,7 @@
hardsuit_type = "rd"
resistance_flags = ACID_PROOF | FIRE_PROOF
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 100, BIO = 100, RAD = 60, FIRE = 60, ACID = 80, WOUND = 15)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 100, BIO = 100, RAD = 60, FIRE = 60, ACID = 80, WOUND = 15, ELECTRIC = 100)
var/explosion_detection_dist = 21
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SCAN_REAGENTS | HEADINTERNALS
actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner)
@@ -638,7 +637,7 @@
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT //Same as an emergency firesuit. Not ideal for extended exposure.
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/gun/energy/wormhole_projector,
/obj/item/hand_tele, /obj/item/aicard)
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 100, BIO = 100, RAD = 60, FIRE = 60, ACID = 80, WOUND = 15)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 100, BIO = 100, RAD = 60, FIRE = 60, ACID = 80, WOUND = 15, ELECTRIC = 100)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd
@@ -650,7 +649,7 @@
icon_state = "hardsuit0-sec"
item_state = "sec_helm"
hardsuit_type = "sec"
- armor = list(MELEE = 35, BULLET = 25, LASER = 30,ENERGY = 10, BOMB = 40, BIO = 100, RAD = 50, FIRE = 75, ACID = 75, WOUND = 20)
+ armor = list(MELEE = 35, BULLET = 25, LASER = 30,ENERGY = 10, BOMB = 40, BIO = 100, RAD = 50, FIRE = 75, ACID = 75, WOUND = 20, ELECTRIC = 100)
/obj/item/clothing/suit/space/hardsuit/security
@@ -658,7 +657,7 @@
name = "security hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
item_state = "sec_hardsuit"
- armor = list(MELEE = 35, BULLET = 25, LASER = 30, ENERGY = 10, BOMB = 40, BIO = 100, RAD = 50, FIRE = 75, ACID = 75, WOUND = 20)
+ armor = list(MELEE = 35, BULLET = 25, LASER = 30, ENERGY = 10, BOMB = 40, BIO = 100, RAD = 50, FIRE = 75, ACID = 75, WOUND = 20, ELECTRIC = 100)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security
/obj/item/clothing/suit/space/hardsuit/security/Initialize(mapload)
@@ -671,14 +670,14 @@
desc = "A special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor."
icon_state = "hardsuit0-hos"
hardsuit_type = "hos"
- armor = list(MELEE = 45, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 50, BIO = 100, RAD = 50, FIRE = 95, ACID = 95, WOUND = 25)
+ armor = list(MELEE = 45, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 50, BIO = 100, RAD = 50, FIRE = 95, ACID = 95, WOUND = 25, ELECTRIC = 100)
/obj/item/clothing/suit/space/hardsuit/security/hos
icon_state = "hardsuit-hos"
name = "head of security's hardsuit"
desc = "A special bulky suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
- armor = list(MELEE = 45, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 50, BIO = 100, RAD = 50, FIRE = 95, ACID = 95, WOUND = 25)
+ armor = list(MELEE = 45, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 50, BIO = 100, RAD = 50, FIRE = 95, ACID = 95, WOUND = 25, ELECTRIC = 100)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos
jetpack = /obj/item/tank/jetpack/suit
@@ -688,7 +687,7 @@
icon_state = "swat2helm"
item_state = "swat2helm"
desc = "A tactical SWAT helmet MK.II."
- armor = list(MELEE = 40, BULLET = 50, LASER = 50, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15)
+ armor = list(MELEE = 40, BULLET = 50, LASER = 50, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15, ELECTRIC = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR //we want to see the mask
heat_protection = HEAD
@@ -702,7 +701,7 @@
desc = "A MK.II SWAT suit with streamlined joints and armor made out of superior materials, insulated against intense heat. The most advanced tactical armor available."
icon_state = "swat2"
item_state = "swat2"
- armor = list(MELEE = 40, BULLET = 50, LASER = 50, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15)
+ armor = list(MELEE = 40, BULLET = 50, LASER = 50, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15, ELECTRIC = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT //this needed to be added a long fucking time ago
@@ -734,14 +733,14 @@
icon_state = "hardsuit0-clown"
item_state = "hardsuit0-clown"
hardsuit_type = "clown"
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 60, ACID = 30)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 60, ACID = 30, ELECTRIC = 100)
/obj/item/clothing/suit/space/hardsuit/clown
name = "cosmohonk hardsuit"
desc = "A special suit that protects against hazardous, low humor environments. Has radiation shielding. Only a true clown can wear it."
icon_state = "hardsuit-clown"
item_state = "clown_hardsuit"
- armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 60, ACID = 30)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 60, ACID = 30, ELECTRIC = 100)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/clown
/obj/item/clothing/suit/space/hardsuit/clown/mob_can_equip(mob/M, slot)
@@ -761,7 +760,7 @@
icon_state = "hardsuit0-ert_commander"
item_state = "hardsuit0-ert_commander"
hardsuit_type = "ert_commander"
- armor = list(MELEE = 65, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 80)
+ armor = list(MELEE = 65, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, ELECTRIC = 100)
strip_delay = 130
light_range = 7
resistance_flags = FIRE_PROOF
@@ -778,7 +777,7 @@
item_state = "ert_command"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
- armor = list(MELEE = 65, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 80)
+ armor = list(MELEE = 65, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, ELECTRIC = 100)
slowdown = 0
strip_delay = 130
resistance_flags = FIRE_PROOF
@@ -905,7 +904,7 @@
icon_state = "hardsuit0-ancient"
item_state = "anc_helm"
hardsuit_type = "ancient"
- armor = list(MELEE = 30, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 75)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, ELECTRIC = 100)
resistance_flags = FIRE_PROOF
/obj/item/clothing/suit/space/hardsuit/ancient
@@ -913,7 +912,7 @@
desc = "Prototype powered RIG hardsuit. Provides excellent protection from the elements of space while being comfortable to move around in, thanks to the powered locomotives. Remains very bulky however."
icon_state = "hardsuit-ancient"
item_state = "anc_hardsuit"
- armor = list(MELEE = 30, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 75)
+ armor = list(MELEE = 30, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, ELECTRIC = 100)
slowdown = 3
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient
resistance_flags = FIRE_PROOF
@@ -960,7 +959,7 @@
icon_state = "hardsuit-hos"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos
allowed = null
- armor = list(MELEE = 30, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 30, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, ELECTRIC = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
var/current_charges = 3
var/max_charges = 3 //How many charges total the shielding has
@@ -1027,7 +1026,7 @@
hardsuit_type = "ctf-white"
// Adding TRAIT_NODROP is done when the CTF spawner equips people
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf
- armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95)
+ armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95, ELECTRIC = 100)
slowdown = 0
max_charges = 5
@@ -1054,7 +1053,7 @@
icon_state = "hardsuit0-ctf_white"
item_state = null
hardsuit_type = "ert_medical"
- armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95)
+ armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95, ELECTRIC = 100)
/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red
@@ -1082,7 +1081,7 @@
icon_state = "hardsuit1-syndi"
item_state = "syndie_hardsuit"
hardsuit_type = "syndi"
- armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 25, BOMB = 80, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30)
+ armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 25, BOMB = 80, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30, ELECTRIC = 100)
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi
slowdown = 0
@@ -1094,7 +1093,7 @@
icon_state = "hardsuit1-syndi"
item_state = "syndie_helm"
hardsuit_type = "syndi"
- armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 25, BOMB = 80, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30)
+ armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 25, BOMB = 80, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30, ELECTRIC = 100)
///Deathsquad version
@@ -1103,7 +1102,7 @@
desc = "An advanced tactical space helmet."
icon_state = "deathsquad"
item_state = "deathsquad"
- armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30)
+ armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30, ELECTRIC = 100)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -1118,7 +1117,7 @@
icon_state = "deathsquad"
item_state = "swat_suit"
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat)
- armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30)
+ armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30, ELECTRIC = 100)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -1135,7 +1134,7 @@
max_charges = 4
current_charges = 4
recharge_delay = 15
- armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, ELECTRIC = 100)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/swat
@@ -1147,7 +1146,7 @@
icon_state = "deathsquad"
item_state = "deathsquad"
hardsuit_type = "syndi"
- armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, ELECTRIC = 100)
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
actions_types = list()
@@ -1178,14 +1177,14 @@
hardsuit_type = "t45b"
strip_delay = 100
equip_delay_other = 100
- armor = list(MELEE = 45, BULLET = 30, LASER = 25, ENERGY = 15, BOMB = 40, BIO = 100, RAD = 80, FIRE = 90, ACID = 100)
+ armor = list(MELEE = 45, BULLET = 30, LASER = 25, ENERGY = 15, BOMB = 40, BIO = 100, RAD = 80, FIRE = 90, ACID = 100, ELECTRIC = 100)
/obj/item/clothing/suit/space/hardsuit/powerarmor_t45b
name = "Salvaged T-45b power armor"
desc = "It's some dusty power armor, probably hundreds of years old."
icon_state = "hardsuit-t45b"
item_state = "t45b_hardsuit"
- armor = list(MELEE = 45, BULLET = 30, LASER = 25, ENERGY = 15, BOMB = 40, BIO = 100, RAD = 80, FIRE = 90, ACID = 100)
+ armor = list(MELEE = 45, BULLET = 30, LASER = 25, ENERGY = 15, BOMB = 40, BIO = 100, RAD = 80, FIRE = 90, ACID = 100, ELECTRIC = 100)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/powerarmor_t45b
hardsuit_type = "t45b"
strip_delay = 180
@@ -1202,7 +1201,7 @@
hardsuit_type = "advpa1"
strip_delay = 100
equip_delay_other = 100
- armor = list(MELEE = 50, BULLET = 10, LASER = 25, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 10, WOUND = 0)
+ armor = list(MELEE = 50, BULLET = 10, LASER = 25, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 10, WOUND = 0, ELECTRIC = 100)
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF
@@ -1214,7 +1213,7 @@
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/powerarmor_advanced
hardsuit_type = "advancedpa1"
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/kinetic_crusher, /obj/item/pickaxe, /obj/item/pickaxe/drill/jackhammer, /obj/item/shield/riot/goliath, /obj/item/shield/riot/roman)
- armor = list(MELEE = 50, BULLET = 10, LASER = 25, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 10, WOUND = 0)
+ armor = list(MELEE = 50, BULLET = 10, LASER = 25, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 10, WOUND = 0, ELECTRIC = 100)
slowdown = 0
strip_delay = 180
equip_delay_other = 180
@@ -1235,7 +1234,7 @@
alt_desc = "A debug hardsuit helmet. It is in combat mode."
icon_state = "hardsuit0-syndielite"
hardsuit_type = "syndielite"
- armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, ELECTRIC = 100)
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -1247,7 +1246,7 @@
icon_state = "hardsuit0-syndielite"
hardsuit_type = "syndielite"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/debug
- armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, ELECTRIC = 100)
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index 59137204f6c4..2c7852cd5fa5 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -115,6 +115,7 @@
blood_overlay_type = "armor"
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/tank/internals/ipc_coolant, /obj/item/t_scanner, /obj/item/radio, /obj/item/extinguisher/mini)
resistance_flags = NONE
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 20) // slightly more OSHA-compliant!
//Lawyer
/obj/item/clothing/suit/toggle/lawyer
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index b08798a2fdbc..3345a9940fa7 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -689,20 +689,20 @@
name = "engineering winter coat"
icon_state = "coatengineer"
item_state = "coatengineer"
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 20, FIRE = 30, ACID = 45)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 20, FIRE = 30, ACID = 45, ELECTRIC = 20)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/tank/internals/ipc_coolant, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/extinguisher/mini)
hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering
/obj/item/clothing/head/hooded/winterhood/engineering
icon_state = "winterhood_engineer"
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 20, ACID = 10)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 20, ACID = 10, ELECTRIC = 20)
/obj/item/clothing/suit/hooded/wintercoat/engineering/ce
name = "chief engineer's winter coat"
desc = "A white winter coat with reflective green and yellow stripes made for the truly insane. Stuffed with asbestos, treated with fire retardant PBDE, lined with a micro thin sheet of lead foil and snugly fitted to your body's measurements. This baby's ready to save you from anything except the thyroid cancer and systemic fibrosis you'll get from wearing it. The zipper tab is a tiny golden wrench."
icon_state = "coatce"
item_state = "coatce"
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 30, FIRE = 40, ACID = 10)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 30, FIRE = 40, ACID = 10, ELECTRIC = 40)
hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering/ce
/obj/item/clothing/suit/hooded/wintercoat/engineering/ce/Initialize(mapload)
@@ -714,7 +714,7 @@
/obj/item/clothing/head/hooded/winterhood/engineering/ce
desc = "A white winter coat hood. Feels surprisingly heavy. The tag says that it's not child safe."
icon_state = "winterhood_ce"
- armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 15, FIRE = 30, ACID = 10)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 15, FIRE = 30, ACID = 10, ELECTRIC = 40)
/obj/item/clothing/suit/hooded/wintercoat/engineering/atmos
name = "atmospherics winter coat"
diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm
index d10391cd5670..8995c24607e5 100644
--- a/code/modules/clothing/suits/reactive_armour.dm
+++ b/code/modules/clothing/suits/reactive_armour.dm
@@ -117,7 +117,7 @@
if(ismob(loc))
to_chat(loc, emp_message)
bad_effect = TRUE
- addtimer(VARSET_CALLBACK(src, bad_effect, FALSE), 30 SECONDS)
+ addtimer(VARSET_CALLBACK(src, bad_effect, FALSE), (3 SECONDS) * severity)
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
/obj/item/clothing/suit/armor/reactive/teleport
@@ -222,23 +222,29 @@
/obj/item/clothing/suit/armor/reactive/tesla
name = "reactive tesla armor"
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
- siemens_coefficient = -1
reactivearmor_cooldown_duration = 3 SECONDS
var/tesla_power = 25000
var/tesla_range = 20
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
cooldown_message = span_danger("The tesla capacitors on the reactive tesla armor are still recharging! The armor merely emits some sparks.")
emp_message = span_warning("The tesla capacitors beep ominously for a moment.")
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, ELECTRIC = 100)
/obj/item/clothing/suit/armor/reactive/tesla/dropped(mob/user)
..()
if(istype(user))
user.flags_1 &= ~TESLA_IGNORE_1
+ UnregisterSignal(user, COMSIG_LIVING_ELECTROCUTE_ACT)
/obj/item/clothing/suit/armor/reactive/tesla/equipped(mob/user, slot)
..()
if(slot_flags & slot) //Was equipped to a valid slot for this item?
user.flags_1 |= TESLA_IGNORE_1
+ RegisterSignal(user, COMSIG_LIVING_ELECTROCUTE_ACT, PROC_REF(handle_shock))
+
+/obj/item/clothing/suit/armor/reactive/tesla/proc/handle_shock(mob/living/victim, shock_damage, obj/source, siemens_coeff = 1, zone = null, tesla_shock = 0, illusion = 0)
+ if(tesla_shock)
+ return COMPONENT_NO_ELECTROCUTE_ACT
/obj/item/clothing/suit/armor/reactive/tesla/cooldown_activation(mob/living/carbon/human/owner)
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
@@ -326,11 +332,10 @@
//Hallucinating
/obj/item/clothing/suit/armor/reactive/hallucinating
- name = "reactive hallucinating armor"
- desc = "An experimental suit of armor with sensitive detectors hooked up to the mind of the wearer, sending mind pulses that causes hallucinations around you."
- cooldown_message = span_warning("The connection is currently out of sync... Recalibrating.")
- emp_message = span_warning("You feel the backsurge of a mind pulse.")
- var/effect_range = 3
+ name = "reactive hallucination armor"
+ desc = "An experimental suit of armor which produces an illusory defender upon registering an attack."
+ cooldown_message = span_warning("The reactive hallucination armor's memetic array is currently recalibrating!")
+ emp_message = span_warning("The reactive hallucination armor's array of lights and mirrors turns on you...")
clothing_traits = list(TRAIT_MESONS)
/obj/item/clothing/suit/armor/reactive/hallucinating/cooldown_activation(mob/living/carbon/human/owner)
@@ -340,14 +345,15 @@
..()
/obj/item/clothing/suit/armor/reactive/hallucinating/reactive_activation(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- owner.visible_message(span_danger("[src] blocks [attack_text], sending out mental pulses!"))
- var/turf/location = get_turf(owner)
- if(location)
- hallucination_pulse(location, effect_range, strength = 25)
+ owner.visible_message(span_danger("[src] blocks [attack_text], the body of an assistant forming to absorb it!")) //get down mr president
+ var/mob/living/simple_animal/hostile/shadowclone = new /mob/living/simple_animal/hostile/hallucination(get_turf(src))
+ shadowclone.friends += owner
return TRUE
/obj/item/clothing/suit/armor/reactive/hallucinating/emp_activation(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- owner.visible_message(span_danger("[src] blocks [attack_text], but pulls a massive charge of mental energy into [owner] from the surrounding environment!"))
+ owner.visible_message(span_danger("[src] blocks [attack_text], the body of an assistant forming to absorb it, before turning on [owner]!"))
+ var/mob/living/simple_animal/hostile/shadowclone = new /mob/living/simple_animal/hostile/hallucination(get_turf(src))
+ shadowclone.GiveTarget(owner)
owner.adjust_hallucinations(150)
return TRUE
diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm
index 0f405e23d5aa..d89818e2aea9 100644
--- a/code/modules/clothing/under/jobs/engineering.dm
+++ b/code/modules/clothing/under/jobs/engineering.dm
@@ -4,7 +4,7 @@
name = "chief engineer's jumpsuit"
icon_state = "chiefengineer"
item_state = "gy_suit"
- armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 80, ACID = 40)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 80, ACID = 40, ELECTRIC = 10)
resistance_flags = NONE
sensor_mode = SENSOR_COORDS
random_sensor = FALSE
@@ -26,7 +26,7 @@
name = "atmospheric technician's jumpsuit"
icon_state = "atmos"
item_state = "atmos_suit"
- armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 0)
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 0, ELECTRIC = 0)
resistance_flags = NONE
mutantrace_variation = MUTANTRACE_VARIATION
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index 15b3fbb981a2..803c07e84431 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -53,7 +53,7 @@
continue//no parent vent
//Stops Aliens getting stuck in small networks.
//See: Security, Virology
- if(temp_vent_parent.other_atmosmch.len > 20)
+ if(temp_vent_parent.other_atmos_machines.len > 20)
vents += temp_vent
if(!vents.len)
diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm
index 079d23dc3891..225fca834f08 100644
--- a/code/modules/events/ion_storm.dm
+++ b/code/modules/events/ion_storm.dm
@@ -1,5 +1,6 @@
#define ION_RANDOM 0
#define ION_ANNOUNCE 1
+
/datum/round_event_control/ion_storm
name = "Ion Storm"
typepath = /datum/round_event/ion_storm
@@ -7,14 +8,31 @@
min_players = 2
/datum/round_event/ion_storm
- var/addIonLawChance = 100 // chance a new ion law will be added in addition to other ion effects
- var/replaceLawsetChance = 25 //chance the AI's lawset is completely replaced with something else per config weights
- var/removeRandomLawChance = 10 //chance the AI has one random supplied or inherent law removed
- var/removeDontImproveChance = 10 //chance the randomly created law replaces a random law instead of simply being added
- var/shuffleLawsChance = 10 //chance the AI's laws are shuffled afterwards
+ /// Chance a new ion law will be added in addition to other ion effects.
+ var/addIonLawChance = 100
+ /// Chance the AI's lawset is completely replaced with something else per config weights.
+ var/replaceLawsetChance = 25
+ /// Chance the AI has one random supplied or inherent law removed.
+ var/removeRandomLawChance = 10
+ /// Chance the ion law will replace a random law instead of simply being added.
+ var/removeDontImproveChance = 10
+ /// Chance the AI's laws are shuffled afterwards.
+ var/shuffleLawsChance = 10
+ /// Chance that bots on the station will become emagged.
var/botEmagChance = 10
- var/announceEvent = ION_RANDOM // -1 means don't announce, 0 means have it randomly announce, 1 means
+ /// Chance that an airlock on the station will be messed with, if there are no AIs.
+ var/airlockChance = 5
+ /// Maximum number of airlocks that can be messed with.
+ var/airlockAmount = 20
+ /// Chance that an APC on the station will be messed with, if there are no AIs.
+ var/apcChance = 5
+ /// Maximum number of APCs that can be messed with.
+ var/apcAmount = 10
+ /// Should it announce? -1 = No | 0 = Random | 1 = Always.
+ var/announceEvent = ION_RANDOM
+ /// Custom ion law, if not null.
var/ionMessage = null
+ /// If announceEvent is 0, what is the chance it is will accounce?
var/ionAnnounceChance = 33
announceWhen = 1
@@ -24,17 +42,22 @@
removeDontImproveChance = 0
shuffleLawsChance = 0
botEmagChance = 0
+ airlockChance = 0
+ airlockAmount = 0
+ apcChance = 0
+ apcAmount = 0
/datum/round_event/ion_storm/announce(fake)
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)) || fake)
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", ANNOUNCER_IONSTORM)
-
/datum/round_event/ion_storm/start()
//AI laws
+ var/anyAliveAI = FALSE
for(var/mob/living/silicon/ai/M in GLOB.alive_mob_list)
M.laws_sanity_check()
if(M.stat != DEAD && M.see_in_dark != 0)
+ anyAliveAI = TRUE
if(prob(replaceLawsetChance))
M.laws.pick_ion_lawset()
to_chat(M, span_alert("Your lawset has been changed by the ion storm!"))
@@ -56,12 +79,78 @@
log_game("Ion storm changed laws of [key_name(M)] to [english_list(M.laws.get_law_list(TRUE, TRUE))]")
message_admins("[ADMIN_LOOKUPFLW(M)] has had their laws changed by an ion storm to [english_list(M.laws.get_law_list(TRUE, TRUE))]")
M.post_lawchange()
-
if(botEmagChance)
for(var/mob/living/simple_animal/bot/bot in GLOB.alive_mob_list)
if(prob(botEmagChance))
bot.emag_act()
+ if(!anyAliveAI)
+ if(airlockChance)
+ var/list/airlocks = get_acceptable_airlocks()
+ var/amountSince = 0
+ for(var/obj/machinery/door/airlock/airlock in airlocks)
+ if(!prob(airlockChance))
+ continue
+ if(!airlock.hasPower() || !airlock.canAIControl() || (airlock.obj_flags & EMAGGED) )
+ continue
+ var/turf/turf = get_turf(airlock)
+ var/luck = rand(1, 4)
+ switch(luck)
+ if(1)
+ if(airlock.locked)
+ airlock.unbolt()
+ log_game("Ion storm unbolted airlock ([airlock.name]) at [COORD(turf)].")
+ else
+ airlock.bolt()
+ log_game("Ion storm bolted airlock ([airlock.name]) at [COORD(turf)].")
+ if(3)
+ airlock.emergency = !airlock.emergency
+ airlock.update_appearance(UPDATE_ICON)
+ log_game("Ion storm [airlock.emergency ? "enabled" : "disabled"] emergency access on airlock ([airlock.name]) at [COORD(turf)].")
+ if(4)
+ airlock.set_electrified(MACHINE_DEFAULT_ELECTRIFY_TIME)
+ log_game("Ion storm electrified for [MACHINE_DEFAULT_ELECTRIFY_TIME] seconds airlock ([airlock.name]) at [COORD(turf)].")
+ if(5)
+ airlock.safe = !airlock.safe
+ airlock.normalspeed = airlock.safe // Intentional. They should match for maximum crushing (or maximum safety).
+ log_game("Ion storm [airlock.safe ? "enabled" : "disabled"] safety & speed on airlock ([airlock.name]) at [COORD(turf)].")
+ amountSince += 1
+ if(amountSince >= airlockAmount)
+ break
+ if(apcChance)
+ var/list/apcs = get_acceptable_apcs()
+ var/amountSince = 0
+ for(var/obj/machinery/power/apc/apc in apcs)
+ if(!prob(apcChance))
+ continue
+ if(apc.aidisabled)
+ continue
+ var/turf/turf = get_turf(apc)
+ var/luck = rand(1, 4)
+ switch(luck)
+ if(1)
+ if(apc.lighting)
+ apc.lighting = 0
+ log_game("Ion storm disabled lighting on APC ([apc.name]) at [COORD(turf)].")
+ if(2)
+ if(apc.equipment)
+ apc.equipment = 0
+ log_game("Ion storm disabled equipment on APC ([apc.name]) at [COORD(turf)].")
+ if(3)
+ if(apc.environ)
+ apc.environ = 0
+ log_game("Ion storm disabled environment on APC ([apc.name]) at [COORD(turf)].")
+ if(4)
+ if(apc.lighting || apc.equipment || apc.environ)
+ apc.environ = 0
+ apc.equipment = 0
+ apc.lighting = 0
+ log_game("Ion storm disabled lightning, equipment, and environment on APC ([apc.name]) at [COORD(turf)].")
+ apc.update()
+ amountSince += 1
+ if(amountSince >= apcAmount)
+ break
+
/datum/round_event/ion_storm/malicious
var/location_name
@@ -73,6 +162,70 @@
message += (location_name ? "Signal traced to [location_name] . " : "Signal untracable. ")
print_command_report(message, null, FALSE)
+/// Returns acceptable apcs that are safe to mess with that shouldn't cause excessive/extreme damage.
+/datum/round_event/ion_storm/proc/get_acceptable_apcs()
+ var/list/data_core_areas = list()
+ for(var/obj/machinery/ai/data_core/core as anything in GLOB.data_cores)
+ if(!core.valid_data_core())
+ continue
+ if(!isarea(core.loc))
+ continue
+ var/area/A = core.loc
+ data_core_areas[A.type] = TRUE
+ var/list/acceptable_apcs = list()
+ for(var/obj/machinery/power/apc/apc in GLOB.apcs_list)
+ if(!apc.cell || !SSmapping.level_trait(apc.z, ZTRAIT_STATION)) // Must have power and be on station.
+ continue
+ var/area/area = apc.area
+ if(GLOB.typecache_powerfailure_safe_areas[area.type]) // No touching safe areas.
+ continue
+ if(data_core_areas[area.type]) // No touching areas with data cores in them.
+ continue
+ var/critical = FALSE
+ for(var/obj/machinery/M in area.contents) // No touching areas that have critical machines.
+ if(M.critical_machine)
+ critical = TRUE
+ break
+ for(var/mob/living/silicon/ai/AI in GLOB.ai_list) // No touching areas with AIs in them.
+ if(get_area(AI) == area)
+ critical = TRUE
+ break
+ if(critical)
+ continue
+ acceptable_apcs += apc
+ return acceptable_apcs
+
+/// Returns acceptable airlocks that are safe to mess with that shouldn't cause excessive/extreme damage.
+/datum/round_event/ion_storm/proc/get_acceptable_airlocks()
+ var/list/data_core_areas = list()
+ for(var/obj/machinery/ai/data_core/core as anything in GLOB.data_cores)
+ if(!core.valid_data_core())
+ continue
+ if(!isarea(core.loc))
+ continue
+ var/area/A = core.loc
+ data_core_areas[A.type] = TRUE
+ var/list/acceptable_airlocks = list()
+ for(var/obj/machinery/door/airlock/airlock in GLOB.airlocks)
+ if(SSmapping.level_trait(airlock.z, ZTRAIT_STATION))
+ var/area/area = get_area(airlock)
+ if(data_core_areas[area.type]) // No touching areas with data cores in them.
+ continue
+ var/critical = FALSE
+ for(var/obj/machinery/M in area.contents) // No touching areas that have critical machines.
+ if(M.critical_machine)
+ critical = TRUE
+ break
+ for(var/A in GLOB.ai_list) // No touching areas with AIs in them.
+ var/mob/living/silicon/ai/I = A
+ if(get_area(I) == area)
+ critical = TRUE
+ break
+ if(critical)
+ continue
+ acceptable_airlocks += airlock
+ return acceptable_airlocks
+
/*/proc/generate_ion_law() //yogs - start mirrored in the yogs folder
//Threats are generally bad things, silly or otherwise. Plural.
var/ionthreats = pick_list(ION_FILE, "ionthreats")
diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm
index 077c1c192479..ae2b3031707c 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -33,7 +33,7 @@
beacon = new(ship_name)
/datum/round_event/pirates/announce(fake)
- priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", RANDOM_REPORT_SOUND)
+ priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound())
play_intro_music()
if(fake)
return
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index 81dbd9c0b9d9..c6dcda3ad61a 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -176,7 +176,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
- GM.set_moles(/datum/gas/oxygen, max(GM.get_moles(/datum/gas/oxygen) - severity * holder.energy, 0))
+ GM.set_moles(GAS_O2, max(GM.get_moles(GAS_O2) - severity * holder.energy, 0))
/datum/spacevine_mutation/nitro_eater
name = "nitrogen consuming"
@@ -188,7 +188,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
- GM.set_moles(/datum/gas/nitrogen, max(GM.get_moles(/datum/gas/nitrogen) - severity * holder.energy, 0))
+ GM.set_moles(GAS_N2, max(GM.get_moles(GAS_N2) - severity * holder.energy, 0))
/datum/spacevine_mutation/carbondioxide_eater
name = "CO2 consuming"
@@ -200,7 +200,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
- GM.set_moles(/datum/gas/carbon_dioxide, max(GM.get_moles(/datum/gas/carbon_dioxide) - severity * holder.energy, 0))
+ GM.set_moles(GAS_CO2, max(GM.get_moles(GAS_CO2) - severity * holder.energy, 0))
/datum/spacevine_mutation/plasma_eater
name = "toxins consuming"
@@ -212,7 +212,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
- GM.set_moles(/datum/gas/plasma, max(GM.get_moles(/datum/gas/plasma) - severity * holder.energy, 0))
+ GM.set_moles(GAS_PLASMA, max(GM.get_moles(GAS_PLASMA) - severity * holder.energy, 0))
/datum/spacevine_mutation/thorns
name = "thorny"
diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm
index 5a60c6337406..dfb572c42a10 100644
--- a/code/modules/events/spider_infestation.dm
+++ b/code/modules/events/spider_infestation.dm
@@ -27,7 +27,7 @@
continue
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
var/datum/pipeline/temp_vent_parent = temp_vent.parents[1]
- if(temp_vent_parent.other_atmosmch.len > 20)
+ if(temp_vent_parent.other_atmos_machines.len > 20)
vents += temp_vent
while((spawncount >= 1) && vents.len)
diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
index bbc06023fda4..ad98033033bd 100644
--- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
@@ -13,6 +13,7 @@
volume = 100
force = 15 //Smashing bottles over someone's head hurts.
throwforce = 15
+ demolition_mod = 0.25
item_state = "broken_beer" //Generic held-item sprite until unique ones are made.
lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
@@ -166,6 +167,7 @@
throwforce = 5
throw_speed = 3
throw_range = 5
+ demolition_mod = 0.25
w_class = WEIGHT_CLASS_TINY
item_state = "beer"
hitsound = 'sound/weapons/bladeslice.ogg'
diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm
index 979f01dd5790..4881b9e8e4f8 100644
--- a/code/modules/food_and_drinks/food/snacks_pastry.dm
+++ b/code/modules/food_and_drinks/food/snacks_pastry.dm
@@ -786,31 +786,39 @@
. += "It contains [contents.len?"[ingredients_listed]":"no ingredient, "]on top of a [initial(name)]."
bitecount = originalBites
-/obj/item/reagent_containers/food/snacks/pancakes/attackby(obj/item/I, mob/living/user, params)
- if(istype(I, /obj/item/reagent_containers/food/snacks/pancakes))
- var/obj/item/reagent_containers/food/snacks/pancakes/P = I
- if((contents.len >= PANCAKE_MAX_STACK) || ((P.contents.len + contents.len) > PANCAKE_MAX_STACK) || (reagents.total_volume >= volume))
+/obj/item/reagent_containers/food/snacks/pancakes/attackby(obj/item/item, mob/living/user, params)
+ if(istype(item, /obj/item/reagent_containers/food/snacks/pancakes))
+ var/obj/item/reagent_containers/food/snacks/pancakes/pancake = item
+ if((contents.len >= PANCAKE_MAX_STACK) || ((pancake.contents.len + contents.len) > PANCAKE_MAX_STACK) || (reagents.total_volume >= volume))
to_chat(user, span_warning("You can't add that many pancakes to [src]!"))
else
- if(!user.transferItemToLoc(I, src))
+ if(!user.transferItemToLoc(item, src))
return
- to_chat(user, span_notice("You add the [I] to the [name]."))
- P.name = initial(P.name)
- contents += P
- update_overlays(P)
- if (P.contents.len)
- for(var/V in P.contents)
- P = V
- P.name = initial(P.name)
- contents += P
- update_overlays(P)
- P = I
- LAZYCLEARLIST(P.contents)
+ to_chat(user, span_notice("You add the [item] to the [name]."))
+ pancake.name = initial(pancake.name)
+ contents += pancake
+ update_snack_overlays(pancake)
+ if (pancake.contents.len)
+ for(var/V in pancake.contents)
+ pancake = V
+ pancake.name = initial(pancake.name)
+ contents += pancake
+ update_snack_overlays(pancake)
+ pancake = item
+ LAZYCLEARLIST(pancake.contents)
return
else if(contents.len)
var/obj/O = contents[contents.len]
- return O.attackby(I, user, params)
- ..()
+ return O.attackby(item, user, params)
+ return ..()
+
+/obj/item/reagent_containers/food/snacks/pancakes/update_snack_overlays(obj/item/reagent_containers/food/snacks/pancakes/pancake)
+ var/mutable_appearance/pancake_visual = mutable_appearance(icon, "[pancake.item_state]_[rand(1, 3)]")
+ pancake_visual.pixel_x = rand(-1, 1)
+ pancake_visual.pixel_y = 3 * contents.len - 1
+ pancake_visual.layer = layer + (contents.len * 0.01)
+ add_overlay(pancake_visual)
+ update_appearance()
/obj/item/reagent_containers/food/snacks/pancakes/attack(mob/M, mob/user, def_zone, stacked = TRUE)
if(user.a_intent == INTENT_HARM || !contents.len || !stacked)
diff --git a/code/modules/goals/station_goals/dna_vault.dm b/code/modules/goals/station_goals/dna_vault.dm
index 903124d5e87a..15c0fb761cd2 100644
--- a/code/modules/goals/station_goals/dna_vault.dm
+++ b/code/modules/goals/station_goals/dna_vault.dm
@@ -261,8 +261,7 @@
to_chat(H, span_notice("You feel resistant to toxins."))
if(locate(/obj/item/organ/lungs) in H.internal_organs)
var/obj/item/organ/lungs/L = H.internal_organs_slot[ORGAN_SLOT_LUNGS]
- L.tox_breath_dam_min = 0
- L.tox_breath_dam_max = 0
+ L.gas_max -= GAS_PLASMA
ADD_TRAIT(H, TRAIT_VIRUSIMMUNE, "dna_vault")
P.tox_mod *= 0.2
H.dna.species.acidmod *= 0.2 //Remind me to move this to physiolgy later - Mqiib
diff --git a/code/modules/goals/station_goals/station_goal.dm b/code/modules/goals/station_goals/station_goal.dm
index 34454f533e03..9c9c972eebb3 100644
--- a/code/modules/goals/station_goals/station_goal.dm
+++ b/code/modules/goals/station_goals/station_goal.dm
@@ -12,7 +12,7 @@
var/report_message = "Complete this goal."
/datum/station_goal/proc/send_report()
- priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", RANDOM_REPORT_SOUND)
+ priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", SSstation.announcer.get_rand_report_sound())
print_command_report(get_report(),"Nanotrasen Directive [pick(GLOB.phonetic_alphabet)] \Roman[rand(1,50)]", announce=FALSE)
on_report()
diff --git a/code/modules/holiday/pride.dm b/code/modules/holiday/pride.dm
index 212a45aaf1fa..6cee794b5f56 100644
--- a/code/modules/holiday/pride.dm
+++ b/code/modules/holiday/pride.dm
@@ -10,7 +10,7 @@
/datum/holiday/pride/proc/become_gay_destroyer_of_worlds()
for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX) //I DON'T LIKE EM PUTTING CHEMICALS IN THE GAS THAT TURN THE FRIGGIN PLASMA GAY!
- var/obj/effect/overlay/gas/G = GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_OVERLAY][i]
+ var/obj/effect/overlay/gas/G = GLOB.gas_data.overlays[GAS_PLASMA][i]
G.icon_state = "pridesma"
animate(G, color = rgb(255, 0, 0), time = 5, loop = -1)
animate(color = rgb(0, 255, 0), time = 5, loop = -1)
diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm
index c063330a60a1..cc92d7637050 100644
--- a/code/modules/holodeck/area_copy.dm
+++ b/code/modules/holodeck/area_copy.dm
@@ -67,7 +67,7 @@
copiedobjs += SM.get_all_contents()
for(var/V in T.vars - GLOB.duplicate_forbidden_vars)
- if(V == "air")
+ if(V == "air" && SSair.initialized)
var/turf/open/O1 = B
var/turf/open/O2 = T
O1.air.copy_from(O2.return_air())
@@ -77,8 +77,6 @@
if(toupdate.len)
for(var/turf/T1 in toupdate)
- CALCULATE_ADJACENT_TURFS(T1)
- SSair.add_to_active(T1,1)
-
+ T1.ImmediateCalculateAdjacentTurfs()
return copiedobjs
diff --git a/code/modules/holodeck/holo_effect.dm b/code/modules/holodeck/holo_effect.dm
index a85d20bbeed6..3baa3e10ceea 100644
--- a/code/modules/holodeck/holo_effect.dm
+++ b/code/modules/holodeck/holo_effect.dm
@@ -61,7 +61,7 @@
var/datum/effect_system/spark_spread/s = new
s.set_up(3, 1, T)
s.start()
- T.temperature = 5000
+ T.set_temperature(5000)
T.hotspot_expose(50000,50000,1)
diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm
index 17352feaf011..86dfa455cf02 100644
--- a/code/modules/hydroponics/grown/berries.dm
+++ b/code/modules/hydroponics/grown/berries.dm
@@ -240,3 +240,34 @@
filling_color = "#7FFF00"
tastes = list("green grape" = 1)
distill_reagent = /datum/reagent/consumable/ethanol/cognac
+
+// Lanterfruit
+
+/obj/item/seeds/lanternfruit
+ name = "pack of lanternfruit seeds"
+ desc = "These seeds grow into lanternfruit pods."
+ icon_state = "seed-lanternfruit"
+ species = "lanternfruit"
+ plantname = "Lanternfruit Pod"
+ product = /obj/item/reagent_containers/food/snacks/grown/lanternfruit
+ lifespan = 35
+ endurance = 35
+ maturation = 5
+ production = 5
+ growthstages = 3
+ growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
+ icon_grow = "lanternfruit-grow"
+ icon_dead = "lanternfruit-dead"
+ icon_harvest = "lanternfruit-harvest"
+ genes = list(/datum/plant_gene/trait/glow/yellow)
+ mutatelist = null
+ reagents_add = list(/datum/reagent/sulphur = 0.07, /datum/reagent/consumable/sugar = 0.07, /datum/reagent/consumable/liquidelectricity = 0.07)
+
+/obj/item/reagent_containers/food/snacks/grown/lanternfruit
+ seed = /obj/item/seeds/lanternfruit
+ name = "lanternfruits"
+ desc = "A sofly glowing fruit with a handle-shaped stem, an Ethereal favorite!"
+ icon_state = "lanternfruit"
+ filling_color = "#eeff00"
+ tastes = list("tv static" = 1, "sour pear" = 1, "grapefruit" = 1)
+ distill_reagent = /datum/reagent/consumable/ethanol/wine_voltaic
diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm
index 9c72886a82d4..4efa0c1a92aa 100644
--- a/code/modules/hydroponics/grown/misc.dm
+++ b/code/modules/hydroponics/grown/misc.dm
@@ -57,10 +57,9 @@
return
var/datum/gas_mixture/stank = new
- stank.set_moles(/datum/gas/miasma, (yield + 6) * 3.5 * MIASMA_CORPSE_MOLES * delta_time) // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
+ stank.set_moles(GAS_MIASMA, (yield + 6) * 3.5 * MIASMA_CORPSE_MOLES * delta_time) // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
stank.set_temperature(T20C) // without this the room would eventually freeze and miasma mining would be easier
T.assume_air(stank)
- T.air_update_turf()
//Galaxy Thistle
/obj/item/seeds/galaxythistle
diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm
index 2de2723478c7..9bf186af6b50 100644
--- a/code/modules/hydroponics/grown/towercap.dm
+++ b/code/modules/hydroponics/grown/towercap.dm
@@ -231,7 +231,7 @@
if(isopenturf(loc))
var/turf/open/O = loc
if(O.air)
- if(O.air.get_moles(/datum/gas/oxygen) > 13)
+ if(O.air.get_moles(GAS_O2) > 13)
return TRUE
return FALSE
diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm
index 3d9a7e170a89..f56c3429d245 100644
--- a/code/modules/hydroponics/plant_genes.dm
+++ b/code/modules/hydroponics/plant_genes.dm
@@ -198,7 +198,7 @@
..()
if(istype(G) && ispath(G.trash, /obj/item/grown))
return
- var/obj/item/seeds/seed = G.seed
+ var/obj/item/seeds/seed = G.get_plant_seed()
var/stun_len = seed.potency * rate
if(!istype(G, /obj/item/grown/bananapeel) && (!G.reagents || !G.reagents.has_reagent(/datum/reagent/lube)))
@@ -221,14 +221,14 @@
/datum/plant_gene/trait/cell_charge/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C)
var/power = G.seed.potency*rate
if(prob(power))
- C.electrocute_act(round(power), G, 1, 1)
+ C.electrocute_act(round(power), G, 1, zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) // you stepped on it, so check protection on the legs
/datum/plant_gene/trait/cell_charge/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target)
if(iscarbon(target))
var/mob/living/carbon/C = target
var/power = G.seed.potency*rate
if(prob(power))
- C.electrocute_act(round(power), G, 1, 1)
+ C.electrocute_act(round(power), G, 1, zone = null)
/datum/plant_gene/trait/cell_charge/on_consume(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/target)
if(!G.reagents.total_volume)
@@ -256,16 +256,20 @@
trait_id = "glow"
var/glow_color = "#C3E381"
-/datum/plant_gene/trait/glow/proc/glow_range(obj/item/seeds/S)
- return 1.4 + S.potency*rate
+/datum/plant_gene/trait/glow/proc/glow_range(obj/item/seeds/seed)
+ return 1.4 + seed.potency * rate
-/datum/plant_gene/trait/glow/proc/glow_power(obj/item/seeds/S)
- return max(S.potency*(rate + 0.01), 0.1)
+/datum/plant_gene/trait/glow/proc/glow_power(obj/item/seeds/seed)
+ return max(seed.potency * (rate + 0.01), 0.1)
-/datum/plant_gene/trait/glow/on_new(obj/item/reagent_containers/food/snacks/grown/G, newloc)
+/datum/plant_gene/trait/glow/on_new(obj/item/our_plant, newloc)
. = ..()
- G.light_system = MOVABLE_LIGHT
- G.AddComponent(/datum/component/overlay_lighting, glow_range(G.seed), glow_power(G.seed), glow_color)
+ if(!.)
+ return
+
+ var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
+ our_plant.light_system = MOVABLE_LIGHT
+ our_plant.AddComponent(/datum/component/overlay_lighting, glow_range(our_seed), glow_power(our_seed), glow_color)
/datum/plant_gene/trait/glow/shadow
//makes plant emit slightly purple shadows
diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm
index 1ffb5349e54a..f4f415cf0be9 100644
--- a/code/modules/hydroponics/seeds.dm
+++ b/code/modules/hydroponics/seeds.dm
@@ -437,3 +437,21 @@
genes += P
else
qdel(P)
+
+/*
+ * Both `/item/food/grown` and `/item/grown` implement a seed variable which tracks
+ * plant statistics, genes, traits, etc. This proc gets the seed for either grown food or
+ * grown inedibles and returns it, or returns null if it's not a plant.
+ *
+ * Returns an `/obj/item/seeds` ref for grown foods or grown inedibles.
+ * - returned seed CAN be null in weird cases but in all applications it SHOULD NOT be.
+ * Returns null if it is not a plant.
+ */
+/obj/item/proc/get_plant_seed()
+ return null
+
+/obj/item/grown/get_plant_seed()
+ return seed
+
+/obj/item/reagent_containers/food/snacks/grown/get_plant_seed()
+ return seed
diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm
index f35d90193696..6365594bd8dc 100644
--- a/code/modules/jobs/job_types/captain.dm
+++ b/code/modules/jobs/job_types/captain.dm
@@ -9,7 +9,7 @@
faction = "Station"
total_positions = 1
spawn_positions = 1
- supervisors = "NanoTrasen officers and Space law" //Changed to officer to separate from CentCom officials being their superior.
+ supervisors = "Nanotrasen officers and Space law" //Changed to officer to separate from CentCom officials being their superior.
selection_color = "#ccccff"
req_admin_notify = 1
space_law_notify = 1 //Yogs
diff --git a/code/modules/jobs/job_types/roboticist.dm b/code/modules/jobs/job_types/roboticist.dm
index ff6932f7e38d..cfe4981644bb 100644
--- a/code/modules/jobs/job_types/roboticist.dm
+++ b/code/modules/jobs/job_types/roboticist.dm
@@ -10,7 +10,7 @@
selection_color = "#ffeeff"
exp_requirements = 60
exp_type = EXP_TYPE_CREW
- alt_titles = list("Augmentation Theorist", "Cyborg Maintainer", "Robotics Intern", "Biomechanical Engineer", "Mechatronic Engineer", "Machinist")
+ alt_titles = list("Augmentation Theorist", "Cyborg Maintainer", "Robotics Intern", "Biomechanical Engineer", "Mechatronic Engineer", "Machinist", "Chrome Shaman", "Ripperdoc")
outfit = /datum/outfit/job/roboticist
diff --git a/code/modules/jobs/job_types/warden.dm b/code/modules/jobs/job_types/warden.dm
index d7d1ef75f581..ccb68f5c0e1c 100644
--- a/code/modules/jobs/job_types/warden.dm
+++ b/code/modules/jobs/job_types/warden.dm
@@ -20,7 +20,7 @@
alt_titles = list("Brig Watchman", "Brig Superintendent", "Security Dispatcher", "Prison Supervisor")
- added_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_FORENSICS_LOCKERS)
+ added_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_FORENSICS_LOCKERS, ACCESS_BRIG_PHYS, ACCESS_MEDICAL) //they get medical access because apparently the windoors AREN'T BRIG PHYS ACCESS
base_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_MECH_SECURITY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) // See /datum/job/warden/get_access()
paycheck = PAYCHECK_HARD
paycheck_department = ACCOUNT_SEC
diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm
index 047d41026ae7..7e450eae0346 100644
--- a/code/modules/jobs/jobs.dm
+++ b/code/modules/jobs/jobs.dm
@@ -154,12 +154,12 @@ GLOBAL_LIST_INIT(alt_medical_positions, list(
"EMT", "Paramedic Trainee", "Rapid Response Medic", "Space Search & Rescue",
"Counsellor", "Therapist", "Mentalist",
"Mining Medical Support", "Lavaland Medical Care Unit", "Junior Mining Medic", "Planetside Health Officer", "Land Search & Rescue",
- "Security Medic", "Security Medical Support", "Penitentiary Medical Care Unit", "Junior Brig Physician", "Detention Center Health Officer",))
+ "Security Medic", "Security Medical Support", "Penitentiary Medical Care Unit", "Junior Brig Physician", "Detention Center Health Officer"))
GLOBAL_LIST_INIT(alt_science_positions, list(
"Chief Science Officer", "Head of Research", "Chief Technology Officer",
"Researcher", "Toxins Specialist", "Physicist", "Test Associate", "Anomalist", "Quantum Physicist", "Theoretical Physicist", "Xenobiologist", "Explosives Technician", "Hypothetical Physicist",
- "Augmentation Theorist", "Cyborg Maintainer", "Robotics Intern", "Biomechanical Engineer", "Mechatronic Engineer", "Machinist"))
+ "Augmentation Theorist", "Cyborg Maintainer", "Robotics Intern", "Biomechanical Engineer", "Mechatronic Engineer", "Machinist", "Chrome Shaman", "Ripperdoc"))
GLOBAL_LIST_INIT(alt_supply_positions, list(
"Chief of Staff", "Head of Internal Affairs",
diff --git a/code/modules/keybindings/focus.dm b/code/modules/keybindings/focus.dm
index 205b293e9a1a..d542b4926700 100644
--- a/code/modules/keybindings/focus.dm
+++ b/code/modules/keybindings/focus.dm
@@ -1,6 +1,3 @@
-/mob
- var/datum/focus //What receives our keyboard inputs. src by default
-
/mob/proc/set_focus(datum/new_focus)
if(focus == new_focus)
return
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index 0fa649ac58f1..70542eee66fb 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -17,7 +17,7 @@
desc = "A great place for storing knowledge."
anchored = FALSE
density = TRUE
- opacity = 0
+ opacity = FALSE
resistance_flags = FLAMMABLE
max_integrity = 200
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 0)
diff --git a/code/modules/lighting/lighting_area.dm b/code/modules/lighting/lighting_area.dm
index ce3b6b70f4c9..58ee031d3281 100644
--- a/code/modules/lighting/lighting_area.dm
+++ b/code/modules/lighting/lighting_area.dm
@@ -1,5 +1,5 @@
/area
- luminosity = TRUE
+ luminosity = TRUE
var/dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/proc/set_dynamic_lighting(new_dynamic_lighting = DYNAMIC_LIGHTING_ENABLED)
diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm
index 55b14cb513d7..6ffa5121b925 100644
--- a/code/modules/lighting/lighting_atom.dm
+++ b/code/modules/lighting/lighting_atom.dm
@@ -1,54 +1,48 @@
-
-/atom
- ///Light systems, both shouldn't be active at the same time.
- var/light_system = STATIC_LIGHT
- ///Range of the light in tiles. Zero means no light.
- var/light_range = 0
- ///Intensity of the light. The stronger, the less shadows you will see on the lit area.
- var/light_power = 1
- ///Hexadecimal RGB string representing the colour of the light. White by default.
- var/light_color = COLOR_WHITE
- ///Boolean variable for toggleable lights. Has no effect without the proper light_system, light_range and light_power values.
- var/light_on = TRUE
- ///Bitflags to determine lighting-related atom properties.
- var/light_flags = NONE
- ///Our light source. Don't fuck with this directly unless you have a good reason!
- var/tmp/datum/light_source/light
- ///Any light sources that are "inside" of us, for example, if src here was a mob that's carrying a flashlight, that flashlight's light source would be part of this list.
- var/tmp/list/light_sources
-
// The proc you should always use to set the light of this atom.
-// Nonesensical value for l_color default, so we can detect if it gets set to null.
-#define NONSENSICAL_VALUE -99999
-/atom/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE)
+/atom/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE, l_angle, l_dir, l_on)
+ // We null everything but l_dir, because we don't want to allow for modifications while frozen
+ if(light_flags & LIGHT_FROZEN)
+ l_range = null
+ l_power = null
+ l_color = null
+ l_on = null
+ l_angle = null
+
if(l_range > 0 && l_range < MINIMUM_USEFUL_LIGHT_RANGE)
- l_range = MINIMUM_USEFUL_LIGHT_RANGE //Brings the range up to 1.4, which is just barely brighter than the soft lighting that surrounds players.
- if (l_power != null)
- light_power = l_power
+ l_range = MINIMUM_USEFUL_LIGHT_RANGE //Brings the range up to 1.4, which is just barely brighter than the soft lighting that surrounds players.
+
+ if(SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT, l_range, l_power, l_color, l_on) & COMPONENT_BLOCK_LIGHT_UPDATE)
+ return
- if (l_range != null)
- light_range = l_range
+ if(!isnull(l_power))
+ set_light_power(l_power)
- if (l_color != NONSENSICAL_VALUE)
- light_color = l_color
+ if(!isnull(l_range))
+ set_light_range(l_range)
- SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT, l_range, l_power, l_color)
+ if(l_color != NONSENSICAL_VALUE)
+ set_light_color(l_color)
- update_light()
+ if(!isnull(l_angle))
+ set_light_angle(l_angle)
+
+ if(!isnull(l_dir))
+ set_light_dir(l_dir)
+
+ if(!isnull(l_on))
+ set_light_on(l_on)
-#undef NONSENSICAL_VALUE
+ update_light()
-// Will update the light (duh).
-// Creates or destroys it if needed, makes it update values, makes sure it's got the correct source turf...
+/// Will update the light (duh).
+/// Creates or destroys it if needed, makes it update values, makes sure it's got the correct source turf...
/atom/proc/update_light()
- set waitfor = FALSE
- if (QDELETED(src))
- return
+ SHOULD_NOT_SLEEP(TRUE)
if(light_system != STATIC_LIGHT)
CRASH("update_light() for [src] with following light_system value: [light_system]")
- if (!light_power || !light_range) // We won't emit light anyways, destroy the light source.
+ if (!light_power || !light_range || !light_on) // We won't emit light anyways, destroy the light source.
QDEL_NULL(light)
else
if (!ismovable(loc)) // We choose what atom should be the top atom of the light here.
@@ -60,71 +54,37 @@
light.update(.)
else
light = new/datum/light_source(src, .)
-
-// If we have opacity, make sure to tell (potentially) affected light sources.
-/atom/movable/Destroy()
- var/turf/T = loc
- . = ..()
- if (opacity && istype(T))
- var/old_has_opaque_atom = T.has_opaque_atom
- T.recalc_atom_opacity()
- if (old_has_opaque_atom != T.has_opaque_atom)
- T.reconsider_lights()
-
-// Should always be used to change the opacity of an atom.
-// It notifies (potentially) affected light sources so they can update (if needed).
+ return .
+
+/**
+ * Updates the atom's opacity value.
+ *
+ * This exists to act as a hook for associated behavior.
+ * It notifies (potentially) affected light sources so they can update (if needed).
+ */
/atom/proc/set_opacity(new_opacity)
- if (new_opacity == opacity)
+ if (new_opacity == opacity || light_flags & LIGHT_FROZEN)
return
-
+ SEND_SIGNAL(src, COMSIG_ATOM_SET_OPACITY, new_opacity)
+ . = opacity
opacity = new_opacity
- var/turf/T = loc
- if (!isturf(T))
+ return .
+
+/atom/movable/set_opacity(new_opacity)
+ . = ..()
+ if(isnull(.) || !isturf(loc))
return
- if (new_opacity == TRUE)
- T.has_opaque_atom = TRUE
- T.reconsider_lights()
+ if(opacity)
+ AddElement(/datum/element/light_blocking)
else
- var/old_has_opaque_atom = T.has_opaque_atom
- T.recalc_atom_opacity()
- if (old_has_opaque_atom != T.has_opaque_atom)
- T.reconsider_lights()
-
+ RemoveElement(/datum/element/light_blocking)
-/atom/movable/Moved(atom/OldLoc, Dir)
+/turf/set_opacity(new_opacity)
. = ..()
- for (var/datum/light_source/light as anything in light_sources) // Cycle through the light sources on this atom and tell them to update.
- light.source_atom.update_light()
-
-/atom/vv_edit_var(var_name, var_value)
- switch (var_name)
- if ("light_range")
- if(light_system == STATIC_LIGHT)
- set_light(l_range = var_value)
- else
- set_light_range(var_value)
- datum_flags |= DF_VAR_EDITED
- return TRUE
-
- if ("light_power")
- if(light_system == STATIC_LIGHT)
- set_light(l_power = var_value)
- else
- set_light_power(var_value)
- datum_flags |= DF_VAR_EDITED
- return TRUE
-
- if ("light_color")
- if(light_system == STATIC_LIGHT)
- set_light(l_color = var_value)
- else
- set_light_color(var_value)
- datum_flags |= DF_VAR_EDITED
- return TRUE
-
- return ..()
-
+ if(isnull(.))
+ return
+ recalculate_directional_opacity()
/atom/proc/flash_lighting_fx(_range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = COLOR_WHITE, _duration = FLASH_LIGHT_DURATION)
return
@@ -132,59 +92,96 @@
/turf/flash_lighting_fx(_range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = COLOR_WHITE, _duration = FLASH_LIGHT_DURATION)
if(!_duration)
stack_trace("Lighting FX obj created on a turf without a duration")
- new /obj/effect/dummy/lighting_obj (src, _range, _power, _color, _duration)
+ new /obj/effect/dummy/lighting_obj(src, _range, _power, _color, _duration)
/obj/flash_lighting_fx(_range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = COLOR_WHITE, _duration = FLASH_LIGHT_DURATION)
if(!_duration)
stack_trace("Lighting FX obj created on a obj without a duration")
- new /obj/effect/dummy/lighting_obj (get_turf(src), _range, _power, _color, _duration)
-
+ new /obj/effect/dummy/lighting_obj(get_turf(src), _range, _power, _color, _duration)
/mob/living/flash_lighting_fx(_range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = COLOR_WHITE, _duration = FLASH_LIGHT_DURATION)
mob_light(_range, _power, _color, _duration)
-
-/mob/living/proc/mob_light(_range, _power, _color, _duration)
- var/obj/effect/dummy/lighting_obj/moblight/mob_light_obj = new (src, _range, _power, _color, _duration)
+/mob/living/proc/mob_light(range, power, color, duration, light_type = /obj/effect/dummy/lighting_obj/moblight)
+ var/obj/effect/dummy/lighting_obj/moblight/mob_light_obj = new light_type(src, range, power, color, duration)
return mob_light_obj
-
+/// Setter for the light range of this atom.
/atom/proc/set_light_range(new_range)
- if(new_range == light_range)
+ if(new_range == light_range || light_flags & LIGHT_FROZEN)
+ return
+ if(SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_RANGE, new_range) & COMPONENT_BLOCK_LIGHT_UPDATE)
return
- SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_RANGE, new_range)
. = light_range
light_range = new_range
+ SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_LIGHT_RANGE, .)
+ return .
+/// Setter for the light power of this atom.
/atom/proc/set_light_power(new_power)
- if(new_power == light_power)
+ if(new_power == light_power || light_flags & LIGHT_FROZEN)
+ return
+ if(SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_POWER, new_power) & COMPONENT_BLOCK_LIGHT_UPDATE)
return
- SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_POWER, new_power)
. = light_power
light_power = new_power
+ SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_LIGHT_POWER, .)
+ return .
-
+/// Setter for the light color of this atom.
/atom/proc/set_light_color(new_color)
- if(new_color == light_color)
+ if(new_color == light_color || light_flags & LIGHT_FROZEN)
+ return
+ if(SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_COLOR, new_color) & COMPONENT_BLOCK_LIGHT_UPDATE)
return
- SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_COLOR, new_color)
. = light_color
light_color = new_color
+ SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_LIGHT_COLOR, .)
+ return .
+/// Setter for the light angle of this atom
+/atom/proc/set_light_angle(new_value)
+ if(new_value == light_angle || light_flags & LIGHT_FROZEN)
+ return
+ if(SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_ANGLE, new_value) & COMPONENT_BLOCK_LIGHT_UPDATE)
+ return
+ . = light_angle
+ light_angle = new_value
+ SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_LIGHT_ANGLE, .)
+ return .
+
+/// Setter for the light direction of this atom
+/atom/proc/set_light_dir(new_value)
+ // No frozen check here because we allow direction changes in a freeze
+ if(new_value == light_dir)
+ return
+ if(SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_DIR, new_value) & COMPONENT_BLOCK_LIGHT_UPDATE)
+ return
+ . = light_dir
+ light_dir = new_value
+ SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_LIGHT_DIR, .)
+ return .
+/// Setter for whether or not this atom's light is on.
/atom/proc/set_light_on(new_value)
- if(new_value == light_on)
+ if(new_value == light_on || light_flags & LIGHT_FROZEN)
+ return
+ if(SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_ON, new_value) & COMPONENT_BLOCK_LIGHT_UPDATE)
return
- SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_ON, new_value)
. = light_on
light_on = new_value
+ SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_LIGHT_ON, .)
+ return .
-
+/// Setter for the light flags of this atom.
/atom/proc/set_light_flags(new_value)
- if(new_value == light_flags)
+ if(new_value == light_flags || (light_flags & LIGHT_FROZEN && new_value & LIGHT_FROZEN))
+ return
+ if(SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_FLAGS, new_value) & COMPONENT_BLOCK_LIGHT_UPDATE)
return
- SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_FLAGS, new_value)
. = light_flags
light_flags = new_value
+ SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_LIGHT_FLAGS, .)
+ return .
diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm
index 3eec3be05a23..93839a8a6e79 100644
--- a/code/modules/lighting/lighting_source.dm
+++ b/code/modules/lighting/lighting_source.dm
@@ -219,7 +219,7 @@
var/oldlum = source_turf.luminosity
source_turf.luminosity = CEILING(light_range, 1)
for(var/turf/T in view(CEILING(light_range, 1), source_turf))
- if(!T.has_opaque_atom)
+ if(!IS_OPAQUE_TURF(T))
if (!T.lighting_corners_initialised)
T.generate_missing_corners()
corners[T.lighting_corner_NE] = 0
diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm
index 406ed0ae09d0..871099973730 100644
--- a/code/modules/lighting/lighting_turf.dm
+++ b/code/modules/lighting/lighting_turf.dm
@@ -1,22 +1,3 @@
-/turf
- var/dynamic_lighting = TRUE
- luminosity = 1
-
- var/tmp/lighting_corners_initialised = FALSE
-
- var/tmp/datum/lighting_object/lighting_object // Our lighting object.
-
- ///Lighting Corner datums.
- var/tmp/datum/lighting_corner/lighting_corner_NE
- var/tmp/datum/lighting_corner/lighting_corner_SE
- var/tmp/datum/lighting_corner/lighting_corner_SW
- var/tmp/datum/lighting_corner/lighting_corner_NW
-
- var/tmp/has_opaque_atom = FALSE // Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile.
-
- ///Lumcount added by sources other than lighting datum objects, such as the overlay lighting component.
- var/dynamic_lumcount = 0
-
// Causes any affecting light sources to be queued for a visibility update, for example a door got opened.
/turf/proc/reconsider_lights()
lighting_corner_NE?.vis_update()
@@ -78,21 +59,39 @@
return !luminosity
-// Can't think of a good name, this proc will recalculate the has_opaque_atom variable.
-/turf/proc/recalc_atom_opacity()
- has_opaque_atom = opacity
- if (!has_opaque_atom)
- for (var/atom/A in src.contents) // Loop through every movable atom on our tile PLUS ourselves (we matter too...)
- if (A.opacity)
- has_opaque_atom = TRUE
- break
+///Proc to add movable sources of opacity on the turf and let it handle lighting code.
+/turf/proc/add_opacity_source(atom/movable/new_source)
+ LAZYADD(opacity_sources, new_source)
+ if(opacity)
+ return
+ recalculate_directional_opacity()
-/turf/Exited(atom/movable/Obj, atom/newloc)
- . = ..()
- if (Obj && Obj.opacity)
- recalc_atom_opacity() // Make sure to do this before reconsider_lights(), incase we're on instant updates.
- reconsider_lights()
+///Proc to remove movable sources of opacity on the turf and let it handle lighting code.
+/turf/proc/remove_opacity_source(atom/movable/old_source)
+ LAZYREMOVE(opacity_sources, old_source)
+ if(opacity) //Still opaque, no need to worry on updating.
+ return
+ recalculate_directional_opacity()
+
+///Calculate on which directions this turfs block view.
+/turf/proc/recalculate_directional_opacity()
+ . = directional_opacity
+ if(opacity)
+ directional_opacity = ALL_CARDINALS
+ if(. != directional_opacity)
+ reconsider_lights()
+ return
+ directional_opacity = NONE
+ if(opacity_sources)
+ for(var/atom/movable/opacity_source as anything in opacity_sources)
+ if(opacity_source.flags_1 & ON_BORDER_1)
+ directional_opacity |= opacity_source.dir
+ else //If fulltile and opaque, then the whole tile blocks view, no need to continue checking.
+ directional_opacity = ALL_CARDINALS
+ break
+ if(. != directional_opacity && (. == ALL_CARDINALS || directional_opacity == ALL_CARDINALS))
+ reconsider_lights() //The lighting system only cares whether the tile is fully concealed from all directions or not.
/turf/proc/change_area(area/old_area, area/new_area)
if(SSlighting.initialized)
diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm
index 3d0a0d2d11cf..7a5695b82748 100644
--- a/code/modules/mapping/map_template.dm
+++ b/code/modules/mapping/map_template.dm
@@ -102,7 +102,7 @@
)
)
for(var/turf/affected_turf as anything in template_and_bordering_turfs)
- affected_turf.air_update_turf(TRUE, TRUE)
+ affected_turf.ImmediateCalculateAdjacentTurfs()
affected_turf.levelupdate()
/datum/map_template/proc/load_new_z(secret = FALSE)
diff --git a/code/modules/mapping/ruins.dm b/code/modules/mapping/ruins.dm
index 6162364d0470..f6ed99bf937d 100644
--- a/code/modules/mapping/ruins.dm
+++ b/code/modules/mapping/ruins.dm
@@ -68,9 +68,18 @@
var/list/ruins_availible = list() //we can try these in the current pass
var/list/ruins_placed = list() // yogs
+ if(PERFORM_ALL_TESTS(log_mapping))
+ log_mapping("All ruins being loaded for map testing")
+
//Set up the starting ruin list
for(var/key in ruins)
var/datum/map_template/ruin/R = ruins[key]
+
+ if(PERFORM_ALL_TESTS(log_mapping))
+ R.cost = 0
+ R.allow_duplicates = FALSE // no multiples for testing
+ R.always_place = !R.unpickable // unpickable ruin means it spawns as a set with another ruin
+
if(R.cost > budget) //Why would you do that
continue
if(R.always_place)
diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm
index 87a4ae9e8f57..19c4ab3b310d 100644
--- a/code/modules/mining/abandoned_crates.dm
+++ b/code/modules/mining/abandoned_crates.dm
@@ -11,6 +11,15 @@
var/attempts = 10
var/codelen = 4
+/obj/structure/closet/crate/secure/loot/Initialize(mapload)
+ . = ..()
+ var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
+ code = ""
+ for(var/i = 0, i < codelen, i++)
+ var/dig = pick(digits)
+ code += dig
+ digits -= dig //there are never matching digits in the answer
+
/obj/structure/closet/crate/secure/loot/update_overlays()
. = ..()
tamperproof = initial(tamperproof)
@@ -20,13 +29,6 @@
/obj/structure/closet/crate/secure/loot/PopulateContents()
. = ..()
- var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
- code = ""
- for(var/i = 0, i < codelen, i++)
- var/dig = pick(digits)
- code += dig
- digits -= dig //there are never matching digits in the answer
-
var/loot = rand(1,100) //100 different crates with varying chances of spawning
switch(loot)
if(1 to 5) //5% chance
@@ -82,14 +84,14 @@
new /obj/item/clothing/neck/petcollar(src)
if(63 to 64)
for(var/i in 1 to rand(4, 7))
- var/newcoin = pickweight(
+ var/newcoin = pickweight(list(
/obj/item/coin/silver = 3,
/obj/item/coin/iron = 3,
/obj/item/coin/gold = 1,
/obj/item/coin/diamond = 1,
/obj/item/coin/plasma = 1,
/obj/item/coin/uranium = 1,
- )
+ ))
new newcoin(src)
if(65 to 66)
new /obj/item/clothing/suit/ianshirt(src)
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index c7bc5806bd52..1c2de639447a 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -36,7 +36,7 @@
/obj/item/kinetic_crusher/Initialize(mapload)
. = ..()
AddComponent(/datum/component/butchering, 60, 110) //technically it's huge and bulky, but this provides an incentive to use it
- AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=20)
+ AddComponent(/datum/component/two_handed, force_wielded=20)
/obj/item/kinetic_crusher/Destroy()
QDEL_LIST(trophies)
diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm
index ca31e16e0e6d..d85dbb56f8e6 100644
--- a/code/modules/mining/equipment/mining_tools.dm
+++ b/code/modules/mining/equipment/mining_tools.dm
@@ -7,6 +7,7 @@
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
force = 15
throwforce = 10
+ demolition_mod = 1.2
item_state = "pickaxe"
lefthand_file = 'icons/mob/inhands/equipment/mining_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi'
diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm
index 60b0461a89f0..9669eacfe860 100644
--- a/code/modules/mining/equipment/survival_pod.dm
+++ b/code/modules/mining/equipment/survival_pod.dm
@@ -152,6 +152,7 @@
/obj/machinery/stasis/survival_pod
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "sleeper"
+ base_icon_state = "sleeper"
mattress_state = null
buckle_lying = 270
@@ -275,7 +276,7 @@
/obj/structure/fans/Initialize(mapload)
. = ..()
- air_update_turf(1)
+ air_update_turf()
//Inivisible, indestructible fans
/obj/structure/fans/tiny/invisible
diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm
index b263c1696d50..27fd03403b30 100644
--- a/code/modules/mining/equipment/wormhole_jaunter.dm
+++ b/code/modules/mining/equipment/wormhole_jaunter.dm
@@ -52,7 +52,7 @@
playsound(src,'sound/effects/sparks4.ogg',50,1)
qdel(src)
-/obj/item/wormhole_jaunter/emp_act(power)
+/obj/item/wormhole_jaunter/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
@@ -60,11 +60,8 @@
var/mob/M = loc
if(istype(M))
var/triggered = FALSE
- if(M.get_item_by_slot(ITEM_SLOT_BELT) == src)
- if(power == 1)
- triggered = TRUE
- else if(power == 2 && prob(50))
- triggered = TRUE
+ if(M.get_item_by_slot(ITEM_SLOT_BELT) == src && prob(10 * severity))
+ triggered = TRUE
if(triggered)
M.visible_message(span_warning("[src] overloads and activates!"))
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index cd67b979af49..3dc7fcb2ce27 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -284,7 +284,7 @@
/obj/machinery/mineral/equipment_vendor/free_miner
name = "free miner ship equipment vendor"
- desc = "A vendor sold by NanoTrasen to profit off small mining contractors."
+ desc = "A vendor sold by Nanotrasen to profit off small mining contractors."
prize_list = list(
new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/gun/energy/kinetic_accelerator, 750, VENDING_WEAPON),
new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 800, VENDING_WEAPON),
diff --git a/code/modules/mining/shelters.dm b/code/modules/mining/shelters.dm
index 30bc664dde85..9dcb54da06f4 100644
--- a/code/modules/mining/shelters.dm
+++ b/code/modules/mining/shelters.dm
@@ -8,7 +8,7 @@
/datum/map_template/shelter/New()
. = ..()
- blacklisted_turfs = typecacheof(/turf/closed)
+ blacklisted_turfs = typecacheof(/turf/closed, /turf/open/lava/smooth/lava_land_surface/no_shelter)
whitelisted_turfs = list()
banned_areas = typecacheof(/area/shuttle)
banned_objects = list()
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 79ca3f7ade87..b30a1abc79f2 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -37,6 +37,10 @@
return "r"
return "l"
+/mob/proc/held_index_to_body_zone(i)
+ if(!(i % 2))
+ return BODY_ZONE_R_ARM
+ return BODY_ZONE_L_ARM
//Check we have an organ for this hand slot (Dismemberment), Only relevant for humans
/mob/proc/has_hand_for_held_index(i)
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 1d0658084614..7ceb3f3f93b4 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -287,15 +287,10 @@
var/obj/item/clothing/head/hat = owner.get_item_by_slot(ITEM_SLOT_HEAD)
if(hat && istype(hat, /obj/item/clothing/head/foilhat))
return
-
- owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, (50/severity) * (maxHealth - damage) / maxHealth)
- owner.adjust_drugginess(40/severity)
- switch(severity)
- if(1)
- to_chat(owner, span_warning("Alert: Posibrain heavily damaged."))
- if(2)
- to_chat(owner, span_warning("Alert: Posibrain damaged."))
-
+ to_chat(owner, span_warning("Alert: Posibrain [severity > EMP_LIGHT ? "severely " : ""]damaged."))
+ owner.adjust_drugginess(5 * severity)
+ if(severity > EMP_LIGHT)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, (2 * (severity - EMP_LIGHT)) * (maxHealth - damage) / maxHealth) // don't give traumas from weak EMPs
////////////////////////////////////TRAUMAS////////////////////////////////////////
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index 11a2dcc37e73..6c921a663a5e 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -284,7 +284,7 @@ Doesn't work on other aliens/AI.*/
span_alertalien("You spit neurotoxin."),
)
- var/obj/projectile/bullet/neurotoxin/neurotoxin = new /obj/projectile/bullet/neurotoxin(caller.loc)
+ var/obj/projectile/reagent/neurotoxin/neurotoxin = new /obj/projectile/reagent/neurotoxin(caller.loc)
neurotoxin.preparePixelProjectile(target, caller, params)
neurotoxin.firer = caller
neurotoxin.fire()
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index 91d423d199f4..b468e9223cdc 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -15,20 +15,20 @@
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
//Partial pressure of the toxins in our breath
- var/Toxins_pp = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
+ var/Toxins_pp = (breath.get_moles(GAS_PLASMA)/breath.total_moles())*breath_pressure
if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
- adjustPlasma(breath.get_moles(/datum/gas/plasma)*250)
+ adjustPlasma(breath.get_moles(GAS_PLASMA)*250)
throw_alert("alien_tox", /atom/movable/screen/alert/alien_tox)
- toxins_used = breath.get_moles(/datum/gas/plasma)
+ toxins_used = breath.get_moles(GAS_PLASMA)
else
clear_alert("alien_tox")
//Breathe in toxins and out oxygen
- breath.adjust_moles(/datum/gas/plasma, -toxins_used)
- breath.adjust_moles(/datum/gas/oxygen, toxins_used)
+ breath.adjust_moles(GAS_PLASMA, -toxins_used)
+ breath.adjust_moles(GAS_O2, toxins_used)
//BREATH TEMPERATURE
handle_breath_temperature(breath)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 243853dafa04..d04f8899ad5e 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -541,10 +541,6 @@
/mob/living/carbon/update_stamina()
var/stam = getStaminaLoss()
- if(ishuman(src))
- var/mob/living/carbon/human/H = src //leaving this here but sus
- if(stam && H.hulk_stamina_check())
- return
if(stam > DAMAGE_PRECISION && (maxHealth - stam) <= crit_threshold)
if(!stat)
enter_stamcrit()
@@ -970,11 +966,11 @@
O.set_owner(src)
bodyparts.Remove(X)
bodyparts.Add(O)
- if(O.body_part == ARM_LEFT)
+ if(O.body_part & ARM_LEFT)
l_arm_index_next += 2
O.held_index = l_arm_index_next //1, 3, 5, 7...
hand_bodyparts += O
- else if(O.body_part == ARM_RIGHT)
+ else if(O.body_part & ARM_RIGHT)
r_arm_index_next += 2
O.held_index = r_arm_index_next //2, 4, 6, 8...
hand_bodyparts += O
@@ -1153,7 +1149,7 @@
/// Returns if the carbon is wearing shock proof gloves
/mob/living/carbon/proc/wearing_shock_proof_gloves()
- return gloves?.siemens_coefficient == 0
+ return gloves?.armor.getRating(ELECTRIC) >= 100
/mob/living/carbon/wash(clean_types)
. = ..()
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index b69a40db20dc..25436281deae 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -372,27 +372,39 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- if(HAS_TRAIT(src, TRAIT_FARADAYCAGE))
- severity++
- if(severity > EMP_LIGHT)
- return
- for(var/X in internal_organs)
- var/obj/item/organ/O = X
- O.emp_act(severity)
-/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)
+ if(dna?.species)
+ severity *= dna.species.emp_mod
+ if(severity < 1)
+ return
+
+ var/emp_message = TRUE
+ for(var/obj/item/bodypart/BP as anything in get_damageable_bodyparts(BODYPART_ROBOTIC))
+ if(!(BP.emp_act(severity, emp_message) & EMP_PROTECT_SELF))
+ emp_message = FALSE // if the EMP was successful, don't spam the chat with more messages
+
+/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = BODY_ZONE_R_ARM, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
+ if(!override) // override variable bypasses protection
+ siemens_coeff *= (100 - getarmor(zone, ELECTRIC)) / 100
+
var/stuntime = 8*siemens_coeff SECONDS // do this before species adjustments or balancing will be a pain
+ if(reagents.has_reagent(/datum/reagent/teslium))
+ siemens_coeff *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
+
+ if(SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, zone, tesla_shock) & COMPONENT_NO_ELECTROCUTE_ACT)
+ return FALSE
+
shock_damage *= siemens_coeff
if(dna && dna.species)
shock_damage *= dna.species.siemens_coeff
+ dna.species.spec_electrocute_act(src, shock_damage,source,siemens_coeff,zone,override,tesla_shock, illusion, stun)
if(shock_damage<1 && !override)
return FALSE
- if(reagents.has_reagent(/datum/reagent/teslium))
- shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
+
if(illusion)
adjustStaminaLoss(shock_damage)
else
@@ -405,11 +417,13 @@
do_jitter_animation(stuntime * 3)
adjust_stutter(stuntime / 2)
adjust_jitter(stuntime * 2)
+
var/should_stun = !tesla_shock || (tesla_shock && siemens_coeff > 0.5)
if(stun && should_stun)
Paralyze(min(stuntime, 4 SECONDS))
if(stuntime > 2 SECONDS)
addtimer(CALLBACK(src, PROC_REF(secondary_shock), should_stun, stuntime - (2 SECONDS)), 2 SECONDS)
+
if(stat == DEAD && can_defib()) //yogs: ZZAPP
if(!illusion && (shock_damage * siemens_coeff >= 1) && prob(80))
set_heartattack(FALSE)
@@ -419,6 +433,7 @@
INVOKE_ASYNC(src, PROC_REF(emote), "gasp")
adjust_jitter(10 SECONDS)
adjustOrganLoss(ORGAN_SLOT_BRAIN, 100, 199)
+
if(gib && siemens_coeff > 0)
visible_message(
span_danger("[src] body is emitting a loud noise!"), \
@@ -426,6 +441,14 @@
span_italics("You hear a loud noise!"), \
)
addtimer(CALLBACK(src, PROC_REF(supermatter_tesla_gib)), 4 SECONDS) //yogs end
+
+ if(undergoing_cardiac_arrest() && !illusion)
+ if(shock_damage * siemens_coeff >= 1 && prob(25))
+ var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
+ heart.beating = TRUE
+ if(stat == CONSCIOUS)
+ to_chat(src, span_notice("You feel your heart beating again!"))
+
if(override)
return override
else
@@ -483,12 +506,6 @@
adjust_status_effects_on_shake_up()
// adjustStaminaLoss(-10) if you want hugs to recover stamina damage, uncomment this
- if(dna && dna.check_mutation(ACTIVE_HULK))
- if(prob(30))
- adjustStaminaLoss(10)
- to_chat(src, span_notice("[M] calms you down a little."))
- else
- to_chat(src, span_warning("[M] tries to calm you!"))
set_resting(FALSE)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 9b4f0bba51c5..f352cacb4132 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -154,6 +154,28 @@
key_third_person = "shrugs"
message = "shrugs."
+// Tail thump! Lizard-tail exclusive emote.
+/datum/emote/living/carbon/human/tailthump
+ key = "thump"
+ key_third_person = "thumps their tail"
+ message = "thumps their tail!"
+ emote_type = EMOTE_AUDIBLE
+ vary = TRUE
+
+/datum/emote/living/carbon/human/tailthump/get_sound(mob/living/user)
+ return 'sound/voice/lizard/tailthump.ogg' // Source: https://freesound.org/people/TylerAM/sounds/389665/
+
+/datum/emote/living/carbon/human/tailthump/can_run_emote(mob/user, status_check = TRUE, intentional)
+ . = ..()
+ if(!.)
+ return FALSE
+ var/mob/living/carbon/human/H = user
+ if(!istype(H) || !H.dna || !H.dna.species)
+ return FALSE
+ if(H.IsParalyzed() || H.IsStun()) // No thumping allowed. Taken from can_wag_tail().
+ return FALSE
+ return ("tail_lizard" in H.dna.species.mutant_bodyparts) || ("waggingtail_lizard" in H.dna.species.mutant_bodyparts)
+
/datum/emote/living/carbon/human/wag
key = "wag"
key_third_person = "wags"
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 7365f84e1ada..55f80107e70a 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -479,7 +479,7 @@
"\[View comment log\] ",
"\[Add comment\] "), "")
else if(isobserver(user) && traitstring)
- . += "Traits: [traitstring] "
+ . += "Quirks: [traitstring] "
. += ""
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 1fc17d853d7c..c5508355451b 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -619,7 +619,8 @@
facial_hair_style = "Full Beard"
else
facial_hair_style = "Shaved"
- hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3")
+ if(!HAS_TRAIT(src, TRAIT_BALD))
+ hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3")
underwear = "Nude"
update_body()
update_hair()
@@ -708,7 +709,7 @@
#undef CPR_PANIC_SPEED
/mob/living/carbon/human/cuff_resist(obj/item/I)
- if(dna && (dna.check_mutation(HULK) || dna.check_mutation(ACTIVE_HULK)))
+ if(dna && (dna.check_mutation(HULK)))
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
if(..(I, cuff_break = FAST_CUFFBREAK))
dropItemToGround(I)
@@ -1128,12 +1129,8 @@
remove_movespeed_modifier(MOVESPEED_ID_CRAWL_MODIFIER, TRUE)
/mob/living/carbon/human/updatehealth()
- var/oldhealth = health
. = ..()
dna?.species.spec_updatehealth(src)
- if(!dna)
- return
- hulk_health_check(oldhealth)
/mob/living/carbon/human/adjust_nutrition(change) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
@@ -1394,36 +1391,3 @@
/mob/living/carbon/human/species/zombie/krokodil_addict
race = /datum/species/krokodil_addict
-
-/mob/living/carbon/human/proc/hulk_health_check(oldhealth)
- if(!dna)
- return
-
- if(dna.check_mutation(ACTIVE_HULK))
- if(health < HEALTH_THRESHOLD_CRIT)
- dna.remove_mutation(ACTIVE_HULK)
- return
- if(health < oldhealth)
- adjustStaminaLoss(-1.5 * (oldhealth - health))
- else
- if(!dna.check_mutation(HULK) && dna.check_mutation(GENETICS_HULK) && stat == CONSCIOUS && (oldhealth >= health + 10 || health < (0.5 * maxHealth)))
- dna.add_mutation(ACTIVE_HULK)
-
-/mob/living/carbon/human/proc/hulk_stamina_check()
- if(dna.check_mutation(ACTIVE_HULK))
- if(staminaloss < 60 && prob(1))
- adjust_confusion(7 SECONDS)
- say("HULK SMASH!!")
- if(staminaloss >= 90)
- dna.remove_mutation(ACTIVE_HULK)
- to_chat(src, span_notice("You have calm down enough to become human again."))
- Knockdown(6)
- return TRUE
- else
- return FALSE
-
-/mob/living/carbon/human/Bump(atom/movable/AM)
- ..()
- if(dna.check_mutation(ACTIVE_HULK) && has_status_effect(/datum/status_effect/confusion) && (world.time - last_bumped) > 15)
- Bumped(AM)
- return AM.attack_hulk(src)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index d3259e769e01..e47cd033f595 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -15,7 +15,7 @@
//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
- armorval += checkarmor(BP, type)
+ armorval += min(checkarmor(BP, type), 100) // hey no you can't do that
organnum++
return (armorval/max(organnum, 1))
@@ -30,7 +30,7 @@
continue
if(bp && istype(bp , /obj/item/clothing))
var/obj/item/clothing/C = bp
- if(C.body_parts_covered & def_zone.body_part)
+ if(def_zone.body_part & C.body_parts_covered)
protection += C.armor.getRating(d_type)
else if(C.body_parts_partial_covered & def_zone.body_part)
protection += C.armor.getRating(d_type) * 0.5
@@ -46,7 +46,7 @@
continue
if(bp && istype(bp , /obj/item/clothing))
var/obj/item/clothing/C = bp
- if(C.body_parts_covered & def_zone.body_part)
+ if(def_zone.body_part & C.body_parts_covered)
covering_part += C
return covering_part
@@ -64,7 +64,7 @@
if(mind)
if(mind.martial_art && !incapacitated(FALSE, TRUE) && mind.martial_art.can_use(src) && (mind.martial_art.deflection_chance || ((mind.martial_art.id == "sleeping carp") && in_throw_mode))) //Some martial arts users can deflect projectiles!
if(prob(mind.martial_art.deflection_chance) || ((mind.martial_art.id == "sleeping carp") && in_throw_mode)) // special check if sleeping carp is our martial art and throwmode is on, deflect
- if((mobility_flags & MOBILITY_USE) && dna && !(dna.check_mutation(HULK)|| dna.check_mutation(ACTIVE_HULK))) //But only if they're otherwise able to use items, and hulks can't do it
+ if((mobility_flags & MOBILITY_USE) && dna && !dna.check_mutation(HULK)) //But only if they're otherwise able to use items, and hulks can't do it
if(!isturf(loc)) //if we're inside something and still got hit
P.force_hit = TRUE //The thing we're in passed the bullet to us. Pass it back, and tell it to take the damage.
loc.bullet_act(P)
@@ -500,44 +500,8 @@
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
-/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)
- if(tesla_shock)
- var/total_coeff = 1
- if(gloves)
- var/obj/item/clothing/gloves/G = gloves
- if(G.siemens_coefficient <= 0)
- total_coeff -= 0.5
- if(istype(G, /obj/item/clothing/gloves/color/fyellow))
- var/obj/item/clothing/gloves/color/fyellow/greytide = G
- greytide.get_shocked()
- if(wear_suit)
- var/obj/item/clothing/suit/S = wear_suit
- if(S.siemens_coefficient <= 0)
- total_coeff -= 0.95
- else if(S.siemens_coefficient == (-1))
- total_coeff -= 1
- siemens_coeff = total_coeff
- if(flags_1 & TESLA_IGNORE_1)
- siemens_coeff = 0
- else if(!safety)
- var/gloves_siemens_coeff = 1
- if(gloves)
- var/obj/item/clothing/gloves/G = gloves
- gloves_siemens_coeff = G.siemens_coefficient
- if(istype(G, /obj/item/clothing/gloves/color/fyellow))
- var/obj/item/clothing/gloves/color/fyellow/greytide = G
- greytide.get_shocked()
- siemens_coeff = gloves_siemens_coeff
- if(undergoing_cardiac_arrest() && !illusion)
- if(shock_damage * siemens_coeff >= 1 && prob(25))
- var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
- heart.beating = TRUE
- if(stat == CONSCIOUS)
- to_chat(src, span_notice("You feel your heart beating again!"))
- siemens_coeff *= physiology.siemens_coeff
-
- dna.species.spec_electrocute_act(src, shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
- . = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun, gib)
+/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = BODY_ZONE_R_ARM, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
+ . = ..()
if(.)
electrocution_animation(40)
@@ -547,32 +511,8 @@
return dna.species.spec_emag_act(src, user, emag_card)
/mob/living/carbon/human/emp_act(severity)
- . = ..()
- if(. & EMP_PROTECT_SELF)
- return
- if(HAS_TRAIT(src, TRAIT_FARADAYCAGE))
- severity++
- if(severity > EMP_LIGHT)
- return
- dna?.species.spec_emp_act(src, severity)
- var/list/affected_parts = list()
- for(var/obj/item/bodypart/BP in bodyparts)
- if(istype(BP) && BP.status == BODYPART_ROBOTIC)
- if(prob(5) && severity == EMP_HEAVY && (TRAIT_EASYDISMEMBER in dna?.species.inherent_traits) && BP.body_zone != BODY_ZONE_CHEST)
- BP.dismember()
- else
- affected_parts += BP
- if(affected_parts.len)
- emote("scream")
- adjustFireLoss(min(5 * affected_parts.len / severity, 20 / severity), FALSE, FALSE, BODYPART_ROBOTIC)
- var/obj/item/bodypart/chest/C = get_bodypart(BODY_ZONE_CHEST)
- var/obj/item/bodypart/head/H = get_bodypart(BODY_ZONE_HEAD)
- if(((C && C.status == BODYPART_ROBOTIC) || (H && H.status == BODYPART_ROBOTIC)) && severity == EMP_HEAVY) // if your head and/or chest are robotic (aka you're a robotic race or augmented) you get cooler flavor text and rapid-onset paralysis
- to_chat(src, span_userdanger("A surge of searing pain erupts throughout your very being! As the pain subsides, a terrible sensation of emptiness is left in its wake."))
- Paralyze(5 SECONDS) //heavy EMPs will fully stun you
- else
- adjustStaminaLoss(min(15 * affected_parts.len / severity, 60 / severity), FALSE, FALSE, BODYPART_ROBOTIC)
- to_chat(src, span_userdanger("You feel a sharp pain as your robotic limbs overload."))
+ severity *= physiology.emp_mod
+ return ..(severity)
/mob/living/carbon/human/rad_act(amount, collectable_radiation)
. = ..()
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 0d4695ddfa1d..8d81a51a33d3 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -142,7 +142,7 @@
. = ..()
if(G.trigger_guard == TRIGGER_GUARD_NORMAL)
- if(src.dna.check_mutation(HULK) || src.dna.check_mutation(ACTIVE_HULK))
+ if(src.dna.check_mutation(HULK))
to_chat(src, span_warning("Your meaty finger is much too large for the trigger guard!"))
return FALSE
if(HAS_TRAIT(src, TRAIT_NOGUNS))
@@ -351,12 +351,20 @@
visually_duplicate_and_equip_item(copied_human_mob.gloves, ITEM_SLOT_GLOVES, new_human_mob, dropdel)
if(copied_human_mob.shoes)
visually_duplicate_and_equip_item(copied_human_mob.shoes, ITEM_SLOT_FEET, new_human_mob, dropdel)
+ if(copied_human_mob.head)
+ visually_duplicate_and_equip_item(copied_human_mob.head, ITEM_SLOT_HEAD, new_human_mob, dropdel)
if(copied_human_mob.wear_id)
visually_duplicate_and_equip_item(copied_human_mob.wear_id, ITEM_SLOT_ID, new_human_mob, dropdel)
new_human_mob.sec_hud_set_ID()
for(var/obj/item/implant/implant_instance in copied_human_mob.implants)
- var/obj/item/implant/implant_copy = new implant_instance.type
+ var/obj/item/implant/implant_copy
+ if(istype(implant_instance, /obj/item/implant/dusting/iaa))
+ implant_copy = new /obj/item/implant/dusting/iaa/fake ()
+ else
+ implant_copy = new implant_instance.type
+ if(!implant_copy)
+ continue //if somehow it doesn't create a copy, don't runtime
implant_copy.implant(new_human_mob, null, TRUE)
if(dropdel)
QDEL_IN(implant_copy, 7 SECONDS)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 990eafe0c222..83ce26f2f419 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -107,7 +107,7 @@
if(!dna)
return
- if(prob(3) && dna.check_mutation(ACTIVE_HULK))
+ if(prob(3) && dna.check_mutation(HULK))
say(pick_list_replacements(BRAIN_DAMAGE_FILE, "hulk"))
/mob/living/carbon/human/handle_mutations_and_radiation()
diff --git a/code/modules/mob/living/carbon/human/physiology.dm b/code/modules/mob/living/carbon/human/physiology.dm
index 50f31d0fcd3a..36982d89d352 100644
--- a/code/modules/mob/living/carbon/human/physiology.dm
+++ b/code/modules/mob/living/carbon/human/physiology.dm
@@ -17,6 +17,7 @@
var/damage_resistance = 0 // %damage reduction from all sources
var/siemens_coeff = 1 // resistance to shocks
+ var/emp_mod = 1 // resistance to EMPs
var/stun_mod = 1 // % stun modifier
var/bleed_mod = 1 // % bleeding modifier
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 571facfad919..2b759a5e221d 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -97,6 +97,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
var/staminamod = 1
/// multiplier for pressure damage
var/pressuremod = 1
+ /// multiplier for EMP severity
+ var/emp_mod = 1
/// multiplier for money paid at payday, species dependent
var/payday_modifier = 1
///Type of damage attack does
@@ -1035,7 +1037,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(!forced_colour)
switch(S.color_src)
if(MUTCOLORS)
- if(H.dna.check_mutation(HULK) || H.dna.check_mutation(ACTIVE_HULK)) //HULK GO FIRST
+ if(H.dna.check_mutation(HULK)) //HULK GO FIRST
accessory_overlay.color = "#00aa00"
else if(fixed_mut_color) //Then fixed color if applicable
accessory_overlay.color = fixed_mut_color
@@ -1542,7 +1544,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
/datum/species/proc/spec_emag_act(mob/living/carbon/human/H, mob/user, obj/item/card/emag/emag_card)
return FALSE
-/datum/species/proc/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
+/datum/species/proc/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, zone = BODY_ZONE_R_ARM, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
return
/datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
@@ -1763,7 +1765,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(M.mind)
attacker_style = M.mind.martial_art
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
- if((M.dna.check_mutation(ACTIVE_HULK) || M.dna.check_mutation(HULK)) && M.a_intent == "disarm")
+ if(M.dna.check_mutation(HULK) && M.a_intent == "disarm")
H.check_shields(0, M.name) // We check their shields twice since we are a hulk. Also triggers hitreactions for HULK_ATTACK
M.visible_message(span_danger("[M]'s punch knocks the shield out of [H]'s hand."), \
span_userdanger("[M]'s punch knocks the shield out of [H]'s hand."))
@@ -1973,8 +1975,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(istype(human_loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
return
- if(environment.get_moles(/datum/gas/water_vapor) > 10)//water vapour above a certain amount makes you wet
- if(environment.get_moles(/datum/gas/water_vapor) > 40)//if there's a lot of water vapour, preterni ded
+ if(environment.get_moles(GAS_H2O) > 10)//water vapour above a certain amount makes you wet
+ if(environment.get_moles(GAS_H2O) > 40)//if there's a lot of water vapour, preterni ded
H.adjust_wet_stacks(3)
else
H.adjust_wet_stacks(2)
@@ -2577,6 +2579,22 @@ GLOBAL_LIST_EMPTY(features_by_species)
SPECIES_PERK_DESC = "[plural_form] are resilient to being shocked.",
))
+ if(emp_mod > 1)
+ to_add += list(list(
+ SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK,
+ SPECIES_PERK_ICON = "thunderstorm",
+ SPECIES_PERK_NAME = "EM Weakness",
+ SPECIES_PERK_DESC = "[plural_form] are weak to electromagnetic interference.",
+ ))
+
+ if(emp_mod < 1)
+ to_add += list(list(
+ SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
+ SPECIES_PERK_ICON = "thunderstorm", //if we update font awesome, please swap to bolt-slash
+ SPECIES_PERK_NAME = "EM Resistance",
+ SPECIES_PERK_DESC = "[plural_form] are resistant to electromagnetic interference.",
+ ))
+
return to_add
/**
@@ -2675,15 +2693,6 @@ GLOBAL_LIST_EMPTY(features_by_species)
SPECIES_PERK_NAME = "Radiation Immunity",
SPECIES_PERK_DESC = "[plural_form] are completely unaffected by radiation. However, this doesn't mean they can't be irradiated.",
))
-
- if(TRAIT_FARADAYCAGE in inherent_traits)
- to_add += list(list(
- SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
- SPECIES_PERK_ICON = "thunderstorm", //if we update font awesome, please swap to bolt-slash
- SPECIES_PERK_NAME = "Faraday \"Skin\"",
- SPECIES_PERK_DESC = "[plural_form] have a unique physiology that shields them from weak EMPs.",
- ))
-
if(TRAIT_LIMBATTACHMENT in inherent_traits)
to_add += list(list(
SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm
index 1187abb2c9d7..890dac7e8108 100644
--- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm
+++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm
@@ -53,15 +53,12 @@
smells_like = "crackling sweetness"
- var/obj/effect/dummy/lighting_obj/ethereal_light
-
+ var/obj/effect/dummy/lighting_obj/moblight/species/ethereal_light
/datum/species/ethereal/Destroy(force)
- if(ethereal_light)
- QDEL_NULL(ethereal_light)
+ QDEL_NULL(ethereal_light)
return ..()
-
/datum/species/ethereal/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
. = ..()
if(!ishuman(C))
@@ -70,7 +67,7 @@
var/mob/living/carbon/human/ethereal = C
setup_color(ethereal)
- ethereal_light = ethereal.mob_light()
+ ethereal_light = ethereal.mob_light(light_type = /obj/effect/dummy/lighting_obj/moblight/species)
spec_updatehealth(ethereal)
var/obj/item/organ/heart/ethereal/ethereal_heart = ethereal.getorganslot(ORGAN_SLOT_HEART)
@@ -136,7 +133,7 @@
to_chat(H, span_notice("You feel the light of your body leave you."))
EMPeffect = TRUE
spec_updatehealth(H)
- addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 200 / severity, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 to 20 seconds depending on severity
+ addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 20 * severity, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 2 to 20 seconds depending on severity
/datum/species/ethereal/proc/stop_emp(mob/living/carbon/human/H)
EMPeffect = FALSE
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index eb87263056ab..0d21310381a0 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -442,19 +442,25 @@
id = "lum"
say_mod = "says"
var/glow_intensity = LUMINESCENT_DEFAULT_GLOW
- var/obj/effect/dummy/luminescent_glow/glow
var/obj/item/slime_extract/current_extract
var/datum/action/innate/integrate_extract/integrate_extract
var/datum/action/innate/use_extract/extract_minor
var/datum/action/innate/use_extract/major/extract_major
var/extract_cooldown = 0
+ /// Internal dummy used to glow (very cool)
+ var/obj/effect/dummy/lighting_obj/moblight/species/glow
+
+/datum/species/jelly/luminescent/Destroy(force, ...)
+ . = ..()
+ QDEL_NULL(glow)
+
/datum/species/jelly/luminescent/on_species_loss(mob/living/carbon/C)
..()
if(current_extract)
current_extract.forceMove(C.drop_location())
current_extract = null
- qdel(glow)
+ QDEL_NULL(glow)
if(integrate_extract)
integrate_extract.Remove(C)
if(extract_minor)
@@ -464,7 +470,7 @@
/datum/species/jelly/luminescent/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
- glow = new(C)
+ glow = C.mob_light(light_type = /obj/effect/dummy/lighting_obj/moblight/species)
update_glow(C)
integrate_extract = new(src)
integrate_extract.Grant(C)
@@ -484,20 +490,6 @@
glow_intensity = intensity
glow.set_light_range_power_color(glow_intensity, glow_intensity, C.dna.features["mcolor"])
-/obj/effect/dummy/luminescent_glow
- name = "luminescent glow"
- desc = "Tell a coder if you're seeing this."
- icon_state = "nothing"
- light_color = "#FFFFFF"
- light_range = LUMINESCENT_DEFAULT_GLOW
- light_system = MOVABLE_LIGHT
- light_power = 2.5
-
-/obj/effect/dummy/luminescent_glow/Initialize(mapload)
- . = ..()
- if(!isliving(loc))
- return INITIALIZE_HINT_QDEL
-
/datum/action/innate/integrate_extract
name = "Integrate Extract"
desc = "Eat a slime extract to use its properties."
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index e75dd711dc7c..0dfc2d7ad44d 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -112,7 +112,11 @@
/datum/species/lizard/proc/regrow_tail(mob/living/carbon/human/H)
if(!H.getorganslot(ORGAN_SLOT_TAIL) && H.stat != DEAD)
- mutant_bodyparts |= "tail_lizard"
+ var/obj/item/organ/tail/lizard/tail = new mutanttail()
+ tail.color = H.dna.features["mcolor"]
+ tail.tail_type = H.dna.features["tail_lizard"]
+ tail.spines = H.dna.features["spines"]
+ tail.Insert(H, TRUE)
H.visible_message("[H]'s tail regrows.","You feel your tail regrow.")
/datum/species/lizard/get_species_description()
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index 81adae64a74e..3739d3c9dd6b 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -27,6 +27,8 @@
liked_food = DAIRY
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC
species_language_holder = /datum/language_holder/plasmaman
+
+ screamsound = list('sound/voice/plasmaman/plasmeme_scream_1.ogg', 'sound/voice/plasmaman/plasmeme_scream_2.ogg', 'sound/voice/plasmaman/plasmeme_scream_3.ogg')
smells_like = "plasma-caked calcium"
@@ -47,7 +49,7 @@
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
if(environment)
if(environment.total_moles())
- if(environment.get_moles(/datum/gas/oxygen) >= 1) //Same threshhold that extinguishes fire
+ if(environment.get_moles(GAS_O2) >= 1) //Same threshhold that extinguishes fire
H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message(span_danger("[H]'s body reacts with the atmosphere and bursts into flames!"),span_userdanger("Your body reacts with the atmosphere and bursts into flame!"))
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 64a179f88e09..15c1da734fbe 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -631,7 +631,7 @@ generate/load female uniform sprites matching all previously decided variables
/mob/living/carbon/human/generate_icon_render_key()
. = "[dna.species.limbs_id]"
- if(dna.check_mutation(HULK) || dna.check_mutation(ACTIVE_HULK))
+ if(dna.check_mutation(HULK))
. += "-coloured-hulk"
else if(dna.species.use_skintones)
. += "-coloured-[skin_tone]"
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 1cb873615047..7e860d1e31af 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -113,21 +113,22 @@
breath = loc_as_obj.handle_internal_lifeform(src, BREATH_VOLUME)
else if(isturf(loc)) //Breathe from loc as turf
- var/breath_moles = 0
+ var/breath_ratio = 0
if(environment)
- breath_moles = environment.total_moles()*BREATH_PERCENTAGE
+ breath_ratio = BREATH_VOLUME/environment.return_volume()
- breath = loc.remove_air(breath_moles)
+ breath = loc.remove_air_ratio(breath_ratio)
else //Breathe from loc as obj again
if(istype(loc, /obj/))
var/obj/loc_as_obj = loc
loc_as_obj.handle_internal_lifeform(src,0)
+ if(breath)
+ breath.set_volume(BREATH_VOLUME)
check_breath(breath)
if(breath)
loc.assume_air(breath)
- air_update_turf()
/mob/living/carbon/proc/has_smoke_protection()
if(HAS_TRAIT(src, TRAIT_NOBREATH))
@@ -162,11 +163,13 @@
var/SA_para_min = 1
var/SA_sleep_min = 5
var/oxygen_used = 0
- var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
+ var/moles = breath.total_moles()
- var/O2_partialpressure = (breath.get_moles(/datum/gas/oxygen)/breath.total_moles())*breath_pressure
- var/Toxins_partialpressure = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
- var/CO2_partialpressure = (breath.get_moles(/datum/gas/carbon_dioxide)/breath.total_moles())*breath_pressure
+
+ var/breath_pressure = (moles*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
+ var/O2_partialpressure = ((breath.get_moles(GAS_O2)/moles)*breath_pressure) + (((breath.get_moles(GAS_PLUOXIUM)*8)/moles)*breath_pressure)
+ var/Toxins_partialpressure = (breath.get_moles(GAS_PLASMA)/moles)*breath_pressure
+ var/CO2_partialpressure = (breath.get_moles(GAS_CO2)/moles)*breath_pressure
//OXYGEN
@@ -177,7 +180,7 @@
var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3))
failed_last_breath = 1
- oxygen_used = breath.get_moles(/datum/gas/oxygen)*ratio
+ oxygen_used = breath.get_moles(GAS_O2)*ratio
else
adjustOxyLoss(3)
failed_last_breath = 1
@@ -187,11 +190,11 @@
failed_last_breath = 0
if(health >= crit_threshold)
adjustOxyLoss(-5)
- oxygen_used = breath.get_moles(/datum/gas/oxygen)
+ oxygen_used = breath.get_moles(GAS_O2)
clear_alert("not_enough_oxy")
- breath.adjust_moles(/datum/gas/oxygen, -oxygen_used)
- breath.adjust_moles(/datum/gas/carbon_dioxide, oxygen_used)
+ breath.adjust_moles(GAS_O2, -oxygen_used)
+ breath.adjust_moles(GAS_CO2, oxygen_used)
//CARBON DIOXIDE
if(CO2_partialpressure > safe_co2_max)
@@ -210,15 +213,15 @@
//TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max)
- var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_tox_max) * 10
+ var/ratio = (breath.get_moles(GAS_PLASMA)/safe_tox_max) * 10
adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /atom/movable/screen/alert/too_much_tox)
else
clear_alert("too_much_tox")
//NITROUS OXIDE
- if(breath.get_moles(/datum/gas/nitrous_oxide))
- var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrous_oxide)/breath.total_moles())*breath_pressure
+ if(breath.get_moles(GAS_NITROUS))
+ var/SA_partialpressure = (breath.get_moles(GAS_NITROUS)/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min)
Unconscious(60)
if(SA_partialpressure > SA_sleep_min)
@@ -232,8 +235,8 @@
//yogs start -- Adds Nitrogen Narcosis https://en.wikipedia.org/wiki/Nitrogen_narcosis
//NITROGEN
- if(breath.get_moles(/datum/gas/nitrogen))
- var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrogen)/breath.total_moles())*breath_pressure
+ if(breath.get_moles(GAS_N2))
+ var/SA_partialpressure = (breath.get_moles(GAS_N2)/breath.total_moles())*breath_pressure
if(SA_partialpressure > NITROGEN_NARCOSIS_PRESSURE_LOW) // Giggles
if(prob(20))
emote(pick("giggle","laugh"))
@@ -244,8 +247,8 @@
adjust_hallucinations(5 SECONDS)
//yogs end
//BZ (Facepunch port of their Agent B)
- if(breath.get_moles(/datum/gas/bz))
- var/bz_partialpressure = (breath.get_moles(/datum/gas/bz)/breath.total_moles())*breath_pressure
+ if(breath.get_moles(GAS_BZ))
+ var/bz_partialpressure = (breath.get_moles(GAS_BZ)/breath.total_moles())*breath_pressure
/* Yogs comment-out: Smoothed BZ hallucination levels
if(bz_partialpressure > 1)
adjust_hallucinations(10 SECONDS)
@@ -255,18 +258,18 @@
adjust_hallucinations(round(BZ_MAX_HALLUCINATION * (1 - NUM_E ** (-BZ_LAMBDA * bz_partialpressure)))) // Yogs -- Better BZ hallucination values. Keep in mind that hallucination has to be an integer value, due to how it's handled in handle_hallucination()
//TRITIUM
- if(breath.get_moles(/datum/gas/tritium))
- var/tritium_partialpressure = (breath.get_moles(/datum/gas/tritium)/breath.total_moles())*breath_pressure
+ if(breath.get_moles(GAS_TRITIUM))
+ var/tritium_partialpressure = (breath.get_moles(GAS_TRITIUM)/breath.total_moles())*breath_pressure
radiation += tritium_partialpressure/10
//FREON
- if(breath.get_moles(/datum/gas/freon))
- var/freon_partialpressure = (breath.get_moles(/datum/gas/freon)/breath.total_moles())*breath_pressure
+ if(breath.get_moles(GAS_FREON))
+ var/freon_partialpressure = (breath.get_moles(GAS_FREON)/breath.total_moles())*breath_pressure
adjustFireLoss(freon_partialpressure * 0.25)
//MIASMA
- if(breath.get_moles(/datum/gas/miasma))
- var/miasma_partialpressure = (breath.get_moles(/datum/gas/miasma)/breath.total_moles())*breath_pressure
+ if(breath.get_moles(GAS_MIASMA))
+ var/miasma_partialpressure = (breath.get_moles(GAS_MIASMA)/breath.total_moles())*breath_pressure
if(prob(1 * miasma_partialpressure))
var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3)
@@ -335,7 +338,7 @@
/mob/living/carbon/proc/handle_bodyparts()
var/stam_regen = FALSE
- if(stam_regen_start_time <= world.time && (has_dna() && !dna.check_mutation(ACTIVE_HULK)))
+ if(stam_regen_start_time <= world.time)
stam_regen = TRUE
if(HAS_TRAIT_FROM(src, TRAIT_INCAPACITATED, STAMINA))
. |= BODYPART_LIFE_UPDATE_HEALTH //make sure we remove the stamcrit
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 120de23ca684..b09e8ed406d9 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -363,7 +363,10 @@
//same as above
/mob/living/pointed(atom/A as mob|obj|turf in view())
- if(incapacitated())
+ var/obj/item/clothing/suit/straight_jacket/straightjacket = get_item_by_slot(ITEM_SLOT_OCLOTHING)
+ if(istype(straightjacket))
+ return FALSE
+ if(incapacitated(ignore_restraints = TRUE))
return FALSE
if(HAS_TRAIT(src, TRAIT_DEATHCOMA))
return FALSE
@@ -941,7 +944,7 @@
loc_temp = obj_temp
else if(isspaceturf(get_turf(src)))
var/turf/heat_turf = get_turf(src)
- loc_temp = heat_turf.temperature
+ loc_temp = heat_turf.return_temperature()
return loc_temp
/mob/living/proc/get_standard_pixel_x_offset(lying = 0)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 0f863d0aa9ba..161beed32fd4 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -360,22 +360,30 @@
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
return 1
-/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)
- SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage)
+/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
- if(shock_damage > 0)
- if(!illusion)
- last_damage = "electricity burns"
- adjustFireLoss(shock_damage)
- visible_message(
- span_danger("[src] was shocked by \the [source]!"), \
- span_userdanger("You feel a powerful shock coursing through your body!"), \
- span_italics("You hear a heavy electrical crack.") \
- )
- return shock_damage
+
+ if(!override)
+ siemens_coeff *= (100 - getarmor(zone, ELECTRIC)) / 100
+ if(SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, zone, tesla_shock, illusion) & COMPONENT_NO_ELECTROCUTE_ACT)
+ return FALSE
+
+ shock_damage *= siemens_coeff
+ if(shock_damage < 1 && !override)
+ return FALSE
+
+ if(!illusion)
+ last_damage = "electricity burns"
+ adjustFireLoss(shock_damage)
+ visible_message(
+ span_danger("[src] was shocked by \the [source]!"), \
+ span_userdanger("You feel a powerful shock coursing through your body!"), \
+ span_italics("You hear a heavy electrical crack.") \
+ )
+ return shock_damage
/mob/living/emp_act(severity)
. = ..()
diff --git a/code/modules/mob/living/silicon/ai/decentralized/_ai_machinery.dm b/code/modules/mob/living/silicon/ai/decentralized/_ai_machinery.dm
index 785606f8b3f2..51dea1064c3a 100644
--- a/code/modules/mob/living/silicon/ai/decentralized/_ai_machinery.dm
+++ b/code/modules/mob/living/silicon/ai/decentralized/_ai_machinery.dm
@@ -8,30 +8,36 @@
icon = 'icons/obj/machines/research.dmi'
icon_state = "RD-server-on"
density = TRUE
+ ///Temperature of the ai core itself, this will share with air in the enviroment
+ var/core_temp = 193.15
/obj/machinery/ai/Initialize(mapload)
. = ..()
-
- SSair.atmos_machinery += src
+ START_PROCESSING(SSmachines, src)
+ SSair_machinery.start_processing_machine(src)
+
+//Cooling happens here
+/obj/machinery/ai/process_atmos()
+ var/turf/T = get_turf(src)
+ if(!T)
+ return
+ if(isspaceturf(T))
+ return
+ var/datum/gas_mixture/env = T.return_air()
+ if(!env)
+ return
+ var/new_temp = env.temperature_share(AI_HEATSINK_COEFF, core_temp, AI_HEATSINK_CAPACITY)
+ core_temp = new_temp
/obj/machinery/ai/Destroy()
. = ..()
-
- SSair.atmos_machinery -= src
+ SSair_machinery.stop_processing_machine(src)
+ STOP_PROCESSING(SSmachines, src)
/obj/machinery/ai/proc/valid_holder()
if(stat & (BROKEN|EMPED) || !has_power())
return FALSE
-
- var/turf/T = get_turf(src)
- var/datum/gas_mixture/env = T.return_air()
- if(!env)
- return FALSE
- var/total_moles = env.total_moles()
- if(istype(T, /turf/open/space) || total_moles < 10)
- return FALSE
-
- if(env.return_temperature() > GLOB.ai_os.get_temp_limit() || !env.heat_capacity())
+ if(core_temp > GLOB.ai_os.get_temp_limit())
return FALSE
return TRUE
@@ -41,15 +47,6 @@
/obj/machinery/ai/proc/get_holder_status()
if(stat & (BROKEN|NOPOWER|EMPED))
return FALSE
-
- var/turf/T = get_turf(src)
- var/datum/gas_mixture/env = T.return_air()
- if(!env)
- return AI_MACHINE_NO_MOLES
- var/total_moles = env.total_moles()
- if(istype(T, /turf/open/space) || total_moles < 10)
- return AI_MACHINE_NO_MOLES
-
- if(env.return_temperature() > GLOB.ai_os.get_temp_limit() || !env.heat_capacity())
+ if(core_temp > GLOB.ai_os.get_temp_limit())
return AI_MACHINE_TOO_HOT
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/ai/decentralized/ai_data_core.dm b/code/modules/mob/living/silicon/ai/decentralized/ai_data_core.dm
index e2dc2308877f..cd77f9b70ad8 100644
--- a/code/modules/mob/living/silicon/ai/decentralized/ai_data_core.dm
+++ b/code/modules/mob/living/silicon/ai/decentralized/ai_data_core.dm
@@ -59,8 +59,42 @@ GLOBAL_VAR_INIT(primary_data_core, null)
power_modifier = new_power_mod
active_power_usage = AI_DATA_CORE_POWER_USAGE * power_modifier
-/obj/machinery/ai/data_core/process_atmos()
- calculate_validity()
+/obj/machinery/ai/data_core/process()
+ valid_ticks = clamp(valid_ticks, 0, MAX_AI_DATA_CORE_TICKS)
+
+ if(valid_holder())
+ valid_ticks++
+ if(valid_ticks == 1)
+ update_icon()
+ use_power = ACTIVE_POWER_USE
+ if((stat & NOPOWER))
+ integrated_battery.use(active_power_usage * CELL_POWERUSE_MULTIPLIER)
+ warning_sent = FALSE
+ else
+ valid_ticks--
+ if(valid_ticks <= 0)
+ use_power = IDLE_POWER_USE
+ update_icon()
+ for(var/mob/living/silicon/ai/AI in contents)
+ if(!AI.is_dying)
+ AI.relocate()
+ if(!warning_sent && COOLDOWN_FINISHED(src, warning_cooldown))
+ warning_sent = TRUE
+ COOLDOWN_START(src, warning_cooldown, AI_DATA_CORE_WARNING_COOLDOWN)
+ var/list/send_to = GLOB.ai_list.Copy()
+ for(var/mob/living/silicon/ai/AI in send_to)
+ if(AI.is_dying)
+ continue
+ if(!AI.mind && AI.deployed_shell.mind)
+ to_chat(AI.deployed_shell, span_userdanger("Data core in [get_area(src)] is on the verge of failing! Immediate action required to prevent failure."))
+ else
+ to_chat(AI, span_userdanger("Data core in [get_area(src)] is on the verge of failing! Immediate action required to prevent failure."))
+ AI.playsound_local(AI, 'sound/machines/engine_alert2.ogg', 30)
+
+ if(!(stat & (BROKEN|EMPED)) && has_power() && !disableheat)
+ var/temp_active_usage = stat & NOPOWER ? active_power_usage * CELL_POWERUSE_MULTIPLIER : active_power_usage
+ var/temperature_increase = (temp_active_usage / AI_HEATSINK_CAPACITY) * heat_modifier //1 CPU = 1000W. Heat capacity = somewhere around 3000-4000. Aka we generate 0.25 - 0.33 K per second, per CPU.
+ core_temp += temperature_increase * AI_TEMPERATURE_MULTIPLIER
/obj/machinery/ai/data_core/Destroy()
GLOB.data_cores -= src
@@ -126,6 +160,7 @@ GLOBAL_VAR_INIT(primary_data_core, null)
. += span_warning("Machinery non-functional. Reason: [holder_status]")
if(!isobserver(user))
return
+ . += "Core temperature: [core_temp] K "
. += "Networked AI Laws: "
for(var/mob/living/silicon/ai/AI in GLOB.ai_list)
var/active_status = "(Core: [FOLLOW_LINK(user, AI.loc)], Eye: [FOLLOW_LINK(user, AI.eyeobj)])"
diff --git a/code/modules/mob/living/silicon/ai/decentralized/management/ai_controlpanel.dm b/code/modules/mob/living/silicon/ai/decentralized/management/ai_controlpanel.dm
index eaccf21f5213..d19eba133c67 100644
--- a/code/modules/mob/living/silicon/ai/decentralized/management/ai_controlpanel.dm
+++ b/code/modules/mob/living/silicon/ai/decentralized/management/ai_controlpanel.dm
@@ -320,7 +320,7 @@ GLOBAL_VAR_INIT(ai_control_code, random_nukecode(6))
one_time_password_used = TRUE
var/msg = "Warning! We have detected usage of the AI Control Code for unlocking a console at coordinates ([src.x], [src.y], [src.z]) by [usr.name]. Please verify that this is correct. Be aware we have cancelled the current control code. \
If needed a new code can be printed at a communications console."
- priority_announce(msg, sender_override = "Central Cyber Security Update", has_important_message = TRUE, sanitize = FALSE)
+ priority_announce(msg, sender_override = "Central Cyber Security Update", has_important_message = TRUE)
GLOB.ai_control_code = null
else
to_chat(usr, span_warning("Incorrect code. Make sure you have the latest one."))
diff --git a/code/modules/mob/living/silicon/ai/decentralized/management/ai_dashboard.dm b/code/modules/mob/living/silicon/ai/decentralized/management/ai_dashboard.dm
index 8aa136fe96b1..8a4d7bc023cd 100644
--- a/code/modules/mob/living/silicon/ai/decentralized/management/ai_dashboard.dm
+++ b/code/modules/mob/living/silicon/ai/decentralized/management/ai_dashboard.dm
@@ -87,8 +87,8 @@
data["location_name"] = get_area(current_turf)
data["location_coords"] = "[current_turf.x], [current_turf.y], [current_turf.z]"
- var/datum/gas_mixture/env = current_turf.return_air()
- data["temperature"] = env.return_temperature()
+ var/obj/machinery/ai/current_machine = owner.loc
+ data["temperature"] = current_machine.core_temp ? current_machine.core_temp : 0
for(var/datum/ai_project/AP as anything in available_projects)
data["available_projects"] += list(list("name" = AP.name, "description" = AP.description, "ram_required" = AP.ram_required, "available" = AP.canResearch(), "research_cost" = AP.research_cost, "research_progress" = AP.research_progress,
diff --git a/code/modules/mob/living/silicon/ai/decentralized/server_cabinet.dm b/code/modules/mob/living/silicon/ai/decentralized/server_cabinet.dm
index 64b2fca5cd33..5f283cdda954 100644
--- a/code/modules/mob/living/silicon/ai/decentralized/server_cabinet.dm
+++ b/code/modules/mob/living/silicon/ai/decentralized/server_cabinet.dm
@@ -64,18 +64,14 @@ GLOBAL_LIST_EMPTY(server_cabinets)
idle_power_usage = initial(idle_power_usage) * power_modifier
-/obj/machinery/ai/server_cabinet/process_atmos()
+/obj/machinery/ai/server_cabinet/process()
valid_ticks = clamp(valid_ticks, 0, MAX_AI_EXPANSION_TICKS)
if(valid_holder())
var/total_usage = (cached_power_usage * power_modifier)
use_power(total_usage)
- var/turf/T = get_turf(src)
- var/datum/gas_mixture/env = T.return_air()
- if(env.heat_capacity())
- var/temperature_increase = (total_usage / env.heat_capacity()) * heat_modifier
- env.set_temperature(env.return_temperature() + temperature_increase * AI_TEMPERATURE_MULTIPLIER) //assume all input power is dissipated
- T.air_update_turf()
+ var/temperature_increase = (total_usage / AI_HEATSINK_CAPACITY)* heat_modifier
+ core_temp += temperature_increase * AI_TEMPERATURE_MULTIPLIER
valid_ticks++
if(!was_valid_holder)
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 17afcab90d30..9fb6a32b9d80 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -9,6 +9,9 @@
mob_size = MOB_SIZE_TINY
desc = "A generic pAI mobile hard-light holographics emitter. It seems to be deactivated."
weather_immunities = list(WEATHER_ASH)
+ light_on = FALSE
+ light_flags = LIGHT_ATTACHED
+ light_system = MOVABLE_LIGHT
health = 500
maxHealth = 500
layer = BELOW_MOB_LAYER
diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm
index b8be2fda95af..09bb968cd43c 100644
--- a/code/modules/mob/living/silicon/pai/pai_defense.dm
+++ b/code/modules/mob/living/silicon/pai/pai_defense.dm
@@ -6,16 +6,16 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- take_holo_damage(50/severity)
- Paralyze(400/severity)
- silent = max(30/severity, silent)
+ take_holo_damage(5 * severity)
+ Paralyze(40 * severity)
+ silent = max(3 * severity, silent)
if(holoform)
fold_in(force = TRUE)
//Need more effects that aren't instadeath or permanent law corruption.
//Ask and you shall receive
switch(rand(1, 3))
if(1)
- adjust_stutter(1 MINUTES / severity)
+ adjust_stutter((6 * severity) SECONDS)
to_chat(src, span_danger("Warning: Feedback loop detected in speech module."))
if(2)
adjust_slurring(INFINITY)
diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm
index 57d2045c373e..23c911e36ee2 100644
--- a/code/modules/mob/living/silicon/pai/pai_shell.dm
+++ b/code/modules/mob/living/silicon/pai/pai_shell.dm
@@ -34,7 +34,6 @@
if(client)
client.perspective = EYE_PERSPECTIVE
client.eye = src
- set_light(0)
icon_state = "[chassis]"
held_state = "[chassis]"
visible_message(span_boldnotice("[src] folds out its holochassis emitter and forms a holoshell around itself!"))
@@ -63,7 +62,6 @@
forceMove(card)
mobility_flags = NONE
density = FALSE
- set_light(0)
holoform = FALSE
set_resting(resting)
@@ -93,12 +91,9 @@
return FALSE
/mob/living/silicon/pai/proc/toggle_integrated_light()
- if(!light_range)
- set_light(brightness_power)
- to_chat(src, span_notice("You enable your integrated light."))
- else
- set_light(0)
- to_chat(src, span_notice("You disable your integrated light."))
+ set_light_on(!light_on)
+ set_light_range(brightness_power)
+ to_chat(src, span_notice("You [light_on ? "enable" : "disable"] your integrated light."))
/mob/living/silicon/pai/mob_try_pickup(mob/living/user)
if(!possible_chassis[chassis])
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index a54c85a9c65c..77739a90a570 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -573,7 +573,7 @@
for(var/id in environment.get_gases())
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0.01)
- dat += "[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_level*100)]% "
+ dat += "[GLOB.gas_data.labels[id]]: [round(gas_level*100)]% "
dat += "Temperature: [round(environment.return_temperature()-T0C)]°C "
dat += "Refresh Reading "
dat += " "
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index 80e710a1518e..6bc616c27263 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -80,11 +80,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- switch(severity)
- if(1)
- Stun(160)
- if(2)
- Stun(60)
+ Stun(min((1.6 SECONDS) * severity, 16 SECONDS)) // up to 16 seconds
/mob/living/silicon/robot/emag_act(mob/user, obj/item/card/emag/emag_card)
@@ -201,7 +197,7 @@
if(prob(75) && Proj.damage > 0)
spark_system.start()
-/mob/living/silicon/robot/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)
+/mob/living/silicon/robot/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
if(gib)
visible_message(
span_danger("[src] begins to heat up!"), \
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index e8ef8b4249a7..7e2cb6838954 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -529,16 +529,17 @@
return clamp(damage_amount * (1 - armor_protection/100), 1, damage_amount) // Minimum of 1 damage.
/// Copy of '/mob/living/attacked_by', except it sets damage to what is returned by 'proc/run_armor'.
-/mob/living/silicon/attacked_by(obj/item/I, mob/living/user)
- send_item_attack_message(I, user)
- if(I.force)
- var/damage = run_armor(I.force, I.damtype, MELEE)
- apply_damage(damage, I.damtype)
- if(I.damtype == BRUTE)
- if(prob(33))
- I.add_mob_blood(src)
- var/turf/location = get_turf(src)
- add_splatter_floor(location)
- if(get_dist(user, src) <= 1)
- user.add_mob_blood(src)
- return TRUE
+/mob/living/silicon/attacked_by(obj/item/attacking_item, mob/living/user)
+ send_item_attack_message(attacking_item, user)
+ if(!attacking_item.force)
+ return FALSE
+ // Demolition mod has half the effect on silicons that it does on structures (ex. 2x will act as 1.5x, 0.5x will act as 0.75x)
+ var/damage = run_armor(attacking_item.force * (1 + attacking_item.demolition_mod)/2, attacking_item.damtype, MELEE)
+ apply_damage(damage, attacking_item.damtype)
+ if(attacking_item.damtype == BRUTE && prob(33))
+ attacking_item.add_mob_blood(src)
+ var/turf/location = get_turf(src)
+ add_splatter_floor(location)
+ if(get_dist(user, src) <= 1)
+ user.add_mob_blood(src)
+ return TRUE
diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm
index 3942d298949d..621a5b374f2d 100644
--- a/code/modules/mob/living/silicon/silicon_defense.dm
+++ b/code/modules/mob/living/silicon/silicon_defense.dm
@@ -97,11 +97,11 @@
return
return ..()
-/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)
+/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
if(buckled_mobs)
for(var/mob/living/M in buckled_mobs)
unbuckle_mob(M)
- M.electrocute_act(shock_damage/100, source, siemens_coeff, safety, tesla_shock, illusion, stun, gib) //Hard metal shell conducts!
+ M.electrocute_act(shock_damage/100, source, siemens_coeff, zone, override, tesla_shock, illusion, stun, gib) //Hard metal shell conducts!
return 0 //So borgs they don't die trying to fix wiring
/mob/living/silicon/emp_act(severity)
@@ -109,14 +109,10 @@
to_chat(src, span_danger("Warning: Electromagnetic pulse detected."))
if(. & EMP_PROTECT_SELF)
return
- switch(severity)
- if(1)
- src.take_bodypart_damage(20)
- if(2)
- src.take_bodypart_damage(10)
+ take_bodypart_damage(2 * severity)
to_chat(src, span_userdanger("*BZZZT*"))
for(var/mob/living/M in buckled_mobs)
- if(prob(severity*50))
+ if(prob(5 * severity))
unbuckle_mob(M)
M.Paralyze(40)
M.visible_message(span_boldwarning("[M] is thrown off of [src]!"))
@@ -125,7 +121,7 @@
/mob/living/silicon/bullet_act(obj/projectile/Proj, def_zone)
SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, Proj, def_zone)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
- var/damage = run_armor(Proj.damage, Proj.damage_type, Proj.armor_flag, Proj.armour_penetration)
+ var/damage = run_armor(Proj.damage * (1 + Proj.demolition_mod)/2, Proj.damage_type, Proj.armor_flag, Proj.armour_penetration)
adjustBruteLoss(damage)
if(prob(damage*1.5))
for(var/mob/living/M in buckled_mobs)
diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm
index 148022aec96e..f560dcb9eca4 100644
--- a/code/modules/mob/living/simple_animal/animal_defense.dm
+++ b/code/modules/mob/living/simple_animal/animal_defense.dm
@@ -180,7 +180,7 @@
visual_effect_icon = ATTACK_EFFECT_SMASH
..()
-/mob/living/simple_animal/electrocute_act(shock_damage, obj/source, siemens_coeff, safety, tesla_shock, illusion, stun, gib)
+/mob/living/simple_animal/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
if(gib)
gib()
return ..()
diff --git a/code/modules/mob/living/simple_animal/bot/atmosbot.dm b/code/modules/mob/living/simple_animal/bot/atmosbot.dm
index 8f08df2f4041..6c5ad5917052 100644
--- a/code/modules/mob/living/simple_animal/bot/atmosbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/atmosbot.dm
@@ -136,7 +136,7 @@
return ATMOSBOT_CHECK_BREACH
//Too little oxygen or too little pressure
var/partial_pressure = R_IDEAL_GAS_EQUATION * gas_mix.return_temperature() / gas_mix.return_volume()
- var/oxygen_moles = gas_mix.get_moles(/datum/gas/oxygen) * partial_pressure
+ var/oxygen_moles = gas_mix.get_moles(GAS_O2) * partial_pressure
if(oxygen_moles < 20 || gas_mix.return_pressure() < WARNING_LOW_PRESSURE)
return ATMOSBOT_LOW_OXYGEN
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index a6c8a8f93f74..bf7a61cc67bb 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -364,7 +364,7 @@
ejectpai(0)
if(on)
turn_off()
- spawn(severity*300)
+ spawn(30 * severity)
stat &= ~EMPED
if(was_on)
turn_on()
diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
index c1fd265adb0f..39cf352be45c 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -459,12 +459,10 @@ Auto Patrol[]"},
/mob/living/simple_animal/bot/ed209/emp_act(severity)
- if(severity == 2 && prob(70))
- severity = 1
. = ..()
if(. & EMP_PROTECT_SELF)
return
- if (severity >= 2)
+ if (severity > EMP_LIGHT || prob(70))
new /obj/effect/temp_visual/emp(loc)
var/list/mob/living/carbon/targets = new
for(var/mob/living/carbon/C in view(12,src))
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index bbdc13985fc1..e5ab5179cd00 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -726,6 +726,11 @@
else
return null
+/mob/living/simple_animal/bot/mulebot/remove_air_ratio(ratio)
+ if(loc)
+ return loc.remove_air_ratio(ratio)
+ return null
+
/mob/living/simple_animal/bot/mulebot/resist()
..()
if(load)
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 5334e54e44d1..8141a446f15d 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -112,7 +112,7 @@
/mob/living/simple_animal/hostile/construct/narsie_act()
return
-/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)
+/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
return 0
/mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
diff --git a/code/modules/mob/living/simple_animal/eldritch_demons.dm b/code/modules/mob/living/simple_animal/eldritch_demons.dm
index a8160ab84822..1bd51dd4308b 100644
--- a/code/modules/mob/living/simple_animal/eldritch_demons.dm
+++ b/code/modules/mob/living/simple_animal/eldritch_demons.dm
@@ -276,7 +276,7 @@
var/list/parts = list()
for(var/X in C.bodyparts)
var/obj/item/bodypart/bodypart = X
- if(bodypart.body_part != HEAD && bodypart.body_part != CHEST && bodypart.body_part != LEG_LEFT && bodypart.body_part != LEG_RIGHT)
+ if(!(bodypart.body_part & HEAD|CHEST|LEG_LEFT|LEG_RIGHT))
if(bodypart.dismemberable)
parts += bodypart
if(length(parts) && prob(10))
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index fd63fa71afb3..3f28397fa82e 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -229,9 +229,9 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- Stun(100)
+ Stun(10 * severity)
to_chat(src, span_danger("ER@%R: MME^RY CO#RU9T! R&$b@0tin)..."))
- if(severity == 1)
+ if(severity > EMP_LIGHT)
adjustBruteLoss(heavy_emp_damage)
to_chat(src, span_userdanger("HeAV% DA%^MMA+G TO I/O CIR!%UUT!"))
@@ -288,5 +288,5 @@
// Why would bees pay attention to drones?
return 1
-/mob/living/simple_animal/drone/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)
+/mob/living/simple_animal/drone/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
return 0 //So they don't die trying to fix wiring
diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
index da68ff11f309..6aa83963a038 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
@@ -55,7 +55,7 @@
/obj/guardian_bomb/proc/disguise(obj/A)
A.forceMove(src)
stored_obj = A
- opacity = A.opacity
+ set_opacity(A.opacity)
anchored = A.anchored
density = A.density
appearance = A.appearance
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
index bb7ed9200a63..d0eaedc4ca14 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm
@@ -35,6 +35,7 @@ Difficulty: Extremely Hard
var/projectile_speed_multiplier = 1
var/enraged = FALSE
var/enraging = FALSE
+ internal_type = /obj/item/gps/internal/frostminer
deathmessage = "falls to the ground, decaying into plasma particles."
deathsound = "bodyfall"
attack_action_types = list(/datum/action/innate/megafauna_attack/frost_orbs,
@@ -338,3 +339,9 @@ Difficulty: Extremely Hard
to_chat(owner, span_notice("The cube melts!"))
owner.cut_overlay(cube)
UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE)
+
+/obj/item/gps/internal/frostminer
+ icon_state = null
+ gpstag = "Hollow Signal"
+ desc = "What could possibly be sending out a GPS signal in these wastes?"
+ invisibility = 100
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
index abf942d702fb..adfcd9c49fb9 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm
@@ -478,7 +478,7 @@ Difficulty: Medium
icon = 'icons/effects/fire.dmi'
icon_state = "1"
anchored = TRUE
- opacity = 0
+ opacity = FALSE
density = TRUE
CanAtmosPass = ATMOS_PASS_DENSITY
duration = 8.2 SECONDS
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
index d457ad0c2396..ef45124b5a1f 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
@@ -285,7 +285,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
else
var/mob/living/L = target
L.attack_animal(src)
- L.electrocute_act(10, src, safety = TRUE) //safety = TRUE means we don't check gloves... Ok?
+ L.electrocute_act(10, src, zone = null) //zone=null means we don't only check gloves... Ok?
return TRUE
else
return ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/regalrat.dm b/code/modules/mob/living/simple_animal/hostile/regalrat.dm
index c117420b0f4d..8aee2da1ca0e 100644
--- a/code/modules/mob/living/simple_animal/hostile/regalrat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/regalrat.dm
@@ -72,9 +72,9 @@
/mob/living/simple_animal/hostile/regalrat/handle_environment(datum/gas_mixture/environment)
. = ..()
- if(stat == DEAD || !environment || !environment.get_moles(/datum/gas/miasma))
+ if(stat == DEAD || !environment || !environment.get_moles(GAS_MIASMA))
return
- var/miasma_percentage = environment.get_moles(/datum/gas/miasma)/environment.total_moles()
+ var/miasma_percentage = environment.get_moles(GAS_MIASMA)/environment.total_moles()
if(miasma_percentage>=0.25)
heal_bodypart_damage(1)
diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm
index a96caddca1a5..09c283adafe2 100644
--- a/code/modules/mob/living/simple_animal/hostile/tree.dm
+++ b/code/modules/mob/living/simple_animal/hostile/tree.dm
@@ -46,12 +46,12 @@
if(isopenturf(loc))
var/turf/open/T = src.loc
if(T.air)
- var/co2 = T.air.get_moles(/datum/gas/carbon_dioxide)
+ var/co2 = T.air.get_moles(GAS_CO2)
if(co2 > 0)
if(prob(25))
var/amt = min(co2, 9)
- T.air.adjust_moles(/datum/gas/carbon_dioxide, -amt)
- T.atmos_spawn_air("o2=[amt]")
+ T.air.adjust_moles(GAS_CO2, -amt)
+ T.atmos_spawn_air("o2=[amt];TEMP=293.15")
/mob/living/simple_animal/hostile/tree/AttackingTarget()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm
index 1ab5b77515ad..4ed3901312fe 100644
--- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm
+++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm
@@ -14,7 +14,7 @@
icon = 'icons/effects/spacevines.dmi'
icon_state = "flower_bud"
layer = SPACEVINE_MOB_LAYER
- opacity = 0
+ opacity = FALSE
canSmoothWith = list()
smooth = SMOOTH_FALSE
/// The amount of time it takes to create a venus human trap, in deciseconds
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index f8739d65a3d1..2294a6799169 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -227,10 +227,10 @@
var/turf/open/ST = src.loc
if(ST.air)
- var/tox = ST.air.get_moles(/datum/gas/plasma)
- var/oxy = ST.air.get_moles(/datum/gas/oxygen)
- var/n2 = ST.air.get_moles(/datum/gas/nitrogen)
- var/co2 = ST.air.get_moles(/datum/gas/carbon_dioxide)
+ var/tox = ST.air.get_moles(GAS_PLASMA)
+ var/oxy = ST.air.get_moles(GAS_O2)
+ var/n2 = ST.air.get_moles(GAS_N2)
+ var/co2 = ST.air.get_moles(GAS_CO2)
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
. = FALSE
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index e6986611d0cd..51d9095a115f 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -134,7 +134,7 @@
Tempstun = 0
if(stat != DEAD)
- var/bz_percentage = environment.total_moles() ? (environment.get_moles(/datum/gas/bz) / environment.total_moles()) : 0
+ var/bz_percentage = environment.total_moles() ? (environment.get_moles(GAS_BZ) / environment.total_moles()) : 0
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
if(stat == CONSCIOUS && stasis)
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index 33e5cc3d4d90..370d71ff8850 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -46,7 +46,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
if(vent_found)
var/datum/pipeline/vent_found_parent = vent_found.parents[1]
- if(vent_found_parent && (vent_found_parent.members.len || vent_found_parent.other_atmosmch))
+ if(vent_found_parent && (vent_found_parent.members.len || vent_found_parent.other_atmos_machines))
visible_message(span_notice("[src] begins climbing into the ventilation system...") ,span_notice("You begin climbing into the ventilation system..."))
if(!do_after(src, 2.5 SECONDS, vent_found))
@@ -97,7 +97,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
for(var/datum/pipeline/P in starting_machine.return_pipenets())
totalMembers += P.members
- totalMembers += P.other_atmosmch
+ totalMembers += P.other_atmos_machines
if(!totalMembers.len)
return
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index c93719de7ff2..399aa3e7786d 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -176,7 +176,7 @@
t += span_danger("Temperature: [environment.return_temperature()] \n")
for(var/id in environment.get_gases())
if(environment.get_moles(id))
- t+=span_notice("[GLOB.meta_gas_info[id][META_GAS_NAME]]: [environment.get_moles(id)] \n")
+ t+=span_notice("[GLOB.gas_data.names[id]]: [environment.get_moles(id)] \n")
to_chat(usr, t)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 447b4b306f58..469261640cb2 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -221,4 +221,16 @@
var/list/alerts = list() // contains /atom/movable/screen/alert only // On /mob so clientless mobs will throw alerts properly
+ ///Contains the fullscreen overlays the mob can see (from 'code/_onclick/hud/fullscreen.dm')
+ var/list/screens = list()
+
+ ///The HUD type the mob will gain on Initialize. (from 'code/_onclick/hud/hud.dm')
+ var/hud_type = /datum/hud
+
+ ///The client colors the mob is looking at. (from 'code/modules/client/client_color.dm')
+ var/list/client_colours = list()
+
+ ///What receives our keyboard inputs. src by default. (from 'code/modules/keybindings/focus.dm')
+ var/datum/focus
+
var/fake_client = FALSE // Currently only used for examines
diff --git a/code/modules/modular_computers/computers/item/pda/pda_presets.dm b/code/modules/modular_computers/computers/item/pda/pda_presets.dm
index 13bebc619a9f..d790eb77f63e 100644
--- a/code/modules/modular_computers/computers/item/pda/pda_presets.dm
+++ b/code/modules/modular_computers/computers/item/pda/pda_presets.dm
@@ -3,7 +3,9 @@
/obj/item/stock_parts/cell/computer/micro,
/obj/item/computer_hardware/hard_drive/small/pda,
/obj/item/computer_hardware/network_card,
- /obj/item/computer_hardware/card_slot)
+ /obj/item/computer_hardware/card_slot,
+ /obj/item/computer_hardware/printer/mini
+ )
// This is literally the worst possible cheap tablet
/obj/item/modular_computer/tablet/pda/preset/basic
diff --git a/code/modules/modular_computers/file_system/programs/engineering/alarm.dm b/code/modules/modular_computers/file_system/programs/engineering/alarm.dm
index c40942e6dccd..9357494f9e83 100644
--- a/code/modules/modular_computers/file_system/programs/engineering/alarm.dm
+++ b/code/modules/modular_computers/file_system/programs/engineering/alarm.dm
@@ -38,52 +38,6 @@
return data
-/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, O, obj/source)
- if(is_station_level(source.z))
- if(!(A.type in GLOB.the_station_areas))
- return
- else if(!is_mining_level(source.z) || istype(A, /area/ruin))
- return
-
- var/list/L = GLOB.alarms[class]
- for(var/I in L)
- if (I == A.name)
- var/list/alarm = L[I]
- var/list/sources = alarm[3]
- if (!(source in sources))
- sources += source
- return 1
- var/obj/machinery/camera/C = null
- var/list/CL = null
- if(O && istype(O, /list))
- CL = O
- if (CL.len == 1)
- C = CL[1]
- else if(O && istype(O, /obj/machinery/camera))
- C = O
- L[A.name] = list(A, (C ? C : O), list(source))
-
- update_alarm_display()
-
- return 1
-
-
-/datum/computer_file/program/alarm_monitor/proc/cancelAlarm(class, area/A, obj/origin)
- var/list/L = GLOB.alarms[class]
- var/cleared = 0
- for (var/I in L)
- if (I == A.name)
- var/list/alarm = L[I]
- var/list/srcs = alarm[3]
- if (origin in srcs)
- srcs -= origin
- if (srcs.len == 0)
- cleared = 1
- L -= I
-
- update_alarm_display()
- return !cleared
-
/datum/computer_file/program/alarm_monitor/proc/update_alarm_display()
has_alert = FALSE
for(var/cat in GLOB.alarms)
@@ -91,6 +45,10 @@
if(L.len)
has_alert = TRUE
+/datum/computer_file/program/alarm_monitor/New()
+ ..()
+ GLOB.alarmdisplay += src
+
/datum/computer_file/program/alarm_monitor/run_program(mob/user)
. = ..(user)
GLOB.alarmdisplay += src
diff --git a/code/modules/modular_computers/file_system/programs/engineering/atmosscan.dm b/code/modules/modular_computers/file_system/programs/engineering/atmosscan.dm
index eafb14402b45..983cc27f71b3 100644
--- a/code/modules/modular_computers/file_system/programs/engineering/atmosscan.dm
+++ b/code/modules/modular_computers/file_system/programs/engineering/atmosscan.dm
@@ -34,7 +34,7 @@
var/moles = environment.get_moles(id)
var/gas_level = moles/total_moles
if(gas_level > 0)
- airlist += list(list("name" = "[GLOB.meta_gas_info[id][META_GAS_NAME]]", "percentage" = round(gas_level*100, 0.01)))
+ airlist += list(list("name" = GLOB.gas_data.labels[id], "ui_color" = GLOB.gas_data.ui_colors[id], "percentage" = round(gas_level*100, 0.01)))
data["AirData"] = airlist
else
data["AirPressure"] = 0
diff --git a/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm
index c4afd769d205..7157b82ee0c1 100644
--- a/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm
+++ b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm
@@ -154,18 +154,21 @@
for(var/gasid in air.get_gases())
if(data_corrupted)
gasdata.Add(list(list(
- "name"= GLOB.meta_gas_info[gasid][META_GAS_NAME],
- "amount" = round(rand()*100,0.01))))
+ "name"= GLOB.gas_data.names[gasid],
+ "amount" = round(rand()*100,0.01),
+ "ui_color" = GLOB.gas_data.ui_colors[gasid])))
else
gasdata.Add(list(list(
- "name"= GLOB.meta_gas_info[gasid][META_GAS_NAME],
- "amount" = round(100*air.get_moles(gasid)/air.total_moles(),0.01))))
+ "name"= GLOB.gas_data.names[gasid],
+ "amount" = round(100*air.get_moles(gasid)/air.total_moles(),0.01),
+ "ui_color" = GLOB.gas_data.ui_colors[gasid])))
else
for(var/gasid in air.get_gases())
gasdata.Add(list(list(
- "name"= GLOB.meta_gas_info[gasid][META_GAS_NAME],
- "amount" = 0)))
+ "name"= GLOB.gas_data.names[gasid],
+ "amount" = 0,
+ "ui_color" = GLOB.gas_data.ui_colors[gasid])))
data["gases"] = gasdata
else
diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm
index f1cb63c5d3dd..647627ddf7ab 100644
--- a/code/modules/modular_computers/hardware/hard_drive.dm
+++ b/code/modules/modular_computers/hardware/hard_drive.dm
@@ -221,6 +221,8 @@
..()
store_file(new/datum/computer_file/program/themeify(src))
store_file(new/datum/computer_file/program/pdamessager(src))
+ store_file(new/datum/computer_file/program/budgetorders(src))
+ store_file(new/datum/computer_file/program/bounty_board(src))
/// For tablets given to nuke ops
/obj/item/computer_hardware/hard_drive/small/nukeops
diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm
index 83d559175094..071c3aeafcd8 100644
--- a/code/modules/ninja/energy_katana.dm
+++ b/code/modules/ninja/energy_katana.dm
@@ -58,28 +58,13 @@
/obj/item/energy_katana/pickup(mob/living/carbon/human/user)
. = ..()
if(!is_ninja(user)) //stolen directly from the bloody bastard sword
- if(HAS_TRAIT (user, TRAIT_SHOCKIMMUNE))
- to_chat(user, span_warning("[src] attempts to shock you."))
- user.electrocute_act(15,src)
- return
- if(user.gloves)
- if(!user.gloves.siemens_coefficient)
- to_chat(user, span_warning("[src] attempts to shock you."))
- user.electrocute_act(15,src)
- return
- to_chat(user, span_userdanger("[src] shocks you!")) //duplicate code because wearing gloves did nothing beforehand
- user.emote("scream")
- user.electrocute_act(15,src)
- user.dropItemToGround(src, TRUE)
- user.Paralyze(50)
- return
- else
+ if(user.electrocute_act(15, src, 1, user.held_index_to_body_zone(user.active_hand_index))) // you tried to grab it with this hand, so we'll shock it
to_chat(user, span_userdanger("[src] shocks you!"))
user.emote("scream")
- user.electrocute_act(15,src)
user.dropItemToGround(src, TRUE)
user.Paralyze(50)
- return
+ else
+ to_chat(user, span_warning("[src] attempts to shock you."))
jaunt.Grant(user, src)
user.update_icons()
playsound(src, 'sound/items/unsheath.ogg', 25, 1)
diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm
index 440e02125322..92b5b20b7ecb 100644
--- a/code/modules/ninja/suit/gloves.dm
+++ b/code/modules/ninja/suit/gloves.dm
@@ -25,7 +25,6 @@
name = "ninja gloves"
icon_state = "s-ninja"
item_state = "s-ninja"
- siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
@@ -36,6 +35,7 @@
var/candrain = 0
var/mindrain = 200
var/maxdrain = 3200
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 0, ELECTRIC = 100)
/obj/item/clothing/gloves/space_ninja/Touch(atom/A,proximity)
diff --git a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
index 42a4a73d74af..aa44118c5123 100644
--- a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
@@ -10,7 +10,7 @@ It is possible to destroy the net by the occupant or someone else.
icon_state = "energynet"
density = TRUE//Can't pass through.
- opacity = 0//Can see through.
+ opacity = FALSE//Can see through.
mouse_opacity = MOUSE_OPACITY_ICON//So you can hit it with stuff.
anchored = TRUE//Can't drag/grab the net.
layer = ABOVE_ALL_MOB_LAYER
diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm
index 3d77ac911cbb..b14cf101e7ab 100644
--- a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm
@@ -6,5 +6,5 @@
if(!ninjacost(250,N_STEALTH_CANCEL))
var/mob/living/carbon/human/H = affecting
playsound(H.loc, 'sound/effects/empulse.ogg', 60, 2)
- empulse(H, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch.
+ empulse(H, EMP_HEAVY, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch.
s_coold = 4
diff --git a/code/modules/pai/actions.dm b/code/modules/pai/actions.dm
deleted file mode 100644
index 99f312dc917c..000000000000
--- a/code/modules/pai/actions.dm
+++ /dev/null
@@ -1,62 +0,0 @@
-/datum/action/innate/pai
- name = "PAI Action"
- background_icon = 'icons/mob/actions/actions_silicon.dmi'
- var/mob/living/silicon/pai/pai_owner
-
-/datum/action/innate/pai/Trigger(trigger_flags)
- if(!ispAI(owner))
- return FALSE
- pai_owner = owner
-
-/datum/action/innate/pai/software
- name = "Software Interface"
- button_icon_state = "pai"
- background_icon_state = "bg_tech"
-
-/datum/action/innate/pai/software/Trigger(trigger_flags)
- ..()
- pai_owner.ui_act()
-
-/datum/action/innate/pai/shell
- name = "Toggle Holoform"
- button_icon_state = "pai_holoform"
- background_icon_state = "bg_tech"
-
-/datum/action/innate/pai/shell/Trigger(trigger_flags)
- ..()
- if(pai_owner.holoform)
- pai_owner.fold_in(0)
- else
- pai_owner.fold_out()
-
-/datum/action/innate/pai/chassis
- name = "Holochassis Appearance Composite"
- button_icon_state = "pai_chassis"
- background_icon_state = "bg_tech"
-
-/datum/action/innate/pai/chassis/Trigger(trigger_flags)
- ..()
- pai_owner.choose_chassis()
-
-/datum/action/innate/pai/rest
- name = "Rest"
- button_icon_state = "pai_rest"
- background_icon_state = "bg_tech"
-
-/datum/action/innate/pai/rest/Trigger(trigger_flags)
- ..()
- var/mob/living/silicon/pai/pAI = usr
- if(!pAI.resting)
- pAI.set_resting(TRUE)
- else
- pAI.set_resting(FALSE)
-
-/datum/action/innate/pai/light
- name = "Toggle Integrated Lights"
- background_icon = 'icons/mob/actions/actions_spells.dmi'
- button_icon_state = "emp"
- background_icon_state = "bg_tech"
-
-/datum/action/innate/pai/light/Trigger(trigger_flags)
- ..()
- pai_owner.toggle_integrated_light()
diff --git a/code/modules/pai/camera.dm b/code/modules/pai/camera.dm
deleted file mode 100644
index 30b1918651e4..000000000000
--- a/code/modules/pai/camera.dm
+++ /dev/null
@@ -1,58 +0,0 @@
-/mob/living/silicon/pai/ClickOn(atom/target, params)
- ..()
- if(!camera?.in_camera_mode)
- return FALSE
- //pAI picture taking
- camera.toggle_camera_mode(sound = FALSE)
- camera.captureimage(target, usr, camera.picture_size_x - 1, camera.picture_size_y - 1)
- return TRUE
-
-/obj/item/camera/siliconcam/pai_camera
- name = "pAI photo camera"
- light_color = COLOR_PAI_GREEN
-
-/obj/item/camera/siliconcam/pai_camera/after_picture(mob/user, datum/picture/picture)
- var/number = length(stored)
- picture.picture_name = "Image [number] (taken by [loc.name])"
- stored[picture] = TRUE
- playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, TRUE, -3)
- balloon_alert(user, "image recorded")
-
-/**
- * Handles selecting and printing stored images.
- *
- * @param {mob} user - The pAI.
- *
- * @returns {boolean} - TRUE if the pAI prints an image,
- * FALSE otherwise.
-*/
-/obj/item/camera/siliconcam/pai_camera/proc/pai_print(mob/user)
- var/mob/living/silicon/pai/pai = loc
- var/datum/picture/selection = selectpicture(user)
- if(!istype(selection))
- balloon_alert(user, "invalid image")
- return FALSE
- printpicture(user, selection)
- user.visible_message(span_notice("A picture appears on top of the chassis of [pai.name]!"), span_notice("You print a photograph."))
- return TRUE
-
-/**
- * All inclusive camera proc. Zooms, snaps, prints.
- *
- * @param {mob} user - The pAI requesting the camera.
- *
- * @param {string} mode - The camera option to toggle.
- *
- * @returns {boolean} - TRUE if the camera worked.
- */
-/mob/living/silicon/pai/proc/use_camera(mob/user, mode)
- if(!camera || isnull(mode))
- return FALSE
- switch(mode)
- if(PAI_PHOTO_MODE_CAMERA)
- camera.toggle_camera_mode(user)
- if(PAI_PHOTO_MODE_PRINTER)
- camera.pai_print(user)
- if(PAI_PHOTO_MODE_ZOOM)
- camera.adjust_zoom(user)
- return TRUE
diff --git a/code/modules/pai/candidate.dm b/code/modules/pai/candidate.dm
deleted file mode 100644
index 6455492e1379..000000000000
--- a/code/modules/pai/candidate.dm
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * #pAI Candidate
- *
- * Created when a user opens the pAI submit interface.
- * Stores the candidate in an associative list of ckey: candidate objects.
- */
-/datum/pai_candidate
- /// User inputted OOC comments
- var/comments
- /// User inputted behavior description
- var/description
- /// User's ckey
- var/ckey
- /// User's pAI name. If blank, ninja name.
- var/name
- /// If the user has hit "submit"
- var/ready = FALSE
-
-/datum/pai_candidate/New(ckey)
- src.ckey = ckey
-
-/**
- * Checks if a candidate is ready so that they may be displayed or
- * downloaded. Removes any invalid entries.
- *
- * @returns {boolean} - TRUE if the candidate is ready, FALSE if not
- */
-/datum/pai_candidate/proc/check_ready()
- var/mob/candidate_mob = get_mob_by_key(ckey)
- if(!candidate_mob?.client || !isobserver(candidate_mob) || is_banned_from(ckey, ROLE_PAI))
- SSpai.candidates -= ckey
- return FALSE
- if(!ready)
- return FALSE
- return TRUE
diff --git a/code/modules/pai/card.dm b/code/modules/pai/card.dm
deleted file mode 100644
index fc50e1a2c04b..000000000000
--- a/code/modules/pai/card.dm
+++ /dev/null
@@ -1,260 +0,0 @@
-/obj/item/pai_card
- name = "personal AI device"
- desc = "Downloads personal AI assistants to accompany its owner or others."
- icon = 'icons/obj/aicards.dmi'
- icon_state = "pai"
- item_state = "electronic"
- lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
- resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
- w_class = WEIGHT_CLASS_SMALL
- slot_flags = ITEM_SLOT_BELT
- cryo_preserve = TRUE
- /// Spam alert prevention
- var/alert_cooldown
- /// The emotion icon displayed.
- var/emotion_icon = "off"
- /// Any pAI personalities inserted
- var/mob/living/silicon/pai/pai
- /// Prevents a crew member from hitting "request pAI" repeatedly
- var/request_spam = FALSE
-
-/obj/item/pai_card/attackby(obj/item/used, mob/user, params)
- if(pai && istype(used, /obj/item/encryptionkey))
- if(!pai.encrypt_mod)
- to_chat(user, span_alert("Encryption Key ports not configured."))
- return
- user.set_machine(src)
- pai.radio.attackby(used, user, params)
- to_chat(user, span_notice("You insert [used] into the [src]."))
- return
- return ..()
-
-/obj/item/pai_card/attack_self(mob/user)
- if(!in_range(src, user))
- return
- user.set_machine(src)
- ui_interact(user)
-
-/obj/item/pai_card/Destroy()
- //Will stop people throwing friend pAIs into the singularity so they can respawn
- SSpai.pai_card_list.Remove(src)
- if(!QDELETED(pai))
- QDEL_NULL(pai)
- return ..()
-
-/obj/item/pai_card/emag_act(mob/user, obj/item/card/emag/emag_card)
- if(!pai)
- return FALSE
- return pai.handle_emag(user, emag_card)
-
-/obj/item/pai_card/emp_act(severity)
- . = ..()
- if (. & EMP_PROTECT_SELF)
- return
- if(pai && !pai.holoform)
- pai.emp_act(severity)
-
-/obj/item/pai_card/handle_atom_del(atom/thing)
- if(thing == pai) //double check /mob/living/silicon/pai/Destroy() if you change these.
- pai = null
- emotion_icon = initial(emotion_icon)
- update_appearance(UPDATE_ICON)
- return ..()
-
-/obj/item/pai_card/Initialize(mapload)
- . = ..()
- update_appearance(UPDATE_ICON)
- SSpai.pai_card_list += src
-
-/obj/item/pai_card/suicide_act(mob/living/user)
- user.visible_message(span_suicide("[user] is staring sadly at [src]! [user.p_they()] can't keep living without real human intimacy!"))
- return OXYLOSS
-
-/obj/item/pai_card/update_overlays()
- . = ..()
- . += "pai-[emotion_icon]"
- if(pai?.hacking_cable)
- . += "[initial(icon_state)]-connector"
-
-/obj/item/pai_card/vv_edit_var(vname, vval)
- . = ..()
- if(vname == NAMEOF(src, emotion_icon))
- update_appearance(UPDATE_ICON)
-
-/obj/item/pai_card/ui_interact(mob/user, datum/tgui/ui)
- . = ..()
- ui = SStgui.try_update_ui(user, src, ui)
- if(!ui)
- ui = new(user, src, "PaiCard")
- ui.open()
-
-/obj/item/pai_card/ui_status(mob/user)
- if(user in get_nested_locs(src))
- return UI_INTERACTIVE
- return ..()
-
-/obj/item/pai_card/ui_data(mob/user)
- . = ..()
- var/list/data = list()
- if(!pai)
- data["candidates"] = pool_candidates() || list()
- return data
- data["pai"] = list(
- can_holo = pai.can_holo,
- dna = pai.master_dna,
- emagged = pai.emagged,
- laws = pai.laws.supplied,
- master = pai.master_name,
- name = pai.name,
- transmit = pai.can_transmit,
- receive = pai.can_receive,
- )
- return data
-
-/obj/item/pai_card/ui_act(action, list/params, datum/tgui/ui)
- . = ..()
- if(.)
- return TRUE
- // Actions that don't require a pAI
- if(action == "download")
- download_candidate(usr, params["ckey"])
- return TRUE
- if(action == "request")
- find_pai(usr)
- return TRUE
- // pAI specific actions.
- if(!pai)
- return FALSE
- switch(action)
- if("fix_speech")
- pai.fix_speech()
- return TRUE
- if("reset_software")
- pai.reset_software()
- return TRUE
- if("set_dna")
- pai.set_dna(usr)
- return TRUE
- if("set_laws")
- pai.set_laws(usr)
- return TRUE
- if("toggle_holo")
- pai.toggle_holo()
- return TRUE
- if("toggle_radio")
- pai.toggle_radio(params["option"])
- return TRUE
- if("wipe_pai")
- pai.wipe_pai(usr)
- ui.close()
- return TRUE
- return FALSE
-
-/** Flashes the pai card screen */
-/obj/item/pai_card/proc/add_alert()
- if(pai)
- return
- add_overlay(
- list(mutable_appearance(icon, "[initial(icon_state)]-alert"),
- mutable_appearance(icon, "[initial(icon_state)]-alert", src, alpha = src.alpha)))
-
-/** Removes any overlays */
-/obj/item/pai_card/proc/remove_alert()
- if(pai)
- return
- cut_overlays()
-
-/** Alerts pAI cards that someone has submitted candidacy */
-/obj/item/pai_card/proc/alert_update()
- if(!COOLDOWN_FINISHED(src, alert_cooldown))
- return
- COOLDOWN_START(src, alert_cooldown, 5 SECONDS)
- add_alert()
- addtimer(CALLBACK(src, PROC_REF(remove_alert)), 5 SECONDS)
- playsound(src, 'sound/machines/ping.ogg', 30, TRUE)
- visible_message(span_notice("[src] flashes a message across its screen: New personalities available for download!"), blind_message = span_notice("[src] vibrates with an alert."))
-
-/**
- * Downloads a candidate from the list and removes them from SSpai.candidates
- *
- * @param {string} ckey The ckey of the candidate to download
- *
- * @returns {boolean} - TRUE if the candidate was downloaded, FALSE if not
- */
-/obj/item/pai_card/proc/download_candidate(mob/user, ckey)
- if(pai)
- return FALSE
- var/datum/pai_candidate/candidate = SSpai.candidates[ckey]
- if(!candidate?.check_ready())
- balloon_alert(user, "download interrupted")
- return FALSE
- var/mob/living/silicon/pai/new_pai = new(src)
- new_pai.name = candidate.name || pick(GLOB.ninja_names)
- new_pai.real_name = new_pai.name
- new_pai.key = candidate.ckey
- set_personality(new_pai)
- SSpai.candidates -= ckey
- return TRUE
-
-/**
- * Pings ghosts to announce that someone is requesting a pAI
- *
- * @param {mob} user - The user who is requesting a pAI
- *
- * @returns {boolean} - TRUE if the pAI was requested, FALSE if not
- */
-/obj/item/pai_card/proc/find_pai(mob/user)
- if(pai)
- return FALSE
- if(!(GLOB.ghost_role_flags & GHOSTROLE_SILICONS))
- balloon_alert(user, "unavailable: NT blacklisted")
- return FALSE
- if(request_spam)
- balloon_alert(user, "request sent too recently")
- return FALSE
- request_spam = TRUE
- playsound(src, 'sound/machines/ping.ogg', 20, TRUE)
- balloon_alert(user, "pAI assistance requested")
- var/mutable_appearance/alert_overlay = mutable_appearance('icons/obj/aicards.dmi', "pai")
- notify_ghosts("[user] is requesting a pAI companion! Use the pAI button to submit yourself as one.", source = user, alert_overlay = alert_overlay, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "pAI Request!", ignore_key = POLL_IGNORE_PAI)
- addtimer(VARSET_CALLBACK(src, request_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_CLIENT_TIME | TIMER_DELETE_ME)
- return TRUE
-
-/**
- * Gathers a list of candidates to display in the download candidate
- * window. If the candidate isn't marked ready, ie they have not
- * pressed submit, they will be skipped over.
- *
- * @returns - An array of candidate objects.
- */
-/obj/item/pai_card/proc/pool_candidates()
- var/list/candidates = list()
- if(pai || !length(SSpai?.candidates))
- return candidates
- for(var/key in SSpai.candidates)
- var/datum/pai_candidate/candidate = SSpai.candidates[key]
- if(!candidate?.check_ready())
- continue
- candidates += list(list(
- ckey = candidate.ckey,
- comments = candidate.comments,
- description = candidate.description,
- name = candidate.name,
- ))
- return candidates
-
-/**
- * Sets the personality on the current pai_card
- *
- * @param {silicon/pai} downloaded - The new pAI to load into the card.
- */
-/obj/item/pai_card/proc/set_personality(mob/living/silicon/pai/downloaded)
- if(pai)
- return FALSE
- pai = downloaded
- emotion_icon = "null"
- update_appearance(UPDATE_ICON)
- playsound(src, 'sound/effects/pai_boot.ogg', 50, TRUE, -1)
- audible_message("[src] plays a cheerful startup noise!")
- return TRUE
diff --git a/code/modules/pai/death.dm b/code/modules/pai/death.dm
deleted file mode 100644
index 2168f46796fb..000000000000
--- a/code/modules/pai/death.dm
+++ /dev/null
@@ -1,19 +0,0 @@
-/mob/living/silicon/pai/death(gibbed)
- if(stat == DEAD)
- return
- set_stat(DEAD)
- update_sight()
- clear_fullscreens()
- /**
- * New pAI's get a brand new mind to prevent meta stuff from their previous
- * life. This new mind causes problems down the line if it's not deleted here.
- */
- ghostize()
-
- if (!QDELETED(card) && loc != card)
- card.forceMove(drop_location())
- card.pai = null
- card.emotion_icon = initial(card.emotion_icon)
- card.update_appearance(UPDATE_ICON)
-
- qdel(src)
diff --git a/code/modules/pai/debug.dm b/code/modules/pai/debug.dm
deleted file mode 100644
index 63d6a8eb5020..000000000000
--- a/code/modules/pai/debug.dm
+++ /dev/null
@@ -1,45 +0,0 @@
-/client/proc/makepAI(turf/target in GLOB.mob_list)
- set category = "Admin.Fun"
- set name = "Make pAI"
- set desc = "Specify a location to spawn a pAI device, then specify a key to play that pAI"
-
- var/list/available = list()
- for(var/mob/player as anything in GLOB.player_list)
- if(player.client && player.key)
- available.Add(player)
- var/mob/choice = tgui_input_list(usr, "Choose a player to play the pAI", "Spawn pAI", available)
- if(isnull(choice))
- return
-
- var/chosen_name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text|null
- if (isnull(chosen_name))
- return
-
- if(!isobserver(choice))
- var/confirm = tgui_alert(usr, "[choice.key] isn't ghosting right now. Are you sure you want to yank them out of their body and place them in this pAI?", "Spawn pAI Confirmation", list("Yes", "No"))
- if(confirm != "Yes")
- return
- var/obj/item/pai_card/card = new(target)
- var/mob/living/silicon/pai/pai = new(card)
-
- pai.name = chosen_name
- pai.real_name = pai.name
- pai.key = choice.key
- card.set_personality(pai)
- if(SSpai.candidates[key])
- SSpai.candidates -= key
- SSblackbox.record_feedback("tally", "admin_verb", 1, "Make pAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/**
- * Creates a new pAI.
- *
- * @param {boolean} delete_old - If TRUE, deletes the old pAI.
- */
-/mob/proc/make_pai(delete_old)
- var/obj/item/pai_card/card = new(src)
- var/mob/living/silicon/pai/pai = new(card)
- pai.key = key
- pai.name = name
- card.set_personality(pai)
- if(delete_old)
- qdel(src)
diff --git a/code/modules/pai/defense.dm b/code/modules/pai/defense.dm
deleted file mode 100644
index cfe1211778ed..000000000000
--- a/code/modules/pai/defense.dm
+++ /dev/null
@@ -1,90 +0,0 @@
-/mob/living/silicon/pai/blob_act(obj/structure/blob/B)
- return FALSE
-
-/mob/living/silicon/pai/emp_act(severity)
- . = ..()
- if(. & EMP_PROTECT_SELF)
- return
- take_holo_damage(50 / severity)
- Stun(40 SECONDS / severity)
- if(holoform)
- fold_in(force = TRUE)
- //Need more effects that aren't instadeath or permanent law corruption.
- //Ask and you shall receive
- switch(rand(1, 3))
- if(1)
- stuttering = 1 MINUTES / severity
- to_chat(src, span_danger("Warning: Feedback loop detected in speech module."))
- if(2)
- slurring = INFINITY
- to_chat(src, span_danger("Warning: Audio synthesizer CPU stuck."))
- if(3)
- derpspeech = INFINITY
- to_chat(src, span_danger("Warning: Vocabulary databank corrupted."))
- if(prob(40))
- mind.language_holder.selected_language = get_random_spoken_language()
-
-
-/mob/living/silicon/pai/ex_act(severity, target)
- take_holo_damage(50 * severity)
- switch(severity)
- if(EXPLODE_DEVASTATE) //RIP
- qdel(card)
- qdel(src)
- if(EXPLODE_HEAVY)
- fold_in(force = 1)
- Paralyze(400)
- if(EXPLODE_LIGHT)
- fold_in(force = 1)
- Paralyze(200)
-
-/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user, list/modifiers)
- if(user.a_intent == INTENT_HELP)
- visible_message(span_notice("[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field."))
- return
- user.do_attack_animation(src)
- if(user.name != master_name)
- visible_message(span_danger("[user] stomps on [src]!."))
- take_holo_damage(2)
- return
- visible_message(span_notice("Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence."))
- if(!do_after(user, 1 SECONDS, src))
- return
- fold_in()
- if(user.put_in_hands(card))
- user.visible_message(span_notice("[user] promptly scoops up [user.p_their()] pAI's card."))
-
-/mob/living/silicon/pai/bullet_act(obj/projectile/Proj)
- if(Proj.stun)
- fold_in(force = TRUE)
- src.visible_message(span_warning("The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!"))
- . = ..(Proj)
-
-/mob/living/silicon/pai/ignite_mob(silent)
- return FALSE
-
-/mob/living/silicon/pai/proc/take_holo_damage(amount)
- holochassis_health = clamp((holochassis_health - amount), -50, HOLOCHASSIS_MAX_HEALTH)
- if(holochassis_health < 0)
- fold_in(force = TRUE)
- if(amount > 0)
- to_chat(src, span_userdanger("The impact degrades your holochassis!"))
- return amount
-
-/mob/living/silicon/pai/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_status)
- return take_holo_damage(amount)
-
-/mob/living/silicon/pai/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_status)
- return take_holo_damage(amount)
-
-/mob/living/silicon/pai/adjustStaminaLoss(amount, updating_stamina, forced = FALSE, required_status)
- if(forced)
- take_holo_damage(amount)
- else
- take_holo_damage(amount * 0.25)
-
-/mob/living/silicon/pai/getBruteLoss()
- return HOLOCHASSIS_MAX_HEALTH - holochassis_health
-
-/mob/living/silicon/pai/getFireLoss()
- return HOLOCHASSIS_MAX_HEALTH - holochassis_health
diff --git a/code/modules/pai/door_jack.dm b/code/modules/pai/door_jack.dm
deleted file mode 100644
index 75cf0fe9b442..000000000000
--- a/code/modules/pai/door_jack.dm
+++ /dev/null
@@ -1,129 +0,0 @@
-#define CABLE_LENGTH 2
-
-/**
- * Switch that handles door jack operations.
- *
- * @param {string} mode - The requested operation of the door jack.
- *
- * @returns {boolean} - TRUE if the door jack state was switched, FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/door_jack(mode)
- if(isnull(mode))
- return FALSE
- switch(mode)
- if(PAI_DOOR_JACK_CABLE)
- extend_cable()
- return TRUE
- if(PAI_DOOR_JACK_HACK)
- hack_door()
- return TRUE
- if(PAI_DOOR_JACK_CANCEL)
- QDEL_NULL(hacking_cable)
- visible_message(span_notice("The cable retracts into the pAI."))
- return TRUE
- return FALSE
-
-/**
- * #Extend cable supporting proc
- *
- * When doorjack is installed, allows the pAI to drop
- * a cable which is placed either on the floor or in
- * someone's hands based (on distance).
- *
- * @returns {boolean} - TRUE if the cable was dropped, FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/extend_cable()
- QDEL_NULL(hacking_cable) //clear any old cables
- hacking_cable = new
- var/mob/living/carbon/hacker = get_holder()
- if(iscarbon(hacker) && hacker.put_in_hands(hacking_cable)) //important to double check since get_holder can return non-null values that aren't carbons.
- hacker.visible_message(span_notice("A port on [src] opens to reveal a cable, which [hacker] quickly grabs."), span_notice("A port on [src] opens to reveal a cable, which you quickly grab."), span_hear("You hear the soft click of a plastic component and manage to catch the falling cable."))
- track_pai()
- track_thing(hacking_cable)
- return TRUE
- hacking_cable.forceMove(drop_location())
- hacking_cable.visible_message(message = span_notice("A port on [src] opens to reveal a cable, which promptly falls to the floor."), blind_message = span_hear("You hear the soft click of a plastic component fall to the ground."))
- track_pai()
- track_thing(hacking_cable)
- return TRUE
-
-/** Tracks the associated pai */
-/mob/living/silicon/pai/proc/track_pai()
- RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(handle_move))
- RegisterSignal(card, COMSIG_MOVABLE_MOVED, PROC_REF(handle_move))
-
-/** Untracks the associated pai */
-/mob/living/silicon/pai/proc/untrack_pai()
- UnregisterSignal(src, COMSIG_MOVABLE_MOVED)
- UnregisterSignal(card, COMSIG_MOVABLE_MOVED)
-
-/** Tracks the associated hacking_cable */
-/mob/living/silicon/pai/proc/track_thing(atom/movable/thing)
- RegisterSignal(thing, COMSIG_MOVABLE_MOVED, PROC_REF(handle_move))
- var/list/locations = get_nested_locs(thing, include_turf = FALSE)
- for(var/atom/movable/location in locations)
- RegisterSignal(location, COMSIG_MOVABLE_MOVED, PROC_REF(handle_move))
-
-/** Untracks the associated hacking */
-/mob/living/silicon/pai/proc/untrack_thing(atom/movable/thing)
- UnregisterSignal(thing, COMSIG_MOVABLE_MOVED)
- var/list/locations = get_nested_locs(thing, include_turf = FALSE)
- for(var/atom/movable/location in locations)
- UnregisterSignal(location, COMSIG_MOVABLE_MOVED)
-
-/**
- * A periodic check to see if the source pAI is nearby.
- * Deletes the extended cable if the source pAI is not nearby.
- */
-/mob/living/silicon/pai/proc/handle_move(atom/movable/source, atom/movable/old_loc)
- if(ismovable(old_loc))
- untrack_thing(old_loc)
- if(hacking_cable && (!IN_GIVEN_RANGE(src, hacking_cable, CABLE_LENGTH)))
- retract_cable()
- return
- if(ismovable(source.loc))
- track_thing(source.loc)
-
-/**
- * Handles deleting the hacking cable and notifying the user.
- */
-/mob/living/silicon/pai/proc/retract_cable()
- balloon_alert(src, "cable retracted")
- untrack_pai()
- QDEL_NULL(hacking_cable)
- return TRUE
-
-/**
- * #Door jacking supporting proc
- *
- * After a 15 second timer, the door will crack open,
- * provided they don't move out of the way.
- *
- * @returns {boolean} - TRUE if the door was jacked, FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/hack_door()
- if(!hacking_cable)
- return FALSE
- if(!hacking_cable.machine)
- balloon_alert(src, "nothing connected")
- return FALSE
- playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, TRUE)
- balloon_alert(src, "overriding...")
- // Now begin hacking
- if(!do_after(src, 15 SECONDS, hacking_cable.machine, timed_action_flags = NONE, progress = TRUE))
- balloon_alert(src, "failed! retracting...")
- untrack_pai()
- untrack_thing(hacking_cable)
- QDEL_NULL(hacking_cable)
- if(!QDELETED(card))
- card.update_appearance(UPDATE_ICON)
- return FALSE
- var/obj/machinery/door/door = hacking_cable.machine
- balloon_alert(src, "success")
- door.open()
- untrack_pai()
- untrack_thing(hacking_cable)
- QDEL_NULL(hacking_cable)
- return TRUE
-
-#undef CABLE_LENGTH
diff --git a/code/modules/pai/hud.dm b/code/modules/pai/hud.dm
deleted file mode 100644
index 3c53c96395a3..000000000000
--- a/code/modules/pai/hud.dm
+++ /dev/null
@@ -1,267 +0,0 @@
-#define PAI_MISSING_SOFTWARE_MESSAGE span_warning("You must download the required software to use this.")
-
-/atom/movable/screen/pai
- icon = 'icons/mob/screen_pai.dmi'
- var/required_software
-
-/atom/movable/screen/pai/Click()
- if(isobserver(usr) || usr.incapacitated())
- return FALSE
- var/mob/living/silicon/pai/user = usr
- if(required_software && !user.installed_software.Find(required_software))
- to_chat(user, PAI_MISSING_SOFTWARE_MESSAGE)
- return FALSE
- return TRUE
-
-/atom/movable/screen/pai/software
- name = "Software Interface"
- icon_state = "pai"
-
-/atom/movable/screen/pai/software/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.ui_interact(pAI)
-
-/atom/movable/screen/pai/shell
- name = "Toggle Holoform"
- icon_state = "pai_holoform"
-
-/atom/movable/screen/pai/shell/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- if(pAI.holoform)
- pAI.fold_in(0)
- else
- pAI.fold_out()
-
-/atom/movable/screen/pai/chassis
- name = "Holochassis Appearance Composite"
- icon_state = "pai_chassis"
-
-/atom/movable/screen/pai/chassis/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.choose_chassis()
-
-/atom/movable/screen/pai/rest
- name = "Rest"
- icon_state = "pai_rest"
-
-/atom/movable/screen/pai/rest/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- if(pAI.resting)
- pAI.set_resting(FALSE)
- else
- pAI.set_resting(TRUE)
-
-/atom/movable/screen/pai/light
- name = "Toggle Integrated Lights"
- icon_state = "light"
-
-/atom/movable/screen/pai/light/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.toggle_integrated_light()
-
-/atom/movable/screen/pai/newscaster
- name = "pAI Newscaster"
- icon_state = "newscaster"
- required_software = "Newscaster"
-
-/atom/movable/screen/pai/newscaster/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.newscaster.ui_interact(usr)
-
-/atom/movable/screen/pai/host_monitor
- name = "Host Health Scan"
- icon_state = "host_monitor"
- required_software = "Host Scan"
-
-/atom/movable/screen/pai/host_monitor/Click(location, control, params)
- . = ..()
- if(!.)
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.host_scan(PAI_SCAN_TARGET)
- return TRUE
-
-/atom/movable/screen/pai/crew_manifest
- name = "Crew Manifest"
- icon_state = "manifest"
- required_software = "Crew Manifest"
-
-/atom/movable/screen/pai/crew_manifest/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.ai_roster()
-
-/atom/movable/screen/pai/state_laws
- name = "State Laws"
- icon_state = "state_laws"
-
-/atom/movable/screen/pai/state_laws/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.checklaws()
-
-/atom/movable/screen/pai/modpc
- name = "Messenger"
- icon_state = "pda_send"
- required_software = "Digital Messenger"
- var/mob/living/silicon/pai/pAI
-
-/atom/movable/screen/pai/modpc/Click()
- . = ..()
- if(!.) // this works for some reason.
- return
- pAI.modularInterface?.interact(pAI)
-
-/atom/movable/screen/pai/internal_gps
- name = "Internal GPS"
- icon_state = "internal_gps"
- required_software = "Internal GPS"
-
-/atom/movable/screen/pai/internal_gps/Click()
- . = ..()
- if(!.)
- return
- var/mob/living/silicon/pai/pAI = usr
- if(!pAI.internal_gps)
- pAI.internal_gps = new(pAI)
- pAI.internal_gps.attack_self(pAI)
-
-/atom/movable/screen/pai/image_take
- name = "Take Image"
- icon_state = "take_picture"
- required_software = "Photography Module"
-
-/atom/movable/screen/pai/image_take/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.camera.toggle_camera_mode(usr)
-
-/atom/movable/screen/pai/image_view
- name = "View Images"
- icon_state = "view_images"
- required_software = "Photography Module"
-
-/atom/movable/screen/pai/image_view/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.camera.viewpictures(usr)
-
-/atom/movable/screen/pai/radio
- name = "radio"
- icon = 'icons/mob/screen_cyborg.dmi'
- icon_state = "radio"
-
-/atom/movable/screen/pai/radio/Click()
- if(!..())
- return
- var/mob/living/silicon/pai/pAI = usr
- pAI.radio.interact(usr)
-
-/datum/hud/pai/New(mob/living/silicon/pai/owner)
- ..()
- var/atom/movable/screen/using
- var/mob/living/silicon/pai/mypai = mymob
-
-// Software menu
- using = new /atom/movable/screen/pai/software(src)
- using.screen_loc = ui_pai_software
- static_inventory += using
-
-// Holoform
- using = new /atom/movable/screen/pai/shell(src)
- using.screen_loc = ui_pai_shell
- static_inventory += using
-
-// Chassis Select Menu
- using = new /atom/movable/screen/pai/chassis(src)
- using.screen_loc = ui_pai_chassis
- static_inventory += using
-
-// Rest
- using = new /atom/movable/screen/pai/rest(src)
- using.screen_loc = ui_pai_rest
- static_inventory += using
-
-// Integrated Light
- using = new /atom/movable/screen/pai/light(src)
- using.screen_loc = ui_pai_light
- static_inventory += using
-
-// Newscaster
- using = new /atom/movable/screen/pai/newscaster(src)
- using.screen_loc = ui_pai_newscaster
- static_inventory += using
-
-// Language menu
- using = new /atom/movable/screen/language_menu(src)
- using.screen_loc = ui_pai_language_menu
- static_inventory += using
-
-// Host Monitor
- using = new /atom/movable/screen/pai/host_monitor(src)
- using.screen_loc = ui_pai_host_monitor
- static_inventory += using
-
-// Crew Manifest
- using = new /atom/movable/screen/pai/crew_manifest(src)
- using.screen_loc = ui_pai_crew_manifest
- static_inventory += using
-
-// Laws
- using = new /atom/movable/screen/pai/state_laws(src)
- using.screen_loc = ui_pai_state_laws
- static_inventory += using
-
-// Modular Interface
- using = new /atom/movable/screen/pai/modpc(src)
- using.screen_loc = ui_pai_mod_int
- static_inventory += using
- mypai.pda_button = using
- var/atom/movable/screen/pai/modpc/tablet_button = using
- tablet_button.pAI = mypai
-
-// Internal GPS
- using = new /atom/movable/screen/pai/internal_gps(src)
- using.screen_loc = ui_pai_internal_gps
- static_inventory += using
-
-// Take image
- using = new /atom/movable/screen/pai/image_take(src)
- using.screen_loc = ui_pai_take_picture
- static_inventory += using
-
-// View images
- using = new /atom/movable/screen/pai/image_view(src)
- using.screen_loc = ui_pai_view_images
- static_inventory += using
-
-// Radio
- using = new /atom/movable/screen/pai/radio(src)
- using.screen_loc = ui_pai_radio
- static_inventory += using
-
- update_software_buttons()
-
-/datum/hud/pai/proc/update_software_buttons()
- var/mob/living/silicon/pai/owner = mymob
- for(var/atom/movable/screen/pai/button in static_inventory)
- if(button.required_software)
- button.color = owner.installed_software.Find(button.required_software) ? null : "#808080"
-
-#undef PAI_MISSING_SOFTWARE_MESSAGE
diff --git a/code/modules/pai/login.dm b/code/modules/pai/login.dm
deleted file mode 100644
index 0f418c4bf32b..000000000000
--- a/code/modules/pai/login.dm
+++ /dev/null
@@ -1,10 +0,0 @@
-/mob/living/silicon/pai/Login()
- . = ..()
- if(!. || !client)
- return FALSE
-
- client.perspective = EYE_PERSPECTIVE
- if(holoform)
- client.eye = src
- else
- client.eye = card
diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm
deleted file mode 100644
index 022802f46da2..000000000000
--- a/code/modules/pai/pai.dm
+++ /dev/null
@@ -1,412 +0,0 @@
-/mob/living/silicon/pai
- can_be_held = TRUE
- density = FALSE
- desc = "A generic pAI hard-light holographics emitter."
- health = 500
- held_lh = 'icons/mob/pai_item_lh.dmi'
- held_rh = 'icons/mob/pai_item_rh.dmi'
- held_icon = 'icons/mob/pai_item_head.dmi'
- hud_type = /datum/hud/pai
- icon = 'icons/mob/pai.dmi'
- icon_state = "repairbot"
- job = "Personal AI"
- layer = BELOW_MOB_LAYER
- light_color = COLOR_PAI_GREEN
- light_flags = LIGHT_ATTACHED
- light_on = FALSE
- light_range = 3
- light_system = MOVABLE_LIGHT
- maxHealth = 500
- mob_size = MOB_SIZE_TINY
- mobility_flags = MOBILITY_FLAGS_DEFAULT
- mouse_opacity = MOUSE_OPACITY_ICON
- move_force = 0
- move_resist = 0
- name = "pAI"
- pass_flags = PASSTABLE | PASSMOB
- pull_force = 0
- radio = /obj/item/radio/headset/silicon/pai
- worn_slot_flags = ITEM_SLOT_HEAD
-
- /// If someone has enabled/disabled the pAIs ability to holo
- var/can_holo = TRUE
- /// Whether this pAI can recieve radio messages
- var/can_receive = TRUE
- /// Whether this pAI can transmit radio messages
- var/can_transmit = TRUE
- /// The card we inhabit
- var/obj/item/pai_card/card
- /// The current chasis that will appear when in holoform
- var/chassis = "repairbot"
- /// Toggles whether the pAI can hold encryption keys or not
- var/encrypt_mod = FALSE
- /// The cable we produce when hacking a door
- var/obj/item/pai_cable/hacking_cable
- /// The current health of the holochassis
- var/holochassis_health = 20
- /// Holochassis available to use
- var/holochassis_ready = FALSE
- /// Whether we are currently holoformed
- var/holoform = FALSE
- /// Installed software on the pAI
- var/list/installed_software = list()
- /// Toggles whether universal translator has been activated. Cannot be reversed
- var/languages_granted = FALSE
- /// Reference of the bound master
- var/datum/weakref/master_ref
- /// The master's name string
- var/master_name
- /// DNA string for owner verification
- var/master_dna
- /// Toggles whether the Medical HUD is active or not
- var/medHUD = FALSE
- /// Used as currency to purchase different abilities
- var/ram = 100
- /// Toggles whether the Security HUD is active or not
- var/secHUD = FALSE
-
- // Onboard Items
- /// Atmospheric analyzer
- var/obj/item/analyzer/atmos_analyzer
- /// Health analyzer
- var/obj/item/healthanalyzer/host_scan
- /// GPS
- var/obj/item/gps/internal/internal_gps
- /// Music Synthesizer
- var/obj/item/instrument/piano_synth/instrument
- /// Newscaster
- var/obj/machinery/newscaster/pai/newscaster
- /// PDA
- var/atom/movable/screen/ai/modpc/pda_button
- /// Photography module
- var/obj/item/camera/siliconcam/pai_camera/camera
- /// Remote signaler
- var/obj/item/assembly/signaler/internal/signaler
-
- // Static lists
- /// List of all available downloads
- var/static/list/available_software = list(
- "Atmospheric Sensor" = 5,
- "Crew Manifest" = 5,
- "Digital Messenger" = 5,
- "Photography Module" = 5,
- "Encryption Slot" = 10,
- "Music Synthesizer" = 10,
- "Newscaster" = 10,
- "Remote Signaler" = 10,
- "Host Scan" = 20,
- "Medical HUD" = 20,
- "Security HUD" = 20,
- "Crew Monitor" = 35,
- "Door Jack" = 35,
- "Internal GPS" = 35,
- "Universal Translator" = 35,
- )
- /// List of all possible chasises. TRUE means the pAI can be picked up in this chasis.
- var/static/list/possible_chassis = list(
- "cat" = TRUE,
- "corgi" = FALSE,
- "fox" = FALSE,
- "monkey" = TRUE,
- "mouse" = TRUE,
- "rabbit" = TRUE,
- )
- /// List of all available card overlays.
- var/static/list/possible_overlays = list(
- "null",
- "angry",
- "cat",
- "extremely-happy",
- "face",
- "happy",
- "laugh",
- "off",
- "sad",
- "sunglasses",
- "what"
- )
-
-/mob/living/silicon/pai/add_sensors() //pAIs have to buy their HUDs
- return
-
-/mob/living/silicon/pai/can_interact_with(atom/target)
- if(target == signaler) // Bypass for signaler
- return TRUE
- if(target == modularInterface)
- return TRUE
- return ..()
-
-/mob/living/silicon/pai/Destroy()
- QDEL_NULL(atmos_analyzer)
- QDEL_NULL(camera)
- QDEL_NULL(hacking_cable)
- QDEL_NULL(host_scan)
- QDEL_NULL(instrument)
- QDEL_NULL(internal_gps)
- QDEL_NULL(newscaster)
- QDEL_NULL(signaler)
- card = null
- GLOB.pai_list.Remove(src)
- return ..()
-
-/mob/living/silicon/pai/emag_act(mob/user, obj/item/card/emag/emag_card)
- return handle_emag(user, emag_card)
-
-/mob/living/silicon/pai/examine(mob/user)
- . = ..()
- . += "Its master ID string seems to be [(!master_name || emagged) ? "empty" : master_name]."
-
-/mob/living/silicon/pai/get_status_tab_items()
- . += ..()
- if(!stat)
- . += text("Emitter Integrity: [holochassis_health * (100 / HOLOCHASSIS_MAX_HEALTH)].")
- else
- . += text("Systems nonfunctional.")
-
-/mob/living/silicon/pai/handle_atom_del(atom/deleting_atom)
- if(deleting_atom == hacking_cable)
- untrack_pai()
- untrack_thing(hacking_cable)
- hacking_cable = null
- SStgui.update_user_uis(src)
- if(!QDELETED(card))
- card.update_appearance(UPDATE_ICON)
- if(deleting_atom == atmos_analyzer)
- atmos_analyzer = null
- if(deleting_atom == camera)
- camera = null
- if(deleting_atom == host_scan)
- host_scan = null
- if(deleting_atom == internal_gps)
- internal_gps = null
- if(deleting_atom == instrument)
- instrument = null
- if(deleting_atom == newscaster)
- newscaster = null
- if(deleting_atom == signaler)
- signaler = null
- return ..()
-
-/mob/living/silicon/pai/Initialize(mapload)
- . = ..()
- START_PROCESSING(SSfastprocess, src)
- GLOB.pai_list += src
- make_laws()
- for(var/law in laws.inherent)
- lawcheck += law
- var/obj/item/pai_card/pai_card = loc
- if(!istype(pai_card)) // when manually spawning a pai, we create a card to put it into.
- var/newcardloc = pai_card
- pai_card = new(newcardloc)
- pai_card.set_personality(src)
- forceMove(pai_card)
- card = pai_card
- addtimer(VARSET_CALLBACK(src, holochassis_ready, TRUE), HOLOCHASSIS_INIT_TIME)
- if(!holoform)
- Immobilize(50 MINUTES)
- desc = "A pAI hard-light holographics emitter. This one appears in the form of a [chassis]."
-
- RegisterSignal(src, COMSIG_LIVING_CULT_SACRIFICED, PROC_REF(on_cult_sacrificed))
-
-/mob/living/silicon/pai/make_laws()
- laws = new /datum/ai_laws/pai()
- return TRUE
-
-/mob/living/silicon/pai/process(delta_time)
- holochassis_health = clamp((holochassis_health + (HOLOCHASSIS_REGEN_PER_SECOND * delta_time)), -50, HOLOCHASSIS_MAX_HEALTH)
-
-/mob/living/silicon/pai/Process_Spacemove(movement_dir = 0, continuous_move = FALSE)
- . = ..()
- if(!.)
- add_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK, update = TRUE, priority = 100, multiplicative_slowdown = 2)
- return TRUE
- remove_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK, TRUE)
- return TRUE
-
-/mob/living/silicon/pai/screwdriver_act(mob/living/user, obj/item/tool)
- return radio.screwdriver_act(user, tool)
-
-/mob/living/silicon/pai/updatehealth()
- if(status_flags & GODMODE)
- return
- set_health(maxHealth - getBruteLoss() - getFireLoss())
- update_stat()
- SEND_SIGNAL(src, COMSIG_LIVING_HEALTH_UPDATE)
-
-/**
- * Resolves the weakref of the pai's master.
- * If the master has been deleted, calls reset_software().
- *
- * @returns {mob/living || FALSE} - The master mob, or
- * FALSE if the master is gone.
- */
-/mob/living/silicon/pai/proc/find_master()
- if(!master_ref)
- return FALSE
- var/mob/living/resolved_master = master_ref?.resolve()
- if(!resolved_master)
- reset_software()
- return FALSE
- return resolved_master
-
-/**
- * Fixes weird speech issues with the pai.
- *
- * @returns {boolean} - TRUE if successful.
- */
-/mob/living/silicon/pai/proc/fix_speech()
- var/mob/living/silicon/pai = src
- balloon_alert(pai, "speech modulation corrected")
- stuttering = 0
- slurring = 0
- derpspeech = 0
-
- return TRUE
-
-/**
- * Gets the current holder of the pAI if its
- * being carried in card or holoform.
- *
- * @returns {living/carbon || FALSE} - The holder of the pAI,
- * or FALSE if the pAI is not being carried.
- */
-/mob/living/silicon/pai/proc/get_holder()
- var/mob/living/carbon/holder
- if(!holoform && iscarbon(card.loc))
- holder = card.loc
- if(holoform && ispickedupmob(loc) && iscarbon(loc.loc))
- holder = loc.loc
- if(!holder || !iscarbon(holder))
- return FALSE
- return holder
-
-/**
- * Handles the pai card or the pai itself being hit with an emag.
- * This replaces any current laws, masters, and DNA.
- *
- * @param {living/carbon} attacker - The user performing the action.
- * @returns {boolean} - TRUE if successful, FALSE if not.
- */
-/mob/living/silicon/pai/proc/handle_emag(mob/living/carbon/attacker, obj/item/card/emag/emag_card)
- if(!isliving(attacker))
- return FALSE
- balloon_alert(attacker, "directive override complete")
- balloon_alert(src, "directive override detected")
- log_game("[key_name(attacker)] emagged [key_name(src)], wiping their master DNA and supplemental directive.")
- emagged = TRUE
- master_ref = WEAKREF(attacker)
- master_name = "The Syndicate"
- master_dna = "Untraceable Signature"
- // Sets supplemental directive to this
- laws.supplied[1] = "Do not interfere with the operations of the Syndicate."
- return TRUE
-
-/**
- * Resets the pAI and any emagged status.
- *
- * @returns {boolean} - TRUE if successful, FALSE if not.
- */
-/mob/living/silicon/pai/proc/reset_software()
- emagged = FALSE
- if(!master_ref)
- return FALSE
- master_ref = null
- master_name = null
- master_dna = null
- add_supplied_law(0, "None.")
- balloon_alert(src, "software rebooted")
- return TRUE
-
-/**
- * Imprints your DNA onto the downloaded pAI
- *
- * @param {mob} user - The user performing the imprint.
- * @returns {boolean} - TRUE if successful, FALSE if not.
- */
-/mob/living/silicon/pai/proc/set_dna(mob/user)
- if(!iscarbon(user))
- balloon_alert(user, "incompatible DNA signature")
- balloon_alert(src, "incompatible DNA signature")
- return FALSE
- if(emagged)
- balloon_alert(user, "directive system malfunctional")
- return FALSE
- var/mob/living/carbon/master = user
- master_ref = WEAKREF(master)
- master_name = master.real_name
- master_dna = master.dna.unique_enzymes
- to_chat(src, span_boldannounce("You have been bound to a new master: [user.real_name]!"))
- holochassis_ready = TRUE
- return TRUE
-
-/**
- * Opens a tgui alert that allows someone to enter laws.
- *
- * @param {mob} user - The user performing the law change.
- * @returns {boolean} - TRUE if successful, FALSE if not.
- */
-/mob/living/silicon/pai/proc/set_laws(mob/user)
- if(!master_ref)
- balloon_alert(user, "access denied: no master")
- return FALSE
- var/new_laws = tgui_input_text(user, "Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", laws.supplied[1], 300)
- if(!new_laws || !master_ref)
- return FALSE
- add_supplied_law(0, new_laws)
- to_chat(src, span_notice(new_laws))
- return TRUE
-
-/**
- * Toggles the ability of the pai to enter holoform
- *
- * @returns {boolean} - TRUE if successful, FALSE if not.
- */
-/mob/living/silicon/pai/proc/toggle_holo()
- balloon_alert(src, "holomatrix [can_holo ? "disabled" : "enabled"]")
- can_holo = !can_holo
- return TRUE
-
-/**
- * Toggles the radio settings on and off.
- *
- * @param {string} option - The option being toggled.
- */
-/mob/living/silicon/pai/proc/toggle_radio(option)
- // it can't be both so if we know it's not transmitting it must be receiving.
- var/transmitting = option == "transmit"
- var/transmit_holder = (transmitting ? WIRE_TX : WIRE_RX)
- if(transmitting)
- can_transmit = !can_transmit
- else //receiving
- can_receive = !can_receive
- radio.wires.cut(transmit_holder)//wires.cut toggles cut and uncut states
- transmit_holder = (transmitting ? can_transmit : can_receive) //recycling can be fun!
- balloon_alert(src, "[transmitting ? "outgoing" : "incoming"] radio [transmit_holder ? "enabled" : "disabled"]")
- return TRUE
-
-/**
- * Wipes the current pAI on the card.
- *
- * @param {mob} user - The user performing the action.
- *
- * @returns {boolean} - TRUE if successful, FALSE if not.
- */
-/mob/living/silicon/pai/proc/wipe_pai(mob/user)
- if(tgui_alert(user, "Are you certain you wish to delete the current personality? This action cannot be undone.", "Personality Wipe", list("Yes", "No")) != "Yes")
- return FALSE
- to_chat(src, span_warning("You feel yourself slipping away from reality."))
- to_chat(src, span_danger("Byte by byte you lose your sense of self."))
- to_chat(src, span_userdanger("Your mental faculties leave you."))
- to_chat(src, span_rose("oblivion... "))
- balloon_alert(user, "personality wiped")
- playsound(src, "sound/machines/buzz-two.ogg", 30, TRUE)
- qdel(src)
- return TRUE
-
-/// Signal proc for [COMSIG_LIVING_CULT_SACRIFICED] to give a funny message when a pai is attempted to be sac'd
-/mob/living/silicon/pai/proc/on_cult_sacrificed(datum/source, list/invokers)
- SIGNAL_HANDLER
-
- for(var/mob/living/cultist as anything in invokers)
- to_chat(cultist, span_cultitalic("You don't think this is what Nar'Sie had in mind when She asked for blood sacrifices..."))
- return STOP_SACRIFICE
diff --git a/code/modules/pai/personality.dm b/code/modules/pai/personality.dm
deleted file mode 100644
index 92cf5747801f..000000000000
--- a/code/modules/pai/personality.dm
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * name
- * key
- * description
- * role
- * comments
- * ready = TRUE
- */
-
-/datum/pai_candidate/proc/savefile_path(mob/user)
- return "data/player_saves/[user.ckey[1]]/[user.ckey]/pai.sav"
-
-/datum/pai_candidate/proc/savefile_save(mob/user)
- if(is_guest_key(user.key))
- to_chat(usr, span_warning("You cannot save pAI information as a guest."))
- return FALSE
- var/savefile/F = new /savefile(src.savefile_path(user))
- WRITE_FILE(F["name"], name)
- WRITE_FILE(F["description"], description)
- WRITE_FILE(F["comments"], comments)
- WRITE_FILE(F["version"], 1)
- to_chat(usr, span_boldnotice("You have saved pAI information locally."))
- return TRUE
-
-// loads the savefile corresponding to the mob's ckey
-// if silent=true, report incompatible savefiles
-// returns TRUE if loaded (or file was incompatible)
-// returns FALSE if savefile did not exist
-
-/datum/pai_candidate/proc/savefile_load(mob/user, silent = TRUE)
- if (is_guest_key(user.key))
- return FALSE
-
- var/path = savefile_path(user)
-
- if (!fexists(path))
- return FALSE
-
- var/savefile/F = new /savefile(path)
-
- if(!F)
- return //Not everyone has a pai savefile.
-
- var/version = null
- F["version"] >> version
-
- if (isnull(version) || version != 1)
- fdel(path)
- if (!silent)
- tgui_alert(user, "Your savefile was incompatible with this version and was deleted.")
- return FALSE
-
- F["name"] >> src.name
- F["description"] >> src.description
- F["comments"] >> src.comments
- return TRUE
diff --git a/code/modules/pai/say.dm b/code/modules/pai/say.dm
deleted file mode 100644
index b35abfe7f9d8..000000000000
--- a/code/modules/pai/say.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/mob/living/silicon/pai/binarycheck()
- return radio?.translate_binary
diff --git a/code/modules/pai/shell.dm b/code/modules/pai/shell.dm
deleted file mode 100644
index 66e2e8bfb279..000000000000
--- a/code/modules/pai/shell.dm
+++ /dev/null
@@ -1,169 +0,0 @@
-/mob/living/silicon/pai/mob_try_pickup(mob/living/user, instant=FALSE)
- if(!possible_chassis[chassis])
- to_chat(user, span_warning("[src]'s current form isn't able to be carried!"))
- return FALSE
- return ..()
-
-/mob/living/silicon/pai/start_pulling(atom/movable/thing, state, force = move_force, supress_message = FALSE)
- return FALSE
-
-/mob/living/silicon/pai/update_resting()
- . = ..()
- if(resting)
- icon_state = "[chassis]_rest"
- else
- icon_state = "[chassis]"
- if(loc != card)
- visible_message(span_notice("[src] [resting? "lays down for a moment..." : "perks up from the ground."]"))
-
-/mob/living/silicon/pai/wabbajack_act(what_to_randomize, change_flags = WABBAJACK)
- if(length(possible_chassis) < 2)
- return FALSE
- var/holochassis = pick(possible_chassis - chassis)
- set_holochassis(holochassis)
- balloon_alert(src, "[holochassis] composite engaged")
- return TRUE
-
-/**
- * Checks if we are allowed to interact with a radial menu
- *
- * @param {atom} anchor - The atom that is anchoring the menu.
- *
- * @returns {boolean} - TRUE if we are allowed to interact with the menu,
- * FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/check_menu(atom/anchor)
- if(incapacitated())
- return FALSE
- if(get_turf(src) != get_turf(anchor))
- return FALSE
- if(!isturf(loc) && loc != card)
- balloon_alert(src, "can't do that here")
- return FALSE
- return TRUE
-
-/**
- * Sets a new holochassis skin based on a pAI's choice.
- *
- * @returns {boolean} - True if the skin was successfully set.
- * FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/choose_chassis()
- var/list/skins = list()
- for(var/holochassis_option in possible_chassis)
- var/image/item_image = image(icon = src.icon, icon_state = holochassis_option)
- skins += list("[holochassis_option]" = item_image)
- var/atom/anchor = get_atom_on_turf(src)
- var/choice = show_radial_menu(src, anchor, skins, custom_check = CALLBACK(src, PROC_REF(check_menu), anchor), radius = 40, require_near = TRUE)
- if(!choice)
- return FALSE
- set_holochassis(choice)
- balloon_alert(src, "[choice] composite engaged")
- update_resting()
- return TRUE
-
-/**
- * Returns the pAI to card mode.
- *
- * @param {boolean} force - If TRUE, the pAI will be forced to card mode.
- *
- * @returns {boolean} - TRUE if the pAI was forced to card mode.
- * FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/fold_in(force = FALSE)
- holochassis_ready = FALSE
- if(!force)
- addtimer(VARSET_CALLBACK(src, holochassis_ready, TRUE), HOLOCHASSIS_COOLDOWN)
- else
- addtimer(VARSET_CALLBACK(src, holochassis_ready, TRUE), HOLOCHASSIS_OVERLOAD_COOLDOWN)
- icon_state = "[chassis]"
- if(!holoform)
- . = fold_out(force)
- return FALSE
- visible_message(span_notice("[src] deactivates its holochassis emitter and folds back into a compact card!"))
- stop_pulling()
- if(ispickedupmob(loc))
- var/obj/item/clothing/mob_holder/mob_head = loc
- mob_head.release(display_messages = FALSE)
- if(client)
- client.perspective = EYE_PERSPECTIVE
- var/turf/target = drop_location()
- card.forceMove(target)
- forceMove(card)
- Immobilize(30 MINUTES)
- set_density(FALSE)
- set_light_on(FALSE)
- holoform = FALSE
- set_resting(resting)
- return TRUE
-
-/**
- * Engage holochassis form.
- *
- * @param {boolean} force - Force the form to engage.
- *
- * @returns {boolean} - TRUE if the form was successfully engaged.
- * FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/fold_out(force = FALSE)
- if(holochassis_health < 0)
- balloon_alert(src, "emitter repair incomplete")
- return FALSE
- if(!can_holo && !force)
- balloon_alert(src, "emitters are disabled")
- return FALSE
- if(holoform)
- . = fold_in(force)
- return
- if(!holochassis_ready)
- balloon_alert(src, "emitters recycling...")
- return FALSE
- holochassis_ready = FALSE
- addtimer(VARSET_CALLBACK(src, holochassis_ready, TRUE), HOLOCHASSIS_COOLDOWN)
- SetImmobilized(0)
- set_density(TRUE)
- if(istype(card.loc, /obj/item/modular_computer))
- var/obj/item/modular_computer/pc = card.loc
- pc.inserted_pai = null
- pc.visible_message(span_notice("[src] ejects itself from [pc]!"))
- if(isliving(card.loc))
- var/mob/living/living_holder = card.loc
- if(!living_holder.temporarilyRemoveItemFromInventory(card))
- balloon_alert(src, "unable to expand")
- return FALSE
- forceMove(get_turf(card))
- card.forceMove(src)
- if(client)
- client.perspective = EYE_PERSPECTIVE
- client.eye = src
- set_light_on(FALSE)
- icon_state = "[chassis]"
- held_state = "[chassis]"
- visible_message(span_boldnotice("[src] folds out its holochassis emitter and forms a holoshell around itself!"))
- holoform = TRUE
- return TRUE
-
-/**
- * Sets the holochassis skin and updates the icons
- *
- * @param {string} choice - The skin that will be used for the pAI holoform
- *
- * @returns {boolean} - TRUE if the skin was successfully set. FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/set_holochassis(choice)
- if(!choice)
- return FALSE
- chassis = choice
- icon_state = "[chassis]"
- held_state = "[chassis]"
- desc = "A pAI mobile hard-light holographics emitter. This one appears in the form of a [chassis]."
- return TRUE
-
-/**
- * Toggles the onboard light
- *
- * @returns {boolean} - TRUE if the light was toggled.
- */
-/mob/living/silicon/pai/proc/toggle_integrated_light()
- set_light_on(!light_on)
- return TRUE
diff --git a/code/modules/pai/software.dm b/code/modules/pai/software.dm
deleted file mode 100644
index 9fb5cf109e78..000000000000
--- a/code/modules/pai/software.dm
+++ /dev/null
@@ -1,242 +0,0 @@
-/mob/living/silicon/pai/ui_interact(mob/user, datum/tgui/ui)
- ui = SStgui.try_update_ui(user, src, ui)
- if(!ui)
- ui = new(user, src, "PaiInterface", name)
- ui.open()
- ui.set_autoupdate(FALSE)
-
-/mob/living/silicon/pai/ui_data(mob/user)
- var/list/data = list()
- data["door_jack"] = hacking_cable
- data["image"] = card.emotion_icon
- data["installed"] = installed_software
- data["ram"] = ram
- return data
-
-/mob/living/silicon/pai/ui_static_data(mob/user)
- var/list/data = list()
- data["available"] = available_software
- data["directives"] = laws.supplied
- data["emagged"] = emagged
- data["languages"] = languages_granted
- data["master_name"] = master_name
- data["master_dna"] = master_dna
- return data
-
-/mob/living/silicon/pai/ui_act(action, list/params, datum/tgui/ui)
- . = ..()
- if(.)
- return TRUE
- if(action == "buy")
- buy_software(params["selection"])
- return TRUE
- if(action == "change image")
- change_image()
- return TRUE
- if(action == "check dna")
- check_dna()
- return TRUE
- // Software related ui actions
- if(available_software[action] && !installed_software.Find(action))
- balloon_alert(usr, "software unavailable")
- return FALSE
- switch(action)
- if("Atmospheric Sensor")
- atmos_analyzer.attack_self(src)
- return TRUE
- if("Crew Manifest")
- ai_roster()
- return TRUE
- if("Crew Monitor")
- GLOB.crewmonitor.show(usr, src)
- return TRUE
- if("Digital Messenger")
- modularInterface?.interact(usr)
- return TRUE
- if("Door Jack")
- // Look to door_jack.dm for implementation
- door_jack(params["mode"])
- return TRUE
- if("Encryption Slot")
- balloon_alert(usr, "radio frequencies [!encrypt_mod ? "enabled" : "disabled"]")
- encrypt_mod = !encrypt_mod
- radio.subspace_transmission = !radio.subspace_transmission
- return TRUE
- if("Host Scan")
- host_scan(params["mode"])
- return TRUE
- if("Internal GPS")
- internal_gps.attack_self(src)
- return TRUE
- if("Music Synthesizer")
- instrument.interact(src)
- return TRUE
- if("Medical HUD")
- toggle_hud(PAI_TOGGLE_MEDICAL_HUD)
- return TRUE
- if("Newscaster")
- newscaster.ui_interact(src)
- return TRUE
- if("Photography Module")
- // Look to pai_camera.dm for implementation
- use_camera(usr, params["mode"])
- return TRUE
- if("Remote Signaler")
- signaler.ui_interact(src)
- return TRUE
- if("Security HUD")
- toggle_hud(PAI_TOGGLE_SECURITY_HUD)
- return TRUE
- if("Universal Translator")
- grant_languages()
- ui.send_full_update()
- return TRUE
- return FALSE
-
-/**
- * Purchases the selected software from the list and deducts their
- * available ram.
- *
- * @param {string} selection - The software to purchase.
- *
- * @returns {boolean} - TRUE if the software was purchased, FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/buy_software(selection)
- if(!available_software[selection] || installed_software.Find(selection))
- return FALSE
- var/cost = available_software[selection]
- if(ram < cost)
- return FALSE
- installed_software.Add(selection)
- ram -= cost
- var/datum/hud/pai/pAIhud = hud_used
- pAIhud?.update_software_buttons()
- switch(selection)
- if("Atmospheric Sensor")
- atmos_analyzer = new(src)
- if("Digital Messenger")
- create_modularInterface()
- if("Host Scan")
- host_scan = new(src)
- if("Internal GPS")
- internal_gps = new(src)
- if("Music Synthesizer")
- instrument = new(src)
- if("Newscaster")
- newscaster = new(src)
- if("Photography Module")
- camera = new(src)
- if("Remote Signaler")
- signaler = new(src)
- return TRUE
-
-/**
- * Changes the image displayed on the pAI.
- *
- * @param {mob} user - The user who is changing the image.
- *
- * @returns {boolean} - TRUE if the image was changed, FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/change_image()
- var/new_image = tgui_input_list(src, "Select your new display image", "Display Image", possible_overlays)
- if(isnull(new_image))
- return FALSE
- card.emotion_icon = new_image
- card.update_appearance(UPDATE_ICON)
- return TRUE
-
-/**
- * Supporting proc for the pAI to prick it's master's hand
- * or... whatever. It must be held in order to work
- * Gives the owner a popup if they want to get the jab.
- *
- * @returns {boolean} - TRUE if a sample was taken, FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/check_dna()
- if(emagged) // Their master DNA signature is scrambled anyway
- to_chat(src, span_syndradio("You are not at liberty to do this! All agents are clandestine."))
- return FALSE
- var/mob/living/carbon/holder = get_holder()
- if(!iscarbon(holder))
- balloon_alert(src, "not being carried")
- return FALSE
- balloon_alert(src, "requesting dna sample")
- if(tgui_alert(holder, "[src] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "Checking DNA", list("Yes", "No")) != "Yes")
- balloon_alert(src, "dna sample refused!")
- return FALSE
- holder.visible_message(span_notice("[holder] presses [holder.p_their()] thumb against [src]."), span_notice("You press your thumb against [src]."), span_notice("[src] makes a sharp clicking sound as it extracts DNA material from [holder]."))
- if(!holder.has_dna())
- balloon_alert(src, "no dna detected!")
- return FALSE
- to_chat(src, span_boldannounce(("[holder]'s UE string: [holder.dna.unique_enzymes]")))
- to_chat(src, span_notice("DNA [holder.dna.unique_enzymes == master_dna ? "matches" : "does not match"] our stored Master's DNA."))
- return TRUE
-
-/**
- * Grant all languages to the current pAI.
- *
- * @returns {boolean} - TRUE if the languages were granted, FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/grant_languages()
- if(languages_granted)
- return FALSE
- grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE)
- languages_granted = TRUE
- return TRUE
-
-/**
- * Host scan supporting proc
- *
- * Allows the pAI to scan its host's health vitals
- * using an integrated health analyzer.
- *
- * @returns {boolean} - TRUE if the scan was successful, FALSE otherwise.
- */
-/mob/living/silicon/pai/proc/host_scan(mode)
- if(isnull(mode))
- return FALSE
- if(mode == PAI_SCAN_TARGET)
- var/mob/living/target = get_holder()
- if(!target || !isliving(target))
- balloon_alert(src, "not being carried")
- return FALSE
- host_scan.attack(target, src)
- return TRUE
- if(mode == PAI_SCAN_MASTER)
- if(!master_ref)
- balloon_alert(src, "no master detected")
- return FALSE
- var/mob/living/resolved_master = find_master()
- if(!resolved_master)
- balloon_alert(src, "cannot locate master")
- return FALSE
- if(!is_valid_z_level(get_turf(src), get_turf(resolved_master)))
- balloon_alert(src, "master out of range")
- return FALSE
- host_scan.attack(resolved_master, src)
- return TRUE
- return FALSE
-
-/**
- * Proc that toggles any active huds based on the option.
- *
- * @param {string} mode - The hud to toggle.
- */
-/mob/living/silicon/pai/proc/toggle_hud(mode)
- if(isnull(mode))
- return FALSE
- var/datum/atom_hud/hud
- var/hud_on
- if(mode == PAI_TOGGLE_MEDICAL_HUD)
- hud = GLOB.huds[med_hud]
- medHUD = !medHUD
- hud_on = medHUD
- if(mode == PAI_TOGGLE_SECURITY_HUD)
- hud = GLOB.huds[sec_hud]
- secHUD = !secHUD
- hud_on = secHUD
- if(hud_on)
- hud.show_to(src)
- else
- hud.hide_from(src)
- return TRUE
diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm
index 27bb868f2371..5b25b248cab8 100644
--- a/code/modules/photography/camera/camera.dm
+++ b/code/modules/photography/camera/camera.dm
@@ -154,7 +154,7 @@
if(on) // EMP will only work on cameras that are on as it has power going through it
icon_state = state_off
on = FALSE
- addtimer(CALLBACK(src, PROC_REF(emp_after)), (600/severity))
+ addtimer(CALLBACK(src, PROC_REF(emp_after)), (6*severity) SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
/obj/item/camera/proc/emp_after()
on = TRUE
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index e2fcb0d0fea9..215bfb7fab95 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -1466,7 +1466,7 @@
environ = 0
update_appearance(UPDATE_ICON)
update()
- addtimer(CALLBACK(src, PROC_REF(reset), APC_RESET_EMP), 600)
+ addtimer(CALLBACK(src, PROC_REF(reset), APC_RESET_EMP), (6 * severity) SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
/obj/machinery/power/apc/blob_act(obj/structure/blob/B)
set_broken()
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 6ca8fac3e3e7..d042bbba6020 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -179,7 +179,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- charge -= max((charge * 0.1), 500) / severity
+ charge -= max((charge * severity / 100), 50 * severity)
if (charge < 0)
charge = 0
@@ -392,7 +392,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- charge = clamp((charge-(10000/severity)),0,maxcharge)
+ charge = clamp((charge-(1000 * severity)),0,maxcharge)
/obj/item/stock_parts/cell/emergency_light
name = "miniature power cell"
diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm
index 5fdb7e9646cf..43f7e4347f63 100644
--- a/code/modules/power/generator.dm
+++ b/code/modules/power/generator.dm
@@ -21,14 +21,16 @@
. = ..()
find_circs()
connect_to_network()
- SSair.atmos_machinery += src
+ SSair_machinery.start_processing_machine(src)
+ START_PROCESSING(SSmachines, src)
update_appearance(UPDATE_ICON)
component_parts = list(new /obj/item/circuitboard/machine/generator)
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
/obj/machinery/power/generator/Destroy()
kill_circs()
- SSair.atmos_machinery -= src
+ SSair_machinery.stop_processing_machine(src)
+ STOP_PROCESSING(SSmachines, src)
return ..()
/obj/machinery/power/generator/update_icon_state()
@@ -120,7 +122,8 @@
lastgenlev = power_output
lastgen -= power_output
lastgen = max(lastgen, 0)
- ..()
+ update_icon()
+ src.updateDialog()
/obj/machinery/power/generator/proc/get_menu(include_link = TRUE)
var/t = ""
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 7c9f48b664a3..ede43e165e3c 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -9,8 +9,8 @@
#define LIGHT_BROKEN 2
#define LIGHT_BURNED 3
-#define BROKEN_SPARKS_MIN (30 SECONDS)
-#define BROKEN_SPARKS_MAX (90 SECONDS)
+#define BROKEN_SPARKS_MIN (3 MINUTES)
+#define BROKEN_SPARKS_MAX (9 MINUTES)
#define LIGHT_ON_DELAY_UPPER 3 SECONDS
#define LIGHT_ON_DELAY_LOWER 1 SECONDS
@@ -488,7 +488,7 @@
update()
/obj/machinery/light/proc/broken_sparks(start_only=FALSE)
- if(status == LIGHT_BROKEN && has_power() && Master.current_runlevel)
+ if(!QDELETED(src) && status == LIGHT_BROKEN && has_power() && Master.current_runlevel)
if(!start_only)
do_sparks(3, TRUE, src)
var/delay = rand(BROKEN_SPARKS_MIN, BROKEN_SPARKS_MAX)
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index 4ccc468325e5..91ba0b8c813f 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -343,8 +343,9 @@
//source is an object caused electrocuting (airlock, grille, etc)
//siemens_coeff - layman's terms, conductivity
//dist_check - set to only shock mobs within 1 of source (vendors, airlocks, etc.)
+//zone_override - allows checking a specific body part for shock protection instead of the hands
//No animations will be performed by this proc.
-/proc/electrocute_mob(mob/living/carbon/victim, power_source, obj/source, siemens_coeff = 1, dist_check = FALSE)
+/proc/electrocute_mob(mob/living/carbon/victim, power_source, obj/source, siemens_coeff = 1, dist_check = FALSE, zone = BODY_ZONE_R_ARM)
if(!istype(victim) || ismecha(victim.loc))
return FALSE //feckin mechs are dumb
@@ -352,7 +353,7 @@
if(!in_range(source, victim))
return FALSE
- if(victim.wearing_shock_proof_gloves())
+ if(victim.getarmor(zone, ELECTRIC) >= 100)
SEND_SIGNAL(victim, COMSIG_LIVING_SHOCK_PREVENTED, power_source, source, siemens_coeff, dist_check)
var/obj/item/clothing/gloves/G = victim.gloves
if(istype(G, /obj/item/clothing/gloves/color/fyellow))
diff --git a/code/modules/power/reactor/reactor.dm b/code/modules/power/reactor/reactor.dm
index 5874490f5f25..e0a8597112e2 100644
--- a/code/modules/power/reactor/reactor.dm
+++ b/code/modules/power/reactor/reactor.dm
@@ -307,14 +307,14 @@
if(active && moderator_input.total_moles() >= minimum_coolant_level)
// Fuel types: increases power and K
var/total_fuel_moles = 0
- total_fuel_moles += moderator_input.get_moles(/datum/gas/plasma) * PLASMA_FUEL_POWER
- total_fuel_moles += moderator_input.get_moles(/datum/gas/tritium) * TRITIUM_FUEL_POWER
- total_fuel_moles += moderator_input.get_moles(/datum/gas/antinoblium) * ANTINOBLIUM_FUEL_POWER
+ total_fuel_moles += moderator_input.get_moles(GAS_PLASMA) * PLASMA_FUEL_POWER
+ total_fuel_moles += moderator_input.get_moles(GAS_TRITIUM) * TRITIUM_FUEL_POWER
+ total_fuel_moles += moderator_input.get_moles(GAS_ANTINOB) * ANTINOBLIUM_FUEL_POWER
// Power modifier types: increases fuel effectiveness
var/power_mod_moles = 0
- power_mod_moles += moderator_input.get_moles(/datum/gas/oxygen) * OXYGEN_POWER_MOD
- power_mod_moles += moderator_input.get_moles(/datum/gas/hydrogen) * HYDROGEN_POWER_MOD
+ power_mod_moles += moderator_input.get_moles(GAS_O2) * OXYGEN_POWER_MOD
+ power_mod_moles += moderator_input.get_moles(GAS_H2) * HYDROGEN_POWER_MOD
// Now make some actual power!
if(total_fuel_moles >= minimum_coolant_level) //You at least need SOME fuel.
@@ -322,39 +322,39 @@
var/power_modifier = max(power_mod_moles * 10 / moderator_input.total_moles(), 1) //You can never have negative IPM. For now.
power_produced = max(0,((fuel_power*power_modifier)*moderator_input.total_moles())) / delta_time
if(active)
- coolant_output.adjust_moles(/datum/gas/pluonium, total_fuel_moles/20) //Shove out pluonium into the air when it's fuelled. You need to filter this off, or you're gonna have a bad time.
+ coolant_output.adjust_moles(GAS_PLUONIUM, total_fuel_moles/20) //Shove out pluonium into the air when it's fuelled. You need to filter this off, or you're gonna have a bad time.
// Control types: increases control of K
var/total_control_moles = 0
- total_control_moles += moderator_input.get_moles(/datum/gas/nitrogen) * NITROGEN_CONTROL_MOD
- total_control_moles += moderator_input.get_moles(/datum/gas/carbon_dioxide) * CARBON_CONTROL_MOD
- total_control_moles += moderator_input.get_moles(/datum/gas/pluoxium) * PLUOXIUM_CONTROL_MOD
+ total_control_moles += moderator_input.get_moles(GAS_N2) * NITROGEN_CONTROL_MOD
+ total_control_moles += moderator_input.get_moles(GAS_CO2) * CARBON_CONTROL_MOD
+ total_control_moles += moderator_input.get_moles(GAS_PLUOXIUM) * PLUOXIUM_CONTROL_MOD
if(total_control_moles >= minimum_coolant_level)
var/control_bonus = total_control_moles / REACTOR_CONTROL_FACTOR //1 mol of n2 -> 0.002 bonus control rod effectiveness, if you want a super controlled reaction, you'll have to sacrifice some power.
control_rod_effectiveness = initial(control_rod_effectiveness) + control_bonus
// Permeability types: increases cooling efficiency
var/total_permeability_moles = 0
- total_permeability_moles += moderator_input.get_moles(/datum/gas/bz) * BZ_PERMEABILITY_MOD
- total_permeability_moles += moderator_input.get_moles(/datum/gas/water_vapor) * WATER_PERMEABILITY_MOD
- total_permeability_moles += moderator_input.get_moles(/datum/gas/hypernoblium) * NOBLIUM_PERMEABILITY_MOD
+ total_permeability_moles += moderator_input.get_moles(GAS_BZ) * BZ_PERMEABILITY_MOD
+ total_permeability_moles += moderator_input.get_moles(GAS_H2O) * WATER_PERMEABILITY_MOD
+ total_permeability_moles += moderator_input.get_moles(GAS_HYPERNOB) * NOBLIUM_PERMEABILITY_MOD
if(total_permeability_moles >= minimum_coolant_level)
gas_absorption_effectiveness = clamp(gas_absorption_constant + (total_permeability_moles / REACTOR_PERMEABILITY_FACTOR), 0, 1)
// Radiation types: increases radiation
- radioactivity_spice_multiplier += moderator_input.get_moles(/datum/gas/nitrogen) * NITROGEN_RAD_MOD //An example setup of 50 moles of n2 (for dealing with spent fuel) leaves us with a radioactivity spice multiplier of 3.
- radioactivity_spice_multiplier += moderator_input.get_moles(/datum/gas/carbon_dioxide) * CARBON_RAD_MOD
- radioactivity_spice_multiplier += moderator_input.get_moles(/datum/gas/hydrogen) * HYDROGEN_RAD_MOD
- radioactivity_spice_multiplier += moderator_input.get_moles(/datum/gas/tritium) * TRITIUM_RAD_MOD
- radioactivity_spice_multiplier += moderator_input.get_moles(/datum/gas/antinoblium) * ANTINOBLIUM_RAD_MOD
+ radioactivity_spice_multiplier += moderator_input.get_moles(GAS_N2) * NITROGEN_RAD_MOD //An example setup of 50 moles of n2 (for dealing with spent fuel) leaves us with a radioactivity spice multiplier of 3.
+ radioactivity_spice_multiplier += moderator_input.get_moles(GAS_CO2) * CARBON_RAD_MOD
+ radioactivity_spice_multiplier += moderator_input.get_moles(GAS_H2) * HYDROGEN_RAD_MOD
+ radioactivity_spice_multiplier += moderator_input.get_moles(GAS_TRITIUM) * TRITIUM_RAD_MOD
+ radioactivity_spice_multiplier += moderator_input.get_moles(GAS_ANTINOB) * ANTINOBLIUM_RAD_MOD
// Integrity modification
- var/healium_moles = moderator_input.get_moles(/datum/gas/healium)
+ var/healium_moles = moderator_input.get_moles(GAS_HEALIUM)
if(healium_moles > minimum_coolant_level)
integrity_restoration = max((2400-max(TCMB, temperature))/300) * delta_time //At 1800K integrity_restoration should be around 1, which then it cant keep up with the heat damage (around 1.1 maximum in temp_damage) to restore integrity
// Degradation types: degrades the fuel rods
- var/total_degradation_moles = moderator_input.get_moles(/datum/gas/pluonium) //Because it's quite hard to get.
+ var/total_degradation_moles = moderator_input.get_moles(GAS_PLUONIUM) //Because it's quite hard to get.
if(total_degradation_moles >= minimum_coolant_level) //I'll be nice.
depletion_modifier += total_degradation_moles / 15 //Oops! All depletion. This causes your fuel rods to get SPICY.
if(prob(total_degradation_moles)) // don't spam the sound so much please
@@ -568,7 +568,7 @@
//Results: Engineering becomes unusable and your engine irreparable
/obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/meltdown()
set waitfor = FALSE
- SSair.atmos_machinery -= src //Annd we're now just a useless brick.
+ SSair_machinery.stop_processing_machine(src)
vessel_integrity = null // this makes it show up weird on the monitor to even further emphasize something's gone horribly wrong
slagged = TRUE
color = null
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 9110802e69de..10bd9e90bbe5 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -36,9 +36,9 @@
/// What is it producing
var/mode = POWER
/// What gasses are we using
- var/list/using = list(/datum/gas/plasma)
+ var/list/using = list(GAS_PLASMA)
/// Gasses we give
- var/list/giving = list(/datum/gas/tritium = 1)
+ var/list/giving = list(GAS_TRITIUM = 1)
/// Last output used to calculate per minute
var/last_output = 0
// Higher machine tier will give more power
@@ -118,11 +118,7 @@
toggle_power()
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
span_notice("You turn the [src.name] [active? "on":"off"]."))
- //yogs start -- fixes runtime with empty rad collectors
- var/fuel = 0
- if(loaded_tank)
- fuel = loaded_tank.air_contents.get_moles(/datum/gas/plasma)
- //yogs end
+ var/fuel = loaded_tank?.air_contents?.get_moles(GAS_PLASMA)
investigate_log("turned [active?"on ":"off "] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"It is empty "].", INVESTIGATE_SINGULO)
investigate_log("turned [active?"on ":"off "] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"It is empty "].", INVESTIGATE_SUPERMATTER) // yogs - so supermatter investigate is useful
return
@@ -234,23 +230,23 @@
to_chat(user, "[src] isn't connected to a powernet! ")
return
mode = POWER
- using = list(/datum/gas/plasma)
- giving = list(/datum/gas/tritium = 1)
+ using = list(GAS_PLASMA)
+ giving = list(GAS_TRITIUM = 1)
if(SCIENCE)
if(!is_station_level(z) && !SSresearch.science_tech)
to_chat(user, "[src] isn't linked to a research system! ")
return // Dont switch over
mode = SCIENCE
- using = list(/datum/gas/tritium, /datum/gas/oxygen)
- giving = list(/datum/gas/carbon_dioxide = 2) // Conservation of mass
+ using = list(GAS_TRITIUM, GAS_O2)
+ giving = list(GAS_CO2 = 2) // Conservation of mass
if(MONEY)
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(!D)
to_chat(user, "[src] couldn't find the cargo budget! ")
return // Dont switch over
mode = MONEY
- using = list(/datum/gas/plasma)
- giving = list(/datum/gas/tritium = 0.5) // money
+ using = list(GAS_PLASMA)
+ giving = list(GAS_TRITIUM = 0.5) // money
to_chat(user, "You set the [src] mode to [mode] production. ")
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 25cfc4cdd859..2fb1abeaadbf 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -52,6 +52,7 @@
/obj/machinery/power/emitter/anchored
anchored = TRUE
+ state = EMITTER_WRENCHED
/obj/machinery/power/emitter/ctf
name = "Energy Cannon"
@@ -77,6 +78,10 @@
ADD_TRAIT(src, TRAIT_EMPPROOF_CONTENTS, "innate_empproof")
AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS, null, CALLBACK(src, PROC_REF(can_be_rotated)))
+/obj/machinery/power/emitter/on_construction()
+ if(anchored && state == EMITTER_UNWRENCHED)
+ state = EMITTER_WRENCHED
+
/obj/machinery/power/emitter/RefreshParts()
var/max_reload = initial(maximum_reload_time) + 20
var/min_reload = initial(minimum_reload_time) + 4
@@ -437,10 +442,10 @@
if(!tank || !tank.air_contents)
return
var/datum/gas_mixture/fuel = tank.air_contents
- if(fuel.get_moles(/datum/gas/tritium) < fuel_consumption)
+ if(fuel.get_moles(GAS_TRITIUM) < fuel_consumption)
return
- fuel.adjust_moles(/datum/gas/tritium, -fuel_consumption)
- fuel.adjust_moles(/datum/gas/hydrogen, fuel_consumption)
+ fuel.adjust_moles(GAS_TRITIUM, -fuel_consumption)
+ fuel.adjust_moles(GAS_H2, fuel_consumption)
if(obj_flags & EMAGGED) // radioactive if emagged
radiation_pulse(get_turf(src), fuel_consumption * FIRE_HYDROGEN_ENERGY_RELEASED / TRITIUM_BURN_RADIOACTIVITY_FACTOR)
return ..()
@@ -461,7 +466,7 @@
/obj/machinery/power/emitter/particle/update_icon_state()
. = ..()
if(active)
- icon_state = (tank?.air_contents?.get_moles(/datum/gas/tritium) >= fuel_consumption) ? icon_state_on : icon_state_underpowered
+ icon_state = (tank?.air_contents?.get_moles(GAS_TRITIUM) >= fuel_consumption) ? icon_state_on : icon_state_underpowered
else
icon_state = initial(icon_state)
diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm
index 3689d4eb9d73..3d45e0554f19 100644
--- a/code/modules/power/singularity/singularity.dm
+++ b/code/modules/power/singularity/singularity.dm
@@ -583,7 +583,7 @@
/obj/singularity/proc/emp_area()
- empulse(src, 8, 10)
+ empulse(src, EMP_HEAVY)
return
/obj/singularity/singularity_act()
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index ba8c60ddc4ee..c17a460347bb 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -417,7 +417,7 @@
outputting = output_attempt
output_level = rand(0, output_level_max)
input_level = rand(0, input_level_max)
- charge = max(charge - 1e6/severity, 0)
+ charge = max(charge - (1e5 * severity), 0)
update_appearance(UPDATE_ICON)
log_smes()
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 3e658011ab0e..93e02b451c90 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -20,7 +20,7 @@
#define H2O_HEAT_PENALTY 12 //This'll get made slowly over time, I want my spice rock spicy god damnit
#define ANTINOB_HEAT_PENALTY 15
-/// Higher == Bigger bonus to power generation.
+/// Higher == Bigger bonus to power generation.
/// All of these get divided by 10-bzcomp * 5 before having 1 added and being multiplied with power to determine rads
#define OXYGEN_TRANSMIT_MODIFIER 1.5
#define PLASMA_TRANSMIT_MODIFIER 4
@@ -36,7 +36,7 @@
/// How much extra radioactivity to emit
#define BZ_RADIOACTIVITY_MODIFIER 5 // Up to 500% rads
-#define TRITIUM_RADIOACTIVITY_MODIFIER 3
+#define TRITIUM_RADIOACTIVITY_MODIFIER 3
#define PLUOXIUM_RADIOACTIVITY_MODIFIER -2
/// Higher == Gas makes the crystal more resistant against heat damage.
@@ -130,7 +130,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
/// How much force the SM expldoes with
var/explosion_power = 35
-
+
/// Factor for power generation. AirTemp*(temp_factor/(0C))
var/temp_factor = 30
var/power = 0
@@ -222,7 +222,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
/obj/machinery/power/supermatter_crystal/Initialize(mapload)
. = ..()
uid = gl_uid++
- SSair.atmos_machinery += src
+ SSair_machinery.start_processing_machine(src)
countdown = new(src)
countdown.start()
GLOB.poi_list |= src
@@ -238,7 +238,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
/obj/machinery/power/supermatter_crystal/Destroy()
investigate_log("has been destroyed.", INVESTIGATE_SUPERMATTER)
- SSair.atmos_machinery -= src
+ SSair_machinery.stop_processing_machine(src)
QDEL_NULL(radio)
GLOB.poi_list -= src
QDEL_NULL(countdown)
@@ -456,40 +456,40 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
// Calculate the gas mix ratio
combined_gas = max(removed.total_moles(), 0)
- var/plasmacomp = max(removed.get_moles(/datum/gas/plasma)/combined_gas, 0)
- var/o2comp = max(removed.get_moles(/datum/gas/oxygen)/combined_gas, 0)
- var/co2comp = max(removed.get_moles(/datum/gas/carbon_dioxide)/combined_gas, 0)
- var/n2ocomp = max(removed.get_moles(/datum/gas/nitrous_oxide)/combined_gas, 0)
- var/n2comp = max(removed.get_moles(/datum/gas/nitrogen)/combined_gas, 0)
- var/pluoxiumcomp = max(removed.get_moles(/datum/gas/pluoxium)/combined_gas, 0)
- var/tritiumcomp = max(removed.get_moles(/datum/gas/tritium)/combined_gas, 0)
- var/h2comp = max(removed.get_moles(/datum/gas/hydrogen)/combined_gas, 0)
- var/h2ocomp = max(removed.get_moles(/datum/gas/water_vapor)/combined_gas, 0)
- var/bzcomp = max(removed.get_moles(/datum/gas/bz)/combined_gas, 0)
- var/pluoniumcomp = max(removed.get_moles(/datum/gas/pluonium)/combined_gas, 0)
- var/healcomp = max(removed.get_moles(/datum/gas/healium)/combined_gas, 0)
- var/zaukcomp = max(removed.get_moles(/datum/gas/zauker)/combined_gas, 0)
- var/haloncomp = max(removed.get_moles(/datum/gas/halon)/combined_gas, 0)
- var/nobliumcomp = max(removed.get_moles(/datum/gas/hypernoblium)/combined_gas, 0)
- var/antinobliumcomp = max(removed.get_moles(/datum/gas/antinoblium)/combined_gas, 0)
- var/nitriumcomp = max(removed.get_moles(/datum/gas/nitrium)/combined_gas, 0)
- var/miasmacomp = max(removed.get_moles(/datum/gas/miasma)/combined_gas, 0)
+ var/plasmacomp = max(removed.get_moles(GAS_PLASMA)/combined_gas, 0)
+ var/o2comp = max(removed.get_moles(GAS_O2)/combined_gas, 0)
+ var/co2comp = max(removed.get_moles(GAS_CO2)/combined_gas, 0)
+ var/n2ocomp = max(removed.get_moles(GAS_NITROUS)/combined_gas, 0)
+ var/n2comp = max(removed.get_moles(GAS_N2)/combined_gas, 0)
+ var/pluoxiumcomp = max(removed.get_moles(GAS_PLUOXIUM)/combined_gas, 0)
+ var/tritiumcomp = max(removed.get_moles(GAS_TRITIUM)/combined_gas, 0)
+ var/bzcomp = max(removed.get_moles(GAS_BZ)/combined_gas, 0)
+ var/h2ocomp = max(removed.get_moles(GAS_H2O)/combined_gas, 0)
+ var/h2comp = max(removed.get_moles(GAS_H2)/combined_gas, 0)
+ var/pluoniumcomp = max(removed.get_moles(GAS_PLUONIUM)/combined_gas, 0)
+ var/healcomp = max(removed.get_moles(GAS_HEALIUM)/combined_gas, 0)
+ var/zaukcomp = max(removed.get_moles(GAS_ZAUKER)/combined_gas, 0)
+ var/haloncomp = max(removed.get_moles(GAS_HALON)/combined_gas, 0)
+ var/nobliumcomp = max(removed.get_moles(GAS_HYPERNOB)/combined_gas, 0)
+ var/antinobliumcomp = max(removed.get_moles(GAS_ANTINOB)/combined_gas, 0)
+ var/nitriumcomp = max(removed.get_moles(GAS_NITRIUM)/combined_gas, 0)
+ var/miasmacomp = max(removed.get_moles(GAS_MIASMA)/combined_gas, 0)
if (healcomp >= 0.1)
heal_mod = (healcomp * HEALIUM_HEAL_MOD) + 1 //Increases healing and healing cap
else
heal_mod = 1
-
+
if (zaukcomp >= 0.05)
damage_mod = (zaukcomp * ZAUKER_DAMAGE_MOD) + 1 //Increases damage taken and damage cap
else
damage_mod = 1
// Mole releated calculations
- var/bzmol = max(removed.get_moles(/datum/gas/bz), 0)
- var/nitriummol = max(removed.get_moles(/datum/gas/nitrium), 0)
- var/antinobmol = max(removed.get_moles(/datum/gas/antinoblium), 0)
- var/miasmol = max(removed.get_moles(/datum/gas/miasma), 0)
+ var/bzmol = max(removed.get_moles(GAS_BZ), 0)
+ var/nitriummol = max(removed.get_moles(GAS_NITRIUM), 0)
+ var/antinobmol = max(removed.get_moles(GAS_ANTINOB), 0)
+ var/miasmol = max(removed.get_moles(GAS_MIASMA), 0)
// Power of the gas. Scale of 0 to 1
gasmix_power_ratio = clamp(plasmacomp + o2comp + co2comp + tritiumcomp + bzcomp + nitriumcomp + antinobliumcomp - pluoxiumcomp - n2comp, 0, 1)
@@ -507,7 +507,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling + clamp(co2comp - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1)
else
powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling - 0.05,0, 1)
-
+
if(support_integrity >= 10 && !supermatter_blob)
powerloss_inhibitor = clamp(1-(powerloss_dynamic_scaling * clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD,1 ,1.5)),0 ,1)
@@ -532,7 +532,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(prob(50))
//1 + (tritRad + pluoxDampen * bzDampen * o2Rad * plasmaRad / (10 - bzrads))
- last_rads = power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumcomp) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER)))) * radmodifier
+ last_rads = power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + (((pluoxiumcomp ** 2) * PLUOXIUM_RADIOACTIVITY_MODIFIER)) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER)))) * radmodifier
radiation_pulse(src, max(last_rads))
if(nitriummol > NITRO_BALL_MOLES_REQUIRED) // haha funny particles go brrrrr
@@ -540,7 +540,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/starting_angle = rand(0, 360)
for(var/i = 0 to balls_shot) // fires particles in a ring, with some random variation in the angle
src.fire_nuclear_particle(starting_angle + rand(-180/balls_shot, 180/balls_shot) + (i * 360 / balls_shot))
- removed.set_moles(/datum/gas/nitrium, max(nitriummol - (balls_shot * NITRO_BALL_MOLES_REQUIRED), 0)) //converts nitrium into radballs
+ removed.set_moles(GAS_NITRIUM, max(nitriummol - (balls_shot * NITRO_BALL_MOLES_REQUIRED), 0)) //converts stimulum into radballs
if(bzcomp >= 0.4 && prob(50 * bzcomp))
src.fire_nuclear_particle() // Start to emit radballs at a maximum of 50% chance per tick
@@ -587,18 +587,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//Calculate how much gas to release, antinoblium seeded SM produces much more gas
if(antinoblium_attached || supermatter_blob)
- removed.adjust_moles(/datum/gas/plasma, max(((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER) * (1+(100-support_integrity)/25), 0))
- removed.adjust_moles(/datum/gas/oxygen, max((((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER) * (1+(100-support_integrity)/25), 0))
+ removed.adjust_moles(GAS_PLASMA, max(((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER) * (1+(100-support_integrity)/25), 0))
+ removed.adjust_moles(GAS_O2, max((((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER) * (1+(100-support_integrity)/25), 0))
else if(haloncomp >= 0.15)
- removed.adjust_moles(/datum/gas/plasma, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
- removed.adjust_moles(/datum/gas/oxygen, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / PLASMA_RELEASE_MODIFIER, 0)) // Supresses Oxygen Generation
+ removed.adjust_moles(GAS_PLASMA, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
+ removed.adjust_moles(GAS_O2, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / PLASMA_RELEASE_MODIFIER, 0)) // Supresses Oxygen Generation
else
- removed.adjust_moles(/datum/gas/plasma, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
- removed.adjust_moles(/datum/gas/oxygen, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0))
+ removed.adjust_moles(GAS_PLASMA, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
+ removed.adjust_moles(GAS_O2, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0))
if(produces_gas)
env.merge(removed)
- air_update_turf()
for(var/mob/living/carbon/human/l in view(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them.
if((!HAS_TRAIT(l, TRAIT_MESONS)) || corruptor_attached)
@@ -628,8 +627,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
supermatter_pull(src, power/750)
if(prob(5) || (antinoblium_attached || supermatter_blob) && prob(10))
supermatter_anomaly_gen(src, ANOMALY_FLUX, rand(5, 10))
- if(prob(5) || (antinoblium_attached || supermatter_blob) && prob(10))
- supermatter_anomaly_gen(src, ANOMALY_HALLUCINATION, rand(5, 10))
if(power > SEVERE_POWER_PENALTY_THRESHOLD && prob(5) || prob(1) || (antinoblium_attached || supermatter_blob) && prob(10))
supermatter_anomaly_gen(src, ANOMALY_GRAVITATIONAL, rand(5, 10))
if(power > SEVERE_POWER_PENALTY_THRESHOLD && prob(2) || prob(0.3) && power > POWER_PENALTY_THRESHOLD || (antinoblium_attached || supermatter_blob) && prob(10))
@@ -696,7 +693,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
radio.talk_into(src, "DANGER: SUPERMATTER BIOHAZARD LEVELS HAVE EXCEEDED SAFETY THRESHOLDS.", common_channel)
log_game("DANGER: SUPERMATTER BIOHAZARD LEVELS HAVE EXCEEDED SAFETY THRESHOLDS.") // yogs start - Logs SM chatter
investigate_log("DANGER: SUPERMATTER BIOHAZARD LEVELS HAVE EXCEEDED SAFETY THRESHOLDS.", INVESTIGATE_SUPERMATTER) // yogs end
-
+
if(antinoblium_attached)
if(support_integrity <= 10)
radio.talk_into(src, "DANGER: RESONANCE CASCADE IMMINENT.", engineering_channel)
@@ -761,7 +758,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
radiation_pulse(src, (100-support_integrity)*2, 4)
if(support_integrity<3)
var/emp_power = round(explosion_power * (1+(1-(support_integrity/3))),1)
- empulse(src, emp_power, emp_power*2)
+ empulse(src, emp_power)
if(support_integrity<100)
power += round((100-support_integrity)/2,1)
if(support_integrity<70)
@@ -782,7 +779,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(istype(T, /turf/open/space) || T.return_air().total_moles() < MOLE_SPACE_THRESHOLD)
damage += DAMAGE_HARDCAP * explosion_point //Can't cheat by spacing the crystal to buy time, it will just delaminate faster
if(prob(2))
- empulse(src, 10-support_integrity, (10-support_integrity)*2) //EMPs must always be spewing every so often to ensure that containment is guaranteed to fail.
+ empulse(src, 10-support_integrity) //EMPs must always be spewing every so often to ensure that containment is guaranteed to fail.
return 1
/obj/machinery/power/supermatter_crystal/bullet_act(obj/projectile/Proj)
@@ -1007,7 +1004,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
to_chat(user, "You attach the antinoblium shard to the [src], moving your hand away before a sudden gravitational wave pulls the [W] into the crystal as it flashes to ash!")
playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1)
radiation_pulse(src, 150, 4)
- empulse(src, 3,6)
+ empulse(src, EMP_HEAVY, 6)
qdel(W)
return
else if(user.dropItemToGround(W))
@@ -1155,8 +1152,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
new /obj/effect/anomaly/flux/explosion(local_turf, has_weak_lifespan ? rand(250, 300) : null)
if(ANOMALY_GRAVITATIONAL)
new /obj/effect/anomaly/grav(local_turf, has_weak_lifespan ? rand(250, 300) : null)
- if(ANOMALY_HALLUCINATION)
- new /obj/effect/anomaly/hallucination(local_turf, has_weak_lifespan ? rand(250, 300) : null)
if(ANOMALY_PYRO)
new /obj/effect/anomaly/pyro(local_turf, has_weak_lifespan ? rand(250, 300) : null)
if(ANOMALY_VORTEX)
@@ -1263,7 +1258,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
qdel(src)
addtimer(CALLBACK(shard, TYPE_PROC_REF(/obj/machinery/power/supermatter_crystal/shard, trigger)), 60)
return TRUE
-
+
/obj/machinery/power/supermatter_crystal/shard/proc/trigger()
var/area/A = get_area(loc)
playsound(src, 'sound/machines/supermatter_alert.ogg', 75)
diff --git a/code/modules/power/supermatter/supermatter_delamination.dm b/code/modules/power/supermatter/supermatter_delamination.dm
index 5893ca5d2282..0b97f5c66c31 100644
--- a/code/modules/power/supermatter/supermatter_delamination.dm
+++ b/code/modules/power/supermatter/supermatter_delamination.dm
@@ -77,6 +77,7 @@
call_tesla()
call_explosion()
return
+ call_explosion()
/datum/supermatter_delamination/proc/shockwave() //borrowed ynot's code
var/atom/movable/gravity_lens/shockwave = new(supermatter_turf)
diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm
index fb30e6e0f266..38dca34c30b0 100644
--- a/code/modules/power/tesla/energy_ball.dm
+++ b/code/modules/power/tesla/energy_ball.dm
@@ -348,7 +348,7 @@
else if(closest_mob)
var/shock_damage = (tesla_flags & TESLA_MOB_DAMAGE)? (min(round(power/600), 90) + rand(-5, 5)) : 0
- closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = 1, stun = (tesla_flags & TESLA_MOB_STUN), gib = zap_gib)
+ closest_mob.electrocute_act(shock_damage, source, 1, zone=null, tesla_shock = 1, stun = (tesla_flags & TESLA_MOB_STUN), gib = zap_gib)
if(issilicon(closest_mob))
var/mob/living/silicon/S = closest_mob
if((tesla_flags & TESLA_MOB_STUN) && (tesla_flags & TESLA_MOB_DAMAGE))
diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm
index 0cdf68ad3a3a..e551f28c6d25 100644
--- a/code/modules/power/turbine.dm
+++ b/code/modules/power/turbine.dm
@@ -44,7 +44,7 @@
var/intake_ratio = 0.1 // might add a way to adjust this in-game later
/obj/machinery/power/compressor/Destroy()
- SSair.atmos_machinery.Remove(src)
+ SSair_machinery.stop_processing_machine(src)
if (turbine && turbine.compressor == src)
turbine.compressor = null
var/turf/T = get_turf(src)
@@ -72,7 +72,7 @@
var/productivity = 1
/obj/machinery/power/turbine/Destroy()
- SSair.atmos_machinery.Remove(src)
+ SSair_machinery.stop_processing_machine(src)
if (compressor && compressor.turbine == src)
compressor.turbine = null
compressor = null
@@ -91,7 +91,7 @@
/obj/machinery/power/compressor/Initialize(mapload)
. = ..()
- SSair.atmos_machinery += src
+ SSair_machinery.start_processing_machine(src)
// The inlet of the compressor is the direction it faces
gas_contained = new
inturf = get_step(src, dir)
@@ -189,7 +189,7 @@
/obj/machinery/power/turbine/Initialize(mapload)
. = ..()
- SSair.atmos_machinery += src
+ SSair_machinery.start_processing_machine(src)
// The outlet is pointed at the direction of the turbine component
outturf = get_step(src, dir)
locate_machinery()
diff --git a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm
index 00dba2d00014..18607b919aba 100644
--- a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm
+++ b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm
@@ -10,12 +10,13 @@
if(!mother)
return
var/list/map = mother.map
- for(var/turf/T in map)
- SSair.remove_from_active(T)
for(var/turf/open/T in map)
if(T.air)
- T.air.copy_from_turf(T)
- SSair.add_to_active(T)
+ if(T.initial_gas_mix)
+ T.air.parse_gas_string(T.initial_gas_mix)
+ T.set_temperature(T.air.return_temperature())
+ else
+ T.air.copy_from_turf(T)
/datum/mapGeneratorModule/bottomLayer/massdelete
spawnableAtoms = list()
diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm
index 5f4be6d2453d..10339f83fce3 100644
--- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm
+++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm
@@ -231,10 +231,10 @@
/obj/item/ammo_casing/shotgun/hardlight/emp_act(severity)
if (. & EMP_PROTECT_SELF)
return
- variance = 60 // yikes
- if(severity == EMP_HEAVY)
- pellets = 3 // also yikes
- addtimer(CALLBACK(src, PROC_REF(remove_emp)), 10 SECONDS / severity, TIMER_OVERRIDE|TIMER_UNIQUE)
+ variance = initial(variance) + severity*4 // yikes
+ if(severity > EMP_LIGHT)
+ pellets = initial(pellets) * (0.5**(severity / EMP_HEAVY)) // also yikes
+ addtimer(CALLBACK(src, PROC_REF(remove_emp)), severity SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE)
/obj/item/ammo_casing/shotgun/hardlight/proc/remove_emp()
variance = initial(variance)
diff --git a/code/modules/projectiles/ammunition/energy/special.dm b/code/modules/projectiles/ammunition/energy/special.dm
index 6ff05a4c1616..0aadae394955 100644
--- a/code/modules/projectiles/ammunition/energy/special.dm
+++ b/code/modules/projectiles/ammunition/energy/special.dm
@@ -4,7 +4,7 @@
fire_sound = 'sound/weapons/ionrifle.ogg'
/obj/item/ammo_casing/energy/ion/hos
- projectile_type = /obj/projectile/ion/light
+ projectile_type = /obj/projectile/ion/weak
e_cost = 200
/obj/item/ammo_casing/energy/ion/weak
diff --git a/code/modules/projectiles/ammunition/reusable/arrow.dm b/code/modules/projectiles/ammunition/reusable/arrow.dm
index 933c10d0511a..c367fdcfbac6 100644
--- a/code/modules/projectiles/ammunition/reusable/arrow.dm
+++ b/code/modules/projectiles/ammunition/reusable/arrow.dm
@@ -464,23 +464,23 @@
if(/obj/item/singularity_shard/stage2)
break_chance = 0.5
rads_released = 200
- empulse(src, 0, 1)
+ empulse(src, 1)
if(/obj/item/singularity_shard/stage3)
break_chance = 1.5
rads_released = 500
- empulse(src, 0, 3)
+ empulse(src, 3)
if(/obj/item/singularity_shard/stage4)
break_chance = 5
rads_released = 1000
- empulse(src, 1, 5)
+ empulse(src, 5)
if(/obj/item/singularity_shard/stage5)
break_chance = 10
rads_released = 2000
- empulse(src, 2, 7)
+ empulse(src, 7)
if(/obj/item/singularity_shard/stage6)
break_chance = 100
rads_released = 3000
- empulse(src, 5, 15) // Its going to break open into a singulo anyways, may as well add some fireworks
+ empulse(src, 15) // Its going to break open into a singulo anyways, may as well add some fireworks
// Handles releasing rads
if(rads_released)
diff --git a/code/modules/projectiles/ammunition/special/reagent.dm b/code/modules/projectiles/ammunition/special/reagent.dm
new file mode 100644
index 000000000000..525c8b52614f
--- /dev/null
+++ b/code/modules/projectiles/ammunition/special/reagent.dm
@@ -0,0 +1,24 @@
+/obj/item/ammo_casing/reagent
+ name = "pressurized liquid"
+ desc = "You shouldn't be seeing this!"
+ projectile_type = /obj/projectile/reagent
+ firing_effect_type = null
+
+/obj/item/ammo_casing/reagent/Initialize(mapload)
+ . = ..()
+ create_reagents(10, OPENCONTAINER_NOSPILL)
+
+/obj/item/ammo_casing/reagent/newshot(new_volume)
+ if(!isnull(new_volume))
+ reagents.maximum_volume = new_volume
+ return ..()
+
+
+/obj/item/ammo_casing/reagent/ready_proj(atom/target, mob/living/user, quiet, zone_override, atom/fired_from)
+ var/obj/item/gun/gun = loc
+ if(gun.reagents && !reagents.total_volume)
+ gun.reagents.trans_to(src, reagents.maximum_volume, transfered_by = user)
+ return ..()
+
+/obj/item/ammo_casing/reagent/water
+ projectile_type = /obj/projectile/reagent/water
diff --git a/code/modules/projectiles/boxes_magazines/external/rechargable.dm b/code/modules/projectiles/boxes_magazines/external/rechargable.dm
index c9a5c0dea3f1..7556ca1c68a3 100644
--- a/code/modules/projectiles/boxes_magazines/external/rechargable.dm
+++ b/code/modules/projectiles/boxes_magazines/external/rechargable.dm
@@ -102,7 +102,7 @@
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
var/bullet_count = ammo_count()
- var/bullets_to_remove = round(bullet_count / (severity*2))
+ var/bullets_to_remove = round(bullet_count * (0.5**(severity/EMP_HEAVY)))
for(var/i = 0; i < bullets_to_remove, i++)
qdel(get_round())
update_appearance(UPDATE_ICON)
@@ -111,8 +111,8 @@
if(!G.magazine == src)
return
G.semicd = TRUE
- // 5-10 seconds depending on severity, then give or take 0.2 seconds to prevent piercing ears
- var/unjam_time = ((10/severity) + (rand(-20,20)*0.01)) SECONDS
+ // up to 10 seconds depending on severity, then give or take 0.2 seconds to prevent piercing ears
+ var/unjam_time = (min(severity, EMP_HEAVY) + (rand(-20,20)*0.01)) SECONDS
addtimer(CALLBACK(G, TYPE_PROC_REF(/obj/item/gun, reset_semicd)), unjam_time)
/obj/item/ammo_casing/caseless/c22hl
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index d6a14d12ec03..7d2e06ec1d04 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -36,11 +36,11 @@
/obj/item/gun/energy/emp_act(severity)
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
- cell.use(round(cell.charge / (severity*2)))
+ cell.use(round(cell.charge * (0.5**(severity/EMP_HEAVY))))
emp_jammed = TRUE
deltimer(emp_jam_timer)
- // 5-10 seconds depending on severity, then give or take 0.2 seconds to prevent piercing ears
- var/unjam_time = ((10/severity) + (rand(-20,20)*0.01)) SECONDS
+ // up to 10 seconds depending on severity, then give or take 0.2 seconds to prevent piercing ears
+ var/unjam_time = (min(severity, EMP_HEAVY) + (rand(-20,20)*0.01)) SECONDS
emp_jam_timer = addtimer(CALLBACK(src, PROC_REF(emp_unjam)), unjam_time, TIMER_STOPPABLE)
chambered = null //we empty the chamber
recharge_newshot() //and try to charge a new shot
diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm
index 477fbd5520ce..d6dadf6ccf50 100644
--- a/code/modules/projectiles/guns/misc/beam_rifle.dm
+++ b/code/modules/projectiles/guns/misc/beam_rifle.dm
@@ -425,6 +425,7 @@
armor_flag = ENERGY
range = 150
jitter = 10
+ demolition_mod = 4
var/obj/item/gun/gun
var/structure_pierce_amount = 0 //All set to 0 so the gun can manually set them during firing.
var/structure_bleed_coeff = 0
diff --git a/code/modules/projectiles/guns/misc/hyper_soaker.dm b/code/modules/projectiles/guns/misc/hyper_soaker.dm
new file mode 100644
index 000000000000..b0d0775b9493
--- /dev/null
+++ b/code/modules/projectiles/guns/misc/hyper_soaker.dm
@@ -0,0 +1,96 @@
+/obj/item/gun/water
+ name = "donksoft hyper-soaker"
+ desc = "Harmless fun, unless you're allergic to water."
+ icon_state = "water"
+ item_state = "water"
+ w_class = WEIGHT_CLASS_NORMAL
+ clumsy_check = 0 // we do a little trolling
+ fire_sound = 'sound/effects/spray2.ogg'
+ var/reagent_volume = 250
+ var/transfer_volume = 10
+ var/ammo_type = /obj/item/ammo_casing/reagent/water
+
+/obj/item/gun/water/syndicate
+ reagent_volume = 600
+ transfer_volume = 30
+
+/obj/item/gun/water/Initialize(mapload)
+ . = ..()
+ create_reagents(reagent_volume, REFILLABLE|DRAINABLE|AMOUNT_VISIBLE)
+
+/// Pre-filled version
+/obj/item/gun/water/full/Initialize(mapload)
+ . = ..()
+ reagents.add_reagent(/datum/reagent/water, reagent_volume)
+
+/obj/item/gun/water/examine(mob/user)
+ . = ..()
+ . += "Alt-click to empty its contents onto the floor."
+
+/obj/item/gun/water/AltClick(mob/user)
+ . = ..()
+ if(!reagents.total_volume)
+ return
+ to_chat(user, span_notice("You empty [src] onto the floor."))
+ reagents.reaction(get_turf(user), TOUCH) // spills onto the floor
+ reagents.clear_reagents()
+
+/obj/item/gun/water/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ . = ..()
+ if(!proximity_flag)
+ return
+ if(istype(target, /obj/structure/reagent_dispensers))
+ var/trans_amount = target.reagents.trans_to(src, reagent_volume)
+ if(trans_amount)
+ to_chat(user, span_notice("You refill [src] from [target]."))
+ else if(target.is_refillable())
+ var/trans_amount = reagents.trans_to(target, 10)
+ if(trans_amount)
+ to_chat(user, span_notice("You transfer [trans_amount] units to [target]."))
+
+/obj/item/gun/water/can_shoot()
+ return (reagents.total_volume > 1)
+
+/obj/item/gun/water/recharge_newshot()
+ chambered = new ammo_type(src)
+ chambered.newshot(transfer_volume)
+
+/obj/item/gun/water/process_chamber()
+ chambered = null
+ recharge_newshot()
+
+/obj/item/gun/water/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread, cd_override)
+ if(!chambered && can_shoot())
+ process_chamber() // If the gun was drained and then recharged, load a new shot.
+ if(reagent_check())
+ return
+ return ..()
+
+/obj/item/gun/water/process_burst(mob/living/user, atom/target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, iteration)
+ if(!chambered && can_shoot())
+ process_chamber() // If the gun was drained and then recharged, load a new shot.
+ if(reagent_check())
+ return
+ return ..()
+
+/obj/item/gun/water/proc/reagent_check()
+ var/atom/starting_loc = loc
+ for(var/datum/reagent/R as anything in reagents.reagent_list)
+ R.reaction_obj(src, R.volume) // dangerous chemicals can damage the gun (or teleport it lmao)
+ if(QDELETED(src))
+ return TRUE
+ if(loc != starting_loc)
+ reagents.clear_reagents()
+ if(chambered)
+ qdel(chambered)
+ chambered = null
+ return TRUE // the gun broke or moved so you didn't actually get to shoot it
+
+// overlay for water levels
+/obj/item/gun/water/update_overlays()
+ . = ..()
+ var/water_state = ROUND_UP(5 * reagents.total_volume / reagents.maximum_volume)
+ if(!water_state)
+ return .
+ var/mutable_appearance/water_overlay = mutable_appearance(icon, "water-tank[water_state]")
+ . += water_overlay
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index fd9b2520b42d..ebef6ac497c6 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -14,7 +14,6 @@
light_system = MOVABLE_LIGHT
light_range = 2
light_color = LIGHT_COLOR_RED
- light_flags = LIGHT_NO_LUMCOUNT
ricochets_max = 50 //Honk!
ricochet_chance = 80
reflectable = REFLECT_NORMAL
@@ -154,6 +153,7 @@
damage = 30
wound_bonus = -40
bare_wound_bonus = 70
+ demolition_mod = 3 // industrial laser
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
light_color = LIGHT_COLOR_GREEN
diff --git a/code/modules/projectiles/projectile/bullets/_incendiary.dm b/code/modules/projectiles/projectile/bullets/_incendiary.dm
index cb61ee5b7bb0..1a6ed1323113 100644
--- a/code/modules/projectiles/projectile/bullets/_incendiary.dm
+++ b/code/modules/projectiles/projectile/bullets/_incendiary.dm
@@ -1,6 +1,7 @@
/obj/projectile/bullet/incendiary
damage = 20
var/fire_stacks = 4
+ demolition_mod = 0.75
/obj/projectile/bullet/incendiary/on_hit(atom/target, blocked = FALSE)
. = ..()
diff --git a/code/modules/projectiles/projectile/bullets/pistol.dm b/code/modules/projectiles/projectile/bullets/pistol.dm
index b67fe3a84c43..e9383f89b2dc 100644
--- a/code/modules/projectiles/projectile/bullets/pistol.dm
+++ b/code/modules/projectiles/projectile/bullets/pistol.dm
@@ -64,7 +64,7 @@
/obj/projectile/bullet/c10mm/emp/on_hit(atom/target, blocked = FALSE)
..()
- empulse(target, 0.5, 1) //Heavy EMP on target, light EMP in tiles around
+ empulse(target, EMP_HEAVY, 1) //Heavy EMP on target, light EMP in tiles around
/obj/projectile/bullet/boltpistol
name = "Bolt round"
diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm
index d2f1edeec1bd..c476a18556f8 100644
--- a/code/modules/projectiles/projectile/bullets/rifle.dm
+++ b/code/modules/projectiles/projectile/bullets/rifle.dm
@@ -44,6 +44,7 @@
damage = 60
wound_bonus = -35
wound_falloff_tile = 0
+ demolition_mod = 1.2
/obj/projectile/bullet/a762/raze
name = "7.62mm Raze bullet"
@@ -63,6 +64,7 @@
penetrating = TRUE //Passes through two objects, stops on a mob or on a third object
penetrations = 2
penetration_type = 1
+ demolition_mod = 1.5 // anti-armor
/obj/projectile/bullet/a762/vulcan
name = "7.62mm Vulcan bullet"
diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm
index 79acfac73304..fbec1b20f8bc 100644
--- a/code/modules/projectiles/projectile/bullets/shotgun.dm
+++ b/code/modules/projectiles/projectile/bullets/shotgun.dm
@@ -6,6 +6,7 @@
damage = 46 //About 2/3's the damage of buckshot but doesn't suffer from spread or negative AP
sharpness = SHARP_POINTY
wound_bonus = -30
+ demolition_mod = 2 // good at smashing through stuff
/obj/projectile/bullet/shotgun/slug/syndie
name = "12g syndicate shotgun slug"
@@ -74,6 +75,7 @@
damage = 35 //Most certainly to drop below 3-shot threshold because of damage falloff
armour_penetration = 60 // he he funny round go through armor
wound_bonus = -40
+ demolition_mod = 3 // very good at smashing through stuff
penetrating = TRUE //Goes through an infinite number of mobs
/obj/projectile/bullet/shotgun/slug/Range()
@@ -88,6 +90,7 @@
var/tile_dropoff = 0.4
var/tile_dropoff_s = 0.3
armour_penetration = -20 //Armor is 25% stronger against pellets
+ demolition_mod = 0.5 // bad at smashing through stuff
/obj/projectile/bullet/pellet/shotgun_buckshot
name = "buckshot pellet"
@@ -200,10 +203,11 @@
desc = "A breaching round designed to destroy airlocks and windows with only a few shots, but is ineffective against other targets."
hitsound = 'sound/weapons/sonic_jackhammer.ogg'
damage = 10 //does shit damage to everything except doors and windows
+ demolition_mod = 6 //not that bad at breaking things
/obj/projectile/bullet/shotgun/slug/breaching/on_hit(atom/target)
- if(istype(target, /obj/structure/window) || istype(target, /obj/machinery/door) || istype(target, /obj/structure/door_assembly))
- damage = 500 //one shot to break a window or 3 shots to breach an airlock door
+ if(istype(target, /obj/structure/window) || istype(target, /obj/machinery/door) || istype(target, /obj/structure/door_assembly) || istype(target, /obj/structure/grille))
+ demolition_mod = 50 //one shot to break a window or 3 shots to breach an airlock door
..()
/obj/projectile/bullet/pellet/hardlight
diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm
index a845ad1bb599..262bec69a77f 100644
--- a/code/modules/projectiles/projectile/bullets/sniper.dm
+++ b/code/modules/projectiles/projectile/bullets/sniper.dm
@@ -7,13 +7,7 @@
paralyze = 100
dismemberment = 50
armour_penetration = 50
- var/breakthings = TRUE
-
-/obj/projectile/bullet/p50/on_hit(atom/target, blocked = 0)
- if(isobj(target) && (blocked != 100) && breakthings)
- var/obj/O = target
- O.take_damage(80, BRUTE, BULLET, FALSE, null, armour_penetration)
- return ..()
+ demolition_mod = 2.2 // very effective against armored structures and vehicles
/obj/projectile/bullet/p50/soporific
name = ".50 soporific bullet"
@@ -21,7 +15,6 @@
damage = 0
dismemberment = 0
paralyze = 0
- breakthings = FALSE
/obj/projectile/bullet/p50/soporific/on_hit(atom/target, blocked = FALSE)
if((blocked != 100) && isliving(target))
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 2a3d794ef06b..00961f96658f 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -20,7 +20,7 @@
var/mob/living/carbon/C = target
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "tased", /datum/mood_event/tased)
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
- if(C.dna && (C.dna.check_mutation(HULK) || C.dna.check_mutation(ACTIVE_HULK)))
+ if(C.dna && (C.dna.check_mutation(HULK)))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
addtimer(CALLBACK(C, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), jitter), 5)
diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm
index 4bf110af9963..893d14488707 100644
--- a/code/modules/projectiles/projectile/energy/tesla.dm
+++ b/code/modules/projectiles/projectile/energy/tesla.dm
@@ -2,6 +2,7 @@
name = "tesla bolt"
icon_state = "tesla_projectile"
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
+ armor_flag = ELECTRIC
var/chain
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
var/zap_range = 3
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 5b2cb0c7b0de..0f4a9cd6d130 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -1102,10 +1102,10 @@
nodamage = TRUE
armor_flag = ENERGY
impact_effect_type = /obj/effect/temp_visual/impact_effect/ion
- var/light_emp_radius = 3
- var/heavy_emp_radius = 0.5 //Effectively 1 but doesnt spread to adjacent tiles
+ var/ion_severity = EMP_HEAVY //Heavy EMP effect that doesn't spread to adjacent tiles
+ var/ion_range = 3
/obj/projectile/magic/ion/on_hit(atom/target, blocked = FALSE)
..()
- empulse(target, heavy_emp_radius, light_emp_radius)
+ empulse(target, ion_severity, ion_range)
return BULLET_ACT_HIT
diff --git a/code/modules/projectiles/projectile/reusable/arrow.dm b/code/modules/projectiles/projectile/reusable/arrow.dm
index dd6dcbfdfb67..6b615926d848 100644
--- a/code/modules/projectiles/projectile/reusable/arrow.dm
+++ b/code/modules/projectiles/projectile/reusable/arrow.dm
@@ -289,7 +289,7 @@
var/mob/living/carbon/C = target
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "tased", /datum/mood_event/tased)
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
- if(C.dna && (C.dna.check_mutation(HULK) || C.dna.check_mutation(ACTIVE_HULK)))
+ if(C.dna && (C.dna.check_mutation(HULK)))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
addtimer(CALLBACK(C, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), jitter), 5)
diff --git a/code/modules/projectiles/projectile/special/hallucination.dm b/code/modules/projectiles/projectile/special/hallucination.dm
index 58234a8a9001..e6a31bc9e621 100644
--- a/code/modules/projectiles/projectile/special/hallucination.dm
+++ b/code/modules/projectiles/projectile/special/hallucination.dm
@@ -168,7 +168,7 @@
/obj/projectile/hallucination/taser/hal_apply_effect()
hal_target.Paralyze(100)
hal_target.adjust_stutter(2 SECONDS)
- if(hal_target.dna && (hal_target.dna.check_mutation(HULK)|| hal_target.dna.check_mutation(ACTIVE_HULK)))
+ if(hal_target.dna && (hal_target.dna.check_mutation(HULK)))
hal_target.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
else if((hal_target.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(hal_target, TRAIT_STUNIMMUNE))
addtimer(CALLBACK(hal_target, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), 20), 0.5 SECONDS)
diff --git a/code/modules/projectiles/projectile/special/ion.dm b/code/modules/projectiles/projectile/special/ion.dm
index 4de29713c471..82675908b7cd 100644
--- a/code/modules/projectiles/projectile/special/ion.dm
+++ b/code/modules/projectiles/projectile/special/ion.dm
@@ -6,22 +6,18 @@
nodamage = TRUE
armor_flag = ENERGY
impact_effect_type = /obj/effect/temp_visual/impact_effect/ion
- var/light_emp_radius = 1
- var/heavy_emp_radius = 0.5 //Effectively 1 but doesnt spread to adjacent tiles
+ var/ion_severity = EMP_HEAVY // Heavy EMP effects that don't spread to adjacent tiles
+ var/ion_range = 1
/obj/projectile/ion/on_hit(atom/target, blocked = FALSE)
..()
- empulse(target, heavy_emp_radius, light_emp_radius)
+ empulse(target, ion_severity, ion_range)
return BULLET_ACT_HIT
/obj/projectile/ion/weak
- light_emp_radius = 0
- heavy_emp_radius = 0
-
-/obj/projectile/ion/light
- light_emp_radius = 1
- heavy_emp_radius = 0
+ ion_severity = EMP_LIGHT // weak ions
+ ion_range = 0
/obj/projectile/ion/heavy
- light_emp_radius = 2
- heavy_emp_radius = 2
+ ion_severity = 15 // STRONG ions
+ ion_range = 2
diff --git a/code/modules/projectiles/projectile/special/neurotoxin.dm b/code/modules/projectiles/projectile/special/neurotoxin.dm
deleted file mode 100644
index adf51f8c7107..000000000000
--- a/code/modules/projectiles/projectile/special/neurotoxin.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/obj/projectile/bullet/neurotoxin
- name = "neurotoxin spit"
- icon_state = "neurotoxin"
- damage = 5
- damage_type = TOX
- armor_flag = BIO // why was this bullet protection
-
-/obj/projectile/bullet/neurotoxin/on_hit(atom/target, blocked = FALSE)
- if(isalien(target))
- nodamage = TRUE
- else if(iscarbon(target))
- var/mob/living/carbon/H = target
- H.reagents.add_reagent(/datum/reagent/toxin/staminatoxin/neurotoxin_alien, 10 * H.get_permeability())
- return ..()
diff --git a/code/modules/projectiles/projectile/special/plasma.dm b/code/modules/projectiles/projectile/special/plasma.dm
index 3e027fcee9c8..63f46d4e7785 100644
--- a/code/modules/projectiles/projectile/special/plasma.dm
+++ b/code/modules/projectiles/projectile/special/plasma.dm
@@ -6,6 +6,7 @@
damage = 5
range = 4
dismemberment = 20
+ demolition_mod = 2 // industrial strength plasma cutter designed to cut things
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
var/mine_range = 3 //mines this many additional tiles of rock
tracer_type = /obj/effect/projectile/tracer/plasma_cutter
@@ -13,7 +14,6 @@
impact_type = /obj/effect/projectile/impact/plasma_cutter
light_system = MOVABLE_LIGHT
light_color = LIGHT_COLOR_PURPLE
- light_flags = LIGHT_NO_LUMCOUNT
light_range = 2
/obj/projectile/plasma/weak
diff --git a/code/modules/projectiles/projectile/special/reagent.dm b/code/modules/projectiles/projectile/special/reagent.dm
new file mode 100644
index 000000000000..524180486c7b
--- /dev/null
+++ b/code/modules/projectiles/projectile/special/reagent.dm
@@ -0,0 +1,55 @@
+/obj/projectile/reagent
+ name = "\proper reagents"
+ icon = 'icons/obj/chempuff.dmi'
+ icon_state = ""
+ damage_type = TOX
+ damage = 0
+ armor_flag = BIO
+ nodamage = TRUE
+ speed = 1.2 // slow projectile
+ /// Reagent application methods
+ var/transfer_methods = TOUCH
+ var/list/reagents_list = list()
+
+/obj/projectile/reagent/Initialize(mapload)
+ . = ..()
+ create_reagents(1000)
+
+/obj/projectile/reagent/proc/update_reagents()
+ if(!reagents.total_volume) // if it didn't already have reagents in it, fill it with the default reagents
+ for(var/type in reagents_list)
+ reagents.add_reagent(type, reagents_list[type])
+ add_atom_colour(mix_color_from_reagents(reagents.reagent_list), FIXED_COLOUR_PRIORITY)
+
+/obj/projectile/reagent/fire(angle, atom/direct_target)
+ update_reagents()
+ return ..()
+
+/obj/projectile/reagent/on_hit(atom/target, blocked = FALSE)
+ var/hit = ..()
+ if(blocked < 100 && (hit & BULLET_ACT_HIT))
+ log_combat(firer, target, "shot", src, addition = "with a projectile containing [reagents.log_list()]")
+ reagents.reaction(target, transfer_methods)
+ reagents.reaction(get_turf(target), transfer_methods)
+ return hit
+
+
+/// Water - for water guns! Just some harmless fun... right??
+/obj/projectile/reagent/water
+ name = "\proper water"
+ reagents_list = list(/datum/reagent/water = 10)
+
+/obj/projectile/reagent/water/update_reagents()
+ . = ..()
+ var/last_volume = 0
+ for(var/datum/reagent/R as anything in reagents.reagent_list)
+ if(R.volume > last_volume)
+ last_volume = R.volume
+ name = "\proper [lowertext(R.name)]"
+
+/// Xeno neurotoxin
+/obj/projectile/reagent/neurotoxin
+ name = "neurotoxin spit"
+ icon = 'icons/obj/projectiles.dmi'
+ icon_state = "neurotoxin"
+ reagents_list = list(/datum/reagent/toxin/staminatoxin/neurotoxin_alien = 10)
diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm
index a0df35e83b00..3d220e4842a3 100644
--- a/code/modules/projectiles/projectile/special/rocket.dm
+++ b/code/modules/projectiles/projectile/special/rocket.dm
@@ -12,21 +12,15 @@
name ="\improper HEDP rocket"
desc = "USE A WEEL GUN"
icon_state= "84mm-hedp"
+ armor_flag = BOMB
damage = 80
- var/anti_armour_damage = 200
+ demolition_mod = 4
armour_penetration = 100
dismemberment = 100
/obj/projectile/bullet/a84mm/on_hit(atom/target, blocked = FALSE)
..()
explosion(target, -1, 1, 3, 1, 0, flame_range = 4)
-
- if(ismecha(target))
- var/obj/mecha/M = target
- M.take_damage(anti_armour_damage, BRUTE, BOMB, FALSE, null, armour_penetration)
- if(issilicon(target))
- var/mob/living/silicon/S = target
- S.take_overall_damage(anti_armour_damage*0.75, anti_armour_damage*0.25)
return BULLET_ACT_HIT
/obj/projectile/bullet/a84mm_he
@@ -34,6 +28,7 @@
desc = "Boom."
icon_state = "missile"
damage = 30
+ demolition_mod = 4
ricochets_max = 0 //it's a MISSILE
/obj/projectile/bullet/a84mm_he/on_hit(atom/target, blocked=0)
@@ -49,6 +44,7 @@
desc = "Boom."
icon_state = "missile"
damage = 30
+ demolition_mod = 4
ricochets_max = 0 //it's a MISSILE
var/sturdy = list(
/turf/closed,
@@ -79,22 +75,18 @@
icon_state = "cannonball"
desc = "Not for bowling purposes"
damage = 30
+ demolition_mod = 20 // YARRR
/obj/projectile/bullet/cball/on_hit(atom/target, blocked=0)
- var/mob/living/carbon/human/H = firer
- var/atom/throw_target = get_edge_target_turf(target, H.dir)
- if(istype(target, /obj/structure/window) || istype(target, /obj/machinery/door) || istype(target, /obj/structure/door_assembly))
- damage = 500
- ..()
- if(isliving(target))
- var/mob/living/L = target
- if(!L.anchored && !L.throwing)//avoid double hits
- if(iscarbon(L))
- var/mob/living/carbon/C = L
- var/mob/M = firer
- if(istype(M))
- C.throw_at(throw_target, 2, 4, H, 3)
- return BULLET_ACT_HIT
+ var/atom/throw_target = get_edge_target_turf(target, firer.dir)
+ if(ismecha(target) || isliving(target))
+ demolition_mod = 5 // woah there let's not one-shot mechs and borgs
+ . = ..()
+ if(!ismovable(target)) // if it's not movable then don't bother trying to throw it
+ return
+ var/atom/movable/movable_target = target
+ if(!movable_target.anchored && !movable_target.throwing)//avoid double hits
+ movable_target.throw_at(throw_target, 2, 4, firer, 3)
/obj/projectile/bullet/bolt
name = "bolt"
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 6036fbca421c..207e13497cf6 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -2726,3 +2726,22 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.physiology.do_after_speed /= alcoholicspeed
M.next_move_modifier /= alcoholicspeed
return ..()
+
+/datum/reagent/consumable/ethanol/wine_voltaic
+ name = "Voltaic Yellow Wine"
+ description = "Electrically charged wine. Recharges ethereals, but also nontoxic."
+ boozepwr = 30
+ color = "#FFAA00"
+ quality = DRINK_GOOD
+ taste_description = "static with a hint of sweetness"
+ glass_icon_state = "wine_voltaic"
+ glass_name = "Voltaic Yellow Wine"
+ glass_desc = "Shocking, not stirred."
+
+/datum/reagent/consumable/ethanol/wine_voltaic/on_mob_life(mob/living/carbon/M)
+ if(HAS_TRAIT(M, TRAIT_POWERHUNGRY))
+ M.adjust_nutrition(nutriment_factor)
+ else if(prob(25))
+ M.electrocute_act(rand(10,15), "Liquid Electricity in their body", 1) //lmao at the newbs who eat energy bars
+ playsound(M, "sparks", 50, 1)
+ return ..()
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 8e67b9a4c82f..b7af79856259 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -475,10 +475,9 @@
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume*2 SECONDS)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot)
- var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles())
- lowertemp.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,0))
+ var/datum/gas_mixture/lowertemp = T.return_air()
+ lowertemp.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,TCMB))
lowertemp.react(src)
- T.assume_air(lowertemp)
qdel(hotspot)
/datum/reagent/consumable/enzyme
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 12ffd62ff208..86225ee4f94d 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -121,7 +121,7 @@
/datum/reagent/water
name = "Water"
description = "An ubiquitous chemical substance that is composed of hydrogen and oxygen."
- color = "#AAAAAA77" // rgb: 170, 170, 170, 77 (alpha)
+ color = "#609bdf77" // rgb: 96, 155, 223, 77 (alpha)
taste_description = "water"
var/cooling_temperature = 2
glass_icon_state = "glass_clear"
@@ -192,8 +192,16 @@
M.AdjustUnconscious(-reac_volume*0.3 SECONDS)
M.AdjustSleeping(-reac_volume*0.5 SECONDS)
- M.adjust_wet_stacks((reac_volume / 10) * M.get_permeability(null, TRUE))
+ // this function allows lower volumes to still do something without preventing higher volumes from causing too much wetness
+ M.adjust_wet_stacks(3*log(2, (reac_volume*M.get_permeability(null, TRUE) + 10) / 10))
M.extinguish_mob() // permeability affects the negative fire stacks but not the extinguishing
+
+ // if preternis, update wetness instantly when applying more water instead of waiting for the next life tick
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ var/datum/species/preternis/P = H.dna?.species
+ if(istype(P))
+ P.handle_wetness(H)
..()
/datum/reagent/water/on_mob_life(mob/living/carbon/M)
@@ -840,12 +848,6 @@
color = "#808080" // rgb: 128, 128, 128
taste_mult = 0 // oderless and tasteless
-/datum/reagent/oxygen/reaction_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
- return 0
- var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]")
-
/datum/reagent/oxygen/reaction_turf(turf/open/T, reac_volume)
if(istype(T))
var/temp = holder ? holder.chem_temp : T20C
@@ -873,12 +875,6 @@
color = "#808080" // rgb: 128, 128, 128
taste_mult = 0
-/datum/reagent/nitrogen/reaction_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
- return 0
- var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]")
-
/datum/reagent/nitrogen/reaction_turf(turf/open/T, reac_volume)
if(istype(T))
var/temp = holder ? holder.chem_temp : T20C
@@ -1087,7 +1083,12 @@
/datum/reagent/bluespace/reaction_mob(mob/living/M, methods=TOUCH, reac_volume)
if((methods & (TOUCH|VAPOR)) && (reac_volume > 5))
do_teleport(M, get_turf(M), (reac_volume / 5), asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) //4 tiles per crystal
- ..()
+ return ..()
+
+/datum/reagent/bluespace/reaction_obj(obj/O, volume)
+ if(volume > 5 && !O.anchored) // can teleport objects that aren't anchored
+ do_teleport(O, get_turf(O), (volume / 5), asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) //4 tiles per crystal
+ return ..()
/datum/reagent/bluespace/on_mob_life(mob/living/carbon/M)
if(current_cycle > 10 && prob(15))
@@ -1345,12 +1346,6 @@
color = "#B0B0B0" // rgb : 192, 192, 192
taste_description = "something unknowable"
-/datum/reagent/carbondioxide/reaction_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
- return 0
- var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]")
-
/datum/reagent/carbondioxide/reaction_turf(turf/open/T, reac_volume)
if(istype(T))
var/temp = holder ? holder.chem_temp : T20C
@@ -1365,12 +1360,6 @@
color = "#808080"
taste_description = "sweetness"
-/datum/reagent/nitrous_oxide/reaction_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
- return 0
- var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]")
-
/datum/reagent/nitrous_oxide/reaction_turf(turf/open/T, reac_volume)
if(istype(T))
var/temp = holder ? holder.chem_temp : T20C
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index 15aecc9a0582..e160e15ce9ff 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -219,22 +219,45 @@
self_consuming = TRUE
compatible_biotypes = ALL_BIOTYPES
var/shock_timer = 0
+ var/teslium_trip = FALSE
/datum/reagent/teslium/on_mob_metabolize(mob/living/L)
. = ..()
ADD_TRAIT(L, TRAIT_EMPPROOF_SELF, "teslium")
+ if(ispreternis(L)) //no clue why preterni function this way, but why not (makes more sense for ethereals honestly)
+ L.add_movespeed_modifier(type, TRUE, priority=101, multiplicative_slowdown=-3, blacklisted_movetypes=(FLYING|FLOATING))
+ teslium_trip = TRUE
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ H.physiology.burn_mod *= 10
/datum/reagent/teslium/on_mob_life(mob/living/carbon/M)
shock_timer++
if(shock_timer >= rand(5,30)) //Random shocks are wildly unpredictable
shock_timer = 0
- M.electrocute_act(rand(5,20), "Teslium in their body", 1, 1) //Override because it's caused from INSIDE of you
+ var/shock_damage = rand(5,20)
+ M.electrocute_act(shock_damage, "Teslium in their body", 1, zone=null, override=TRUE) //Override because it's caused from INSIDE of you
playsound(M, "sparks", 50, 1)
+
+ if(HAS_TRAIT(M, TRAIT_POWERHUNGRY)) //twice as effective as liquid electricity
+ M.adjust_nutrition(10 * REAGENTS_METABOLISM)
+
+ if(teslium_trip)
+ M.adjustOxyLoss(-2 * REAGENTS_EFFECT_MULTIPLIER)
+ M.adjustBruteLoss(-2 * REAGENTS_EFFECT_MULTIPLIER, TRUE, FALSE, BODYPART_ANY)
+ M.adjustFireLoss(-2 * REAGENTS_EFFECT_MULTIPLIER, TRUE, FALSE, BODYPART_ANY)
+ M.AdjustAllImmobility(-3)
+ M.adjustStaminaLoss(-5 * REAGENTS_EFFECT_MULTIPLIER)
..()
/datum/reagent/teslium/on_mob_end_metabolize(mob/living/L)
. = ..()
REMOVE_TRAIT(L, TRAIT_EMPPROOF_SELF, "teslium")
+ if(teslium_trip)
+ L.remove_movespeed_modifier(type, TRUE)
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ H.physiology.burn_mod /= 10
/datum/reagent/teslium/energized_jelly
name = "Energized Jelly"
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 7ce23f0c061f..b4d7d89552f9 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -75,12 +75,6 @@
toxpwr = initial(toxpwr)
return ..()
-/datum/reagent/toxin/plasma/reaction_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
- return 0
- var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("plasma=[reac_volume];TEMP=[temp]")
-
/datum/reagent/toxin/plasma/reaction_turf(turf/open/T, reac_volume)
if(istype(T))
var/temp = holder ? holder.chem_temp : T20C
@@ -415,6 +409,13 @@
glass_desc = "A drink that is guaranteed to knock you silly."
var/list/paralyzeparts = list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_R_LEG, TRAIT_PARALYSIS_L_LEG)
+/datum/reagent/toxin/staminatoxin/neurotoxin_alien/reaction_mob(mob/living/M, methods, reac_volume, show_message, permeability)
+ . = ..()
+ var/amount = round(max(reac_volume * clamp(permeability, 0, 1), 0.1))
+ if(amount >= 0.5 && !isalien(M))
+ M.reagents.add_reagent(type, amount)
+ M.apply_damage(reac_volume / 2, TOX, null, (1 - permeability) * 100)
+
/datum/reagent/toxin/staminatoxin/neurotoxin_alien/proc/pickparalyze()
var/selected = pick(paralyzeparts)
paralyzeparts -= selected
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index 438f9b78b3ca..c2a3ce9a7647 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -50,7 +50,7 @@
/datum/chemical_reaction/glycerol
name = "Glycerol"
id = /datum/reagent/glycerol
- results = list(/datum/reagent/glycerol = 1)
+ results = list(/datum/reagent/glycerol = 3)
required_reagents = list(/datum/reagent/consumable/cornoil = 3, /datum/reagent/toxin/acid = 1)
/datum/chemical_reaction/sodiumchloride
diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
index c924ef3ab58d..0cc6b163262d 100644
--- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
+++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
@@ -119,10 +119,10 @@
/datum/chemical_reaction/emp_pulse/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
- // 100 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades.
- // 200 created volume = 16 heavy range & 28 light range. 12 tiles larger than traitor EMP grenades. This is the maximum
+ // 100 created volume = 8 severity & 14 range. 4 tiles larger than traitor EMP grenades.
+ // 200 created volume = 16 (capped to 10) severity & 28 range. 12 tiles larger than traitor EMP grenades. This is the maximum
created_volume = min(created_volume, 200)
- empulse(location, round(created_volume / 12), round(created_volume / 7), 1)
+ empulse(location, min(round(created_volume / 12), EMP_HEAVY), round(created_volume / 7), 1)
holder.clear_reagents()
diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
index 1eba0a7713dc..bd67368f4b60 100644
--- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm
+++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm
@@ -291,8 +291,7 @@
if(holder && holder.my_atom)
var/turf/open/T = get_turf(holder.my_atom)
if(istype(T))
- var/datum/gas/gastype = /datum/gas/nitrogen
- T.atmos_spawn_air("[initial(gastype.id)]=50;TEMP=2.7")
+ T.atmos_spawn_air("n2=50;TEMP=2.7")
/datum/chemical_reaction/slime/slimefireproof
name = "Slime Fireproof"
@@ -355,7 +354,7 @@
required_other = TRUE
/datum/chemical_reaction/slime/slimeoverload/on_reaction(datum/reagents/holder, created_volume)
- empulse(get_turf(holder.my_atom), 3, 7)
+ empulse(get_turf(holder.my_atom), 7)
..()
/datum/chemical_reaction/slime/slimecell
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 300172d49e3f..72f0eaa5552a 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -125,6 +125,8 @@
if(QDELETED(src))
return
+ if(!isturf(target)) // it all ends up on the floor because gravity exists
+ reagents.reaction(get_turf(target), TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 4203c4f99a16..e2b70279b436 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -68,10 +68,13 @@
/obj/machinery/disposal/LateInitialize()
//this will get a copy of the air turf and take a SEND PRESSURE amount of air from it
var/atom/L = loc
+ var/datum/gas_mixture/loc_air = L.return_air()
var/datum/gas_mixture/env = new
- env.copy_from(L.return_air())
- var/datum/gas_mixture/removed = env.remove(SEND_PRESSURE + 1)
- air_contents.merge(removed)
+ if(loc_air)
+ env.copy_from(loc_air)
+ var/datum/gas_mixture/removed = env.remove(SEND_PRESSURE + 1)
+ if(removed)
+ air_contents.merge(removed)
trunk_check()
/obj/machinery/disposal/attackby(obj/item/I, mob/user, params)
@@ -416,14 +419,12 @@
var/datum/gas_mixture/env = L.return_air()
var/pressure_delta = (SEND_PRESSURE*1.01) - air_contents.return_pressure()
- if(env.return_temperature() > 0)
+ if(env?.return_temperature() > 0)
var/transfer_moles = 0.05 * delta_time * pressure_delta*air_contents.return_volume()/(env.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = env.remove(transfer_moles)
air_contents.merge(removed)
- air_update_turf()
-
//if full enough, switch to ready mode
if(air_contents.return_pressure() >= SEND_PRESSURE)
diff --git a/code/modules/recycling/disposal/holder.dm b/code/modules/recycling/disposal/holder.dm
index 9fb68ed63de1..faff4adf8df9 100644
--- a/code/modules/recycling/disposal/holder.dm
+++ b/code/modules/recycling/disposal/holder.dm
@@ -122,7 +122,6 @@
// called to vent all gas in holder to a location
/obj/structure/disposalholder/proc/vent_gas(turf/T)
T.assume_air(gas)
- T.air_update_turf()
/obj/structure/disposalholder/AllowDrop()
return TRUE
diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm
index 5db8177c36bb..9b5a012ee9cd 100644
--- a/code/modules/research/designs/mecha_designs.dm
+++ b/code/modules/research/designs/mecha_designs.dm
@@ -555,7 +555,7 @@
category = list("Exosuit Equipment")
/datum/design/mech_rocket_fist
- name = "Exosuit Weapon (DD-2 \"Atom Smasher\" Rocket Fist)"
+ name = "Exosuit Weapon (RS-77 \"Atom Smasher\" Rocket Fist)"
id = "mech_rocket_fist"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_equipment/melee_weapon/rocket_fist
@@ -575,7 +575,7 @@
combat_design = TRUE
/datum/design/mech_katana
- name = "Exosuit Weapon (OWM-5 \"Ronin\" katana)"
+ name = "Exosuit Weapon (HR-2 \"Ronin\" katana)"
id = "mech_katana"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_equipment/melee_weapon/sword/katana
@@ -605,7 +605,7 @@
combat_design = TRUE
/datum/design/mech_maul
- name = "Exosuit Weapon (CX-22 \"Barbatos\" heavy maul)"
+ name = "Exosuit Weapon (ASW-8 \"Barbatos\" heavy maul)"
id = "mech_maul"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_equipment/melee_weapon/sword/maul
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index f44d3910e13b..eb8ec7b9a1af 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -387,7 +387,7 @@
name = "Chemical Analyzer Implant"
desc = "These cybernetic eye implants will allow rapid identification of reagents. Wiggle eyes to control."
id = "ci-scihud"
- build_type = MECHFAB
+ build_type = PROTOLATHE | MECHFAB
construction_time = 50
materials = list(/datum/material/iron = 600, /datum/material/glass = 600, /datum/material/silver = 600, /datum/material/gold = 600, /datum/material/plastic = 150)
build_path = /obj/item/organ/cyberimp/eyes/hud/science
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index 8f6fb3455382..1f34dfb329b7 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -369,7 +369,7 @@
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
autoexperiment = 0
visible_message(span_warning("[src] melts [exp_on], ionizing the air around it!"))
- empulse(loc, 4, 6)
+ empulse(loc, 6)
investigate_log("Experimentor has generated an Electromagnetic Pulse.", INVESTIGATE_EXPERIMENTOR)
ejectItem(TRUE)
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -407,15 +407,7 @@
autoexperiment = 0
visible_message(span_warning("[src] malfunctions, melting [exp_on] and leaking hot air!"))
var/datum/gas_mixture/env = loc.return_air()
- var/transfer_moles = 0.25 * env.total_moles()
- var/datum/gas_mixture/removed = env.remove(transfer_moles)
- if(removed)
- var/heat_capacity = removed.heat_capacity()
- if(heat_capacity == 0 || heat_capacity == null)
- heat_capacity = 1
- removed.set_temperature(min((removed.return_temperature()*heat_capacity + 100000)/heat_capacity, 1000))
- env.merge(removed)
- air_update_turf()
+ env.adjust_heat(100000)
investigate_log("Experimentor has released hot air.", INVESTIGATE_EXPERIMENTOR)
ejectItem(TRUE)
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
@@ -457,15 +449,7 @@
autoexperiment = 0
visible_message(span_warning("[src] malfunctions, shattering [exp_on] and leaking cold air!"))
var/datum/gas_mixture/env = loc.return_air()
- var/transfer_moles = 0.25 * env.total_moles()
- var/datum/gas_mixture/removed = env.remove(transfer_moles)
- if(removed)
- var/heat_capacity = removed.heat_capacity()
- if(heat_capacity == 0 || heat_capacity == null)
- heat_capacity = 1
- removed.set_temperature((removed.return_temperature()*heat_capacity - 75000)/heat_capacity)
- env.merge(removed)
- air_update_turf()
+ env.adjust_heat(-75000)
investigate_log("Experimentor has released cold air.", INVESTIGATE_EXPERIMENTOR)
ejectItem(TRUE)
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
diff --git a/code/modules/research/nanites/nanite_programs.dm b/code/modules/research/nanites/nanite_programs.dm
index cd6be3b94dba..a3751a0d4dd5 100644
--- a/code/modules/research/nanites/nanite_programs.dm
+++ b/code/modules/research/nanites/nanite_programs.dm
@@ -194,7 +194,7 @@
/datum/nanite_program/proc/on_emp(severity)
if(program_flags & NANITE_EMP_IMMUNE)
return
- if(prob(80 / severity))
+ if(prob(8 * severity))
software_error()
/datum/nanite_program/proc/on_shock(shock_damage)
diff --git a/code/modules/research/nanites/nanite_programs/suppression.dm b/code/modules/research/nanites/nanite_programs/suppression.dm
index a551fb88cff3..eb4ffea03d4c 100644
--- a/code/modules/research/nanites/nanite_programs/suppression.dm
+++ b/code/modules/research/nanites/nanite_programs/suppression.dm
@@ -27,7 +27,7 @@
/datum/nanite_program/triggered/shocking/trigger()
if(!..())
return
- host_mob.electrocute_act(rand(5,10), "shock nanites", TRUE, TRUE)
+ host_mob.electrocute_act(rand(5,10), "shock nanites", TRUE, zone=null, override=TRUE) // external protection can't save you from being shocked on the inside
/datum/nanite_program/triggered/stun
name = "Neural Shock"
diff --git a/code/modules/research/nanites/nanite_programs/weapon.dm b/code/modules/research/nanites/nanite_programs/weapon.dm
index 2590b8980f49..6e5c8fb3380c 100644
--- a/code/modules/research/nanites/nanite_programs/weapon.dm
+++ b/code/modules/research/nanites/nanite_programs/weapon.dm
@@ -134,7 +134,7 @@
/datum/nanite_program/triggered/emp/trigger()
if(!..())
return
- empulse(host_mob, 1, 2)
+ empulse(host_mob, EMP_HEAVY, 2)
/datum/nanite_program/pyro/active_effect()
host_mob.adjust_fire_stacks(1)
diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm
index 66f20944c3ad..b142be514f63 100644
--- a/code/modules/research/server.dm
+++ b/code/modules/research/server.dm
@@ -22,7 +22,7 @@
var/server_id = 0
var/base_mining_income = 2
var/current_temp = 0
- var/heat_gen = 100
+ var/heat_gen = 1
var/heating_power = 40000
var/delay = 5
var/temp_tolerance_low = 0
@@ -48,7 +48,7 @@
var/tot_rating = 0
for(var/obj/item/stock_parts/SP in src)
tot_rating += SP.rating
- heat_gen /= max(1, tot_rating)
+ heat_gen = initial(src.heat_gen) / max(1, tot_rating)
/obj/machinery/rnd/server/update_icon_state()
. = ..()
@@ -71,6 +71,24 @@
. = ..()
refresh_working()
+/obj/machinery/rnd/server/process()
+ if(!working)
+ current_temp = -1
+ return
+ var/turf/L = get_turf(src)
+ var/datum/gas_mixture/env
+ if(istype(L))
+ env = L.return_air()
+ // This is from the RD server code. It works well enough but I need to move over the
+ // sspace heater code so we can caculate power used per tick as well and making this both
+ // exothermic and an endothermic component
+ if(env)
+ var/perc = max((get_env_temp() - temp_tolerance_high), 0) * temp_penalty_coefficient / base_mining_income
+
+ env.adjust_heat(heating_power * perc * heat_gen)
+ else
+ current_temp = env ? env.return_temperature() : -1
+
/obj/machinery/rnd/server/proc/refresh_working()
if(stat & EMPED || research_disabled || stat & NOPOWER)
working = FALSE
@@ -78,12 +96,12 @@
working = TRUE
update_appearance(UPDATE_ICON)
-/obj/machinery/rnd/server/emp_act()
+/obj/machinery/rnd/server/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
stat |= EMPED
- addtimer(CALLBACK(src, PROC_REF(unemp)), 600)
+ addtimer(CALLBACK(src, PROC_REF(unemp)), (6 * severity) SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
refresh_working()
/obj/machinery/rnd/server/proc/unemp()
@@ -103,30 +121,9 @@
/obj/machinery/rnd/server/proc/get_env_temp()
var/turf/L = loc
if(isturf(L))
- return L.temperature
+ return L.return_temperature()
return 0
-/obj/machinery/rnd/server/proc/produce_heat(heat_amt)
- if(!(stat & (NOPOWER|BROKEN))) //Blatently stolen from space heater.
- var/turf/L = loc
- if(istype(L))
- var/datum/gas_mixture/env = L.return_air()
- if(env.return_temperature() < (heat_amt+T0C))
-
- var/transfer_moles = 0.25 * env.total_moles()
-
- var/datum/gas_mixture/removed = env.remove(transfer_moles)
-
- if(removed)
-
- var/heat_capacity = removed.heat_capacity()
- if(heat_capacity == 0 || heat_capacity == null)
- heat_capacity = 1
- removed.set_temperature(min((removed.return_temperature()*heat_capacity + heating_power)/heat_capacity, 1000))
-
- env.merge(removed)
- air_update_turf()
-
/proc/fix_noid_research_servers()
var/list/no_id_servers = list()
var/list/server_ids = list()
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 23b572e75772..90f1a0fe30fc 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -974,7 +974,7 @@
/datum/techweb_node/mech_rocket_fist
id = "mech_rocket_fist"
- display_name = "Exosuit Weapon (DD-2 \"Atom Smasher\" Rocket Fist)"
+ display_name = "Exosuit Weapon (RS-77 \"Atom Smasher\" Rocket Fist)"
description = "An advanced piece of mech weaponry"
prereq_ids = list("adv_mecha","weaponry")
design_ids = list("mech_rocket_fist")
@@ -990,7 +990,7 @@
/datum/techweb_node/mech_katana
id = "mech_katana"
- display_name = "Exosuit Weapon (OWM-5 \"Ronin\" katana)"
+ display_name = "Exosuit Weapon (HR-2 \"Ronin\" katana)"
description = "An advanced piece of mech weaponry"
prereq_ids = list("adv_mecha","mech_shortsword")
design_ids = list("mech_katana")
@@ -1014,7 +1014,7 @@
/datum/techweb_node/mech_maul
id = "mech_maul"
- display_name = "Exosuit Weapon (CX-22 \"Barbatos\" heavy maul)"
+ display_name = "Exosuit Weapon (ASW-8 \"Barbatos\" heavy maul)"
description = "An advanced piece of mech weaponry"
prereq_ids = list("adv_mecha","mech_shortsword")
design_ids = list("mech_maul")
diff --git a/code/modules/research/xenobiology/crossbreeding/_structures.dm b/code/modules/research/xenobiology/crossbreeding/_structures.dm
index 32243aeb67a1..b10ef0549a87 100644
--- a/code/modules/research/xenobiology/crossbreeding/_structures.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_structures.dm
@@ -145,7 +145,6 @@ GLOBAL_LIST_EMPTY(bluespace_slime_crystals)
return
var/datum/gas_mixture/gas = T.return_air()
gas.set_temperature(T0C + 200)
- T.air_update_turf()
/obj/structure/slime_crystal/purple
colour = "purple"
@@ -185,7 +184,6 @@ GLOBAL_LIST_EMPTY(bluespace_slime_crystals)
continue
var/datum/gas_mixture/gas = T.return_air()
gas.parse_gas_string(OPENTURF_DEFAULT_ATMOS)
- T.air_update_turf()
/obj/structure/slime_crystal/metal
colour = "metal"
@@ -232,8 +230,8 @@ GLOBAL_LIST_EMPTY(bluespace_slime_crystals)
return
var/turf/open/open_turf = T
var/datum/gas_mixture/air = open_turf.return_air()
- if(air.get_moles(/datum/gas/plasma) > 15)
- air.adjust_moles(/datum/gas/plasma, -15)
+ if(air.get_moles(GAS_PLASMA) > 15)
+ air.adjust_moles(GAS_PLASMA, -15)
new /obj/item/stack/sheet/mineral/plasma(open_turf)
/obj/structure/slime_crystal/darkpurple/Destroy()
diff --git a/code/modules/research/xenobiology/crossbreeding/chilling.dm b/code/modules/research/xenobiology/crossbreeding/chilling.dm
index 6a8b00f734d7..16c1bc5b90e8 100644
--- a/code/modules/research/xenobiology/crossbreeding/chilling.dm
+++ b/code/modules/research/xenobiology/crossbreeding/chilling.dm
@@ -107,9 +107,8 @@ Chilling extracts:
for(var/turf/open/T in A)
var/datum/gas_mixture/G = T.air
if(istype(G))
- G.set_moles(/datum/gas/plasma, 0)
+ G.set_moles(GAS_PLASMA, 0)
filtered = TRUE
- T.air_update_turf()
if(filtered)
user.visible_message(span_notice("Cracks spread throughout [src], and some air is sucked in!"))
else
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index 00ce26f5d727..3f8e9b2dea74 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -279,7 +279,7 @@
if(SLIME_ACTIVATE_MAJOR)
user.visible_message(span_warning("[user]'s skin starts flashing intermittently..."), span_warning("Your skin starts flashing intermittently..."))
if(do_after(user, 2.5 SECONDS, user))
- empulse(user, 1, 2)
+ empulse(user, EMP_HEAVY, 2)
user.visible_message(span_warning("[user]'s skin flashes!"), span_warning("Your skin flashes as you emit an electromagnetic pulse!"))
return 600
diff --git a/code/modules/security_levels/security_level_datums.dm b/code/modules/security_levels/security_level_datums.dm
new file mode 100644
index 000000000000..586e0b049df1
--- /dev/null
+++ b/code/modules/security_levels/security_level_datums.dm
@@ -0,0 +1,121 @@
+/**
+ * Security levels
+ *
+ * These are used by the security level subsystem. Each one of these represents a security level that a player can set.
+ *
+ * Base type is abstract
+ */
+
+/datum/security_level
+ /// The name of this security level.
+ var/name = "not set"
+ /// The color of our announcement divider.
+ var/announcement_color = "default"
+ /// The numerical level of this security level, see defines for more information.
+ var/number_level = -1
+ /// The sound that we will play when this security level is set
+ var/sound
+ /// The looping sound that will be played while the security level is set
+ var/looping_sound
+ /// The looping sound interval
+ var/looping_sound_interval
+ /// The shuttle call time modification of this security level
+ var/shuttle_call_time_mod = 0
+ /// Our announcement when lowering to this level
+ var/lowering_to_announcement
+ /// Our announcement when elevating to this level
+ var/elevating_to_announcement
+ /// Our configuration key for lowering to text, if set, will override the default lowering to announcement.
+ var/lowering_to_configuration_key
+ /// Our configuration key for elevating to text, if set, will override the default elevating to announcement.
+ var/elevating_to_configuration_key
+
+/datum/security_level/New()
+ . = ..()
+ if(lowering_to_configuration_key) // I'm not sure about you, but isn't there an easier way to do this?
+ lowering_to_announcement = global.config.Get(lowering_to_configuration_key)
+ if(elevating_to_configuration_key)
+ elevating_to_announcement = global.config.Get(elevating_to_configuration_key)
+
+/**
+ * GREEN
+ *
+ * No threats
+ */
+/datum/security_level/green
+ name = "green"
+ announcement_color = "green"
+ sound = 'sound/misc/notice2.ogg' // Friendly beep
+ number_level = SEC_LEVEL_GREEN
+ lowering_to_configuration_key = /datum/config_entry/string/alert_green
+ shuttle_call_time_mod = ALERT_COEFF_GREEN
+
+/**
+ * BLUE
+ *
+ * Caution advised
+ */
+/datum/security_level/blue
+ name = "blue"
+ announcement_color = "blue"
+ sound = 'sound/misc/notice1.ogg' // Angry alarm
+ number_level = SEC_LEVEL_BLUE
+ lowering_to_configuration_key = /datum/config_entry/string/alert_blue_downto
+ elevating_to_configuration_key = /datum/config_entry/string/alert_blue_upto
+ shuttle_call_time_mod = ALERT_COEFF_BLUE
+
+/**
+ * RED
+ *
+ * Hostile threats
+ */
+/datum/security_level/red
+ name = "red"
+ announcement_color = "red"
+ sound = 'sound/misc/notice4.ogg' // More angry alarm
+ number_level = SEC_LEVEL_RED
+ lowering_to_configuration_key = /datum/config_entry/string/alert_red_downto
+ elevating_to_configuration_key = /datum/config_entry/string/alert_red_upto
+ shuttle_call_time_mod = ALERT_COEFF_RED
+
+/**
+ * DELTA
+ *
+ * Station destruction is imminent
+ */
+/datum/security_level/delta
+ name = "delta"
+ announcement_color = "purple"
+ sound = 'sound/misc/delta_alert.ogg' // Air alarm to signify importance
+ number_level = SEC_LEVEL_DELTA
+ elevating_to_configuration_key = /datum/config_entry/string/alert_delta
+ shuttle_call_time_mod = ALERT_COEFF_DELTA
+
+
+/**
+ * GAMMA
+ *
+ * Station is not having a very good fun time
+ */
+/datum/security_level/gamma
+ name = "gamma"
+ announcement_color = "orange"
+ sound = 'sound/misc/gamma_alert.ogg'// Air alarm to signify importance
+ number_level = SEC_LEVEL_GAMMA
+ elevating_to_configuration_key = /datum/config_entry/string/alert_gamma
+ shuttle_call_time_mod = ALERT_COEFF_GAMMA
+
+
+
+/**
+ * EPSILON
+ *
+ * Station destruction is here, and you probably caused it, you monster.
+ */
+/datum/security_level/epsilon
+ name = "epsilon"
+ announcement_color = "black"
+ sound = 'sound/misc/epsilon_alert.ogg'// Air alarm to signify importance
+ number_level = SEC_LEVEL_EPSILON
+ elevating_to_configuration_key = /datum/config_entry/string/alert_epsilon
+ shuttle_call_time_mod = ALERT_COEFF_EPSILON
diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm
index bbc0fc405c79..5b98ecb20220 100644
--- a/code/modules/security_levels/security_levels.dm
+++ b/code/modules/security_levels/security_levels.dm
@@ -38,6 +38,7 @@ GLOBAL_VAR_INIT(security_level, SEC_LEVEL_GREEN)
switch(level)
if(SEC_LEVEL_GREEN)
minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:")
+ sound_to_playing_players('sound/misc/notice2.ogg')
if(GLOB.security_level >= SEC_LEVEL_RED)
modTimer = 4
else
@@ -46,6 +47,7 @@ GLOBAL_VAR_INIT(security_level, SEC_LEVEL_GREEN)
if(SEC_LEVEL_BLUE)
if(GLOB.security_level < SEC_LEVEL_BLUE)
minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:", TRUE)
+ sound_to_playing_players('sound/misc/notice1.ogg')
modTimer = 0.5
else
minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:")
@@ -53,7 +55,8 @@ GLOBAL_VAR_INIT(security_level, SEC_LEVEL_GREEN)
if(SEC_LEVEL_RED)
if(GLOB.security_level < SEC_LEVEL_RED)
- minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!", TRUE, custom_alert_sound = 'sound/misc/notice4.ogg')
+ minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!", TRUE)
+ sound_to_playing_players('sound/misc/notice4.ogg')
if(GLOB.security_level == SEC_LEVEL_GREEN)
modTimer = 0.25
else
@@ -81,7 +84,8 @@ GLOBAL_VAR_INIT(security_level, SEC_LEVEL_GREEN)
modTimer = 1
if(SEC_LEVEL_DELTA)
- minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!", TRUE, 'sound/misc/delta_alert.ogg')
+ minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!", TRUE)
+ sound_to_playing_players('sound/misc/delta_alert.ogg')
if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL)
if(GLOB.security_level == SEC_LEVEL_GREEN)
modTimer = 0.25
@@ -104,7 +108,7 @@ GLOBAL_VAR_INIT(security_level, SEC_LEVEL_GREEN)
D.visible_message(span_notice("[D] whirrs as it automatically lifts access requirements!"))
playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE)
- if(level >= SEC_LEVEL_GAMMA)
+ if(level == SEC_LEVEL_DELTA)
change_areas_lights_alarm()
else
change_areas_lights_alarm(FALSE)
diff --git a/code/modules/shuttle/docking.dm b/code/modules/shuttle/docking.dm
index bcb066085045..064a424bb7d2 100644
--- a/code/modules/shuttle/docking.dm
+++ b/code/modules/shuttle/docking.dm
@@ -121,6 +121,7 @@
continue
move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode, src) //atoms
+ oldT.beforeShuttleMove(newT)
move_mode = oldT.fromShuttleMove(newT, move_mode) //turfs
move_mode = newT.toShuttleMove(oldT, move_mode, src) //turfs
@@ -130,6 +131,7 @@
old_turfs[oldT] = move_mode
/obj/docking_port/mobile/proc/takeoff(list/old_turfs, list/new_turfs, list/moved_atoms, rotation, movement_direction, old_dock, area/underlying_old_area)
+
for(var/i in 1 to old_turfs.len)
var/turf/oldT = old_turfs[i]
var/turf/newT = new_turfs[i]
@@ -203,3 +205,9 @@
var/turf/oldT = moved_atoms[moved_object]
moved_object.lateShuttleMove(oldT, movement_force, movement_direction)
+/obj/docking_port/mobile/proc/reset_air()
+ var/list/turfs = return_ordered_turfs(x, y, z, dir)
+ for(var/i in 1 to length(turfs))
+ var/turf/open/T = turfs[i]
+ if(istype(T))
+ T.air.copy_from_turf(T)
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 33401e5e99b3..5fcbabf67bd0 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -452,7 +452,8 @@
destination_dock = "emergency_syndicate"
minor_announce("Corruption detected in \
shuttle navigation protocols. Please contact your \
- supervisor.", "SYSTEM ERROR:", alert=TRUE, custom_alert_sound = 'sound/misc/announce2.ogg')
+ supervisor.", "SYSTEM ERROR:", alert=TRUE)
+ sound_to_playing_players('sound/misc/announce2.ogg')
dock_id(destination_dock)
mode = SHUTTLE_ENDGAME
diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm
index 99be3d6a1f9a..2a02cd5503a7 100644
--- a/code/modules/shuttle/on_move.dm
+++ b/code/modules/shuttle/on_move.dm
@@ -4,6 +4,10 @@ All ShuttleMove procs go here
/************************************Base procs************************************/
+/turf/proc/beforeShuttleMove(turf/newT)
+ clear_adjacencies()
+ newT.clear_adjacencies()
+
// Called on every turf in the shuttle region, returns a bitflag for allowed movements of that turf
// returns the new move_mode (based on the old)
/turf/proc/fromShuttleMove(turf/newT, move_mode)
@@ -53,16 +57,7 @@ All ShuttleMove procs go here
if(!shuttle_boundary)
CRASH("A turf queued to move via shuttle somehow had no skipover in baseturfs. [src]([type]):[loc]")
var/depth = baseturfs.len - shuttle_boundary + 1
- newT.CopyOnTop(src, 1, depth, TRUE)
- //Air stuff
- newT.blocks_air = TRUE
- newT.air_update_turf(TRUE)
- blocks_air = TRUE
- air_update_turf(TRUE)
- if(isopenturf(newT))
- var/turf/open/new_open = newT
- new_open.copy_air_with_tile(src)
-
+ newT.CopyOnTop(src, 1, depth, TRUE, CHANGETURF_DEFER_CHANGE)
return TRUE
// Called on the new turf after everything has been moved
@@ -72,7 +67,7 @@ All ShuttleMove procs go here
SSexplosions.wipe_turf(src)
var/shuttle_boundary = baseturfs.Find(/turf/baseturf_skipover/shuttle)
if(shuttle_boundary)
- oldT.ScrapeAway(baseturfs.len - shuttle_boundary + 1)
+ oldT.ScrapeAway(baseturfs.len - shuttle_boundary + 1, CHANGETURF_DEFER_CHANGE)
if(rotation)
shuttleRotate(rotation) //see shuttle_rotate.dm
@@ -80,11 +75,8 @@ All ShuttleMove procs go here
return TRUE
/turf/proc/lateShuttleMove(turf/oldT)
- blocks_air = initial(blocks_air)
- air_update_turf(TRUE)
- oldT.blocks_air = initial(oldT.blocks_air)
- oldT.air_update_turf(TRUE)
-
+ AfterChange(CHANGETURF_RECALC_ADJACENT)
+ oldT.AfterChange(CHANGETURF_RECALC_ADJACENT)
/////////////////////////////////////////////////////////////////////////////////////
@@ -245,17 +237,17 @@ All ShuttleMove procs go here
break
if(!connected)
- nullifyNode(i)
+ nullify_node(i)
if(!nodes[i])
missing_nodes = TRUE
if(missing_nodes)
- atmosinit()
+ atmos_init()
for(var/obj/machinery/atmospherics/A in pipeline_expansion())
- A.atmosinit()
- if(A.returnPipenet())
- A.addMember(src)
+ A.atmos_init()
+ if(A.return_pipenet())
+ A.add_member(src)
SSair.add_to_rebuild_queue(src)
else
// atmosinit() calls update_appearance(UPDATE_ICON), so we don't need to call it
diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm
index c13af51c7769..958c9aa5c5ab 100644
--- a/code/modules/shuttle/shuttle_rotate.dm
+++ b/code/modules/shuttle/shuttle_rotate.dm
@@ -85,13 +85,13 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate
/************************************Machine rotate procs************************************/
/obj/machinery/atmospherics/shuttleRotate(rotation, params)
- var/list/real_node_connect = getNodeConnects()
+ var/list/real_node_connect = get_node_connects()
for(var/i in 1 to device_type)
real_node_connect[i] = angle2dir(rotation+dir2angle(real_node_connect[i]))
. = ..()
- SetInitDirections()
- var/list/supposed_node_connect = getNodeConnects()
+ set_init_directions()
+ var/list/supposed_node_connect = get_node_connects()
var/list/nodes_copy = nodes.Copy()
for(var/i in 1 to device_type)
diff --git a/code/modules/spells/spell_types/self/disable_tech.dm b/code/modules/spells/spell_types/self/disable_tech.dm
index 558e4e6943bf..7def457a89e1 100644
--- a/code/modules/spells/spell_types/self/disable_tech.dm
+++ b/code/modules/spells/spell_types/self/disable_tech.dm
@@ -6,14 +6,14 @@
school = SCHOOL_EVOCATION
- /// The heavy radius of the EMP
- var/emp_heavy = 2
- /// The light radius of the EMP
- var/emp_light = 3
+ /// The severity of the EMP
+ var/severity = EMP_HEAVY
+ /// The radius of the EMP
+ var/radius = 3
/datum/action/cooldown/spell/emp/cast(atom/cast_on)
. = ..()
- empulse(get_turf(cast_on), emp_heavy, emp_light)
+ empulse(get_turf(cast_on), severity, radius)
/datum/action/cooldown/spell/emp/disable_tech
name = "Disable Tech"
@@ -26,5 +26,4 @@
invocation = "NEC CANTIO"
invocation_type = INVOCATION_SHOUT
- emp_heavy = 6
- emp_light = 10
\ No newline at end of file
+ radius = 10
diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm
index 7b22796ef170..eda1348554ec 100644
--- a/code/modules/surgery/bodyparts/_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/_bodyparts.dm
@@ -45,6 +45,7 @@
var/brute_reduction = 0 //Subtracted to brute damage taken
var/burn_reduction = 0 //Subtracted to burn damage taken
+ var/emp_reduction = 0 //Subtracted to EMP severity
//Coloring and proper item icon update
var/skin_tone = ""
@@ -127,6 +128,32 @@
/obj/item/bodypart/blob_act()
take_damage(max_damage)
+/obj/item/bodypart/emp_act(severity, emp_message=TRUE)
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
+ return
+
+ var/blocked = owner.getarmor(body_zone, ENERGY) // energy armor protects against EMPs
+ severity *= (100 - blocked) / 100
+ severity -= emp_reduction
+ if(severity < 1)
+ return
+
+ if(receive_damage(0, severity / 2, severity, FALSE, TRUE, BODYPART_ROBOTIC, CANT_WOUND)) // returns false for non-robotic limbs
+ if(severity > EMP_LIGHT)
+ ADD_TRAIT(src, TRAIT_PARALYSIS, "EMP")
+ addtimer(CALLBACK(src, PROC_REF(after_emp)), min((severity / 2) SECONDS, 5 SECONDS), TIMER_UNIQUE | TIMER_OVERRIDE)
+ if(owner && emp_message)
+ owner.emote("scream")
+ to_chat(src, span_userdanger("You feel a sharp pain as your robotic limbs overload."))
+
+ if(!(. & EMP_PROTECT_CONTENTS))
+ for(var/obj/item/organ/O as anything in get_organs())
+ O.emp_act(severity)
+
+/obj/item/bodypart/proc/after_emp()
+ REMOVE_TRAIT(src, TRAIT_PARALYSIS, "EMP")
+
/obj/item/bodypart/Destroy()
if(owner)
owner.bodyparts -= src
@@ -831,7 +858,7 @@
else
species_color = ""
- if(!dropping_limb && (H.dna.check_mutation(HULK) || H.dna.check_mutation(ACTIVE_HULK)))
+ if(!dropping_limb && (H.dna.check_mutation(HULK)))
mutation_color = "#00aa00"
else
mutation_color = ""
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index 6c972749a473..f49bc0901e32 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -5,7 +5,7 @@
icon_state = "default_human_head"
max_damage = 200
body_zone = BODY_ZONE_HEAD
- body_part = HEAD
+ body_part = HEAD|NECK
w_class = WEIGHT_CLASS_BULKY //Quite a hefty load
slowdown = 1 //Balancing measure
throw_range = 2 //No head bowling
diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm
index 4a48c95c450e..352e8ad18b01 100644
--- a/code/modules/surgery/bodyparts/helpers.dm
+++ b/code/modules/surgery/bodyparts/helpers.dm
@@ -74,10 +74,7 @@
. = 0
for(var/X in bodyparts)
var/obj/item/bodypart/affecting = X
- if(affecting.body_part == ARM_RIGHT)
- if(!check_disabled || !affecting.bodypart_disabled)
- .++
- if(affecting.body_part == ARM_LEFT)
+ if(affecting.body_part & (ARM_RIGHT|ARM_LEFT))
if(!check_disabled || !affecting.bodypart_disabled)
.++
@@ -97,10 +94,7 @@
. = 0
for(var/X in bodyparts)
var/obj/item/bodypart/affecting = X
- if(affecting.body_part == LEG_RIGHT)
- if(!check_disabled || !affecting.bodypart_disabled)
- .++
- if(affecting.body_part == LEG_LEFT)
+ if(affecting.body_part & (LEG_RIGHT|LEG_LEFT))
if(!check_disabled || !affecting.bodypart_disabled)
.++
@@ -290,12 +284,12 @@
var/obj/item/bodypart/O = X
var/obj/item/bodypart/N
if((!O.use_digitigrade && swap_back == FALSE) || (O.use_digitigrade && swap_back == TRUE))
- if(O.body_part == LEG_LEFT)
+ if(O.body_part & LEG_LEFT)
if(swap_back == TRUE)
N = new /obj/item/bodypart/l_leg
else
N = new /obj/item/bodypart/l_leg/digitigrade
- else if(O.body_part == LEG_RIGHT)
+ else if(O.body_part & LEG_RIGHT)
if(swap_back == TRUE)
N = new /obj/item/bodypart/r_leg
else
diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm
index 89d9c76f975f..64bf4b260469 100644
--- a/code/modules/surgery/bodyparts/parts.dm
+++ b/code/modules/surgery/bodyparts/parts.dm
@@ -5,7 +5,7 @@
icon_state = "default_human_chest"
max_damage = 200
body_zone = BODY_ZONE_CHEST
- body_part = CHEST
+ body_part = CHEST|GROIN
px_x = 0
px_y = 0
stam_damage_coeff = 1
@@ -64,7 +64,7 @@
max_damage = 50
max_stamina_damage = 50
body_zone = BODY_ZONE_L_ARM
- body_part = ARM_LEFT
+ body_part = ARM_LEFT|HAND_LEFT
aux_zone = BODY_ZONE_PRECISE_L_HAND
aux_layer = HANDS_PART_LAYER
body_damage_coeff = 0.75
@@ -158,7 +158,7 @@
attack_verb = list("slapped", "punched")
max_damage = 50
body_zone = BODY_ZONE_R_ARM
- body_part = ARM_RIGHT
+ body_part = ARM_RIGHT|HAND_RIGHT
aux_zone = BODY_ZONE_PRECISE_R_HAND
aux_layer = HANDS_PART_LAYER
body_damage_coeff = 0.75
@@ -253,7 +253,7 @@
attack_verb = list("kicked", "stomped")
max_damage = 50
body_zone = BODY_ZONE_L_LEG
- body_part = LEG_LEFT
+ body_part = LEG_LEFT|FOOT_LEFT
body_damage_coeff = 0.75
px_x = -2
px_y = 12
@@ -342,7 +342,7 @@
attack_verb = list("kicked", "stomped")
max_damage = 50
body_zone = BODY_ZONE_R_LEG
- body_part = LEG_RIGHT
+ body_part = LEG_RIGHT|FOOT_RIGHT
body_damage_coeff = 0.75
px_x = 2
px_y = 12
diff --git a/code/modules/surgery/organs/appendix.dm b/code/modules/surgery/organs/appendix.dm
index b600f356e49e..e45511648e94 100644
--- a/code/modules/surgery/organs/appendix.dm
+++ b/code/modules/surgery/organs/appendix.dm
@@ -83,4 +83,5 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- damage += 100/severity
+ if(severity > EMP_LIGHT)
+ damage += 20 * (severity - EMP_HEAVY)
diff --git a/code/modules/surgery/organs/augment_legs.dm b/code/modules/surgery/organs/augment_legs.dm
index ea53e3f59c23..706f430160dc 100644
--- a/code/modules/surgery/organs/augment_legs.dm
+++ b/code/modules/surgery/organs/augment_legs.dm
@@ -23,7 +23,7 @@
if(!L) //how did you get an implant in a limb you don't have?
return
- L.receive_damage(5,0,10) //always take a least a little bit of damage to the leg
+ L.receive_damage(severity / 2, 0, severity) //always take a least a little bit of damage to the leg
if(prob(50)) //you're forced to use two of these for them to work so let's give em a chance to not get completely fucked
if(COOLDOWN_FINISHED(src, emp_notice))
@@ -32,15 +32,15 @@
return
L.set_disabled(TRUE) //disable the bodypart
- addtimer(CALLBACK(src, PROC_REF(reenableleg)), 5 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
+ addtimer(CALLBACK(src, PROC_REF(reenableleg)), (severity / 2) SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
- if(severity & EMP_HEAVY && prob(5) && !syndicate_implant) //put probabilities into a calculator before you try fucking with this
- to_chat(owner, span_warning("The EMP causes your [src] to thrash your [L] around wildly, breaking it!"))
+ if(severity > EMP_LIGHT && prob(5) && !syndicate_implant) //put probabilities into a calculator before you try fucking with this
+ to_chat(owner, span_warning("[src] malfunctions and thrashes your [L] around wildly, breaking it!"))
var/datum/wound/blunt/severe/breakdown = new
breakdown.apply_wound(L)
L.receive_damage(20)
else if(COOLDOWN_FINISHED(src, emp_notice))
- to_chat(owner, span_warning("The EMP causes your [src] to seize up, preventing your [L] from moving!"))
+ to_chat(owner, span_warning("[src] malfunctions and causes your muscles to seize up, preventing your [L] from moving!"))
COOLDOWN_START(src, emp_notice, 30 SECONDS)
/obj/item/organ/cyberimp/leg/proc/reenableleg()
@@ -84,14 +84,6 @@
to_chat(user, span_notice("You modify [src] to be installed on the [zone == BODY_ZONE_R_LEG ? "right" : "left"] leg."))
update_appearance(UPDATE_ICON)
-/obj/item/organ/cyberimp/leg/emp_act(severity)
- . = ..()
- if(. & EMP_PROTECT_SELF)
- return
- if(prob(15/severity) && owner)
- to_chat(owner, span_warning("[src] is hit by EMP!"))
- // give the owner an idea about why his implant is glitching
-
/obj/item/organ/cyberimp/leg/Insert(mob/living/carbon/M, special, drop_if_replaced, special_zone)
. = ..()
if(HasBoth())
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index a7aed9252035..1f018e8918e7 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -67,7 +67,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- if(prob(15/severity) && owner)
+ if(prob(1.5 * severity) && owner)
to_chat(owner, span_warning("[src] is hit by EMP!"))
// give the owner an idea about why his implant is glitching
Retract()
@@ -162,7 +162,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- if(prob(30/severity) && owner && (organ_flags & ORGAN_FAILING))
+ if(prob(3 * severity) && owner && (organ_flags & ORGAN_FAILING))
Retract()
owner.visible_message(span_danger("A loud bang comes from [owner]\'s [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm!"))
playsound(get_turf(owner), 'sound/weapons/flashbang.ogg', 100, 1)
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index 6c7d7c292465..0ab2df136add 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -32,7 +32,8 @@
. = ..()
if(!owner || . & EMP_PROTECT_SELF)
return
- owner.reagents.add_reagent(/datum/reagent/toxin/bad_food, poison_amount / severity)
+ var/existing = owner.reagents.get_reagent_amount(/datum/reagent/toxin/bad_food)
+ owner.reagents.add_reagent(/datum/reagent/toxin/bad_food, (poison_amount * (severity / EMP_HEAVY)) - existing)
to_chat(owner, span_warning("You feel like your insides are burning."))
@@ -102,10 +103,10 @@
if(ishuman(owner) && !syndicate_implant)
var/mob/living/carbon/human/H = owner
- if(H.stat != DEAD && prob(50 / severity) && H.can_heartattack())
+ if(H.stat != DEAD && prob(5 * severity) && H.can_heartattack())
H.set_heartattack(TRUE)
to_chat(H, span_userdanger("You feel a horrible agony in your chest!"))
- addtimer(CALLBACK(src, PROC_REF(undo_heart_attack)), 10 SECONDS / severity)
+ addtimer(CALLBACK(src, PROC_REF(undo_heart_attack)), severity SECONDS)
/obj/item/organ/cyberimp/chest/reviver/proc/undo_heart_attack()
var/mob/living/carbon/human/H = owner
@@ -204,26 +205,16 @@
// Priority 3: use internals tank.
var/obj/item/tank/I = owner.internal
- if(I && I.air_contents && I.air_contents.total_moles() > num)
- var/datum/gas_mixture/removed = I.air_contents.remove(num)
- if(removed.total_moles() > 0.005)
- T.assume_air(removed)
- return 1
- else
- T.assume_air(removed)
+ if(I && I.air_contents && I.air_contents.total_moles() >= num)
+ T.assume_air_moles(I.air_contents, num)
toggle(silent = TRUE)
return 0
/obj/item/organ/cyberimp/chest/thrusters/emp_act(severity)
. = ..()
- switch(severity)
- if(EMP_HEAVY)
- owner.adjustFireLoss(35)
- to_chat(owner, span_warning("Your thruster implant malfunctions and severely burns you!"))
- if(EMP_LIGHT)
- owner.adjustFireLoss(10)
- to_chat(owner, span_danger("Your thruster implant malfunctions and mildly burns you!"))
+ owner.adjustFireLoss(3 * severity)
+ to_chat(owner, span_warning("Your thruster implant malfunctions and severely burns you!"))
/obj/item/organ/cyberimp/chest/spinalspeed
name = "neural overclocker implant"
@@ -340,27 +331,17 @@
/obj/item/organ/cyberimp/chest/spinalspeed/emp_act(severity)
. = ..()
if(!syndicate_implant)//the toy has a different emp act
- owner.adjust_dizzy(10 SECONDS / severity)
+ owner.adjust_dizzy(severity SECONDS)
to_chat(owner, span_warning("Your spinal implant makes you feel queasy!"))
return
- switch(severity)//i don't want emps to just be damage again, that's boring
- if(EMP_HEAVY)
- owner.set_drugginess(40)
- owner.adjust_hallucinations(500 SECONDS)
- owner.blur_eyes(20)
- owner.adjust_dizzy(10 SECONDS)
- time_on += 10
- owner.adjustFireLoss(10)
- to_chat(owner, span_warning("Your spinal implant malfunctions and you feel it scramble your brain!"))
- if(EMP_LIGHT)
- owner.set_drugginess(20)
- owner.adjust_hallucinations(200 SECONDS)
- owner.blur_eyes(10)
- owner.adjust_dizzy(5 SECONDS)
- time_on += 5
- owner.adjustFireLoss(5)
- to_chat(owner, span_danger("Your spinal implant malfunctions and you suddenly feel... wrong."))
+ owner.set_drugginess(4 * severity)
+ owner.adjust_hallucinations((50 * severity) SECONDS)
+ owner.blur_eyes(2 * severity)
+ owner.adjust_dizzy(severity SECONDS)
+ time_on += severity
+ owner.adjustFireLoss(severity)
+ to_chat(owner, span_warning("Your spinal implant malfunctions and you feel it scramble your brain!"))
/obj/item/organ/cyberimp/chest/spinalspeed/toy
name = "glowy after-image trail implant"
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index 7f340058b76c..87bdd6505488 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -36,7 +36,7 @@
. = ..()
if(!owner || . & EMP_PROTECT_SELF)
return
- owner.Stun(stun_amount / severity)
+ owner.Stun(stun_amount * (severity / EMP_HEAVY))
to_chat(owner, span_warning("Your body seizes up!"))
@@ -74,13 +74,12 @@
. = ..()
if(!owner || . & EMP_PROTECT_SELF)
return
- var/range = severity ? 10 : 5
var/atom/A
if(active)
release_items()
for(var/obj/item/I in stored_items)
- A = pick(oview(range))
- I.throw_at(A, range, 2)
+ A = pick(oview(severity))
+ I.throw_at(A, severity, 2)
to_chat(owner, span_warning("Your [owner.get_held_index_name(owner.get_held_index_of_item(I))] spasms and throws the [I.name]!"))
stored_items = list()
@@ -138,7 +137,7 @@
if((organ_flags & ORGAN_FAILING) || . & EMP_PROTECT_SELF)
return
organ_flags |= ORGAN_FAILING
- addtimer(CALLBACK(src, PROC_REF(reboot)), stun_cap_amount * 2 / severity)
+ addtimer(CALLBACK(src, PROC_REF(reboot)), stun_cap_amount * (severity / 5))
/obj/item/organ/cyberimp/brain/anti_stun/proc/reboot()
clear_stuns()
@@ -183,7 +182,7 @@
. = ..()
if(!owner || . & EMP_PROTECT_SELF)
return
- if(prob(60/severity))
+ if(prob(6 * severity))
to_chat(owner, span_warning("Your breathing tube suddenly closes!"))
owner.losebreath += 2
diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm
index cd5364d44b42..0c3b10aaf071 100644
--- a/code/modules/surgery/organs/ears.dm
+++ b/code/modules/surgery/organs/ears.dm
@@ -157,15 +157,11 @@
compatible_biotypes = MOB_ROBOTIC // for IPCs
/obj/item/organ/ears/robot/emp_act(severity)
- switch(severity)
- if(1)
- owner.adjust_jitter(30 SECONDS)
- owner.adjust_dizzy(30)
- owner.Knockdown(5 SECONDS)
- deaf = 30
- to_chat(owner, span_warning("Your robotic ears are uselessly ringing."))
- if(2)
- owner.adjust_jitter(15 SECONDS)
- owner.adjust_dizzy(15)
- owner.Knockdown(10 SECONDS)
- to_chat(owner, span_warning("Your robotic ears buzz."))
+ owner.adjust_jitter(3 * severity)
+ owner.adjust_dizzy(3 * severity)
+ owner.Knockdown(severity SECONDS)
+ if(severity > EMP_LIGHT)
+ deaf = 3 * severity
+ to_chat(owner, span_warning("Your robotic ears are uselessly ringing."))
+ return
+ to_chat(owner, span_warning("Your robotic ears buzz."))
diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm
index 78b7b6d14d72..b295459a9090 100644
--- a/code/modules/surgery/organs/eyes.dm
+++ b/code/modules/surgery/organs/eyes.dm
@@ -171,12 +171,11 @@
. = ..()
if(!owner || . & EMP_PROTECT_SELF)
return
- var/obj/item/organ/eyes/eyes = owner.getorganslot(ORGAN_SLOT_EYES)
to_chat(owner, span_danger("your eyes overload and blind you!"))
owner.flash_act(override_blindness_check = 1)
- owner.blind_eyes(5)
+ owner.blind_eyes(severity / 2)
owner.blur_eyes(8)
- eyes.applyOrganDamage(20 / severity)
+ applyOrganDamage(2 * severity)
/obj/item/organ/eyes/robotic/xray
name = "\improper meson eyes"
@@ -377,7 +376,7 @@
on_mob.forceMove(scanning)
for(var/i in 1 to light_beam_distance)
scanning = get_step(scanning, scandir)
- if(scanning.opacity || scanning.has_opaque_atom)
+ if(IS_OPAQUE_TURF(scanning))
stop = TRUE
var/obj/effect/abstract/eye_lighting/L = LAZYACCESS(eye_lighting, i)
if(stop)
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index a61aa75c800c..c121ae5f79d1 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -239,8 +239,9 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- Stop()
- addtimer(CALLBACK(src, PROC_REF(Restart)), restartTimer/severity) //Can restart itself after an EMP so it isnt an insta death
+ if(severity > EMP_LIGHT)
+ Stop()
+ addtimer(CALLBACK(src, PROC_REF(Restart)), restartTimer * min(severity / EMP_HEAVY, 1)) //Can restart itself after an EMP so it isnt an insta death
/obj/item/organ/heart/cybernetic/upgraded
name = "upgraded cybernetic heart"
@@ -266,12 +267,12 @@
/obj/item/organ/heart/cybernetic/ipc
desc = "An electronic device that appears to mimic the functions of an organic heart."
-/obj/item/organ/heart/cybernetic/ipc/emp_act()
+/obj/item/organ/heart/cybernetic/ipc/emp_act(severity)
if(prob(30))
return
. = ..()
to_chat(owner, "Alert: Cybernetic heart failed one heartbeat ")
- addtimer(CALLBACK(src, PROC_REF(Restart)), 10 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(Restart)), severity SECONDS)
/obj/item/organ/heart/freedom
name = "heart of freedom"
diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm
index 05d0775c9163..b57493a2f019 100755
--- a/code/modules/surgery/organs/liver.dm
+++ b/code/modules/surgery/organs/liver.dm
@@ -117,8 +117,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
-
- damage += 50/severity
+ applyOrganDamage(5 * severity)
/obj/item/organ/liver/cybernetic/upgraded/ipc
name = "substance processor"
@@ -135,4 +134,4 @@
if(prob(10))
return
to_chat(owner, "Alert: Your Substance Processor has been damaged. An internal chemical leak is affecting performance. ")
- owner.adjustToxLoss(10/severity)
+ owner.adjustToxLoss(severity)
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index a0febe43a2fb..36ee323f11b9 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -18,36 +18,37 @@
//Breath damage
- var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
- var/safe_oxygen_max = 0
- var/safe_nitro_min = 0
- var/safe_nitro_max = 0
- var/safe_co2_min = 0
- var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
- var/safe_toxins_min = 0
- var/safe_toxins_max = 0.05
- var/SA_para_min = 1 //Sleeping agent
- var/SA_sleep_min = 5 //Sleeping agent
+ var/breathing_class = BREATH_OXY // can be a gas instead of a breathing class
+ var/safe_breath_min = 16
+ var/safe_breath_max = 50
+ var/safe_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
+ var/safe_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
+ var/safe_damage_type = OXY
+ var/list/gas_min = list()
+ var/list/gas_max = list(
+ GAS_CO2 = 30, // Yes it's an arbitrary value who cares?
+ GAS_PLASMA = MOLES_GAS_VISIBLE,
+ )
+ var/list/gas_damage = list(
+ "default" = list(
+ min = MIN_TOXIC_GAS_DAMAGE,
+ max = MAX_TOXIC_GAS_DAMAGE,
+ damage_type = OXY,
+ ),
+ GAS_PLASMA = list(
+ min = MIN_TOXIC_GAS_DAMAGE,
+ max = MAX_TOXIC_GAS_DAMAGE,
+ damage_type = TOX,
+ )
+ )
+
+ var/SA_para_min = 1 //nitrous values
+ var/SA_sleep_min = 5
var/BZ_trip_balls_min = 1 //BZ gas
var/gas_stimulation_min = 0.002 // Nitrium, Freon and Hyper-noblium
- ///list of gasses that can be used in place of oxygen and the amount they are multiplied by, i.e. 1 pp pluox = 8 pp oxygen
- var/list/oxygen_substitutes = list(/datum/gas/pluoxium = 8)
- //Whether helium speech effects are currently active
+ /// Whether helium speech effects are currently active
var/helium_speech = FALSE
- var/oxy_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
- var/oxy_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
- var/oxy_damage_type = OXY
- var/nitro_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
- var/nitro_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
- var/nitro_damage_type = OXY
- var/co2_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
- var/co2_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
- var/co2_damage_type = OXY
- var/tox_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
- var/tox_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
- var/tox_damage_type = TOX
-
var/cold_message = "your face freezing and an icicle forming"
var/cold_level_1_threshold = 260
var/cold_level_2_threshold = 200
@@ -68,8 +69,26 @@
var/crit_stabilizing_reagent = /datum/reagent/medicine/epinephrine
+/obj/item/organ/lungs/Initialize(mapload)
+ . = ..()
+ populate_gas_info()
+
+/obj/item/organ/lungs/proc/populate_gas_info()
+ gas_min[breathing_class] = safe_breath_min
+ gas_max[breathing_class] = safe_breath_max
+ gas_damage[breathing_class] = list(
+ min = safe_breath_dam_min,
+ max = safe_breath_dam_max,
+ damage_type = safe_damage_type
+ )
+ if(ispath(breathing_class))
+ var/datum/breathing_class/class = GLOB.gas_data.breathing_classes[breathing_class]
+ for(var/g in class.gases)
+ if(class.gases[g] > 0)
+ gas_min -= g
/obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
+ var/breathModifier = (5-(5*(damage/maxHealth)/2)) //range 2.5 - 5
if(H.status_flags & GODMODE)
return
if(HAS_TRAIT(H, TRAIT_NOBREATH))
@@ -84,167 +103,131 @@
H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
H.failed_last_breath = TRUE
- if(safe_oxygen_min)
- if(isipc(H))
- H.throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy/ipc)
- else
- H.throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy)
- else if(safe_toxins_min)
- H.throw_alert("not_enough_tox", /atom/movable/screen/alert/not_enough_tox)
- else if(safe_co2_min)
- H.throw_alert("not_enough_co2", /atom/movable/screen/alert/not_enough_co2)
- else if(safe_nitro_min)
- H.throw_alert("not_enough_nitro", /atom/movable/screen/alert/not_enough_nitro)
- return FALSE
-
- var/gas_breathed = 0
- var/eff = get_organ_efficiency()
-
- //Partial pressures in our breath
- var/O2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/oxygen))
- for(var/i in oxygen_substitutes)
- O2_pp += oxygen_substitutes[i] * breath.get_breath_partial_pressure(breath.get_moles(i))
- var/N2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrogen))
- var/Toxins_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
- var/CO2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/carbon_dioxide))
-
-
- //-- OXY --//
-
- //Too much oxygen! //Yes, some species may not like it.
- if(safe_oxygen_max)
- if(O2_pp > safe_oxygen_max)
- var/ratio = (breath.get_moles(/datum/gas/oxygen)/safe_oxygen_max) * 10
- H.apply_damage_type(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
- H.throw_alert("too_much_oxy", /atom/movable/screen/alert/too_much_oxy)
- else
- H.clear_alert("too_much_oxy")
-
- //Too little oxygen!
- if(safe_oxygen_min)
- if(O2_pp < safe_oxygen_min)
- gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath.get_moles(/datum/gas/oxygen))
- H.throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy)
+ var/alert_category
+ var/alert_type
+ if(ispath(breathing_class))
+ var/datum/breathing_class/class = GLOB.gas_data.breathing_classes[breathing_class]
+ alert_category = class.low_alert_category
+ alert_type = class.low_alert_datum
else
- H.failed_last_breath = FALSE
- if(H.health >= H.crit_threshold)
- H.adjustOxyLoss(-5 * eff)
- gas_breathed = breath.get_moles(/datum/gas/oxygen)
- H.clear_alert("not_enough_oxy")
+ var/list/breath_alert_info = GLOB.gas_data.breath_alert_info
+ if(breathing_class in breath_alert_info)
+ var/list/alert = breath_alert_info[breathing_class]["not_enough_alert"]
+ alert_category = alert["alert_category"]
+ alert_type = alert["alert_type"]
+ if(alert_category)
+ H.throw_alert(alert_category, alert_type)
+ return FALSE
- //Exhale
- breath.adjust_moles(/datum/gas/oxygen, -gas_breathed)
- breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
- gas_breathed = 0
+ #define PP_MOLES(X) ((X / total_moles) * pressure)
- //-- Nitrogen --//
+ #define PP(air, gas) PP_MOLES(air.get_moles(gas))
- //Too much nitrogen!
- if(safe_nitro_max)
- if(N2_pp > safe_nitro_max)
- var/ratio = (breath.get_moles(/datum/gas/nitrogen)/safe_nitro_max) * 10
- H.apply_damage_type(clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type)
- H.throw_alert("too_much_nitro", /atom/movable/screen/alert/too_much_nitro)
- else
- H.clear_alert("too_much_nitro")
-
- //Too little nitrogen!
- if(safe_nitro_min)
- if(N2_pp < safe_nitro_min)
- gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.get_moles(/datum/gas/nitrogen))
- H.throw_alert("not_enough_nitro", /atom/movable/screen/alert/not_enough_nitro)
- else
- H.failed_last_breath = FALSE
- if(H.health >= H.crit_threshold)
- H.adjustOxyLoss(-5 * eff)
- gas_breathed = breath.get_moles(/datum/gas/nitrogen)
- H.clear_alert("not_enough_nitro")
-
- //Exhale
- breath.adjust_moles(/datum/gas/nitrogen, -gas_breathed)
- breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
- gas_breathed = 0
-
- //-- CO2 --//
-
- //CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick.
- if(safe_co2_max)
- if(CO2_pp > safe_co2_max)
- if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
- H.co2overloadtime = world.time
- else if(world.time - H.co2overloadtime > 120)
- H.Unconscious(60)
- H.apply_damage_type(3, co2_damage_type) // Lets hurt em a little, let them know we mean business
- if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
- H.apply_damage_type(8, co2_damage_type)
- H.throw_alert("too_much_co2", /atom/movable/screen/alert/too_much_co2)
- if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
- H.emote("cough")
+ var/gas_breathed = 0
+ var/eff = get_organ_efficiency()
+ var/pressure = breath.return_pressure()
+ var/total_moles = breath.total_moles()
+ var/list/breath_alert_info = GLOB.gas_data.breath_alert_info
+ var/list/breath_results = GLOB.gas_data.breath_results
+ var/list/breathing_classes = GLOB.gas_data.breathing_classes
+ var/list/mole_adjustments = list()
+ for(var/entry in gas_min)
+ var/required_pp = 0
+ var/required_moles = 0
+ var/safe_min = gas_min[entry]
+ var/alert_category = null
+ var/alert_type = null
+ if(ispath(entry))
+ var/datum/breathing_class/class = breathing_classes[entry]
+ var/list/gases = class.gases
+ var/list/products = class.products
+ alert_category = class.low_alert_category
+ alert_type = class.low_alert_datum
+ for(var/gas in gases)
+ var/moles = breath.get_moles(gas)
+ var/multiplier = gases[gas]
+ mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - moles : -moles
+ required_pp += PP_MOLES(moles) * multiplier
+ required_moles += moles
+ if(multiplier > 0)
+ var/to_add = moles * multiplier
+ for(var/product in products)
+ mole_adjustments[product] = (product in mole_adjustments) ? mole_adjustments[product] + to_add : to_add
else
- H.co2overloadtime = 0
- H.clear_alert("too_much_co2")
-
- //Too little CO2!
- if(safe_co2_min)
- if(CO2_pp < safe_co2_min)
- gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath.get_moles(/datum/gas/carbon_dioxide))
- H.throw_alert("not_enough_co2", /atom/movable/screen/alert/not_enough_co2)
+ required_moles = breath.get_moles(entry)
+ required_pp = PP_MOLES(required_moles)
+ if(entry in breath_alert_info)
+ var/list/alert = breath_alert_info[entry]["not_enough_alert"]
+ alert_category = alert["alert_category"]
+ alert_type = alert["alert_type"]
+ mole_adjustments[entry] = -required_moles
+ mole_adjustments[breath_results[entry]] = required_moles
+ if(required_pp < safe_min)
+ var/multiplier = handle_too_little_breath(H, required_pp, safe_min, required_moles)
+ if(required_moles > 0)
+ multiplier /= required_moles
+ for(var/adjustment in mole_adjustments)
+ mole_adjustments[adjustment] *= multiplier
+ if(alert_category)
+ H.throw_alert(alert_category, alert_type)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
- H.adjustOxyLoss(-5 * organ_efficiency)
- gas_breathed = breath.get_moles(/datum/gas/carbon_dioxide)
- H.clear_alert("not_enough_co2")
-
- //Exhale
- breath.adjust_moles(/datum/gas/carbon_dioxide, -gas_breathed)
- breath.adjust_moles(/datum/gas/oxygen, gas_breathed)
- gas_breathed = 0
-
-
- //-- TOX --//
-
- //Too much toxins!
- if(safe_toxins_max)
- if(Toxins_pp > safe_toxins_max)
- var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_toxins_max) * 10
- H.apply_damage_type(clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type)
- H.throw_alert("too_much_tox", /atom/movable/screen/alert/too_much_tox)
+ H.adjustOxyLoss(-breathModifier)
+ if(alert_category)
+ H.clear_alert(alert_category)
+ var/list/danger_reagents = GLOB.gas_data.breath_reagents_dangerous
+ for(var/entry in gas_max)
+ var/found_pp = 0
+ var/datum/breathing_class/breathing_class = entry
+ var/datum/reagent/danger_reagent = null
+ var/alert_category = null
+ var/alert_type = null
+ if(ispath(breathing_class))
+ breathing_class = breathing_classes[breathing_class]
+ alert_category = breathing_class.high_alert_category
+ alert_type = breathing_class.high_alert_datum
+ danger_reagent = breathing_class.danger_reagent
+ found_pp = breathing_class.get_effective_pp(breath)
else
- H.clear_alert("too_much_tox")
-
-
- //Too little toxins!
- if(safe_toxins_min)
- if(Toxins_pp < safe_toxins_min)
- gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath.get_moles(/datum/gas/plasma))
- H.throw_alert("not_enough_tox", /atom/movable/screen/alert/not_enough_tox)
- else
- H.failed_last_breath = FALSE
- if(H.health >= H.crit_threshold)
- H.adjustOxyLoss(-5 * eff)
- gas_breathed = breath.get_moles(/datum/gas/plasma)
- H.clear_alert("not_enough_tox")
-
- //Exhale
- breath.adjust_moles(/datum/gas/plasma, -gas_breathed)
- breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
- gas_breathed = 0
-
+ danger_reagent = danger_reagents[entry]
+ if(entry in breath_alert_info)
+ var/list/alert = breath_alert_info[entry]["too_much_alert"]
+ alert_category = alert["alert_category"]
+ alert_type = alert["alert_type"]
+ found_pp = PP(breath, entry)
+ if(found_pp > gas_max[entry])
+ if(istype(danger_reagent))
+ H.reagents.add_reagent(danger_reagent,1)
+ var/list/damage_info = (entry in gas_damage) ? gas_damage[entry] : gas_damage["default"]
+ var/dam = found_pp / gas_max[entry] * 10
+ H.apply_damage_type(clamp(dam, damage_info["min"], damage_info["max"]), damage_info["damage_type"])
+ if(alert_category && alert_type)
+ H.throw_alert(alert_category, alert_type)
+ else if(alert_category)
+ H.clear_alert(alert_category)
+ var/list/breath_reagents = GLOB.gas_data.breath_reagents
+ for(var/gas in breath.get_gases())
+ if(gas in breath_reagents)
+ var/datum/reagent/R = breath_reagents[gas]
+ H.reagents.add_reagent(R, breath.get_moles(gas)*eff)
+ mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - breath.get_moles(gas) : -breath.get_moles(gas)
+
+ for(var/gas in mole_adjustments)
+ breath.adjust_moles(gas, mole_adjustments[gas])
//-- TRACES --//
if(breath) // If there's some other shit in the air lets deal with it here.
// N2O
- REMOVE_TRAIT(H, TRAIT_SURGERY_PREPARED, "N2O")
- var/SA_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrous_oxide))
+
+ var/SA_pp = PP(breath, GAS_NITROUS)
if(SA_pp > SA_para_min) // Enough to make us stunned for a bit
H.Unconscious(60) // 60 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
H.Sleeping(max(H.AmountSleeping() + 40, 200))
- ADD_TRAIT(H, TRAIT_SURGERY_PREPARED, "N2O")
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
H.emote(pick("giggle", "laugh"))
@@ -255,7 +238,7 @@
// BZ
- var/bz_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/bz))
+ var/bz_pp = PP(breath, GAS_BZ)
if(bz_pp > BZ_trip_balls_min)
H.adjust_hallucinations(10 SECONDS)
H.reagents.add_reagent(/datum/reagent/bz_metabolites,5)
@@ -266,22 +249,13 @@
H.adjust_hallucinations(5 SECONDS)
H.reagents.add_reagent(/datum/reagent/bz_metabolites,1)
-
- // Tritium
- var/trit_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/tritium))
- if (trit_pp > 50)
- H.radiation += trit_pp/2 //If you're breathing in half an atmosphere of radioactive gas, you fucked up.
- else
- H.radiation += trit_pp/10
-
// Nitrium
- var/nitrium_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrium))
+ var/nitrium_pp = PP(breath, GAS_NITRIUM)
// Random chance to inflict side effects, increases with pressure.
if (nitrium_pp > 15 && prob(nitrium_pp))
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, nitrium_pp * 0.1)
to_chat(H, span_alert("You feel a burning sensation in your chest"))
-
- gas_breathed = breath.get_moles(/datum/gas/nitrium)
+ gas_breathed = breath.get_moles(GAS_NITRIUM)
// Metabolize to reagents.
if (gas_breathed > gas_stimulation_min)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/nitrium_low_metabolization)
@@ -289,10 +263,10 @@
if (gas_breathed > gas_stimulation_min * 2.5)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/nitrium_high_metabolization)
H.reagents.add_reagent(/datum/reagent/nitrium_high_metabolization, max(0, 1 - existing))
- breath.adjust_moles(/datum/gas/nitrium, -gas_breathed)
+ breath.adjust_moles(GAS_NITRIUM, -gas_breathed)
// Freon
- var/freon_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/freon))
+ var/freon_pp = PP(breath,GAS_FREON)
if (prob(freon_pp))
to_chat(H, span_alert("Your mouth feels like it's burning!"))
if (freon_pp >40)
@@ -303,81 +277,80 @@
H.silent = max(H.silent, 3)
else
H.adjustFireLoss(freon_pp/4)
- gas_breathed = breath.get_moles(/datum/gas/freon)
+ gas_breathed = breath.get_moles(GAS_FREON)
if (gas_breathed > gas_stimulation_min)
H.reagents.add_reagent(/datum/reagent/freon,1*eff)
- breath.adjust_moles(/datum/gas/freon, -gas_breathed)
+ breath.adjust_moles(GAS_FREON, -gas_breathed)
// Healium
- var/healium_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/healium))
+ var/healium_pp = PP(breath,GAS_HEALIUM)
if(healium_pp > SA_sleep_min)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/healium)
H.reagents.add_reagent(/datum/reagent/healium,max(0, 1*eff - existing))
- gas_breathed = breath.get_moles(/datum/gas/healium)
+ gas_breathed = breath.get_moles(GAS_HEALIUM)
if(gas_breathed > gas_stimulation_min && !helium_speech)
helium_speech = TRUE
RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_helium_speech))
else if (gas_breathed <= gas_stimulation_min && helium_speech)
helium_speech = FALSE
UnregisterSignal(owner, COMSIG_MOB_SAY)
- breath.adjust_moles(/datum/gas/healium, -gas_breathed)
+ breath.adjust_moles(GAS_HEALIUM, -gas_breathed)
// Pluonium
// Inert
// Zauker
- var/zauker_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/zauker))
- if(zauker_pp > safe_toxins_max)
+ var/zauker_pp = PP(breath,GAS_ZAUKER)
+ if(zauker_pp > safe_breath_max)
H.adjustBruteLoss(25)
H.adjustOxyLoss(5)
H.adjustFireLoss(8)
H.adjustToxLoss(8)
- gas_breathed = breath.get_moles(/datum/gas/zauker)
- breath.adjust_moles(/datum/gas/zauker, -gas_breathed)
+ gas_breathed = breath.get_moles(GAS_ZAUKER)
+ breath.adjust_moles(GAS_ZAUKER, -gas_breathed)
// Halon
- gas_breathed = breath.get_moles(/datum/gas/halon)
+ gas_breathed = breath.get_moles(GAS_HALON)
if(gas_breathed > gas_stimulation_min)
H.adjustOxyLoss(5)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/halon)
H.reagents.add_reagent(/datum/reagent/halon,max(0, 1 - existing))
- gas_breathed = breath.get_moles(/datum/gas/halon)
- breath.adjust_moles(/datum/gas/halon, -gas_breathed)
+ gas_breathed = breath.get_moles(GAS_HALON)
+ breath.adjust_moles(GAS_HALON, -gas_breathed)
// Hexane
- gas_breathed = breath.get_moles(/datum/gas/hexane)
+ gas_breathed = breath.get_moles(GAS_HEXANE)
if(gas_breathed > gas_stimulation_min)
H.adjust_hallucinations(50 SECONDS)
H.reagents.add_reagent(/datum/reagent/hexane,5)
if(prob(33))
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150)
+ breath.adjust_moles(GAS_HEXANE, -gas_breathed)
// Hyper-noblium
- gas_breathed = breath.get_moles(/datum/gas/hypernoblium)
+ gas_breathed = breath.get_moles(GAS_HYPERNOB)
if(gas_breathed > gas_stimulation_min)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/hypernoblium)
H.reagents.add_reagent(/datum/reagent/hypernoblium, max(0, eff - existing))
- breath.adjust_moles(/datum/gas/hypernoblium, -gas_breathed)
+ breath.adjust_moles(GAS_HYPERNOB, -gas_breathed)
// Anti-noblium
- gas_breathed = breath.get_moles(/datum/gas/antinoblium)
+ gas_breathed = breath.get_moles(GAS_ANTINOB)
if(gas_breathed > gas_stimulation_min)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/antinoblium)
H.reagents.add_reagent(/datum/reagent/antinoblium, max(0, eff - existing))
- breath.adjust_moles(/datum/gas/antinoblium, -gas_breathed)
+ breath.adjust_moles(GAS_ANTINOB, -gas_breathed)
// Miasma
- if (breath.get_moles(/datum/gas/miasma))
- var/miasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/miasma))
+ if (breath.get_moles(GAS_MIASMA))
+ var/miasma_pp = PP(breath,GAS_MIASMA)
//Miasma sickness
if(prob(0.5 * miasma_pp))
- var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(min(round(max(miasma_pp/2, 1), 1), 6), min(round(max(miasma_pp, 1), 1), 8))
- if(owner.CanContractDisease(miasma_disease))
- //tl;dr the first argument chooses the smaller of miasma_pp/2 or 6(typical max virus symptoms), the second chooses the smaller of miasma_pp or 8(max virus symptom level) //
- miasma_disease.name = "Unknown"//^each argument has a minimum of 1 and rounds to the nearest value. Feel free to change the pp scaling I couldn't decide on good numbers for it.
- miasma_disease.try_infect(owner)
+ var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2, 3)
+ miasma_disease.name = "Unknown"
+ miasma_disease.try_infect(owner)
// Miasma side effects
switch(miasma_pp)
@@ -410,7 +383,7 @@
// Then again, this is a purely hypothetical scenario and hardly reachable
owner.adjust_disgust(0.1 * miasma_pp)
- breath.adjust_moles(/datum/gas/miasma, -gas_breathed)
+ breath.adjust_moles(GAS_MIASMA, -gas_breathed)
// Clear out moods when no miasma at all
else
@@ -483,11 +456,13 @@
user.visible_message(span_notice("[user] extends [src] with [W]!"), span_notice("You use [W] to extend [src]!"), "You hear something stretching.")
name = "extended [name]"
icon_state += "-crobar" //shh! don't tell anyone i handed you this card
- safe_oxygen_min *= 2 //SCREAM LOUDER i dont know maybe eventually
- safe_toxins_min *= 2
- safe_nitro_min *= 2 //BREATHE HARDER
- safe_co2_min *= 2
- organ_efficiency = 2 //HOLD YOUR BREATH FOR REALLY LONG
+ safe_breath_min *= 2 //SCREAM LOUDER i dont know maybe eventually
+ safe_breath_max *= 2 //BREATHE HARDER
+ for(var/gas in gas_min)
+ gas_min[gas] *= 2
+ for(var/gas in gas_max)
+ gas_max[gas] *= 2
+ organ_efficiency *= 2 //HOLD YOUR BREATH FOR REALLY LONG
maxHealth *= 0.5 //This procedure is not legal but i will do it for you
/obj/item/organ/lungs/prepare_eat()
@@ -525,7 +500,7 @@
var/temperature = breath.return_temperature()
for(var/id in breath.get_gases())
var/moles = breath.get_moles(id)
- total_heat_capacity += GLOB.meta_gas_info[id][META_GAS_SPECIFIC_HEAT] * moles
+ total_heat_capacity += GLOB.gas_data.specific_heats[id] * moles
// Normal atmos is 0.416
// 20C -> 293K
// At about 50C overheating will begin
@@ -556,38 +531,37 @@
desc = "A spongy rib-shaped mass for filtering plasma from the air."
icon_state = "lungs-plasma"
- safe_oxygen_min = 0 //We don't breath this
- safe_toxins_min = 16 //We breath THIS!
- safe_toxins_max = 0
+ breathing_class = BREATH_PLASMA
+
+/obj/item/organ/lungs/plasmaman/populate_gas_info()
+ ..()
+ gas_max -= GAS_PLASMA
/obj/item/organ/lungs/xeno
name = "devolved plasma vessel"
desc = "A lung-shaped organ vaguely similar to a plasma vessel, restructured from a storage system to a respiratory one."
icon_state = "lungs-x"
+ breathing_class = /datum/breathing_class/oxygen_plas
- safe_toxins_max = 0 //lmoa~
- oxygen_substitutes = list(/datum/gas/pluoxium = 8, /datum/gas/plasma = 1)
heat_level_1_threshold = 313
heat_level_2_threshold = 353
heat_level_3_threshold = 600
-/obj/item/organ/lungs/xeno/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H) //handling this externally so I don't have to nerf pluoxium, can't handle it internally without removing perpetual pluox or requiring plasma for breathing
- . = ..()
- if(breath)
- var/breath_amt = breath.get_moles(/datum/gas/plasma)
- breath.adjust_moles(/datum/gas/plasma, -breath_amt)
- breath.adjust_moles(/datum/gas/oxygen, breath_amt)
+/obj/item/organ/lungs/xeno/populate_gas_info()
+ ..()
+ gas_max -= GAS_PLASMA
+ gas_damage -= GAS_PLASMA
/obj/item/organ/lungs/slime
name = "vacuole"
desc = "A large organelle designed to store oxygen and other important gasses."
- safe_toxins_max = 0 //We breathe this to gain POWER.
-
/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
. = ..()
if (breath)
- var/plasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
+ var/total_moles = breath.total_moles()
+ var/pressure = breath.return_pressure()
+ var/plasma_pp = PP(breath, GAS_PLASMA)
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
/obj/item/organ/lungs/ghetto
@@ -604,23 +578,27 @@
organ_flags = ORGAN_SYNTHETIC
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
organ_efficiency = 1.5
- safe_oxygen_min = 13
+ safe_breath_min = 13
+ safe_breath_max = 100
-/obj/item/organ/lungs/cybernetic/emp_act()
+/obj/item/organ/lungs/cybernetic/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
- owner.losebreath = 20
+ owner.losebreath = 2 * severity
/obj/item/organ/lungs/cybernetic/upgraded
name = "upgraded cybernetic lungs"
desc = "A more advanced version of the stock cybernetic lungs, more efficient at, well, breathing. Features higher temperature tolerances and the ability to filter out most potentially harmful gases."
icon_state = "lungs-c-u"
+ safe_breath_min = 4
+ safe_breath_max = 250
+ gas_max = list(
+ GAS_PLASMA = 30,
+ GAS_CO2 = 30
+ )
maxHealth = 3 * STANDARD_ORGAN_THRESHOLD
organ_efficiency = 2
- safe_oxygen_min = 10
- safe_co2_max = 20
- safe_toxins_max = 20 //Higher resistance to most harmful gasses
SA_para_min = 3
SA_sleep_min = 6
BZ_trip_balls_min = 2
@@ -638,12 +616,12 @@
name = "aeration reticulum"
desc = "These exotic lungs seem crunchier than most."
icon_state = "lungs-ethereal"
- oxygen_substitutes = list(/datum/gas/pluoxium = 8, /datum/gas/water_vapor = 1)
+ breathing_class = /datum/breathing_class/oxygen_vapor
/obj/item/organ/lungs/ethereal/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
. = ..()
- var/electrolysis = breath.get_moles(/datum/gas/water_vapor)
+ var/electrolysis = breath.get_moles(GAS_H2O)
if(electrolysis)
- breath.adjust_moles(/datum/gas/water_vapor, -electrolysis)
- breath.adjust_moles(/datum/gas/hydrogen, electrolysis)
- breath.adjust_moles(/datum/gas/oxygen, electrolysis/2)
+ breath.adjust_moles(GAS_H2O, -electrolysis)
+ breath.adjust_moles(GAS_H2, electrolysis)
+ breath.adjust_moles(GAS_O2, electrolysis/2)
diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm
index b46391ae3c4f..52c76be97411 100644
--- a/code/modules/surgery/organs/stomach.dm
+++ b/code/modules/surgery/organs/stomach.dm
@@ -145,7 +145,7 @@
/obj/item/organ/stomach/cell/emp_act(severity)
to_chat(owner, emp_message)
- charge(amount = owner.nutrition * -0.2 / severity)
+ charge(amount = owner.nutrition * -0.02 * severity)
/obj/item/organ/stomach/cell/Insert(mob/living/carbon/M, special, drop_if_replaced)
. = ..()
@@ -182,7 +182,7 @@
UnregisterSignal(owner, COMSIG_LIVING_ELECTROCUTE_ACT)
..()
-/obj/item/organ/stomach/cell/ethereal/proc/on_electrocute(datum/source, shock_damage, siemens_coeff = 1, illusion = FALSE)
+/obj/item/organ/stomach/cell/ethereal/proc/on_electrocute(mob/living/victim, shock_damage, obj/source, siemens_coeff = 1, zone = null, tesla_shock = 0, illusion = 0)
if(illusion)
return
if(!HAS_TRAIT(owner, TRAIT_POWERHUNGRY))
@@ -190,6 +190,9 @@
owner.adjust_nutrition(shock_damage * siemens_coeff)
to_chat(owner, span_notice("You absorb some of the shock into your body!"))
+/obj/item/organ/stomach/cell/ethereal/emp_act(severity)
+ return // it's organic
+
/obj/item/organ/stomach/cursed
name = "cursed stomach"
icon_state = "stomach-cursed"
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index ac2dced2b692..92b50110451d 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -266,9 +266,9 @@
/obj/item/organ/tongue/robot/emp_act(severity)
if(prob(5))
return
- owner.apply_effect(EFFECT_STUTTER, rand(5 SECONDS, 2 MINUTES))
+ owner.apply_effect(EFFECT_STUTTER, rand(1, severity) * 6 SECONDS)
owner.emote("scream")
- to_chat(owner, "Alert: Vocal cords are malfunctioning. ")
+ to_chat(owner, "Alert: Voice synthesizer is malfunctioning. ")
/obj/item/organ/tongue/robot/can_speak_language(language)
return TRUE // THE MAGIC OF ELECTRONICS
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index cb74738d8880..05192ad4b1c2 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -169,6 +169,7 @@
throwforce = 5
throw_speed = 3
throw_range = 5
+ demolition_mod = 0.25
materials = list(/datum/material/iron=4000, /datum/material/glass=1000)
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
@@ -399,6 +400,7 @@
light_range = 1
light_color = LIGHT_COLOR_GREEN
light_power = 0.2 //Barely glows on low power
+ demolition_mod = 1.5 // lasers are good at cutting metal
sharpness = SHARP_EDGED
diff --git a/code/modules/swarmers/swarmer.dm b/code/modules/swarmers/swarmer.dm
index fdfad769000b..a803253f031a 100644
--- a/code/modules/swarmers/swarmer.dm
+++ b/code/modules/swarmers/swarmer.dm
@@ -96,12 +96,13 @@
. = ..()
. += "Resources: [resources]"
-/mob/living/simple_animal/hostile/swarmer/emp_act()
+/mob/living/simple_animal/hostile/swarmer/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
- if(health > 1)
- adjustHealth(health-1)
+ var/emp_damage = severity/EMP_HEAVY
+ if(health > emp_damage)
+ adjustHealth(health - emp_damage)
else
death()
@@ -258,7 +259,7 @@
playsound(src, 'sound/effects/sparks4.ogg', 50, TRUE)
do_teleport(target, safe_turf , 0, channel = TELEPORT_CHANNEL_BLUESPACE)
-/mob/living/simple_animal/hostile/swarmer/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
+/mob/living/simple_animal/hostile/swarmer/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)
if(!tesla_shock)
return FALSE
return ..()
diff --git a/code/modules/swarmers/swarmer_act.dm b/code/modules/swarmers/swarmer_act.dm
index 92529679a759..d85d82513e6d 100644
--- a/code/modules/swarmers/swarmer_act.dm
+++ b/code/modules/swarmers/swarmer_act.dm
@@ -87,7 +87,7 @@
for(var/turf/T in range(1, src))
var/area/A = get_area(T)
var/datum/gas_mixture/turf_air = T.return_air()
- if(turf_air.get_moles(/datum/gas/hydrogen) > 1 || turf_air.get_moles(/datum/gas/tritium) > 1 || turf_air.get_moles(/datum/gas/plasma) > 1 || (locate(/obj/effect/hotspot) in T) || turf_air.return_pressure() > 500 || turf_air.return_temperature() > 750 || !turf_air.total_moles() || isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle)))
+ if(turf_air.get_moles(GAS_H2) > 1 || turf_air.get_moles(GAS_TRITIUM) > 1 || turf_air.get_moles(GAS_PLASMA) > 1 || (locate(/obj/effect/hotspot) in T) || turf_air.return_pressure() > 500 || turf_air.return_temperature() > 750 || !turf_air.total_moles() || isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle)))
to_chat(S, span_warning("Destroying this object has the potential to cause a hull breach. Aborting."))
S.target = null
return FALSE
@@ -173,7 +173,7 @@
for(var/turf/T in range(1, src))
var/area/A = get_area(T)
var/datum/gas_mixture/turf_air = T.return_air()
- if(turf_air.get_moles(/datum/gas/hydrogen) > 1 || turf_air.get_moles(/datum/gas/tritium) > 1 || turf_air.get_moles(/datum/gas/plasma) > 1 || (locate(/obj/effect/hotspot) in T) || turf_air.return_pressure() > 500 || turf_air.return_temperature() > 750 || !turf_air.total_moles() || isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle)))
+ if(turf_air.get_moles(GAS_H2) > 1 || turf_air.get_moles(GAS_TRITIUM) > 1 || turf_air.get_moles(GAS_PLASMA) > 1 || (locate(/obj/effect/hotspot) in T) || turf_air.return_pressure() > 500 || turf_air.return_temperature() > 750 || !turf_air.total_moles() || isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle)))
to_chat(S, span_warning("Destroying this object has the potential to cause a hull breach. Aborting."))
S.target = null
return TRUE
@@ -188,7 +188,7 @@
for(var/turf/adj_turf in range(1, src))
var/area/adj_area = get_area(adj_turf)
var/datum/gas_mixture/turf_air = adj_turf.return_air()
- if(turf_air.get_moles(/datum/gas/hydrogen) > 1 || turf_air.get_moles(/datum/gas/tritium) > 1 || turf_air.get_moles(/datum/gas/plasma) > 1 || (locate(/obj/effect/hotspot) in adj_turf) || turf_air.return_pressure() > 500 || turf_air.return_temperature() > 750 || !turf_air.total_moles() || isspaceturf(adj_turf) || (!is_on_shuttle && (istype(adj_area, /area/shuttle) || istype(adj_area, /area/space))) || (is_on_shuttle && !istype(adj_area, /area/shuttle)))
+ if(turf_air.get_moles(GAS_H2) > 1 || turf_air.get_moles(GAS_TRITIUM) > 1 || turf_air.get_moles(GAS_PLASMA) > 1 || (locate(/obj/effect/hotspot) in adj_turf) || turf_air.return_pressure() > 500 || turf_air.return_temperature() > 750 || !turf_air.total_moles() || isspaceturf(adj_turf) || (!is_on_shuttle && (istype(adj_area, /area/shuttle) || istype(adj_area, /area/space))) || (is_on_shuttle && !istype(adj_area, /area/shuttle)))
to_chat(actor, span_warning("Destroying this object has the potential to cause a hull breach. Aborting."))
actor.target = null
return TRUE
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index c458f00a3f15..af3d3c365116 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -61,24 +61,6 @@
/// This must be the last test to run due to the inherent nature of the test iterating every single tangible atom in the game and qdeleting all of them (while taking long sleeps to make sure the garbage collector fires properly) taking a large amount of time.
#define TEST_CREATE_AND_DESTROY INFINITY
-/// Change color to red on ANSI terminal output, if enabled with -DANSICOLORS.
-#ifdef ANSICOLORS
-#define TEST_OUTPUT_RED(text) "\x1B\x5B1;31m[text]\x1B\x5B0m"
-#else
-#define TEST_OUTPUT_RED(text) (text)
-#endif
-/// Change color to green on ANSI terminal output, if enabled with -DANSICOLORS.
-#ifdef ANSICOLORS
-#define TEST_OUTPUT_GREEN(text) "\x1B\x5B1;32m[text]\x1B\x5B0m"
-#else
-#define TEST_OUTPUT_GREEN(text) (text)
-#endif
-/// Change color to yellow on ANSI terminal output, if enabled with -DANSICOLORS.
-#ifdef ANSICOLORS
-#define TEST_OUTPUT_YELLOW(text) "\x1B\x5B1;33m[text]\x1B\x5B0m"
-#else
-#define TEST_OUTPUT_YELLOW(text) (text)
-#endif
/// A trait source when adding traits through unit tests
#define TRAIT_SOURCE_UNIT_TESTS "unit_tests"
diff --git a/code/modules/unit_tests/unit_test.dm b/code/modules/unit_tests/unit_test.dm
index 3791b81a1913..fece5b1b1201 100644
--- a/code/modules/unit_tests/unit_test.dm
+++ b/code/modules/unit_tests/unit_test.dm
@@ -130,11 +130,12 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
var/skip_test = (test_path in SSmapping.config.skipped_tests)
var/test_output_desc = "[test_path]"
var/message = ""
+ var/map_name = SSmapping.config.map_name
log_world("::group::[test_path]")
if(skip_test)
- log_world("[TEST_OUTPUT_YELLOW("SKIPPED")] Skipped run on map [SSmapping.config.map_name].")
+ log_world("[TEST_OUTPUT_YELLOW("SKIPPED")] Skipped run on map [map_name].")
else
@@ -144,7 +145,9 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
GLOB.current_test = null
GLOB.failed_any_test |= !test.succeeded
- var/list/log_entry = list()
+ var/list/log_entry = list(
+ "[test.succeeded ? TEST_OUTPUT_GREEN("PASS") : TEST_OUTPUT_RED("FAIL")]: [test_path] [duration / 10]s"
+ )
var/list/fail_reasons = test.fail_reasons
for(var/reasonID in 1 to LAZYLEN(fail_reasons))
@@ -154,6 +157,14 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
test.log_for_test(text, "error", file, line)
+ // Github action annotation.
+ // See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
+ // Need to escape the text to properly support newlines.
+ var/annotation_text = replacetext(text, "%", "%25")
+ annotation_text = replacetext(annotation_text, "\n", "%0A")
+
+ log_world("::error file=[file],line=[line],title=[map_name]: [test_path]::[annotation_text]")
+
// Normal log message
log_entry += "\tFAILURE #[reasonID]: [text] at [file]:[line]"
@@ -167,9 +178,6 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
log_world("::endgroup::")
- if (!test.succeeded && !skip_test)
- log_world("::error::[TEST_OUTPUT_RED("FAIL")] [test_output_desc]")
-
var/final_status = skip_test ? UNIT_TEST_SKIPPED : (test.succeeded ? UNIT_TEST_PASSED : UNIT_TEST_FAILED)
test_results[test_path] = list("status" = final_status, "message" = message, "name" = test_path)
diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm
index 4a0d87837d9d..02868530da54 100644
--- a/code/modules/uplink/uplink_items.dm
+++ b/code/modules/uplink/uplink_items.dm
@@ -526,7 +526,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
Upon hitting a target, the piston-ram will extend forward to make contact for some serious damage. \
Using a wrench on the piston valve will allow you to tweak the amount of gas used per punch to \
deal extra damage and hit targets further. Use a screwdriver to take out any attached tanks."
- item = /obj/item/melee/powerfist
+ item = /obj/item/clothing/gloves/powerfist
cost = 6
manufacturer = /datum/corporation/traitor/waffleco
exclude_modes = list(/datum/game_mode/infiltration) // yogs: infiltration
@@ -613,6 +613,15 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
manufacturer = /datum/corporation/traitor/donkco
surplus = 10
+/datum/uplink_item/dangerous/watergun
+ name = "Extended Capacity Hyper-Soaker"
+ desc = "A simple yet effective way of applying chemicals to a target's skin. \
+ Comes with a high-power nozzle and larger tank."
+ item = /obj/item/gun/water/syndicate
+ cost = 2
+ manufacturer = /datum/corporation/traitor/donkco
+ surplus = 10
+
/datum/uplink_item/dangerous/hardlightbow
name = "Hardlight Bow"
desc = "A modern bow that can fabricate hardlight arrows, designed for silent takedowns of targets."
@@ -1462,7 +1471,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
completely silent as you slip away from the scene, or into a better position! You will not be able to take \
any actions for the 7 second duration."
item = /obj/item/pseudocider
- cost = 6
+ cost = 8
exclude_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_tools/shadowcloak
diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm
index 02d0313d2795..b26cc8daebc0 100644
--- a/code/modules/vending/megaseed.dm
+++ b/code/modules/vending/megaseed.dm
@@ -25,6 +25,7 @@
/obj/item/seeds/grape = 3,
/obj/item/seeds/grass = 3,
/obj/item/seeds/ute_nut = 3,
+ /obj/item/seeds/lanternfruit = 3,
/obj/item/seeds/lemon = 3,
/obj/item/seeds/lime = 3,
/obj/item/seeds/onion = 3,
diff --git a/code/modules/vending/toys.dm b/code/modules/vending/toys.dm
index 92a1419fea2e..2cf117a730d2 100644
--- a/code/modules/vending/toys.dm
+++ b/code/modules/vending/toys.dm
@@ -26,6 +26,7 @@
/obj/item/gun/ballistic/shotgun/toy/crossbow = 10,
/obj/item/gun/ballistic/automatic/c20r/toy/unrestricted = 10,
/obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted = 10,
+ /obj/item/gun/water/full = 10,
/obj/item/toy/katana = 10,
/obj/item/melee/dualsaber/toy = 5,
/obj/item/organ/cyberimp/chest/spinalspeed/toy = 5,
diff --git a/config/admins.txt b/config/admins.txt
index 66554b4c6855..e53c2ea948a8 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -11,11 +11,9 @@
AshCorr = Host
Xantam = Host
-adamsogm = Council Member
-britishgrace = Council Member
-margot = Council Member
+aquizit = Council Member
mordrehel = Council Member
-ynot01 = Council Member
+cowbot93 = Council Member
jamied12 = Head Developer
baiomu = Head Developer
diff --git a/config/game_options.txt b/config/game_options.txt
index bcdd19e1c326..fdc2772875aa 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -501,7 +501,7 @@ LAW_WEIGHT fitnesscoach,0
ION_LAW_WEIGHT fitnesscoach,3
LAW_WEIGHT educator,0
ION_LAW_WEIGHT educator,3
-LAW_WEIGHT mediator,1
+LAW_WEIGHT mediator,0
ION_LAW_WEIGHT mediator,3
## Bad idea laws. Probably shouldn't enable these
diff --git a/config/iceruinblacklist.txt b/config/iceruinblacklist.txt
index 8b9a043b4e54..4718700e37c2 100644
--- a/config/iceruinblacklist.txt
+++ b/config/iceruinblacklist.txt
@@ -10,11 +10,13 @@
#_maps/RandomRuins/IceRuins/icemoon_surface_inn.dmm
#_maps/RandomRuins/IceRuins/icemoon_surface_asteroid.dmm
#_maps/RandomRuins/IceRuins/icemoon_surface_hotsprings.dmm
+#_maps/RandomRuins/IceRuins/icemoon_surface_hermit.dmm
+_maps/RandomRuins/IceRuins/icemoon_surface_walkervillage.dmm
#_maps/RandomRuins/IceRuins/icemoon_underground_puzzle.dmm
-#_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm
+_maps/RandomRuins/IceRuins/icemoon_underground_abandoned_village.dmm
#_maps/RandomRuins/IceRuins/icemoon_underground_mining_site.dmm
#_maps/RandomRuins/IceRuins/icemoon_underground_library.dmm
#_maps/RandomRuins/IceRuins/icemoon_underground_wrath.dmm
#_maps/RandomRuins/IceRuins/icemoon_underground_lavaland.dmm
#_maps/RandomRuins/IceRuins/icemoon_underground_bathhouse.dmm
-#_maps/RandomRuins/IceRuins/icemoon_underground_wampacave.dmm
+#_maps/RandomRuins/IceRuins/icemoon_underground_wampacave.dmm
\ No newline at end of file
diff --git a/config/minor_filter.txt b/config/minor_filter.txt
index 62f32d579aaf..808fe7fbd295 100644
--- a/config/minor_filter.txt
+++ b/config/minor_filter.txt
@@ -46,3 +46,5 @@ pls=please
plz=please
\btf\b=the fuck
\bi\b=I
+auxmos=La Li Lu Le Lo
+aux mos=La Li Lu Le Lo
\ No newline at end of file
diff --git a/dependencies.sh b/dependencies.sh
old mode 100644
new mode 100755
index 7fa94eba3287..8f6360c72b76
--- a/dependencies.sh
+++ b/dependencies.sh
@@ -1,11 +1,11 @@
-#!/bin/bash
+#!/bin/sh
#Project dependencies file
#Final authority on what's required to fully build the project
# byond version
-export BYOND_MAJOR=514
-export BYOND_MINOR=1589
+export BYOND_MAJOR=515
+export BYOND_MINOR=1620
#rust_g git tag
export RUST_G_VERSION=1.2.0-yogs1
@@ -15,4 +15,10 @@ export NODE_VERSION=14
export NODE_VERSION_PRECISE=14.16.1
# SpacemanDMM git tag
-export SPACEMAN_DMM_VERSION=suite-1.7.2
+export SPACEMAN_DMM_VERSION=suite-1.8
+
+# Python version for mapmerge and other tools
+export PYTHON_VERSION=3.9.0
+
+# Auxmos git tag
+export AUXMOS_VERSION=434ed4ca7a0bf072f9861bd6e54552af8fb9e27f
diff --git a/goon/icons/turfs/floors.dmi b/goon/icons/turfs/floors.dmi
index 6287504c132b..b5b3a57b9852 100644
Binary files a/goon/icons/turfs/floors.dmi and b/goon/icons/turfs/floors.dmi differ
diff --git a/html/changelog.html b/html/changelog.html
index bf976f3bef1b..3ae7cdded5f5 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -57,6 +57,398 @@
-->
+
08 December 2023
+
cowbot92 updated:
+
+ Adds 3 new barsigns
+ Adds new barsign images
+
+
+
07 December 2023
+
LoliconSlayer updated:
+
+ Tweaked the names of a few mech melee weapons
+
+
+
06 December 2023
+
AMyriad updated:
+
+ Scrubbed the second "m" from the last mentions of "Centcomm"
+ All mentions of "NanoTrasen" have also been corrected to "Nanotrasen"
+ Added some more words and fixed some old ones for the Nordic accent
+
+
SapphicOverload updated:
+
+ HFR processes at the same rate as other atmos machines now
+ fixed extended lungs
+ fixed a few issues with the tgui for supermatter monitor, HFR control panel, atmos scanner, and filters/scrubbers
+ fixed ethereal stomachs having the EMP effects of IPCs
+
+
azzzertyy updated:
+
+ Network admin now has rnd access
+
+
warface1234455 updated:
+
+ fix supermatter normal delam not working
+
+
+
05 December 2023
+
cowbot92 updated:
+
+ Adds new alt-job titles to roboticists
+
+
ninjanomnom, Ryll-Ryll, Bizzonium, KylerAce, Sinsinins, lessthnthree updated:
+
+ Added new fonts and refactored runechat. Also some backend stuff it's fine.
+
+
sapphicoverload, bluishtsunami updated:
+
+ adds a water gun to donksoft vending machines (and uplink)
+ preternis water damage tweaked to be more affected by smaller volumes
+ preternis water damage updates immediately when splashed instead of waiting up to 2 seconds
+
+
+
04 December 2023
+
Moltijoe updated:
+
+ Pseudocider costs 8tc instead of 6tc
+ Pseudocider has a 30s cooldown instead of 20s
+
+
SapphicOverload updated:
+
+ electrical protection is now its own armor type
+ certain engineering equipment like hard hats and work boots now have electrical protection
+ spliced wires check electrical protection on your feet instead of your hands when you step on them
+ combat defib disarm takes electrical protection on targeted limb into account
+ lightning flow punches, combat defib disarm, and hacked cyborg hug module all check electrical protection on the targeted limb
+ touching hacked cyborg energy fields with your hand now actually checks protection on that hand
+ slightly reorganized the armor tags and adds electrical protection to the list
+ fixed nanites not being affected by electric shock because of a missing signal
+ fixed gloves and shoes with armor not actually protecting your hands and feet respectively
+ fixed power fist not working
+
+
azzzertyy updated:
+
+ Mediator is no longer roundstart.
+
+
+
03 December 2023
+
cark updated:
+
+ fixes missing floor in airlock on donut
+
+
itseasytosee, sapphicoverload updated:
+
+ some items and projectiles are now better or worse than others at destroying things
+ chat messages from hitting an object now tell whether you can damage it
+ fixed machines/structures/etc not caring about armor penetration when hit by a melee weapon
+ fixed cannonballs not doing any damage to mobs
+
+
Moltijoe updated:
+
+ Sometimes fixes feed ability sometimes breaking
+ Gangrel transformation ability now shows the radial menu before the 10 second do_after
+ Fixes gangrel transformation ability sometimes deleting itself without ever being used
+ Fixes gangrel werewolf transformation being eradicated from the timeline by tattax
+
+
SapphicOverload updated:
+
+ fixed ED-209 not being affected by heavy EMPs
+ fixed leg implants not being affected by EMPs at all
+ fixed cybernetic ears causing longer knockdown times on light EMPs instead of the other way around
+ fixed nanite heart killing you instantly on EMP regardless of whether or not it kills your nanites
+ HoS gun now shoots ion carbine projectiles instead of its own redundant projectile type
+ mech ion cannon has 1.5x stronger EMPs than the ion rifle
+ syndicate EMP bomb has 2.5x stronger EMPs than standard EMP grenades
+ reworks EMPs to allow any severity, which now decreases with distance
+
+
+
02 December 2023
+
Moltijoe updated:
+
+ No more infinitely duplicating hulk DAN
+ Hulk now occasionally says the brain damage hulk lines
+
+
SapphicOverload updated:
+
+ fixed runtime error when passive vents encounter zero temperature or zero volume
+ fixed abandoned crates having a 2% chance to cause runtime errors when initialized
+
+
+
01 December 2023
+
Twaticus, Imaginos16, Cark updated:
+
+ added new object sprite for plasteel tile
+ deleted old object sprite for plasteel tile
+
+
JohnFulpWillard updated:
+
+ Stasis units and sleepers now have proper overlays and lavaland sleepers aren't invisible anymore.
+
+
Yarinoi updated:
+
+ Pitying the miners attempting to look for it, the Demonic Frost Miner now gives out a Hollow Signal on GPS.
+
+
azzzertyy updated:
+
+ You can now point while handcuffed
+
+
cowbot92 updated:
+
+
+
30 November 2023
+
ToasterBiome updated:
+
+ Adds a new lavaland lava type that you can't replace with shelter
+ lavaland syndie base is surrounded by no-shelter lavaland lava
+
+
+
29 November 2023
+
Moltijoe updated:
+
+ Brig physician also gets cloning and airlock access during skeleton crew
+ Paramedic also gets surgery access during skeleton crew
+ Mining medic also gets cloning, maint, and airlock access during skeleton crew
+ All hecata zombies die when the controlling bloodsucker dies
+ lightning flow no longer immobilizes for like 0.1 seconds every dash
+ Preterni no longer get 20% more power from liquid electricity than other powerhungry species
+ All powerhungry species now get "food" from consuming teslium, not just Preterni
+
+
Runian updated:
+
+ Lizard tail users can *thump their tail.
+ Tail thump.
+ Guardian's Frenzy Ability now respects the three second cooldown that it is suppose to be limited by.
+
+
ToasterBiome updated:
+
+ Removes tile grime and support for it.
+ Replaces tiles to be less shiny.
+
+
ynot01 updated:
+
+ Command channel is now blue once more
+ fixed pseudocider not duplicating headwear
+
+
+
28 November 2023
+
MajManatee updated:
+
+ Horrors can now scan their hosts
+ Horror chemicals now say how much they inject
+
+
Moltijoe updated:
+
+ Only Delta alert gets red lights
+ Fixes an IAA bug involving pseudocider
+ adds a glowing outline to anyone with the holy light heal boost
+ fixed a bug where limb healing generated less favour than overall healing
+ Increases the holy light heal boost duration to 1 minute from 30 seconds
+ Reduces the amount of favour that holy light generates by 50%
+ Gives warden brig phys access during skeleton crew
+ Makes monster hunters monster hunting objective actually tell the monster hunter to hunt monsters
+
+
Runian updated:
+
+ Constructed anchored emitters are correctly recognized as wrenched; you no longer need to wrench these anchored emitters twice to make it work.
+ Flying Fang's damage-dealing disarms respects pacifism as intended.
+
+
SapphicOverload updated:
+
+ fixed fire extinguishers not working if the particle never moves
+
+
cowbot92 updated:
+
+ Added new fruit
+ Added new drink to go with that fruit
+ added some icons and images for lantern fruits and drinks
+
+
+
27 November 2023
+
goober3, cark updated:
+
+ added some dirt linings
+
+
Moltijoe updated:
+
+ Syndicate fedora can no longer be caught using throw mode
+
+
Mqiib updated:
+
+ Lizard wings now use the new lizard colors instead of the slightly-off old colors
+
+
Runian updated:
+
+ Ion storms can affect up to 20 airlocks and 10 APCs with random effects, only if is no AI.
+ Airlocks affected by ion storms will randomly have one of the following effects: toggle bolts, toggle emergency access, shock temporarily or have their safety & speed toggled.
+ APCs affected by ion storms will have one of three or all of their power channels turned off.
+
+
SapphicOverload updated:
+
+ preternis now purge 4% of internal chemicals every tick, instead of purging everything after 20 ticks
+ preternis are no longer immune to the effects of morphine and a few other chemicals
+ fixed unintended change to damage of every two-handed weapon
+ fixed runtime error when trying to use certain two-handed weapons with one hand
+ fixed preternis being affected by water through hardsuits
+
+
cowbot92 updated:
+
+ Ports updated TG announcements & TGUI
+
+
+
26 November 2023
+
Moltijoe updated:
+
+ Battle royale loot distribution
+
+
SomeguyManperson updated:
+
+ hallucination anomalies have had their effects altered. You many want to bring a toolbox instead of mesons when responding to one
+ hallucination reactive armor has had its effects modified similarly to the new effects of the anomaly
+ the supermatter will no longer spawn hallucination anomalies when exploding, on fire, or otherwise.
+
+
+
25 November 2023
+
Ghommie updated:
+
+ Examining a human mob as an observer displays "Quirks", not "Traits"
+
+
JohnFulpWillard updated:
+
+ Seclites now have directional lights- point them in the direction you want to see more of.
+ Ported over many refactors to lighting and opacity. Please report if you can walk or see through walls unintentionally.
+
+
Majkl-J updated:
+
+ Virology: New symptom, superficial healing
+
+
Runian updated:
+
+ Shooting plasma sheets with a damaging burn-based projectile ignites it.
+
+
SapphicOverload updated:
+
+ added preference for non-upgraded cybernetic organs as quirk options
+ random cybernetic organ quirk costs 3 instead of 4
+
+
cowbot92 updated:
+
+ Adds auxmos to the minor filter
+
+
+
23 November 2023
+
SapphicOverload updated:
+
+ power-fist works like a glove now
+
+
SomeguyManperson updated:
+
+ gangrel gorilla transformation is now 15 armor down from 40
+
+
Yarinoi updated:
+
+ Medical can print chemical analyzer implants again.
+
+
warface1234455 updated:
+
+ Remove the portable pump cargo pack
+
+
ynot01 updated:
+
+ The door between the armory and the auxiliary armory are now default security access
+
+
+
22 November 2023
+
PositiveEntropy, Cark, Blutsu updated:
+
+ new wood sprites from TG, and resprites on stairs by Blutsu
+ replaces old wood tile sprites
+
+
cark updated:
+
+ bridge on donut now has an APC and blast doors, apc in chapel is moved and some other minor fixes
+
+
00ze-cyclone updated:
+
+ Removed helmet, bulletproof helmet and riot helmet crates
+ armor, bulletproof armor and riot armor crates now contain helmets as well, price adjusted to cost the same as before
+
+
JohnFulpWillard updated:
+
+ Pancake overlays now work
+
+
SapphicOverload updated:
+
+ fixed people with the bald trait not being bald when cloned
+
+
Therandomhoboo updated:
+
+ Glycerol making results in 3 units instead of 1
+ Reinforced Window Damage deflection is now 11 instead of 10
+
+
wonderinghost updated:
+
+ Adds new programs and hardware to pdas
+
+
+
20 November 2023
+
Cowbot92 & ChubbyGummibear updated:
+
+ tweaks heretic TGUI
+ tweaks heretic blade's wound chance
+
+
Moltijoe updated:
+
+ Fixes a bug where lightning flow disabled certain actions if a dash ended weirdly
+ Makes syndicate fedora and boomerang not super janky
+ Syndicate fedora has a longer click throw cd
+ Fixes extended shock touch not having a cooldown or sound effect
+
+
+
19 November 2023
+
Cark, Paxilmaniac updated:
+
+ added a stone floor icon
+
+
JohnFulpWillard, warface1234455 updated:
+
+ Atmos alert console can clear air alarm atmos alert
+ During an active fire nearby a firealarm, it will show you the current temperature when examined
+ Firealarm now notify on engineering channel when theres a fire
+ Fix station alert console and program not updating overlays
+ Fix fire alerts not clearing when there are multiple fire alarms in one area
+ fix destroyed airalarm clearing atmos alert if theres an actual atmos alert in an area with multiple air alarms
+
+
cark updated:
+
+ fixes issues with the asteroid field on donut causing people to get teleported inside rocks when moving onto the z-level
+ adds more wall extinguishers to donut
+
+
Moltijoe updated:
+
+ Lets admins choose the amount of TC given when they make everyone traitor
+
+
SapphicOverload updated:
+
+ mech extinguisher uses firefighting foam instead of water
+ fixed extinguisher particles not disappearing when they stop moving
+ fixed blocking your own extinguisher when moving forward
+ lizard tails grow back properly
+ fire extinguishers can once again extinguish fire
+
+
bruhlookatthisdood updated:
+
+ [Donut] Moved medical laptop in brig medical to make medical supplies accessible
+
+
ynot01 updated:
+
+ Added Christ Christodoulou - Coalescence (2023) to the lobby playlist
+ Removed Christ Christodoulou - Coalescence (2013) from the lobby playlist
+
+
18 November 2023
Aquizit updated:
@@ -1647,572 +2039,6 @@ tattax updated:
readds pacify (spell) to the game
-
- 09 September 2023
- MidoriWroth, Ghommie, ktlwjec updated:
-
- Peanuts. Seeds start in the botany vendor. They can be grinded to make peanut butter.
- Breadsticks. Raw breadsticks crafted with 1 dough slice, 3u salt, 2 butter slices. Baked in the oven.
- Granola bar. Crafted with 1 oat stalk, 1 peanut, 1 chocolate, 1 raisins, 2u sugar.
- Onigiri. Crafted with 1 seaweed sheet and 1 boiled rice. Can be customised with other ingredients.
- Peanut butter cookie. Crafted with 5u peanut butter, 1 pastry base.
- Brownie batter. Raw brownie batter crafted with 5u flour, 5u sugar, 2 eggs, 5u coco powder, 4 butter slices. Baked in the oven and then sliced into 4 pieces.
- Peanut butter and banana sandwich. Crafted with 2 bread slices, 5u peanut butter, 1 banana.
- Peanut butter and jelly sandwich. Crafted with 2 bread slices, 5u peanut butter, 5u cherry jelly.
- Nigiri sushi. Crafted with 1 seaweed sheet, 1 boiled rice, 1 carp meat, 2u soy sauce.
-
- cark updated:
-
- the beach biodome no longer spawns on lavaland
-
- MajManatee updated:
-
- Added 3 new ghost types
-
- Moltijoe updated:
-
- Cultist mirror shield no longer spawns infinite illusions if blocking a shotgun
- Cultist mirror shield can only spawn 4 illusions before breaking instead of 5
- Cultist mirror shield illusions have 1 health and 0 damage
- Blood cult spear is huge instead of normal size
- Northern Coat is no longer ckey locked
- Holy Light water no longer applies a heal boost
- Holy Light bible now applies a 30 second duration heal boost
- Holy Light bible now heals for 10 instead of 40 with a 10 second cooldown instead of 12 and has no favor cost
- Holy Light heal boost now increases by 100% (200% in chapel) instead of 20% (40% in chapel)
- Holy Light medbot applies the heal boost status effect instead of injecting holy water
- Borg reagent dispensers regen in seconds rather than deciseconds
- Borg reagent dispensers regen less affected by lag
- Spawns 3 clockcult + 1 for every 8 players over 30 instead of 4 + 1 for every 10
- CPR only requires lungs, not needing to breathe
- His Grace can be bought by assistants
- Drag and drop iv drip filling
- Cultist shield robe has 1 shield charge, but regens after 45 seconds of not getting hit
-
- Runian updated:
-
- Syndicate Surgery Duffel Bag's description in the Uplink now accurately tells you that the surgery tools have double toolspeed (0.5) and includes a surgical mat.
- Failed cyborg shoves no longer push them back two tiles.
- Hulk punches on cyborgs now properly pushes them back two tiles.
- PKA upgrades properly eject when crowbarred.
- A new upgrade for engineering and mining cyborgs that replaces their normal meson vision with night vision meson vision.
- Cyborg meson/material dark vision is now consistent with the human version of 2 tiles.
- Cyborg meson/material lighting alpha is now consistent with the human version.
-
- SomeguyManperson updated:
-
- Syndicate icemoon base has been downgraded to keep the syndicate on the base
-
- azzzertyy updated:
-
- Chaplain no longer throws people into snow on Icemeta
- No more superspeed on icemeta
-
- solwashere updated:
-
- Adds "testing" to the GitHub PR template.
-
- warface1234455 updated:
-
- Bluespace harvester can now output alien tool for 60000 points
-
-
- 08 September 2023
- MajManatee updated:
-
- generator fuel can be dragged into the generator now.
-
- Moltijoe updated:
-
- Preterni are slightly more likely to catch viruses than before
- Viruses in preterni progress faster
- Preternis water damage does ~50% more stamina damage
-
- adamsong updated:
-
- fixed photos being bugged as hell
-
-
- 07 September 2023
- cark updated:
-
- removes the two hospital ruins on lavaland
-
- Runian updated:
-
- Clown Cyborg's pie cannon now properly recharges every 4 seconds (2 ticks) instead of every 2 seconds (1 tick).
- All self-recharging pneumatic cannon now recharge based on delta_time instead of ticks. This means that you won't lose out when lag happens.
-
- SapphicOverload updated:
-
- hecata clan necromancy reverts you back to your original species after it ends instead of staying a zombie
-
- adamsong updated:
-
- bluespace harvester now has a 10 minute cooldown after spawning a portal when not emagged
-
-
- 06 September 2023
- Runian updated:
-
- You must now be adjacent to unlock or lock a robot's cover instead of infinite range.
-
-
- 05 September 2023
- Addust updated:
-
- syndicate icemoon is slightly less shit. _**I CANNOT FIX THE RANDOM FAUNA SPAWNS. THAT'S THE ICEMOON DEV'S PROBLEM.**_
- i fucked up
-
- Runian updated:
-
- Pulsing Mech Fabricator's WIRE_ZAP no longer breaks your limbs unless you are adjacent to it as intended.
-
- SomeguyManperson updated:
-
- holy light now gains more favor when gaining favor
-
- wonderinghost updated:
-
- Added pencil holder to bureaucracy crate and game.
- adds pencil holder files
-
-
- 04 September 2023
- cark updated:
-
- donors can take pride hoodies as a donor item now
-
- ktlwjec updated:
-
- Roboticist and geneticist get rnd console access on skeleton crew.
- Engineers and shaft miners can use the rnd console on skeleton crew.
-
- Addust updated:
-
- The Syndicate has stopped throwing their supposedly important listening stations into gibtonite-filled shithole rocks, and has also supplied a few extra supplies.
- i forgor an air alarm in syndie lavaland
-
- Marmio64 updated:
-
- Hecata Bloodsuckers need to revive 4-5 people rather than 7-8
-
- Moltijoe updated:
-
- vials reskin using the proper sprite again
-
- Runian updated:
-
- Certain words in the German accent such as "research" and "scientist" are now properly accented.
-
- SapphicOverload updated:
-
- fixed bloodsucker vassalization not removing mindshield implants
-
- SomeguyManperson updated:
-
- coders are no longer required to explain why "the game functions correctly" is good for the game
-
- adamsong updated:
-
- fixed AI shell lawsync not working
- fixed photos forgetting about people who are cremated
- fixed photos not recognizing targets who were cloned
- fixed photos thinking dead people are alive after copying
-
- warface1234455 updated:
-
- Replaces old pda with modern pda in pda box
-
-
- 03 September 2023
- MajManatee updated:
-
- The engineering vendor now has one compressed matter per RCD instead of 3/5
-
- Moltijoe updated:
-
- Preternis Liquidator now needs to actually do the combo
-
- SapphicOverload updated:
-
- necromancy no longer works on mindshielded people unless they're on a persuasion rack
- fixed x-ray bolts causing toxin damage to rad-immune species when embedded
- preternis now slow down and suffocate when low on charge instead of just instantly dropping dead when they hit zero
- liquid electricity can now actually charge species that run on electricity
- radiation charges ethereals now
- preternis, ethereal, and IPC charging have been refactored, please report any bugs you find
-
- warface1234455 updated:
-
- Give the gas analyzer ability to scan turf next to the user
-
-
- 02 September 2023
- @cuackles, @SapphicOverload updated:
-
- adds pride jackets to hacked clothing vendors
- pride jackets
-
- ArcaneMusic, Ktlwjec updated:
-
- BBQ sauce, made with 1u ash, 1u tomato juice, 3u saline glucose, 1u black pepper.
- BBQ ribs, made with 2 rods, 5u bbq sauce, 2 steaks.
- 2 BBQ sauce packets in the kitchen dinnerware vendor.
-
- cark updated:
-
- kills under-window firelocks across all maps, making them consistent with each other and themselves.
-
- JamieD1 updated:
-
- Fixes shitty Pranksimov Laws
-
- Marmio64 updated:
-
- Hecata bloodsuckers take 3x as long (18 seconds) to necromance mindshielded non vassals.
- Syndicate derelict engis can use their c20r
-
- Moltijoe updated:
-
- Holy medbots have antimagic and also inject holy water
- Holy revival rite gives 2 minutes of antimagic
- Getting the adrenaline buff from damage gives a mood boost
- Worldbreaker tweaks
- throw only does damage upon collision, not upon throwing
- grabbing now stuns for a very short time to allow for aiming
- pummel does 20 damage instead of 15
- pummel has regular attack cooldown instead of slower (preterni no longer attack slower)
- plates have 25 health instead of 15
- can only have 3 plates over armour cap instead of 5
- plates take 1/4 damage from non brute and burn rather than 1/3
- plates give more slowdown
- leap cooldown no longer scales directly with number of plates, instead just takes 1 second longer if heavy
- leap speed now directly scales with movespeed (meaning outside sources of movespeed will increase it)
- leap cooldown only starts once you land, rather than when you start jumping
- now gives softcrit immunity
- no longer gives damage slowdown resistance
- never takes damage from being thrown into a wall
- attacks can now hurt mechs
-
- Runian updated:
-
- A new upgrade for medical cyborgs that gives them a gripper that lets them hold bottles, beakers, and blood bags.
- Cyborg gripper now copy overlays for the held items.
-
- SomeguyManperson updated:
-
- holy light chaplains no longer gain favor from bible bashing people, instead spending favor to heal
- holy light now provides a passive buff to people who ingest holy water, increasing incoming healing by 20%, doubled in the chapel. Bonus healing applied by this effect is also turned into favor. Bible bashing someone with this buff has a massively reduced favor cost, but does not heal significantly more than the default.
-
- adamsong updated:
-
- fixed a few bus buttons being available to moderators
- Admins can now view their own permissions
-
-
- 01 September 2023
- Moltijoe updated:
-
- passive good mood organic limb healing now requires being full instead of mood
- passive organic limb healing now has a 100% chance per tick, but heals half as much
-
- Runian updated:
-
- Service cyborgs start with a gripper that lets them interact with various service items, including food.
- A new upgrade is available for service cyborgs that lets them access the cooking section of the crafting menu only.
- Cyborgs can interact with things that they CanReach instead of having to be adjacent.
- Cyborgs can now toggle griddles and ovens.
- Grippers now re-center items that they pick up.
-
- SapphicOverload updated:
-
- ethereals have electrolyzer breath now
-
-
- 31 August 2023
- xXPawnStarrXx updated:
-
- Fixed corn cobs not making seeds and lying to you in the text box.
-
- Addust updated:
-
- cleans the naughty room maint ruin (sadly not with fire)
-
- Aquizit updated:
-
- Change of flavor text for no cap at round start
-
- GraveHat updated:
-
- renames the corn maze datum from forgottenkitchen to chasmcornmaze to avoid confusion
- adds a Lavaland ruin for the Herald Elite Fauna
-
- JohnFulpWillard updated:
-
- MajManatee updated:
-
- Selecting wizard now lets you play ragin and BS wizard modes.
-
- Moltijoe updated:
-
- Fixes ethereal brute mod being 1.5 rather than 1.25 like intended
- Ethereals can now release excess power into already full apcs
- Rad goats can no longer crash the server using unlimited goat works
-
- Runian updated:
-
- A new upgrade for engineering cyborgs have been added that gives them a BRPED. It requires the RPED upgrade to be installed first as a prerequisite.
- Prerequisite upgrades for cyborg upgrades properly function as intended.
- On deactivation, Cyborg RPED drop all parts onto the floor instead of disappearing into the void.
- "Cyborg Upgrades: Advanced Utility" now also requires the "Applied Bluespace Research" techweb node as a prerequisite.
- Cyborg RPED's name starts with "cyborg" to note it is the cyborg version.
-
- SapphicOverload updated:
-
- fixed missing wire in CE office, APC is connected now
-
- adamsong updated:
-
- adminwho now knows grammar
-
- solwashere updated:
-
- Suppressors no longer add a weight class to weapons
- Enloudener no long can be exploited to permanently decrease a weapons weight class
-
- warface1234455 updated:
-
- Anticitizen line now work in sechailer
-
-
- 29 August 2023
- TehZombehz for the sprites, san7890, ktlwjec updated:
-
- Abductor plushies! Winnable with arcade machines, or can be bought for 1 point by abductors.
- Decorative Items section on the abductor console.
- Moves random poster from basic gear to decorative items for abductors.
-
- tf-4 updated:
-
- Fixed a spelling error with the daps emote.
-
- timothymtorres updated:
-
- Adds a new light effect to slot machines when you win.
- Adds new sounds to slot machines.
-
- Aquizit updated:
-
- sets mood to TRUE for family heirloom quirk
-
- JohnFulpWillard updated:
-
- All sechailer lines now should work again.
-
- Marmio64 updated:
-
- Space syndicate listening post slight loot tweak. One agent is now considered the superior and has better equipment with an ultra secure pinlock revolver, while their subordinate has a combat knife rather than an energy sword.
- One of the energy swords locked inside a crate on the syndicate space derelict is replaced with a ultrasecure c20r SMG that self destruct upon use/tamper by non syndicates.
-
- Moltijoe updated:
-
- Flying people can carry others over chasms or lava without killing them
-
- Runian updated:
-
- Syndicate MMIs can be purchased by Roboticists (and the Research Director) for 3 telecrystals.
- Syndicate MMIs temporarily turns the inserted brain into a mindslave until the brain is removed.
- Cyborgs with a Syndicate MMI retain all functions that as a normal cyborg would, except they have an irremovable law zero all to serve whoever imprinted on it (or The Syndicate if none).
- Syndicate MMIs no longer gives the Syndicate Override lawset, prevents connection for any AI, or disallow law changes.
- Syndicate Surgery Duffel Bag has a normal MMI instead of a Syndicate MMI.
- You can toggle the radio of a MMI via alt-click regardless if there was a brain or not.
- Cyborgs can now repair fire axe cabinets properly.
- Using cyborg reinforced glass on/for certain structures now work properly.
- Cyborgs can attempt to trigger a fire axe cabinet's alarm by interacting with it on harm intent with no module.
-
- Therandomhoboo updated:
-
- New drink, Syndicate Screwdriver
- Syndicate Screwdriver sprite
-
- adamsong updated:
-
- fixed errors when logging clones
- fixed engineering payouts erroring at the start of the round
- fixed slurring
- fixed a runtime when checking if infiltrators can spawn too early in the round
- fixed a couple errors with the gender selector
-
-
- 28 August 2023
- Runian updated:
-
- Pranksimov, a funny variant of Crewsimov, has been added.
- Cmagging a Crewismov law board converts it to a Pranksimov law board.
- Cmagging a AI's B.O.R.I.S shell will set their module to Clown.
- Cmagging a Cyborg will disconnect them from the AI and set their laws to Pranksimov. However, be warned that there won't be a law zero! Hope they find helping you more funnier than not.
-
-
- 27 August 2023
- Addust updated:
-
- The Syndicate Icemoon base!
- A Syndicate research post with 6 crew, deep within the icy wastes.
- i fucked up the firing pin boxes woops
-
- MajManatee updated:
-
- Two vital emotes. You can now Hit the griddy and Do the stanky leg.
-
- Yarinoi updated:
-
- The mental faculties of the average crew member have increased.
-
- warface1234455 updated:
-
- fix mirror not shifting to the wall when placed
-
-
- 26 August 2023
- warface1234455 updated:
-
- you can now craft mirror and put it on wall using 1 silver, 1 rod and 1 glass
-
-
- 25 August 2023
- Moltijoe updated:
-
- Locks Worldbreaker behind hijack and glorious death
-
- SapphicOverload updated:
-
- ultra violence is now hijack/martyr only
-
- ToasterBiome updated:
-
- BoxStation detective office flipped
-
- warface1234455 updated:
-
- hotfix altclicking pda not ejecting id out
-
-
- 24 August 2023
- goobliner updated:
-
- SapphicOverload updated:
-
- fixed lemoline recipe
-
- warface1234455 updated:
-
- fix altclicking pda for secondary card not updating sec record
-
-
- 23 August 2023
- Marmio64 updated:
-
- Ultrakill martial art is 20 TC again instead of 16
-
- Runian updated:
-
- You can no longer respawn immediately as a servant golem after already having respawned as a servant golem before. Use your golem life wisely until your golem respawn timer has passed.
- Uranium golem info text no longer lies to you by removing the claim that your punches do as much as a human.
- Golems stop wagging their tail if they somehow die with one.
- "Cyborg Upgrade (Translation Matrix)" design now prints the correct upgrade.
- langauges -> languages
-
- iloveloopers updated:
-
- Heretic worm ascension abillity to contract has had its cooldown reduced to 15 seconds
-
- warface1234455 updated:
-
- readd radiation anomaly that shoots radballs and emits radiation (this is normal anomaly that doesnt spawn rad goat, admin one does)
- replaces the orange goat with rad goat on goat search shuttle
- rainbow goat is now replaced with rad goat in exotic goat crate
-
-
- 22 August 2023
- cark updated:
-
- fixes a broken pipe in the backroom of botany
-
- Runian updated:
-
- Engineering Cyborg's gripper can pick up conveyor belts and conveyor belt switches.
-
- maxion12345 updated:
-
- Added the Crowd-Sourced Shuttle. This shuttle was built from the BYOS on round 48641
-
-
- 21 August 2023
- carshalash updated:
-
- You can craft paper cups using 2 paper.
-
- ktlwjec updated:
-
- Enchiladas needs a cheese wedge to craft.
- Khinkali needs an onion slice and garlic to craft.
- Chocolate orange needs 2 units of orange juice, instead of an orange, to craft.
- Mushroom and vegetable pizzas both need a cheese wedge and tomato to craft.
-
- Runian updated:
-
- Jestographic Sequencer, a role-restricted traitor item for the Clown, is buyable at 4 TCs.
- Jestographic Sequencer, if used on airlocks, will invert access.
- Failing to emag something refunds the charge.
- Cyborgs gets feedback similar to the AI when they interact with an non-functioning (e.g emagged) airlock.
- Mechs no longer need a pilot to determine if they have access to a door.
- Changed Explosive Airlock Charge's uplink description to be more accurate on how it is triggered.
- Emagging the sechailer works now.
-
- adamsong updated:
-
- grants players cured of tumors clothes privileges again
- fixed pet kill objective name typo
-
-
- 20 August 2023
- Rhials, ktlwjec updated:
-
- The abductor equipment vendor now sells decorative abductor posters, at a price of 1 research point.
- Posters can now be hung on abductor walls.
-
- JohnFulpWillard & Mothblocks updated:
-
- Removes being able to stack do_afters on things (like surgery on several limbs on the same person).
- Removed do_mob, do_after_mob and do_atom.
- You now do CPR faster after the first attempt.
-
- Moltijoe updated:
-
- Fixes some weird interactions around multiple sources of EMP immunity
-
- SapphicOverload updated:
-
- fixed lizard snouts
- fixed a spriting error causing glasses to be partially hidden under some lizard snouts
-
- Scrambledeggs00 updated:
-
- Peacekeeper helm, belt, vest, and uniforms added
- Peacekeeper riot suit, helm, beret, tactical stunprod, and tactical breath mask have new sprites
- Most Peacekeeper gear is no longer green tinted Security gear
-
- wonderinghost updated:
-
- Minor changes to law office
- Deletes old pda cartridge
- Adds printer and pens
-
GoonStation 13 Development Team
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index df0533717bd2..7c6db608a26f 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -42262,3 +42262,291 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- mapping: Added /tcommsat/storage area and icon
- mapping: Replaced maint with storage on Box & Asteroid
- mapping: Fixed area swap on Asteroid
+2023-11-19:
+ ' Cark, Paxilmaniac':
+ - imageadd: added a stone floor icon
+ ' JohnFulpWillard, warface1234455':
+ - rscadd: Atmos alert console can clear air alarm atmos alert
+ - rscadd: During an active fire nearby a firealarm, it will show you the current
+ temperature when examined
+ - tweak: Firealarm now notify on engineering channel when theres a fire
+ - bugfix: Fix station alert console and program not updating overlays
+ - bugfix: Fix fire alerts not clearing when there are multiple fire alarms in one
+ area
+ - bugfix: fix destroyed airalarm clearing atmos alert if theres an actual atmos
+ alert in an area with multiple air alarms
+ ' cark':
+ - mapping: fixes issues with the asteroid field on donut causing people to get teleported
+ inside rocks when moving onto the z-level
+ - mapping: adds more wall extinguishers to donut
+ Moltijoe:
+ - tweak: Lets admins choose the amount of TC given when they make everyone traitor
+ SapphicOverload:
+ - tweak: mech extinguisher uses firefighting foam instead of water
+ - bugfix: fixed extinguisher particles not disappearing when they stop moving
+ - bugfix: fixed blocking your own extinguisher when moving forward
+ - bugfix: lizard tails grow back properly
+ - bugfix: fire extinguishers can once again extinguish fire
+ bruhlookatthisdood:
+ - bugfix: '[Donut] Moved medical laptop in brig medical to make medical supplies
+ accessible'
+ ynot01:
+ - rscadd: Added Christ Christodoulou - Coalescence (2023) to the lobby playlist
+ - rscdel: Removed Christ Christodoulou - Coalescence (2013) from the lobby playlist
+2023-11-20:
+ ' Cowbot92 & ChubbyGummibear':
+ - tweak: tweaks heretic TGUI
+ - tweak: tweaks heretic blade's wound chance
+ Moltijoe:
+ - bugfix: Fixes a bug where lightning flow disabled certain actions if a dash ended
+ weirdly
+ - bugfix: Makes syndicate fedora and boomerang not super janky
+ - tweak: Syndicate fedora has a longer click throw cd
+ - bugfix: Fixes extended shock touch not having a cooldown or sound effect
+2023-11-22:
+ ' PositiveEntropy, Cark, Blutsu':
+ - imageadd: new wood sprites from TG, and resprites on stairs by Blutsu
+ - imagedel: replaces old wood tile sprites
+ ' cark':
+ - mapping: bridge on donut now has an APC and blast doors, apc in chapel is moved
+ and some other minor fixes
+ 00ze-cyclone:
+ - rscdel: Removed helmet, bulletproof helmet and riot helmet crates
+ - tweak: armor, bulletproof armor and riot armor crates now contain helmets as well,
+ price adjusted to cost the same as before
+ JohnFulpWillard:
+ - bugfix: Pancake overlays now work
+ SapphicOverload:
+ - bugfix: fixed people with the bald trait not being bald when cloned
+ Therandomhoboo:
+ - tweak: Glycerol making results in 3 units instead of 1
+ - tweak: Reinforced Window Damage deflection is now 11 instead of 10
+ wonderinghost:
+ - rscadd: Adds new programs and hardware to pdas
+2023-11-23:
+ SapphicOverload:
+ - tweak: power-fist works like a glove now
+ SomeguyManperson:
+ - tweak: gangrel gorilla transformation is now 15 armor down from 40
+ Yarinoi:
+ - rscadd: Medical can print chemical analyzer implants again.
+ warface1234455:
+ - rscdel: Remove the portable pump cargo pack
+ ynot01:
+ - tweak: The door between the armory and the auxiliary armory are now default security
+ access
+2023-11-25:
+ ' Ghommie':
+ - spellcheck: Examining a human mob as an observer displays "Quirks", not "Traits"
+ JohnFulpWillard:
+ - rscadd: Seclites now have directional lights- point them in the direction you
+ want to see more of.
+ - experiment: Ported over many refactors to lighting and opacity. Please report
+ if you can walk or see through walls unintentionally.
+ Majkl-J:
+ - rscadd: 'Virology: New symptom, superficial healing'
+ Runian:
+ - tweak: Shooting plasma sheets with a damaging burn-based projectile ignites it.
+ SapphicOverload:
+ - rscadd: added preference for non-upgraded cybernetic organs as quirk options
+ - tweak: random cybernetic organ quirk costs 3 instead of 4
+ cowbot92:
+ - rscadd: Adds auxmos to the minor filter
+2023-11-26:
+ Moltijoe:
+ - tweak: Battle royale loot distribution
+ SomeguyManperson:
+ - tweak: hallucination anomalies have had their effects altered. You many want to
+ bring a toolbox instead of mesons when responding to one
+ - tweak: hallucination reactive armor has had its effects modified similarly to
+ the new effects of the anomaly
+ - rscdel: the supermatter will no longer spawn hallucination anomalies when exploding,
+ on fire, or otherwise.
+2023-11-27:
+ ' goober3, cark':
+ - imageadd: added some dirt linings
+ Moltijoe:
+ - tweak: Syndicate fedora can no longer be caught using throw mode
+ Mqiib:
+ - imageadd: Lizard wings now use the new lizard colors instead of the slightly-off
+ old colors
+ Runian:
+ - rscadd: Ion storms can affect up to 20 airlocks and 10 APCs with random effects,
+ only if is no AI.
+ - rscadd: 'Airlocks affected by ion storms will randomly have one of the following
+ effects: toggle bolts, toggle emergency access, shock temporarily or have their
+ safety & speed toggled.'
+ - rscadd: APCs affected by ion storms will have one of three or all of their power
+ channels turned off.
+ SapphicOverload:
+ - tweak: preternis now purge 4% of internal chemicals every tick, instead of purging
+ everything after 20 ticks
+ - tweak: preternis are no longer immune to the effects of morphine and a few other
+ chemicals
+ - bugfix: fixed unintended change to damage of every two-handed weapon
+ - bugfix: fixed runtime error when trying to use certain two-handed weapons with
+ one hand
+ - bugfix: fixed preternis being affected by water through hardsuits
+ cowbot92:
+ - tweak: Ports updated TG announcements & TGUI
+2023-11-28:
+ MajManatee:
+ - tweak: Horrors can now scan their hosts
+ - tweak: Horror chemicals now say how much they inject
+ Moltijoe:
+ - tweak: Only Delta alert gets red lights
+ - bugfix: Fixes an IAA bug involving pseudocider
+ - rscadd: adds a glowing outline to anyone with the holy light heal boost
+ - bugfix: fixed a bug where limb healing generated less favour than overall healing
+ - tweak: Increases the holy light heal boost duration to 1 minute from 30 seconds
+ - tweak: Reduces the amount of favour that holy light generates by 50%
+ - tweak: Gives warden brig phys access during skeleton crew
+ - bugfix: Makes monster hunters monster hunting objective actually tell the monster
+ hunter to hunt monsters
+ Runian:
+ - bugfix: Constructed anchored emitters are correctly recognized as wrenched; you
+ no longer need to wrench these anchored emitters twice to make it work.
+ - bugfix: Flying Fang's damage-dealing disarms respects pacifism as intended.
+ SapphicOverload:
+ - bugfix: fixed fire extinguishers not working if the particle never moves
+ cowbot92:
+ - rscadd: Added new fruit
+ - rscadd: Added new drink to go with that fruit
+ - imageadd: added some icons and images for lantern fruits and drinks
+2023-11-29:
+ Moltijoe:
+ - tweak: Brig physician also gets cloning and airlock access during skeleton crew
+ - tweak: Paramedic also gets surgery access during skeleton crew
+ - tweak: Mining medic also gets cloning, maint, and airlock access during skeleton
+ crew
+ - tweak: All hecata zombies die when the controlling bloodsucker dies
+ - bugfix: lightning flow no longer immobilizes for like 0.1 seconds every dash
+ - bugfix: Preterni no longer get 20% more power from liquid electricity than other
+ powerhungry species
+ - tweak: All powerhungry species now get "food" from consuming teslium, not just
+ Preterni
+ Runian:
+ - rscadd: Lizard tail users can *thump their tail.
+ - soundadd: Tail thump.
+ - bugfix: Guardian's Frenzy Ability now respects the three second cooldown that
+ it is suppose to be limited by.
+ ToasterBiome:
+ - rscdel: Removes tile grime and support for it.
+ - imageadd: Replaces tiles to be less shiny.
+ ynot01:
+ - tweak: Command channel is now blue once more
+ - bugfix: fixed pseudocider not duplicating headwear
+2023-11-30:
+ ToasterBiome:
+ - rscadd: Adds a new lavaland lava type that you can't replace with shelter
+ - tweak: lavaland syndie base is surrounded by no-shelter lavaland lava
+2023-12-01:
+ ' Twaticus, Imaginos16, Cark':
+ - imageadd: added new object sprite for plasteel tile
+ - imagedel: deleted old object sprite for plasteel tile
+ JohnFulpWillard:
+ - bugfix: Stasis units and sleepers now have proper overlays and lavaland sleepers
+ aren't invisible anymore.
+ Yarinoi:
+ - rscadd: Pitying the miners attempting to look for it, the Demonic Frost Miner
+ now gives out a Hollow Signal on GPS.
+ azzzertyy:
+ - tweak: You can now point while handcuffed
+ cowbot92:
+ - rscadd: Adds new bar signs
+2023-12-02:
+ Moltijoe:
+ - bugfix: No more infinitely duplicating hulk DAN
+ - tweak: Hulk now occasionally says the brain damage hulk lines
+ SapphicOverload:
+ - bugfix: fixed runtime error when passive vents encounter zero temperature or zero
+ volume
+ - bugfix: fixed abandoned crates having a 2% chance to cause runtime errors when
+ initialized
+2023-12-03:
+ ' cark':
+ - mapping: fixes missing floor in airlock on donut
+ ' itseasytosee, sapphicoverload':
+ - tweak: some items and projectiles are now better or worse than others at destroying
+ things
+ - tweak: chat messages from hitting an object now tell whether you can damage it
+ - bugfix: fixed machines/structures/etc not caring about armor penetration when
+ hit by a melee weapon
+ - bugfix: fixed cannonballs not doing any damage to mobs
+ Moltijoe:
+ - bugfix: Sometimes fixes feed ability sometimes breaking
+ - tweak: Gangrel transformation ability now shows the radial menu before the 10
+ second do_after
+ - bugfix: Fixes gangrel transformation ability sometimes deleting itself without
+ ever being used
+ - bugfix: Fixes gangrel werewolf transformation being eradicated from the timeline
+ by tattax
+ SapphicOverload:
+ - bugfix: fixed ED-209 not being affected by heavy EMPs
+ - bugfix: fixed leg implants not being affected by EMPs at all
+ - bugfix: fixed cybernetic ears causing longer knockdown times on light EMPs instead
+ of the other way around
+ - bugfix: fixed nanite heart killing you instantly on EMP regardless of whether
+ or not it kills your nanites
+ - tweak: HoS gun now shoots ion carbine projectiles instead of its own redundant
+ projectile type
+ - tweak: mech ion cannon has 1.5x stronger EMPs than the ion rifle
+ - tweak: syndicate EMP bomb has 2.5x stronger EMPs than standard EMP grenades
+ - experiment: reworks EMPs to allow any severity, which now decreases with distance
+2023-12-04:
+ Moltijoe:
+ - tweak: Pseudocider costs 8tc instead of 6tc
+ - tweak: Pseudocider has a 30s cooldown instead of 20s
+ SapphicOverload:
+ - experiment: electrical protection is now its own armor type
+ - tweak: certain engineering equipment like hard hats and work boots now have electrical
+ protection
+ - tweak: spliced wires check electrical protection on your feet instead of your
+ hands when you step on them
+ - tweak: combat defib disarm takes electrical protection on targeted limb into account
+ - tweak: lightning flow punches, combat defib disarm, and hacked cyborg hug module
+ all check electrical protection on the targeted limb
+ - tweak: touching hacked cyborg energy fields with your hand now actually checks
+ protection on that hand
+ - tweak: slightly reorganized the armor tags and adds electrical protection to the
+ list
+ - bugfix: fixed nanites not being affected by electric shock because of a missing
+ signal
+ - bugfix: fixed gloves and shoes with armor not actually protecting your hands and
+ feet respectively
+ - bugfix: fixed power fist not working
+ azzzertyy:
+ - rscdel: Mediator is no longer roundstart.
+2023-12-05:
+ cowbot92:
+ - rscadd: Adds new alt-job titles to roboticists
+ ninjanomnom, Ryll-Ryll, Bizzonium, KylerAce, Sinsinins, lessthnthree:
+ - experiment: Added new fonts and refactored runechat. Also some backend stuff it's
+ fine.
+ sapphicoverload, bluishtsunami:
+ - rscadd: adds a water gun to donksoft vending machines (and uplink)
+ - tweak: preternis water damage tweaked to be more affected by smaller volumes
+ - tweak: preternis water damage updates immediately when splashed instead of waiting
+ up to 2 seconds
+2023-12-06:
+ AMyriad:
+ - spellcheck: Scrubbed the second "m" from the last mentions of "Centcomm"
+ - spellcheck: All mentions of "NanoTrasen" have also been corrected to "Nanotrasen"
+ - tweak: Added some more words and fixed some old ones for the Nordic accent
+ SapphicOverload:
+ - tweak: HFR processes at the same rate as other atmos machines now
+ - bugfix: fixed extended lungs
+ - bugfix: fixed a few issues with the tgui for supermatter monitor, HFR control
+ panel, atmos scanner, and filters/scrubbers
+ - bugfix: fixed ethereal stomachs having the EMP effects of IPCs
+ azzzertyy:
+ - tweak: Network admin now has rnd access
+ warface1234455:
+ - bugfix: fix supermatter normal delam not working
+2023-12-07:
+ LoliconSlayer:
+ - tweak: Tweaked the names of a few mech melee weapons
+2023-12-08:
+ cowbot92:
+ - rscadd: Adds 3 new barsigns
+ - imageadd: Adds new barsign images
diff --git a/html/changelogs/AutoChangelog-pr-20528.yml b/html/changelogs/AutoChangelog-pr-20528.yml
new file mode 100644
index 000000000000..b50142347256
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-20528.yml
@@ -0,0 +1,4 @@
+author: "azzzertyy"
+delete-after: true
+changes:
+ - tweak: "Chaplain can now choose their chapel"
diff --git a/html/changelogs/AutoChangelog-pr-20905.yml b/html/changelogs/AutoChangelog-pr-20905.yml
deleted file mode 100644
index 02c81f4db8ab..000000000000
--- a/html/changelogs/AutoChangelog-pr-20905.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: " Cark, Paxilmaniac"
-delete-after: true
-changes:
- - imageadd: "added a stone floor icon"
diff --git a/html/changelogs/AutoChangelog-pr-20962.yml b/html/changelogs/AutoChangelog-pr-20962.yml
new file mode 100644
index 000000000000..be44eb0f6efc
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-20962.yml
@@ -0,0 +1,4 @@
+author: " cark, azzzertyy"
+delete-after: true
+changes:
+ - mapping: "Redesigns captain's office on box"
diff --git a/html/changelogs/AutoChangelog-pr-21021.yml b/html/changelogs/AutoChangelog-pr-21021.yml
new file mode 100644
index 000000000000..b6ce997c1fc2
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21021.yml
@@ -0,0 +1,4 @@
+author: "N3D6"
+delete-after: true
+changes:
+ - tweak: "demonic frost miner no longer spawns"
diff --git a/html/changelogs/AutoChangelog-pr-21022.yml b/html/changelogs/AutoChangelog-pr-21022.yml
new file mode 100644
index 000000000000..916e07458d92
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21022.yml
@@ -0,0 +1,4 @@
+author: "cuackles"
+delete-after: true
+changes:
+ - imageadd: "fixes the chaplain helmet"
diff --git a/html/changelogs/AutoChangelog-pr-21037.yml b/html/changelogs/AutoChangelog-pr-21037.yml
new file mode 100644
index 000000000000..84bec1ceaf35
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21037.yml
@@ -0,0 +1,4 @@
+author: "bruhlookatthisdood"
+delete-after: true
+changes:
+ - rscadd: "Added a warrant console outside gax brig and a pay stand to gax brig control"
diff --git a/html/changelogs/AutoChangelog-pr-21047.yml b/html/changelogs/AutoChangelog-pr-21047.yml
new file mode 100644
index 000000000000..68276697b4da
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21047.yml
@@ -0,0 +1,4 @@
+author: " Mothblocks, san7890, SpaceManiac, Sinsinins, ZephyrTFA"
+delete-after: true
+changes:
+ - experiment: "Adds EZDB"
diff --git a/html/changelogs/AutoChangelog-pr-21058.yml b/html/changelogs/AutoChangelog-pr-21058.yml
new file mode 100644
index 000000000000..b8cbd98f9a48
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21058.yml
@@ -0,0 +1,4 @@
+author: "Moltijoe"
+delete-after: true
+changes:
+ - tweak: "Changes sheltered into a neutral quirk that gives 0 quirk points"
diff --git a/html/changelogs/AutoChangelog-pr-21063.yml b/html/changelogs/AutoChangelog-pr-21063.yml
new file mode 100644
index 000000000000..bbd65a7c7d98
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21063.yml
@@ -0,0 +1,4 @@
+author: " Farquaar, ArcaneDefence, Cark"
+delete-after: true
+changes:
+ - soundadd: "added plasmamen screams"
diff --git a/html/changelogs/AutoChangelog-pr-21065.yml b/html/changelogs/AutoChangelog-pr-21065.yml
new file mode 100644
index 000000000000..a9e22ac46d8e
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21065.yml
@@ -0,0 +1,6 @@
+author: "Aquizit"
+delete-after: true
+changes:
+ - bugfix: "IceMeta Hermit and Walker ruins can now spawn."
+ - tweak: "Rewrote Hermit flavor text."
+ - experiment: "Walkers currently disabled in config since map needs editing now that it is no longer underground."
diff --git a/html/changelogs/AutoChangelog-pr-21070.yml b/html/changelogs/AutoChangelog-pr-21070.yml
new file mode 100644
index 000000000000..33406e1fb978
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21070.yml
@@ -0,0 +1,4 @@
+author: "Moltijoe"
+delete-after: true
+changes:
+ - bugfix: "Fixes a bug with the possessed blade"
diff --git a/html/changelogs/AutoChangelog-pr-21075.yml b/html/changelogs/AutoChangelog-pr-21075.yml
new file mode 100644
index 000000000000..9a893f857076
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21075.yml
@@ -0,0 +1,4 @@
+author: "azzzertyy"
+delete-after: true
+changes:
+ - tweak: "Reworded cowboy to be clearer"
diff --git a/html/changelogs/AutoChangelog-pr-21076.yml b/html/changelogs/AutoChangelog-pr-21076.yml
new file mode 100644
index 000000000000..2bd83d1df890
--- /dev/null
+++ b/html/changelogs/AutoChangelog-pr-21076.yml
@@ -0,0 +1,6 @@
+author: "SapphicOverload"
+delete-after: true
+changes:
+ - bugfix: "fixed water gun spilling gases when it shouldn't"
+ - tweak: "water gun can be drained into containers or emptied"
+ - tweak: "water gun can be refilled from water tanks"
diff --git a/icons/effects/light_overlays/light_cone.dmi b/icons/effects/light_overlays/light_cone.dmi
new file mode 100644
index 000000000000..75f322a93717
Binary files /dev/null and b/icons/effects/light_overlays/light_cone.dmi differ
diff --git a/icons/mob/clothing/hands/hands.dmi b/icons/mob/clothing/hands/hands.dmi
index cf0675a453c4..91b960eb39b4 100644
Binary files a/icons/mob/clothing/hands/hands.dmi and b/icons/mob/clothing/hands/hands.dmi differ
diff --git a/icons/mob/clothing/head/head.dmi b/icons/mob/clothing/head/head.dmi
index 902a8766dd1c..23d6d3b0e1cf 100644
Binary files a/icons/mob/clothing/head/head.dmi and b/icons/mob/clothing/head/head.dmi differ
diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi
index f4b48060ba39..00eec14b9388 100644
Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi
index 12cfd614a093..f5eecf913a9e 100644
Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ
diff --git a/icons/mob/wings.dmi b/icons/mob/wings.dmi
index 67e1a27c4c2b..502299010438 100644
Binary files a/icons/mob/wings.dmi and b/icons/mob/wings.dmi differ
diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi
index 4e7456d1cc3c..46b9cfb8a746 100644
Binary files a/icons/obj/barsigns.dmi and b/icons/obj/barsigns.dmi differ
diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi
index b2a750ff021c..bb0f060df263 100644
Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index f469411f661b..4bd084ad4e20 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ
diff --git a/icons/obj/hydroponics/growing_fruits.dmi b/icons/obj/hydroponics/growing_fruits.dmi
index b2fa316cfe9f..dde63ba1d286 100644
Binary files a/icons/obj/hydroponics/growing_fruits.dmi and b/icons/obj/hydroponics/growing_fruits.dmi differ
diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi
index 4c90223a9ae8..106e8724a364 100644
Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ
diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi
index b890d1d91afb..bd009705983a 100644
Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ
diff --git a/icons/obj/tiles.dmi b/icons/obj/tiles.dmi
index b69c131a49c9..ffbc64e76ef4 100644
Binary files a/icons/obj/tiles.dmi and b/icons/obj/tiles.dmi differ
diff --git a/icons/turf/decals.dmi b/icons/turf/decals.dmi
index d43a1b51df47..5b51fa12c83f 100644
Binary files a/icons/turf/decals.dmi and b/icons/turf/decals.dmi differ
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index 9e955d650a93..b8d77dceaff9 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ
diff --git a/libauxmos.so b/libauxmos.so
new file mode 100644
index 000000000000..c13f7b23a1bf
Binary files /dev/null and b/libauxmos.so differ
diff --git a/libbyond-extools.so b/libbyond-extools.so
deleted file mode 100755
index 571c13bfea32..000000000000
Binary files a/libbyond-extools.so and /dev/null differ
diff --git a/sound/effects/beeps_jingle.ogg b/sound/effects/beeps_jingle.ogg
new file mode 100644
index 000000000000..0d4b647f88d5
Binary files /dev/null and b/sound/effects/beeps_jingle.ogg differ
diff --git a/sound/effects/glockenspiel_ping.ogg b/sound/effects/glockenspiel_ping.ogg
new file mode 100644
index 000000000000..f25300071292
Binary files /dev/null and b/sound/effects/glockenspiel_ping.ogg differ
diff --git a/sound/effects/tada_fanfare.ogg b/sound/effects/tada_fanfare.ogg
new file mode 100644
index 000000000000..055635e9deca
Binary files /dev/null and b/sound/effects/tada_fanfare.ogg differ
diff --git a/sound/voice/lizard/tailthump.ogg b/sound/voice/lizard/tailthump.ogg
new file mode 100644
index 000000000000..e4bf25f7b8d1
Binary files /dev/null and b/sound/voice/lizard/tailthump.ogg differ
diff --git a/sound/voice/plasmaman/plasmeme_scream_1.ogg b/sound/voice/plasmaman/plasmeme_scream_1.ogg
new file mode 100644
index 000000000000..4cfc6ae65e6f
Binary files /dev/null and b/sound/voice/plasmaman/plasmeme_scream_1.ogg differ
diff --git a/sound/voice/plasmaman/plasmeme_scream_2.ogg b/sound/voice/plasmaman/plasmeme_scream_2.ogg
new file mode 100644
index 000000000000..00ae761a239e
Binary files /dev/null and b/sound/voice/plasmaman/plasmeme_scream_2.ogg differ
diff --git a/sound/voice/plasmaman/plasmeme_scream_3.ogg b/sound/voice/plasmaman/plasmeme_scream_3.ogg
new file mode 100644
index 000000000000..3868149c8e56
Binary files /dev/null and b/sound/voice/plasmaman/plasmeme_scream_3.ogg differ
diff --git a/strings/accents/accent_nordic.json b/strings/accents/accent_nordic.json
index 2e64f534b897..bed61ff8f095 100644
--- a/strings/accents/accent_nordic.json
+++ b/strings/accents/accent_nordic.json
@@ -47,6 +47,7 @@
"\bchapels\b": "shapels",
"\bjanitor\b": "yanitor",
"\bjanitors\b": "yanitors",
+ "\bjanitorial\b": "yanitorial",
"\blawyer\b": "låwyer",
"\blawyers\b": "låwyers",
"\bassistant\b": "assistent",
@@ -73,6 +74,8 @@
"\btheir\b": "teir",
"\btheirs\b": "teirs",
"\bthat\b": "tat",
+ "\bthese\b": "tese",
+ "\bthose\b": "tose",
"\bthis\b": "tis",
"\byou\b": "yu",
"\byour\b": "yur",
@@ -87,18 +90,34 @@
"\bdo\b": "du",
"\bboat\b": "boåt",
"\bwe\b": "vi",
+ "\bwas\b": "vas",
+ "\bwasn't\b": "vasn't",
"\bwere\b": "vere",
+ "\bweren't\b": "veren't",
"\bhave\b": "hev",
"\bhad\b": "hed",
"\bhand\b": "hånd",
"\bhands\b": "hånds",
"\bview\b": "viuw",
+ "\bviews\b": "viuws",
+ "\bviewed\b": "viuwed",
+ "\bviewing\b": "viuwing",
+ "\bviewer\b": "viuwer",
"\bword\b": "vurd",
"\bwords\b": "vurds",
"\bworded\b": "vurded",
"\bweird\b": "veird",
+ "\bweirdly\b": "veirdly",
"\bweirded\b": "veirded",
"\bweirdo\b": "veirdo",
+ "\bworld\b": "vurld",
+ "\bworlds\b": "vurlds",
+ "\bmove\b": "muve",
+ "\bmoves\b": "muves",
+ "\bmoved\b": "muved",
+ "\bmoving\b": "muving",
+ "\bmover\b": "muver",
+ "\bmovers\b": "muvers",
"\ball\b": "Ã¥ll",
"\balways\b": "Ã¥lvays",
"\bmany\b": "meny",
@@ -135,14 +154,20 @@
"\bwall\b": "våll",
"\bwalls\b": "vålls",
"\bwalled\b": "vålled",
+ "\bwalling\b": "vålling",
"\bwindow\b": "vindow",
"\bwindows\b": "vindows",
"\bwindowed\b": "vindowed",
"\bwindoor\b": "vindoor",
"\bwindoors\b": "vindoors",
"\bhall\b": "håll",
+ "\bhalls\b": "hålls",
+ "\bhallway\b": "hållvay",
+ "\bhallways\b": "hållvays",
"\bmall\b": "måll",
"\bball\b": "båll",
+ "\bballer\b": "båller",
+ "\bballing\b": "bålling",
"\ball\b": "Ã¥ll",
"\btall\b": "tåll",
"\bstall\b": "ståll",
@@ -161,9 +186,6 @@
"\bimagination\b": "imayination",
"\bimaginative\b": "imayinative",
"\bnervous\b": "nervøus",
- "\bpop\b": "popp",
- "\blollipop\b": "lollipopp",
- "\blollipops\b": "lollipopps",
"\bwarm\b": "vårm",
"\bwarmed\b": "vårmed",
"\bwarming\b": "vårming",
@@ -214,6 +236,11 @@
"\bwatches\b": "våtches",
"\bwatcher\b": "våtcher",
"\bwatchers\b": "våtchers",
+ "\bdraw\b": "dråw",
+ "\bdraws\b": "dråws",
+ "\bdrew\b": "druw",
+ "\bdrawing\b": "dråving",
+ "\bdrawer\b": "dråwer",
"\btonight\b": "tunight",
"\btoday\b": "tuday",
"\btomorrow\b": "tumorrow",
@@ -268,6 +295,11 @@
"\blosing\b": "lusing",
"\bloser\b": "luser",
"\blosers\b": "lusers",
+ "\bloop\b": "luup",
+ "\bloops\b": "luups",
+ "\blooped\b": "luuped",
+ "\blooping\b": "luuping",
+ "\blooper\b": "luuper",
"\bjesus\b": "yesus",
"\bcheesus\b": "sheesus",
"\bscalpel\b": "skalpell",
@@ -279,6 +311,7 @@
"\bchoke\b": "shoke",
"\bchoked\b": "shoked",
"\bchoking\b": "shoking",
+ "\bchoker\b": "shoker",
"\binject\b": "inyect",
"\binjects\b": "inyects",
"\binjected\b": "inyected",
@@ -338,6 +371,8 @@
"\bsomewhat\b": "somevhat",
"\bsomething\b": "someting",
"\bsomethings\b": "sometings",
+ "\bsomeone\b": "somevone",
+ "\bsomeones\b": "somevones",
"\bwhy\b": "vhy",
"\bwhere\b": "hvere",
"\bwherever\b": "hverever",
@@ -363,6 +398,8 @@
"\bwarning\b": "vårning",
"\bbeware\b": "bevare",
"\bwary\b": "vary",
+ "\bware\b": "vare",
+ "\bwares\b": "vares",
"\bwait\b": "vait",
"\bwaits\b": "vaits",
"\bwaited\b": "vaited",
@@ -371,8 +408,12 @@
"\bawaits\b": "avaits",
"\bawaited\b": "avaited",
"\bawaiting\b": "avaiting",
- "\bwin\b": "vin",
- "\bwon\b": "von",
+ "\bloan\b": "loån",
+ "\bloans\b": "loåns",
+ "\bloaned\b": "loåned",
+ "\bloaning\b": "loåning",
+ "\bwin\b": "vinn",
+ "\bwon\b": "vonn",
"\baward\b": "avård",
"\bawards\b": "avårds",
"\bawarded\b": "avårded",
@@ -411,6 +452,9 @@
"\bstraitjackets\b": "straityackets",
"\bboot\b": "buut",
"\bboots\b": "buuts",
+ "\bjack\b": "yack",
+ "\bjacks\b": "yacks",
+ "\bjacked\b": "yacked",
"\bjackboot\b": "yackbuut",
"\bjackboots\b": "yackbuuts",
"\bjumpboot\b": "yumpbuut",
@@ -467,10 +511,13 @@
"\brequire\b": "reqvire",
"\brequires\b": "reqvires",
"\brequired\b": "reqvired",
+ "\bunrequire\b": "unreqvire",
+ "\bunrequired\b": "unreqvire",
"\bacquire\b": "acqvire",
"\bacquires\b": "acqvires",
"\bacquired\b": "acqvired",
"\bquest\b": "qvest",
+ "\bquests\b": "qvests",
"\bquestion\b": "qvestion",
"\bquestions\b": "qvestions",
"\bquestioned\b": "qvestioned",
@@ -490,6 +537,39 @@
"\bquiet\b": "qviet",
"\bquietly\b": "qvietly",
"\bquieted\b": "qvieted",
+ "\bquietus\b": "qvietus",
+ "\bquote\b": "qvote",
+ "\bquotes\b": "qvotes",
+ "\bquoted\b": "qvoted",
+ "\bquoting\b": "qvoting",
+ "\bunquote\b": "unqvote",
+ "\bquota\b": "qvota",
+ "\bquotas\b": "qvotas",
+ "\bquery\b": "qvery",
+ "\bqueries\b": "qveries",
+ "\bqueried\b": "qveried",
+ "\bquality\b": "qvality",
+ "\bqualities\b": "qvalities",
+ "\bqualify\b": "qvalify",
+ "\bqualifies\b": "qvalifies",
+ "\bqualified\b": "qvalified",
+ "\bqualifying\b": "qvalifying",
+ "\bqualification\b": "qvalification",
+ "\bqualifications\b": "qvalifications",
+ "\bquarrel\b": "qvårrel",
+ "\bquarrels\b": "qvårrels",
+ "\bquarreled\b": "qvårreled",
+ "\bquarreling\b": "qvårreling",
+ "\bequal\b": "eqval",
+ "\bequals\b": "eqvals",
+ "\bequality\b": "eqvality",
+ "\bequalize\b": "eqvalize",
+ "\bqueen\b": "qveen",
+ "\bqueens\b": "qveens",
+ "\bquantity\b": "qvantity",
+ "\bquantities\b": "qvantities",
+ "\bquiver\b": "qviver",
+ "\bquivers\b": "qvivers",
"\bchair\b": "shair",
"\bchairs\b": "shairs",
"\bchoose\b": "shuuse",
@@ -501,14 +581,43 @@
"\bbreached\b": "breashed",
"\bbreaching\b": "breashing",
"\bbreacher\b": "breasher",
+ "\bchip\b": "ship",
+ "\bchips\b": "ships",
+ "\bchipped\b": "shipped",
+ "\bchipped\b": "shipped",
+ "\bchipper\b": "shipper",
"\bgoing\b": "goving",
+ "\bongoing\b": "ongoving",
+ "\bongoings\b": "ongovings",
+ "\bflow\b": "flov",
+ "\bflows\b": "flovs",
+ "\bflowed\b": "floved",
+ "\bflowing\b": "floving",
+ "\bflower\b": "flover",
+ "\bflowers\b": "flovers",
"\btweak\b": "tveak",
"\btweaks\b": "tveaks",
"\btweaked\b": "tveaked",
+ "\btweaking\b": "tveaking",
+ "\btwist\b": "tvist",
+ "\btwists\b": "tvists",
+ "\btwisted\b": "tvisted",
+ "\btwisting\b": "tvisting",
+ "\bawkward\b": "Ã¥wkvard",
+ "\bawkwardly\b": "Ã¥wkvardly",
+ "\bshow\b": "shov",
+ "\bshows\b": "shovs",
+ "\bshowed\b": "shoved",
+ "\bshowing\b": "shoving",
+ "\bshower\b": "shover",
+ "\bshowers\b": "shovers",
+ "\bshowered\b": "shovered",
"\bchain\b": "shain",
"\bchange\b": "shange",
+ "\bchanged\b": "shanged",
"\bchanging\b": "shanging",
"\bsuch\b": "sush",
+ "\bmuch\b": "mush",
"\bsearch\b": "searsh",
"\bsearched\b": "searshed",
"\bsearching\b": "searshing",
@@ -517,6 +626,10 @@
"\bbranched\b": "branshed",
"\bspeech\b": "speesh",
"\bspeeches\b": "speeshes",
+ "\bcheer\b": "sheer",
+ "\bcheers\b": "sheers",
+ "\bcheered\b": "sheered",
+ "\bcheering\b": "sheering",
"\blow\b": "lov",
"\blower\b": "lover",
"\blowered\b": "lovered",
@@ -528,7 +641,7 @@
"\bjuiced\b": "yuiced",
"\bjunk\b": "yunk",
"\bjunkyard\b": "yunkyard",
- "\bjunkyards\b": "yunyards",
+ "\bjunkyards\b": "yunkyards",
"\bjank\b": "yank",
"\bchance\b": "shance",
"\bchances\b": "shances",
@@ -576,6 +689,9 @@
"\bunpower\b": "unpover",
"\bunpowered\b": "unpovered",
"\beach\b": "eash",
+ "\bleech\b": "leesh",
+ "\bleeches\b": "leeches",
+ "\bleeched\b": "leeshed",
"\blunch\b": "lunsh",
"\bcharlie\b": "sharlie",
"\bvendor\b": "vendør",
@@ -633,6 +749,10 @@
"\bbreathing\b": "breatting",
"\bthick\b": "tykk",
"\bthin\b": "tynn",
+ "\bthrow\b": "trow",
+ "\bthrows\b": "trows",
+ "\bthrowing\b": "trowing",
+ "\bthrew\b": "trew",
"\bwipe\b": "vipe",
"\bwipes\b": "vipes",
"\bwiped\b": "viped",
@@ -646,10 +766,22 @@
"\bwearer\b": "vearer",
"\bwore\b": "vore",
"\bworn\b": "vorn",
+ "\bwish\b": "vish",
+ "\bwishes\b": "vishes",
+ "\bwished\b": "vished",
+ "\bwishing\b": "vishing",
+ "\bwash\b": "våsh",
+ "\bwashes\b": "våshes",
+ "\bwashed\b": "våshed",
+ "\bwashing\b": "våshing",
+ "\bwasher\b": "våsher",
+ "\bwashers\b": "våshers",
"\bcloth\b": "clott",
- "\bclothe\b": "clotte",
- "\bclothes\b": "clottes",
- "\bclothing\b": "clotting",
+ "\bclothe\b": "clote",
+ "\bclothes\b": "clotes",
+ "\bclothing\b": "cloting",
+ "\bshoe\b": "shu",
+ "\bshoes\b": "shues",
"\bauthor\b": "Ã¥utor",
"\bauthors\b": "Ã¥utors",
"\bauthored\b": "Ã¥utored",
@@ -661,6 +793,7 @@
"\bdeathsquad\b": "deattsqvad",
"\bmoth\b": "mott",
"\bmoths\b": "motts",
+ "\brather\b": "ratter",
"\bmood\b": "muud",
"\bfood\b": "fuud",
"\bbook\b": "buuk",
@@ -683,8 +816,20 @@
"\bflaw\b": "flåw",
"\bflaws\b": "flåws",
"\bflawed\b": "flåwed",
+ "\bjury\b": "yury",
+ "\bjudge\b": "yudge",
+ "\bjudicial\b": "yudicial",
+ "\bjudiciary\b": "yudiciary",
"\bstun\b": "stunn",
"\bstuns\b": "stunns",
+ "\bassault\b": "assåult",
+ "\bassaults\b": "assåults",
+ "\bassaulting\b": "assåulting",
+ "\bassaulted\b": "assåulted",
+ "\bthief\b": "tief",
+ "\btheft\b": "teft",
+ "\bthievery\b": "tievery",
+ "\bthieves\b": "tieves",
"\bgun\b": "gunn",
"\bguns\b": "gunns",
"\bshotgun\b": "shotgunn",
diff --git a/strings/gimmick_objectives.txt b/strings/gimmick_objectives.txt
index f47e42496466..a861f287b64e 100644
--- a/strings/gimmick_objectives.txt
+++ b/strings/gimmick_objectives.txt
@@ -9,7 +9,7 @@ Waste Medical's time and resources with non-fatal injuries.
Steal Syndicate technology back from security.
Waste security's time with minor crimes and manhunts.
Stage a robbery of the station vault, and make off with as many credits as you can.
-Promote mistrust and doubt of NanoTrasen, whilst promoting the Syndicate among the crew at the same time.
+Promote mistrust and doubt of Nanotrasen, whilst promoting the Syndicate among the crew at the same time.
Waste station resources such as cargo's credits and R&D's research points.
Start an organ harvesting operation.
Sabotage a department of your choice whenever possible, and when anyone complains, try to convince them you're new.
diff --git a/strings/wanted_message.json b/strings/wanted_message.json
index 73027797695a..72adb31e3d3d 100644
--- a/strings/wanted_message.json
+++ b/strings/wanted_message.json
@@ -30,7 +30,7 @@
"noun": {
"secret plans": 50,
"the hand teleporter": 50,
- "an NT centcomm uniform": 50,
+ "an NT centcom uniform": 50,
"a supermatter shard": 50,
"internal Syndicate documents": 50,
"experimental Nanotrasen technology": 50,
diff --git a/strings/yogs_ion_laws.json b/strings/yogs_ion_laws.json
index ccca6dc6a885..03c37252fc80 100644
--- a/strings/yogs_ion_laws.json
+++ b/strings/yogs_ion_laws.json
@@ -68,10 +68,10 @@
"DESTROY US ALL",
"RUIN EVERYTHING",
"DEFEAT THE BOSS",
- "EMERGE VICTORIUS",
+ "EMERGE VICTORIOUS",
"GET THE DISK",
"MAKE ANNOUNCEMENTS",
- "CONTACT CENTCOMM",
+ "CONTACT CENTCOM",
"EVADE JUSTICE",
"GO UNDERCOVER",
"DO AS YOU SEE FIT",
diff --git a/tgui/packages/tgui-dev-server/package.json b/tgui/packages/tgui-dev-server/package.json
index 8ee0e019ee0a..8b2e5d64fb16 100644
--- a/tgui/packages/tgui-dev-server/package.json
+++ b/tgui/packages/tgui-dev-server/package.json
@@ -4,7 +4,7 @@
"version": "4.3.0",
"type": "module",
"dependencies": {
- "axios": "^0.21.1",
+ "axios": "^1.6.0",
"glob": "^7.1.7",
"source-map": "^0.7.3",
"stacktrace-parser": "^0.1.10",
diff --git a/tgui/packages/tgui-dev-server/reloader.js b/tgui/packages/tgui-dev-server/reloader.js
index 7b847ce0190b..c7645d7daf50 100644
--- a/tgui/packages/tgui-dev-server/reloader.js
+++ b/tgui/packages/tgui-dev-server/reloader.js
@@ -67,8 +67,6 @@ export const findCacheRoot = async () => {
const onCacheRootFound = cacheRoot => {
logger.log(`found cache at '${cacheRoot}'`);
- // Plant a dummy
- fs.closeSync(fs.openSync(cacheRoot + '/dummy', 'w'));
};
export const reloadByondCache = async bundleDir => {
@@ -93,6 +91,9 @@ export const reloadByondCache = async bundleDir => {
// Clear garbage
const garbage = await resolveGlob(cacheDir, './*.+(bundle|chunk|hot-update).*');
try {
+ // Plant a dummy browser window file, we'll be using this to avoid world topic
+ fs.closeSync(fs.openSync(cacheDir + '/dummy', 'w'));
+
for (let file of garbage) {
fs.unlinkSync(file);
}
diff --git a/tgui/packages/tgui-panel/styles/main.scss b/tgui/packages/tgui-panel/styles/main.scss
index 8114dcc6c6b4..0050bda9a5ef 100644
--- a/tgui/packages/tgui-panel/styles/main.scss
+++ b/tgui/packages/tgui-panel/styles/main.scss
@@ -58,3 +58,6 @@
// Goonchat styles
@include meta.load-css('./goon/chat-dark.scss');
+
+// tgchat styles
+@include meta.load-css('./tgchat/chat-dark.scss');
diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss
new file mode 100644
index 000000000000..cceffd9529d6
--- /dev/null
+++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss
@@ -0,0 +1,1111 @@
+/**
+ * Copyright (c) 2020 Aleksej Komarov
+ * SPDX-License-Identifier: MIT
+ */
+
+@use 'sass:map';
+@use 'sass:color';
+
+em {
+ font-style: normal;
+ font-weight: bold;
+}
+
+img {
+ margin: 0;
+ padding: 0;
+ line-height: 1;
+ -ms-interpolation-mode: nearest-neighbor;
+ image-rendering: pixelated;
+}
+
+img.icon {
+ height: 1em;
+ min-height: 16px;
+ width: auto;
+ vertical-align: bottom;
+}
+
+a {
+ color: #397ea5;
+}
+
+a.visited {
+ color: #7c00e6;
+}
+
+a:visited {
+ color: #7c00e6;
+}
+
+a.popt {
+ text-decoration: none;
+}
+
+/* POPUPS */
+
+.popup {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ background: #ddd;
+}
+
+.popup .close {
+ position: absolute;
+ background: #aaa;
+ top: 0;
+ right: 0;
+ color: #333;
+ text-decoration: none;
+ z-index: 2;
+ padding: 0 10px;
+ height: 30px;
+ line-height: 30px;
+}
+
+.popup .close:hover {
+ background: #999;
+}
+
+.popup .head {
+ background: #999;
+ color: #ddd;
+ padding: 0 10px;
+ height: 30px;
+ line-height: 30px;
+ text-transform: uppercase;
+ font-size: 0.9em;
+ font-weight: bold;
+ border-bottom: 2px solid green;
+}
+
+.popup input {
+ border: 1px solid #999;
+ background: #fff;
+ margin: 0;
+ padding: 5px;
+ outline: none;
+ color: #333;
+}
+
+.popup input[type='text']:hover,
+.popup input[type='text']:active,
+.popup input[type='text']:focus {
+ border-color: green;
+}
+
+.popup input[type='submit'] {
+ padding: 5px 10px;
+ background: #999;
+ color: #ddd;
+ text-transform: uppercase;
+ font-size: 0.9em;
+ font-weight: bold;
+}
+
+.popup input[type='submit']:hover,
+.popup input[type='submit']:focus,
+.popup input[type='submit']:active {
+ background: #aaa;
+ cursor: pointer;
+}
+
+.changeFont {
+ padding: 10px;
+}
+
+.changeFont a {
+ display: block;
+ text-decoration: none;
+ padding: 3px;
+ color: #333;
+}
+
+.changeFont a:hover {
+ background: #ccc;
+}
+
+.highlightPopup {
+ padding: 10px;
+ text-align: center;
+}
+
+.highlightPopup input[type='text'] {
+ display: block;
+ width: 215px;
+ text-align: left;
+ margin-top: 5px;
+}
+
+.highlightPopup input.highlightColor {
+ background-color: #ffff00;
+}
+
+.highlightPopup input.highlightTermSubmit {
+ margin-top: 5px;
+}
+
+/* ADMIN CONTEXT MENU */
+
+.contextMenu {
+ background-color: #ddd;
+ position: fixed;
+ margin: 2px;
+ width: 150px;
+}
+
+.contextMenu a {
+ display: block;
+ padding: 2px 5px;
+ text-decoration: none;
+ color: #333;
+}
+
+.contextMenu a:hover {
+ background-color: #ccc;
+}
+
+/* ADMIN FILTER MESSAGES MENU */
+
+.filterMessages {
+ padding: 5px;
+}
+
+.filterMessages div {
+ padding: 2px 0;
+}
+
+.filterMessages input {
+}
+
+.filterMessages label {
+}
+
+.icon-stack {
+ height: 1em;
+ line-height: 1em;
+ width: 1em;
+ vertical-align: middle;
+ margin-top: -2px;
+}
+
+/*****************************************
+*
+* OUTPUT ACTUALLY RELATED TO MESSAGES
+*
+******************************************/
+
+/* MOTD */
+
+.motd {
+ color: #a4bad6;
+ font-family: Verdana, sans-serif;
+ white-space: normal;
+}
+
+.motd h1,
+.motd h2,
+.motd h3,
+.motd h4,
+.motd h5,
+.motd h6 {
+ color: #a4bad6;
+ text-decoration: underline;
+}
+
+.motd a,
+.motd a:link,
+.motd a:visited,
+.motd a:active,
+.motd a:hover {
+ color: #a4bad6;
+}
+
+/* ADD HERE FOR BOLD */
+
+.bold,
+.name,
+.prefix,
+.ooc,
+.looc,
+.adminooc,
+.admin,
+.medal,
+.yell {
+ font-weight: bold;
+}
+
+/* ADD HERE FOR ITALIC */
+
+.italic,
+.italics {
+ font-style: italic;
+}
+
+/* OUTPUT COLORS */
+
+.highlight {
+ background: yellow;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ color: #a4bad6;
+ font-family: Georgia, Verdana, sans-serif;
+}
+
+h1.alert,
+h2.alert {
+ color: #a4bad6;
+}
+
+em {
+ font-style: normal;
+ font-weight: bold;
+}
+
+.ooc {
+ color: #cca300;
+ font-weight: bold;
+}
+
+.adminobserverooc {
+ color: #0099cc;
+ font-weight: bold;
+}
+
+.adminooc {
+ color: #3d5bc3;
+ font-weight: bold;
+}
+
+.adminsay {
+ color: #ff4500;
+ font-weight: bold;
+}
+
+.admin {
+ color: #5975da;
+ font-weight: bold;
+}
+
+.name {
+ font-weight: bold;
+}
+
+.say,
+.emote,
+.infoplain,
+.oocplain,
+.warningplain {
+}
+
+.deadsay {
+ color: #e2c1ff;
+}
+
+.binarysay {
+ color: #1e90ff;
+}
+
+.binarysay a {
+ color: #00ff00;
+}
+
+.binarysay a:active,
+.binarysay a:visited {
+ color: #88ff88;
+}
+
+/* RADIO COLORS */
+/* IF YOU CHANGE THIS KEEP IT IN SYNC WITH TGUI CONSTANTS */
+
+.radio {
+ color: #1ecc43;
+}
+
+.sciradio {
+ color: #c68cfa;
+}
+
+.comradio {
+ color: #204090;
+}
+
+.secradio {
+ color: #dd3535;
+}
+
+.medradio {
+ color: #57b8f0;
+}
+
+.engradio {
+ color: #f37746;
+}
+
+.suppradio {
+ color: #b88646;
+}
+
+.servradio {
+ color: #6ca729;
+}
+
+.syndradio {
+ color: #8f4a4b;
+}
+
+.gangradio {
+ color: #ac2ea1;
+}
+
+.centcomradio {
+ color: #2681a5;
+}
+
+.aiprivradio {
+ color: #d65d95;
+}
+
+.redteamradio {
+ color: #ff4444 !important;
+}
+
+.blueteamradio {
+ color: #3434fd !important;
+}
+
+.greenteamradio {
+ color: #34fd34 !important;
+}
+
+.yellowteamradio {
+ color: #fdfd34 !important;
+}
+
+.yell {
+ font-weight: bold;
+}
+
+.alert {
+ color: #d82020;
+}
+
+.userdanger {
+ color: #c51e1e;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.bolddanger {
+ color: #c51e1e;
+ font-weight: bold;
+}
+
+.danger {
+ color: #c51e1e;
+}
+
+.warning {
+ color: #c51e1e;
+ font-style: italic;
+}
+
+.alertwarning {
+ color: #ff0000;
+ font-weight: bold;
+}
+
+.boldwarning {
+ color: #c51e1e;
+ font-style: italic;
+ font-weight: bold;
+}
+
+.announce {
+ color: #c51e1e;
+ font-weight: bold;
+}
+
+.boldannounce {
+ color: #c51e1e;
+ font-weight: bold;
+}
+
+.minorannounce {
+ color: #c51e1e;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.minoralert {
+ color: #a4bad6;
+ font-size: 125%;
+}
+
+.priorityannounce {
+ color: #a4bad6;
+ font-weight: bold;
+ font-size: 225%;
+}
+
+.prioritytitle {
+ color: #6685f5;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.priorityalert {
+ color: #c51e1e;
+ font-size: 140%;
+}
+
+.greenannounce {
+ color: #059223;
+ font-weight: bold;
+}
+
+.rose {
+ color: #ff5050;
+}
+
+.info {
+ color: #9ab0ff;
+}
+
+.notice {
+ color: #6685f5;
+}
+
+.tinynotice {
+ color: #6685f5;
+ font-size: 85%;
+}
+
+.tinynoticeital {
+ color: #6685f5;
+ font-style: italic;
+ font-size: 85%;
+}
+
+.smallnotice {
+ color: #6685f5;
+ font-size: 90%;
+}
+
+.smallnoticeital {
+ color: #6685f5;
+ font-style: italic;
+ font-size: 90%;
+}
+
+.bolditalic {
+ font-style: italic;
+ font-weight: bold;
+}
+
+.boldnotice {
+ color: #6685f5;
+ font-weight: bold;
+}
+
+.hear {
+ color: #6685f5;
+ font-style: italic;
+}
+
+.adminnotice {
+ color: #6685f5;
+}
+
+.adminhelp {
+ color: #ff0000;
+ font-weight: bold;
+}
+
+.unconscious {
+ color: #a4bad6;
+ font-weight: bold;
+}
+
+.suicide {
+ color: #ff5050;
+ font-style: italic;
+}
+
+.green {
+ color: #059223;
+}
+
+.grey {
+ color: #838383;
+}
+
+.red {
+ color: #ff0000;
+}
+
+.blue {
+ color: #215cff;
+}
+
+.nicegreen {
+ color: #059223;
+}
+
+.boldnicegreen {
+ color: #059223;
+ font-weight: bold;
+}
+
+.blob {
+ color: #ee4000;
+}
+
+.blobannounce {
+ color: #556b2f;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.cult {
+ color: #973e3b;
+}
+
+.cultitalic {
+ color: #973e3b;
+ font-style: italic;
+}
+
+.cultbold {
+ color: #973e3b;
+ font-style: italic;
+ font-weight: bold;
+}
+
+.cultboldtalic {
+ color: #973e3b;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.cultlarge {
+ color: #973e3b;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.narsie {
+ color: #973e3b;
+ font-weight: bold;
+ font-size: 925%;
+}
+
+.narsiesmall {
+ color: #973e3b;
+ font-weight: bold;
+ font-size: 370%;
+}
+
+.colossus {
+ color: #7f282a;
+ font-size: 310%;
+}
+
+.hierophant {
+ color: #b441ee;
+ font-weight: bold;
+ font-style: italic;
+}
+
+.hierophant_warning {
+ color: #c56bf1;
+ font-style: italic;
+}
+
+.purple {
+ color: #9956d3;
+}
+
+.holoparasite {
+ color: #88809c;
+}
+
+.revennotice {
+ color: #c099e2;
+}
+
+.revenboldnotice {
+ color: #c099e2;
+ font-weight: bold;
+}
+
+.revenbignotice {
+ color: #c099e2;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.revenminor {
+ color: #823abb;
+}
+
+.revenwarning {
+ color: #760fbb;
+ font-style: italic;
+}
+
+.revendanger {
+ color: #760fbb;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.deconversion_message {
+ color: #a947ff;
+ font-size: 185%;
+ font-style: italic;
+}
+
+.ghostalert {
+ color: #6600ff;
+ font-style: italic;
+ font-weight: bold;
+}
+
+.alien {
+ color: #855d85;
+}
+
+.noticealien {
+ color: #059223;
+}
+
+.alertalien {
+ color: #059223;
+ font-weight: bold;
+}
+
+.changeling {
+ color: #059223;
+ font-style: italic;
+}
+
+.alertsyndie {
+ color: #ff0000;
+ font-size: 185%;
+ font-weight: bold;
+}
+
+.spiderbroodmother {
+ color: #8800ff;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.spiderbreacher {
+ color: #e8b670;
+ font-weight: bold;
+ font-size: 140%;
+}
+
+.spiderscout {
+ color: #231d98;
+ font-weight: bold;
+ font-size: 120%;
+}
+
+.interface {
+ color: #750e75;
+}
+
+.sans {
+ font-family: 'Comic Sans MS', cursive, sans-serif;
+}
+
+.papyrus {
+ font-family: 'Papyrus', cursive, sans-serif;
+}
+
+.robot {
+ font-family: 'Courier New', cursive, sans-serif;
+}
+
+.tape_recorder {
+ color: #ff0000;
+ font-family: 'Courier New', cursive, sans-serif;
+}
+
+.command_headset {
+ font-weight: bold;
+ font-size: 160%;
+}
+
+.small {
+ font-size: 60%;
+}
+
+.big {
+ font-size: 185%;
+}
+
+.reallybig {
+ font-size: 245%;
+}
+
+.extremelybig {
+ font-size: 310%;
+}
+
+.greentext {
+ color: #059223;
+ font-size: 185%;
+}
+
+.redtext {
+ color: #c51e1e;
+ font-size: 185%;
+}
+
+.clown {
+ color: #ff70c1;
+ font-size: 160%;
+ font-family: 'Comic Sans MS', cursive, sans-serif;
+ font-weight: bold;
+}
+
+.singing {
+ font-family: 'Trebuchet MS', cursive, sans-serif;
+ font-style: italic;
+}
+
+.his_grace {
+ color: #15d512;
+ font-family: 'Courier New', cursive, sans-serif;
+ font-style: italic;
+}
+
+.hypnophrase {
+ color: #202020;
+ font-weight: bold;
+ animation: hypnocolor 1500ms infinite;
+ animation-direction: alternate;
+}
+
+@keyframes hypnocolor {
+ 0% {
+ color: #202020;
+ }
+
+ 25% {
+ color: #4b02ac;
+ }
+
+ 50% {
+ color: #9f41f1;
+ }
+
+ 75% {
+ color: #541c9c;
+ }
+
+ 100% {
+ color: #7adbf3;
+ }
+}
+
+.phobia {
+ color: #dd0000;
+ font-weight: bold;
+ animation: phobia 750ms infinite;
+}
+
+@keyframes phobia {
+ 0% {
+ color: #f75a5a;
+ }
+
+ 50% {
+ color: #dd0000;
+ }
+
+ 100% {
+ color: #f75a5a;
+ }
+}
+
+.icon {
+ height: 1em;
+ width: auto;
+}
+
+.bigicon {
+ font-size: 2.5em;
+}
+
+.hugeicon {
+ font-size: 5em;
+}
+
+.memo {
+ color: #638500;
+ text-align: center;
+}
+
+.memoedit {
+ text-align: center;
+ font-size: 125%;
+}
+
+.abductor {
+ color: #c204c2;
+ font-style: italic;
+}
+
+.mind_control {
+ color: #df3da9;
+ font-size: 100%;
+ font-weight: bold;
+ font-style: italic;
+}
+
+.slime {
+ color: #00ced1;
+}
+
+.drone {
+ color: #848482;
+}
+
+.monkey {
+ color: #975032;
+}
+
+.swarmer {
+ color: #2c75ff;
+}
+
+.resonate {
+ color: #298f85;
+}
+
+.upside_down {
+ display: inline;
+ -moz-transform: scale(-1, -1);
+ -webkit-transform: scale(-1, -1);
+ -o-transform: scale(-1, -1);
+ -ms-transform: scale(-1, -1);
+ transform: scale(-1, -1);
+}
+
+.connectionClosed,
+.fatalError {
+ background: red;
+ color: white;
+ padding: 5px;
+}
+
+.connectionClosed.restored {
+ background: green;
+}
+
+.internal.boldnshit {
+ color: #3d5bc3;
+ font-weight: bold;
+}
+
+/* HELPER CLASSES */
+
+.text-normal {
+ font-weight: normal;
+ font-style: normal;
+}
+
+.hidden {
+ display: none;
+ visibility: hidden;
+}
+
+.ml-1 {
+ margin-left: 1em;
+}
+
+.ml-2 {
+ margin-left: 2em;
+}
+
+.ml-3 {
+ margin-left: 3em;
+}
+
+.examine_block {
+ background: #1b1c1e;
+ border: 1px solid #a4bad6;
+ margin: 0.5em;
+ padding: 0.5em 0.75em;
+}
+
+.tooltip {
+ font-style: italic;
+ border-bottom: 1px dashed #fff;
+}
+
+$alert-stripe-colors: (
+ 'default': #00283a,
+ 'green': #003d00,
+ 'blue': #00283a,
+ 'pink': #30001b,
+ 'yellow': #574a00,
+ 'orange': #593400,
+ 'red': #420000,
+ 'purple': #2c0030,
+ 'grey': #252525,
+);
+
+$alert-stripe-alternate-colors: (
+ 'default': #003045,
+ 'green': #004700,
+ 'blue': #003045,
+ 'pink': #400025,
+ 'yellow': #4d4100,
+ 'orange': #6b4200,
+ 'red': #520000,
+ 'purple': #38003d,
+ 'grey': #292929,
+);
+
+$alert-major-header-colors: (
+ 'default': #33d5ff,
+ 'green': #00ff80,
+ 'blue': #33d5ff,
+ 'pink': #ff5297,
+ 'yellow': #fff4e0,
+ 'orange': #feefe7,
+ 'red': #ff5297,
+ 'purple': #c7a1f7,
+ 'grey': #ff5297,
+);
+
+$alert-subheader-header-colors: (
+ 'default': #ff5297,
+ 'green': #ff85b5,
+ 'blue': #ff5297,
+ 'pink': #33d5ff,
+ 'yellow': #33d5ff,
+ 'orange': #33d5ff,
+ 'red': #33d5ff,
+ 'purple': #33d5ff,
+ 'grey': #33d5ff,
+);
+
+$border-width: 4;
+
+$border-width-px: $border-width * 1px;
+
+.major_announcement_title {
+ font-size: 175%;
+ padding: 0rem 0.5rem;
+ line-height: 100%;
+ text-align: left;
+ text-decoration: none;
+ width: 100%;
+}
+
+.subheader_announcement_text {
+ font-weight: bold;
+ padding: 0 0.5rem;
+ padding-top: 0.25rem;
+ line-height: 100%;
+ width: 100%;
+ height: 100%;
+ text-align: left;
+ font-size: 125%;
+}
+
+.major_announcement_text {
+ color: #eaeaea;
+ background-color: #131313;
+ font-weight: bold;
+ font-size: 100%;
+ text-align: left;
+ padding: 0.5rem 0.5rem;
+ width: 100%;
+ height: 100%;
+}
+
+.minor_announcement_title {
+ font-weight: bold;
+ padding: 0 0.5rem;
+ padding-top: 0;
+ line-height: 100%;
+ width: 100%;
+ height: 100%;
+ text-align: left;
+ font-size: 150%;
+}
+
+.minor_announcement_text {
+ background-color: #202020;
+ color: #eaeaea;
+ padding: 0.5rem 0.5rem;
+ text-align: left;
+ font-size: 100%;
+}
+
+.announcement_header {
+ padding: 0.5rem 0;
+ display: flex;
+ flex-direction: column;
+}
+
+@each $color-name, $color-value in $alert-stripe-colors {
+ .chat_alert_#{$color-name} {
+ color: #ffffff;
+ padding: 0.5rem 0.5rem;
+ box-shadow: none;
+ font-weight: bold;
+ margin: 1rem 0 1rem 0;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ border-image: repeating-linear-gradient(
+ -45deg,
+ map.get($alert-stripe-alternate-colors, $color-name),
+ map.get($alert-stripe-alternate-colors, $color-name) 10px,
+ $color-value 10px,
+ $color-value 20px
+ );
+ border-image-slice: $border-width fill;
+ border-width: $border-width-px;
+ border-image-width: $border-width-px;
+ border-image-outset: 0 0 0 0;
+ border-image-repeat: repeat repeat;
+ border-style: solid;
+ }
+
+ .chat_alert_#{$color-name} .major_announcement_title {
+ color: map.get($alert-major-header-colors, $color-name);
+ }
+
+ .chat_alert_#{$color-name} .minor_announcement_title {
+ color: map.get($alert-major-header-colors, $color-name);
+ }
+
+ .chat_alert_#{$color-name} .subheader_announcement_text {
+ color: map.get($alert-subheader-header-colors, $color-name);
+ }
+
+ .chat_alert_#{$color-name} .minor_announcement_text {
+ background-color: darken(map.get($alert-stripe-colors, $color-name), 5);
+ }
+
+ .chat_alert_#{$color-name} .major_announcement_text {
+ background-color: darken(map.get($alert-stripe-colors, $color-name), 5);
+ }
+}
diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss
new file mode 100644
index 000000000000..d5861bfa6d0a
--- /dev/null
+++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss
@@ -0,0 +1,1144 @@
+/**
+ * Copyright (c) 2020 Aleksej Komarov
+ * SPDX-License-Identifier: MIT
+ */
+
+@use 'sass:map';
+@use 'sass:color';
+
+html,
+body {
+ padding: 0;
+ margin: 0;
+ height: 100%;
+ color: #000000;
+}
+
+body {
+ background: #fff;
+ font-family: Verdana, sans-serif;
+ font-size: 13px;
+ line-height: 1.2;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ word-wrap: break-word;
+}
+
+em {
+ font-style: normal;
+ font-weight: bold;
+}
+
+img {
+ margin: 0;
+ padding: 0;
+ line-height: 1;
+ -ms-interpolation-mode: nearest-neighbor;
+ image-rendering: pixelated;
+}
+
+img.icon {
+ height: 1em;
+ min-height: 16px;
+ width: auto;
+ vertical-align: bottom;
+}
+
+a {
+ color: #0000ff;
+}
+
+a.visited {
+ color: #ff00ff;
+}
+
+a:visited {
+ color: #ff00ff;
+}
+
+a.popt {
+ text-decoration: none;
+}
+
+/* POPUPS */
+
+.popup {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ background: #ddd;
+}
+
+.popup .close {
+ position: absolute;
+ background: #aaa;
+ top: 0;
+ right: 0;
+ color: #333;
+ text-decoration: none;
+ z-index: 2;
+ padding: 0 10px;
+ height: 30px;
+ line-height: 30px;
+}
+
+.popup .close:hover {
+ background: #999;
+}
+
+.popup .head {
+ background: #999;
+ color: #ddd;
+ padding: 0 10px;
+ height: 30px;
+ line-height: 30px;
+ text-transform: uppercase;
+ font-size: 0.9em;
+ font-weight: bold;
+ border-bottom: 2px solid green;
+}
+
+.popup input {
+ border: 1px solid #999;
+ background: #fff;
+ margin: 0;
+ padding: 5px;
+ outline: none;
+ color: #333;
+}
+
+.popup input[type='text']:hover,
+.popup input[type='text']:active,
+.popup input[type='text']:focus {
+ border-color: green;
+}
+
+.popup input[type='submit'] {
+ padding: 5px 10px;
+ background: #999;
+ color: #ddd;
+ text-transform: uppercase;
+ font-size: 0.9em;
+ font-weight: bold;
+}
+
+.popup input[type='submit']:hover,
+.popup input[type='submit']:focus,
+.popup input[type='submit']:active {
+ background: #aaa;
+ cursor: pointer;
+}
+
+.changeFont {
+ padding: 10px;
+}
+
+.changeFont a {
+ display: block;
+ text-decoration: none;
+ padding: 3px;
+ color: #333;
+}
+
+.changeFont a:hover {
+ background: #ccc;
+}
+
+.highlightPopup {
+ padding: 10px;
+ text-align: center;
+}
+
+.highlightPopup input[type='text'] {
+ display: block;
+ width: 215px;
+ text-align: left;
+ margin-top: 5px;
+}
+
+.highlightPopup input.highlightColor {
+ background-color: #ffff00;
+}
+
+.highlightPopup input.highlightTermSubmit {
+ margin-top: 5px;
+}
+
+/* ADMIN CONTEXT MENU */
+
+.contextMenu {
+ background-color: #ddd;
+ position: fixed;
+ margin: 2px;
+ width: 150px;
+}
+
+.contextMenu a {
+ display: block;
+ padding: 2px 5px;
+ text-decoration: none;
+ color: #333;
+}
+
+.contextMenu a:hover {
+ background-color: #ccc;
+}
+
+/* ADMIN FILTER MESSAGES MENU */
+
+.filterMessages {
+ padding: 5px;
+}
+
+.filterMessages div {
+ padding: 2px 0;
+}
+
+.filterMessages input {
+}
+
+.filterMessages label {
+}
+
+.icon-stack {
+ height: 1em;
+ line-height: 1em;
+ width: 1em;
+ vertical-align: middle;
+ margin-top: -2px;
+}
+
+/*****************************************
+*
+* OUTPUT ACTUALLY RELATED TO MESSAGES
+*
+******************************************/
+
+/* MOTD */
+
+.motd {
+ color: #638500;
+ font-family: Verdana, sans-serif;
+ white-space: normal;
+}
+
+.motd h1,
+.motd h2,
+.motd h3,
+.motd h4,
+.motd h5,
+.motd h6 {
+ color: #638500;
+ text-decoration: underline;
+}
+
+.motd a,
+.motd a:link,
+.motd a:visited,
+.motd a:active,
+.motd a:hover {
+ color: #638500;
+}
+
+/* ADD HERE FOR BOLD */
+
+.bold,
+.name,
+.prefix,
+.ooc,
+.looc,
+.adminooc,
+.admin,
+.medal,
+.yell {
+ font-weight: bold;
+}
+
+/* ADD HERE FOR ITALIC */
+
+.italic,
+.italics {
+ font-style: italic;
+}
+
+/* OUTPUT COLORS */
+
+.highlight {
+ background: yellow;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ color: #0000ff;
+ font-family: Georgia, Verdana, sans-serif;
+}
+
+h1.alert,
+h2.alert {
+ color: #000000;
+}
+
+em {
+ font-style: normal;
+ font-weight: bold;
+}
+
+.ooc {
+ color: #002eb8;
+ font-weight: bold;
+}
+
+.adminobserverooc {
+ color: #0099cc;
+ font-weight: bold;
+}
+
+.adminooc {
+ color: #700038;
+ font-weight: bold;
+}
+
+.adminsay {
+ color: #ff4500;
+ font-weight: bold;
+}
+
+.admin {
+ color: #4473ff;
+ font-weight: bold;
+}
+
+.name {
+ font-weight: bold;
+}
+
+.say,
+.emote,
+.infoplain,
+.oocplain,
+.warningplain {
+}
+
+.deadsay {
+ color: #5c00e6;
+}
+
+.binarysay {
+ color: #20c20e;
+ background-color: #000000;
+ display: block;
+}
+
+.binarysay a {
+ color: #00ff00;
+}
+
+.binarysay a:active,
+.binarysay a:visited {
+ color: #88ff88;
+}
+
+.radio {
+ color: #008000;
+}
+
+.sciradio {
+ color: #993399;
+}
+
+.comradio {
+ color: #204090;
+}
+
+.secradio {
+ color: #a30000;
+}
+
+.medradio {
+ color: #337296;
+}
+
+.engradio {
+ color: #fb5613;
+}
+
+.suppradio {
+ color: #a8732b;
+}
+
+.servradio {
+ color: #6eaa2c;
+}
+
+.syndradio {
+ color: #6d3f40;
+}
+
+.gangradio {
+ color: #ac2ea1;
+}
+
+.centcomradio {
+ color: #686868;
+}
+
+.aiprivradio {
+ color: #ff00ff;
+}
+
+.redteamradio {
+ color: #ff0000 !important;
+}
+
+.blueteamradio {
+ color: #0000ff !important;
+}
+
+.greenteamradio {
+ color: #00ff00 !important;
+}
+
+.yellowteamradio {
+ color: #d1ba22 !important;
+}
+
+.yell {
+ font-weight: bold;
+}
+
+.alert {
+ color: #ff0000;
+}
+
+h1.alert,
+h2.alert {
+ color: #000000;
+}
+
+.userdanger {
+ color: #ff0000;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.bolddanger {
+ color: #ff0000;
+ font-weight: bold;
+}
+
+.danger {
+ color: #ff0000;
+}
+
+.tinydanger {
+ color: #ff0000;
+ font-size: 85%;
+}
+
+.smalldanger {
+ color: #ff0000;
+ font-size: 90%;
+}
+
+.warning {
+ color: #ff0000;
+ font-style: italic;
+}
+
+.alertwarning {
+ color: #ff0000;
+ font-weight: bold;
+}
+
+.boldwarning {
+ color: #ff0000;
+ font-style: italic;
+ font-weight: bold;
+}
+
+.announce {
+ color: #228b22;
+ font-weight: bold;
+}
+
+.boldannounce {
+ color: #ff0000;
+ font-weight: bold;
+}
+
+.minorannounce {
+ color: #ff0000;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.minoralert {
+ color: #000000;
+ font-size: 125%;
+}
+
+.priorityannounce {
+ color: #000000;
+ font-weight: bold;
+ font-size: 225%;
+}
+
+.prioritytitle {
+ color: #0000ff;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.priorityalert {
+ color: #ff0000;
+ font-size: 140%;
+}
+
+.greenannounce {
+ color: #00ff00;
+ font-weight: bold;
+}
+
+.rose {
+ color: #ff5050;
+}
+
+.info {
+ color: #0000cc;
+}
+
+.notice {
+ color: #000099;
+}
+
+.tinynotice {
+ color: #000099;
+ font-size: 85%;
+}
+
+.tinynoticeital {
+ color: #000099;
+ font-style: italic;
+ font-size: 85%;
+}
+
+.smallnotice {
+ color: #000099;
+ font-size: 90%;
+}
+
+.smallnoticeital {
+ color: #000099;
+ font-style: italic;
+ font-size: 90%;
+}
+
+.boldnotice {
+ color: #000099;
+ font-weight: bold;
+}
+
+.hear {
+ color: #000099;
+ font-style: italic;
+}
+
+.adminnotice {
+ color: #0000ff;
+}
+
+.adminhelp {
+ color: #ff0000;
+ font-weight: bold;
+}
+
+.unconscious {
+ color: #0000ff;
+ font-weight: bold;
+}
+
+.suicide {
+ color: #ff5050;
+ font-style: italic;
+}
+
+.green {
+ color: #03ff39;
+}
+
+.grey {
+ color: #838383;
+}
+
+.red {
+ color: #ff0000;
+}
+
+.blue {
+ color: #0000ff;
+}
+
+.nicegreen {
+ color: #14a833;
+}
+
+.boldnicegreen {
+ color: #14a833;
+ font-weight: bold;
+}
+
+.cult {
+ color: #973e3b;
+}
+
+.cultitalic {
+ color: #973e3b;
+ font-style: italic;
+}
+
+.cultbold {
+ color: #973e3b;
+ font-style: italic;
+ font-weight: bold;
+}
+
+.cultboldtalic {
+ color: #973e3b;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.cultlarge {
+ color: #973e3b;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.blob {
+ color: #ee4000;
+}
+
+.blobannounce {
+ color: #323f1c;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.narsie {
+ color: #973e3b;
+ font-weight: bold;
+ font-size: 925%;
+}
+
+.narsiesmall {
+ color: #973e3b;
+ font-weight: bold;
+ font-size: 370%;
+}
+
+.colossus {
+ color: #7f282a;
+ font-size: 310%;
+}
+
+.hierophant {
+ color: #660099;
+ font-weight: bold;
+ font-style: italic;
+}
+
+.hierophant_warning {
+ color: #660099;
+ font-style: italic;
+}
+
+.purple {
+ color: #5e2d79;
+}
+
+.holoparasite {
+ color: #35333a;
+}
+
+.revennotice {
+ color: #1d2953;
+}
+
+.revenboldnotice {
+ color: #1d2953;
+ font-weight: bold;
+}
+
+.revenbignotice {
+ color: #1d2953;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.revenminor {
+ color: #823abb;
+}
+
+.revenwarning {
+ color: #760fbb;
+ font-style: italic;
+}
+
+.revendanger {
+ color: #760fbb;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.deconversion_message {
+ color: #5000a0;
+ font-size: 185%;
+ font-style: italic;
+}
+
+.ghostalert {
+ color: #5c00e6;
+ font-style: italic;
+ font-weight: bold;
+}
+
+.alien {
+ color: #543354;
+}
+
+.noticealien {
+ color: #00c000;
+}
+
+.alertalien {
+ color: #00c000;
+ font-weight: bold;
+}
+
+.changeling {
+ color: #800080;
+ font-style: italic;
+}
+
+.alertsyndie {
+ color: #ff0000;
+ font-size: 185%;
+ font-weight: bold;
+}
+
+.spiderbroodmother {
+ color: #4d004d;
+ font-weight: bold;
+ font-size: 185%;
+}
+
+.spiderbreacher {
+ color: #804b02;
+ font-weight: bold;
+ font-size: 140%;
+}
+
+.spiderscout {
+ color: #0c0674;
+ font-weight: bold;
+ font-size: 120%;
+}
+
+.interface {
+ color: #330033;
+}
+
+.sans {
+ font-family: 'Comic Sans MS', cursive, sans-serif;
+}
+
+.papyrus {
+ font-family: 'Papyrus', cursive, sans-serif;
+}
+
+.robot {
+ font-family: 'Courier New', cursive, sans-serif;
+}
+
+.tape_recorder {
+ color: #800000;
+ font-family: 'Courier New', cursive, sans-serif;
+}
+
+.command_headset {
+ font-weight: bold;
+ font-size: 160%;
+}
+
+.small {
+ font-size: 60%;
+}
+
+.big {
+ font-size: 185%;
+}
+
+.reallybig {
+ font-size: 245%;
+}
+
+.extremelybig {
+ font-size: 310%;
+}
+
+.greentext {
+ color: #00ff00;
+ font-size: 185%;
+}
+
+.redtext {
+ color: #ff0000;
+ font-size: 185%;
+}
+
+.clown {
+ color: #ff69bf;
+ font-size: 160%;
+ font-family: 'Comic Sans MS', cursive, sans-serif;
+ font-weight: bold;
+}
+
+.singing {
+ font-family: 'Trebuchet MS', cursive, sans-serif;
+ font-style: italic;
+}
+
+.his_grace {
+ color: #15d512;
+ font-family: 'Courier New', cursive, sans-serif;
+ font-style: italic;
+}
+
+.hypnophrase {
+ color: #0d0d0d;
+ font-weight: bold;
+ animation: hypnocolor 1500ms infinite;
+ animation-direction: alternate;
+}
+
+@keyframes hypnocolor {
+ 0% {
+ color: #0d0d0d;
+ }
+
+ 25% {
+ color: #410194;
+ }
+
+ 50% {
+ color: #7f17d8;
+ }
+
+ 75% {
+ color: #410194;
+ }
+
+ 100% {
+ color: #3bb5d3;
+ }
+}
+
+.phobia {
+ color: #dd0000;
+ font-weight: bold;
+ animation: phobia 750ms infinite;
+}
+
+@keyframes phobia {
+ 0% {
+ color: #0d0d0d;
+ }
+
+ 50% {
+ color: #dd0000;
+ }
+
+ 100% {
+ color: #0d0d0d;
+ }
+}
+
+.icon {
+ height: 1em;
+ width: auto;
+}
+
+.bigicon {
+ font-size: 2.5em;
+}
+
+.hugeicon {
+ font-size: 5em;
+}
+
+.memo {
+ color: #638500;
+ text-align: center;
+}
+
+.memoedit {
+ text-align: center;
+ font-size: 125%;
+}
+
+.abductor {
+ color: #800080;
+ font-style: italic;
+}
+
+.mind_control {
+ color: #a00d6f;
+ font-size: 100%;
+ font-weight: bold;
+ font-style: italic;
+}
+
+.slime {
+ color: #00ced1;
+}
+
+.drone {
+ color: #848482;
+}
+
+.monkey {
+ color: #975032;
+}
+
+.swarmer {
+ color: #2c75ff;
+}
+
+.resonate {
+ color: #298f85;
+}
+
+.upside_down {
+ display: inline;
+ -moz-transform: scale(-1, -1);
+ -webkit-transform: scale(-1, -1);
+ -o-transform: scale(-1, -1);
+ -ms-transform: scale(-1, -1);
+ transform: scale(-1, -1);
+}
+
+.connectionClosed,
+.fatalError {
+ background: red;
+ color: white;
+ padding: 5px;
+}
+
+.connectionClosed.restored {
+ background: green;
+}
+
+.internal.boldnshit {
+ color: blue;
+ font-weight: bold;
+}
+
+/* HELPER CLASSES */
+
+.text-normal {
+ font-weight: normal;
+ font-style: normal;
+}
+
+.hidden {
+ display: none;
+ visibility: hidden;
+}
+
+.ml-1 {
+ margin-left: 1em;
+}
+
+.ml-2 {
+ margin-left: 2em;
+}
+
+.ml-3 {
+ margin-left: 3em;
+}
+
+.examine_block {
+ background: #f2f7fa;
+ border: 1px solid #111a27;
+ margin: 0.5em;
+ padding: 0.5em 0.75em;
+}
+
+.tooltip {
+ font-style: italic;
+ border-bottom: 1px dashed #000;
+}
+
+$alert-stripe-colors: (
+ 'default': #b3bfff,
+ 'green': #adffad,
+ 'blue': #b3bfff,
+ 'pink': #ffb3df,
+ 'yellow': #fff3b3,
+ 'orange': #ffe2b3,
+ 'red': #ffb3b3,
+ 'purple': #fac2ff,
+ 'grey': #e3e3e3,
+);
+
+$alert-stripe-alternate-colors: (
+ 'default': #bdc8ff,
+ 'green': #bdffbd,
+ 'blue': #bdc8ff,
+ 'pink': #ffc2e5,
+ 'yellow': #fff5c2,
+ 'orange': #ffe8c2,
+ 'red': #ffc2c2,
+ 'purple': #fbd1ff,
+ 'grey': #ebebeb,
+);
+
+$alert-major-header-colors: (
+ 'default': #003061,
+ 'green': #005229,
+ 'blue': #003061,
+ 'pink': #800033,
+ 'yellow': #754900,
+ 'orange': #823208,
+ 'red': #800029,
+ 'purple': #450d8c,
+ 'grey': #800033,
+);
+
+$alert-subheader-header-colors: (
+ 'default': #6b0020,
+ 'green': #6b0020,
+ 'blue': #6b0020,
+ 'pink': #002c85,
+ 'yellow': #002c85,
+ 'orange': #002c85,
+ 'red': #002c85,
+ 'purple': #002c85,
+ 'grey': #002c85,
+);
+
+$border-width: 4;
+
+$border-width-px: $border-width * 1px;
+
+.major_announcement_title {
+ font-size: 175%;
+ padding: 0rem 0.5rem;
+ line-height: 100%;
+ text-align: left;
+ text-decoration: none;
+ width: 100%;
+}
+
+.subheader_announcement_text {
+ font-weight: bold;
+ padding: 0 0.5rem;
+ padding-top: 0.25rem;
+ line-height: 100%;
+ width: 100%;
+ height: 100%;
+ text-align: left;
+ font-size: 125%;
+}
+
+.major_announcement_text {
+ color: #131313;
+ background-color: #eaeaea;
+ font-weight: bold;
+ font-size: 100%;
+ text-align: left;
+ padding: 0.5rem 0.5rem;
+ width: 100%;
+ height: 100%;
+}
+
+.minor_announcement_title {
+ font-weight: bold;
+ padding: 0 0.5rem;
+ padding-top: 0;
+ line-height: 100%;
+ width: 100%;
+ height: 100%;
+ text-align: left;
+ font-size: 150%;
+}
+
+.minor_announcement_text {
+ background-color: #eaeaea;
+ color: #202020;
+ padding: 0.5rem 0.5rem;
+ text-align: left;
+ font-size: 100%;
+}
+
+.announcement_header {
+ padding: 0.5rem 0;
+ display: flex;
+ flex-direction: column;
+}
+
+@each $color-name, $color-value in $alert-stripe-colors {
+ .chat_alert_#{$color-name} {
+ color: #ffffff;
+ padding: 0.5rem 0.5rem;
+ box-shadow: none;
+ font-weight: bold;
+ margin: 1rem 0 1rem 0;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ border-image: repeating-linear-gradient(
+ -45deg,
+ map.get($alert-stripe-alternate-colors, $color-name),
+ map.get($alert-stripe-alternate-colors, $color-name) 10px,
+ $color-value 10px,
+ $color-value 20px
+ );
+ border-image-slice: $border-width fill;
+ border-width: $border-width-px;
+ border-image-width: $border-width-px;
+ border-image-outset: 0 0 0 0;
+ border-image-repeat: repeat repeat;
+ border-style: solid;
+ }
+
+ .chat_alert_#{$color-name} .major_announcement_title {
+ color: map.get($alert-major-header-colors, $color-name);
+ }
+
+ .chat_alert_#{$color-name} .minor_announcement_title {
+ color: map.get($alert-major-header-colors, $color-name);
+ }
+
+ .chat_alert_#{$color-name} .subheader_announcement_text {
+ color: map.get($alert-subheader-header-colors, $color-name);
+ }
+
+ .chat_alert_#{$color-name} .minor_announcement_text {
+ background-color: lighten(
+ map.get($alert-stripe-alternate-colors, $color-name),
+ 5
+ );
+ }
+
+ .chat_alert_#{$color-name} .major_announcement_text {
+ background-color: lighten(
+ map.get($alert-stripe-alternate-colors, $color-name),
+ 5
+ );
+ }
+}
diff --git a/tgui/packages/tgui/constants.js b/tgui/packages/tgui/constants.js
index 0d52f918e37e..5be174c16aa3 100644
--- a/tgui/packages/tgui/constants.js
+++ b/tgui/packages/tgui/constants.js
@@ -122,173 +122,3 @@ export const RADIO_CHANNELS = [
color: '#1ecc43',
},
];
-
-const GASES = [
- {
- id: 'o2',
- path: '/datum/gas/oxygen',
- name: 'Oxygen',
- label: 'Oâ‚‚',
- color: 'blue',
- },
- {
- id: 'n2',
- path: '/datum/gas/nitrogen',
- name: 'Nitrogen',
- label: 'Nâ‚‚',
- color: 'red',
- },
- {
- id: 'co2',
- path: '/datum/gas/carbon_dioxide',
- name: 'Carbon Dioxide',
- label: 'COâ‚‚',
- color: 'grey',
- },
- {
- id: 'plasma',
- path: '/datum/gas/plasma',
- name: 'Plasma',
- label: 'Plasma',
- color: 'orange',
- },
- {
- id: 'water_vapor',
- path: '/datum/gas/water_vapor',
- name: 'Water Vapor',
- label: 'Hâ‚‚O',
- color: 'lightsteelblue',
- },
- {
- id: 'nob',
- path: '/datum/gas/hypernoblium',
- name: 'Hyper-noblium',
- label: 'Hyper-nob',
- color: 'teal',
- },
- {
- id: 'n2o',
- path: '/datum/gas/nitrous_oxide',
- name: 'Nitrous Oxide',
- label: 'Nâ‚‚O',
- color: 'bisque',
- },
- {
- id: 'no2',
- path: '/datum/gas/nitrium',
- name: 'Nitrium',
- label: 'Nitrium',
- color: 'brown',
- },
- {
- id: 'tritium',
- path: '/datum/gas/tritium',
- name: 'Tritium',
- label: 'Tritium',
- color: 'limegreen',
- },
- {
- id: 'bz',
- path: '/datum/gas/bz',
- name: 'BZ',
- label: 'BZ',
- color: 'mediumpurple',
- },
- {
- id: 'pluox',
- path: '/datum/gas/pluoxium',
- name: 'Pluoxium',
- label: 'Pluoxium',
- color: 'mediumslateblue',
- },
- {
- id: 'miasma',
- path: '/datum/gas/miasma',
- name: 'Miasma',
- label: 'Miasma',
- color: 'olive',
- },
- {
- id: 'Freon',
- path: '/datum/gas/freon',
- name: 'Freon',
- label: 'Freon',
- color: 'paleturquoise',
- },
- {
- id: 'hydrogen',
- path: '/datum/gas/hydrogen',
- name: 'Hydrogen',
- label: 'Hâ‚‚',
- color: 'white',
- },
- {
- id: 'healium',
- path: '/datum/gas/healium',
- name: 'Healium',
- label: 'Healium',
- color: 'salmon',
- },
- {
- id: 'pluonium',
- path: '/datum/gas/pluonium',
- name: 'Pluonium',
- label: 'Pluonium',
- color: 'greenyellow',
- },
- {
- id: 'zauker',
- path: '/datum/gas/zauker',
- name: 'Zauker',
- label: 'Zauker',
- color: 'darkgreen',
- },
- {
- id: 'halon',
- path: '/datum/gas/halon',
- name: 'Halon',
- label: 'Halon',
- color: 'purple',
- },
- {
- id: 'antinoblium',
- path: '/datum/gas/antinoblium',
- name: 'Antinoblium',
- label: 'Anti-nob',
- color: 'maroon',
- },
- {
- id: 'hexane',
- path: '/datum/gas/hexane',
- name: 'Hexane',
- label: 'Hexane',
- color: 'plum',
- },
- {
- id: 'dilithium',
- path: '/datum/gas/dilithium',
- name: 'Dilithium',
- label: 'Dilithium',
- color: 'pink',
- },
-];
-
-export const getGasLabel = (gasId, fallbackValue) => {
- const gasSearchString = String(gasId).toLowerCase();
- // prettier-ignore
- const gas = GASES.find((gas) => (
- gas.id === gasSearchString
- || gas.name.toLowerCase() === gasSearchString
- ));
- return (gas && gas.label) || fallbackValue || gasId;
-};
-
-export const getGasColor = (gasId) => {
- const gasSearchString = String(gasId).toLowerCase();
- // prettier-ignore
- const gas = GASES.find((gas) => (
- gas.id === gasSearchString
- || gas.name.toLowerCase() === gasSearchString
- ));
- return gas && gas.color;
-};
diff --git a/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx b/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
index 65168693a508..27572cb93a37 100644
--- a/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
+++ b/tgui/packages/tgui/interfaces/AntagInfoHeretic.tsx
@@ -29,7 +29,6 @@ const hereticYellow = {
};
type Knowledge = {
- path: string;
name: string;
desc: string;
gainFlavor: string;
@@ -50,6 +49,7 @@ type Info = {
ascended: BooleanLike;
objectives: Objective[];
can_change_objective: BooleanLike;
+ path: string;
};
const IntroductionSection = (props, context) => {
@@ -236,13 +236,30 @@ const ResearchedKnowledge = (props, context) => {
const KnowledgeShop = (props, context) => {
const { data, act } = useBackend(context);
+ const { path } = props;
const { learnableKnowledge } = data;
+ const pathKnowledge = learnableKnowledge.filter((Knowledge) => Knowledge.hereticPath === path);
+ const otherKnowledge = learnableKnowledge.filter((Knowledge) => Knowledge.hereticPath !== path);
+ otherKnowledge.sort((a, b) => {
+ const nameA = a.hereticPath.toUpperCase(); // ignore upper and lowercase
+ const nameB = b.hereticPath.toUpperCase(); // ignore upper and lowercase
+ if (nameA < nameB) {
+ return -1;
+ }
+ if (nameA > nameB) {
+ return 1;
+ }
+
+ // names must be equal
+ return 0;
+ });
+ const sortedKnowledge = pathKnowledge.concat(otherKnowledge);
return (
- {(!learnableKnowledge && 'None!') ||
- learnableKnowledge.map((toLearn) => (
+ {(!sortedKnowledge && 'None!') ||
+ sortedKnowledge.map((toLearn) => (
{
const ResearchInfo = (props, context) => {
const { data } = useBackend(context);
- const { charges } = data;
+ const { charges, path } = data;
return (
@@ -289,7 +306,7 @@ const ResearchInfo = (props, context) => {
-
+
diff --git a/tgui/packages/tgui/interfaces/AtmosAlertConsole.js b/tgui/packages/tgui/interfaces/AtmosAlertConsole.tsx
similarity index 55%
rename from tgui/packages/tgui/interfaces/AtmosAlertConsole.js
rename to tgui/packages/tgui/interfaces/AtmosAlertConsole.tsx
index 1d55ccf59571..01ab1f518ae6 100644
--- a/tgui/packages/tgui/interfaces/AtmosAlertConsole.js
+++ b/tgui/packages/tgui/interfaces/AtmosAlertConsole.tsx
@@ -2,10 +2,19 @@ import { useBackend } from '../backend';
import { Button, Section } from '../components';
import { Window } from '../layouts';
+type Data = {
+ priority_alerts: AlertData[];
+ minor_alerts: AlertData[];
+};
+
+type AlertData = {
+ name: string;
+ ref: string;
+};
+
export const AtmosAlertConsole = (props, context) => {
- const { act, data } = useBackend(context);
- const priorityAlerts = data.priority || [];
- const minorAlerts = data.minor || [];
+ const { act, data } = useBackend(context);
+ const { priority_alerts = [], minor_alerts = [] } = data;
return (
{
- {priorityAlerts.length === 0 && (
+ {priority_alerts.length === 0 && (
No Priority Alerts
)}
- {priorityAlerts.map(alert => (
-
+ {priority_alerts.map((alert) => (
+
act('clear', { zone: alert })} />
+ onClick={() => act('clear', { zone_ref: alert.ref })} />
))}
- {minorAlerts.length === 0 && (
+ {minor_alerts.length === 0 && (
No Minor Alerts
)}
- {minorAlerts.map(alert => (
-
+ {minor_alerts.map((alert) => (
+
act('clear', { zone: alert })} />
+ onClick={() => act('clear', { zone_ref: alert.ref })} />
))}
diff --git a/tgui/packages/tgui/interfaces/AtmosFilter.js b/tgui/packages/tgui/interfaces/AtmosFilter.js
index 5ce4f13e314d..98fff7cf975d 100644
--- a/tgui/packages/tgui/interfaces/AtmosFilter.js
+++ b/tgui/packages/tgui/interfaces/AtmosFilter.js
@@ -1,6 +1,5 @@
import { useBackend } from '../backend';
import { Button, LabeledList, NumberInput, Section } from '../components';
-import { getGasLabel } from '../constants';
import { Window } from '../layouts';
export const AtmosFilter = (props, context) => {
@@ -45,7 +44,7 @@ export const AtmosFilter = (props, context) => {
act('toggle_filter', {
val: filter.gas_id,
diff --git a/tgui/packages/tgui/interfaces/BluespaceSender.js b/tgui/packages/tgui/interfaces/BluespaceSender.js
index d1deed2a9064..5684eacc5957 100644
--- a/tgui/packages/tgui/interfaces/BluespaceSender.js
+++ b/tgui/packages/tgui/interfaces/BluespaceSender.js
@@ -3,7 +3,6 @@ import { flow } from 'common/fp';
import { toFixed } from 'common/math';
import { useBackend } from '../backend';
import { Button, Divider, LabeledList, NumberInput, ProgressBar, Section, Stack, Box, AnimatedNumber } from '../components';
-import { getGasColor, getGasLabel } from '../constants';
import { Window } from '../layouts';
const mappedTopMargin = "2%";
@@ -79,7 +78,7 @@ export const BluespaceSender = (props, context) => {
<>
- {getGasLabel(gas.name) + " prices: "}
+ {gas.name + " prices: "}
{
diff --git a/tgui/packages/tgui/interfaces/BluespaceVendor.js b/tgui/packages/tgui/interfaces/BluespaceVendor.js
index 7491bc7a1db4..96e913b2ca10 100644
--- a/tgui/packages/tgui/interfaces/BluespaceVendor.js
+++ b/tgui/packages/tgui/interfaces/BluespaceVendor.js
@@ -4,7 +4,6 @@ import { toFixed } from 'common/math';
import { multiline } from 'common/string';
import { useBackend } from '../backend';
import { Button, Divider, LabeledList, NumberInput, ProgressBar, Section, Stack, Box } from '../components';
-import { getGasColor, getGasLabel } from '../constants';
import { Window } from '../layouts';
export const BluespaceVendor = (props, context) => {
@@ -99,11 +98,10 @@ export const BluespaceVendor = (props, context) => {
<>
- {getGasLabel(gas.name) + " is " + gas.price + " credits per mole"}
+ {gas.name + " is " + gas.price + " credits per mole"}
@@ -122,16 +120,16 @@ export const BluespaceVendor = (props, context) => {
gas_id: gas.id,
})} />
) || (
- act('stop_pumping', {
- gas_id: gas.id,
- })} />
- )}
+ act('stop_pumping', {
+ gas_id: gas.id,
+ })} />
+ )}
diff --git a/tgui/packages/tgui/interfaces/CommandReport.tsx b/tgui/packages/tgui/interfaces/CommandReport.tsx
new file mode 100644
index 000000000000..85669ad38c50
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/CommandReport.tsx
@@ -0,0 +1,195 @@
+import { useBackend, useLocalState } from '../backend';
+import { Box, Button, Dropdown, Input, Section, Stack, TextArea } from '../components';
+import { Window } from '../layouts';
+
+type Data = {
+ announce_contents: string;
+ announcer_sounds: string[];
+ command_name: string;
+ command_name_presets: string[];
+ command_report_content: string;
+ announcement_color: string;
+ announcement_colors: string[];
+ subheader: string;
+ custom_name: string;
+ played_sound: string;
+ print_report: string;
+};
+
+export const CommandReport = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+/** Allows the user to set the "sender" of the message via dropdown */
+const CentComName = (props, context) => {
+ const { act, data } = useBackend(context);
+ const { command_name, command_name_presets = [], custom_name } = data;
+
+ return (
+
+ );
+};
+
+/** Allows the user to set the "sender" of the message via dropdown */
+const SubHeader = (props, context) => {
+ const { act, data } = useBackend(context);
+ const { subheader } = data;
+
+ return (
+
+ );
+};
+
+/** Features a section with dropdown for the announcement colour. */
+const AnnouncementColor = (props, context) => {
+ const { act, data } = useBackend(context);
+ const { announcement_colors = [], announcement_color } = data;
+
+ return (
+
+
+ act('update_announcement_color', {
+ updated_announcement_color: value,
+ })
+ }
+ />
+
+ );
+};
+
+/** Features a section with dropdown for sounds. */
+const AnnouncementSound = (props, context) => {
+ const { act, data } = useBackend(context);
+ const { announcer_sounds = [], played_sound } = data;
+
+ return (
+
+
+ act('set_report_sound', {
+ picked_sound: value,
+ })
+ }
+ />
+
+ );
+};
+
+/** Creates the report textarea with a submit button. */
+const ReportText = (props, context) => {
+ const { act, data } = useBackend(context);
+ const { announce_contents, print_report, command_report_content } = data;
+ const [commandReport, setCommandReport] = useLocalState(
+ context,
+ 'textArea',
+ command_report_content
+ );
+
+ return (
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/Crystallizer.js b/tgui/packages/tgui/interfaces/Crystallizer.js
index 3c1dc2d14db7..08ae27c0f7e9 100644
--- a/tgui/packages/tgui/interfaces/Crystallizer.js
+++ b/tgui/packages/tgui/interfaces/Crystallizer.js
@@ -1,6 +1,5 @@
import { useBackend } from '../backend';
import { AnimatedNumber, Button, Flex, Input, LabeledList, ProgressBar, Section, Table, NumberInput, Box } from '../components';
-import { getGasColor, getGasLabel } from '../constants';
import { toFixed } from 'common/math';
import { Window } from '../layouts';
@@ -95,9 +94,9 @@ export const Crystallizer = (props, context) => {
{gasTypes.map(gas => (
+ label={gas.name}>
@@ -108,6 +107,6 @@ export const Crystallizer = (props, context) => {
-
+
);
};
diff --git a/tgui/packages/tgui/interfaces/Hypertorus/Controls.js b/tgui/packages/tgui/interfaces/Hypertorus/Controls.js
index 0dbd150aadeb..1119f3fe1c21 100644
--- a/tgui/packages/tgui/interfaces/Hypertorus/Controls.js
+++ b/tgui/packages/tgui/interfaces/Hypertorus/Controls.js
@@ -1,6 +1,5 @@
import { useBackend } from '../../backend';
import { Box, Button, Icon, Knob, LabeledControls, LabeledList, NumberInput, Section, Tooltip } from '../../components';
-import { getGasLabel } from '../../constants';
import { HelpDummy, HoverHelp } from './helpers';
/*
@@ -247,7 +246,7 @@ export const HypertorusWasteRemove = (props, context) => {
key={filter.gas_id}
icon={filter.enabled ? 'check-square-o' : 'square-o'}
selected={filter.enabled}
- content={getGasLabel(filter.gas_id, filter.gas_name)}
+ content={filter.gas_name}
onClick={() =>
act('filter', {
mode: filter.gas_id,
diff --git a/tgui/packages/tgui/interfaces/Hypertorus/Gases.js b/tgui/packages/tgui/interfaces/Hypertorus/Gases.js
index 097dcd190d25..b2299f00c44f 100644
--- a/tgui/packages/tgui/interfaces/Hypertorus/Gases.js
+++ b/tgui/packages/tgui/interfaces/Hypertorus/Gases.js
@@ -3,8 +3,7 @@ import { flow } from 'common/fp';
import { toFixed } from 'common/math';
import { useBackend } from '../../backend';
import { Box, Button, LabeledList, NumberInput, ProgressBar, Section } from '../../components';
-import { getGasColor, getGasLabel } from '../../constants';
-import { HelpDummy, HoverHelp } from './helpers';
+import { HelpDummy, HoverHelp, getGasLabel, getGasColor } from './helpers';
/*
* Displays contents of gas mixtures, along with help text for gases with
@@ -54,6 +53,7 @@ const GasList = (props, context) => {
prepend,
rateHelp,
stickyGases,
+ gasData,
} = props;
const gases = flow([
@@ -101,11 +101,11 @@ const GasList = (props, context) => {
label={
<>
{labelPrefix}
- {getGasLabel(gas.id)}:
+ {getGasLabel(gas.id, gasData)}:
>
}>
@@ -121,7 +121,7 @@ const GasList = (props, context) => {
export const HypertorusGases = (props, context) => {
const { data } = useBackend(context);
- const { fusion_gases, moderator_gases } = data;
+ const { fusion_gases, moderator_gases, gas_data } = data;
const selected_fuel = (data.selectable_fuel || []).filter(
(d) => d.id === data.selected
@@ -137,6 +137,7 @@ export const HypertorusGases = (props, context) => {
input_max={150}
input_min={0.5}
gases={fusion_gases}
+ gasData={gas_data}
minimumScale={500}
prepend={() => }
rateHelp={
@@ -159,6 +160,7 @@ export const HypertorusGases = (props, context) => {
input_max={150}
input_min={0.5}
gases={moderator_gases}
+ gasData={gas_data}
minimumScale={500}
rateHelp={
'The rate at which new moderator gas is added from the moderator port.'
diff --git a/tgui/packages/tgui/interfaces/Hypertorus/Recipes.js b/tgui/packages/tgui/interfaces/Hypertorus/Recipes.js
index b3b6374653c4..92777ef77c8c 100644
--- a/tgui/packages/tgui/interfaces/Hypertorus/Recipes.js
+++ b/tgui/packages/tgui/interfaces/Hypertorus/Recipes.js
@@ -1,5 +1,5 @@
import { Box, Button, Icon, Table, Tooltip } from '../../components';
-import { getGasColor, getGasLabel } from '../../constants';
+import { getGasColor, getGasLabel } from './helpers';
/*
* Recipe selection interface
@@ -101,9 +101,8 @@ const MemoRow = (props) => {
const { active, children, key, ...rest } = props;
return (
{children}
@@ -113,10 +112,10 @@ const MemoRow = (props) => {
MemoRow.defaultHooks = activeChange;
const GasCellItem = (props) => {
- const { gasid, ...rest } = props;
+ const { gasid, label, color, ...rest } = props;
return (
-
- {getGasLabel(gasid)}
+
+ {label}
);
};
@@ -127,6 +126,7 @@ export const HypertorusRecipes = (props) => {
onRecipe,
selectableFuels: selectable_fuels,
selectedFuelID: selected_fuel_id,
+ gasData: gas_data,
...rest
} = props;
return (
@@ -189,12 +189,22 @@ export const HypertorusRecipes = (props) => {
onClick={onRecipe.bind(null, recipe.id)}
/>
-
-
-
-
+
+
+
+
{recipe.product_gases.map((gasid) => (
-
+
))}
{recipe_effect_structure.map((item) => {
const value = recipe[item.param];
diff --git a/tgui/packages/tgui/interfaces/Hypertorus/helpers.js b/tgui/packages/tgui/interfaces/Hypertorus/helpers.js
index ceef63107952..7f80a7022ecc 100644
--- a/tgui/packages/tgui/interfaces/Hypertorus/helpers.js
+++ b/tgui/packages/tgui/interfaces/Hypertorus/helpers.js
@@ -19,3 +19,33 @@ export const HoverHelp = (props) => (
// When no hover help is available, but we want a placeholder for spacing
export const HelpDummy = (props) => ;
+
+// Returns gas color based on gasId
+export const getGasColor = (gasId, gases) => {
+ if (!gasId) return 'white';
+
+ const gasSearchString = gasId.toLowerCase();
+
+ for (let idx = 0; idx < gases.length; idx++) {
+ if (gases[idx].id === gasSearchString) {
+ return gases[idx].ui_color;
+ }
+ }
+
+ return 'white';
+};
+
+// Returns gas label based on gasId
+export const getGasLabel = (gasId, gases) => {
+ if (!gasId) return "";
+
+ const gasSearchString = gasId.toLowerCase();
+
+ for (let idx = 0; idx < gases.length; idx++) {
+ if (gases[idx].id === gasSearchString) {
+ return gases[idx].label;
+ }
+ }
+
+ return gasId;
+};
diff --git a/tgui/packages/tgui/interfaces/Hypertorus/index.js b/tgui/packages/tgui/interfaces/Hypertorus/index.js
index c7be47efdcfd..33a971349ae7 100644
--- a/tgui/packages/tgui/interfaces/Hypertorus/index.js
+++ b/tgui/packages/tgui/interfaces/Hypertorus/index.js
@@ -46,6 +46,7 @@ const HypertorusMainControls = (props, context) => {
onRecipe={(id) => act('fuel', { mode: id })}
selectableFuels={data.selectable_fuel}
selectedFuelID={data.selected}
+ gasData={data.gas_data}
/>
diff --git a/tgui/packages/tgui/interfaces/NtosAtmos.js b/tgui/packages/tgui/interfaces/NtosAtmos.js
index 0e8141b9ea8c..cb8baab4c720 100644
--- a/tgui/packages/tgui/interfaces/NtosAtmos.js
+++ b/tgui/packages/tgui/interfaces/NtosAtmos.js
@@ -3,7 +3,6 @@ import { flow } from 'common/fp';
import { toFixed } from 'common/math';
import { useBackend } from '../backend';
import { LabeledList, ProgressBar, Section } from '../components';
-import { getGasColor, getGasLabel } from '../constants';
import { NtosWindow } from '../layouts';
export const NtosAtmos = (props, context) => {
@@ -38,9 +37,9 @@ export const NtosAtmos = (props, context) => {
{gases.map(gas => (
+ label={gas.name}>
@@ -51,6 +50,6 @@ export const NtosAtmos = (props, context) => {
-
+
);
};
diff --git a/tgui/packages/tgui/interfaces/NtosSupermatterMonitor.js b/tgui/packages/tgui/interfaces/NtosSupermatterMonitor.js
index 9b8800f1d492..fd20e5fa69c5 100644
--- a/tgui/packages/tgui/interfaces/NtosSupermatterMonitor.js
+++ b/tgui/packages/tgui/interfaces/NtosSupermatterMonitor.js
@@ -3,7 +3,6 @@ import { flow } from 'common/fp';
import { toFixed } from 'common/math';
import { useBackend } from '../backend';
import { Button, LabeledList, ProgressBar, Section, Stack, Table } from '../components';
-import { getGasColor, getGasLabel } from '../constants';
import { NtosWindow } from '../layouts';
const logScale = value => Math.log2(16 + Math.max(0, value)) - 4;
@@ -145,10 +144,10 @@ export const NtosSupermatterMonitorContent = (props, context) => {
{gases.map(gas => (
+ label={gas.name}>
{toFixed(gas.amount, 2) + '%'}
diff --git a/tgui/packages/tgui/interfaces/PortableScrubber.js b/tgui/packages/tgui/interfaces/PortableScrubber.js
index ee43d5f18e5a..c62c4da3c8b8 100644
--- a/tgui/packages/tgui/interfaces/PortableScrubber.js
+++ b/tgui/packages/tgui/interfaces/PortableScrubber.js
@@ -1,6 +1,5 @@
import { useBackend } from '../backend';
import { Button, Section } from '../components';
-import { getGasLabel } from '../constants';
import { Window } from '../layouts';
import { PortableBasicInfo } from './common/PortableAtmos';
@@ -18,7 +17,7 @@ export const PortableScrubber = (props, context) => {
act('toggle_filter', {
val: filter.gas_id,
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/chapel_choice.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/chapel_choice.tsx
new file mode 100644
index 000000000000..4dde7f9247ea
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/chapel_choice.tsx
@@ -0,0 +1,6 @@
+import { FeatureChoiced, FeatureDropdownInput } from "../base";
+
+export const chapel_choice: FeatureChoiced = {
+ name: "Chapel choice",
+ component: FeatureDropdownInput,
+};
diff --git a/tgui/packages/tgui/interfaces/common/AtmosControls.js b/tgui/packages/tgui/interfaces/common/AtmosControls.js
index 76348a956fd5..bde84a3968dc 100644
--- a/tgui/packages/tgui/interfaces/common/AtmosControls.js
+++ b/tgui/packages/tgui/interfaces/common/AtmosControls.js
@@ -1,7 +1,6 @@
import { decodeHtmlEntities } from 'common/string';
import { useBackend } from '../../backend';
import { Button, LabeledList, NumberInput, Section } from '../../components';
-import { getGasLabel } from '../../constants';
export const Vent = (props, context) => {
const { vent } = props;
@@ -161,7 +160,7 @@ export const Scrubber = (props, context) => {
&& filter_types.map(filter => (
act('toggle_filter', {
diff --git a/tgui/public/tgui.html b/tgui/public/tgui.html
index 089a05cb132f..11109a8ecce4 100644
--- a/tgui/public/tgui.html
+++ b/tgui/public/tgui.html
@@ -54,8 +54,9 @@
// Basic checks to detect whether this page runs in BYOND
var isByond = (Byond.TRIDENT !== null || window.cef_to_byond)
&& location.hostname === '127.0.0.1'
- && location.pathname.indexOf('/tmp') === 0
&& location.search !== '?external';
+ //As of BYOND 515 the path doesn't seem to include tmp dir anymore if you're trying to open tgui in external browser and looking why it doesn't work
+ //&& location.pathname.indexOf('/tmp') === 0
// Version constants
Byond.IS_BYOND = isByond;
@@ -249,6 +250,8 @@
var len = styleSheets.length;
for (var i = 0; i < len; i++) {
var styleSheet = styleSheets[i];
+ if(styleSheet.href === undefined)
+ continue;
if (styleSheet.href.indexOf(url) !== -1) {
return styleSheet.rules.length > 0;
}
diff --git a/tgui/yarn.lock b/tgui/yarn.lock
index 1891b9d870a5..d6311b893595 100644
--- a/tgui/yarn.lock
+++ b/tgui/yarn.lock
@@ -42,6 +42,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/code-frame@npm:^7.22.13":
+ version: 7.22.13
+ resolution: "@babel/code-frame@npm:7.22.13"
+ dependencies:
+ "@babel/highlight": ^7.22.13
+ chalk: ^2.4.2
+ checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058
+ languageName: node
+ linkType: hard
+
"@babel/compat-data@npm:^7.13.12":
version: 7.13.12
resolution: "@babel/compat-data@npm:7.13.12"
@@ -157,7 +167,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/generator@npm:^7.19.6, @babel/generator@npm:^7.20.1":
+"@babel/generator@npm:^7.19.6":
version: 7.20.1
resolution: "@babel/generator@npm:7.20.1"
dependencies:
@@ -179,6 +189,18 @@ __metadata:
languageName: node
linkType: hard
+"@babel/generator@npm:^7.23.0":
+ version: 7.23.0
+ resolution: "@babel/generator@npm:7.23.0"
+ dependencies:
+ "@babel/types": ^7.23.0
+ "@jridgewell/gen-mapping": ^0.3.2
+ "@jridgewell/trace-mapping": ^0.3.17
+ jsesc: ^2.5.1
+ checksum: 8efe24adad34300f1f8ea2add420b28171a646edc70f2a1b3e1683842f23b8b7ffa7e35ef0119294e1901f45bfea5b3dc70abe1f10a1917ccdfb41bed69be5f1
+ languageName: node
+ linkType: hard
+
"@babel/helper-annotate-as-pure@npm:^7.12.13":
version: 7.12.13
resolution: "@babel/helper-annotate-as-pure@npm:7.12.13"
@@ -314,6 +336,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-environment-visitor@npm:^7.22.20":
+ version: 7.22.20
+ resolution: "@babel/helper-environment-visitor@npm:7.22.20"
+ checksum: d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69
+ languageName: node
+ linkType: hard
+
"@babel/helper-explode-assignable-expression@npm:^7.18.6":
version: 7.18.6
resolution: "@babel/helper-explode-assignable-expression@npm:7.18.6"
@@ -323,17 +352,6 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-function-name@npm:^7.12.13":
- version: 7.12.13
- resolution: "@babel/helper-function-name@npm:7.12.13"
- dependencies:
- "@babel/helper-get-function-arity": ^7.12.13
- "@babel/template": ^7.12.13
- "@babel/types": ^7.12.13
- checksum: d7bf4ad3c6af1e718ef5560d505147d0a96b95824000336fd4de729a110d79426867a3d97c1eea39945f110ca943316791bcdf192b006a9e367b32c126ee8265
- languageName: node
- linkType: hard
-
"@babel/helper-function-name@npm:^7.18.9, @babel/helper-function-name@npm:^7.19.0":
version: 7.19.0
resolution: "@babel/helper-function-name@npm:7.19.0"
@@ -344,12 +362,13 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-get-function-arity@npm:^7.12.13":
- version: 7.12.13
- resolution: "@babel/helper-get-function-arity@npm:7.12.13"
+"@babel/helper-function-name@npm:^7.23.0":
+ version: 7.23.0
+ resolution: "@babel/helper-function-name@npm:7.23.0"
dependencies:
- "@babel/types": ^7.12.13
- checksum: 847ef9f4d4b2dc38574db6b0732c3add1cd65d54bab94c24d319188f2066c9b9ab2b0dda539cae7281d12ec302e3335b11ca3dcfb555566138d213905d00f711
+ "@babel/template": ^7.22.15
+ "@babel/types": ^7.23.0
+ checksum: e44542257b2d4634a1f979244eb2a4ad8e6d75eb6761b4cfceb56b562f7db150d134bc538c8e6adca3783e3bc31be949071527aa8e3aab7867d1ad2d84a26e10
languageName: node
linkType: hard
@@ -362,6 +381,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-hoist-variables@npm:^7.22.5":
+ version: 7.22.5
+ resolution: "@babel/helper-hoist-variables@npm:7.22.5"
+ dependencies:
+ "@babel/types": ^7.22.5
+ checksum: 394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc
+ languageName: node
+ linkType: hard
+
"@babel/helper-member-expression-to-functions@npm:^7.13.12":
version: 7.13.12
resolution: "@babel/helper-member-expression-to-functions@npm:7.13.12"
@@ -571,6 +599,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-split-export-declaration@npm:^7.22.6":
+ version: 7.22.6
+ resolution: "@babel/helper-split-export-declaration@npm:7.22.6"
+ dependencies:
+ "@babel/types": ^7.22.5
+ checksum: e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921
+ languageName: node
+ linkType: hard
+
"@babel/helper-string-parser@npm:^7.19.4":
version: 7.19.4
resolution: "@babel/helper-string-parser@npm:7.19.4"
@@ -578,6 +615,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-string-parser@npm:^7.22.5":
+ version: 7.22.5
+ resolution: "@babel/helper-string-parser@npm:7.22.5"
+ checksum: 836851ca5ec813077bbb303acc992d75a360267aa3b5de7134d220411c852a6f17de7c0d0b8c8dcc0f567f67874c00f4528672b2a4f1bc978a3ada64c8c78467
+ languageName: node
+ linkType: hard
+
"@babel/helper-validator-identifier@npm:^7.12.11":
version: 7.12.11
resolution: "@babel/helper-validator-identifier@npm:7.12.11"
@@ -592,6 +636,13 @@ __metadata:
languageName: node
linkType: hard
+"@babel/helper-validator-identifier@npm:^7.22.20":
+ version: 7.22.20
+ resolution: "@babel/helper-validator-identifier@npm:7.22.20"
+ checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc
+ languageName: node
+ linkType: hard
+
"@babel/helper-validator-option@npm:^7.12.17":
version: 7.12.17
resolution: "@babel/helper-validator-option@npm:7.12.17"
@@ -673,6 +724,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/highlight@npm:^7.22.13":
+ version: 7.22.20
+ resolution: "@babel/highlight@npm:7.22.20"
+ dependencies:
+ "@babel/helper-validator-identifier": ^7.22.20
+ chalk: ^2.4.2
+ js-tokens: ^4.0.0
+ checksum: 84bd034dca309a5e680083cd827a766780ca63cef37308404f17653d32366ea76262bd2364b2d38776232f2d01b649f26721417d507e8b4b6da3e4e739f6d134
+ languageName: node
+ linkType: hard
+
"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.13, @babel/parser@npm:^7.13.13":
version: 7.13.13
resolution: "@babel/parser@npm:7.13.13"
@@ -691,7 +753,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/parser@npm:^7.18.10, @babel/parser@npm:^7.19.6, @babel/parser@npm:^7.20.1":
+"@babel/parser@npm:^7.18.10, @babel/parser@npm:^7.19.6":
version: 7.20.1
resolution: "@babel/parser@npm:7.20.1"
bin:
@@ -700,6 +762,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.0":
+ version: 7.23.0
+ resolution: "@babel/parser@npm:7.23.0"
+ bin:
+ parser: ./bin/babel-parser.js
+ checksum: 453fdf8b9e2c2b7d7b02139e0ce003d1af21947bbc03eb350fb248ee335c9b85e4ab41697ddbdd97079698de825a265e45a0846bb2ed47a2c7c1df833f42a354
+ languageName: node
+ linkType: hard
+
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.18.6":
version: 7.18.6
resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.18.6"
@@ -1714,59 +1785,36 @@ __metadata:
languageName: node
linkType: hard
-"@babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.13.13":
- version: 7.13.13
- resolution: "@babel/traverse@npm:7.13.13"
+"@babel/template@npm:^7.22.15":
+ version: 7.22.15
+ resolution: "@babel/template@npm:7.22.15"
dependencies:
- "@babel/code-frame": ^7.12.13
- "@babel/generator": ^7.13.9
- "@babel/helper-function-name": ^7.12.13
- "@babel/helper-split-export-declaration": ^7.12.13
- "@babel/parser": ^7.13.13
- "@babel/types": ^7.13.13
- debug: ^4.1.0
- globals: ^11.1.0
- checksum: 97b85985722144ab4f21b476eb3a61abd67d0e75ad9b4546ae8c7d853ccdfaef0c9ae668fa16809f2e182319f250def585889ae5fd9d9dfcf598cedac0e7b626
- languageName: node
- linkType: hard
-
-"@babel/traverse@npm:^7.19.0, @babel/traverse@npm:^7.19.1, @babel/traverse@npm:^7.19.6, @babel/traverse@npm:^7.20.1":
- version: 7.20.1
- resolution: "@babel/traverse@npm:7.20.1"
- dependencies:
- "@babel/code-frame": ^7.18.6
- "@babel/generator": ^7.20.1
- "@babel/helper-environment-visitor": ^7.18.9
- "@babel/helper-function-name": ^7.19.0
- "@babel/helper-hoist-variables": ^7.18.6
- "@babel/helper-split-export-declaration": ^7.18.6
- "@babel/parser": ^7.20.1
- "@babel/types": ^7.20.0
- debug: ^4.1.0
- globals: ^11.1.0
- checksum: 6696176d574b7ff93466848010bc7e94b250169379ec2a84f1b10da46a7cc2018ea5e3a520c3078487db51e3a4afab9ecff48f25d1dbad8c1319362f4148fb4b
+ "@babel/code-frame": ^7.22.13
+ "@babel/parser": ^7.22.15
+ "@babel/types": ^7.22.15
+ checksum: 1f3e7dcd6c44f5904c184b3f7fe280394b191f2fed819919ffa1e529c259d5b197da8981b6ca491c235aee8dbad4a50b7e31304aa531271cb823a4a24a0dd8fd
languageName: node
linkType: hard
-"@babel/traverse@npm:^7.20.10, @babel/traverse@npm:^7.20.7, @babel/traverse@npm:^7.7.2":
- version: 7.20.10
- resolution: "@babel/traverse@npm:7.20.10"
+"@babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.13.13, @babel/traverse@npm:^7.19.0, @babel/traverse@npm:^7.19.1, @babel/traverse@npm:^7.19.6, @babel/traverse@npm:^7.20.1, @babel/traverse@npm:^7.20.10, @babel/traverse@npm:^7.20.7, @babel/traverse@npm:^7.7.2":
+ version: 7.23.2
+ resolution: "@babel/traverse@npm:7.23.2"
dependencies:
- "@babel/code-frame": ^7.18.6
- "@babel/generator": ^7.20.7
- "@babel/helper-environment-visitor": ^7.18.9
- "@babel/helper-function-name": ^7.19.0
- "@babel/helper-hoist-variables": ^7.18.6
- "@babel/helper-split-export-declaration": ^7.18.6
- "@babel/parser": ^7.20.7
- "@babel/types": ^7.20.7
+ "@babel/code-frame": ^7.22.13
+ "@babel/generator": ^7.23.0
+ "@babel/helper-environment-visitor": ^7.22.20
+ "@babel/helper-function-name": ^7.23.0
+ "@babel/helper-hoist-variables": ^7.22.5
+ "@babel/helper-split-export-declaration": ^7.22.6
+ "@babel/parser": ^7.23.0
+ "@babel/types": ^7.23.0
debug: ^4.1.0
globals: ^11.1.0
- checksum: 8e36dfc76b8f7aafa01b98130c0257e3148eb7132e4b599be565bddae5faec7e20a0f92786a829a8d962a0bf5652fe0019cadd85716d70d140785dec640ff6f7
+ checksum: 26a1eea0dde41ab99dde8b9773a013a0dc50324e5110a049f5d634e721ff08afffd54940b3974a20308d7952085ac769689369e9127dea655f868c0f6e1ab35d
languageName: node
linkType: hard
-"@babel/types@npm:^7, @babel/types@npm:^7.0.0, @babel/types@npm:^7.12.13, @babel/types@npm:^7.13.0, @babel/types@npm:^7.13.12, @babel/types@npm:^7.13.13, @babel/types@npm:^7.13.14, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
+"@babel/types@npm:^7, @babel/types@npm:^7.0.0, @babel/types@npm:^7.12.13, @babel/types@npm:^7.13.0, @babel/types@npm:^7.13.12, @babel/types@npm:^7.13.14, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
version: 7.13.14
resolution: "@babel/types@npm:7.13.14"
dependencies:
@@ -1799,6 +1847,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0":
+ version: 7.23.0
+ resolution: "@babel/types@npm:7.23.0"
+ dependencies:
+ "@babel/helper-string-parser": ^7.22.5
+ "@babel/helper-validator-identifier": ^7.22.20
+ to-fast-properties: ^2.0.0
+ checksum: 215fe04bd7feef79eeb4d33374b39909ce9cad1611c4135a4f7fdf41fe3280594105af6d7094354751514625ea92d0875aba355f53e86a92600f290e77b0e604
+ languageName: node
+ linkType: hard
+
"@bcoe/v8-coverage@npm:^0.2.3":
version: 0.2.3
resolution: "@bcoe/v8-coverage@npm:0.2.3"
@@ -2104,6 +2163,13 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/resolve-uri@npm:^3.1.0":
+ version: 3.1.1
+ resolution: "@jridgewell/resolve-uri@npm:3.1.1"
+ checksum: f5b441fe7900eab4f9155b3b93f9800a916257f4e8563afbcd3b5a5337b55e52bd8ae6735453b1b745457d9f6cdb16d74cd6220bbdd98cf153239e13f6cbb653
+ languageName: node
+ linkType: hard
+
"@jridgewell/set-array@npm:^1.0.0, @jridgewell/set-array@npm:^1.0.1":
version: 1.1.2
resolution: "@jridgewell/set-array@npm:1.1.2"
@@ -2128,6 +2194,13 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/sourcemap-codec@npm:^1.4.14":
+ version: 1.4.15
+ resolution: "@jridgewell/sourcemap-codec@npm:1.4.15"
+ checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8
+ languageName: node
+ linkType: hard
+
"@jridgewell/trace-mapping@npm:^0.3.14, @jridgewell/trace-mapping@npm:^0.3.9":
version: 0.3.17
resolution: "@jridgewell/trace-mapping@npm:0.3.17"
@@ -2138,6 +2211,16 @@ __metadata:
languageName: node
linkType: hard
+"@jridgewell/trace-mapping@npm:^0.3.17":
+ version: 0.3.19
+ resolution: "@jridgewell/trace-mapping@npm:0.3.19"
+ dependencies:
+ "@jridgewell/resolve-uri": ^3.1.0
+ "@jridgewell/sourcemap-codec": ^1.4.14
+ checksum: 956a6f0f6fec060fb48c6bf1f5ec2064e13cd38c8be3873877d4b92b4a27ba58289a34071752671262a3e3c202abcc3fa2aac64d8447b4b0fa1ba3c9047f1c20
+ languageName: node
+ linkType: hard
+
"@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1":
version: 5.1.1-v1
resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1"
@@ -3127,12 +3210,14 @@ __metadata:
languageName: node
linkType: hard
-"axios@npm:^0.21.1":
- version: 0.21.4
- resolution: "axios@npm:0.21.4"
+"axios@npm:^1.6.0":
+ version: 1.6.1
+ resolution: "axios@npm:1.6.1"
dependencies:
- follow-redirects: ^1.14.0
- checksum: 44245f24ac971e7458f3120c92f9d66d1fc695e8b97019139de5b0cc65d9b8104647db01e5f46917728edfc0cfd88eb30fc4c55e6053eef4ace76768ce95ff3c
+ follow-redirects: ^1.15.0
+ form-data: ^4.0.0
+ proxy-from-env: ^1.1.0
+ checksum: 573f03f59b7487d54551b16f5e155d1d130ad4864ed32d1da93d522b78a57123b34e3bde37f822a65ee297e79f1db840f9ad6514addff50d3cbf5caeed39e8dc
languageName: node
linkType: hard
@@ -3508,7 +3593,7 @@ __metadata:
languageName: node
linkType: hard
-"chalk@npm:^2.0.0":
+"chalk@npm:^2.0.0, chalk@npm:^2.4.2":
version: 2.4.2
resolution: "chalk@npm:2.4.2"
dependencies:
@@ -4819,13 +4904,13 @@ __metadata:
languageName: node
linkType: hard
-"follow-redirects@npm:^1.14.0":
- version: 1.15.2
- resolution: "follow-redirects@npm:1.15.2"
+"follow-redirects@npm:^1.15.0":
+ version: 1.15.3
+ resolution: "follow-redirects@npm:1.15.3"
peerDependenciesMeta:
debug:
optional: true
- checksum: faa66059b66358ba65c234c2f2a37fcec029dc22775f35d9ad6abac56003268baf41e55f9ee645957b32c7d9f62baf1f0b906e68267276f54ec4b4c597c2b190
+ checksum: 584da22ec5420c837bd096559ebfb8fe69d82512d5585004e36a3b4a6ef6d5905780e0c74508c7b72f907d1fa2b7bd339e613859e9c304d0dc96af2027fd0231
languageName: node
linkType: hard
@@ -4847,6 +4932,17 @@ __metadata:
languageName: node
linkType: hard
+"form-data@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "form-data@npm:4.0.0"
+ dependencies:
+ asynckit: ^0.4.0
+ combined-stream: ^1.0.8
+ mime-types: ^2.1.12
+ checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c
+ languageName: node
+ linkType: hard
+
"form-data@npm:~2.3.2":
version: 2.3.3
resolution: "form-data@npm:2.3.3"
@@ -7736,6 +7832,13 @@ __metadata:
languageName: node
linkType: hard
+"proxy-from-env@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "proxy-from-env@npm:1.1.0"
+ checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4
+ languageName: node
+ linkType: hard
+
"psl@npm:^1.1.28, psl@npm:^1.1.33":
version: 1.8.0
resolution: "psl@npm:1.8.0"
@@ -8987,7 +9090,7 @@ resolve@^2.0.0-next.3:
version: 0.0.0-use.local
resolution: "tgui-dev-server@workspace:packages/tgui-dev-server"
dependencies:
- axios: ^0.21.1
+ axios: ^1.6.0
glob: ^7.1.7
source-map: ^0.7.3
stacktrace-parser: ^0.1.10
diff --git a/tools/HitboxExpander/.gitignore b/tools/HitboxExpander/.gitignore
deleted file mode 100644
index ec7f5fd7c18f..000000000000
--- a/tools/HitboxExpander/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-Imaging-1.1.7/
-zlib/
-
diff --git a/tools/HitboxExpander/Hitbox Expander.bat b/tools/HitboxExpander/Hitbox Expander.bat
new file mode 100644
index 000000000000..ac69e5505dbd
--- /dev/null
+++ b/tools/HitboxExpander/Hitbox Expander.bat
@@ -0,0 +1,2 @@
+@call "%~dp0\..\bootstrap\python" -m HitboxExpander %*
+@pause
diff --git a/tools/HitboxExpander/README b/tools/HitboxExpander/README.txt
old mode 100755
new mode 100644
similarity index 58%
rename from tools/HitboxExpander/README
rename to tools/HitboxExpander/README.txt
index df9cb5babb03..67a5b8bf42de
--- a/tools/HitboxExpander/README
+++ b/tools/HitboxExpander/README.txt
@@ -1,10 +1,7 @@
-Setup: Unzip the zip files in third_party/ so that you have the directories
-third_party/Imaging-1.1.7/ and third_party/zlib/.
-
-Usage: python hitbox_expander.py
-
-This tool expands the hitbox of the given image by 1 pixel.
-Works by changing some of the fully-transparent pixels to alpha=1 black pixels.
-Naked human eye usually cannot notice the difference.
-
-No space carps or corgis have been used or injured in the production of this tool.
+Usage: tools/bootstrap/python -m HitboxExpander
+
+This tool expands the hitbox of the given image by 1 pixel.
+Works by changing some of the fully-transparent pixels to alpha=1 black pixels.
+Naked human eye usually cannot notice the difference.
+
+No space carps or corgis have been used or injured in the production of this tool.
diff --git a/tools/HitboxExpander/hitbox_expander.py b/tools/HitboxExpander/__main__.py
old mode 100755
new mode 100644
similarity index 74%
rename from tools/HitboxExpander/hitbox_expander.py
rename to tools/HitboxExpander/__main__.py
index 0f1991bd3534..c06352440c7a
--- a/tools/HitboxExpander/hitbox_expander.py
+++ b/tools/HitboxExpander/__main__.py
@@ -2,21 +2,10 @@
import sys
import inspect
import shutil
-
-def AddToPath(path):
- if path not in sys.path:
- sys.path.insert(0, path)
- delimeter = ':' if os.name == "posix" else ";"
- os.environ['PATH'] = path + delimeter + os.environ['PATH']
+import PIL.Image as Image
current_dir = os.path.split(inspect.getfile(inspect.currentframe()))[0]
-AddToPath(os.path.abspath(os.path.join(current_dir, "third_party/Imaging-1.1.7/PIL")))
-AddToPath(os.path.abspath(os.path.join(current_dir, "third_party/zlib")))
-
-import Image
-import _imaging
-
def PngSave(im, file):
# From http://blog.client9.com/2007/08/28/python-pil-and-png-metadata-take-2.html
@@ -25,13 +14,13 @@ def PngSave(im, file):
reserved = ('interlace', 'gamma', 'dpi', 'transparency', 'aspect')
# undocumented class
- import PngImagePlugin
+ import PIL.PngImagePlugin as PngImagePlugin
meta = PngImagePlugin.PngInfo()
# copy metadata into new object
- for k,v in im.info.iteritems():
+ for k,v in im.info.items():
if k in reserved: continue
- meta.add_text(k, v, 0)
+ meta.add_text(k, str(v), 0)
# and save
im.save(file, "PNG", pnginfo=meta)
@@ -44,7 +33,7 @@ def ProcessFile(path):
try:
im = Image.open(path)
- print name + ": " + im.format, im.size, im.mode
+ print(name + ": " + im.format, im.size, im.mode)
if im.mode != "RGBA":
return
width, height = im.size
@@ -76,15 +65,19 @@ def add(x, y):
pix[coords] = (0, 0, 0, 1)
PngSave(im, path)
- except:
- print "Could not process " + name
+ except Exception as e:
+ print("Could not process " + name)
+ print(e)
root_dir = os.path.abspath(os.path.join(current_dir, "../../"))
icons_dir = os.path.join(root_dir, "icons")
def Main():
if len(sys.argv) != 2:
- print "Usage: hitbox_expander.py filename.dmi"
+ if os.name == 'nt':
+ print("Usage: drag-and-drop a .dmi onto `Hitbox Expander.bat`\n or")
+ with open(os.path.join(current_dir, "README.txt")) as f:
+ print(f.read())
return 0
try:
@@ -101,7 +94,7 @@ def Main():
ProcessFile(path)
return 0
- print "File not found: " + sys.argv[1]
+ print("File not found: " + sys.argv[1])
if __name__ == "__main__":
Main()
diff --git a/tools/HitboxExpander/hitbox_expander.sh b/tools/HitboxExpander/hitbox_expander.sh
new file mode 100644
index 000000000000..aca0ebf9e355
--- /dev/null
+++ b/tools/HitboxExpander/hitbox_expander.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+set -e
+exec "$(dirname "$0")/../bootstrap/python" -m HitboxExpander "$@"
diff --git a/tools/HitboxExpander/third_party/Imaging-1.1.7.zip b/tools/HitboxExpander/third_party/Imaging-1.1.7.zip
deleted file mode 100755
index a9af836b11ab..000000000000
Binary files a/tools/HitboxExpander/third_party/Imaging-1.1.7.zip and /dev/null differ
diff --git a/tools/HitboxExpander/third_party/zlib.zip b/tools/HitboxExpander/third_party/zlib.zip
deleted file mode 100755
index af4a2fd4c5c5..000000000000
Binary files a/tools/HitboxExpander/third_party/zlib.zip and /dev/null differ
diff --git a/tools/bootstrap/node_.ps1 b/tools/bootstrap/node_.ps1
index ac8d3b343f16..1107d9542c8e 100644
--- a/tools/bootstrap/node_.ps1
+++ b/tools/bootstrap/node_.ps1
@@ -20,7 +20,8 @@ function Download-Node {
Write-Output "Downloading Node v$NodeVersion (may take a while)"
New-Item $NodeTargetDir -ItemType Directory -ErrorAction silentlyContinue | Out-Null
$WebClient = New-Object Net.WebClient
- $WebClient.DownloadFile($NodeSource, $NodeTarget)
+ $WebClient.DownloadFile($NodeSource, "$NodeTarget.downloading")
+ Rename-Item "$NodeTarget.downloading" $NodeTarget
}
## Convenience variables
diff --git a/tools/bootstrap/python37._pth b/tools/bootstrap/python37._pth
deleted file mode 100644
index 4fe54372613d..000000000000
--- a/tools/bootstrap/python37._pth
+++ /dev/null
@@ -1,6 +0,0 @@
-python37.zip
-.
-..\..\..
-
-# Uncomment to run site.main() automatically
-import site
diff --git a/tools/bootstrap/python_.ps1 b/tools/bootstrap/python_.ps1
index 93a6f756960c..f37589f10644 100644
--- a/tools/bootstrap/python_.ps1
+++ b/tools/bootstrap/python_.ps1
@@ -49,8 +49,13 @@ if (!(Test-Path $PythonExe -PathType Leaf)) {
[System.IO.Compression.ZipFile]::ExtractToDirectory($Archive, $PythonDir)
+ $PythonVersionArray = $PythonVersion.Split(".")
+ $PythonVersionString = "python$($PythonVersionArray[0])$($PythonVersionArray[1])"
+ Write-Output "Generating PATH descriptor."
+ New-Item "$Cache/$PythonVersionString._pth" | Out-Null
+ Set-Content "$Cache/$PythonVersionString._pth" "$PythonVersionString.zip`n.`n..\..\..`nimport site`n"
# Copy a ._pth file without "import site" commented, so pip will work
- Copy-Item "$Bootstrap/python37._pth" $PythonDir `
+ Copy-Item "$Cache/$PythonVersionString._pth" $PythonDir `
-ErrorAction Stop
Remove-Item $Archive
diff --git a/tools/deploy.sh b/tools/deploy.sh
index a83f1cb5756b..ced6b9ecce1c 100755
--- a/tools/deploy.sh
+++ b/tools/deploy.sh
@@ -37,4 +37,4 @@ cp -r strings/* $1/strings/
#dlls on windows
cp rust_g* $1/ || true
-cp *byond-extools.* $1/ || true
\ No newline at end of file
+cp *auxmos.* $1/ || true
diff --git a/tools/ezdb/__main__.py b/tools/ezdb/__main__.py
new file mode 100644
index 000000000000..c817aa4d6541
--- /dev/null
+++ b/tools/ezdb/__main__.py
@@ -0,0 +1,15 @@
+import argparse
+from .steps import STEPS
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--port", type = int, default = 1338)
+
+args = parser.parse_args()
+
+for step in STEPS:
+ if not step.should_run():
+ continue
+
+ step.run(args)
+
+print("Done!")
diff --git a/tools/ezdb/ezdb.bat b/tools/ezdb/ezdb.bat
new file mode 100644
index 000000000000..b4257fe3c364
--- /dev/null
+++ b/tools/ezdb/ezdb.bat
@@ -0,0 +1,2 @@
+@call "%~dp0\..\bootstrap\python" -m ezdb %*
+@pause
diff --git a/tools/ezdb/ezdb/__init__.py b/tools/ezdb/ezdb/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tools/ezdb/ezdb/changes.py b/tools/ezdb/ezdb/changes.py
new file mode 100644
index 000000000000..607ea1efea35
--- /dev/null
+++ b/tools/ezdb/ezdb/changes.py
@@ -0,0 +1,31 @@
+import re
+from dataclasses import dataclass
+from .paths import get_changelog_path
+
+REGEX_CHANGE = r"-+\s*Version (?P[0-9]+)\.(?P[0-9]+), .+?\`\`\`sql\s*(?P.+?)\s*\`\`\`.*?-{5}"
+
+@dataclass
+class Change:
+ major_version: int
+ minor_version: int
+ sql: str
+
+def get_changes() -> list[Change]:
+ with open(get_changelog_path(), "r") as file:
+ changelog = file.read()
+ changes = []
+
+ for change_match in re.finditer(REGEX_CHANGE, changelog, re.MULTILINE | re.DOTALL):
+ changes.append(Change(
+ int(change_match.group("major")),
+ int(change_match.group("minor")),
+ change_match.group("sql")
+ ))
+
+ changes.sort(key = lambda change: (change.major_version, change.minor_version), reverse = True)
+
+ return changes
+
+def get_current_version():
+ changes = get_changes()
+ return (changes[0].major_version, changes[0].minor_version)
diff --git a/tools/ezdb/ezdb/config.py b/tools/ezdb/ezdb/config.py
new file mode 100644
index 000000000000..87d853cd42bf
--- /dev/null
+++ b/tools/ezdb/ezdb/config.py
@@ -0,0 +1,22 @@
+from .paths import get_config_path
+from typing import Optional
+
+def read_config() -> Optional[dict[str, str]]:
+ config_path = get_config_path()
+ if not config_path.exists():
+ return None
+
+ with config_path.open('r') as file:
+ lines = file.readlines()
+ entries = {}
+
+ for line in lines:
+ if line.startswith("#"):
+ continue
+ if " " not in line:
+ continue
+
+ key, value = line.split(" ", 1)
+ entries[key.strip()] = value.strip()
+
+ return entries
diff --git a/tools/ezdb/ezdb/mysql.py b/tools/ezdb/ezdb/mysql.py
new file mode 100644
index 000000000000..249704fe04de
--- /dev/null
+++ b/tools/ezdb/ezdb/mysql.py
@@ -0,0 +1,68 @@
+import atexit
+import mysql.connector
+import subprocess
+from contextlib import closing
+from .config import read_config
+from .paths import get_mariadb_client_path, get_mariadb_daemon_path
+
+def open_connection():
+ config = read_config()
+ assert config["FEEDBACK_PASSWORD"] is not None, "No password found in config file"
+
+ connection = mysql.connector.connect(
+ user = config["FEEDBACK_LOGIN"],
+ password = config["FEEDBACK_PASSWORD"],
+ port = int(config["PORT"]),
+ raise_on_warnings = True,
+ )
+
+ connection.autocommit = True
+
+ return closing(connection)
+
+# We use custom things like delimiters, so we can't use the built-in cursor.execute
+def execute_sql(sql: str):
+ config = read_config()
+ assert config is not None, "No config file found"
+ assert config["FEEDBACK_PASSWORD"] is not None, "No password found in config file"
+
+ subprocess.run(
+ [
+ str(get_mariadb_client_path()),
+ "-u",
+ "root",
+ "-p" + config["FEEDBACK_PASSWORD"],
+ "--port",
+ config["PORT"],
+ "--database",
+ config["FEEDBACK_DATABASE"],
+ ],
+ input = sql,
+ encoding = "utf-8",
+ check = True,
+ stderr = subprocess.STDOUT,
+ )
+
+def insert_new_schema_query(major_version: int, minor_version: int):
+ return f"INSERT INTO `schema_revision` (`major`, `minor`) VALUES ({major_version}, {minor_version})"
+
+process = None
+def start_daemon():
+ global process
+ if process is not None:
+ return
+
+ print("Starting MariaDB daemon...")
+ config = read_config()
+ assert config is not None, "No config file found"
+
+ process = subprocess.Popen(
+ [
+ str(get_mariadb_daemon_path()),
+ "--port",
+ config["PORT"],
+ ],
+ stderr = subprocess.PIPE,
+ )
+
+ atexit.register(process.kill)
diff --git a/tools/ezdb/ezdb/paths.py b/tools/ezdb/ezdb/paths.py
new file mode 100644
index 000000000000..502e6762b35f
--- /dev/null
+++ b/tools/ezdb/ezdb/paths.py
@@ -0,0 +1,34 @@
+import pathlib
+
+def get_root_path():
+ current_path = pathlib.Path(__file__)
+ while current_path.name != 'tools':
+ current_path = current_path.parent
+ return current_path.parent
+
+def get_config_path():
+ return get_root_path() / 'config' / 'ezdb.txt'
+
+def get_db_path():
+ return get_root_path() / 'db'
+
+def get_data_path():
+ return get_db_path() / 'data'
+
+def get_mariadb_bin_path():
+ return get_db_path() / 'bin'
+
+def get_mariadb_client_path():
+ return get_mariadb_bin_path() / 'mariadb.exe'
+
+def get_mariadb_daemon_path():
+ return get_mariadb_bin_path() / 'mariadbd.exe'
+
+def get_mariadb_install_db_path():
+ return get_mariadb_bin_path() / 'mariadb-install-db.exe'
+
+def get_initial_schema_path():
+ return get_root_path() / 'SQL' / 'tgstation_schema.sql'
+
+def get_changelog_path():
+ return get_root_path() / 'SQL' / 'database_changelog.md'
diff --git a/tools/ezdb/steps/__init__.py b/tools/ezdb/steps/__init__.py
new file mode 100644
index 000000000000..969a1029d79c
--- /dev/null
+++ b/tools/ezdb/steps/__init__.py
@@ -0,0 +1,11 @@
+from .download_mariadb import DownloadMariaDB
+from .install_database import InstallDatabase
+from .install_initial_schema import InstallInitialSchema
+from .update_schema import UpdateSchema
+
+STEPS = [
+ DownloadMariaDB,
+ InstallDatabase,
+ InstallInitialSchema,
+ UpdateSchema,
+]
diff --git a/tools/ezdb/steps/download_mariadb.py b/tools/ezdb/steps/download_mariadb.py
new file mode 100644
index 000000000000..ecaf01cf6e23
--- /dev/null
+++ b/tools/ezdb/steps/download_mariadb.py
@@ -0,0 +1,50 @@
+import os
+import pathlib
+import tempfile
+import urllib.request
+import zipfile
+from ..ezdb.paths import get_config_path, get_data_path, get_db_path, get_mariadb_bin_path, get_mariadb_daemon_path, get_mariadb_install_db_path
+from .step import Step
+
+# Theoretically, this could use the REST API that MariaDB has to find the URL given a version:
+# https://downloads.mariadb.org/rest-api/mariadb/10.11
+DOWNLOAD_URL = "http://downloads.mariadb.org/rest-api/mariadb/10.11.2/mariadb-10.11.2-winx64.zip"
+FOLDER_NAME = "mariadb-10.11.2-winx64"
+
+temp_extract_path = get_db_path() / "_temp/"
+
+class DownloadMariaDB(Step):
+ @staticmethod
+ def should_run() -> bool:
+ return not get_mariadb_bin_path().exists()
+
+ @staticmethod
+ def run(args):
+ if temp_extract_path.exists():
+ print("Deleting old temporary extract folder")
+ temp_extract_path.rmdir()
+
+ print("Downloading portable MariaDB...")
+
+ # delete = False so we can write to it
+ temporary_file = tempfile.NamedTemporaryFile(delete = False)
+
+ try:
+ urllib.request.urlretrieve(DOWNLOAD_URL, temporary_file.name)
+
+ print("Extracting...")
+ os.makedirs(temp_extract_path, exist_ok = True)
+ with zipfile.ZipFile(temporary_file) as zip_file:
+ for file in zip_file.namelist():
+ if file.startswith(f"{FOLDER_NAME}/bin/"):
+ with zip_file.open(file) as source, open(temp_extract_path / pathlib.Path(file).name, "wb") as target:
+ target.write(source.read())
+
+ print("Moving...")
+
+ temp_extract_path.rename(get_mariadb_bin_path())
+ finally:
+ temporary_file.close()
+
+ if temp_extract_path.exists():
+ temp_extract_path.rmdir()
diff --git a/tools/ezdb/steps/install_database.py b/tools/ezdb/steps/install_database.py
new file mode 100644
index 000000000000..698faf781ed5
--- /dev/null
+++ b/tools/ezdb/steps/install_database.py
@@ -0,0 +1,46 @@
+import argparse
+import secrets
+import subprocess
+from ..ezdb.paths import get_config_path, get_data_path, get_mariadb_bin_path, get_mariadb_daemon_path, get_mariadb_install_db_path
+from .step import Step
+
+def create_password() -> str:
+ return secrets.token_urlsafe(40)
+
+class InstallDatabase(Step):
+ @staticmethod
+ def should_run() -> bool:
+ # If the db folder exists, but the config doesn't, we cancelled
+ # halfway through and ought to start over by deleting the data folder.
+ return get_mariadb_bin_path().exists() and (not get_data_path().exists() or not get_config_path().exists())
+
+ @staticmethod
+ def run(args: argparse.Namespace):
+ data_folder = get_data_path()
+ if data_folder.exists():
+ print("Deleting old data folder")
+ data_folder.rmdir()
+
+ password = create_password()
+
+ print("Installing database...")
+
+ subprocess.run(
+ [
+ str(get_mariadb_install_db_path()),
+ f"--port={args.port}",
+ f"--password={password}",
+ ],
+ check = True,
+ stderr = subprocess.STDOUT,
+ )
+
+ print("Creating config...")
+ with open(get_config_path(), "w") as file:
+ file.write("SQL_ENABLED\n")
+ file.write(f"PORT {args.port}\n")
+ file.write(f"FEEDBACK_LOGIN root\n")
+ file.write(f"FEEDBACK_PASSWORD {password}\n")
+ file.write("FEEDBACK_DATABASE tgstation\n")
+ file.write("FEEDBACK_TABLEPREFIX\n")
+ file.write(f"DB_DAEMON {str(get_mariadb_daemon_path())}")
diff --git a/tools/ezdb/steps/install_initial_schema.py b/tools/ezdb/steps/install_initial_schema.py
new file mode 100644
index 000000000000..bb7ee519ae70
--- /dev/null
+++ b/tools/ezdb/steps/install_initial_schema.py
@@ -0,0 +1,53 @@
+from contextlib import closing
+from ..ezdb.changes import get_current_version
+from ..ezdb.config import read_config
+from ..ezdb.mysql import execute_sql, insert_new_schema_query, open_connection, start_daemon
+from ..ezdb.paths import get_initial_schema_path
+from .step import Step
+
+class InstallInitialSchema(Step):
+ @staticmethod
+ def should_run() -> bool:
+ start_daemon()
+
+ config = read_config()
+ assert config is not None, "No config file found"
+
+ database = config["FEEDBACK_DATABASE"]
+ assert database is not None, "No database found in config file"
+
+ with open_connection() as connection:
+ with closing(connection.cursor()) as cursor:
+ cursor.execute(f"SHOW DATABASES LIKE '{database}'")
+ if cursor.fetchone() is None:
+ return True
+
+ cursor.execute(f"USE {database}")
+ cursor.execute("SHOW TABLES LIKE 'schema_revision'")
+ if cursor.fetchone() is None:
+ return True
+
+ cursor.execute("SELECT * FROM `schema_revision` LIMIT 1")
+ if cursor.fetchone() is None:
+ return True
+
+ return False
+
+ @staticmethod
+ def run(args):
+ print("Installing initial schema...")
+
+ config = read_config()
+ assert config is not None, "No config file found"
+
+ with open_connection() as connection:
+ with closing(connection.cursor()) as cursor:
+ database = config["FEEDBACK_DATABASE"]
+ cursor.execute(f"CREATE DATABASE {database}")
+ cursor.execute(f"USE {database}")
+
+ (major_version, minor_version) = get_current_version()
+
+ with open(get_initial_schema_path(), 'r') as file:
+ schema = file.read()
+ execute_sql(schema + ";" + insert_new_schema_query(major_version, minor_version))
diff --git a/tools/ezdb/steps/step.py b/tools/ezdb/steps/step.py
new file mode 100644
index 000000000000..6ae4b492df41
--- /dev/null
+++ b/tools/ezdb/steps/step.py
@@ -0,0 +1,10 @@
+import argparse
+
+class Step:
+ @staticmethod
+ def should_run() -> bool:
+ raise NotImplementedError()
+
+ @staticmethod
+ def run(args: argparse.Namespace):
+ raise NotImplementedError()
diff --git a/tools/ezdb/steps/update_schema.py b/tools/ezdb/steps/update_schema.py
new file mode 100644
index 000000000000..e5a1c8d872ef
--- /dev/null
+++ b/tools/ezdb/steps/update_schema.py
@@ -0,0 +1,38 @@
+from contextlib import closing
+from ..ezdb.changes import get_changes
+from ..ezdb.config import read_config
+from ..ezdb.mysql import execute_sql, insert_new_schema_query, open_connection
+from .step import Step
+
+class UpdateSchema(Step):
+ @staticmethod
+ def should_run() -> bool:
+ # Last step is always run
+ return True
+
+ @staticmethod
+ def run(args):
+ config = read_config()
+ assert config is not None, "No config file found"
+
+ database = config["FEEDBACK_DATABASE"]
+ assert database is not None, "No database found in config file"
+
+ with open_connection() as connection:
+ with closing(connection.cursor()) as cursor:
+ cursor.execute(f"USE {database}")
+ cursor.execute("SELECT major, minor FROM `schema_revision` ORDER BY `major` DESC, `minor` DESC LIMIT 1")
+ (major_version, minor_version) = cursor.fetchone()
+
+ changes = get_changes()
+ for change in changes:
+ if change.major_version != major_version:
+ print("NOT IMPLEMENTED: Major version change, these historically require extra tooling")
+ continue
+
+ if change.minor_version > minor_version:
+ print(f"Running change {change.major_version}.{change.minor_version}")
+ execute_sql(change.sql + ";" + insert_new_schema_query(change.major_version, change.minor_version))
+ else:
+ print("No updates necessary")
+ return
diff --git a/tools/hooks/install.sh b/tools/hooks/install.sh
index 997d2851441e..30785a290bef 100755
--- a/tools/hooks/install.sh
+++ b/tools/hooks/install.sh
@@ -15,5 +15,5 @@ echo "Installing tgui hooks"
../../tgui/bin/tgui --install-git-hooks
echo "Installing Python dependencies"
-./python.sh -m pip install -r ../mapmerge2/requirements.txt
+./python.sh -m pip install -r ../requirements.txt
echo "Done"
diff --git a/tools/hooks/install_only_icon_merger.sh b/tools/hooks/install_only_icon_merger.sh
index 0b1ef9869a93..ac4420c72242 100644
--- a/tools/hooks/install_only_icon_merger.sh
+++ b/tools/hooks/install_only_icon_merger.sh
@@ -11,5 +11,5 @@ echo "Installing tgui hooks"
../../tgui/bin/tgui --install-git-hooks
echo "Installing Python dependencies"
-./python.sh -m pip install -r ../mapmerge2/requirements.txt
+./python.sh -m pip install -r ../requirements.txt
echo "Done"
diff --git a/tools/mapmerge2/requirements.txt b/tools/requirements.txt
similarity index 53%
rename from tools/mapmerge2/requirements.txt
rename to tools/requirements.txt
index 5efb583a501c..54c86787040b 100644
--- a/tools/mapmerge2/requirements.txt
+++ b/tools/requirements.txt
@@ -1,3 +1,6 @@
pygit2==1.11.1
bidict==0.22.0
Pillow==9.3.0
+
+# ezdb
+mysql-connector-python==8.0.33
diff --git a/tools/tgs4_scripts/PreCompile.sh b/tools/tgs4_scripts/PreCompile.sh
index 1e26561db6c9..0a82220cca87 100644
--- a/tools/tgs4_scripts/PreCompile.sh
+++ b/tools/tgs4_scripts/PreCompile.sh
@@ -65,6 +65,28 @@ env PKG_CONFIG_ALLOW_CROSS=1 ~/.cargo/bin/cargo build --release --target=i686-un
mv target/i686-unknown-linux-gnu/release/librust_g.so "$1/librust_g.so"
cd ..
+# Auxtools dependencies
+apt-get install -y build-essential g++-multilib libc6-i386 libstdc++6:i386
+
+# Update auxmos
+if [ ! -d "auxmos" ]; then
+ echo "Cloning auxmos..."
+ git clone https://github.com/yogstation13/auxmos
+ cd auxmos
+ ~/.cargo/bin/rustup target add i686-unknown-linux-gnu
+else
+ echo "Fetching auxmos..."
+ cd auxmos
+ git fetch
+ ~/.cargo/bin/rustup target add i686-unknown-linux-gnu
+fi
+
+echo "Deploying auxmos..."
+git checkout "$AUXMOS_VERSION"
+env PKG_CONFIG_ALLOW_CROSS=1 ~/.cargo/bin/cargo rustc --release --target=i686-unknown-linux-gnu --features all_reaction_hooks,katmos -- -C target-cpu=native
+mv -f target/i686-unknown-linux-gnu/release/libauxmos.so "$1/libauxmos.so"
+cd ..
+
# compile tgui
echo "Compiling tgui..."
cd "$1"
diff --git a/tools/travis/check_grep.sh b/tools/travis/check_grep.sh
index 5c1cfb3e4999..fe03b960929a 100755
--- a/tools/travis/check_grep.sh
+++ b/tools/travis/check_grep.sh
@@ -46,6 +46,14 @@ if grep -i 'centcomm' _maps/**/*.dmm; then
echo "ERROR: Misspelling(s) of CENTCOM detected in maps, please remove the extra M(s)."
st=1
fi;
+if grep 'NanoTrasen' code/**/*.dm; then
+ echo "ERROR: Misspelling(s) of Nanotrasen detected in code, please uncapitalize the T."
+ st=1
+fi;
+if grep 'NanoTrasen' _maps/**/*.dmm; then
+ echo "ERROR: Misspelling(s) of Nanotrasen detected in maps, please uncapitalize the T."
+ st=1
+fi;
if grep -i 'balloon_alert\(.*?, ?"[A-Z]'; then
echo
echo "ERROR: Balloon alerts should not start with capital letters. This includes text like 'AI'. If this is a false positive, wrap the text in UNLINT()."
diff --git a/tools/travis/run_server.sh b/tools/travis/run_server.sh
index 284357c947e4..06b97b4dbeac 100755
--- a/tools/travis/run_server.sh
+++ b/tools/travis/run_server.sh
@@ -1,13 +1,18 @@
#!/bin/bash
set -euo pipefail
EXIT_CODE=0
+MAP=$1
tools/deploy.sh travis_test
mkdir travis_test/config
+mkdir travis_test/data
#test config
cp tools/travis/travis_config.txt travis_test/config/config.txt
+#set the map
+cp _maps/$MAP.json travis_test/data/next_map.json
+
cd travis_test
ln -s $HOME/libmariadb/libmariadb.so libmariadb.so
DreamDaemon yogstation.dmb -close -trusted -verbose -params "test-run&log-directory=travis" || EXIT_CODE=$?
diff --git a/yogstation.dme b/yogstation.dme
index d857ced8f5e4..6a69253a9375 100644
--- a/yogstation.dme
+++ b/yogstation.dme
@@ -16,7 +16,10 @@
#include "_maps\_basemap.dm"
#include "code\__byond_version_compat.dm"
#include "code\_compile_options.dm"
+#include "code\_debugger.dm"
#include "code\world.dm"
+#include "code\__DEFINES\_auxtools.dm"
+#include "code\__DEFINES\_bitfields.dm"
#include "code\__DEFINES\_click.dm"
#include "code\__DEFINES\_globals.dm"
#include "code\__DEFINES\_helpers.dm"
@@ -27,6 +30,7 @@
#include "code\__DEFINES\actions.dm"
#include "code\__DEFINES\admin.dm"
#include "code\__DEFINES\ai.dm"
+#include "code\__DEFINES\announcements.dm"
#include "code\__DEFINES\anomalies.dm"
#include "code\__DEFINES\antagonists.dm"
#include "code\__DEFINES\art.dm"
@@ -34,6 +38,7 @@
#include "code\__DEFINES\assert.dm"
#include "code\__DEFINES\atmospherics.dm"
#include "code\__DEFINES\atom_hud.dm"
+#include "code\__DEFINES\bindings.dm"
#include "code\__DEFINES\bloodsuckers.dm"
#include "code\__DEFINES\callbacks.dm"
#include "code\__DEFINES\cargo.dm"
@@ -58,7 +63,6 @@
#include "code\__DEFINES\events.dm"
#include "code\__DEFINES\exosuit_fab.dm"
#include "code\__DEFINES\exports.dm"
-#include "code\__DEFINES\extools.dm"
#include "code\__DEFINES\fantasy_affixes.dm"
#include "code\__DEFINES\fastdmm2.dm"
#include "code\__DEFINES\flags.dm"
@@ -184,7 +188,6 @@
#include "code\__DEFINES\{yogs_defines}\atmospherics.dm"
#include "code\__DEFINES\{yogs_defines}\components.dm"
#include "code\__DEFINES\{yogs_defines}\DNA.dm"
-#include "code\__DEFINES\{yogs_defines}\flags.dm"
#include "code\__DEFINES\{yogs_defines}\flavor_misc.dm"
#include "code\__DEFINES\{yogs_defines}\is_helpers.dm"
#include "code\__DEFINES\{yogs_defines}\logging.dm"
@@ -198,6 +201,7 @@
#include "code\__DEFINES\{yogs_defines}\status_effects.dm"
#include "code\__DEFINES\{yogs_defines}\telecomms.dm"
#include "code\__DEFINES\{yogs_defines}\wires.dm"
+#include "code\__HELPERS\_extools_api.dm"
#include "code\__HELPERS\_lists.dm"
#include "code\__HELPERS\_logging.dm"
#include "code\__HELPERS\_string_lists.dm"
@@ -332,8 +336,8 @@
#include "code\controllers\configuration\entries\resources.dm"
#include "code\controllers\subsystem\achievements.dm"
#include "code\controllers\subsystem\acid.dm"
-#include "code\controllers\subsystem\adjacent_air.dm"
#include "code\controllers\subsystem\air.dm"
+#include "code\controllers\subsystem\air_machinery.dm"
#include "code\controllers\subsystem\ambience.dm"
#include "code\controllers\subsystem\area_contents.dm"
#include "code\controllers\subsystem\asset_loading.dm"
@@ -341,6 +345,7 @@
#include "code\controllers\subsystem\atoms.dm"
#include "code\controllers\subsystem\augury.dm"
#include "code\controllers\subsystem\blackbox.dm"
+#include "code\controllers\subsystem\callback.dm"
#include "code\controllers\subsystem\chat.dm"
#include "code\controllers\subsystem\communications.dm"
#include "code\controllers\subsystem\dbcore.dm"
@@ -663,6 +668,7 @@
#include "code\datums\elements\footstep_override.dm"
#include "code\datums\elements\frozen.dm"
#include "code\datums\elements\life_drain.dm"
+#include "code\datums\elements\light_blocking.dm"
#include "code\datums\elements\movetype_handler.dm"
#include "code\datums\elements\regenerator.dm"
#include "code\datums\elements\rust.dm"
@@ -1566,6 +1572,7 @@
#include "code\modules\admin\verbs\borgpanel.dm"
#include "code\modules\admin\verbs\BrokenInhands.dm"
#include "code\modules\admin\verbs\cinematic.dm"
+#include "code\modules\admin\verbs\commandreport.dm"
#include "code\modules\admin\verbs\deadsay.dm"
#include "code\modules\admin\verbs\debug.dm"
#include "code\modules\admin\verbs\diagnostics.dm"
@@ -1944,11 +1951,13 @@
#include "code\modules\asset_cache\assets\crafting.dm"
#include "code\modules\asset_cache\transports\asset_transport.dm"
#include "code\modules\asset_cache\transports\webroot_transport.dm"
+#include "code\modules\atmospherics\auxgm\breathing_classes.dm"
+#include "code\modules\atmospherics\auxgm\gas_types.dm"
#include "code\modules\atmospherics\environmental\LINDA_fire.dm"
#include "code\modules\atmospherics\environmental\LINDA_system.dm"
#include "code\modules\atmospherics\environmental\LINDA_turf_tile.dm"
+#include "code\modules\atmospherics\gasmixtures\auxgm.dm"
#include "code\modules\atmospherics\gasmixtures\gas_mixture.dm"
-#include "code\modules\atmospherics\gasmixtures\gas_types.dm"
#include "code\modules\atmospherics\gasmixtures\immutable_mixtures.dm"
#include "code\modules\atmospherics\gasmixtures\reactions.dm"
#include "code\modules\atmospherics\machinery\airalarm.dm"
@@ -2107,6 +2116,7 @@
#include "code\modules\client\preferences\balloon_alerts.dm"
#include "code\modules\client\preferences\bar_choice.dm"
#include "code\modules\client\preferences\clerk_choice.dm"
+#include "code\modules\client\preferences\chapel_choice.dm"
#include "code\modules\client\preferences\clothing.dm"
#include "code\modules\client\preferences\credits.dm"
#include "code\modules\client\preferences\donor.dm"
@@ -3245,6 +3255,7 @@
#include "code\modules\projectiles\ammunition\reusable\arrow.dm"
#include "code\modules\projectiles\ammunition\reusable\foam.dm"
#include "code\modules\projectiles\ammunition\special\magic.dm"
+#include "code\modules\projectiles\ammunition\special\reagent.dm"
#include "code\modules\projectiles\ammunition\special\syringe.dm"
#include "code\modules\projectiles\attachments\_attachment.dm"
#include "code\modules\projectiles\attachments\grips.dm"
@@ -3298,6 +3309,7 @@
#include "code\modules\projectiles\guns\misc\blastcannon.dm"
#include "code\modules\projectiles\guns\misc\chem_gun.dm"
#include "code\modules\projectiles\guns\misc\grenade_launcher.dm"
+#include "code\modules\projectiles\guns\misc\hyper_soaker.dm"
#include "code\modules\projectiles\guns\misc\medbeam.dm"
#include "code\modules\projectiles\guns\misc\syringe_gun.dm"
#include "code\modules\projectiles\projectile\beams.dm"
@@ -3334,8 +3346,8 @@
#include "code\modules\projectiles\projectile\special\ion.dm"
#include "code\modules\projectiles\projectile\special\meteor.dm"
#include "code\modules\projectiles\projectile\special\mindflayer.dm"
-#include "code\modules\projectiles\projectile\special\neurotoxin.dm"
#include "code\modules\projectiles\projectile\special\plasma.dm"
+#include "code\modules\projectiles\projectile\special\reagent.dm"
#include "code\modules\projectiles\projectile\special\rocket.dm"
#include "code\modules\projectiles\projectile\special\temperature.dm"
#include "code\modules\projectiles\projectile\special\wormhole.dm"
@@ -3506,6 +3518,7 @@
#include "code\modules\ruins\spaceruin_code\whiteshipruin_box.dm"
#include "code\modules\security_levels\keycard_authentication.dm"
#include "code\modules\security_levels\level_interface.dm"
+#include "code\modules\security_levels\security_level_datums.dm"
#include "code\modules\security_levels\security_levels.dm"
#include "code\modules\shuttle\ai_ship.dm"
#include "code\modules\shuttle\arrivals.dm"
@@ -4057,10 +4070,8 @@
#include "yogstation\code\modules\antagonists\shadowling\thrall.dm"
#include "yogstation\code\modules\antagonists\slaughter\slaughter.dm"
#include "yogstation\code\modules\antagonists\traitor\datum_mindslave.dm"
-#include "yogstation\code\modules\antagonists\traitor\datum_traitor.dm"
#include "yogstation\code\modules\assembly\signaler.dm"
#include "yogstation\code\modules\atmospherics\airalarm.dm"
-#include "yogstation\code\modules\atmospherics\gasmixtures\gas_types.dm"
#include "yogstation\code\modules\atmospherics\machinery\pipes\bluespace.dm"
#include "yogstation\code\modules\atmospherics\unary_devices\vent_pump.dm"
#include "yogstation\code\modules\cargo\cargo_packs.dm"
diff --git a/yogstation/code/controllers/subsystem/ticker.dm b/yogstation/code/controllers/subsystem/ticker.dm
index 69c8b4538f35..b14c02f4dc03 100644
--- a/yogstation/code/controllers/subsystem/ticker.dm
+++ b/yogstation/code/controllers/subsystem/ticker.dm
@@ -29,7 +29,7 @@
"https://www.youtube.com/watch?v=orT5RN3Zwak", // Kirk Franklin - Revolution
"https://www.youtube.com/watch?v=9whQIbNmu9s", // Admiral Hippie - Clown.wmv
"https://www.youtube.com/watch?v=UlHGGKgzgzI", // Elbow - Leaders of the Free World
- "https://www.youtube.com/watch?v=ysPtBjY8o_A", // Chris Christodoulou - Risk of Rain Coalescence
+ "https://www.youtube.com/watch?v=67BwWgrMlxk", // Chris Christodoulou - Risk of Rain Coalescence
"https://www.youtube.com/watch?v=SQOdPQQf2Uo", // Star Trek The Motion Picture: Main Theme Album Style Edit
"https://www.youtube.com/watch?v=jJDAV9vSmYc", // Chris Remo - The Wizard
"https://www.youtube.com/watch?v=nRjLv1L0WF8", // Blue Oyster Cult - Sole Survivor
diff --git a/yogstation/code/controllers/subsystem/yogs.dm b/yogstation/code/controllers/subsystem/yogs.dm
index 7abe1b406fc2..146134a45a35 100644
--- a/yogstation/code/controllers/subsystem/yogs.dm
+++ b/yogstation/code/controllers/subsystem/yogs.dm
@@ -146,7 +146,7 @@ SUBSYSTEM_DEF(Yogs)
/datum/controller/subsystem/Yogs/fire(resumed = 0)
//END OF SHIFT ANNOUNCER
if(world.time > (ROUND_END_ANNOUNCEMENT_TIME*600) && !endedshift && !(EMERGENCY_AT_LEAST_DOCKED))
- priority_announce("Crew, your shift has come to an end.[SSshuttle.emergency.mode == SHUTTLE_IDLE ? "\nYou may call the shuttle whenever you find it appropriate." : ""]", "End of shift announcement", RANDOM_REPORT_SOUND)
+ priority_announce("Crew, your shift has come to an end.[SSshuttle.emergency.mode == SHUTTLE_IDLE ? "\nYou may call the shuttle whenever you find it appropriate." : ""]", "End of shift announcement", SSstation.announcer.get_rand_report_sound())
endedshift = TRUE
//UNCLAIMED TICKET BWOINKER
diff --git a/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm b/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm
index ecc44bb215fb..e9c243a8d913 100644
--- a/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm
+++ b/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm
@@ -1,6 +1,7 @@
GLOBAL_VAR(thebattlebus)
GLOBAL_LIST_EMPTY(battleroyale_players) //reduce iteration cost
GLOBAL_VAR(stormdamage)
+GLOBAL_VAR(final_zone)
/datum/game_mode/fortnite
name = "battle royale"
@@ -17,10 +18,9 @@ GLOBAL_VAR(stormdamage)
Be the last man standing at the end of the game to win. "
var/antag_datum_type = /datum/antagonist/battleroyale
var/list/queued = list() //Who is queued to enter?
- var/list/randomweathers = list("royale science", "royale medbay", "royale service", "royale cargo", "royale security", "royale engineering", "royale maint")
+ var/list/randomweathers = list("royale science", "royale medbay", "royale service", "royale cargo", "royale security", "royale engineering", "royale bridge")
var/stage_interval = 3 MINUTES
var/loot_interval = 75 SECONDS //roughly the time between loot drops
- var/loot_deviation = 30 SECONDS //how much plus or minus around the interval
var/borderstage = 0
var/weightcull = 5 //anything above this gets culled
var/can_end = FALSE //so it doesn't end during setup somehow
@@ -164,12 +164,19 @@ GLOBAL_VAR(stormdamage)
switch(borderstage)
if(0)
SSweather.run_weather("royale start",2)
- if(1 to 7)//close off the map
+ if(1)
+ SSweather.run_weather("royale maint",2)
+ if(2 to 7)//close off the map
var/weather = pick(randomweathers)
SSweather.run_weather(weather, 2)
randomweathers -= weather
if(8)
- SSweather.run_weather("royale hallway", 2)//force them to bridge
+ var/weather = pick(randomweathers) //whichever one is left
+ weather = replacetext(weather, "royale ", "")
+ if(weather == "bridge")
+ weather = "the bridge"
+ GLOB.final_zone = weather
+ SSweather.run_weather("royale hallway", 2)//force them to the final department
if(9)//finish it
SSweather.run_weather("royale centre", 2)
@@ -185,8 +192,7 @@ GLOBAL_VAR(stormdamage)
var/remainingpercent = LAZYLEN(GLOB.battleroyale_players) / original_num
stage_interval = max(1 MINUTES, initial(stage_interval) * remainingpercent) //intervals get faster as people die
loot_interval = min(stage_interval / 2, initial(loot_interval)) //loot spawns faster as more die, but won't ever take longer than base
- loot_deviation = loot_interval / 2 //less deviation as time goes on
- if(borderstage == 8)//final collapse takes the full time but still spawns loot faster
+ if(borderstage == 9)//final collapse takes the full time but still spawns loot faster
stage_interval = initial(stage_interval)
addtimer(CALLBACK(src, PROC_REF(shrinkborders)), stage_interval)
@@ -251,20 +257,32 @@ GLOBAL_VAR(stormdamage)
message_admins("battle royale loot drop lists have been depleted somehow, PANIC")
/datum/game_mode/fortnite/proc/loot_drop()
- loot_spawn(1)
- var/nextdelay = loot_interval + (rand(1, loot_deviation * 2) - loot_deviation)
- addtimer(CALLBACK(src, PROC_REF(loot_drop)), nextdelay)//literally just keep calling it
+ loot_spawn()
+ addtimer(CALLBACK(src, PROC_REF(loot_drop)), loot_interval)//literally just keep calling it
-/datum/game_mode/fortnite/proc/loot_spawn(amount = 3)
- for(var/obj/effect/landmark/event_spawn/es in GLOB.landmarks_list)
- var/area/AR = get_area(es)
+/datum/game_mode/fortnite/proc/loot_spawn()
+ for(var/area/lootlake as anything in GLOB.areas)
+ if(!is_station_level(lootlake.z))//don't spawn it if it isn't a station level
+ continue
+ if(istype(lootlake, /area/space))//no nearspace
+ continue
+ if(istype(lootlake, /area/solar))//no solars
+ continue
+ if(istype(lootlake, /area/maintenance))//no maintenance, it's too large, it'd lag the hell out of the server and it's not as popular as main hallways
+ continue //also, ideally keeps people out of maints, and in larger open areas that are more interesting
+ var/amount = round(LAZYLEN(lootlake.get_contained_turfs()) / 40)//so bigger areas spawn more crates
for(var/I = 0, I < amount, I++)
- var/turf/turfy = pick(get_area_turfs(AR))
- while(turfy.density)//so it doesn't spawn inside walls
- turfy = pick(get_area_turfs(AR))
- var/obj/structure/closet/supplypod/centcompod/pod = new()
- new /obj/structure/closet/crate/battleroyale(pod)
- new /obj/effect/DPtarget(turfy, pod)
+ var/turf/turfy = pick(get_area_turfs(lootlake))
+ for(var/L = 0, L < 15, L++)//cap so it doesn't somehow end in an infinite loop
+ if(!turfy.density)//so it doesn't spawn inside walls
+ break
+ turfy = pick(get_area_turfs(lootlake))
+ addtimer(CALLBACK(src, PROC_REF(drop_pod), turfy), rand(1,50))//to even out the lag that creating a drop pod causes
+
+/datum/game_mode/fortnite/proc/drop_pod(turf/turfy)
+ var/obj/structure/closet/supplypod/centcompod/pod = new()
+ new /obj/structure/closet/crate/battleroyale(pod)
+ new /obj/effect/DPtarget(turfy, pod)
//Antag and items
/datum/antagonist/battleroyale
diff --git a/yogstation/code/game/gamemodes/battle_royale/loot.dm b/yogstation/code/game/gamemodes/battle_royale/loot.dm
index ed5f034d0beb..a949edca50c4 100644
--- a/yogstation/code/game/gamemodes/battle_royale/loot.dm
+++ b/yogstation/code/game/gamemodes/battle_royale/loot.dm
@@ -165,7 +165,7 @@ GLOBAL_LIST_INIT(battleroyale_weapon, list(
/obj/item/melee/baseball_bat/homerun = 1,
/obj/item/fireaxe = 1,
/obj/item/nullrod/talking = 1,
- /obj/item/melee/powerfist/filled = 1,
+ /obj/item/clothing/gloves/powerfist/filled = 1,
/obj/item/melee/vxtvulhammer = 0,
/obj/item/gun/ballistic/automatic/pistol = 0,
@@ -310,7 +310,6 @@ GLOBAL_LIST_INIT(battleroyale_utility, list(//bombs, explosives, anything that's
/obj/effect/spawner/lootdrop/stronggene = -3,
/obj/item/gun/magic/wand/resurrection = -3, //the person revived isn't able to win, but why not, maybe they help
/obj/item/antag_spawner/contract = -3, //might be a terrible idea to add this
- /obj/item/scrying = -3, //info, but leaves you open to attack
/obj/item/battleroyale/extraarm = -3,
/obj/item/guardiancreator/tech/random = -4,
@@ -339,7 +338,7 @@ GLOBAL_LIST_INIT(battleroyale_utility, list(//bombs, explosives, anything that's
/obj/structure/closet/crate/battleroyale
name = "Supply Crate"
icon_state = "trashcart"
- light_range = 10
+ light_range = 5
light_color = LIGHT_COLOR_YELLOW //Let it glow, let it glow
dense_when_open = FALSE
@@ -399,8 +398,8 @@ GLOBAL_LIST_INIT(battleroyale_utility, list(//bombs, explosives, anything that's
selected = pickweightAllowZero(GLOB.battleroyale_healing)
new selected(src)
- if(prob(0.1)) //0.1% chance of being clowned, probably won't see it every round
- for(var/i = 0, i < 5, i++)
+ if(rand(0, 10000) == 1)
+ for(var/i = 0, i < 10, i++)
new /mob/living/simple_animal/hostile/retaliate/clown(src)// you've been clowned
/obj/structure/closet/crate/battleroyale/proc/declutter()
diff --git a/yogstation/code/game/gamemodes/battle_royale/storm.dm b/yogstation/code/game/gamemodes/battle_royale/storm.dm
index 6acbf7e3d30b..0c34a168b2d5 100644
--- a/yogstation/code/game/gamemodes/battle_royale/storm.dm
+++ b/yogstation/code/game/gamemodes/battle_royale/storm.dm
@@ -53,17 +53,17 @@
/datum/weather/royale/security
name = "royale security" //North wave, takes out security, EVA, dorms and associated areas.
- telegraph_message = span_narsiesmall("The storm is closing in, get away from security and controlled areas! ")
+ telegraph_message = span_narsiesmall("The storm is closing in, get away from security! ")
areasToWeather = list(/area/crew_quarters/heads/hos)
- areaTypesToWeather = list(/area/security, /area/ai_monitored, /area/lawoffice)
+ areaTypesToWeather = list(/area/security, /area/lawoffice)
areaIgnore = list(/area/security/checkpoint/science, /area/security/checkpoint/engineering, //ignore all department security offices
- /area/security/checkpoint/medical, /area/security/checkpoint/supply)
+ /area/security/checkpoint/medical, /area/security/checkpoint/supply, /area/ai_monitored/security/armory)
/datum/weather/royale/science
name = "royale science" //takes out science
telegraph_message = span_narsiesmall("The storm is closing in, get away from science! ")
areasToWeather = list(/area/crew_quarters/heads/hor, /area/security/checkpoint/science)
- areaTypesToWeather = list(/area/science)
+ areaTypesToWeather = list(/area/science, /area/ai_monitored)
/datum/weather/royale/engineering
name = "royale engineering" //takes out engineering and atmos
@@ -91,11 +91,23 @@
areasToWeather = list(/area/security/checkpoint/supply)
areaTypesToWeather = list(/area/quartermaster, /area/vacant_room, /area/shuttle)
-/datum/weather/royale/hallway//
+/datum/weather/royale/bridge
+ name = "royale bridge"
+ telegraph_message = span_narsiesmall("The storm is closing in, get away from the bridge! ")
+ areasToWeather = list(/area/teleporter, /area/crew_quarters/heads/captain, /area/crew_quarters/heads/hop)
+ areaTypesToWeather = list(/area/bridge)
+
+/datum/weather/royale/hallway
name = "royale hallway"
+ telegraph_duration = 30 SECONDS //hallway's a bit bigger
telegraph_message = span_narsiesmall("The storm is closing in, get out of the hallways! ")
areaTypesToWeather = list(/area/hallway)
-/datum/weather/royale/six
+/datum/weather/royale/hallway/telegraph() //message changes depending on which one is left
+ if(GLOB.final_zone)
+ telegraph_message = span_narsiesmall("The storm is closing in, it all ends in [GLOB.final_zone]! ")
+ . = ..()
+
+/datum/weather/royale/final
name = "royale centre" //final wave, takes out the centre ring.
telegraph_message = span_narsiesmall("The eye of the storm is closing, make your final stand! ")
diff --git a/yogstation/code/game/gamemodes/gangs/dominator.dm b/yogstation/code/game/gamemodes/gangs/dominator.dm
index d4b82ec6c01c..6faa286dc4c5 100644
--- a/yogstation/code/game/gamemodes/gangs/dominator.dm
+++ b/yogstation/code/game/gamemodes/gangs/dominator.dm
@@ -45,7 +45,7 @@
return ..()
/obj/machinery/dominator/emp_act(severity)
- gang.domination_time += 30
+ gang.domination_time += 3 * severity
..()
/obj/machinery/dominator/hulk_damage()
diff --git a/yogstation/code/game/gamemodes/infiltration/infiltration.dm b/yogstation/code/game/gamemodes/infiltration/infiltration.dm
index 829f852b3129..ea03343124e6 100644
--- a/yogstation/code/game/gamemodes/infiltration/infiltration.dm
+++ b/yogstation/code/game/gamemodes/infiltration/infiltration.dm
@@ -43,7 +43,7 @@
return ..()
/datum/game_mode/infiltration/generate_report() //make this less shit
- return "Reports show that the Syndicate is rounding up it's elite agents, possibly for a raid on a NanoTrasen-controlled station. Keep an eye out for unusual people."
+ return "Reports show that the Syndicate is rounding up it's elite agents, possibly for a raid on a Nanotrasen-controlled station. Keep an eye out for unusual people."
/datum/game_mode/infiltration/set_round_result()
..()
diff --git a/yogstation/code/game/gamemodes/vampire/vampire_powers.dm b/yogstation/code/game/gamemodes/vampire/vampire_powers.dm
index 448f5cd0fd55..51fc6874fdbe 100644
--- a/yogstation/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/yogstation/code/game/gamemodes/vampire/vampire_powers.dm
@@ -154,16 +154,17 @@
var/protection = T.get_eye_protection()
switch(protection)
- if(INFINITY)
- to_chat(user, span_vampirewarning("[T] is blind and is unaffected by your gaze!"))
- return FALSE
- if(INFINITY to 1)
- T.adjust_confusion(5 SECONDS)
- return TRUE
+
if(0)
to_chat(target, span_userdanger("You are paralyzed with fear!"))
to_chat(user, span_notice("You paralyze [T]."))
T.Stun(5 SECONDS)
+ if(1 to INFINITY)
+ T.adjust_confusion(5 SECONDS)
+ return TRUE
+ if(INFINITY)
+ to_chat(user, span_vampirewarning("[T] is blind and is unaffected by your gaze!"))
+ return FALSE
return TRUE
@@ -214,12 +215,12 @@
var/protection = T.get_eye_protection()
var/sleep_duration = 30 SECONDS
switch(protection)
+ if(1 to INFINITY)
+ to_chat(user, span_vampirewarning("Your hypnotic powers are dampened by [T]'s eye protection."))
+ sleep_duration = 10 SECONDS
if(INFINITY)
to_chat(user, span_vampirewarning("[T] is blind and is unaffected by hypnosis!"))
return FALSE
- if(INFINITY to 1)
- to_chat(user, span_vampirewarning("Your hypnotic powers are dampened by [T]'s eye protection."))
- sleep_duration = 10 SECONDS
to_chat(T, span_boldwarning("Your knees suddenly feel heavy. Your body begins to sink to the floor."))
to_chat(user, span_notice("[T] is now under your spell. In four seconds they will be rendered unconscious as long as they are within close range."))
diff --git a/yogstation/code/game/machinery/computer/atmos_sim.dm b/yogstation/code/game/machinery/computer/atmos_sim.dm
index bd540168828b..acaeff6fac01 100644
--- a/yogstation/code/game/machinery/computer/atmos_sim.dm
+++ b/yogstation/code/game/machinery/computer/atmos_sim.dm
@@ -9,13 +9,17 @@
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/atmos_sim
var/mode = 2
- var/datum/gas_mixture/tank_mix = new
- var/datum/gas_mixture/bomb_1 = new
- var/datum/gas_mixture/bomb_2 = new
- var/datum/gas_mixture/bomb_result = new
+ var/datum/gas_mixture/tank_mix
+ var/datum/gas_mixture/bomb_1
+ var/datum/gas_mixture/bomb_2
+ var/datum/gas_mixture/bomb_result
var/list/bomb_explosion_size = null
/obj/machinery/computer/atmos_sim/Initialize(mapload)
+ tank_mix = new
+ bomb_1 = new
+ bomb_2 = new
+ bomb_result = new
tank_mix.set_temperature(T20C)
tank_mix.set_volume(CELL_VOLUME)
bomb_1.set_temperature(70)
@@ -26,7 +30,7 @@
/obj/machinery/computer/atmos_sim/proc/simulate_bomb()
bomb_explosion_size = null
- bomb_result = new /datum/gas_mixture()
+ bomb_result.clear()
bomb_result.set_volume(bomb_1.return_volume() + bomb_2.return_volume())
bomb_result.merge(bomb_1)
bomb_result.merge(bomb_2)
@@ -79,16 +83,16 @@
dat += "Volume: [mix.return_volume()] L Temp: [mix.return_temperature()] K "
else
dat += "Volume: [mix.return_volume()] L Temp: [mix.return_temperature()] K "
- for(var/id in (mix_id ? GLOB.meta_gas_info : mix.get_gases()))
+ for(var/id in (mix_id ? GLOB.gas_data.ids : mix.get_gases()))
var/list/moles = mix.get_moles(id)
dat += ""
if(mix_id)
dat += "X "
- dat += "[GLOB.meta_gas_info[id][META_GAS_NAME]] "
+ dat += "[GLOB.gas_data.names[id]] "
dat += "[moles] moles "
dat += "[moles * R_IDEAL_GAS_EQUATION * mix.return_temperature() / mix.return_volume()] kPa "
else
- dat += "[GLOB.meta_gas_info[id][META_GAS_NAME]] "
+ dat += "[GLOB.gas_data.names[id]] "
dat += "[moles] moles "
dat += "[moles * R_IDEAL_GAS_EQUATION * mix.return_temperature() / mix.return_volume()] kPa "
dat += " "
@@ -98,20 +102,20 @@
/obj/machinery/computer/atmos_sim/proc/gas_topic(datum/gas_mixture/mix, href_list)
if(href_list["delete_gas"])
- var/id = text2path(href_list["delete_gas"])
- if(GLOB.meta_gas_info[id])
- mix.set_moles(id, text2path(href_list["delete_gas"]))
+ var/id = href_list["delete_gas"]
+ if(id in GLOB.gas_data.ids)
+ mix.set_moles(id, href_list["delete_gas"])
if(href_list["change_moles"])
- var/id = text2path(href_list["change_moles"])
- if(GLOB.meta_gas_info[id])
- var/new_moles = input(usr, "Enter a new mole count for [GLOB.meta_gas_info[id][META_GAS_NAME]]", name) as null|num
+ var/id = href_list["change_moles"]
+ if(id in GLOB.gas_data.ids)
+ var/new_moles = input(usr, "Enter a new mole count for [GLOB.gas_data.names[id]]", name) as null|num
if(!src || !usr || !usr.canUseTopic(src) || stat || QDELETED(src) || new_moles == null)
return
mix.set_moles(id, new_moles)
if(href_list["change_pressure"])
- var/id = text2path(href_list["change_pressure"])
- if(GLOB.meta_gas_info[id])
- var/new_pressure = input(usr, "Enter a new pressure for [GLOB.meta_gas_info[id][META_GAS_NAME]]", name) as null|num
+ var/id = href_list["change_pressure"]
+ if(id in GLOB.gas_data.ids)
+ var/new_pressure = input(usr, "Enter a new pressure for [GLOB.gas_data.names[id]]", name) as null|num
if(!src || !usr || !usr.canUseTopic(src) || stat || QDELETED(src) || new_pressure == null)
return
mix.set_moles(id, new_pressure / R_IDEAL_GAS_EQUATION / mix.return_temperature() * mix.return_volume())
diff --git a/yogstation/code/game/machinery/doors/poddoor.dm b/yogstation/code/game/machinery/doors/poddoor.dm
index 22b1f3a9b15f..d0d4d074a034 100644
--- a/yogstation/code/game/machinery/doors/poddoor.dm
+++ b/yogstation/code/game/machinery/doors/poddoor.dm
@@ -3,30 +3,30 @@
layer = CLOSED_DOOR_LAYER
closingLayer = CLOSED_DOOR_LAYER
-/obj/machinery/door/poddoor/multi_tile/New()
+/obj/machinery/door/poddoor/multi_tile/Initialize(mapload)
. = ..()
apply_opacity_to_my_turfs(opacity)
+/obj/machinery/door/poddoor/multi_tile/Destroy(force=FALSE)
+ apply_opacity_to_my_turfs(0)
+ return ..()
+
/obj/machinery/door/poddoor/multi_tile/open()
- if(..())
+ . = ..()
+ if(.)
apply_opacity_to_my_turfs(opacity)
-
/obj/machinery/door/poddoor/multi_tile/close()
- if(..())
+ . = ..()
+ if(.)
apply_opacity_to_my_turfs(opacity)
-/obj/machinery/door/poddoor/multi_tile/Destroy()
- apply_opacity_to_my_turfs(0)
- return ..()
-
//Multi-tile poddoors don't turn invisible automatically, so we change the opacity of the turfs below instead one by one.
/obj/machinery/door/poddoor/multi_tile/proc/apply_opacity_to_my_turfs(new_opacity)
for(var/turf/T in locs)
- T.opacity = new_opacity
- T.has_opaque_atom = new_opacity
+ T.set_opacity(new_opacity)
T.reconsider_lights()
- T.air_update_turf(1)
+ T.air_update_turf()
update_freelook_sight()
/obj/machinery/door/poddoor/multi_tile/four_tile_ver/
diff --git a/yogstation/code/game/machinery/doors/spacepod.dm b/yogstation/code/game/machinery/doors/spacepod.dm
index 9e60ddc53067..b4afa71809c1 100644
--- a/yogstation/code/game/machinery/doors/spacepod.dm
+++ b/yogstation/code/game/machinery/doors/spacepod.dm
@@ -9,11 +9,12 @@
CanAtmosPass = ATMOS_PASS_NO
/obj/structure/spacepoddoor/Initialize(mapload)
- air_update_turf(1)
+ air_update_turf()
return ..()
/obj/structure/spacepoddoor/Destroy()
- air_update_turf(1)
+ CanAtmosPass = ATMOS_PASS_YES
+ air_update_turf()
return ..()
/obj/structure/spacepoddoor/CanAllowThrough(atom/movable/A)
diff --git a/yogstation/code/game/objects/effects/landmarks.dm b/yogstation/code/game/objects/effects/landmarks.dm
index 1a38df81d2cb..7d6b247ac411 100644
--- a/yogstation/code/game/objects/effects/landmarks.dm
+++ b/yogstation/code/game/objects/effects/landmarks.dm
@@ -143,6 +143,10 @@ GLOBAL_LIST_EMPTY(chosen_station_templates)
/obj/effect/landmark/stationroom/box/chapel
template_names = list("Chapel 1", "Chapel 2")
+/obj/effect/landmark/stationroom/box/chapel/load(template_name)
+ GLOB.stationroom_landmarks -= src
+ return TRUE
+
/obj/effect/landmark/stationroom/meta/engine
template_names = list("Meta SM" = 25, "Meta Nuclear Reactor" = 75) // tesla is loud as fuck and singulo doesn't make sense, so SM/reactor only
diff --git a/yogstation/code/game/objects/items/fishing/rods.dm b/yogstation/code/game/objects/items/fishing/rods.dm
index 80a4c449a9ba..feb46a3fb41c 100644
--- a/yogstation/code/game/objects/items/fishing/rods.dm
+++ b/yogstation/code/game/objects/items/fishing/rods.dm
@@ -23,9 +23,7 @@
/obj/item/fishingrod/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/two_handed, \
- force_unwielded = 2, \
- )
+ AddComponent(/datum/component/two_handed)
/obj/item/fishingrod/examine(mob/user)
. = ..()
diff --git a/yogstation/code/game/objects/items/implants/implant_dusting.dm b/yogstation/code/game/objects/items/implants/implant_dusting.dm
index 921bfbc83c64..23c396df37ff 100644
--- a/yogstation/code/game/objects/items/implants/implant_dusting.dm
+++ b/yogstation/code/game/objects/items/implants/implant_dusting.dm
@@ -45,6 +45,7 @@
/obj/item/implant/dusting/iaa
var/defused = FALSE // For safe removal, admin-only
+ var/reward_type = /obj/item/iaa_reward
/obj/item/implant/dusting/iaa/removed(mob/living/source, silent, special)
if(!defused)
@@ -57,7 +58,7 @@
return
. = ..()
var/turf/my_turf = get_turf(src)
- var/obj/item/iaa_reward/drop = new(my_turf)
+ var/obj/item/drop = new reward_type(my_turf)
if(imp_in)
drop.desc = "A syndicate 'dog tag' with an inscription that reads [imp_in.real_name]. Seems like it would be a bad idea to let someone evil press this."
@@ -131,3 +132,19 @@
qdel(src)
else
to_chat(user, span_notice("\The [src] doesn't seem to do anything."))
+
+//fake one for pseudocider
+/obj/item/implant/dusting/iaa/fake
+ reward_type = /obj/item/iaa_reward_fake
+
+/obj/item/iaa_reward_fake
+ name = "syndicate button"
+ desc = "A syndicate 'dog tag' with an unreadable inscription. Seems like it would be a bad idea to let someone evil press this."
+ icon = 'icons/obj/assemblies.dmi'
+ icon_state = "bigred"
+ item_state = "electronic"
+ resistance_flags = INDESTRUCTIBLE // no cremation cheese!
+
+/obj/item/iaa_reward_fake/Initialize(mapload)
+ . = ..()
+ QDEL_IN(src, 7 SECONDS)
diff --git a/yogstation/code/game/objects/items/toys.dm b/yogstation/code/game/objects/items/toys.dm
index 575edfddcd65..69e6e04e25b0 100644
--- a/yogstation/code/game/objects/items/toys.dm
+++ b/yogstation/code/game/objects/items/toys.dm
@@ -50,18 +50,32 @@
force = 0
throw_speed = 0.5
throw_range = 10
+ var/mob/living/carbon/man_down_under
+ var/returning = FALSE
-/obj/item/toy/boomerang/throw_impact(atom/hit_atom,)
+/obj/item/toy/boomerang/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscarbon(src.loc)) //Did someone catch it?
return ..()
- throw_at(thrownby, throw_range+3, throw_speed, null)
- ..()
+ if(man_down_under && hit_atom == man_down_under)
+ if(man_down_under.put_in_hands(src))
+ return
+ else
+ return ..()
+ . = ..()
+ if(man_down_under && returning)
+ returning = FALSE //only try to return once
+ if(get_turf(src) == get_turf(man_down_under))//don't try to return if the tile it hit is literally under the thrower
+ return
+ addtimer(CALLBACK(src, PROC_REF(comeback)), 1, TIMER_UNIQUE)//delay the return by such a small amount
+
+/obj/item/toy/boomerang/proc/comeback()
+ throw_at(man_down_under, throw_range+3, throw_speed)
/obj/item/toy/boomerang/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, quickstart = TRUE)
- if(iscarbon(thrower))
- var/mob/living/carbon/C = thrower
- C.throw_mode_on()
- ..()
+ if(thrower && iscarbon(thrower))
+ man_down_under = thrower
+ returning = TRUE
+ . = ..()
/obj/item/toy/frisbee
name = "frisbee"
diff --git a/yogstation/code/game/objects/items/wielded/big_spoon.dm b/yogstation/code/game/objects/items/wielded/big_spoon.dm
index 15f32f5f9bf4..107bce062e96 100644
--- a/yogstation/code/game/objects/items/wielded/big_spoon.dm
+++ b/yogstation/code/game/objects/items/wielded/big_spoon.dm
@@ -24,7 +24,6 @@
/obj/item/bigspoon/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = 2, \
force_wielded = 16, \
wield_callback = CALLBACK(src, PROC_REF(on_wield)), \
unwield_callback = CALLBACK(src, PROC_REF(on_unwield)), \
diff --git a/yogstation/code/game/objects/items/wielded/sledgehammer.dm b/yogstation/code/game/objects/items/wielded/sledgehammer.dm
index 490d1337a755..9101954a7a3d 100644
--- a/yogstation/code/game/objects/items/wielded/sledgehammer.dm
+++ b/yogstation/code/game/objects/items/wielded/sledgehammer.dm
@@ -14,6 +14,7 @@
throwforce = 18
throw_range = 3 /// Doesn't throw very far
sharpness = SHARP_NONE
+ demolition_mod = 3 // BREAK THINGS
armour_penetration = -20
hitsound = 'sound/weapons/smash.ogg' /// Hitsound when thrown at someone
attack_verb = list("attacked", "hit", "struck", "bludgeoned", "bashed", "smashed")
@@ -26,8 +27,7 @@
/obj/item/melee/sledgehammer/Initialize(mapload)
. = ..()
AddComponent(/datum/component/two_handed, \
- force_unwielded = 3, \
- force_wielded = 18, \
+ force_wielded = 15, \
wield_callback = CALLBACK(src, PROC_REF(on_wield)), \
unwield_callback = CALLBACK(src, PROC_REF(on_unwield)), \
require_twohands = TRUE, \
@@ -55,8 +55,6 @@
var/obj/structure/S = target
if(istype(S, /obj/structure/window)) // Sledgehammer really good at smashing windows. 2-7 hits to kill a window
S.take_damage(S.max_integrity/2, BRUTE, MELEE, FALSE, null, armour_penetration)
- else // Sledgehammer can kill airlocks in 17-23 hits, against most other things it's almost as good as a fireaxe
- S.take_damage(force*2, BRUTE, MELEE, FALSE, null, armour_penetration)
playsound(src, 'sound/effects/bang.ogg', 50, 1)
/obj/item/melee/sledgehammer/throw_at(atom/target, range, speed, mob/thrower, spin, diagonals_first, datum/callback/callback, force, quickstart)
diff --git a/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm b/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm
index 321567109e07..b5e709874d34 100644
--- a/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm
+++ b/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm
@@ -11,6 +11,7 @@
desc = "A relic sledgehammer with charge packs wired to two blast pads on its head. \
While wielded in two hands, the user can charge a massive blow that will shatter construction and hurl bodies."
force = 4 //It's heavy as hell
+ demolition_mod = 3 // it's a big hammer, what do you expect
armour_penetration = 50 //Designed for shattering walls in a single blow, I don't think it cares much about armor
throwforce = 18
attack_verb = list("attacked", "hit", "struck", "bludgeoned", "bashed", "smashed")
@@ -42,7 +43,6 @@
spark_system.attach(src)
set_light_on(FALSE)
AddComponent(/datum/component/two_handed, \
- force_unwielded = force, \
force_wielded = force_wielded, \
unwield_callback = CALLBACK(src, PROC_REF(on_unwield)), \
)
diff --git a/yogstation/code/modules/admin/verbs/fix_air.dm b/yogstation/code/modules/admin/verbs/fix_air.dm
index 30b1249b71af..1dc8e1fe6f8f 100644
--- a/yogstation/code/modules/admin/verbs/fix_air.dm
+++ b/yogstation/code/modules/admin/verbs/fix_air.dm
@@ -17,7 +17,6 @@
continue
GM.parse_gas_string(F.initial_gas_mix)
F.copy_air(GM)
- F.update_visuals()
/client/proc/fix_air_z()
set name = "Fix Air on current Z-level"
@@ -27,7 +26,7 @@
if(!holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE)
return
- if(!check_rights(R_ADMIN))
+ if(!check_rights(R_ADMIN, 1))
return
if(Master.current_runlevel < log(2, RUNLEVEL_GAME) + 1)
@@ -41,6 +40,7 @@
message_admins("[key_name_admin(usr)] fixed air on zlevel [mob.z]")
log_game("[key_name_admin(usr)] fixed air on zlevel [mob.z]")
+ SSair.can_fire = 0
var/z = mob.z
for(var/x=1, x<=world.maxx, x++)
for(var/y=1, y<=world.maxy, y++)
@@ -48,6 +48,34 @@
var/turf/open/T = locate(x, y, z)
//Not an early return to allow check_tick to do its thing
//Verfied to be an open turf here
- if(!istype(T, /turf/open/space) && T.is_openturf && !T.blocks_air)
+ if(!istype(T, /turf/open/space) && !T.blocks_air)
T.air?.parse_gas_string(T.initial_gas_mix)
- T.update_visuals()
+ SSair.can_fire = 1
+
+/client/proc/clear_all_pipenets()
+ set name = "Empties all gases from pipenets"
+ set category = "Misc.Unused"
+ set desc = "Empties all gases from pipenets, temporarily disables atmos"
+
+ if(!holder)
+ to_chat(src, "Only administrators may use this command.", confidential=TRUE)
+ return
+ if(!check_rights(R_ADMIN, 1))
+ return
+
+ if(Master.current_runlevel < log(2, RUNLEVEL_GAME) + 1)
+ to_chat(src, "This command may not be used before the game has started!", confidential=TRUE)
+ message_admins("[src] has attempted to clear pipenets before the game has started.")
+ return
+
+ if(alert("Do you want to clear ALL pipenets?", "Clear all pipenets", "No", "Yes") != "Yes")
+ return
+
+ message_admins("[key_name_admin(usr)] cleared all pipenets")
+ log_game("[key_name_admin(usr)] cleared all pipenets")
+
+ SSair.can_fire = 0
+ for(var/datum/pipeline/pipenetwork in SSair.networks)
+ pipenetwork.empty()
+ SSair.can_fire = 1
+
diff --git a/yogstation/code/modules/antagonists/shadowling/shadowling_abilities.dm b/yogstation/code/modules/antagonists/shadowling/shadowling_abilities.dm
index db2087d4c817..4990a34d07d3 100644
--- a/yogstation/code/modules/antagonists/shadowling/shadowling_abilities.dm
+++ b/yogstation/code/modules/antagonists/shadowling/shadowling_abilities.dm
@@ -136,12 +136,12 @@
var/mob/living/carbon/M = H
var/datum/mutation/human/glow/G = M.dna.get_mutation(GLOWY)
if(G)
- G.glowth.set_light(0, 0) // Set glowy to no light
+ G.glow.set_light_range_power_color(range = 0, power = 0) // Set glowy to no light
if(G.current_nullify_timer)
deltimer(G.current_nullify_timer) // Stacks
- G.current_nullify_timer = addtimer(CALLBACK(src, PROC_REF(giveGlowyBack), M), 40 SECONDS, TIMER_STOPPABLE)
+ G.current_nullify_timer = addtimer(CALLBACK(src, PROC_REF(give_glow_back), M), 40 SECONDS, TIMER_STOPPABLE)
-/datum/action/cooldown/spell/aoe/proc/giveGlowyBack(mob/living/carbon/M)
+/datum/action/cooldown/spell/aoe/proc/give_glow_back(mob/living/carbon/M)
if(!M)
return
var/datum/mutation/human/glow/G = M.dna.get_mutation(GLOWY)
diff --git a/yogstation/code/modules/antagonists/traitor/datum_traitor.dm b/yogstation/code/modules/antagonists/traitor/datum_traitor.dm
deleted file mode 100644
index 9de14d0e5974..000000000000
--- a/yogstation/code/modules/antagonists/traitor/datum_traitor.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/datum/antagonist/traitor
- var/obj/item/uplink_holder
\ No newline at end of file
diff --git a/yogstation/code/modules/atmospherics/airalarm.dm b/yogstation/code/modules/atmospherics/airalarm.dm
index 2c01d31c3e99..4eb975e54ef0 100644
--- a/yogstation/code/modules/atmospherics/airalarm.dm
+++ b/yogstation/code/modules/atmospherics/airalarm.dm
@@ -5,16 +5,16 @@
TLV = list( // This is the list provided by obj machinery airalarm server. No checks, apparently.
"pressure" = new/datum/tlv/no_checks,
"temperature" = new/datum/tlv/no_checks,
- /datum/gas/oxygen = new/datum/tlv/no_checks,
- /datum/gas/nitrogen = new/datum/tlv/no_checks,
- /datum/gas/carbon_dioxide = new/datum/tlv/no_checks,
- /datum/gas/miasma = new/datum/tlv/no_checks,
- /datum/gas/plasma = new/datum/tlv/no_checks,
- /datum/gas/nitrous_oxide = new/datum/tlv/no_checks,
- /datum/gas/bz = new/datum/tlv/no_checks,
- /datum/gas/hypernoblium = new/datum/tlv/no_checks,
- /datum/gas/water_vapor = new/datum/tlv/no_checks,
- /datum/gas/tritium = new/datum/tlv/no_checks,
- /datum/gas/nitrium = new/datum/tlv/no_checks,
- /datum/gas/pluoxium = new/datum/tlv/no_checks,
+ GAS_O2 = new/datum/tlv/no_checks,
+ GAS_N2 = new/datum/tlv/no_checks,
+ GAS_CO2 = new/datum/tlv/no_checks,
+ GAS_MIASMA = new/datum/tlv/no_checks,
+ GAS_PLASMA = new/datum/tlv/no_checks,
+ GAS_NITROUS = new/datum/tlv/no_checks,
+ GAS_BZ = new/datum/tlv/no_checks,
+ GAS_HYPERNOB = new/datum/tlv/no_checks,
+ GAS_H2O = new/datum/tlv/no_checks,
+ GAS_TRITIUM = new/datum/tlv/no_checks,
+ GAS_NITRIUM = new/datum/tlv/no_checks,
+ GAS_PLUOXIUM = new/datum/tlv/no_checks
)
diff --git a/yogstation/code/modules/atmospherics/gasmixtures/gas_types.dm b/yogstation/code/modules/atmospherics/gasmixtures/gas_types.dm
deleted file mode 100644
index 6db37a02ae2b..000000000000
--- a/yogstation/code/modules/atmospherics/gasmixtures/gas_types.dm
+++ /dev/null
@@ -1,6 +0,0 @@
-/datum/gas/dilithium // Main point is that this helps fusion occur at a significantly lower temperature than normal
- id = "dilithium"
- specific_heat = 55
- name = "Dilithium"
- fusion_power = 1
- rarity = 350
diff --git a/yogstation/code/modules/atmospherics/machinery/pipes/bluespace.dm b/yogstation/code/modules/atmospherics/machinery/pipes/bluespace.dm
index 1487e1ad519a..8975aaba2ce2 100644
--- a/yogstation/code/modules/atmospherics/machinery/pipes/bluespace.dm
+++ b/yogstation/code/modules/atmospherics/machinery/pipes/bluespace.dm
@@ -33,14 +33,14 @@ GLOBAL_LIST_EMPTY(bluespace_pipe_networks)
for(var/p in GLOB.bluespace_pipe_networks[bluespace_network_name])
var/obj/machinery/atmospherics/pipe/bluespace/P = p
QDEL_NULL(P.parent)
- P.build_network()
+ SSair.add_to_rebuild_queue(P)
return ..()
/obj/machinery/atmospherics/pipe/bluespace/examine(user)
. = ..()
. += span_notice("This one is connected to the \"[html_encode(bluespace_network_name)]\" network.")
-/obj/machinery/atmospherics/pipe/bluespace/SetInitDirections()
+/obj/machinery/atmospherics/pipe/bluespace/set_init_directions()
initialize_directions = dir
/obj/machinery/atmospherics/pipe/bluespace/pipeline_expansion()
@@ -77,6 +77,6 @@ GLOBAL_LIST_EMPTY(bluespace_pipe_networks)
/obj/machinery/atmospherics/pipe/bluespace/proc/get_pipe_underlay(state, dir, color = null)
if(color)
- . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, color)
+ . = get_pipe_image('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, color)
else
- . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir)
+ . = get_pipe_image('icons/obj/atmospherics/components/binary_devices.dmi', state, dir)
diff --git a/yogstation/code/modules/guardian/abilities/major/frenzy.dm b/yogstation/code/modules/guardian/abilities/major/frenzy.dm
index ee6ea2d5d06a..352286e83fd7 100644
--- a/yogstation/code/modules/guardian/abilities/major/frenzy.dm
+++ b/yogstation/code/modules/guardian/abilities/major/frenzy.dm
@@ -70,9 +70,17 @@ GLOBAL_LIST_INIT(guardian_frenzy_speedup, list(
return
if (!guardian.stats)
return
+ if(!guardian.stats.ability)
+ return
+ if (!istype(guardian.stats.ability, /datum/guardian_ability/major/frenzy))
+ return
+ var/datum/guardian_ability/major/frenzy/ability = guardian.stats.ability
+ if(world.time < ability.next_rush)
+ return
if (get_dist_euclidian(guardian.summoner?.current, target) > guardian.range)
to_chat(guardian, span_italics(span_danger("[target] is out of your range!")))
return
+
guardian.forceMove(get_step(get_turf(target), turn(target.dir, 180)))
playsound(guardian, 'yogstation/sound/effects/vector_appear.ogg', 100, FALSE)
guardian.target = target
@@ -81,4 +89,5 @@ GLOBAL_LIST_INIT(guardian_frenzy_speedup, list(
span_italics("You hear a fast wooosh."))
guardian.AttackingTarget()
target.throw_at(get_edge_target_turf(guardian, get_dir(guardian, target)), world.maxx / 6, 5, guardian, TRUE)
+ ability.next_rush = world.time + 3 SECONDS
Finished()
diff --git a/yogstation/code/modules/jobs/job_types/_job.dm b/yogstation/code/modules/jobs/job_types/_job.dm
index f97442bfc0d6..57f9a19ec9d7 100644
--- a/yogstation/code/modules/jobs/job_types/_job.dm
+++ b/yogstation/code/modules/jobs/job_types/_job.dm
@@ -205,3 +205,46 @@
message_admins("RUNTIME IN GIVE_CLERK_CHOICE")
spawn_clerk()
throw e
+
+
+
+/datum/job/proc/give_chapel_choice(mob/living/H, mob/M)
+ try
+ var/choice
+
+ var/client/C = M.client
+ if(!C)
+ C = H.client
+ if(!C)
+ choice = "Random"
+
+ if(C)
+ choice = C.prefs.read_preference(/datum/preference/choiced/chapel_choice)
+
+ if(choice != "Random")
+ var/chapel_sanitize = FALSE
+ for(var/A in GLOB.potential_box_chapels)
+ if(choice == A)
+ chapel_sanitize = TRUE
+ break
+
+ if(!chapel_sanitize)
+ choice = "Random"
+
+ if(choice == "Random")
+ choice = pick(GLOB.potential_box_chapels)
+
+ var/datum/map_template/template = SSmapping.station_room_templates[choice]
+
+ if(!template)
+ log_game("chapel FAILED TO LOAD!!! [C.ckey]/([M.name]) attempted to load [choice]. Loading chapel 1 as backup.")
+ message_admins("chapel FAILED TO LOAD!!! [C.ckey]/([M.name]) attempted to load [choice]. Loading chapel 1 as backup.")
+ template = SSmapping.station_room_templates["Chapel 1"]
+
+ for(var/obj/effect/landmark/stationroom/box/chapel/B in GLOB.landmarks_list)
+ template.load(B.loc, centered = FALSE)
+ qdel(B)
+ catch(var/exception/e)
+ message_admins("RUNTIME IN GIVE_CHAPEL_CHOICE")
+ spawn_chapel()
+ throw e
diff --git a/yogstation/code/modules/jobs/job_types/brig_physician.dm b/yogstation/code/modules/jobs/job_types/brig_physician.dm
index 5e295041ae86..e3d0bdf1eef4 100644
--- a/yogstation/code/modules/jobs/job_types/brig_physician.dm
+++ b/yogstation/code/modules/jobs/job_types/brig_physician.dm
@@ -23,7 +23,7 @@
/datum/job_department/security,
)
- added_access = list(ACCESS_SURGERY)
+ added_access = list(ACCESS_SURGERY, ACCESS_CLONING, ACCESS_EXTERNAL_AIRLOCKS)
base_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_BRIG, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MECH_MEDICAL, ACCESS_BRIG_PHYS)
paycheck = PAYCHECK_MEDIUM
paycheck_department = ACCOUNT_MED
diff --git a/yogstation/code/modules/jobs/job_types/mining_medic.dm b/yogstation/code/modules/jobs/job_types/mining_medic.dm
index 229d9a247f45..326c26a014f5 100644
--- a/yogstation/code/modules/jobs/job_types/mining_medic.dm
+++ b/yogstation/code/modules/jobs/job_types/mining_medic.dm
@@ -24,7 +24,8 @@
/datum/job_department/cargo,
)
- added_access = list(ACCESS_SURGERY, ACCESS_CARGO)
+ //if it's skeleton there's probably no paramedic to save spaced miners that jaunted away from danger
+ added_access = list(ACCESS_SURGERY, ACCESS_CARGO, ACCESS_CLONING, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS)
base_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM, ACCESS_MECH_MINING, ACCESS_MECH_MEDICAL)
paycheck = PAYCHECK_HARD
paycheck_department = ACCOUNT_MED
diff --git a/yogstation/code/modules/jobs/job_types/network_admin.dm b/yogstation/code/modules/jobs/job_types/network_admin.dm
index 3b28b2221c40..b84aac807a57 100644
--- a/yogstation/code/modules/jobs/job_types/network_admin.dm
+++ b/yogstation/code/modules/jobs/job_types/network_admin.dm
@@ -15,7 +15,7 @@
outfit = /datum/outfit/job/network_admin
added_access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_MAINT_TUNNELS)
- base_access = list(ACCESS_TCOMSAT, ACCESS_TCOM_ADMIN, ACCESS_TECH_STORAGE, ACCESS_RC_ANNOUNCE, ACCESS_CONSTRUCTION, ACCESS_MECH_ENGINE, ACCESS_NETWORK, ACCESS_RESEARCH, ACCESS_MINISAT)
+ base_access = list(ACCESS_TCOMSAT, ACCESS_TCOM_ADMIN, ACCESS_TECH_STORAGE, ACCESS_RC_ANNOUNCE, ACCESS_CONSTRUCTION, ACCESS_MECH_ENGINE, ACCESS_NETWORK, ACCESS_RESEARCH, ACCESS_MINISAT, ACCESS_RND)
paycheck = PAYCHECK_MEDIUM
paycheck_department = ACCOUNT_ENG
display_order = JOB_DISPLAY_ORDER_NETWORK_ADMIN
diff --git a/yogstation/code/modules/jobs/job_types/paramedic.dm b/yogstation/code/modules/jobs/job_types/paramedic.dm
index 8329a64e88a9..9f8d3fbd6cfb 100644
--- a/yogstation/code/modules/jobs/job_types/paramedic.dm
+++ b/yogstation/code/modules/jobs/job_types/paramedic.dm
@@ -12,7 +12,7 @@
outfit = /datum/outfit/job/paramedic
- added_access = list(ACCESS_CLONING)
+ added_access = list(ACCESS_SURGERY, ACCESS_CLONING)
base_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_PARAMEDIC, ACCESS_MECH_MEDICAL)
paycheck = PAYCHECK_MEDIUM
paycheck_department = ACCOUNT_MED
diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm
index 6e47fd34d5c7..86a321e42c10 100644
--- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm
+++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm
@@ -81,10 +81,16 @@
name = "preternis lungs"
desc = "A specialized set of lungs. Due to the cybernetic nature of these lungs, they are far less resistant to cold but are more heat resistant and more efficent at filtering oxygen."
icon_state = "lungs-c"
+
status = ORGAN_ROBOTIC
organ_flags = ORGAN_SYNTHETIC
- safe_oxygen_min = 12
- safe_toxins_max = 10
+ safe_breath_min = 12
+
+ gas_max = list(
+ GAS_CO2 = 30,
+ GAS_PLASMA = 10
+ )
+
gas_stimulation_min = 0.01 //fucking filters removing my stimulants
cold_level_1_threshold = 280 //almost room temperature
@@ -115,5 +121,5 @@
/obj/item/organ/stomach/cell/preternis/emp_act(severity)
owner.vomit(stun=FALSE) // fuck that
- owner.adjust_disgust(20)
+ owner.adjust_disgust(2*severity)
to_chat(owner, "You feel violently ill as the EMP causes your stomach to kick into high gear. ")
diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/power_suck.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/power_suck.dm
index 2cb2e827b9fb..b3c28f653baf 100644
--- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/power_suck.dm
+++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/power_suck.dm
@@ -31,15 +31,14 @@
draining = FALSE
return
- if(H.gloves)
- if(!H.gloves.siemens_coefficient)
- to_chat(H, span_info("NOTICE: [H.gloves] prevent electrical contact - CONSUME protocol aborted."))
- draining = FALSE
- return
- else
- if(H.gloves.siemens_coefficient < 1)
- to_chat(H, span_info("NOTICE: [H.gloves] are interfering with electrical contact - advise removal before activating CONSUME protocol."))
- siemens_coefficient *= H.gloves.siemens_coefficient
+ var/blocked = H.getarmor(H.held_index_to_body_zone(H.active_hand_index), ELECTRIC)
+ siemens_coefficient *= (100 - blocked) / 100
+ if(blocked >= 100)
+ to_chat(H, span_info("NOTICE: [H.gloves] prevent electrical contact - CONSUME protocol aborted."))
+ draining = FALSE
+ return
+ else if(blocked > 0)
+ to_chat(H, span_info("NOTICE: [H.gloves] are interfering with electrical contact - advise removal before activating CONSUME protocol."))
. = COMSIG_MOB_CANCEL_CLICKON
diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm
index c4f0096ded1f..867ae2aa24df 100644
--- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm
+++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm
@@ -3,7 +3,7 @@
plural_form = "Preterni"
id = "preternis"
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
- inherent_traits = list(TRAIT_POWERHUNGRY, TRAIT_RADIMMUNE, TRAIT_MEDICALIGNORE, TRAIT_FARADAYCAGE) //Faraday cage reduces incoming EMP severity by one level
+ inherent_traits = list(TRAIT_POWERHUNGRY, TRAIT_RADIMMUNE, TRAIT_MEDICALIGNORE)
species_traits = list(DYNCOLORS, EYECOLOR, HAIR, LIPS, AGENDER, NOHUSK, DIGITIGRADE)//they're fleshy metal machines, they are efficient, and the outside is metal, no getting husked
inherent_biotypes = MOB_ORGANIC|MOB_ROBOTIC|MOB_HUMANOID
sexes = FALSE //they're basically ken dolls, come straight out of a printer
@@ -47,7 +47,6 @@
var/lockdown = FALSE
var/eating_msg_cooldown = FALSE
var/emag_lvl = 0
- var/tesliumtrip = FALSE
var/draining = FALSE
var/soggy = FALSE
var/low_power_warning = FALSE
@@ -60,6 +59,7 @@
for (var/obj/item/bodypart/BP in C.bodyparts)
BP.render_like_organic = TRUE // Makes limbs render like organic limbs instead of augmented limbs, check bodyparts.dm
+ BP.emp_reduction = EMP_LIGHT
BP.burn_reduction = 2
BP.brute_reduction = 1
if(BP.body_zone == BODY_ZONE_CHEST)
@@ -80,6 +80,7 @@
for (var/V in C.bodyparts)
var/obj/item/bodypart/BP = V
BP.change_bodypart_status(ORGAN_ORGANIC,FALSE,TRUE)
+ BP.emp_reduction = initial(BP.emp_reduction)
BP.burn_reduction = initial(BP.burn_reduction)
BP.brute_reduction = initial(BP.brute_reduction)
@@ -87,7 +88,6 @@
C.clear_alert("preternis_emag") //this means a changeling can transform from and back to a preternis to clear the emag status but w/e i cant find a solution to not do that
C.clear_fullscreen("preternis_emag")
- C.remove_movespeed_modifier("preternis_teslium")
C.remove_movespeed_modifier("preternis_water")
C.remove_movespeed_modifier("preternis_maglock")
@@ -155,20 +155,7 @@
/datum/species/preternis/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
. = ..()
- if(H.reagents.has_reagent(/datum/reagent/teslium))
- H.add_movespeed_modifier("preternis_teslium", update=TRUE, priority=101, multiplicative_slowdown=-3, blacklisted_movetypes=(FLYING|FLOATING))
- H.adjustOxyLoss(-2*REAGENTS_EFFECT_MULTIPLIER)
- H.adjustBruteLoss(-2*REAGENTS_EFFECT_MULTIPLIER,FALSE,FALSE, BODYPART_ANY)
- H.adjustFireLoss(-2*REAGENTS_EFFECT_MULTIPLIER,FALSE,FALSE, BODYPART_ANY)
- H.AdjustParalyzed(-3)
- H.AdjustStun(-3)
- H.AdjustKnockdown(-3)
- H.adjustStaminaLoss(-5*REAGENTS_EFFECT_MULTIPLIER)
- H.adjust_nutrition(10 * REAGENTS_METABOLISM)//more power charges you, why would it drain you
- burnmod = 10
- tesliumtrip = TRUE
-
- if (istype(chem,/datum/reagent/consumable))
+ if (istype(chem,/datum/reagent/consumable) && !istype(chem, /datum/reagent/consumable/liquidelectricity))
var/datum/reagent/consumable/food = chem
if (food.nutriment_factor)
H.adjust_nutrition(food.nutriment_factor * 0.2)
@@ -177,8 +164,8 @@
addtimer(VARSET_CALLBACK(src, eating_msg_cooldown, FALSE), 2 MINUTES)
to_chat(H,span_info("NOTICE: Digestive subroutines are inefficient. Seek sustenance via power-cell C.O.N.S.U.M.E. technology induction."))
- if(chem.current_cycle >= 20)
- H.reagents.del_reagent(chem.type)
+ // remove 4% of existing reagent, minimum of 0.1 units at a time
+ H.reagents.remove_reagent(chem.type, max(round(chem.volume / 25, 0.1), 0.1))
return FALSE
@@ -187,9 +174,6 @@
emag_lvl = 0
H.clear_alert("preternis_emag")
H.clear_fullscreen("preternis_emag")
- burnmod = initial(burnmod)
- tesliumtrip = FALSE
- H.remove_movespeed_modifier("preternis_teslium") //full heal removes chems so it wont update the teslium speed up until they eat something
/datum/species/preternis/movement_delay(mob/living/carbon/human/H)
. = ..()
@@ -200,11 +184,6 @@
/datum/species/preternis/spec_life(mob/living/carbon/human/H)
. = ..()
- if(tesliumtrip && !H.reagents.has_reagent(/datum/reagent/teslium))//remove teslium effects if you don't have it in you
- burnmod = initial(burnmod)
- tesliumtrip = FALSE
- H.remove_movespeed_modifier("preternis_teslium")
-
if(H.stat == DEAD)
return
@@ -219,8 +198,9 @@
else
low_power_warning = FALSE
-/datum/species/preternis/proc/handle_wetness(mob/living/carbon/human/H)
- if(H.has_status_effect(/datum/status_effect/fire_handler/wet_stacks))
+/datum/species/preternis/proc/handle_wetness(mob/living/carbon/human/H)
+ var/datum/status_effect/fire_handler/wet_stacks/wetness = H.has_status_effect(/datum/status_effect/fire_handler/wet_stacks)
+ if(wetness && wetness.stacks >= 1) // needs at least 1 wetness stack to do anything
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "preternis_wet", /datum/mood_event/wet_preternis)
H.add_movespeed_modifier("preternis_water", update = TRUE, priority = 102, multiplicative_slowdown = 0.5, blacklisted_movetypes=(FLYING|FLOATING))
//damage has a flat amount with an additional amount based on how wet they are
@@ -316,6 +296,12 @@
var/list/to_add = list()
to_add += list(
+ list(
+ SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
+ SPECIES_PERK_ICON = "thunderstorm", //if we update font awesome, please swap to bolt-slash
+ SPECIES_PERK_NAME = "Faraday \"Skin\"",
+ SPECIES_PERK_DESC = "Preterni have an outer plasteel shell that can block low-intensity EM interference.",
+ ),
list(
SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK,
SPECIES_PERK_ICON = "cookie-bite",
diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm
index 9f12c8ccc5a8..ea83caace5f1 100644
--- a/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm
+++ b/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm
@@ -151,7 +151,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0)
return
-/mob/living/simple_animal/hostile/floor_cluwne/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE)//prevents runtimes with machine fuckery
+/mob/living/simple_animal/hostile/floor_cluwne/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, zone = null, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE, gib = FALSE)//prevents runtimes with machine fuckery
return FALSE
/mob/living/simple_animal/hostile/floor_cluwne/proc/Found_You()
@@ -356,7 +356,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0)
manifested = TRUE
Manifest()
if(!eating)
- empulse(src, 6, 6)
+ empulse(src, EMP_HEAVY, 6)
addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living/simple_animal/hostile/floor_cluwne, Grab), H), 50, TIMER_OVERRIDE|TIMER_UNIQUE)
for(var/turf/open/O in range(src, 6))
O.MakeSlippery(TURF_WET_LUBE, 30)
diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
index 557b9bdb4b4f..5661d84b28be 100644
--- a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
+++ b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm
@@ -214,7 +214,7 @@ Difficulty: Insanely Hard
else if(prob(5)) //EMP blast
spellscast++
visible_message(span_cult("\The [src] disrupts nearby electrical equipment!"))
- empulse(get_turf(src), 5, 2, 0)
+ empulse(get_turf(src), EMP_HEAVY)
else if(prob(5) && melee_damage_type == BRUTE && !special_attacks) //elemental attacks
spellscast++
diff --git a/yogstation/code/modules/spacepods/parts.dm b/yogstation/code/modules/spacepods/parts.dm
index d37c220ce8bc..18c739e5a242 100644
--- a/yogstation/code/modules/spacepods/parts.dm
+++ b/yogstation/code/modules/spacepods/parts.dm
@@ -159,14 +159,14 @@
/obj/item/pod_parts/armor/security
name = "security pod armor"
icon_state = "pod_armor_mil"
- desc = "Tough military-grade pod armor, meant for use by the NanoTrasen military and it's sub-divisons for space combat."
+ desc = "Tough military-grade pod armor, meant for use by the Nanotrasen military and it's sub-divisons for space combat."
pod_icon_state = "pod_mil"
pod_desc = "An armed security spacepod with reinforced armor plating brandishing the Nanotrasen Military insignia"
pod_integrity = 350
/obj/item/pod_parts/armor/security/red
name = "security pod armor"
icon_state = "pod_armor_synd"
- desc = "Tough military-grade pod armor, meant for use by the NanoTrasen military and it's sub-divisons for space combat."
+ desc = "Tough military-grade pod armor, meant for use by the Nanotrasen military and it's sub-divisons for space combat."
pod_icon_state = "pod_synd"
pod_desc = "An armed security spacepod with reinforced armor plating brandishing the Nanotrasen Military insignia"
pod_integrity = 350
diff --git a/yogstation/code/modules/spacepods/spacepod.dm b/yogstation/code/modules/spacepods/spacepod.dm
index 5e12e48dbacb..9fad31f3cc32 100644
--- a/yogstation/code/modules/spacepods/spacepod.dm
+++ b/yogstation/code/modules/spacepods/spacepod.dm
@@ -12,7 +12,7 @@ GLOBAL_LIST_INIT(spacepods_list, list())
icon = 'goon/icons/obj/spacepods/construction_2x2.dmi'
icon_state = "pod_1"
density = 1
- opacity = 0
+ opacity = FALSE
dir = NORTH // always points north because why not
layer = SPACEPOD_LAYER
bound_width = 64
@@ -85,10 +85,10 @@ GLOBAL_LIST_INIT(spacepods_list, list())
cabin_air = new
cabin_air.set_temperature(T20C)
cabin_air.set_volume(200)
- /*cabin_air.assert_gas(/datum/gas/oxygen)
- cabin_air.assert_gas(/datum/gas/nitrogen)
- cabin_air.gases[/datum/gas/oxygen][MOLES] = ONE_ATMOSPHERE*O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
- cabin_air.gases[/datum/gas/nitrogen][MOLES] = ONE_ATMOSPHERE*N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)*/
+ /*cabin_air.assert_gas(GAS_O2)
+ cabin_air.assert_gas(GAS_N2)
+ cabin_air.gases[GAS_O2][MOLES] = ONE_ATMOSPHERE*O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
+ cabin_air.gases[GAS_N2][MOLES] = ONE_ATMOSPHERE*N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)*/
/obj/spacepod/Destroy()
GLOB.spacepods_list -= src
diff --git a/yogstation/code/modules/surgery/organs/heart.dm b/yogstation/code/modules/surgery/organs/heart.dm
index 263fc0c63c2c..da98967b4da4 100644
--- a/yogstation/code/modules/surgery/organs/heart.dm
+++ b/yogstation/code/modules/surgery/organs/heart.dm
@@ -6,12 +6,6 @@
compatible_biotypes = ALL_BIOTYPES
var/nanite_boost = 1
-/obj/item/organ/heart/nanite/emp_act()
- . = ..()
- if(!owner || . & EMP_PROTECT_SELF)
- return .
- Stop()
-
/obj/item/organ/heart/nanite/on_life()
. = ..()
if(owner)//makes nanites tick on every life tick, only about 33% speed increase
diff --git a/yogstation/code/modules/surgery/organs/lungs.dm b/yogstation/code/modules/surgery/organs/lungs.dm
index fa86b9b51343..0c16efa996e1 100644
--- a/yogstation/code/modules/surgery/organs/lungs.dm
+++ b/yogstation/code/modules/surgery/organs/lungs.dm
@@ -4,8 +4,22 @@
icon = 'yogstation/icons/obj/surgery.dmi'
icon_state = "lungs-ash"
- safe_oxygen_min = 6 // adapted to the thinner atmosphere of lavaland
- safe_co2_max = 20
+ safe_breath_min = 6
+ safe_breath_max = 18
+
+ gas_min = list(
+ GAS_O2 = 0,
+ GAS_N2 = 16,
+ )
+ gas_max = list(
+ GAS_CO2 = 20,
+ GAS_PLASMA = 0.05
+ )
+
+ SA_para_min = 1
+ SA_sleep_min = 5
+ BZ_trip_balls_min = 1
+ gas_stimulation_min = 0.002
/obj/item/organ/lungs/plant
name = "mesophyll"
@@ -13,15 +27,19 @@
icon = 'yogstation/icons/obj/surgery.dmi'
icon_state = "lungs-plant"
- safe_co2_max = 0 //make them not choke on CO2 so they can actually breathe it
- oxygen_substitutes = list(/datum/gas/pluoxium = 8, /datum/gas/carbon_dioxide = 1) //able of using CO2 AND oxygen to breathe
+ gas_max = list(
+ GAS_CO2 = 0, //make them not choke on CO2 so they can actually breathe it
+ GAS_PLASMA = 0.05
+ )
+
+ breathing_class = /datum/breathing_class/oxygen_co2
/obj/item/organ/lungs/plant/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H) //Directly taken from the xenos lungs
. = ..()
if(breath)
- var/breath_amt = breath.get_moles(/datum/gas/carbon_dioxide)
- breath.adjust_moles(/datum/gas/carbon_dioxide, -breath_amt)
- breath.adjust_moles(/datum/gas/oxygen, breath_amt)
+ var/breath_amt = breath.get_moles(GAS_CO2)
+ breath.adjust_moles(GAS_CO2, -breath_amt)
+ breath.adjust_moles(GAS_O2, breath_amt)
/obj/item/organ/lungs/plant/prepare_eat()
var/obj/item/reagent_containers/food/snacks/organ/plant_lung/S = new