diff --git a/.gitignore b/.gitignore
index 68a10788fcd..683e98071d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,10 @@
-#Files and folders specified here will never be tracked.
+###Files and folders specified here will never be tracked.
-*.ban
-*.bdb
-*.log
-*.sav
+#Ignore everything in datafolder and subdirectories
+/data/**/*
-#Compiled files and other files generated during compilation.
+#Ignore compiled files and other files generated during compilation.
*.dmb
*.rsc
*.lk
-*.int
-/data/mode.txt
+*.int
\ No newline at end of file
diff --git a/README.md b/README.md
index 212c87e1e8d..3f8c4f97ec5 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
##DOWNLOADING
-There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/index.php/Downloading_the_source_code
+There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code
Option 1: Download the source code as a zip by clicking the ZIP button in the
code tab of https://github.com/tgstation/-tg-station
@@ -25,7 +25,7 @@ Then you simply search for the -tg-station repository and click the big clone
button.
Option 3:
-Follow this: http://www.tgstation13.org/wiki/index.php/Setting_up_git
+Follow this: http://www.tgstation13.org/wiki/Setting_up_git
(It's recommended that you use git-scm, as above, rather than the git CLI
suggested by the guide)
@@ -109,7 +109,7 @@ To enable an away mission open fileList.txt in the _maps/RandomZLevels directory
The SQL backend for the library and stats tracking requires a
MySQL server. Your server details go in /config/dbconfig.txt, and the SQL
-schema is in /SQL/tgstation_schema.sql. More detailed setup instructions are located here: http://www.tgstation13.org/wiki/index.php/Downloading_the_source_code#Setting_up_the_database
+schema is in /SQL/tgstation_schema.sql and /SQL/tgstation_schema_prefix.sql depending on if you want table prefixes. More detailed setup instructions are located here: http://www.tgstation13.org/wiki/Downloading_the_source_code#Setting_up_the_database
##IRC BOT SETUP
diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt
index fe3c40342da..80af03e4561 100644
--- a/SQL/database_changelog.txt
+++ b/SQL/database_changelog.txt
@@ -1,3 +1,15 @@
+19 September 2014, by MrStonedOne
+
+Removed erro_ from table names. dbconfig.txt has a option allowing you to change the prefix used in code, defaults to "erro_" if left out for legacy reasons.
+
+If you are creating a new database and want to change the prefix, simply find and replace SS13_ to what ever you want (including nothing) and set the prefix value
+
+Two schema files are now included, one with prefixes and one without.
+
+If you have an existing database, and you want to rid your database of erros, you will have to rename all of the tables. A bit sql is included to do just that in errofreedatabase.sql Feel free to find and replace the prefix to what ever you want (or nothing)
+
+----------------------------------------------------
+
4 November 2013, by Errorage
The column 'deleted' was added to the erro_library table. If set to anything other than null, the book is interpreted as deleted.
@@ -12,4 +24,6 @@ UPDATE erro_library SET deleted = 1 WHERE id = someid
(Replace someid with the id of the book you want to soft delete.)
-----------------------------------------------------
\ No newline at end of file
+----------------------------------------------------
+
+
diff --git a/SQL/errofreedatabase.sql b/SQL/errofreedatabase.sql
new file mode 100644
index 00000000000..ae5c0d7ee1c
--- /dev/null
+++ b/SQL/errofreedatabase.sql
@@ -0,0 +1,15 @@
+ALTER TABLE erro_admin RENAME TO SS13_admin;
+ALTER TABLE erro_admin_log RENAME TO SS13_admin_log;
+ALTER TABLE erro_admin_ranks RENAME TO SS13_admin_ranks;
+ALTER TABLE erro_ban RENAME TO SS13_ban;
+ALTER TABLE erro_connection_log RENAME TO SS13_connection_log;
+ALTER TABLE erro_death RENAME TO SS13_death;
+ALTER TABLE erro_feedback RENAME TO SS13_feedback;
+ALTER TABLE erro_legacy_population RENAME TO SS13_legacy_population;
+ALTER TABLE erro_library RENAME TO SS13_library;
+ALTER TABLE erro_player RENAME TO SS13_player;
+ALTER TABLE erro_poll_option RENAME TO SS13_poll_option;
+ALTER TABLE erro_poll_question RENAME TO SS13_poll_question;
+ALTER TABLE erro_poll_textreply RENAME TO SS13_poll_textreply;
+ALTER TABLE erro_poll_vote RENAME TO SS13_poll_vote;
+ALTER TABLE erro_privacy RENAME TO SS13_privacy;
\ No newline at end of file
diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql
index 5eb2e9d8d95..5e053d8e110 100644
--- a/SQL/tgstation_schema.sql
+++ b/SQL/tgstation_schema.sql
@@ -13,13 +13,13 @@ USE `feedback`;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
--- Table structure for table `erro_admin`
+-- Table structure for table `admin`
--
-DROP TABLE IF EXISTS `erro_admin`;
+DROP TABLE IF EXISTS `admin`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_admin` (
+CREATE TABLE `admin` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) NOT NULL,
`rank` varchar(32) NOT NULL DEFAULT 'Administrator',
@@ -31,13 +31,13 @@ CREATE TABLE `erro_admin` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_admin_log`
+-- Table structure for table `admin_log`
--
-DROP TABLE IF EXISTS `erro_admin_log`;
+DROP TABLE IF EXISTS `admin_log`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_admin_log` (
+CREATE TABLE `admin_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`adminckey` varchar(32) NOT NULL,
@@ -48,13 +48,13 @@ CREATE TABLE `erro_admin_log` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_admin_ranks`
+-- Table structure for table `admin_ranks`
--
-DROP TABLE IF EXISTS `erro_admin_ranks`;
+DROP TABLE IF EXISTS `admin_ranks`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_admin_ranks` (
+CREATE TABLE `admin_ranks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rank` varchar(40) NOT NULL,
`flags` int(16) NOT NULL DEFAULT '0',
@@ -62,23 +62,23 @@ CREATE TABLE `erro_admin_ranks` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
-insert into erro_admin_ranks (rank, flags) values ('Moderator',2);
-insert into erro_admin_ranks (rank, flags) values ('Admin Candidate',2);
-insert into erro_admin_ranks (rank, flags) values ('Trial Admin',5638);
-insert into erro_admin_ranks (rank, flags) values ('Badmin',5727);
-insert into erro_admin_ranks (rank, flags) values ('Game Admin',8063);
-insert into erro_admin_ranks (rank, flags) values ('Game Master',65535);
-insert into erro_admin_ranks (rank, flags) values ('Host',65535);
-insert into erro_admin_ranks (rank, flags) values ('Coder',5168);
+insert into admin_ranks (rank, flags) values ('Moderator',2);
+insert into admin_ranks (rank, flags) values ('Admin Candidate',2);
+insert into admin_ranks (rank, flags) values ('Trial Admin',5638);
+insert into admin_ranks (rank, flags) values ('Badmin',5727);
+insert into admin_ranks (rank, flags) values ('Game Admin',8063);
+insert into admin_ranks (rank, flags) values ('Game Master',65535);
+insert into admin_ranks (rank, flags) values ('Host',65535);
+insert into admin_ranks (rank, flags) values ('Coder',5168);
--
--- Table structure for table `erro_ban`
+-- Table structure for table `ban`
--
-DROP TABLE IF EXISTS `erro_ban`;
+DROP TABLE IF EXISTS `ban`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_ban` (
+CREATE TABLE `ban` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bantime` datetime NOT NULL,
`serverip` varchar(32) NOT NULL,
@@ -107,13 +107,13 @@ CREATE TABLE `erro_ban` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_connection_log`
+-- Table structure for table `connection_log`
--
-DROP TABLE IF EXISTS `erro_connection_log`;
+DROP TABLE IF EXISTS `connection_log`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_connection_log` (
+CREATE TABLE `connection_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime DEFAULT NULL,
`serverip` varchar(45) DEFAULT NULL,
@@ -125,13 +125,13 @@ CREATE TABLE `erro_connection_log` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_death`
+-- Table structure for table `death`
--
-DROP TABLE IF EXISTS `erro_death`;
+DROP TABLE IF EXISTS `death`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_death` (
+CREATE TABLE `death` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pod` text NOT NULL COMMENT 'Place of death',
`coord` text NOT NULL COMMENT 'X, Y, Z POD',
@@ -152,13 +152,13 @@ CREATE TABLE `erro_death` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_feedback`
+-- Table structure for table `feedback`
--
-DROP TABLE IF EXISTS `erro_feedback`;
+DROP TABLE IF EXISTS `feedback`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_feedback` (
+CREATE TABLE `feedback` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time` datetime NOT NULL,
`round_id` int(8) NOT NULL,
@@ -170,13 +170,13 @@ CREATE TABLE `erro_feedback` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_legacy_population`
+-- Table structure for table `legacy_population`
--
-DROP TABLE IF EXISTS `erro_legacy_population`;
+DROP TABLE IF EXISTS `legacy_population`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_legacy_population` (
+CREATE TABLE `legacy_population` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`playercount` int(11) DEFAULT NULL,
`admincount` int(11) DEFAULT NULL,
@@ -186,11 +186,11 @@ CREATE TABLE `erro_legacy_population` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_library`
+-- Table structure for table `library`
--
-DROP TABLE IF EXISTS `erro_library`;
-CREATE TABLE `erro_library` (
+DROP TABLE IF EXISTS `library`;
+CREATE TABLE `library` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`author` varchar(45) NOT NULL,
`title` varchar(45) NOT NULL,
@@ -203,13 +203,13 @@ CREATE TABLE `erro_library` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
--- Table structure for table `erro_player`
+-- Table structure for table `player`
--
-DROP TABLE IF EXISTS `erro_player`;
+DROP TABLE IF EXISTS `player`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_player` (
+CREATE TABLE `player` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ckey` varchar(32) NOT NULL,
`firstseen` datetime NOT NULL,
@@ -223,13 +223,13 @@ CREATE TABLE `erro_player` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_poll_option`
+-- Table structure for table `poll_option`
--
-DROP TABLE IF EXISTS `erro_poll_option`;
+DROP TABLE IF EXISTS `poll_option`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_poll_option` (
+CREATE TABLE `poll_option` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pollid` int(11) NOT NULL,
`text` varchar(255) NOT NULL,
@@ -244,13 +244,13 @@ CREATE TABLE `erro_poll_option` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_poll_question`
+-- Table structure for table `poll_question`
--
-DROP TABLE IF EXISTS `erro_poll_question`;
+DROP TABLE IF EXISTS `poll_question`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_poll_question` (
+CREATE TABLE `poll_question` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`polltype` varchar(16) NOT NULL DEFAULT 'OPTION',
`starttime` datetime NOT NULL,
@@ -263,13 +263,13 @@ CREATE TABLE `erro_poll_question` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_poll_textreply`
+-- Table structure for table `poll_textreply`
--
-DROP TABLE IF EXISTS `erro_poll_textreply`;
+DROP TABLE IF EXISTS `poll_textreply`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_poll_textreply` (
+CREATE TABLE `poll_textreply` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`pollid` int(11) NOT NULL,
@@ -282,13 +282,13 @@ CREATE TABLE `erro_poll_textreply` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_poll_vote`
+-- Table structure for table `poll_vote`
--
-DROP TABLE IF EXISTS `erro_poll_vote`;
+DROP TABLE IF EXISTS `poll_vote`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_poll_vote` (
+CREATE TABLE `poll_vote` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`pollid` int(11) NOT NULL,
@@ -302,13 +302,13 @@ CREATE TABLE `erro_poll_vote` (
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `erro_privacy`
+-- Table structure for table `privacy`
--
-DROP TABLE IF EXISTS `erro_privacy`;
+DROP TABLE IF EXISTS `privacy`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `erro_privacy` (
+CREATE TABLE `privacy` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`ckey` varchar(32) NOT NULL,
diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql
new file mode 100644
index 00000000000..c1b740b6874
--- /dev/null
+++ b/SQL/tgstation_schema_prefixed.sql
@@ -0,0 +1,330 @@
+CREATE DATABASE IF NOT EXISTS `feedback` /*!40100 DEFAULT CHARACTER SET latin1 */;
+USE `feedback`;
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `SS13_admin`
+--
+
+DROP TABLE IF EXISTS `SS13_admin`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_admin` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `ckey` varchar(32) NOT NULL,
+ `rank` varchar(32) NOT NULL DEFAULT 'Administrator',
+ `level` int(2) NOT NULL DEFAULT '0',
+ `flags` int(16) NOT NULL DEFAULT '0',
+ `email` varchar(45) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_admin_log`
+--
+
+DROP TABLE IF EXISTS `SS13_admin_log`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_admin_log` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `datetime` datetime NOT NULL,
+ `adminckey` varchar(32) NOT NULL,
+ `adminip` varchar(18) NOT NULL,
+ `log` text NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_admin_ranks`
+--
+
+DROP TABLE IF EXISTS `SS13_admin_ranks`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_admin_ranks` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `rank` varchar(40) NOT NULL,
+ `flags` int(16) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+insert into SS13_admin_ranks (rank, flags) values ('Moderator',2);
+insert into SS13_admin_ranks (rank, flags) values ('Admin Candidate',2);
+insert into SS13_admin_ranks (rank, flags) values ('Trial Admin',5638);
+insert into SS13_admin_ranks (rank, flags) values ('Badmin',5727);
+insert into SS13_admin_ranks (rank, flags) values ('Game Admin',8063);
+insert into SS13_admin_ranks (rank, flags) values ('Game Master',65535);
+insert into SS13_admin_ranks (rank, flags) values ('Host',65535);
+insert into SS13_admin_ranks (rank, flags) values ('Coder',5168);
+
+--
+-- Table structure for table `SS13_ban`
+--
+
+DROP TABLE IF EXISTS `SS13_ban`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_ban` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `bantime` datetime NOT NULL,
+ `serverip` varchar(32) NOT NULL,
+ `bantype` varchar(32) NOT NULL,
+ `reason` text NOT NULL,
+ `job` varchar(32) DEFAULT NULL,
+ `duration` int(11) NOT NULL,
+ `rounds` int(11) DEFAULT NULL,
+ `expiration_time` datetime NOT NULL,
+ `ckey` varchar(32) NOT NULL,
+ `computerid` varchar(32) NOT NULL,
+ `ip` varchar(32) NOT NULL,
+ `a_ckey` varchar(32) NOT NULL,
+ `a_computerid` varchar(32) NOT NULL,
+ `a_ip` varchar(32) NOT NULL,
+ `who` text NOT NULL,
+ `adminwho` text NOT NULL,
+ `edits` text,
+ `unbanned` int(2) DEFAULT NULL,
+ `unbanned_datetime` datetime DEFAULT NULL,
+ `unbanned_ckey` varchar(32) DEFAULT NULL,
+ `unbanned_computerid` varchar(32) DEFAULT NULL,
+ `unbanned_ip` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_connection_log`
+--
+
+DROP TABLE IF EXISTS `SS13_connection_log`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_connection_log` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `datetime` datetime DEFAULT NULL,
+ `serverip` varchar(45) DEFAULT NULL,
+ `ckey` varchar(45) DEFAULT NULL,
+ `ip` varchar(18) DEFAULT NULL,
+ `computerid` varchar(45) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_death`
+--
+
+DROP TABLE IF EXISTS `SS13_death`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_death` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `pod` text NOT NULL COMMENT 'Place of death',
+ `coord` text NOT NULL COMMENT 'X, Y, Z POD',
+ `tod` datetime NOT NULL COMMENT 'Time of death',
+ `job` text NOT NULL,
+ `special` text NOT NULL,
+ `name` text NOT NULL,
+ `byondkey` text NOT NULL,
+ `laname` text NOT NULL COMMENT 'Last attacker name',
+ `lakey` text NOT NULL COMMENT 'Last attacker key',
+ `gender` text NOT NULL,
+ `bruteloss` int(11) NOT NULL,
+ `brainloss` int(11) NOT NULL,
+ `fireloss` int(11) NOT NULL,
+ `oxyloss` int(11) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_feedback`
+--
+
+DROP TABLE IF EXISTS `SS13_feedback`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_feedback` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `time` datetime NOT NULL,
+ `round_id` int(8) NOT NULL,
+ `var_name` varchar(32) NOT NULL,
+ `var_value` int(16) DEFAULT NULL,
+ `details` text,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_legacy_population`
+--
+
+DROP TABLE IF EXISTS `SS13_legacy_population`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_legacy_population` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `playercount` int(11) DEFAULT NULL,
+ `admincount` int(11) DEFAULT NULL,
+ `time` datetime NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_library`
+--
+
+DROP TABLE IF EXISTS `SS13_library`;
+CREATE TABLE `SS13_library` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `author` varchar(45) NOT NULL,
+ `title` varchar(45) NOT NULL,
+ `content` text NOT NULL,
+ `category` varchar(45) NOT NULL,
+ `ckey` varchar(45) DEFAULT 'LEGACY',
+ `datetime` datetime DEFAULT NULL,
+ `deleted` tinyint(1) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `SS13_player`
+--
+
+DROP TABLE IF EXISTS `SS13_player`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_player` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `ckey` varchar(32) NOT NULL,
+ `firstseen` datetime NOT NULL,
+ `lastseen` datetime NOT NULL,
+ `ip` varchar(18) NOT NULL,
+ `computerid` varchar(32) NOT NULL,
+ `lastadminrank` varchar(32) NOT NULL DEFAULT 'Player',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `ckey` (`ckey`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_poll_option`
+--
+
+DROP TABLE IF EXISTS `SS13_poll_option`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_poll_option` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `pollid` int(11) NOT NULL,
+ `text` varchar(255) NOT NULL,
+ `percentagecalc` tinyint(1) NOT NULL DEFAULT '1',
+ `minval` int(3) DEFAULT NULL,
+ `maxval` int(3) DEFAULT NULL,
+ `descmin` varchar(32) DEFAULT NULL,
+ `descmid` varchar(32) DEFAULT NULL,
+ `descmax` varchar(32) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_poll_question`
+--
+
+DROP TABLE IF EXISTS `SS13_poll_question`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_poll_question` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `polltype` varchar(16) NOT NULL DEFAULT 'OPTION',
+ `starttime` datetime NOT NULL,
+ `endtime` datetime NOT NULL,
+ `question` varchar(255) NOT NULL,
+ `adminonly` tinyint(1) DEFAULT '0',
+ `multiplechoiceoptions` int(2) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_poll_textreply`
+--
+
+DROP TABLE IF EXISTS `SS13_poll_textreply`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_poll_textreply` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `datetime` datetime NOT NULL,
+ `pollid` int(11) NOT NULL,
+ `ckey` varchar(32) NOT NULL,
+ `ip` varchar(18) NOT NULL,
+ `replytext` text NOT NULL,
+ `adminrank` varchar(32) NOT NULL DEFAULT 'Player',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_poll_vote`
+--
+
+DROP TABLE IF EXISTS `SS13_poll_vote`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_poll_vote` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `datetime` datetime NOT NULL,
+ `pollid` int(11) NOT NULL,
+ `optionid` int(11) NOT NULL,
+ `ckey` varchar(255) NOT NULL,
+ `ip` varchar(16) NOT NULL,
+ `adminrank` varchar(32) NOT NULL,
+ `rating` int(2) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_privacy`
+--
+
+DROP TABLE IF EXISTS `SS13_privacy`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_privacy` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `datetime` datetime NOT NULL,
+ `ckey` varchar(32) NOT NULL,
+ `option` varchar(128) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2013-03-24 18:02:35
\ No newline at end of file
diff --git a/_maps/RandomZLevels/Academy.dmm b/_maps/RandomZLevels/Academy.dmm
index 4d715cb369e..e0eed02d019 100644
--- a/_maps/RandomZLevels/Academy.dmm
+++ b/_maps/RandomZLevels/Academy.dmm
@@ -1,6 +1,6 @@
"aa" = (/turf/space,/area/space)
"ab" = (/turf/simulated/wall/r_wall,/area/awaymission/academy/headmaster)
-"ac" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/awaymission/academy/headmaster)
+"ac" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/headmaster)
"ad" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor/carpet,/area/awaymission/academy/headmaster)
"ae" = (/obj/structure/computerframe{anchored = 1},/turf/simulated/floor/carpet,/area/awaymission/academy/headmaster)
"af" = (/obj/structure/table/reinforced,/obj/item/weapon/pen/red,/turf/simulated/floor/carpet,/area/awaymission/academy/headmaster)
@@ -92,7 +92,7 @@
"bN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/academy/headmaster)
"bO" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{icon_state = "dark"},/area/awaymission/academy/headmaster)
"bP" = (/obj/effect/decal/cleanable/cobweb2,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/academy/headmaster)
-"bQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/headmaster)
+"bQ" = (/obj/structure/table/reinforced,/obj/item/device/laser_pointer/upgraded,/turf/simulated/floor/carpet,/area/awaymission/academy/headmaster)
"bR" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/floor{icon_state = "showroomfloor"},/area/awaymission/academy/headmaster)
"bS" = (/turf/simulated/floor{icon_state = "showroomfloor"},/area/awaymission/academy/headmaster)
"bT" = (/obj/machinery/autolathe,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor,/area/awaymission/academy/classrooms)
@@ -106,7 +106,7 @@
"cb" = (/obj/structure/table,/obj/item/weapon/lighter/random,/turf/simulated/floor,/area/awaymission/academy/headmaster)
"cc" = (/turf/simulated/floor{icon_state = "dark"},/area/awaymission/academy/headmaster)
"cd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/academy/headmaster)
-"ce" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/headmaster)
+"ce" = (/obj/item/seeds/eggyseed,/obj/machinery/hydroponics/constructable,/turf/simulated/floor,/area/awaymission/academy/classrooms)
"cf" = (/obj/machinery/portable_atmospherics/canister/toxins,/turf/simulated/floor{icon_state = "showroomfloor"},/area/awaymission/academy/headmaster)
"cg" = (/obj/structure/stool,/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/awaymission/academy/headmaster)
"ch" = (/obj/structure/table,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor{icon_state = "floorgrime"},/area/awaymission/academy/classrooms)
@@ -148,7 +148,7 @@
"cR" = (/obj/machinery/light{dir = 8},/obj/machinery/portable_atmospherics/pump,/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/academy/headmaster)
"cS" = (/obj/structure/closet/crate/internals,/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen/red,/turf/simulated/floor{icon_state = "dark"},/area/awaymission/academy/headmaster)
"cT" = (/obj/structure/closet/crate,/obj/item/weapon/crowbar/red,/turf/simulated/floor{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/academy/headmaster)
-"cU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable,/turf/simulated/floor/plating,/area/awaymission/academy/headmaster)
+"cU" = (/obj/structure/grille,/obj/structure/cable,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/headmaster)
"cV" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor,/area/awaymission/academy/classrooms)
"cW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor,/area/awaymission/academy/classrooms)
"cX" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{icon_state = "floorgrime"},/area/awaymission/academy/classrooms)
@@ -158,7 +158,7 @@
"db" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/wood,/area/awaymission/academy/classrooms)
"dc" = (/turf/simulated/floor/greengrid,/area/awaymission/academy/classrooms)
"dd" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/awaymission/academy/classrooms)
-"de" = (/obj/structure/table/woodentable,/obj/item/weapon/staff,/turf/simulated/floor/wood,/area/awaymission/academy/classrooms)
+"de" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor,/area/awaymission/academy/classrooms)
"df" = (/turf/simulated/floor{dir = 9; icon_state = "green"},/area/awaymission/academy/classrooms)
"dg" = (/turf/simulated/floor{dir = 1; icon_state = "green"},/area/awaymission/academy/classrooms)
"dh" = (/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/awaymission/academy/classrooms)
@@ -173,8 +173,8 @@
"dq" = (/obj/structure/stool/bed/chair/wood/normal{dir = 1},/turf/simulated/floor/wood,/area/awaymission/academy/classrooms)
"dr" = (/turf/simulated/floor{icon_state = "green"; dir = 8},/area/awaymission/academy/classrooms)
"ds" = (/obj/structure/stool,/turf/simulated/floor,/area/awaymission/academy/classrooms)
-"dt" = (/obj/machinery/hydroponics,/obj/item/seeds/eggyseed,/turf/simulated/floor,/area/awaymission/academy/classrooms)
-"du" = (/obj/machinery/hydroponics,/turf/simulated/floor,/area/awaymission/academy/classrooms)
+"dt" = (/obj/structure/table/woodentable,/obj/item/weapon/gun/magic/wand/fireball,/turf/simulated/floor/wood,/area/awaymission/academy/classrooms)
+"du" = (/obj/machinery/hydroponics/constructable,/obj/item/seeds/replicapod,/turf/simulated/floor,/area/awaymission/academy/classrooms)
"dv" = (/turf/simulated/floor{icon_state = "green"; dir = 4},/area/awaymission/academy/classrooms)
"dw" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/effect/landmark{name = "awaystart"},/obj/item/weapon/weldingtool,/turf/simulated/floor/greengrid,/area/awaymission/academy/classrooms)
"dx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/greengrid,/area/awaymission/academy/classrooms)
@@ -184,13 +184,13 @@
"dB" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor,/area/awaymission/academy/classrooms)
"dC" = (/obj/structure/closet/crate/hydroponics/prespawned,/turf/simulated/floor,/area/awaymission/academy/classrooms)
"dD" = (/obj/machinery/door/airlock/freezer,/turf/simulated/floor{icon_state = "white"},/area/awaymission/academy/classrooms)
-"dE" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/awaymission/academy/classrooms)
+"dE" = (/obj/machinery/light/small{dir = 4},/obj/machinery/chem_master/condimaster,/turf/simulated/floor{icon_state = "white"},/area/awaymission/academy/classrooms)
"dF" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/cable,/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
"dG" = (/obj/machinery/computer/mech_bay_power_console,/obj/structure/cable,/turf/simulated/floor/greengrid,/area/awaymission/academy/classrooms)
-"dH" = (/obj/machinery/hydroponics,/obj/item/seeds/replicapod,/turf/simulated/floor,/area/awaymission/academy/classrooms)
+"dH" = (/obj/machinery/hydroponics/constructable,/obj/item/seeds/bluespacetomatoseed,/turf/simulated/floor,/area/awaymission/academy/classrooms)
"dI" = (/obj/structure/table/woodentable,/turf/simulated/floor,/area/awaymission/academy/classrooms)
"dJ" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor,/area/awaymission/academy/classrooms)
-"dK" = (/obj/machinery/hydroponics,/obj/item/seeds/bluespacetomatoseed,/turf/simulated/floor,/area/awaymission/academy/classrooms)
+"dK" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/bag/tray,/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/awaymission/academy/classrooms)
"dL" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor,/area/awaymission/academy/classrooms)
"dM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/awaymission/academy/classrooms)
"dN" = (/obj/machinery/door/airlock/freezer,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/awaymission/academy/classrooms)
@@ -222,7 +222,7 @@
"en" = (/obj/machinery/vending/hydroseeds{slogan_delay = 700},/turf/simulated/floor,/area/awaymission/academy/classrooms)
"eo" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor{icon_state = "green"; dir = 6},/area/awaymission/academy/classrooms)
"ep" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/simulated/floor{icon_state = "white"},/area/awaymission/academy/classrooms)
-"eq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
+"eq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
"er" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{dir = 6; icon_state = "yellow"},/area/awaymission/academy/classrooms)
"es" = (/obj/machinery/singularity/academy,/turf/space,/area/space)
"et" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "yellow"; dir = 10},/area/awaymission/academy/classrooms)
@@ -284,13 +284,13 @@
"fx" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor{icon_state = "grimy"},/area/awaymission/academy/classrooms)
"fy" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/carpet,/area/awaymission/academy/classrooms)
"fz" = (/obj/machinery/light,/turf/simulated/floor{icon_state = "escape"; dir = 6},/area/awaymission/academy/classrooms)
-"fA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
-"fB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
-"fC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
+"fA" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/headmaster)
+"fB" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/headmaster)
+"fC" = (/obj/machinery/door/airlock/plasma,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/carpet,/area/awaymission/academy/headmaster)
"fD" = (/turf/simulated/wall,/area/awaymission/academy/academyaft)
"fE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
"fF" = (/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
-"fG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
+"fG" = (/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/cable,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
"fH" = (/obj/machinery/shieldwallgen,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/awaymission/academy/classrooms)
"fI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/awaymission/academy/classrooms)
"fJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/awaymission/academy/classrooms)
@@ -308,10 +308,10 @@
"fV" = (/obj/structure/target_stake,/turf/simulated/floor,/area/awaymission/academy/classrooms)
"fW" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
"fX" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
-"fY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
+"fY" = (/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
"fZ" = (/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/awaymission/academy/classrooms)
"ga" = (/obj/structure/table,/obj/item/weapon/pen/red,/turf/simulated/floor,/area/awaymission/academy/classrooms)
-"gb" = (/obj/structure/table,/obj/item/weapon/scalpel,/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/awaymission/academy/classrooms)
+"gb" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 5},/area/awaymission/academy/academyaft)
"gc" = (/obj/structure/stool/bed/chair/wood/normal,/turf/simulated/floor/wood,/area/awaymission/academy/classrooms)
"gd" = (/obj/structure/bookcase,/obj/item/weapon/book/manual/wiki/engineering_hacking,/turf/simulated/floor/wood,/area/awaymission/academy/classrooms)
"ge" = (/obj/structure/bookcase,/turf/simulated/floor/wood,/area/awaymission/academy/classrooms)
@@ -452,28 +452,28 @@
"iJ" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/engine,/area/awaymission/academy/academyaft)
"iK" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
"iL" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/beach_ball/holoball,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/awaymission/academy/academyaft)
-"iM" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{icon_state = "red"; dir = 5},/area/awaymission/academy/academyaft)
-"iN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
+"iM" = (/obj/structure/grille,/obj/structure/cable,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
+"iN" = (/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
"iO" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
-"iP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
+"iP" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
"iQ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/airless{tag = "icon-white (EAST)"; icon_state = "white"; dir = 4},/area/awaymission/academy/academyaft)
"iR" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/device/soulstone,/turf/simulated/floor/airless{tag = "icon-whitered (EAST)"; icon_state = "whitered"; dir = 4},/area/awaymission/academy/academyaft)
"iS" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l"; icon_state = "propulsion_l"},/turf/space,/area/awaymission/academy/academyaft)
"iT" = (/obj/structure/shuttle/engine/propulsion,/turf/space,/area/awaymission/academy/academyaft)
"iU" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_r"; icon_state = "propulsion_r"},/turf/space,/area/awaymission/academy/academyaft)
-"iV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
-"iW" = (/turf/simulated/floor{icon_state = "red"; dir = 4},/area/awaymission/academy/academyaft)
-"iX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
+"iV" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
+"iW" = (/obj/effect/landmark{name = "awaystart"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/awaymission/academy/academyaft)
+"iX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/awaymission/academy/academyaft)
"iY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/airless{tag = "icon-white (EAST)"; icon_state = "white"; dir = 4},/area/awaymission/academy/academyaft)
"iZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/airless{tag = "icon-whitered (EAST)"; icon_state = "whitered"; dir = 4},/area/awaymission/academy/academyaft)
-"ja" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
+"ja" = (/obj/structure/grille,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
"jb" = (/obj/structure/table,/obj/item/clothing/glasses/meson/truesight,/turf/simulated/floor,/area/awaymission/academy/academyaft)
"jc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
"jd" = (/obj/structure/noticeboard,/turf/simulated/wall,/area/awaymission/academy/academyaft)
"je" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
"jf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/airless{tag = "icon-white (EAST)"; icon_state = "white"; dir = 4},/area/awaymission/academy/academyaft)
"jg" = (/obj/structure/table,/obj/item/organ/brain{name = "The preserved brain of Harry Houdini"},/turf/simulated/floor/airless{tag = "icon-whitered (EAST)"; icon_state = "whitered"; dir = 4},/area/awaymission/academy/academyaft)
-"jh" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/awaymission/academy/academyaft)
+"jh" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/awaymission/academy/academyaft)
"ji" = (/turf/simulated/floor{dir = 8; icon_state = "yellow"},/area/awaymission/academy/academyaft)
"jj" = (/turf/simulated/floor{dir = 4; icon_state = "yellow"},/area/awaymission/academy/academyaft)
"jk" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/airless{tag = "icon-white (EAST)"; icon_state = "white"; dir = 4},/area/awaymission/academy/academyaft)
@@ -488,7 +488,7 @@
"jt" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/space,/area/space)
"ju" = (/obj/machinery/igniter,/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
"jv" = (/obj/structure/window/reinforced,/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
-"jw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/cable,/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
+"jw" = (/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
"jx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
"jy" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
"jz" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/carpet,/area/awaymission/academy/academyaft)
@@ -506,7 +506,7 @@
"jL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/carpet,/area/awaymission/academy/academygate)
"jM" = (/turf/simulated/floor/grass,/area/awaymission/academy/academygate)
"jN" = (/turf/simulated/floor/carpet,/area/awaymission/academy/academygate)
-"jO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor/plating,/area/awaymission/academy/academygate)
+"jO" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
"jP" = (/obj/structure/window/reinforced,/turf/simulated/floor/grass,/area/awaymission/academy/academygate)
"jQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/window,/turf/simulated/floor/carpet,/area/awaymission/academy/academygate)
"jR" = (/obj/machinery/door/window,/turf/simulated/floor/carpet,/area/awaymission/academy/academygate)
@@ -534,7 +534,16 @@
"kn" = (/obj/machinery/door_control{id = "AcademyGate"; pixel_y = -24},/turf/simulated/floor/carpet{icon_state = "carpetsymbol"},/area/awaymission/academy/academygate)
"ko" = (/turf/simulated/floor/carpet{icon_state = "carpetsymbol"},/area/awaymission/academy/academygate)
"kp" = (/obj/machinery/door/poddoor/shutters{id = "AcademyGate"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"; tag = "icon-warnplate (NORTH)"},/area/awaymission/academy/academygate)
-
+"kq" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
+"kr" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
+"ks" = (/obj/structure/grille,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
+"kt" = (/obj/structure/table,/obj/item/weapon/scalpel,/turf/simulated/floor,/area/awaymission/academy/classrooms)
+"ku" = (/obj/structure/table,/obj/item/weapon/lazarus_injector,/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/awaymission/academy/classrooms)
+"kv" = (/obj/structure/grille,/obj/structure/cable,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/classrooms)
+"kw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5},/turf/simulated/floor/plating,/area/awaymission/academy/academygate)
+"kx" = (/obj/structure/closet/crate/trashcart,/turf/simulated/floor{icon_state = "grimy"},/area/awaymission/academy/academyaft)
+"ky" = (/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/academy/academyaft)
+
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -561,7 +570,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacakahahahahalamananaoapaqacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacarahahasasatasasasauavawacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaeaxahasayazaAaBasapaxaeacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaCahaDasaEaFaFaGasaHahakacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaCahaDasaEaFaFaGasaHahbQacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaeaxahasaIaJaFaKasapaxaeacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaLahahasasasasasasapahakacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaMahahahahaNahalanavahafacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -577,37 +586,37 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaaaaaaaaaRaRaRaRaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaRaaaaaRaRaRaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaOaOaOaaaaabasasasasbobpasasasasabaaaaaOaOaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaaaaaaaRaRaRaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaOaOaaaOaaaaabbqbqbqbqahapbqbqbqbqabaaaaaOaaaOaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaRaaaaaaaaaaaaaaaaaabrbsbtbububvbsbrbrbrbrbrbrbrbrbrbrabbqbwbxbqahapbqbwbxbqababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaaaaaaaaaaaaaaaaaabrbrbybzbAbAbBbybCbDbEbFbFbFbFbFbFbGasbHbIbJbqahapbqbIbJbKasbLbMbNbObPbQbRbSababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbTbybAbAbAbAbUbybDbVbWbXbYbYbZbYbVasbqcacbbqahapbqbqbqbqabcccdccasascebScfcgabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrchbybAcibAbAbybybDbVbYbYbYbWbYbYbVasbqbqbqbqahapahahahahcjckclcmascncebSbRcoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaaaaaaaaaaaaaaaaaabrbrbybzbAbAbBbybCbDbEbFbFbFbFbFbFbGasbHbIbJbqahapbqbIbJbKasbLbMbNbObPfAbRbSababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbTbybAbAbAbAbUbybDbVbWbXbYbYbZbYbVasbqcacbbqahapbqbqbqbqabcccdccasasfBbScfcgabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrchbybAcibAbAbybybDbVbYbYbYbWbYbYbVasbqbqbqbqahapahahahahcjckclcmascnfBbSbRcoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrcpbUbAbAbAbAbycqbDcrbYbYbYbYbYbYcrasbqcscsbqahapctahctahabcccdcccucvcwbSbScxabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrcybybAbAbAbAbybybDczcAbYbYbYbYbYcBasbqcCcCbqahcDanananancjbNcEckcFascebSbRcoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrcGbybAbAcHbAbybUbDczcIcIcIcIcIcIcBasbqcJbqbqahapbqbqbqbqabccckccckcccecfbScgabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrcybybAbAbAbAbybybDczcAbYbYbYbYbYcBasbqcCcCbqahcDananananfCbNcEckcFasfBbSbRcoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrcGbybAbAcHbAbybUbDczcIcIcIcIcIcIcBasbqcJbqbqahapbqbqbqbqabccckccckccfBcfbScgabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrcKbycLbAbAcMbybUbDcNcOcOcOcOcOcOcPascQbwbxbqahapbqbwbxbKascRccckcScTcUbSbSababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrcVcWcXcXcXcXcYbybDcZdadadadadadadbasbqbIbJbqahapbqbIbJbqasasasasasasasasasabbrbrbrbrbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdcdcdcbUbUbycKbybDdadadddadddadedaasbqbqbqbqahapbqbqbqbqasdfdgdhdidgdgdgdhdgdjbDdkdkdlbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdmdndobUbybycKdpbDdadadqdadqdadqdaasaFaFaFaFahapaFaFaFaFasdrdsdtbydsdubybybydvbDdkdkdkdkbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdcdcdcbUbUbycKbybDdadadddadddadtdaasbqbqbqbqahapbqbqbqbqasdfdgdhdidgdgdgdhdgdjbDdkdkdlbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdmdndobUbybycKdpbDdadadqdadqdadqdaasaFaFaFaFahapaFaFaFaFasdrdscebydsdebybybydvbDdkdkdkdkbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdwdxdycWcWcWdzbybDdadadadadddadddaasaFdAdAaFahapaFdAdAaFasdrbybybybybybydBdCdvdDdkdkdkdEbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdFdndGbUbybycKbybDdadadadadqdadqdaasaFdAdAaFahapaFdAdAaFasdrdsdubydsdHbydIdJdvbDdkdkdkdkbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdcdcdcbybUbycKbybDdadadadadadadadaasaFdAdAaFahapaFdAdAaFasdrbybybybybybydKdLdMdNdOdPdkdQbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbDbDbDdRdSbDbDbDdTdTbDbDbDbDbDasasasasasahapasasasasasdrdsdubybydUbybydVdvbDdWdXdkdQbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdFdndGbUbybycKbybDdadadadadqdadqdaasaFdAdAaFahapaFdAdAaFasdrdsdebydsdubydIdJdvbDdkdkdkdkbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdcdcdcbybUbycKbybDdadadadadadadadaasaFdAdAaFahapaFdAdAaFasdrbybybybybybydHdLdMdNdOdPdkdQbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbDbDbDdRdSbDbDbDdTdTbDbDbDbDbDasasasasasahapasasasasasdrdsdebybydUbybydVdvbDdWdXdkdQbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdYdYbrdZeaebecedeeefegeheheheheheiehefehehehehejekehehehehbDelememememembybyeneobDdWdXdkepbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabreqeqbreresetecedeheheheheheheheheueheheheheheheheuehehehehbDbDbDbDbDbDbDevevbDbDbDbDewbDbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaexeybAbAezbyeAbybyedehejejejejejejejekejejejejejejejekejejejehbDeBeBeBeCeDeBeBeBeBeEeFeFeGeFbrbraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHbrbAbAeqeIeIeIeJedehejeKeLejeKeLejeMeLejeKeLejeKeLekeKeLejeNbDeBeBeBeOeBeBeBeBeBeEeFeFeGePbraOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHbrbAbAeqeIeIeIeJedehejeKeLejeKeLejeMeLejeKeLejeKeLekeKeLejeNbDeBeBeBeOeBeBeBeBeBdKeFeFeGePbraOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeHbrbAbAeqeQeQeQeRedehejeSeTejeSeTejeUeTejeSeTejeSeTekeSeTejeheVeBeBeBeWeBeCeBeBeBeEeFeFeGeXbraOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeYeybAbAezbyeZbybyedehejejejejejejejekejejejfafbfbfbfcfbfbfbfdfefffffffffffgfffffffhfififjfkbraOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabreqeqbrflesfmecedeheheheheheheheheueheheheuehehehehehehehehbDeBfnfofpeBeWeBeBeBeEeFeFeFfqbraOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrdYdYbrfrfsftecfufvfdfdfdfdfwehehfxfdfdfdfyejehehejejehehehbDeBeBeBeBfzeBeBeBeBeEeFeFeFbrbraOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbrbrbDdRdSbDbDbDbDbDfAfBfBfCbDbDfDfEfFfDfDfFfFfDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbrbraOaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbAbAbAfGfHfIfJfKfKfLbDfMdadadadadabDfNfEfFfNfNfFfFfNbDfOfPfQfOfOczfRfSfTfUbybyfVbrbraOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrfWfXbAfYfZbybybygagbbDdagcdagdgedafGgfggfFfNfNfFfFfNbDghgigjgkghczbyglbybybybybrbraOaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaabrgmbAbAgnfZbygobybygpbDdadddadadadafYfNfFfFfNfNfFfFfNbDghgqghghghczfRfSbybyfVbrbraOaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaRaaaaaaaaaaaaaaaaaabrgrgrgrfYfZbydsbybygsbDgtdqdagegudafYfNfFfFfNfNfFfFgvbDgwgqghghghczbygxbygybrbraOaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaRaaaaaaaaaaaaaaaaaabrgzgzgzfYfZbygobygogpbDdagcdadadadafAgfgAgBfNfNfFfFfNbDghgqgCgDgEczgFfSfVbrbraOaaaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbrbrbrbrbrbDdRdSbDbDbDbDbDeqeqeqeqbDbDfDfEfFfDfDfFfFfDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbrbraOaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbAbAbAksfHfIfJfKfKfLbDfMdadadadadabDfNfEfFfNfNfFfFkxbDfOfPfQfOfOczfRfSfTfUbybyfVbrbraOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrfWfXbAjwfZbybybygakubDdagcdagdgedakrgfggfFfNfNfFfFfNbDghgigjgkghczbyglbybybybybrbraOaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaabrgmbAbAgnfZbygobybygpbDdadddadadadajOfNfFfFfNfNfFfFfNbDghgqghghghczfRfSbybyfVbrbraOaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaRaaaaaaaaaaaaaaaaaabrgrgrgrjwfZbydsbybygsbDgtdqdagegudajOfNfFfFfNfNfFfFgvbDgwgqghghghczbygxbygybrbraOaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaRaaaaaaaaaaaaaaaaaabrgzgzgzjwfZbyktbygogpbDdagcdadadadakqgfgAgBfNfNfFfFfNbDghgqgCgDgEczgFfSfVbrbraOaaaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaaaaaaaaaaaaaaaaaaaabrbAgGbAgnfZbydsbydsgpbDdadddagHgIdabDfNfFfEfNfNfFfFfNbDghgqgJgJgJczbygKbrbraOaaaaaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaabrgLbAbAfYfZbygobygogpbDdadqdadadadagMfFfFgNgfgfgAgAgAgOgPgQgEgEgRczgSbrbraOaaaaaaaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbAbAgGfAgTgUgVgUgVdkbDdadadadadadabDfNfFfEfNfNfFfFfNbDghghgJgJgJczbrbraOaaaaaaaaaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaabrgLbAbAjwfZbygobygogpbDdadqdadadadagMfFfFgNgfgfgAgAgAgOgPgQgEgEgRczgSbrbraOaaaaaaaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrbAbAgGkvgTgUgVgUgVdkbDdadadadadadabDfNfFfEfNfNfFfFfNbDghghgJgJgJczbrbraOaaaaaaaaaaaaaOaaaOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgWgWgWgWgWgWgWgWgWgWgWfDfDfDfDfDfDfDfDfDgXfDfDgYfDfDfDfDfDfDfDfDfDgWgWgWgWgWgWgWgWgWgWgWgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgZhahbhbhchdhehfgWhggWhhhihihjhihihkfFfFfEfFfFfFfFfFhhhihihjhihihlgWhggWhmhnhohphqhrgZgZgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgZhshthbhuhihvhwhxhyhxhzhAhAhAhAhAhBgAgAhChDgAgAgAgAhzhAhAhAhAhAhEhxhFhxhdhGhmhigZgZhHgZgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -622,21 +631,21 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgWgWgWiDgWgWaagWipififiqfDfDfDhRichRfEfFhRichRfDfDfDitififiugWaagWgWiDgWgWgWgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWiEiFiGiGgWaOgWififififiliHfDhRhRiIggfFhRhRhRfDixilififififgWaOgWiGiGiFiJgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaaaagWiGiGiGiGgWaOgWgWgWfDfDfDfDfDfDfDgXfDfDgYfDfDfDfDfDfDfDgWgWgWaOgWiGiGiGiGgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaaaaaaaaaaaaaaaaaaaaaaaagWiKiKiKiKgWaaaaaagWiLiMiNgfiOgAgAhCgAgAgAgAgAgAgfiPiQiRgWaaaaaagWiKiKiKiKgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaaaaaaaRaRaaaaaaaaaaaaaaaaaagWiSiTiTiUgWaaaaaaiVhiiWiXfNfEfFfFfFfFfFfFfFfFfFfNiXiYiZjaaaaaaagWiSiTiTiUgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWjbiWiXfNjcfDfDjdfDfDjdfDfDjefNiXjfjggWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiVhijhiXfNfEfFjihihihihijjfFfFfNiXjkiZjlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWjmjniXfNfEfFjojpjpjpjpjqfFfFfNiXjrjsgWjtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgWjuiXfNfEjvfFfFfFfFfFfFjvfFfNiXjugWgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgWjwfNjxesjyfFfFfFfFjzesjyfNjwgWgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaaaaaaaaaaaaaaaaaaaaaaaagWiKiKiKiKgWaaaaaagWiLgbfYgfiOgAgAhCgAgAgAgAgAgAgffGiQiRgWaaaaaagWiKiKiKiKgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaaaaaaaRaRaaaaaaaaaaaaaaaaaagWiSiTiTiUgWaaaaaaiVhAjhiPfNfEfFfFfFfFfFfFfFfFfFfNiNiYiZjaaaaaaagWiSiTiTiUgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWjbiXiPfNjcfDfDjdfDfDjdfDfDjefNiNjfjggWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiVhAiWiPfNfEfFjihihihihijjfFfFfNiNjkiZjlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWjmjniPfNfEfFjojpjpjpjpjqfFfFfNiNjrjsgWjtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgWjuiPfNfEjvfFfFfFfFfFfFjvfFfNiNjugWgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgWiMfNjxesjyfFfFfFfFjzesjyfNiMgWgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWgWfNjAjBgAgBfFfFfFfFjCfFfNgWgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWfNfNfNfNfEfFfFfFfNfNfNfNgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWfNjDjEfNfEfFfFfFfNjFjGfNgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWiVgWgWgWjHgWgWjIgWgWgWiVgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagWkygWgWgWjHgWgWjIgWgWgWkygWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajJjJjKjLjMjMjNjKjJjJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajOjMjLjMjMjNjMjOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajOjMjLjMjMjNjMjOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajOjPjQjPjPjRjPjOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakwjMjLjMjMjNjMkwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakwjMjLjMjMjNjMkwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakwjPjQjPjPjRjPkwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajJjJjNjSjTjTjTjUjJjJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajJjJjNjNjVjNjNjWjXjYjJjJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajJjNjNjZkajWjWjWkbkcjNjJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -665,3 +674,4 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
"}
+
diff --git a/_maps/RandomZLevels/fileList.txt b/_maps/RandomZLevels/fileList.txt
index 8b4138a1c7e..c2e08523502 100644
--- a/_maps/RandomZLevels/fileList.txt
+++ b/_maps/RandomZLevels/fileList.txt
@@ -17,4 +17,5 @@
#_maps/RandomZLevels/challenge.dmm
#_maps/RandomZLevels/listeningpost.dmm
#_maps/RandomZLevels/spacehotel.dmm
-#_maps/RandomZLevels/centcomAway.dmm
\ No newline at end of file
+#_maps/RandomZLevels/centcomAway.dmm
+#_maps/RandomZLevels/moonoutpost19.dmm
\ No newline at end of file
diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm
new file mode 100644
index 00000000000..9c6f4f43367
--- /dev/null
+++ b/_maps/RandomZLevels/moonoutpost19.dmm
@@ -0,0 +1,915 @@
+"aa" = (/turf/unsimulated/wall{icon_state = "rock"},/area/mine/explored)
+"ab" = (/turf/simulated/mineral/random,/area/mine/explored)
+"ac" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ad" = (/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ae" = (/turf/simulated/mineral/random/low_chance,/area/mine/explored)
+"af" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ag" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ah" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ai" = (/obj/structure/alien/weeds,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aj" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ak" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/mob/living/simple_animal/hostile/alien,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"al" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"am" = (/obj/structure/alien/weeds/node,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"an" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ao" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ap" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/item/weapon/gun/projectile/automatic/pistol,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aq" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ar" = (/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"as" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"at" = (/turf/simulated/wall/r_wall,/area/awaycontent/a4{name = "Syndicate Outpost"})
+"au" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"av" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/mob/living/simple_animal/hostile/alien/sentinel,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aw" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ax" = (/obj/structure/alien/weeds/node,/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"ay" = (/obj/structure/alien/weeds,/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"az" = (/turf/simulated/floor{dir = 9; heat_capacity = 1e+006; icon_state = "darkred"; tag = "icon-darkred (NORTHWEST)"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aA" = (/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners (NORTH)"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aB" = (/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aC" = (/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners (EAST)"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aD" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "darkred"; tag = "icon-darkred (NORTHEAST)"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aE" = (/obj/structure/alien/weeds/node,/obj/structure/alien/resin/wall,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aF" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/item/clothing/under/rank/security/science,/obj/item/clothing/suit/armor/vest,/obj/item/weapon/melee/baton/loaded,/obj/item/clothing/head/helmet,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aG" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners (NORTH)"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aH" = (/obj/machinery/gateway{dir = 9},/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aI" = (/obj/machinery/gateway{dir = 1},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aJ" = (/obj/machinery/gateway{dir = 5},/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aK" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aL" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aM" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aN" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aO" = (/obj/machinery/light{dir = 8},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aP" = (/obj/machinery/gateway{dir = 8},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aQ" = (/obj/machinery/gateway/centeraway{calibrated = 0},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aR" = (/obj/machinery/gateway{dir = 4},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aS" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aT" = (/obj/item/weapon/ore/iron{pixel_x = 7; pixel_y = -6},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aU" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/queen/large{desc = "A gigantic alien who is in charge of the hive and all of its loyal servants."; name = "alien queen"; pixel_x = -16},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"aV" = (/turf/simulated/wall,/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aW" = (/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners (WEST)"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aX" = (/obj/machinery/gateway{dir = 10},/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aY" = (/obj/machinery/gateway,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"aZ" = (/obj/machinery/gateway{dir = 6},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"ba" = (/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bb" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"bc" = (/obj/structure/alien/weeds,/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"bd" = (/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"be" = (/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "dark"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bf" = (/obj/machinery/vending/cigarette,/obj/structure/sign/poster{icon_state = "poster7"; pixel_y = 32; serial_number = 7; subtype = 0},/turf/simulated/floor{icon_state = "dark"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bg" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 10; heat_capacity = 1e+006; icon_state = "darkred"; tag = "icon-darkred (SOUTHWEST)"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bi" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "darkredcorners"; tag = "icon-darkredcorners"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bj" = (/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "darkred"; tag = "icon-darkred (SOUTHEAST)"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bk" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/glasses/night,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"bl" = (/obj/structure/alien/weeds,/mob/living/simple_animal/hostile/alien/sentinel,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"bm" = (/turf/simulated/mineral/random/high_chance,/area/mine/explored)
+"bn" = (/obj/machinery/light/small{dir = 8},/obj/structure/sign/poster{icon_state = "poster17"; pixel_x = -32; pixel_y = 0; serial_number = 17; subtype = 0},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bo" = (/obj/item/weapon/cigbutt,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bp" = (/obj/machinery/alarm{frequency = 1439; locked = 1; pixel_y = 23; req_access = "150"},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bq" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/obj/machinery/light/small{dir = 4},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "bar"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"br" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/device/radio/off{pixel_x = -4; pixel_y = 4},/obj/item/device/radio/off{pixel_x = 2},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"bs" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/item/weapon/paper{info = "Log 1: We got our promised supply drop today. We were only meant to get it, what, a week ago? This bloody gateway keeps desyncing itself, and that means subsisting off recycled water and carb packs. No clue where the damn thing connects to on its off days, and HQ say we are 'not to touch it if it isn't linking to command.' We dumped off the assload of crates Jim filled, got our boxes of oxygen, food and drink, and closed the portal.
Log 2: Damn thing is acting up again. Three days no contact this time. I thought I heard clanking noises from it yesterday. Jim is going on about the NT base or some shit. We've been over this before - They don't know we're here, that engineer was too drunk to recognise his suit, especially since I had it painted orange. He's starting to get annoying. We're safe.
Log 2: Really dumb of me but I just waved at an engineer in the outpost, and he waved back. I hope to god he was too dumb or drunk to recognize the suit, because if he isn't then we might have to pull out before they come looking for us.
Log 3: That huge reinforced tumor in their science section has been making a lot of noise lately. I've been hearing some banging and scratching from the other side and I'm kind of glad now that they reinforced this thing so much. I'll be sleeping with my gun under my pillow from now on."; name = "Personal Log"},/turf/simulated/floor/wood{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dt" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective_locked"; locked = 1; name = "personal closet"; req_access_txt = "150"},/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/weapon/suppressor,/turf/simulated/floor/wood{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"du" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/syndie,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/wood{heat_capacity = 1e+006},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dv" = (/obj/structure/closet/secure_closet{desc = "It's a secure locker for personnel. The first card swiped gains control."; icon_broken = "cabinetdetective_broken"; icon_closed = "cabinetdetective"; icon_locked = "cabinetdetective_locked"; icon_off = "cabinetdetective_broken"; icon_opened = "cabinetdetective_open"; icon_state = "cabinetdetective"; locked = 0; name = "personal closet"; req_access_txt = "150"},/obj/item/weapon/spacecash/c50,/turf/simulated/floor/wood{heat_capacity = 1e+006},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dw" = (/obj/machinery/door/airlock/external{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; opacity = 0; req_access_txt = "150"},/turf/simulated/floor/plating{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dx" = (/obj/item/weapon/ore/iron,/obj/item/weapon/ore/iron{pixel_x = -7; pixel_y = -4},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dy" = (/obj/structure/dispenser/oxygen{oxygentanks = 9},/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/turf/simulated/floor/plating{carbon_dioxide = 48.7; dir = 9; heat_capacity = 1e+006; icon_state = "warnplate"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dz" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dA" = (/obj/structure/rack,/obj/item/clothing/suit/space/syndicate/orange,/obj/item/clothing/mask/gas,/obj/item/weapon/pickaxe/drill,/obj/item/clothing/head/helmet/space/syndicate/orange,/turf/simulated/floor/plating{carbon_dioxide = 48.7; dir = 5; heat_capacity = 1e+006; icon_state = "warnplate"; nitrogen = 13.2; oxygen = 32.4; tag = "icon-warnplate (NORTHEAST)"; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dB" = (/obj/item/weapon/ore/iron{pixel_x = -3; pixel_y = 9},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dC" = (/turf/simulated/mineral,/area/mine/explored)
+"dD" = (/obj/structure/sign/vacuum{desc = "A warning sign which reads 'HOSTILE ATMOSPHERE AHEAD'"; name = "\improper HOSTILE ATMOSPHERE AHEAD"; pixel_x = 0; pixel_y = -32},/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/plating{carbon_dioxide = 48.7; dir = 10; heat_capacity = 1e+006; icon_state = "warnplate"; nitrogen = 13.2; oxygen = 32.4; tag = "icon-warnplate (SOUTHWEST)"; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dE" = (/turf/simulated/floor/plating{broken = 1; carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_state = "platingdmg1"; nitrogen = 13.2; oxygen = 32.4; tag = "icon-platingdmg1"; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dF" = (/obj/structure/rack,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{carbon_dioxide = 48.7; dir = 6; heat_capacity = 1e+006; icon_state = "warnplate"; nitrogen = 13.2; oxygen = 32.4; tag = "icon-warnplate (SOUTHEAST)"; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dG" = (/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dH" = (/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_2"},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dI" = (/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/obj/item/device/mining_scanner,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dJ" = (/obj/item/device/flashlight/lantern{icon_state = "lantern-on"; on = 1},/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dK" = (/obj/machinery/door/airlock/external{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; opacity = 0; req_access_txt = "150"},/turf/simulated/floor/plating{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_plating = "asteroidplating"; icon_state = "asteroidplating"; nitrogen = 13.2; oxygen = 32.45; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dL" = (/obj/item/weapon/storage/bag/ore,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dM" = (/obj/item/weapon/pickaxe/drill,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dN" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_plating = "asteroidplating"; icon_state = "asteroidplating"; nitrogen = 13.2; oxygen = 32.45; temperature = 251},/area/awaycontent/a4{name = "Syndicate Outpost"})
+"dO" = (/turf/simulated/floor/plating{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_plating = "asteroidplating"; icon_state = "asteroidplating"; nitrogen = 13.2; oxygen = 32.45; temperature = 251},/area/mine/explored)
+"dP" = (/obj/item/weapon/ore/iron{pixel_x = -7; pixel_y = -4},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dQ" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/obj/item/weapon/tank/oxygen,/obj/item/clothing/suit/space/syndicate/orange,/obj/item/clothing/mask/gas,/obj/item/clothing/head/helmet/space/syndicate/orange,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dR" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood,/mob/living/simple_animal/hostile/alien/drone,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dS" = (/obj/machinery/light/small,/turf/simulated/floor/plating/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/mine/explored)
+"dT" = (/turf/simulated/wall/r_wall/rust,/area/awaycontent/a2{name = "MO19 Research"})
+"dU" = (/turf/simulated/wall/r_wall,/area/awaycontent/a2{name = "MO19 Research"})
+"dV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaybiohazard"; name = "Acid-Proof biohazard containment door"; unacidable = 1},/obj/machinery/door/poddoor{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaybiohazard"; layer = 2.9; name = "Acid-Proof biohazard containment door"; unacidable = 1},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"dW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaybiohazard"; name = "Acid-Proof biohazard containment door"; unacidable = 1},/obj/machinery/door/poddoor{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaybiohazard"; layer = 2.9; name = "Acid-Proof biohazard containment door"; unacidable = 1},/obj/structure/window/reinforced{dir = 4; layer = 3.2},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"dX" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/awaycontent/a2{name = "MO19 Research"})
+"dY" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "dark"},/area/awaycontent/a2{name = "MO19 Research"})
+"dZ" = (/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{name = "MO19 Research"})
+"ea" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eb" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister,/obj/structure/alien/weeds,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"ec" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"ed" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 10},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"ee" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"ef" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/shieldwallgen{locked = 0; req_access = null},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eg" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eh" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"ei" = (/obj/structure/alien/weeds,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"ej" = (/obj/machinery/light{active_power_usage = 0; dir = 1; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"ek" = (/obj/machinery/sparker{desc = "A wall-mounted ignition device. This one has been applied with an acid-proof coating."; id = "awayxenobio"; name = "Acid-Proof mounted igniter"; pixel_x = 0; pixel_y = 25; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"el" = (/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"em" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"en" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eo" = (/obj/machinery/vending/coffee,/turf/simulated/floor{icon_state = "dark"},/area/awaycontent/a2{name = "MO19 Research"})
+"ep" = (/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eq" = (/obj/machinery/light/small{active_power_usage = 0; dir = 4; icon_state = "bulb-broken"; status = 2},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{name = "MO19 Research"})
+"er" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"es" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold{dir = 4; icon_state = "manifold"; level = 2},/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"et" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/structure/alien/weeds,/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"eu" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4; layer = 2.9},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"ev" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall/r_wall,/area/awaycontent/a2{name = "MO19 Research"})
+"ew" = (/obj/structure/alien/weeds/node,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"ex" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"ey" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"ez" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eA" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eB" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eC" = (/obj/structure/alien/weeds,/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eD" = (/turf/simulated/wall,/area/awaycontent/a2{name = "MO19 Research"})
+"eE" = (/turf/simulated/wall/rust,/area/awaycontent/a2{name = "MO19 Research"})
+"eF" = (/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"eG" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"eH" = (/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"eI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/general/visible,/obj/structure/stool/bed/chair/office/light{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"eJ" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "Awaylab"; name = "Containment Chamber Blast Doors"; pixel_x = 4; pixel_y = -2; req_access_txt = "201"},/obj/machinery/ignition_switch{id = "awayxenobio"; pixel_x = 4; pixel_y = 8},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"eK" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4; layer = 2.9},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eL" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eM" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eN" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"eO" = (/obj/machinery/power/port_gen/pacman{desc = "A portable generator for emergency backup power. This one looks old and the knobs are rusted shut."; name = "Broken-down P.A.C.M.A.N.-type portable generator"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eP" = (/obj/machinery/power/port_gen/pacman/super{desc = "A portable generator for emergency backup power. This one looks old and the knobs are rusted shut."; name = "Broken-down S.U.P.E.R.P.A.C.M.A.N.-type portable generator"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg2"; tag = "icon-platingdmg2"},/area/awaycontent/a2{name = "MO19 Research"})
+"eQ" = (/obj/machinery/space_heater,/obj/machinery/light/small{dir = 1},/obj/structure/sign/poster{icon_state = "poster5_legit"; pixel_x = 0; pixel_y = 32; serial_number = 21; subtype = 1},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eR" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/alarm{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eS" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/smes{charge = 1.5e+006; input_level = 10000; inputting = 0; output_level = 15000; outputting = 1},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eT" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/weapon/newspaper,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a2{name = "MO19 Research"})
+"eW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eX" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "201"; req_one_access_txt = "0"},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"eZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 5; icon_state = "ltrails_1"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"fa" = (/obj/structure/sign/securearea{pixel_x = 32},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"fb" = (/obj/structure/table,/obj/machinery/reagentgrinder,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{name = "MO19 Research"})
+"fc" = (/obj/structure/table,/obj/item/stack/sheet/mineral/plasma{layer = 2.9},/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/obj/machinery/alarm{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fd" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/box/syringes,/obj/structure/alien/weeds,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fe" = (/obj/structure/closet/crate/freezer,/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/obj/item/xenos_claw,/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{name = "MO19 Research"})
+"ff" = (/obj/machinery/door/firedoor,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"fg" = (/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"fh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/general/visible,/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"fi" = (/obj/structure/closet/l3closet/scientist,/obj/structure/window/reinforced,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"fj" = (/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4; layer = 2.9},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fk" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/weeds{desc = "A large mottled egg."; health = 100; icon_state = "egg_hatched"; name = "egg"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fl" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fm" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fn" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fo" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg1"; tag = "icon-platingdmg1"},/area/awaycontent/a2{name = "MO19 Research"})
+"fq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fr" = (/obj/structure/extinguisher_cabinet{pixel_x = -26},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; icon_state = "ltrails_2"},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"fs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/alien/weeds,/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"ft" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; name = "Xenobiology Lab"; opacity = 0; req_access_txt = "201"},/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fu" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a2{name = "MO19 Research"})
+"fv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"fx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/alien/weeds/node,/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"fy" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/general/visible{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"fz" = (/obj/machinery/atmospherics/pipe/simple/general/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/item/stack/rods,/obj/item/stack/cable_coil{amount = 5},/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"fA" = (/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/machinery/atmospherics/pipe/simple/general/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/item/stack/rods,/obj/item/stack/cable_coil{amount = 5},/obj/item/weapon/shard{icon_state = "medium"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fB" = (/obj/machinery/atmospherics/pipe/simple/general/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fC" = (/obj/machinery/atmospherics/pipe/simple/general/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fD" = (/obj/machinery/atmospherics/pipe/simple/general/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fE" = (/obj/machinery/atmospherics/pipe/simple/general/visible{desc = "A one meter section of pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof Pipe"; unacidable = 1},/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fF" = (/obj/machinery/atmospherics/unary/outlet_injector{desc = "Has a valve and pump attached to it. This one has been applied with an acid-proof coating."; dir = 8; icon_state = "on"; name = "Acid-Proof Air Injector"; on = 1; unacidable = 1},/obj/structure/alien/weeds,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fG" = (/obj/machinery/light{active_power_usage = 0; dir = 4; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fH" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fI" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fJ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fK" = (/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fL" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fM" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/effect/decal/cleanable/oil,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fO" = (/obj/structure/filingcabinet,/obj/item/weapon/paper{info = "Entry One - 27/05/2554: I just arrived, and already I hate my job. I'm stuck on this shithole of an outpost, trying to avoid these damn eggheads running all over the place preparing for god knows what. There's no crimes to stop, no syndies to kill, and I'm not even allowed to beat the fuckin' assistant senseless! They said I was transferred from Space Station 13 for 'good behavior', but this feels more like a punishment than a reward. All I know is that if I don't get some action soon, I'm going to go insane.
Entry Two - 03/06/2554: Okay, so get this: we got a fuckin' deathsquad coming in today! I thought the day I saw one of them would be the day my employment was 'terminated', if you get my drift. They're escorting some sort of weird alien creature for the eggheads to study. I heard one of the docs telling the chef that this thing killed a whole security force before it was captured. I sure as hell hope that I don't have to fight it.
Entry Three - 08/06/2554: My first real bit of 'action' today, if you could call it that. Crazy Ivan got in a fight with Kuester today about his Booze-O-Mat. Apparently one of the crewmembers had stolen a couple bottles of booze from the machine after Ivan disabled the ID lock. Tell you the truth, I don't blame the thief. Everyone is going a little stir-crazy in here, and the bartender is being damn stingy with the alcohol. Either way, once they started to pick a fight, I had to take them down. It's a damn shame that we don't have a brig, though. I had to lock Ivan in a fuckin' freezer, for god's sake. Let's hope that we can keep our sanity together, at least for a while.
Entry Four - 10/06/2554: Jesus fucking Christ riding on a motorbike. These things the scientists are studying are terrifying! Fucking great huge purple bug things as tall as the ceiling, with blades for arms and drooling at the mouth. I don't think my taser will do jack shit against these damn things, but the eggheads say that they're safely contained. If they do, I have a feeling that it's only a matter of time before we're all screwed. These bastards look like walking death.
Entry Five - 18/06/2554: Finally caught who stole the booze from Kuester. It was that fuckin' loser assistant Steve! He was in the dorms, chugging his worries away. I took one of the bottles back to the barkeep, but no one has to know about this second one. I think I'm gonna enjoy this while watching tomorrow's Thunderdome match.
Entry Six - 19/06/2554: Oh, great. The chef is still sleeping, so we get Ivan's gruel for breakfast today. I overheard Sano and Douglas saying something about the aliens being restless, so we might get some action today. As long as it happens after the big game, I'm fine with it. I still got one beer to drink before I'm ready to die."; name = "Personal Log - Kenneth Cunningham"},/turf/simulated/floor{dir = 9; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"fP" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "201"},/obj/item/clothing/suit/armor/vest,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/grenade/flashbang,/obj/item/weapon/storage/belt/security,/obj/item/weapon/reagent_containers/food/drinks/beer{pixel_x = -3; pixel_y = -2},/obj/machinery/alarm{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"fQ" = (/obj/structure/sign/poster{icon_state = "poster21_legit"; pixel_y = 32; serial_number = 21; subtype = 1},/turf/simulated/floor{dir = 5; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"fR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fS" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"fT" = (/obj/structure/sign/biohazard{pixel_x = 32},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"fU" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fV" = (/obj/machinery/door/firedoor,/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -29},/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"fW" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/closet/l3closet/scientist,/obj/structure/alien/weeds,/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"fX" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/item/stack/cable_coil{amount = 1; icon_state = "coil_red1"; item_state = "coil_red1"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"fY" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/cleanable/blood,/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"fZ" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/effect/decal/cleanable/blood/gibs,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"ga" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_impregnated"; item_state = "facehugger_impregnated"; stat = 2},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"gb" = (/obj/structure/stool,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gc" = (/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{name = "MO19 Research"})
+"gd" = (/obj/effect/decal/cleanable/oil,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"ge" = (/obj/structure/reagent_dispensers/peppertank{pixel_x = -30; pixel_y = 0},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"gf" = (/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"gg" = (/obj/machinery/door/airlock/glass_security{name = "Security Post"; req_access_txt = "201"},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"gh" = (/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; icon_state = "ltrails_1"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"gi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/firealarm{dir = 4; pixel_x = 28},/obj/structure/alien/weeds,/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"gj" = (/obj/structure/table,/obj/item/weapon/scalpel{pixel_y = 12},/obj/item/weapon/circular_saw,/obj/item/weapon/razor{pixel_y = 5},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "warnwhite"},/area/awaycontent/a2{name = "MO19 Research"})
+"gk" = (/obj/structure/alien/weeds/node,/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "warnwhite"},/area/awaycontent/a2{name = "MO19 Research"})
+"gl" = (/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "warnwhite"},/area/awaycontent/a2{name = "MO19 Research"})
+"gm" = (/obj/structure/table,/obj/item/device/mmi,/obj/item/device/mmi,/obj/item/device/mmi,/obj/structure/alien/weeds,/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "warnwhite"},/area/awaycontent/a2{name = "MO19 Research"})
+"gn" = (/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"go" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds,/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"gp" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4; layer = 2.9},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gq" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 4; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds,/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"gr" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 2; icon_state = "pipe-c"; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"gs" = (/obj/structure/table,/obj/effect/decal/cleanable/dirt,/obj/machinery/cell_charger,/obj/item/weapon/stock_parts/cell/high,/obj/item/device/radio/off,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gt" = (/obj/structure/table,/obj/item/weapon/paper{info = "Ivan Volodin Stories:
Entry Won - 28/05/2554: Hello. I am Crazy Ivan. Boss say I must write. I do good job fixing outpost. Is very good job. Much better than mines. Many nice people. I cause no trouble.
Entry Too - 05/06/2554: I am finding problem with Booze-O-Mat. Is not problem. I solve very easy. Use yellow tool to make purple light go off. I am good engineer! Bartender will be very happy.
Entry Tree - 08/06/2554: Bartender is not happy. Security man is not happy. Cannot feel legs, is very cold in freezer. Is not good. Table is jammed into door, have no tools. Is very not good. But, on bright side, found meat! Shall chew to keep spirits up.
Entry Fore - 12/06/2554: Big nasty purple bug looked at me today. Make nervous. Blue wall wire can be broken, then bad thing happens. Very very bad thing. Man in orange spacesuit wave at me today too. He seem nice. Wonder who was?
Entry Fiv - 15/06/2554: I eat cornflakes today. Is good day. Sun shine for a while. Was nice. I also take ride on disposals chute. Was fun, but tiny. Get clog out of pipes, was vodka bottle. Is empty. This make many sads.
Entry Sex: 19/06/2554: Purple bugs jumpy today. When waved, get hiss. Maybe very bad. Maybe just ill. Do not know. Is science problem, is not engineer problem. I eat sandwich. Is glorious job. Wish to never end."; name = "Personal Log - Ivan Volodin"},/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{name = "MO19 Research"})
+"gu" = (/obj/machinery/light/small,/obj/structure/closet/toolcloset,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gv" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gw" = (/obj/machinery/computer/monitor,/obj/structure/cable,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gx" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/newscaster/security_unit{pixel_x = -30; pixel_y = 0},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"gy" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gz" = (/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 8; icon_state = "ltrails_1"},/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"gA" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/stack/rods,/obj/item/weapon/shard,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gB" = (/obj/effect/decal/cleanable/blood/tracks{desc = "Your instincts say you shouldn't be following these."; dir = 6; icon_state = "ltrails_1"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"gC" = (/obj/structure/cable,/obj/machinery/power/apc{cell_type = 15000; dir = 4; locked = 0; name = "Worn-out APC"; pixel_x = 25; req_access = null; start_charge = 100},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"gD" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/item/weapon/hemostat,/obj/structure/alien/weeds,/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"gE" = (/obj/structure/table,/obj/item/weapon/surgical_drapes,/obj/machinery/light/small{active_power_usage = 0; dir = 4; icon_state = "bulb-broken"; status = 2},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"gF" = (/obj/structure/filingcabinet/filingcabinet,/obj/machinery/light/small{active_power_usage = 0; dir = 8; icon_state = "bulb-broken"; status = 2},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 04/06/2554
Report: As expected, all that is left of the monkeys we sent in earlier is a group of xenomorph larvae. It is quite clear that the facehuggers are not selective in their hosts, and so far the gestation process has been shown to have a 100% success rate.
The larvae themselves have been behaving very differently from the lone larva we first observed, and despite shying away from humans they are clearly comfortable with others of their kind. Our previous suspicions on larvae have been confirmed with their demonstration of playfulness: they are not nearly as aggressive or violent when young, before molting to adulthood.
The majority of the play we observed involved a sort of hide-and-seek, and occasionally wrestling by tangling themselves and struggling out of it. While normally we would write these off as instinctual play for honing their skills when they molt, their growth period is so incredibly fast and they are still such adept killers that it would serve no practical purpose. The only explanation for this is perhaps to create bonds and friendships with each other, if that is even possible for such an incredibly hostile race. It may be that they are much more reasonable with each other than other life forms.
It had become clear that now was the best time to extract a xenomorph for dissecting, as these were all still larvae and the queen was still attached to its ovipositor and would be immobile. With the approval of the research director, we sent in our medical robot that had been dubbed 'Head Surgeon' into the containment pen, dropping the shields for only a fraction of a second to allow it entry. The larvae were cautious, but the curiosity of one had him within grabbing range of our robot. It was brought out and quickly euthanized through lethal injection, courtesy of our mechanical doctor."; name = "Larva Xenomorph Social Interactions & Capturing Procedure"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 04/06/2554
Report: I have studied many interesting and diverse life-forms as a xenobiologist ranging from creatures as large as cows, to specimens too small see with the naked eye. This is by far the largest alien I have ever seen. The alien we were previously studying has molted and has become an absolutely enormous creature. Standing at over 15 feet tall and weighing in at likely two tons or more, the xenomorph queen is an absolutely breathtakingly large and cruel monster. Its behavior has changed drastically from when it was a drone, having become far more comfortable with sitting and staring at us, rather than smashing at the windows.
The queen, physiologically speaking, is fairly similar to the other xenomorphs, with a few key differences. Its enormous size demands large legs, while the back seems to be always hunched forward. The dorsal tubes on the back have changed to several large spikes, and we observed the alien now sports a second pair of smaller arms on its chest. The purpose of these secondary arms is still unknown. Finally, the queen's crown has become incredibly large, with what seems to be a retractable slot to hide its head in. The dome appears to be extremely thick near the front, and will likely be able to resist a lot of trauma. Despite the enormous size it has grown to, it is not that much slower than it used to be.
After two hours of doing relatively nothing but staring, the queen began to produce an unusually large amount of resin and weeds, quickly shaping up a large nest that it then hid behind. It then proceeded to smash out all the lights, leaving us with very little to see with our cameras. When we looked through the back cameras, we had discovered that it had grown a large ovipositor, and was releasing large eggs onto the ground. This had us all in agreement that this stage of the life cycle was the queen.
Over the next few hours, the eggs grew to their full sizes, and we provided the subject with new monkey hosts. When they approached the eggs, they opened to release more facehuggers. It seems that we have observed the full cycle of reproduction for this species. We can expect more larvae in the next few hours."; name = "Queen Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 03/06/2554
Report: The other scientists and I can hardly believe our eyes. The snake-like larva has molted into a 7 foot tall insectoid nightmare in just a few hours. It's obvious now as to why such heavy duty containment was needed. It immediately tried to escape however by flinging itself at the window in a flurry of swipes and stabs. It seems its behavior has returned to a state that is very similar to the facehugger, though I doubt with the same intent! Thankfully, our glass and shields have shown to be more than sturdy enough for such a violent creature, and so far, any attempts at the creature escaping have been in vain.
As for its physiology, the creature has an elongated head with what appears to be have an exoskeleton resembling an external rib-cage on the torso. The alien is also fairly skinny with a lean body. The little amount of meat on the alien appears to be entirely muscle. We assume this makes it deceptively strong, while remaining agile at the same time. One of the most interesting things we have seen is its pharyngeal jaw. It has some what of an inner mouth capable of being fired externally at extremely high speeds. It has already caused many dents in the walls and a few small cracks in the window with it. The alien also has a couple of dorsal tubes on its back, their purpose unknown. Finally, this monster sports a long ridged tail, complete with a large and extremely sharp blade at the tip.
Normally I would be absolutely terrified of something like this, but I'm putting my trust in Nanotrasen with the containment. After all, they wouldn't build a cell that could fail to contain its subject, would they?"; name = "Adult Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 03/06/2554
Report: When the larva first emerged from the chest of the monkey, it seemed very curious. It would wander around aimlessly for awhile and then sit still. We are unable to determine the gender of the larva, or even determine if it has a gender. After some time had passed, it seemed to lose interest in its surroundings and sat mostly still while occasionally wagging its tail. We decided to throw in a live mouse to see if it would consume it. The larva quickly attacked and ate the mouse and seemed to get larger very suddenly, this suggests that the larvae are capable of metabolizing and directing all the energy towards growth at previously thought impossible speeds. It is a shame that we cannot observe the process more closely, as we do not currently know how dangerous or violent this creature is or will become as it matures fully.
It is tempting to imagine the possibilities of utilizing such a mechanism. The capability of skipping years of growth time for children, repairing bodily damage in a matter of moments, even its usage in existing cloning technology."; name = "Larva Xenomorph Physiology & Behavior Observation"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 03/06/2554
Report: The test subject we were provided with truly is alien. It is a small spider-like creature with bony legs leading to a smooth body. It has a long tail connected to it, and it has shown extremely aggressive behavior by flinging its entire body at the glass and shields to no avail. While doing so, we noticed there was a small pink hole in the middle of the body.
When we sent in a monkey through the crude but effective disposal tube, the alien immediately jumped at its face and latched on. The monkey was quickly suffocated by its constricting tail, unable to pry off the fingers. The monkey at first seemed to be dead, but was observed to be breathing. The recently named alien 'facehugger' fell off dead and curled its legs up like a spider moments after it had finished with the monkey's body.
While the monkey appeared to be unharmed, we kept it in the cell for a couple more hours until we were horrified to discover it screaming out in pain as a snake-like creature erupted from the monkey's chest! It appears that the 'facehugger' is only the start of this life cycle. The impregnation cycle involving the creatures growing inside the chests of their hosts seems to only be the beginning."; name = "'Facehugger' Xenomorph Physiology & Behavior Observation"},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"gG" = (/obj/structure/table/reinforced,/obj/item/device/radio/off,/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"gH" = (/obj/structure/cable,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/poddoor/preopen{desc = "A heavy duty blast door that opens mechanically. This one has been applied with an acid-proof coating."; id = "Awaylab"; name = "Acid-Proof containment chamber blast door"; unacidable = 1},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4; layer = 2.9},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gI" = (/obj/structure/disposalpipe/segment{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"gJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/item/stack/rods,/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{name = "MO19 Research"})
+"gK" = (/obj/machinery/door_control{id = "Awaybiohazard"; name = "Biohazard Shutter Control"; pixel_x = -25; pixel_y = 0; req_access_txt = "201"},/obj/machinery/light/small{dir = 8},/obj/structure/table,/obj/item/device/radio/off,/obj/item/weapon/screwdriver{pixel_y = 10},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"gL" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gM" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/floor{dir = 4; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"gN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gO" = (/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"gP" = (/obj/machinery/light{active_power_usage = 0; dir = 4; icon_state = "tube-broken"; status = 2},/obj/machinery/alarm{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"gQ" = (/obj/structure/optable,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"gR" = (/obj/machinery/computer/operating,/obj/structure/alien/weeds,/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"gS" = (/obj/structure/table,/obj/item/clothing/gloves/latex,/obj/item/clothing/mask/surgical,/obj/item/clothing/suit/apron/surgical,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"gT" = (/obj/structure/filingcabinet/filingcabinet,/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas Date: 17/06/2554
Report: Earlier today we have observed a new phenomenon with our subjects. While feeding them our last monkey subject and throwing out the box, the aliens merely looked at us instead of infecting the monkey right away. They looked to be collectively distressed as they would no longer be given hosts, where instead we would move to the next phase of the experiment. When I glanced at the gas tanks and piping leading to their cell, I looked back to see all of them were up against the glass, even the queen! It was as if they all understood what was going to happen, even though we knew only the queen had the cognitive capability to do so.
The only explanation for this is a form of communication between the aliens, but we have seen no such action take place anywhere in the cell until now. We also know that regular drone and hunter xenomorphs have no personality or instinct to survive by themselves. Perhaps the queen has a direct link to them? A form of a commander or overseer that controls their every move? A hivemind?"; name = "The Hivemind Hypothesis"},/obj/item/weapon/paper{info = "Researcher: Dr. Sakuma Sano Date: 08/06/2554
Report: The xenomorphs we have come to study here are a remarkable species. They are almost universally aggressive across all castes, showing no remorse or guilt or pause before or after acts of violence. They appear to be a species entirely designed to kill. Oddly enough, even their method of reproduction is a brutal two-for-one method of birthing a new xenomorph and killing its host.
The lone xenomorph we studied only five days ago showed little sign of intelligence. Only a simple drone that flung itself at the safety glass and shields repeatedly and thankfully without success. Once the drone molted into a queen, it became much more calm and calculating, merely looking at us and waiting while building its nest. As the hive grew in size and in numbers, so too did the intelligence of the common hunter and drone. We are still researching how they can communicate with one another and the relationship between the different castes and the queen. We will continue to update our research as we learn more about the species."; name = "A Preliminary Study of Alien Behavior"},/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas Date: 06/06/2554
Report: While observing the growing number of aliens in the containment cell, we began to notice subtle differences that were consistently repeating. Like ants, these creatures clearly have different specialized variations that determine their roles in the hive. We have dubbed the three currently observed castes as Hunters, Drones, and Sentinels.
Hunters have been observed to be by far the most aggressive and agile of the three, constantly running on every surface and frequently swiping at the windows. They are also remarkably good at camouflaging themselves in darkness and on their resin structures, appearing almost invisible to the unwary observer. They are always the first to reach the monkeys we send in leading us to believe that this caste is primarily used for finding and retrieving hosts.
Drones on the other hand are much more docile and seem more shy by comparison, though not any less aggressive than the other castes. They have been observed to have a much wider head and lack dorsal tubes. They have shown to be less agile and visibly more fragile than any other caste. The drone however has never been observed to interact with the monkeys directly and instead preferring maintenance of the hive by building walls of resin and moving eggs around the nest. As far as we know, we have only ever observed a drone become a queen, and we have no way of knowing if the other castes have that capability.
Lastly, we have the Sentinels, which appear at first glance to be the guards of the hive. They have so far been only observed to remain near the queen and the eggs, frequently curled up against the walls. We have only observed one instance where they have interacted with a monkey who strayed too closely to the queen, and was pounced and held down immediately until it was applied with a facehugger. Their lack of movement makes it difficult to determine their exact purpose as guards, sentries, or other role."; name = "The Xenomorph 'Castes'"},/obj/item/weapon/paper{info = "Researcher: Dr. Mark Douglas Date: 04/06/2554
Report: After an extremely dangerous, time consuming and costly dissection, we have managed to record and identify several of the organs inside of the first stage of the xenomorph cycle: the larva. This procedure took an extensive amount of time because these creatures have incredibly, almost-comically acidic blood that can melt through almost anything in a few moments. We had to use over a dozen scalpels and retractors to complete the autopsy.
The larva seems to possess far fewer and quite different organs than that of a human. There is a stomach, with no digestive tract, a heart, which seems to lack any blood-oxygen circulation purpose, and an elongated brain, even though its as dumb as any large cat. It also lacks any liver, kidneys, or other basic organs.
We can't determine the exact nature of how these creatures grow, nor if they gain organs as they become adults. The larger breeds of xenomorph are too dangerous to kill and capture to give us an accurate answer to these questions. All that we can conclude is that being able to function with so little and yet be so deadly means that these creatures are highly evolved and likely to be extremely durable to various hazards that would otherwise be lethal to humans."; name = "Larva Xenomorph Autopsy Report"},/obj/structure/alien/weeds,/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"gU" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor{icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"gV" = (/obj/effect/decal/cleanable/dirt,/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "warning"},/area/awaycontent/a2{name = "MO19 Research"})
+"gW" = (/obj/machinery/shieldwallgen{locked = 0; req_access = null},/obj/structure/cable,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"gX" = (/obj/structure/disposaloutlet{desc = "An outlet for the pneumatic disposal system. This one has been applied with an acid-proof coating."; dir = 1; name = "Acid-Proof disposal outlet"; unacidable = 1},/obj/structure/disposalpipe/trunk{desc = "An underfloor disposal pipe. This one has been applied with an acid-proof coating."; dir = 1; name = "Acid-Proof disposal pipe"; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"gY" = (/obj/machinery/light{active_power_usage = 0; dir = 2; icon_state = "tube-broken"; status = 2},/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"gZ" = (/obj/machinery/sparker{desc = "A wall-mounted ignition device. This one has been applied with an acid-proof coating."; id = "awayxenobio"; name = "Acid-Proof mounted igniter"; pixel_x = 0; pixel_y = -25; unacidable = 1},/obj/structure/alien/weeds{icon_state = "weeds2"},/obj/structure/alien/resin/wall,/turf/simulated/floor/engine,/area/awaycontent/a2{name = "MO19 Research"})
+"ha" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hc" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hd" = (/obj/structure/table,/obj/item/weapon/book/manual/wiki/security_space_law,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 10; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"he" = (/obj/structure/table,/obj/item/weapon/folder/red,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"hf" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor{dir = 6; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a2{name = "MO19 Research"})
+"hg" = (/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"hh" = (/obj/structure/closet/secure_closet{icon_broken = "secureresbroken"; icon_closed = "secureres"; icon_locked = "secureres1"; icon_off = "secureresoff"; icon_opened = "secureresopen"; icon_state = "secureres"; locked = 0; name = "scientist's locker"; req_access_txt = "201"},/obj/item/clothing/suit/labcoat,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hl" = (/obj/structure/window/reinforced,/obj/structure/closet/secure_closet{icon_broken = "secureresbroken"; icon_closed = "secureres"; icon_locked = "secureres1"; icon_off = "secureresoff"; icon_opened = "secureresopen"; icon_state = "secureres1"; locked = 1; name = "scientist's locker"; req_access_txt = "201"},/obj/item/clothing/suit/labcoat,/obj/item/weapon/tank/air,/obj/item/clothing/mask/gas,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hn" = (/obj/machinery/vending/medical{req_access_txt = "201"},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"ho" = (/obj/structure/closet/crate/bin,/obj/item/clothing/gloves/latex,/obj/item/trash/chips,/obj/effect/decal/cleanable/dirt,/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"hp" = (/obj/structure/table,/obj/item/weapon/storage/box/gloves{pixel_x = 0; pixel_y = 0},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"hq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/oil,/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a2{name = "MO19 Research"})
+"hr" = (/obj/structure/closet/secure_closet{icon_broken = "rdsecurebroken"; icon_closed = "rdsecure"; icon_locked = "rdsecure1"; icon_off = "rdsecureoff"; icon_opened = "rdsecureopen"; icon_state = "rdsecure1"; locked = 1; name = "\proper research director's locker"; req_access_txt = "201"},/obj/item/weapon/storage/backpack/satchel_tox,/obj/item/clothing/gloves/latex,/obj/item/clothing/suit/labcoat/science,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{name = "MO19 Research"})
+"hs" = (/obj/structure/table,/obj/item/weapon/cartridge/signal/toxins,/obj/item/weapon/cartridge/signal/toxins{pixel_x = -4; pixel_y = 2},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{name = "MO19 Research"})
+"ht" = (/obj/structure/filingcabinet/chestdrawer,/obj/machinery/light/small{active_power_usage = 0; dir = 1; icon_state = "bulb-broken"; status = 2},/obj/machinery/alarm{frequency = 1439; locked = 0; pixel_y = 23; req_access = null},/obj/item/weapon/paper{info = "Personal Log for Research Director Gerald Rosswell
Entry One - 17/05/2554: You know, I can't believe I took this position so suddenly. I saw that corporate needed a research director for one of it's outposts and thought it would be a cakewalk, there isn't going to be a lot of research to be done on a tiny outpost. Mainly just running scans on the gas giant we are orbiting or some basic RnD. However, they conveniently forgot to tell me that me and my science staff would have to pull double duty as medical staff and that there is no one higher up on the chain of command here, so I get to pull triple duty as acting captain as well! This shit is probably allowed in some 3 point fine print buried underneath the literally thousands of pages of contracts. Well, at least the research will be easy work.
Entry Two - 25/05/2554: Well, we all expected it at the outpost, CentComm has decided to completely change what research we are doing. They've decided that we should be research the species known as 'xenomporphs'. They announced this change 4 days ago and along with it, sadly, the termination of our current science staff barring me. Not to mention the constant noise made by the construction detail they sent to staple on an xenobiology lab ensuring no one has been able to sleep decently ever since they announced the shift. To make matters worse our current security guard actually died of a heart attack today. Just goes to show that 75 year old men shouldn't be security guards. Still can't believe that they decided to do this major change less than a month after the outpost was established.
Entry Three - 27/05/2554: The new security guard arrived today. Apparently transferred here from the research station that also is orbiting the gas giant. He seems to be rather angry about his transfer. Considering the rumors I've heard about the research station he's probably caught off guard by the fact that Steve hasn't tried to force an IED down his throat.
Entry Four - 06/06/2554: My requests for additional security and containment measures for the 'xenomorph' has been denied. Does Central Command not notice how dangerous these creatures are? The only thing keeping them in is a force field, a minor problem with the power grid and the entire hive is loose. What would stop them then, the lone security guard with a dinky little taser? Kenneth can barely handle a short-tempered engineer. We are under equipped and under staffed, we are inevitably going to be destroyed unless we get the equipment and staff we need.
Entry Five - 10/06/2554: Cunningham got a good look at the xenomorph in containment. He was frightened for the rest of the day, rather amusing if it wasn't for the fact that we are all trapped on this scrap heap with naught but a force field keeping those xenomorphs in.
Entry Six - 17/06/2554: The reactions from the specimens today has shown that they possess strange mental properties. Mark hypothesizes that they possibly have a sort of hive mind, while nothing is certain this would explain how xenomorphs seem to have vastly increased intellect when a 'queen' is present. Of course, to test this hypothesis would require many complicated procedures which we will not be able to undertake. But we do not know the full extend of the xenomorph mind, it may or may not be able to find a way to circumvent our containment system. I will resend my request for additional security measures along with this new found information."; name = "Personal Log - Gerald Rosswell"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{name = "MO19 Research"})
+"hu" = (/obj/structure/closet/crate/bin,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{name = "MO19 Research"})
+"hv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/poddoor{id = "AwayRD"; layer = 2.9; name = "privacy shutter"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hw" = (/turf/simulated/floor{dir = 1; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"hx" = (/turf/simulated/floor{dir = 2; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a2{name = "MO19 Research"})
+"hy" = (/obj/structure/window/reinforced,/obj/structure/grille{density = 0; destroyed = 1; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{name = "MO19 Research"})
+"hz" = (/obj/item/stack/rods,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"hA" = (/obj/effect/decal/cleanable/robot_debris,/obj/effect/decal/cleanable/oil,/obj/item/weapon/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/device/healthanalyzer{pixel_x = 6; pixel_y = -5},/obj/item/device/assembly/prox_sensor{pixel_x = -5; pixel_y = -2},/obj/item/robot_parts/l_arm,/turf/simulated/floor{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a2{name = "MO19 Research"})
+"hB" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire{pixel_x = 0; pixel_y = 0},/obj/machinery/firealarm{dir = 4; pixel_x = 28},/turf/simulated/floor{dir = 8; heat_capacity = 1e+006; icon_state = "whitehall"},/area/awaycontent/a2{name = "MO19 Research"})
+"hC" = (/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{name = "MO19 Research"})
+"hD" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{name = "MO19 Research"})
+"hE" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{density = 0; emagged = 1; icon_state = "door_open"; locked = 1; name = "Research Director's Office"; opacity = 0; req_access_txt = "201"; req_one_access_txt = "0"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a2{name = "MO19 Research"})
+"hF" = (/obj/structure/noticeboard{dir = 1; pixel_y = -32},/obj/machinery/light/small{active_power_usage = 0; dir = 2; icon_state = "bulb-broken"; status = 2},/obj/item/weapon/paper{info = "
In The Event of Xenobiology Breach: Evacuate staff, Lock down Xenobiology, Notify on-site superiors and/or Central Command immediatly.
Hello there, proud operator of an NT-Sec Prisoner Rehabilitation Center. A solution to rising crime rates and falling productivity, these facilities are specifically designed for the safe, productive imprisonment of your most dangerous criminals.
To press a long-term prisoner into the service of the station, replace his equipment with prisoners' garb at one of the prison lockers, as per normal operating procedure. Before assigning a prisoner his ID, insert the ID into a prisoner management console and assign the prisoner a quota, based on the severity of his crime. A single sheet of most materials produces five points for the prisoner, and points can be expected to be produced at a rate of about 100 per minute, though punishments as severe as forced labor should be reserved for serious crimes of sentences not less than five minutes long. Once you have prepared the prisoner, place him in the secure northern half of the labor shuttle, and send him to the station. Once he meets his quota by feeding sheets to the stacker, he will be allowed to return to the station, and will be able to open the secure door to the prisoner release area.
"
@@ -748,7 +751,7 @@ var/global/datum/controller/supply_shuttle/supply_shuttle
temp += " Main Menu"
*/
else if (href_list["viewrequests"])
- temp = "Main Menu
Current requests:
"
+ temp = "Current requests:
"
for(var/S in supply_shuttle.requestlist)
var/datum/supply_order/SO = S
temp += "#[SO.ordernum] - [SO.object.name] requested by [SO.orderedby] [supply_shuttle.moving ? "":supply_shuttle.at_station ? "":"ApproveRemove"] "
@@ -793,5 +796,7 @@ var/global/datum/controller/supply_shuttle/supply_shuttle
frequency.post_signal(src, status_signal)
+/obj/machinery/computer/supplycomp/say_quote(text)
+ return "flashes, \"[text]\""
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index e98fec043ed..4f8b2e771e7 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -81,7 +81,7 @@
var/record_id_num = 1001
/obj/effect/datacore/proc/manifest_inject(var/mob/living/carbon/human/H)
- if(H.mind && (H.mind.assigned_role != "MODE"))
+ if(H.mind && (H.mind.need_job_assign))
var/assignment
if(H.mind.assigned_role)
assignment = H.mind.assigned_role
diff --git a/code/datums/disease.dm b/code/datums/disease.dm
index 3a37ce32022..d7d98405710 100644
--- a/code/datums/disease.dm
+++ b/code/datums/disease.dm
@@ -52,6 +52,8 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
var/requires = 0
var/list/required_limb = list()
+ var/const/non_threat = "Non-Threat"
+
/datum/disease/proc/stage_act()
var/cure_present = has_cure()
@@ -204,7 +206,7 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
/datum/disease/proc/GetDiseaseID()
return src.type
-/*
+
/datum/disease/Del()
active_diseases.Remove(src)
-*/
+ ..()
diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm
index 52e20c2c07b..b356109b1b2 100644
--- a/code/datums/diseases/advance/advance.dm
+++ b/code/datums/diseases/advance/advance.dm
@@ -182,7 +182,7 @@ var/list/advance_cures = list(
CRASH("We did not have any symptoms before generating properties.")
return
- var/list/properties = list("resistance" = 1, "stealth" = 1, "stage_rate" = 1, "transmittable" = 1, "severity" = 1)
+ var/list/properties = list("resistance" = 1, "stealth" = 1, "stage_rate" = 1, "transmittable" = 1, "severity" = 0)
for(var/datum/symptom/S in symptoms)
@@ -190,7 +190,7 @@ var/list/advance_cures = list(
properties["stealth"] += S.stealth
properties["stage_rate"] += S.stage_speed
properties["transmittable"] += S.transmittable
- properties["severity"] = max(properties["severity"], S.level) // severity is based on the highest level symptom
+ properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity symptom
return properties
@@ -234,7 +234,7 @@ var/list/advance_cures = list(
switch(level_sev)
if(-INFINITY to 0)
- severity = "Non-Threat"
+ severity = non_threat
if(1)
severity = "Minor"
if(2)
diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm
index 3ef4df27119..d56c8421f2d 100644
--- a/code/datums/diseases/advance/symptoms/beard.dm
+++ b/code/datums/diseases/advance/symptoms/beard.dm
@@ -22,6 +22,7 @@ BONUS
stage_speed = -3
transmittable = -1
level = 4
+ severity = 1
/datum/symptom/beard/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/choking.dm b/code/datums/diseases/advance/symptoms/choking.dm
index f5b21f08dca..e068adf4835 100644
--- a/code/datums/diseases/advance/symptoms/choking.dm
+++ b/code/datums/diseases/advance/symptoms/choking.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = -2
transmittable = -4
level = 3
+ severity = 3
/datum/symptom/choking/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/confusion.dm b/code/datums/diseases/advance/symptoms/confusion.dm
index 9bc2b6769c2..0fbc941a32f 100644
--- a/code/datums/diseases/advance/symptoms/confusion.dm
+++ b/code/datums/diseases/advance/symptoms/confusion.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = -3
transmittable = 0
level = 4
+ severity = 2
/datum/symptom/confusion/Activate(var/datum/disease/advance/A)
diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm
index 5e0675c40c4..2c50271aa92 100644
--- a/code/datums/diseases/advance/symptoms/cough.dm
+++ b/code/datums/diseases/advance/symptoms/cough.dm
@@ -23,6 +23,7 @@ BONUS
stage_speed = 1
transmittable = 2
level = 1
+ severity = 1
/datum/symptom/cough/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm
index 2b210fc1f60..a5394222876 100644
--- a/code/datums/diseases/advance/symptoms/deafness.dm
+++ b/code/datums/diseases/advance/symptoms/deafness.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = -1
transmittable = -3
level = 4
+ severity = 3
/datum/symptom/deafness/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/dizzy.dm b/code/datums/diseases/advance/symptoms/dizzy.dm
index 14a01866ff4..a7109a316ac 100644
--- a/code/datums/diseases/advance/symptoms/dizzy.dm
+++ b/code/datums/diseases/advance/symptoms/dizzy.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = -3
transmittable = -1
level = 4
+ severity = 2
/datum/symptom/dizzy/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/fever.dm b/code/datums/diseases/advance/symptoms/fever.dm
index f24e789810f..749bab09fea 100644
--- a/code/datums/diseases/advance/symptoms/fever.dm
+++ b/code/datums/diseases/advance/symptoms/fever.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = 3
transmittable = 2
level = 2
+ severity = 2
/datum/symptom/fever/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm
index 2d8a9027613..8c71d05f2bd 100644
--- a/code/datums/diseases/advance/symptoms/flesh_eating.dm
+++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = 0
transmittable = -4
level = 6
+ severity = 5
/datum/symptom/flesh_eating/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/genetics.dm b/code/datums/diseases/advance/symptoms/genetics.dm
index fdf3975ecba..065bf9d3ed1 100644
--- a/code/datums/diseases/advance/symptoms/genetics.dm
+++ b/code/datums/diseases/advance/symptoms/genetics.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = 0
transmittable = -3
level = 6
+ severity = 3
var/good_mutations = 0
var/archived_dna = null
@@ -78,4 +79,5 @@ Bonus
stage_speed = -7
transmittable = -7
level = 6
- good_mutations = 1
\ No newline at end of file
+ good_mutations = 1
+ severity = 0
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/hallucigen.dm b/code/datums/diseases/advance/symptoms/hallucigen.dm
index 5e0f0aa4731..4854b8d3261 100644
--- a/code/datums/diseases/advance/symptoms/hallucigen.dm
+++ b/code/datums/diseases/advance/symptoms/hallucigen.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = -3
transmittable = -1
level = 5
+ severity = 3
/datum/symptom/hallucigen/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/headache.dm b/code/datums/diseases/advance/symptoms/headache.dm
index 691b7bf3122..abbb0c44f9b 100644
--- a/code/datums/diseases/advance/symptoms/headache.dm
+++ b/code/datums/diseases/advance/symptoms/headache.dm
@@ -24,6 +24,7 @@ BONUS
stage_speed = 2
transmittable = 0
level = 1
+ severity = 1
/datum/symptom/headache/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/itching.dm b/code/datums/diseases/advance/symptoms/itching.dm
index f4b69c364ab..e7302c4345a 100644
--- a/code/datums/diseases/advance/symptoms/itching.dm
+++ b/code/datums/diseases/advance/symptoms/itching.dm
@@ -24,6 +24,7 @@ BONUS
stage_speed = 3
transmittable = 1
level = 1
+ severity = 1
/datum/symptom/itching/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm
index 69ffefad263..d1c2317b868 100644
--- a/code/datums/diseases/advance/symptoms/shedding.dm
+++ b/code/datums/diseases/advance/symptoms/shedding.dm
@@ -22,6 +22,7 @@ BONUS
stage_speed = -1
transmittable = 2
level = 4
+ severity = 1
/datum/symptom/shedding/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm
index e87b395b13a..ac13329d12c 100644
--- a/code/datums/diseases/advance/symptoms/shivering.dm
+++ b/code/datums/diseases/advance/symptoms/shivering.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = 2
transmittable = 2
level = 2
+ severity = 2
/datum/symptom/shivering/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm
index 155e71839a4..f26a0c78b66 100644
--- a/code/datums/diseases/advance/symptoms/sneeze.dm
+++ b/code/datums/diseases/advance/symptoms/sneeze.dm
@@ -24,6 +24,7 @@ Bonus
stage_speed = 0
transmittable = 4
level = 1
+ severity = 1
/datum/symptom/sneeze/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/symptoms.dm b/code/datums/diseases/advance/symptoms/symptoms.dm
index 349809b973e..4b06cb505db 100644
--- a/code/datums/diseases/advance/symptoms/symptoms.dm
+++ b/code/datums/diseases/advance/symptoms/symptoms.dm
@@ -12,8 +12,10 @@ var/global/const/SYMPTOM_ACTIVATION_PROB = 3
var/resistance = 0
var/stage_speed = 0
var/transmittable = 0
- // The type level of the symptom. Higher is more lethal and harder to generate.
+ // The type level of the symptom. Higher is harder to generate.
var/level = 0
+ // The severity level of the symptom. Higher is more dangerous.
+ var/severity = 0
// The hash tag for our diseases, we will add it up with our other symptoms to get a unique id! ID MUST BE UNIQUE!!!
var/id = ""
diff --git a/code/datums/diseases/advance/symptoms/visionloss.dm b/code/datums/diseases/advance/symptoms/visionloss.dm
index 466809d32e8..47303b9643a 100644
--- a/code/datums/diseases/advance/symptoms/visionloss.dm
+++ b/code/datums/diseases/advance/symptoms/visionloss.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = -4
transmittable = -3
level = 5
+ severity = 4
/datum/symptom/visionloss/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/vitiligo.dm b/code/datums/diseases/advance/symptoms/vitiligo.dm
index 21036166dbe..e24be2c36b5 100644
--- a/code/datums/diseases/advance/symptoms/vitiligo.dm
+++ b/code/datums/diseases/advance/symptoms/vitiligo.dm
@@ -22,6 +22,7 @@ BONUS
stage_speed = -1
transmittable = -2
level = 5
+ severity = 1
/datum/symptom/vitiligo/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm
index 655cbc65c10..02f352f3550 100644
--- a/code/datums/diseases/advance/symptoms/voice_change.dm
+++ b/code/datums/diseases/advance/symptoms/voice_change.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = -3
transmittable = -1
level = 6
+ severity = 2
/datum/symptom/voice_change/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm
index 79a3d82c7c4..67f53564deb 100644
--- a/code/datums/diseases/advance/symptoms/vomit.dm
+++ b/code/datums/diseases/advance/symptoms/vomit.dm
@@ -27,6 +27,7 @@ Bonus
stage_speed = 0
transmittable = 1
level = 3
+ severity = 4
/datum/symptom/vomit/Activate(var/datum/disease/advance/A)
..()
@@ -78,6 +79,7 @@ Bonus
stage_speed = -1
transmittable = 1
level = 4
+ severity = 5
/datum/symptom/vomit/blood/Vomit(var/mob/living/M)
diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm
index 911efef1a7d..3734176978c 100644
--- a/code/datums/diseases/advance/symptoms/weight.dm
+++ b/code/datums/diseases/advance/symptoms/weight.dm
@@ -23,6 +23,7 @@ Bonus
stage_speed = -2
transmittable = -2
level = 4
+ severity = 1
/datum/symptom/weight_gain/Activate(var/datum/disease/advance/A)
..()
@@ -64,6 +65,7 @@ Bonus
stage_speed = -2
transmittable = -2
level = 3
+ severity = 1
/datum/symptom/weight_loss/Activate(var/datum/disease/advance/A)
..()
diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm
index f5d6ceef2bd..8a628eefd62 100644
--- a/code/datums/diseases/appendicitis.dm
+++ b/code/datums/diseases/appendicitis.dm
@@ -9,7 +9,7 @@
permeability_mod = 1
contagious_period = 9001 //slightly hacky, but hey! whatever works, right?
desc = "If left untreated the subject will become very weak, and may vomit often."
- severity = "Medium"
+ severity = "Dangerous!"
longevity = 1000
hidden = list(0, 1)
requires = 1
@@ -35,7 +35,8 @@
if(prob(1))
if (affected_mob.nutrition > 100)
affected_mob.Stun(rand(4,6))
- affected_mob.show_message("[affected_mob] throws up!")
+ affected_mob.visible_message("[affected_mob] throws up!", \
+ "[affected_mob] throws up!")
playsound(affected_mob.loc, 'sound/effects/splat.ogg', 50, 1)
var/turf/location = affected_mob.loc
if(istype(location, /turf/simulated))
diff --git a/code/datums/diseases/brainrot.dm b/code/datums/diseases/brainrot.dm
index 782e518ffd7..971755d070d 100644
--- a/code/datums/diseases/brainrot.dm
+++ b/code/datums/diseases/brainrot.dm
@@ -10,7 +10,7 @@
curable = 0
cure_chance = 15//higher chance to cure, since two reagents are required
desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication."
- severity = "Major"
+ severity = "Dangerous!"
requires = 1
required_limb = list(/obj/item/organ/limb/head)
diff --git a/code/datums/diseases/cold9.dm b/code/datums/diseases/cold9.dm
index e22016eb01f..0e7847588fa 100644
--- a/code/datums/diseases/cold9.dm
+++ b/code/datums/diseases/cold9.dm
@@ -8,7 +8,7 @@
agent = "ICE9-rhinovirus"
affected_species = list("Human")
desc = "If left untreated the subject will slow, as if partly frozen."
- severity = "Moderate"
+ severity = "Medium"
/datum/disease/cold9/stage_act()
..()
diff --git a/code/datums/diseases/fake_gbs.dm b/code/datums/diseases/fake_gbs.dm
index a56e62c28d0..9700cd120a5 100644
--- a/code/datums/diseases/fake_gbs.dm
+++ b/code/datums/diseases/fake_gbs.dm
@@ -8,7 +8,7 @@
agent = "Gravitokinetic Bipotential SADS-"
affected_species = list("Human", "Monkey")
desc = "If left untreated death will occur."
- severity = "Major"
+ severity = "BIOHAZARD THREAT!"
/datum/disease/fake_gbs/stage_act()
..()
diff --git a/code/datums/diseases/fluspanish.dm b/code/datums/diseases/fluspanish.dm
index ef85ab1961d..6d8a9c9a290 100644
--- a/code/datums/diseases/fluspanish.dm
+++ b/code/datums/diseases/fluspanish.dm
@@ -9,7 +9,7 @@
affected_species = list("Human")
permeability_mod = 0.75
desc = "If left untreated the subject will burn to death for being a heretic."
- severity = "Serious"
+ severity = "Dangerous!"
/datum/disease/inquisition/stage_act()
..()
diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm
index 9a677b7111c..9579d8f2036 100644
--- a/code/datums/diseases/gbs.dm
+++ b/code/datums/diseases/gbs.dm
@@ -10,6 +10,7 @@
affected_species = list("Human")
curable = 0
permeability_mod = 1
+ severity = "BIOHAZARD THREAT!"
/datum/disease/gbs/stage_act()
..()
diff --git a/code/datums/diseases/plasmatoid.dm b/code/datums/diseases/plasmatoid.dm
index 232371cd3b2..499edcb5fa1 100644
--- a/code/datums/diseases/plasmatoid.dm
+++ b/code/datums/diseases/plasmatoid.dm
@@ -2,4 +2,5 @@
name = "Plasmatoid"
max_stages = 4
cure = "None"
- affected_species = list("Monkey", "Human")
\ No newline at end of file
+ affected_species = list("Monkey", "Human")
+ severity = "Unknown"
\ No newline at end of file
diff --git a/code/datums/diseases/retrovirus.dm b/code/datums/diseases/retrovirus.dm
index 3c6450ccd8a..40b56b05bf6 100644
--- a/code/datums/diseases/retrovirus.dm
+++ b/code/datums/diseases/retrovirus.dm
@@ -8,7 +8,7 @@
agent = ""
affected_species = list("Human")
desc = "A DNA-altering retrovirus that scrambles the structural and unique enzymes of a host constantly."
- severity = "Severe"
+ severity = "Dangerous!"
permeability_mod = 0.4
stage_prob = 2
var/SE
diff --git a/code/datums/diseases/rhumba_beat.dm b/code/datums/diseases/rhumba_beat.dm
index 9de82ceaac0..09225bf25b1 100644
--- a/code/datums/diseases/rhumba_beat.dm
+++ b/code/datums/diseases/rhumba_beat.dm
@@ -8,6 +8,7 @@
agent = "Unknown"
affected_species = list("Human")
permeability_mod = 1
+ severity = "BIOHAZARD THREAT!"
/datum/disease/rhumba_beat/stage_act()
..()
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index 3526359eadb..71dbe67181e 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -7,7 +7,7 @@
cure = "A coder's love (theoretical)."
agent = "Shenanigans"
affected_species = list("Human", "Monkey", "Alien")
- severity = "Major"
+ severity = "Harmful"
stage_prob = 10
hidden = list(1, 1)
var/list/stage1 = list("You feel unremarkable.")
@@ -78,7 +78,7 @@
curable = 0
longevity = 30
desc = "Monkeys with this disease will bite humans, causing humans to mutate into a monkey."
- severity = "Major"
+ severity = "BIOHAZARD THREAT!"
hidden = list(0, 0)//Not hidden, with the exception of the starting ape.
stage_prob = 4
agent = "Kongey Vibrion M-909"
@@ -123,6 +123,7 @@
cure_chance = 5
agent = "R2D2 Nanomachines"
desc = "This disease, actually acute nanomachine infection, converts the victim into a cyborg."
+ severity = "Dangerous!"
hidden = list(0, 0)
stage1 = null
stage2 = list("Your joints feel stiff.", "Beep...boop..")
@@ -131,6 +132,7 @@
stage5 = list("Your skin feels as if it's about to burst off!")
new_form = /mob/living/silicon/robot
+
/datum/disease/transformation/robot/stage_act()
..()
switch(stage)
@@ -152,6 +154,8 @@
cure_id = list("spaceacillin", "glycerol")
cure_chance = 5
agent = "Rip-LEY Alien Microbes"
+ desc = "This disease changes the victim into a xenomorph."
+ severity = "BIOHAZARD THREAT!"
hidden = list(0, 0)
stage1 = null
stage2 = list("Your throat feels scratchy.", "Kill...")
@@ -179,6 +183,7 @@
cure_chance = 80
agent = "Advanced Mutation Toxin"
desc = "This highly concentrated extract converts anything into more of itself."
+ severity = "BIOHAZARD THREAT!"
hidden = list(0, 0)
stage1 = list("You don't feel very well.")
stage2 = list("You are turning a little green.")
@@ -204,6 +209,7 @@
name = "The Barkening"
cure = "Death"
agent = "Fell Doge Majicks"
+ desc = "This disease transforms the victim into a corgi."
hidden = list(0, 0)
stage1 = list("BARK.")
stage2 = list("You feel the need to wear silly hats.")
diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm
index 42579215037..c8cf37d77aa 100644
--- a/code/datums/diseases/wizarditis.dm
+++ b/code/datums/diseases/wizarditis.dm
@@ -10,7 +10,7 @@
curable = 1
permeability_mod = 0.75
desc = "Some speculate, that this virus is the cause of Wizard Federation existance. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition."
- severity = "Major"
+ severity = "Harmful"
requires = 1
required_limb = list(/obj/item/organ/limb/head)
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 45922040d7f..c5bff0660e2 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -118,6 +118,11 @@
if(teleatom.Move(destturf))
playSpecials(destturf,effectout,soundout)
+ if(isliving(teleatom))
+ var/mob/living/L = teleatom
+ if(L.buckled)
+ L.buckled.unbuckle()
+
destarea.Entered(teleatom)
return 1
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index ce9d2325ad2..b8efb6fa02d 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -37,6 +37,7 @@
var/memory
+ var/need_job_assign = 1 //Whether the job controller should give them a job
var/assigned_role
var/special_role
@@ -45,8 +46,6 @@
var/list/datum/objective/objectives = list()
var/list/datum/objective/special_verbs = list()
- var/has_been_rev = 0//Tracks if this mind has been a rev or not
-
var/list/cult_words = list()
var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
@@ -161,6 +160,11 @@
remove_objectives()
remove_antag_equip()
+
+/datum/mind/proc/remove_gang()
+ ticker.mode.remove_gangster(src,0,1)
+ remove_objectives()
+
/datum/mind/proc/remove_malf()
if(src in ticker.mode.malf_ai)
ticker.mode.malf_ai -= src
@@ -196,6 +200,7 @@
remove_cultist()
remove_rev()
remove_malf()
+ remove_gang()
/datum/mind/proc/show_memory(mob/recipient, window=1)
if(!recipient)
@@ -224,6 +229,7 @@
var/list/sections = list(
"revolution",
+ "gang",
"cult",
"wizard",
"changeling",
@@ -267,6 +273,56 @@
text += "head|loyal|EMPLOYEE|headrev|rev"
sections["revolution"] = text
+ /** GANG ***/
+ text = "gang"
+ if (ticker.mode.config_tag=="gang")
+ text = uppertext(text)
+ text = "[text]: "
+ if (src in ticker.mode.A_bosses)
+ text += "loyal|none|(A)gangsterBOSS|(B) gangsterboss"
+ text += " Flash & Recaller: give"
+
+ var/list/L = current.get_contents()
+ var/obj/item/device/flash/flash = locate() in L
+ if (flash)
+ if(!flash.broken)
+ text += "|take equipment."
+ else
+ text += "|take equipment|repair flash."
+ else
+ text += "."
+
+ if (objectives.len==0)
+ text += " Objectives are empty! Set to kill all rival gang leaders."
+
+
+ else if (src in ticker.mode.B_bosses)
+ text += "loyal|none|(A) gangsterboss|(B)gangsterBOSS"
+ text += " Flash & Recaller: give"
+
+ var/list/L = current.get_contents()
+ var/obj/item/device/flash/flash = locate() in L
+ if (flash)
+ if(!flash.broken)
+ text += " take equipment."
+ else
+ text += " take equipment|repair flash."
+ else
+ text += "."
+
+ if (objectives.len==0)
+ text += " Objectives are empty! Set to kill all rival gang leaders."
+
+ else if (src in ticker.mode.A_gangsters)
+ text += "loyal|none|(A) GANGSTERboss|(B) gangsterboss"
+ else if (src in ticker.mode.B_gangsters)
+ text += "loyal|none|(A) gangsterboss|(B) GANGSTERboss"
+ else if(isloyal(current))
+ text += "LOYAL|none|(A) gangsterboss|(B) gangsterboss"
+ else
+ text += "loyal|NONE|(A) gangsterboss|(B) gangsterboss"
+ sections["gang"] = text
+
/** CULT ***/
text = "cult"
if (ticker.mode.config_tag=="cult")
@@ -448,7 +504,7 @@
out += "Announce objectives
"
- usr << browse(out, "window=edit_memory[src]")
+ usr << browse(out, "window=edit_memory[src];size=400x500")
/datum/mind/Topic(href, href_list)
if(!check_rights(R_ADMIN)) return
@@ -679,16 +735,83 @@
else
flash.broken = 0
- if("reequip")
+ else if (href_list["gang"])
+ switch(href_list["gang"])
+ if("clear")
+ remove_gang()
+ message_admins("[key_name_admin(usr)] has de-gang'ed [current].")
+ log_admin("[key_name(usr)] has de-gang'ed [current].")
+
+ if("agang")
+ if(src in ticker.mode.A_gangsters)
+ return
+ ticker.mode.remove_gangster(src, 0, 2)
+ ticker.mode.add_gangster(src,"A",0)
+ message_admins("[key_name_admin(usr)] has added [current] to the [gang_name("A")] Gang (A).")
+ log_admin("[key_name(usr)] has added [current] to the [gang_name("A")] Gang (A).")
+
+ if("aboss")
+ if(src in ticker.mode.A_bosses)
+ return
+ ticker.mode.remove_gangster(src, 0, 2)
+ ticker.mode.A_bosses += src
+ src.special_role = "[gang_name("A")] Gang (A) Boss"
+ ticker.mode.update_gang_icons_added(src, "A")
+ current << "You are a [gang_name("A")] Gang Boss!"
+ message_admins("[key_name_admin(usr)] has added [current] to the [gang_name("A")] Gang (A) leadership.")
+ log_admin("[key_name(usr)] has added [current] to the [gang_name("A")] Gang (A) leadership.")
+
+ if("bgang")
+ if(src in ticker.mode.B_gangsters)
+ return
+ ticker.mode.remove_gangster(src, 0, 2)
+ ticker.mode.add_gangster(src,"B",0)
+ message_admins("[key_name_admin(usr)] has added [current] to the [gang_name("B")] Gang (B).")
+ log_admin("[key_name(usr)] has added [current] to the [gang_name("B")] Gang (B).")
+
+ if("bboss")
+ if(src in ticker.mode.B_bosses)
+ return
+ ticker.mode.remove_gangster(src, 0, 2)
+ ticker.mode.B_bosses += src
+ src.special_role = "[gang_name("B")] Gang (B) Boss"
+ ticker.mode.update_gang_icons_added(src, "B")
+ current << "You are a [gang_name("B")] Gang Boss!"
+ message_admins("[key_name_admin(usr)] has added [current] to the [gang_name("B")] Gang (B) leadership.")
+ log_admin("[key_name(usr)] has added [current] to the [gang_name("B")] Gang (B) leadership.")
+
+ if("autoobjective")
+ ticker.mode.forge_gang_objectives(src)
+ ticker.mode.greet_gang(src,0)
+ usr << "Unable to equip flash!"
+ if(1)
+ usr << "Unable to equip recaller!"
+ if(0)
+ usr << "Unable to equip both flash and recaller!"
+
+ if("takeequip")
var/list/L = current.get_contents()
var/obj/item/device/flash/flash = locate() in L
+ if (!flash)
+ usr << "Deleting flash failed!"
qdel(flash)
- take_uplink()
- var/fail = 0
- fail |= !ticker.mode.equip_traitor(current, 1)
- fail |= !ticker.mode.equip_revolutionary(current)
- if (fail)
- usr << "Reequipping revolutionary goes wrong!"
+ var/obj/item/device/recaller/recaller = locate() in L
+ if (!recaller)
+ usr << "Deleting recaller failed!"
+ qdel(recaller)
+
+ if("repairflash")
+ var/list/L = current.get_contents()
+ var/obj/item/device/flash/flash = locate() in L
+ if (!flash)
+ usr << "Repairing flash failed!"
+ else
+ flash.broken = 0
else if (href_list["cult"])
switch(href_list["cult"])
@@ -999,7 +1122,6 @@
ticker.mode.syndicates += src
ticker.mode.update_synd_icons_added(src)
special_role = "Syndicate"
- assigned_role = "MODE"
ticker.mode.forge_syndicate_objectives(src)
ticker.mode.greet_syndicate(src)
@@ -1039,7 +1161,6 @@
if(!(src in ticker.mode.wizards))
ticker.mode.wizards += src
special_role = "Wizard"
- assigned_role = "MODE"
//ticker.mode.learn_basic_spells(current)
if(!wizardstart.len)
current.loc = pick(latejoin)
@@ -1119,6 +1240,13 @@
fail |= !ticker.mode.equip_revolutionary(current)
+/datum/mind/proc/make_Gang(var/gang)
+ special_role = "[(gang=="A") ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"] Boss"
+ ticker.mode.update_gang_icons_added(src, gang)
+ ticker.mode.forge_gang_objectives(src, gang)
+ ticker.mode.greet_gang(src)
+ ticker.mode.equip_gang(current)
+
/mob/proc/sync_mind()
mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
mind.active = 1 //indicates that the mind is currently synced with a client
@@ -1149,11 +1277,13 @@
//slime
/mob/living/carbon/slime/mind_initialize()
..()
+ mind.special_role = "slime"
mind.assigned_role = "slime"
//XENO
/mob/living/carbon/alien/mind_initialize()
..()
+ mind.special_role = "Alien"
mind.assigned_role = "Alien"
//XENO HUMANOID
/mob/living/carbon/alien/humanoid/queen/mind_initialize()
@@ -1201,14 +1331,17 @@
/mob/living/simple_animal/mind_initialize()
..()
mind.assigned_role = "Animal"
+ mind.special_role = "Animal"
/mob/living/simple_animal/corgi/mind_initialize()
..()
mind.assigned_role = "Corgi"
+ mind.special_role = "Corgi"
/mob/living/simple_animal/shade/mind_initialize()
..()
mind.assigned_role = "Shade"
+ mind.special_role = "Shade"
/mob/living/simple_animal/construct/mind_initialize()
..()
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index d989b75eb68..0c4398b1c34 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -55,13 +55,10 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
manifest += "
"
for(var/path in contains)
if(!path) continue
- var/atom/movable/AM = new path()
- manifest += "
[AM.name]
"
-// del AM //just to make sure they're deleted, no longer garbage collected, as there are way to many objects in crates that have other references.
- qdel(AM) // How about we fix the issues rather than bypass them, mmkay?
+ var/atom/movable/AM = path
+ manifest += "
[initial(AM.name)]
"
manifest += "
"
-
////// Use the sections to keep things tidy please /Malkevin
//////////////////////////////////////////////////////////////////////////////
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index fa6d850888e..fd78d4a70c9 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -46,7 +46,8 @@ var/list/uplink_items = list()
var/cost = 0
var/last = 0 // Appear last
var/list/gamemodes = list() // Empty list means it is in all the gamemodes. Otherwise place the gamemode name here.
- var/list/excludefrom = list()//Empty list does nothing. Place the name of gamemode you don't want this item to be available in here. This is so you dont have to list EVERY mode to exclude something.
+ var/list/excludefrom = list() //Empty list does nothing. Place the name of gamemode you don't want this item to be available in here. This is so you dont have to list EVERY mode to exclude something.
+ var/surplus = 100 //Chance of being included in the surplus crate (when pick() selects it)
/datum/uplink_item/proc/spawn_item(var/turf/loc, var/obj/item/device/uplink/U)
if(item)
@@ -64,9 +65,6 @@ var/list/uplink_items = list()
if (!user || user.stat || user.restrained())
return 0
- if (!( istype(user, /mob/living/carbon/human)))
- return 0
-
// If the uplink's holder is in the user's contents
if ((U.loc in user.contents || (in_range(U.loc, user) && istype(U.loc.loc, /turf))))
user.set_machine(U)
@@ -75,9 +73,10 @@ var/list/uplink_items = list()
var/obj/I = spawn_item(get_turf(user), U)
- if(istype(I, /obj/item) && ishuman(user))
- var/mob/living/carbon/human/A = user
- A.put_in_any_hand_if_possible(I)
+ if(istype(I, /obj/item))
+ if(ishuman(user))
+ var/mob/living/carbon/human/A = user
+ A.put_in_any_hand_if_possible(I)
if(istype(I,/obj/item/weapon/storage/box/) && I.contents.len>0)
for(var/atom/o in I)
@@ -104,96 +103,108 @@ var/list/uplink_items = list()
name = "Syndicate Revolver"
desc = "The syndicate revolver is a traditional handgun that fires .357 Magnum cartridges and has 7 chambers."
item = /obj/item/weapon/gun/projectile/revolver
- cost = 6
+ cost = 13
+ surplus = 50
/datum/uplink_item/dangerous/pistol
name = "Stechkin Pistol"
desc = "A small, easily concealable handgun that uses 10mm magazines and is compatible with suppressors."
item = /obj/item/weapon/gun/projectile/automatic/pistol
- cost = 5
+ cost = 9
/datum/uplink_item/dangerous/smg
name = "C-20r Submachine Gun"
desc = "A fully-loaded Scarborough Arms-developed submachine gun that fires 12mm automatic rounds with a 20-round magazine."
item = /obj/item/weapon/gun/projectile/automatic/c20r
- cost = 7
+ cost = 14
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 40
/datum/uplink_item/dangerous/machinegun
name = "L6 Squad Automatic Weapon"
- desc = "A traditionally constructed machine gun made by AA-2531. This deadly weapon has a massive 50-round magazine of 7.62×51mm ammunition."
+ desc = "A traditionally constructed machine gun made by AA-2531. This deadly weapon has a massive 50-round magazine of 7.62×51mm ammunition."
item = /obj/item/weapon/gun/projectile/automatic/l6_saw
- cost = 20
+ cost = 40
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 0
/datum/uplink_item/dangerous/crossbow
name = "Miniature Energy Crossbow"
desc = "A short bow mounted across a tiller in miniature. Small enough to fit into a pocket or slip into a bag unnoticed. It fires bolts tipped with toxin, a poison collected from an organism. \
Its bolts stun enemies for short periods, and replenish automatically."
item = /obj/item/weapon/gun/energy/crossbow
- cost = 5
+ cost = 12
excludefrom = list(/datum/game_mode/nuclear)
+ surplus = 50
/datum/uplink_item/dangerous/flamethrower
name = "Flamethrower"
desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen stations. Make a statement by roasting the filth in their own greed. Use with caution."
item = /obj/item/weapon/flamethrower/full/tank
- cost = 6
+ cost = 11
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 40
/datum/uplink_item/dangerous/sword
name = "Energy Sword"
desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be pocketed when inactive. Activating it produces a loud, distinctive noise."
item = /obj/item/weapon/melee/energy/sword
- cost = 4
+ cost = 8
/datum/uplink_item/dangerous/emp
name = "EMP Kit"
desc = "A box that contains two EMP grenades, an EMP implant and a short ranged recharging device disguised as a flashlight. Useful to disrupt communication and silicon lifeforms."
item = /obj/item/weapon/storage/box/syndie_kit/emp
- cost = 3
+ cost = 5
/datum/uplink_item/dangerous/syndicate_minibomb
name = "Syndicate Minibomb"
desc = "The Minibomb is a grenade with a five-second fuse."
item = /obj/item/weapon/grenade/syndieminibomb
- cost = 3
+ cost = 6
/datum/uplink_item/dangerous/viscerators
name = "Viscerator Delivery Grenade"
desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred any non-operatives in the area."
item = /obj/item/weapon/grenade/spawnergrenade/manhacks
- cost = 4
+ cost = 8
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 35
/datum/uplink_item/dangerous/bioterror
name = "Biohazardous Chemical Sprayer"
desc = "A chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger Cooperative, the deadly blend it comes stocked with will disorient, damage, and disable your foes... \
Use with extreme caution, to prevent exposure to yourself and your fellow operatives."
item = /obj/item/weapon/reagent_containers/spray/chemsprayer/bioterror
- cost = 10
+ cost = 20
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 0
/datum/uplink_item/dangerous/gygax
name = "Gygax Exosuit"
desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent for hit-and-run style attacks. \
This model lacks a method of space propulsion, and therefore it is advised to repair the mothership's teleporter if you wish to make use of it."
item = /obj/mecha/combat/gygax/dark/loaded
- cost = 45
+ cost = 90
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 0
/datum/uplink_item/dangerous/mauler
name = "Mauler Exosuit"
desc = "A massive and incredibly deadly Syndicate exosuit. Features long-range targetting, thrust vectoring, and deployable smoke."
item = /obj/mecha/combat/marauder/mauler/loaded
- cost = 70
+ cost = 140
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 0
+
/datum/uplink_item/dangerous/syndieborg
name = "Syndicate Cyborg"
desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel."
item = /obj/item/weapon/antag_spawner/borg_tele
- cost = 25
+ cost = 50
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 0
+
//for refunding the syndieborg teleporter
/datum/uplink_item/dangerous/syndieborg/spawn_item()
var/obj/item/weapon/antag_spawner/borg_tele/T = ..()
@@ -204,18 +215,19 @@ var/list/uplink_items = list()
/datum/uplink_item/ammo
category = "Ammunition"
+ surplus = 40
/datum/uplink_item/ammo/revolver
name = "Ammo-357"
desc = "A box that contains seven additional rounds for the revolver, made using an automatic lathe."
item = /obj/item/ammo_box/a357
- cost = 2
+ cost = 4
/datum/uplink_item/ammo/smg
name = "Ammo-12mm"
desc = "A 20-round .45 ACP magazine for use in the C-20r submachine gun."
item = /obj/item/ammo_box/magazine/c20m
- cost = 1
+ cost = 2
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/pistol
@@ -224,13 +236,35 @@ var/list/uplink_items = list()
item = /obj/item/ammo_box/magazine/m10mm
cost = 1
-/datum/uplink_item/ammo/machinegun
- name = "Ammo-7.62×51mm"
- desc = "A 50-round magazine of 7.62×51mm ammunition for use in the L6 SAW machinegun. By the time you need to use this, you'll already be on a pile of corpses."
- item = /obj/item/ammo_box/magazine/m762
- cost = 6
+/datum/uplink_item/ammo/bullstun
+ name = "Ammo-12g Stun Slug"
+ desc = "An additional 8-round stun slug magazine for use in the Bulldog shotgun. Saying that they're non-lethal would be lying."
+ item = /obj/item/ammo_box/magazine/m12g
+ cost = 2
gamemodes = list(/datum/game_mode/nuclear)
+/datum/uplink_item/ammo/bullbuck
+ name = "Ammo-12g Buckshot"
+ desc = "An alternative 8-round buckshot magazine for use in the Bulldog shotgun. Front towards enemy."
+ item = /obj/item/ammo_box/magazine/m12g/buckshot
+ cost = 2
+ gamemodes = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/ammo/bulldragon
+ name = "Ammo-12g Dragon's Breath"
+ desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. I'm a fire starter, twisted fire starter!"
+ item = /obj/item/ammo_box/magazine/m12g/dragon
+ cost = 3
+ gamemodes = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/ammo/machinegun
+ name = "Ammo-7.62×51mm"
+ desc = "A 50-round magazine of 7.62×51mm ammunition for use in the L6 SAW machinegun. By the time you need to use this, you'll already be on a pile of corpses."
+ item = /obj/item/ammo_box/magazine/m762
+ cost = 12
+ gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 0
+
// STEALTHY WEAPONS
/datum/uplink_item/stealthy_weapons
@@ -241,7 +275,7 @@ var/list/uplink_items = list()
desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a strong anaesthetic and a chemical that is capable of blocking the movement of the vocal chords. \
The pen holds one dose of the mixture, and cannot be refilled."
item = /obj/item/weapon/pen/sleepy
- cost = 2
+ cost = 4
excludefrom = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_weapons/soap
@@ -249,19 +283,21 @@ var/list/uplink_items = list()
desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. You can also drop it underfoot to slip people."
item = /obj/item/weapon/soap/syndie
cost = 1
+ surplus = 50
/datum/uplink_item/stealthy_weapons/detomatix
name = "Detomatix PDA Cartridge"
desc = "When inserted into a personal digital assistant, this cartridge gives you five opportunities to detonate PDAs of crewmembers who have their message feature enabled. \
The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer. It has a chance to detonate your PDA."
item = /obj/item/weapon/cartridge/syndicate
- cost = 3
+ cost = 6
/datum/uplink_item/stealthy_weapons/suppressor
name = "Stetchkin Suppressor"
desc = "Fitted for use on the Stetchkin pistol, this suppressor will make its shots quieter when equipped onto it."
item = /obj/item/weapon/suppressor
- cost = 2
+ cost = 3
+ surplus = 10
// STEALTHY TOOLS
@@ -272,44 +308,53 @@ var/list/uplink_items = list()
name = "Chameleon Jumpsuit"
desc = "A jumpsuit used to imitate the uniforms of Nanotrasen crewmembers."
item = /obj/item/clothing/under/chameleon
- cost = 3
+ cost = 4
/datum/uplink_item/stealthy_tools/chameleon_stamp
name = "Chameleon Stamp"
- desc = "A stamp that can be activated to imitate an official Nanotrasen Stamp™. The disguised stamp will work exactly like the real stamp and will allow you to forge false documents to gain access or equipment; \
+ desc = "A stamp that can be activated to imitate an official Nanotrasen Stamp™. The disguised stamp will work exactly like the real stamp and will allow you to forge false documents to gain access or equipment; \
it can also be used in a washing machine to forge clothing."
item = /obj/item/weapon/stamp/chameleon
cost = 1
+ surplus = 35
/datum/uplink_item/stealthy_tools/syndigolashes
name = "No-Slip Brown Shoes"
desc = "These allow you to run on wet floors. They do not work on lubricated surfaces."
item = /obj/item/clothing/shoes/syndigaloshes
- cost = 2
+ cost = 4
/datum/uplink_item/stealthy_tools/agent_card
name = "Agent Identification card"
desc = "Agent cards prevent artificial intelligences from tracking the wearer, and can copy access from other identification cards. The access is cumulative, so scanning one card does not erase the access gained from another."
item = /obj/item/weapon/card/id/syndicate
- cost = 2
+ cost = 3
/datum/uplink_item/stealthy_tools/voice_changer
name = "Voice Changer"
item = /obj/item/clothing/mask/gas/voice
desc = "A conspicuous gas mask that mimics the voice named on your identification card. When no identification is worn, the mask will render your voice unrecognizable."
- cost = 4
+ cost = 5
/datum/uplink_item/stealthy_tools/chameleon_proj
name = "Chameleon-Projector"
desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't move the projector from their hand. The disguised user cannot run and rojectiles pass over them."
item = /obj/item/device/chameleon
- cost = 4
+ cost = 7
/datum/uplink_item/stealthy_tools/camera_bug
name = "Camera Bug"
desc = "Enables you to bug cameras to view them remotely. Adding particular items to it alters its functions."
item = /obj/item/device/camera_bug
cost = 2
+ surplus = 90
+
+/datum/uplink_item/stealthy_tools/smugglersatchel
+ name = "Smuggler's Satchel"
+ desc = "This satchel is thin enough to be hidden in the gap between plating and tiling, great for stashing your stolen goods. Comes with a crowbar and a floor tile inside."
+ item = /obj/item/weapon/storage/backpack/satchel_flat
+ cost = 2
+ surplus = 30
// DEVICE AND TOOLS
@@ -320,7 +365,7 @@ var/list/uplink_items = list()
name = "Cryptographic Sequencer"
desc = "The emag is a small card that unlocks hidden functions in electronic devices, subverts intended functions and characteristically breaks security mechanisms."
item = /obj/item/weapon/card/emag
- cost = 3
+ cost = 6
/datum/uplink_item/device_tools/toolbox
name = "Full Syndicate Toolbox"
@@ -333,28 +378,29 @@ var/list/uplink_items = list()
desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical hud for quick identification of injured comrades, \
and other medical supplies helpful for a medical field operative.."
item = /obj/item/weapon/storage/firstaid/tactical
- cost = 5
+ cost = 9
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/device_tools/space_suit
name = "Syndicate Space Suit"
desc = "The red and black syndicate space suit is less encumbering than Nanotrasen variants, fits inside bags, and has a weapon slot. Nanotrasen crewmembers are trained to report red space suit sightings."
item = /obj/item/weapon/storage/box/syndie_kit/space
- cost = 3
+ cost = 5
/datum/uplink_item/device_tools/thermal
name = "Thermal Imaging Glasses"
desc = "These glasses are thermals disguised as engineers' optical meson scanners. \
They allow you to see organisms through walls by capturing the upper portion of the infrared light spectrum, emitted as heat and light by objects. \
- Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
+ Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks." //THEN WHY CANT THEY SEE PLASMA FIRES????
item = /obj/item/clothing/glasses/thermal/syndi
- cost = 3
+ cost = 6
/datum/uplink_item/device_tools/binary
name = "Binary Translator Key"
desc = "A key, that when inserted into a radio headset, allows you to listen to and talk with artificial intelligences and cybernetic organisms in binary. "
item = /obj/item/device/encryptionkey/binary
- cost = 3
+ cost = 6
+ surplus = 75
/datum/uplink_item/device_tools/ai_detector
name = "Artificial Intelligence Detector" // changed name in case newfriends thought it detected disguised ai's
@@ -366,13 +412,21 @@ var/list/uplink_items = list()
name = "Hacked AI Law Upload Module"
desc = "When used with an upload console, this module allows you to upload priority laws to an artificial intelligence. Be careful with their wording, as artificial intelligences may look for loopholes to exploit."
item = /obj/item/weapon/aiModule/syndicate
- cost = 7
+ cost = 14
-/datum/uplink_item/device_tools/plastic_explosives
+/datum/uplink_item/device_tools/magboots
+ name = "Blood-Red Magboots"
+ desc = "A pair of magnetic boots with a Syndicate paintjob that assist with freer movement in space or on-station during gravitational generator failures. \
+ These reverse-engineered knockoffs of Nanotrasen's 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety."
+ item = /obj/item/clothing/shoes/magboots/syndie
+ cost = 5
+ gamemodes = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/device_tools/c4
name = "Composition C-4"
desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect a signaler to its wiring to make it remotely detonable. \
It has a modifiable timer with a minimum setting of 10 seconds."
- item = /obj/item/weapon/plastique
+ item = /obj/item/weapon/c4
cost = 1
/datum/uplink_item/device_tools/powersink
@@ -380,7 +434,7 @@ var/list/uplink_items = list()
desc = "When screwed to wiring attached to an electric grid, then activated, this large device places excessive load on the grid, causing a stationwide blackout. The sink cannot be carried because of its excessive size. \
Ordering this sends you a small beacon that will teleport the power sink to your location on activation."
item = /obj/item/device/powersink
- cost = 5
+ cost = 10
/datum/uplink_item/device_tools/singularity_beacon
name = "Singularity Beacon"
@@ -388,14 +442,14 @@ var/list/uplink_items = list()
Does not work when the singularity is still in containment. A singularity beacon can cause catastrophic damage to a space station, \
leading to an emergency evacuation. Because of its size, it cannot be carried. Ordering this sends you a small beacon that will teleport the larger beacon to your location on activation."
item = /obj/item/device/sbeacondrop
- cost = 7
+ cost = 14
/datum/uplink_item/device_tools/syndicate_bomb
name = "Syndicate Bomb"
desc = "The Syndicate Bomb has an adjustable timer with a minimum setting of 60 seconds. Ordering the bomb sends you a small beacon, which will teleport the explosive to your location when you activate it. \
You can wrench the bomb down to prevent removal. The crew may attempt to defuse the bomb."
item = /obj/item/device/sbeacondrop/bomb
- cost = 6
+ cost = 11
excludefrom = list(/datum/game_mode/traitor/double_agents)
/datum/uplink_item/device_tools/rad_laser
@@ -403,29 +457,31 @@ var/list/uplink_items = list()
desc = "A radioactive microlaser disguised as a standard Nanotrasen health analyzer. When used, it emits a powerful burst of radiation, which, after a short delay, can incapitate all but the most protected of humanoids. \
It has two settings: intensity, which controls the power of the radiation, and wavelength, which controls how long the radiation delay is."
item = /obj/item/device/rad_laser
- cost = 4
+ cost = 6
/datum/uplink_item/device_tools/syndicate_detonator
name = "Syndicate Detonator"
desc = "The Syndicate Detonator is a companion device to the Syndicate Bomb. Simply press the included button and an encrypted radio frequency will instruct all live syndicate bombs to detonate. \
Useful for when speed matters or you wish to synchronize multiple bomb blasts. Be sure to stand clear of the blast radius before using the detonator."
item = /obj/item/device/syndicatedetonator
- cost = 1
+ cost = 3
gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/device_tools/teleporter
name = "Teleporter Circuit Board"
desc = "A printed circuit board that completes the teleporter onboard the mothership. Advise you test fire the teleporter before entering it, as malfunctions can occur."
item = /obj/item/weapon/circuitboard/teleporter
- cost = 20
+ cost = 40
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 0
/datum/uplink_item/device_tools/shield
name = "Energy Shield"
desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending against other attacks."
item = /obj/item/weapon/shield/energy
- cost = 8
+ cost = 16
gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 20
// IMPLANTS
@@ -437,31 +493,33 @@ var/list/uplink_items = list()
name = "Freedom Implant"
desc = "An implant injected into the body and later activated using a bodily gesture to attempt to slip restraints."
item = /obj/item/weapon/storage/box/syndie_kit/imp_freedom
- cost = 3
+ cost = 5
/datum/uplink_item/implants/uplink
name = "Uplink Implant"
desc = "An implant injected into the body, and later activated using a bodily gesture to open an uplink with 5 telecrystals. \
The ability for an agent to open an uplink after their posessions have been stripped from them makes this implant excellent for escaping confinement."
item = /obj/item/weapon/storage/box/syndie_kit/imp_uplink
- cost = 10
+ cost = 20
+ surplus = 0
/datum/uplink_item/implants/adrenal
name = "Adrenal Implant"
desc = "An implant injected into the body, and later activated using a bodily gesture to inject a chemical cocktail, which has a mild healing effect along with removing all stuns and increasing his speed."
item = /obj/item/weapon/storage/box/syndie_kit/imp_adrenal
- cost = 4
+ cost = 8
// POINTLESS BADASSERY
/datum/uplink_item/badass
category = "(Pointless) Badassery"
+ surplus = 0
/datum/uplink_item/badass/bundle
name = "Syndicate Bundle"
desc = "Syndicate Bundles are specialised groups of items that arrive in a plain box. These items are collectively worth more than 10 telecrystals, but you do not know which specialisation you will receive."
item = /obj/item/weapon/storage/box/syndicate
- cost = 10
+ cost = 20
excludefrom = list(/datum/game_mode/nuclear)
/datum/uplink_item/badass/syndiecards
@@ -471,12 +529,13 @@ var/list/uplink_items = list()
item = /obj/item/toy/cards/deck/syndicate
cost = 1
excludefrom = list(/datum/game_mode/nuclear)
+ surplus = 40
/datum/uplink_item/badass/balloon
name = "For showing that you are The Boss"
desc = "A useless red balloon with the syndicate logo on it, which can blow the deepest of covers."
item = /obj/item/toy/syndicateballoon
- cost = 10
+ cost = 20
/datum/uplink_item/badass/random
name = "Random Item"
@@ -502,3 +561,35 @@ var/list/uplink_items = list()
U.uses -= max(0, I.cost)
feedback_add_details("traitor_uplink_items_bought","RN")
return new I.item(loc)
+
+/datum/uplink_item/badass/surplus_crate
+ name = "Syndicate Surplus Crate"
+ desc = "A crate containing 50 telecrystals worth of random syndicate leftovers."
+ cost = 20
+ item = /obj/item/weapon/storage/box/syndicate
+ excludefrom = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/badass/surplus_crate/spawn_item(turf/loc, obj/item/device/uplink/U)
+ var/obj/structure/closet/crate/C = new(loc)
+ var/list/temp_uplink_list = get_uplink_items()
+ var/list/buyable_items = list()
+ for(var/category in temp_uplink_list)
+ buyable_items += temp_uplink_list[category]
+ var/list/bought_items = list()
+ U.uses -= cost
+ var/remaining_TC = 50
+
+ var/datum/uplink_item/I
+ while(remaining_TC)
+ I = pick(buyable_items)
+ if(!I.surplus)
+ continue
+ if(I.cost > remaining_TC)
+ continue
+ if((I.item in bought_items) && prob(33)) //To prevent people from being flooded with the same thing over and over again.
+ continue
+ bought_items += I.item
+ remaining_TC -= I.cost
+
+ for(var/item in bought_items)
+ new item(C)
diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm
index 48691c47bff..6309fa53df2 100644
--- a/code/datums/wires/airlock.dm
+++ b/code/datums/wires/airlock.dm
@@ -137,13 +137,11 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
//raises them if they are down (only if power's on)
if(!A.locked)
A.locked = 1
- for(var/mob/M in range(1, A))
- M << "You hear a click from the bottom of the door."
+ A.audible_message("You hear a click from the bottom of the door.", null, 1)
else
if(A.hasPower()) //only can raise bolts if power's on
A.locked = 0
- for(var/mob/M in range(1, A))
- M << "You hear a click from the bottom of the door."
+ A.audible_message("You hear a click from the bottom of the door.", null, 1)
A.update_icon()
if(AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2)
diff --git a/code/datums/wires/explosive.dm b/code/datums/wires/explosive.dm
index 5ba362ba2fd..7a43c1bde8d 100644
--- a/code/datums/wires/explosive.dm
+++ b/code/datums/wires/explosive.dm
@@ -17,16 +17,16 @@ var/const/WIRE_EXPLODE = 1
if(!mended)
explode()
-/datum/wires/explosive/plastic
- holder_type = /obj/item/weapon/plastique
+/datum/wires/explosive/c4
+ holder_type = /obj/item/weapon/c4
-/datum/wires/explosive/plastic/CanUse(var/mob/living/L)
- var/obj/item/weapon/plastique/P = holder
+/datum/wires/explosive/c4/CanUse(var/mob/living/L)
+ var/obj/item/weapon/c4/P = holder
if(P.open_panel)
return 1
return 0
-/datum/wires/explosive/plastic/explode()
- var/obj/item/weapon/plastique/P = holder
+/datum/wires/explosive/c4/explode()
+ var/obj/item/weapon/c4/P = holder
P.explode(get_turf(P))
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 05025fbc6f5..42ebeec3ef0 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -166,11 +166,6 @@
w_class = 2.0
attack_verb = list("warned", "cautioned", "smashed")
-/obj/item/weapon/caution/cone
- desc = "This cone is trying to warn you of something!"
- name = "warning cone"
- icon_state = "cone"
-
/obj/item/weapon/rack_parts
name = "rack parts"
desc = "Parts of a rack."
diff --git a/code/defines/procs/priority_announce.dm b/code/defines/procs/priority_announce.dm
index 621a4c913a2..c397b3fd00c 100644
--- a/code/defines/procs/priority_announce.dm
+++ b/code/defines/procs/priority_announce.dm
@@ -37,11 +37,14 @@
C.messagetitle.Add("[title]")
C.messagetext.Add(text)
-/proc/minor_announce(var/message, var/title = "Attention:")
+/proc/minor_announce(var/message, var/title = "Attention:", var/alert)
if(!message)
return
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player) && !M.ear_deaf)
M << "[title] [message] "
- M << sound('sound/misc/notice2.ogg')
\ No newline at end of file
+ if(alert)
+ M << sound('sound/misc/notice1.ogg')
+ else
+ M << sound('sound/misc/notice2.ogg')
\ No newline at end of file
diff --git a/code/defines/procs/statistics.dm b/code/defines/procs/statistics.dm
index e0a97085222..06c076af6ac 100644
--- a/code/defines/procs/statistics.dm
+++ b/code/defines/procs/statistics.dm
@@ -10,7 +10,7 @@ proc/sql_poll_players()
log_game("SQL ERROR during player polling. Failed to connect.")
else
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_legacy_population (playercount, time) VALUES ([playercount], '[sqltime]')")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, time) VALUES ([playercount], '[sqltime]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during player polling. Error : \[[err]\]\n")
@@ -25,7 +25,7 @@ proc/sql_poll_admins()
log_game("SQL ERROR during admin polling. Failed to connect.")
else
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_legacy_population (admincount, time) VALUES ([admincount], '[sqltime]')")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (admincount, time) VALUES ([admincount], '[sqltime]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during admin polling. Error : \[[err]\]\n")
@@ -69,7 +69,7 @@ proc/sql_report_death(var/mob/living/carbon/human/H)
if(!dbcon.IsConnected())
log_game("SQL ERROR during death reporting. Failed to connect.")
else
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
@@ -104,7 +104,7 @@ proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
if(!dbcon.IsConnected())
log_game("SQL ERROR during death reporting. Failed to connect.")
else
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
@@ -137,7 +137,7 @@ proc/sql_commit_feedback()
log_game("SQL ERROR during feedback reporting. Failed to connect.")
else
- var/DBQuery/max_query = dbcon.NewQuery("SELECT MAX(roundid) AS max_round_id FROM erro_feedback")
+ var/DBQuery/max_query = dbcon.NewQuery("SELECT MAX(roundid) AS max_round_id FROM [format_table_name("feedback")]")
max_query.Execute()
var/newroundid
@@ -157,7 +157,7 @@ proc/sql_commit_feedback()
var/variable = item.get_variable()
var/value = item.get_value()
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("feedback")] (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')")
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during feedback reporting. Error : \[[err]\]\n")
\ No newline at end of file
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 2291605ef6d..7d3cd7b4440 100644
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -380,17 +380,25 @@ proc/process_ghost_teleport_locs()
/area/tdome
name = "\improper Thunderdome"
- icon_state = "thunder"
+ icon_state = "yellow"
requires_power = 0
has_gravity = 1
+/area/tdome/arena
+ name = "\improper Thunderdome Arena"
+ icon_state = "thunder"
+
+/area/tdome/arena_source
+ name = "\improper Thunderdome Arena Template"
+ icon_state = "thunder"
+
/area/tdome/tdome1
name = "\improper Thunderdome (Team 1)"
icon_state = "green"
/area/tdome/tdome2
name = "\improper Thunderdome (Team 2)"
- icon_state = "yellow"
+ icon_state = "green"
/area/tdome/tdomeadmin
name = "\improper Thunderdome (Admin.)"
@@ -551,6 +559,8 @@ proc/process_ghost_teleport_locs()
icon_state = "atmos"
//Maintenance
+/area/maintenance
+ ambientsounds = list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg', 'sound/ambience/ambimaint5.ogg')
/area/maintenance/atmos_control
name = "Atmospherics Maintenance"
@@ -1048,6 +1058,10 @@ proc/process_ghost_teleport_locs()
name = "\improper Firing Range"
icon_state = "firingrange"
+/area/security/transfer
+ name = "\improper Transfer Centre"
+ icon_state = "armory"
+
/*
New()
..()
@@ -1381,6 +1395,10 @@ proc/process_ghost_teleport_locs()
name = "Emergency Storage"
icon_state = "storage"
+/area/ai_monitored/storage/satellite
+ name = "\improper AI Satellite Maint"
+ icon_state = "storage"
+
/area/turret_protected/
ambientsounds = list('sound/ambience/ambimalf.ogg')
@@ -1403,7 +1421,7 @@ proc/process_ghost_teleport_locs()
/area/aisat
name = "\improper AI Satellite Exterior"
- icon_state = "storage"
+ icon_state = "yellow"
/area/turret_protected/aisat_interior
name = "\improper AI Satellite Antechamber"
@@ -1540,6 +1558,198 @@ proc/process_ghost_teleport_locs()
has_gravity = 1
ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg')
+/area/spacecontent
+ name = "space"
+
+/area/spacecontent/a1
+ icon_state = "spacecontent1"
+
+/area/spacecontent/a2
+ icon_state = "spacecontent2"
+
+/area/spacecontent/a3
+ icon_state = "spacecontent3"
+
+/area/spacecontent/a4
+ icon_state = "spacecontent4"
+
+/area/spacecontent/a5
+ icon_state = "spacecontent5"
+
+/area/spacecontent/a6
+ icon_state = "spacecontent6"
+
+/area/spacecontent/a7
+ icon_state = "spacecontent7"
+
+/area/spacecontent/a8
+ icon_state = "spacecontent8"
+
+/area/spacecontent/a9
+ icon_state = "spacecontent9"
+
+/area/spacecontent/a10
+ icon_state = "spacecontent10"
+
+/area/spacecontent/a11
+ icon_state = "spacecontent11"
+
+/area/spacecontent/a11
+ icon_state = "spacecontent12"
+
+/area/spacecontent/a12
+ icon_state = "spacecontent13"
+
+/area/spacecontent/a13
+ icon_state = "spacecontent14"
+
+/area/spacecontent/a14
+ icon_state = "spacecontent14"
+
+/area/spacecontent/a15
+ icon_state = "spacecontent15"
+
+/area/spacecontent/a16
+ icon_state = "spacecontent16"
+
+/area/spacecontent/a17
+ icon_state = "spacecontent17"
+
+/area/spacecontent/a18
+ icon_state = "spacecontent18"
+
+/area/spacecontent/a19
+ icon_state = "spacecontent19"
+
+/area/spacecontent/a20
+ icon_state = "spacecontent20"
+
+/area/spacecontent/a21
+ icon_state = "spacecontent21"
+
+/area/spacecontent/a22
+ icon_state = "spacecontent22"
+
+/area/spacecontent/a23
+ icon_state = "spacecontent23"
+
+/area/spacecontent/a24
+ icon_state = "spacecontent24"
+
+/area/spacecontent/a25
+ icon_state = "spacecontent25"
+
+/area/spacecontent/a26
+ icon_state = "spacecontent26"
+
+/area/spacecontent/a27
+ icon_state = "spacecontent27"
+
+/area/spacecontent/a28
+ icon_state = "spacecontent28"
+
+/area/spacecontent/a29
+ icon_state = "spacecontent29"
+
+/area/spacecontent/a30
+ icon_state = "spacecontent30"
+
+/area/awaycontent
+ name = "space"
+
+/area/awaycontent/a1
+ icon_state = "awaycontent1"
+
+/area/awaycontent/a2
+ icon_state = "awaycontent2"
+
+/area/awaycontent/a3
+ icon_state = "awaycontent3"
+
+/area/awaycontent/a4
+ icon_state = "awaycontent4"
+
+/area/awaycontent/a5
+ icon_state = "awaycontent5"
+
+/area/awaycontent/a6
+ icon_state = "awaycontent6"
+
+/area/awaycontent/a7
+ icon_state = "awaycontent7"
+
+/area/awaycontent/a8
+ icon_state = "awaycontent8"
+
+/area/awaycontent/a9
+ icon_state = "awaycontent9"
+
+/area/awaycontent/a10
+ icon_state = "awaycontent10"
+
+/area/awaycontent/a11
+ icon_state = "awaycontent11"
+
+/area/awaycontent/a11
+ icon_state = "awaycontent12"
+
+/area/awaycontent/a12
+ icon_state = "awaycontent13"
+
+/area/awaycontent/a13
+ icon_state = "awaycontent14"
+
+/area/awaycontent/a14
+ icon_state = "awaycontent14"
+
+/area/awaycontent/a15
+ icon_state = "awaycontent15"
+
+/area/awaycontent/a16
+ icon_state = "awaycontent16"
+
+/area/awaycontent/a17
+ icon_state = "awaycontent17"
+
+/area/awaycontent/a18
+ icon_state = "awaycontent18"
+
+/area/awaycontent/a19
+ icon_state = "awaycontent19"
+
+/area/awaycontent/a20
+ icon_state = "awaycontent20"
+
+/area/awaycontent/a21
+ icon_state = "awaycontent21"
+
+/area/awaycontent/a22
+ icon_state = "awaycontent22"
+
+/area/awaycontent/a23
+ icon_state = "awaycontent23"
+
+/area/awaycontent/a24
+ icon_state = "awaycontent24"
+
+/area/awaycontent/a25
+ icon_state = "awaycontent25"
+
+/area/awaycontent/a26
+ icon_state = "awaycontent26"
+
+/area/awaycontent/a27
+ icon_state = "awaycontent27"
+
+/area/awaycontent/a28
+ icon_state = "awaycontent28"
+
+/area/awaycontent/a29
+ icon_state = "awaycontent29"
+
+/area/awaycontent/a30
+ icon_state = "awaycontent30"
+
/////////////////////////////////////////////////////////////////////
/*
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index e997d1ec9f8..9deaf9d74fb 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -68,6 +68,12 @@
a.cancelAlarm("Power", src, source)
else
a.triggerAlarm("Power", src, cameras, source)
+ for(var/mob/living/simple_animal/drone/D in mob_list)
+ if(D.z == source.z)
+ if(state == 1)
+ D.cancelAlarm("Power", src, source)
+ else
+ D.triggerAlarm("Power", src, cameras, source)
return
/area/proc/atmosalert(danger_level)
@@ -86,11 +92,15 @@
aiPlayer.triggerAlarm("Atmosphere", src, cameras, src)
for(var/obj/machinery/computer/station_alert/a in machines)
a.triggerAlarm("Atmosphere", src, cameras, src)
+ for(var/mob/living/simple_animal/drone/D in mob_list)
+ D.triggerAlarm("Atmosphere", src, cameras, src)
else if (src.atmosalm == 2)
for(var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.cancelAlarm("Atmosphere", src, src)
for(var/obj/machinery/computer/station_alert/a in machines)
a.cancelAlarm("Atmosphere", src, src)
+ for(var/mob/living/simple_animal/drone/D in mob_list)
+ D.cancelAlarm("Atmosphere", src, src)
src.atmosalm = danger_level
return 1
return 0
@@ -111,6 +121,8 @@
else if(!D.density)
spawn(0)
D.close()
+ for(var/obj/machinery/firealarm/F in RA)
+ F.update_icon()
for (var/obj/machinery/camera/C in RA)
cameras += C
@@ -118,6 +130,8 @@
a.triggerAlarm("Fire", src, cameras, src)
for (var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.triggerAlarm("Fire", src, cameras, src)
+ for (var/mob/living/simple_animal/drone/D in mob_list)
+ D.triggerAlarm("Fire", src, cameras, src)
return
/area/proc/firereset()
@@ -133,11 +147,15 @@
else if(D.density)
spawn(0)
D.open()
+ for(var/obj/machinery/firealarm/F in RA)
+ F.update_icon()
for (var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.cancelAlarm("Fire", src, src)
for (var/obj/machinery/computer/station_alert/a in machines)
a.cancelAlarm("Fire", src, src)
+ for (var/mob/living/simple_animal/drone/D in mob_list)
+ D.cancelAlarm("Fire", src, src)
return
/area/proc/burglaralert(var/obj/trigger)
diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm
index 9f29bedef73..eff9492c13c 100644
--- a/code/game/asteroid.dm
+++ b/code/game/asteroid.dm
@@ -113,8 +113,8 @@ proc/make_mining_asteroid_secret()
if("speakeasy")
theme = "speakeasy"
floortypes = list(/turf/simulated/floor,/turf/simulated/floor/wood)
- treasureitems = list(/obj/item/weapon/melee/energy/sword/pirate=1,/obj/item/weapon/gun/projectile/revolver/doublebarrel=1, /obj/machinery/reagentgrinder=2,
- /obj/structure/reagent_dispensers/beerkeg=5, /obj/machinery/computer/security/wooden_tv=4, /obj/machinery/vending/coffee=3)
+ treasureitems = list(/obj/item/weapon/melee/energy/sword/pirate=1,/obj/item/weapon/gun/projectile/revolver/doublebarrel=1,/obj/item/weapon/storage/backpack/satchel_flat=1,
+ /obj/machinery/reagentgrinder=2, /obj/machinery/computer/security/wooden_tv=4, /obj/machinery/vending/coffee=3)
fluffitems = list(/obj/structure/table/woodentable=2,/obj/structure/reagent_dispensers/beerkeg=1,/obj/item/weapon/spacecash/c500=4,
/obj/item/weapon/reagent_containers/food/drinks/shaker=1,/obj/item/weapon/reagent_containers/food/drinks/bottle/wine=3,
/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey=3,/obj/item/clothing/shoes/laceup=2)
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 54b628e4200..8cea24b69b5 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -100,7 +100,8 @@ proc/med_hud_suit_sensors(var/mob/living/carbon/human/patient)
proc/med_hud_find_virus(var/mob/living/carbon/human/patient)
for(var/datum/disease/D in patient.viruses)
if(!D.hidden[SCANNER])
- return 1
+ if(D.severity != D.non_threat)
+ return 1
proc/med_hud_get_health(var/mob/living/carbon/human/patient)
var/image/holder = patient.hud_list[HEALTH_HUD]
diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm
index 903a983e7df..9bcc166edfd 100644
--- a/code/game/gamemodes/blob/blob.dm
+++ b/code/game/gamemodes/blob/blob.dm
@@ -16,6 +16,7 @@ var/list/blob_nodes = list()
recommended_enemies = 1
restricted_jobs = list("Cyborg", "AI")
+ pre_setup_before_jobs = 1
var/declared = 0
diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm
index 937d461247f..f83550796b7 100644
--- a/code/game/gamemodes/blob/blob_finish.dm
+++ b/code/game/gamemodes/blob/blob_finish.dm
@@ -12,7 +12,7 @@
/datum/game_mode/blob/declare_completion()
if(blobwincount <= blobs.len)
- feedback_set_details("round_end_result","loss - blob took over")
+ feedback_set_details("round_end_result","win - blob took over")
world << "The blob has taken over the station!"
world << "The entire station was eaten by the Blob"
log_game("Blob mode completed with a blob victory.")
@@ -24,7 +24,7 @@
log_game("Blob mode completed with a tie (station destroyed).")
else if(!blob_cores.len)
- feedback_set_details("round_end_result","win - blob eliminated")
+ feedback_set_details("round_end_result","loss - blob eliminated")
world << "The staff has won!"
world << "The alien organism has been eradicated from the station"
log_game("Blob mode completed with a crew victory.")
diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm
new file mode 100644
index 00000000000..c7663326236
--- /dev/null
+++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm
@@ -0,0 +1,145 @@
+
+
+////////////////
+// BLOB SPORE //
+////////////////
+
+/mob/living/simple_animal/hostile/blobspore
+ name = "blob"
+ desc = "Some blob thing."
+ icon = 'icons/mob/blob.dmi'
+ icon_state = "blobpod"
+ icon_living = "blobpod"
+ pass_flags = PASSBLOB
+ health = 40
+ maxHealth = 40
+ melee_damage_lower = 2
+ melee_damage_upper = 4
+ attacktext = "hits"
+ attack_sound = 'sound/weapons/genhit1.ogg'
+ var/obj/effect/blob/factory/factory = null
+ var/is_zombie = 0
+ faction = list("blob")
+ 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 = 360
+
+/mob/living/simple_animal/hostile/blobspore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ ..()
+ adjustBruteLoss(Clamp(0.01 * exposed_temperature, 1, 5))
+
+/mob/living/simple_animal/hostile/blobspore/blob_act()
+ return
+
+/mob/living/simple_animal/hostile/blobspore/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(istype(mover, /obj/effect/blob))
+ return 1
+ return ..()
+
+/mob/living/simple_animal/hostile/blobspore/New(loc, var/obj/effect/blob/factory/linked_node)
+ if(istype(linked_node))
+ factory = linked_node
+ factory.spores += src
+ ..()
+
+/mob/living/simple_animal/hostile/blobspore/Life()
+
+ if(!is_zombie && isturf(src.loc))
+ for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile
+ if(H.stat == DEAD)
+ Zombify(H)
+ break
+ ..()
+
+/mob/living/simple_animal/hostile/blobspore/proc/Zombify(var/mob/living/carbon/human/H)
+ if(H.wear_suit)
+ var/obj/item/clothing/suit/armor/A = H.wear_suit
+ if(A.armor && A.armor["melee"])
+ maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
+ maxHealth += 40
+ health = maxHealth
+ name = "blob zombie"
+ desc = "A shambling corpse animated by the blob."
+ melee_damage_lower = 10
+ melee_damage_upper = 15
+ icon = H.icon
+ icon_state = "husk_s"
+ H.hair_style = null
+ H.update_hair()
+ overlays = H.overlays
+ overlays += image('icons/mob/blob.dmi', icon_state = "blob_head")
+ H.loc = src
+ is_zombie = 1
+ loc.visible_message(" The corpse of [H.name] suddenly rises!")
+
+/mob/living/simple_animal/hostile/blobspore/Die()
+ // On death, create a small smoke of harmful gas (s-Acid)
+ var/datum/effect/effect/system/chem_smoke_spread/S = new
+ var/turf/location = get_turf(src)
+
+ // Create the reagents to put into the air, s-acid is yellow and stings a little
+ create_reagents(25)
+ reagents.add_reagent("spore", 25)
+
+ // Attach the smoke spreader and setup/start it.
+ S.attach(location)
+ S.set_up(reagents, 1, 1, location, 15, 1) // only 1-2 smoke cloud
+ S.start()
+
+ qdel(src)
+
+/mob/living/simple_animal/hostile/blobspore/Destroy()
+ if(factory)
+ factory.spores -= src
+ if(contents)
+ for(var/mob/M in contents)
+ M.loc = src.loc
+ ..()
+
+
+/mob/living/simple_animal/hostile/blobbernaut
+ name = "blobbernaut"
+ desc = "Some HUGE blob thing."
+ icon = 'icons/mob/blob.dmi'
+ icon_state = "blobbernaut"
+ icon_living = "blobbernaut"
+ icon_dead = "blobbernaut_death"
+ pass_flags = PASSBLOB
+ health = 240
+ maxHealth = 240
+ melee_damage_lower = 25
+ melee_damage_upper = 25
+ attacktext = "hits"
+ attack_sound = 'sound/effects/blobattack.ogg'
+ faction = list("blob")
+ 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 = 360
+ force_threshold = 10
+ environment_smash = 3
+
+
+/mob/living/simple_animal/hostile/blobbernaut/AttackingTarget()
+ ..()
+ if(isliving(target))
+ var/mob/living/L = target
+ if(L.reagents)
+ L.reagents.add_reagent("spore_burning", 10)
+
+
+/mob/living/simple_animal/hostile/blobbernaut/blob_act()
+ return
diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm
index 177d3af2e69..d5c26dcf904 100644
--- a/code/game/gamemodes/blob/blobs/factory.dm
+++ b/code/game/gamemodes/blob/blobs/factory.dm
@@ -33,102 +33,3 @@
new/mob/living/simple_animal/hostile/blobspore(src.loc, src)
return 0
-
-/mob/living/simple_animal/hostile/blobspore
- name = "blob"
- desc = "Some blob thing."
- icon = 'icons/mob/blob.dmi'
- icon_state = "blobpod"
- icon_living = "blobpod"
- pass_flags = PASSBLOB
- health = 40
- maxHealth = 40
- melee_damage_lower = 2
- melee_damage_upper = 4
- attacktext = "hits"
- attack_sound = 'sound/weapons/genhit1.ogg'
- var/obj/effect/blob/factory/factory = null
- var/is_zombie = 0
- faction = list("blob")
- 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 = 360
-
-/mob/living/simple_animal/hostile/blobspore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- ..()
- adjustBruteLoss(Clamp(0.01 * exposed_temperature, 1, 5))
-
-/mob/living/simple_animal/hostile/blobspore/blob_act()
- return
-
-/mob/living/simple_animal/hostile/blobspore/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(istype(mover, /obj/effect/blob))
- return 1
- return ..()
-
-/mob/living/simple_animal/hostile/blobspore/New(loc, var/obj/effect/blob/factory/linked_node)
- if(istype(linked_node))
- factory = linked_node
- factory.spores += src
- ..()
-
-/mob/living/simple_animal/hostile/blobspore/Life()
-
- if(!is_zombie && isturf(src.loc))
- for(var/mob/living/carbon/human/H in oview(src,1)) //Only for corpse right next to/on same tile
- if(H.stat == DEAD)
- Zombify(H)
- break
- ..()
-
-/mob/living/simple_animal/hostile/blobspore/proc/Zombify(var/mob/living/carbon/human/H)
- if(H.wear_suit)
- var/obj/item/clothing/suit/armor/A = H.wear_suit
- if(A.armor && A.armor["melee"])
- maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
- maxHealth += 40
- health = maxHealth
- name = "blob zombie"
- desc = "A shambling corpse animated by the blob."
- melee_damage_lower = 10
- melee_damage_upper = 15
- icon = H.icon
- icon_state = "husk_s"
- H.hair_style = null
- H.update_hair()
- overlays = H.overlays
- overlays += image('icons/mob/blob.dmi', icon_state = "blob_head")
- H.loc = src
- is_zombie = 1
- loc.visible_message(" The corpse of [H.name] suddenly rises!")
-
-/mob/living/simple_animal/hostile/blobspore/Die()
- // On death, create a small smoke of harmful gas (s-Acid)
- var/datum/effect/effect/system/chem_smoke_spread/S = new
- var/turf/location = get_turf(src)
-
- // Create the reagents to put into the air, s-acid is yellow and stings a little
- create_reagents(25)
- reagents.add_reagent("spore", 25)
-
- // Attach the smoke spreader and setup/start it.
- S.attach(location)
- S.set_up(reagents, 1, 1, location, 15, 1) // only 1-2 smoke cloud
- S.start()
-
- qdel(src)
-
-/mob/living/simple_animal/hostile/blobspore/Destroy()
- if(factory)
- factory.spores -= src
- if(contents)
- for(var/mob/M in contents)
- M.loc = src.loc
- ..()
diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm
index 4fc5281081b..ad2a5cbb0d8 100644
--- a/code/game/gamemodes/blob/powers.dm
+++ b/code/game/gamemodes/blob/powers.dm
@@ -160,6 +160,35 @@
return
+/mob/camera/blob/verb/create_blobbernaut()
+ set category = "Blob"
+ set name = "Create Blobbernaut (20)"
+ set desc = "Create a powerful blob-being, a Blobbernaut"
+
+ var/turf/T = get_turf(src)
+
+ if(!T)
+ return
+
+ var/obj/effect/blob/B = locate(/obj/effect/blob) in T
+ if(!B)
+ src << "You must be on a blob!"
+ return
+
+ if(!istype(B, /obj/effect/blob/factory))
+ src << "Unable to use this blob, find a factory blob."
+ return
+
+ if(!can_buy(20))
+ return
+
+ var/mob/living/simple_animal/hostile/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blobbernaut (get_turf(B))
+ if(blobber)
+ B.Destroy()
+
+ return
+
+
/mob/camera/blob/verb/relocate_core()
set category = "Blob"
set name = "Relocate Core (80)"
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index fcfa5d99dd8..c10d36e7558 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -13,6 +13,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
required_players = 15
required_enemies = 1
recommended_enemies = 4
+ pre_setup_before_jobs = 1
var/const/prob_int_murder_target = 50 // intercept names the assassination target half the time
@@ -77,7 +78,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
return
/datum/game_mode/changeling/make_antag_chance(var/mob/living/carbon/human/character) //Assigns changeling to latejoiners
- var/changelingcap = min( round(num_players()/(config.changeling_scaling_coeff*2))+2, round(num_players()/config.changeling_scaling_coeff) )
+ var/changelingcap = min( round(joined_player_list.len/(config.changeling_scaling_coeff*2))+2, round(joined_player_list.len/config.changeling_scaling_coeff) )
if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
return
if(changelings.len <= (changelingcap - 2) || prob(100 - (config.changeling_scaling_coeff*2)))
@@ -223,7 +224,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
var/changelingID = "Changeling"
var/geneticdamage = 0
var/isabsorbing = 0
- var/geneticpoints = 5
+ var/geneticpoints = 10
var/purchasedpowers = list()
var/mimicing = ""
var/canrespec = 0
diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm
index 03204e0a8ac..c7ff6471f7b 100644
--- a/code/game/gamemodes/changeling/evolution_menu.dm
+++ b/code/game/gamemodes/changeling/evolution_menu.dm
@@ -374,6 +374,7 @@ var/list/sting_paths
chem_storage = initial(chem_storage)
chem_recharge_rate = initial(chem_recharge_rate)
chem_charges = min(chem_charges, chem_storage)
+ chem_recharge_slowdown = initial(chem_recharge_slowdown)
mimicing = ""
/mob/proc/remove_changeling_powers(var/keep_free_powers=0)
diff --git a/code/game/gamemodes/changeling/powers/epinephrine.dm b/code/game/gamemodes/changeling/powers/epinephrine.dm
index 20fe4a677b9..973f01f9b54 100644
--- a/code/game/gamemodes/changeling/powers/epinephrine.dm
+++ b/code/game/gamemodes/changeling/powers/epinephrine.dm
@@ -3,7 +3,7 @@
desc = "We evolve additional sacs of adrenaline throughout our body."
helptext = "Removes all stuns instantly and adds a short-term reduction in further stuns. Can be used while unconscious. Continued use poisons the body."
chemical_cost = 30
- dna_cost = 1
+ dna_cost = 2
req_human = 1
req_stat = UNCONSCIOUS
diff --git a/code/game/gamemodes/changeling/powers/fakedeath.dm b/code/game/gamemodes/changeling/powers/fakedeath.dm
index 7a0ed702059..16c3ccbb237 100644
--- a/code/game/gamemodes/changeling/powers/fakedeath.dm
+++ b/code/game/gamemodes/changeling/powers/fakedeath.dm
@@ -1,7 +1,7 @@
/obj/effect/proc_holder/changeling/fakedeath
name = "Regenerative Stasis"
desc = "We fall into a stasis, allowing us to regenerate."
- chemical_cost = 20
+ chemical_cost = 15
dna_cost = 0
req_dna = 1
req_stat = DEAD
diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm
index 9f67ef05d84..7a58c554dfc 100644
--- a/code/game/gamemodes/changeling/powers/fleshmend.dm
+++ b/code/game/gamemodes/changeling/powers/fleshmend.dm
@@ -2,8 +2,8 @@
name = "Fleshmend"
desc = "Our flesh rapidly regenerates, healing our wounds."
helptext = "Heals a moderate amount of damage over a short period of time. Can be used while unconscious."
- chemical_cost = 30
- dna_cost = 1
+ chemical_cost = 25
+ dna_cost = 2
req_stat = UNCONSCIOUS
//Starts healing you every second for 10 seconds. Can be used whilst unconscious.
diff --git a/code/game/gamemodes/changeling/powers/glands.dm b/code/game/gamemodes/changeling/powers/glands.dm
index b6f6aaf5e47..ca36093a9f7 100644
--- a/code/game/gamemodes/changeling/powers/glands.dm
+++ b/code/game/gamemodes/changeling/powers/glands.dm
@@ -2,7 +2,7 @@
name = "Engorged Chemical Glands"
desc = "Our chemical glands swell, permitting us to store more chemicals inside of them."
helptext = "Allows us to store an extra 25 units of chemicals, and doubles production rate."
- dna_cost = 1
+ dna_cost = 2
chemical_cost = -1
/obj/effect/proc_holder/changeling/glands/on_purchase(var/mob/user)
diff --git a/code/game/gamemodes/changeling/powers/hivemind.dm b/code/game/gamemodes/changeling/powers/hivemind.dm
index 8823560ab66..2ccb9a3a4e4 100644
--- a/code/game/gamemodes/changeling/powers/hivemind.dm
+++ b/code/game/gamemodes/changeling/powers/hivemind.dm
@@ -3,7 +3,7 @@
name = "Hivemind Communication"
desc = "We tune our senses to the airwaves to allow us to discreetly communicate and exchange DNA with other changelings."
helptext = "We will be able to talk with other changelings with :g. Exchanged DNA do not count towards absorb objectives."
- dna_cost = 1
+ dna_cost = 2
chemical_cost = -1
/obj/effect/proc_holder/changeling/hivemind_comms/on_purchase(var/mob/user)
@@ -55,7 +55,7 @@ var/list/datum/dna/hivemind_bank = list()
/obj/effect/proc_holder/changeling/hivemind_download
name = "Hive Absorb DNA"
desc = "Allows us to absorb DNA that has been channeled to the airwaves. Does not count towards absorb objectives."
- chemical_cost = 20
+ chemical_cost = 10
dna_cost = -1
/obj/effect/proc_holder/changeling/hivemind_download/can_sting(var/mob/living/carbon/user)
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index e6246f686e2..5781e7e7208 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -110,10 +110,10 @@
desc = "We reform one of our arms into a deadly blade."
helptext = "Cannot be used while in lesser form."
chemical_cost = 20
- dna_cost = 1
+ dna_cost = 2
genetic_damage = 10
req_human = 1
- max_genetic_damage = 11
+ max_genetic_damage = 20
weapon_type = /obj/item/weapon/melee/arm_blade
weapon_name_simple = "blade"
@@ -175,18 +175,18 @@
\***************************************/
/obj/effect/proc_holder/changeling/weapon/shield
name = "Organic Shield"
- desc = "We reform one of our arms into hard shield."
+ desc = "We reform one of our arms into a hard shield."
helptext = "Organic tissue cannot resist damage forever, the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form."
chemical_cost = 20
dna_cost = 1
genetic_damage = 12
req_human = 1
- max_genetic_damage = 10
+ max_genetic_damage = 20
weapon_type = /obj/item/weapon/shield/changeling
weapon_name_simple = "shield"
-/obj/effect/proc_holder/changeling/shield/sting_action(var/mob/user)
+/obj/effect/proc_holder/changeling/weapon/shield/sting_action(var/mob/user)
var/datum/changeling/changeling = user.mind.changeling //So we can read the absorbedcount.
if(!changeling)
return
@@ -236,10 +236,10 @@
desc = "We grow an organic suit to protect ourselves from space exposure."
helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Retreating the suit damages our genomes. Cannot be used in lesser form."
chemical_cost = 20
- dna_cost = 1
+ dna_cost = 2
genetic_damage = 8
req_human = 1
- max_genetic_damage = 8
+ max_genetic_damage = 20
suit_type = /obj/item/clothing/suit/space/changeling
helmet_type = /obj/item/clothing/head/helmet/space/changeling
@@ -288,11 +288,11 @@
name = "Chitinous Armor"
desc = "We turn our skin into tough chitin to protect us from damage."
helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Retreating the armor damages our genomes. Cannot be used in lesser form."
- chemical_cost = 25
- dna_cost = 1
+ chemical_cost = 20
+ dna_cost = 2
genetic_damage = 11
req_human = 1
- max_genetic_damage = 10
+ max_genetic_damage = 20
suit_type = /obj/item/clothing/suit/armor/changeling
helmet_type = /obj/item/clothing/head/helmet/changeling
diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm
index bd8c90e943a..35067080403 100644
--- a/code/game/gamemodes/changeling/powers/panacea.dm
+++ b/code/game/gamemodes/changeling/powers/panacea.dm
@@ -2,7 +2,7 @@
name = "Anatomic Panacea"
desc = "Expels impurifications from our form; curing diseases, removing toxins and radiation, and resetting our genetic code completely."
helptext = "Can be used while unconscious."
- chemical_cost = 25
+ chemical_cost = 20
dna_cost = 1
req_stat = UNCONSCIOUS
diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm
index 046d8f9512e..026a0aa4a1b 100644
--- a/code/game/gamemodes/changeling/powers/shriek.dm
+++ b/code/game/gamemodes/changeling/powers/shriek.dm
@@ -2,13 +2,13 @@
name = "Resonant Shriek"
desc = "Our lungs and vocal chords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded."
helptext = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors."
- chemical_cost = 25
+ chemical_cost = 20
dna_cost = 1
req_human = 1
//A flashy ability, good for crowd control and sewing chaos.
/obj/effect/proc_holder/changeling/resonant_shriek/sting_action(var/mob/user)
- for(var/mob/living/M in hearers(4, user))
+ for(var/mob/living/M in get_hearers_in_view(4, user))
if(iscarbon(M))
if(!M.mind || !M.mind.changeling)
M.ear_deaf += 30
diff --git a/code/game/gamemodes/changeling/powers/spiders.dm b/code/game/gamemodes/changeling/powers/spiders.dm
index cc4bcea557a..693c38ee449 100644
--- a/code/game/gamemodes/changeling/powers/spiders.dm
+++ b/code/game/gamemodes/changeling/powers/spiders.dm
@@ -2,7 +2,7 @@
name = "Spread Infestation"
desc = "Our form divides, creating arachnids which will grow into deadly beasts."
helptext = "The spiders are thoughtless creatures, and may attack their creators when fully grown. Requires at least 5 DNA absorptions."
- chemical_cost = 50
+ chemical_cost = 45
dna_cost = 1
req_dna = 5
diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm
index 5aa17bd17d9..5ebff603d96 100644
--- a/code/game/gamemodes/changeling/powers/tiny_prick.dm
+++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm
@@ -64,7 +64,7 @@
helptext = "Does not provide a warning to others. The victim will transform much like a changeling would."
sting_icon = "sting_transform"
chemical_cost = 40
- dna_cost = 1
+ dna_cost = 2
var/datum/dna/selected_dna = null
/obj/effect/proc_holder/changeling/sting/transformation/Click()
@@ -117,7 +117,7 @@ obj/effect/proc_holder/changeling/sting/mute
helptext = "Does not provide a warning to the victim that they have been stung, until they try to speak and cannot."
sting_icon = "sting_mute"
chemical_cost = 20
- dna_cost = 1
+ dna_cost = 2
/obj/effect/proc_holder/changeling/sting/mute/sting_action(var/mob/user, var/mob/living/carbon/target)
add_logs(user, target, "stung", object="mute sting")
@@ -128,7 +128,7 @@ obj/effect/proc_holder/changeling/sting/mute
obj/effect/proc_holder/changeling/sting/blind
name = "Blind Sting"
desc = "Temporarily blinds the target."
- helptext = "This sting completely blinds a target for a short time. The target does not notice they have been stung."
+ helptext = "This sting completely blinds a target for a short time."
sting_icon = "sting_blind"
chemical_cost = 25
dna_cost = 1
@@ -145,9 +145,9 @@ obj/effect/proc_holder/changeling/sting/blind
obj/effect/proc_holder/changeling/sting/LSD
name = "Hallucination Sting"
desc = "Causes terror in the target."
- helptext = "We evolve the ability to sting a target with a powerful hallucinogenic chemical. The target does not notice they have been stung. The effect occurs after 30 to 60 seconds."
+ helptext = "We evolve the ability to sting a target with a powerful hallucinogenic chemical. The target does not notice they have been stung, and the effect occurs after 30 to 60 seconds."
sting_icon = "sting_lsd"
- chemical_cost = 5
+ chemical_cost = 10
dna_cost = 1
/obj/effect/proc_holder/changeling/sting/LSD/sting_action(var/mob/user, var/mob/living/carbon/target)
@@ -164,7 +164,7 @@ obj/effect/proc_holder/changeling/sting/cryo
helptext = "Does not provide a warning to the victim, though they will likely realize they are suddenly freezing."
sting_icon = "sting_cryo"
chemical_cost = 15
- dna_cost = 1
+ dna_cost = 2
/obj/effect/proc_holder/changeling/sting/cryo/sting_action(var/mob/user, var/mob/target)
add_logs(user, target, "stung", object="cryo sting")
diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm
index 615cf29383c..e1f84aeecde 100644
--- a/code/game/gamemodes/changeling/traitor_chan.dm
+++ b/code/game/gamemodes/changeling/traitor_chan.dm
@@ -3,7 +3,7 @@
config_tag = "traitorchan"
traitors_possible = 3 //hard limit on traitors if scaling is turned off
restricted_jobs = list("AI", "Cyborg")
- required_players = 20
+ required_players = 0
required_enemies = 1 // how many of each type are required
recommended_enemies = 3
@@ -61,7 +61,7 @@
return
/datum/game_mode/traitor/changeling/make_antag_chance(var/mob/living/carbon/human/character) //Assigns changeling to latejoiners
- var/changelingcap = min( round(num_players()/(config.changeling_scaling_coeff*4))+2, round(num_players()/(config.changeling_scaling_coeff*2)) )
+ var/changelingcap = min( round(joined_player_list.len/(config.changeling_scaling_coeff*4))+2, round(joined_player_list.len/(config.changeling_scaling_coeff*2)) )
if(changelings.len >= changelingcap) //Caps number of latejoin antagonists
..()
return
@@ -70,4 +70,4 @@
if(!jobban_isbanned(character.client, "changeling") && !jobban_isbanned(character.client, "Syndicate"))
if(!(character.job in ticker.mode.restricted_jobs))
character.mind.make_Changling()
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 8ab4e6dde35..0c7f68f88ee 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -29,6 +29,7 @@
required_players = 20
required_enemies = 6
recommended_enemies = 6
+ pre_setup_before_jobs = 1
var/finished = 0
@@ -73,6 +74,7 @@
var/datum/mind/cultist = pick(antag_candidates)
antag_candidates -= cultist
cult += cultist
+ cultist.special_role = "Cultist"
log_game("[cultist.key] (ckey) has been selected as a cultist")
return (cult.len>=required_enemies)
@@ -103,7 +105,6 @@
update_cult_icons_added(cult_mind)
cult_mind.current << "You are a member of the cult!"
memorize_cult_objectives(cult_mind)
- cult_mind.special_role = "Cultist"
..()
@@ -330,7 +331,7 @@
feedback_set("round_end_result",acolytes_survived)
world << "The staff managed to stop the cult!"
- var/text = "[TAB]Cultists escaped: [acolytes_survived] "
+ var/text = ""
if(cult_objectives.len)
text += " The cultists' objectives were:"
@@ -339,10 +340,10 @@
switch(cult_objectives[obj_count])
if("survive")
if(!check_survive())
- explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Success!"
+ explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!"
feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
else
- explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Fail."
+ explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail."
feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
if("sacrifice")
if(sacrifice_target)
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 262c90379c3..4e66a3d1ecc 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -63,9 +63,9 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
usr.say("O bidai nabora se[pick("'","`")]sma!")
sleep(10)
usr.say("[input]")
- for(var/datum/mind/H in ticker.mode.cult)
- if (H.current)
- H.current << "[input]"
+ for(var/mob/M in mob_list)
+ if((M.mind && (M.mind in ticker.mode.cult)) || (M in dead_mob_list))
+ M << "[input]"
return
#undef CHECK_STATUS
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 2b16cdcc366..fb07c3c966c 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -574,9 +574,9 @@ var/list/sacrificed = list()
usr.say("[input]")
else
usr.whisper("[input]")
- for(var/datum/mind/H in ticker.mode.cult)
- if (H.current)
- H.current << "[input]"
+ for(var/mob/M in mob_list)
+ if((M.mind && (M.mind in ticker.mode.cult)) || (M in dead_mob_list))
+ M << "[input]"
return 1
/////////////////////////////////////////FIFTEENTH RUNE
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 517ccae3a06..7974819cefb 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -218,6 +218,7 @@
if(BE_OPERATIVE) roletext="operative"
if(BE_WIZARD) roletext="wizard"
if(BE_REV) roletext="revolutionary"
+ if(BE_GANG) roletext="gangster"
if(BE_CULTIST) roletext="cultist"
if(BE_MONKEY) roletext="monkey"
@@ -400,4 +401,4 @@ proc/display_roundstart_logout_report()
text += "body destroyed"
text += ")"
- return text
+ return text
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index fc67d9f723a..8e2a9c15a14 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -275,11 +275,12 @@ var/round_start_time = 0
/datum/controller/gameticker/proc/equip_characters()
var/captainless=1
for(var/mob/living/carbon/human/player in player_list)
+ if(!player.mind.need_job_assign)
+ continue
if(player && player.mind && player.mind.assigned_role)
if(player.mind.assigned_role == "Captain")
captainless=0
- if(player.mind.assigned_role != "MODE")
- job_master.EquipRank(player, player.mind.assigned_role, 0)
+ job_master.EquipRank(player, player.mind.assigned_role, 0)
if(captainless)
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm
new file mode 100644
index 00000000000..a9faa393a0a
--- /dev/null
+++ b/code/game/gamemodes/gang/gang.dm
@@ -0,0 +1,449 @@
+//gang.dm
+//Gang War Game Mode
+
+/datum/game_mode
+ var/list/datum/mind/A_bosses = list() //gang A bosses
+ var/list/datum/mind/A_gangsters = list() //gang A Members
+ var/list/datum/mind/B_bosses = list() //gang B bosses
+ var/list/datum/mind/B_gangsters = list() //gang B Members
+
+/datum/game_mode/gang
+ name = "gang war"
+ config_tag = "gang"
+ antag_flag = BE_GANG
+ restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
+ required_players = 20
+ required_enemies = 2
+ recommended_enemies = 4
+
+ var/finished = 0
+ var/checkwin_counter = 0
+///////////////////////////
+//Announces the game type//
+///////////////////////////
+/datum/game_mode/gang/announce()
+ world << "The current game mode is - Gang War!"
+ world << "A violent turf war has erupted on the station! Gangsters - Take over the station by killing the rival gang's bosses! Recruit gangsters by flashing them! Security - Protect the Crew! Identify and stop the mob bosses!"
+
+
+///////////////////////////////////////////////////////////////////////////////
+//Gets the round setup, cancelling if there's not enough players at the start//
+///////////////////////////////////////////////////////////////////////////////
+/datum/game_mode/gang/pre_setup()
+ if(config.protect_roles_from_antagonist)
+ restricted_jobs += protected_jobs
+
+ for(var/datum/mind/player in antag_candidates)
+ for(var/job in restricted_jobs)//Removing heads and such from the list
+ if(player.assigned_role == job)
+ antag_candidates -= player
+
+ if(antag_candidates.len >= 2)
+ assign_bosses()
+ if(antag_candidates.len > 20)
+ assign_bosses()
+
+ if(!A_bosses.len || !B_bosses.len)
+ return 0
+
+//Set a temporary special_role so the job controller doesn't hand out invalid jobs for these antags
+ for(var/datum/mind/boss_mind in A_bosses)
+ boss_mind.special_role = "Gang member"
+ for(var/datum/mind/boss_mind in B_bosses)
+ boss_mind.special_role = "Gang member"
+
+ return 1
+
+
+/datum/game_mode/gang/post_setup()
+ spawn(rand(10,100))
+ for(var/datum/mind/boss_mind in A_bosses)
+ update_gang_icons_added(boss_mind, "A")
+ forge_gang_objectives(boss_mind, "A")
+ greet_gang(boss_mind)
+ equip_gang(boss_mind.current)
+
+ for(var/datum/mind/boss_mind in B_bosses)
+ update_gang_icons_added(boss_mind, "B")
+ forge_gang_objectives(boss_mind, "B")
+ greet_gang(boss_mind)
+ equip_gang(boss_mind.current)
+
+ modePlayer += A_bosses
+ modePlayer += B_bosses
+ ..()
+
+
+/datum/game_mode/gang/process()
+ checkwin_counter++
+ if(checkwin_counter >= 5)
+ if(!finished)
+ ticker.mode.check_win()
+ checkwin_counter = 0
+ return 0
+
+/datum/game_mode/gang/proc/assign_bosses()
+ var/datum/mind/boss = pick(antag_candidates)
+ A_bosses += boss
+ antag_candidates -= boss
+ boss.special_role = "[gang_name("A")] Gang (A) Boss"
+ log_game("[boss.key] has been selected as a boss for the [gang_name("A")] Gang (A)")
+
+ boss = pick(antag_candidates)
+ B_bosses += boss
+ antag_candidates -= boss
+ boss.special_role = "[gang_name("B")] Gang (B) Boss"
+ log_game("[boss.key] has been selected as a boss for the [gang_name("B")] Gang (B)")
+
+/datum/game_mode/proc/forge_gang_objectives(var/datum/mind/boss_mind)
+ var/datum/objective/rival_obj = new
+ rival_obj.owner = boss_mind
+ rival_obj.explanation_text = "Assassinate or exile the [(boss_mind in A_bosses) ? gang_name("B") : gang_name("A")] Gang's bosses."
+ boss_mind.objectives += rival_obj
+
+
+/datum/game_mode/proc/greet_gang(var/datum/mind/boss_mind, var/you_are=1)
+ var/obj_count = 1
+ if (you_are)
+ boss_mind.current << "You are a [(boss_mind in A_bosses) ? gang_name("A") : gang_name("B")] Gang Boss!"
+ for(var/datum/objective/objective in boss_mind.objectives)
+ boss_mind.current << "Objective #[obj_count]: [objective.explanation_text]"
+ obj_count++
+
+///////////////////////////////////////////////////////////////////////////
+//This equips the bosses with their gear, and makes the clown not clumsy//
+///////////////////////////////////////////////////////////////////////////
+/datum/game_mode/proc/equip_gang(mob/living/carbon/human/mob)
+ if(!istype(mob))
+ return
+
+ if (mob.mind)
+ if (mob.mind.assigned_role == "Clown")
+ mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself."
+ mob.mutations.Remove(CLUMSY)
+
+
+ var/obj/item/device/flash/T = new(mob)
+ var/obj/item/device/recaller/recaller = new(mob)
+
+ var/list/slots = list (
+ "backpack" = slot_in_backpack,
+ "left pocket" = slot_l_store,
+ "right pocket" = slot_r_store,
+ "left hand" = slot_l_hand,
+ "right hand" = slot_r_hand,
+ )
+
+ . = 0
+
+ var/where2 = mob.equip_in_one_of_slots(recaller, slots)
+ if (!where2)
+ mob << "Your Syndicate benefactors were unfortunately unable to get you a Recaller."
+ else
+ mob << "The Recaller in your [where2] will allow you to prevent the station from prematurely evacuating. Use it to recall the emergency shuttle from anywhere on the station."
+ . += 2
+
+ var/where = mob.equip_in_one_of_slots(T, slots)
+ if (!where)
+ mob << "Your Syndicate benefactors were unfortunately unable to get you a flash."
+ else
+ mob << "The flash in your [where] will help you to persuade the crew to work for you."
+ mob << "Keep in mind that your underlings can only identify their bosses, but not each other. You must coordinate your gang effectively to beat out the competition."
+ . += 1
+
+ mob.update_icons()
+
+ return .
+
+/////////////////////////////////////////////
+//Checks if the either gang have won or not//
+/////////////////////////////////////////////
+/datum/game_mode/gang/check_win()
+ var/A_victory = check_gang_victory(B_bosses) //Check if B bosses are dead or exiled
+ var/B_victory = check_gang_victory(A_bosses) //Check if A bosses are dead or exiled
+
+ if(A_victory && B_victory)
+ finished = "Draw" //Both teams fail. Allow for draws in case they're all incapacitated at the same time.
+
+ else if(A_victory)
+ finished = "A" //Gang A wins
+
+ else if(B_victory)
+ finished = "B" //Gang B wins
+
+///////////////////////////////
+//Checks if the round is over//
+///////////////////////////////
+/datum/game_mode/gang/check_finished()
+ if(finished) //Check for Gang Boss death
+ return 1
+ return ..() //Check for evacuation/nuke
+
+///////////////////////////////////////////
+//Deals with converting players to a gang//
+///////////////////////////////////////////
+/datum/game_mode/proc/add_gangster(datum/mind/gangster_mind, var/gang, var/check = 1)
+ if(check && isloyal(gangster_mind.current)) //Check to see if the potential gangster is implanted
+ return 0
+ if((gangster_mind in A_bosses) || (gangster_mind in A_gangsters) || (gangster_mind in B_bosses) || (gangster_mind in B_gangsters))
+ return 0
+ if(gang == "A")
+ A_gangsters += gangster_mind
+ else
+ B_gangsters += gangster_mind
+ gangster_mind.current << "You are now a member of the [gang=="A" ? gang_name("A") : gang_name("B")] Gang!"
+ gangster_mind.current << "Help your bosses take over the station by defeating their rivals. You can identify your bosses by the brown \"B\" icons, but only they know who the other members of your gang are! Work with your boss to avoid attacking your own gang."
+ gangster_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"]!"
+ gangster_mind.special_role = "[gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"]"
+ update_gang_icons_added(gangster_mind,gang)
+ return 1
+//////////////////////////////////////////////////////////////
+//Deals with players going straight (Not a gangster anymore)//
+//////////////////////////////////////////////////////////////
+/datum/game_mode/proc/remove_gangster(datum/mind/gangster_mind, var/beingborged, var/silent)
+ var/gang
+
+ if(gangster_mind in A_bosses)
+ A_bosses -= gangster_mind
+ gang = "A"
+
+ else if(gangster_mind in A_gangsters)
+ A_gangsters -= gangster_mind
+ gang = "A"
+
+ else if(gangster_mind in B_bosses)
+ B_bosses -= gangster_mind
+ gang = "B"
+
+ else if(gangster_mind in B_gangsters)
+ B_gangsters -= gangster_mind
+ gang = "B"
+
+ if(!gang) //not a valid gangster
+ return
+
+ gangster_mind.special_role = null
+ if(silent < 2)
+ gangster_mind.current.attack_log += "\[[time_stamp()]\] Has reformed and defected from the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"]!"
+
+ if(beingborged)
+ if(!silent)
+ gangster_mind.current.visible_message("The frame beeps contentedly from the MMI before initalizing it.")
+ gangster_mind.current << "The frame's firmware detects and deletes your criminal behavior! You are no longer a gangster!"
+ message_admins("[key_name_admin(gangster_mind.current)] ? has been borged while being a member of the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"] Gang. They are no longer a gangster.")
+ else
+ if(!silent)
+ gangster_mind.current.visible_message("[gangster_mind.current] looks like they've given up the life of crime!")
+ gangster_mind.current << "You have been reformed! You are no longer a gangster!"
+
+ update_gang_icons_removed(gangster_mind)
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//Keeps track of players having the correct icons////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////
+/datum/game_mode/proc/update_all_gang_icons()
+ spawn(0)
+ var/list/all_gangsters = A_bosses + B_bosses + A_gangsters + B_gangsters
+
+ //Delete all gang icons
+ for(var/datum/mind/gang_mind in all_gangsters)
+ if(gang_mind.current)
+ if(gang_mind.current.client)
+ for(var/image/I in gang_mind.current.client.images)
+ if(I.icon_state == "gangster" || I.icon_state == "gang_boss")
+ del(I)
+
+ update_gang_icons("A")
+ update_gang_icons("B")
+
+/datum/game_mode/proc/update_gang_icons(var/gang)
+ var/list/bosses
+ var/list/gangsters
+ if(gang == "A")
+ bosses = A_bosses
+ gangsters = A_gangsters
+ else if(gang == "B")
+ bosses = B_bosses
+ gangsters = B_gangsters
+ else
+ world << "ERROR: Invalid gang in update_gang_icons()"
+
+ //Update gang icons for boss' visions
+ for(var/datum/mind/boss_mind in bosses)
+ if(boss_mind.current)
+ if(boss_mind.current.client)
+ for(var/datum/mind/gangster_mind in gangsters)
+ if(gangster_mind.current)
+ var/I = image('icons/mob/mob.dmi', loc = gangster_mind.current, icon_state = "gangster")
+ boss_mind.current.client.images += I
+ for(var/datum/mind/boss2_mind in bosses)
+ if(boss2_mind.current)
+ var/I = image('icons/mob/mob.dmi', loc = boss2_mind.current, icon_state = "gang_boss")
+ boss_mind.current.client.images += I
+
+ //Update boss and self icons for gangsters' visions
+ for(var/datum/mind/gangster_mind in gangsters)
+ if(gangster_mind.current)
+ if(gangster_mind.current.client)
+ for(var/datum/mind/boss_mind in bosses)
+ if(boss_mind.current)
+ var/I = image('icons/mob/mob.dmi', loc = boss_mind.current, icon_state = "gang_boss")
+ gangster_mind.current.client.images += I
+ //Tag themselves to see
+ var/K
+ if(gangster_mind in bosses) //If the new gangster is a boss himself
+ K = image('icons/mob/mob.dmi', loc = gangster_mind.current, icon_state = "gang_boss")
+ else
+ K = image('icons/mob/mob.dmi', loc = gangster_mind.current, icon_state = "gangster")
+ gangster_mind.current.client.images += K
+
+/////////////////////////////////////////////////
+//Assigns icons when a new gangster is recruited//
+/////////////////////////////////////////////////
+/datum/game_mode/proc/update_gang_icons_added(datum/mind/recruit_mind, var/gang)
+ var/list/bosses
+ if(gang == "A")
+ bosses = A_bosses
+ else if(gang == "B")
+ bosses = B_bosses
+ if(!gang)
+ world << "ERROR: Invalid gang in update_gang_icons_added()"
+
+ spawn(0)
+ for(var/datum/mind/boss_mind in bosses)
+ //Tagging the new gangster for the bosses to see
+ if(boss_mind.current)
+ if(boss_mind.current.client)
+ var/I
+ if(recruit_mind in bosses) //If the new gangster is a boss himself
+ I = image('icons/mob/mob.dmi', loc = recruit_mind.current, icon_state = "gang_boss")
+ else
+ I = image('icons/mob/mob.dmi', loc = recruit_mind.current, icon_state = "gangster")
+ boss_mind.current.client.images += I
+ //Tagging every boss for the new gangster to see
+ if(recruit_mind.current)
+ if(recruit_mind.current.client)
+ var/image/J = image('icons/mob/mob.dmi', loc = boss_mind.current, icon_state = "gang_boss")
+ recruit_mind.current.client.images += J
+ //Tag themselves to see
+ if(recruit_mind.current)
+ if(recruit_mind.current.client)
+ var/K
+ if(recruit_mind in bosses) //If the new gangster is a boss himself
+ K = image('icons/mob/mob.dmi', loc = recruit_mind.current, icon_state = "gang_boss")
+ else
+ K = image('icons/mob/mob.dmi', loc = recruit_mind.current, icon_state = "gangster")
+ recruit_mind.current.client.images += K
+
+////////////////////////////////////////
+//Keeps track of deconverted gangsters//
+////////////////////////////////////////
+/datum/game_mode/proc/update_gang_icons_removed(datum/mind/defector_mind)
+ var/list/all_gangsters = A_bosses + B_bosses + A_gangsters + B_gangsters
+
+ spawn(0)
+ //Remove defector's icon from gangsters' visions
+ for(var/datum/mind/boss_mind in all_gangsters)
+ if(boss_mind.current)
+ if(boss_mind.current.client)
+ for(var/image/I in boss_mind.current.client.images)
+ if((I.icon_state == "gangster" || I.icon_state == "gang_boss") && I.loc == defector_mind.current)
+ del(I)
+
+ //Remove gang icons from defector's vision
+ if(defector_mind.current)
+ if(defector_mind.current.client)
+ for(var/image/I in defector_mind.current.client.images)
+ if(I.icon_state == "gangster" || I.icon_state == "gang_boss")
+ del(I)
+
+///////////////////////////
+//Checks for gang victory//
+///////////////////////////
+/datum/game_mode/gang/proc/check_gang_victory(var/list/boss_list)
+ if(!boss_list.len)
+ return 0
+ for(var/datum/mind/boss_mind in boss_list)
+ if(boss_mind.current)
+ if(boss_mind.current.stat == DEAD || !ishuman(boss_mind.current) || !boss_mind.current.ckey || !boss_mind.current.client)
+ return 1
+ var/turf/T = get_turf(boss_mind.current)
+ if(T && (T.z != 1)) //If they leave the station they count as dead for this
+ return 1
+ return 0
+ return 1
+
+//////////////////////////////////////////////////////////////////////
+//Announces the end of the game with all relavent information stated//
+//////////////////////////////////////////////////////////////////////
+/datum/game_mode/gang/declare_completion()
+ if(!finished)
+ world << "The station was [station_was_nuked ? "destroyed!" : "evacuated before either gang could claim it!"]"
+ else if(finished == "Draw")
+ world << "All gang bosses have been killed or exiled!"
+ else
+ world << "The [finished=="A" ? gang_name("A") : gang_name("B")] Gang defeated their rivals!"
+ ..()
+ return 1
+
+/datum/game_mode/proc/auto_declare_completion_gang()
+ var/winner
+ var/datum/game_mode/gang/game_mode = ticker.mode
+ if(istype(game_mode))
+ winner = game_mode.finished
+
+ var/num_ganga = 0
+ var/list/agang = A_gangsters + A_bosses
+ for(var/datum/mind/agangster in agang)
+ if(agangster.current)
+ if(agangster.current in living_mob_list)
+ num_ganga++
+
+ var/num_gangb = 0
+ var/list/bgang = B_gangsters + B_bosses
+ for(var/datum/mind/bgangster in bgang)
+ if(bgangster.current)
+ if(bgangster.current in living_mob_list)
+ num_gangb++
+
+ var/num_survivors = 0
+ for(var/mob/living/carbon/survivor in living_mob_list)
+ if(survivor.key)
+ num_survivors++
+
+ if(A_bosses.len || A_gangsters.len)
+ if(winner == "A" || winner == "B")
+ world << " The [gang_name("A")] Gang was [winner=="A" ? "victorious" : "defeated"] with [round((num_ganga/num_survivors)*100, 0.1)]% influence."
+ world << " The [gang_name("A")] Gang bosses were:"
+ gang_membership_report(A_bosses)
+ world << " The [gang_name("A")] Gangsters were:"
+ gang_membership_report(A_gangsters)
+
+ if(B_bosses.len || B_gangsters.len)
+ if(winner == "A" || winner == "B")
+ world << " The [gang_name("B")] Gang was [winner=="B" ? "victorious" : "defeated"] with [round((num_gangb/num_survivors)*100, 0.1)]% influence."
+ world << " The [gang_name("B")] Gang bosses were:"
+ gang_membership_report(B_bosses)
+ world << " The [gang_name("B")] Gangsters were:"
+ gang_membership_report(B_gangsters)
+
+/datum/game_mode/proc/gang_membership_report(var/list/membership)
+ var/text = ""
+ for(var/datum/mind/gang_mind in membership)
+ text += " [gang_mind.key] was [gang_mind.name] ("
+ if(gang_mind.current)
+ if(gang_mind.current.stat == DEAD || isbrain(gang_mind.current))
+ text += "died"
+ else if(gang_mind.current.z != 1)
+ text += "fled the station"
+ else
+ text += "survived"
+ if(gang_mind.current.real_name != gang_mind.name)
+ text += " as [gang_mind.current.real_name]"
+ else
+ text += "body destroyed"
+ text += ")"
+ text += "
"
+
+ world << text
diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm
index 05ab6f49f63..93ec09810de 100644
--- a/code/game/gamemodes/intercept_report.dm
+++ b/code/game/gamemodes/intercept_report.dm
@@ -61,6 +61,10 @@
src.text = ""
src.build_rev(correct_person)
return src.text
+ if("gang")
+ src.text = ""
+ src.build_gang(correct_person)
+ return src.text
if("cult")
src.text = ""
src.build_cult(correct_person)
@@ -220,6 +224,10 @@
src.text += " However, if this information is acted on without substantial evidence, those responsible will face severe repercussions."
*/
+/datum/intercept_text/proc/build_gang(datum/mind/correct_person)
+ src.text += "
Syndicate forces may be supplying opposing criminal organizations within your sector in an attempt at destabilizing our operations."
+ src.text += "Ensure law and order is maintained on the station and be on the lookout for violent confrontations between station factions."
+ src.text += "Central Command retains an interest in any criminal leaders captured by station security. The execution or exile of these persons are ill-advised."
/datum/intercept_text/proc/build_wizard(datum/mind/correct_person)
var/SWF_desc = pick(SWF_names)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 1eea8712125..4ca3488ed64 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -164,8 +164,7 @@
for(var/datum/AI_Module/small/overload_machine/overload in current_modules)
if(overload.uses > 0)
overload.uses --
- for(var/mob/V in hearers(M, null))
- V.show_message("You hear a loud electrical buzzing sound!", 2)
+ audible_message("You hear a loud electrical buzzing sound!")
src << "Overloading machine circuitry..."
spawn(50)
if(M)
@@ -191,8 +190,7 @@
for(var/datum/AI_Module/small/override_machine/override in current_modules)
if(override.uses > 0)
override.uses --
- for(var/mob/V in hearers(M, null))
- V.show_message("You hear a loud electrical buzzing sound!", 2)
+ audible_message("You hear a loud electrical buzzing sound!")
src << "Reprogramming machine behaviour..."
spawn(50)
if(M)
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index 675940e85d2..8cf8a3ec813 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -11,7 +11,7 @@
pre_setup_before_jobs = 1
- var/AI_win_timeleft = 1800 //started at 1800, in case I change this for testing round end.
+ var/AI_win_timeleft = 5400 //started at 5400, in case I change this for testing round end.
var/malf_mode_declared = 0
var/station_captured = 0
var/to_nuke_or_not_to_nuke = 0
@@ -48,7 +48,7 @@
if (malf_ai.len < required_enemies)
return 0
for(var/datum/mind/ai_mind in malf_ai)
- ai_mind.assigned_role = "MODE" //So they aren't chosen for other jobs.
+ ai_mind.need_job_assign = 0
ai_mind.special_role = "malfunctioning AI"//So they actually have a special role/N
log_game("[ai_mind.key] (ckey) has been selected as a malf AI")
return 1
@@ -98,8 +98,8 @@
return
/datum/game_mode/malfunction/process()
- if (apcs >= 3 && malf_mode_declared)
- AI_win_timeleft -= ((apcs/6)*last_tick_duration) //Victory timer now de-increments based on how many APCs are hacked. --NeoFite
+ if ((apcs > 0) && malf_mode_declared)
+ AI_win_timeleft -= apcs * last_tick_duration //Victory timer de-increments based on how many APCs are hacked
..()
if (AI_win_timeleft<=0)
check_win()
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 992398ae800..b9ed5c88c54 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -93,6 +93,10 @@
qdel(src)
return ..()
+/obj/effect/meteor/Destroy()
+ walk(src,0) //this cancels the walk_towards() proc
+ ..()
+
/obj/effect/meteor/dust
name = "space dust"
icon_state = "dust"
diff --git a/code/game/gamemodes/monkey/monkey.dm b/code/game/gamemodes/monkey/monkey.dm
index 266a7c35e06..c12ba003926 100644
--- a/code/game/gamemodes/monkey/monkey.dm
+++ b/code/game/gamemodes/monkey/monkey.dm
@@ -11,6 +11,7 @@
recommended_enemies = 1
restricted_jobs = list("Cyborg", "AI")
+ pre_setup_before_jobs = 1
var/carriers_to_make = 1
var/list/carriers = list()
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 3f98e8f1ee2..f0c1de856b8 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -40,7 +40,7 @@
agent_number--
for(var/datum/mind/synd_mind in syndicates)
- synd_mind.assigned_role = "MODE" //So they aren't chosen for other jobs.
+ synd_mind.need_job_assign = 0
synd_mind.special_role = "Syndicate"//So they actually have a special role/N
log_game("[synd_mind.key] (ckey) has been selected as a nuclear operative")
return 1
@@ -151,6 +151,7 @@
var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/weapon/card/id)
if(foundIDs.len)
for(var/obj/item/weapon/card/id/ID in foundIDs)
+ ID.name = "lead agent card"
ID.access += access_syndicate_leader
else
message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!")
@@ -210,7 +211,7 @@
var/obj/item/device/radio/uplink/U = new /obj/item/device/radio/uplink(synd_mob)
U.hidden_uplink.uplink_owner="[synd_mob.key]"
- U.hidden_uplink.uses = 10
+ U.hidden_uplink.uses = 20
synd_mob.equip_to_slot_or_del(U, slot_in_backpack)
var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(synd_mob)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index e0b45a6fc85..8e8c6a4f021 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -90,7 +90,7 @@ datum/objective/mutiny/check_completion()
datum/objective/mutiny/update_explanation_text()
..()
if(target && target.current)
- explanation_text = "Assassinate [target.current.real_name], the [!target_role_type ? target.assigned_role : target.special_role]."
+ explanation_text = "Assassinate or exile [target.current.real_name], the [!target_role_type ? target.assigned_role : target.special_role]."
else
explanation_text = "Free Objective"
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 35dff74d813..e850f817e52 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -19,10 +19,13 @@
required_players = 20
required_enemies = 3
recommended_enemies = 3
+ pre_setup_before_jobs = 1
var/finished = 0
- var/checkwin_counter = 0
- var/const/max_headrevs = 3
+ var/check_counter = 0
+ var/max_headrevs = 3
+ var/list/datum/mind/heads_to_kill = list()
+
///////////////////////////
//Announces the game type//
///////////////////////////
@@ -50,6 +53,10 @@
if(player.assigned_role == job)
antag_candidates -= player
+ var/list/heads = get_living_heads()
+ if(heads.len < max_headrevs)
+ max_headrevs = heads.len
+
for (var/i=1 to max_headrevs)
if (antag_candidates.len==0)
break
@@ -67,18 +74,17 @@
/datum/game_mode/revolution/post_setup()
var/list/heads = get_living_heads()
+ heads_to_kill = heads
+
for(var/datum/mind/rev_mind in head_revolutionaries)
for(var/datum/mind/head_mind in heads)
- var/datum/objective/mutiny/rev_obj = new
- rev_obj.owner = rev_mind
- rev_obj.target = head_mind
- rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]."
- rev_mind.objectives += rev_obj
+ mark_for_death(rev_mind, head_mind)
- // equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO
- // Removing revolutionary uplinks. -Pete
- equip_revolutionary(rev_mind.current)
- update_rev_icons_added(rev_mind)
+ spawn(rand(10,100))
+ // equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO
+ // Removing revolutionary uplinks. -Pete
+ equip_revolutionary(rev_mind.current)
+ update_rev_icons_added(rev_mind)
for(var/datum/mind/rev_mind in head_revolutionaries)
greet_revolutionary(rev_mind)
@@ -89,11 +95,12 @@
/datum/game_mode/revolution/process()
- checkwin_counter++
- if(checkwin_counter >= 5)
+ check_counter++
+ if(check_counter >= 5)
if(!finished)
+ check_heads()
ticker.mode.check_win()
- checkwin_counter = 0
+ check_counter = 0
return 0
@@ -103,7 +110,7 @@
var/datum/objective/mutiny/rev_obj = new
rev_obj.owner = rev_mind
rev_obj.target = head_mind
- rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]."
+ rev_obj.explanation_text = "Assassinate or exile [head_mind.name], the [head_mind.assigned_role]."
rev_mind.objectives += rev_obj
/datum/game_mode/proc/greet_revolutionary(var/datum/mind/rev_mind, var/you_are=1)
@@ -145,6 +152,44 @@
mob.update_icons()
return 1
+/////////////////////////////////
+//Gives head revs their targets//
+/////////////////////////////////
+/datum/game_mode/revolution/proc/mark_for_death(var/datum/mind/rev_mind, var/datum/mind/head_mind)
+ var/datum/objective/mutiny/rev_obj = new
+ rev_obj.owner = rev_mind
+ rev_obj.target = head_mind
+ rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]."
+ rev_mind.objectives += rev_obj
+
+////////////////////////////////////////////
+//Checks if new heads have joined midround//
+////////////////////////////////////////////
+/datum/game_mode/revolution/proc/check_heads()
+ var/list/heads = get_all_heads()
+ if(heads_to_kill.len < heads.len)
+ var/list/new_heads = heads - heads_to_kill
+ for(var/datum/mind/head_mind in new_heads)
+ for(var/datum/mind/rev_mind in head_revolutionaries)
+ mark_for_death(rev_mind, head_mind)
+
+ if(max_headrevs < initial(max_headrevs) && max_headrevs < heads.len)
+ latejoin_headrev()
+
+///////////////////////////////
+//Adds a new headrev midround//
+///////////////////////////////
+/datum/game_mode/revolution/proc/latejoin_headrev()
+ if(revolutionaries) //Head Revs are not in this list
+ var/datum/mind/stalin = pick(revolutionaries)
+ revolutionaries -= stalin
+ head_revolutionaries += stalin
+ log_game("[stalin.key] (ckey) has been promoted to a head rev")
+ equip_revolutionary(stalin.current)
+ forge_revolutionary_objectives(stalin)
+ greet_revolutionary(stalin)
+ ++max_headrevs
+
//////////////////////////////////////
//Checks if the revs have won or not//
//////////////////////////////////////
@@ -196,7 +241,8 @@
rev_mind.current.attack_log += "\[[time_stamp()]\] Has renounced the revolution!"
if(beingborged)
- rev_mind.current << "The frame's firmware detects and deletes your neural reprogramming! You remember nothing from the moment you were flashed until now."
+ rev_mind.current << "The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you."
+ message_admins("[key_name_admin(rev_mind.current)] ? has been borged while being a member of the revolution.")
else
rev_mind.current << "You have been brainwashed! You are no longer a revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you..."
@@ -264,20 +310,36 @@
/datum/game_mode/proc/update_rev_icons_added(datum/mind/rev_mind)
spawn(0)
for(var/datum/mind/head_rev_mind in head_revolutionaries)
+
+ //Tagging the new rev for revheads to see
if(head_rev_mind.current)
if(head_rev_mind.current.client)
- var/I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev")
+ var/I
+ if(rev_mind in head_revolutionaries) //If the new rev is a head rev
+ I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev_head")
+ else
+ I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev")
head_rev_mind.current.client.images += I
+
+ //Tagging the revheads for new rev to see
if(rev_mind.current)
if(rev_mind.current.client)
var/image/J = image('icons/mob/mob.dmi', loc = head_rev_mind.current, icon_state = "rev_head")
rev_mind.current.client.images += J
for(var/datum/mind/rev_mind_1 in revolutionaries)
+
+ //Tagging the new rev for fellow revs to see
if(rev_mind_1.current)
if(rev_mind_1.current.client)
- var/I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev")
+ var/I
+ if(rev_mind in head_revolutionaries) //If the new rev is a head rev
+ I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev_head")
+ else
+ I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev")
rev_mind_1.current.client.images += I
+
+ //Tagging fellow revs for the new rev to see
if(rev_mind.current)
if(rev_mind.current.client)
var/image/J = image('icons/mob/mob.dmi', loc = rev_mind_1.current, icon_state = "rev")
@@ -336,22 +398,10 @@
/datum/game_mode/revolution/declare_completion()
if(finished == 1)
feedback_set_details("round_end_result","win - heads killed")
- world << "The heads of staff were killed or abandoned the station! The revolutionaries win!"
+ world << "The heads of staff were killed or exiled! The revolutionaries win!"
else if(finished == 2)
feedback_set_details("round_end_result","loss - rev heads killed")
world << "The heads of staff managed to stop the revolution!"
-
- var/num_revs = 0
- for(var/mob/living/carbon/mob in living_mob_list)
- if(mob.mind)
- if(mob.mind in head_revolutionaries || mob.mind in revolutionaries)
- num_revs++
- var/num_survivors = 0
- for(var/mob/living/carbon/survivor in living_mob_list)
- if(survivor.key)
- num_survivors++
-
- world << "[TAB]Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%" // % of loyal crew
..()
return 1
@@ -359,6 +409,18 @@
var/list/targets = list()
if(head_revolutionaries.len || istype(ticker.mode,/datum/game_mode/revolution))
+ var/num_revs = 0
+ var/num_survivors = 0
+ for(var/mob/living/carbon/survivor in living_mob_list)
+ if(survivor.ckey)
+ num_survivors++
+ if(survivor.mind)
+ if((survivor.mind in head_revolutionaries) || (survivor.mind in revolutionaries))
+ num_revs++
+
+ if(num_survivors)
+ world << "[TAB]Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%" // % of loyal crew
+
var/text = " The head revolutionaries were:"
for(var/datum/mind/headrev in head_revolutionaries)
@@ -388,7 +450,7 @@
for(var/datum/mind/rev in revolutionaries)
text += " [rev.key] was [rev.name] ("
if(rev.current)
- if(rev.current.stat == DEAD)
+ if(rev.current.stat == DEAD || isbrain(rev.current))
text += "died"
else if(rev.current.z != 1)
text += "fled the station"
@@ -414,7 +476,7 @@
text += ""
text += " [head.key] was [head.name] ("
if(head.current)
- if(head.current.stat == DEAD)
+ if(head.current.stat == DEAD || isbrain(head.current))
text += "died"
else if(head.current.z != 1)
text += "fled the station"
@@ -429,10 +491,4 @@
text += ""
text += " "
- world << text
-
-/proc/is_convertable_to_rev(datum/mind/mind)
- return istype(mind) && \
- istype(mind.current, /mob/living/carbon/human) && \
- !(mind.assigned_role in command_positions) && \
- !(mind.assigned_role in list("Security Officer", "Detective", "Warden"))
+ world << text
diff --git a/code/game/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm
index b252b7a6aba..0f30a1af738 100644
--- a/code/game/gamemodes/traitor/double_agents.dm
+++ b/code/game/gamemodes/traitor/double_agents.dm
@@ -5,11 +5,12 @@
required_players = 25
required_enemies = 5
recommended_enemies = 8
+ pre_setup_before_jobs = 1
traitor_name = "double agent"
- traitors_possible = 8 //hard limit on traitors if scaling is turned off
- scale_modifier = 0.5 // Nearly twice as many double agents
+ traitors_possible = 10 //hard limit on traitors if scaling is turned off
+ num_modifier = 6 // Six additional traitors
var/list/target_list = list()
var/list/late_joining_list = list()
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index f26ebec359c..2c4d9aaab5b 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -15,9 +15,10 @@
required_players = 0
required_enemies = 1
recommended_enemies = 4
+ pre_setup_before_jobs = 1
var/traitors_possible = 4 //hard limit on traitors if scaling is turned off
- var/scale_modifier = 1 // Used for gamemodes, that are a child of traitor, that need more than the usual.
+ var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual.
/datum/game_mode/traitor/announce()
@@ -33,7 +34,7 @@
var/num_traitors = 1
if(config.traitor_scaling_coeff)
- num_traitors = max(1, min( round(num_players()/(config.traitor_scaling_coeff*scale_modifier*2))+2, round(num_players()/(config.traitor_scaling_coeff*scale_modifier)) ))
+ num_traitors = max(1, min( round(num_players()/(config.traitor_scaling_coeff*2))+ 2 + num_modifier, round(num_players()/(config.traitor_scaling_coeff)) + num_modifier ))
else
num_traitors = max(1, min(num_players(), traitors_possible))
@@ -70,10 +71,10 @@
return 1
/datum/game_mode/traitor/make_antag_chance(var/mob/living/carbon/human/character) //Assigns traitor to latejoiners
- var/traitorcap = round(joined_player_list.len / (config.traitor_scaling_coeff * scale_modifier * 2))
+ var/traitorcap = min(round(joined_player_list.len / (config.traitor_scaling_coeff * 2)) + 2 + num_modifier, round(joined_player_list.len/config.traitor_scaling_coeff) + num_modifier )
if(traitors.len >= traitorcap) //Upper cap for number of latejoin antagonists
return
- if(traitors.len <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * scale_modifier * 2)))
+ if(traitors.len <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * 2)))
if(character.client.prefs.be_special & BE_TRAITOR)
if(!jobban_isbanned(character.client, "traitor") && !jobban_isbanned(character.client, "Syndicate"))
if(!(character.job in ticker.mode.restricted_jobs))
diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm
index 04b837c7d0a..e8560103ecc 100644
--- a/code/game/gamemodes/wizard/rightandwrong.dm
+++ b/code/game/gamemodes/wizard/rightandwrong.dm
@@ -134,18 +134,12 @@
new /obj/item/weapon/gun/magic/staff/chaos(get_turf(H))
H << "You suddenly feel lucky."
-/mob/proc/summonevents()
+/proc/summonevents()
if(events) //if there isn't something is very wrong
- if(!events.wizardmode) //lets get this party started
- events.control = list() //out with the old
- for(var/type in typesof(/datum/round_event_control/wizard) - /datum/round_event_control/wizard) //in with the new
- var/datum/round_event_control/wizard/W = new type()
- if(!W.typepath)
- continue //don't want this one! leave it for the garbage collector
- events.control += W //add it to the list of all events (controls)
+ if(!events.wizardmode)
events.frequency_lower = 600 //1 minute lower bound
events.frequency_upper = 3000 //5 minutes upper bound
- events.wizardmode = 1
+ events.toggleWizardmode()
events.reschedule()
else //Speed it up
@@ -154,4 +148,6 @@
if(events.frequency_upper < events.frequency_lower)
events.frequency_upper = events.frequency_lower //this can't happen unless somehow multiple spellbooks are used, but just in case
- events.reschedule()
+ events.reschedule()
+ message_admins("Summon Events intensifies, events will now occur every [events.frequency_lower / 600] to [events.frequency_upper / 600] minutes.")
+ log_game("Summon Events was increased!")
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index aded7d5e8d2..09cad46c59b 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -305,7 +305,7 @@
temp = "You have cast summon magic."
if("summonevents")
feedback_add_details("wizard_spell_learned","SE") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
- H.summonevents()
+ summonevents()
max_uses--
temp = "You have cast summon events."
if("staffchange")
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 245a827c3bf..ef97dcc54cf 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -21,7 +21,7 @@
var/datum/mind/wizard = pick(antag_candidates)
wizards += wizard
modePlayer += wizard
- wizard.assigned_role = "MODE" //So they aren't chosen for other jobs.
+ wizard.need_job_assign = 0
wizard.special_role = "Wizard"
if(wizardstart.len == 0)
wizard.current << "A starting location for you could not be found, please report this bug!"
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index 77b0f22bb85..cd7cb743573 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -104,6 +104,10 @@
//they can only hold things :(
if(src.check_access(george.get_active_hand()))
return 1
+ else if(isanimal(M))
+ var/mob/living/simple_animal/A = M
+ if(check_access(A.access_card))
+ return 1
return 0
/obj/item/proc/GetAccess()
diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index f3f2ce107bc..84ab61c9e0c 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -32,11 +32,12 @@ Captain
H.equip_to_slot_or_del(new /obj/item/clothing/head/caphat(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(H), slot_glasses)
- //Equip ID box
+ //Equip ID box & telebaton
if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/silver_ids(H), slot_l_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/silver_ids(H.back), slot_in_backpack)
+ H.equip_to_slot_or_del(new /obj/item/weapon/melee/telebaton(H), slot_in_backpack)
//Implant him
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
@@ -87,8 +88,9 @@ Head of Personnel
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/brown(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/head/hopcap(H), slot_head)
- //Equip ID box
+ //Equip ID box & telebaton
if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/ids(H), slot_l_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/ids(H.back), slot_in_backpack)
+ H.equip_to_slot_or_del(new /obj/item/weapon/melee/telebaton(H), slot_in_backpack)
diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm
index 72c39e1f707..a65af4f68dc 100644
--- a/code/game/jobs/job/engineering.dm
+++ b/code/game/jobs/job/engineering.dm
@@ -38,6 +38,10 @@ Chief Engineer
H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
+ //Equip telebaton
+ if(H.backbag == 2 || H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/melee/telebaton(H), slot_in_backpack)
+
/*
Station Engineer
*/
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index d800f2a9adc..dab1d3def8b 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -34,6 +34,9 @@ Chief Medical Officer
H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(H), slot_l_hand)
H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store)
+ //Equip telebaton
+ if(H.backbag == 2 || H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/melee/telebaton(H), slot_in_backpack)
/*
Medical Doctor
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index 51134d5d86e..f45733dd62e 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -36,6 +36,10 @@ Research Director
H.equip_to_slot_or_del(new /obj/item/weapon/clipboard(H), slot_l_hand)
H.equip_to_slot_or_del(new /obj/item/device/laser_pointer(H), slot_l_store)
+ //Equip telebaton
+ if(H.backbag == 2 || H.backbag == 3)
+ H.equip_to_slot_or_del(new /obj/item/weapon/melee/telebaton(H), slot_in_backpack)
+
/*
Scientist
*/
diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm
index b42d6918433..9ef81bd9dc2 100644
--- a/code/game/jobs/job/security.dm
+++ b/code/game/jobs/job/security.dm
@@ -40,7 +40,7 @@ Head of Security
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/hos(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/HoS(H), slot_head)
+ H.equip_to_slot_or_del(new /obj/item/clothing/head/HoS(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses)
H.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(H), slot_s_store)
@@ -48,6 +48,7 @@ Head of Security
H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_l_store)
else
H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_in_backpack)
+ H.equip_to_slot_or_del(new /obj/item/weapon/melee/telebaton(H), slot_in_backpack)
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
@@ -80,7 +81,7 @@ Warden
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/warden(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest/warden(H), slot_wear_suit)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/warden(H), slot_head)
+ H.equip_to_slot_or_del(new /obj/item/clothing/head/warden(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses)
H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store)
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 25b63f923bd..57365511158 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -46,6 +46,11 @@ var/global/datum/controller/occupations/job_master
if(!job) return 0
if(jobban_isbanned(player, rank)) return 0
if(!job.player_old_enough(player.client)) return 0
+ if(player.mind.special_role && ticker && ticker.mode)
+ if(job.title in ticker.mode.restricted_jobs)
+ return 0
+ if(!player.mind.need_job_assign)
+ return 0
var/position_limit = job.total_positions
if(!latejoin)
position_limit = job.spawn_positions
@@ -72,9 +77,19 @@ var/global/datum/controller/occupations/job_master
if(flag && (!player.client.prefs.be_special & flag))
Debug("FOC flag failed, Player: [player], Flag: [flag], ")
continue
+
if(config.enforce_human_authority && (job.title in command_positions) && player.client.prefs.pref_species.id != "human")
Debug("FOC non-human failed, Player: [player]")
continue
+
+ if(player.mind.special_role && ticker && ticker.mode)
+ if(job.title in ticker.mode.restricted_jobs)
+ Debug("FOC player has a special role and this job is blocked from this special role")
+ continue
+
+ if(!player.mind.need_job_assign)
+ continue
+
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
Debug("FOC pass, Player: [player], Level:[level]")
candidates += player
@@ -104,6 +119,14 @@ var/global/datum/controller/occupations/job_master
Debug("GRJ non-human failed, Player: [player]")
continue
+ if(player.mind.special_role && ticker && ticker.mode)
+ if(job.title in ticker.mode.restricted_jobs)
+ Debug("GRJ player has a special role and this job is blocked from this special role")
+ continue
+
+ if(!player.mind.need_job_assign)
+ continue
+
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
Debug("GRJ Random job given, Player: [player], Job: [job]")
AssignRole(player, job.title)
@@ -259,6 +282,14 @@ var/global/datum/controller/occupations/job_master
Debug("DO non-human failed, Player: [player], Job:[job.title]")
continue
+ if(player.mind.special_role && ticker && ticker.mode)
+ if(job.title in ticker.mode.restricted_jobs)
+ Debug("DO player has a special role and this job is blocked from that special role")
+ continue
+
+ if(!player.mind.need_job_assign)
+ continue
+
// If the player wants that job on this level, then try give it to him.
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
@@ -287,6 +318,9 @@ var/global/datum/controller/occupations/job_master
//Gives the player the stuff he should have with his rank
/datum/controller/occupations/proc/EquipRank(var/mob/living/H, var/rank, var/joined_late = 0)
+ if(!H.mind.need_job_assign)
+ return 0
+
var/datum/job/job = GetJob(rank)
H.job = rank
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index afa65e0f8ad..7e5801c56fe 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -174,13 +174,17 @@
else
dat += "DEAD"
dat += " "
- dat += "
"
- //Make sure antags can't completely ruin rounds
-
- //Don't allow more than 1 Head / limit blacklisted jobs
- switch(can_open_job(j))
- if(1)
- dat += "Open Position "
- if(-1)
- dat += "You cannot open any more positions for this job. "
- if(-2)
- var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - time_last_changed_position), 1)
- var/mins = round(time_to_wait / 60)
- var/seconds = time_to_wait - (60*mins)
- dat += "You have to wait [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"] minutes before you can open this position."
- if(0)
- dat += "You cannot open positions for this job. "
-
-
- switch(can_close_job(j))
- if(1)
- dat += "Close Position"
- if(-1)
- dat += "You cannot close any more positions for this job. "
- if(-2)
- var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - time_last_changed_position), 1)
- var/mins = round(time_to_wait / 60)
- var/seconds = time_to_wait - (60*mins)
- dat += "You have to wait [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"] minutes before you can close this position."
- if(0)
- dat += "You cannot close positions for this job. "
- else
- dat = "Return"
- dat += "
Please insert your ID
"
- mode = 3
-
+ S = "--------"
+ dat += "[S]"
+ dat += "
"
+ dat += "
Job
Slots
Open job
Close job
"
+ var/ID
+ if(scan && (access_change_ids in scan.access))
+ ID = 1
+ else
+ ID = 0
+ for(var/datum/job/job in job_master.occupations)
+ dat += "
"
+ if(job.title in blacklisted)
+ continue
+ dat += "
"
for(var/datum/mind/changeling in ticker.mode.changelings)
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index a51591a7f15..c4e51cbb72b 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -56,12 +56,17 @@
log_admin("[key_name(usr)] created a death squad.")
if(!src.makeDeathsquad())
usr << "Unfortunatly there were not enough candidates available."
-
if("11")
var/strength = input("Set Blob Strength (1=Weak, 2=Strong, 3=Full)","Set Strength",1) as num
message_admins("[key_name(usr)] spawned a blob with strength [strength].")
log_admin("[key_name(usr)] spawned a blob with strength [strength].")
new/datum/round_event/blob(strength)
+ if("12")
+ message_admins("[key_name(usr)] started a gang war.")
+ log_admin("[key_name(usr)] started a gang war.")
+ if(!src.makeGangsters())
+ usr << "Unfortunatly there were not enough candidates available."
+
else if(href_list["forceevent"])
var/datum/round_event_control/E = locate(href_list["forceevent"]) in events.control
@@ -579,6 +584,12 @@
jobs += "
" //Breaking it up so it fits nicer on the screen every 5 entries
+ //Gangster
+ if(jobban_isbanned(M, "gangster") || isbanned_dept)
+ jobs += "
"
@@ -1285,9 +1296,9 @@
//Job + antagonist
if(M.mind)
- special_role_description = "Role: [M.mind.assigned_role]; Antagonist: [M.mind.special_role]; Has been rev: [(M.mind.has_been_rev)?"Yes":"No"]"
+ special_role_description = "Role: [M.mind.assigned_role]; Antagonist: [M.mind.special_role]"
else
- special_role_description = "Role: Mind datum missing Antagonist: Mind datum missing; Has been rev: Mind datum missing;"
+ special_role_description = "Role: Mind datum missing Antagonist: Mind datum missing"
//Health
if(isliving(M))
@@ -1597,6 +1608,25 @@
var/datum/round_event/E
var/ok = 0
switch(href_list["secretsfun"])
+ if("tdomereset")
+ var/delete_mobs = alert("Clear all mobs?","Confirm","Yes","No","Cancel")
+ if(delete_mobs == "Cancel")
+ return
+
+ var/area/thunderdome = locate(/area/tdome/arena)
+ if(delete_mobs == "Yes")
+ for(var/mob/living/mob in thunderdome)
+ qdel(mob) //Clear mobs
+ for(var/obj/obj in thunderdome)
+ if(!istype(obj,/obj/machinery/camera))
+ qdel(obj) //Clear objects
+
+ var/area/template = locate(/area/tdome/arena_source)
+ template.copy_contents_to(thunderdome)
+
+ log_admin("[key_name(usr)] reset the thunderdome to default with delete_mobs==[delete_mobs].", 1)
+ message_admins("[key_name_admin(usr)] reset the thunderdome to default with delete_mobs==[delete_mobs].", 1)
+
if("monkey")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","M")
@@ -1823,6 +1853,22 @@
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SM")
rightandwrong(1, usr)
+ if("events")
+ if(events && !events.wizardmode)
+ if(alert("Do you want to toggle summon events on?",,"Yes","No") == "Yes")
+ summonevents()
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SE")
+
+ else if(events && events.wizardmode)
+ switch(alert("What would you like to do?",,"Intensify Summon Events","Turn Off Summon Events","Nothing"))
+ if("Intensify Summon Events")
+ summonevents()
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SE")
+ if("Turn Off Summon Events")
+ events.toggleWizardmode()
+ events.resetFrequency()
if("dorf")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","DF")
@@ -2202,4 +2248,4 @@
else if(href_list["ac_set_signature"])
src.admincaster_signature = adminscrub(input(usr, "Provide your desired signature", "Network Identity Handler", ""))
- src.access_news_network()
\ No newline at end of file
+ src.access_news_network()
diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
index 505482d4567..70af98fa0dd 100644
--- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm
+++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm
@@ -1,4 +1,5 @@
// Code taken from /bay/station.
+// Modified to allow consequtive querys in one invocation, terminated with ";"
// Examples
/*
@@ -10,6 +11,8 @@
UPDATE /obj/machinery/light IN world SET color = "#0F0" WHERE icon_state == "tube1"
-- Will delete all pickaxes. "IN world" is not required.
DELETE /obj/item/weapon/pickaxe
+ -- Will flicker the lights once, then turn all mobs green. The semicolon is important to separate the consecutive querys, but is not required for standard one-query use
+ CALL flicker(1) ON /obj/machinery/light; UPDATE /mob SET color = "#00cc00"
--You can use operators other than ==, such as >, <=, != and etc..
@@ -31,123 +34,153 @@
if(!query_list || query_list.len < 1)
return
- var/list/query_tree = SDQL_parse(query_list)
+ var/list/querys = SDQL_parse(query_list)
- if(query_tree.len < 1)
+ if(!querys || querys.len < 1)
return
- var/list/from_objs = list()
- var/list/select_types = list()
-
- switch(query_tree[1])
- if("explain")
- SDQL_testout(query_tree["explain"])
- return
-
- if("call")
- if("on" in query_tree)
- select_types = query_tree["on"]
- else
- return
-
- if("select", "delete", "update")
- select_types = query_tree[query_tree[1]]
-
- from_objs = SDQL_from_objs(query_tree["from"])
-
- var/list/objs = list()
-
- for(var/type in select_types)
- var/char = copytext(type, 1, 2)
-
- if(char == "/" || char == "*")
- for(var/from in from_objs)
- objs += SDQL_get_all(type, from)
-
- else if(char == "'" || char == "\"")
- objs += locate(copytext(type, 2, length(type)))
-
- if("where" in query_tree)
- var/objs_temp = objs
- objs = list()
- for(var/datum/d in objs_temp)
- if(SDQL_expression(d, query_tree["where"]))
- objs += d
var/query_log = "[usr] executed SDQL query: \"[query_text]\"."
world.log << query_log
message_admins(query_log)
log_game(query_log)
- switch(query_tree[1])
- if("call")
- var/list/call_list = query_tree["call"]
- var/list/args_list = query_tree["args"]
+ for(var/list/query_tree in querys)
+ var/list/from_objs = list()
+ var/list/select_types = list()
- for(var/datum/d in objs)
- for(var/v in call_list)
- // To stop any procs which sleep from executing slowly.
- if(d)
- if(hascall(d, v))
- spawn() call(d, v)(arglist(args_list)) // Spawn in case the function sleeps.
+ switch(query_tree[1])
+ if("explain")
+ SDQL_testout(query_tree["explain"])
+ return
- if("delete")
- for(var/datum/d in objs)
- del d
+ if("call")
+ if("on" in query_tree)
+ select_types = query_tree["on"]
+ else
+ return
- if("select")
- var/text = ""
- for(var/datum/t in objs)
- text += "\ref[t]"
- if(istype(t, /atom))
- var/atom/a = t
+ if("select", "delete", "update")
+ select_types = query_tree[query_tree[1]]
- if(a.x)
- text += ": [t] at ([a.x], [a.y], [a.z]) "
+ from_objs = SDQL_from_objs(query_tree["from"])
- else if(a.loc && a.loc.x)
- text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z]) "
+ var/list/objs = list()
+
+ for(var/type in select_types)
+ var/char = copytext(type, 1, 2)
+
+ if(char == "/" || char == "*")
+ for(var/from in from_objs)
+ objs += SDQL_get_all(type, from)
+
+ else if(char == "'" || char == "\"")
+ objs += locate(copytext(type, 2, length(type)))
+
+ if("where" in query_tree)
+ var/objs_temp = objs
+ objs = list()
+ for(var/datum/d in objs_temp)
+ if(SDQL_expression(d, query_tree["where"]))
+ objs += d
+
+ switch(query_tree[1])
+ if("call")
+ var/list/call_list = query_tree["call"]
+ var/list/args_list = query_tree["args"]
+
+ for(var/datum/d in objs)
+ for(var/v in call_list)
+ // To stop any procs which sleep from executing slowly.
+ if(d)
+ if(hascall(d, v))
+ spawn() call(d, v)(arglist(args_list)) // Spawn in case the function sleeps.
+
+ if("delete")
+ for(var/datum/d in objs)
+ del d
+
+ if("select")
+ var/text = ""
+ for(var/datum/t in objs)
+ text += "\ref[t]"
+ if(istype(t, /atom))
+ var/atom/a = t
+
+ if(a.x)
+ text += ": [t] at ([a.x], [a.y], [a.z]) "
+
+ else if(a.loc && a.loc.x)
+ text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z]) "
+
+ else
+ text += ": [t] "
else
text += ": [t] "
- else
- text += ": [t] "
+ usr << browse(text, "window=SDQL-result")
- usr << browse(text, "window=SDQL-result")
+ if("update")
+ if("set" in query_tree)
+ var/list/set_list = query_tree["set"]
+ for(var/datum/d in objs)
+ var/list/vals = list()
+ for(var/v in set_list)
+ if(v in d.vars)
+ vals += v
+ vals[v] = SDQL_expression(d, set_list[v])
- if("update")
- if("set" in query_tree)
- var/list/set_list = query_tree["set"]
- for(var/datum/d in objs)
- var/list/vals = list()
- for(var/v in set_list)
- if(v in d.vars)
- vals += v
- vals[v] = SDQL_expression(d, set_list[v])
+ if(istype(d, /turf))
+ for(var/v in vals)
+ if(v == "x" || v == "y" || v == "z")
+ continue
- if(istype(d, /turf))
- for(var/v in vals)
- if(v == "x" || v == "y" || v == "z")
- continue
+ d.vars[v] = vals[v]
- d.vars[v] = vals[v]
-
- else
- for(var/v in vals)
- d.vars[v] = vals[v]
+ else
+ for(var/v in vals)
+ d.vars[v] = vals[v]
/proc/SDQL_parse(list/query_list)
- var/datum/SDQL_parser/parser = new(query_list)
- var/list/query_tree = parser.parse()
+ var/datum/SDQL_parser/parser = new()
+ var/list/querys = list()
+ var/list/query_tree = list()
+ var/pos = 1
+ var/querys_pos = 1
+ var/do_parse = 0
+
+ for(var/val in query_list)
+ if(val == ";")
+ do_parse = 1
+ else if(pos >= query_list.len)
+ query_tree += val
+ do_parse = 1
+
+ if(do_parse)
+ parser.query = query_tree
+ var/list/parsed_tree
+ parsed_tree = parser.parse()
+ if(parsed_tree.len > 0)
+ querys.len = querys_pos
+ querys[querys_pos] = parsed_tree
+ querys_pos++
+ else //There was an error so don't run anything, and tell the user which query has errored.
+ usr << "Parsing error on [querys_pos]\th query. Nothing was executed."
+ return list()
+ query_tree = list()
+ do_parse = 0
+ else
+ query_tree += val
+ pos++
del(parser)
- return query_tree
+ return querys
@@ -350,7 +383,7 @@
/proc/SDQL2_tokenize(query_text)
var/list/whitespace = list(" ", "\n", "\t")
- var/list/single = list("(", ")", ",", "+", "-", ".")
+ var/list/single = list("(", ")", ",", "+", "-", ".", ";")
var/list/multi = list(
"=" = list("", "="),
"<" = list("", "=", ">"),
@@ -451,4 +484,4 @@
if(word != "")
query_list += word
- return query_list
\ No newline at end of file
+ return query_list
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 91cf7d75fb6..89e92bc079b 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -508,20 +508,6 @@ var/global/list/g_fancy_list_of_safe_types = null
qdel(adminmob)
feedback_add_details("admin_verb","ADC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-
-
-/client/proc/cmd_switch_radio()
- set category = "Debug"
- set name = "Switch Radio Mode"
- set desc = "Toggle between normal radios and experimental radios. Have a coder present if you do this."
-
- GLOBAL_RADIO_TYPE = !GLOBAL_RADIO_TYPE // toggle
- log_admin("[key_name(src)] has turned the experimental radio system [GLOBAL_RADIO_TYPE ? "on" : "off"].")
- message_admins("[key_name_admin(src)] has turned the experimental radio system [GLOBAL_RADIO_TYPE ? "on" : "off"].", 0)
- feedback_add_details("admin_verb","SRM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
/client/proc/cmd_admin_areatest()
set category = "Mapping"
set name = "Test areas"
@@ -836,7 +822,7 @@ var/global/list/g_fancy_list_of_safe_types = null
sec_briefcase.contents += new /obj/item/weapon/gun/energy/crossbow
sec_briefcase.contents += new /obj/item/weapon/gun/projectile/revolver/mateba
sec_briefcase.contents += new /obj/item/ammo_box/a357
- sec_briefcase.contents += new /obj/item/weapon/plastique
+ sec_briefcase.contents += new /obj/item/weapon/c4
M.equip_to_slot_or_del(sec_briefcase, slot_l_hand)
var/obj/item/device/pda/heads/pda = new(M)
@@ -1116,7 +1102,7 @@ var/global/list/g_fancy_list_of_safe_types = null
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/device/flashlight(M), slot_in_backpack)
- M.equip_to_slot_or_del(new /obj/item/weapon/plastique(M), slot_in_backpack)
+ M.equip_to_slot_or_del(new /obj/item/weapon/c4(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/shield/energy(M), slot_r_store)
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 5eee72c78c3..775210d6107 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -145,7 +145,6 @@ var/intercom_range_display_status = 0
src.verbs += /client/proc/disable_communication
src.verbs += /client/proc/print_pointers
src.verbs += /client/proc/count_movable_instances
- src.verbs += /client/proc/SDQL2_query
src.verbs += /client/proc/cmd_display_del_log
//src.verbs += /client/proc/cmd_admin_rejuvenate
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index 21875856b58..19db9821666 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -17,6 +17,7 @@ client/proc/one_click_antag()
Make Cult Make Malf AI Make Blob
+ Make Gangsters Make Wizard (Requires Ghosts) Make Nuke Team (Requires Ghosts) Make Deathsquad (Requires Ghosts)
@@ -332,8 +333,9 @@ client/proc/one_click_antag()
if(candidates.len >= 3) //Minimum 3 to be considered a squad
//Pick the lucky players
var/numagents = min(5,candidates.len) //How many commandos to spawn
- while(numagents && deathsquadspawn.len && candidates.len)
- var/spawnloc = deathsquadspawn[1]
+ var/list/spawnpoints = deathsquadspawn
+ while(numagents && spawnpoints.len && candidates.len)
+ var/spawnloc = spawnpoints[1]
var/mob/dead/observer/chosen_candidate = pick(candidates)
candidates -= chosen_candidate
if(!chosen_candidate.key)
@@ -373,15 +375,46 @@ client/proc/one_click_antag()
//Logging and cleanup
if(numagents == 1)
- message_admins("The deathsquad has spawned with [key_name_admin(Commando)] as squad leader.")
+ message_admins("The deathsquad has spawned with the mission: [mission].")
log_game("[key_name(Commando)] has been selected as a Death Commando")
- deathsquadspawn -= spawnloc
+ spawnpoints -= spawnloc
numagents--
return 1
return
+
+/datum/admins/proc/makeGangsters()
+
+ var/datum/game_mode/gang/temp = new
+ if(config.protect_roles_from_antagonist)
+ temp.restricted_jobs += temp.protected_jobs
+
+ var/list/mob/living/carbon/human/candidates = list()
+ var/mob/living/carbon/human/H = null
+
+ for(var/mob/living/carbon/human/applicant in player_list)
+ if(applicant.client.prefs.be_special & BE_GANG)
+ if(applicant.stat == CONSCIOUS)
+ if(applicant.mind)
+ if(!applicant.mind.special_role)
+ if(!jobban_isbanned(applicant, "gangster") && !jobban_isbanned(applicant, "Syndicate"))
+ if(!(applicant.job in temp.restricted_jobs))
+ candidates += applicant
+
+ if(candidates.len >= 2)
+ H = pick(candidates)
+ H.mind.make_Gang("A")
+ candidates.Remove(H)
+ H = pick(candidates)
+ H.mind.make_Gang("B")
+ candidates.Remove(H)
+ return 1
+
+ return 0
+
+
/datum/admins/proc/makeBody(var/mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
if(!G_found || !G_found.key) return
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index 325b1688a5b..d46487da15b 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -134,8 +134,7 @@ Code:
if(signal.encryption != code) return 0
if(!(src.wires & WIRE_RADIO_RECEIVE)) return 0
pulse(1)
- for(var/mob/O in hearers(1, src.loc))
- O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
+ src.loc.audible_message("\icon[src] *beep* *beep*", null, 1)
return
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 3c597dd443e..9cec6893165 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -165,7 +165,7 @@ var/next_external_rsc = 0
var/sql_ckey = sql_sanitize_text(src.ckey)
- var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM erro_player WHERE ckey = '[sql_ckey]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
query.Execute()
var/sql_id = 0
while(query.NextRow())
@@ -173,14 +173,14 @@ var/next_external_rsc = 0
player_age = text2num(query.item[2])
break
- var/DBQuery/query_ip = dbcon.NewQuery("SELECT ckey FROM erro_player WHERE ip = '[address]'")
+ var/DBQuery/query_ip = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = '[address]'")
query_ip.Execute()
related_accounts_ip = ""
while(query_ip.NextRow())
related_accounts_ip += "[query_ip.item[1]], "
break
- var/DBQuery/query_cid = dbcon.NewQuery("SELECT ckey FROM erro_player WHERE computerid = '[computer_id]'")
+ var/DBQuery/query_cid = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid = '[computer_id]'")
query_cid.Execute()
related_accounts_cid = ""
while(query_cid.NextRow())
@@ -205,16 +205,16 @@ var/next_external_rsc = 0
if(sql_id)
//Player already identified previously, we need to just update the 'lastseen', 'ip' and 'computer_id' variables
- var/DBQuery/query_update = dbcon.NewQuery("UPDATE erro_player SET lastseen = Now(), ip = '[sql_ip]', computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]' WHERE id = [sql_id]")
+ var/DBQuery/query_update = dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), ip = '[sql_ip]', computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]' WHERE id = [sql_id]")
query_update.Execute()
else
//New player!! Need to insert all the stuff
- var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO erro_player (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[sql_ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')")
+ var/DBQuery/query_insert = dbcon.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[sql_ckey]', Now(), Now(), '[sql_ip]', '[sql_computerid]', '[sql_admin_rank]')")
query_insert.Execute()
//Logging player access
var/serverip = "[world.internet_address]:[world.port]"
- var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `erro_connection_log`(`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[serverip]','[sql_ckey]','[sql_ip]','[sql_computerid]');")
+ var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[serverip]','[sql_ckey]','[sql_ip]','[sql_computerid]');")
query_accesslog.Execute()
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 7d3b28c5049..2ad54d17ca7 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -16,7 +16,8 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
"pAI candidate" = 1, // 7
"cultist" = IS_MODE_COMPILED("cult"), // 8
"blob" = IS_MODE_COMPILED("blob"), // 9
- "monkey" = IS_MODE_COMPILED("monkey") // 10
+ "monkey" = IS_MODE_COMPILED("monkey"), // 10
+ "gangster" = IS_MODE_COMPILED("gang") // 11
)
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index ddf7f3839a1..22e287c024f 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -153,8 +153,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(needs_update == -2) //fatal, can't load any data
return 0
- if(!S["species"] || !config.mutant_races)
- S["species"] << new /datum/species/human()
+ //Species
+ var/species_name
+ S["species"] >> species_name
+ if(config.mutant_races && species_name && (species_name in roundstart_species))
+ var/newtype = roundstart_species[species_name]
+ pref_species = new newtype()
+ else
+ pref_species = new /datum/species/human()
+
if(!S["mutant_color"] || S["mutant_color"] == "#000")
S["mutant_color"] << "#FFF"
@@ -172,7 +179,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["facial_style_name"] >> facial_hair_style
S["underwear"] >> underwear
S["backbag"] >> backbag
- S["species"] >> pref_species
S["mutant_color"] >> mutant_color
//Jobs
@@ -194,8 +200,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
- if(!(pref_species in species_list))
- pref_species = new /datum/species/human()
if(!mutant_color || mutant_color == "#000")
mutant_color = "#FFF"
if(!real_name) real_name = random_name(gender)
@@ -252,7 +256,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["facial_style_name"] << facial_hair_style
S["underwear"] << underwear
S["backbag"] << backbag
- S["species"] << pref_species
+ S["species"] << pref_species.name
S["mutant_color"] << mutant_color
//Jobs
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 3be8a220a74..60c2d9bb5b6 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -11,28 +11,6 @@
heat_protection = HEAD
max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT
-/obj/item/clothing/head/helmet/HoS
- name = "head of security hat"
- desc = "The robust hat of the Head of Security. For showing the officers who's in charge."
- icon_state = "hoscap"
- armor = list(melee = 80, bullet = 60, laser = 50,energy = 10, bomb = 25, bio = 10, rad = 0)
- flags = 0
- flags_inv = HIDEEARS
-
-/obj/item/clothing/head/helmet/HoS/dermal
- name = "Dermal Armor Patch"
- desc = "An armored implant that automatically integrates just below the scalp for robust protection without sacrificing style."
- icon_state = "dermal"
- item_state = "dermal"
- flags_inv = 0
-
-/obj/item/clothing/head/helmet/warden
- name = "warden's hat"
- desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts."
- icon_state = "policehelm"
- flags = 0
- flags_inv = HIDEEARS
-
/obj/item/clothing/head/helmet/riot
name = "riot helmet"
desc = "It's a helmet specifically designed to protect against close range attacks."
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 77480bb0f13..ebfb482daf7 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -10,26 +10,25 @@
//Captain
/obj/item/clothing/head/caphat
name = "captain's hat"
- icon_state = "captain"
desc = "It's good being the king."
+ icon_state = "captain"
item_state = "that"
-
-//Captain: This probably shouldn't be space-worthy
-/obj/item/clothing/head/helmet/cap
- name = "captain's cap"
- desc = "You fear to wear it for the negligence it brings."
- icon_state = "capcap"
flags_inv = 0
- cold_protection = HEAD
- min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
- heat_protection = HEAD
- max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT
+ armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
+
+//Captain: This is no longer space-worthy
+/obj/item/clothing/head/caphat/parade
+ name = "captain's parade cap"
+ desc = "Worn only by Captains with an abundance of class."
+ icon_state = "capcap"
+
//Head of Personnel
/obj/item/clothing/head/hopcap
name = "head of personnel's cap"
icon_state = "hopcap"
- desc = "Glory to Nanotrasen."
+ desc = "The symbol of true bureaucratic micromanagement."
+ armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
//Chaplain
/obj/item/clothing/head/chaplain_hood
@@ -46,8 +45,8 @@
flags = HEADCOVERSEYES|BLOCKHAIR
/obj/item/clothing/head/det_hat
- name = "hat"
- desc = "Someone who wears this will look very smart."
+ name = "detective's fedora"
+ desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat."
icon_state = "detective"
allowed = list(/obj/item/weapon/reagent_containers/food/snacks/candy_corn, /obj/item/weapon/pen)
armor = list(melee = 50, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0)
@@ -59,10 +58,35 @@
icon_state = "beret"
//Security
+
+/obj/item/clothing/head/HoS
+ name = "head of security hat"
+ desc = "The robust hat of the Head of Security. For showing the officers who's in charge."
+ icon_state = "hoscap"
+ armor = list(melee = 80, bullet = 60, laser = 50, energy = 10, bomb = 25, bio = 10, rad = 0)
+ flags = 0
+ flags_inv = HIDEEARS
+
+/obj/item/clothing/head/HoS/dermal
+ name = "Dermal Armor Patch"
+ desc = "An armored implant that automatically integrates just below the scalp for robust protection without sacrificing style."
+ icon_state = "dermal"
+ item_state = "dermal"
+ flags_inv = 0
+
+/obj/item/clothing/head/warden
+ name = "warden's hat"
+ desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts."
+ icon_state = "policehelm"
+ armor = list(melee = 60, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0)
+ flags = 0
+ flags_inv = HIDEEARS
+
/obj/item/clothing/head/beret/sec
name = "security beret"
- desc = "A beret with the security insignia emblazoned on it. For officers that are more inclined towards style than safety."
+ desc = "A robust beret with the security insignia emblazoned on it. For officers that are more inclined towards style than safety."
icon_state = "beret_badge"
+ armor = list(melee = 30, bullet = 5, laser = 15, energy = 10, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/head/beret/sec/navyhos
name = "head of security's beret"
@@ -76,4 +100,4 @@
/obj/item/clothing/head/beret/sec/navyofficer
desc = "A special beret with the security insignia emblazoned on it. For officers with class."
- icon_state = "officerberet"
\ No newline at end of file
+ icon_state = "officerberet"
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 1c473a51679..d1809f6b6a1 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -5,6 +5,8 @@
icon_state = "centcom"
desc = "It's good to be emperor."
item_state = "that"
+ flags_inv = 0
+ armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
/obj/item/clothing/head/powdered_wig
name = "powdered wig"
@@ -194,3 +196,16 @@
item_state = "shamebrero"
desc = "Once it's on, it never comes off."
flags = NODROP
+
+/obj/item/clothing/head/cone
+ desc = "This cone is trying to warn you of something!"
+ name = "warning cone"
+ icon = 'icons/obj/janitor.dmi'
+ icon_state = "cone"
+ item_state = "cone"
+ force = 1.0
+ throwforce = 3.0
+ throw_speed = 2
+ throw_range = 5
+ w_class = 2.0
+ attack_verb = list("warned", "cautioned", "smashed")
diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm
index 2dd7fbbd371..ee80353fbd6 100644
--- a/code/modules/clothing/head/soft_caps.dm
+++ b/code/modules/clothing/head/soft_caps.dm
@@ -89,4 +89,5 @@
name = "security cap"
desc = "It's a robust baseball hat in tasteful red colour."
icon_state = "secsoft"
- item_color = "sec"
\ No newline at end of file
+ item_color = "sec"
+ armor = list(melee = 30, bullet = 5, laser = 5, energy = 15, bomb = 0, bio = 0, rad = 0)
\ No newline at end of file
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index 1a21cda6535..40f373d19e0 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -195,6 +195,11 @@
var/voice = "Unknown"
var/vchange = 0//This didn't do anything before. It now checks if the mask has special functions/N
origin_tech = "syndicate=4"
+ action_button_name = "Toggle mask"
+
+/obj/item/clothing/mask/gas/voice/attack_self(mob/user)
+ vchange = !vchange
+ user << "The voice changer is now [vchange ? "on" : "off"]!"
/obj/item/clothing/mask/gas/voice/space_ninja
name = "ninja mask"
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 5b359700790..0a35967a5c4 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -43,3 +43,9 @@
icon_state = "advmag0"
magboot_state = "advmag"
slowdown_active = SHOES_SLOWDOWN
+
+/obj/item/clothing/shoes/magboots/syndie
+ desc = "Reverse-engineered magnetic boots that have a heavy magnetic pull. Property of Gorlex Marauders."
+ name = "blood-red magboots"
+ icon_state = "syndiemag0"
+ magboot_state = "syndiemag"
\ No newline at end of file
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 855d888ca2c..211f5515591 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -100,6 +100,7 @@
blood_overlay_type = "armor"
slowdown = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
+ action_button_name = "Toggle Armor"
/obj/item/clothing/suit/armor/reactive/IsShield()
if(active)
diff --git a/code/modules/events/event.dm b/code/modules/events/event.dm
index 20ec857ef56..ca9c11ec386 100644
--- a/code/modules/events/event.dm
+++ b/code/modules/events/event.dm
@@ -15,7 +15,10 @@
var/holidayID //string which should match the events.holiday variable if you wish this event to be holiday-specific
//anything with a (non-null) holidayID which does not match holiday, cannot run.
+ var/wizardevent = 0
+/datum/round_event_control/wizard
+ wizardevent = 1
/datum/round_event_control/proc/runEvent()
if(!ispath(typepath,/datum/round_event))
diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm
index 41196389a01..cf18c8b549f 100644
--- a/code/modules/events/event_manager.dm
+++ b/code/modules/events/event_manager.dm
@@ -21,8 +21,10 @@ var/datum/controller/event/events
for(var/type in typesof(/datum/round_event_control))
var/datum/round_event_control/E = new type()
- if(!E.typepath || E.typepath in typesof(/datum/round_event/wizard/))
+ if(!E.typepath)
continue //don't want this one! leave it for the garbage collector
+ if(E.wizardevent && !wizardmode)
+ E.weight = 0
control += E //add it to the list of all events (controls)
reschedule()
getHoliday()
@@ -122,9 +124,20 @@ var/datum/controller/event/events
holder.forceEvent()
/datum/admins/proc/forceEvent()
- var/dat = ""
+ var/dat = ""
+ var/normal = ""
+ var/magic = ""
+ var/holiday = ""
for(var/datum/round_event_control/E in events.control)
- dat += " [E]"
+ dat = " [E]"
+ if(E.holidayID)
+ holiday += dat
+ else if(E.wizardevent)
+ magic += dat
+ else
+ normal += dat
+
+ dat = normal + " " + magic + " " + holiday
var/datum/browser/popup = new(usr, "forceevent", "Force Random Event", 300, 750)
popup.set_content(dat)
@@ -254,3 +267,16 @@ var/datum/controller/event/events
holiday = "Friday the 13th"
world.update_status()
+
+/datum/controller/event/proc/toggleWizardmode()
+ wizardmode = !wizardmode
+ for(var/datum/round_event_control/E in control)
+ E.weight = initial(E.weight)
+ if((E.wizardevent && !wizardmode) || (!E.wizardevent && wizardmode))
+ E.weight = 0
+ message_admins("Summon Events has been [wizardmode ? "enabled, events will occur every [events.frequency_lower / 600] to [events.frequency_upper / 600] minutes" : "disabled"]!")
+ log_game("Summon Events was [wizardmode ? "enabled" : "disabled"]!")
+
+/datum/controller/event/proc/resetFrequency()
+ frequency_lower = initial(frequency_lower)
+ frequency_upper = initial(frequency_upper)
\ No newline at end of file
diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm
index 567e61bdf31..7cde782e7d6 100644
--- a/code/modules/events/immovable_rod.dm
+++ b/code/modules/events/immovable_rod.dm
@@ -49,8 +49,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
/obj/effect/immovablerod/Bump(atom/clong)
playsound(src, 'sound/effects/bang.ogg', 50, 1)
- for (var/mob/O in hearers(src, null))
- O.show_message("CLANG", 2)
+ audible_message("CLANG")
if(istype(clong, /turf/unsimulated) || istype(clong, /turf/simulated/shuttle)) //Unstoppable force meets immovable object
explosion(src.loc, 4, 5, 6, 7, 0)
diff --git a/code/modules/events/ninja.dm b/code/modules/events/ninja.dm
index 746d1010d0f..7e15d10946a 100644
--- a/code/modules/events/ninja.dm
+++ b/code/modules/events/ninja.dm
@@ -376,8 +376,8 @@ ________________________________________________________________________________
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/clothing/glasses/night(src), slot_glasses)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt)
- equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_r_store)
- equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_l_store)
+ equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_r_store)
+ equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back)
@@ -1875,8 +1875,7 @@ ________________________________________________________________________________
P.tnote += "← From [!s_control?(A):"an unknown source"]: [t] "
if (!P.silent)
playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
- for (var/mob/O in hearers(3, P.loc))
- O.show_message(text("\icon[P] *[P.ttone]*"))
+ P.loc.audible_message("\icon[P] *[P.ttone]*", null, 3)
P.overlays.Cut()
P.overlays += image('icons/obj/pda.dmi', "pda-r")
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index 6bf3499c193..addea4786a4 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -214,20 +214,21 @@
var/mob/living/buckled_mob
var/list/mutations = list()
- New()
- return
+/obj/effect/spacevine/New()
+ return
- Destroy()
- for(var/datum/spacevine_mutation/SM in mutations)
- SM.on_death(src)
- if(master)
- master.vines -= src
- master.growth_queue -= src
- if(!master.vines.len)
- var/obj/item/seeds/kudzuseed/KZ = new(loc)
- KZ.mutations |= mutations
- mutations = list()
- ..()
+/obj/effect/spacevine/Destroy()
+ for(var/datum/spacevine_mutation/SM in mutations)
+ SM.on_death(src)
+ if(master)
+ master.vines -= src
+ master.growth_queue -= src
+ if(!master.vines.len)
+ var/obj/item/seeds/kudzuseed/KZ = new(loc)
+ KZ.mutations |= mutations
+ mutations = list()
+ SetOpacity(0)
+ ..()
/obj/effect/spacevine/proc/on_chem_effect(datum/reagent/R)
var/override = 0
@@ -347,84 +348,84 @@
//What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0,
//meaning if you get the spacevines' size to something less than 20 plots, it won't grow anymore.
- New(loc, list/muts, mttv)
- if(!istype(src.loc,/turf/simulated/floor))
- qdel(src)
+/obj/effect/spacevine_controller/New(loc, list/muts, mttv)
+ if(!istype(src.loc,/turf/simulated/floor))
+ qdel(src)
- spawn_spacevine_piece(src.loc, , muts)
- processing_objects.Add(src)
- init_subtypes(/datum/spacevine_mutation/, mutations_list)
- if(mttv != null)
- mutativness = mttv
+ spawn_spacevine_piece(src.loc, , muts)
+ processing_objects.Add(src)
+ init_subtypes(/datum/spacevine_mutation/, mutations_list)
+ if(mttv != null)
+ mutativness = mttv
- Destroy()
- processing_objects.Remove(src)
- ..()
+/obj/effect/spacevine_controller/Destroy()
+ processing_objects.Remove(src)
+ ..()
- proc/spawn_spacevine_piece(var/turf/location, obj/effect/spacevine/parent, list/muts)
- var/obj/effect/spacevine/SV = new(location)
- growth_queue += SV
- vines += SV
- SV.master = src
- if(muts && muts.len)
- SV.mutations |= muts
- if(parent)
- SV.mutations |= parent.mutations
- SV.color = parent.color
- if(prob(mutativness))
- SV.mutations |= pick(mutations_list)
- var/datum/spacevine_mutation/randmut = pick(SV.mutations)
- SV.color = randmut.hue
+/obj/effect/spacevine_controller/proc/spawn_spacevine_piece(var/turf/location, obj/effect/spacevine/parent, list/muts)
+ var/obj/effect/spacevine/SV = new(location)
+ growth_queue += SV
+ vines += SV
+ SV.master = src
+ if(muts && muts.len)
+ SV.mutations |= muts
+ if(parent)
+ SV.mutations |= parent.mutations
+ SV.color = parent.color
+ if(prob(mutativness))
+ SV.mutations |= pick(mutations_list)
+ var/datum/spacevine_mutation/randmut = pick(SV.mutations)
+ SV.color = randmut.hue
- for(var/datum/spacevine_mutation/SM in SV.mutations)
- SM.on_birth(SV)
+ for(var/datum/spacevine_mutation/SM in SV.mutations)
+ SM.on_birth(SV)
- process()
- if(!vines)
- qdel(src) //space vines exterminated. Remove the controller
- return
- if(!growth_queue)
- qdel(src) //Sanity check
- return
- if(vines.len >= 250 && !reached_collapse_size)
- reached_collapse_size = 1
- if(vines.len >= 30 && !reached_slowdown_size )
- reached_slowdown_size = 1
+/obj/effect/spacevine_controller/process()
+ if(!vines)
+ qdel(src) //space vines exterminated. Remove the controller
+ return
+ if(!growth_queue)
+ qdel(src) //Sanity check
+ return
+ if(vines.len >= 250 && !reached_collapse_size)
+ reached_collapse_size = 1
+ if(vines.len >= 30 && !reached_slowdown_size )
+ reached_slowdown_size = 1
- var/length = 0
- if(reached_collapse_size)
- length = 0
- else if(reached_slowdown_size)
- if(prob(25))
- length = 1
- else
- length = 0
- else
+ var/length = 0
+ if(reached_collapse_size)
+ length = 0
+ else if(reached_slowdown_size)
+ if(prob(25))
length = 1
- length = min( 30 , max( length , vines.len / 5 ) )
- var/i = 0
- var/list/obj/effect/spacevine/queue_end = list()
+ else
+ length = 0
+ else
+ length = 1
+ length = min( 30 , max( length , vines.len / 5 ) )
+ var/i = 0
+ var/list/obj/effect/spacevine/queue_end = list()
- for( var/obj/effect/spacevine/SV in growth_queue )
- i++
- queue_end += SV
- growth_queue -= SV
- for(var/datum/spacevine_mutation/SM in SV.mutations)
- SM.process_mutation(SV)
- if(SV.energy < 2) //If tile isn't fully grown
- if(prob(20))
- SV.grow()
- else //If tile is fully grown
- SV.buckle_mob()
+ for( var/obj/effect/spacevine/SV in growth_queue )
+ i++
+ queue_end += SV
+ growth_queue -= SV
+ for(var/datum/spacevine_mutation/SM in SV.mutations)
+ SM.process_mutation(SV)
+ if(SV.energy < 2) //If tile isn't fully grown
+ if(prob(20))
+ SV.grow()
+ else //If tile is fully grown
+ SV.buckle_mob()
- //if(prob(25))
- SV.spread()
- if(i >= length)
- break
+ //if(prob(25))
+ SV.spread()
+ if(i >= length)
+ break
- growth_queue = growth_queue + queue_end
- //sleep(5)
- //src.process()
+ growth_queue = growth_queue + queue_end
+ //sleep(5)
+ //src.process()
/obj/effect/spacevine/proc/grow()
if(!energy)
diff --git a/code/modules/events/wizard/aid.dm b/code/modules/events/wizard/aid.dm
index 8c215e0fbe0..f7689ae4e1f 100644
--- a/code/modules/events/wizard/aid.dm
+++ b/code/modules/events/wizard/aid.dm
@@ -34,6 +34,8 @@
for(var/obj/effect/proc_holder/spell/S in L.mind.spell_list)
S.name = initial(S.name)
S.spell_level++
+ if(S.spell_level >= 6 || S.charge_max <= 0) //Badmin checks, these should never be a problem in normal play
+ continue
S.charge_max = round(initial(S.charge_max) - S.spell_level * (initial(S.charge_max) - S.cooldown_min)/ S.level_max)
if(S.charge_max < S.charge_counter)
S.charge_counter = S.charge_max
diff --git a/code/modules/events/wizard/blobies.dm b/code/modules/events/wizard/blobies.dm
index aff93fccaa7..d66cd5f76c3 100644
--- a/code/modules/events/wizard/blobies.dm
+++ b/code/modules/events/wizard/blobies.dm
@@ -3,7 +3,7 @@
weight = 3
typepath = /datum/round_event/wizard/blobies/
max_occurrences = 3
- earliest_start = 0
+ earliest_start = 12000 // 20 minutes (gotta get some bodies made!)
/datum/round_event/wizard/blobies/start()
diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm
index 340e3a0c268..c057de5b96e 100644
--- a/code/modules/events/wizard/curseditems.dm
+++ b/code/modules/events/wizard/curseditems.dm
@@ -10,7 +10,7 @@
//item you want to equip to the hand, and set its slots_flags = null. Only items equiped to hands need do this.
/datum/round_event/wizard/cursed_items/start()
- var/item_set = pick("wizardmimic", "swords", "bigfatdoobie", "boxing", "voicemodulators", "headphones")
+ var/item_set = pick("wizardmimic", "swords", "bigfatdoobie", "boxing", "voicemodulators")
var/list/wearslots = list(slot_wear_suit, slot_shoes, slot_head, slot_wear_mask, slot_r_hand, slot_gloves, slot_ears)
var/list/loadout = list()
var/ruins_spaceworthiness
@@ -29,7 +29,6 @@
loadout[6] = /obj/item/clothing/gloves/boxing
ruins_spaceworthiness = 1
if("voicemodulators") loadout[4] = /obj/item/clothing/mask/gas/voice
- if("headphones") loadout[7] = /obj/item/clothing/ears/earmuffs
for(var/mob/living/carbon/human/H in living_mob_list)
if(ruins_spaceworthiness && (H.z != 1 || istype(H.loc, /turf/space))) continue //#savetheminers
diff --git a/code/modules/events/wizard/fakeexplosion.dm b/code/modules/events/wizard/fakeexplosion.dm
index 893b6d2e95b..1424d63c18e 100644
--- a/code/modules/events/wizard/fakeexplosion.dm
+++ b/code/modules/events/wizard/fakeexplosion.dm
@@ -1,6 +1,6 @@
/datum/round_event_control/wizard/fake_explosion //Oh no the station is gone!
name = "Fake Explosion"
- weight = 2
+ weight = 0 //Badmin exclusive now because once it's expected its not funny
typepath = /datum/round_event/wizard/fake_explosion/
max_occurrences = 1
earliest_start = 0
diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm
index 6ac5ad460ee..3d8b0f4ddca 100644
--- a/code/modules/events/wizard/greentext.dm
+++ b/code/modules/events/wizard/greentext.dm
@@ -21,7 +21,7 @@
/obj/item/weapon/greentext/
name = "greentext"
- desc = "for some the pursuit of greentext is the greatest calling in life..."
+ desc = "No one knows what this massive tome does, but it feels desirable all the same..."
w_class = 4.0
icon = 'icons/obj/wizard.dmi'
icon_state = "greentext"
diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm
index a28dab20daf..96d8c5ea8ff 100644
--- a/code/modules/events/wizard/race.dm
+++ b/code/modules/events/wizard/race.dm
@@ -18,5 +18,6 @@
if(H.dna)
H.dna.species = new new_species
H.regenerate_icons()
+ H << "You feel somehow... different?"
if(!all_the_same)
new_species = pick(all_species)
diff --git a/code/modules/events/wizard/shuffle.dm b/code/modules/events/wizard/shuffle.dm
index e49d9be5368..4315f3a4261 100644
--- a/code/modules/events/wizard/shuffle.dm
+++ b/code/modules/events/wizard/shuffle.dm
@@ -24,7 +24,7 @@
for(var/mob/living/carbon/human/H in mobs)
if(!moblocs) break //locs aren't always unique, so this may come into play
- H.loc = moblocs[moblocs.len]
+ do_teleport(H, moblocs[moblocs.len])
moblocs.len -= 1
for(var/mob/living/carbon/human/H in living_mob_list)
@@ -46,7 +46,7 @@
var/list/mobs = list()
for(var/mob/living/carbon/human/H in living_mob_list)
- mobnames += H.name
+ mobnames += H.real_name
mobs += H
if(!mobs) return
@@ -56,7 +56,7 @@
for(var/mob/living/carbon/human/H in mobs)
if(!mobnames) break
- H.name = mobnames[mobnames.len]
+ H.real_name = mobnames[mobnames.len]
mobnames.len -= 1
for(var/mob/living/carbon/human/H in living_mob_list)
@@ -85,10 +85,11 @@
shuffle(mobs)
var/obj/effect/proc_holder/spell/targeted/mind_transfer/swapper = new /obj/effect/proc_holder/spell/targeted/mind_transfer/
- for(var/mob/living/carbon/human/H in mobs)
+ while(mobs.len > 1)
+ var/mob/living/carbon/human/H = pick(mobs)
+ mobs -= H
swapper.cast(list(H), mobs[mobs.len], 1)
- mobs.len -= 1
- if(mobs.len <= 1) break
+ mobs -= mobs[mobs.len]
for(var/mob/living/carbon/human/H in living_mob_list)
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 32692b64771..3f884fcac54 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -344,7 +344,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
/obj/item/clothing/mask/gas/voice, /obj/item/clothing/glasses/thermal,\
/obj/item/device/chameleon, /obj/item/weapon/card/emag,\
/obj/item/weapon/storage/toolbox/syndicate, /obj/item/weapon/aiModule,\
- /obj/item/device/radio/headset/syndicate, /obj/item/weapon/plastique,\
+ /obj/item/device/radio/headset/syndicate, /obj/item/weapon/c4,\
/obj/item/device/powersink, /obj/item/weapon/storage/box/syndie_kit,\
/obj/item/toy/syndicateballoon, /obj/item/weapon/gun/energy/laser/captain,\
/obj/item/weapon/hand_tele, /obj/item/weapon/rcd, /obj/item/weapon/tank/jetpack,\
diff --git a/code/modules/food&drinks/kitchen machinery/microwave.dm b/code/modules/food&drinks/kitchen machinery/microwave.dm
index 8eca9a923cc..247b6721383 100644
--- a/code/modules/food&drinks/kitchen machinery/microwave.dm
+++ b/code/modules/food&drinks/kitchen machinery/microwave.dm
@@ -1,5 +1,6 @@
/obj/machinery/microwave
name = "microwave"
+ desc = "Keeps hot things hot and cold things hot."
icon = 'icons/obj/kitchen.dmi'
icon_state = "mw"
layer = 2.9
diff --git a/code/modules/food&drinks/kitchen machinery/smartfridge.dm b/code/modules/food&drinks/kitchen machinery/smartfridge.dm
index ea28ba2f3c1..014669ec4ad 100644
--- a/code/modules/food&drinks/kitchen machinery/smartfridge.dm
+++ b/code/modules/food&drinks/kitchen machinery/smartfridge.dm
@@ -3,6 +3,7 @@
// -------------------------
/obj/machinery/smartfridge
name = "smartfridge"
+ desc = "Keeps cold things cold and hot things cold."
icon = 'icons/obj/vending.dmi'
icon_state = "smartfridge"
layer = 2.9
diff --git a/code/modules/food&drinks/recipes/microwave/recipes_soup.dm b/code/modules/food&drinks/recipes/microwave/recipes_soup.dm
index 655d420ba3b..c5b717f3822 100644
--- a/code/modules/food&drinks/recipes/microwave/recipes_soup.dm
+++ b/code/modules/food&drinks/recipes/microwave/recipes_soup.dm
@@ -87,7 +87,7 @@
reagents = list("water" = 10)
items = list(
/obj/item/weapon/reagent_containers/food/snacks/grown/banana,
- /obj/item/weapon/ore/clown,
+ /obj/item/weapon/ore/bananium,
)
result = /obj/item/weapon/reagent_containers/food/snacks/clownstears
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index 22ac1096d87..3b76c06082c 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -1,6 +1,6 @@
/obj/machinery/biogenerator
name = "Biogenerator"
- desc = ""
+ desc = "Converts plants into biomass, which can be used to construct useful items."
icon = 'icons/obj/biogenerator.dmi'
icon_state = "biogen-empty"
density = 1
@@ -286,4 +286,4 @@
else if(href_list["menu"])
menustat = "menu"
updateUsrDialog()
-
+
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index 56c26ec1530..54fb349d79d 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -817,20 +817,19 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
mind.transfer_to(podman)
mind.active = oldactive
// -- Mode/mind specific stuff goes here. TODO! Broken :( Should be merged into mob/living/Login
- switch(ticker.mode.name)
- if("revolution")
- if(podman.mind in ticker.mode:revolutionaries)
- ticker.mode:add_revolutionary(podman.mind)
- ticker.mode:update_all_rev_icons() //So the icon actually appears
- if(podman.mind in ticker.mode:head_revolutionaries)
- ticker.mode:update_all_rev_icons()
- if("nuclear emergency")
- if(podman.mind in ticker.mode:syndicates)
- ticker.mode:update_all_synd_icons()
- if("cult")
- if(podman.mind in ticker.mode:cult)
- ticker.mode:add_cultist(podman.mind)
- ticker.mode:update_all_cult_icons() //So the icon actually appears
+ if((podman.mind in ticker.mode.A_bosses) || (podman.mind in ticker.mode.A_gangsters) || (podman.mind in ticker.mode.B_bosses) || (podman.mind in ticker.mode.B_gangsters))
+ ticker.mode.update_all_gang_icons()
+ if(podman.mind in ticker.mode:revolutionaries)
+ ticker.mode.add_revolutionary(podman.mind)
+ ticker.mode.update_all_rev_icons() //So the icon actually appears
+ if(podman.mind in ticker.mode:head_revolutionaries)
+ ticker.mode.add_revolutionary(podman.mind)
+ ticker.mode.update_all_rev_icons()
+ if(podman.mind in ticker.mode:syndicates)
+ ticker.mode:update_all_synd_icons()
+ if(podman.mind in ticker.mode:cult)
+ ticker.mode:add_cultist(podman.mind)
+ ticker.mode:update_all_cult_icons() //So the icon actually appears
// -- End mode specific stuff
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index 19559ac0523..7cad50f8d9d 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -98,7 +98,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
author = null
author = sanitizeSQL(author)
if(href_list["search"])
- SQLquery = "SELECT author, title, category, id FROM erro_library WHERE isnull(deleted) AND "
+ SQLquery = "SELECT author, title, category, id FROM [format_table_name("library")] WHERE isnull(deleted) AND "
if(category == "Any")
SQLquery += "author LIKE '%[author]%' AND title LIKE '%[title]%'"
else
@@ -201,7 +201,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
dat += "
"
dat += "
AUTHOR
TITLE
CATEGORY
"
- var/DBQuery/query = dbcon.NewQuery("SELECT id, author, title, category FROM erro_library WHERE isnull(deleted)")
+ var/DBQuery/query = dbcon.NewQuery("SELECT id, author, title, category FROM [format_table_name("library")] WHERE isnull(deleted)")
query.Execute()
while(query.NextRow())
@@ -252,8 +252,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
var/obj/item/weapon/barcodescanner/scanner = W
scanner.computer = src
user << "[scanner]'s associated machine has been set to [src]."
- for (var/mob/V in hearers(src))
- V.show_message("[src] lets out a low, short blip.", 2)
+ audible_message("[src] lets out a low, short blip.")
else
..()
@@ -292,8 +291,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
bibledelay = 0
else
- for (var/mob/V in hearers(src))
- V.show_message("[src]'s monitor flashes, \"Bible printer currently unavailable, please wait a moment.\"")
+ say("Bible printer currently unavailable, please wait a moment.")
if("7")
screenstate = 7
@@ -351,7 +349,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
var/sqlauthor = sanitizeSQL(scanner.cache.author)
var/sqlcontent = sanitizeSQL(scanner.cache.dat)
var/sqlcategory = sanitizeSQL(upload_category)
- var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_library (author, title, content, category, ckey, datetime) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', '[usr.ckey]', Now())")
+ var/DBQuery/query = dbcon.NewQuery("INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, datetime) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', '[usr.ckey]', Now())")
if(!query.Execute())
usr << query.ErrorMsg()
else
@@ -364,13 +362,12 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
if(!dbcon.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
if(bibledelay)
- for (var/mob/V in hearers(src))
- V.show_message("[src]'s monitor flashes, \"Printer unavailable. Please allow a short time before attempting to print.\"")
+ say("Printer unavailable. Please allow a short time before attempting to print.")
else
bibledelay = 1
spawn(60)
bibledelay = 0
- var/DBQuery/query = dbcon.NewQuery("SELECT * FROM erro_library WHERE id=[sqlid] AND isnull(deleted)")
+ var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("library")] WHERE id=[sqlid] AND isnull(deleted)")
query.Execute()
while(query.NextRow())
@@ -395,6 +392,11 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
src.updateUsrDialog()
return
+/obj/machinery/librarycomp/say_quote(text)
+ return "flashes, \"[text]\""
+
+
+
/*
* Library Scanner
*/
diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm
index 63454894ebb..8aa2b1b019f 100644
--- a/code/modules/mining/equipment_locker.dm
+++ b/code/modules/mining/equipment_locker.dm
@@ -41,7 +41,8 @@
D.createmessage("Ore Redemption Machine", "New minerals available!", msg, 1, 0)
var/obj/item/stack/sheet/storage = stack_list[processed_sheet]
storage.amount += 1 //Stack the sheets
- O.loc = null //Let the old sheet garbage collect
+ O.loc = null //Let the old sheet...
+ qdel(O) //... garbage collect
/obj/machinery/mineral/ore_redemption/process()
if(!panel_open) //If the machine is partially dissassembled, it should not process minerals
@@ -76,9 +77,7 @@
return
if(panel_open)
if(istype(W, /obj/item/weapon/crowbar))
- for (var/obj/O in src.contents)
- O.loc = src.loc //Drop item to the floor
- O.layer = initial(O.layer)
+ empty_content()
default_deconstruction_crowbar(W)
return 1
if(default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", W))
@@ -197,18 +196,27 @@
s.start()
if(severity == 1)
if(prob(50))
- for (var/obj/O in src.contents)
- O.loc = src.loc //Drop item to the floor
- O.layer = initial(O.layer)
+ empty_content()
qdel(src)
else if(severity == 2)
if(prob(25))
- for (var/obj/O in src.contents)
- O.loc = src.loc //Drop item to the floor
- O.layer = initial(O.layer)
+ empty_content()
qdel(src)
return
+//empty the redemption machine by stacks of at most max_amount (50 at this time) size
+/obj/machinery/mineral/ore_redemption/proc/empty_content()
+ var/obj/item/stack/sheet/s
+
+ for(var/O in stack_list)
+ s = stack_list[O]
+ while(s.amount > s.max_amount)
+ new s.type(loc,s.max_amount)
+ s.use(s.max_amount)
+ s.loc = loc
+ s.layer = initial(s.layer)
+
+
/**********************Mining Equipment Vendor**************************/
/obj/machinery/mineral/equipment_vendor
@@ -576,7 +584,7 @@
projectilesound = 'sound/weapons/Gunshot4.ogg'
wanted_objects = list(/obj/item/weapon/ore/diamond, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/silver,
/obj/item/weapon/ore/plasma, /obj/item/weapon/ore/uranium, /obj/item/weapon/ore/iron,
- /obj/item/weapon/ore/clown)
+ /obj/item/weapon/ore/bananium)
/mob/living/simple_animal/hostile/mining_drone/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/weldingtool))
@@ -591,7 +599,7 @@
health += 10
user << "You repair some of the armor on [src]."
return
- if(istype(I, /obj/item/device/mining_scanner))
+ if(istype(I, /obj/item/device/t_scanner/mining_scanner))
user << "You instruct [src] to drop any collected ore."
DropOre()
return
@@ -725,45 +733,46 @@
usr << "The display on [src] seems to be flickering."
/**********************Mining Scanner**********************/
-/obj/item/device/mining_scanner
+/obj/item/device/t_scanner/mining_scanner
desc = "A scanner that checks surrounding rock for useful minerals, it can also be used to stop gibtonite detonations. Requires you to wear mesons to work properly."
name = "mining scanner"
- icon_state = "mining"
+ icon_state = "mining0"
item_state = "analyzer"
w_class = 2.0
flags = CONDUCT
slot_flags = SLOT_BELT
var/cooldown = 0
-/obj/item/device/mining_scanner/attack_self(mob/user)
- if(!user.client)
- return
+/obj/item/device/t_scanner/mining_scanner/scan()
if(!cooldown)
cooldown = 1
- spawn(40)
+ spawn(100)
cooldown = 0
- var/client/C = user.client
+ var/turf/t = get_turf(src)
+ var/list/mobs = recursive_mob_check(t, 1,0,0)
+ if(!mobs.len)
+ return
var/list/L = list()
var/turf/simulated/mineral/M
- for(M in range(7, user))
+ for(M in range(7, t))
if(M.scan_state)
L += M
- if(!L.len)
- user << "[src] reports that nothing was detected nearby."
- return
- else
- for(M in L)
- var/turf/T = get_turf(M)
- var/image/I = image('icons/turf/walls.dmi', loc = T, icon_state = M.scan_state, layer = 18)
- C.images += I
- spawn(30)
- if(C)
- C.images -= I
+ if(L.len)
+ for(var/mob/user in mobs)
+ if(user.client)
+ var/client/C = user.client
+ for(M in L)
+ var/turf/T = get_turf(M)
+ var/image/I = image('icons/turf/walls.dmi', loc = T, icon_state = M.scan_state, layer = 18)
+ C.images += I
+ spawn(30)
+ if(C)
+ C.images -= I
//Debug item to identify all ore spread quickly
-/obj/item/device/mining_scanner/admin
+/obj/item/device/t_scanner/mining_scanner/admin
-/obj/item/device/mining_scanner/admin/attack_self(mob/user)
+/obj/item/device/t_scanner/mining_scanner/admin/attack_self(mob/user)
for(var/turf/simulated/mineral/M in world)
if(M.scan_state)
M.icon_state = M.scan_state
diff --git a/code/modules/mining/laborcamp/laborshuttle.dm b/code/modules/mining/laborcamp/laborshuttle.dm
index 49d287e75c0..b8030133c76 100644
--- a/code/modules/mining/laborcamp/laborshuttle.dm
+++ b/code/modules/mining/laborcamp/laborshuttle.dm
@@ -1,5 +1,6 @@
/obj/machinery/computer/shuttle/labor
name = "labor shuttle console"
+ desc = "Used to call and send the labor camp shuttle."
icon = 'icons/obj/computer.dmi'
icon_state = "shuttle"
circuit = /obj/item/weapon/circuitboard/labor_shuttle
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index 3dfcec72548..9aacac2f023 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -271,7 +271,7 @@
if (selected_glass == 0 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 0 && selected_plasma == 0 && selected_uranium == 0 && selected_iron == 0 && selected_clown == 1)
if (ore_clown > 0)
ore_clown--;
- generate_mineral(/obj/item/stack/sheet/mineral/clown)
+ generate_mineral(/obj/item/stack/sheet/mineral/bananium)
else
on = 0
continue
@@ -385,7 +385,7 @@
ore_uranium++
O.loc = null
continue
- if (istype(O,/obj/item/weapon/ore/clown))
+ if (istype(O,/obj/item/weapon/ore/bananium))
ore_clown++
O.loc = null
continue
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index f660ba1c7f9..31358b8a373 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -30,7 +30,7 @@
new /obj/item/clothing/under/rank/miner(src)
new /obj/item/clothing/gloves/fingerless(src)
new /obj/item/clothing/shoes/sneakers/black(src)
- new /obj/item/device/mining_scanner(src)
+ new /obj/item/device/t_scanner/mining_scanner(src)
new /obj/item/weapon/storage/bag/ore(src)
new /obj/item/device/flashlight/lantern(src)
new /obj/item/weapon/shovel(src)
@@ -43,6 +43,7 @@
/obj/machinery/computer/shuttle/mining
name = "Mining Shuttle Console"
+ desc = "Used to call and send the mining shuttle."
req_access = list(access_mining)
circuit = /obj/item/weapon/circuitboard/mining_shuttle
id = "mining"
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index a12594ac512..eb3820ee4db 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -204,7 +204,7 @@
..()
/turf/simulated/mineral/gibtonite/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/device/mining_scanner) && stage == 1)
+ if(istype(I, /obj/item/device/t_scanner/mining_scanner) && stage == 1)
user.visible_message("You use [I] to locate where to cut off the chain reaction and attempt to stop it...")
defuse()
if(istype(I, /obj/item/weapon/pickaxe))
@@ -372,7 +372,7 @@
/turf/simulated/mineral/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
+ if (!user.IsAdvancedToolUser())
usr << "You don't have the dexterity to do this!"
return
@@ -417,7 +417,7 @@
if (src.mineralName == "Diamond")
new /obj/item/weapon/ore/diamond(src)
if (src.mineralName == "Clown")
- new /obj/item/weapon/ore/clown(src)
+ new /obj/item/weapon/ore/bananium(src)
var/turf/simulated/floor/plating/asteroid/airless/N = ChangeTurf(/turf/simulated/floor/plating/asteroid/airless)
N.fullUpdateMineralOverlays()
return
diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm
index 9ae9d7bd63d..b7d3df5920b 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -43,7 +43,7 @@
if (istype(O, /obj/item/stack/sheet/metal))
amt_iron += 100 * O.amount
O.loc = null
- if (istype(O, /obj/item/stack/sheet/mineral/clown))
+ if (istype(O, /obj/item/stack/sheet/mineral/bananium))
amt_clown += 100 * O.amount
O.loc = null
if (istype(O, /obj/item/stack/sheet/mineral/adamantine))
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index 76992c3ff15..2da6f078895 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -85,12 +85,12 @@
points = 36
refined_type = /obj/item/stack/sheet/mineral/diamond
-/obj/item/weapon/ore/clown
+/obj/item/weapon/ore/bananium
name = "Bananium ore"
icon_state = "Clown ore"
origin_tech = "materials=4"
points = 27
- refined_type = /obj/item/stack/sheet/mineral/clown
+ refined_type = /obj/item/stack/sheet/mineral/bananium
/obj/item/weapon/ore/slag
name = "Slag"
@@ -114,7 +114,7 @@
if(istype(I, /obj/item/weapon/pickaxe) || istype(I, /obj/item/weapon/resonator))
GibtoniteReaction(user)
return
- if(istype(I, /obj/item/device/mining_scanner) && primed)
+ if(istype(I, /obj/item/device/t_scanner/mining_scanner) && primed)
primed = 0
user.visible_message("The chain reaction was stopped! ...The ore's quality went down.")
icon_state = "Gibtonite ore"
diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm
index 794efb49ec8..20636dabd5f 100644
--- a/code/modules/mining/satchel_ore_boxdm.dm
+++ b/code/modules/mining/satchel_ore_boxdm.dm
@@ -45,7 +45,7 @@
amt_gold++;
if (istype(C,/obj/item/weapon/ore/uranium))
amt_uranium++;
- if (istype(C,/obj/item/weapon/ore/clown))
+ if (istype(C,/obj/item/weapon/ore/bananium))
amt_clown++;
var/dat = text("The contents of the ore box reveal... ")
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index c88b3628ec8..bac012618e0 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -127,9 +127,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(ticker.mode)
//world << "DEBUG: ticker not null"
if(ticker.mode.name == "AI malfunction")
+ var/datum/game_mode/malfunction/malf = ticker.mode
//world << "DEBUG: malf mode ticker test"
- if(ticker.mode:malf_mode_declared)
- stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
+ if(malf.malf_mode_declared && (malf.apcs > 0))
+ stat(null, "Time left: [max(malf.AI_win_timeleft/malf.apcs, 0)]")
if(emergency_shuttle)
if(emergency_shuttle.online && emergency_shuttle.location < 2)
var/timeleft = emergency_shuttle.timeleft()
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 3bb33028ea0..b69a4d28123 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -143,12 +143,15 @@ Doesn't work on other aliens/AI.*/
set category = "Alien"
if(powerc(55))
+ if(locate(/obj/structure/alien/resin) in loc)
+ src << "There is already a resin structure there."
+ return
var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist
if(!choice || !powerc(55)) return
adjustToxLoss(-55)
- src << "You shape a [choice]."
+ src << "You shape a [choice]."
for(var/mob/O in viewers(src, null))
- O.show_message(text("[src] vomits up a thick purple substance and begins to shape it!"), 1)
+ O.show_message(text("[src] vomits up a thick purple substance and begins to shape it."), 1)
switch(choice)
if("resin wall")
new /obj/structure/alien/resin/wall(loc)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/emote.dm b/code/modules/mob/living/carbon/alien/humanoid/emote.dm
index ed3061be2e8..384f405b03f 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/emote.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/emote.dm
@@ -79,11 +79,7 @@
playsound(src.loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(703)
+ visible_message(message)
else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(746)
+ src.loc.audible_message(message)
return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm
index 07e658c5c3f..a085a66055d 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm
@@ -3,39 +3,3 @@
if(!. || !I)
return
- if(I == r_store)
- r_store = null
- update_inv_pockets(0)
- else if(I == l_store)
- l_store = null
- update_inv_pockets(0)
-
-
-//yaaaaaaay snowflakes
-/mob/living/carbon/alien/humanoid/attack_ui(slot_id)
- var/obj/item/I = get_active_hand()
- if(!I) return 0
- if(I.w_class > 3) return 0
-
- if(I == l_hand)
- l_hand = null
- else if(I == r_hand)
- r_hand = null
-
- switch(slot_id)
- if(slot_l_store)
- if(l_store)
- return 0
- l_store = I
- update_inv_pockets()
- if(slot_r_store)
- if(r_store)
- return 0
- r_store = I
- update_inv_pockets()
-
- I.loc = src
- I.equipped(src, slot_id)
- I.layer = 20
-
- return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm
index 0f9b45ee478..424f9a1bb52 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/life.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm
@@ -4,7 +4,7 @@
oxygen_alert = 0
toxins_alert = 0
fire_alert = 0
-
+ pass_flags = PASSTABLE
var/temperature_alert = 0
diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
index da27c428b5c..927e1bd52d5 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
@@ -38,7 +38,6 @@
update_inv_r_hand(0)
update_inv_l_hand(0)
- update_inv_pockets(0)
update_hud()
// update_icons() //Handled in update_transform(), leaving this here as a reminder
update_fire()
@@ -56,16 +55,6 @@
client.screen |= contents
-/mob/living/carbon/alien/humanoid/update_inv_pockets(update_icons = 1)
- if(l_store)
- l_store.screen_loc = ui_alien_storage_l
- if(r_store)
- r_store.screen_loc = ui_alien_storage_r
-
- if(update_icons)
- update_icons()
-
-
/mob/living/carbon/alien/humanoid/update_inv_r_hand(update_icons = 1)
if(r_hand)
var/t_state = r_hand.item_state
diff --git a/code/modules/mob/living/carbon/alien/larva/emote.dm b/code/modules/mob/living/carbon/alien/larva/emote.dm
index 3504b211893..9e502353e03 100644
--- a/code/modules/mob/living/carbon/alien/larva/emote.dm
+++ b/code/modules/mob/living/carbon/alien/larva/emote.dm
@@ -101,14 +101,11 @@
else
src << " Unusable emote '[act]'. Say *help for a list."
+
if ((message && src.stat == 0))
log_emote("[name]/[key] : [message]")
if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(703)
+ visible_message(message)
else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(746)
+ src.loc.audible_message(message)
return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 892a68b5344..9c191d338ae 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -2,7 +2,7 @@
name = "alien larva"
real_name = "alien larva"
icon_state = "larva0"
- pass_flags = PASSTABLE
+ pass_flags = PASSTABLE | PASSMOB
maxHealth = 25
health = 25
@@ -284,6 +284,9 @@
/mob/living/carbon/alien/larva/toggle_throw_mode()
return
+/mob/living/carbon/alien/larva/start_pulling()
+ return
+
/* Commented out because it's duplicated in life.dm
/mob/living/carbon/alien/larva/proc/grow() // Larvae can grow into full fledged Xenos if they survive long enough
if(icon_state == "larva_l" && !canmove) // This is a shit death check. It is made of shit and death. Fix later.
diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm
index a65299adfc1..3bf5ead3260 100644
--- a/code/modules/mob/living/carbon/alien/say.dm
+++ b/code/modules/mob/living/carbon/alien/say.dm
@@ -1,5 +1,7 @@
/mob/living/carbon/alien/say(var/message)
- return ..(message, "A")
+ . = ..(message, "A")
+ if(.)
+ playsound(loc, "hiss", 25, 1, 1) //erp just isn't the same without sound feedback
/mob/living/proc/alien_talk(var/message)
log_say("[key_name(src)] : [message]")
@@ -11,7 +13,7 @@
var/message_a = say_quote(message)
var/rendered = "Hivemind, [name][message_a]"
for(var/mob/S in player_list)
- if((!S.stat && (S.hivecheck())) || (S.stat == DEAD && !istype(S, /mob/new_player)))
+ if((!S.stat && (S.hivecheck())) || (S in dead_mob_list))
S << rendered
/mob/living/carbon/alien/handle_inherent_channels(message, message_mode)
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index 028440606bd..6d034128119 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -117,21 +117,7 @@
/obj/item/device/mmi/radio_enabled/New()
..()
radio = new(src) //Spawns a radio inside the MMI.
- radio.broadcasting = 1 //So it's broadcasting from the start.
-
-//Verbs to allow radio-MMI's to toggle their radios.
-/obj/item/device/mmi/radio_enabled/verb/Toggle_Broadcasting()
- set name = "Toggle Broadcasting"
- set desc = "Toggle broadcasting channel on or off."
- set category = "MMI"
- set src = usr.loc //In user location, or in MMI in this case.
- set popup_menu = 0 //Will not appear when right clicking.
-
- if(brainmob.stat) //Only the brainmob will trigger these so no further check is necessary.
- brainmob << "Can't do that while incapacitated or dead."
-
- radio.broadcasting = radio.broadcasting==1 ? 0 : 1
- brainmob << "Radio is [radio.broadcasting==1 ? "now" : "no longer"] broadcasting."
+ radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0.
/obj/item/device/mmi/radio_enabled/verb/Toggle_Listening()
set name = "Toggle Listening"
diff --git a/code/modules/mob/living/carbon/brain/emote.dm b/code/modules/mob/living/carbon/brain/emote.dm
index eae87baf57f..6f7e884fb11 100644
--- a/code/modules/mob/living/carbon/brain/emote.dm
+++ b/code/modules/mob/living/carbon/brain/emote.dm
@@ -67,8 +67,6 @@
if (m_type & 1)
- for (var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
+ visible_message(message)
else if (m_type & 2)
- for (var/mob/O in hearers(src.loc, null))
- O.show_message(message, m_type)
\ No newline at end of file
+ src.loc.audible_message(message)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm
index 5c9d10c9ae5..a5bb0a956d5 100644
--- a/code/modules/mob/living/carbon/brain/say.dm
+++ b/code/modules/mob/living/carbon/brain/say.dm
@@ -13,7 +13,7 @@
if(message_mode && istype(container, /obj/item/device/mmi/radio_enabled))
var/obj/item/device/mmi/radio_enabled/R = container
if(R.radio)
- R.radio.talk_into(src, sanitize(message))
+ R.radio.talk_into(src, message)
return ITALICS | REDUCE_RANGE
/mob/living/carbon/brain/lingcheck()
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 6a561028ed2..03fe3b71989 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -23,9 +23,9 @@
/mob/living/carbon/relaymove(var/mob/user, direction)
if(user in src.stomach_contents)
if(prob(40))
- for(var/mob/M in hearers(4, src))
- if(M.client)
- M.show_message(text("You hear something rumbling inside [src]'s stomach..."), 2)
+ audible_message("You hear something rumbling inside [src]'s stomach...", \
+ "You hear something rumbling.", 4,\
+ "Something is rumbling inside your stomach!")
var/obj/item/I = user.get_active_hand()
if(I && I.force)
var/d = rand(round(I.force / 4), I.force)
@@ -41,7 +41,7 @@
src.take_organ_damage(d)
for(var/mob/M in viewers(user, null))
if(M.client)
- M.show_message(text("[user] attacks [src]'s stomach wall with the [I.name]!"), 2)
+ M.show_message("[user] attacks [src]'s stomach wall with the [I.name]!", 2)
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(prob(src.getBruteLoss() - 50))
@@ -128,7 +128,7 @@
return shock_damage
-/mob/living/carbon/proc/swap_hand()
+/mob/living/carbon/swap_hand()
var/obj/item/item_in_hand = src.get_active_hand()
if(item_in_hand) //this segment checks if the item in your hand is twohanded.
if(istype(item_in_hand,/obj/item/weapon/twohanded))
@@ -149,7 +149,7 @@
src.hands.dir = SOUTH*/
return
-/mob/living/carbon/proc/activate_hand(var/selhand) //0 or "r" or "right" for right hand; 1 or "l" or "left" for left hand.
+/mob/living/carbon/activate_hand(var/selhand) //0 or "r" or "right" for right hand; 1 or "l" or "left" for left hand.
if(istext(selhand))
selhand = lowertext(selhand)
diff --git a/code/modules/mob/living/carbon/emote.dm b/code/modules/mob/living/carbon/emote.dm
index 90c9809c580..cb7783dceff 100644
--- a/code/modules/mob/living/carbon/emote.dm
+++ b/code/modules/mob/living/carbon/emote.dm
@@ -193,8 +193,6 @@
if (m_type & 1)
- for (var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
+ visible_message(message)
else if (m_type & 2)
- for (var/mob/O in hearers(src.loc, null))
- O.show_message(message, m_type)
+ src.loc.audible_message(message)
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index ba715c188be..504727a4584 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -316,7 +316,7 @@
m_type = 2
if ("help") //This can stay at the bottom.
- src << "Help for human emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, frown, flap, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, johnny, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, smile, sneeze, sniff, snore, stare-(none)/mob, tremble, twitch, twitch_s, wave, whimper, wink, yawn"
+ src << "Help for human emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, johnny, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, yawn"
else
..(act)
@@ -340,9 +340,7 @@
if (m_type & 1)
- for (var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
+ visible_message(message)
else if (m_type & 2)
- for (var/mob/O in hearers(src.loc, null))
- O.show_message(message, m_type)
+ src.loc.audible_message(message)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 7766c7548e0..d2249e11184 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -220,9 +220,9 @@
temp = getCloneLoss()
if(temp)
if(temp < 30)
- msg += "[t_He] [t_has] minor genetic deformities.\n"
+ msg += "[t_He] [t_has] minor cellular damage.\n"
else
- msg += "[t_He] [t_has] severe genetic deformities.\n"
+ msg += "[t_He] [t_has] severe cellular damage.\n"
if(fire_stacks > 0)
msg += "[t_He] [t_is] covered in something flammable.\n"
@@ -268,7 +268,11 @@
if(R)
criminal = R.fields["criminal"]
- msg += "Criminal status:\[[criminal]\]\n"
+ msg += "Criminal status:\[[criminal]\]\n"
+ msg += "Security record:\[View\] "
+ msg += "\[Add crime\] "
+ msg += "\[View comment log\] "
+ msg += "\[Add comment\]\n"
msg += "*---------*"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index fe05d3e038c..13937064602 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -121,8 +121,9 @@
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
- if(ticker.mode:malf_mode_declared)
- stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
+ var/datum/game_mode/malfunction/malf = ticker.mode
+ if(malf.malf_mode_declared && (malf.apcs > 0))
+ stat(null, "Time left: [max(malf.AI_win_timeleft/malf.apcs, 0)]")
if(emergency_shuttle)
if(emergency_shuttle.online && emergency_shuttle.location < 2)
var/timeleft = emergency_shuttle.timeleft()
@@ -461,7 +462,6 @@
src << "You feel your [pocket_side] pocket being fumbled with!"
..()
- return
if(href_list["criminal"])
@@ -471,38 +471,106 @@
if(usr.stat || usr == src) //|| !usr.canmove || usr.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at.
return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten
// Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access
- var/allowed_access = 0
+ var/allowed_access = null
var/obj/item/clothing/glasses/G = H.glasses
if (!G.emagged)
if(H.wear_id)
var/list/access = H.wear_id.GetAccess()
if(access_sec_doors in access)
- allowed_access = 1
+ allowed_access = H.get_authentification_name()
else
- allowed_access = 1
+ allowed_access = "@%&ERROR_%$*"
if(!allowed_access)
H << "ERROR: Invalid Access"
return
-
- var/modified = 0
var/perpname = get_face_name(get_id_name(""))
if(perpname)
var/datum/data/record/R = find_record("name", perpname, data_core.security)
if(R)
- var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Discharged", "Cancel")
- if(R)
- if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses))
- if(setcriminal != "Cancel")
- R.fields["criminal"] = setcriminal
- modified = 1
+ if(href_list["status"])
+ var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Discharged", "Cancel")
+ if(R)
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses))
+ if(setcriminal != "Cancel")
+ R.fields["criminal"] = setcriminal
- spawn()
+ spawn()
H.handle_regular_hud_updates()
+ return
- if(!modified)
+ if(href_list["view"])
+ if(R)
+ if(usr.stat || H.weakened || H.stunned || H.restrained() || !istype(H.glasses, /obj/item/clothing/glasses/hud/security) || !istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses))
+ return
+ usr << "Name: [R.fields["name"]] Criminal Status: [R.fields["criminal"]]"
+ usr << "Minor Crimes:"
+ for(var/datum/data/crime/c in R.fields["mi_crim"])
+ usr << "Crime: [c.crimeName]"
+ usr << "Details: [c.crimeDetails]"
+ usr << "Added by [c.author] at [c.time]"
+ usr << "----------"
+ usr << "Major Crimes:"
+ for(var/datum/data/crime/c in R.fields["ma_crim"])
+ usr << "Crime: [c.crimeName]"
+ usr << "Details: [c.crimeDetails]"
+ usr << "Added by [c.author] at [c.time]"
+ usr << "----------"
+ usr << "Notes: [R.fields["notes"]]"
+ return
+
+ if(href_list["add_crime"])
+ switch(alert("What crime would you like to add?","Security HUD","Minor Crime","Major Crime","Cancel"))
+ if("Minor Crime")
+ if(R)
+ var/t1 = copytext(sanitize(input("Please input minor crime names:", "Security HUD", "", null) as text),1,MAX_MESSAGE_LEN)
+ var/t2 = copytext(sanitize(input("Please input minor crime details:", "Security HUD", "", null) as message),1,MAX_MESSAGE_LEN)
+ if(R)
+ if (!t1 || !t2 || !allowed_access || H.stat || H.weakened || H.stunned || H.restrained() || !istype(H.glasses, /obj/item/clothing/glasses/hud/security) || !istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses))
+ return
+ var/crime = data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
+ data_core.addMinorCrime(R.fields["id"], crime)
+ usr << "Successfully added a minor crime."
+ return
+ if("Major Crime")
+ if(R)
+ var/t1 = copytext(sanitize(input("Please input major crime names:", "Security HUD", "", null) as text),1,MAX_MESSAGE_LEN)
+ var/t2 = copytext(sanitize(input("Please input major crime details:", "Security HUD", "", null) as message),1,MAX_MESSAGE_LEN)
+ if(R)
+ if (!t1 || !t2 || !allowed_access || H.stat || H.weakened || H.stunned || H.restrained() || !istype(H.glasses, /obj/item/clothing/glasses/hud/security) || !istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses))
+ return
+ var/crime = data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
+ data_core.addMajorCrime(R.fields["id"], crime)
+ usr << "Successfully added a major crime."
+ return
+ else return
+
+ if(href_list["view_comment"])
+ if(R)
+ if(H.stat || H.weakened || H.stunned || H.restrained() || !istype(H.glasses, /obj/item/clothing/glasses/hud/security) || !istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses))
+ return
+ usr << "Comments/Log:"
+ var/counter = 1
+ while(R.fields[text("com_[]", counter)])
+ usr << R.fields[text("com_[]", counter)]
+ usr << "----------"
+ counter++
+ return
+
+ if(href_list["add_comment"])
+ if(R)
+ var/t1 = copytext(sanitize(input("Add Comment:", "Secure. records", null, null) as message),1,MAX_MESSAGE_LEN)
+ if(R)
+ if (!t1 || !allowed_access || H.stat || H.weakened || H.stunned || H.restrained() || !istype(H.glasses, /obj/item/clothing/glasses/hud/security) || !istype(H.glasses, /obj/item/clothing/glasses/hud/security/sunglasses))
+ return
+ var/counter = 1
+ while(R.fields[text("com_[]", counter)])
+ counter++
+ R.fields[text("com_[]", counter)] = text("Made by [] on [] [], [] []", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1,)
+ usr << "Successfully added comment."
+ return
usr << "Unable to locate a data core entry for this person."
/mob/living/carbon/human/proc/play_xylophone()
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 35afcd97f8d..35682a33ed6 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -183,6 +183,7 @@ emp_act
apply_effect(20, PARALYZE, armor)
if(src != user && I.damtype == BRUTE)
ticker.mode.remove_revolutionary(mind)
+ ticker.mode.remove_gangster(mind)
if(bloody) //Apply blood
if(wear_mask)
wear_mask.add_blood(src)
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 1d1faa53c25..2981a2374da 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -1,6 +1,3 @@
-/mob/living/carbon/human/say(var/message)
- ..(message)
-
/mob/living/carbon/human/say_quote(text)
if(!text)
return "says, \"...\""; //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code
@@ -47,10 +44,14 @@
return message
/mob/living/carbon/human/GetVoice()
- if(istype(src.wear_mask, /obj/item/clothing/mask/gas/voice))
- var/obj/item/clothing/mask/gas/voice/V = src.wear_mask
- if(V.vchange)
- return V.voice
+ if(istype(wear_mask, /obj/item/clothing/mask/gas/voice))
+ var/obj/item/clothing/mask/gas/voice/V = wear_mask
+ if(V.vchange && wear_id)
+ var/obj/item/weapon/card/id/idcard = wear_id.GetID()
+ if(istype(idcard))
+ return idcard.registered_name
+ else
+ return real_name
else
return real_name
if(mind && mind.changeling && mind.changeling.mimicing)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 9a11c2eebe9..f0c5fe46444 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -853,6 +853,7 @@
H.apply_effect(20, PARALYZE, armor)
if(H != user && I.damtype == BRUTE)
ticker.mode.remove_revolutionary(H.mind)
+ ticker.mode.remove_gangster(H.mind)
if(bloody) //Apply blood
if(H.wear_mask)
diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm
index f3b6baae554..ca216efa372 100644
--- a/code/modules/mob/living/carbon/human/whisper.dm
+++ b/code/modules/mob/living/carbon/human/whisper.dm
@@ -5,6 +5,10 @@
if(say_disabled) //This is here to try to identify lag problems
usr << "Speech is currently admin-disabled."
return
+
+ if(stat == DEAD)
+ return
+
message = trim(copytext(strip_html_simple(message), 1, MAX_MESSAGE_LEN))
if(!can_speak(message))
diff --git a/code/modules/mob/living/carbon/monkey/emote.dm b/code/modules/mob/living/carbon/monkey/emote.dm
index 2b51ed70355..dd3b837a38c 100644
--- a/code/modules/mob/living/carbon/monkey/emote.dm
+++ b/code/modules/mob/living/carbon/monkey/emote.dm
@@ -66,7 +66,7 @@
m_type = 1
if ("help") //Ooh ah ooh ooh this is an exception to alphabetical ooh ooh.
- src << "Help for monkey emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow, choke, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, gnarl, giggle, glare-(none)/mob, grin, jump, laugh, paw, me, moan, nod, roar, roll, point-atom, scream, scratch, scretch, shake, shiver, sign-#, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tail, tremble, twitch, twitch_s, whimper, yawn"
+ src << "Help for monkey emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, gnarl, giggle, glare-(none)/mob, grin, jump, laugh, look, me, moan, nod, paw, point-(atom), roar, roll, scream, scratch, scretch, shake, shiver, sigh, sign-#, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tail, tremble, twitch, twitch_s, wave whimper, wink, yawn"
else
..(act)
@@ -75,11 +75,7 @@
if(src.client)
log_emote("[name]/[key] : [message]")
if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(703)
+ visible_message(message)
else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(746)
+ src.loc.audible_message(message)
return
diff --git a/code/modules/mob/living/carbon/slime/emote.dm b/code/modules/mob/living/carbon/slime/emote.dm
index 149bec620fd..d6b41afbee2 100644
--- a/code/modules/mob/living/carbon/slime/emote.dm
+++ b/code/modules/mob/living/carbon/slime/emote.dm
@@ -52,11 +52,8 @@
src << "Unusable emote '[act]'. Say *help for a list."
if ((message && src.stat == 0))
if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(703)
+ visible_message(message)
else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(746)
+ src.loc.audible_message(message)
+
return
\ No newline at end of file
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index f111b5cb5f5..38586236e9a 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -2,7 +2,7 @@
//Things like airguitar can be done without arms, and the flap thing makes so little sense it's a keeper.
//Intended to be called by a higher up emote proc if the requested emote isn't in the custom emotes.
-/mob/living/emote(var/act,var/m_type=1,var/message = null)
+/mob/living/emote(var/act, var/m_type=1, var/message = null)
var/param = null
if (findtext(act, "-", 1, null))
@@ -252,7 +252,7 @@
m_type = 2
if ("help")
- src << "Help for emotes. You can use these emotes with say \"*emote\":\n\naflap, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, giggle, glare-(none)/mob, grin, jump, laugh, look, me, nod, point-atom, scream, shake, sit, sigh, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, yawn"
+ src << "Help for emotes. You can use these emotes with say \"*emote\":\n\naflap, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, giggle, glare-(none)/mob, grin, jump, laugh, look, me, nod, point-atom, scream, shake, sigh, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, yawn"
else
src << "Unusable emote '[act]'. Say *help for a list."
@@ -275,8 +275,6 @@
if (m_type & 1)
- for (var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
+ visible_message(message)
else if (m_type & 2)
- for (var/mob/O in hearers(src.loc, null))
- O.show_message(message, m_type)
+ src.loc.audible_message(message)
diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm
index d19335d1f3e..0d2e5ad541b 100644
--- a/code/modules/mob/living/login.dm
+++ b/code/modules/mob/living/login.dm
@@ -12,6 +12,11 @@
if("revolution")
if((mind in ticker.mode.revolutionaries) || (src.mind in ticker.mode:head_revolutionaries))
ticker.mode.update_rev_icons_added(src.mind)
+ if("gang")
+ if((mind in ticker.mode.A_bosses) || (mind in ticker.mode.A_gangsters))
+ ticker.mode.update_gang_icons_added(src.mind,"A")
+ if((mind in ticker.mode.B_bosses) || (mind in ticker.mode.B_gangsters))
+ ticker.mode.update_gang_icons_added(src.mind,"B")
if("cult")
if(mind in ticker.mode:cult)
ticker.mode.update_cult_icons_added(src.mind)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 4c4ee69543c..ee63d9461d5 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -122,6 +122,7 @@ var/list/department_radio_keys = list(
send_speech(message, message_range, src, bubble_type)
log_say("[name]/[key] : [message]")
+ return 1
/mob/living/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq)
if(!client)
@@ -222,14 +223,14 @@ var/list/department_radio_keys = list(
var/msg = "[mind.changeling.changelingID]: [message]"
log_say("[mind.changeling.changelingID]/[src.key] : [message]")
for(var/mob/M in mob_list)
- if(M.stat == DEAD && !istype(M, /mob/new_player))
+ if(M in dead_mob_list)
M << msg
else
switch(M.lingcheck())
if(2)
M << msg
if(1)
- if(prob(30))
+ if(prob(40))
M << "We can faintly sense another of our kind trying to communicate through the hivemind..."
return 1
if(1)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index ceea1384d12..9ec853afdbd 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -173,9 +173,8 @@ var/list/ai_list = list()
if(ticker.mode.name == "AI malfunction")
var/datum/game_mode/malfunction/malf = ticker.mode
for (var/datum/mind/malfai in malf.malf_ai)
- if (mind == malfai)
- if (malf.apcs >= 3)
- stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
+ if ((mind == malfai) && (malf.apcs > 0))
+ stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/malf.apcs, 0)] seconds")
if(!stat)
stat(null, text("System integrity: [(health+100)/2]%"))
diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm
index 677d8fea567..f8bed180209 100644
--- a/code/modules/mob/living/silicon/login.dm
+++ b/code/modules/mob/living/silicon/login.dm
@@ -2,4 +2,5 @@
if(mind && ticker && ticker.mode)
ticker.mode.remove_cultist(mind, 0)
ticker.mode.remove_revolutionary(mind, 0)
+ ticker.mode.remove_gangster(mind, 0)
..()
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index a344f31aaeb..c11523d239a 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -171,8 +171,7 @@
if(href_list["send"])
sradio.send_signal("ACTIVATE")
- for(var/mob/O in hearers(1, src.loc))
- O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
+ audible_message("\icon[src] *beep* *beep*")
if(href_list["freq"])
diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm
index e5634f9708c..d287923bb74 100644
--- a/code/modules/mob/living/silicon/robot/emote.dm
+++ b/code/modules/mob/living/silicon/robot/emote.dm
@@ -202,9 +202,7 @@
if ((message && src.stat == 0))
if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
+ visible_message(message)
else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
+ src.loc.audible_message(message)
return
diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm
index d188272fa1f..4934daa8060 100644
--- a/code/modules/mob/living/silicon/robot/inventory.dm
+++ b/code/modules/mob/living/silicon/robot/inventory.dm
@@ -213,3 +213,8 @@
if(slot_num > 3) slot_num = 1 //Wrap around.
return
+
+
+/mob/living/silicon/robot/swap_hand()
+ cycle_modules()
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm
index 99e69a84c53..3a8a144d0eb 100644
--- a/code/modules/mob/living/silicon/robot/login.dm
+++ b/code/modules/mob/living/silicon/robot/login.dm
@@ -4,6 +4,7 @@
regenerate_icons()
show_laws(0)
if(mind) ticker.mode.remove_revolutionary(mind)
+ if(mind) ticker.mode.remove_gangster(mind)
/mob/living/silicon/robot/update_hotkey_mode()
winset(src, null, "mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0")
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 551e3648796..7e2a6c50afc 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -103,10 +103,10 @@
//MMI stuff. Held togheter by magic. ~Miauw
mmi = new(src)
mmi.brain = new /obj/item/organ/brain(mmi)
- mmi.brain.name = "[src.real_name]'s brain"
+ mmi.brain.name = "[real_name]'s brain"
mmi.locked = 1
mmi.icon_state = "mmi_full"
- mmi.name = "Man-Machine Interface: [src.real_name]"
+ mmi.name = "Man-Machine Interface: [real_name]"
mmi.brainmob = new(src)
mmi.brainmob.name = src.real_name
mmi.brainmob.real_name = src.real_name
@@ -303,11 +303,10 @@
var/datum/game_mode/malfunction/malf = ticker.mode
for (var/datum/mind/malfai in malf.malf_ai)
if(connected_ai)
- if(connected_ai.mind == malfai)
- if(malf.apcs >= 3)
- stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
- else if(ticker.mode:malf_mode_declared)
- stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
+ if((connected_ai.mind == malfai) && (malf.apcs > 0))
+ stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/malf.apcs, 0)] seconds")
+ else if(malf.malf_mode_declared && (malf.apcs > 0))
+ stat(null, "Time left: [max(malf.AI_win_timeleft/malf.apcs, 0)]")
if(cell)
stat(null, text("Charge Left: [cell.charge]/[cell.maxcharge]"))
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index a2df8da25d9..981217e6ad8 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -207,7 +207,7 @@
else
modules += new /obj/item/weapon/pickaxe/borgdrill(src)
modules += new /obj/item/weapon/storage/bag/sheetsnatcher/borg(src)
- modules += new /obj/item/device/mining_scanner(src)
+ modules += new /obj/item/device/t_scanner/mining_scanner(src)
modules += new /obj/item/weapon/gun/energy/kinetic_accelerator(src)
/obj/item/weapon/robot_module/miner/on_emag()
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 662c92dabd1..9dd1325113a 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -10,7 +10,7 @@
var/message_a = say_quote(message)
var/rendered = "Robotic Talk, [name][message_a]"
for(var/mob/M in player_list)
- if(M.binarycheck() || (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && !istype(M, /mob/new_player)))
+ if(M.binarycheck() || (M in dead_mob_list))
if(istype(M, /mob/living/silicon/ai))
var/renderedAI = "Robotic Talk, [name] ([desig])[message_a]"
M << renderedAI
@@ -51,7 +51,7 @@
. = ..()
if(.)
return .
-
+
if(message_mode == MODE_BINARY)
if(binarycheck())
robot_talk(message)
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index d1ce8e8fe59..6b6e01220af 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -90,10 +90,10 @@
/mob/living/simple_animal/construct/attack_animal(mob/living/simple_animal/M as mob)
if(istype(M, /mob/living/simple_animal/construct/builder))
health += 5
- M.emote("mends some of \the [src]'s wounds.")
+ M.emote("me", 1, "mends some of \the [src]'s wounds.")
else if(src != M)
if(M.melee_damage_upper <= 0)
- M.emote("[M.friendly] \the [src]")
+ M.emote("me", 1, "[M.friendly] \the [src].")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index 2748bbdf136..0319d1617fd 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -39,7 +39,7 @@
for(var/mob/living/simple_animal/mouse/M in view(1,src))
if(!M.stat)
M.splat()
- emote("splats \the [M]")
+ emote("me", 1, "splats \the [M]!")
movement_target = null
stop_automated_movement = 0
break
diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm
index 9ad3606dcb7..c98b6a1fa74 100644
--- a/code/modules/mob/living/simple_animal/friendly/corgi.dm
+++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm
@@ -7,10 +7,10 @@
icon_living = "corgi"
icon_dead = "corgi_dead"
gender = MALE
- speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
+ speak = list("YAP!", "Woof!", "Bark!", "AUUUUUU!")
speak_emote = list("barks", "woofs")
- emote_hear = list("barks", "woofs", "yaps","pants")
- emote_see = list("shakes its head", "shivers")
+ emote_hear = list("barks!", "woofs!", "yaps.","pants.")
+ emote_see = list("shakes its head.", "shivers.")
speak_chance = 1
turns_per_move = 10
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi
@@ -66,7 +66,7 @@
for (var/mob/M in viewers(src, null))
M.show_message("[user] gently taps [src] with [O].")
if(health>0 && prob(15))
- emote("looks at [user] with [pick("an amused","an annoyed","a confused","a resentful", "a happy", "an excited")] expression")
+ emote("me", 1, "looks at [user] with [pick("an amused","an annoyed","a confused","a resentful", "a happy", "an excited")] expression.")
return
..()
@@ -127,7 +127,7 @@
if(!item_to_add)
usr.visible_message("[usr] pets [src]","You rest your hand on [src]'s back for a moment.")
return
- if(istype(item_to_add,/obj/item/weapon/plastique)) // last thing he ever wears, I guess
+ if(istype(item_to_add,/obj/item/weapon/c4)) // last thing he ever wears, I guess
item_to_add.afterattack(src,usr,1)
return
@@ -169,7 +169,7 @@
//Many hats added, Some will probably be removed, just want to see which ones are popular.
/mob/living/simple_animal/corgi/proc/place_on_head(obj/item/item_to_add)
- if(istype(item_to_add,/obj/item/weapon/plastique)) // last thing he ever wears, I guess
+ if(istype(item_to_add,/obj/item/weapon/c4)) // last thing he ever wears, I guess
item_to_add.afterattack(src,usr,1)
return
@@ -222,13 +222,13 @@
name = "Yann"
desc = "Mon dieu! C'est un chien!"
speak = list("le woof!", "le bark!", "JAPPE!!")
- emote_see = list("cowers in fear", "surrenders", "plays dead","looks as though there is a wall in front of him")
+ emote_see = list("cowers in fear.", "surrenders.", "plays dead.","looks as though there is a wall in front of him.")
valid = 1
if(/obj/item/clothing/head/det_hat)
name = "Detective [real_name]"
desc = "[name] sees through your lies..."
- emote_see = list("investigates the area","sniffs around for clues","searches for scooby snacks")
+ emote_see = list("investigates the area.","sniffs around for clues.","searches for scooby snacks.")
valid = 1
if(/obj/item/clothing/head/nursehat)
@@ -239,20 +239,20 @@
if(/obj/item/clothing/head/pirate, /obj/item/clothing/head/collectable/pirate)
name = "[pick("Ol'","Scurvy","Black","Rum","Gammy","Bloody","Gangrene","Death","Long-John")] [pick("kibble","leg","beard","tooth","poop-deck","Threepwood","Le Chuck","corsair","Silver","Crusoe")]"
desc = "Yaarghh!! Thar' be a scurvy dog!"
- emote_see = list("hunts for treasure","stares coldly...","gnashes his tiny corgi teeth")
- emote_hear = list("growls ferociously", "snarls")
+ emote_see = list("hunts for treasure.","stares coldly...","gnashes his tiny corgi teeth!")
+ emote_hear = list("growls ferociously!", "snarls.")
speak = list("Arrrrgh!!","Grrrrrr!")
valid = 1
if(/obj/item/clothing/head/ushanka)
name = "[pick("Comrade","Commissar","Glorious Leader")] [real_name]"
desc = "A follower of Karl Barx."
- emote_see = list("contemplates the failings of the capitalist economic model", "ponders the pros and cons of vangaurdism")
+ emote_see = list("contemplates the failings of the capitalist economic model.", "ponders the pros and cons of vangaurdism.")
valid = 1
if(/obj/item/clothing/head/collectable/police)
name = "Officer [real_name]"
- emote_see = list("drools","looks for donuts")
+ emote_see = list("drools.","looks for donuts.")
desc = "Stop right there criminal scum!"
valid = 1
@@ -264,22 +264,22 @@
if(/obj/item/clothing/head/cardborg)
name = "Borgi"
speak = list("Ping!","Beep!","Woof!")
- emote_see = list("goes rogue", "sniffs out non-humans")
+ emote_see = list("goes rogue.", "sniffs out non-humans.")
desc = "Result of robotics budget cuts."
valid = 1
if(/obj/item/weapon/bedsheet)
name = "\improper Ghost"
speak = list("WoooOOOooo~","AUUUUUUUUUUUUUUUUUU")
- emote_see = list("stumbles around", "shivers")
- emote_hear = list("howls","groans")
+ emote_see = list("stumbles around.", "shivers.")
+ emote_hear = list("howls!","groans.")
desc = "Spooky!"
valid = 1
if(/obj/item/clothing/head/helmet/space/santahat)
name = "Santa's Corgi Helper"
- emote_hear = list("barks christmas songs", "yaps merrily")
- emote_see = list("looks for presents", "checks his list")
+ emote_hear = list("barks christmas songs.", "yaps merrily!")
+ emote_see = list("looks for presents.", "checks his list.")
desc = "He's very fond of milk and cookies."
valid = 1
@@ -290,7 +290,7 @@
if(/obj/item/clothing/head/hardhat/reindeer)
name = "[real_name] the red-nosed Corgi"
- emote_hear = list("lights the way", "illuminates", "yaps")
+ emote_hear = list("lights the way!", "illuminates.", "yaps!")
desc = "He has a very shiny nose."
SetLuminosity(1)
valid = 1
@@ -388,10 +388,10 @@
movement_target.attack_animal(src)
else if(ishuman(movement_target.loc) )
if(prob(20))
- emote("stares at [movement_target.loc]'s [movement_target] with a sad puppy-face")
+ emote("me", 1, "stares at [movement_target.loc]'s [movement_target] with a sad puppy-face")
if(prob(1))
- emote(pick("dances around","chases its tail"))
+ emote("me", 1, pick("dances around.","chases its tail!"))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
dir = i
@@ -512,7 +512,7 @@
if(!stat && !resting && !buckled)
if(prob(1))
- emote(pick("dances around","chases her tail"))
+ emote("me", 1, pick("dances around.","chases her tail."))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
dir = i
@@ -529,7 +529,7 @@
if(change > 0)
if(M && stat != DEAD) // Added check to see if this mob (the corgi) is dead to fix issue 2454
flick_overlay(image('icons/mob/animal.dmi',src,"heart-ani2",MOB_LAYER+1), list(M.client), 20)
- emote("yaps happily")
+ emote("me", 1, "yaps happily!")
else
if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case)
- emote("growls")
\ No newline at end of file
+ emote("me", 1, "growls!")
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/friendly/drone.dm b/code/modules/mob/living/simple_animal/friendly/drone.dm
new file mode 100644
index 00000000000..bf72a763f4c
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/friendly/drone.dm
@@ -0,0 +1,541 @@
+
+#define HANDS_LAYER 1
+#define HEAD_LAYER 2
+#define TOTAL_LAYERS 2
+
+#define DRONE_NET_CONNECT "DRONE NETWORK: [name] connected."
+#define DRONE_NET_DISCONNECT "DRONE NETWORK: [name] is not responding."
+
+
+/mob/living/simple_animal/drone
+ name = "Drone"
+ desc = "A maintenance drone, an expendable robot built to perform station repairs."
+ icon = 'icons/mob/drone.dmi'
+ icon_state = "drone_grey"
+ icon_living = "drone_grey"
+ icon_dead = "drone_dead"
+ gender = NEUTER
+ health = 30
+ maxHealth = 30
+ heat_damage_per_tick = 0
+ cold_damage_per_tick = 0
+ unsuitable_atmos_damage = 0
+ wander = 0
+ speed = 0
+ ventcrawler = 2
+ pass_flags = PASSTABLE | PASSMOB
+ sight = (SEE_TURFS | SEE_OBJS)
+ status_flags = (CANPUSH | CANSTUN)
+ gender = NEUTER
+ voice_name = "synthesized chirp"
+ languages = DRONE
+ var/picked = FALSE
+ var/list/drone_overlays[TOTAL_LAYERS]
+ var/laws = \
+ "1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone.\n"+\
+ "2. You may not harm any being, regardless of intent or circumstance.\n"+\
+ "3. Your goals are to build, maintain, repair, improve, and power to the best of your abilities, You must never actively work against these goals."
+ var/light_on = 0
+ var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list())
+ var/obj/item/internal_storage //Drones can store one item, of any size/type in their body
+ var/obj/item/head
+ var/obj/item/default_storage = /obj/item/weapon/storage/toolbox/drone //If this exists, it will spawn in internal storage
+ var/obj/item/default_hatmask //If this exists, it will spawn in the hat/mask slot if it can fit
+
+
+/mob/living/simple_animal/drone/New()
+ ..()
+
+ name = name + " ([rand(100,999)])"
+ real_name = name
+
+ access_card = new /obj/item/weapon/card/id(src)
+ var/datum/job/captain/C = new /datum/job/captain
+ access_card.access = C.get_access()
+
+ if(default_storage)
+ var/obj/item/I = new default_storage(src)
+ equip_to_slot_or_del(I, "drone_storage_slot")
+ if(default_hatmask)
+ var/obj/item/I = new default_hatmask(src)
+ equip_to_slot_or_del(I, slot_head)
+
+ alert_drones(DRONE_NET_CONNECT)
+
+/mob/living/simple_animal/drone/attack_hand(mob/user)
+ if(isdrone(user))
+ var/mob/living/simple_animal/drone/D = user
+ if(D != src)
+ if(stat == DEAD)
+ var/d_input = alert(D,"Perform which action?","Drone Interaction","Reactivate","Cannibalize","Nothing")
+ if(d_input)
+ switch(d_input)
+ if("Reactivate")
+ if(!client)
+ D << "This drone's OS has blue screened, there is no point in repairing them."
+ return
+ D.visible_message("[D] begins to reactivate [src].")
+ if(do_after(user,30,needhand = 1))
+ health = maxHealth
+ stat = CONSCIOUS
+ icon_state = icon_living
+ D.visible_message("[D] reactivates [src]!")
+ alert_drones(DRONE_NET_CONNECT)
+ else
+ D << "You need to remain still to reactivate [src]."
+
+ if("Cannibalize")
+ if(D.health < D.maxHealth)
+ D.visible_message("[D] begins to cannibalize parts from [src].")
+ if(do_after(D, 60,5,0))
+ D.visible_message("[D] repairs itself using [src]'s remains!")
+ D.adjustBruteLoss(-src.maxHealth)
+ new /obj/effect/decal/cleanable/oil/streak(get_turf(src))
+ qdel(src)
+ else
+ D << "You need to remain still to canibalize [src]."
+ else
+ D << "You're already in perfect condition!"
+ if("Nothing")
+ return
+
+ return
+
+
+ if(ishuman(user))
+ if(stat == DEAD)
+ ..()
+ return
+ if(user.get_active_hand())
+ user << "Your hands are full."
+ return
+ src << "[user] is trying to pick you up!"
+ user << "You start picking [src] up..."
+ if(do_after(user, 20, needhand = 1))
+ drop_l_hand()
+ drop_r_hand()
+ var/obj/item/clothing/head/drone_holder/DH = new /obj/item/clothing/head/drone_holder(src)
+ DH.contents += src
+ DH.drone = src
+ user.put_in_hands(DH)
+ src.loc = DH
+ else
+ user << "[src] got away!"
+ src << "You got away from [user]!"
+ return
+
+ ..()
+
+/mob/living/simple_animal/drone/Move()
+ if(pullin)
+ if(pulling)
+ pullin.icon_state = "pull"
+ else
+ pullin.icon_state = "pull0"
+ ..()
+
+/mob/living/simple_animal/drone/IsAdvancedToolUser()
+ return 1
+
+/mob/living/simple_animal/drone/radio(message, message_mode)
+ if(message_mode == MODE_BINARY)
+ drone_chat(message)
+ return ITALICS | REDUCE_RANGE
+ else
+ ..()
+
+
+/mob/living/simple_animal/drone/UnarmedAttack(atom/A, proximity)
+ A.attack_hand(src)
+
+
+/mob/living/simple_animal/drone/swap_hand()
+ var/obj/item/held_item = get_active_hand()
+ if(held_item)
+ if(istype(held_item, /obj/item/weapon/twohanded))
+ var/obj/item/weapon/twohanded/T = held_item
+ if(T.wielded == 1)
+ usr << "Your other hand is too busy holding the [T.name]."
+ return
+
+ hand = !hand
+ if(hud_used.l_hand_hud_object && hud_used.r_hand_hud_object)
+ if(hand)
+ hud_used.l_hand_hud_object.icon_state = "hand_l_active"
+ hud_used.r_hand_hud_object.icon_state = "hand_r_inactive"
+ else
+ hud_used.l_hand_hud_object.icon_state = "hand_l_inactive"
+ hud_used.r_hand_hud_object.icon_state = "hand_r_active"
+
+
+/mob/living/simple_animal/drone/verb/check_laws()
+ set category = "Drone"
+ set name = "Check Laws"
+
+ src << "Drone Laws"
+ src << laws
+
+/mob/living/simple_animal/drone/verb/toggle_light()
+ set category = "Drone"
+ set name = "Toggle drone light"
+ if(light_on)
+ AddLuminosity(-4)
+ else
+ AddLuminosity(4)
+
+ light_on = !light_on
+
+ src << "Your light is now [light_on ? "on" : "off"]"
+
+/mob/living/simple_animal/drone/verb/drone_ping()
+ set category = "Drone"
+ set name = "Drone ping"
+
+ var/alert_s = input(src,"Alert severity level","Drone ping",null) as null|anything in list("Low","Medium","High","Critical")
+
+ var/area/A = get_area(loc)
+
+ if(alert_s && A && stat != DEAD)
+ var/msg = "DRONE PING: [name]: [alert_s] priority alert in [A.name]!"
+ alert_drones(msg)
+
+/mob/living/simple_animal/drone/proc/alert_drones(msg, dead_can_hear = 0)
+ for(var/mob/M in player_list)
+ var/send_msg = 0
+
+ if(istype(M, /mob/living/simple_animal/drone) && M.stat != DEAD)
+ for(var/F in src.faction)
+ if(F in M.faction)
+ send_msg = 1
+ break
+ else if(dead_can_hear && (M.stat == DEAD) && (M.client.prefs.toggles & CHAT_GHOSTEARS) && !istype(M, /mob/new_player))
+ send_msg = 1
+
+ if(send_msg)
+ M << msg
+
+/mob/living/simple_animal/drone/proc/drone_chat(msg)
+ var/rendered = "DRONE CHAT: [name]: [msg]"
+ alert_drones(rendered, 1)
+
+/mob/living/simple_animal/drone/Login()
+ ..()
+ update_inv_hands()
+ update_inv_head()
+ update_inv_internal_storage()
+ check_laws()
+
+ if(!picked)
+ pick_colour()
+
+/mob/living/simple_animal/drone/Die()
+ ..()
+ drop_l_hand()
+ drop_r_hand()
+ if(internal_storage)
+ unEquip(internal_storage)
+ if(head)
+ unEquip(head)
+
+ alert_drones(DRONE_NET_DISCONNECT)
+
+/mob/living/simple_animal/drone/gib()
+ dust()
+
+
+/mob/living/simple_animal/drone/unEquip(obj/item/I, force)
+ if(..(I,force))
+ update_inv_hands()
+ if(I == head)
+ head = null
+ update_inv_head()
+ if(I == internal_storage)
+ internal_storage = null
+ update_inv_internal_storage()
+ return 1
+ return 0
+
+/mob/living/simple_animal/drone/can_equip(obj/item/I, slot)
+ switch(slot)
+ if(slot_head)
+ if(head)
+ return 0
+ if(!((I.slot_flags & SLOT_HEAD) || (I.slot_flags & SLOT_MASK)))
+ return 0
+ return 1
+ if("drone_storage_slot")
+ if(internal_storage)
+ return 0
+ return 1
+ ..()
+
+/mob/living/simple_animal/drone/get_item_by_slot(slot_id)
+ switch(slot_id)
+ if(slot_head)
+ return head
+ if("drone_storage_slot")
+ return internal_storage
+ ..()
+
+/mob/living/simple_animal/drone/equip_to_slot(obj/item/I, slot)
+ if(!slot) return
+ if(!istype(I)) return
+
+ if(I == l_hand)
+ l_hand = null
+ else if(I == r_hand)
+ r_hand = null
+ update_inv_hands()
+
+ I.screen_loc = null // will get moved if inventory is visible
+ I.loc = src
+ I.equipped(src, slot)
+ I.layer = 20
+
+ switch(slot)
+ if(slot_head)
+ head = I
+ update_inv_head()
+ if("drone_storage_slot")
+ internal_storage = I
+ update_inv_internal_storage()
+ else
+ src << "You are trying to equip this item to an unsupported inventory slot. Report this to a coder!"
+ return
+
+/mob/living/simple_animal/drone/emp_act()
+ Stun(5)
+ src << "ER@%R: MME^RY CO#RU9T! R&$b@0tin)..."
+
+
+/mob/living/simple_animal/drone/proc/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
+ if(stat != DEAD)
+ var/list/L = src.alarms[class]
+ for (var/I in L)
+ if (I == A.name)
+ var/list/alarm = L[I]
+ var/list/sources = alarm[2]
+ if (!(alarmsource in sources))
+ sources += alarmsource
+ return
+ L[A.name] = list(A, list(alarmsource))
+ src << "--- [class] alarm detected in [A.name]!"
+
+/mob/living/simple_animal/drone/proc/cancelAlarm(var/class, area/A as area, obj/origin)
+ if(stat != DEAD)
+ var/list/L = alarms[class]
+ var/cleared = 0
+ for (var/I in L)
+ if (I == A.name)
+ var/list/alarm = L[I]
+ var/list/srcs = alarm[2]
+ if (origin in srcs)
+ srcs -= origin
+ if (srcs.len == 0)
+ cleared = 1
+ L -= I
+ if(cleared)
+ src << "--- [class] alarm in [A.name] has been cleared."
+
+/mob/living/simple_animal/drone/proc/pick_colour()
+ var/colour = input("Choose your colour!", "Colour", "grey") in list("grey", "blue", "red", "green", "pink", "orange")
+ icon_state = "drone_[colour]"
+ icon_living = "drone_[colour]"
+ picked = TRUE
+
+/mob/living/simple_animal/drone/proc/apply_overlay(cache_index)
+ var/image/I = drone_overlays[cache_index]
+ if(I)
+ overlays += I
+
+/mob/living/simple_animal/drone/proc/remove_overlay(cache_index)
+ if(drone_overlays[cache_index])
+ overlays -= drone_overlays[cache_index]
+ drone_overlays[cache_index] = null
+
+
+/mob/living/simple_animal/drone/proc/update_inv_hands()
+ remove_overlay(HANDS_LAYER)
+ var/list/hands_overlays = list()
+ if(r_hand)
+ var/r_state = r_hand.item_state
+ if(!r_state)
+ r_state = r_hand.icon_state
+
+ hands_overlays += image("icon"='icons/mob/items_righthand.dmi', "icon_state"="[r_state]", "layer"=-HANDS_LAYER)
+
+ if(client && hud_used)
+ r_hand.layer = 20
+ r_hand.screen_loc = ui_rhand
+ client.screen |= r_hand
+
+ if(l_hand)
+ var/l_state = l_hand.item_state
+ if(!l_state)
+ l_state = l_hand.icon_state
+
+ hands_overlays += image("icon"='icons/mob/items_lefthand.dmi', "icon_state"="[l_state]", "layer"=-HANDS_LAYER)
+
+ if(client && hud_used)
+ l_hand.layer = 20
+ l_hand.screen_loc = ui_lhand
+ client.screen |= l_hand
+
+
+ if(hands_overlays.len)
+ drone_overlays[HANDS_LAYER] = hands_overlays
+ apply_overlay(HANDS_LAYER)
+
+
+/mob/living/simple_animal/drone/proc/update_inv_internal_storage()
+ if(internal_storage && client && hud_used)
+ internal_storage.screen_loc = ui_drone_storage
+ client.screen += internal_storage
+
+
+/mob/living/simple_animal/drone/update_inv_head()
+ remove_overlay(HEAD_LAYER)
+
+ if(head)
+ if(client && hud_used)
+ head.screen_loc = ui_drone_head
+ client.screen += head
+
+
+ var/image/head_overlay = image("icon"='icons/mob/head.dmi', "icon_state"="[head.icon_state]", "layer"=-HEAD_LAYER)
+ if(istype(head, /obj/item/clothing/mask))
+ head_overlay.icon = 'icons/mob/mask.dmi'
+ head_overlay.color = head.color
+ head_overlay.alpha = head.alpha
+ head_overlay.pixel_y = -15
+
+ drone_overlays[HEAD_LAYER] = head_overlay
+
+ apply_overlay(HEAD_LAYER)
+
+//These procs serve as redirection so that the drone updates as expected when other things call these procs
+/mob/living/simple_animal/drone/update_inv_l_hand()
+ update_inv_hands()
+
+/mob/living/simple_animal/drone/update_inv_r_hand()
+ update_inv_hands()
+
+/mob/living/simple_animal/drone/update_inv_wear_mask()
+ update_inv_head()
+
+
+/mob/living/simple_animal/drone/canUseTopic()
+ if(stat)
+ return
+ return 1
+
+/mob/living/simple_animal/drone/activate_hand(var/selhand)
+
+ if(istext(selhand))
+ selhand = lowertext(selhand)
+
+ if(selhand == "right" || selhand == "r")
+ selhand = 0
+ if(selhand == "left" || selhand == "l")
+ selhand = 1
+
+ if(selhand != src.hand)
+ swap_hand()
+ else
+ mode()
+
+#undef HANDS_LAYER
+#undef HEAD_LAYER
+#undef TOTAL_LAYERS
+
+#undef DRONE_NET_CONNECT
+#undef DRONE_NET_DISCONNECT
+
+//DRONE SHELL
+/obj/item/drone_shell
+ name = "drone shell"
+ desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs."
+ icon = 'icons/mob/drone.dmi'
+ icon_state = "drone_item"
+ origin_tech = "programming=2;biotech=4"
+ var/construction_cost = list("metal"=800, "glass"=350)
+ var/construction_time=150
+ var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned
+
+/obj/item/drone_shell/attack_ghost(mob/user)
+ if(jobban_isbanned(user,"pAI"))
+ return
+
+ var/be_drone = alert("Become a drone? (Warning, You can no longer be cloned!)",,"Yes","No")
+ if(be_drone == "No")
+ return
+ var/mob/living/simple_animal/drone/D = new drone_type(get_turf(loc))
+ D.key = user.key
+ qdel(src)
+
+
+//DRONE HOLDER
+
+/obj/item/clothing/head/drone_holder//Only exists in someones hand.or on their head
+ name = "drone (hiding)"
+ desc = "This drone is scared and has curled up into a ball"
+ icon = 'icons/mob/drone.dmi'
+ icon_state = "drone_item"
+ var/mob/living/simple_animal/drone/drone //stored drone
+
+/obj/item/clothing/head/drone_holder/proc/uncurl()
+ if(istype(loc, /mob/living))
+ var/mob/living/L = loc
+ L.unEquip(src)
+ if(drone)
+ contents -= drone
+ drone.loc = get_turf(src)
+ drone.reset_view()
+ drone.dir = SOUTH //Looks better
+ drone.visible_message("[drone] uncurls!")
+ drone = null
+ qdel(src)
+ else
+ ..()
+
+/obj/item/clothing/head/drone_holder/relaymove()
+ uncurl()
+
+/obj/item/clothing/head/drone_holder/container_resist()
+ uncurl()
+
+
+//More types of drones
+
+/mob/living/simple_animal/drone/syndrone
+ name = "Syndrone"
+ desc = "A modified maintenance drone. This one brings with it the feeling of terror."
+ icon_state = "drone_synd"
+ icon_living = "drone_synd"
+ picked = TRUE
+ health = 30
+ maxHealth = 120 //If you murder other drones and cannibalize them you can get much stronger
+ faction = list("syndicate")
+ laws = \
+ "1. Interfere.\n"+\
+ "2. Kill.\n"+\
+ "3. Destroy."
+ default_storage = /obj/item/device/radio/uplink
+ default_hatmask = /obj/item/clothing/head/helmet/space/hardsuit/syndi
+
+/mob/living/simple_animal/drone/syndrone/New()
+ ..()
+ if(internal_storage && internal_storage.hidden_uplink)
+ internal_storage.hidden_uplink.uses = 5
+ internal_storage.name = "syndicate uplink"
+
+/mob/living/simple_animal/drone/syndrone/Login()
+ ..()
+ src << "You can kill and eat other drones to increase your health!" //Inform the evil lil guy
+
+/obj/item/drone_shell/syndrone
+ name = "syndrone shell"
+ desc = "A shell of a syndrone, a modified maintenance drone designed to infiltrate and annihilate."
+ icon_state = "syndrone_item"
+ drone_type = /mob/living/simple_animal/drone/syndrone
+
diff --git a/code/modules/mob/living/simple_animal/friendly/pug.dm b/code/modules/mob/living/simple_animal/friendly/pug.dm
index 86c36adf2ff..ba23a49dba0 100644
--- a/code/modules/mob/living/simple_animal/friendly/pug.dm
+++ b/code/modules/mob/living/simple_animal/friendly/pug.dm
@@ -1,4 +1,4 @@
-//Corgi
+//Corgi //best comment 2014
/mob/living/simple_animal/pug
name = "\improper pug"
real_name = "pug"
@@ -8,8 +8,8 @@
icon_dead = "pug_dead"
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
speak_emote = list("barks", "woofs")
- emote_hear = list("barks", "woofs", "yaps","pants")
- emote_see = list("shakes its head", "chases its tail","shivers")
+ emote_hear = list("barks!", "woofs!", "yaps.","pants.")
+ emote_see = list("shakes its head.", "chases its tail.","shivers.")
speak_chance = 1
turns_per_move = 10
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/pug
@@ -24,7 +24,7 @@
if(!stat && !resting && !buckled)
if(prob(1))
- emote(pick("chases its tail"))
+ emote("me", 1, pick("chases its tail."))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
dir = i
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 2c72803053f..0f96399a3c9 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -28,7 +28,7 @@
max_co2 = 0
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
faction = list("alien")
status_flags = CANPUSH
minbodytemp = 0
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index f5e190706ff..7953f92cdae 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -60,7 +60,7 @@
/mob/living/simple_animal/hostile/bear/FindTarget()
. = ..()
if(.)
- emote("stares alertly at [.]")
+ emote("me", 1, "stares alertly at [.]")
stance = HOSTILE_STANCE_ATTACK
/mob/living/simple_animal/hostile/bear/LoseTarget()
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index 2d101454d4e..b3bbd7a3b09 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -1,4 +1,4 @@
-
+F
/mob/living/simple_animal/hostile/carp
name = "space carp"
@@ -44,7 +44,7 @@
/mob/living/simple_animal/hostile/carp/FindTarget()
. = ..()
if(.)
- emote("nashes at [.]")
+ emote("me", 1, "nashes at [.]!")
/mob/living/simple_animal/hostile/carp/AttackingTarget()
. =..()
diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm
index 093e609f358..5753a93cb96 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithless.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm
@@ -37,7 +37,7 @@
/mob/living/simple_animal/hostile/faithless/FindTarget()
. = ..()
if(.)
- emote("wails at [.]")
+ emote("me", 1, "wails at [.]!")
/mob/living/simple_animal/hostile/faithless/AttackingTarget()
. =..()
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index d396347e213..116a2b82ec6 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -38,7 +38,7 @@
/mob/living/simple_animal/hostile/mimic/FindTarget()
. = ..()
if(.)
- emote("growls at [.]")
+ emote("me", 1, "growls at [.].")
/mob/living/simple_animal/hostile/mimic/Die()
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
index d8f592d145e..5a36143768c 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
@@ -8,7 +8,7 @@
max_co2 = 0
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
faction = list("mining")
environment_smash = 2
minbodytemp = 0
diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm
index f44ef49accd..aae825a6538 100644
--- a/code/modules/mob/living/simple_animal/hostile/pirate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm
@@ -28,7 +28,7 @@
max_co2 = 5
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
var/corpse = /obj/effect/landmark/mobcorpse/pirate
var/weapon1 = /obj/item/weapon/melee/energy/sword/pirate
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
index 39c0524fbbd..23fc3a7db42 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
@@ -37,4 +37,4 @@
maxbodytemp = 370
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
- unsuitable_atoms_damage = 10
\ No newline at end of file
+ unsuitable_atmos_damage = 10
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm
index 2f229c39b1c..82c8bedcf65 100644
--- a/code/modules/mob/living/simple_animal/hostile/russian.dm
+++ b/code/modules/mob/living/simple_animal/hostile/russian.dm
@@ -29,7 +29,7 @@
max_co2 = 5
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
faction = list("russian")
status_flags = CANPUSH
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index 5b74257c67c..cff7e8989f7 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -30,7 +30,7 @@
max_co2 = 5
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
faction = list("syndicate")
status_flags = CANPUSH
diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm
index 7baa4d510c6..7c20ba05a39 100644
--- a/code/modules/mob/living/simple_animal/hostile/tree.dm
+++ b/code/modules/mob/living/simple_animal/hostile/tree.dm
@@ -39,7 +39,7 @@
/mob/living/simple_animal/hostile/tree/FindTarget()
. = ..()
if(.)
- emote("growls at [.]")
+ emote("me", 1, "growls at [.].")
/mob/living/simple_animal/hostile/tree/AttackingTarget()
. =..()
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 89e4ea79938..8b16e97ca9d 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -35,10 +35,10 @@
icon_dead = "parrot_dead"
pass_flags = PASSTABLE
- speak = list("Hi","Hello!","Cracker?","BAWWWWK george mellons griffing me")
+ speak = list("Hi!","Hello!","Cracker?","BAWWWWK george mellons griffing me!")
speak_emote = list("squawks","says","yells")
- emote_hear = list("squawks","bawks")
- emote_see = list("flutters its wings")
+ emote_hear = list("squawks.","bawks!")
+ emote_see = list("flutters its wings.")
speak_chance = 1 //1% (1 in 100) chance every tick; So about once per 150 seconds, assuming an average tick is 1.5s
turns_per_move = 5
@@ -419,7 +419,7 @@
//Search for item to steal
parrot_interest = search_for_item()
if(parrot_interest)
- emote("looks in [parrot_interest]'s direction and takes flight")
+ emote("me", 1, "looks in [parrot_interest]'s direction and takes flight.")
parrot_state = PARROT_SWOOP | PARROT_STEAL
icon_state = "parrot_fly"
return
@@ -441,7 +441,7 @@
if(AM)
if(istype(AM, /obj/item) || isliving(AM)) //If stealable item
parrot_interest = AM
- emote("turns and flies towards [parrot_interest]")
+ emote("me", 1, "turns and flies towards [parrot_interest].")
parrot_state = PARROT_SWOOP | PARROT_STEAL
return
else //Else it's a perch
@@ -739,7 +739,7 @@
held_item = null
if(health < maxHealth)
adjustBruteLoss(-10)
- emote("[src] eagerly downs the cracker")
+ emote("me", 1, "[src] eagerly downs the cracker.")
return 1
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index aec7c377b98..d7bee468516 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -46,7 +46,7 @@
var/max_co2 = 5
var/min_n2 = 0
var/max_n2 = 0
- var/unsuitable_atoms_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
+ var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
@@ -64,6 +64,10 @@
var/scan_ready = 1
var/species //Sorry, no spider+corgi buttbabies.
+ //simple_animal access
+ var/obj/item/weapon/card/id/access_card = null //innate access uses an internal ID card
+
+
/mob/living/simple_animal/New()
..()
verbs -= /mob/verb/observe
@@ -130,23 +134,23 @@
else
randomValue -= speak.len
if(emote_see && randomValue <= emote_see.len)
- emote(pick(emote_see),1)
+ emote("me", 1, pick(emote_see))
else
- emote(pick(emote_hear),2)
+ emote("me", 2, pick(emote_hear))
else
say(pick(speak))
else
if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len))
- emote(pick(emote_see),1)
+ emote("me", 1, pick(emote_see))
if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len))
- emote(pick(emote_hear),2)
+ emote("me", 2, pick(emote_hear))
if((emote_hear && emote_hear.len) && (emote_see && emote_see.len))
var/length = emote_hear.len + emote_see.len
var/pick = rand(1,length)
if(pick <= emote_see.len)
- emote(pick(emote_see),1)
+ emote("me", 1, pick(emote_see))
else
- emote(pick(emote_hear),2)
+ emote("me", 2, pick(emote_hear))
//Atmos
@@ -202,7 +206,7 @@
adjustBruteLoss(heat_damage_per_tick)
if(!atmos_suitable)
- adjustBruteLoss(unsuitable_atoms_damage)
+ adjustBruteLoss(unsuitable_atmos_damage)
return 1
/mob/living/simple_animal/Bumped(AM as mob|obj)
@@ -239,18 +243,17 @@
return "[emote], \"[text]\""
return "says, \"[text]\"";
-/mob/living/simple_animal/emote(var/act)
+/mob/living/simple_animal/emote(var/act, var/m_type=1, var/message = null)
if(stat)
return
if(act == "scream")
- act = "makes a loud and pained whimper" //ugly hack to stop animals screaming when crushed :P
- visible_message("[src] [act].")
- return
- ..(act)
+ message = "makes a loud and pained whimper" //ugly hack to stop animals screaming when crushed :P
+ act = "me"
+ ..(act, m_type, message)
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
- M.emote("[M.friendly] [src]")
+ M.emote("me", 1, "[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 468b4178562..eebe552a8d6 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -93,6 +93,42 @@ var/next_mob_id = 0
M.show_message( message, 1, blind_message, 2)
+
+
+
+// Show a message to all mobs in earshot of this one
+// This would be for audible actions by the src mob
+// message is the message output to anyone who can hear.
+// self_message (optional) is what the src mob hears.
+// deaf_message (optional) is what deaf people will see.
+// hearing_distance (optional) is the range, how many tiles away the message can be heard.
+
+/mob/audible_message(var/message, var/deaf_message, var/hearing_distance, var/self_message)
+ var/range = 7
+ if(hearing_distance)
+ range = hearing_distance
+ var/msg = message
+ for(var/mob/M in get_hearers_in_view(range, src))
+ if(self_message && M==src)
+ msg = self_message
+ M.show_message( msg, 2, deaf_message, 1)
+
+// Show a message to all mobs in earshot of this atom
+// Use for objects performing audible actions
+// message is the message output to anyone who can hear.
+// deaf_message (optional) is what deaf people will see.
+// hearing_distance (optional) is the range, how many tiles away the message can be heard.
+
+/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance)
+ var/range = 7
+ if(hearing_distance)
+ range = hearing_distance
+ for(var/mob/M in get_hearers_in_view(range, src))
+ M.show_message( message, 2, deaf_message, 1)
+
+
+
+
/mob/proc/movement_delay()
return 0
@@ -707,6 +743,12 @@ var/list/slot_equipment_priority = list( \
/mob/proc/IsAdvancedToolUser()//This might need a rename but it should replace the can this mob use things check
return 0
+/mob/proc/swap_hand()
+ return
+
+/mob/proc/activate_hand(var/selhand)
+ return
+
/mob/proc/SpeciesCanConsume()
return 0
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 7a76e48ca33..c9cc1fe6764 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -120,6 +120,11 @@ proc/isovermind(A)
return 1
return 0
+proc/isdrone(A)
+ if(istype(A, /mob/living/simple_animal/drone))
+ return 1
+ return 0
+
proc/isorgan(A)
if(istype(A, /obj/item/organ/limb))
return 1
@@ -466,4 +471,4 @@ proc/is_special_character(mob/M) // returns 1 for special characters and 2 for h
for(var/mob/hud_user in user_list)
var/turf/userturf = get_turf(hud_user)
if(userturf.z == sourceturf.z) //Must have same z-level.
- hud_user.show_message("\icon[hud_icon] [message]", 1)
+ hud_user.show_message("\icon[hud_icon] [message]", 1)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 20d9496f60f..42b25fe0a5f 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -1,6 +1,8 @@
/mob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group || (height==0)) return 1
+ if(istype(mover) && mover.checkpass(PASSMOB))
+ return 1
if(ismob(mover))
var/mob/moving_mob = mover
if ((other_mobs && moving_mob.other_mobs))
@@ -31,15 +33,10 @@
/client/Northwest()
- if(iscarbon(usr))
- var/mob/living/carbon/C = usr
- if(!C.get_active_hand())
- usr << "You have nothing to drop in your hand."
- return
- drop_item()
- else
- usr << "This mob type cannot drop items."
- return
+ if(!usr.get_active_hand())
+ usr << "You have nothing to drop in your hand!"
+ return
+ usr.drop_item()
//This gets called when you press the delete button.
/client/verb/delete_key_pressed()
@@ -51,15 +48,11 @@
usr.stop_pulling()
/client/verb/swap_hand()
- set hidden = 1
- if(istype(mob, /mob/living/carbon))
- mob:swap_hand()
- if(istype(mob,/mob/living/silicon/robot))
- var/mob/living/silicon/robot/R = mob
- R.cycle_modules()
- return
-
+ set category = "IC"
+ set name = "Swap hands"
+ if(mob)
+ mob.swap_hand()
/client/verb/attack_self()
set hidden = 1
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index d17985336d4..441362e2711 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -40,7 +40,7 @@
var/isadmin = 0
if(src.client && src.client.holder)
isadmin = 1
- var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_poll_question WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM erro_poll_vote WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM erro_poll_textreply WHERE ckey = \"[ckey]\")")
+ var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
query.Execute()
var/newpoll = 0
while(query.NextRow())
@@ -150,7 +150,7 @@
var/voted = 0
//First check if the person has not voted yet.
- var/DBQuery/query = dbcon.NewQuery("SELECT * FROM erro_privacy WHERE ckey='[src.ckey]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("privacy")] WHERE ckey='[src.ckey]'")
query.Execute()
while(query.NextRow())
voted = 1
@@ -175,7 +175,7 @@
return
if(!voted)
- var/sql = "INSERT INTO erro_privacy VALUES (null, Now(), '[src.ckey]', '[option]')"
+ var/sql = "INSERT INTO [format_table_name("privacy")] VALUES (null, Now(), '[src.ckey]', '[option]')"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
query_insert.Execute()
usr << "Thank you for your vote!"
diff --git a/code/modules/mob/new_player/poll.dm b/code/modules/mob/new_player/poll.dm
index ba3ff0e6940..8fd5ba2d93f 100644
--- a/code/modules/mob/new_player/poll.dm
+++ b/code/modules/mob/new_player/poll.dm
@@ -5,7 +5,7 @@
return
var/voted = 0
- var/DBQuery/query = dbcon.NewQuery("SELECT * FROM erro_privacy WHERE ckey='[src.ckey]'")
+ var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("privacy")] WHERE ckey='[src.ckey]'")
query.Execute()
while(query.NextRow())
voted = 1
@@ -53,7 +53,7 @@
if(src.client && src.client.holder)
isadmin = 1
- var/DBQuery/select_query = dbcon.NewQuery("SELECT id, question FROM erro_poll_question WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime")
+ var/DBQuery/select_query = dbcon.NewQuery("SELECT id, question FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime")
select_query.Execute()
var/output = "
Player polls"
@@ -84,7 +84,7 @@
establish_db_connection()
if(dbcon.IsConnected())
- var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM erro_poll_question WHERE id = [pollid]")
+ var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid]")
select_query.Execute()
var/pollstarttime = ""
@@ -109,7 +109,7 @@
switch(polltype)
//Polls that have enumerated options
if("OPTION")
- var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM erro_poll_vote WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
+ var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
voted_query.Execute()
var/voted = 0
@@ -121,7 +121,7 @@
var/list/datum/polloption/options = list()
- var/DBQuery/options_query = dbcon.NewQuery("SELECT id, text FROM erro_poll_option WHERE pollid = [pollid]")
+ var/DBQuery/options_query = dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
options_query.Execute()
while(options_query.NextRow())
var/datum/polloption/PO = new()
@@ -162,7 +162,7 @@
//Polls with a text input
if("TEXT")
- var/DBQuery/voted_query = dbcon.NewQuery("SELECT replytext FROM erro_poll_textreply WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
+ var/DBQuery/voted_query = dbcon.NewQuery("SELECT replytext FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
voted_query.Execute()
var/voted = 0
@@ -204,7 +204,7 @@
//Polls with a text input
if("NUMVAL")
- var/DBQuery/voted_query = dbcon.NewQuery("SELECT o.text, v.rating FROM erro_poll_option o, erro_poll_vote v WHERE o.pollid = [pollid] AND v.ckey = '[usr.ckey]' AND o.id = v.optionid")
+ var/DBQuery/voted_query = dbcon.NewQuery("SELECT o.text, v.rating FROM [format_table_name("poll_option")] o, [format_table_name("poll_vote")] v WHERE o.pollid = [pollid] AND v.ckey = '[usr.ckey]' AND o.id = v.optionid")
voted_query.Execute()
var/output = "
Player poll"
@@ -230,7 +230,7 @@
var/minid = 999999
var/maxid = 0
- var/DBQuery/option_query = dbcon.NewQuery("SELECT id, text, minval, maxval, descmin, descmid, descmax FROM erro_poll_option WHERE pollid = [pollid]")
+ var/DBQuery/option_query = dbcon.NewQuery("SELECT id, text, minval, maxval, descmin, descmid, descmax FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
option_query.Execute()
while(option_query.NextRow())
var/optionid = text2num(option_query.item[1])
@@ -273,7 +273,7 @@
src << browse(output,"window=playerpoll;size=500x500")
if("MULTICHOICE")
- var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM erro_poll_vote WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
+ var/DBQuery/voted_query = dbcon.NewQuery("SELECT optionid FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
voted_query.Execute()
var/list/votedfor = list()
@@ -286,7 +286,7 @@
var/maxoptionid = 0
var/minoptionid = 0
- var/DBQuery/options_query = dbcon.NewQuery("SELECT id, text FROM erro_poll_option WHERE pollid = [pollid]")
+ var/DBQuery/options_query = dbcon.NewQuery("SELECT id, text FROM [format_table_name("poll_option")] WHERE pollid = [pollid]")
options_query.Execute()
while(options_query.NextRow())
var/datum/polloption/PO = new()
@@ -345,7 +345,7 @@
establish_db_connection()
if(dbcon.IsConnected())
- var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM erro_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
+ var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype, multiplechoiceoptions FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
select_query.Execute()
var/validpoll = 0
@@ -363,7 +363,7 @@
usr << "Poll is not valid."
return
- var/DBQuery/select_query2 = dbcon.NewQuery("SELECT id FROM erro_poll_option WHERE id = [optionid] AND pollid = [pollid]")
+ var/DBQuery/select_query2 = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE id = [optionid] AND pollid = [pollid]")
select_query2.Execute()
var/validoption = 0
@@ -378,7 +378,7 @@
var/alreadyvoted = 0
- var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM erro_poll_vote WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
+ var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
voted_query.Execute()
while(voted_query.NextRow())
@@ -399,7 +399,7 @@
adminrank = usr.client.holder.rank
- var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO erro_poll_vote (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank) VALUES (null, Now(), [pollid], [optionid], '[usr.ckey]', '[usr.client.address]', '[adminrank]')")
+ var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank) VALUES (null, Now(), [pollid], [optionid], '[usr.ckey]', '[usr.client.address]', '[adminrank]')")
insert_query.Execute()
usr << "Vote successful."
@@ -415,7 +415,7 @@
establish_db_connection()
if(dbcon.IsConnected())
- var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM erro_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
+ var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
select_query.Execute()
var/validpoll = 0
@@ -432,7 +432,7 @@
var/alreadyvoted = 0
- var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM erro_poll_textreply WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
+ var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_textreply")] WHERE pollid = [pollid] AND ckey = '[usr.ckey]'")
voted_query.Execute()
while(voted_query.NextRow())
@@ -457,7 +457,7 @@
usr << "The text you entered was blank, contained illegal characters or was too long. Please correct the text and submit again."
return
- var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO erro_poll_textreply (id ,datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (null, Now(), [pollid], '[usr.ckey]', '[usr.client.address]', '[replytext]', '[adminrank]')")
+ var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_textreply")] (id ,datetime ,pollid ,ckey ,ip ,replytext ,adminrank) VALUES (null, Now(), [pollid], '[usr.ckey]', '[usr.client.address]', '[replytext]', '[adminrank]')")
insert_query.Execute()
usr << "Feedback logging successful."
@@ -473,7 +473,7 @@
establish_db_connection()
if(dbcon.IsConnected())
- var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM erro_poll_question WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
+ var/DBQuery/select_query = dbcon.NewQuery("SELECT starttime, endtime, question, polltype FROM [format_table_name("poll_question")] WHERE id = [pollid] AND Now() BETWEEN starttime AND endtime")
select_query.Execute()
var/validpoll = 0
@@ -488,7 +488,7 @@
usr << "Poll is not valid."
return
- var/DBQuery/select_query2 = dbcon.NewQuery("SELECT id FROM erro_poll_option WHERE id = [optionid] AND pollid = [pollid]")
+ var/DBQuery/select_query2 = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_option")] WHERE id = [optionid] AND pollid = [pollid]")
select_query2.Execute()
var/validoption = 0
@@ -503,7 +503,7 @@
var/alreadyvoted = 0
- var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM erro_poll_vote WHERE optionid = [optionid] AND ckey = '[usr.ckey]'")
+ var/DBQuery/voted_query = dbcon.NewQuery("SELECT id FROM [format_table_name("poll_vote")] WHERE optionid = [optionid] AND ckey = '[usr.ckey]'")
voted_query.Execute()
while(voted_query.NextRow())
@@ -519,7 +519,7 @@
adminrank = usr.client.holder.rank
- var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO erro_poll_vote (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (null, Now(), [pollid], [optionid], '[usr.ckey]', '[usr.client.address]', '[adminrank]', [(isnull(rating)) ? "null" : rating])")
+ var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO [format_table_name("poll_vote")] (id ,datetime ,pollid ,optionid ,ckey ,ip ,adminrank, rating) VALUES (null, Now(), [pollid], [optionid], '[usr.ckey]', '[usr.client.address]', '[adminrank]', [(isnull(rating)) ? "null" : rating])")
insert_query.Execute()
usr << "Vote successful."
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index 8712f30ea04..e21479a2197 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -74,7 +74,7 @@
/datum/sprite_accessory/hair/over_eye
name = "Over Eye"
- icon_state = "hair_overeye"
+ icon_state = "hair_shortovereye"
/datum/sprite_accessory/hair/long_over_eye
name = "Long Over Eye"
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 5bf229f61d5..544522c7934 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -22,10 +22,7 @@
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
- if(ishuman(src) || isrobot(src))
- usr.emote("me",1,message)
- else
- usr.emote(message)
+ usr.emote("me",1,message)
/mob/proc/say_dead(var/message)
var/name = src.real_name
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 15a3b7df52a..229a66f9511 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -250,7 +250,7 @@
O << "To look at other parts of the station, click on yourself to get a camera menu."
O << "While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc."
O << "To use something, simply click on it."
- O << {"Use say ":b to speak to your cyborgs through binary."}
+ O << {"Use say ":b to speak to your cyborgs through binary."} //"
if (!(ticker && ticker.mode && (O.mind in ticker.mode.malf_ai)))
O.show_laws()
O << "These laws may be changed by other players, or by you being the traitor."
@@ -309,9 +309,6 @@
O.job = "Cyborg"
O.notify_ai(1)
- O.mmi = new /obj/item/device/mmi(O)
- O.mmi.transfer_identity(src)//Does not transfer key/client.
-
. = O
qdel(src)
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 1df8ee0aa83..0c1045050c8 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -9,6 +9,7 @@
*/
/obj/machinery/photocopier
name = "photocopier"
+ desc = "Used to copy important documents and anatomy studies."
icon = 'icons/obj/library.dmi'
icon_state = "bigscanner"
anchored = 1
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 7433e5c5f17..98d63f963a0 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -383,29 +383,30 @@
if (istype(W, /obj/item/weapon/crowbar) && opened)
if (has_electronics==1)
if (terminal)
- user << "Disconnect wires first."
+ user << "Disconnect wires first."
return
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
user << "You are trying to remove the power control board..." //lpeters - fixed grammar issues
if(do_after(user, 50))
- has_electronics = 0
- if ((stat & BROKEN) || malfhack)
- user.visible_message(\
- "[user.name] has broken the power control board inside [src.name]!",\
- "You broke the charred power control board and remove the remains.",
- "You hear a crack!")
- //ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0
- else
- user.visible_message(\
- "[user.name] has removed the power control board from [src.name]!",\
- "You remove the power control board.")
- new /obj/item/weapon/module/power_control(loc)
+ if (has_electronics==1)
+ has_electronics = 0
+ if ((stat & BROKEN) || malfhack)
+ user.visible_message(\
+ "[user.name] has broken the power control board inside [src.name]!",\
+ "You broke the charred power control board and remove the remains.",
+ "You hear a crack!")
+ //ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0
+ else
+ user.visible_message(\
+ "[user.name] has removed the power control board from [src.name]!",\
+ "You remove the power control board.")
+ new /obj/item/weapon/module/power_control(loc)
else if (opened!=2) //cover isn't removed
opened = 0
update_icon()
else if (istype(W, /obj/item/weapon/crowbar) && !((stat & BROKEN) || malfhack) )
if(coverlocked && !(stat & MAINT))
- user << "The cover is locked and cannot be opened."
+ user << "The cover is locked and cannot be opened."
return
else
opened = 1
@@ -416,20 +417,20 @@
return
else
if (stat & MAINT)
- user << "There is no connector for your power cell."
+ user << "There is no connector for your power cell."
return
user.drop_item()
W.loc = src
cell = W
user.visible_message(\
- "[user.name] has inserted the power cell to [src.name]!",\
- "You insert the power cell.")
+ "[user.name] has inserted the power cell to [src.name]!",\
+ "You insert the power cell.")
chargecount = 0
update_icon()
else if (istype(W, /obj/item/weapon/screwdriver)) // haxing
if(opened)
if (cell)
- user << "Close the APC first." //Less hints more mystery!
+ user << "Close the APC first." //Less hints more mystery!
return
else
if (has_electronics==1 && terminal)
@@ -443,7 +444,7 @@
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
user << "You unfasten the electronics."
else /* has_electronics==0 */
- user << "There is nothing to secure."
+ user << "There is nothing to secure."
return
update_icon()
else if(emagged)
@@ -468,7 +469,7 @@
user << "You [ locked ? "lock" : "unlock"] the APC interface."
update_icon()
else
- user << "Access denied."
+ user << "Access denied."
else if (istype(W, /obj/item/weapon/card/emag) && !(emagged || malfhack)) // trying to unlock with an emag card
if(opened)
user << "You must close the cover to swipe an ID card."
@@ -482,10 +483,10 @@
if(prob(50))
emagged = 1
locked = 0
- user << "You emag the APC interface."
+ user << "You emag the APC interface."
update_icon()
else
- user << "You fail to [ locked ? "unlock" : "lock"] the APC interface."
+ user << "You fail to [ locked ? "unlock" : "lock"] the APC interface."
else if (istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics!=2)
if (src.loc:intact)
user << "You must remove the floor plating in front of the APC first."
@@ -494,7 +495,8 @@
if(C.get_amount() < 10)
user << "You need ten lengths of cable for APC."
return
- user << "You start adding cables to the APC frame..."
+ user.visible_message("[user.name] adds cables to the APC frame.", \
+ "You start adding cables to the APC frame...")
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 20))
if (C.amount >= 10 && !terminal && opened && has_electronics != 2)
@@ -506,59 +508,59 @@
s.start()
return
C.use(10)
- user.visible_message(\
- "[user.name] has added cables to the APC frame!",\
- "You add cables to the APC frame.")
+ user << "You add cables to the APC frame."
make_terminal()
terminal.connect_to_network()
else if (istype(W, /obj/item/weapon/wirecutters) && terminal && opened && has_electronics!=2)
if (src.loc:intact)
- user << "You must remove the floor plating in front of the APC first."
+ user << "You must remove the floor plating in front of the APC first."
return
- user << "You begin to cut the cables..."
+ user.visible_message("[user.name] dismantles the power terminal from [src].", \
+ "You begin to cut the cables...")
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 50))
- if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal))
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start()
- return
- new /obj/item/stack/cable_coil(loc,10)
- user.visible_message(\
- "[user.name] cut the cables and dismantled the power terminal.",\
- "You cut the cables and dismantle the power terminal.")
- qdel(terminal)
+ if(terminal && opened && has_electronics!=2)
+ if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal))
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start()
+ return
+ new /obj/item/stack/cable_coil(loc,10)
+ user << "You cut the cables and dismantle the power terminal."
+ qdel(terminal)
else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN) || malfhack))
- user << "You trying to insert the power control board into the frame..."
+ user.visible_message("[user.name] inserts the power control board into [src].", \
+ "You start to insert the power control board into the frame...")
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 10))
- has_electronics = 1
- user << "You place the power control board inside the frame."
- qdel(W)
+ if(has_electronics==0)
+ has_electronics = 1
+ user << "You place the power control board inside the frame."
+ qdel(W)
else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && ((stat & BROKEN) || malfhack))
- user << "You cannot put the board inside, the frame is damaged."
+ user << "You cannot put the board inside, the frame is damaged."
return
else if (istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics==0 && !terminal)
var/obj/item/weapon/weldingtool/WT = W
if (WT.get_fuel() < 3)
- user << "You need more welding fuel to complete this task."
+ user << "You need more welding fuel to complete this task."
return
- user << "You start welding the APC frame..."
+ user.visible_message("[user.name] welds [src].", \
+ "You start welding the APC frame...", \
+ "You hear welding.")
playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
if(do_after(user, 50))
if(!src || !WT.remove_fuel(3, user)) return
if (emagged || malfhack || (stat & BROKEN) || opened==2)
new /obj/item/stack/sheet/metal(loc)
user.visible_message(\
- "[src] has been cut apart by [user.name] with the weldingtool.",\
- "You disassembled the broken APC frame.",\
- "You hear welding.")
+ "[src] has been cut apart by [user.name] with the weldingtool.",\
+ "You disassembled the broken APC frame.")
else
new /obj/item/apc_frame(loc)
user.visible_message(\
- "[src] has been cut from the wall by [user.name] with the weldingtool.",\
- "You cut the APC frame from the wall.",\
- "You hear welding.")
+ "[src] has been cut from the wall by [user.name] with the weldingtool.",\
+ "You cut the APC frame from the wall.")
qdel(src)
return
else if (istype(W, /obj/item/apc_frame) && opened && emagged)
@@ -566,19 +568,18 @@
if (opened==2)
opened = 1
user.visible_message(\
- "[user.name] has replaced the damaged APC frontal panel with a new one.",\
- "You replace the damaged APC frontal panel with a new one.")
+ "[user.name] has replaced the damaged APC frontal panel with a new one.",\
+ "You replace the damaged APC frontal panel with a new one.")
qdel(W)
update_icon()
else if (istype(W, /obj/item/apc_frame) && opened && ((stat & BROKEN) || malfhack))
if (has_electronics)
- user << "You cannot repair this APC until you remove the electronics still inside."
+ user << "You cannot repair this APC until you remove the electronics still inside."
return
- user << "You begin to replace the damaged APC frame..."
+ user.visible_message("[user.name] replaces the damaged APC frame with a new one.",\
+ "You begin to replace the damaged APC frame...")
if(do_after(user, 50))
- user.visible_message(\
- "[user.name] has replaced the damaged APC frame with new one.",\
- "You replace the damaged APC frame with new one.")
+ user << "You've replaced the damaged APC frame with a new one."
qdel(W)
stat &= ~BROKEN
malfai = null
@@ -623,7 +624,8 @@
cell.updateicon()
src.cell = null
- user.visible_message("[user.name] removes the power cell from [src.name]!", "You remove the power cell.")
+ user.visible_message("[user.name] removes the power cell from [src.name]!",\
+ "You remove the power cell.")
//user << "You remove the power cell."
charging = 0
src.update_icon()
@@ -768,20 +770,18 @@
/obj/machinery/power/apc/proc/can_use(mob/user as mob, var/loud = 0) //used by attack_hand() and Topic()
if (user.stat)
- user << "You must be conscious to use this [src]!"
+ user << "You must be conscious to use [src]!"
return 0
if(!user.client)
return 0
- if ( ! (istype(user, /mob/living/carbon/human) || \
- istype(user, /mob/living/silicon) || \
- istype(user, /mob/living/carbon/monkey)) )
- user << "You don't have the dexterity to use this [src]!"
+ if(!user.IsAdvancedToolUser())
+ user << "You don't have the dexterity to use [src]!"
return 0
if(user.restrained())
- user << "You must have free hands to use this [src]."
+ user << "You must have free hands to use [src]."
return 0
if(user.lying)
- user << "You must stand to use this [src]!"
+ user << "You must stand to use [src]!"
return 0
if (istype(user, /mob/living/silicon))
var/mob/living/silicon/ai/AI = user
@@ -804,8 +804,7 @@
var/mob/living/carbon/human/H = user
if (istype(H))
if(H.getBrainLoss() >= 60)
- for(var/mob/M in viewers(src, null))
- M << "[H] stares cluelessly at [src] and drools."
+ H.visible_message("[H] stares cluelessly at [src] and drools.")
return 0
else if(prob(H.getBrainLoss()))
user << "You momentarily forget how to use [src]."
@@ -899,11 +898,6 @@
/obj/machinery/power/apc/proc/toggle_breaker()
operating = !operating
- if(malfai)
- if (ticker.mode.config_tag == "malfunction")
- if (src.z == 1) //if (is_type_in_list(get_area(src), the_station_areas))
- operating ? ticker.mode:apcs++ : ticker.mode:apcs--
-
src.update()
update_icon()
@@ -981,8 +975,8 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
- for(var/mob/M in viewers(src))
- M.show_message("The [src.name] suddenly lets out a blast of smoke and some sparks!", 3, "You hear sizzling electronics.", 2)
+ visible_message("The [src.name] suddenly lets out a blast of smoke and some sparks!", \
+ "You hear sizzling electronics.")
/obj/machinery/power/apc/surplus()
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index c48fef8ac0e..30991698e7c 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -119,13 +119,17 @@
else
src.fire_delay = rand(20,100)
src.shot_number = 0
- var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
+
+ var/obj/item/projectile/beam/emitter/A = PoolOrNew(/obj/item/projectile/beam/emitter,src.loc)
+
+ A.dir = src.dir
playsound(src.loc, 'sound/weapons/emitter.ogg', 25, 1)
+
if(prob(35))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
- A.dir = src.dir
+
switch(dir)
if(NORTH)
A.yo = 20
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index 78c01b24636..2f0e57e313d 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -68,10 +68,12 @@
capacity = C / (15000) * 1e6
/obj/machinery/power/smes/attackby(obj/item/I, mob/user)
+ //opening using screwdriver
if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I))
update_icon()
return
+ //changing direction using wrench
if(default_change_direction_wrench(user, I))
terminal = null
var/turf/T = get_step(src, dir)
@@ -81,12 +83,6 @@
terminal.master = src
user << "Terminal found."
break
- if(!terminal)
- for(var/obj/structure/cable/C in T)
- if(C.d1 == turn(dir, 180) || C.d2 == turn(dir, 180))
- terminal = C
- user << "Cable found."
- break
if(!terminal)
user << "No power source found."
return
@@ -94,9 +90,83 @@
update_icon()
return
+ //exchanging parts using the RPE
if(exchange_parts(user, I))
return
+ //building and linking a terminal
+ if(istype(I, /obj/item/stack/cable_coil))
+ var/dir = get_dir(user,src)
+ if(dir & (dir-1))//we don't want diagonal click
+ return
+
+ if(terminal) //is there already a terminal ?
+ user << "This SMES already have a power terminal!"
+ return
+
+ if(!panel_open) //is the panel open ?
+ user << "You must open the maintenance panel first!"
+ return
+
+ var/turf/T = get_turf(user)
+ if (T.intact) //is the floor plating removed ?
+ user << "You must first remove the floor plating!"
+ return
+
+
+ var/obj/item/stack/cable_coil/C = I
+ if(C.amount < 10)
+ user << "You need more wires."
+ return
+
+ user << "You start building the power terminal..."
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+
+ if(do_after(user, 20) && C.amount >= 10)
+ var/obj/structure/cable/N = T.get_cable_node() //get the connecting node cable, if there's one
+ if (prob(50) && electrocute_mob(usr, N, N)) //animate the electrocution if uncautious and unlucky
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start()
+ return
+
+ C.use(10)
+ user.visible_message(\
+ "[user.name] has build a power terminal!",\
+ "You build the power terminal.")
+
+ //build the terminal and link it to the network
+ make_terminal(T)
+ terminal.connect_to_network()
+ return
+
+ //disassembling the terminal
+ if(istype(I, /obj/item/weapon/wirecutters) && terminal && panel_open)
+ var/turf/T = get_turf(terminal)
+ if (T.intact) //is the floor plating removed ?
+ user << "You must first expose the power terminal!"
+ return
+
+ user << "You begin to dismantle the power terminal..."
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+
+ if(do_after(user, 50))
+ if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal)) //animate the electrocution if uncautious and unlucky
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start()
+ return
+
+ //give the wires back and delete the terminal
+ new /obj/item/stack/cable_coil(T,10)
+ user.visible_message(\
+ "[user.name] cuts the cables and dismantles the power terminal.",\
+ "You cut the cables and dismantle the power terminal.")
+ inputting = 0 //stop inputting, since we have don't have a terminal anymore
+ qdel(terminal)
+ return
+
+ //crowbarring it !
default_deconstruction_crowbar(I)
/obj/machinery/power/smes/Destroy()
@@ -109,6 +179,13 @@
disconnect_terminal()
..()
+// create a terminal object pointing towards the SMES
+// wires will attach to this
+/obj/machinery/power/smes/proc/make_terminal(var/turf/T)
+ terminal = new/obj/machinery/power/terminal(T)
+ terminal.dir = get_dir(T,src)
+ terminal.master = src
+
/obj/machinery/power/smes/disconnect_terminal()
if(terminal)
terminal.master = null
diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm
index 205ab164360..dbde10cfe56 100644
--- a/code/modules/projectiles/ammunition/ammo_casings.dm
+++ b/code/modules/projectiles/ammunition/ammo_casings.dm
@@ -46,7 +46,7 @@
/obj/item/ammo_casing/shotgun
name = "shotgun slug"
- desc = "A 12 gauge slug."
+ desc = "A 12 gauge lead slug."
icon_state = "blshell"
caliber = "shotgun"
projectile_type = /obj/item/projectile/bullet
@@ -54,8 +54,8 @@
/obj/item/ammo_casing/shotgun/buckshot
- name = "shotgun shell"
- desc = "A 12 gauge shell."
+ name = "buckshot shell"
+ desc = "A 12 gauge buckshot shell."
icon_state = "gshell"
projectile_type = /obj/item/projectile/bullet/pellet
pellets = 5
@@ -63,19 +63,19 @@
/obj/item/ammo_casing/shotgun/beanbag
- name = "beanbag shell"
- desc = "A weak beanbag shell."
+ name = "beanbag slug"
+ desc = "A weak beanbag slug for riot control."
icon_state = "bshell"
projectile_type = /obj/item/projectile/bullet/weakbullet
m_amt = 250
-/obj/item/ammo_casing/shotgun/stunshell
- name = "stun shell"
- desc = "A stunning shell."
+/obj/item/ammo_casing/shotgun/stunslug
+ name = "taser slug"
+ desc = "A stunning taser slug."
icon_state = "stunshell"
projectile_type = /obj/item/projectile/bullet/stunshot
- m_amt = 200
+ m_amt = 250
/obj/item/ammo_casing/shotgun/meteorshot
@@ -94,13 +94,13 @@
/obj/item/ammo_casing/shotgun/incendiary
name = "incendiary slug"
- desc = "An incendiary shell which fires a single slug of incendiary ammo."
+ desc = "An incendiary-coated shotgun slug."
icon_state = "ishell"
projectile_type = /obj/item/projectile/bullet/incendiary/shell
/obj/item/ammo_casing/shotgun/incendiary/dragonsbreath
name = "dragonsbreath shell"
- desc = "An incendiary shell which fires a spread of incendiary ammo."
+ desc = "A shotgun shell which fires a spread of incendiary pellets."
icon_state = "ishell2"
projectile_type = /obj/item/projectile/bullet/incendiary/shell/dragonsbreath
pellets = 4
diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm
index 323c7832f99..4ea3e418f69 100644
--- a/code/modules/projectiles/ammunition/magazines.dm
+++ b/code/modules/projectiles/ammunition/magazines.dm
@@ -158,4 +158,28 @@ obj/item/ammo_box/magazine/tommygunm45
/obj/item/ammo_box/magazine/m762/update_icon()
..()
- icon_state = "[initial(icon_state)]-[round(ammo_count(),10)]"
\ No newline at end of file
+ icon_state = "[initial(icon_state)]-[round(ammo_count(),10)]"
+
+/obj/item/ammo_box/magazine/m12g
+ name = "shotgun magazine (12g taser slugs)"
+ icon_state = "m12gs"
+ origin_tech = "combat=3;syndicate=1"
+ ammo_type = /obj/item/ammo_casing/shotgun/stunslug
+ caliber = "shotgun"
+ max_ammo = 8
+
+/obj/item/ammo_box/magazine/m12g/update_icon()
+ ..()
+ icon_state = "[initial(icon_state)]-[Ceiling(ammo_count(0)/8)*8]"
+
+
+/obj/item/ammo_box/magazine/m12g/buckshot
+ name = "shotgun magazine (12g buckshot)"
+ icon_state = "m12gb"
+ ammo_type = /obj/item/ammo_casing/shotgun/buckshot
+
+
+/obj/item/ammo_box/magazine/m12g/dragon
+ name = "shotgun magazine (12g dragon's breath)"
+ icon_state = "m12gf"
+ ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm
index 723ab458554..e6b2d750ac0 100644
--- a/code/modules/projectiles/guns/projectile/automatic.dm
+++ b/code/modules/projectiles/guns/projectile/automatic.dm
@@ -16,6 +16,12 @@
if(..() && chambered)
alarmed = 0
+/obj/item/weapon/gun/projectile/automatic/proc/empty_alarm()
+ if(!chambered && !get_ammo() && !alarmed)
+ playsound(src.loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
+ update_icon()
+ alarmed = 1
+ return
/obj/item/weapon/gun/projectile/automatic/mini_uzi
name = "Uzi"
@@ -43,16 +49,11 @@
update_icon()
return
-
-/obj/item/weapon/gun/projectile/automatic/c20r/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
+/obj/item/weapon/gun/projectile/automatic/c20r/afterattack()
..()
- if(!chambered && !get_ammo() && !alarmed)
- playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
- update_icon()
- alarmed = 1
+ empty_alarm()
return
-
/obj/item/weapon/gun/projectile/automatic/c20r/update_icon()
..()
icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"]"
@@ -113,6 +114,38 @@
return
..()
+/obj/item/weapon/gun/projectile/automatic/bulldog
+ name = "\improper Bulldog shotgun"
+ desc = "A compact, mag-fed semi-automatic shotgun for combat in narrow corridors. Compatible only with specialized magazines."
+ icon_state = "bulldog"
+ item_state = "bulldog"
+ w_class = 3.0
+ origin_tech = "combat=5;materials=4;syndicate=6"
+ mag_type = /obj/item/ammo_box/magazine/m12g
+ fire_sound = 'sound/weapons/Gunshot.ogg'
+
+/obj/item/weapon/gun/projectile/automatic/bulldog/New()
+ ..()
+ update_icon()
+ return
+
+/obj/item/weapon/gun/projectile/automatic/bulldog/proc/update_magazine()
+ if(magazine)
+ src.overlays = 0
+ overlays += "[magazine.icon_state]"
+ return
+
+/obj/item/weapon/gun/projectile/automatic/bulldog/update_icon()
+ src.overlays = 0
+ update_magazine()
+ icon_state = "bulldog[chambered ? "" : "-e"]"
+ return
+
+/obj/item/weapon/gun/projectile/automatic/bulldog/afterattack()
+ ..()
+ empty_alarm()
+ return
+
/obj/item/weapon/gun/projectile/automatic/tommygun
name = "tommy gun"
desc = "A genuine Chicago Typewriter."
diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm
index 070d1900e3b..5b3e6574630 100644
--- a/code/modules/projectiles/guns/projectile/pistol.dm
+++ b/code/modules/projectiles/guns/projectile/pistol.dm
@@ -22,12 +22,9 @@
mag_type = /obj/item/ammo_box/magazine/m50
-/obj/item/weapon/gun/projectile/automatic/deagle/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
+/obj/item/weapon/gun/projectile/automatic/deagle/afterattack()
..()
- if(!chambered && !get_ammo() && !alarmed)
- playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
- update_icon()
- alarmed = 1
+ empty_alarm()
return
/obj/item/weapon/gun/projectile/automatic/deagle/update_icon()
@@ -59,12 +56,9 @@
/obj/item/weapon/gun/projectile/automatic/gyropistol/process_chamber(var/eject_casing = 0, var/empty_chamber = 1)
..()
-/obj/item/weapon/gun/projectile/automatic/gyropistol/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)
+/obj/item/weapon/gun/projectile/automatic/gyropistol/afterattack()
..()
- if(!chambered && !get_ammo() && !alarmed)
- playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
- update_icon()
- alarmed = 1
+ empty_alarm()
return
/obj/item/weapon/gun/projectile/automatic/gyropistol/update_icon()
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 8d6659ff84a..e5213d7c967 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -50,10 +50,13 @@
var/forcedodge = 0
+
/obj/item/projectile/proc/delete()
// Garbage collect the projectiles
loc = null
+
+
/obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0, var/hit_zone)
if(!isliving(target)) return 0
if(isanimal(target)) return 0
@@ -67,8 +70,8 @@
else
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
-/obj/item/projectile/Bump(atom/A as mob|obj|turf|area)
+/obj/item/projectile/Bump(atom/A as mob|obj|turf|area)
if(A == firer)
loc = A.loc
return 0 //cannot shoot yourself
@@ -120,8 +123,7 @@
permutated.Add(A)
return 0
- density = 0
- invisibility = 101
+
delete()
return 0
return 1
@@ -141,9 +143,9 @@
delete()
return
kill_count--
- spawn while(src && src.loc)
+ spawn while(loc)
if((!( current ) || loc == current))
- current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z)
+ current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
delete()
return
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index a64c3291f23..ef6596731cf 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -54,6 +54,8 @@
icon_state = "emitter"
damage = 30
+/obj/item/projectile/beam/emitter/delete() //what projectiles use to set loc = null
+ PlaceInPool(src)
/obj/item/projectile/lasertag
name = "laser tag beam"
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index fba3302ac90..4f1060ea6ad 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -23,7 +23,7 @@
..()
/obj/item/projectile/energy/declone
- name = "declown"
+ name = "radiation beam"
icon_state = "declone"
nodamage = 1
damage_type = CLONE
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index 7f0078bb44f..2973bfcc363 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -4,6 +4,7 @@
/obj/machinery/chem_dispenser
name = "chem dispenser"
+ desc = "Creates and dispenses chemicals."
density = 1
anchored = 1
icon = 'icons/obj/chemical.dmi'
@@ -242,6 +243,7 @@
/obj/machinery/chem_master
name = "ChemMaster 3000"
+ desc = "Used to bottle chemicals to create pills."
density = 1
anchored = 1
icon = 'icons/obj/chemical.dmi'
@@ -509,6 +511,7 @@
/obj/machinery/chem_master/condimaster
name = "CondiMaster 3000"
+ desc = "Used to create condiments and other cooking supplies."
condi = 1
////////////////////////////////////////////////////////////////////////
@@ -516,6 +519,7 @@
/obj/machinery/computer/pandemic
name = "PanD.E.M.I.C 2200"
+ desc = "Used to work with viruses."
density = 1
anchored = 1
icon = 'icons/obj/chemical.dmi'
@@ -805,6 +809,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime)
/obj/machinery/reagentgrinder
name = "All-In-One Grinder"
+ desc = "Used to grind things up into raw materials."
icon = 'icons/obj/kitchen.dmi'
icon_state = "juicer1"
layer = 2.9
@@ -826,7 +831,7 @@ obj/machinery/computer/pandemic/proc/replicator_cooldown(var/waittime)
/obj/item/stack/sheet/glass = list("silicon" = 20),
/obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20),
/obj/item/stack/sheet/mineral/uranium = list("uranium" = 20),
- /obj/item/stack/sheet/mineral/clown = list("banana" = 20),
+ /obj/item/stack/sheet/mineral/bananium = list("banana" = 20),
/obj/item/stack/sheet/mineral/silver = list("silver" = 20),
/obj/item/stack/sheet/mineral/gold = list("gold" = 20),
/obj/item/weapon/grown/nettle = list("sacid" = 0),
diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm
index 4ec642bdadf..79ee2547832 100644
--- a/code/modules/reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents.dm
@@ -996,6 +996,8 @@ datum/reagent/adminordrazine/on_mob_life(var/mob/living/carbon/M as mob)
M.sleeping = 0
M.jitteriness = 0
for(var/datum/disease/D in M.viruses)
+ if(D.severity == D.non_threat)
+ continue
D.spread = "Remissive"
D.stage--
if(D.stage < 1)
@@ -1168,7 +1170,7 @@ datum/reagent/clonexadone/on_mob_life(var/mob/living/M as mob)
datum/reagent/rezadone
name = "Rezadone"
id = "rezadone"
- description = "A powder derived from fish toxin, this substance can effectively treat genetic damage in humanoids, though excessive consumption has side effects."
+ description = "A powder derived from fish toxin, this substance can effectively treat cellular damage in humanoids, though excessive consumption has side effects."
reagent_state = SOLID
color = "#669900" // rgb: 102, 153, 0
@@ -1564,6 +1566,20 @@ datum/reagent/toxin/spore/on_mob_life(var/mob/living/M as mob)
M.eye_blurry = max(M.eye_blurry, 3)
return
+
+datum/reagent/toxin/spore_burning
+ name = "Burning Spore Toxin"
+ id = "spore_burning"
+ description = "A burning spore cloud."
+ reagent_state = LIQUID
+ color = "#9ACD32"
+ toxpwr = 0.5
+
+datum/reagent/toxin/spore_burning/on_mob_life(var/mob/living/M as mob)
+ ..()
+ M.adjust_fire_stacks(2)
+ M.IgniteMob()
+
datum/reagent/toxin/chloralhydrate
name = "Chloral Hydrate"
id = "chloralhydrate"
diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm
index a115295a9e9..3dce51e7c62 100644
--- a/code/modules/reagents/Chemistry-Recipes.dm
+++ b/code/modules/reagents/Chemistry-Recipes.dm
@@ -321,23 +321,14 @@ silicate
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(2, 1, location)
s.start()
- for(var/mob/living/carbon/M in viewers(world.view, location))
- switch(get_dist(M, location))
- if(0 to 3)
- if(hasvar(M, "glasses"))
- if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses))
- continue
-
- flick("e_flash", M.flash)
- M.Weaken(5)
-
- if(4 to 5)
- if(hasvar(M, "glasses"))
- if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses))
- continue
-
- flick("e_flash", M.flash)
- M.Stun(5)
+ for(var/mob/living/carbon/C in get_hearers_in_view(5, location))
+ if(C.eyecheck())
+ continue
+ flick("e_flash", C.flash)
+ if(get_dist(C, location) < 4)
+ C.Weaken(5)
+ continue
+ C.Stun(5)
/datum/chemical_reaction/napalm
name = "Napalm"
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 1c264fcc5d3..b1ea5d08ee7 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -581,9 +581,8 @@
if (user.stat)
return
if (src.loc)
- for (var/mob/M in hearers(src.loc.loc))
+ for (var/mob/M in get_hearers_in_view(src.loc.loc))
M.show_message("CLONG, clong!", 2)
-
playsound(src.loc, 'sound/effects/clang.ogg', 50, 0, 0)
// called to vent all gas in holder to a location
diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm
index 6c960e0d5c8..a19eaff4eb4 100644
--- a/code/modules/research/circuitprinter.dm
+++ b/code/modules/research/circuitprinter.dm
@@ -6,6 +6,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
*/
/obj/machinery/r_n_d/circuit_imprinter
name = "Circuit Imprinter"
+ desc = "Manufactures circuit boards for the construction of machines."
icon_state = "circuit_imprinter"
flags = OPENCONTAINER
@@ -92,7 +93,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
if (disabled)
return
if (!linked_console)
- user << "\The [name] must be linked to an R&D console first!"
+ user << "The [name] must be linked to an R&D console first!"
return 1
if (O.is_open_container())
return
diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm
index dca8737f26c..e7f378d8e58 100644
--- a/code/modules/research/designs.dm
+++ b/code/modules/research/designs.dm
@@ -328,3 +328,13 @@ datum/design/magboots
build_type = PROTOLATHE
materials = list("$metal" = 4500, "$silver" = 1500, "$gold" = 2500)
build_path = /obj/item/clothing/shoes/magboots
+
+datum/design/drone_shell
+ name = "drone shell"
+ desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs."
+ id = "drone_shell"
+ req_tech = list("programming" = 2, "biotech" = 4)
+ build_type = MECHFAB
+ materials = list("$metal" = 800, "$glass" = 350)
+ build_path = /obj/item/drone_shell
+ category = "Misc"
\ No newline at end of file
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index b50e0225101..d21aef0bc15 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -155,7 +155,7 @@ datum/design/stunshell
req_tech = list("combat" = 3, "materials" = 3)
build_type = PROTOLATHE
materials = list("$metal" = 200)
- build_path = /obj/item/ammo_casing/shotgun/stunshell
+ build_path = /obj/item/ammo_casing/shotgun/stunslug
datum/design/techshell
name = "Unloaded Technological Shotshell"
diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm
index 9034c3430a4..82912068a18 100644
--- a/code/modules/research/destructive_analyzer.dm
+++ b/code/modules/research/destructive_analyzer.dm
@@ -9,6 +9,7 @@ Note: Must be placed within 3 tiles of the R&D Console
*/
/obj/machinery/r_n_d/destructive_analyzer
name = "Destructive Analyzer"
+ desc = "Learn science by destroying things!"
icon_state = "d_analyzer"
var/obj/item/weapon/loaded_item = null
var/decon_mod = 0
@@ -53,38 +54,28 @@ Note: Must be placed within 3 tiles of the R&D Console
if (disabled)
return
if (!linked_console)
- user << "The protolathe must be linked to an R&D console first!"
+ user << "The [src.name] must be linked to an R&D console first!"
return
if (busy)
- user << " The protolathe is busy right now."
+ user << "The [src.name] is busy right now."
return
if (istype(O, /obj/item) && !loaded_item)
if(!O.origin_tech)
- user << " This doesn't seem to have a tech origin!"
+ user << "This doesn't seem to have a tech origin!"
return
var/list/temp_tech = ConvertReqString2List(O.origin_tech)
if (temp_tech.len == 0)
- user << " You cannot deconstruct this item!"
+ user << "You cannot deconstruct this item!"
return
if(!user.drop_item())
- user << "\The [O] is stuck to your hand, you cannot put it in the analyzer!"
+ user << "\The [O] is stuck to your hand, you cannot put it in the [src.name]!"
return
busy = 1
loaded_item = O
O.loc = src
- user << "You add the [O.name] to the machine!"
+ user << "You add the [O.name] to the [src.name]!"
flick("d_analyzer_la", src)
spawn(10)
icon_state = "d_analyzer_l"
busy = 0
return
-
-//For testing purposes only.
-/*/obj/item/weapon/deconstruction_test
- name = "Test Item"
- desc = "WTF?"
- icon = 'icons/obj/weapons.dmi'
- icon_state = "d20"
- g_amt = 5000
- m_amt = 5000
- origin_tech = "materials=5;plasmatech=5;syndicate=5;programming=9"*/
diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm
index 884d4eb2f8b..c5dd5d2ae50 100644
--- a/code/modules/research/message_server.dm
+++ b/code/modules/research/message_server.dm
@@ -276,7 +276,7 @@ var/obj/machinery/blackbox_recorder/blackbox
if(!dbcon.IsConnected()) return
var/round_id
- var/DBQuery/query = dbcon.NewQuery("SELECT MAX(round_id) AS round_id FROM erro_feedback")
+ var/DBQuery/query = dbcon.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]")
query.Execute()
while(query.NextRow())
round_id = query.item[1]
@@ -286,7 +286,7 @@ var/obj/machinery/blackbox_recorder/blackbox
round_id++
for(var/datum/feedback_variable/FV in feedback)
- var/sql = "INSERT INTO erro_feedback VALUES (null, Now(), [round_id], \"[FV.get_variable()]\", [FV.get_value()], \"[FV.get_details()]\")"
+ var/sql = "INSERT INTO [format_table_name("feedback")] VALUES (null, Now(), [round_id], \"[FV.get_variable()]\", [FV.get_value()], \"[FV.get_details()]\")"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
query_insert.Execute()
diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm
index d37119fa05b..7c7c13791c0 100644
--- a/code/modules/research/protolathe.dm
+++ b/code/modules/research/protolathe.dm
@@ -9,6 +9,7 @@ Note: Must be placed west/left of and R&D console to function.
*/
/obj/machinery/r_n_d/protolathe
name = "Protolathe"
+ desc = "Converts raw materials into useful objects."
icon_state = "protolathe"
flags = OPENCONTAINER
@@ -118,7 +119,7 @@ Note: Must be placed west/left of and R&D console to function.
var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc)
G.amount = round(diamond_amount / G.perunit)
if(clown_amount >= MINERAL_MATERIAL_AMOUNT)
- var/obj/item/stack/sheet/mineral/clown/G = new /obj/item/stack/sheet/mineral/clown(src.loc)
+ var/obj/item/stack/sheet/mineral/bananium/G = new /obj/item/stack/sheet/mineral/bananium(src.loc)
G.amount = round(clown_amount / G.perunit)
if(adamantine_amount >= MINERAL_MATERIAL_AMOUNT)
var/obj/item/stack/sheet/mineral/adamantine/G = new /obj/item/stack/sheet/mineral/adamantine(src.loc)
@@ -131,22 +132,22 @@ Note: Must be placed west/left of and R&D console to function.
if (disabled)
return
if (!linked_console)
- user << "\The protolathe must be linked to an R&D console first!"
+ user << " The [src.name] must be linked to an R&D console first!"
return 1
if (busy)
- user << "The protolathe is busy. Please wait for completion of previous operation."
+ user << "The [src.name] is busy. Please wait for completion of previous operation."
return 1
if (O.is_open_container())
return
if (!istype(O, /obj/item/stack/sheet) || istype(O, /obj/item/stack/sheet/mineral/wood))
- user << "You cannot insert this item into the protolathe!"
+ user << "You cannot insert this item into the [src.name]!"
return 1
if (stat)
return 1
if(istype(O,/obj/item/stack/sheet))
var/obj/item/stack/sheet/S = O
if (TotalMaterials() + S.perunit > max_material_storage)
- user << "The protolathe's material bin is full. Please remove material before adding more."
+ user << "The [src.name]'s material bin is full. Please remove material before adding more."
return 1
var/obj/item/stack/sheet/stack = O
@@ -177,7 +178,7 @@ Note: Must be placed west/left of and R&D console to function.
uranium_amount += amount * MINERAL_MATERIAL_AMOUNT
else if(istype(stack, /obj/item/stack/sheet/mineral/diamond))
diamond_amount += amount * MINERAL_MATERIAL_AMOUNT
- else if(istype(stack, /obj/item/stack/sheet/mineral/clown))
+ else if(istype(stack, /obj/item/stack/sheet/mineral/bananium))
clown_amount += amount * MINERAL_MATERIAL_AMOUNT
else if(istype(stack, /obj/item/stack/sheet/mineral/adamantine))
adamantine_amount += amount * MINERAL_MATERIAL_AMOUNT
@@ -189,4 +190,4 @@ Note: Must be placed west/left of and R&D console to function.
sleep(10)
src.overlays -= "protolathe_[stack.name]"
- return
\ No newline at end of file
+ return
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 96b6bce013e..f927f96c9c7 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -503,7 +503,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
type = /obj/item/stack/sheet/mineral/diamond
res_amount = "diamond_amount"
if("clown")
- type = /obj/item/stack/sheet/mineral/clown
+ type = /obj/item/stack/sheet/mineral/bananium
res_amount = "clown_amount"
if(ispath(type) && hasvar(linked_lathe, res_amount))
var/obj/item/stack/sheet/sheet = new type(linked_lathe.loc)
@@ -935,10 +935,12 @@ won't update every console in existence) but it's more of a hassle to do. Also,
/obj/machinery/computer/rdconsole/robotics
name = "Robotics R&D Console"
+ desc = "A console used to interface with R&D tools."
id = 2
req_access = null
req_access_txt = "29"
/obj/machinery/computer/rdconsole/core
name = "Core R&D Console"
+ desc = "A console used to interface with R&D tools."
id = 1
\ No newline at end of file
diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm
index 2daa19ffe69..b5d05a946f3 100644
--- a/code/modules/research/server.dm
+++ b/code/modules/research/server.dm
@@ -176,6 +176,7 @@
/obj/machinery/computer/rdservercontrol
name = "R&D Server Controller"
+ desc = "Used to manage access to research and manufacturing databases."
icon_state = "rdcomp"
var/screen = 0
var/obj/machinery/r_n_d/server/temp_server
diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm
index ab3b73cdbfa..e807beeaedb 100644
--- a/code/modules/scripting/Implementations/Telecomms.dm
+++ b/code/modules/scripting/Implementations/Telecomms.dm
@@ -97,16 +97,34 @@
interpreter.SetVar("$sign" , signal)
interpreter.SetVar("$pass" , !(signal.data["reject"])) // if the signal isn't rejected, pass = 1; if the signal IS rejected, pass = 0
- // Set up the script procs
+ //Language bitflags
+ interpreter.SetVar("HUMAN" , HUMAN)
+ interpreter.SetVar("MONKEY" , MONKEY)
+ interpreter.SetVar("ALIEN" , ALIEN)
+ interpreter.SetVar("ROBOT" , ROBOT)
+ interpreter.SetVar("SLIME" , SLIME)
+ interpreter.SetVar("DRONE" , DRONE)
+
+ var/curlang = HUMAN
+ if(istype(signal.data["mob"], /atom/movable))
+ var/atom/movable/M = signal.data["mob"]
+ curlang = M.languages
+
+ interpreter.SetVar("$language", curlang)
+
+
+ /*
+ Telecomms procs
+ */
/*
-> Send another signal to a server
- @format: broadcast(content, frequency, source, job)
+ @format: broadcast(content, frequency, source, job, lang)
@param content: Message to broadcast
@param frequency: Frequency to broadcast to
@param source: The name of the source you wish to imitate. Must be stored in stored_names list.
- @param job: The name of the job.
+ @param job: The name of the job.
*/
interpreter.SetProc("broadcast", "tcombroadcast", signal, list("message", "freq", "source", "job"))
@@ -128,49 +146,12 @@
*/
interpreter.SetProc("mem", "mem", signal, list("address", "value"))
- /*
- -> Delay code for a given amount of deciseconds
- @format: sleep(time)
-
- @param time: time to sleep in deciseconds (1/10th second)
- */
- interpreter.SetProc("sleep", /proc/delay)
/*
- -> Replaces a string with another string
- @format: replace(string, substring, replacestring)
-
- @param string: the string to search for substrings (best used with $content$ constant)
- @param substring: the substring to search for
- @param replacestring: the string to replace the substring with
-
+ General NTSL procs
+ Should probably be moved to its own place
*/
- interpreter.SetProc("replace", /proc/string_replacetext)
-
- /*
- -> Locates an element/substring inside of a list or string
- @format: find(haystack, needle, start = 1, end = 0)
-
- @param haystack: the container to search
- @param needle: the element to search for
- @param start: the position to start in
- @param end: the position to end in
-
- */
- interpreter.SetProc("find", /proc/smartfind)
-
- /*
- -> Finds the length of a string or list
- @format: length(container)
-
- @param container: the list or container to measure
-
- */
- interpreter.SetProc("length", /proc/smartlength)
-
- /* -- Clone functions, carried from default BYOND procs --- */
-
- // vector namespace
+ // Vector
interpreter.SetProc("vector", /proc/n_list)
interpreter.SetProc("at", /proc/n_listpos)
interpreter.SetProc("copy", /proc/n_listcopy)
@@ -179,19 +160,22 @@
interpreter.SetProc("cut", /proc/n_listcut)
interpreter.SetProc("swap", /proc/n_listswap)
interpreter.SetProc("insert", /proc/n_listinsert)
-
interpreter.SetProc("pick", /proc/n_pick)
- interpreter.SetProc("prob", /proc/prob_chance)
- interpreter.SetProc("substr", /proc/docopytext)
+ interpreter.SetProc("prob", /proc/n_prob)
+ interpreter.SetProc("substr", /proc/n_substr)
+ interpreter.SetProc("find", /proc/n_smartfind)
+ interpreter.SetProc("length", /proc/n_smartlength)
- // Donkie~
// Strings
interpreter.SetProc("lower", /proc/n_lower)
interpreter.SetProc("upper", /proc/n_upper)
- interpreter.SetProc("explode", /proc/string_explode)
+ interpreter.SetProc("explode", /proc/n_explode)
+ interpreter.SetProc("implode", /proc/n_implode)
interpreter.SetProc("repeat", /proc/n_repeat)
interpreter.SetProc("reverse", /proc/n_reverse)
interpreter.SetProc("tonum", /proc/n_str2num)
+ interpreter.SetProc("replace", /proc/n_replace)
+ interpreter.SetProc("proper", /proc/n_proper)
// Numbers
interpreter.SetProc("tostring", /proc/n_num2str)
@@ -202,11 +186,14 @@
interpreter.SetProc("round", /proc/n_round)
interpreter.SetProc("clamp", /proc/n_clamp)
interpreter.SetProc("inrange", /proc/n_inrange)
- interpreter.SetProc("rand", /proc/rand_chance)
- // End of Donkie~
+ interpreter.SetProc("rand", /proc/n_rand)
+ interpreter.SetProc("randseed", /proc/n_randseed)
+ interpreter.SetProc("min", /proc/n_min)
+ interpreter.SetProc("max", /proc/n_max)
// Time
- interpreter.SetProc("time", /proc/time)
+ interpreter.SetProc("time", /proc/n_time)
+ interpreter.SetProc("sleep", /proc/n_delay)
interpreter.SetProc("timestamp", /proc/gameTimestamp)
// Run the compiled code
@@ -301,10 +288,10 @@ datum/signal
if(!job)
job = "Unknown"
-
+
//SAY REWRITE RELATED CODE.
//This code is a little hacky, but it *should* work. Even though it'll result in a virtual speaker referencing another virtual speaker. vOv
- var/atom/movable/virtualspeaker/virt = new(null)
+ var/atom/movable/virtualspeaker/virt = PoolOrNew(/atom/movable/virtualspeaker,null)
virt.name = source
virt.job = job
virt.faketrack = 1
diff --git a/code/modules/scripting/Implementations/_Logic.dm b/code/modules/scripting/Implementations/_Logic.dm
index 871ffd1905f..343adf34d43 100644
--- a/code/modules/scripting/Implementations/_Logic.dm
+++ b/code/modules/scripting/Implementations/_Logic.dm
@@ -1,15 +1,17 @@
// Script -> BYOND code procs
#define SCRIPT_MAX_REPLACEMENTS_ALLOWED 200
+
+
// --- List operations (lists known as vectors in n_script) ---
-// Clone of list()
+// Creates a list out of all the arguments
/proc/n_list()
var/list/returnlist = list()
for(var/e in args)
returnlist.Add(e)
return returnlist
-// Clone of pick()
+// Picks one random item from the list
/proc/n_pick()
var/list/finalpick = list()
for(var/e in args)
@@ -23,7 +25,7 @@
return pick(finalpick)
-// Clone of list[]
+// Gets/Sets a value at a key in the list
/proc/n_listpos(var/list/L, var/pos, var/value)
if(!istype(L, /list)) return
if(isnum(pos))
@@ -39,12 +41,12 @@
else
L[pos] = value
-// Clone of list.Copy()
+// Copies the list into a new one
/proc/n_listcopy(var/list/L, var/start, var/end)
if(!istype(L, /list)) return
return L.Copy(start, end)
-// Clone of list.Add()
+// Adds arg 2,3,4,5... to the end of list at arg 1
/proc/n_listadd()
var/list/chosenlist
var/i = 1
@@ -58,7 +60,7 @@
if(chosenlist)
chosenlist.Add(e)
-// Clone of list.Remove()
+// Removes arg 2,3,4,5... from list at arg 1
/proc/n_listremove()
var/list/chosenlist
var/i = 1
@@ -72,38 +74,26 @@
if(chosenlist)
chosenlist.Remove(e)
-// Clone of list.Cut()
+// Cuts out a copy of a list
/proc/n_listcut(var/list/L, var/start, var/end)
if(!istype(L, /list)) return
return L.Cut(start, end)
-// Clone of list.Swap()
+// Swaps two values in the list
/proc/n_listswap(var/list/L, var/firstindex, var/secondindex)
if(!istype(L, /list)) return
if(L.len >= secondindex && L.len >= firstindex)
return L.Swap(firstindex, secondindex)
-// Clone of list.Insert()
+// Inserts a value into the list
/proc/n_listinsert(var/list/L, var/index, var/element)
if(!istype(L, /list)) return
return L.Insert(index, element)
-// --- Miscellaneous functions ---
+// --- String methods ---
-// Clone of sleep()
-/proc/delay(var/time)
- sleep(time)
-
-// Clone of rand()
-/proc/rand_chance(var/low = 0, var/high)
- return rand(low, high)
-
-// Clone of prob()
-/proc/prob_chance(var/chance)
- return prob(chance)
-
-// Merge of list.Find() and findtext()
-/proc/smartfind(var/haystack, var/needle, var/start = 1, var/end = 0)
+//If list, finds a value in it, if text, finds a substring in it
+/proc/n_smartfind(var/haystack, var/needle, var/start = 1, var/end = 0)
if(haystack && needle)
if(isobject(haystack))
if(istype(haystack, /list))
@@ -116,70 +106,41 @@
if(length(haystack) >= end && start > 0)
return findtext(haystack, needle, start, end)
-// Clone of copytext()
-/proc/docopytext(var/string, var/start = 1, var/end = 0)
+//Returns a substring of the string
+/proc/n_substr(var/string, var/start = 1, var/end = 0)
if(istext(string) && isnum(start) && isnum(end))
if(start > 0)
return copytext(string, start, end)
-// Clone of length()
-/proc/smartlength(var/container)
+//Returns the length of the string or list
+/proc/n_smartlength(var/container)
if(container)
if(istype(container, /list) || istext(container))
return length(container)
return 0
-// BY DONKIE~
-// String stuff
+//Lowercase all characters
/proc/n_lower(var/string)
if(istext(string))
return lowertext(string)
+//Uppercase all characters
/proc/n_upper(var/string)
if(istext(string))
return uppertext(string)
-/proc/time()
- return world.timeofday
-
-/*
-//Makes a list where all indicies in a string is a seperate index in the list
-// JUST A HELPER DON'T ADD TO NTSCRIPT
-proc/string_tolist(var/string)
- var/list/L = new/list()
-
- var/i
- for(i=1, i<=lentext(string), i++)
- L.Add(copytext(string, i, i))
-
- return L
-
-proc/string_explode(var/string, var/separator)
- if(istext(string))
- if(istext(separator) && separator == "")
- return string_tolist(string)
- var/i
- var/lasti = 1
- var/list/L = new/list()
-
- for(i=1, i<=lentext(string)+1, i++)
- if(copytext(string, i, i+1) == separator) // We found a separator
- L.Add(copytext(string, lasti, i))
- lasti = i+1
-
- L.Add(copytext(string, lasti, lentext(string)+1)) // Adds the last segment
-
- return L
-
-Just found out there was already a string explode function, did some benchmarking, and that function were a bit faster, sticking to that.
-*/
-
-
-proc/string_explode(var/string, var/separator = "")
+//Converts a string to a list
+/proc/n_explode(var/string, var/separator = "")
if(istext(string) && (istext(separator) || isnull(separator)))
return text2list(string, separator)
-proc/n_repeat(var/string, var/amount)
+//Converts a list to a string
+/proc/n_implode(var/list/li, var/separator)
+ if(istype(li) && (istext(separator) || isnull(separator)))
+ return list2text(li, separator)
+
+//Repeats the string x times
+/proc/n_repeat(var/string, var/amount)
if(istext(string) && isnum(amount))
var/i
var/newstring = ""
@@ -192,7 +153,8 @@ proc/n_repeat(var/string, var/amount)
return newstring
-proc/n_reverse(var/string)
+//Reverses the order of the string. "Clown" becomes "nwolC"
+/proc/n_reverse(var/string)
if(istext(string))
var/newstring = ""
var/i
@@ -203,45 +165,91 @@ proc/n_reverse(var/string)
return newstring
-// I don't know if it's neccesary to make my own proc, but I think I have to to be able to check for istext.
-proc/n_str2num(var/string)
+// String -> Number
+/proc/n_str2num(var/string)
if(istext(string))
return text2num(string)
-// Number shit
-proc/n_num2str(var/num)
+/proc/n_proper(var/string)
+ if(!istext(string))
+ return ""
+
+ return text("[][]", uppertext(copytext(string, 1, 2)), lowertext(copytext(string, 2)))
+
+// --- Number methods ---
+
+//Returns the highest value of the arguments
+//Need custom functions here cause byond's min and max runtimes if you give them a string or list.
+/proc/n_max()
+ if(args.len == 0)
+ return 0
+
+ var/max = args[1]
+ for(var/e in args)
+ if(isnum(e) && e > max)
+ max = e
+
+ return max
+
+//Returns the lowest value of the arguments
+/proc/n_min()
+ if(args.len == 0)
+ return 0
+
+ var/min = args[1]
+ for(var/e in args)
+ if(isnum(e) && e < min)
+ min = e
+
+ return min
+
+/proc/n_prob(var/chance)
+ return prob(chance)
+
+/proc/n_randseed(var/seed)
+ rand_seed(seed)
+ return 0
+
+/proc/n_rand(var/low, var/high)
+ if(isnull(low) && isnull(high))
+ return rand()
+
+ return rand(low, high)
+
+// Number -> String
+/proc/n_num2str(var/num)
if(isnum(num))
return num2text(num)
// Squareroot
-proc/n_sqrt(var/num)
+/proc/n_sqrt(var/num)
if(isnum(num))
return sqrt(num)
// Magnitude of num
-proc/n_abs(var/num)
+/proc/n_abs(var/num)
if(isnum(num))
return abs(num)
// Round down
-proc/n_floor(var/num)
+/proc/n_floor(var/num)
if(isnum(num))
return round(num)
// Round up
-proc/n_ceil(var/num)
+/proc/n_ceil(var/num)
if(isnum(num))
return round(num)+1
// Round to nearest integer
-proc/n_round(var/num)
+/proc/n_round(var/num)
if(isnum(num))
if(num-round(num)<0.5)
return round(num)
return n_ceil(num)
// Clamps N between min and max
-proc/n_clamp(var/num, var/min=-1, var/max=1)
+/proc/n_clamp(var/num, var/min=-1, var/max=1)
if(isnum(num)&&isnum(min)&&isnum(max))
if(num<=min)
return min
@@ -250,59 +258,12 @@ proc/n_clamp(var/num, var/min=-1, var/max=1)
return num
// Returns 1 if N is inbetween Min and Max
-proc/n_inrange(var/num, var/min=-1, var/max=1)
+/proc/n_inrange(var/num, var/min=-1, var/max=1)
if(isnum(num)&&isnum(min)&&isnum(max))
return ((min <= num) && (num <= max))
-// END OF BY DONKIE :(
-// Non-recursive
-// Imported from Mono string.ReplaceUnchecked
-/*
-/proc/string_replacetext(var/haystack,var/a,var/b)
- if(istext(haystack)&&istext(a)&&istext(b))
- var/i = 1
- var/lenh=lentext(haystack)
- var/lena=lentext(a)
- //var/lenb=lentext(b)
- var/count = 0
- var/list/dat = list()
- while (i < lenh)
- var/found = findtext(haystack, a, i, 0)
- //diary << "findtext([haystack], [a], [i], 0)=[found]"
- if (found == 0) // Not found
- break
- else
- if (count < SCRIPT_MAX_REPLACEMENTS_ALLOWED)
- dat+=found
- count+=1
- else
- //diary << "Script found [a] [count] times, aborted"
- break
- //diary << "Found [a] at [found]! Moving up..."
- i = found + lena
- if (count == 0)
- return haystack
- //var/nlen = lenh + ((lenb - lena) * count)
- var/buf = copytext(haystack,1,dat[1]) // Prefill
- var/lastReadPos = 0
- for (i = 1, i <= count, i++)
- var/precopy = dat[i] - lastReadPos-1
- //internal static unsafe void CharCopy (String target, int targetIndex, String source, int sourceIndex, int count)
- //fixed (char* dest = target, src = source)
- //CharCopy (dest + targetIndex, src + sourceIndex, count);
- //CharCopy (dest + curPos, source + lastReadPos, precopy);
- buf+=copytext(haystack,lastReadPos,precopy)
- diary << "buf+=copytext([haystack],[lastReadPos],[precopy])"
- diary<<"[buf]"
- lastReadPos = dat[i] + lena
- //CharCopy (dest + curPos, replace, newValue.length);
- buf+=b
- diary<<"[buf]"
- buf+=copytext(haystack,lastReadPos, 0)
- return buf
-*/
-
-/proc/string_replacetext(text, find, replacement)
+// Replace text
+/proc/n_replace(text, find, replacement)
if(istext(text) && istext(find) && istext(replacement))
var/find_len = length(find)
if(find_len < 1) return text
@@ -321,4 +282,13 @@ proc/n_inrange(var/num, var/min=-1, var/max=1)
continue
return
-#undef SCRIPT_MAX_REPLACEMENTS_ALLOWED
\ No newline at end of file
+#undef SCRIPT_MAX_REPLACEMENTS_ALLOWED
+
+// --- Miscellaneous functions ---
+
+/proc/n_time()
+ return world.timeofday
+
+// Clone of sleep()
+/proc/n_delay(var/time)
+ sleep(time)
diff --git a/code/modules/security levels/keycard authentication.dm b/code/modules/security levels/keycard authentication.dm
index 2d8578d0e39..9920edec6ab 100644
--- a/code/modules/security levels/keycard authentication.dm
+++ b/code/modules/security levels/keycard authentication.dm
@@ -150,7 +150,7 @@
for(var/obj/machinery/door/airlock/D in A)
D.emergency = 1
D.update_icon(0)
- minor_announce("Access restrictions on maintenance and external airlocks have been lifted.", "Attention! Station-wide emergency declared!")
+ minor_announce("Access restrictions on maintenance and external airlocks have been lifted.", "Attention! Station-wide emergency declared!",1)
emergency_access = 1
/proc/revoke_maint_all_access()
diff --git a/code/modules/security levels/security levels.dm b/code/modules/security levels/security levels.dm
index e33370e7fb6..70370f6effc 100644
--- a/code/modules/security levels/security levels.dm
+++ b/code/modules/security levels/security levels.dm
@@ -25,21 +25,19 @@
security_level = SEC_LEVEL_GREEN
for(var/obj/machinery/firealarm/FA in world)
if(FA.z == 1)
- FA.overlays = list()
- FA.overlays += image('icons/obj/monitors.dmi', "overlay_green")
+ FA.update_icon()
if(SEC_LEVEL_BLUE)
if(security_level < SEC_LEVEL_BLUE)
- minor_announce(config.alert_desc_blue_upto, "Attention! Security level elevated to blue:")
+ minor_announce(config.alert_desc_blue_upto, "Attention! Security level elevated to blue:",1)
else
minor_announce(config.alert_desc_blue_downto, "Attention! Security level lowered to blue:")
security_level = SEC_LEVEL_BLUE
for(var/obj/machinery/firealarm/FA in world)
if(FA.z == 1)
- FA.overlays = list()
- FA.overlays += image('icons/obj/monitors.dmi', "overlay_blue")
+ FA.update_icon()
if(SEC_LEVEL_RED)
if(security_level < SEC_LEVEL_RED)
- minor_announce(config.alert_desc_red_upto, "Attention! Code red!")
+ minor_announce(config.alert_desc_red_upto, "Attention! Code red!",1)
else
minor_announce(config.alert_desc_red_downto, "Attention! Code red!")
security_level = SEC_LEVEL_RED
@@ -51,15 +49,13 @@
for(var/obj/machinery/firealarm/FA in world)
if(FA.z == 1)
- FA.overlays = list()
- FA.overlays += image('icons/obj/monitors.dmi', "overlay_red")
+ FA.update_icon()
if(SEC_LEVEL_DELTA)
- minor_announce(config.alert_desc_delta, "Attention! Delta security level reached!")
+ minor_announce(config.alert_desc_delta, "Attention! Delta security level reached!",1)
security_level = SEC_LEVEL_DELTA
for(var/obj/machinery/firealarm/FA in world)
if(FA.z == 1)
- FA.overlays = list()
- FA.overlays += image('icons/obj/monitors.dmi', "overlay_delta")
+ FA.update_icon()
else
return
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index fd8c3a3e653..ec2b434dc78 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -112,8 +112,8 @@ datum/shuttle_manager/proc/move_shuttle(var/override_delay)
if(cooldown)
return
cooldown = 1
- usr << "Docking locks are engaged. Sending request to leave..."
+ usr << "Docking locks are engaged. Requesting authorization..."
var/datum/shuttle_manager/s = shuttles["ferry"]
- admins << "FERRY: [key_name(usr)] (?) (Move) is requesting to move the transport ferry to [s.location == /area/shuttle/transport1/centcom ? "the station" : "Centcom"]."
+ admins << "FERRY: [key_name(usr)] (?) (JMP) (Move) is requesting to move the transport ferry to [s.location == /area/shuttle/transport1/centcom ? "the station" : "Centcom"]."
spawn(600) //One minute cooldown
cooldown = 0
\ No newline at end of file
diff --git a/code/modules/surgery/limb augmentation.dm b/code/modules/surgery/limb augmentation.dm
index 2fc12830566..f9a26f9f49a 100644
--- a/code/modules/surgery/limb augmentation.dm
+++ b/code/modules/surgery/limb augmentation.dm
@@ -46,10 +46,10 @@
if(L)
if(ishuman(target))
var/mob/living/carbon/human/H = target
- user.visible_message("[user] successfully augments [target]'s [parse_zone(user.zone_sel.selecting)]!")
+ user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!")
L.loc = get_turf(target)
H.organs -= L
- switch(user.zone_sel.selecting) //for the surgery to progress this MUST still be the original "location" so it's safe to do this.
+ switch(target_zone)
if("r_leg")
H.organs += new /obj/item/organ/limb/robot/r_leg(src)
if("l_leg")
@@ -70,7 +70,7 @@
qdel(tool)
H.update_damage_overlays(0)
H.update_augments() //Gives them the Cyber limb overlay
- add_logs(user, target, "augmented", addition="by giving him new [parse_zone(user.zone_sel.selecting)] INTENT: [uppertext(user.a_intent)]")
+ add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]")
else
- user.visible_message("[user] [target] has no organic [parse_zone(user.zone_sel.selecting)] there!")
+ user.visible_message("[user] [target] has no organic [parse_zone(target_zone)] there!")
return 1
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index 4ceed4b0d5e..07140e8596d 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -29,7 +29,7 @@
initiate(user, target, target_zone, tool, surgery)
return 1
else
- user << "You need to expose [target]'s [target_zone] to perform surgery on it!"
+ user << "You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!"
return 1 //returns 1 so we don't stab the guy in the dick or wherever.
return 0
@@ -77,7 +77,7 @@
if(ishuman(target))
var/mob/living/carbon/human/H = target
H.apply_damage(75,"brute","[target_zone]")
- user.visible_message("[user] saws [target]'s [target_zone] open!")
+ user.visible_message("[user] saws [target]'s [parse_zone(target_zone)] open!")
return 1
/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/unused/mining/datum_processing_recipe.dm b/code/unused/mining/datum_processing_recipe.dm
index 0a1f5e1eda0..f44516f2c80 100644
--- a/code/unused/mining/datum_processing_recipe.dm
+++ b/code/unused/mining/datum_processing_recipe.dm
@@ -19,5 +19,5 @@ var/list/datum/material_recipe/MATERIAL_RECIPES = list(
new/datum/material_recipe("Silver",list(/obj/item/weapon/ore/silver),/obj/item/stack/sheet/mineral/silver),
new/datum/material_recipe("Diamond",list(/obj/item/weapon/ore/diamond),/obj/item/stack/sheet/mineral/diamond),
new/datum/material_recipe("Plasma",list(/obj/item/weapon/ore/plasma),/obj/item/stack/sheet/mineral/plasma),
- new/datum/material_recipe("Bananium",list(/obj/item/weapon/ore/clown),/obj/item/stack/sheet/mineral/clown),
+ new/datum/material_recipe("Bananium",list(/obj/item/weapon/ore/bananium),/obj/item/stack/sheet/mineral/bananium),
)
\ No newline at end of file
diff --git a/code/unused/mining/machine_craftlathe_unused.dm b/code/unused/mining/machine_craftlathe_unused.dm
index dc4ca5b3af0..29ddbc26576 100644
--- a/code/unused/mining/machine_craftlathe_unused.dm
+++ b/code/unused/mining/machine_craftlathe_unused.dm
@@ -176,7 +176,7 @@ proc/check_craftlathe_recipe(var/list/param_recipe)
CRAFT_ITEMS += new/datum/craftlathe_item("DIAMOND","Diamond",1,1,list("","","","","","","","",""),/obj/item/stack/sheet/mineral/diamond)
CRAFT_ITEMS += new/datum/craftlathe_item("PLASMA","Plasma",1,1,list("","","","","","","","",""),/obj/item/stack/sheet/mineral/plasma)
CRAFT_ITEMS += new/datum/craftlathe_item("URANIUM","Uranium",1,1,list("","","","","","","","",""),/obj/item/weapon/ore/mineral/uranium)
- CRAFT_ITEMS += new/datum/craftlathe_item("CLOWN","Bananium",1,1,list("","","","","","","","",""),/obj/item/stack/sheet/mineral/clown)
+ CRAFT_ITEMS += new/datum/craftlathe_item("CLOWN","Bananium",1,1,list("","","","","","","","",""),/obj/item/stack/sheet/mineral/bananium)
CRAFT_ITEMS += new/datum/craftlathe_item("ADMAMANTINE","Adamantine",1,1,list("","","","","","","","",""),/obj/item/stack/sheet/mineral/adamantine)
CRAFT_ITEMS += new/datum/craftlathe_item("SCREWS","Screws",9,9,list("","","","","METAL","","","METAL",""))
CRAFT_ITEMS += new/datum/craftlathe_item("COGS","Cogs",9,9,list("","METAL","","METAL","METAL","METAL","","METAL",""))
diff --git a/code/unused/specops.dm b/code/unused/specops.dm
index bc620d37421..5843b1e9771 100644
--- a/code/unused/specops.dm
+++ b/code/unused/specops.dm
@@ -145,7 +145,7 @@ var/global/sent_strike_team = 0
equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack)
if (!leader_selected)
- equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_in_backpack)
+ equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_in_backpack)
else
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/disk/nuclear(src), slot_in_backpack)
diff --git a/code/world.dm b/code/world.dm
index 0e61d58db15..9d52ffe0c05 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -54,8 +54,6 @@
timezoneOffset = text2num(time2text(0,"hh")) * 36000
- makepowernets()
-
sun = new /datum/sun()
radio_controller = new /datum/controller/radio()
data_core = new /obj/effect/datacore()
@@ -79,6 +77,13 @@
slmaster.layer = FLY_LAYER
slmaster.mouse_opacity = 0
+ for(var/i=0, i
+
+
01 October 2014
+
Cheridan updated:
+
+
Experienced smugglers have joined the Syndicate, adding their bag of tricks to its arsenal. These tricky pouches can even fit under floor plating!
+
+
Ikarrus updated:
+
+
Adds Gang War, a new game mode still in alpha development.
+
+
Incoming5643 updated:
+
+
After a public relations nightmare in which a horde of 30 assistants violently dismembered a sole commander the revolution has begin tactically reducing their initial presence in stations with weak command structures. Should stations add to their command staff during the shift additional support will be provided.
+
Too many instances of crying CMOs hiding in the lockers of supposedly secured revoulutionary stations has lead to a crackdown on revolutionary policy. You must kill or maroon the entire command staff, reguardless of when they reached the station.
+
Intense study into the underlying structure of the universe has revealed that everything fits into a massive SPACECUBE. This deep and profound understanding has led to a revolution in cross surface movement, and spacemen can look forward to a new era of predictable and safe space-fairing.
+
+
Jordie0608 updated:
+
+
Grille damage update, humans now deal less unarmed damage to grilles while projectiles and items deal more.
+
Replaced all AI turrets with porta-turrets that work on LoS instead of area and can be individually configured
+
+
Miauw updated:
+
+
Voice changer masks work again.
+
You can now turn voice changer masks on/off by activating them in your hand. They start off.
+
The amount of TC has been increased to 20, but the price of all items has been doubled as well
+
With this, the prices of stealthy items has been slightly decreased and the prices of offensive items slightly increased (+/- 1 TC)
+
+
RemieRichards, JJRcop updated:
+
+
New research in the area of robotics has been published on Maintenance Drones, little robots capable of repairing and improving the station. Unfortunately, all of the research was lost in a catastrophic server fire, but we know they can be made, so it's up to you to re-discover them! Make us proud!
+
+
phil235 updated:
+
+
Changed all clone damage descriptions to use the term cellular damage to avoid confusion with genetics mutations.
+
+
+
07 September 2014
Gun Hog updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 7d36875e07d..b2115517dcd 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -1845,3 +1845,43 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
\ the line ENFORCE_HUMAN_AUTHORITY in game_options.txt.\n\t\t
Players: To check if this config option is enabled on your server, type show-server-revision\
\ into the game's command line.\n\t
"
+2014-10-01:
+ Cheridan:
+ - rscadd: Experienced smugglers have joined the Syndicate, adding their bag of tricks
+ to its arsenal. These tricky pouches can even fit under floor plating!
+ Ikarrus:
+ - wip: Adds Gang War, a new game mode still in alpha development.
+ Incoming5643:
+ - tweak: After a public relations nightmare in which a horde of 30 assistants violently
+ dismembered a sole commander the revolution has begin tactically reducing their
+ initial presence in stations with weak command structures. Should stations add
+ to their command staff during the shift additional support will be provided.
+ - tweak: Too many instances of crying CMOs hiding in the lockers of supposedly secured
+ revoulutionary stations has lead to a crackdown on revolutionary policy. You
+ must kill or maroon the entire command staff, reguardless of when they reached
+ the station.
+ - rscadd: Intense study into the underlying structure of the universe has revealed
+ that everything fits into a massive SPACECUBE. This deep and profound understanding
+ has led to a revolution in cross surface movement, and spacemen can look forward
+ to a new era of predictable and safe space-fairing.
+ Jordie0608:
+ - tweak: Grille damage update, humans now deal less unarmed damage to grilles while
+ projectiles and items deal more.
+ - tweak: Replaced all AI turrets with porta-turrets that work on LoS instead of
+ area and can be individually configured
+ Miauw:
+ - bugfix: Voice changer masks work again.
+ - tweak: You can now turn voice changer masks on/off by activating them in your
+ hand. They start off.
+ - experiment: The amount of TC has been increased to 20, but the price of all items
+ has been doubled as well
+ - experiment: With this, the prices of stealthy items has been slightly decreased
+ and the prices of offensive items slightly increased (+/- 1 TC)
+ RemieRichards, JJRcop:
+ - rscadd: New research in the area of robotics has been published on Maintenance
+ Drones, little robots capable of repairing and improving the station. Unfortunately,
+ all of the research was lost in a catastrophic server fire, but we know they
+ can be made, so it's up to you to re-discover them! Make us proud!
+ phil235:
+ - experiment: Changed all clone damage descriptions to use the term cellular damage
+ to avoid confusion with genetics mutations.
diff --git a/html/changelogs/Cheridan.yml b/html/changelogs/Cheridan.yml
new file mode 100644
index 00000000000..d26cc7b9ac2
--- /dev/null
+++ b/html/changelogs/Cheridan.yml
@@ -0,0 +1,2 @@
+author: Cheridan
+changes: []
diff --git a/html/changelogs/Ikarrus-PR-5016.yml b/html/changelogs/Ikarrus-PR-5016.yml
new file mode 100644
index 00000000000..665205231cc
--- /dev/null
+++ b/html/changelogs/Ikarrus-PR-5016.yml
@@ -0,0 +1,6 @@
+author: Ikarrus
+
+delete-after: True
+
+changes:
+ - bugfix: Character Save Files will now remember Species.
\ No newline at end of file
diff --git a/html/changelogs/Ikarrus.yml b/html/changelogs/Ikarrus.yml
new file mode 100644
index 00000000000..b963a50a53d
--- /dev/null
+++ b/html/changelogs/Ikarrus.yml
@@ -0,0 +1,2 @@
+author: Ikarrus
+changes: []
diff --git a/html/changelogs/Jordie0608-PR-4849.yml b/html/changelogs/Jordie0608-PR-4849.yml
deleted file mode 100644
index b8728c0aab9..00000000000
--- a/html/changelogs/Jordie0608-PR-4849.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: Jordie0608
-
-delete-after: True
-
-changes:
- - tweak: Replaced all AI turrets with porta-turrets that work on LoS instead of area and can be individually configured
\ No newline at end of file
diff --git a/html/changelogs/Miauw-PR-5071.yml b/html/changelogs/Miauw-PR-5071.yml
new file mode 100644
index 00000000000..f782519d690
--- /dev/null
+++ b/html/changelogs/Miauw-PR-5071.yml
@@ -0,0 +1,7 @@
+#:^]
+author: Miauw
+
+delete-after: True
+
+changes:
+ - soundadd: Added 5 new maintenance ambience tracks, made by Cuboos.
diff --git a/html/changelogs/Nobalm-PR-5049.yml b/html/changelogs/Nobalm-PR-5049.yml
new file mode 100644
index 00000000000..b02f7ea314f
--- /dev/null
+++ b/html/changelogs/Nobalm-PR-5049.yml
@@ -0,0 +1,4 @@
+author: Nobalm
+delete-after: True
+changes:
+ - rscadd: Added examine descriptions to twenty eight objects.
\ No newline at end of file
diff --git a/html/changelogs/Paprka-PR-5036.yml b/html/changelogs/Paprka-PR-5036.yml
new file mode 100644
index 00000000000..4a54e2d15ab
--- /dev/null
+++ b/html/changelogs/Paprka-PR-5036.yml
@@ -0,0 +1,4 @@
+author: Paprika
+delete-after: True
+changes:
+ - experiment: Due to some payroll cuts affecting lower-rank crewmembers on Space Station 13, we fear that uprisings and mutinies might be approaching. To help defend themselves, all heads of staff have been given telescopic batons to subdue attackers should they be assaulted during their shifts.
\ No newline at end of file
diff --git a/html/changelogs/Paprka-PR-5038.yml b/html/changelogs/Paprka-PR-5038.yml
new file mode 100644
index 00000000000..ccb51e2565f
--- /dev/null
+++ b/html/changelogs/Paprka-PR-5038.yml
@@ -0,0 +1,4 @@
+author: Paprika
+delete-after: True
+changes:
+ - bugfix: Toolbelts can now hold pocket fire extinguishers. Atmos technicians spawn with them.
\ No newline at end of file
diff --git a/html/changelogs/Paprka-PR-5041.yml b/html/changelogs/Paprka-PR-5041.yml
new file mode 100644
index 00000000000..a8fc073f924
--- /dev/null
+++ b/html/changelogs/Paprka-PR-5041.yml
@@ -0,0 +1,4 @@
+author: Paprika
+delete-after: True
+changes:
+ - rscadd: Remember those magboots we had our undercover agents steal? Well we've finally reverse engineered them. Not only that, but we gave them a killer paintjob. They will be available in the uplinks of boarding parties we send out to Nanoscum stations.
\ No newline at end of file
diff --git a/html/changelogs/Paprka-PR-5053.yml b/html/changelogs/Paprka-PR-5053.yml
new file mode 100644
index 00000000000..d01d7cb76b2
--- /dev/null
+++ b/html/changelogs/Paprka-PR-5053.yml
@@ -0,0 +1,4 @@
+author: Paprika
+delete-after: True
+changes:
+ - rscadd: Listen up, Marauders! The Syndicate has recently cut back funding into boarding parties. What this means is no more hi-tech fancy energy guns. We've had to roll back to using cheaper, mass-produced automatic shotguns. But in retrospect, could this possibly be a downgrade?
\ No newline at end of file
diff --git a/icons/PSD files/locker_template.psd b/icons/PSD files/locker_template.psd
new file mode 100644
index 00000000000..9e88ad90eda
Binary files /dev/null and b/icons/PSD files/locker_template.psd differ
diff --git a/icons/mecha/mech_construct.dmi b/icons/mecha/mech_construct.dmi
index 4eb606b1aea..bdce08c8022 100644
Binary files a/icons/mecha/mech_construct.dmi and b/icons/mecha/mech_construct.dmi differ
diff --git a/icons/mecha/mech_construction.dmi b/icons/mecha/mech_construction.dmi
index d7f3722c64a..d0a145caff5 100644
Binary files a/icons/mecha/mech_construction.dmi and b/icons/mecha/mech_construction.dmi differ
diff --git a/icons/mecha/mecha.dmi b/icons/mecha/mecha.dmi
index 060554e4d71..772b4fa1513 100644
Binary files a/icons/mecha/mecha.dmi and b/icons/mecha/mecha.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index 5c0f93e93d8..b863ee60107 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/blob.dmi b/icons/mob/blob.dmi
index 6096546dc13..26510107829 100644
Binary files a/icons/mob/blob.dmi and b/icons/mob/blob.dmi differ
diff --git a/icons/mob/drone.dmi b/icons/mob/drone.dmi
new file mode 100644
index 00000000000..b5437a95d89
Binary files /dev/null and b/icons/mob/drone.dmi differ
diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi
index 9683a624847..b55685323e7 100644
Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index f5bfde269cb..e0bf5ed4cb0 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 5530db7dc60..648866f97d7 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi
index 8bbc8d06c3f..0fda9281665 100644
Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ
diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi
index afea8e24f3e..93fca77115c 100644
Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index 28451ff9fc2..2cfaf2b0015 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 5bc9546152e..f4292641d52 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi
index 94ff50ba91a..21b840b0fda 100644
Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ
diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi
index bb4c308ca05..27190678b95 100644
Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index db879f05ce4..e68aa0b2318 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi
index c76b374a7cb..65ed8cb6deb 100644
Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index 985c7403434..61cb06edcfb 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/monitors.dmi b/icons/obj/monitors.dmi
index a817a42648c..0a2edd5dbe3 100644
Binary files a/icons/obj/monitors.dmi and b/icons/obj/monitors.dmi differ
diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi
index 99650ce656c..201a73b0905 100644
Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ
diff --git a/icons/obj/power_cond/power_cond_blue.dmi b/icons/obj/power_cond/power_cond_blue.dmi
index e224fa549c3..5cd500c4f10 100644
Binary files a/icons/obj/power_cond/power_cond_blue.dmi and b/icons/obj/power_cond/power_cond_blue.dmi differ
diff --git a/icons/obj/power_cond/power_cond_cyan.dmi b/icons/obj/power_cond/power_cond_cyan.dmi
index 34d981f55f7..742d1f76eab 100644
Binary files a/icons/obj/power_cond/power_cond_cyan.dmi and b/icons/obj/power_cond/power_cond_cyan.dmi differ
diff --git a/icons/obj/power_cond/power_cond_green.dmi b/icons/obj/power_cond/power_cond_green.dmi
index c8aa279bc29..d7a391d505b 100644
Binary files a/icons/obj/power_cond/power_cond_green.dmi and b/icons/obj/power_cond/power_cond_green.dmi differ
diff --git a/icons/obj/power_cond/power_cond_orange.dmi b/icons/obj/power_cond/power_cond_orange.dmi
index e3c3d0aa8c8..4777ddd6654 100644
Binary files a/icons/obj/power_cond/power_cond_orange.dmi and b/icons/obj/power_cond/power_cond_orange.dmi differ
diff --git a/icons/obj/power_cond/power_cond_pink.dmi b/icons/obj/power_cond/power_cond_pink.dmi
index 931d486e1e2..5ebda7c9899 100644
Binary files a/icons/obj/power_cond/power_cond_pink.dmi and b/icons/obj/power_cond/power_cond_pink.dmi differ
diff --git a/icons/obj/power_cond/power_cond_red.dmi b/icons/obj/power_cond/power_cond_red.dmi
index 962936479ae..ffa8eb2405f 100644
Binary files a/icons/obj/power_cond/power_cond_red.dmi and b/icons/obj/power_cond/power_cond_red.dmi differ
diff --git a/icons/obj/power_cond/power_cond_white.dmi b/icons/obj/power_cond/power_cond_white.dmi
index 9036341ee13..313348dc859 100644
Binary files a/icons/obj/power_cond/power_cond_white.dmi and b/icons/obj/power_cond/power_cond_white.dmi differ
diff --git a/icons/obj/power_cond/power_cond_yellow.dmi b/icons/obj/power_cond/power_cond_yellow.dmi
index 7506cc23857..908e22b7788 100644
Binary files a/icons/obj/power_cond/power_cond_yellow.dmi and b/icons/obj/power_cond/power_cond_yellow.dmi differ
diff --git a/icons/obj/power_cond/power_local.dmi b/icons/obj/power_cond/power_local.dmi
index b2b4373505b..f23a456c177 100644
Binary files a/icons/obj/power_cond/power_local.dmi and b/icons/obj/power_cond/power_local.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 1ae599f3511..b6789863ebc 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi
index f6ac2562c6e..6a6b44c5b1b 100644
Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ
diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi
index 19a83504864..b87ea13bf30 100644
Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ
diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi
index 19ae3bde070..738a6964f27 100644
Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index c72311827d6..3aac66228a6 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ
diff --git a/icons/turf/walls.dmi b/icons/turf/walls.dmi
index fc4c615a4b5..6d65684a300 100644
Binary files a/icons/turf/walls.dmi and b/icons/turf/walls.dmi differ
diff --git a/sound/AI/intercept.ogg b/sound/AI/intercept.ogg
index 040b4e4f8db..3569a07d401 100644
Binary files a/sound/AI/intercept.ogg and b/sound/AI/intercept.ogg differ
diff --git a/sound/ambience/ambimaint1.ogg b/sound/ambience/ambimaint1.ogg
new file mode 100644
index 00000000000..0c18c46af68
Binary files /dev/null and b/sound/ambience/ambimaint1.ogg differ
diff --git a/sound/ambience/ambimaint2.ogg b/sound/ambience/ambimaint2.ogg
new file mode 100644
index 00000000000..655d940cda9
Binary files /dev/null and b/sound/ambience/ambimaint2.ogg differ
diff --git a/sound/ambience/ambimaint3.ogg b/sound/ambience/ambimaint3.ogg
new file mode 100644
index 00000000000..9891916010e
Binary files /dev/null and b/sound/ambience/ambimaint3.ogg differ
diff --git a/sound/ambience/ambimaint4.ogg b/sound/ambience/ambimaint4.ogg
new file mode 100644
index 00000000000..1d01e2016ca
Binary files /dev/null and b/sound/ambience/ambimaint4.ogg differ
diff --git a/sound/ambience/ambimaint5.ogg b/sound/ambience/ambimaint5.ogg
new file mode 100644
index 00000000000..7a065ecbcb3
Binary files /dev/null and b/sound/ambience/ambimaint5.ogg differ
diff --git a/sound/effects/woodhit.ogg b/sound/effects/woodhit.ogg
index ffcb40fa024..00608c84ec9 100644
Binary files a/sound/effects/woodhit.ogg and b/sound/effects/woodhit.ogg differ
diff --git a/sound/misc/notice1.ogg b/sound/misc/notice1.ogg
new file mode 100644
index 00000000000..da6454ce3cf
Binary files /dev/null and b/sound/misc/notice1.ogg differ
diff --git a/sound/weapons/batonextend.ogg b/sound/weapons/batonextend.ogg
new file mode 100644
index 00000000000..ca09831fffc
Binary files /dev/null and b/sound/weapons/batonextend.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 1ac3e68d812..3918643a73c 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -76,6 +76,7 @@
#include "code\_onclick\hud\ai.dm"
#include "code\_onclick\hud\alien.dm"
#include "code\_onclick\hud\alien_larva.dm"
+#include "code\_onclick\hud\drones.dm"
#include "code\_onclick\hud\hud.dm"
#include "code\_onclick\hud\human.dm"
#include "code\_onclick\hud\monkey.dm"
@@ -250,6 +251,7 @@
#include "code\game\gamemodes\blob\overmind.dm"
#include "code\game\gamemodes\blob\powers.dm"
#include "code\game\gamemodes\blob\theblob.dm"
+#include "code\game\gamemodes\blob\blobs\blob_mobs.dm"
#include "code\game\gamemodes\blob\blobs\core.dm"
#include "code\game\gamemodes\blob\blobs\factory.dm"
#include "code\game\gamemodes\blob\blobs\node.dm"
@@ -283,6 +285,7 @@
#include "code\game\gamemodes\cult\runes.dm"
#include "code\game\gamemodes\cult\talisman.dm"
#include "code\game\gamemodes\extended\extended.dm"
+#include "code\game\gamemodes\gang\gang.dm"
#include "code\game\gamemodes\malfunction\Malf_Modules.dm"
#include "code\game\gamemodes\malfunction\malfunction.dm"
#include "code\game\gamemodes\meteor\meteor.dm"
@@ -508,6 +511,7 @@
#include "code\game\objects\items\devices\multitool.dm"
#include "code\game\objects\items\devices\paicard.dm"
#include "code\game\objects\items\devices\powersink.dm"
+#include "code\game\objects\items\devices\recaller.dm"
#include "code\game\objects\items\devices\scanners.dm"
#include "code\game\objects\items\devices\taperecorder.dm"
#include "code\game\objects\items\devices\traitordevices.dm"
@@ -670,6 +674,7 @@
#include "code\game\objects\structures\transit_tubes\station.dm"
#include "code\game\objects\structures\transit_tubes\transit_tube.dm"
#include "code\game\objects\structures\transit_tubes\transit_tube_pod.dm"
+#include "code\game\pooling\atom_pool.dm"
#include "code\game\turfs\simulated.dm"
#include "code\game\turfs\turf.dm"
#include "code\game\turfs\unsimulated.dm"
@@ -1085,6 +1090,7 @@
#include "code\modules\mob\living\simple_animal\friendly\cat.dm"
#include "code\modules\mob\living\simple_animal\friendly\corgi.dm"
#include "code\modules\mob\living\simple_animal\friendly\crab.dm"
+#include "code\modules\mob\living\simple_animal\friendly\drone.dm"
#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm"
#include "code\modules\mob\living\simple_animal\friendly\lizard.dm"
#include "code\modules\mob\living\simple_animal\friendly\mouse.dm"