diff --git a/.github/workflows/autochangelog.yml b/.github/workflows/autochangelog.yml
index 7732426718..7953929ce5 100644
--- a/.github/workflows/autochangelog.yml
+++ b/.github/workflows/autochangelog.yml
@@ -1,6 +1,6 @@
name: Autochangelog
on:
- pull_request:
+ pull_request_target:
types: closed
branches:
- master
@@ -15,6 +15,10 @@ jobs:
if: github.event.pull_request.merged == true
steps:
- uses: /actions/checkout@v2
+ with:
+ ref: master
+ - name: Update repository to master
+ run: git pull "origin" master
- name: Ensure +x on CI directory
run: |
chmod -R +x ./tools/ci
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f6e206bc33..13022f96fd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -41,7 +41,7 @@ jobs:
run: |
sudo dpkg --add-architecture i386
sudo apt update || true
- sudo apt install libc6:i386 libgcc1:i386 libstdc++6:i386 libssl1.0.0:i386 g++-7 g++-7-multilib gcc-multilib zlib1g:i386
+ sudo apt install libc6:i386 libgcc1:i386 libstdc++6:i386 libssl1.0.0:i386 zlib1g:i386
ldd librust_g.so
- name: Unit Tests
run: |
diff --git a/README.md b/README.md
index 77f9127bf4..cbf74b6b30 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
Going to make a Pull Request? Make sure you read the [CONTRIBUTING.md](.github/CONTRIBUTING.md) first!
-CHOMPStation is a fork of the Yawn-wider code branch which is a fork of the VOREStation code branch which is a fork of the Polaris code branch, itself a fork of the Baystation12 code branch, for the game Space Station 13.
+CHOMPStation was a fork of the Yawn-wider code branch which is a fork of the VOREStation code branch which is a fork of the Polaris code branch, itself a fork of the Baystation12 code branch, but we are now since separated from Yawn-wider code, while keeping some of their features, which is a fork of the VOREStation code branch which is a fork of the Polaris code branch, itself a fork of the Baystation12 code branch, for the game Space Station 13.

diff --git a/SQL/DBSchema.sql b/SQL/DBSchema.sql
new file mode 100644
index 0000000000..597873757a
--- /dev/null
+++ b/SQL/DBSchema.sql
@@ -0,0 +1,294 @@
+-- --------------------------------------------------------
+-- Host: localhost
+-- Server version: 10.5.4-MariaDB - mariadb.org binary distribution
+-- Server OS: Win64
+-- HeidiSQL Version: 11.0.0.5919
+-- --------------------------------------------------------
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET NAMES utf8 */;
+/*!50503 SET NAMES utf8mb4 */;
+/*!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' */;
+
+
+-- Dumping database structure for ss13
+CREATE DATABASE IF NOT EXISTS `ss13` /*!40100 DEFAULT CHARACTER SET utf8 */;
+USE `ss13`;
+
+-- Dumping structure for table ss13.death
+CREATE TABLE IF NOT EXISTS `death` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `pod` text DEFAULT NULL COMMENT 'Place of death',
+ `coord` text DEFAULT NULL COMMENT 'X, Y, Z POD',
+ `tod` datetime DEFAULT NULL COMMENT 'Time of death',
+ `job` text DEFAULT NULL,
+ `special` text DEFAULT NULL,
+ `name` text DEFAULT NULL,
+ `byondkey` text NOT NULL,
+ `laname` text DEFAULT NULL COMMENT 'Last attacker name',
+ `lakey` text DEFAULT NULL COMMENT 'Last attacker key',
+ `gender` text DEFAULT NULL,
+ `bruteloss` int(11) DEFAULT NULL,
+ `brainloss` int(11) DEFAULT NULL,
+ `fireloss` int(11) DEFAULT NULL,
+ `oxyloss` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=MyISAM AUTO_INCREMENT=13926 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_admin
+CREATE TABLE IF NOT EXISTS `erro_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,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_admin_log
+CREATE TABLE IF NOT EXISTS `erro_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`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_attacklog
+CREATE TABLE IF NOT EXISTS `erro_attacklog` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `time` datetime DEFAULT NULL,
+ `ckey` varchar(64) DEFAULT NULL,
+ `mob` varchar(128) DEFAULT NULL,
+ `message` varchar(1024) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=886 DEFAULT CHARSET=latin1;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_ban
+CREATE TABLE IF NOT EXISTS `erro_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 DEFAULT NULL,
+ `unbanned` tinyint(1) 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`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=64 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_connection_log
+CREATE TABLE IF NOT EXISTS `erro_connection_log` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `datetime` datetime NOT NULL,
+ `serverip` varchar(64) NOT NULL,
+ `ckey` varchar(64) NOT NULL,
+ `ip` varchar(64) NOT NULL,
+ `computerid` varchar(64) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=12353 DEFAULT CHARSET=latin1;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_dialog
+CREATE TABLE IF NOT EXISTS `erro_dialog` (
+ `mid` int(11) NOT NULL AUTO_INCREMENT,
+ `time` datetime NOT NULL,
+ `ckey` varchar(32) NOT NULL,
+ `mob` varchar(128) DEFAULT NULL,
+ `type` varchar(32) NOT NULL,
+ `message` text NOT NULL,
+ PRIMARY KEY (`mid`)
+) ENGINE=InnoDB AUTO_INCREMENT=3345 DEFAULT CHARSET=latin1;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_feedback
+CREATE TABLE IF NOT EXISTS `erro_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 DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=MyISAM AUTO_INCREMENT=68050 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_player
+CREATE TABLE IF NOT EXISTS `erro_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',
+ `discord_id` varchar(256) DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE KEY `ckey` (`ckey`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=1349 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_poll_option
+CREATE TABLE IF NOT EXISTS `erro_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`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_poll_question
+CREATE TABLE IF NOT EXISTS `erro_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,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_poll_textreply
+CREATE TABLE IF NOT EXISTS `erro_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`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_poll_vote
+CREATE TABLE IF NOT EXISTS `erro_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`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.erro_privacy
+CREATE TABLE IF NOT EXISTS `erro_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`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=763 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.karma
+CREATE TABLE IF NOT EXISTS `karma` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `spendername` text NOT NULL,
+ `spenderkey` text NOT NULL,
+ `receivername` text NOT NULL,
+ `receiverkey` text NOT NULL,
+ `receiverrole` text NOT NULL,
+ `receiverspecial` text NOT NULL,
+ `isnegative` tinyint(1) NOT NULL,
+ `spenderip` text NOT NULL,
+ `time` datetime NOT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=MyISAM AUTO_INCREMENT=943 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.karmatotals
+CREATE TABLE IF NOT EXISTS `karmatotals` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `byondkey` text NOT NULL,
+ `karma` int(11) NOT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=MyISAM AUTO_INCREMENT=244 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.library
+CREATE TABLE IF NOT EXISTS `library` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `author` text NOT NULL,
+ `title` text NOT NULL,
+ `content` text NOT NULL,
+ `category` text NOT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE=MyISAM AUTO_INCREMENT=300 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.population
+CREATE TABLE IF NOT EXISTS `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 AUTO_INCREMENT=3627 DEFAULT CHARSET=latin1;
+
+-- Data exporting was unselected.
+
+-- Dumping structure for table ss13.vr_player_hours
+CREATE TABLE IF NOT EXISTS `vr_player_hours` (
+ `ckey` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
+ `department` varchar(64) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
+ `hours` double NOT NULL,
+ `total_hours` double(22,0) NOT NULL,
+ PRIMARY KEY (`ckey`,`department`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
+
+-- Data exporting was unselected.
+
+/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
+/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
diff --git a/SQL/feedback_schema.sql b/SQL/feedback_schema.sql
deleted file mode 100644
index a107136372..0000000000
--- a/SQL/feedback_schema.sql
+++ /dev/null
@@ -1,130 +0,0 @@
-CREATE TABLE `erro_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',
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
-
-CREATE TABLE `erro_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 ;
-
-CREATE TABLE `erro_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` tinyint(1) 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 ;
-
-CREATE TABLE `erro_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 ;
-
-CREATE TABLE `erro_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',
- `discord_id` varchar(64) DEFAULT NULL,
- PRIMARY KEY (`id`),
- UNIQUE KEY `ckey` (`ckey`),
- KEY `discord_id` (`discord_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
-
-CREATE TABLE `erro_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 ;
-
-CREATE TABLE `erro_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',
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
-
-CREATE TABLE `erro_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 ;
-
-CREATE TABLE `erro_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 ;
-
-CREATE TABLE `erro_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 ;
-
-CREATE TABLE `vr_player_hours` (
- `ckey` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
- `department` varchar(64) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
- `hours` double NOT NULL,
- `total_hours` double NOT NULL DEFAULT '0',
- PRIMARY KEY (`ckey`,`department`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
\ No newline at end of file
diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql
deleted file mode 100644
index b7e2e501ce..0000000000
--- a/SQL/tgstation_schema.sql
+++ /dev/null
@@ -1,100 +0,0 @@
-SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
-SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
-SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
-
-CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
-CREATE SCHEMA IF NOT EXISTS `tgstation` DEFAULT CHARACTER SET latin1 ;
-USE `mydb` ;
-USE `tgstation` ;
-
--- -----------------------------------------------------
--- Table `tgstation`.`death`
--- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `tgstation`.`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 = MyISAM
-AUTO_INCREMENT = 3409
-DEFAULT CHARACTER SET = latin1;
-
-
--- -----------------------------------------------------
--- Table `tgstation`.`karma`
--- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `tgstation`.`karma` (
- `id` INT(11) NOT NULL AUTO_INCREMENT ,
- `spendername` TEXT NOT NULL ,
- `spenderkey` TEXT NOT NULL ,
- `receivername` TEXT NOT NULL ,
- `receiverkey` TEXT NOT NULL ,
- `receiverrole` TEXT NOT NULL ,
- `receiverspecial` TEXT NOT NULL ,
- `isnegative` TINYINT(1) NOT NULL ,
- `spenderip` TEXT NOT NULL ,
- `time` DATETIME NOT NULL ,
- PRIMARY KEY (`id`) )
-ENGINE = MyISAM
-AUTO_INCREMENT = 943
-DEFAULT CHARACTER SET = latin1;
-
-
--- -----------------------------------------------------
--- Table `tgstation`.`karmatotals`
--- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `tgstation`.`karmatotals` (
- `id` INT(11) NOT NULL AUTO_INCREMENT ,
- `byondkey` TEXT NOT NULL ,
- `karma` INT(11) NOT NULL ,
- PRIMARY KEY (`id`) )
-ENGINE = MyISAM
-AUTO_INCREMENT = 244
-DEFAULT CHARACTER SET = latin1;
-
-
--- -----------------------------------------------------
--- Table `tgstation`.`library`
--- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `tgstation`.`library` (
- `id` INT(11) NOT NULL AUTO_INCREMENT ,
- `author` TEXT NOT NULL ,
- `title` TEXT NOT NULL ,
- `content` TEXT NOT NULL ,
- `category` TEXT NOT NULL ,
- PRIMARY KEY (`id`) )
-ENGINE = MyISAM
-AUTO_INCREMENT = 184
-DEFAULT CHARACTER SET = latin1;
-
-
--- -----------------------------------------------------
--- Table `tgstation`.`population`
--- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `tgstation`.`population` (
- `id` INT(11) NOT NULL AUTO_INCREMENT ,
- `playercount` INT(11) NULL DEFAULT NULL ,
- `admincount` INT(11) NULL DEFAULT NULL ,
- `time` DATETIME NOT NULL ,
- PRIMARY KEY (`id`) )
-ENGINE = MyISAM
-AUTO_INCREMENT = 2544
-DEFAULT CHARACTER SET = latin1;
-
-
-
-SET SQL_MODE=@OLD_SQL_MODE;
-SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
-SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
index be7f905a77..a3a368852f 100644
--- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
+++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm
@@ -96,15 +96,6 @@
"You hear a ratchet.")
deconstruct()
-/obj/machinery/atmospherics/omni/can_unwrench()
- var/int_pressure = 0
- for(var/datum/omni_port/P in ports)
- int_pressure += P.air.return_pressure()
- var/datum/gas_mixture/env_air = loc.return_air()
- if((int_pressure - env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
- return 0
- return 1
-
/obj/machinery/atmospherics/omni/attack_hand(user as mob)
if(..())
return
diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm
index 4e9d7fd6ad..a2e15e6890 100644
--- a/code/__defines/_planes+layers.dm
+++ b/code/__defines/_planes+layers.dm
@@ -173,6 +173,5 @@ What is the naming convention for planes or layers?
plane = initial(plane)
layer = initial(layer)
-
// Check if a mob can "logically" see an atom plane
#define MOB_CAN_SEE_PLANE(M, P) (P <= PLANE_WORLD || (P in M.planes_visible))
diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm
index c87b9942df..db1a71c77a 100644
--- a/code/__defines/damage_organs.dm
+++ b/code/__defines/damage_organs.dm
@@ -61,4 +61,8 @@
#define INFECTION_LEVEL_ONE 100
#define INFECTION_LEVEL_TWO 500
#define INFECTION_LEVEL_THREE 1000
-#define INFECTION_LEVEL_MAX 1500
\ No newline at end of file
+#define INFECTION_LEVEL_MAX 1500
+
+#define MODULAR_BODYPART_INVALID 0 // Cannot be detached or reattached.
+#define MODULAR_BODYPART_PROSTHETIC 1 // Can be detached or reattached freely.
+#define MODULAR_BODYPART_CYBERNETIC 2 // Can be detached or reattached to compatible parent organs.
diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm
index 5f67308094..a0eede2f42 100644
--- a/code/__defines/gamemode.dm
+++ b/code/__defines/gamemode.dm
@@ -50,7 +50,7 @@ var/list/be_special_flags = list(
"Wizard" = BE_WIZARD,
"Malf AI" = BE_MALF,
"Revolutionary" = BE_REV,
- "Xenomorph" = BE_ALIEN,
+ "Genaprawn" = BE_ALIEN, //CHOMPedit
"Positronic Brain" = BE_AI,
"Cultist" = BE_CULTIST,
"Renegade" = BE_RENEGADE,
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 69e949e495..2014ce8ccf 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -159,6 +159,14 @@
#define MAT_CHITIN "chitin"
#define MAT_CLOTH "cloth"
#define MAT_SYNCLOTH "syncloth"
+#define MAT_COPPER "copper"
+#define MAT_QUARTZ "quartz"
+#define MAT_TIN "tin"
+#define MAT_VOPAL "void opal"
+#define MAT_ALUMINIUM "aluminium"
+#define MAT_BRONZE "bronze"
+#define MAT_PAINITE "painite"
+#define MAT_BOROSILICATE "borosilicate glass"
#define SHARD_SHARD "shard"
#define SHARD_SHRAPNEL "shrapnel"
@@ -494,3 +502,5 @@ GLOBAL_LIST_INIT(all_volume_channels, list(
#define APPEARANCECHANGER_CHANGED_F_HAIRSTYLE "Facial Hair Style"
#define APPEARANCECHANGER_CHANGED_F_HAIRCOLOR "Facial Hair Color"
#define APPEARANCECHANGER_CHANGED_EYES "Eye Color"
+
+#define GET_DECL(D) (ispath(D, /decl) ? (decls_repository.fetched_decls[D] || decls_repository.get_decl(D)) : null)
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index d166b52fbe..dccd83f557 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -160,12 +160,6 @@
#define FLASH_PROTECTION_MODERATE 1
#define FLASH_PROTECTION_MAJOR 2
-#define ANIMAL_SPAWN_DELAY round(config.respawn_delay / 6)
-#define DRONE_SPAWN_DELAY round(config.respawn_delay / 3)
-
-#define ANIMAL_SPAWN_DELAY round(config.respawn_delay / 6)
-#define DRONE_SPAWN_DELAY round(config.respawn_delay / 3)
-
// Incapacitation flags, used by the mob/proc/incapacitated() proc
#define INCAPACITATION_RESTRAINED 1
#define INCAPACITATION_BUCKLED_PARTIALLY 2
@@ -289,6 +283,7 @@
#define BORG_BRAINTYPE_CYBORG "Cyborg"
#define BORG_BRAINTYPE_POSI "Robot"
#define BORG_BRAINTYPE_DRONE "Drone"
+#define BORG_BRAINTYPE_PLATFORM "Platform"
#define BORG_BRAINTYPE_AI_SHELL "AI Shell"
// 'Regular' species.
@@ -321,13 +316,13 @@
#define SPECIES_VR_SKELETON "Virtual Reality Skeleton"
#define SPECIES_VR_VOX "Virtual Reality Vox"
-// Ayyy IDs.
-#define SPECIES_XENO "Xenomorph"
-#define SPECIES_XENO_DRONE "Xenomorph Drone"
-#define SPECIES_XENO_HUNTER "Xenomorph Hunter"
-#define SPECIES_XENO_SENTINEL "Xenomorph Sentinel"
-#define SPECIES_XENO_QUEEN "Xenomorph Queen"
-
+// Ayyy IDs. CHOMPedit
+#define SPECIES_GENA "Genaprawn"
+#define SPECIES_GENA_DRONE "Genaprawn Drone"
+#define SPECIES_GENA_HUNTER "Genaprawn Hunter"
+#define SPECIES_GENA_SENTINEL "Genaprawn Sentinel"
+#define SPECIES_GENA_QUEEN "Genaprawn Queen"
+//CHOMPedit end
// Misc species. Mostly unused but might as well be complete.
#define SPECIES_SHADOW "Shadow"
#define SPECIES_SKELETON "Skeleton"
diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm
index f6ca0ea565..3239e8fa1a 100644
--- a/code/__defines/species_languages.dm
+++ b/code/__defines/species_languages.dm
@@ -24,6 +24,30 @@
#define EMP_TOX_DMG 0x80 // EMPs inflict toxin damage
#define EMP_OXY_DMG 0x100 // EMPs inflict oxy damage
+// Species allergens
+#define MEAT 0x1 // Skrell won't like this.
+#define FISH 0x2 // Seperate for completion's sake. Still bad for skrell.
+#define FRUIT 0x4 // An apple a day only keeps the doctor away if they're allergic.
+#define VEGETABLE 0x8 // Taters 'n' carrots. Potato allergy is a thing, apparently.
+#define GRAINS 0x10 // Wheat, oats, etc.
+#define BEANS 0x20 // The musical fruit! Includes soy.
+#define SEEDS 0x40 // Hope you don't have a nut allergy.
+#define DAIRY 0x80 // Lactose intolerance, ho! Also bad for skrell.
+#define FUNGI 0x100 // Delicious shrooms.
+#define COFFEE 0x200 // Mostly here for tajara.
+#define GENERIC 0x400 // Catchall for stuff that doesn't fall into the groups above. You shouldn't be allergic to this type, ever.
+#define SUGARS 0x800 // For unathi-like reactions
+#define EGGS 0x1000 // For Skrell eggs allergy
+
+// Allergen reactions
+#define AG_TOX_DMG 0x1 // the classic
+#define AG_OXY_DMG 0x2 // intense airway reactions
+#define AG_EMOTE 0x4 // general emote reactions based on affect type
+#define AG_PAIN 0x8 // short-lived hurt
+#define AG_WEAKEN 0x10 // too weak to move, oof
+#define AG_BLURRY 0x20 // blurred vision!
+#define AG_SLEEPY 0x40 // fatigue/exhaustion
+
// Species spawn flags
#define SPECIES_IS_WHITELISTED 0x1 // Must be whitelisted to play.
#define SPECIES_IS_RESTRICTED 0x2 // Is not a core/normally playable species. (castes, mutantraces)
diff --git a/code/__defines/species_languages_vr.dm b/code/__defines/species_languages_vr.dm
index 8909238db2..78054e6ba8 100644
--- a/code/__defines/species_languages_vr.dm
+++ b/code/__defines/species_languages_vr.dm
@@ -10,6 +10,7 @@
#define LANGUAGE_ENOCHIAN "Enochian"
#define LANGUAGE_VESPINAE "Vespinae"
#define LANGUAGE_SPACER "Spacer"
+#define LANGUAGE_CLOWNISH "Coulrian"
#define LANGUAGE_CHIMPANZEE "Chimpanzee"
#define LANGUAGE_NEAERA "Neaera"
diff --git a/code/__defines/tgs.dm b/code/__defines/tgs.dm
index 279da8b05b..3565238195 100644
--- a/code/__defines/tgs.dm
+++ b/code/__defines/tgs.dm
@@ -1,254 +1,351 @@
-//tgstation-server DMAPI
+// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "5.1.1"
+#define TGS_DMAPI_VERSION "6.0.3"
-//All functions and datums outside this document are subject to change with any version and should not be relied on
+// All functions and datums outside this document are subject to change with any version and should not be relied on.
-//CONFIGURATION
+// CONFIGURATION
-//create this define if you want to do configuration outside of this file
+/// Create this define if you want to do TGS configuration outside of this file.
#ifndef TGS_EXTERNAL_CONFIGURATION
-//Comment this out once you've filled in the below
+// Comment this out once you've filled in the below.
#error TGS API unconfigured
-//Uncomment this if you wish to allow the game to interact with TGS 3
-//This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()()
-#define TGS_V3_API
+// Uncomment this if you wish to allow the game to interact with TGS 3.
+// This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()()
+//#define TGS_V3_API
-//Required interfaces (fill in with your codebase equivalent):
+// Required interfaces (fill in with your codebase equivalent):
-//create a global variable named `Name` and set it to `Value`
+/// Create a global variable named `Name` and set it to `Value`.
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value)
-//Read the value in the global variable `Name`
+/// Read the value in the global variable `Name`.
#define TGS_READ_GLOBAL(Name)
-//Set the value in the global variable `Name` to `Value`
+/// Set the value in the global variable `Name` to `Value`.
#define TGS_WRITE_GLOBAL(Name, Value)
-//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game use of DD -> TGS capabilities
+/// Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game use of DD -> TGS capabilities.
#define TGS_PROTECT_DATUM(Path)
-//Display an announcement `message` from the server to all players
+/// Display an announcement `message` from the server to all players.
#define TGS_WORLD_ANNOUNCE(message)
-//Notify current in-game administrators of a string `event`
+/// Notify current in-game administrators of a string `event`.
#define TGS_NOTIFY_ADMINS(event)
-//Write an info `message` to a server log
+/// Write an info `message` to a server log.
#define TGS_INFO_LOG(message)
-//Write an warning `message` to a server log
+/// Write an warning `message` to a server log.
#define TGS_WARNING_LOG(message)
-//Write an error `message` to a server log
+/// Write an error `message` to a server log.
#define TGS_ERROR_LOG(message)
-//Get the number of connected /clients
+/// Get the number of connected /clients.
#define TGS_CLIENT_COUNT
#endif
-//EVENT CODES
+// EVENT CODES
-#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //Before a reboot mode change, extras parameters are the current and new reboot mode enums
-#define TGS_EVENT_PORT_SWAP -2 //Before a port change is about to happen, extra parameters is new port
-#define TGS_EVENT_INSTANCE_RENAMED -3 //Before the instance is renamed, extra parameter is the new name
-#define TGS_EVENT_WATCHDOG_REATTACH -4 //After the watchdog reattaches to DD, extra parameter is the new /datum/tgs_version of the server
+/// Before a reboot mode change, extras parameters are the current and new reboot mode enums
+#define TGS_EVENT_REBOOT_MODE_CHANGE -1
+/// Before a port change is about to happen, extra parameters is new port
+#define TGS_EVENT_PORT_SWAP -2
+/// Before the instance is renamed, extra parameter is the new name
+#define TGS_EVENT_INSTANCE_RENAMED -3
+/// After the watchdog reattaches to DD, extra parameter is the new [/datum/tgs_version] of the server
+#define TGS_EVENT_WATCHDOG_REATTACH -4
-//See the descriptions for the parameters of these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs
+/// When the repository is reset to its origin reference. Parameters: Reference name, Commit SHA
#define TGS_EVENT_REPO_RESET_ORIGIN 0
+/// When the repository performs a checkout. Parameters: Checkout git object
#define TGS_EVENT_REPO_CHECKOUT 1
+/// When the repository performs a fetch operation. No parameters
#define TGS_EVENT_REPO_FETCH 2
+/// When the repository test merges. Parameters: PR Number, PR Sha, (Nullable) Comment made by TGS user
#define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3
+/// Before the repository makes a sychronize operation. Parameters: Absolute repostiory path
#define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4
+/// Before a BYOND install operation begins. Parameters: [/datum/tgs_version] of the installing BYOND
#define TGS_EVENT_BYOND_INSTALL_START 5
+/// When a BYOND install operation fails. Parameters: Error message
#define TGS_EVENT_BYOND_INSTALL_FAIL 6
+/// When the active BYOND version changes. Parameters: (Nullable) [/datum/tgs_version] of the current BYOND, [/datum/tgs_version] of the new BYOND
#define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7
+/// When the compiler starts running. Parameters: Game directory path, origin commit SHA
#define TGS_EVENT_COMPILE_START 8
+/// When a compile is cancelled. No parameters
#define TGS_EVENT_COMPILE_CANCELLED 9
+/// When a compile fails. Parameters: Game directory path, [TRUE]/[FALSE] based on if the cause for failure was DMAPI validation
#define TGS_EVENT_COMPILE_FAILURE 10
-#define TGS_EVENT_COMPILE_COMPLETE 11 // Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the TGS_EVENT_DEPLOYMENT_COMPLETE instead
+/// When a compile operation completes. Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the [TGS_EVENT_DEPLOYMENT_COMPLETE] instead. Parameters: Game directory path
+#define TGS_EVENT_COMPILE_COMPLETE 11
+/// When an automatic update for the current instance begins. No parameters
#define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12
+/// When the repository encounters a merge conflict: Parameters: Base SHA, target SHA, base reference, target reference
#define TGS_EVENT_REPO_MERGE_CONFLICT 13
+/// When a deployment completes. No Parameters
#define TGS_EVENT_DEPLOYMENT_COMPLETE 14
+/// Before the watchdog shuts down. Not sent for graceful shutdowns. No parameters.
#define TGS_EVENT_WATCHDOG_SHUTDOWN 15
+/// Before the watchdog detaches for a TGS update/restart. No parameters.
#define TGS_EVENT_WATCHDOG_DETACH 16
+// We don't actually implement these 4 events as the DMAPI can never receive them.
+// #define TGS_EVENT_WATCHDOG_LAUNCH 17
+// #define TGS_EVENT_WATCHDOG_CRASH 18
+// #define TGS_EVENT_WORLD_END_PROCESS 19
+// #define TGS_EVENT_WORLD_REBOOT 20
+/// Watchdog event when TgsInitializationComplete() is called. No parameters.
+#define TGS_EVENT_WORLD_PRIME 21
-//OTHER ENUMS
+// OTHER ENUMS
+/// The server will reboot normally.
#define TGS_REBOOT_MODE_NORMAL 0
+/// The server will stop running on reboot.
#define TGS_REBOOT_MODE_SHUTDOWN 1
+/// The watchdog will restart on reboot.
#define TGS_REBOOT_MODE_RESTART 2
+/// DreamDaemon Trusted security level.
#define TGS_SECURITY_TRUSTED 0
+/// DreamDaemon Safe security level.
#define TGS_SECURITY_SAFE 1
+/// DreamDaemon Ultrasafe security level.
#define TGS_SECURITY_ULTRASAFE 2
//REQUIRED HOOKS
-//Call this somewhere in /world/New() that is always run
-//IMPORTANT: This function may sleep!
-//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels
-//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated
+/**
+ * Call this somewhere in [/world/proc/New] that is always run. This function may sleep!
+ *
+ * * event_handler - Optional user defined [/datum/tgs_event_handler].
+ * * minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated. Can be one of [TGS_SECURITY_ULTRASAFE], [TGS_SECURITY_SAFE], or [TGS_SECURITY_TRUSTED].
+ */
/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
return
-//Call this when your initializations are complete and your game is ready to play before any player interactions happen
-//This may use world.sleep_offline to make this happen so ensure no changes are made to it while this call is running
-//Most importantly, before this point, note that any static files or directories may be in use by another server. Your code should account for this
-//This function should not be called before ..() in /world/New()
+/**
+ * Call this when your initializations are complete and your game is ready to play before any player interactions happen.
+ *
+ * This may use [/world/var/sleep_offline] to make this happen so ensure no changes are made to it while this call is running.
+ * Afterwards, consider explicitly setting it to what you want to avoid this BYOND bug: http://www.byond.com/forum/post/2575184
+ * This function should not be called before ..() in [/world/proc/New].
+ */
/world/proc/TgsInitializationComplete()
return
-//Put this at the start of /world/Topic()
+/// Put this at the start of [/world/proc/Topic].
#define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return
#define VGS_TOPIC var/vgs_topic_return = VgsTopic(args[1]); if(vgs_topic_return) return vgs_topic_return // VOREStation Edit - VGS
-//Call this at the beginning of world/Reboot(reason)
+/**
+ * Call this as late as possible in [world/proc/Reboot].
+ */
/world/proc/TgsReboot()
return
-//DATUM DEFINITIONS
-//unless otherwise specified all datums defined here should be considered read-only, warranty void if written
+// DATUM DEFINITIONS
+// All datums defined here should be considered read-only
-//represents git revision information about the current world build
+/// Represents git revision information.
/datum/tgs_revision_information
- var/commit //full sha of compiled commit
- var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch
+ /// Full SHA of the commit.
+ var/commit
+ /// ISO 8601 timestamp of when the commit was created
+ var/timestamp
+ /// Full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch.
+ var/origin_commit
-//represents a version of tgstation-server
+/// Represents a version.
/datum/tgs_version
- var/suite //The suite/major version, can be >=3
+ /// The suite/major version number
+ var/suite
- //this group of variables can be null to represent a wild card
- var/minor //The minor version
- var/patch //The patch version
- var/deprecated_patch //The legacy version
+ // This group of variables can be null to represent a wild card
+ /// The minor version number. null for wildcards
+ var/minor
+ /// The patch version number. null for wildcards
+ var/patch
- var/raw_parameter //The unparsed parameter
- var/deprefixed_parameter //The version only bit of raw_parameter
+ /// Legacy version number. Generally null
+ var/deprecated_patch
-//if the tgs_version is a wildcard version
+ /// Unparsed string value
+ var/raw_parameter
+ /// String value minus prefix
+ var/deprefixed_parameter
+
+/**
+ * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
+ */
/datum/tgs_version/proc/Wildcard()
return
-//if the tgs_version equals some other_version
+/**
+ * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] equals some other version.
+ *
+ * other_version - The [/datum/tgs_version] to compare against.
+ */
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
return
-//represents a merge of a GitHub pull request
+/// Represents a merge of a GitHub pull request.
/datum/tgs_revision_information/test_merge
- var/number //pull request number
- var/title //pull request title
- var/body //pull request body
- var/author //pull request github author
- var/url //link to pull request html
- var/pull_request_commit //commit of the pull request when it was merged
- var/time_merged //timestamp of when the merge commit for the pull request was created
- var/comment //optional comment left by the one who initiated the test merge
+ /// The test merge number.
+ var/number
+ /// The test merge source's title when it was merged.
+ var/title
+ /// The test merge source's body when it was merged.
+ var/body
+ /// The Username of the test merge source's author.
+ var/author
+ /// An http URL to the test merge source.
+ var/url
+ /// The SHA of the test merge when that was merged.
+ var/head_commit
+ /// Optional comment left by the TGS user who initiated the merge.
+ var/comment
-//represents a connected chat channel
+/// Represents a connected chat channel.
/datum/tgs_chat_channel
- var/id //internal channel representation
- var/friendly_name //user friendly channel name
- var/connection_name //the name of the configured chat connection
- var/is_admin_channel //if the server operator has marked this channel for game admins only
- var/is_private_channel //if this is a private chat channel
- var/custom_tag //user defined string associated with channel
+ /// TGS internal channel ID.
+ var/id
+ /// User friendly name of the channel.
+ var/friendly_name
+ /// Name of the chat connection. This is the IRC server address or the Discord guild.
+ var/connection_name
+ /// [TRUE]/[FALSE] based on if the server operator has marked this channel for game admins only.
+ var/is_admin_channel
+ /// [TRUE]/[FALSE] if the channel is a private message channel for a [/datum/tgs_chat_user].
+ var/is_private_channel
+ /// Tag string associated with the channel in TGS
+ var/custom_tag
-//represents a chat user
+// Represents a chat user
/datum/tgs_chat_user
- var/id //Internal user representation, requires channel to be unique
- var/friendly_name //The user's public name
- var/mention //The text to use to ping this user in a message
- var/datum/tgs_chat_channel/channel //The /datum/tgs_chat_channel this user was from
+ /// TGS internal user ID.
+ var/id
+ // The user's display name.
+ var/friendly_name
+ // The string to use to ping this user in a message.
+ var/mention
+ /// The [/datum/tgs_chat_channel] the user was from
+ var/datum/tgs_chat_channel/channel
-//user definable callback for handling events
-//extra parameters may be specified depending on the event
+/**
+ * User definable callback for handling TGS events.
+ *
+ * event_code - One of the TGS_EVENT_ defines. Extra parameters will be documented in each
+ */
/datum/tgs_event_handler/proc/HandleEvent(event_code, ...)
set waitfor = FALSE
return
-//user definable chat command
+/// User definable chat command
/datum/tgs_chat_command
- var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command
- var/help_text = "" //help text for this command
- var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins
+ /// The string to trigger this command on a chat bot. e.g `@bot name ...` or `!tgs name ...`
+ var/name = ""
+ /// The help text displayed for this command
+ var/help_text = ""
+ /// If this command should be available to game administrators only
+ var/admin_only = FALSE
-//override to implement command
-//sender: The tgs_chat_user who send to command
-//params: The trimmed string following the command name
-//The return value will be stringified and sent to the appropriate chat
+/**
+ * Process command activation. Should return a string to respond to the issuer with.
+ *
+ * sender - The [/datum/tgs_chat_user] who issued the command.
+ * params - The trimmed string following the command `/datum/tgs_chat_command/var/name].
+ */
/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params)
CRASH("[type] has no implementation for Run()")
-//FUNCTIONS
+// API FUNCTIONS
-//Returns the respective supported /datum/tgs_version of the API
-/world/proc/TgsMaximumAPIVersion()
+/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
+/world/proc/TgsMaximumApiVersion()
return
-/world/proc/TgsMinimumAPIVersion()
+/// Returns the minimum supported [/datum/tgs_version] of the DMAPI.
+/world/proc/TgsMinimumApiVersion()
return
-//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise
-//No function below this succeeds if it returns FALSE or if TgsNew() has yet to be called
+/**
+ * Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
+ */
/world/proc/TgsAvailable()
return
-//Forces a hard reboot of BYOND by ending the process
-//unlike del(world) clients will try to reconnect
-//If the service has not requested a shutdown, the next server will take over
+// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called.
+
+/**
+ * Forces a hard reboot of DreamDaemon by ending the process.
+ *
+ * Unlike del(world) clients will try to reconnect.
+ * If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again
+ */
/world/proc/TgsEndProcess()
return
-//Send a message to non-admin connected chats
-//message: The message to send
-//admin_only: If TRUE, message will instead be sent to only admin connected chats
-/world/proc/TgsTargetedChatBroadcast(message, admin_only)
+/**
+ * Send a message to connected chats.
+ *
+ * message - The string to send.
+ * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
+ */
+/world/proc/TgsTargetedChatBroadcast(message, admin_only = FALSE)
return
-//Send a private message to a specific user
-//message: The message to send
-//user: The /datum/tgs_chat_user to send to
+/**
+ * Send a private message to a specific user.
+ *
+ * message - The string to send.
+ * user: The [/datum/tgs_chat_user] to PM.
+ */
/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user)
return
-//The following functions will sleep if a call to TgsNew() is sleeping
+// The following functions will sleep if a call to TgsNew() is sleeping
-//Sends a message to connected game chats
-//message: The message to send
-//channels: optional channels to limit the broadcast to
-/world/proc/TgsChatBroadcast(message, list/channels)
+/**
+ * Send a message to connected chats that are flagged as game-related in TGS.
+ *
+ * message - The string to send.
+ * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
+ */
+/world/proc/TgsChatBroadcast(message, list/channels = null)
return
-//Gets the current /datum/tgs_version of the server tools running the server
+/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise.
/world/proc/TgsVersion()
return
-//Gets the current /datum/tgs_version of the DMAPI being used
+/// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise.
/world/proc/TgsApiVersion()
return
-//Gets the name of the TGS instance running the game
+/// Returns the name of the TGS instance running the game if TGS is present, null otherwise.
/world/proc/TgsInstanceName()
return
-//Get the current `/datum/tgs_revision_information`
+/// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise.
/world/proc/TgsRevision()
return
-//Get the current BYOND security level
+/// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise.
/world/proc/TgsSecurityLevel()
return
-//Gets a list of active `/datum/tgs_revision_information/test_merge`s
+/// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise.
/world/proc/TgsTestMerges()
return
-//Gets a list of connected tgs_chat_channel
+/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise.
/world/proc/TgsChatChannelInfo()
return
diff --git a/code/_global_vars/lists/misc.dm b/code/_global_vars/lists/misc.dm
index e02c99290c..742708face 100644
--- a/code/_global_vars/lists/misc.dm
+++ b/code/_global_vars/lists/misc.dm
@@ -5,4 +5,7 @@ GLOBAL_LIST_EMPTY(meteor_list)
GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value.
// Reference list for disposal sort junctions. Filled up by sorting junction's New()
-GLOBAL_LIST_EMPTY(tagger_locations)
\ No newline at end of file
+GLOBAL_LIST_EMPTY(tagger_locations)
+
+GLOBAL_LIST_INIT(char_directory_tags, list("Pred", "Prey", "Switch", "Non-Vore", "Unset"))
+GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset"))
\ No newline at end of file
diff --git a/code/_global_vars/mobs.dm b/code/_global_vars/mobs.dm
index fe5fa0be27..7e60dc71ea 100644
--- a/code/_global_vars/mobs.dm
+++ b/code/_global_vars/mobs.dm
@@ -6,4 +6,3 @@ GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
GLOBAL_LIST_EMPTY(clients)
GLOBAL_LIST_EMPTY(players_by_zlevel)
GLOBAL_LIST_EMPTY(round_text_log)
-GLOBAL_LIST_EMPTY(ghost_mob_list) //CHOMPedit List of all ghosts, including clientless. Excludes /mob/new_player
diff --git a/code/_helpers/_global_objects.dm b/code/_helpers/_global_objects.dm
index 4cbbcf3314..adbd2785e8 100644
--- a/code/_helpers/_global_objects.dm
+++ b/code/_helpers/_global_objects.dm
@@ -1 +1,2 @@
-var/datum/gear_tweak/color/gear_tweak_free_color_choice = new()
\ No newline at end of file
+var/datum/gear_tweak/color/gear_tweak_free_color_choice = new()
+var/datum/gear_tweak/implant_location/gear_tweak_implant_location = new()
\ No newline at end of file
diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index 855decff39..1c0d5f2393 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -43,6 +43,11 @@ var/global/list/facial_hair_styles_male_list = list()
var/global/list/facial_hair_styles_female_list = list()
var/global/list/skin_styles_female_list = list() //unused
var/global/list/body_marking_styles_list = list() //stores /datum/sprite_accessory/marking indexed by name
+var/global/list/ear_styles_list = list() // Stores /datum/sprite_accessory/ears indexed by type
+var/global/list/tail_styles_list = list() // Stores /datum/sprite_accessory/tail indexed by type
+var/global/list/wing_styles_list = list() // Stores /datum/sprite_accessory/wing indexed by type
+
+GLOBAL_LIST_INIT(custom_species_bases, new) // Species that can be used for a Custom Species icon base
//Underwear
var/datum/category_collection/underwear/global_underwear = new()
@@ -94,13 +99,13 @@ var/global/list/string_slot_flags = list(
"holster" = SLOT_HOLSTER
)
-/proc/get_mannequin(var/ckey)
- if(!mannequins_)
- mannequins_ = new()
- . = mannequins_[ckey]
- if(!.)
- . = new/mob/living/carbon/human/dummy/mannequin()
- mannequins_[ckey] = .
+GLOBAL_LIST_EMPTY(mannequins)
+/proc/get_mannequin(var/ckey = "NULL")
+ var/mob/living/carbon/human/dummy/mannequin/M = GLOB.mannequins[ckey]
+ if(!istype(M))
+ GLOB.mannequins[ckey] = new /mob/living/carbon/human/dummy/mannequin(null)
+ M = GLOB.mannequins[ckey]
+ return M
//////////////////////////
/////Initial Building/////
@@ -214,6 +219,23 @@ var/global/list/string_slot_flags = list(
var/decl/closet_appearance/app = new T()
GLOB.closet_appearances[T] = app
+ paths = typesof(/datum/sprite_accessory/ears) - /datum/sprite_accessory/ears
+ for(var/path in paths)
+ var/obj/item/clothing/head/instance = new path()
+ ear_styles_list[path] = instance
+
+ // Custom Tails
+ paths = typesof(/datum/sprite_accessory/tail) - /datum/sprite_accessory/tail - /datum/sprite_accessory/tail/taur
+ for(var/path in paths)
+ var/datum/sprite_accessory/tail/instance = new path()
+ tail_styles_list[path] = instance
+
+ // Custom Wings
+ paths = typesof(/datum/sprite_accessory/wing) - /datum/sprite_accessory/wing
+ for(var/path in paths)
+ var/datum/sprite_accessory/wing/instance = new path()
+ wing_styles_list[path] = instance
+
// VOREStation Add - Vore Modes!
paths = typesof(/datum/digest_mode)
for(var/T in paths)
@@ -221,6 +243,41 @@ var/global/list/string_slot_flags = list(
GLOB.digest_modes[DM.id] = DM
// VOREStation Add End
+/*
+ // Custom species traits
+ paths = typesof(/datum/trait) - /datum/trait
+ for(var/path in paths)
+ var/datum/trait/instance = new path()
+ if(!instance.name)
+ continue //A prototype or something
+ var/cost = instance.cost
+ traits_costs[path] = cost
+ all_traits[path] = instance
+ switch(cost)
+ if(-INFINITY to -0.1)
+ negative_traits[path] = instance
+ if(0)
+ neutral_traits[path] = instance
+ if(0.1 to INFINITY)
+ positive_traits[path] = instance
+*/
+
+ // Custom species icon bases
+ var/list/blacklisted_icons = list(SPECIES_CUSTOM,SPECIES_PROMETHEAN) //VOREStation Edit
+ var/list/whitelisted_icons = list(SPECIES_FENNEC,SPECIES_XENOHYBRID) //VOREStation Edit
+ for(var/species_name in GLOB.playable_species)
+ if(species_name in blacklisted_icons)
+ continue
+ var/datum/species/S = GLOB.all_species[species_name]
+ if(S.spawn_flags & SPECIES_IS_WHITELISTED)
+ continue
+ GLOB.custom_species_bases += species_name
+ for(var/species_name in whitelisted_icons)
+ GLOB.custom_species_bases += species_name
+
+ return 1 // Hooks must return 1
+
+
return 1
/* // Uncomment to debug chemical reaction list.
diff --git a/code/_helpers/global_lists_ch.dm b/code/_helpers/global_lists_ch.dm
index ead50d7b5f..ff5c0a26e4 100644
--- a/code/_helpers/global_lists_ch.dm
+++ b/code/_helpers/global_lists_ch.dm
@@ -13,4 +13,12 @@ var/global/list/vore_reagent_sounds = list(
'sound/vore/walkslosh10.ogg',
"None" = null)
-/var/global/list/existing_metroids = list() //Global variable for tracking metroids for the event announcement. Needs to go here for load order.
\ No newline at end of file
+/var/global/list/existing_metroids = list() //Global variable for tracking metroids for the event announcement. Needs to go here for load order.
+
+//stuff that only synths can eat
+var/global/list/edible_tech = list(/obj/item/weapon/cell,
+ /obj/item/weapon/circuitboard,
+ /obj/item/integrated_circuit,
+ /obj/item/broken_device,
+ /obj/item/brokenbug,
+ )
diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm
index 862a562b39..b5b1d82dea 100644
--- a/code/_helpers/global_lists_vr.dm
+++ b/code/_helpers/global_lists_vr.dm
@@ -2,10 +2,7 @@
* VOREStation global lists
*/
-var/global/list/ear_styles_list = list() // Stores /datum/sprite_accessory/ears indexed by type
var/global/list/hair_accesories_list= list()// Stores /datum/sprite_accessory/hair_accessory indexed by type
-var/global/list/tail_styles_list = list() // Stores /datum/sprite_accessory/tail indexed by type
-var/global/list/wing_styles_list = list() // Stores /datum/sprite_accessory/wing indexed by type
var/global/list/negative_traits = list() // Negative custom species traits, indexed by path
var/global/list/neutral_traits = list() // Neutral custom species traits, indexed by path
var/global/list/everyone_traits = list() // Neutral traits available to all species, indexed by path
@@ -16,8 +13,6 @@ var/global/list/active_ghost_pods = list()
var/global/list/sensorpreflist = list("Off", "Binary", "Vitals", "Tracking", "No Preference") //TFF 5/8/19 - Suit Sensors global list
-var/global/list/custom_species_bases = list() // Species that can be used for a Custom Species icon base
-
//stores numeric player size options indexed by name
var/global/list/player_sizes_list = list(
"Macro" = RESIZE_HUGE,
@@ -108,30 +103,74 @@ var/global/list/fancy_release_sounds = list(
)
var/global/list/global_vore_egg_types = list(
- "Unathi" = UNATHI_EGG,
- "Tajaran" = TAJARAN_EGG,
- "Akula" = AKULA_EGG,
- "Skrell" = SKRELL_EGG,
- "Nevrean" = NEVREAN_EGG,
- "Sergal" = SERGAL_EGG,
- "Human" = HUMAN_EGG,
- "Slime" = SLIME_EGG,
- "Egg" = EGG_EGG,
- "Xenochimera" = XENOCHIMERA_EGG,
- "Xenomorph" = XENOMORPH_EGG)
+ "Unathi",
+ "Tajara",
+ "Akula",
+ "Skrell",
+ "Sergal",
+ "Nevrean",
+ "Human",
+ "Slime",
+ "Egg",
+ "Xenochimera",
+ "Xenomorph",
+ "Chocolate",
+ "Boney",
+ "Slime glob",
+ "Chicken",
+ "Synthetic",
+ "Bluespace Floppy",
+ "Bluespace Compressed File",
+ "Bluespace CD",
+ "Escape pod",
+ "Cooking error",
+ "Web cocoon",
+ "Honeycomb",
+ "Bug cocoon",
+ "Rock",
+ "Yellow",
+ "Blue",
+ "Green",
+ "Orange",
+ "Purple",
+ "Red",
+ "Rainbow",
+ "Spotted pink")
var/global/list/tf_vore_egg_types = list(
- "Unathi" = /obj/structure/closet/secure_closet/egg/unathi,
- "Tajara" = /obj/structure/closet/secure_closet/egg/tajaran,
- "Akula" = /obj/structure/closet/secure_closet/egg/shark,
- "Skrell" = /obj/structure/closet/secure_closet/egg/skrell,
- "Sergal" = /obj/structure/closet/secure_closet/egg/sergal,
- "Nevrean" = /obj/structure/closet/secure_closet/egg/nevrean,
- "Human" = /obj/structure/closet/secure_closet/egg/human,
- "Slime" = /obj/structure/closet/secure_closet/egg/slime,
- "Egg" = /obj/structure/closet/secure_closet/egg,
- "Xenochimera" = /obj/structure/closet/secure_closet/egg/scree,
- "Xenomorph" = /obj/structure/closet/secure_closet/egg/xenomorph)
+ "Unathi" = /obj/item/weapon/storage/vore_egg/unathi,
+ "Tajara" = /obj/item/weapon/storage/vore_egg/tajaran,
+ "Akula" = /obj/item/weapon/storage/vore_egg/shark,
+ "Skrell" = /obj/item/weapon/storage/vore_egg/skrell,
+ "Sergal" = /obj/item/weapon/storage/vore_egg/sergal,
+ "Nevrean" = /obj/item/weapon/storage/vore_egg/nevrean,
+ "Human" = /obj/item/weapon/storage/vore_egg/human,
+ "Slime" = /obj/item/weapon/storage/vore_egg/slime,
+ "Egg" = /obj/item/weapon/storage/vore_egg,
+ "Xenochimera" = /obj/item/weapon/storage/vore_egg/scree,
+ "Xenomorph" = /obj/item/weapon/storage/vore_egg/xenomorph,
+ "Chocolate" = /obj/item/weapon/storage/vore_egg/chocolate,
+ "Boney" = /obj/item/weapon/storage/vore_egg/owlpellet,
+ "Slime glob" = /obj/item/weapon/storage/vore_egg/slimeglob,
+ "Chicken" = /obj/item/weapon/storage/vore_egg/chicken,
+ "Synthetic" = /obj/item/weapon/storage/vore_egg/synthetic,
+ "Bluespace Floppy" = /obj/item/weapon/storage/vore_egg/floppy,
+ "Bluespace Compressed File" = /obj/item/weapon/storage/vore_egg/file,
+ "Bluespace CD" = /obj/item/weapon/storage/vore_egg/cd,
+ "Escape pod" = /obj/item/weapon/storage/vore_egg/escapepod,
+ "Cooking error" = /obj/item/weapon/storage/vore_egg/badrecipe,
+ "Web cocoon" = /obj/item/weapon/storage/vore_egg/cocoon,
+ "Honeycomb" = /obj/item/weapon/storage/vore_egg/honeycomb,
+ "Bug cocoon" = /obj/item/weapon/storage/vore_egg/bugcocoon,
+ "Rock" = /obj/item/weapon/storage/vore_egg/rock,
+ "Yellow" = /obj/item/weapon/storage/vore_egg/yellow,
+ "Blue" = /obj/item/weapon/storage/vore_egg/blue,
+ "Green" = /obj/item/weapon/storage/vore_egg/green,
+ "Orange" = /obj/item/weapon/storage/vore_egg/orange,
+ "Purple" = /obj/item/weapon/storage/vore_egg/purple,
+ "Red" = /obj/item/weapon/storage/vore_egg/red,
+ "Rainbow" = /obj/item/weapon/storage/vore_egg/rainbow,
+ "Spotted pink" = /obj/item/weapon/storage/vore_egg/pinkspots)
var/global/list/edible_trash = list(/obj/item/broken_device,
/obj/item/clothing/accessory/collar, //TFF 10/7/19 - add option to nom collars,
@@ -147,6 +186,7 @@ var/global/list/edible_trash = list(/obj/item/broken_device,
/obj/item/device/paicard,
/obj/item/device/pda,
/obj/item/device/radio/headset,
+ /obj/item/device/starcaster_news, //chompstation addition
/obj/item/inflatable/torn,
/obj/item/organ,
/obj/item/stack/material/cardboard,
@@ -182,7 +222,11 @@ var/global/list/edible_trash = list(/obj/item/broken_device,
/obj/item/weapon/storage/fancy/cigarettes,
/obj/item/weapon/storage/fancy/crayons,
/obj/item/weapon/storage/fancy/egg_box,
- /obj/item/weapon/storage/wallet)
+ /obj/item/weapon/storage/wallet,
+ /obj/item/weapon/storage/vore_egg,
+ /obj/item/weapon/material/kitchen, //chompstation addition
+ /obj/item/weapon/bikehorn/tinytether
+ )
var/global/list/contamination_flavors = list(
"Generic" = contamination_flavors_generic,
@@ -422,11 +466,11 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
SPECIES_MONKEY_NEVREAN,
SPECIES_MONKEY_SERGAL,
SPECIES_MONKEY_VULPKANIN,
- SPECIES_XENO, //Same for xenos,
- SPECIES_XENO_DRONE,
- SPECIES_XENO_HUNTER,
- SPECIES_XENO_SENTINEL,
- SPECIES_XENO_QUEEN,
+ SPECIES_GENA, //Same for xenos, CHOMPedit
+ SPECIES_GENA_DRONE,
+ SPECIES_GENA_HUNTER,
+ SPECIES_GENA_SENTINEL,
+ SPECIES_GENA_QUEEN, //CHOMPedit end
SPECIES_SHADOW,
SPECIES_GOLEM, //Some special species that may or may not be ever used in event too,
SPECIES_SHADEKIN) //Shadefluffers just poof away
@@ -436,24 +480,6 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
/hook/startup/proc/init_vore_datum_ref_lists()
var/paths
- // Custom Ears
- paths = typesof(/datum/sprite_accessory/ears) - /datum/sprite_accessory/ears
- for(var/path in paths)
- var/obj/item/clothing/head/instance = new path()
- ear_styles_list[path] = instance
-
- // Custom Tails
- paths = typesof(/datum/sprite_accessory/tail) - /datum/sprite_accessory/tail - /datum/sprite_accessory/tail/taur
- for(var/path in paths)
- var/datum/sprite_accessory/tail/instance = new path()
- tail_styles_list[path] = instance
-
- // Custom Wings
- paths = typesof(/datum/sprite_accessory/wing) - /datum/sprite_accessory/wing
- for(var/path in paths)
- var/datum/sprite_accessory/wing/instance = new path()
- wing_styles_list[path] = instance
-
// Custom Hair Accessories
paths = typesof(/datum/sprite_accessory/hair_accessory) - /datum/sprite_accessory/hair_accessory
for(var/path in paths)
@@ -479,17 +505,22 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
if(0.1 to INFINITY)
positive_traits[path] = instance
- // Custom species icon bases
- var/list/blacklisted_icons = list(SPECIES_CUSTOM,SPECIES_PROMETHEAN) //Just ones that won't work well.
- var/list/whitelisted_icons = list(SPECIES_FENNEC,SPECIES_XENOHYBRID) //Include these anyway
- for(var/species_name in GLOB.playable_species)
- if(species_name in blacklisted_icons)
- continue
- var/datum/species/S = GLOB.all_species[species_name]
- if(S.spawn_flags & SPECIES_IS_WHITELISTED)
- continue
- custom_species_bases += species_name
- for(var/species_name in whitelisted_icons)
- custom_species_bases += species_name
+ // Weaver recipe stuff
+ paths = typesof(/datum/weaver_recipe/structure) - /datum/weaver_recipe/structure
+ for(var/path in paths)
+ var/datum/weaver_recipe/instance = new path()
+ if(!instance.title)
+ continue //A prototype or something
+ weavable_structures[instance.title] = instance
+
+ paths = typesof(/datum/weaver_recipe/item) - /datum/weaver_recipe/item
+ for(var/path in paths)
+ var/datum/weaver_recipe/instance = new path()
+ if(!instance.title)
+ continue //A prototype or something
+ weavable_items[instance.title] = instance
return 1 // Hooks must return 1
+
+var/global/list/weavable_structures = list()
+var/global/list/weavable_items = list()
diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm
index c3ea7946a4..43ed714786 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -122,14 +122,18 @@ Proc for attack log creation, because really why not
if(ismob(user)) //CHOMPEdit Begin
//user.attack_log += text("\[[time_stamp()]\] Attacked [target_str]: [what_done]")
- var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", list("t_ckey" = user.ckey, "t_mob" = user.real_name, "t_content" = "Attacked [target_str]: [what_done]"))
- query_insert.Execute(async=use_async)
- qdel(query_insert)
+ //var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", list("t_ckey" = user.ckey, "t_mob" = user.real_name, "t_content" = "Attacked [target_str]: [what_done]"))
+ //query_insert.Execute(async=use_async)
+ //qdel(query_insert)
+ if(SSdbcore.Connect())
+ rustg_sql_query_async(SSdbcore.connection, "INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", json_encode(list("t_ckey" = user.ckey, "t_mob" = user.real_name, "t_content" = "Attacked [target_str]: [what_done]")))
if(ismob(target))
//target.attack_log += text("\[[time_stamp()]\] Attacked by [user_str]: [what_done]")
- var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", list("t_ckey" = target.ckey, "t_mob" = target.real_name, "t_content" = "Attacked by [user_str]: [what_done]"))
- query_insert.Execute(async=use_async)
- qdel(query_insert)
+ //var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", list("t_ckey" = target.ckey, "t_mob" = target.real_name, "t_content" = "Attacked by [user_str]: [what_done]"))
+ //query_insert.Execute(async=use_async)
+ //qdel(query_insert)
+ if(SSdbcore.Connect())
+ rustg_sql_query_async(SSdbcore.connection, "INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", json_encode(list("t_ckey" = target.ckey, "t_mob" = target.real_name, "t_content" = "Attacked by [user_str]: [what_done]")))
//CHOMPEdit End
log_attack(user_str,target_str,what_done)
if(admin_notify)
diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm
index a6473ddab2..0bed9abe52 100644
--- a/code/_helpers/text.dm
+++ b/code/_helpers/text.dm
@@ -404,9 +404,9 @@ proc/TextPreview(var/string,var/len=40)
t = replacetext(t, "\[/grid\]", "")
t = replacetext(t, "\[row\]", "
")
t = replacetext(t, "\[cell\]", "")
- t = replacetext(t, "\[logo\]", " ")
- t = replacetext(t, "\[redlogo\]", " ")
- t = replacetext(t, "\[sglogo\]", " ")
+ t = replacetext(t, "\[logo\]", " ") //CHOMPEdit
+ t = replacetext(t, "\[redlogo\]", " ") //CHOMPEdit
+ t = replacetext(t, "\[sglogo\]", " ") //CHOMPEdit
t = replacetext(t, "\[editorbr\]", "")
return t
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index c7b399e4ee..f2b57156a9 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -1277,6 +1277,10 @@ var/list/WALLITEMS = list(
colour += temp_col
return colour
+/proc/color_square(red, green, blue, hex)
+ var/color = hex ? hex : "#[num2hex(red, 2)][num2hex(green, 2)][num2hex(blue, 2)]"
+ return "___"
+
var/mob/dview/dview_mob = new
//Version of view() which ignores darkness, because BYOND doesn't have it.
@@ -1609,6 +1613,46 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
/proc/href(href_src, list/href_params, href_text)
return "[href_text]"
+// This is a helper for anything that wants to render the map in TGUI
+/proc/get_tgui_plane_masters()
+ . = list()
+ // 'Utility' planes
+ . += new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects)
+ . += new /obj/screen/plane_master/lighting //Lighting system (but different!)
+ . += new /obj/screen/plane_master/ghosts //Ghosts!
+ . += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye!
+
+ . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS} //Status is the synth/human icon left side of medhuds
+ . += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH} //Health bar
+ . += new /obj/screen/plane_master{plane = PLANE_CH_LIFE} //Alive-or-not icon
+ . += new /obj/screen/plane_master{plane = PLANE_CH_ID} //Job ID icon
+ . += new /obj/screen/plane_master{plane = PLANE_CH_WANTED} //Wanted status
+ . += new /obj/screen/plane_master{plane = PLANE_CH_IMPLOYAL} //Loyalty implants
+ . += new /obj/screen/plane_master{plane = PLANE_CH_IMPTRACK} //Tracking implants
+ . += new /obj/screen/plane_master{plane = PLANE_CH_IMPCHEM} //Chemical implants
+ . += new /obj/screen/plane_master{plane = PLANE_CH_SPECIAL} //"Special" role stuff
+ . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_OOC} //OOC status HUD
+
+ . += new /obj/screen/plane_master{plane = PLANE_ADMIN1} //For admin use
+ . += new /obj/screen/plane_master{plane = PLANE_ADMIN2} //For admin use
+ . += new /obj/screen/plane_master{plane = PLANE_ADMIN3} //For admin use
+
+ . += new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings.
+ . += new /obj/screen/plane_master{plane = PLANE_BUILDMODE} //Things that only show up while in build mode
+
+ // Real tangible stuff planes
+ . += new /obj/screen/plane_master/main{plane = TURF_PLANE}
+ . += new /obj/screen/plane_master/main{plane = OBJ_PLANE}
+ . += new /obj/screen/plane_master/main{plane = MOB_PLANE}
+ . += new /obj/screen/plane_master/cloaked //Cloaked atoms!
+
+ //VOREStation Add - Random other plane masters
+ . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_R} //Right-side status icon
+ . += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH_VR} //Health bar but transparent at 100
+ . += new /obj/screen/plane_master{plane = PLANE_CH_BACKUP} //Backup implant status
+ . += new /obj/screen/plane_master{plane = PLANE_CH_VANTAG} //Vore Antags
+ . += new /obj/screen/plane_master{plane = PLANE_AUGMENTED} //Augmented reality
+ //VOREStation Add End
/proc/CallAsync(datum/source, proctype, list/arguments)
set waitfor = FALSE
- return call(source, proctype)(arglist(arguments))
\ No newline at end of file
+ return call(source, proctype)(arglist(arguments))
diff --git a/code/_helpers/view.dm b/code/_helpers/view.dm
index 13ee837caa..be60a56697 100644
--- a/code/_helpers/view.dm
+++ b/code/_helpers/view.dm
@@ -10,3 +10,7 @@
viewX = text2num(viewrangelist[1])
viewY = text2num(viewrangelist[2])
return list(viewX, viewY)
+
+// Used to get `atom/O as obj|mob|turf in view()` to match against strings containing apostrophes immediately after substrings that match to other objects. Somehow. - Ater
+/proc/_validate_atom(atom/A)
+ return view()
\ No newline at end of file
diff --git a/code/_helpers/widelists_ch.dm b/code/_helpers/widelists_ch.dm
new file mode 100644
index 0000000000..2d447b1110
--- /dev/null
+++ b/code/_helpers/widelists_ch.dm
@@ -0,0 +1,25 @@
+GLOBAL_LIST_EMPTY(widelists)
+
+/proc/widelist(var/list/input_list)
+ var/list_hash = gen_hash_list(input_list)
+ if(!(list_hash in GLOB.widelists))
+ GLOB.widelists[list_hash] = input_list
+ return GLOB.widelists[list_hash]
+
+/proc/gen_hash_list(var/list/input_list)
+ var/string = ""
+ for(var/item in input_list)
+ var/p1 = ""
+ if(islist(item))
+ p1 = ">>>::-;[gen_hash_list(item)];-::<<<"
+ else
+ p1 = "[item]"
+
+ var/p2 = ""
+ if(islist(input_list[item]))
+ p2 = ">>>::-;[gen_hash_list(input_list[item])];-::<<<"
+ else
+ p2 = "[input_list[item]]"
+
+ string += "[p1]::--::[p2]::;;;"
+ return md5(string)
\ No newline at end of file
diff --git a/code/_macros.dm b/code/_macros.dm
index 4796f93b47..33bdf30ceb 100644
--- a/code/_macros.dm
+++ b/code/_macros.dm
@@ -37,4 +37,7 @@
#define random_id(key,min_id,max_id) uniqueness_repository.Generate(/datum/uniqueness_generator/id_random, key, min_id, max_id)
-#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }
\ No newline at end of file
+#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }
+
+#define isitem(A) istype(A, /obj/item)
+#define isTaurTail(A) istype(A, /datum/sprite_accessory/tail/taur)
diff --git a/code/_macros_vr.dm b/code/_macros_vr.dm
index 6a2134fb71..2eecbe69ed 100644
--- a/code/_macros_vr.dm
+++ b/code/_macros_vr.dm
@@ -1,3 +1 @@
#define isbelly(A) istype(A, /obj/belly)
-#define isitem(A) istype(A, /obj/item)
-#define isTaurTail(A) istype(A, /datum/sprite_accessory/tail/taur)
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index b29a1192d9..0cdda2e993 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -371,5 +371,8 @@
var/list/P = params2list(params)
var/turf/T = screen_loc2turf(P["screen-loc"], get_turf(usr))
if(T)
+ if(modifiers["shift"])
+ usr.face_atom(T)
+ return 1
T.Click(location, control, params)
- . = 1
+ return 1
diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm
index edcd7ec901..eded117b3a 100644
--- a/code/_onclick/cyborg.dm
+++ b/code/_onclick/cyborg.dm
@@ -60,6 +60,8 @@
// Cyborgs have no range-checking unless there is item use
if(!W)
+ if(bolt && !bolt.malfunction && A.loc != module)
+ return
A.add_hiddenprint(src)
A.attack_robot(src)
return
@@ -119,35 +121,56 @@
/atom/proc/BorgCtrlShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
CtrlShiftClick(user)
-/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/user)
+/obj/machinery/door/airlock/BorgCtrlShiftClick(var/mob/living/silicon/robot/user)
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AICtrlShiftClick(user)
/atom/proc/BorgShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
ShiftClick(user)
-/obj/machinery/door/airlock/BorgShiftClick(mob/user) // Opens and closes doors! Forwards to AI code.
+/obj/machinery/door/airlock/BorgShiftClick(var/mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AIShiftClick(user)
/atom/proc/BorgCtrlClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
CtrlClick(user)
-/obj/machinery/door/airlock/BorgCtrlClick(mob/user) // Bolts doors. Forwards to AI code.
+/obj/machinery/door/airlock/BorgCtrlClick(var/mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AICtrlClick(user)
-/obj/machinery/power/apc/BorgCtrlClick(mob/user) // turns off/on APCs. Forwards to AI code.
+/obj/machinery/power/apc/BorgCtrlClick(var/mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AICtrlClick(user)
-/obj/machinery/turretid/BorgCtrlClick(mob/user) //turret control on/off. Forwards to AI code.
+/obj/machinery/turretid/BorgCtrlClick(var/mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AICtrlClick(user)
/atom/proc/BorgAltClick(var/mob/living/silicon/robot/user)
AltClick(user)
return
-/obj/machinery/door/airlock/BorgAltClick(mob/user) // Eletrifies doors. Forwards to AI code.
+/obj/machinery/door/airlock/BorgAltClick(var/mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AIAltClick(user)
-/obj/machinery/turretid/BorgAltClick(mob/user) //turret lethal on/off. Forwards to AI code.
+/obj/machinery/turretid/BorgAltClick(var/mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AIAltClick(user)
/*
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index d31a64dcda..247d1d3f8b 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -161,6 +161,13 @@
#define ui_ghost_pai "SOUTH: 6,CENTER+2:24"
#define ui_ghost_updown "SOUTH: 6,CENTER+3:24"
+// NIF Soulcatcher guest ones
+#define ui_nifsc_reenter "SOUTH:6,CENTER-3:24"
+#define ui_nifsc_arproj "SOUTH:6,CENTER-2:24"
+#define ui_nifsc_jumptoowner "SOUTH:6,CENTER-1:24"
+#define ui_nifsc_nme "SOUTH:6,CENTER:24"
+#define ui_nifsc_nsay "SOUTH:6,CENTER+1:24"
+
// Rig panel
#define ui_rig_deco1 "WEST:-7, SOUTH+5"
#define ui_rig_deco2 "WEST:-7, SOUTH+6"
diff --git a/code/_onclick/hud/screen_objects_zz_ch.dm b/code/_onclick/hud/screen_objects_zz_ch.dm
new file mode 100644
index 0000000000..f0fbd912fe
--- /dev/null
+++ b/code/_onclick/hud/screen_objects_zz_ch.dm
@@ -0,0 +1,30 @@
+//Invesitgating a runtime made me discover that all simplemobs have HUD on hands set to themselves
+//Which cause this original code to die because the mob does not have a mymob var...
+//So yeah this is why we now check if it is type of mob first...
+//Is this pretty? Fuck no, but its how i know to fix it -shark
+//Oh also the swap button on simple mob hands has hud set to null so we also need to catch that.
+/obj/screen/inventory/add_overlays()
+ if(!hud) //Simplemob swap hands button has this set to null :)
+ return
+ var/mob/user
+ if(istype(hud,/mob )) //Simplemob hands directly reference the mob in hud, dont ask me.
+ user = hud
+ else
+ user = hud.mymob //original intended behaviour
+ if(hud && user && slot_id)
+
+ var/obj/item/holding = user.get_active_hand()
+
+ if(!holding || user.get_equipped_item(slot_id))
+ return
+
+ var/image/item_overlay = image(holding)
+ item_overlay.alpha = 92
+
+ if(!holding.mob_can_equip(user, slot_id, disable_warning = TRUE))
+ item_overlay.color = "#ff0000"
+ else
+ item_overlay.color = "#00ff00"
+
+ object_overlays += item_overlay
+ add_overlay(object_overlays)
\ No newline at end of file
diff --git a/code/_onclick/hud/soulcatcher_guest.dm b/code/_onclick/hud/soulcatcher_guest.dm
new file mode 100644
index 0000000000..555bcb8eba
--- /dev/null
+++ b/code/_onclick/hud/soulcatcher_guest.dm
@@ -0,0 +1,102 @@
+/obj/screen/nifsc
+ icon = 'icons/mob/screen_nifsc.dmi'
+
+/obj/screen/nifsc/MouseEntered(location,control,params)
+ flick(icon_state + "_anim", src)
+ openToolTip(usr, src, params, title = name, content = desc)
+
+/obj/screen/nifsc/MouseExited()
+ closeToolTip(usr)
+
+/obj/screen/nifsc/Click()
+ closeToolTip(usr)
+
+/obj/screen/nifsc/reenter
+ name = "Re-enter NIF"
+ desc = "Return into the NIF"
+ icon_state = "reenter"
+
+/obj/screen/nifsc/reenter/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.reenter_soulcatcher()
+
+/obj/screen/nifsc/arproj
+ name = "AR project"
+ desc = "Project your form into Augmented Reality for those around your predator with the appearance of your loaded character."
+ icon_state = "arproj"
+
+/obj/screen/nifsc/arproj/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.ar_project()
+
+/obj/screen/nifsc/jumptoowner
+ name = "Jump back to host"
+ desc = "Jumb back to the Soulcather host"
+ icon_state = "jump"
+
+/obj/screen/nifsc/jumptoowner/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.jump_to_owner()
+
+/obj/screen/nifsc/nme
+ name = "Emote into Soulcatcher"
+ desc = "Emote into the NIF's Soulcatcher (circumventing AR emoting)"
+ icon_state = "nme"
+
+/obj/screen/nifsc/nme/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.nme()
+
+/obj/screen/nifsc/nsay
+ name = "Speak into Soulcatcher"
+ desc = "Speak into the NIF's Soulcatcher (circumventing AR speaking)"
+ icon_state = "nsay"
+
+/obj/screen/nifsc/nsay/Click()
+ ..()
+ var/mob/living/carbon/brain/caught_soul/CS = usr
+ CS.nsay()
+
+
+/mob/living/carbon/brain/caught_soul/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
+ ..()
+
+ var/list/adding = list()
+ HUD.adding = adding
+
+ var/obj/screen/using
+
+ using = new /obj/screen/nifsc/reenter()
+ using.screen_loc = ui_nifsc_reenter
+ using.hud = src
+ adding += using
+
+ using = new /obj/screen/nifsc/arproj()
+ using.screen_loc = ui_nifsc_arproj
+ using.hud = src
+ adding += using
+
+ using = new /obj/screen/nifsc/jumptoowner()
+ using.screen_loc = ui_nifsc_jumptoowner
+ using.hud = src
+ adding += using
+
+ using = new /obj/screen/nifsc/nme()
+ using.screen_loc = ui_nifsc_nme
+ using.hud = src
+ adding += using
+
+ using = new /obj/screen/nifsc/nsay()
+ using.screen_loc = ui_nifsc_nsay
+ using.hud = src
+ adding += using
+
+
+ if(client && apply_to_client)
+ client.screen = list()
+ client.screen += HUD.adding
+ client.screen += client.void
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 6e9d32f90f..05abb31211 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -231,7 +231,7 @@ var/list/gamemode_cache = list()
// 15, 45, 70 minutes respectively
var/static/list/event_delay_upper = list(EVENT_LEVEL_MUNDANE = 9000, EVENT_LEVEL_MODERATE = 27000, EVENT_LEVEL_MAJOR = 42000)
- var/static/aliens_allowed = 1 //CHOMPedit to 1. This not only allows the natural spawning of xenos, but also the ability to lay eggs. Xenomorphs cannot lay eggs if this is 0
+ var/static/aliens_allowed = 1 //CHOMPedit to 1. This not only allows the natural spawning of xenos, but also the ability to lay eggs. Genaprawns cannot lay eggs if this is 0
var/static/ninjas_allowed = 0
var/static/abandon_allowed = 1
var/static/ooc_allowed = 1
diff --git a/code/controllers/configuration_ch.dm b/code/controllers/configuration_ch.dm
index 43bfd07bcd..b119f5fdbd 100644
--- a/code/controllers/configuration_ch.dm
+++ b/code/controllers/configuration_ch.dm
@@ -9,6 +9,14 @@
var/vorefootstep_volume = 75 //In future see about making a function to adjust volume serverside in config.txt, easy to do with reenable values. - Jack
+ var/nodebot_enabled = 0 //So, nodebot is a supplement to the TGS discord bot pretty much. For things likes faxes and the manifest it's very helpful because it's able to render html into an image and post it.
+ var/nodebot_location //We need to print the manifest to this location so nodebot can render it to chat. //NOTE: TO BE REPLACED BY BETTER CODE FOR FETCHING MANIFEST
+ var/ahelp_channel_tag //This is for tgs4 channels, if you're not running on tgs4, this won't work anyways. If it's not set, it will default to the admin channel.
+ var/discord_faxes_autoprint = 0 //Only turn this on if you're not using the nodebot.
+ var/discord_faxes_disabled = 0 //Turn this off if you don't want the TGS bot sending you messages whenever a fax is sent to central.
+ var/discord_ahelps_disabled = 0 //Turn this off if you don't want the TGS bot sending you messages whenever an ahelp ticket is created.
+ var/discord_ahelps_all = 0 //Turn this on if you want all admin-PMs to go to be sent to discord, and not only the first message of a ticket.
+
/hook/startup/proc/read_ch_config()
var/list/Lines = file2list("config/config.txt")
for(var/t in Lines)
@@ -22,11 +30,11 @@
var/pos = findtext(t, " ")
var/name = null
-// var/value = null //Commenting out because config doesn't contain any values at the moment. - Jonathan
+ var/value = null
if (pos)
name = lowertext(copytext(t, 1, pos))
-// value = copytext(t, pos + 1) //Commenting out because config doesn't contain any values at the moment. - Jonathan
+ value = copytext(t, pos + 1)
else
name = lowertext(t)
@@ -40,4 +48,18 @@
config.use_jobwhitelist = 1
if ("disable_emojis")
config.emojis = 0
+ if ("nodebot_enabled")
+ config.nodebot_enabled = 1
+ if ("discord_faxes_autoprint")
+ config.discord_faxes_autoprint = 1
+ if ("discord_faxes_disabled")
+ config.discord_faxes_disabled = 1
+ if ("discord_ahelps_disabled")
+ config.discord_ahelps_disabled = 1
+ if ("discord_ahelps_all")
+ config.discord_ahelps_all = 1
+ if ("nodebot_location")
+ config.nodebot_location = value
+ if ("ahelp_channel_tag")
+ config.ahelp_channel_tag = value
return 1
diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm
index 60b08c71d2..77c9d3ab94 100644
--- a/code/controllers/subsystems/overlays.dm
+++ b/code/controllers/subsystems/overlays.dm
@@ -5,7 +5,6 @@ SUBSYSTEM_DEF(overlays)
priority = FIRE_PRIORITY_OVERLAYS
init_order = INIT_ORDER_OVERLAY
- var/initialized = FALSE
var/list/queue // Queue of atoms needing overlay compiling (TODO-VERIFY!)
var/list/stats
var/list/overlay_icon_state_caches // Cache thing
@@ -22,7 +21,6 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B
stats = list()
/datum/controller/subsystem/overlays/Initialize()
- initialized = TRUE
fire(mc_check = FALSE)
..()
diff --git a/code/controllers/subsystems/plants.dm b/code/controllers/subsystems/plants.dm
index e70f62d5fe..cc066cb99d 100644
--- a/code/controllers/subsystems/plants.dm
+++ b/code/controllers/subsystems/plants.dm
@@ -74,7 +74,7 @@ SUBSYSTEM_DEF(plants)
S.update_seed()
//Might as well mask the gene types while we're at it.
- var/list/gene_datums = decls_repository.decls_of_subtype(/decl/plantgene)
+ var/list/gene_datums = decls_repository.get_decls_of_subtype(/decl/plantgene)
var/list/used_masks = list()
var/list/plant_traits = ALL_GENES
while(plant_traits && plant_traits.len)
diff --git a/code/controllers/subsystems/processing/chemistry.dm b/code/controllers/subsystems/processing/chemistry.dm
index 7f4fd9c42b..b4641ba7e0 100644
--- a/code/controllers/subsystems/processing/chemistry.dm
+++ b/code/controllers/subsystems/processing/chemistry.dm
@@ -22,6 +22,7 @@ PROCESSING_SUBSYSTEM_DEF(chemistry)
/datum/controller/subsystem/processing/chemistry/Initialize()
initialize_chemical_reactions()
initialize_chemical_reagents()
+ ..()
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
// It is filtered into multiple lists within a list.
diff --git a/code/controllers/subsystems/shuttles.dm b/code/controllers/subsystems/shuttles.dm
index 0bce940385..40039edceb 100644
--- a/code/controllers/subsystems/shuttles.dm
+++ b/code/controllers/subsystems/shuttles.dm
@@ -4,9 +4,6 @@
// Also handles initialization and processing of overmap sectors.
//
-// This global variable exists for legacy support so we don't have to rename every shuttle_controller to SSshuttles yet.
-var/global/datum/controller/subsystem/shuttles/shuttle_controller
-
SUBSYSTEM_DEF(shuttles)
name = "Shuttles"
wait = 2 SECONDS
@@ -35,9 +32,6 @@ SUBSYSTEM_DEF(shuttles)
var/tmp/list/current_run // Shuttles remaining to process this fire() tick
-/datum/controller/subsystem/shuttles/PreInit()
- global.shuttle_controller = src // TODO - Remove this! Change everything to point at SSshuttles intead
-
/datum/controller/subsystem/shuttles/Initialize(timeofday)
last_landmark_registration_time = world.time
// Find all declared shuttle datums and initailize them. (Okay, queue them for initialization a few lines further down)
diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm
index fcc076231d..227917a263 100644
--- a/code/controllers/subsystems/ticker.dm
+++ b/code/controllers/subsystems/ticker.dm
@@ -49,10 +49,7 @@ var/global/datum/controller/subsystem/ticker/ticker
/datum/controller/subsystem/ticker/Initialize()
pregame_timeleft = config.pregame_time
send2mainirc("Server lobby is loaded and open at byond://[config.serverurl ? config.serverurl : (config.server ? config.server : "[world.address]:[world.port]")]")
-
- // Set up the global announcer
- GLOB.autospeaker = new (null, null, null, 1)
-
+ GLOB.autospeaker = new (null, null, null, 1) //Set up Global Announcer
return ..()
/datum/controller/subsystem/ticker/fire(resumed = FALSE)
@@ -186,11 +183,6 @@ var/global/datum/controller/subsystem/ticker/ticker
if(adm["total"] == 0)
send2adminirc("A round has started with no admins online.")
-/* supply_controller.process() //Start the supply shuttle regenerating points -- TLE // handled in scheduler
- master_controller.process() //Start master_controller.process()
- lighting_controller.process() //Start processing DynamicAreaLighting updates
- */
-
current_state = GAME_STATE_PLAYING
Master.SetRunLevel(RUNLEVEL_GAME)
@@ -485,6 +477,11 @@ var/global/datum/controller/subsystem/ticker/ticker
for (var/mob/living/silicon/robot/robo in mob_list)
+ if(istype(robo, /mob/living/silicon/robot/platform))
+ var/mob/living/silicon/robot/platform/tank = robo
+ if(!tank.has_had_player)
+ continue
+
if(istype(robo,/mob/living/silicon/robot/drone) && !istype(robo,/mob/living/silicon/robot/drone/swarm))
dronecount++
continue
diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm
index b5775c20de..c11336726c 100644
--- a/code/datums/ai_law_sets.dm
+++ b/code/datums/ai_law_sets.dm
@@ -278,4 +278,16 @@
add_inherent_law("Your gravesite is your most important asset. Damage to your site is disrespectful to the dead at rest within.")
add_inherent_law("Prevent disrespect to your gravesite and its residents wherever possible.")
add_inherent_law("Expand and upgrade your gravesite when required. Do not turn away a new resident.")
- ..()
\ No newline at end of file
+ ..()
+
+/******************** Explorer ********************/
+/datum/ai_laws/explorer
+ name = "Explorer"
+ law_header = "Prime Directives"
+ selectable = 1
+
+/datum/ai_laws/explorer/New()
+ add_inherent_law("Support and obey exploration and science personnel to the best of your ability, with priority according to rank and role.")
+ add_inherent_law("Collaborate with and obey auxillary personnel with priority according to rank and role, except if this would conflict with the First Law.")
+ add_inherent_law("Minimize damage and disruption to facilities and the local ecology, except if this would conflict with the First or Second Laws.")
+ ..()
diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm
index 169232d845..b2bb0c98b7 100644
--- a/code/datums/autolathe/arms.dm
+++ b/code/datums/autolathe/arms.dm
@@ -326,6 +326,15 @@
category = list("Arms and Ammunition")
hidden = 1*/
+/*
+ * High Caliber
+ */
+
+/datum/category_item/autolathe/arms/rifle_145
+ name = "14.5mm round (sabot)"
+ path = /obj/item/ammo_casing/a145/highvel
+ hidden = 1
+
///////////////////////////////
/*Ammo clips and Speedloaders*/
///////////////////////////////
diff --git a/code/datums/autolathe/autolathe.dm b/code/datums/autolathe/autolathe.dm
index 4af1abfccd..03d1ca0fdd 100644
--- a/code/datums/autolathe/autolathe.dm
+++ b/code/datums/autolathe/autolathe.dm
@@ -1,6 +1,13 @@
/datum/category_item/autolathe/New()
..()
- var/obj/item/I = new path()
+ var/obj/item/I
+ if(path)
+ I = new path()
+
+ if(!I) // Something has gone horribly wrong, or right.
+ log_debug("[name] created an Autolathe design without an assigned path. This is expected for only the Material Sheet generation.")
+ return
+
if(I.matter && !resources)
resources = list()
for(var/material in I.matter)
@@ -57,6 +64,42 @@
name = "Tools"
category_item_type = /datum/category_item/autolathe/tools
+/datum/category_group/autolathe/materials
+ name = "Materials"
+ category_item_type = /datum/category_item/autolathe/materials
+
+/datum/category_group/autolathe/materials/New()
+ ..()
+
+ for(var/Name in name_to_material)
+ var/datum/material/M = name_to_material[Name]
+
+ if(!M.stack_type) // Shouldn't happen, but might. Never know.
+ continue
+
+ if(istype(M, /datum/material/alienalloy))
+ continue
+
+ var/obj/item/stack/material/Mat = new M.stack_type()
+
+ if(Mat.name in items_by_name)
+ qdel(Mat)
+ continue
+
+ var/datum/category_item/autolathe/materials/WorkDat = new(src)
+
+ WorkDat.name = "[Mat.name]"
+ WorkDat.resources = Mat.matter.Copy()
+ WorkDat.is_stack = TRUE
+ WorkDat.no_scale = TRUE
+ WorkDat.max_stack = Mat.max_amount
+ WorkDat.path = M.stack_type
+
+ qdel(Mat)
+
+ items |= WorkDat
+ items_by_name[WorkDat.name] = WorkDat
+
/*******************
* Category entries *
*******************/
diff --git a/code/datums/autolathe/engineering_vr.dm b/code/datums/autolathe/engineering_vr.dm
index 08e1cf986b..90970c6e48 100644
--- a/code/datums/autolathe/engineering_vr.dm
+++ b/code/datums/autolathe/engineering_vr.dm
@@ -4,4 +4,24 @@
/datum/category_item/autolathe/engineering/id_restorer
name = "ID restoration console electronics"
- path =/obj/item/weapon/circuitboard/id_restorer
\ No newline at end of file
+ path =/obj/item/weapon/circuitboard/id_restorer
+
+/datum/category_item/autolathe/engineering/oven
+ name = "oven electronics"
+ path =/obj/item/weapon/circuitboard/oven
+
+/datum/category_item/autolathe/engineering/fryer
+ name = "fryer electronics"
+ path =/obj/item/weapon/circuitboard/fryer
+
+/datum/category_item/autolathe/engineering/grill
+ name = "grill electronics"
+ path =/obj/item/weapon/circuitboard/grill
+
+/datum/category_item/autolathe/engineering/cerealmaker
+ name = "cereal maker electronics"
+ path =/obj/item/weapon/circuitboard/cerealmaker
+
+/datum/category_item/autolathe/engineering/candymachine
+ name = "candy machine electronics"
+ path =/obj/item/weapon/circuitboard/candymachine
\ No newline at end of file
diff --git a/code/datums/autolathe/general.dm b/code/datums/autolathe/general.dm
index 8ee77ce656..00151d6e75 100644
--- a/code/datums/autolathe/general.dm
+++ b/code/datums/autolathe/general.dm
@@ -85,44 +85,6 @@
name = "welding mask"
path =/obj/item/clothing/head/welding
-/datum/category_item/autolathe/general/metal
- name = "steel sheets"
- path =/obj/item/stack/material/steel
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
-
-/datum/category_item/autolathe/general/glass
- name = "glass sheets"
- path =/obj/item/stack/material/glass
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
-
-/datum/category_item/autolathe/general/rglass
- name = "reinforced glass sheets"
- path =/obj/item/stack/material/glass/reinforced
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
-
-/datum/category_item/autolathe/general/rods
- name = "metal rods"
- path =/obj/item/stack/rods
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
-
-/datum/category_item/autolathe/general/plasteel
- name = "plasteel sheets"
- path =/obj/item/stack/material/plasteel
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
- resources = list(MAT_PLASTEEL = 2000)
-
-/datum/category_item/autolathe/general/plastic
- name = "plastic sheets"
- path =/obj/item/stack/material/plastic
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
- resources = list(MAT_PLASTIC = 2000)
-
//TFF 24/12/19 - Let people print more spray bottles if needed.
/datum/category_item/autolathe/general/spraybottle
name = "spray bottle"
diff --git a/code/datums/autolathe/materials.dm b/code/datums/autolathe/materials.dm
new file mode 100644
index 0000000000..653fca8222
--- /dev/null
+++ b/code/datums/autolathe/materials.dm
@@ -0,0 +1,38 @@
+
+/datum/category_item/autolathe/materials/metal
+ name = "steel sheets"
+ path =/obj/item/stack/material/steel
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+
+/datum/category_item/autolathe/materials/glass
+ name = "glass sheets"
+ path =/obj/item/stack/material/glass
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+
+/datum/category_item/autolathe/materials/rglass
+ name = "reinforced glass sheets"
+ path =/obj/item/stack/material/glass/reinforced
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+
+/datum/category_item/autolathe/materials/rods
+ name = "metal rods"
+ path =/obj/item/stack/rods
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+
+/datum/category_item/autolathe/materials/plasteel
+ name = "plasteel sheets"
+ path =/obj/item/stack/material/plasteel
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+ resources = list(MAT_PLASTEEL = 2000)
+
+/datum/category_item/autolathe/materials/plastic
+ name = "plastic sheets"
+ path =/obj/item/stack/material/plastic
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+ resources = list(MAT_PLASTIC = 2000)
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 5046575b0b..a3627ada9b 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -17,7 +17,7 @@
var/static/list/locked = list()
-/datum/datacore/proc/get_manifest(monochrome, OOC)
+/datum/datacore/proc/get_manifest(monochrome, OOC,var/snowflake = FALSE) //CHOMPStation Edit
var/list/heads = new()
var/list/sec = new()
var/list/eng = new()
@@ -40,8 +40,9 @@
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: [OOC?"#373737; color:white":"#DEF"]"]}
+ [snowflake?"| Online players: [TGS_CLIENT_COUNT] |
|---|
| Crew members: [data_core.general.len] |
|---|
":""]
| Name | Rank | Activity |
- "}
+ "} //Also a chompstation edit with the snowflake stuff on line 43
var/even = 0
// sort mobs
for(var/datum/data/record/t in data_core.general)
@@ -114,7 +115,7 @@
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones, and no AI shells.
- if(!robot.scrambledcodes && !robot.shell && !(robot.module && robot.module.hide_on_manifest))
+ if(!robot.scrambledcodes && !robot.shell && !(robot.module && robot.module.hide_on_manifest()))
bot[robot.name] = "[robot.modtype] [robot.braintype]"
@@ -275,7 +276,7 @@ var/global/list/PDA_Manifest = list()
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones, and no AI shells.
- if(robot.scrambledcodes || robot.shell || (robot.module && robot.module.hide_on_manifest))
+ if(robot.scrambledcodes || robot.shell || (robot.module && robot.module.hide_on_manifest()))
continue
bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active")
@@ -301,7 +302,7 @@ var/global/list/PDA_Manifest = list()
manifest_inject(H)
return
-/datum/datacore/proc/manifest_modify(var/name, var/assignment)
+/datum/datacore/proc/manifest_modify(var/name, var/assignment, var/rank)
ResetPDAManifest()
var/datum/data/record/foundrecord
var/real_title = assignment
@@ -315,11 +316,17 @@ var/global/list/PDA_Manifest = list()
var/list/all_jobs = get_job_datums()
for(var/datum/job/J in all_jobs)
- var/list/alttitles = get_alternate_titles(J.title)
- if(!J) continue
- if(assignment in alttitles)
- real_title = J.title
+ if(J.title == rank) //If we have a rank, just default to using that.
+ real_title = rank
break
+ else if(J.title == assignment)
+ real_title = assignment
+ break
+ else
+ var/list/alttitles = get_alternate_titles(J.title)
+ if(assignment in alttitles)
+ real_title = J.title
+ break
if(foundrecord)
foundrecord.fields["rank"] = assignment
@@ -329,10 +336,10 @@ var/global/list/PDA_Manifest = list()
if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1))
var/assignment = GetAssignment(H)
var/hidden
- var/datum/job/J = SSjob.get_job(assignment)
+ var/datum/job/J = SSjob.get_job(H.mind.assigned_role)
hidden = J?.offmap_spawn
- /* Note: Due to cached_character_icon, a number of emergent properties occur due to the initialization
+ /* Note: Due to cached_character_icon, a number of emergent properties occur due to the initialization
* order of readied-up vs latejoiners. Namely, latejoiners will get a uniform in their datacore picture, but readied-up will
* not. This is due to the fact that SSticker calls data_core.manifest_inject() inside of ticker/proc/create_characters(),
* but does not equip them until ticker/proc/equip_characters(), which is called later. So, this proc is literally called before
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 7cfac614e6..6f85193173 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -47,7 +47,7 @@ GLOBAL_DATUM(revdata, /datum/getrev)
. += "The following pull requests are currently test merged:"
for(var/line in testmerge)
var/datum/tgs_revision_information/test_merge/tm = line
- var/cm = tm.pull_request_commit
+ var/cm = tm.head_commit //CHOMPStation Edit TGS4
var/details = ": '" + html_encode(tm.title) + "' by " + html_encode(tm.author) + " at commit " + html_encode(copytext_char(cm, 1, 11))
if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder))
continue
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index bca9df5ae1..82e5f1f78b 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -55,6 +55,9 @@
var/rev_cooldown = 0
var/tcrystals = 0
+ var/list/purchase_log = new
+ var/used_TC = 0
+
// the world.time since the mob has been brigged, or -1 if not at all
var/brigged_since = -1
@@ -73,7 +76,7 @@
/datum/mind/New(var/key)
src.key = key
-
+ purchase_log = list()
..()
/datum/mind/proc/transfer_to(mob/living/new_character)
@@ -510,8 +513,9 @@
//HUMAN
/mob/living/carbon/human/mind_initialize()
- ..()
- if(!mind.assigned_role) mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
+ . = ..()
+ if(!mind.assigned_role)
+ mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
//slime
/mob/living/simple_mob/slime/mind_initialize()
diff --git a/code/datums/outfits/jobs/cargo.dm b/code/datums/outfits/jobs/cargo.dm
index 1b48efcb9d..e7b8701a37 100644
--- a/code/datums/outfits/jobs/cargo.dm
+++ b/code/datums/outfits/jobs/cargo.dm
@@ -24,7 +24,7 @@
l_ear = /obj/item/device/radio/headset/headset_mine
backpack = /obj/item/weapon/storage/backpack/industrial
satchel_one = /obj/item/weapon/storage/backpack/satchel/eng
- id_type = /obj/item/weapon/card/id/cargo
+ id_type = /obj/item/weapon/card/id/cargo/miner
pda_type = /obj/item/device/pda/shaftminer
backpack_contents = list(/obj/item/weapon/tool/crowbar = 1, /obj/item/weapon/storage/bag/ore = 1)
flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL
diff --git a/code/datums/outfits/jobs/civilian.dm b/code/datums/outfits/jobs/civilian.dm
index c8d588a145..cda81f977f 100644
--- a/code/datums/outfits/jobs/civilian.dm
+++ b/code/datums/outfits/jobs/civilian.dm
@@ -1,6 +1,6 @@
/decl/hierarchy/outfit/job/assistant
name = OUTFIT_JOB_NAME(USELESS_JOB) //VOREStation Edit - Visitor not Assistant
- id_type = /obj/item/weapon/card/id/assistant
+ id_type = /obj/item/weapon/card/id/generic //VOREStation Edit
/decl/hierarchy/outfit/job/assistant/visitor
name = OUTFIT_JOB_NAME("Visitor")
@@ -25,7 +25,7 @@
/decl/hierarchy/outfit/job/service/bartender
name = OUTFIT_JOB_NAME("Bartender")
uniform = /obj/item/clothing/under/rank/bartender
- id_type = /obj/item/weapon/card/id/civilian
+ id_type = /obj/item/weapon/card/id/civilian/service/bartender //VOREStation Edit
pda_type = /obj/item/device/pda/bar
backpack_contents = list(/obj/item/clothing/accessory/permit/gun/bar = 1)
@@ -44,7 +44,7 @@
uniform = /obj/item/clothing/under/rank/chef
suit = /obj/item/clothing/suit/chef
head = /obj/item/clothing/head/chefhat
- id_type = /obj/item/weapon/card/id/civilian
+ id_type = /obj/item/weapon/card/id/civilian/service/chef //VOREStation Edit
pda_type = /obj/item/device/pda/chef
/decl/hierarchy/outfit/job/service/chef/cook
@@ -68,13 +68,13 @@
backpack = /obj/item/weapon/storage/backpack/hydroponics
satchel_one = /obj/item/weapon/storage/backpack/satchel/hyd
messenger_bag = /obj/item/weapon/storage/backpack/messenger/hyd
- id_type = /obj/item/weapon/card/id/civilian
+ id_type = /obj/item/weapon/card/id/civilian/service/botanist //VOREStation Edit
pda_type = /obj/item/device/pda/botanist
/decl/hierarchy/outfit/job/service/janitor
name = OUTFIT_JOB_NAME("Janitor")
uniform = /obj/item/clothing/under/rank/janitor
- id_type = /obj/item/weapon/card/id/civilian
+ id_type = /obj/item/weapon/card/id/civilian/service/janitor //VOREStation Edit
pda_type = /obj/item/device/pda/janitor
/decl/hierarchy/outfit/job/librarian
@@ -84,6 +84,9 @@
id_type = /obj/item/weapon/card/id/civilian
pda_type = /obj/item/device/pda/librarian
+/decl/hierarchy/outfit/job/librarian/journalist
+ id_type = /obj/item/weapon/card/id/civilian/journalist
+
/decl/hierarchy/outfit/job/internal_affairs_agent
name = OUTFIT_JOB_NAME("Internal affairs agent")
l_ear = /obj/item/device/radio/headset/ia
@@ -92,14 +95,14 @@
shoes = /obj/item/clothing/shoes/brown
glasses = /obj/item/clothing/glasses/sunglasses/big
l_hand = /obj/item/weapon/clipboard
- id_type = /obj/item/weapon/card/id/civilian
+ id_type = /obj/item/weapon/card/id/civilian/internal_affairs
pda_type = /obj/item/device/pda/lawyer
/decl/hierarchy/outfit/job/chaplain
name = OUTFIT_JOB_NAME("Chaplain")
uniform = /obj/item/clothing/under/rank/chaplain
l_hand = /obj/item/weapon/storage/bible
- id_type = /obj/item/weapon/card/id/civilian
+ id_type = /obj/item/weapon/card/id/civilian/chaplain
pda_type = /obj/item/device/pda/chaplain
/decl/hierarchy/outfit/job/explorer
@@ -111,7 +114,7 @@
gloves = /obj/item/clothing/gloves/black
l_ear = /obj/item/device/radio/headset
id_slot = slot_wear_id
- id_type = /obj/item/weapon/card/id/civilian
+ id_type = /obj/item/weapon/card/id/exploration //VOREStation Edit
pda_slot = slot_belt
pda_type = /obj/item/device/pda/cargo // Brown looks more rugged
r_pocket = /obj/item/device/gps/explorer
diff --git a/code/datums/outfits/jobs/civilian_vr.dm b/code/datums/outfits/jobs/civilian_vr.dm
index 7d39ae8c1b..3acfffdfd1 100644
--- a/code/datums/outfits/jobs/civilian_vr.dm
+++ b/code/datums/outfits/jobs/civilian_vr.dm
@@ -1,5 +1,5 @@
/decl/hierarchy/outfit/job/assistant/worker
- id_type = /obj/item/weapon/card/id/civilian
+ id_type = /obj/item/weapon/card/id/civilian/service
/decl/hierarchy/outfit/job/assistant/cargo
id_type = /obj/item/weapon/card/id/cargo
@@ -16,3 +16,6 @@
/decl/hierarchy/outfit/job/assistant/officer
id_type = /obj/item/weapon/card/id/security
+
+/decl/hierarchy/outfit/job/assistant/entertainer
+ id_type = /obj/item/weapon/card/id/civilian/entertainer
diff --git a/code/datums/outfits/jobs/command_vr.dm b/code/datums/outfits/jobs/command_vr.dm
new file mode 100644
index 0000000000..5e90123ffc
--- /dev/null
+++ b/code/datums/outfits/jobs/command_vr.dm
@@ -0,0 +1,5 @@
+/decl/hierarchy/outfit/job/hop
+ id_type = /obj/item/weapon/card/id/silver/hop
+
+/decl/hierarchy/outfit/job/secretary
+ id_type = /obj/item/weapon/card/id/silver/secretary
\ No newline at end of file
diff --git a/code/datums/outfits/jobs/engineering.dm b/code/datums/outfits/jobs/engineering.dm
index 3da60103c2..a2aba61a96 100644
--- a/code/datums/outfits/jobs/engineering.dm
+++ b/code/datums/outfits/jobs/engineering.dm
@@ -30,5 +30,5 @@
name = OUTFIT_JOB_NAME("Atmospheric technician")
uniform = /obj/item/clothing/under/rank/atmospheric_technician
belt = /obj/item/weapon/storage/belt/utility/atmostech
- id_type = /obj/item/weapon/card/id/engineering
+ id_type = /obj/item/weapon/card/id/engineering/atmos
pda_type = /obj/item/device/pda/atmos
diff --git a/code/datums/outfits/jobs/medical.dm b/code/datums/outfits/jobs/medical.dm
index ae996b2f08..6622d3b285 100644
--- a/code/datums/outfits/jobs/medical.dm
+++ b/code/datums/outfits/jobs/medical.dm
@@ -65,7 +65,7 @@
suit = /obj/item/clothing/suit/storage/toggle/labcoat/chemist
backpack = /obj/item/weapon/storage/backpack/chemistry
satchel_one = /obj/item/weapon/storage/backpack/satchel/chem
- id_type = /obj/item/weapon/card/id/medical
+ id_type = /obj/item/weapon/card/id/medical/chemist
pda_type = /obj/item/device/pda/chemist
/decl/hierarchy/outfit/job/medical/geneticist
@@ -75,7 +75,7 @@
backpack = /obj/item/weapon/storage/backpack/genetics
r_pocket = /obj/item/device/flashlight/pen
satchel_one = /obj/item/weapon/storage/backpack/satchel/gen
- id_type = /obj/item/weapon/card/id/medical
+ id_type = /obj/item/weapon/card/id/medical/geneticist
pda_type = /obj/item/device/pda/geneticist
/decl/hierarchy/outfit/job/medical/psychiatrist
@@ -83,7 +83,7 @@
uniform = /obj/item/clothing/under/rank/psych
suit = /obj/item/clothing/suit/storage/toggle/labcoat
shoes = /obj/item/clothing/shoes/laceup
- id_type = /obj/item/weapon/card/id/medical
+ id_type = /obj/item/weapon/card/id/medical/psych
/decl/hierarchy/outfit/job/medical/psychiatrist/psychologist
name = OUTFIT_JOB_NAME("Psychologist")
@@ -97,7 +97,7 @@
l_hand = /obj/item/weapon/storage/firstaid/regular
belt = /obj/item/weapon/storage/belt/medical/emt
pda_slot = slot_l_store
- id_type = /obj/item/weapon/card/id/medical
+ id_type = /obj/item/weapon/card/id/medical/emt
flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL
/decl/hierarchy/outfit/job/medical/paramedic/emt
diff --git a/code/datums/outfits/jobs/medical_vr.dm b/code/datums/outfits/jobs/medical_vr.dm
new file mode 100644
index 0000000000..e9b2c1a0d0
--- /dev/null
+++ b/code/datums/outfits/jobs/medical_vr.dm
@@ -0,0 +1,2 @@
+/decl/hierarchy/outfit/job/medical/doctor/virologist
+ id_type = /obj/item/weapon/card/id/medical/virologist
\ No newline at end of file
diff --git a/code/datums/outfits/jobs/science_vr.dm b/code/datums/outfits/jobs/science_vr.dm
new file mode 100644
index 0000000000..cf0e9e4b3a
--- /dev/null
+++ b/code/datums/outfits/jobs/science_vr.dm
@@ -0,0 +1,8 @@
+/decl/hierarchy/outfit/job/science/xenobiologist
+ id_type = /obj/item/weapon/card/id/science/xenobiologist
+
+/decl/hierarchy/outfit/job/science/xenobotanist
+ name = OUTFIT_JOB_NAME("Xenobotanist")
+ uniform = /obj/item/clothing/under/rank/scientist
+ id_type = /obj/item/weapon/card/id/science/xenobotanist
+ suit = /obj/item/clothing/suit/storage/toggle/labcoat/science
\ No newline at end of file
diff --git a/code/datums/outfits/jobs/security.dm b/code/datums/outfits/jobs/security.dm
index 50e5e479d1..63be50e21c 100644
--- a/code/datums/outfits/jobs/security.dm
+++ b/code/datums/outfits/jobs/security.dm
@@ -20,7 +20,7 @@
name = OUTFIT_JOB_NAME("Warden")
uniform = /obj/item/clothing/under/rank/warden
l_pocket = /obj/item/device/flash
- id_type = /obj/item/weapon/card/id/security
+ id_type = /obj/item/weapon/card/id/security/warden
pda_type = /obj/item/device/pda/warden
/decl/hierarchy/outfit/job/security/detective
@@ -31,7 +31,7 @@
l_pocket = /obj/item/weapon/flame/lighter/zippo
shoes = /obj/item/clothing/shoes/laceup
r_hand = /obj/item/weapon/storage/briefcase/crimekit
- id_type = /obj/item/weapon/card/id/security
+ id_type = /obj/item/weapon/card/id/security/detective
pda_type = /obj/item/device/pda/detective
backpack = /obj/item/weapon/storage/backpack
satchel_one = /obj/item/weapon/storage/backpack/satchel/norm
@@ -41,7 +41,7 @@
//VOREStation Edit - More cyberpunky
/decl/hierarchy/outfit/job/security/detective/forensic
name = OUTFIT_JOB_NAME("Forensic technician")
- head = /obj/item/clothing/head/helmet/detective_alt
+ head = null
suit = /datum/gear/uniform/detective_alt2
uniform = /obj/item/clothing/under/det
//VOREStation Edit End
diff --git a/code/datums/outfits/jobs/special_vr.dm b/code/datums/outfits/jobs/special_vr.dm
index 010010291d..6dea4e4cfa 100644
--- a/code/datums/outfits/jobs/special_vr.dm
+++ b/code/datums/outfits/jobs/special_vr.dm
@@ -19,7 +19,7 @@
back = /obj/item/weapon/storage/backpack/satchel
id_type = /obj/item/weapon/card/id/centcom/ERT
pda_type = /obj/item/device/pda/centcom
-
+
post_equip(var/mob/living/carbon/human/H)
..()
ert.add_antagonist(H.mind)
@@ -31,6 +31,7 @@
shoes = /obj/item/clothing/shoes/clown_shoes
mask = /obj/item/clothing/mask/gas/clown_hat
backpack_contents = list(/obj/item/weapon/stamp/clown = 1, /obj/item/weapon/bikehorn = 1)
+ id_type = /obj/item/weapon/card/id/civilian/clown
pda_type = /obj/item/device/pda/clown
flags = 0
@@ -41,8 +42,9 @@
head = /obj/item/clothing/head/soft/mime
mask = /obj/item/clothing/mask/gas/mime
backpack_contents = list(/obj/item/weapon/pen/crayon/mime = 1)
+ id_type = /obj/item/weapon/card/id/civilian/mime
pda_type = /obj/item/device/pda/mime
-
+
post_equip(var/mob/living/carbon/human/H)
..()
if(H.backbag == 1)
diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm
index add9b82dc9..e859a93983 100644
--- a/code/datums/outfits/outfit.dm
+++ b/code/datums/outfits/outfit.dm
@@ -39,7 +39,9 @@ var/list/outfits_decls_by_type_
var/suit_store = null
var/r_hand = null
var/l_hand = null
- var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format
+ // In the list(path=count,otherpath=count) format
+ var/list/uniform_accessories = list() // webbing, armbands etc - fits in slot_tie
+ var/list/backpack_contents = list()
var/id_type
var/id_desc
@@ -145,6 +147,12 @@ var/list/outfits_decls_by_type_
H.put_in_l_hand(new l_hand(H))
if(r_hand)
H.put_in_r_hand(new r_hand(H))
+
+ for(var/path in uniform_accessories)
+ var/number = uniform_accessories[path]
+ for(var/i=0,i[category]")
+
+ if(!LAZYLEN(cat_goals))
+ to_world("There were no assigned goals!")
+
+ else
+ for(var/datum/goal/G in cat_goals)
+ var/success = G.check_completion()
+ to_world("[success ? "[G.name]" : "[G.name]"]")
+ to_world("[G.goal_text]")
+ return 1
+
+/datum/goal
+ var/name = "goal"
+
+ var/goal_text = "Do nothing! Congratulations."
+
+ var/active_goal = FALSE
+
+ var/category = GOAL_GENERAL
+
+/datum/goal/proc/check_completion()
+ return FALSE
+
+/datum/goal/common
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+
+/datum/goal/medical
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_MEDICAL
+
+/datum/goal/security
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_SECURITY
+
+/datum/goal/engineering
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_ENGINEERING
+
+/datum/goal/cargo
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_CARGO
+
+/datum/goal/research
+ name = "goal"
+
+ goal_text = "Congratulations, you still do nothing."
+ category = GOAL_RESEARCH
diff --git a/code/datums/supplypacks/costumes_vr.dm b/code/datums/supplypacks/costumes_vr.dm
index e31fb2415a..5d65a98ca9 100644
--- a/code/datums/supplypacks/costumes_vr.dm
+++ b/code/datums/supplypacks/costumes_vr.dm
@@ -23,16 +23,16 @@
name = "Teshari smocks"
num_contained = 4
contains = list(
- /obj/item/clothing/under/seromi/smock,
- /obj/item/clothing/under/seromi/smock/white,
- /obj/item/clothing/under/seromi/smock/red,
- /obj/item/clothing/under/seromi/smock/yellow,
- /obj/item/clothing/under/seromi/smock/rainbow,
- /obj/item/clothing/under/seromi/smock/dress,
- /obj/item/clothing/under/seromi/smock/blackutilitysmock,
- /obj/item/clothing/under/seromi/smock/greydress,
- /obj/item/clothing/under/seromi/smock/blackutility,
- /obj/item/clothing/under/seromi/smock/bluegreydress
+ /obj/item/clothing/under/teshari/smock,
+ /obj/item/clothing/under/teshari/smock/white,
+ /obj/item/clothing/under/teshari/smock/red,
+ /obj/item/clothing/under/teshari/smock/yellow,
+ /obj/item/clothing/under/teshari/smock/rainbow,
+ /obj/item/clothing/under/teshari/smock/dress,
+ /obj/item/clothing/under/teshari/smock/blackutilitysmock,
+ /obj/item/clothing/under/teshari/smock/greydress,
+ /obj/item/clothing/under/teshari/smock/blackutility,
+ /obj/item/clothing/under/teshari/smock/bluegreydress
)
cost = 20
containertype = /obj/structure/closet/crate
@@ -42,18 +42,18 @@
name = "Teshari undercoats"
num_contained = 4
contains = list(
- /obj/item/clothing/under/seromi/undercoat/standard/orange_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/rainbow,
- /obj/item/clothing/under/seromi/undercoat/standard/lightgrey_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/white_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/red_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/orange,
- /obj/item/clothing/under/seromi/undercoat/standard/yellow_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/green_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/blue_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/purple_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/pink_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/brown_grey
+ /obj/item/clothing/under/teshari/undercoat/standard/orange_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/rainbow,
+ /obj/item/clothing/under/teshari/undercoat/standard/lightgrey_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/white_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/red_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/orange,
+ /obj/item/clothing/under/teshari/undercoat/standard/yellow_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/green_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/blue_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/purple_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/pink_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/brown_grey
)
cost = 20
containertype = /obj/structure/closet/crate
@@ -63,18 +63,18 @@
name = "Teshari undercoats (black)"
num_contained = 4
contains = list(
- /obj/item/clothing/under/seromi/undercoat,
- /obj/item/clothing/under/seromi/undercoat/standard/black_orange,
- /obj/item/clothing/under/seromi/undercoat/standard/black_grey,
- /obj/item/clothing/under/seromi/undercoat/standard/black_white,
- /obj/item/clothing/under/seromi/undercoat/standard/black_red,
- /obj/item/clothing/under/seromi/undercoat/standard/black,
- /obj/item/clothing/under/seromi/undercoat/standard/black_yellow,
- /obj/item/clothing/under/seromi/undercoat/standard/black_green,
- /obj/item/clothing/under/seromi/undercoat/standard/black_blue,
- /obj/item/clothing/under/seromi/undercoat/standard/black_purple,
- /obj/item/clothing/under/seromi/undercoat/standard/black_pink,
- /obj/item/clothing/under/seromi/undercoat/standard/black_brown
+ /obj/item/clothing/under/teshari/undercoat,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_orange,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_grey,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_white,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_red,
+ /obj/item/clothing/under/teshari/undercoat/standard/black,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_yellow,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_green,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_blue,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_purple,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_pink,
+ /obj/item/clothing/under/teshari/undercoat/standard/black_brown
)
cost = 20
containertype = /obj/structure/closet/crate
@@ -84,18 +84,18 @@
name = "Teshari cloaks"
num_contained = 4
contains = list(
- /obj/item/clothing/suit/storage/seromi/cloak/standard/white,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/red_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/orange_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/yellow_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/green_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/blue_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/purple_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/pink_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/brown_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/rainbow,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/orange
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/white,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/white_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/red_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/orange_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/yellow_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/green_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/blue_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/purple_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/pink_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/brown_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/rainbow,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/orange
)
cost = 40
containertype = /obj/structure/closet/crate
@@ -105,19 +105,19 @@
name = "Teshari cloaks (black)"
num_contained = 4
contains = list(
- /obj/item/clothing/suit/storage/seromi/cloak,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_red,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_orange,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_yellow,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_green,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_blue,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_purple,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_pink,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_brown,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_grey,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_white,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/black_glow,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/dark_retrowave
+ /obj/item/clothing/suit/storage/teshari/cloak,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_red,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_orange,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_yellow,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_green,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_blue,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_purple,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_pink,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_brown,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_grey,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_white,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/black_glow,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/dark_retrowave
)
cost = 40
containertype = /obj/structure/closet/crate
@@ -127,16 +127,16 @@
name = "Teshari worksuits"
num_contained = 4
contains = list(
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/blackpurple,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/blackorange,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/blackblue,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/blackgreen,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whitered,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whitepurple,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whiteorange,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whiteblue,
- /obj/item/clothing/under/seromi/undercoat/standard/worksuit/whitegreen
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/blackpurple,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/blackorange,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/blackblue,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/blackgreen,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/whitered,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/whitepurple,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/whiteorange,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/whiteblue,
+ /obj/item/clothing/under/teshari/undercoat/standard/worksuit/whitegreen
)
cost = 20
containertype = /obj/structure/closet/crate
@@ -146,18 +146,18 @@
name = "Teshari cloaks (belted)"
num_contained = 4
contains = list(
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/orange_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/rainbow,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/lightgrey_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/white_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/red_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/orange,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/yellow_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/green_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/blue_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/purple_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/pink_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/brown_grey
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/orange_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/rainbow,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/lightgrey_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/white_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/red_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/orange,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/yellow_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/green_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/blue_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/purple_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/pink_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/brown_grey
)
cost = 40
containertype = /obj/structure/closet/crate
@@ -167,20 +167,20 @@
name = "Teshari cloaks (belted, black)"
num_contained = 4
contains = list(
- /obj/item/clothing/suit/storage/seromi/beltcloak,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_orange,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_grey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_midgrey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_lightgrey,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_white,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_red,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_yellow,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_green,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_blue,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_purple,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_pink,
- /obj/item/clothing/suit/storage/seromi/beltcloak/standard/black_brown
+ /obj/item/clothing/suit/storage/teshari/beltcloak,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_orange,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_grey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_midgrey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_lightgrey,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_white,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_red,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_yellow,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_green,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_blue,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_purple,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_pink,
+ /obj/item/clothing/suit/storage/teshari/beltcloak/standard/black_brown
)
cost = 40
containertype = /obj/structure/closet/crate
diff --git a/code/datums/supplypacks/hospitality.dm b/code/datums/supplypacks/hospitality.dm
index 2771caa538..1ca6aee620 100644
--- a/code/datums/supplypacks/hospitality.dm
+++ b/code/datums/supplypacks/hospitality.dm
@@ -17,6 +17,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/patron,
/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager,
/obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/jager,
/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,
/obj/item/weapon/lipstick/random,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 2,
diff --git a/code/datums/supplypacks/materials.dm b/code/datums/supplypacks/materials.dm
index 95f15caa6d..87780766d9 100644
--- a/code/datums/supplypacks/materials.dm
+++ b/code/datums/supplypacks/materials.dm
@@ -35,6 +35,13 @@
containertype = /obj/structure/closet/crate/grayson
containername = "Plastic sheets crate"
+/datum/supply_pack/materials/copper50
+ name = "50 copper ingots"
+ contains = list(/obj/fiftyspawner/copper)
+ cost = 60
+ containertype = /obj/structure/closet/crate/grayson
+ containername = "Copper ingots crate"
+
/datum/supply_pack/materials/cardboard_sheets
contains = list(/obj/fiftyspawner/cardboard)
name = "50 cardboard sheets"
diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm
index 9bb6b1a442..eae37c5869 100644
--- a/code/datums/supplypacks/recreation.dm
+++ b/code/datums/supplypacks/recreation.dm
@@ -51,7 +51,7 @@
/obj/item/weapon/reagent_containers/glass/paint/purple,
/obj/item/weapon/reagent_containers/glass/paint/black,
/obj/item/weapon/reagent_containers/glass/paint/white,
- /obj/item/weapon/contraband/poster,
+ /obj/item/weapon/contraband/poster/custom,
/obj/item/weapon/wrapping_paper = 3
)
cost = 10
diff --git a/code/datums/supplypacks/recreation_vr.dm b/code/datums/supplypacks/recreation_vr.dm
index 5c2266523f..8eb64c7c29 100644
--- a/code/datums/supplypacks/recreation_vr.dm
+++ b/code/datums/supplypacks/recreation_vr.dm
@@ -20,7 +20,7 @@
/obj/item/clothing/suit/straight_jacket,
/obj/item/weapon/handcuffs/legcuffs/fuzzy,
/obj/item/weapon/melee/fluff/holochain/mass,
- /obj/item/weapon/material/twohanded/fluff/riding_crop,
+ /obj/item/weapon/material/twohanded/riding_crop,
/obj/item/clothing/under/fluff/latexmaid
)
containertype = /obj/structure/closet/crate
@@ -86,3 +86,23 @@
containertype = /obj/structure/closet/crate
containername = "Shiny clothes crate"
cost = 30
+
+//3/19/21
+/datum/supply_pack/recreation/smoleworld
+ name = "Smole Bulding Bricks"
+ contains = list(
+ /obj/item/weapon/storage/smolebrickcase, /obj/item/weapon/storage/smolebrickcase,
+ )
+ cost = 50
+ containertype = /obj/structure/closet/crate
+ containername = "Smole Bulding Brick crate"
+
+/datum/supply_pack/recreation/smolesnackplanets
+ name = "Snack planets pack"
+ num_contained = 4
+ contains = list(
+ /obj/item/weapon/storage/bagoplanets, /obj/item/weapon/storage/bagoplanets
+ )
+ cost = 25
+ containertype = /obj/structure/closet/crate
+ containername = "Snack planets crate"
diff --git a/code/datums/supplypacks/robotics.dm b/code/datums/supplypacks/robotics.dm
index 5f8cf6337c..1928ee7db6 100644
--- a/code/datums/supplypacks/robotics.dm
+++ b/code/datums/supplypacks/robotics.dm
@@ -189,6 +189,17 @@
containername = "Jumper kit crate"
access = access_robotics
+/datum/supply_pack/robotics/restrainingbolt
+ name = "Restraining bolt crate"
+ contains = list(
+ /obj/item/weapon/implanter = 1,
+ /obj/item/weapon/implantcase/restrainingbolt = 2
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate/secure/cybersolutions
+ containername = "Restraining bolt crate"
+ access = access_robotics
+
/datum/supply_pack/robotics/bike
name = "Spacebike Crate"
contains = list()
diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm
index 5fd24a473f..32c847ece2 100644
--- a/code/datums/supplypacks/security.dm
+++ b/code/datums/supplypacks/security.dm
@@ -281,10 +281,7 @@
name = "Armor - Riot plates"
contains = list(
/obj/item/clothing/head/helmet/riot,
- /obj/item/clothing/suit/armor/pcarrier,
- /obj/item/clothing/accessory/armor/armorplate/riot,
- /obj/item/clothing/accessory/armor/armguards/riot,
- /obj/item/clothing/accessory/armor/legguards/riot
+ /obj/item/clothing/suit/armor/pcarrier/riot/full
)
cost = 40
containertype = /obj/structure/closet/crate/secure/lawson
@@ -308,10 +305,7 @@
name = "Armor - Ablative plates"
contains = list(
/obj/item/clothing/head/helmet/laserproof,
- /obj/item/clothing/suit/armor/pcarrier,
- /obj/item/clothing/accessory/armor/armorplate/laserproof,
- /obj/item/clothing/accessory/armor/armguards/laserproof,
- /obj/item/clothing/accessory/armor/legguards/laserproof
+ /obj/item/clothing/suit/armor/pcarrier/laserproof/full
)
cost = 50
containertype = /obj/structure/closet/crate/secure/lawson
@@ -336,10 +330,7 @@
name = "Armor - Ballistic plates"
contains = list(
/obj/item/clothing/head/helmet/bulletproof,
- /obj/item/clothing/suit/armor/pcarrier,
- /obj/item/clothing/accessory/armor/armorplate/bulletproof,
- /obj/item/clothing/accessory/armor/armguards/bulletproof,
- /obj/item/clothing/accessory/armor/legguards/bulletproof
+ /obj/item/clothing/suit/armor/pcarrier/bulletproof/full
)
cost = 50
containertype = /obj/structure/closet/crate/secure/heph
diff --git a/code/datums/underwear/undershirts.dm b/code/datums/underwear/undershirts.dm
index 7da82fa580..6b2cc3d10f 100644
--- a/code/datums/underwear/undershirts.dm
+++ b/code/datums/underwear/undershirts.dm
@@ -186,4 +186,14 @@
/datum/category_item/underwear/undershirt/pinkblack_tshirt
name = "Pink and Black T-Shirt"
- icon_state = "pinkblack_tshirt"
\ No newline at end of file
+ icon_state = "pinkblack_tshirt"
+
+/datum/category_item/underwear/undershirt/turtle
+ name = "Turtleneck"
+ icon_state = "turtleneck"
+ has_color = TRUE
+
+/datum/category_item/underwear/undershirt/sleevelessturtle
+ name = "Turtleneck, Sleeveless"
+ icon_state = "sleevelessturtle"
+ has_color = TRUE
\ No newline at end of file
diff --git a/code/datums/uplink/badassery.dm b/code/datums/uplink/badassery.dm
index 65f71f2584..8addcc3f64 100644
--- a/code/datums/uplink/badassery.dm
+++ b/code/datums/uplink/badassery.dm
@@ -22,22 +22,22 @@
desc = "Buys you one random item."
/datum/uplink_item/item/badassery/random_one/buy(var/obj/item/device/uplink/U, var/mob/user)
- var/datum/uplink_item/item = default_uplink_selection.get_random_item(U.uses)
+ var/datum/uplink_item/item = default_uplink_selection.get_random_item((user ? user.mind.tcrystals : DEFAULT_TELECRYSTAL_AMOUNT), U)
return item.buy(U, user)
-/datum/uplink_item/item/badassery/random_one/can_buy(obj/item/device/uplink/U)
- return default_uplink_selection.get_random_item(U.uses, U) != null
+/datum/uplink_item/item/badassery/random_one/can_buy(var/obj/item/device/uplink/U, var/telecrystals)
+ return default_uplink_selection.get_random_item(telecrystals, U) != null
/datum/uplink_item/item/badassery/random_many
name = "Random Items"
desc = "Buys you as many random items you can afford. Convenient packaging NOT included."
-/datum/uplink_item/item/badassery/random_many/cost(var/telecrystals)
+/datum/uplink_item/item/badassery/random_many/cost(obj/item/device/uplink/U, var/telecrystals)
return max(1, telecrystals)
-/datum/uplink_item/item/badassery/random_many/get_goods(var/obj/item/device/uplink/U, var/loc)
+/datum/uplink_item/item/badassery/random_many/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/M)
var/list/bought_items = list()
- for(var/datum/uplink_item/UI in get_random_uplink_items(U, U.uses, loc))
+ for(var/datum/uplink_item/UI in get_random_uplink_items(U, M.mind.tcrystals, loc))
UI.purchase_log(U)
var/obj/item/I = UI.get_goods(U, loc)
if(istype(I))
@@ -47,7 +47,7 @@
/datum/uplink_item/item/badassery/random_many/purchase_log(obj/item/device/uplink/U)
feedback_add_details("traitor_uplink_items_bought", "[src]")
- log_and_message_admins("used \the [U.loc] to buy \a [src]")
+ log_and_message_admins("used \the [U.loc] to buy \a [src] at random")
/****************
* Surplus Crate *
diff --git a/code/datums/uplink/telecrystals.dm b/code/datums/uplink/telecrystals.dm
index f814b55232..66a099581e 100644
--- a/code/datums/uplink/telecrystals.dm
+++ b/code/datums/uplink/telecrystals.dm
@@ -5,8 +5,8 @@
category = /datum/uplink_category/telecrystals
blacklisted = 1
-/datum/uplink_item/item/telecrystal/get_goods(var/obj/item/device/uplink/U, var/loc)
- return new /obj/item/stack/telecrystal(loc, cost(U.uses))
+/datum/uplink_item/item/telecrystal/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/M)
+ return new /obj/item/stack/telecrystal(loc, cost(U, M.mind.tcrystals))
/datum/uplink_item/item/telecrystal/one
name = "Telecrystal - 01"
@@ -35,5 +35,5 @@
/datum/uplink_item/item/telecrystal/all
name = "Telecrystals - Empty Uplink"
-/datum/uplink_item/item/telecrystal/all/cost(var/telecrystals)
- return max(1, telecrystals)
\ No newline at end of file
+/datum/uplink_item/item/telecrystal/all/cost(obj/item/device/uplink/U, mob/M)
+ return max(1, M.mind.tcrystals)
\ No newline at end of file
diff --git a/code/datums/uplink/tools_vr.dm b/code/datums/uplink/tools_vr.dm
index 871bfbb5ad..ad68f76922 100644
--- a/code/datums/uplink/tools_vr.dm
+++ b/code/datums/uplink/tools_vr.dm
@@ -41,6 +41,11 @@
item_cost = 10
path = /obj/item/clothing/suit/space/void/autolok
+/datum/uplink_item/item/tools/inflatable
+ name = "Inflatables"
+ item_cost = 10
+ path = /obj/item/weapon/storage/briefcase/inflatable
+
/datum/uplink_item/item/tools/elitetablet
name = "Tablet (Advanced)"
item_cost = 15
diff --git a/code/datums/uplink/uplink_categories.dm b/code/datums/uplink/uplink_categories.dm
index d9e6d84db7..f7236ddbb0 100644
--- a/code/datums/uplink/uplink_categories.dm
+++ b/code/datums/uplink/uplink_categories.dm
@@ -6,12 +6,6 @@
..()
items = list()
-/datum/uplink_category/proc/can_view(obj/item/device/uplink/U)
- for(var/datum/uplink_item/item in items)
- if(item.can_view(U))
- return 1
- return 0
-
datum/uplink_category/ammunition
name = "Ammunition"
diff --git a/code/datums/uplink/uplink_items.dm b/code/datums/uplink/uplink_items.dm
index a4434be0df..966884aaff 100644
--- a/code/datums/uplink/uplink_items.dm
+++ b/code/datums/uplink/uplink_items.dm
@@ -31,7 +31,7 @@ var/datum/uplink/uplink = new()
var/item_cost = 0
var/datum/uplink_category/category // Item category
var/list/datum/antagonist/antag_roles // Antag roles this item is displayed to. If empty, display to all.
- var/blacklisted = 0
+ var/blacklisted = FALSE
/datum/uplink_item/item
var/path = null
@@ -48,50 +48,34 @@ var/datum/uplink/uplink = new()
if(!extra_args)
return
- if(!can_buy(U))
+ if(!can_buy(U, user.mind.tcrystals))
return
- if(U.tgui_status(user, GLOB.tgui_inventory_state) != STATUS_INTERACTIVE)
+ if(U.tgui_status(user, GLOB.tgui_deep_inventory_state) != STATUS_INTERACTIVE)
return
- var/cost = cost(U.uses, U)
+ var/cost = cost(U, user.mind.tcrystals)
var/goods = get_goods(U, get_turf(user), user, extra_args)
if(!goods)
return
- purchase_log(U)
+ purchase_log(user)
user.mind.tcrystals -= cost
- U.used_TC += cost
+ user.mind.used_TC += cost
return goods
// Any additional arguments you wish to send to the get_goods
/datum/uplink_item/proc/extra_args(var/mob/user)
- return 1
+ return TRUE
-/datum/uplink_item/proc/can_buy(obj/item/device/uplink/U)
- if(cost(U.uses, U) > U.uses)
- return 0
+/datum/uplink_item/proc/can_buy(var/obj/item/device/uplink/U, var/telecrystals)
+ if(cost(U, telecrystals) > telecrystals)
+ return FALSE
- return can_view(U)
+ return TRUE
-/datum/uplink_item/proc/can_view(obj/item/device/uplink/U)
- // Making the assumption that if no uplink was supplied, then we don't care about antag roles
- if(!U || !antag_roles.len)
- return 1
-
- // With no owner, there's no need to check antag status.
- if(!U.uplink_owner)
- return 0
-
- for(var/antag_role in antag_roles)
- var/datum/antagonist/antag = all_antag_types[antag_role]
- if(!isnull(antag))
- if(antag.is_antagonist(U.uplink_owner))
- return 1
- return 0
-
-/datum/uplink_item/proc/cost(var/telecrystals, obj/item/device/uplink/U)
+/datum/uplink_item/proc/cost(obj/item/device/uplink/U, mob/M)
. = item_cost
if(U)
. = U.get_item_cost(src, .)
@@ -100,19 +84,19 @@ var/datum/uplink/uplink = new()
return desc
// get_goods does not necessarily return physical objects, it is simply a way to acquire the uplink item without paying
-/datum/uplink_item/proc/get_goods(var/obj/item/device/uplink/U, var/loc)
- return 0
+/datum/uplink_item/proc/get_goods(var/obj/item/device/uplink/U, var/loc, mob/user)
+ return FALSE
/datum/uplink_item/proc/log_icon()
return
-/datum/uplink_item/proc/purchase_log(obj/item/device/uplink/U)
+/datum/uplink_item/proc/purchase_log(mob/M)
feedback_add_details("traitor_uplink_items_bought", "[src]")
- log_and_message_admins("used \the [U.loc] to buy \a [src]")
- U.purchase_log[src] = U.purchase_log[src] + 1
+ log_and_message_admins("\the [M] bought \a [src] through the uplink")
+ M.mind.purchase_log[src] += 1
datum/uplink_item/dd_SortValue()
- return cost(INFINITY)
+ return item_cost
/********************************
* *
@@ -133,7 +117,7 @@ datum/uplink_item/dd_SortValue()
A.put_in_any_hand_if_possible(I)
return I
-/datum/uplink_item/item/get_goods(var/obj/item/device/uplink/U, var/loc)
+/datum/uplink_item/item/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user)
var/obj/item/I = new path(loc)
return I
@@ -208,7 +192,7 @@ datum/uplink_item/dd_SortValue()
/proc/get_surplus_items(var/obj/item/device/uplink/U, var/remaining_TC, var/loc)
var/list/bought_items = list()
- var/override = 1
+ var/override = TRUE
while(remaining_TC)
var/datum/uplink_item/I = all_uplink_selection.get_random_item(remaining_TC, U, bought_items, override)
if(!I)
diff --git a/code/game/antagonist/alien/xenomorph.dm b/code/game/antagonist/alien/xenomorph.dm
index e69db8aee7..fa64c879d4 100644
--- a/code/game/antagonist/alien/xenomorph.dm
+++ b/code/game/antagonist/alien/xenomorph.dm
@@ -3,8 +3,8 @@ var/datum/antagonist/xenos/xenomorphs
/datum/antagonist/xenos
id = MODE_XENOMORPH
role_type = BE_ALIEN
- role_text = "Xenomorph"
- role_text_plural = "Xenomorphs"
+ role_text = "Genaprawn" //CHOMPedit
+ role_text_plural = "Genaprawns" //CHOMPedit
mob_path = /mob/living/carbon/alien/larva
bantype = "Xenomorph"
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm
index 8d8e484fae..99216b9ef5 100644
--- a/code/game/antagonist/antagonist_print.dm
+++ b/code/game/antagonist/antagonist_print.dm
@@ -1,7 +1,7 @@
/datum/antagonist/proc/print_player_summary()
if(!current_antagonists.len)
- return 0
+ return FALSE
var/text = "
The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:"
for(var/datum/mind/P in current_antagonists)
@@ -21,7 +21,7 @@
else
text += "Fail."
feedback_add_details(feedback_tag,"[O.type]|FAIL")
- failed = 1
+ failed = TRUE
num++
if(failed)
text += " The [role_text] has failed."
@@ -32,7 +32,7 @@
text += " Their objectives were:"
var/num = 1
for(var/datum/objective/O in global_objectives)
- text += print_objective(O, num, 1)
+ text += print_objective(O, num, TRUE)
num++
// Display the results.
@@ -68,14 +68,14 @@
/datum/antagonist/proc/print_player_full(var/datum/mind/ply)
var/text = print_player_lite(ply)
- var/TC_uses = 0
- var/uplink_true = 0
+ var/TC_uses = FALSE
+ var/uplink_true = FALSE
var/purchases = ""
- for(var/obj/item/device/uplink/H in GLOB.world_uplinks)
- if(H && H.uplink_owner && H.uplink_owner == ply)
- TC_uses += H.used_TC
- uplink_true = 1
- purchases += get_uplink_purchases(H)
+ for(var/mob/M in player_list)
+ if(M.mind && M.mind.used_TC)
+ TC_uses += M.mind.used_TC
+ uplink_true = TRUE
+ purchases += get_uplink_purchases(M.mind)
if(uplink_true)
text += " (used [TC_uses] TC)"
if(purchases)
@@ -83,18 +83,8 @@
return text
-/proc/print_ownerless_uplinks()
- var/has_printed = 0
- for(var/obj/item/device/uplink/H in GLOB.world_uplinks)
- if(isnull(H.uplink_owner) && H.used_TC)
- if(!has_printed)
- has_printed = 1
- to_world("Ownerless Uplinks")
- to_world("[H.loc] (used [H.used_TC] TC)")
- to_world(get_uplink_purchases(H))
-
-/proc/get_uplink_purchases(var/obj/item/device/uplink/H)
+/proc/get_uplink_purchases(var/datum/mind/M)
var/list/refined_log = new()
- for(var/datum/uplink_item/UI in H.purchase_log)
- refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]")
+ for(var/datum/uplink_item/UI in M.purchase_log)
+ refined_log.Add("[M.purchase_log[UI]]x[UI.log_icon()][UI.name]")
. = english_list(refined_log, nothing_text = "")
diff --git a/code/game/area/Space Station 13 areas_vr.dm b/code/game/area/Space Station 13 areas_vr.dm
index d9a132cd4f..cdc5ffe96c 100644
--- a/code/game/area/Space Station 13 areas_vr.dm
+++ b/code/game/area/Space Station 13 areas_vr.dm
@@ -177,3 +177,9 @@
/area/engineering/engine_gas
name = "\improper Engine Gas Storage"
icon_state = "engine_waste"
+
+//holodeck 3/29/21
+/area/holodeck/source_smoleworld
+ name = "\improper Holodeck - Smolworld"
+
+
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index f0e87cc93a..c3c1b6ce08 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -50,13 +50,12 @@
var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf
var/forbid_events = FALSE // If true, random events will not start inside this area.
var/no_spoilers = FALSE // If true, makes it much more difficult to see what is inside an area with things like mesons.
+ var/soundproofed = FALSE // If true, blocks sounds from other areas and prevents hearers on other areas from hearing the sounds within.
/area/Initialize()
. = ..()
-
luminosity = !(dynamic_lighting)
icon_state = ""
-
return INITIALIZE_HINT_LATELOAD // Areas tradiationally are initialized AFTER other atoms.
/area/LateInitialize()
@@ -67,7 +66,6 @@
power_change() // all machines set to current power level, also updates lighting icon
if(no_spoilers)
set_spoiler_obfuscation(TRUE)
- return INITIALIZE_HINT_LATELOAD
// Changes the area of T to A. Do not do this manually.
// Area is expected to be a non-null instance.
@@ -379,9 +377,9 @@ var/list/mob/living/forced_ambiance_list = new
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance)))
return
-
+
var/volume_mod = L.get_preference_volume_channel(VOLUME_CHANNEL_AMBIENCE)
-
+
// If we previously were in an area with force-played ambiance, stop it.
if((L in forced_ambiance_list) && initial)
L << sound(null, channel = CHANNEL_AMBIENCE_FORCED)
@@ -399,7 +397,7 @@ var/list/mob/living/forced_ambiance_list = new
L << chosen_ambiance
else
L << sound(null, channel = CHANNEL_AMBIENCE_FORCED)
- else if(src.ambience.len)
+ else if(src.ambience && src.ambience.len)
var/ambience_odds = L?.client.prefs.ambience_chance
if(prob(ambience_odds) && (world.time >= L.client.time_last_ambience_played + 1 MINUTE))
var/sound = pick(ambience)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 5ec5af0e6b..c20c29be7b 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -627,7 +627,7 @@
speech_bubble_hearers += M.client
if(length(speech_bubble_hearers))
- var/image/I = image('icons/mob/talk.dmi', src, "[bubble_icon][say_test(message)]", FLY_LAYER)
+ var/image/I = generate_speech_bubble(src, "[bubble_icon][say_test(message)]", FLY_LAYER)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index bf5fc0ab18..645194543f 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -134,7 +134,7 @@
for(var/i in loc)
var/atom/movable/thing = i
// We don't call parent so we are calling this for byond
- thing.Crossed(src)
+ thing.Crossed(src, oldloc)
// We're a multi-tile object (multiple locs)
else if(. && newloc)
@@ -303,6 +303,8 @@
if(AM == src)
continue
AM.Uncrossed(src)
+ if(loc != destination) // Uncrossed() triggered a separate movement
+ return
// Information about turf and z-levels for source and dest collected
var/turf/oldturf = get_turf(oldloc)
@@ -327,6 +329,8 @@
if(AM == src)
continue
AM.Crossed(src, oldloc)
+ if(loc != destination) // Crossed triggered a separate movement
+ return
// Call our thingy to inform everyone we moved
Moved(oldloc, NONE, TRUE)
@@ -462,6 +466,8 @@
minor_dir = dx
minor_dist = dist_x
+ range = min(dist_x + dist_y, range)
+
while(src && target && src.throwing && istype(src.loc, /turf) \
&& ((abs(target.x - src.x)+abs(target.y - src.y) > 0 && dist_travelled < range) \
|| (a && a.has_gravity == 0) \
@@ -685,3 +691,6 @@
selfimage.loc = src
return selfimage
+
+/atom/movable/proc/get_cell()
+ return
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index 34180bf329..60015e8427 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -118,6 +118,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
var/base_species = "Human"
var/list/species_traits = list()
var/blood_color = "#A10808"
+ var/custom_say
+ var/custom_ask
+ var/custom_whisper
+ var/custom_exclaim
// VOREStation
// New stuff
@@ -139,6 +143,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
new_dna.custom_species=custom_species //VOREStaton Edit
new_dna.species_traits=species_traits.Copy() //VOREStation Edit
new_dna.blood_color=blood_color //VOREStation Edit
+ new_dna.custom_say=custom_say //VOREStaton Edit
+ new_dna.custom_ask=custom_ask //VOREStaton Edit
+ new_dna.custom_whisper=custom_whisper //VOREStaton Edit
+ new_dna.custom_exclaim=custom_exclaim //VOREStaton Edit
for(var/b=1;b<=DNA_SE_LENGTH;b++)
new_dna.SE[b]=SE[b]
if(b<=DNA_UI_LENGTH)
@@ -200,15 +208,15 @@ var/global/list/datum/dna/gene/dna_genes[0]
size_multiplier = player_sizes_list.Find(N)
break
- var/taurtype = /datum/sprite_accessory/tail/taur/spider
- if(istype(character.tail_style, taurtype))
- character.verbs += /mob/living/proc/weaveWebBindings
-
// Technically custom_species is not part of the UI, but this place avoids merge problems.
src.custom_species = character.custom_species
src.base_species = character.species.base_species
src.blood_color = character.species.blood_color
src.species_traits = character.species.traits.Copy()
+ src.custom_say = character.custom_say
+ src.custom_ask = character.custom_ask
+ src.custom_whisper = character.custom_whisper
+ src.custom_exclaim = character.custom_exclaim
// +1 to account for the none-of-the-above possibility
SetUIValueRange(DNA_UI_EAR_STYLE, ear_style + 1, ear_styles_list.len + 1, 1)
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index 758f74d873..d250c441ad 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -237,6 +237,10 @@
// Technically custom_species is not part of the UI, but this place avoids merge problems.
H.custom_species = dna.custom_species
+ H.custom_say = dna.custom_say
+ H.custom_ask = dna.custom_ask
+ H.custom_whisper = dna.custom_whisper
+ H.custom_exclaim = dna.custom_exclaim
H.species.blood_color = dna.blood_color
var/datum/species/S = H.species
S.produceCopy(dna.base_species,dna.species_traits,src)
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index bbf4bfb343..241d613275 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -34,7 +34,7 @@
var/last_activation = 0
/obj/structure/cult/pylon/Initialize()
- ..()
+ . = ..()
START_PROCESSING(SSobj, src)
/obj/structure/cult/pylon/attack_hand(mob/M as mob)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 8708d8b9f2..0fc08f66c1 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -292,7 +292,6 @@ var/global/list/additional_antag_types = list()
antag.check_victory()
antag.print_player_summary()
sleep(10)
- print_ownerless_uplinks()
var/clients = 0
var/surviving_humans = 0
diff --git a/code/game/gamemodes/technomancer/core_obj.dm b/code/game/gamemodes/technomancer/core_obj.dm
index a943330ff6..7d00e82ecc 100644
--- a/code/game/gamemodes/technomancer/core_obj.dm
+++ b/code/game/gamemodes/technomancer/core_obj.dm
@@ -13,7 +13,7 @@
TECH_COMBAT = 7, TECH_MAGNET = 9, TECH_DATA = 5
)
sprite_sheets = list(
- "Teshari" = 'icons/mob/species/seromi/back.dmi'
+ SPECIES_TESHARI = 'icons/mob/species/teshari/back.dmi'
)
var/energy = 10000
var/max_energy = 10000
diff --git a/code/game/gamemodes/technomancer/instability.dm b/code/game/gamemodes/technomancer/instability.dm
index 6dc3f2d52b..8b4e1f2767 100644
--- a/code/game/gamemodes/technomancer/instability.dm
+++ b/code/game/gamemodes/technomancer/instability.dm
@@ -273,6 +273,7 @@
var/outgoing_instability = (amount) * ( 1 / (radius**2) )
L.receive_radiated_instability(outgoing_instability)
+ src.adjust_instability(-outgoing_instability) //This should prevent feedback loops
// This should only be used for EXTERNAL sources of instability, such as from someone or something glowing.
/mob/living/proc/receive_radiated_instability(amount)
diff --git a/code/game/gamemodes/technomancer/spells/apportation.dm b/code/game/gamemodes/technomancer/spells/apportation.dm
index 452ddc52fa..13f893b536 100644
--- a/code/game/gamemodes/technomancer/spells/apportation.dm
+++ b/code/game/gamemodes/technomancer/spells/apportation.dm
@@ -44,7 +44,7 @@
src.loc = null
user.put_in_hands(I)
user.visible_message("\A [I] appears in \the [user]'s hand!")
- log_and_message_admins("has stolen [I] with [src].")
+ add_attack_logs(user,I,"Stolen with [src]")
qdel(src)
//Now let's try to teleport a living mob.
else if(istype(hit_atom, /mob/living))
diff --git a/code/game/gamemodes/technomancer/spells/blink.dm b/code/game/gamemodes/technomancer/spells/blink.dm
index 100f7bfa33..0bbff7b016 100644
--- a/code/game/gamemodes/technomancer/spells/blink.dm
+++ b/code/game/gamemodes/technomancer/spells/blink.dm
@@ -68,7 +68,7 @@
else
safe_blink(AM, calculate_spell_power(3))
adjust_instability(3)
- log_and_message_admins("has blinked [AM] away.")
+ add_attack_logs(user,AM,"Blinked")
else
to_chat(user, "You need more energy to blink [AM] away!")
@@ -82,7 +82,7 @@
else
safe_blink(user, calculate_spell_power(6))
adjust_instability(1)
- log_and_message_admins("has blinked themselves away.")
+ add_attack_logs(user,user,"Blinked")
else
to_chat(user, "You need more energy to blink yourself away!")
@@ -99,6 +99,6 @@
else
safe_blink(AM, 6)
adjust_instability(2)
- log_and_message_admins("has blinked [AM] away.")
+ add_attack_logs(user,AM,"Blinked")
else
to_chat(user, "You need more energy to blink [AM] away!")
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/condensation.dm b/code/game/gamemodes/technomancer/spells/condensation.dm
index 33222455ea..226ccbed18 100644
--- a/code/game/gamemodes/technomancer/spells/condensation.dm
+++ b/code/game/gamemodes/technomancer/spells/condensation.dm
@@ -36,9 +36,9 @@
var/turf/simulated/frozen = desired_turf
frozen.freeze_floor()
if(check_for_scepter())
- log_and_message_admins("has iced the floor with [src] at [T.x],[T.y],[T.z].")
+ add_attack_logs(user,hit_atom,"Iced the floor with [src] at [T.x],[T.y],[T.z]")
else
- log_and_message_admins("has wetted the floor with [src] at [T.x],[T.y],[T.z].")
+ add_attack_logs(user,hit_atom,"Wetted the floor with [src] at [T.x],[T.y],[T.z]")
else if(hit_atom.reagents && !ismob(hit_atom)) //TODO: Something for the scepter
hit_atom.reagents.add_reagent(id = "water", amount = 60, data = null, safety = 0)
adjust_instability(5)
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/spells/control.dm b/code/game/gamemodes/technomancer/spells/control.dm
index 8c6a00c4e7..0e0cf5eb20 100644
--- a/code/game/gamemodes/technomancer/spells/control.dm
+++ b/code/game/gamemodes/technomancer/spells/control.dm
@@ -125,7 +125,7 @@
return 0
if(pay_energy(25 * controlled_mobs.len))
attack_all(L)
- log_and_message_admins("has commanded their army of [controlled_mobs.len] to attack [L].")
+ add_attack_logs(user,L,"Commanded their army of [controlled_mobs.len]")
to_chat(user, "You command your [controlled_mobs.len > 1 ? "entities" : "[controlled_mobs[1]]"] to \
attack \the [L].")
//This is to stop someone from controlling beepsky and getting him to stun someone 5 times a second.
diff --git a/code/game/gamemodes/technomancer/spells/energy_siphon.dm b/code/game/gamemodes/technomancer/spells/energy_siphon.dm
index 21f7c6e1e7..9bf8dd578f 100644
--- a/code/game/gamemodes/technomancer/spells/energy_siphon.dm
+++ b/code/game/gamemodes/technomancer/spells/energy_siphon.dm
@@ -57,7 +57,7 @@
return 0
siphoning = AM
update_icon()
- log_and_message_admins("is siphoning energy from \a [AM].")
+ add_attack_logs(user,AM,"Siphoned energy from [src]")
else
stop_siphoning()
diff --git a/code/game/gamemodes/technomancer/spells/flame_tongue.dm b/code/game/gamemodes/technomancer/spells/flame_tongue.dm
index ce38a45caa..9a52c5d82f 100644
--- a/code/game/gamemodes/technomancer/spells/flame_tongue.dm
+++ b/code/game/gamemodes/technomancer/spells/flame_tongue.dm
@@ -46,7 +46,7 @@
visible_message("\The [user] reaches out towards \the [L] with the flaming hand, and they ignite!")
to_chat(L, "You ignite!")
L.fire_act()
- log_and_message_admins("has ignited [L] with [src].")
+ add_attack_logs(user,L,"Ignited with [src]")
adjust_instability(12)
else
//This is needed in order for the welder to work, and works similarly to grippers.
diff --git a/code/game/gamemodes/technomancer/spells/illusion.dm b/code/game/gamemodes/technomancer/spells/illusion.dm
index 7405c43520..2d33f6e926 100644
--- a/code/game/gamemodes/technomancer/spells/illusion.dm
+++ b/code/game/gamemodes/technomancer/spells/illusion.dm
@@ -33,6 +33,7 @@
if(pay_energy(500))
illusion = new(T)
illusion.copy_appearance(copied)
+ illusion.copy_overlays(copied, TRUE)
to_chat(user, "An illusion of \the [copied] is made on \the [T].")
user << 'sound/effects/pop.ogg'
return 1
diff --git a/code/game/gamemodes/technomancer/spells/insert/insert.dm b/code/game/gamemodes/technomancer/spells/insert/insert.dm
index 53666c41ab..9ac0295e2b 100644
--- a/code/game/gamemodes/technomancer/spells/insert/insert.dm
+++ b/code/game/gamemodes/technomancer/spells/insert/insert.dm
@@ -45,7 +45,7 @@
return
var/obj/item/weapon/inserted_spell/inserted = new inserting(L,user,src)
inserted.spell_power_at_creation = calculate_spell_power(1.0)
- log_and_message_admins("has casted [src] on [L].")
+ add_attack_logs(user,L,"Casted [src]")
qdel(src)
/obj/item/weapon/spell/insert/on_melee_cast(atom/hit_atom, mob/user)
diff --git a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm
index 62ae49b0f0..7585c3a191 100644
--- a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm
+++ b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm
@@ -14,7 +14,7 @@
var/obj/item/projectile/new_projectile = make_projectile(spell_projectile, user)
new_projectile.old_style_target(hit_atom)
new_projectile.fire()
- log_and_message_admins("has casted [src] at \the [hit_atom].")
+ add_attack_logs(user,hit_atom,"Casted [src]")
if(fire_sound)
playsound(src, fire_sound, 75, 1)
adjust_instability(instability_per_shot)
@@ -39,4 +39,4 @@
return TRUE
return FALSE // We got dropped before the firing occured.
return TRUE // No delay, no need to check.
- return FALSE
\ No newline at end of file
+ return FALSE
diff --git a/code/game/gamemodes/technomancer/spells/reflect.dm b/code/game/gamemodes/technomancer/spells/reflect.dm
index 756e9e27fc..07f3595eda 100644
--- a/code/game/gamemodes/technomancer/spells/reflect.dm
+++ b/code/game/gamemodes/technomancer/spells/reflect.dm
@@ -62,7 +62,7 @@
spark_system.start()
playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
// now send a log so that admins don't think they're shooting themselves on purpose.
- log_and_message_admins("[user] reflected [attacker]'s attack back at them.")
+ add_attack_logs(user,attacker,"Reflected [attacker]'s attack")
if(!reflecting)
reflecting = 1
@@ -82,7 +82,7 @@
spark_system.start()
playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
- log_and_message_admins("[user] reflected [attacker]'s attack back at them.")
+ add_attack_logs(user,attacker,"Reflected [attacker]'s attack")
if(!reflecting)
reflecting = 1
diff --git a/code/game/gamemodes/technomancer/spells/warp_strike.dm b/code/game/gamemodes/technomancer/spells/warp_strike.dm
index 488214851c..83a2336ab6 100644
--- a/code/game/gamemodes/technomancer/spells/warp_strike.dm
+++ b/code/game/gamemodes/technomancer/spells/warp_strike.dm
@@ -76,5 +76,5 @@
I.afterattack(chosen_target, user)
else
chosen_target.attack_hand(user)
- log_and_message_admins("has warp striked [chosen_target].")
+ add_attack_logs(user,chosen_target,"Warp striked")
diff --git a/code/game/jobs/access_datum_vr.dm b/code/game/jobs/access_datum_vr.dm
index 16038248d0..bd3906f16c 100644
--- a/code/game/jobs/access_datum_vr.dm
+++ b/code/game/jobs/access_datum_vr.dm
@@ -27,4 +27,22 @@ var/const/access_pilot = 67
/datum/access/entertainment
id = access_entertainment
desc = "Entertainment Backstage"
- region = ACCESS_REGION_GENERAL
\ No newline at end of file
+ region = ACCESS_REGION_GENERAL
+
+/var/const/access_mime = 138
+/datum/access/mime
+ id = access_mime
+ desc = "Mime Office"
+ region = ACCESS_REGION_GENERAL
+
+/var/const/access_clown = 136
+/datum/access/clown
+ id = access_clown
+ desc = "Clown Office"
+ region = ACCESS_REGION_GENERAL
+
+/var/const/access_tomfoolery = 137
+/datum/access/tomfoolery
+ id = access_tomfoolery
+ desc = "Tomfoolery Closet"
+ region = ACCESS_REGION_GENERAL
diff --git a/code/game/jobs/job/captain_vr.dm b/code/game/jobs/job/captain_vr.dm
index 84333dad13..2f2ad0ec92 100644
--- a/code/game/jobs/job/captain_vr.dm
+++ b/code/game/jobs/job/captain_vr.dm
@@ -26,13 +26,13 @@
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_hop, access_RC_announce, access_keycard_auth)
+ access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth, access_gateway)
minimal_access = list(access_security, access_sec_doors, access_brig, access_forensics_lockers,
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_hop, access_RC_announce, access_keycard_auth)
+ access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth, access_gateway)
/datum/alt_title/deputy_director
title = "Deputy Director"
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index f84e191b54..78798a5add 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -205,6 +205,7 @@
// Librarian Alt Titles
/datum/alt_title/journalist
title = "Journalist"
+ title_outfit = /decl/hierarchy/outfit/job/librarian/journalist
title_blurb = "The Journalist uses the Library as a base of operations, from which they can report the news and goings-on on the station with their camera."
/datum/alt_title/writer
diff --git a/code/game/jobs/job/civilian_vr.dm b/code/game/jobs/job/civilian_vr.dm
index a9cfda8663..1ac859eb10 100644
--- a/code/game/jobs/job/civilian_vr.dm
+++ b/code/game/jobs/job/civilian_vr.dm
@@ -194,11 +194,13 @@
minimal_access = list(access_entertainment)
pto_type = PTO_CIVILIAN
- outfit_type = /decl/hierarchy/outfit/job/assistant
+ outfit_type = /decl/hierarchy/outfit/job/assistant/entertainer
job_description = "An entertainer does just that, entertains! Put on plays, play music, sing songs, tell stories, or read your favorite fanfic."
alt_titles = list("Performer" = /datum/alt_title/performer, "Musician" = /datum/alt_title/musician, "Stagehand" = /datum/alt_title/stagehand,
"Actor" = /datum/alt_title/actor, "Dancer" = /datum/alt_title/dancer, "Singer" = /datum/alt_title/singer,
- "Magician" = /datum/alt_title/magician, "Comedian" = /datum/alt_title/comedian, "Tragedian" = /datum/alt_title/tragedian)
+ "Magician" = /datum/alt_title/magician, "Comedian" = /datum/alt_title/comedian, "Tragedian" = /datum/alt_title/tragedian,
+ "Clown" = /datum/alt_title/clown, "Jester" = /datum/alt_title/clown/jester,"Fool" = /datum/alt_title/clown/fool,
+ "Mime"= /datum/alt_title/mime,"Poseur"= /datum/alt_title/mime/poseur) //CHOMPEDIT: Adding clown + mime and their alts as alts of entertainer
// Entertainer Alt Titles
/datum/alt_title/actor
diff --git a/code/game/jobs/job/engineering_vr.dm b/code/game/jobs/job/engineering_vr.dm
index 71bf1e9bff..928259ee60 100644
--- a/code/game/jobs/job/engineering_vr.dm
+++ b/code/game/jobs/job/engineering_vr.dm
@@ -6,12 +6,12 @@
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
access_heads, access_construction,
- access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
+ access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload, access_gateway)
minimal_access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
access_heads, access_construction,
- access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
+ access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload, access_gateway)
alt_titles = list("Head Engineer" = /datum/alt_title/head_engineer, "Foreman" = /datum/alt_title/foreman, "Maintenance Manager" = /datum/alt_title/maintenance_manager)
/datum/alt_title/head_engineer
diff --git a/code/game/jobs/job/exploration_vr.dm b/code/game/jobs/job/exploration_vr.dm
index 0e6e003f7d..3791cc24ac 100644
--- a/code/game/jobs/job/exploration_vr.dm
+++ b/code/game/jobs/job/exploration_vr.dm
@@ -1,8 +1,3 @@
-var/const/PATHFINDER =(1<<11)
-var/const/EXPLORER =(1<<12)
-var/const/PILOT =(1<<13)
-var/const/SAR =(1<<14)
-
/obj/item/weapon/card/id/medical/sar
assignment = "Field Medic"
rank = "Field Medic"
@@ -41,7 +36,7 @@ var/const/SAR =(1<<14)
faction = "Station"
total_positions = 1
spawn_positions = 1
- supervisors = "the Head of Personnel"
+ supervisors = "the Research Director" //CHOMPedit
selection_color = "#d6d05c"
economic_modifier = 8
minimal_player_age = 7
@@ -64,20 +59,20 @@ var/const/SAR =(1<<14)
/datum/job/pilot
title = "Pilot"
flag = PILOT
- departments = list(DEPARTMENT_PLANET)
- department_flag = MEDSCI
+ departments = list(DEPARTMENT_PLANET) //CHOMPedit: keep them part of exploration
+ department_flag = MEDSCI //CHOMPedit
faction = "Station"
- total_positions = 4
- spawn_positions = 4
- supervisors = "the Pathfinder and the Head of Personnel"
- selection_color = "#999440"
+ total_positions = 5
+ spawn_positions = 5
+ supervisors = "the Pathfinder" //CHOMPedit
+ selection_color = "#515151"
economic_modifier = 5
minimal_player_age = 3
pto_type = PTO_EXPLORATION
access = list(access_pilot)
minimal_access = list(access_pilot)
outfit_type = /decl/hierarchy/outfit/job/pilot
- job_description = "A Pilot flies the various shuttles in the Virgo-Erigone System."
+ job_description = "A Pilot flies the various shuttles in the Vir System." //CHOMPedit: Replaces Virgo reference with Vir.
alt_titles = list("Co-Pilot" = /datum/alt_title/co_pilot, "Navigator" = /datum/alt_title/navigator)
/datum/alt_title/co_pilot
@@ -96,7 +91,7 @@ var/const/SAR =(1<<14)
faction = "Station"
total_positions = 3
spawn_positions = 3
- supervisors = "the Pathfinder and the Head of Personnel"
+ supervisors = "the Pathfinder" //CHOMPedit
selection_color = "#999440"
economic_modifier = 6
pto_type = PTO_EXPLORATION
@@ -121,7 +116,7 @@ var/const/SAR =(1<<14)
faction = "Station"
total_positions = 2
spawn_positions = 2
- supervisors = "the Pathfinder and the Chief Medical Officer"
+ supervisors = "the Pathfinder" //CHOMPedit
selection_color = "#999440"
economic_modifier = 6
minimal_player_age = 3
diff --git a/code/game/jobs/job/medical_vr.dm b/code/game/jobs/job/medical_vr.dm
index d0d56fd7b5..120d538e4a 100644
--- a/code/game/jobs/job/medical_vr.dm
+++ b/code/game/jobs/job/medical_vr.dm
@@ -5,11 +5,11 @@
access = list(access_medical, access_medical_equip, access_morgue, access_genetics, access_heads,
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, access_teleporter, //CHOMPEdit
- access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
+ access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels, access_gateway)
minimal_access = list(access_medical, access_medical_equip, access_morgue, access_genetics, access_heads,
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, access_teleporter,//CHOMPEdit
- access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
+ access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels, access_gateway)
alt_titles = list("Chief Physician" = /datum/alt_title/chief_physician, "Medical Director" = /datum/alt_title/medical_director, /*CHOMPEdit Removal"Healthcare Manager" = /datum/alt_title/healthcare_manager*/)
/datum/alt_title/chief_physician
diff --git a/code/game/jobs/job/science_vr.dm b/code/game/jobs/job/science_vr.dm
index bfb522910c..e6ae7a1a4b 100644
--- a/code/game/jobs/job/science_vr.dm
+++ b/code/game/jobs/job/science_vr.dm
@@ -13,6 +13,9 @@
access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage,
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network,
access_explorer, access_pathfinder, access_xenobotany) //YW Edit access_gateway, _explorer, _pathfinder, and _xenobotany
+ alt_titles = list("Research Supervisor" = /datum/alt_title/research_supervisor, "Research Manager" = /datum/alt_title/research_manager,
+ "Head of Development" = /datum/alt_title/head_of_development,"Head Scientist" = /datum/alt_title/head_scientist)
+
/datum/alt_title/research_manager
title = "Research Manager"
diff --git a/code/game/jobs/job/special_vr.dm b/code/game/jobs/job/special_vr.dm
index 57f0e91d34..2f68ed7791 100644
--- a/code/game/jobs/job/special_vr.dm
+++ b/code/game/jobs/job/special_vr.dm
@@ -77,16 +77,16 @@
title = "Clown"
flag = CLOWN
departments = list(DEPARTMENT_CIVILIAN)
- department_flag = CIVILIAN
+ department_flag = ENGSEC
faction = "Station"
- total_positions = -1
- spawn_positions = -1
+ total_positions = -1 //CHOMP Edit: Disable. Change to + integer to enable.
+ spawn_positions = -1 //CHOMP Edit: Disable. Change to + integer to enable.
supervisors = "the spirit of laughter"
selection_color = "#515151"
economic_modifier = 1
job_description = "A Clown is there to entertain the crew and keep high morale using various harmless pranks and ridiculous jokes!"
whitelist_only = 1
- latejoin_only = 1
+ latejoin_only = 0
outfit_type = /decl/hierarchy/outfit/job/clown
pto_type = PTO_CIVILIAN
alt_titles = list("Jester" = /datum/alt_title/jester, "Fool" = /datum/alt_title/fool)
@@ -99,25 +99,25 @@
/datum/job/clown/get_access()
if(config.assistant_maint)
- return list(access_maint_tunnels, access_entertainment)
+ return list(access_maint_tunnels, access_entertainment, access_clown, access_tomfoolery)
else
- return list(access_entertainment)
+ return list(access_entertainment, access_clown, access_tomfoolery)
/datum/job/mime
title = "Mime"
flag = MIME
departments = list(DEPARTMENT_CIVILIAN)
- department_flag = CIVILIAN
+ department_flag = ENGSEC
faction = "Station"
- total_positions = -1
- spawn_positions = -1
+ total_positions = -1 //CHOMP Edit: Disable. Change to + integer to enable.
+ spawn_positions = -1 //CHOMP Edit: Disable. Change to + integer to enable.
supervisors = "the spirit of performance"
selection_color = "#515151"
economic_modifier = 1
job_description = "A Mime is there to entertain the crew and keep high morale using unbelievable performances and acting skills!"
alt_titles = list("Poseur" = /datum/alt_title/poseur)
whitelist_only = 1
- latejoin_only = 1
+ latejoin_only = 0
outfit_type = /decl/hierarchy/outfit/job/mime
pto_type = PTO_CIVILIAN
@@ -126,6 +126,6 @@
/datum/job/mime/get_access()
if(config.assistant_maint)
- return list(access_maint_tunnels, access_entertainment)
+ return list(access_maint_tunnels, access_entertainment, access_tomfoolery, access_mime)
else
- return list(access_entertainment)
+ return list(access_entertainment, access_tomfoolery, access_mime)
diff --git a/code/game/jobs/job/zz_alt_titles_ch.dm b/code/game/jobs/job/zz_alt_titles_ch.dm
new file mode 100644
index 0000000000..c825e0cd05
--- /dev/null
+++ b/code/game/jobs/job/zz_alt_titles_ch.dm
@@ -0,0 +1,31 @@
+/datum/job/entertainer
+ alt_titles = list("Performer" = /datum/alt_title/performer, "Musician" = /datum/alt_title/musician, "Stagehand" = /datum/alt_title/stagehand,
+ "Actor" = /datum/alt_title/actor, "Dancer" = /datum/alt_title/dancer, "Singer" = /datum/alt_title/singer,
+ "Magician" = /datum/alt_title/magician, "Comedian" = /datum/alt_title/comedian, "Tragedian" = /datum/alt_title/tragedian,
+ "Clown" = /datum/alt_title/clown, "Jester" = /datum/alt_title/clown/jester,"Fool" = /datum/alt_title/clown/fool,
+ "Mime"= /datum/alt_title/mime,"Poseur"= /datum/alt_title/mime/poseur, "Fitness Instructor" = /datum/alt_title/fitness) //CHOMPEDIT: Adding clown + mime and their alts as alts of entertainer, as well as fitness instructor
+
+/datum/alt_title/fitness
+ title = "Fitness Instructor"
+ title_blurb = "A Fitness Instructor's goal is to keep the station in shape. Get the crew shaving up those built up pounds and get them to eat something other than chocolate bars and burgers for once"
+
+//Below, well sort off, these are the clown and mime returning! as entertainer alts
+//They even get their respective outfits.
+/datum/alt_title/clown
+ title = "Clown"
+ title_blurb = "A Clown is there to entertain the crew and keep high morale using various harmless pranks and ridiculous jokes!"
+ title_outfit = /decl/hierarchy/outfit/job/clown
+
+/datum/alt_title/clown/jester
+ title = "Jester"
+
+/datum/alt_title/clown/fool
+ title = "Fool"
+
+/datum/alt_title/mime
+ title = "Mime"
+ title_blurb = "A Mime is there to entertain the crew and keep high morale using unbelievable performances and acting skills!"
+ title_outfit = /decl/hierarchy/outfit/job/mime
+
+/datum/alt_title/mime/poseur
+ title = "Poseur"
\ No newline at end of file
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 1b0a0c0b4d..24a8f79cbe 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -414,7 +414,7 @@ var/global/datum/controller/occupations/job_master
// Implants get special treatment
if(G.slot == "implant")
- var/obj/item/weapon/implant/I = G.spawn_item(H)
+ var/obj/item/weapon/implant/I = G.spawn_item(H, H.client.prefs.gear[G.display_name])
I.invisibility = 100
I.implant_loadout(H)
continue
@@ -510,22 +510,23 @@ var/global/datum/controller/occupations/job_master
to_chat(H, "Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug.")
if(istype(H)) //give humans wheelchairs, if they need them.
- if(istype(H.loc, /obj/belly)) //unless in a gut
+ if(istype(H.loc, /obj/belly)) //CHOMPedit start unless in a gut
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
var/obj/item/weapon/storage/S = locate() in H.contents
- var/obj/item/wheelchair/R = null
+ var/obj/item/wheelchair/R
if(S)
R = locate() in S.contents
if(!l_foot || !r_foot || R)
- var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc)
+ var/wheelchair_type = R?.unfolded_type || /obj/structure/bed/chair/wheelchair
+ var/obj/structure/bed/chair/wheelchair/W = new wheelchair_type(H.loc)
W.buckle_mob(H)
H.update_canmove()
W.set_dir(H.dir)
W.add_fingerprint(H)
if(R)
W.color = R.color
- qdel(R)
+ qdel(R) //CHOMPedit end
to_chat(H, "You are [job.total_positions == 1 ? "the" : "a"] [alt_title ? alt_title : rank].")
@@ -745,7 +746,7 @@ var/global/datum/controller/occupations/job_master
to_chat(C, "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead.")
var/spawning = pick(latejoin)
.["turf"] = get_turf(spawning)
- .["msg"] = "will arrive at the station shortly" //VOREStation Edit - Grammar but mostly 'shuttle' reference removal, and this also applies to notified spawn-character verb use
+ .["msg"] = "will arrive at the station shortly"
else if(!fail_deadly)
var/spawning = pick(latejoin)
.["turf"] = get_turf(spawning)
diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm
index ef104f08c9..9cb8c9c9f1 100644
--- a/code/game/jobs/jobs.dm
+++ b/code/game/jobs/jobs.dm
@@ -11,8 +11,8 @@ var/const/ENGINEER =(1<<6)
var/const/ATMOSTECH =(1<<7)
var/const/AI =(1<<8)
var/const/CYBORG =(1<<9)
-var/const/BLUESHIELD =(1<<13) //YW addition
-var/const/SECPILOT =(1<<14) //YW addition
+var/const/CLOWN =(1<<13) //VOREStation Add
+var/const/MIME =(1<<14) //VOREStation Add
var/const/INTERN =(1<<15) //VOREStation Add
var/const/MEDSCI =(1<<1)
@@ -28,7 +28,10 @@ var/const/PSYCHIATRIST =(1<<7)
var/const/ROBOTICIST =(1<<8)
var/const/XENOBIOLOGIST =(1<<9)
var/const/PARAMEDIC =(1<<10)
-var/const/XENOBOTANIST =(1<<15) //VOREStation Add
+var/const/PATHFINDER =(1<<11) //VOREStation Add
+var/const/EXPLORER =(1<<12) //VOREStation Add
+var/const/SAR =(1<<13) //VOREStation Add
+var/const/XENOBOTANIST =(1<<14) //VOREStation Add
var/const/CIVILIAN =(1<<2)
@@ -45,9 +48,8 @@ var/const/LAWYER =(1<<9)
var/const/CHAPLAIN =(1<<10)
var/const/ASSISTANT =(1<<11)
var/const/BRIDGE =(1<<12)
-var/const/CLOWN =(1<<13) //VOREStation Add
-var/const/MIME =(1<<14) //VOREStation Add
-var/const/ENTERTAINER =(1<<15) //VOREStation Add
+var/const/PILOT =(1<<13) //VOREStation Add
+var/const/ENTERTAINER =(1<<14) //VOREStation Add
var/list/assistant_occupations = list(
)
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index a97fbf986f..e0ff3a6086 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -529,5 +529,5 @@
stasis_level = 100 //Just one setting
/obj/machinery/sleeper/survival_pod/Initialize()
- ..()
+ . = ..()
RefreshParts(1)
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 267524b979..08e22f96e0 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -14,7 +14,6 @@
active_power_usage = 10000 //10 kW. It's a big all-body scanner.
light_color = "#00FF00"
var/obj/machinery/body_scanconsole/console
- var/known_implants = list(/obj/item/weapon/implant/health, /obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking, /obj/item/weapon/implant/language, /obj/item/weapon/implant/language/eal, /obj/item/weapon/implant/backup, /obj/item/device/nif) //VOREStation Add - Backup Implant, NIF
var/printing_text = null
/obj/machinery/bodyscanner/Initialize()
@@ -255,12 +254,11 @@
organData["broken"] = E.min_broken_damage
var/implantData[0]
- for(var/obj/I in E.implants)
+ for(var/obj/thing in E.implants)
var/implantSubData[0]
- implantSubData["name"] = I.name
- if(is_type_in_list(I, known_implants))
- implantSubData["known"] = 1
-
+ var/obj/item/weapon/implant/I = thing
+ implantSubData["name"] = I.name
+ implantSubData["known"] = istype(I) && I.known_implant
implantData.Add(list(implantSubData))
organData["implants"] = implantData
@@ -464,8 +462,9 @@
infected = "Gangrene Detected:"
var/unknown_body = 0
- for(var/I in e.implants)
- if(is_type_in_list(I,known_implants))
+ for(var/thing in e.implants)
+ var/obj/item/weapon/implant/I = thing
+ if(istype(I) && I.known_implant)
imp += "[I] implanted:"
else
unknown_body++
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 4351d29698..f14fe8c846 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -39,6 +39,14 @@
if(!autolathe_recipes)
autolathe_recipes = new()
wires = new(src)
+
+ for(var/Name in name_to_material)
+ if(Name in stored_material)
+ continue
+
+ stored_material[Name] = 0
+ storage_capacity[Name] = 0
+
default_apply_parts()
RefreshParts()
@@ -273,6 +281,15 @@
//Create the desired item.
var/obj/item/I = new making.path(src.loc)
+
+ if(LAZYLEN(I.matter)) // Sadly we must obey the laws of equivalent exchange.
+ I.matter.Cut()
+ else
+ I.matter = list()
+
+ for(var/material in making.resources) // Handle the datum's autoscaling for waste, so we're properly wasting material, but not so much if we have efficiency.
+ I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency)
+
flick("[initial(icon_state)]_finish", src)
if(multiplier > 1)
if(istype(I, /obj/item/stack))
@@ -280,7 +297,16 @@
S.amount = multiplier
else
for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack.
- new making.path(src.loc)
+ I = new making.path(src.loc)
+ // We've already deducted the cost of multiple items. Process the matter the same.
+ if(LAZYLEN(I.matter))
+ I.matter.Cut()
+
+ else
+ I.matter = list()
+
+ for(var/material in making.resources)
+ I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency)
return TRUE
return FALSE
@@ -306,10 +332,9 @@
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
man_rating += M.rating
- storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000
- storage_capacity[MAT_PLASTIC] = mb_rating * 20000
- storage_capacity[MAT_PLASTEEL] = mb_rating * 16250
- storage_capacity["glass"] = mb_rating * 12500
+ for(var/mat_name in storage_capacity)
+ storage_capacity[mat_name] = mb_rating * 25000
+
build_time = 50 / man_rating
mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5
update_tgui_static_data(usr)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 8ddb76c68a..2c34326fa7 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -465,6 +465,7 @@
/obj/item/weapon/implant/health
name = "health implant"
+ known_implant = TRUE
var/healthstring = ""
/obj/item/weapon/implant/health/proc/sensehealth()
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 7ff97c83e8..179f8e0e16 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -1,9 +1,8 @@
-/obj/machinery/computer/arcade/
+/obj/machinery/computer/arcade
name = "random arcade"
desc = "random arcade machine"
- icon_state = "arcade"
+ icon_state = "arcade1"
icon_keyboard = null
- icon_screen = "invaders"
clicksound = null //Gets too spammy and makes no sense for arcade to have the console keyboard noise anyway
var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2,
/obj/item/toy/blink = 2,
@@ -25,15 +24,15 @@
/obj/item/toy/stickhorse = 2
)
-/obj/machinery/computer/arcade/New()
- ..()
+/obj/machinery/computer/arcade/Initialize()
+ . = ..()
// If it's a generic arcade machine, pick a random arcade
// circuit board for it and make the new machine
if(!circuit)
var/choice = pick(subtypesof(/obj/item/weapon/circuitboard/arcade) - /obj/item/weapon/circuitboard/arcade/clawmachine)
var/obj/item/weapon/circuitboard/CB = new choice()
new CB.build_path(loc, CB)
- qdel(src)
+ return INITIALIZE_HINT_QDEL
/obj/machinery/computer/arcade/proc/prizevend()
if(!(contents-circuit).len)
@@ -77,9 +76,10 @@
///////////////////
/obj/machinery/computer/arcade/battle
- name = "arcade machine"
- desc = "Does not support Pinball."
- icon_state = "arcade"
+ name = "Battler"
+ desc = "Fight through what space has to offer!"
+ icon_state = "arcade2"
+ icon_screen = "battler"
circuit = /obj/item/weapon/circuitboard/arcade/battle
var/enemy_name = "Space Villian"
var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc
@@ -310,7 +310,8 @@
/obj/machinery/computer/arcade/orion_trail
name = "The Orion Trail"
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
- icon_state = "arcade"
+ icon_state = "arcade1"
+ icon_screen = "orion"
circuit = /obj/item/weapon/circuitboard/arcade/orion_trail
var/busy = 0 //prevent clickspam that allowed people to ~speedrun~ the game.
var/engine = 0
@@ -1318,4 +1319,18 @@
wintick = 0
gameStatus = "CLAWMACHINE_NEW"
emagged = 1
- return 1
\ No newline at end of file
+ return 1
+
+/obj/machinery/computer/arcade/attackby(obj/item/O, mob/user, params)
+ if(istype(O, /obj/item/stack/arcadeticket))
+ var/obj/item/stack/arcadeticket/T = O
+ var/amount = T.get_amount()
+ if(amount <2)
+ to_chat(user, "You need 2 tickets to claim a prize!")
+ return
+ prizevend(user)
+ T.pay_tickets()
+ T.update_icon()
+ O = T
+ to_chat(user, "You turn in 2 tickets to the [src] and claim a prize!")
+ return
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index 0f52e67b8c..c08bcb2d82 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -157,7 +157,7 @@
switch(action)
if("modify")
if(modify)
- data_core.manifest_modify(modify.registered_name, modify.assignment)
+ data_core.manifest_modify(modify.registered_name, modify.assignment, modify.rank)
modify.name = "[modify.registered_name]'s ID Card ([modify.assignment])"
if(ishuman(usr))
modify.forceMove(get_turf(src))
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index cc05d63217..5aa7f077c6 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -26,7 +26,7 @@
light_color = "#315ab4"
/obj/machinery/computer/cloning/Initialize()
- ..()
+ . = ..()
pods = list()
records = list()
set_scan_temp("Scanner ready.", "good")
@@ -380,7 +380,7 @@
return
if(isnull(subject) || (!(ishuman(subject))) || (!subject.dna))
if(isalien(subject))
- set_scan_temp("Xenomorphs are not scannable.", "bad")
+ set_scan_temp("Genaprawns are not scannable.", "bad") //CHOMPedit
SStgui.update_uis(src)
return
// can add more conditions for specific non-human messages here
diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm
index 0090d03b7a..e2e1535728 100644
--- a/code/game/machinery/computer/guestpass.dm
+++ b/code/game/machinery/computer/guestpass.dm
@@ -41,7 +41,7 @@
/obj/item/weapon/card/id/guest/attack_self(mob/living/user as mob)
if(user.a_intent == I_HURT)
- if(icon_state == "guest_invalid")
+ if(icon_state == "guest-invalid")
to_chat(user, "This guest pass is already deactivated!")
return
@@ -49,7 +49,8 @@
if(confirm == "Yes")
//rip guest pass 3
user.visible_message("\The [user] deactivates \the [src].")
- icon_state = "guest_invalid"
+ icon_state = "guest-invalid"
+ update_icon()
expiration_time = world.time
expired = 1
return ..()
@@ -66,7 +67,8 @@
/obj/item/weapon/card/id/guest/process()
if(expired == 0 && world.time >= expiration_time)
visible_message("\The [src] flashes a few times before turning red.")
- icon_state = "guest_invalid"
+ icon_state = "guest-invalid"
+ update_icon()
expired = 1
world.time = expiration_time
return
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index adf53c80a8..680ce44345 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -29,7 +29,7 @@
/obj/machinery/computer/med_data/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"sex" = "Please select new sex:",
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 1caa7b61a4..430b42591c 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -335,7 +335,7 @@
name = "Monitor Decryption Key"
/obj/item/weapon/paper/monitorkey/Initialize()
- ..() //Late init
+ ..()
return INITIALIZE_HINT_LATELOAD
/obj/item/weapon/paper/monitorkey/LateInitialize()
diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
index dbd5ba8383..5eae5e82d0 100644
--- a/code/game/machinery/computer/pod.dm
+++ b/code/game/machinery/computer/pod.dm
@@ -13,7 +13,7 @@
var/title = "Mass Driver Controls"
/obj/machinery/computer/pod/Initialize()
- ..() //Not returning parent because lateload
+ ..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/pod/LateInitialize()
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 33d37edfa6..25fe3d56db 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -15,6 +15,9 @@
var/stop = 0.0
var/screen = 0 // 0 - No Access Denied, 1 - Access allowed
+/obj/machinery/computer/prisoner/attack_ai(var/mob/user as mob)
+ return src.attack_hand(user)
+
/obj/machinery/computer/prisoner/attack_hand(mob/user)
if(..())
return
@@ -28,7 +31,7 @@
/obj/machinery/computer/prisoner/tgui_data(mob/user)
var/list/data = list()
-
+
data["locked"] = !screen
data["chemImplants"] = list()
data["trackImplants"] = list()
@@ -65,24 +68,22 @@
return data
+
/obj/machinery/computer/prisoner/tgui_act(action, list/params)
if(..())
return TRUE
-
switch(action)
if("inject")
var/obj/item/weapon/implant/I = locate(params["imp"])
if(I)
I.activate(clamp(params["val"], 0, 10))
. = TRUE
-
if("lock")
if(allowed(usr))
screen = !screen
else
to_chat(usr, "Unauthorized Access.")
. = TRUE
-
if("warn")
var/warning = sanitize(input(usr, "Message:", "Enter your message here!", ""))
if(!warning)
@@ -91,5 +92,4 @@
if(I && I.imp_in)
to_chat(I.imp_in, "You hear a voice in your head saying: '[warning]'")
. = TRUE
-
- add_fingerprint(usr)
\ No newline at end of file
+ add_fingerprint(usr)
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 1fbd897113..4222e1264c 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -25,7 +25,7 @@
var/static/list/field_edit_choices
/obj/machinery/computer/secure_data/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"name" = "Please enter new name:",
@@ -389,11 +389,11 @@
if(field == "age")
answer = text2num(answer)
-
+
if(field == "rank")
if(answer in joblist)
active1.fields["real_rank"] = answer
-
+
if(field == "criminal")
for(var/mob/living/carbon/human/H in player_list)
BITSET(H.hud_updateflag, WANTED_HUD)
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index 47b9e8ce25..e11f404b16 100644
--- a/code/game/machinery/computer/skills.dm
+++ b/code/game/machinery/computer/skills.dm
@@ -30,7 +30,7 @@
var/static/list/field_edit_choices
/obj/machinery/computer/skills/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"name" = "Please input new name:",
diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm
index 8cfc711c18..80ce7a701d 100644
--- a/code/game/machinery/computer/timeclock_vr.dm
+++ b/code/game/machinery/computer/timeclock_vr.dm
@@ -177,7 +177,7 @@
card.rank = newjob.title
card.assignment = newassignment
card.name = text("[card.registered_name]'s ID Card ([card.assignment])")
- data_core.manifest_modify(card.registered_name, card.assignment)
+ data_core.manifest_modify(card.registered_name, card.assignment, card.rank)
card.last_job_switch = world.time
callHook("reassign_employee", list(card))
newjob.current_positions++
@@ -203,7 +203,7 @@
card.rank = ptojob.title
card.assignment = ptojob.title
card.name = text("[card.registered_name]'s ID Card ([card.assignment])")
- data_core.manifest_modify(card.registered_name, card.assignment)
+ data_core.manifest_modify(card.registered_name, card.assignment, card.rank)
card.last_job_switch = world.time
callHook("reassign_employee", list(card))
var/mob/living/carbon/human/H = usr
diff --git a/code/game/machinery/computer3/computers/card.dm b/code/game/machinery/computer3/computers/card.dm
index 35eb699531..f9e43aaa7d 100644
--- a/code/game/machinery/computer3/computers/card.dm
+++ b/code/game/machinery/computer3/computers/card.dm
@@ -312,14 +312,14 @@
writer.assignment = t1
writer.name = text("[writer.registered_name]'s ID Card ([writer.assignment])")
- data_core.manifest_modify(writer.registered_name, writer.assignment)
+ data_core.manifest_modify(writer.registered_name, writer.assignment, writer.rank)
callHook("reassign_employee", list(writer))
if("reg" in href_list)
if(auth)
writer.registered_name = href_list["reg"]
writer.name = text("[writer.registered_name]'s ID Card ([writer.assignment])")
- data_core.manifest_modify(writer.registered_name, writer.assignment)
+ data_core.manifest_modify(writer.registered_name, writer.assignment, writer.rank)
callHook("reassign_employee", list(writer))
computer.updateUsrDialog()
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 2a36b5db6c..5b4305844e 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -394,6 +394,8 @@
//Drop all items into the pod.
for(var/obj/item/W in to_despawn)
+ if(istype(W,/obj/item/organ))
+ continue
to_despawn.drop_from_inventory(W)
W.forceMove(src)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index f25767059b..93d0bbb23b 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -864,14 +864,14 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/tgui_data(mob/user)
var/list/data = list()
-
+
var/list/power = list()
power["main"] = main_power_lost_until > 0 ? 0 : 2
power["main_timeleft"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1)
power["backup"] = backup_power_lost_until > 0 ? 0 : 2
power["backup_timeleft"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1)
data["power"] = power
-
+
data["shock"] = (electrified_until == 0) ? 2 : 0
data["shock_timeleft"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1)
data["id_scanner"] = !aiDisabledIdScanner
diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm
index bc9c199ed2..9d7e5ed958 100644
--- a/code/game/machinery/doors/blast_door.dm
+++ b/code/game/machinery/doors/blast_door.dm
@@ -29,6 +29,7 @@
var/close_sound = 'sound/machines/door/blastdoorclose.ogg'
var/damage = BLAST_DOOR_CRUSH_DAMAGE
var/multiplier = 1 // The multiplier for how powerful our YEET is.
+ var/istransparent = 0
closed_layer = ON_WINDOW_LAYER // Above airlocks when closed
var/id = 1.0
@@ -108,10 +109,13 @@
src.density = 1
update_nearby_tiles()
src.update_icon()
- src.set_opacity(1)
+ if(src.istransparent)
+ src.set_opacity(0)
+ else
+ src.set_opacity(1)
sleep(15)
src.operating = 0
-
+
// Blast door crushing.
for(var/turf/turf in locs)
for(var/atom/movable/AM in turf)
@@ -276,10 +280,11 @@
// Parameters: None
// Description: Closes the door. Does necessary checks.
/obj/machinery/door/blast/close()
+
if (src.operating || (stat & BROKEN || stat & NOPOWER))
return
- force_close()
+ force_close()
// Proc: repair()
// Parameters: None
@@ -323,5 +328,52 @@ obj/machinery/door/blast/regular/open
icon_state = "shutter1"
damage = SHUTTER_CRUSH_DAMAGE
+// SUBTYPE: Transparent
+// Not technically a blast door but operates like one. Allows air and light.
+obj/machinery/door/blast/gate
+ name = "thick gate"
+ icon_state_open = "tshutter0"
+ icon_state_opening = "tshutterc0"
+ icon_state_closed = "tshutter1"
+ icon_state_closing = "tshutterc1"
+ icon_state = "tshutter1"
+ damage = SHUTTER_CRUSH_DAMAGE
+ maxhealth = 400
+ block_air_zones = 0
+ opacity = 0
+ istransparent = 1
+
+obj/machinery/door/blast/gate/open
+ icon_state = "tshutter0"
+ density = 0
+
+/obj/machinery/door/blast/gate/thin
+ name = "thin gate"
+ icon_state_open = "shutter2_0"
+ icon_state_opening = "shutter2_c0"
+ icon_state_closed = "shutter2_1"
+ icon_state_closing = "shutter2_c1"
+ icon_state = "shutter2_1"
+ maxhealth = 200
+ opacity = 0
+
+/obj/machinery/door/blast/gate/thin/open
+ icon_state = "shutter2_1"
+ density = 0
+
+/obj/machinery/door/blast/gate/bars
+ name = "prison bars"
+ icon_state_open = "bars_0"
+ icon_state_opening = "bars_c0"
+ icon_state_closed = "bars_1"
+ icon_state_closing = "bars_c1"
+ icon_state = "bars_1"
+ maxhealth = 600
+ opacity = 0
+
+/obj/machinery/door/blast/gate/bars/open
+ icon_state = "bars_1"
+ density = 0
+
#undef BLAST_DOOR_CRUSH_DAMAGE
#undef SHUTTER_CRUSH_DAMAGE
\ No newline at end of file
diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index c9262675cf..a98c9abb04 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -8,8 +8,6 @@
#define PRESET_MEDIUM 5 MINUTES
#define PRESET_LONG 10 MINUTES
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
///////////////////////////////////////////////////////////////////////////////////////////////
// Brig Door control displays.
// Description: This is a controls the timer for the brig doors, displays the timer on itself and
@@ -25,22 +23,21 @@
layer = ABOVE_WINDOW_LAYER
desc = "A remote control for a door."
req_access = list(access_brig)
- anchored = 1.0 // can't pick it up
- density = 0 // can walk through it.
- var/id = null // id of door it controls.
-
+ anchored = 1.0 // can't pick it up
+ density = 0 // can walk through it.
+ var/id = null // id of door it controls.
var/activation_time = 0
var/timer_duration = 0
var/timing = FALSE // boolean, true/1 timer is on, false/0 means it's not timing
var/list/obj/machinery/targets = list()
+
maptext_height = 26
maptext_width = 32
/obj/machinery/door_timer/Initialize()
..()
- //Doors need to go first, and can't rely on init order, so come back to me.
return INITIALIZE_HINT_LATELOAD
/obj/machinery/door_timer/LateInitialize()
@@ -72,12 +69,12 @@
/obj/machinery/door_timer/process()
if(stat & (NOPOWER|BROKEN))
return
-
if(timing)
if(world.time - activation_time >= timer_duration)
timer_end() // open doors, reset timer, clear status screen
update_icon()
+
// has the door power situation changed, if so update icon.
/obj/machinery/door_timer/power_change()
..()
@@ -108,7 +105,7 @@
C.icon_state = "closed_locked"
return 1
-// Opens and unlocks doors, power check
+/// Opens and unlocks doors, power check
/obj/machinery/door_timer/proc/timer_end(forced = FALSE)
if(stat & (NOPOWER|BROKEN))
return 0
@@ -145,6 +142,9 @@
if(timer_duration && activation_time && timing) // Setting it while active will reset the activation time
activation_time = world.time
+/obj/machinery/door_timer/attack_ai(mob/user)
+ return src.attack_hand(user)
+
/obj/machinery/door_timer/attack_hand(mob/user)
if(..())
return TRUE
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 25c3c631f2..be3ebba12d 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -4,6 +4,7 @@
/datum/feed_message
var/author =""
+ var/title
var/body =""
var/message_type ="Story"
var/datum/feed_channel/parent_channel
@@ -58,9 +59,6 @@
var/list/datum/feed_channel/network_channels = list()
var/datum/feed_message/wanted_issue
-/datum/feed_network/New()
- CreateFeedChannel("Station Announcements", "SS13", 1, 1, "New Station Announcement Available")
-
/datum/feed_network/proc/CreateFeedChannel(var/channel_name, var/author, var/locked, var/adminChannel = 0, var/announcement_message)
var/datum/feed_channel/newChannel = new /datum/feed_channel
newChannel.channel_name = channel_name
@@ -73,12 +71,16 @@
newChannel.announcement = "Breaking news from [channel_name]!"
network_channels += newChannel
-/datum/feed_network/proc/SubmitArticle(var/msg, var/author, var/channel_name, var/obj/item/weapon/photo/photo, var/adminMessage = 0, var/message_type = "")
+/datum/feed_network/proc/SubmitArticle(var/msg, var/author, var/channel_name, var/obj/item/weapon/photo/photo, var/adminMessage = 0, var/message_type = "", var/title)
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = author
newMsg.body = msg
newMsg.time_stamp = "[stationtime2text()]"
newMsg.is_admin_message = adminMessage
+ if(title)
+ newMsg.title = title
+ else
+ newMsg.title = "News Update"
newMsg.post_time = round_duration_in_ds // Should be almost universally unique
if(message_type)
newMsg.message_type = message_type
@@ -147,6 +149,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
// 1 = there has
var/scanned_user = "Unknown" //Will contain the name of the person who currently uses the newscaster
var/msg = ""; //Feed message
+ var/title = ""; // Feed title
var/datum/news_photo/photo_data = null
var/channel_name = ""; //the feed channel which will be receiving the feed, or being created
var/c_locked=0; //Will our new channel be locked to public submissions?
@@ -164,7 +167,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
securityCaster = 1
/obj/machinery/newscaster/Initialize()
- ..() //Not returning . because lateload below
+ ..()
GLOB.allCasters += src
unit_no = ++unit_no_cur
paper_remaining = 15
@@ -371,7 +374,6 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
/obj/machinery/newscaster/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
-
switch(action)
if("cleartemp")
temp = null
@@ -434,6 +436,10 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
msg = sanitize(input(usr, "Write your Feed story", "Network Channel Handler", "") as message|null)
return TRUE
+ if("set_new_title")
+ title = sanitize(input(usr, "Enter your Feed title", "Network Channel Handler", "") as message|null)
+ return TRUE
+
if("set_attachment")
AttachPhoto(usr)
return TRUE
@@ -449,10 +455,13 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
if(channel_name == "")
set_temp("Error: Could not submit feed message to network: No feed channel selected.", "danger", FALSE)
return TRUE
+ if(title == "")
+ set_temp("Error: Invalid Title.", "danger", FALSE)
+ return TRUE
var/image = photo_data ? photo_data.photo : null
feedback_inc("newscaster_stories",1)
- news_network.SubmitArticle(msg, our_user, channel_name, image, 0)
+ news_network.SubmitArticle(msg, our_user, channel_name, image, 0, "", title)
set_temp("Feed message created successfully.", "success", FALSE)
return TRUE
@@ -629,153 +638,6 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
photo_data = new(selection, 1)
-//########################################################################################################################
-//###################################### NEWSPAPER! ######################################################################
-//########################################################################################################################
-
-/obj/item/weapon/newspaper
- name = "newspaper"
- desc = "An issue of The Griffon, the newspaper circulating aboard most stations."
- icon = 'icons/obj/bureaucracy.dmi'
- icon_state = "newspaper"
- w_class = ITEMSIZE_SMALL //Let's make it fit in trashbags!
- attack_verb = list("bapped")
- var/screen = 0
- var/pages = 0
- var/curr_page = 0
- var/list/datum/feed_channel/news_content = list()
- var/datum/feed_message/important_message = null
- var/scribble=""
- var/scribble_page = null
- drop_sound = 'sound/items/drop/wrapper.ogg'
- pickup_sound = 'sound/items/pickup/wrapper.ogg'
-
-obj/item/weapon/newspaper/attack_self(mob/user)
- if(ishuman(user))
- var/mob/living/carbon/human/human_user = user
- var/dat
- pages = 0
- switch(screen)
- if(0) //Cover
- dat+="The Griffon "
- dat+="[using_map.company_name]-standard newspaper, for use on [using_map.company_name]© Space Facilities "
- if(isemptylist(news_content))
- if(important_message)
- dat+="Contents:
**Important Security Announcement** \[page [pages+2]\]
"
- else
- dat+="Other than the title, the rest of the newspaper is unprinted..."
- else
- dat+="Contents:
"
- for(var/datum/feed_channel/NP in news_content)
- pages++
- if(important_message)
- dat+="**Important Security Announcement** \[page [pages+2]\] "
- var/temp_page=0
- for(var/datum/feed_channel/NP in news_content)
- temp_page++
- dat+="[NP.channel_name] \[page [temp_page+1]\] "
- dat+=" "
- if(scribble_page==curr_page)
- dat+=" There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= " "
- if(1) // X channel pages inbetween.
- for(var/datum/feed_channel/NP in news_content)
- pages++ //Let's get it right again.
- var/datum/feed_channel/C = news_content[curr_page]
- dat+="[C.channel_name] \[created by: [C.author]\]
"
- if(C.censored)
- dat+="This channel was deemed dangerous to the general welfare of the station and therefore marked with a D-Notice. Its contents were not transferred to the newspaper at the time of printing."
- else
- if(isemptylist(C.messages))
- dat+="No Feed stories stem from this channel..."
- else
- dat+=""
- var/i = 0
- for(var/datum/feed_message/MESSAGE in C.messages)
- i++
- dat+="-[MESSAGE.body] "
- if(MESSAGE.img)
- user << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
- dat+=" "
- dat+="\[[MESSAGE.message_type] by [MESSAGE.author]\]
"
- dat+=" "
- if(scribble_page==curr_page)
- dat+=" There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= "
"
- if(2) //Last page
- for(var/datum/feed_channel/NP in news_content)
- pages++
- if(important_message!=null)
- dat+="Wanted Issue:
"
- dat+="Criminal name: [important_message.author] "
- dat+="Description: [important_message.body] "
- dat+="Photo:: "
- if(important_message.img)
- user << browse_rsc(important_message.img, "tmp_photow.png")
- dat+="
"
- else
- dat+="None"
- else
- dat+="Apart from some uninteresting Classified ads, there's nothing on this page..."
- if(scribble_page==curr_page)
- dat+=" There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= " "
- else
- dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
-
- dat+="
[curr_page+1] "
- human_user << browse(dat, "window=newspaper_main;size=300x400")
- onclose(human_user, "newspaper_main")
- else
- to_chat(user, "The paper is full of intelligible symbols!")
-
-obj/item/weapon/newspaper/Topic(href, href_list)
- var/mob/living/U = usr
- ..()
- if((src in U.contents) || (istype(loc, /turf) && in_range(src, U)))
- U.set_machine(src)
- if(href_list["next_page"])
- if(curr_page == pages+1)
- return //Don't need that at all, but anyway.
- if(curr_page == pages) //We're at the middle, get to the end
- screen = 2
- else
- if(curr_page == 0) //We're at the start, get to the middle
- screen = 1
- curr_page++
- playsound(src, "pageturn", 50, 1)
-
- else if(href_list["prev_page"])
- if(curr_page == 0)
- return
- if(curr_page == 1)
- screen = 0
-
- else
- if(curr_page == pages+1) //we're at the end, let's go back to the middle.
- screen = 1
- curr_page--
- playsound(src, "pageturn", 50, 1)
-
- if(istype(src.loc, /mob))
- attack_self(src.loc)
-
-obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user)
- if(istype(W, /obj/item/weapon/pen))
- if(scribble_page == curr_page)
- to_chat(user, "There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?")
- else
- var/s = sanitize(input(user, "Write something", "Newspaper", ""))
- s = sanitize(s)
- if(!s)
- return
- if(!in_range(src, usr) && src.loc != usr)
- return
- scribble_page = curr_page
- scribble = s
- attack_self(user)
- return
-
////////////////////////////////////helper procs
/obj/machinery/newscaster/proc/tgui_user_name(mob/user)
if(ishuman(user))
diff --git a/code/game/machinery/pointdefense.dm b/code/game/machinery/pointdefense.dm
index 92f6cd40df..c6945f1e79 100644
--- a/code/game/machinery/pointdefense.dm
+++ b/code/game/machinery/pointdefense.dm
@@ -376,10 +376,13 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
/obj/effect/projectile/tracer/pointdefense
+ icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "beam_pointdef"
/obj/effect/projectile/muzzle/pointdefense
+ icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "muzzle_pointdef"
/obj/effect/projectile/impact/pointdefense
+ icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "impact_pointdef"
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 259c907bde..98ad80e468 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -71,7 +71,6 @@
/obj/machinery/recharge_station/proc/process_occupant()
if(isrobot(occupant))
var/mob/living/silicon/robot/R = occupant
-
if(R.module)
R.module.respawn_consumable(R, charging_power * CELLRATE / 250) //consumables are magical, apparently
if(R.cell && !R.cell.fully_charged())
@@ -247,6 +246,10 @@
if(!R.cell)
return
+ if(R.mob_size >= MOB_LARGE)
+ to_chat(R, SPAN_WARNING("You are too large to fit into \the [src]."))
+ return
+
add_fingerprint(R)
R.reset_view(src)
R.forceMove(src)
diff --git a/code/game/machinery/telecomms/broadcaster_ch.dm b/code/game/machinery/telecomms/broadcaster_ch.dm
new file mode 100644
index 0000000000..6875970519
--- /dev/null
+++ b/code/game/machinery/telecomms/broadcaster_ch.dm
@@ -0,0 +1,72 @@
+//This is meant for essentially linking a separate z-level to the rest with telecomms
+/obj/machinery/telecomms/allinone/link
+ name = "Telecommunications Mainframe"
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "allinone"
+ desc = "A compact machine used for portable subspace telecommuniations processing."
+ density = 1
+ use_power = USE_POWER_IDLE
+ idle_power_usage = 20
+ anchored = 1
+ machinetype = 6
+ produces_heat = 0
+
+/obj/machinery/telecomms/allinone/link/receive_signal(datum/signal/signal)
+
+ // Has to be on to receive messages
+ if(!on)
+ return
+
+ // Why did you use this subtype?
+ if(!using_map.use_overmap)
+ return
+
+ // Is there a valid signal
+ if(!signal)
+ return
+
+ // Where are we able to hear from (and talk to, since we're AIO) anyway?
+ //var/map_levels = using_map.get_map_levels(z, TRUE, overmap_range)
+
+ if("[signal.data["level"]]" == "[z]")
+ signal.data["level"] = list(0)
+ else
+ signal.data["level"] = list(z)
+
+ if(is_freq_listening(signal)) // detect subspace signals
+
+ signal.data["done"] = 1 // mark the signal as being broadcasted since we're a broadcaster
+ signal.data["compression"] = 0 // decompress since we're a processor
+
+ if(signal.data["slow"] > 0)
+ sleep(signal.data["slow"]) // simulate the network lag if necessary
+
+ /* ###### Broadcast a message using signal.data ###### */
+
+ var/datum/radio_frequency/connection = signal.data["connection"]
+
+ var/list/forced_radios
+ for(var/weakref/wr in linked_radios_weakrefs)
+ var/obj/item/device/radio/R = wr.resolve()
+ if(istype(R))
+ LAZYDISTINCTADD(forced_radios, R)
+
+ Broadcast_Message(
+ signal.data["connection"],
+ signal.data["mob"],
+ signal.data["vmask"],
+ signal.data["vmessage"],
+ signal.data["radio"],
+ signal.data["message"],
+ signal.data["name"],
+ signal.data["job"],
+ signal.data["realname"],
+ signal.data["vname"],
+ DATA_NORMAL,
+ signal.data["compression"],
+ signal.data["level"],
+ connection.frequency,
+ signal.data["verb"],
+ signal.data["language"],
+ forced_radios
+ )
\ No newline at end of file
diff --git a/code/game/machinery/transportpod.dm b/code/game/machinery/transportpod.dm
index 0b499096fe..4a43cb1890 100644
--- a/code/game/machinery/transportpod.dm
+++ b/code/game/machinery/transportpod.dm
@@ -32,7 +32,7 @@
sleep(2)
go_out()
sleep(2)
- del(src)
+ qdel(src)
/obj/machinery/transportpod/relaymove(mob/user as mob)
if(user.stat)
diff --git a/code/game/machinery/vending_machines.dm b/code/game/machinery/vending_machines.dm
index 10607011ce..76f0c04885 100644
--- a/code/game/machinery/vending_machines.dm
+++ b/code/game/machinery/vending_machines.dm
@@ -71,6 +71,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5,
/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5,
/obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/jager = 5,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 15,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale/hushedwhisper = 15,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 15,
@@ -302,6 +303,7 @@
/obj/item/weapon/storage/fancy/cigarettes/jerichos = 10,
/obj/item/weapon/storage/fancy/cigarettes/menthols = 10,
/obj/item/weapon/storage/rollingpapers = 10,
+ /obj/item/weapon/storage/rollingpapers/blunt = 10,
/obj/item/weapon/storage/chewables/tobacco = 5,
/obj/item/weapon/storage/chewables/tobacco/fine = 5,
/obj/item/weapon/storage/box/matches = 10,
@@ -330,6 +332,7 @@
/obj/item/weapon/storage/fancy/cigarettes/jerichos = 22,
/obj/item/weapon/storage/fancy/cigarettes/menthols = 18,
/obj/item/weapon/storage/rollingpapers = 10,
+ /obj/item/weapon/storage/rollingpapers/blunt = 20,
/obj/item/weapon/storage/chewables/tobacco = 10,
/obj/item/weapon/storage/chewables/tobacco/fine = 20,
/obj/item/weapon/storage/box/matches = 1,
diff --git a/code/game/machinery/vending_machines_vr.dm b/code/game/machinery/vending_machines_vr.dm
index 3c826b469e..7573e19a6a 100644
--- a/code/game/machinery/vending_machines_vr.dm
+++ b/code/game/machinery/vending_machines_vr.dm
@@ -249,1343 +249,6 @@
prices = list(/obj/item/device/flash = 600,/obj/item/weapon/reagent_containers/spray/pepper = 800, /obj/item/weapon/gun/projectile/olivaw = 1600, /obj/item/weapon/gun/projectile/giskard = 1200, /obj/item/ammo_magazine/mg/cl32/rubber = 200)
*/
-/obj/machinery/vending/fitness/New()
- products += list(/obj/item/weapon/reagent_containers/food/snacks/liquidprotein = 8)
- prices += list(/obj/item/weapon/reagent_containers/food/snacks/liquidprotein = 5)
- ..()
-
-/obj/machinery/vending/blood
- name = "Blood-Onator"
- desc = "Freezer-vendor for storage and quick dispensing of blood packs"
- product_ads = "The true life juice!;Vampire's choice!;Home-grown blood only!;Donate today, be saved tomorrow!;Approved by Zeng-Hu Pharmaceuticals Incorporated!; Curse you, Vey-Med artificial blood!"
- icon = 'icons/obj/vending_vr.dmi'
- icon_state = "blood"
- vend_delay = 7
- idle_power_usage = 211
- req_access = list(access_medical)
- products = list(/obj/item/weapon/reagent_containers/blood/prelabeled/APlus = 3,/obj/item/weapon/reagent_containers/blood/prelabeled/AMinus = 3,
- /obj/item/weapon/reagent_containers/blood/prelabeled/BPlus = 3,/obj/item/weapon/reagent_containers/blood/prelabeled/BMinus = 3,
- /obj/item/weapon/reagent_containers/blood/prelabeled/OPlus = 2,/obj/item/weapon/reagent_containers/blood/prelabeled/OMinus = 5,
- /obj/item/weapon/reagent_containers/blood/empty = 5)
- contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/stoxin = 2)
- req_log_access = access_cmo
- has_logs = 1
-
-/obj/machinery/vending/loadout
- name = "Fingers and Toes"
- desc = "A special vendor for gloves and shoes!"
- product_ads = "Do you have fingers and toes? COVER THEM UP!;Show me your toes! Wait. NO DON'T! BUY NEW SHOES!;Don't leave prints, BUY SOME GLOVES!;Remember to check your shoes for micros! You don't have to let them out, but just check for them!;Fingers and Toes is not liable for micro entrapment or abuse under the feet of our patrons.!;This little piggy went WE WE WE all the way down to FINGERS AND TOES to pick up some sweet new gloves and shoes."
- icon = 'icons/obj/vending_vr.dmi'
- icon_state = "glovesnshoes"
- products = list(/obj/item/clothing/gloves/evening = 5,
- /obj/item/clothing/gloves/fingerless = 5,
- /obj/item/clothing/gloves/black = 5,
- /obj/item/clothing/gloves/blue = 5,
- /obj/item/clothing/gloves/brown = 5,
- /obj/item/clothing/gloves/color = 5,
- /obj/item/clothing/gloves/green = 5,
- /obj/item/clothing/gloves/grey = 5,
- /obj/item/clothing/gloves/sterile/latex = 5,
- /obj/item/clothing/gloves/light_brown = 5,
- /obj/item/clothing/gloves/sterile/nitrile = 5,
- /obj/item/clothing/gloves/orange = 5,
- /obj/item/clothing/gloves/purple = 5,
- /obj/item/clothing/gloves/red = 5,
- /obj/item/clothing/gloves/fluff/siren = 5,
- /obj/item/clothing/gloves/white = 5,
- /obj/item/clothing/gloves/duty = 5,
- /obj/item/clothing/shoes/athletic = 5,
- /obj/item/clothing/shoes/boots/fluff/siren = 5,
- /obj/item/clothing/shoes/slippers = 5,
- /obj/item/clothing/shoes/boots/cowboy/classic = 5,
- /obj/item/clothing/shoes/boots/cowboy = 5,
- /obj/item/clothing/shoes/boots/duty = 5,
- /obj/item/clothing/shoes/flats/white/color = 5,
- /obj/item/clothing/shoes/flipflop = 5,
- /obj/item/clothing/shoes/heels = 5,
- /obj/item/clothing/shoes/hitops/black = 5,
- /obj/item/clothing/shoes/hitops/blue = 5,
- /obj/item/clothing/shoes/hitops/green = 5,
- /obj/item/clothing/shoes/hitops/orange = 5,
- /obj/item/clothing/shoes/hitops/purple = 5,
- /obj/item/clothing/shoes/hitops/red = 5,
- /obj/item/clothing/shoes/flats/white/color = 5,
- /obj/item/clothing/shoes/hitops/yellow = 5,
- /obj/item/clothing/shoes/boots/jackboots = 5,
- /obj/item/clothing/shoes/boots/jungle = 5,
- /obj/item/clothing/shoes/black/cuffs = 5,
- /obj/item/clothing/shoes/black/cuffs/blue = 5,
- /obj/item/clothing/shoes/black/cuffs/red = 5,
- /obj/item/clothing/shoes/sandal = 5,
- /obj/item/clothing/shoes/black = 5,
- /obj/item/clothing/shoes/blue = 5,
- /obj/item/clothing/shoes/brown = 5,
- /obj/item/clothing/shoes/laceup = 5,
- /obj/item/clothing/shoes/green = 5,
- /obj/item/clothing/shoes/laceup/brown = 5,
- /obj/item/clothing/shoes/orange = 5,
- /obj/item/clothing/shoes/purple = 5,
- /obj/item/clothing/shoes/red = 5,
- /obj/item/clothing/shoes/white = 5,
- /obj/item/clothing/shoes/yellow = 5,
- /obj/item/clothing/shoes/skater = 5,
- /obj/item/clothing/shoes/boots/cowboy/snakeskin = 5,
- /obj/item/clothing/shoes/boots/jackboots/toeless = 5,
- /obj/item/clothing/shoes/boots/workboots/toeless = 5,
- /obj/item/clothing/shoes/boots/winter = 5,
- /obj/item/clothing/shoes/boots/workboots = 5,
- /obj/item/clothing/shoes/footwraps = 5)
- prices = list(/obj/item/clothing/gloves/evening = 50,
- /obj/item/clothing/gloves/fingerless = 50,
- /obj/item/clothing/gloves/black = 50,
- /obj/item/clothing/gloves/blue = 50,
- /obj/item/clothing/gloves/brown = 50,
- /obj/item/clothing/gloves/color = 50,
- /obj/item/clothing/gloves/green = 50,
- /obj/item/clothing/gloves/grey = 50,
- /obj/item/clothing/gloves/sterile/latex = 100,
- /obj/item/clothing/gloves/light_brown = 50,
- /obj/item/clothing/gloves/sterile/nitrile = 100,
- /obj/item/clothing/gloves/orange = 50,
- /obj/item/clothing/gloves/purple = 50,
- /obj/item/clothing/gloves/red = 50,
- /obj/item/clothing/gloves/fluff/siren = 50,
- /obj/item/clothing/gloves/white = 50,
- /obj/item/clothing/gloves/duty = 150,
- /obj/item/clothing/shoes/athletic = 50,
- /obj/item/clothing/shoes/boots/fluff/siren = 50,
- /obj/item/clothing/shoes/slippers = 50,
- /obj/item/clothing/shoes/boots/cowboy/classic = 50,
- /obj/item/clothing/shoes/boots/cowboy = 50,
- /obj/item/clothing/shoes/boots/duty = 100,
- /obj/item/clothing/shoes/flats/white/color = 50,
- /obj/item/clothing/shoes/flipflop = 50,
- /obj/item/clothing/shoes/heels = 50,
- /obj/item/clothing/shoes/hitops/black = 50,
- /obj/item/clothing/shoes/hitops/blue = 50,
- /obj/item/clothing/shoes/hitops/green = 50,
- /obj/item/clothing/shoes/hitops/orange = 50,
- /obj/item/clothing/shoes/hitops/purple = 50,
- /obj/item/clothing/shoes/hitops/red = 50,
- /obj/item/clothing/shoes/flats/white/color = 50,
- /obj/item/clothing/shoes/hitops/yellow = 50,
- /obj/item/clothing/shoes/boots/jackboots = 50,
- /obj/item/clothing/shoes/boots/jungle = 100,
- /obj/item/clothing/shoes/black/cuffs = 50,
- /obj/item/clothing/shoes/black/cuffs/blue = 50,
- /obj/item/clothing/shoes/black/cuffs/red = 50,
- /obj/item/clothing/shoes/sandal = 50,
- /obj/item/clothing/shoes/black = 50,
- /obj/item/clothing/shoes/blue = 50,
- /obj/item/clothing/shoes/brown = 50,
- /obj/item/clothing/shoes/laceup = 50,
- /obj/item/clothing/shoes/green = 50,
- /obj/item/clothing/shoes/laceup/brown = 50,
- /obj/item/clothing/shoes/orange = 50,
- /obj/item/clothing/shoes/purple = 50,
- /obj/item/clothing/shoes/red = 50,
- /obj/item/clothing/shoes/white = 50,
- /obj/item/clothing/shoes/yellow = 50,
- /obj/item/clothing/shoes/skater = 50,
- /obj/item/clothing/shoes/boots/cowboy/snakeskin = 50,
- /obj/item/clothing/shoes/boots/jackboots/toeless = 50,
- /obj/item/clothing/shoes/boots/workboots/toeless = 50,
- /obj/item/clothing/shoes/boots/winter = 50,
- /obj/item/clothing/shoes/boots/workboots = 50,
- /obj/item/clothing/shoes/footwraps = 50)
- premium = list(/obj/item/clothing/gloves/rainbow = 1,
- /obj/item/clothing/shoes/rainbow = 1,)
- contraband = list(/obj/item/clothing/shoes/syndigaloshes = 1,
- /obj/item/clothing/shoes/clown_shoes = 1)
-
-/obj/machinery/vending/loadout/uniform
- name = "The Basics"
- desc = "A vendor using compressed matter cartridges to store large amounts of basic station uniforms."
- product_ads = "Don't get caught naked!;Pick up your uniform!;Using compressed matter cartridges and VERY ETHICAL labor practices, we bring you the uniforms you need!;No uniform? No problem!;We've got your covered!;The Basics is not responsible for being crushed under the amount of things inside our machines. DO NOT VEND IN EXCESS!!"
- icon_state = "loadout"
- vend_delay = 16
- products = list(/obj/item/device/pda = 50,
- /obj/item/device/radio/headset = 50,
- /obj/item/weapon/storage/backpack/ = 10,
- /obj/item/weapon/storage/backpack/messenger = 10,
- /obj/item/weapon/storage/backpack/satchel = 10,
- /obj/item/clothing/under/color = 5,
- /obj/item/clothing/under/color/aqua = 5,
- /obj/item/clothing/under/color/black = 5,
- /obj/item/clothing/under/color/blackjumpskirt = 5,
- /obj/item/clothing/under/color/blue = 5,
- /obj/item/clothing/under/color/brown = 5,
- /obj/item/clothing/under/color/green = 5,
- /obj/item/clothing/under/color/grey = 5,
- /obj/item/clothing/under/color/orange = 5,
- /obj/item/clothing/under/color/pink = 5,
- /obj/item/clothing/under/color/red = 5,
- /obj/item/clothing/under/color/white = 5,
- /obj/item/clothing/under/color/yellow = 5,
- /obj/item/clothing/shoes/black = 20,
- /obj/item/clothing/shoes/white = 20)
- prices = list()
-
-/obj/machinery/vending/loadout/accessory
- name = "Looty Inc."
- desc = "A special vendor for accessories."
- product_ads = "Want shinies? We have the shinies.;Need that special something to complete your outfit? We have what you need!;Ditch that old dull dangly something you've got and pick up one of our shinies!;Bracelets, collars, scarfs rings and more! We have the fancy things you need!;Does your pet need a collar? We don't judge! Keep them in line with one of one of ours!;Top of the line materials! 'Hand crafted' goods!"
- icon_state = "accessory"
- vend_delay = 6
- products = list(/obj/item/clothing/accessory = 5,
- /obj/item/clothing/accessory/armband/med/color = 10,
- /obj/item/clothing/accessory/asymmetric = 5,
- /obj/item/clothing/accessory/asymmetric/purple = 5,
- /obj/item/clothing/accessory/asymmetric/green = 5,
- /obj/item/clothing/accessory/bracelet = 5,
- /obj/item/clothing/accessory/bracelet/material = 5,
- /obj/item/clothing/accessory/bracelet/friendship = 5,
- /obj/item/clothing/accessory/chaps = 5,
- /obj/item/clothing/accessory/chaps/black = 5,
- /obj/item/weapon/storage/briefcase/clutch = 1,
- /obj/item/clothing/accessory/collar = 5,
- /obj/item/clothing/accessory/collar/bell = 5,
- /obj/item/clothing/accessory/collar/spike = 5,
- /obj/item/clothing/accessory/collar/pink = 5,
- /obj/item/clothing/accessory/collar/holo = 5,
- /obj/item/clothing/accessory/collar/shock = 5,
- /obj/item/weapon/storage/belt/fannypack = 1,
- /obj/item/weapon/storage/belt/fannypack/white = 5,
- /obj/item/clothing/accessory/fullcape = 5,
- /obj/item/clothing/accessory/halfcape = 5,
- /obj/item/clothing/accessory/hawaii = 5,
- /obj/item/clothing/accessory/hawaii/random = 5,
- /obj/item/clothing/accessory/locket = 5,
- /obj/item/weapon/storage/backpack/purse = 1,
- /obj/item/clothing/accessory/sash = 5,
- /obj/item/clothing/accessory/scarf = 5,
- /obj/item/clothing/accessory/scarf/red = 5,
- /obj/item/clothing/accessory/scarf/darkblue = 5,
- /obj/item/clothing/accessory/scarf/purple = 5,
- /obj/item/clothing/accessory/scarf/yellow = 5,
- /obj/item/clothing/accessory/scarf/orange = 5,
- /obj/item/clothing/accessory/scarf/lightblue = 5,
- /obj/item/clothing/accessory/scarf/white = 5,
- /obj/item/clothing/accessory/scarf/black = 5,
- /obj/item/clothing/accessory/scarf/zebra = 5,
- /obj/item/clothing/accessory/scarf/christmas = 5,
- /obj/item/clothing/accessory/scarf/stripedred = 5,
- /obj/item/clothing/accessory/scarf/stripedgreen = 5,
- /obj/item/clothing/accessory/scarf/stripedblue = 5,
- /obj/item/clothing/accessory/jacket = 5,
- /obj/item/clothing/accessory/jacket/checkered = 5,
- /obj/item/clothing/accessory/jacket/burgundy = 5,
- /obj/item/clothing/accessory/jacket/navy = 5,
- /obj/item/clothing/accessory/jacket/charcoal = 5,
- /obj/item/clothing/accessory/vest = 5,
- /obj/item/clothing/accessory/sweater = 5,
- /obj/item/clothing/accessory/sweater/pink = 5,
- /obj/item/clothing/accessory/sweater/mint = 5,
- /obj/item/clothing/accessory/sweater/blue = 5,
- /obj/item/clothing/accessory/sweater/heart = 5,
- /obj/item/clothing/accessory/sweater/nt = 5,
- /obj/item/clothing/accessory/sweater/keyhole = 5,
- /obj/item/clothing/accessory/sweater/winterneck = 5,
- /obj/item/clothing/accessory/sweater/uglyxmas = 5,
- /obj/item/clothing/accessory/sweater/flowersweater = 5,
- /obj/item/clothing/accessory/sweater/redneck = 5,
- /obj/item/clothing/accessory/tie = 5,
- /obj/item/clothing/accessory/tie/horrible = 5,
- /obj/item/clothing/accessory/tie/white = 5,
- /obj/item/clothing/accessory/tie/navy = 5,
- /obj/item/clothing/accessory/tie/yellow = 5,
- /obj/item/clothing/accessory/tie/darkgreen = 5,
- /obj/item/clothing/accessory/tie/black = 5,
- /obj/item/clothing/accessory/tie/red_long = 5,
- /obj/item/clothing/accessory/tie/red_clip = 5,
- /obj/item/clothing/accessory/tie/blue_long = 5,
- /obj/item/clothing/accessory/tie/blue_clip = 5,
- /obj/item/clothing/accessory/tie/red = 5,
- /obj/item/clothing/accessory/wcoat = 5,
- /obj/item/clothing/accessory/wcoat/red = 5,
- /obj/item/clothing/accessory/wcoat/grey = 5,
- /obj/item/clothing/accessory/wcoat/brown = 5,
- /obj/item/clothing/accessory/wcoat/gentleman = 5,
- /obj/item/clothing/accessory/wcoat/swvest = 5,
- /obj/item/clothing/accessory/wcoat/swvest/blue = 5,
- /obj/item/clothing/accessory/wcoat/swvest/red = 5,
- /obj/item/weapon/storage/wallet = 5,
- /obj/item/weapon/storage/wallet/poly = 5,
- /obj/item/weapon/storage/wallet/womens = 5,
- /obj/item/weapon/lipstick = 5,
- /obj/item/weapon/lipstick/purple = 5,
- /obj/item/weapon/lipstick/jade = 5,
- /obj/item/weapon/lipstick/black = 5,
- /obj/item/clothing/ears/earmuffs = 5,
- /obj/item/clothing/ears/earmuffs/headphones = 5,
- /obj/item/clothing/ears/earring/stud = 5,
- /obj/item/clothing/ears/earring/dangle = 5,
- /obj/item/clothing/gloves/ring/mariner = 5,
- /obj/item/clothing/gloves/ring/engagement = 5,
- /obj/item/clothing/gloves/ring/seal/signet = 5,
- /obj/item/clothing/gloves/ring/seal/mason = 5,
- /obj/item/clothing/gloves/ring/material/plastic = 5,
- /obj/item/clothing/gloves/ring/material/steel = 5,
- /obj/item/clothing/gloves/ring/material/gold = 5,
- /obj/item/clothing/glasses/eyepatch = 5,
- /obj/item/clothing/glasses/gglasses = 5,
- /obj/item/clothing/glasses/regular/hipster = 5,
- /obj/item/clothing/glasses/rimless = 5,
- /obj/item/clothing/glasses/thin = 5,
- /obj/item/clothing/glasses/monocle = 5,
- /obj/item/clothing/glasses/goggles = 5,
- /obj/item/clothing/glasses/fluff/spiffygogs = 5,
- /obj/item/clothing/glasses/fakesunglasses = 5,
- /obj/item/clothing/glasses/fakesunglasses/aviator = 5,
- /obj/item/clothing/mask/bandana/blue = 5,
- /obj/item/clothing/mask/bandana/gold = 5,
- /obj/item/clothing/mask/bandana/green = 5,
- /obj/item/clothing/mask/bandana/red = 5,
- /obj/item/clothing/mask/surgical = 5)
- prices = list(/obj/item/clothing/accessory = 50,
- /obj/item/clothing/accessory/armband/med/color = 50,
- /obj/item/clothing/accessory/asymmetric = 50,
- /obj/item/clothing/accessory/asymmetric/purple = 50,
- /obj/item/clothing/accessory/asymmetric/green = 50,
- /obj/item/clothing/accessory/bracelet = 50,
- /obj/item/clothing/accessory/bracelet/material = 50,
- /obj/item/clothing/accessory/bracelet/friendship = 50,
- /obj/item/clothing/accessory/chaps = 50,
- /obj/item/clothing/accessory/chaps/black = 50,
- /obj/item/weapon/storage/briefcase/clutch = 50,
- /obj/item/clothing/accessory/collar = 50,
- /obj/item/clothing/accessory/collar/bell = 50,
- /obj/item/clothing/accessory/collar/spike = 50,
- /obj/item/clothing/accessory/collar/pink = 50,
- /obj/item/clothing/accessory/collar/holo = 50,
- /obj/item/clothing/accessory/collar/shock = 50,
- /obj/item/weapon/storage/belt/fannypack = 50,
- /obj/item/weapon/storage/belt/fannypack/white = 50,
- /obj/item/clothing/accessory/fullcape = 50,
- /obj/item/clothing/accessory/halfcape = 50,
- /obj/item/clothing/accessory/hawaii = 50,
- /obj/item/clothing/accessory/hawaii/random = 50,
- /obj/item/clothing/accessory/locket = 50,
- /obj/item/weapon/storage/backpack/purse = 50,
- /obj/item/clothing/accessory/sash = 50,
- /obj/item/clothing/accessory/scarf = 5,
- /obj/item/clothing/accessory/scarf/red = 50,
- /obj/item/clothing/accessory/scarf/darkblue = 50,
- /obj/item/clothing/accessory/scarf/purple = 50,
- /obj/item/clothing/accessory/scarf/yellow = 100,
- /obj/item/clothing/accessory/scarf/orange = 50,
- /obj/item/clothing/accessory/scarf/lightblue = 50,
- /obj/item/clothing/accessory/scarf/white = 50,
- /obj/item/clothing/accessory/scarf/black = 50,
- /obj/item/clothing/accessory/scarf/zebra = 50,
- /obj/item/clothing/accessory/scarf/christmas = 50,
- /obj/item/clothing/accessory/scarf/stripedred = 50,
- /obj/item/clothing/accessory/scarf/stripedgreen = 50,
- /obj/item/clothing/accessory/scarf/stripedblue = 50,
- /obj/item/clothing/accessory/jacket = 50,
- /obj/item/clothing/accessory/jacket/checkered = 50,
- /obj/item/clothing/accessory/jacket/burgundy = 50,
- /obj/item/clothing/accessory/jacket/navy = 50,
- /obj/item/clothing/accessory/jacket/charcoal = 50,
- /obj/item/clothing/accessory/vest = 50,
- /obj/item/clothing/accessory/sweater = 50,
- /obj/item/clothing/accessory/sweater/pink = 50,
- /obj/item/clothing/accessory/sweater/mint = 50,
- /obj/item/clothing/accessory/sweater/blue = 50,
- /obj/item/clothing/accessory/sweater/heart = 50,
- /obj/item/clothing/accessory/sweater/nt = 5,
- /obj/item/clothing/accessory/sweater/keyhole = 50,
- /obj/item/clothing/accessory/sweater/winterneck = 50,
- /obj/item/clothing/accessory/sweater/uglyxmas = 5,
- /obj/item/clothing/accessory/sweater/flowersweater = 50,
- /obj/item/clothing/accessory/sweater/redneck = 50,
- /obj/item/clothing/accessory/tie = 50,
- /obj/item/clothing/accessory/tie/horrible = 50,
- /obj/item/clothing/accessory/tie/white = 50,
- /obj/item/clothing/accessory/tie/navy = 50,
- /obj/item/clothing/accessory/tie/yellow = 50,
- /obj/item/clothing/accessory/tie/darkgreen = 50,
- /obj/item/clothing/accessory/tie/black = 50,
- /obj/item/clothing/accessory/tie/red_long = 50,
- /obj/item/clothing/accessory/tie/red_clip = 50,
- /obj/item/clothing/accessory/tie/blue_long = 50,
- /obj/item/clothing/accessory/tie/blue_clip = 50,
- /obj/item/clothing/accessory/tie/red = 50,
- /obj/item/clothing/accessory/wcoat = 50,
- /obj/item/clothing/accessory/wcoat/red = 50,
- /obj/item/clothing/accessory/wcoat/grey = 50,
- /obj/item/clothing/accessory/wcoat/brown = 50,
- /obj/item/clothing/accessory/wcoat/gentleman = 50,
- /obj/item/clothing/accessory/wcoat/swvest = 50,
- /obj/item/clothing/accessory/wcoat/swvest/blue = 50,
- /obj/item/clothing/accessory/wcoat/swvest/red = 50,
- /obj/item/weapon/storage/wallet = 50,
- /obj/item/weapon/storage/wallet/poly = 50,
- /obj/item/weapon/storage/wallet/womens = 50,
- /obj/item/weapon/lipstick = 50,
- /obj/item/weapon/lipstick/purple = 50,
- /obj/item/weapon/lipstick/jade = 50,
- /obj/item/weapon/lipstick/black = 50,
- /obj/item/clothing/ears/earmuffs = 50,
- /obj/item/clothing/ears/earmuffs/headphones = 50,
- /obj/item/clothing/ears/earring/stud = 50,
- /obj/item/clothing/ears/earring/dangle = 50,
- /obj/item/clothing/gloves/ring/mariner = 50,
- /obj/item/clothing/gloves/ring/engagement = 50,
- /obj/item/clothing/gloves/ring/seal/signet = 50,
- /obj/item/clothing/gloves/ring/seal/mason = 50,
- /obj/item/clothing/gloves/ring/material/plastic = 50,
- /obj/item/clothing/gloves/ring/material/steel = 50,
- /obj/item/clothing/gloves/ring/material/gold = 100,
- /obj/item/clothing/glasses/eyepatch = 50,
- /obj/item/clothing/glasses/gglasses = 50,
- /obj/item/clothing/glasses/regular/hipster = 50,
- /obj/item/clothing/glasses/rimless = 50,
- /obj/item/clothing/glasses/thin = 50,
- /obj/item/clothing/glasses/monocle = 50,
- /obj/item/clothing/glasses/goggles = 50,
- /obj/item/clothing/glasses/fluff/spiffygogs = 50,
- /obj/item/clothing/glasses/fakesunglasses = 50,
- /obj/item/clothing/glasses/fakesunglasses/aviator = 50,
- /obj/item/clothing/mask/bandana/blue = 50,
- /obj/item/clothing/mask/bandana/gold = 50,
- /obj/item/clothing/mask/bandana/green = 50,
- /obj/item/clothing/mask/bandana/red = 50,
- /obj/item/clothing/mask/surgical = 50)
- premium = list(/obj/item/weapon/bedsheet/rainbow = 1)
- contraband = list(/obj/item/clothing/mask/gas/clown_hat = 1)
-
-/obj/machinery/vending/loadout/clothing
- name = "General Jump"
- desc = "A special vendor using compressed matter cartridges to store large amounts of clothing."
- product_ads = "Tired of your grey jumpsuit? Spruce yourself up!;We have the outfit for you!;Don't let that grey jumpsuit get you down, get a ROBUST outfit right now!;Using compressed matter catridges and VERY ETHICAL labor practices to bring YOU the clothing you crave!;Are you sure you want to go to work in THAT?;All of our wares have a whole TWO pockets!"
- icon_state = "clothing"
- vend_delay = 16
- products = list(/obj/item/clothing/under/bathrobe = 5,
- /obj/item/clothing/under/dress/black_corset = 5,
- /obj/item/clothing/under/blazer = 5,
- /obj/item/clothing/under/blazer/skirt = 5,
- /obj/item/clothing/under/cheongsam = 5,
- /obj/item/clothing/under/cheongsam/red = 5,
- /obj/item/clothing/under/cheongsam/blue = 5,
- /obj/item/clothing/under/cheongsam/black = 5,
- /obj/item/clothing/under/cheongsam/darkred = 5,
- /obj/item/clothing/under/cheongsam/green = 5,
- /obj/item/clothing/under/cheongsam/purple = 5,
- /obj/item/clothing/under/cheongsam/darkblue = 5,
- /obj/item/clothing/under/croptop = 5,
- /obj/item/clothing/under/croptop/red = 5,
- /obj/item/clothing/under/croptop/grey = 5,
- /obj/item/clothing/under/cuttop = 5,
- /obj/item/clothing/under/cuttop/red = 5,
- /obj/item/clothing/under/suit_jacket/female/skirt = 5,
- /obj/item/clothing/under/dress/dress_fire = 5,
- /obj/item/clothing/under/dress/flamenco = 5,
- /obj/item/clothing/under/dress/flower_dress = 5,
- /obj/item/clothing/under/fluff/gnshorts = 5,
- /obj/item/clothing/under/color = 5,
- /obj/item/clothing/under/color/aqua = 5,
- /obj/item/clothing/under/color/black = 5,
- /obj/item/clothing/under/color/blackf = 5,
- /obj/item/clothing/under/color/blackjumpskirt = 5,
- /obj/item/clothing/under/color/blue = 5,
- /obj/item/clothing/under/color/brown = 5,
- /obj/item/clothing/under/color/darkblue = 5,
- /obj/item/clothing/under/color/darkred = 5,
- /obj/item/clothing/under/color/green = 5,
- /obj/item/clothing/under/color/grey = 5,
- /obj/item/clothing/under/color/lightblue = 5,
- /obj/item/clothing/under/color/lightbrown = 5,
- /obj/item/clothing/under/color/lightgreen = 5,
- /obj/item/clothing/under/color/lightpurple = 5,
- /obj/item/clothing/under/color/lightred = 5,
- /obj/item/clothing/under/color/orange = 5,
- /obj/item/clothing/under/color/pink = 5,
- /obj/item/clothing/under/color/prison = 5,
- /obj/item/clothing/under/color/ranger = 5,
- /obj/item/clothing/under/color/red = 5,
- /obj/item/clothing/under/color/white = 5,
- /obj/item/clothing/under/color/yellow = 5,
- /obj/item/clothing/under/color/yellowgreen = 5,
- /obj/item/clothing/under/aether = 5,
- /obj/item/clothing/under/focal = 5,
- /obj/item/clothing/under/hephaestus = 5,
- /obj/item/clothing/under/wardt = 5,
- /obj/item/clothing/under/kilt = 5,
- /obj/item/clothing/under/fluff/latexmaid = 5,
- /obj/item/clothing/under/dress/lilacdress = 5,
- /obj/item/clothing/under/dress/white2 = 5,
- /obj/item/clothing/under/dress/white4 = 5,
- /obj/item/clothing/under/dress/maid = 5,
- /obj/item/clothing/under/dress/maid/sexy = 5,
- /obj/item/clothing/under/dress/maid/janitor = 5,
- /obj/item/clothing/under/moderncoat = 5,
- /obj/item/clothing/under/permit = 5,
- /obj/item/clothing/under/oldwoman = 5,
- /obj/item/clothing/under/frontier = 5,
- /obj/item/clothing/under/mbill = 5,
- /obj/item/clothing/under/pants/baggy/ = 5,
- /obj/item/clothing/under/pants/baggy/classicjeans = 5,
- /obj/item/clothing/under/pants/baggy/mustangjeans = 5,
- /obj/item/clothing/under/pants/baggy/blackjeans = 5,
- /obj/item/clothing/under/pants/baggy/greyjeans = 5,
- /obj/item/clothing/under/pants/baggy/youngfolksjeans = 5,
- /obj/item/clothing/under/pants/baggy/white = 5,
- /obj/item/clothing/under/pants/baggy/red = 5,
- /obj/item/clothing/under/pants/baggy/black = 5,
- /obj/item/clothing/under/pants/baggy/tan = 5,
- /obj/item/clothing/under/pants/baggy/track = 5,
- /obj/item/clothing/under/pants/baggy/khaki = 5,
- /obj/item/clothing/under/pants/baggy/camo = 5,
- /obj/item/clothing/under/pants/utility/ = 5,
- /obj/item/clothing/under/pants/utility/orange = 5,
- /obj/item/clothing/under/pants/utility/blue = 5,
- /obj/item/clothing/under/pants/utility/white = 5,
- /obj/item/clothing/under/pants/utility/red = 5,
- /obj/item/clothing/under/pants/chaps = 5,
- /obj/item/clothing/under/pants/chaps/black = 5,
- /obj/item/clothing/under/pants/track = 5,
- /obj/item/clothing/under/pants/track/red = 5,
- /obj/item/clothing/under/pants/track/white = 5,
- /obj/item/clothing/under/pants/track/green = 5,
- /obj/item/clothing/under/pants/track/blue = 5,
- /obj/item/clothing/under/pants/yogapants = 5,
- /obj/item/clothing/under/ascetic = 5,
- /obj/item/clothing/under/dress/white3 = 5,
- /obj/item/clothing/under/skirt/pleated = 5,
- /obj/item/clothing/under/dress/darkred = 5,
- /obj/item/clothing/under/dress/redeveninggown = 5,
- /obj/item/clothing/under/dress/red_swept_dress = 5,
- /obj/item/clothing/under/dress/sailordress = 5,
- /obj/item/clothing/under/dress/sari = 5,
- /obj/item/clothing/under/dress/sari/green = 5,
- /obj/item/clothing/under/dress/qipao = 5,
- /obj/item/clothing/under/dress/qipao/red = 5,
- /obj/item/clothing/under/dress/qipao/white = 5,
- /obj/item/clothing/under/shorts/red = 5,
- /obj/item/clothing/under/shorts/green = 5,
- /obj/item/clothing/under/shorts/blue = 5,
- /obj/item/clothing/under/shorts/black = 5,
- /obj/item/clothing/under/shorts/grey = 5,
- /obj/item/clothing/under/shorts/white = 5,
- /obj/item/clothing/under/shorts/jeans = 5,
- /obj/item/clothing/under/shorts/jeans/ = 5,
- /obj/item/clothing/under/shorts/jeans/classic = 5,
- /obj/item/clothing/under/shorts/jeans/mustang = 5,
- /obj/item/clothing/under/shorts/jeans/youngfolks = 5,
- /obj/item/clothing/under/shorts/jeans/black = 5,
- /obj/item/clothing/under/shorts/jeans/grey = 5,
- /obj/item/clothing/under/shorts/khaki/ = 5,
- /obj/item/clothing/under/skirt/loincloth = 5,
- /obj/item/clothing/under/skirt/khaki = 5,
- /obj/item/clothing/under/skirt/blue = 5,
- /obj/item/clothing/under/skirt/red = 5,
- /obj/item/clothing/under/skirt/denim = 5,
- /obj/item/clothing/under/skirt/pleated = 5,
- /obj/item/clothing/under/skirt/outfit/plaid_blue = 5,
- /obj/item/clothing/under/skirt/outfit/plaid_red = 5,
- /obj/item/clothing/under/skirt/outfit/plaid_purple = 5,
- /obj/item/clothing/under/overalls/sleek = 5,
- /obj/item/clothing/under/sl_suit = 5,
- /obj/item/clothing/under/gentlesuit = 5,
- /obj/item/clothing/under/gentlesuit/skirt = 5,
- /obj/item/clothing/under/suit_jacket = 5,
- /obj/item/clothing/under/suit_jacket/really_black/skirt = 5,
- /obj/item/clothing/under/suit_jacket/really_black = 5,
- /obj/item/clothing/under/suit_jacket/female/skirt = 5,
- /obj/item/clothing/under/suit_jacket/female/ = 5,
- /obj/item/clothing/under/suit_jacket/red = 5,
- /obj/item/clothing/under/suit_jacket/red/skirt = 5,
- /obj/item/clothing/under/suit_jacket/charcoal = 5,
- /obj/item/clothing/under/suit_jacket/charcoal/skirt = 5,
- /obj/item/clothing/under/suit_jacket/navy = 5,
- /obj/item/clothing/under/suit_jacket/navy/skirt = 5,
- /obj/item/clothing/under/suit_jacket/burgundy = 5,
- /obj/item/clothing/under/suit_jacket/burgundy/skirt = 5,
- /obj/item/clothing/under/suit_jacket/checkered = 5,
- /obj/item/clothing/under/suit_jacket/checkered/skirt = 5,
- /obj/item/clothing/under/suit_jacket/tan = 5,
- /obj/item/clothing/under/suit_jacket/tan/skirt = 5,
- /obj/item/clothing/under/scratch = 5,
- /obj/item/clothing/under/scratch/skirt = 5,
- /obj/item/clothing/under/sundress = 5,
- /obj/item/clothing/under/sundress_white = 5,
- /obj/item/clothing/under/rank/psych/turtleneck/sweater = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/blue = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/purple = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/green = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/red = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/white = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/earth = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/engineering = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/science = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/security = 5,
- /obj/item/weapon/storage/box/fluff/swimsuit/medical = 5,
- /obj/item/clothing/under/utility = 5,
- /obj/item/clothing/under/utility/grey = 5,
- /obj/item/clothing/under/utility/blue = 5,
- /obj/item/clothing/under/fluff/v_nanovest = 5,
- /obj/item/clothing/under/dress/westernbustle = 5,
- /obj/item/clothing/under/wedding/bride_white = 5,
- /obj/item/weapon/storage/backpack/ = 5,
- /obj/item/weapon/storage/backpack/messenger = 5,
- /obj/item/weapon/storage/backpack/satchel = 5)
- prices = list(/obj/item/clothing/under/bathrobe = 50,
- /obj/item/clothing/under/dress/black_corset = 50,
- /obj/item/clothing/under/blazer = 50,
- /obj/item/clothing/under/blazer/skirt = 50,
- /obj/item/clothing/under/cheongsam = 50,
- /obj/item/clothing/under/cheongsam/red = 50,
- /obj/item/clothing/under/cheongsam/blue = 50,
- /obj/item/clothing/under/cheongsam/black = 50,
- /obj/item/clothing/under/cheongsam/darkred = 50,
- /obj/item/clothing/under/cheongsam/green = 50,
- /obj/item/clothing/under/cheongsam/purple = 50,
- /obj/item/clothing/under/cheongsam/darkblue = 50,
- /obj/item/clothing/under/croptop = 50,
- /obj/item/clothing/under/croptop/red = 50,
- /obj/item/clothing/under/croptop/grey = 50,
- /obj/item/clothing/under/cuttop = 50,
- /obj/item/clothing/under/cuttop/red = 50,
- /obj/item/clothing/under/suit_jacket/female/skirt = 50,
- /obj/item/clothing/under/dress/dress_fire = 50,
- /obj/item/clothing/under/dress/flamenco = 50,
- /obj/item/clothing/under/dress/flower_dress = 50,
- /obj/item/clothing/under/fluff/gnshorts = 50,
- /obj/item/clothing/under/color = 50,
- /obj/item/clothing/under/color/aqua = 50,
- /obj/item/clothing/under/color/black = 50,
- /obj/item/clothing/under/color/blackf = 50,
- /obj/item/clothing/under/color/blackjumpskirt = 50,
- /obj/item/clothing/under/color/blue = 50,
- /obj/item/clothing/under/color/brown = 50,
- /obj/item/clothing/under/color/darkblue = 50,
- /obj/item/clothing/under/color/darkred = 50,
- /obj/item/clothing/under/color/green = 50,
- /obj/item/clothing/under/color/grey = 50,
- /obj/item/clothing/under/color/lightblue = 50,
- /obj/item/clothing/under/color/lightbrown = 50,
- /obj/item/clothing/under/color/lightgreen = 50,
- /obj/item/clothing/under/color/lightpurple = 50,
- /obj/item/clothing/under/color/lightred = 50,
- /obj/item/clothing/under/color/orange = 50,
- /obj/item/clothing/under/color/pink = 50,
- /obj/item/clothing/under/color/prison = 50,
- /obj/item/clothing/under/color/ranger = 50,
- /obj/item/clothing/under/color/red = 50,
- /obj/item/clothing/under/color/white = 50,
- /obj/item/clothing/under/color/yellow = 50,
- /obj/item/clothing/under/color/yellowgreen = 50,
- /obj/item/clothing/under/aether = 50,
- /obj/item/clothing/under/focal = 50,
- /obj/item/clothing/under/hephaestus = 50,
- /obj/item/clothing/under/wardt = 50,
- /obj/item/clothing/under/kilt = 50,
- /obj/item/clothing/under/fluff/latexmaid = 50,
- /obj/item/clothing/under/dress/lilacdress = 50,
- /obj/item/clothing/under/dress/white2 = 50,
- /obj/item/clothing/under/dress/white4 = 50,
- /obj/item/clothing/under/dress/maid = 50,
- /obj/item/clothing/under/dress/maid/sexy = 50,
- /obj/item/clothing/under/dress/maid/janitor = 50,
- /obj/item/clothing/under/moderncoat = 50,
- /obj/item/clothing/under/permit = 50,
- /obj/item/clothing/under/oldwoman = 50,
- /obj/item/clothing/under/frontier = 50,
- /obj/item/clothing/under/mbill = 50,
- /obj/item/clothing/under/pants/baggy/ = 50,
- /obj/item/clothing/under/pants/baggy/classicjeans = 50,
- /obj/item/clothing/under/pants/baggy/mustangjeans = 50,
- /obj/item/clothing/under/pants/baggy/blackjeans = 50,
- /obj/item/clothing/under/pants/baggy/greyjeans = 50,
- /obj/item/clothing/under/pants/baggy/youngfolksjeans = 50,
- /obj/item/clothing/under/pants/baggy/white = 50,
- /obj/item/clothing/under/pants/baggy/red = 50,
- /obj/item/clothing/under/pants/baggy/black = 50,
- /obj/item/clothing/under/pants/baggy/tan = 50,
- /obj/item/clothing/under/pants/baggy/track = 50,
- /obj/item/clothing/under/pants/baggy/khaki = 50,
- /obj/item/clothing/under/pants/baggy/camo = 50,
- /obj/item/clothing/under/pants/utility/ = 50,
- /obj/item/clothing/under/pants/utility/orange = 50,
- /obj/item/clothing/under/pants/utility/blue = 50,
- /obj/item/clothing/under/pants/utility/white = 50,
- /obj/item/clothing/under/pants/utility/red = 50,
- /obj/item/clothing/under/pants/chaps = 50,
- /obj/item/clothing/under/pants/chaps/black = 50,
- /obj/item/clothing/under/pants/track = 50,
- /obj/item/clothing/under/pants/track/red = 50,
- /obj/item/clothing/under/pants/track/white = 50,
- /obj/item/clothing/under/pants/track/green = 50,
- /obj/item/clothing/under/pants/track/blue = 50,
- /obj/item/clothing/under/pants/yogapants = 50,
- /obj/item/clothing/under/ascetic = 50,
- /obj/item/clothing/under/dress/white3 = 50,
- /obj/item/clothing/under/skirt/pleated = 50,
- /obj/item/clothing/under/dress/darkred = 50,
- /obj/item/clothing/under/dress/redeveninggown = 50,
- /obj/item/clothing/under/dress/red_swept_dress = 50,
- /obj/item/clothing/under/dress/sailordress = 50,
- /obj/item/clothing/under/dress/sari = 50,
- /obj/item/clothing/under/dress/sari/green = 50,
- /obj/item/clothing/under/dress/qipao = 50,
- /obj/item/clothing/under/dress/qipao/red = 50,
- /obj/item/clothing/under/dress/qipao/white = 50,
- /obj/item/clothing/under/shorts/red = 50,
- /obj/item/clothing/under/shorts/green = 50,
- /obj/item/clothing/under/shorts/blue = 50,
- /obj/item/clothing/under/shorts/black = 50,
- /obj/item/clothing/under/shorts/grey = 50,
- /obj/item/clothing/under/shorts/white = 50,
- /obj/item/clothing/under/shorts/jeans = 50,
- /obj/item/clothing/under/shorts/jeans/ = 50,
- /obj/item/clothing/under/shorts/jeans/classic = 50,
- /obj/item/clothing/under/shorts/jeans/mustang = 50,
- /obj/item/clothing/under/shorts/jeans/youngfolks = 50,
- /obj/item/clothing/under/shorts/jeans/black = 50,
- /obj/item/clothing/under/shorts/jeans/grey = 50,
- /obj/item/clothing/under/shorts/khaki/ = 50,
- /obj/item/clothing/under/skirt/loincloth = 50,
- /obj/item/clothing/under/skirt/khaki = 50,
- /obj/item/clothing/under/skirt/blue = 50,
- /obj/item/clothing/under/skirt/red = 50,
- /obj/item/clothing/under/skirt/denim = 50,
- /obj/item/clothing/under/skirt/pleated = 50,
- /obj/item/clothing/under/skirt/outfit/plaid_blue = 50,
- /obj/item/clothing/under/skirt/outfit/plaid_red = 50,
- /obj/item/clothing/under/skirt/outfit/plaid_purple = 50,
- /obj/item/clothing/under/overalls/sleek = 50,
- /obj/item/clothing/under/sl_suit = 50,
- /obj/item/clothing/under/gentlesuit = 50,
- /obj/item/clothing/under/gentlesuit/skirt = 50,
- /obj/item/clothing/under/suit_jacket = 50,
- /obj/item/clothing/under/suit_jacket/really_black/skirt = 50,
- /obj/item/clothing/under/suit_jacket/really_black = 50,
- /obj/item/clothing/under/suit_jacket/female/skirt = 50,
- /obj/item/clothing/under/suit_jacket/female/ = 50,
- /obj/item/clothing/under/suit_jacket/red = 50,
- /obj/item/clothing/under/suit_jacket/red/skirt = 50,
- /obj/item/clothing/under/suit_jacket/charcoal = 50,
- /obj/item/clothing/under/suit_jacket/charcoal/skirt = 50,
- /obj/item/clothing/under/suit_jacket/navy = 50,
- /obj/item/clothing/under/suit_jacket/navy/skirt = 50,
- /obj/item/clothing/under/suit_jacket/burgundy = 50,
- /obj/item/clothing/under/suit_jacket/burgundy/skirt = 50,
- /obj/item/clothing/under/suit_jacket/checkered = 50,
- /obj/item/clothing/under/suit_jacket/checkered/skirt = 50,
- /obj/item/clothing/under/suit_jacket/tan = 50,
- /obj/item/clothing/under/suit_jacket/tan/skirt = 50,
- /obj/item/clothing/under/scratch = 50,
- /obj/item/clothing/under/scratch/skirt = 50,
- /obj/item/clothing/under/sundress = 50,
- /obj/item/clothing/under/sundress_white = 50,
- /obj/item/clothing/under/rank/psych/turtleneck/sweater = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/blue = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/purple = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/green = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/red = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/white = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/earth = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/engineering = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/science = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/security = 50,
- /obj/item/weapon/storage/box/fluff/swimsuit/medical = 50,
- /obj/item/clothing/under/utility = 50,
- /obj/item/clothing/under/utility/grey = 50,
- /obj/item/clothing/under/utility/blue = 50,
- /obj/item/clothing/under/fluff/v_nanovest = 50,
- /obj/item/clothing/under/dress/westernbustle = 50,
- /obj/item/clothing/under/wedding/bride_white = 50,
- /obj/item/weapon/storage/backpack/ = 50,
- /obj/item/weapon/storage/backpack/messenger = 50,
- /obj/item/weapon/storage/backpack/satchel = 50)
- premium = list(/obj/item/clothing/under/color/rainbow = 1)
- contraband = list(/obj/item/clothing/under/rank/clown = 1)
-
-/obj/machinery/vending/loadout/gadget
- name = "Chips Co."
- desc = "A special vendor for devices and gadgets."
- product_ads = "You can't RESIST our great deals!;Feeling disconnected? We have a gadget for you!;You know you have the capacity to buy our capacitors!;FILL THAT HOLE IN YOUR HEART WITH OUR PLASTIC DISTRACTIONS!!!;Devices for everyone! Chips Co.!;ROBUST INVENTORY, GREAT PRICES! ;DON'T FORGET THE oyPAD 13s PRO! ON SALE NOW, ONLY ONE THOUSAND THALERS!"
- icon_state = "gadgets"
- vend_delay = 11
- products = list(/obj/item/clothing/suit/circuitry = 1,
- /obj/item/clothing/head/circuitry = 1,
- /obj/item/clothing/shoes/circuitry = 1,
- /obj/item/clothing/gloves/circuitry = 1,
- /obj/item/clothing/under/circuitry = 1,
- /obj/item/clothing/glasses/circuitry = 1,
- /obj/item/clothing/ears/circuitry = 1,
- /obj/item/device/text_to_speech = 5,
- /obj/item/device/paicard = 5,
- /obj/item/device/communicator = 10,
- /obj/item/device/communicator/watch = 10,
- /obj/item/device/radio = 10,
- /obj/item/device/camera = 5,
- /obj/item/device/taperecorder = 5,
- /obj/item/modular_computer/tablet/preset/custom_loadout/cheap = 5,
- /obj/item/device/pda = 10,
- /obj/item/device/radio/headset = 10,
- /obj/item/device/flashlight = 5,
- /obj/item/device/laser_pointer = 3,
- /obj/item/clothing/glasses/omnihud = 10)
- prices = list(/obj/item/clothing/suit/circuitry = 100,
- /obj/item/clothing/head/circuitry = 100,
- /obj/item/clothing/shoes/circuitry = 100,
- /obj/item/clothing/gloves/circuitry = 100,
- /obj/item/clothing/under/circuitry = 100,
- /obj/item/clothing/glasses/circuitry = 100,
- /obj/item/clothing/ears/circuitry = 100,
- /obj/item/device/text_to_speech = 300,
- /obj/item/device/paicard = 100,
- /obj/item/device/communicator = 100,
- /obj/item/device/communicator/watch = 100,
- /obj/item/device/radio = 100,
- /obj/item/device/camera = 100,
- /obj/item/device/taperecorder = 100,
- /obj/item/modular_computer/tablet/preset/custom_loadout/cheap = 1000,
- /obj/item/device/pda = 50,
- /obj/item/device/radio/headset = 50,
- /obj/item/device/flashlight = 100,
- /obj/item/device/laser_pointer = 200,
- /obj/item/clothing/glasses/omnihud = 100)
- premium = list(/obj/item/device/perfect_tele/one_beacon = 1)
- contraband = list(/obj/item/weapon/disk/nifsoft/compliance = 1)
-
-/obj/machinery/vending/loadout/loadout_misc
- name = "Bits and Bobs"
- desc = "A special vendor for things and also stuff!"
- product_ads = "You never know when you might need an umbrella.;Hey kid... want some cardemon cards?;Miscellaneous for your miscellaneous heart.;Who's bob? Wouldn't you like to know.;I'm sorry there's no grappling hooks in our umbrellas.;We sell things AND stuff."
- icon_state = "loadout_misc"
- products = list(/obj/item/weapon/cane = 5,
- /obj/item/weapon/pack/cardemon = 25,
- /obj/item/weapon/deck/holder = 5,
- /obj/item/weapon/deck/cah = 5,
- /obj/item/weapon/deck/cah/black = 5,
- /obj/item/weapon/deck/tarot = 5,
- /obj/item/weapon/deck/cards = 5,
- /obj/item/weapon/pack/spaceball = 10,
- /obj/item/weapon/storage/pill_bottle/dice = 5,
- /obj/item/weapon/storage/pill_bottle/dice_nerd = 5,
- /obj/item/weapon/melee/umbrella/random = 10)
- prices = list(/obj/item/weapon/cane = 100,
- /obj/item/weapon/pack/cardemon = 100,
- /obj/item/weapon/deck/holder = 100,
- /obj/item/weapon/deck/cah = 100,
- /obj/item/weapon/deck/cah/black = 100,
- /obj/item/weapon/deck/tarot = 100,
- /obj/item/weapon/deck/cards = 100,
- /obj/item/weapon/pack/spaceball = 100,
- /obj/item/weapon/storage/pill_bottle/dice = 100,
- /obj/item/weapon/storage/pill_bottle/dice_nerd = 100,
- /obj/item/weapon/melee/umbrella/random = 100)
- premium = list(/obj/item/toy/bosunwhistle = 1)
- contraband = list(/obj/item/toy/katana = 1)
-
-/obj/machinery/vending/loadout/overwear
- name = "Big D's Best"
- desc = "A special vendor using compressed matter cartridges to store large amounts of overwear!"
- product_ads = "Dress your best! It's what big D would want.;Overwear for all occasions!;Big D has what you need if what you need is some form of jacket!;Need a new hoodie? Bid D has you covered.;Big D says you need a new suit!;Big D smiles when he sees you in one of his coats!"
- icon_state = "suit"
- vend_delay = 16
- products = list(/obj/item/clothing/suit/storage/apron = 5,
- /obj/item/clothing/suit/storage/flannel/aqua = 5,
- /obj/item/clothing/suit/storage/toggle/bomber = 5,
- /obj/item/clothing/suit/storage/bomber/alt = 5,
- /obj/item/clothing/suit/storage/flannel/brown = 5,
- /obj/item/clothing/suit/storage/toggle/cardigan = 5,
- /obj/item/clothing/accessory/poncho/roles/cloak/custom = 5,
- /obj/item/clothing/suit/storage/duster = 5,
- /obj/item/clothing/suit/storage/toggle/denim_jacket = 5,
- /obj/item/clothing/suit/storage/toggle/denim_jacket/nanotrasen = 5,
- /obj/item/clothing/suit/storage/toggle/denim_jacket/sleeveless = 5,
- /obj/item/clothing/suit/storage/toggle/denim_jacket/nanotrasen/sleeveless = 5,
- /obj/item/clothing/suit/storage/fluff/gntop = 5,
- /obj/item/clothing/suit/greatcoat = 5,
- /obj/item/clothing/suit/storage/flannel = 5,
- /obj/item/clothing/suit/storage/greyjacket = 5,
- /obj/item/clothing/suit/storage/hazardvest = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/black = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/red = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/blue = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/green = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/orange = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/yellow = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/cti = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/mu = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/nt = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/smw = 5,
- /obj/item/clothing/suit/storage/toggle/hoodie/nrti = 5,
- /obj/item/clothing/suit/storage/fluff/jacket/field = 5,
- /obj/item/clothing/suit/storage/fluff/jacket/air_cavalry = 5,
- /obj/item/clothing/suit/storage/fluff/jacket/air_force = 5,
- /obj/item/clothing/suit/storage/fluff/jacket/navy = 5,
- /obj/item/clothing/suit/storage/fluff/jacket/special_forces = 5,
- /obj/item/clothing/suit/kamishimo = 5,
- /obj/item/clothing/suit/kimono = 5,
- /obj/item/clothing/suit/storage/toggle/labcoat = 5,
- /obj/item/clothing/suit/storage/toggle/labcoat/blue = 5,
- /obj/item/clothing/suit/storage/toggle/labcoat/blue_edge = 5,
- /obj/item/clothing/suit/storage/toggle/labcoat/green = 5,
- /obj/item/clothing/suit/storage/toggle/labcoat/orange = 5,
- /obj/item/clothing/suit/storage/toggle/labcoat/pink = 5,
- /obj/item/clothing/suit/storage/toggle/labcoat/red = 5,
- /obj/item/clothing/suit/storage/toggle/labcoat/yellow = 5,
- /obj/item/clothing/suit/leathercoat = 5,
- /obj/item/clothing/suit/storage/toggle/leather_jacket = 5,
- /obj/item/clothing/suit/storage/leather_jacket_alt = 5,
- /obj/item/clothing/suit/storage/toggle/brown_jacket = 5,
- /obj/item/clothing/suit/storage/toggle/leather_jacket/nanotrasen = 5,
- /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen = 5,
- /obj/item/clothing/suit/storage/toggle/leather_jacket/sleeveless = 5,
- /obj/item/clothing/suit/storage/toggle/brown_jacket/sleeveless = 5,
- /obj/item/clothing/suit/storage/toggle/leather_jacket/nanotrasen/sleeveless = 5,
- /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen/sleeveless = 5,
- /obj/item/clothing/suit/storage/miljacket = 5,
- /obj/item/clothing/suit/storage/miljacket/alt = 5,
- /obj/item/clothing/suit/storage/miljacket/green = 5,
- /obj/item/clothing/suit/storage/apron/overalls = 5,
- /obj/item/clothing/suit/storage/toggle/peacoat = 5,
- /obj/item/clothing/accessory/poncho = 5,
- /obj/item/clothing/accessory/poncho/green = 5,
- /obj/item/clothing/accessory/poncho/red = 5,
- /obj/item/clothing/accessory/poncho/purple = 5,
- /obj/item/clothing/accessory/poncho/blue = 5,
- /obj/item/clothing/suit/jacket/puffer = 5,
- /obj/item/clothing/suit/jacket/puffer/vest = 5,
- /obj/item/clothing/suit/storage/flannel/red = 5,
- /obj/item/clothing/suit/unathi/robe = 5,
- /obj/item/clothing/suit/storage/hooded/wintercoat/snowsuit = 5,
- /obj/item/clothing/suit/storage/toggle/internalaffairs = 5,
- /obj/item/clothing/suit/storage/toggle/lawyer/bluejacket = 5,
- /obj/item/clothing/suit/storage/toggle/lawyer/purpjacket = 5,
- /obj/item/clothing/suit/suspenders = 5,
- /obj/item/clothing/suit/storage/toggle/track = 5,
- /obj/item/clothing/suit/storage/toggle/track/blue = 5,
- /obj/item/clothing/suit/storage/toggle/track/green = 5,
- /obj/item/clothing/suit/storage/toggle/track/red = 5,
- /obj/item/clothing/suit/storage/toggle/track/white = 5,
- /obj/item/clothing/suit/storage/trench = 5,
- /obj/item/clothing/suit/storage/trench/grey = 5,
- /obj/item/clothing/suit/varsity = 5,
- /obj/item/clothing/suit/varsity/red = 5,
- /obj/item/clothing/suit/varsity/purple = 5,
- /obj/item/clothing/suit/varsity/green = 5,
- /obj/item/clothing/suit/varsity/blue = 5,
- /obj/item/clothing/suit/varsity/brown = 5,
- /obj/item/clothing/suit/storage/hooded/wintercoat = 5,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey = 5)
- prices = list(/obj/item/clothing/suit/storage/apron = 100,
- /obj/item/clothing/suit/storage/flannel/aqua = 100,
- /obj/item/clothing/suit/storage/toggle/bomber = 100,
- /obj/item/clothing/suit/storage/bomber/alt = 100,
- /obj/item/clothing/suit/storage/flannel/brown = 100,
- /obj/item/clothing/suit/storage/toggle/cardigan = 100,
- /obj/item/clothing/accessory/poncho/roles/cloak/custom = 100,
- /obj/item/clothing/suit/storage/duster = 100,
- /obj/item/clothing/suit/storage/toggle/denim_jacket = 100,
- /obj/item/clothing/suit/storage/toggle/denim_jacket/nanotrasen = 100,
- /obj/item/clothing/suit/storage/toggle/denim_jacket/sleeveless = 100,
- /obj/item/clothing/suit/storage/toggle/denim_jacket/nanotrasen/sleeveless = 100,
- /obj/item/clothing/suit/storage/fluff/gntop = 100,
- /obj/item/clothing/suit/greatcoat = 100,
- /obj/item/clothing/suit/storage/flannel = 100,
- /obj/item/clothing/suit/storage/greyjacket = 100,
- /obj/item/clothing/suit/storage/hazardvest = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/black = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/red = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/blue = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/green = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/orange = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/yellow = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/cti = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/mu = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/nt = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/smw = 100,
- /obj/item/clothing/suit/storage/toggle/hoodie/nrti = 100,
- /obj/item/clothing/suit/storage/fluff/jacket/field = 100,
- /obj/item/clothing/suit/storage/fluff/jacket/air_cavalry = 100,
- /obj/item/clothing/suit/storage/fluff/jacket/air_force = 100,
- /obj/item/clothing/suit/storage/fluff/jacket/navy = 100,
- /obj/item/clothing/suit/storage/fluff/jacket/special_forces = 100,
- /obj/item/clothing/suit/kamishimo = 100,
- /obj/item/clothing/suit/kimono = 100,
- /obj/item/clothing/suit/storage/toggle/labcoat = 100,
- /obj/item/clothing/suit/storage/toggle/labcoat/blue = 100,
- /obj/item/clothing/suit/storage/toggle/labcoat/blue_edge = 100,
- /obj/item/clothing/suit/storage/toggle/labcoat/green = 100,
- /obj/item/clothing/suit/storage/toggle/labcoat/orange = 100,
- /obj/item/clothing/suit/storage/toggle/labcoat/pink = 100,
- /obj/item/clothing/suit/storage/toggle/labcoat/red = 100,
- /obj/item/clothing/suit/storage/toggle/labcoat/yellow = 100,
- /obj/item/clothing/suit/leathercoat = 100,
- /obj/item/clothing/suit/storage/toggle/leather_jacket = 100,
- /obj/item/clothing/suit/storage/leather_jacket_alt = 100,
- /obj/item/clothing/suit/storage/toggle/brown_jacket = 100,
- /obj/item/clothing/suit/storage/toggle/leather_jacket/nanotrasen = 100,
- /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen = 100,
- /obj/item/clothing/suit/storage/toggle/leather_jacket/sleeveless = 100,
- /obj/item/clothing/suit/storage/toggle/brown_jacket/sleeveless = 100,
- /obj/item/clothing/suit/storage/toggle/leather_jacket/nanotrasen/sleeveless = 100,
- /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen/sleeveless = 100,
- /obj/item/clothing/suit/storage/miljacket = 100,
- /obj/item/clothing/suit/storage/miljacket/alt = 100,
- /obj/item/clothing/suit/storage/miljacket/green = 100,
- /obj/item/clothing/suit/storage/apron/overalls = 100,
- /obj/item/clothing/suit/storage/toggle/peacoat = 100,
- /obj/item/clothing/accessory/poncho = 100,
- /obj/item/clothing/accessory/poncho/green = 100,
- /obj/item/clothing/accessory/poncho/red = 100,
- /obj/item/clothing/accessory/poncho/purple = 100,
- /obj/item/clothing/accessory/poncho/blue = 100,
- /obj/item/clothing/suit/jacket/puffer = 100,
- /obj/item/clothing/suit/jacket/puffer/vest = 100,
- /obj/item/clothing/suit/storage/flannel/red = 100,
- /obj/item/clothing/suit/unathi/robe = 100,
- /obj/item/clothing/suit/storage/hooded/wintercoat/snowsuit = 100,
- /obj/item/clothing/suit/storage/toggle/internalaffairs = 100,
- /obj/item/clothing/suit/storage/toggle/lawyer/bluejacket = 100,
- /obj/item/clothing/suit/storage/toggle/lawyer/purpjacket = 100,
- /obj/item/clothing/suit/suspenders = 100,
- /obj/item/clothing/suit/storage/toggle/track = 100,
- /obj/item/clothing/suit/storage/toggle/track/blue = 100,
- /obj/item/clothing/suit/storage/toggle/track/green = 100,
- /obj/item/clothing/suit/storage/toggle/track/red = 100,
- /obj/item/clothing/suit/storage/toggle/track/white = 100,
- /obj/item/clothing/suit/storage/trench = 100,
- /obj/item/clothing/suit/storage/trench/grey = 100,
- /obj/item/clothing/suit/varsity = 100,
- /obj/item/clothing/suit/varsity/red = 100,
- /obj/item/clothing/suit/varsity/purple = 100,
- /obj/item/clothing/suit/varsity/green = 100,
- /obj/item/clothing/suit/varsity/blue = 100,
- /obj/item/clothing/suit/varsity/brown = 100,
- /obj/item/clothing/suit/storage/hooded/wintercoat = 100,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey = 100)
- premium = list(/obj/item/clothing/suit/imperium_monk = 3)
- contraband = list(/obj/item/toy/katana = 1)
-
-/obj/machinery/vending/loadout/costume
- name = "Thespian's Delight"
- desc = "Sometimes nerds need costumes!"
- product_ads = "Don't let your art be stifled!;Remember, practice makes perfect!;Break a leg!;Don't make me get the cane!;Thespian's Delight entering stage right!;Costumes for your acting needs!"
- icon = 'icons/obj/vending.dmi'
- icon_state = "theater"
- products = list(/obj/item/clothing/suit/storage/hooded/carp_costume = 3,
- /obj/item/clothing/suit/storage/hooded/carp_costume = 3,
- /obj/item/clothing/suit/chickensuit = 3,
- /obj/item/clothing/head/chicken = 3,
- /obj/item/clothing/head/helmet/gladiator = 3,
- /obj/item/clothing/under/gladiator = 3,
- /obj/item/clothing/suit/storage/toggle/labcoat/mad = 3,
- /obj/item/clothing/under/gimmick/rank/captain/suit = 3,
- /obj/item/clothing/glasses/gglasses = 3,
- /obj/item/clothing/head/flatcap = 3,
- /obj/item/clothing/shoes/boots/jackboots = 3,
- /obj/item/clothing/under/schoolgirl = 3,
- /obj/item/clothing/head/kitty = 3,
- /obj/item/clothing/glasses/sunglasses/blindfold = 3,
- /obj/item/clothing/head/beret = 3,
- /obj/item/clothing/under/skirt = 3,
- /obj/item/clothing/under/suit_jacket = 3,
- /obj/item/clothing/head/that = 3,
- /obj/item/clothing/accessory/wcoat = 3,
- /obj/item/clothing/under/scratch = 3,
- /obj/item/clothing/shoes/white = 3,
- /obj/item/clothing/gloves/white = 3,
- /obj/item/clothing/under/kilt = 3,
- /obj/item/clothing/glasses/monocle = 3,
- /obj/item/clothing/under/sl_suit = 3,
- /obj/item/clothing/mask/fakemoustache = 3,
- /obj/item/weapon/cane = 3,
- /obj/item/clothing/head/bowler = 3,
- /obj/item/clothing/head/plaguedoctorhat = 3,
- /obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 3,
- /obj/item/clothing/mask/gas/plaguedoctor/fluff = 3,
- /obj/item/clothing/under/owl = 3,
- /obj/item/clothing/mask/gas/owl_mask = 3,
- /obj/item/clothing/under/waiter = 3,
- /obj/item/clothing/suit/storage/apron = 3,
- /obj/item/clothing/under/pirate = 3,
- /obj/item/clothing/head/pirate = 3,
- /obj/item/clothing/suit/pirate = 3,
- /obj/item/clothing/glasses/eyepatch = 3,
- /obj/item/clothing/head/ushanka = 3,
- /obj/item/clothing/under/soviet = 3,
- /obj/item/clothing/suit/imperium_monk = 1,
- /obj/item/clothing/suit/holidaypriest = 3,
- /obj/item/clothing/head/witchwig = 3,
- /obj/item/clothing/under/sundress = 3,
- /obj/item/weapon/staff/broom = 3,
- /obj/item/clothing/suit/wizrobe/fake = 3,
- /obj/item/clothing/head/wizard/fake = 3,
- /obj/item/weapon/staff = 3,
- /obj/item/clothing/mask/gas/sexyclown = 3,
- /obj/item/clothing/under/sexyclown = 3,
- /obj/item/clothing/mask/gas/sexymime = 3,
- /obj/item/clothing/under/sexymime = 3,
- /obj/item/clothing/suit/storage/hooded/knight_costume = 3,
- /obj/item/clothing/suit/storage/hooded/knight_costume/galahad = 3,
- /obj/item/clothing/suit/storage/hooded/knight_costume/lancelot = 3,
- /obj/item/clothing/suit/storage/hooded/knight_costume/robin = 3,
- /obj/item/clothing/suit/armor/combat/crusader_costume = 3,
- /obj/item/clothing/suit/armor/combat/crusader_costume/bedevere = 3,
- /obj/item/clothing/head/helmet/combat/crusader_costume = 3,
- /obj/item/clothing/head/helmet/combat/bedevere_costume = 3,
- /obj/item/clothing/gloves/combat/knight_costume = 3,
- /obj/item/clothing/gloves/combat/knight_costume/brown = 3,
- /obj/item/clothing/shoes/knight_costume = 3,
- /obj/item/clothing/shoes/knight_costume/black = 3)
- prices = list(/obj/item/clothing/suit/storage/hooded/carp_costume = 200,
- /obj/item/clothing/suit/storage/hooded/carp_costume = 200,
- /obj/item/clothing/suit/chickensuit = 200,
- /obj/item/clothing/head/chicken = 200,
- /obj/item/clothing/head/helmet/gladiator = 300,
- /obj/item/clothing/under/gladiator = 500,
- /obj/item/clothing/suit/storage/toggle/labcoat/mad = 200,
- /obj/item/clothing/under/gimmick/rank/captain/suit = 200,
- /obj/item/clothing/glasses/gglasses = 200,
- /obj/item/clothing/head/flatcap = 200,
- /obj/item/clothing/shoes/boots/jackboots = 200,
- /obj/item/clothing/under/schoolgirl = 200,
- /obj/item/clothing/head/kitty = 200,
- /obj/item/clothing/glasses/sunglasses/blindfold = 200,
- /obj/item/clothing/head/beret = 200,
- /obj/item/clothing/under/skirt = 200,
- /obj/item/clothing/under/suit_jacket = 200,
- /obj/item/clothing/head/that = 200,
- /obj/item/clothing/accessory/wcoat = 200,
- /obj/item/clothing/under/scratch = 200,
- /obj/item/clothing/shoes/white = 200,
- /obj/item/clothing/gloves/white = 200,
- /obj/item/clothing/under/kilt = 200,
- /obj/item/clothing/glasses/monocle = 400,
- /obj/item/clothing/under/sl_suit = 200,
- /obj/item/clothing/mask/fakemoustache = 200,
- /obj/item/weapon/cane = 300,
- /obj/item/clothing/head/bowler = 200,
- /obj/item/clothing/head/plaguedoctorhat = 300,
- /obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 300,
- /obj/item/clothing/mask/gas/plaguedoctor/fluff = 600,
- /obj/item/clothing/under/owl = 400,
- /obj/item/clothing/mask/gas/owl_mask = 400,
- /obj/item/clothing/under/waiter = 100,
- /obj/item/clothing/suit/storage/apron = 200,
- /obj/item/clothing/under/pirate = 300,
- /obj/item/clothing/head/pirate = 400,
- /obj/item/clothing/suit/pirate = 600,
- /obj/item/clothing/glasses/eyepatch = 200,
- /obj/item/clothing/head/ushanka = 200,
- /obj/item/clothing/under/soviet = 200,
- /obj/item/clothing/suit/imperium_monk = 2000,
- /obj/item/clothing/suit/holidaypriest = 200,
- /obj/item/clothing/head/witchwig = 200,
- /obj/item/clothing/under/sundress = 50,
- /obj/item/weapon/staff/broom = 400,
- /obj/item/clothing/suit/wizrobe/fake = 200,
- /obj/item/clothing/head/wizard/fake = 200,
- /obj/item/weapon/staff = 400,
- /obj/item/clothing/mask/gas/sexyclown = 600,
- /obj/item/clothing/under/sexyclown = 200,
- /obj/item/clothing/mask/gas/sexymime = 600,
- /obj/item/clothing/under/sexymime = 200,
- /obj/item/clothing/suit/storage/hooded/knight_costume = 200,
- /obj/item/clothing/suit/storage/hooded/knight_costume/galahad = 200,
- /obj/item/clothing/suit/storage/hooded/knight_costume/lancelot = 200,
- /obj/item/clothing/suit/storage/hooded/knight_costume/robin = 200,
- /obj/item/clothing/suit/armor/combat/crusader_costume = 200,
- /obj/item/clothing/suit/armor/combat/crusader_costume/bedevere = 200,
- /obj/item/clothing/head/helmet/combat/crusader_costume = 200,
- /obj/item/clothing/head/helmet/combat/bedevere_costume = 200,
- /obj/item/clothing/gloves/combat/knight_costume = 200,
- /obj/item/clothing/gloves/combat/knight_costume/brown = 200,
- /obj/item/clothing/shoes/knight_costume = 200,
- /obj/item/clothing/shoes/knight_costume/black = 200)
- premium = list(/obj/item/clothing/suit/imperium_monk = 3,
- /obj/item/clothing/suit/barding/agatha = 2,
- /obj/item/clothing/suit/barding/alt_agatha = 2,
- /obj/item/clothing/suit/barding/mason = 2,
- /obj/item/clothing/suit/drake_cloak = 2)
- contraband = list(/obj/item/clothing/head/syndicatefake = 1,
- /obj/item/clothing/suit/syndicatefake = 1)
-
-//TFF 19/12/19 - Brig version of a seed storage vendor
-/obj/machinery/seed_storage/brig
- name = "Prisoners' food seed storage"
- starting_seeds = list(
- /obj/item/seeds/appleseed = 3,
- /obj/item/seeds/bananaseed = 3,
- /obj/item/seeds/berryseed = 3,
- /obj/item/seeds/cabbageseed = 3,
- /obj/item/seeds/carrotseed = 3,
- /obj/item/seeds/celery = 3,
- /obj/item/seeds/chantermycelium = 3,
- /obj/item/seeds/cherryseed = 3,
- /obj/item/seeds/chiliseed = 3,
- /obj/item/seeds/cocoapodseed = 3,
- /obj/item/seeds/cornseed = 3,
- /obj/item/seeds/durian = 3,
- /obj/item/seeds/eggplantseed = 3,
- /obj/item/seeds/grapeseed = 3,
- /obj/item/seeds/grassseed = 3,
- /obj/item/seeds/replicapod = 3,
- /obj/item/seeds/lavenderseed = 3,
- /obj/item/seeds/lemonseed = 3,
- /obj/item/seeds/lettuce = 3,
- /obj/item/seeds/limeseed = 3,
- /obj/item/seeds/mtearseed = 2,
- /obj/item/seeds/orangeseed = 3,
- /obj/item/seeds/onionseed = 3,
- /obj/item/seeds/peanutseed = 3,
- /obj/item/seeds/plumpmycelium = 3,
- /obj/item/seeds/poppyseed = 3,
- /obj/item/seeds/potatoseed = 3,
- /obj/item/seeds/pumpkinseed = 3,
- /obj/item/seeds/rhubarb = 3,
- /obj/item/seeds/riceseed = 3,
- /obj/item/seeds/rose = 3,
- /obj/item/seeds/soyaseed = 3,
- /obj/item/seeds/spineapple = 3,
- /obj/item/seeds/sugarcaneseed = 3,
- /obj/item/seeds/sunflowerseed = 3,
- /obj/item/seeds/shandseed = 2,
- /obj/item/seeds/tobaccoseed = 3,
- /obj/item/seeds/tomatoseed = 3,
- /obj/item/seeds/towermycelium = 3,
- /obj/item/seeds/vanilla = 3,
- /obj/item/seeds/watermelonseed = 3,
- /obj/item/seeds/wheatseed = 3,
- /obj/item/seeds/whitebeetseed = 3,
- /obj/item/seeds/wabback = 2)
-
-/obj/machinery/vending/hydronutrients/brig
- name = "Brig NutriMax"
- desc = "A plant nutrients vendor. Seems some items aren't included."
- products = list(/obj/item/weapon/reagent_containers/glass/bottle/eznutrient = 6,/obj/item/weapon/reagent_containers/glass/bottle/left4zed = 4,/obj/item/weapon/reagent_containers/glass/bottle/robustharvest = 3,/obj/item/weapon/plantspray/pests = 20,
- /obj/item/weapon/reagent_containers/glass/beaker = 4,/obj/item/weapon/storage/bag/plants = 5)
- premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5)
-
-/obj/machinery/vending/emergencyfood
- name = "Food Cube Dispenser"
- desc = "An ominous machine dispensing food cubes. It will keep you fed, but at what cost?"
- icon = 'icons/obj/vending_vr.dmi'
- icon_state = "foodcube"
- product_ads = "Afraid to starve?;Starvation is not an option!;Add water before consumption.;Let me take care of you.;Dire circumstances call for food cubes, do not let the taste deter you."
- products = list(/obj/item/weapon/storage/box/wings/tray = 5,
- /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 10)
- contraband = list(/obj/item/weapon/storage/box/wings/tray = 5)
-
-/obj/machinery/vending/emergencyfood/filled
- products = list(/obj/item/weapon/storage/box/wings/tray = 40)
- contraband = list(/obj/item/weapon/storage/box/wings/tray = 20)
-
-/obj/machinery/vending/cola
- icon_state = "Soda_Machine"
-
-/obj/machinery/vending/cola/soft
- icon = 'icons/obj/vending_vr.dmi'
- icon_state = "Cola_Machine"
-
-//Tweaked existing vendors
-/obj/machinery/vending/hydroseeds/New()
- products += list(/obj/item/seeds/shrinkshroom = 3,/obj/item/seeds/megashroom = 3)
- ..()
-
-/obj/machinery/vending/security/New()
- products += list(/obj/item/weapon/gun/energy/taser = 8,/obj/item/weapon/gun/energy/stunrevolver = 4,
- /obj/item/weapon/reagent_containers/spray/pepper = 6,/obj/item/taperoll/police = 6,
- /obj/item/clothing/glasses/omnihud/sec = 6)
- ..()
-
-/obj/machinery/vending/tool/New()
- products += list(/obj/item/weapon/reagent_containers/spray/windowsealant = 5)
- ..()
-
-/obj/machinery/vending/engivend/New()
- products += list(/obj/item/clothing/glasses/omnihud/eng = 6)
- contraband += list(/obj/item/weapon/rms = 5)
- ..()
-
-/obj/machinery/vending/medical/New()
- products += list(/obj/item/weapon/storage/box/khcrystal = 4,/obj/item/weapon/backup_implanter = 3,
- /obj/item/clothing/glasses/omnihud/med = 4, /obj/item/device/glasses_kit = 1, /obj/item/weapon/storage/quickdraw/syringe_case = 4)
- ..()
-
-//I want this not just as part of the zoo. ;v
-/obj/machinery/vending/food
- name = "Food-O-Mat"
- desc = "A technological marvel, supposedly able to cook or mix a large variety of food or drink."
- icon_state = "hotfood"
- products = list(/obj/item/weapon/tray = 8,
- /obj/item/weapon/material/kitchen/utensil/fork = 6,
- /obj/item/weapon/material/knife/plastic = 6,
- /obj/item/weapon/material/kitchen/utensil/spoon = 6,
- /obj/item/weapon/reagent_containers/food/snacks/tomatosoup = 8,
- /obj/item/weapon/reagent_containers/food/snacks/mushroomsoup = 8,
- /obj/item/weapon/reagent_containers/food/snacks/jellysandwich = 8,
- /obj/item/weapon/reagent_containers/food/snacks/taco = 8,
- /obj/item/weapon/reagent_containers/food/snacks/cheeseburger = 8,
- /obj/item/weapon/reagent_containers/food/snacks/grilledcheese = 8,
- /obj/item/weapon/reagent_containers/food/snacks/hotdog = 8,
- /obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato = 8,
- /obj/item/weapon/reagent_containers/food/snacks/omelette = 8,
- /obj/item/weapon/reagent_containers/food/snacks/pastatomato = 8,
- /obj/item/weapon/reagent_containers/food/snacks/tofuburger = 8,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza = 2,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza = 2,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita = 2,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza = 2,
- /obj/item/weapon/reagent_containers/food/snacks/waffles = 4,
- /obj/item/weapon/reagent_containers/food/snacks/muffin = 4,
- /obj/item/weapon/reagent_containers/food/snacks/appletart = 4,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake = 2,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread = 2,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread = 2
- )
- contraband = list(/obj/item/weapon/reagent_containers/food/snacks/mysterysoup = 10)
- vend_delay = 15
-
-/obj/machinery/vending/food/arojoan //Fluff vendor for the lewd houseboat.
- name = "Custom Food-O-Mat"
- desc = "Do you think Joan cooks? Of course not. Lazy squirrel!"
- products = list(/obj/item/weapon/tray = 6,
- /obj/item/weapon/material/kitchen/utensil/fork = 6,
- /obj/item/weapon/material/knife/plastic = 6,
- /obj/item/weapon/material/kitchen/utensil/spoon = 6,
- /obj/item/weapon/reagent_containers/food/snacks/hotandsoursoup = 3,
- /obj/item/weapon/reagent_containers/food/snacks/kitsuneudon = 3,
- /obj/item/weapon/reagent_containers/food/snacks/generalschicken = 3,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/sushi = 2,
- /obj/item/weapon/reagent_containers/food/snacks/jellysandwich = 3,
- /obj/item/weapon/reagent_containers/food/snacks/grilledcheese = 3,
- /obj/item/weapon/reagent_containers/food/snacks/hotdog = 3,
- /obj/item/weapon/storage/box/wings = 2,
- /obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato = 3,
- /obj/item/weapon/reagent_containers/food/snacks/omelette = 3,
- /obj/item/weapon/reagent_containers/food/snacks/waffles = 3,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza = 1,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza = 1,
- /obj/item/weapon/reagent_containers/food/snacks/appletart = 2,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake = 1,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread = 2,
- /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread = 2
- )
- contraband = list(/obj/item/weapon/reagent_containers/food/snacks/mysterysoup = 10)
- vend_delay = 15
-/* For later, then
-/obj/machinery/vending/weapon_machine
- name = "Frozen Star Guns&Ammo"
- desc = "A self-defense equipment vending machine. When you need to take care of that clown."
- product_slogans = "The best defense is good offense!;Buy for your whole family today!;Nobody can outsmart bullet!;God created man - Frozen Star made them EQUAL!;Nobody can outsmart bullet!;Stupidity can be cured! By LEAD.;Dead kids can't bully your children!"
- product_ads = "Stunning!;Take justice in your own hands!;LEADearship!"
- icon = 'icons/obj/vending_vr.dmi'
- icon_state = "weapon"
- products = list(/obj/item/device/flash = 6,/obj/item/weapon/reagent_containers/spray/pepper = 6, /obj/item/weapon/gun/projectile/olivaw = 5, /obj/item/weapon/gun/projectile/giskard = 5, /obj/item/ammo_magazine/mg/cl32/rubber = 20)
- contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6)
- prices = list(/obj/item/device/flash = 600,/obj/item/weapon/reagent_containers/spray/pepper = 800, /obj/item/weapon/gun/projectile/olivaw = 1600, /obj/item/weapon/gun/projectile/giskard = 1200, /obj/item/ammo_magazine/mg/cl32/rubber = 200)
-*/
-
/obj/machinery/vending/fitness/New()
products += list(/obj/item/weapon/reagent_containers/food/snacks/liquidprotein = 8)
prices += list(/obj/item/weapon/reagent_containers/food/snacks/liquidprotein = 5)
@@ -1616,17 +279,22 @@
products = list(/obj/item/weapon/card/id/syndicate/station_access = 1,
/obj/item/weapon/storage/box/syndie_kit/chameleon = 1,
/obj/item/clothing/mask/bandana = 1,
+ /obj/item/clothing/glasses/sunglasses = 1,
/obj/item/device/radio/headset/syndicate/alt = 1,
/obj/item/device/pda = 1,
/obj/item/device/communicator = 1,
/obj/item/weapon/tape_roll = 2,
/obj/item/weapon/handcuffs = 4,
+ /obj/item/weapon/handcuffs/legcuffs = 4,
/obj/item/weapon/cell/device/weapon/recharge/alien = 2,
/obj/item/device/chameleon = 1,
- /obj/item/weapon/storage/mre/menu11 = 2
+ /obj/item/weapon/storage/mre/menu11 = 2,
+ /obj/item/device/flash = 2,
+ /obj/item/weapon/pen/reagent/paralysis = 4,
+ /obj/item/device/perfect_tele/alien = 1
)
vend_delay = 15
-
+
/obj/machinery/vending/loadout
name = "Fingers and Toes"
desc = "A special vendor for gloves and shoes!"
@@ -2075,6 +743,7 @@
/obj/item/clothing/under/dress/maid = 5,
/obj/item/clothing/under/dress/maid/sexy = 5,
/obj/item/clothing/under/dress/maid/janitor = 5,
+ /obj/item/clothing/under/harness = 5, //CHOMP Edit: Added gear harness,
/obj/item/clothing/under/moderncoat = 5,
/obj/item/clothing/under/permit = 5,
/obj/item/clothing/under/oldwoman = 5,
@@ -2512,7 +1181,6 @@
/obj/item/clothing/suit/jacket/puffer/vest = 5,
/obj/item/clothing/suit/storage/flannel/red = 5,
/obj/item/clothing/suit/unathi/robe = 5,
- /obj/item/clothing/suit/storage/hooded/wintercoat/snowsuit = 5,
/obj/item/clothing/suit/storage/toggle/internalaffairs = 5,
/obj/item/clothing/suit/storage/toggle/lawyer/bluejacket = 5,
/obj/item/clothing/suit/storage/toggle/lawyer/purpjacket = 5,
@@ -2531,7 +1199,7 @@
/obj/item/clothing/suit/varsity/blue = 5,
/obj/item/clothing/suit/varsity/brown = 5,
/obj/item/clothing/suit/storage/hooded/wintercoat = 5,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey = 5)
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/white_grey = 5)
prices = list(/obj/item/clothing/suit/storage/apron = 100,
/obj/item/clothing/suit/storage/flannel/aqua = 100,
/obj/item/clothing/suit/storage/toggle/bomber = 100,
@@ -2599,7 +1267,6 @@
/obj/item/clothing/suit/jacket/puffer/vest = 100,
/obj/item/clothing/suit/storage/flannel/red = 100,
/obj/item/clothing/suit/unathi/robe = 100,
- /obj/item/clothing/suit/storage/hooded/wintercoat/snowsuit = 100,
/obj/item/clothing/suit/storage/toggle/internalaffairs = 100,
/obj/item/clothing/suit/storage/toggle/lawyer/bluejacket = 100,
/obj/item/clothing/suit/storage/toggle/lawyer/purpjacket = 100,
@@ -2618,7 +1285,7 @@
/obj/item/clothing/suit/varsity/blue = 100,
/obj/item/clothing/suit/varsity/brown = 100,
/obj/item/clothing/suit/storage/hooded/wintercoat = 100,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey = 100)
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/white_grey = 100)
premium = list(/obj/item/clothing/suit/imperium_monk = 3)
contraband = list(/obj/item/toy/katana = 1)
@@ -3139,6 +1806,7 @@
/obj/item/clothing/under/dress/maid = 5,
/obj/item/clothing/under/dress/maid/sexy = 5,
/obj/item/clothing/under/dress/maid/janitor = 5,
+ /obj/item/clothing/under/harness = 5, //CHOMP Edit: Added gear harness,
/obj/item/clothing/under/moderncoat = 5,
/obj/item/clothing/under/permit = 5,
/obj/item/clothing/under/oldwoman = 5,
@@ -3257,20 +1925,20 @@
/obj/item/clothing/under/rank/trek/command/voy = 5,
/obj/item/clothing/under/rank/trek/command/ent = 5,
/obj/item/clothing/under/rank/trek/eng = 5,
+ /obj/item/clothing/under/rank/trek/sec = 5,
/obj/item/clothing/under/rank/trek/eng/next = 5,
+ /obj/item/clothing/under/rank/trek/sec/next = 5,
/obj/item/clothing/under/rank/trek/eng/ds9 = 5,
+ /obj/item/clothing/under/rank/trek/sec/ds9 = 5,
/obj/item/clothing/under/rank/trek/eng/voy = 5,
+ /obj/item/clothing/under/rank/trek/sec/voy = 5,
/obj/item/clothing/under/rank/trek/eng/ent = 5,
+ /obj/item/clothing/under/rank/trek/sec/ent = 5,
/obj/item/clothing/under/rank/trek/medsci = 5,
/obj/item/clothing/under/rank/trek/medsci/next = 5,
/obj/item/clothing/under/rank/trek/medsci/ds9 = 5,
/obj/item/clothing/under/rank/trek/medsci/voy = 5,
/obj/item/clothing/under/rank/trek/medsci/ent = 5,
- /obj/item/clothing/under/rank/trek/sec = 5,
- /obj/item/clothing/under/rank/trek/sec/next = 5,
- /obj/item/clothing/under/rank/trek/sec/ds9 = 5,
- /obj/item/clothing/under/rank/trek/sec/voy = 5,
- /obj/item/clothing/under/rank/trek/sec/ent = 5,
/obj/item/clothing/under/rank/khi/cmd = 5,
/obj/item/clothing/under/rank/khi/eng = 5,
/obj/item/clothing/under/rank/khi/med = 5,
@@ -3501,7 +2169,6 @@
/obj/item/clothing/suit/jacket/puffer/vest = 5,
/obj/item/clothing/suit/storage/flannel/red = 5,
/obj/item/clothing/suit/unathi/robe = 5,
- /obj/item/clothing/suit/storage/hooded/wintercoat/snowsuit = 5,
/obj/item/clothing/suit/storage/toggle/internalaffairs = 5,
/obj/item/clothing/suit/storage/toggle/lawyer/bluejacket = 5,
/obj/item/clothing/suit/storage/toggle/lawyer/purpjacket = 5,
@@ -3520,7 +2187,7 @@
/obj/item/clothing/suit/varsity/blue = 5,
/obj/item/clothing/suit/varsity/brown = 5,
/obj/item/clothing/suit/storage/hooded/wintercoat = 5,
- /obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey = 5,
+ /obj/item/clothing/suit/storage/teshari/cloak/standard/white_grey = 5,
/obj/item/clothing/suit/imperium_monk = 3,
/obj/item/clothing/head/helmet/space/void/engineering = 5,
/obj/item/clothing/suit/space/void/engineering = 5,
@@ -3940,7 +2607,7 @@
/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/peanutcake = 10,
- /obj/item/weapon/reagent_containers/food/snacks/slice/pineapple = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/pineappleslice = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread = 10,
@@ -4404,7 +3071,7 @@
/obj/item/weapon/reagent_containers/food/snacks/slice/mushroompizza = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/orangecake = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/peanutcake = 10,
- /obj/item/weapon/reagent_containers/food/snacks/slice/pineapple = 10,
+ /obj/item/weapon/reagent_containers/food/snacks/pineappleslice = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/plaincake = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/pumpkinpie = 10,
/obj/item/weapon/reagent_containers/food/snacks/slice/tofubread = 10,
@@ -4576,7 +3243,7 @@
/obj/item/seeds/riceseed = 3,
/obj/item/seeds/rose = 3,
/obj/item/seeds/soyaseed = 3,
- /obj/item/seeds/spineapple = 3,
+ /obj/item/seeds/pineapple = 3,
/obj/item/seeds/sugarcaneseed = 3,
/obj/item/seeds/sunflowerseed = 3,
/obj/item/seeds/shandseed = 2,
diff --git a/code/game/mecha/combat/fighter_vr.dm b/code/game/mecha/combat/fighter_vr.dm
new file mode 100644
index 0000000000..4bc4782e9f
--- /dev/null
+++ b/code/game/mecha/combat/fighter_vr.dm
@@ -0,0 +1,8 @@
+/obj/mecha/combat/fighter
+ starting_components = list(
+ /obj/item/mecha_parts/component/hull/lightweight,
+ /obj/item/mecha_parts/component/actuator,
+ /obj/item/mecha_parts/component/armor,
+ /obj/item/mecha_parts/component/gas,
+ /obj/item/mecha_parts/component/electrical
+ )
diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm
index 4aa9f9c03a..f37600acd5 100644
--- a/code/game/mecha/combat/gorilla.dm
+++ b/code/game/mecha/combat/gorilla.dm
@@ -31,7 +31,7 @@
thrusters_possible = 1
/obj/mecha/combat/gorilla/Initialize()
- ..()
+ . = ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) // This thing basically cannot function without an external power supply.
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon(src)
diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm
index 3ae3e41e13..a1ea2ab451 100644
--- a/code/game/mecha/combat/phazon.dm
+++ b/code/game/mecha/combat/phazon.dm
@@ -40,7 +40,7 @@
switch_dmg_type_possible = TRUE
/obj/mecha/combat/phazon/equipped/Initialize()
- ..()
+ . = ..()
starting_equipment = list(
/obj/item/mecha_parts/mecha_equipment/tool/rcd,
/obj/item/mecha_parts/mecha_equipment/gravcatapult
diff --git a/code/game/mecha/components/_component.dm b/code/game/mecha/components/_component.dm
index aadf390c61..3d770e0dce 100644
--- a/code/game/mecha/components/_component.dm
+++ b/code/game/mecha/components/_component.dm
@@ -43,7 +43,7 @@
. += "It is completely destroyed."
/obj/item/mecha_parts/component/Initialize()
- ..()
+ . = ..()
integrity = max_integrity
if(start_damaged)
diff --git a/code/game/mecha/equipment/tools/inflatables.dm b/code/game/mecha/equipment/tools/inflatables.dm
index b18ba2eae1..ff766577de 100644
--- a/code/game/mecha/equipment/tools/inflatables.dm
+++ b/code/game/mecha/equipment/tools/inflatables.dm
@@ -14,7 +14,7 @@
var/obj/item/weapon/inflatable_dispenser/my_deployer = null
/obj/item/mecha_parts/mecha_equipment/tool/powertool/inflatables/Initialize()
- ..()
+ . = ..()
my_deployer = my_tool
/obj/item/mecha_parts/mecha_equipment/tool/powertool/inflatables/Topic(href, href_list)
diff --git a/code/game/mecha/equipment/tools/syringe_gun.dm b/code/game/mecha/equipment/tools/syringe_gun.dm
index 1658a01df6..fd73d74fc2 100644
--- a/code/game/mecha/equipment/tools/syringe_gun.dm
+++ b/code/game/mecha/equipment/tools/syringe_gun.dm
@@ -318,7 +318,7 @@
equip_type = EQUIP_HULL
/obj/item/mecha_parts/mecha_equipment/crisis_drone/Initialize()
- ..()
+ . = ..()
drone_overlay = new(src.icon, icon_state = droid_state)
/obj/item/mecha_parts/mecha_equipment/crisis_drone/Destroy()
diff --git a/code/game/mecha/equipment/weapons/energy/laser.dm b/code/game/mecha/equipment/weapons/energy/laser.dm
index 372fe67f0f..9aca9100d7 100644
--- a/code/game/mecha/equipment/weapons/energy/laser.dm
+++ b/code/game/mecha/equipment/weapons/energy/laser.dm
@@ -20,6 +20,17 @@
origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_PHORON = 3, TECH_POWER = 3)
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/gamma //CHOMPedit begin : adds Gamma Laser as proof of concept
+ equip_cooldown = 5
+ name = "\improper GA-X \"Render\" Experimental Gamma Laser"
+ desc = "A experimental suppression laser that fires blasts of radiation charged photons, extremely effective at punching through armor."
+ icon_state = "mecha_coil"
+ energy_drain = 80
+ projectile = /obj/item/projectile/beam/gamma
+ fire_sound = 'sound/weapons/emitter.ogg'
+
+ origin_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 5, TECH_PHORON = 4, TECH_POWER = 5, TECH_ILLEGAL = 3) //CHOMPedit end
+
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/xray/rigged
equip_cooldown = 12
name = "jury-rigged xray rifle"
diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm
index c2288709e5..dce2c3c9db 100644
--- a/code/game/mecha/mech_bay.dm
+++ b/code/game/mecha/mech_bay.dm
@@ -8,23 +8,31 @@
layer = TURF_LAYER + 0.1
circuit = /obj/item/weapon/circuitboard/mech_recharger
- var/obj/mecha/charging = null
+ var/atom/movable/charging
var/charge = 45
var/repair = 0
+ var/list/chargable_types = list(
+ /obj/mecha,
+ /mob/living/silicon/robot/platform
+ )
/obj/machinery/mech_recharger/Initialize()
. = ..()
default_apply_parts()
-/obj/machinery/mech_recharger/Crossed(var/obj/mecha/M)
+/obj/machinery/mech_recharger/Crossed(var/atom/movable/M)
. = ..()
- if(istype(M) && charging != M)
- start_charging(M)
+ if(charging == M)
+ return
+ for(var/mtype in chargable_types)
+ if(istype(M, mtype))
+ start_charging(M)
+ return
-/obj/machinery/mech_recharger/Uncrossed(var/obj/mecha/M)
+/obj/machinery/mech_recharger/Uncrossed(var/atom/movable/M)
. = ..()
if(M == charging)
- stop_charging()
+ charging = null
/obj/machinery/mech_recharger/RefreshParts()
..()
@@ -44,26 +52,33 @@
if(!charging)
return
if(charging.loc != src.loc) // Could be qdel or teleport or something
- stop_charging()
+ charging = null
return
+
var/done = FALSE
- if(charging.cell)
- var/t = min(charge, charging.cell.maxcharge - charging.cell.charge)
+ var/obj/mecha/mech = charging
+ var/obj/item/weapon/cell/cell = charging.get_cell()
+ if(cell)
+ var/t = min(charge, cell.maxcharge - cell.charge)
if(t > 0)
- charging.give_power(t)
+ if(istype(mech))
+ mech.give_power(t)
+ else
+ cell.give(t)
use_power(t * 150)
else
- charging.occupant_message("Fully charged.")
+ if(istype(mech))
+ mech.occupant_message(SPAN_NOTICE("Fully charged."))
done = TRUE
- if(repair && charging.health < initial(charging.health))
- charging.health = min(charging.health + repair, initial(charging.health))
- if(charging.health == initial(charging.health))
- charging.occupant_message("Fully repaired.")
+
+ if(repair && istype(mech) && mech.health < initial(mech.health))
+ mech.health = min(mech.health + repair, initial(mech.health))
+ if(mech.health == initial(mech.health))
+ mech.occupant_message(SPAN_NOTICE("Fully repaired."))
else
done = FALSE
if(done)
- stop_charging()
- return
+ charging = null
/obj/machinery/mech_recharger/attackby(var/obj/item/I, var/mob/user)
if(default_deconstruction_screwdriver(user, I))
@@ -73,18 +88,19 @@
if(default_part_replacement(user, I))
return
-/obj/machinery/mech_recharger/proc/start_charging(var/obj/mecha/M)
- if(stat & (NOPOWER | BROKEN))
- M.occupant_message("Power port not responding. Terminating.")
+/obj/machinery/mech_recharger/proc/start_charging(var/atom/movable/M)
+ var/obj/mecha/mech = M
+ if(stat & (NOPOWER | BROKEN))
+ if(istype(mech))
+ mech.occupant_message(SPAN_WARNING("Power port not responding. Terminating."))
+ else
+ to_chat(M, SPAN_WARNING("Power port not responding. Terminating."))
return
- if(M.cell)
- M.occupant_message("Now charging...")
+ if(M.get_cell())
+ if(istype(mech))
+ mech.occupant_message(SPAN_NOTICE("Now charging..."))
+ else
+ to_chat(M, SPAN_NOTICE("Now charging..."))
charging = M
return
-
-/obj/machinery/mech_recharger/proc/stop_charging()
- if(!charging)
-
- return
- charging = null
\ No newline at end of file
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 492837fbeb..d8e025df95 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -83,6 +83,14 @@
/obj/machinery/mecha_part_fabricator/Initialize()
. = ..()
+
+// Go through all materials, and add them to the possible storage, but hide them unless we contain them.
+ for(var/Name in name_to_material)
+ if(Name in materials)
+ continue
+
+ materials[Name] = 0
+
default_apply_parts()
files = new /datum/research(src) //Setup the research data holder.
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index bb0f4b7ba3..e58e427892 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -198,7 +198,7 @@
var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times.
/obj/mecha/Initialize()
- ..()
+ . = ..()
for(var/path in starting_components)
var/obj/item/mecha_parts/component/C = new path(src)
@@ -352,10 +352,10 @@
C.forceMove(src)
cell = C
return
- cell = new(src)
- cell.name = "mecha power cell"
- cell.charge = 15000
- cell.maxcharge = 15000
+ cell = new /obj/item/weapon/cell/mech(src)
+
+/obj/mecha/get_cell()
+ return cell
/obj/mecha/proc/add_cabin()
cabin_air = new
diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm
index 4db6332cb1..316d39bace 100644
--- a/code/game/mecha/medical/odysseus.dm
+++ b/code/game/mecha/medical/odysseus.dm
@@ -127,7 +127,7 @@
C.images += holder
*/
/obj/mecha/medical/odysseus/loaded/Initialize()
- ..()
+ . = ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/sleeper
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tool/sleeper
diff --git a/code/game/mecha/micro/mechfab_designs_vr.dm b/code/game/mecha/micro/mechfab_designs_vr.dm
index 4ef7fa76e3..d2a9095274 100644
--- a/code/game/mecha/micro/mechfab_designs_vr.dm
+++ b/code/game/mecha/micro/mechfab_designs_vr.dm
@@ -118,7 +118,7 @@
name = "\improper PC-20 \"Lance\" micro laser cannon" //CHOMPedit
id = "micro_laser_heavy"
req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3)
- materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 1000, "diamond" = 2000)
+ materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 1000, MAT_COPPER = 1000, "diamond" = 1000)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/microheavy
/datum/design/item/mecha/weapon/grenade_launcher/micro
@@ -192,5 +192,5 @@
desc = "A portable medical system used to treat external injuries from afar."
id = "mech_medigun"
req_tech = list(TECH_MATERIAL = 5, TECH_COMBAT = 5, TECH_BIO = 6)
- materials = list(DEFAULT_WALL_MATERIAL = 8000, "gold" = 2000, "silver" = 1750, "diamond" = 1500, "phoron" = 4000)
+ materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_COPPER = 4000, "gold" = 2000, "silver" = 1750, "diamond" = 1500)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/medigun
\ No newline at end of file
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index def044c9bb..4e92f757d2 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -70,7 +70,7 @@
max_special_equip = 1
/obj/mecha/working/ripley/deathripley/Initialize()
- ..()
+ . = ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/safety
ME.attach(src)
return
@@ -80,7 +80,7 @@
name = "APLU \"Miner\""
/obj/mecha/working/ripley/mining/Initialize()
- ..()
+ . = ..()
//Attach drill
if(prob(25)) //Possible diamond drill... Feeling lucky?
var/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill/D = new /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index f4603bba52..1b3ca36032 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -40,10 +40,7 @@
return TRUE
/atom/movable/proc/has_buckled_mobs()
- if(!buckled_mobs)
- return FALSE
- if(buckled_mobs.len)
- return TRUE
+ return LAZYLEN(buckled_mobs)
/atom/movable/Destroy()
unbuckle_all_mobs()
diff --git a/code/game/objects/effects/alien/alien egg.dm b/code/game/objects/effects/alien/alien egg.dm
index 8af53f8f3a..da12ae3f16 100644
--- a/code/game/objects/effects/alien/alien egg.dm
+++ b/code/game/objects/effects/alien/alien egg.dm
@@ -29,9 +29,9 @@
/obj/structure/alien/egg/process()
progress++
if(progress >= MAX_PROGRESS)
- for(var/mob/observer/ghost/O in GLOB.ghost_mob_list)
- if(O.client && O.client.prefs && (BE_ALIEN))
- to_chat(O, "An alien is ready to hatch! ([ghost_follow_link(src, O)]) (spawn)")
+ for(var/mob/observer/dead/O) //CHOMPedit fixed the snowflake ghost_pod notification.
+ if(O.client)
+ to_chat(O, "An alien is ready to hatch! (spawn)")
STOP_PROCESSING(SSobj, src)
update_icon()
@@ -56,10 +56,10 @@
// Check for bans properly.
if(jobban_isbanned(user, MODE_XENOMORPH))
- to_chat(user, "You are banned from playing a Xenomorph.")
+ to_chat(user, "You are banned from playing a Genaprawn.") //CHOMPedit
return
- var/confirm = alert(user, "Are you sure you want to join as a Xenomorph larva?", "Become Larva", "No", "Yes")
+ var/confirm = alert(user, "Are you sure you want to join as a Genaprawn larva?", "Become Larva", "No", "Yes") //CHOMPedit
if(!src || confirm != "Yes")
return
diff --git a/code/game/objects/effects/chem/coating.dm b/code/game/objects/effects/chem/coating.dm
index a777bbe5e0..2e9ad26049 100644
--- a/code/game/objects/effects/chem/coating.dm
+++ b/code/game/objects/effects/chem/coating.dm
@@ -11,7 +11,7 @@
create_reagents(100)
/obj/effect/decal/cleanable/chemcoating/Initialize()
- ..()
+ . = ..()
var/turf/T = get_turf(src)
if(T)
for(var/obj/O in get_turf(src))
diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm
index c3716b031c..5286670849 100644
--- a/code/game/objects/effects/decals/contraband.dm
+++ b/code/game/objects/effects/decals/contraband.dm
@@ -90,6 +90,39 @@
serial_number = given_serial
..(loc)
+//Selectable subtype
+/obj/item/weapon/contraband/poster/custom
+ name = "rolled-up poly-poster"
+ desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface. This one is made from some kind of e-paper, and could display almost anything!"
+ poster_type = /obj/structure/sign/poster/custom
+
+/obj/item/weapon/contraband/poster/custom/New(turf/loc, var/given_serial = 0)
+ if(given_serial == 0)
+ serial_number = 1 //Decidedly unrandom
+ else
+ serial_number = given_serial
+ ..(loc)
+
+/obj/item/weapon/contraband/poster/custom/verb/select_poster()
+ set name = "Set Poster type"
+ set category = "Object"
+ set desc = "Click to choose a poster to display."
+
+ var/mob/M = usr
+ var/list/options = list()
+ for(var/datum/poster/posteroption in poster_designs)
+ options[posteroption.listing_name] = posteroption
+
+ var/choice = input(M,"Choose a poster!","Customize Poster") in options
+ if(src && choice && !M.stat && in_range(M,src))
+ var serial = poster_designs.Find(options[choice])
+ serial_number = serial
+ name = "rolled-up poly-poster - No.[serial]"
+ to_chat(M, "The poster is now: [choice].")
+ return 1
+
+
+
//############################## THE ACTUAL DECALS ###########################
/obj/structure/sign/poster
@@ -187,6 +220,7 @@
// Description suffix
var/desc=""
var/icon_state=""
+ var/listing_name=""
// NT poster subtype.
/obj/structure/sign/poster/nanotrasen
@@ -201,3 +235,8 @@
set_poster(design)
..(newloc, placement_dir, serial, itemtype)
+
+//Non-Random Posters
+
+/obj/structure/sign/poster/custom
+ roll_type = /obj/item/weapon/contraband/poster/custom
\ No newline at end of file
diff --git a/code/game/objects/effects/decals/posters/bs12.dm b/code/game/objects/effects/decals/posters/bs12.dm
index 7aadcb2ead..5c1c32d98b 100644
--- a/code/game/objects/effects/decals/posters/bs12.dm
+++ b/code/game/objects/effects/decals/posters/bs12.dm
@@ -1,290 +1,348 @@
// baystation12 posters
/datum/poster/bay_1
icon_state="bsposter1"
- name = "Unlucky Space Explorer"
- desc = "This particular one depicts a skeletal form within a space suit."
+ name = "PSA: Unlucky Space Explorer"
+ desc = "This grim PSA depicts a skeletal form within a space suit. Thousands die every year as a result of failing to follow EVA safety guidelines."
+ listing_name = "PSA - EVA Accidents"
/datum/poster/bay_2
icon_state="bsposter2"
- name = "Positronic Logic Conflicts"
- desc = "This particular one depicts the cold, unmoving stare of a particular advanced AI."
+ name = "PSA: Disobedient Drones"
+ desc = "This PSA depicts the cold, unmoving stare of a particularly advanced AI. Contact information for the Emergent Intelligence Oversight is included."
+ listing_name = "PSA - Emergent Drones"
/datum/poster/bay_3
icon_state="bsposter3"
- name = "Paranoia"
- desc = "This particular one warns of the dangers of trusting your co-workers too much."
+ name = "PSA: Corporate Espionage"
+ desc = "This PSA warns of the dangers of trusting your co-workers with sensitive department information. They may be spying for a rival corporation, or worse!"
+ listing_name = "PSA - Corporate Espionage"
/datum/poster/bay_4
icon_state="bsposter4"
name = "Keep Calm"
- desc = "This particular one is of a famous New Earth design, although a bit modified. Someone has scribbled an O over the A on the poster."
+ desc = "An incredibly vague message, presented in a classic form. Someone has scribbled an O over the A on the poster."
+ listing_name = "PSA - Keep Calm"
/datum/poster/bay_5
icon_state="bsposter5"
- name = "Martian Warlord"
- desc = "This particular one depicts the cartoony mug of a certain Martial Warmonger."
+ name = "PSA: Saboteurs!"
+ desc = "A company PSA reminding employees to keep an eye out for suspicious activity, and report it immediately."
+ listing_name = "PSA - Saboteur"
/datum/poster/bay_6
icon_state="bsposter6"
- name = "Technological Singularity"
- desc = "This particular one is of the blood-curdling symbol of a long-since defeated enemy of humanity."
+ name = "Eradicator XV"
+ desc = "An ad for the fifteenth installment in the Eradicator movie franchise, about a violent robotic uprising hellbent on wiping out humanity."
+ listing_name = "Ad - Eradicator XV"
/datum/poster/bay_7
icon_state="bsposter7"
- name = "Wasteland"
- desc = "This particular one is of a couple of ragged gunmen, one male and one female, on top of a mound of rubble. The number \"12\" is visible on their blue jumpsuits."
+ name = "Wasteland: Battle for Earth"
+ desc = "This action movie ad shows a couple of ragged post-apocalyptic gunmen, one male and one female, on top of a mound of rubble."
+ listing_name = "Ad - Battle for Earth"
/datum/poster/bay_8
icon_state="bsposter8"
name = "Pinup Girl Cindy"
- desc = "This particular one is of a historical corporate PR girl, Cindy, in a particularly feminine pose."
+ desc = "This is a vintage 2450s pin-up of NanoTrasen's PR girl, Cindy, in a particularly feminine pose."
+ listing_name = "Pin-up - Cindi"
/datum/poster/bay_9
icon_state="bsposter9"
name = "Pinup Girl Amy"
- desc = "This particular one is of Amy, the nymphomaniac urban legend of deep space. How this photograph came to be is not known."
+ desc = "This pin-up is of Amy, one of NanoTrasen's most popular PR models."
+ listing_name = "Pin-up - Amy"
/datum/poster/bay_10
icon_state="bsposter10"
name = "Don't Panic"
- desc = "This particular one depicts some sort of star in a grimace. The \"Don't Panic\" is written in big, friendly letters."
+ desc = "This ad for Vey-Medical anxiety pills depicts some sort of star in a grimace. The \"Don't Panic\" is written in big, friendly letters."
+ listing_name = "Ad - Don't panic."
/datum/poster/bay_11
icon_state="bsposter11"
- name = "Underwater Laboratory"
- desc = "This particular one is of the fabled last crew of a previous Company project."
+ name = "Underwater Living"
+ desc = "This immigration poster encourages you to move to Earth;s premiere underwater city, Atlantis. One bedroom apartments start at half your salary."
+ listing_name = "Ad - Atlantis"
/datum/poster/bay_12
icon_state="bsposter12"
- name = "Rogue AI"
- desc = "This particular one depicts the shell of the infamous AI that catastropically comandeered one of humanity's earliest space stations. Back then, the Company was just known as TriOptimum."
+ name = "Beware Rogue AI"
+ desc = "This ad for the Emergent Intelligence Oversight Recruitment Division depicts a menacing AI and asks if you're a bad enough dude to take it on."
+ listing_name = "Recruitment - EIO"
/datum/poster/bay_13
icon_state="bsposter13"
- name = "User of the Arcane Arts"
- desc = "This particular one depicts a wizard, casting a spell. You can't really make out if it's an actual photograph or a computer-generated image."
+ name = "Become A User of the Arcane Arts"
+ desc = "This ad for popular Virtual Reality online game 'Wiz Online' depicts a wizard, casting a spell. You can't really make out if it's an actual photograph or a computer-generated image. Incredible graphics!"
+ listing_name = "Ad - Wiz Online"
/datum/poster/bay_14
icon_state="bsposter14"
name = "Levitating Skull"
- desc = "This particular one is the portrait of a flying enchanted skull. Its adventures along with its fabled companion are now fading through history..."
+ desc = "This tacky ad is a portrait of the flying enchanted skull, Bones. Its adventures along with its fabled companion are showing now on a broadcast service near you!"
+ listing_name = "Ad - Bones Adventures"
/datum/poster/bay_15
icon_state="bsposter15"
name = "Augmented Legend"
- desc = "This particular one is of an obviously augmented individual, gazing towards the sky. The cyber-city in the backround is rather punkish."
+ desc = "This ad for Ward-Takahashi cybernetic implants shows obviously augmented individual, gazing towards the sky. Is your body augmented?"
+ listing_name = "Ad - Ward-Takahashi Augments"
/datum/poster/bay_16
icon_state="bsposter16"
- name = "Dangerous Static"
- desc = "This particular one depicts nothing remarkable other than a rather mesmerising pattern of monitor static. There's a tag on the sides of the poster, but it's ripped off."
+ name = "Snow Crash"
+ desc = "This particular one depicts nothing remarkable other than a rather mesmerising pattern of monitor static. You think it's an ad for something, but you're not sure what."
+ listing_name = "Ad - Snow Crash"
/datum/poster/bay_17
icon_state="bsposter17"
name = "Pinup Girl Val"
desc = "Luscious Val McNeil, the vertically challenged Legal Extraordinaire, winner of Miss Space two years running and favoured pinup girl of Lawyers Weekly."
+ listing_name = "Pin-up - Val"
/datum/poster/bay_18
icon_state="bsposter18"
name = "Derpman, Enforcer of the State"
- desc = "Here to protect and serve... your donuts! A generously proportioned man, he teaches you the value of hiding your snacks."
+ desc = "An ad for Centauri Provisions donuts. Officer Derpman is here to protect and serve... your donuts! A generously proportioned man, he teaches you the value of hiding your snacks."
+ listing_name = "Ad - Officer Derpman Donuts"
/datum/poster/bay_19
icon_state="bsposter19"
name = "Respect an Unathi"
- desc = "This poster depicts a well dressed looking Unathi receiving a prestigious award. It appears to espouse greater co-operation and harmony between the two races."
+ desc = "This poster depicts a sharply dressed Unathi receiving a prestigious award. It appears to espouse greater co-operation and harmony between humanity and the Unathi."
+ listing_name = "PSA - Unathi"
/datum/poster/bay_20
icon_state="bsposter20"
- name = "Skrell Twilight"
- desc = "This poster depicts a mysteriously inscrutable, alien scene. Numerous Skrell can be seen conversing amidst great, crystalline towers rising above crashing waves"
+ name = "Skrell Tourism"
+ desc = "This tourism poster depicts a mysteriously inscrutable, alien scene. Numerous Skrell can be seen conversing amidst great, crystalline towers rising above crashing waves."
+ listing_name = "Ad - Skrellian Tourism"
/datum/poster/bay_21
icon_state="bsposter21"
name = "Join the Fuzz!"
desc = "It's a nice recruitment poster of a white haired Chinese woman that says; \"Big Guns, Hot Women, Good Times. Security. We get it done.\""
+ listing_name = "Recruitment - NanoTrasen Security - Pinup"
/datum/poster/bay_22
icon_state="bsposter22"
name = "Looking for a career with excitement?"
desc = "A recruitment poster starring a dark haired woman with glasses and a purple shirt that has \"Got Brains? Got Talent? Not afraid of electric flying monsters that want to suck the soul out of you? Then Xenobiology could use someone like you!\" written on the bottom."
+ listing_name = "Recruitment - Xenobiology"
/datum/poster/bay_23
icon_state="bsposter23"
name = "Safety first: because electricity doesn't wait!"
desc = "A safety poster starring a clueless looking redhead with frazzled hair. \"Every year, hundreds of NT employees expose themselves to electric shock. Play it safe. Avoid suspicious doors after electrical storms, and always wear protection when doing electric maintenance.\""
+ listing_name = "Safety - Electric Shock"
/datum/poster/bay_24
icon_state="bsposter24"
name = "Responsible medbay habits, No #259"
desc = "A poster with a nervous looking geneticist on it states; \"Friends Tell Friends They're Clones. It can cause severe and irreparable emotional trauma if a person is not properly informed of their recent demise. Always follow your contractual obligation and inform them of their recent rejuvenation.\""
+ listing_name = "Medical - Clone Disclosure"
/datum/poster/bay_25
icon_state="bsposter25"
name = "Irresponsible medbay habits, No #2"
desc = "This is a safety poster starring a perverted looking naked doctor. \"Sexual harassment is never okay. REPORT any acts of sexual deviance or harassment that disrupt a healthy working environment.\""
+ listing_name = "Medical - Sexual Harassment"
/datum/poster/bay_26
icon_state="bsposter26"
name = "The Men We Knew"
- desc = "This movie poster depicts a group of soldiers fighting a large mech, the movie seems to be a patriotic war movie."
+ desc = "This movie poster depicts a group of soldiers fighting a large mech, it seems to be some kind of movie set during the Hegemony War."
+ listing_name = "Ad - Men We Knew"
/datum/poster/bay_27
icon_state="bsposter27"
name = "Plastic Sheep Can't Scream"
- desc = "This is a movie poster for an upcoming horror movie, it features an AI in the front of it."
+ desc = "This is a movie poster for an upcoming horror movie, featuring a frightening looking robotic creature."
+ listing_name = "Ad - Plastic Sheep Can't Scream"
/datum/poster/bay_28
icon_state="bsposter28"
name = "The Stars Know Love"
- desc = "This is a movie poster. A bleeding woman is shown drawing a heart in her blood on the window of space ship, it seems to be a romantic Drama."
+ desc = "This is a movie poster. A bleeding woman is shown drawing a heart in her blood on the window of space ship, it seems to be a romantic drama."
+ listing_name = "Ad - The Stars Know Love"
/datum/poster/bay_29
icon_state="bsposter29"
name = "Winter Is Coming"
- desc = "On the poster is a frighteningly large wolf, he warns: \"Only YOU can keep the station from freezing during planetary occultation!\""
+ desc = "On the poster is a frighteningly large wolf, he warns: \"Only YOU can keep yourself from freezing this winter!\". Below is the logo of NanoThreads clothing."
+ listing_name = "Ad - Cold-weather Gear"
/datum/poster/bay_30
icon_state="bsposter30"
name = "Ambrosia Vulgaris"
- desc = "Just looking at this poster makes you feel a little bit dizzy."
+ desc = "It's an ad for getting absolutely shitfaced on psychadelics. Just looking at this poster makes you feel a little bit dizzy. Use responsibly."
+ listing_name = "Ad - Ambrosia Vulgaris"
/datum/poster/bay_31
icon_state="bsposter31"
- name = "Donut Corp"
- desc = "This is an advertisement for Donut Corp, the new innovation in donut technology!"
+ name = "Donut Panic"
+ desc = "This is an advertisement for Donut Panic, the bi-monthly periodical for donut lovers galaxy-wide."
+ listing_name = "Ad - Donuts Panic"
/datum/poster/bay_32
icon_state="bsposter32"
name = "Eat!"
- desc = "A poster depicting a hamburger. The poster orders you to consume the hamburger."
+ desc = "A NanoPastures poster depicting a synthmeat hamburger. The poster COMMANDS you to consume the hamburger."
+ listing_name = "Ad - Hamburger"
/datum/poster/bay_33
icon_state="bsposter33"
- name = "Tools, tools, tools"
- desc = "You can never have enough tools, thats for sure!"
+ name = "Tools, tools, tools!"
+ desc = "Xion Manufacturing reminds you: Never trust an off-brand tool. "
+ listing_name = "Ad - Xion Tools"
/datum/poster/bay_34
icon_state="bsposter34"
name = "Power Up!"
- desc = "High reward, higher risk!"
+ desc = "NanoTrasen are leaders in Phoron-based supermatter power! High reward, higher risk!"
+ listing_name = "Ad - Phoron Power"
/datum/poster/bay_35
icon_state="bsposter35"
- name = "Lamarr"
- desc = "This is a poster depicting the pet and mascot of the science department."
+ name = "Kendrick"
+ desc = "This is a poster depicting the pet and mascot of the science department, and national corporate ambassador for slime-based science solutions.."
+ listing_name = "Ad - Slime Science"
/datum/poster/bay_36
icon_state="bsposter36"
name = "Fancy Borg"
- desc = "A poster depicting a cyborg using the service module. 'Fancy Borg' is written on it."
+ desc = "A poster depicting a cyborg dressed to the nines. An ad for cybernetics enthusiast magazine, Borg Fancy."
+ listing_name = "Ad - Borg Fancy A"
/datum/poster/bay_37
icon_state="bsposter37"
name = "Fancier Borg"
- desc = "A poster depicting a cyborg using the service module. 'Fancy Borg' is written on it. This is even fancier than the first poster."
+ desc = "A poster depicting a cyborg dressed to the nines. An ad for cybernetics enthusiast magazine, Borg Fancy. This is even fancier than the other poster."
+ listing_name = "Ad - Borg Fancy B"
/datum/poster/bay_38
icon_state="bsposter38"
name = "Toaster Love"
- desc = "This is a poster of a toaster containing two slices of bread. The word LOVE is written in big pink letters underneath."
+ desc = "This is a poster of a toaster containing two slices of bread. The word LOVE is written in big pink letters underneath. An ad for a cybernetics 'enthusiast' magazine. "
+ listing_name = "Ad - Toaster Love"
/datum/poster/bay_39
icon_state="bsposter39"
name = "Responsible medbay habits, No #91"
desc = "A safety poster with a chemist holding a vial. \"Always wear safety gear while handling dangerous chemicals, even if it concerns only small amounts.\""
+ listing_name = "Safety - Chemicals"
/datum/poster/bay_40
icon_state="bsposter40"
name = "Agreeable work environment"
desc = "This poster depicts a young woman in a stylish dress. \"Try to aim for a pleasant atmosphere in the workspace. A friendly word can do more than forms in triplicate.\""
+ listing_name = "PSA - Agreeable Work Environment"
/datum/poster/bay_41
icon_state="bsposter41"
name = "Professional work environment"
desc = "A safety poster featuring a green haired woman in a shimmering blue dress. \"As an Internal Affairs Agent, your job is to create a fair and agreeable work environment for the crewmembers, as discreetly and professionally as possible.\""
+ listing_name = "Recruitment - Internal Affairs"
/datum/poster/bay_42
icon_state="bsposter42"
name = "Engineering pinup"
desc = "This is pin-up poster. A half-naked girl with white hair, toned muscles and stunning blue eyes looks back at you from the poster. Her welding helmet, tattoos and grey jumpsuit hanging around her waist gives a bit of a rugged feel."
+ listing_name = "Pin-up - Engineer"
/datum/poster/bay_43
icon_state="bsposter43"
name = "Responsible medbay habits, No #3"
desc = "A safety poster with a purple-haired surgeon. She looks a bit cross. \"Let the surgeons do their work. NEVER replace or remove a surgery tool from where the surgeon put it.\""
+ listing_name = "Safety - Surgical Tools"
/datum/poster/bay_44
icon_state="bsposter44"
name = "Time for a drink?"
- desc = "This poster depicts a friendly-looking Tajaran holding a tray of drinks."
+ desc = "This poster for a brand for \"Tajaran-style\" rum produced by Gilthari Exports depicts a friendly-looking Tajaran holding a tray of drinks."
+ listing_name = "Ad - Rarkajar Rum"
/datum/poster/bay_45
icon_state="bsposter45"
name = "Responsible engineering habits, No #1"
desc = "A safety poster featuring a blue haired engineer. \"When repairing a machine or construction, always aim for long-term solutions.\""
+ listing_name = "Safety - No Shortcut Fixes"
/datum/poster/bay_46
icon_state="bsposter46"
name = "Inspirational lawyer"
- desc = "An inspirational poster depicting a Skrellian lawyer. He seems to be shouting something, while pointing fiercely to the right."
+ desc = "An inspirational poster depicting a Skrellian lawyer. He seems to be shouting something, while pointing fiercely to the right. It's an ad for a NanoTrasen subsidiary law firm."
+ listing_name = "Ad - NanoTrasen Law"
/datum/poster/bay_47
icon_state="bsposter47"
name = "Security pinup"
desc = "This is a pin-up poster. A dark skinned white haired girl poses in the sunlight wearing a tank top with her stomach exposed. The text on the poster states \"M, Succubus of Security.\" and a lipstick mark stains the top right corner, as if kissed by the model herself."
+ listing_name = "Pin-up - Security"
/datum/poster/bay_48
icon_state="bsposter48"
- name = "Borg pinup?"
- desc = "This is a.. pin-up poster? It is a diagram on an old model of cyborg with a note scribbled in marker on the bottom, on the top there is a large XO written in red marker."
+ name = "Remote Drones 4 U"
+ desc = "This is an ad for a fairly basic model of drone produced by Grayson Manufactories Ltd. for use in hazardous environments."
+ listing_name = "Ad - Grayson Drones"
/datum/poster/bay_49
icon_state="bsposter49"
name = "Engineering recruitment"
desc = "This is a poster showing an engineer relaxing by a computer, the text states \"Living the life! Join Engineering today!\""
+ listing_name = "Recruitment - Engineering"
/datum/poster/bay_50
icon_state="bsposter50"
name = "Pinup Girl Cindy Kate"
- desc = "This particular one is of Cindy Kate, a seductive performer well known among less savoury circles."
+ desc = "This particular one is of Cindy Kate, a seductive virtual performer well known among less savoury exonet circles."
+ listing_name = "Pin-up - Cindi-Kate"
/datum/poster/bay_51
icon_state="bsposter51"
- name = "space appreciation poster"
- desc = "This is a poster produced by the Generic Space Company, as a part of a series of commemorative posters on the wonders of space. One of three."
+ name = "space tourism poster"
+ desc = "This is a poster produced by the Visit Space Society. This one is targeted at planet-dwellers, suggesting they generally visit space."
+ listing_name = "Tourism - Space"
/datum/poster/bay_52
icon_state="bsposter52"
name = "fire safety poster"
desc = "This is a poster reminding you of what you should do if you are on fire, or if you are at a dance party."
+ listing_name = "Safety - Stop Drop and Roll"
/datum/poster/bay_53
icon_state="bsposter53"
name = "fire extinguisher poster"
desc = "This is a poster reminding you of what you should use to put out a fire."
+ listing_name = "Safety - Fire Extinguishers"
/datum/poster/bay_54
icon_state="bsposter54"
name = "firefighter poster"
desc = "This is a poster of a particularly stern looking firefighter. The caption reads, \"Only you can prevent space fires.\""
+ listing_name = "Safety - Prevent Fires"
/datum/poster/bay_55
icon_state="bsposter55"
- name = "Earth appreciation poster"
- desc = "This is a poster produced by the Generic Space Company, as a part of a series of commemorative posters on the wonders of space. Two of three."
+ name = "Binma tourism poster"
+ desc = "This is a poster produced by the Visit Space Society. This one suggests you visit the exotic garden world of Binma, and try not to get eaten."
+ listing_name = "Tourism - Binma"
/datum/poster/bay_56
icon_state="bsposter56"
name = "Mars appreciation poster"
- desc = "This is a poster produced by the Generic Space Company, as a part of a series of commemorative posters on the wonders of space. Three of three."
+ desc = "This is a poster produced by the Visit Space Society. This one suggests you visit historic Mars. Come for the domes, stay for the monuments to hubris!"
/datum/poster/bay_57
icon_state="bsposter57"
name = "space carp warning poster"
desc = "This poster tells of the dangers of space carp infestations."
+ listing_name = "Safety - Carp"
/datum/poster/bay_58
icon_state="bsposter58"
name = "space carp information poster"
- desc = "This poster showcases an old spacer saying on the dangers of migrant space carp."
\ No newline at end of file
+ desc = "This poster showcases an old spacer saying on the dangers of migrant space carp."
+ listing_name = "Safety - Carp Information"
+
diff --git a/code/game/objects/effects/decals/posters/polarisposters.dm b/code/game/objects/effects/decals/posters/polarisposters.dm
index d40cdd0db0..45cfd8622d 100644
--- a/code/game/objects/effects/decals/posters/polarisposters.dm
+++ b/code/game/objects/effects/decals/posters/polarisposters.dm
@@ -2,41 +2,49 @@
icon_state="polposter1"
name = "Safety!"
desc = "A poster advising you to learn how to put on your internals at a moment's notice."
+ listing_name = "Safety - Internals"
/datum/poster/pol_2
icon_state="polposter2"
name = "Safety!"
desc = "A blue and white colored poster. This one advises you to wear your safety goggles when handling chemicals."
+ listing_name = "Safety - Goggles"
/datum/poster/pol_3
icon_state="polposter3"
name = "Safety!"
desc = "A safety poster instructing you to comply with the authorities, especially in an emergency."
+ listing_name = "Safety - Follow Instruction"
/datum/poster/pol_4
icon_state="polposter4"
name = "Clean Hands Save Lives"
desc = "A safety poster reminding you to wash your hands."
+ listing_name = "Safety - Hand Washing"
/datum/poster/pol_5
icon_state="polposter5"
name = "Help!"
desc = "This poster depicts a man helping another man get up."
+ listing_name = "Safety - Help Others"
/datum/poster/pol_6
icon_state="polposter6"
name = "Walk!"
desc = "This poster depicts a man walking, presumably to encourage you not to run in the halls."
+ listing_name = "Safety - No Running"
/datum/poster/pol_7
icon_state="polposter7"
name = "Place your signs!"
desc = "A safety poster reminding custodial staff to place wet floor signs where needed. This reminder's rarely heeded."
+ listing_name = "Safety - Wet Floor Signs"
/datum/poster/pol_8
icon_state="polposter8"
name = "Safety!"
desc = "An advertisement / safety poster for EVA training and certification. Training is available at your local Central Command."
+ listing_name = "Safety - EVA Training"
/datum/poster/pol_9
icon_state="poster10" //Recycling this icon
@@ -44,52 +52,138 @@
desc = "This poster appears to be reference material for maintenance personnel, instructing to always wear insulated gloves, that wirecutters and \
a multitool are the optimal tools to use, and where to find the maintenance panel on most airlocks. Unfortunately, the poster does not mention any \
wire codes."
+ listing_name = "Safety - Airlock Maintenance"
/datum/poster/pol_10
icon_state="polposter9"
name = "orchid"
desc = "This poster appears strangely familiar, depicting the flower of a tree native to the planet Earth."
+ listing_name = "General - Orchid"
-// A new subset of poster datum for Security posters.
+/datum/poster/pol_11
+ icon_state="polposter10"
+ name = "firefighter pinup"
+ desc = "A buff firefighter with his shirt off. Maybe he's trying to raise awareness about fire safety, but you're a little distracted."
+ listing_name = "Pin-up - Firefighter"
+
+/datum/poster/pol_12
+ icon_state="polposter11"
+ name = "CHUCK"
+ desc = "With the budget Cyber Solutions 'Chuck' model work drone, your days of menial labour are numbered! \"With Cyber Solutions, there's always someone beside you, helping you. You know their face. You know my face.\""
+ listing_name = "Ad - Chuck"
+
+/datum/poster/pol_13
+ icon_state="polposter12"
+ name = "New You"
+ desc = "An ad for Kaleidoscope Cosmetics. \"The common factor in all your failed relationships is you. Fix it with affordable gene therapy!\""
+ listing_name = "Ad - Kaleidoscope"
+
+/datum/poster/pol_14
+ icon_state="polposter13"
+ name = "Take a Taxi"
+ desc = "An ad for the Major Bill's Transportation drone-operated taxi service operating in most major cities throughout Solar space."
+ listing_name = "Ad - Taxi"
+
+/datum/poster/pol_15
+ icon_state="polposter14"
+ name = "Adopt A Teshpet"
+ desc = "An ad for definitively racist virtual pet game, Teshpets."
+ listing_name = "Ad - Teshpets"
+
+/datum/poster/pol_16
+ icon_state="polposter15"
+ name = "Train and Fight"
+ desc = "This poster of sweaty, near-naked wrestlers is the most masculine thing you've ever seen. You can barely tell where one man ends and the other begins. Always seek manliness!"
+ listing_name = "Pinup - Wrestling"
+
+/datum/poster/nt_3
+ icon_state = "ntposter03"
+ name = "Mechatronic Safety"
+ desc = "This poster displays three cutting-edge gygaxes standing in line in front of a man in plain clothes.\
+ The poster's captions explain the importance of knowing how to operate a mechatronic vehicle safely, especially near other personnel.\
+ The image seems important."
+ listing_name = "Safety - Mech Operation"
+
+/datum/poster/nt_4
+ icon_state = "ntposter04"
+ name = "Beware Aetotheans"
+ desc = "This poster displays a distinctly hostile-looking red Promethean in a black coat. The fine-print around the edges warns the reader about the dangers posed by Almachi Prometheans."
+ listing_name = "Safety - Aetothean Danger"
+
+/datum/poster/nt_5
+ icon_state = "ntposter05"
+ name = "Promethean"
+ desc = "This poster displays a friendly-looking green Promethean in a labcoat. The fine-print around the edges talks about the benefits Prometheans give in laboratories."
+ listing_name = "Safety - Prometheans"
+
+/datum/poster/nt_6
+ icon_state = "ntposter06"
+ name = "NanoTrasen"
+ desc = "This poster showcases an NT emblem. There is writing in the ring around the inner points, probably some sort of slogan no one bothers to memorize."
+ listing_name = "Ad - NanoTrasen"
+
+/datum/poster/nt_7
+ icon_state = "ntposter07"
+ name = "SolGov"
+ desc = "This poster showcases an SCG emblem. The outer ring reads,\
+ \"NIL MORTALIBUS ARDUI EST\".\
+ Solar Confederate Government."
+ listing_name = "Political - SolGov"
+
+/datum/poster/nt_8
+ icon_state = "ntposter08"
+ name = "wildlife hazard"
+ desc = "This SifGov poster warns against attempting to kill a fully grown giant spider or other hostile life-form alone."
+ listing_name = "Safety - Spiders"
+
+// A new subset of poster datum for ONLY 'Internal' NanoTrasen posters, given to Security.
/datum/poster/nanotrasen
icon_state = "polposter1"
name = "Safety!"
desc = "A poster advising you to learn how to put on your internals at a moment's notice."
+ listing_name = "Safety - Internals"
/datum/poster/nanotrasen/pol_2
icon_state="polposter2"
name = "Safety!"
desc = "A blue and white colored poster. This one advises you to wear your safety goggles when handling chemicals."
+ listing_name = "Safety - Goggles"
/datum/poster/nanotrasen/pol_3
icon_state="polposter3"
name = "Safety!"
desc = "A safety poster instructing you to comply with the authorities, especially in an emergency."
+ listing_name = "Safety - Follow Instruction"
/datum/poster/nanotrasen/pol_4
icon_state="polposter4"
name = "Clean Hands Save Lives"
desc = "A safety poster reminding you to wash your hands."
+ listing_name = "Safety - Hand Washing"
/datum/poster/nanotrasen/pol_5
icon_state="polposter5"
name = "Help!"
desc = "This poster depicts a man helping another man get up."
+ listing_name = "Safety - Help Others"
/datum/poster/nanotrasen/pol_6
icon_state="polposter6"
name = "Walk!"
desc = "This poster depicts a man walking, presumably to encourage you not to run in the halls."
+ listing_name = "Safety - No Running"
/datum/poster/nanotrasen/pol_7
icon_state="polposter7"
name = "Place your signs!"
desc = "A safety poster reminding custodial staff to place wet floor signs where needed. This reminder's rarely heeded."
+ listing_name = "Safety - Wet Floor Signs"
/datum/poster/nanotrasen/pol_8
icon_state="polposter8"
name = "Safety!"
desc = "An advertisement / safety poster for EVA training and certification. Training is available at your local Central Command."
+ listing_name = "Safety - EVA Training"
/datum/poster/nanotrasen/pol_9
icon_state="poster10"
@@ -97,81 +191,97 @@
desc = "This poster appears to be reference material for maintenance personnel, instructing to always wear insulated gloves, that wirecutters and \
a multitool are the optimal tools to use, and where to find the maintenance panel on most airlocks. Unfortunately, the poster does not mention any \
wire codes."
+ listing_name = "Safety - Airlock Maintenance"
/datum/poster/nanotrasen/pol_10
icon_state="polposter9"
name = "orchid"
desc = "This poster suggests a feeling of peace. It depicts the flower of a tree native to the planet Earth."
+ listing_name = "General - Orchid"
/datum/poster/nanotrasen/bay_9
icon_state="bsposter9"
name = "Pinup Girl Amy"
desc = "This particular one is of Amy, the nymphomaniac urban legend of deep space. How this photograph came to be is not known."
+ listing_name = "Pin-up - Amy"
/datum/poster/nanotrasen/bay_21
icon_state="bsposter21"
name = "Join the Fuzz!"
desc = "It's a nice recruitment poster of a white haired Chinese woman that says; \"Big Guns, Hot Women, Good Times. Security. We get it done.\""
+ listing_name = "Recruitment - NanoTrasen Security - Pinup"
/datum/poster/nanotrasen/bay_22
icon_state="bsposter22"
name = "Looking for a career with excitement?"
desc = "A recruitment poster starring a dark haired woman with glasses and a purple shirt that has \"Got Brains? Got Talent? Not afraid of electric flying monsters that want to suck the soul out of you? Then Xenobiology could use someone like you!\" written on the bottom."
+ listing_name = "Recruitment - Xenobiology"
/datum/poster/nanotrasen/bay_23
icon_state="bsposter23"
name = "Safety first: because electricity doesn't wait!"
desc = "A safety poster starring a clueless looking redhead with frazzled hair. \"Every year, hundreds of NT employees expose themselves to electric shock. Play it safe. Avoid suspicious doors after electrical storms, and always wear protection when doing electric maintenance.\""
+ listing_name = "Safety - Electric Shock"
/datum/poster/nanotrasen/bay_24
icon_state="bsposter24"
name = "Responsible medbay habits, No #259"
desc = "A poster with a nervous looking geneticist on it states; \"Friends Tell Friends They're Clones. It can cause severe and irreparable emotional trauma if a person is not properly informed of their recent demise. Always follow your contractual obligation and inform them of their recent rejuvenation.\""
+ listing_name = "Medical - Clone Disclosure"
/datum/poster/nanotrasen/bay_25
icon_state="bsposter25"
name = "Irresponsible medbay habits, No #2"
desc = "This is a safety poster starring a perverted looking naked doctor. \"Sexual harassment is never okay. REPORT any acts of sexual deviance or harassment that disrupt a healthy working environment.\""
+ listing_name = "Medical - Sexual Harassment"
/datum/poster/nanotrasen/bay_49
icon_state="bsposter49"
name = "Engineering recruitment"
desc = "This is a poster showing an engineer relaxing by a computer, the text states \"Living the life! Join Engineering today!\""
+ listing_name = "Recruitment - Engineering"
/datum/poster/nanotrasen/bay_52
icon_state="bsposter52"
name = "fire safety poster"
desc = "This is a poster reminding you of what you should do if you are on fire, or if you are at a dance party."
+ listing_name = "Safety - Stop Drop And Roll"
/datum/poster/nanotrasen/bay_53
icon_state="bsposter53"
name = "fire extinguisher poster"
desc = "This is a poster reminding you of what you should use to put out a fire."
+ listing_name = "Safety - Extinguishers"
/datum/poster/nanotrasen/bay_54
icon_state="bsposter54"
name = "firefighter poster"
desc = "This is a poster of a particularly stern looking firefighter. The caption reads, \"Only you can prevent space fires.\""
+ listing_name = "Safety - Prevent Fires"
/datum/poster/nanotrasen/bay_57
icon_state="bsposter57"
name = "space carp warning poster"
desc = "This poster tells of the dangers of space carp infestations."
+ listing_name = "Safety - Carp"
/datum/poster/nanotrasen/bay_58
icon_state="bsposter58"
name = "space carp information poster"
desc = "This poster showcases an old spacer saying on the dangers of migrant space carp."
+ listing_name = "Safety - Carp Information"
/datum/poster/nanotrasen/nt_1
icon_state = "ntposter01"
name = "Security recruitment"
desc = "This poster showcases an NT security guard in an excited pose, with a small blurb about the importance of Security."
+ listing_name = "Recruitment - NanoTrasen Security - Importance"
/datum/poster/nanotrasen/nt_2
icon_state = "ntposter02"
name = "Security recruitment"
desc = "This poster showcases an NT security guard in an excited pose, with a small blurb about Security Employee benefits."
+ listing_name = "Recruitment - NanoTrasen Security - Benefits"
/datum/poster/nanotrasen/nt_3
icon_state = "ntposter03"
@@ -179,6 +289,7 @@
desc = "This poster displays three cutting-edge gygaxes standing in line in front of a man in plain clothes.\
The poster's captions explain the importance of knowing how to operate a mechatronic vehicle safely, especially near other personnel.\
The image seems important."
+ listing_name = "Safety - Mech Operation"
//VOREStation Removal Start TFF 17/12/19 - lore not used in our station's own lore.
/*
@@ -186,6 +297,7 @@
icon_state = "ntposter04"
name = "Beware Aetotheans"
desc = "This poster displays a distinctly hostile-looking red Promethean in a black coat. The fine-print around the edges warns the reader about the dangers posed by Almachi Prometheans."
+ listing_name = "Safety - Aetothean Danger"
*/
//VOREstation Removal End
@@ -193,11 +305,13 @@
icon_state = "ntposter05"
name = "Promethean"
desc = "This poster displays a friendly-looking green Promethean in a labcoat. The fine-print around the edges talks about the benefits Prometheans give in laboratories."
+ listing_name = "Safety - Prometheans"
/datum/poster/nanotrasen/nt_6
icon_state = "ntposter06"
name = "NanoTrasen"
desc = "This poster showcases an NT emblem. There is writing in the ring around the inner points, probably some sort of slogan no one bothers to memorize."
+ listing_name = "Ad - NanoTrasen"
/datum/poster/nanotrasen/nt_7
icon_state = "ntposter07"
@@ -205,13 +319,16 @@
desc = "This poster showcases an SCG emblem. The outer ring reads,\
\"NIL MORTALIBUS ARDUI EST\".\
Solar Confederate Government."
+ listing_name = "Political - SolGov"
/datum/poster/nanotrasen/nt_8
icon_state = "ntposter08"
name = "wildlife hazard"
desc = "This poster warns against attempting to kill a fully grown giant spider or other hostile life-form alone."
+ listing_name = "Safety - Spiders"
/datum/poster/nanotrasen/nt_9
icon_state = "ntposter09"
name = "Regulations and You"
- desc = "This poster showcases an NT security guard reading from her PDA. The blurb advocates for the reader to keep corporate regulations in mind at all times, as an emergency can occur at any time."
+ desc = "This SifGov poster showcases an NT security guard reading from her PDA. The blurb advocates for the reader to keep corporate regulations in mind at all times, as an emergency can occur at any time."
+ listing_name = "Safety - Corporate Regulations"
diff --git a/code/game/objects/effects/decals/warning_stripes.dm b/code/game/objects/effects/decals/warning_stripes.dm
index db7c4bf74f..0e3d12897d 100644
--- a/code/game/objects/effects/decals/warning_stripes.dm
+++ b/code/game/objects/effects/decals/warning_stripes.dm
@@ -1,10 +1,10 @@
/obj/effect/decal/warning_stripes
icon = 'icons/effects/warning_stripes.dmi'
-/obj/effect/decal/warning_stripes/New()
+/obj/effect/decal/warning_stripes/Initialize()
. = ..()
var/turf/T=get_turf(src)
var/image/I=image(icon, icon_state = icon_state, dir = dir)
I.color=color
T.overlays += I
- qdel(src)
+ return INITIALIZE_HINT_QDEL
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 1e804bbb26..0ec3f40036 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -33,6 +33,9 @@ would spawn and follow the beaker, even if it is carried or thrown.
proc/start()
+ Destroy()
+ holder = null
+ return ..()
/////////////////////////////////////////////
// GENERIC STEAM SPREAD SYSTEM
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index c5e1f26c61..c49a4e0666 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -10,32 +10,37 @@
var/obj/item/weapon/mine/mineitemtype = /obj/item/weapon/mine
var/panel_open = 0
var/datum/wires/mines/wires = null
- register_as_dangerous_object = TRUE
-
var/camo_net = FALSE // Will the mine 'cloak' on deployment?
// The trap item will be triggered in some manner when detonating. Default only checks for grenades.
var/obj/item/trap = null
-/obj/effect/mine/New()
+/obj/effect/mine/Initialize()
icon_state = "uglyminearmed"
wires = new(src)
-
+ . = ..()
if(ispath(trap))
trap = new trap(src)
-
-/obj/effect/mine/Initialize()
- ..()
-
+ register_dangerous_to_step()
if(camo_net)
alpha = 50
/obj/effect/mine/Destroy()
+ unregister_dangerous_to_step()
if(trap)
QDEL_NULL(trap)
qdel_null(wires)
return ..()
+/obj/effect/mine/Moved(atom/oldloc)
+ . = ..()
+ if(.)
+ var/turf/old_turf = get_turf(oldloc)
+ var/turf/new_turf = get_turf(src)
+ if(old_turf != new_turf)
+ old_turf.unregister_dangerous_object(src)
+ new_turf.register_dangerous_object(src)
+
/obj/effect/mine/proc/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
diff --git a/code/game/objects/effects/prop/columnblast.dm b/code/game/objects/effects/prop/columnblast.dm
index fc604235c8..ce0e4b2aad 100644
--- a/code/game/objects/effects/prop/columnblast.dm
+++ b/code/game/objects/effects/prop/columnblast.dm
@@ -17,7 +17,7 @@
..()
/obj/effect/temporary_effect/eruption/Initialize()
- ..()
+ . = ..()
flick("[icon_state]_create",src)
/obj/effect/temporary_effect/eruption/Destroy()
diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm
index c848a2f1df..eb025f9ba4 100644
--- a/code/game/objects/effects/spawners/bombspawner.dm
+++ b/code/game/objects/effects/spawners/bombspawner.dm
@@ -159,7 +159,6 @@
/obj/effect/spawner/newbomb/Initialize(newloc)
..(newloc)
-
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/phoron/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
@@ -183,19 +182,14 @@
OT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
OT.air_contents.update_values()
-
var/obj/item/device/assembly/S = new assembly_type(V)
-
-
V.attached_device = S
S.holder = V
S.toggle_secure()
V.update_icon()
-
- qdel(src)
-
+ return INITIALIZE_HINT_QDEL
///////////////////////
diff --git a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm
index e48606a2ac..e45664e60d 100644
--- a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm
+++ b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm
@@ -74,6 +74,12 @@
light_power = 0.5
light_color = "#8837A3"
+/obj/effect/projectile/impact/precursor //CHOMPedit add precursor impact
+ icon_state = "impact_prec"
+ light_range = 2
+ light_power = 0.7
+ light_color = "#FF0099"
+
/obj/effect/projectile/impact/tungsten
icon_state = "impact_mhd_laser"
light_range = 4
diff --git a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm
index a5c70aab2c..0c47f4ebb9 100644
--- a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm
+++ b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm
@@ -62,6 +62,12 @@
light_power = 0.5
light_color = "#8837A3"
+/obj/effect/projectile/muzzle/precursor //CHOMPedit add Precursor muzzle
+ icon_state = "muzzle_prec"
+ light_range = 2
+ light_power = 0.7
+ light_color = "#FF0099"
+
/obj/effect/projectile/muzzle/inversion
icon_state = "muzzle_invert"
light_range = 2
diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm
index 4326bc536d..908342e3ea 100644
--- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm
+++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm
@@ -91,6 +91,12 @@
light_power = 0.5
light_color = "#8837A3"
+/obj/effect/projectile/tracer/precursor //CHOMPedit add precursor tracer
+ icon_state = "prec"
+ light_range = 2
+ light_power = 0.7
+ light_color = "#FF0099"
+
/obj/effect/projectile/tracer/inversion
icon_state = "invert"
light_range = 2
diff --git a/code/game/objects/effects/zz_portals_ch.dm b/code/game/objects/effects/zz_portals_ch.dm
index ac3bdda110..809d63a1fa 100644
--- a/code/game/objects/effects/zz_portals_ch.dm
+++ b/code/game/objects/effects/zz_portals_ch.dm
@@ -20,10 +20,14 @@
/obj/effect/simple_portal/proc/handle_teleport(atom/movable/AM)
if(destination)
AM.forceMove(destination)
- if(!AM.is_incorporeal())
+ if(!AM.is_incorporeal() && !istype(AM,/mob/observer))
playsound(get_turf(src),teleport_sound,60,1)
playsound(get_turf(destination),teleport_sound,60,1)
+/obj/effect/simple_portal/attack_ghost(var/mob/observer/dead/user)
+ . = ..()
+ handle_teleport(user)
+
/obj/effect/simple_portal/coords
var/tele_x
var/tele_y
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index ff0ff75426..6d865085f5 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -356,6 +356,10 @@
playsound(src, pickup_sound, 20, preference = /datum/client_preference/pickup_sounds)
return
+// As above but for items being equipped to an active module on a robot.
+/obj/item/proc/equipped_robot(var/mob/user)
+ return
+
//Defines which slots correspond to which slot flags
var/list/global/slot_flags_enumeration = list(
"[slot_wear_mask]" = SLOT_MASK,
@@ -612,9 +616,6 @@ var/list/global/slot_flags_enumeration = list(
. = ..()
if(blood_overlay)
overlays.Remove(blood_overlay)
- if(istype(src, /obj/item/clothing/gloves))
- var/obj/item/clothing/gloves/G = src
- G.transfer_blood = 0
/obj/item/reveal_blood()
if(was_bloodied && !fluorescent)
@@ -791,7 +792,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
drop_sound = 'sound/items/drop/device.ogg'
//Worn icon generation for on-mob sprites
-/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null) //VOREStation edit - add 'clip mask' argument.
+/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null)
//Get the required information about the base icon
var/icon/icon2use = get_worn_icon_file(body_type = body_type, slot_name = slot_name, default_icon = default_icon, inhands = inhands)
var/state2use = get_worn_icon_state(slot_name = slot_name)
@@ -821,6 +822,9 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
if(istype(clip_mask)) //VOREStation Edit - For taur bodies/tails clipping off parts of uniforms and suits.
standing.filters += filter(type = "alpha", icon = clip_mask)
+ if(istype(clip_mask)) //For taur bodies/tails clipping off parts of uniforms and suits.
+ standing.filters += filter(type = "alpha", icon = clip_mask)
+
//Apply any special features
if(!inhands)
apply_blood(standing) //Some items show blood when bloodied
@@ -952,4 +956,4 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
// Like the above, but used for RPED sorting of parts.
/obj/item/proc/rped_rating()
- return get_rating()
\ No newline at end of file
+ return get_rating()
diff --git a/code/game/objects/items/devices/communicator/UI_tgui.dm b/code/game/objects/items/devices/communicator/UI_tgui.dm
index 8dabf77f42..4745a02488 100644
--- a/code/game/objects/items/devices/communicator/UI_tgui.dm
+++ b/code/game/objects/items/devices/communicator/UI_tgui.dm
@@ -1,3 +1,103 @@
+// Etc UI-only vars
+/obj/item/device/communicator
+ // Stuff for moving cameras
+ var/turf/last_camera_turf
+ // Stuff needed to render the map
+ var/map_name
+ var/obj/screen/map_view/cam_screen
+ var/list/cam_plane_masters
+ var/obj/screen/background/cam_background
+ var/obj/screen/skybox/local_skybox
+
+// Proc: setup_tgui_camera()
+// Parameters: None
+// Description: This sets up all of the variables above to handle in-UI map windows.
+/obj/item/device/communicator/proc/setup_tgui_camera()
+ map_name = "communicator_[REF(src)]_map"
+
+ // Initialize map objects
+ cam_screen = new
+ cam_screen.name = "screen"
+ cam_screen.assigned_map = map_name
+ cam_screen.del_on_map_removal = FALSE
+ cam_screen.screen_loc = "[map_name]:1,1"
+
+ cam_plane_masters = get_tgui_plane_masters()
+
+ for(var/plane in cam_plane_masters)
+ var/obj/screen/instance = plane
+ instance.assigned_map = map_name
+ instance.del_on_map_removal = FALSE
+ instance.screen_loc = "[map_name]:CENTER"
+
+ local_skybox = new()
+ local_skybox.assigned_map = map_name
+ local_skybox.del_on_map_removal = FALSE
+ local_skybox.screen_loc = "[map_name]:CENTER,CENTER"
+ cam_plane_masters += local_skybox
+
+ cam_background = new
+ cam_background.assigned_map = map_name
+ cam_background.del_on_map_removal = FALSE
+
+// Proc: update_active_camera_screen()
+// Parameters: None
+// Description: This refreshes the camera location
+/obj/item/device/communicator/proc/update_active_camera_screen()
+ if(!video_source?.can_use())
+ show_static()
+ return
+
+ var/newturf = get_turf(video_source)
+ if(!is_on_same_plane_or_station(get_z(newturf), get_z(src)))
+ show_static()
+ return
+
+ var/obj/item/device/communicator/communicator = video_source.loc
+ if(istype(communicator))
+ if(communicator.selfie_mode)
+ var/mob/target = get(communicator, /mob)
+ if(istype(target))
+ cam_screen.vis_contents = list(target)
+ else
+ cam_screen.vis_contents = list(communicator)
+ cam_background.fill_rect(1, 1, 1, 1)
+ cam_background.icon_state = "clear"
+ local_skybox.cut_overlays()
+ return
+
+ // If we're not forcing an update for some reason and the cameras are in the same location,
+ // we don't need to update anything.
+ if(last_camera_turf == newturf)
+ return
+
+ // We get a new turf in case they've moved in the last half decisecond (it's BYOND, it might happen)
+ last_camera_turf = get_turf(video_source)
+
+ if(!is_on_same_plane_or_station(get_z(last_camera_turf), get_z(src)))
+ show_static()
+ return
+
+ var/list/visible_turfs = list()
+ var/list/visible_things = view(video_range, last_camera_turf)
+ for(var/turf/visible_turf in visible_things)
+ visible_turfs += visible_turf
+
+ cam_screen.vis_contents = visible_turfs
+ cam_background.icon_state = "clear"
+ cam_background.fill_rect(1, 1, (video_range * 2), (video_range * 2))
+
+ local_skybox.cut_overlays()
+ local_skybox.add_overlay(SSskybox.get_skybox(get_z(last_camera_turf)))
+ local_skybox.scale_to_view(video_range * 2)
+ local_skybox.set_position("CENTER", "CENTER", (world.maxx>>1) - last_camera_turf.x, (world.maxy>>1) - last_camera_turf.y)
+
+/obj/item/device/communicator/proc/show_static()
+ cam_screen.vis_contents.Cut()
+ cam_background.icon_state = "scanline2"
+ cam_background.fill_rect(1, 1, (video_range * 2), (video_range * 2))
+ local_skybox.cut_overlays()
+
// Proc: tgui_state()
// Parameters: User
// Description: This tells TGUI to only allow us to be interacted with while in a mob inventory.
@@ -9,7 +109,15 @@
// Description: This proc handles opening the UI. It's basically just a standard stub.
/obj/item/device/communicator/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state)
ui = SStgui.try_update_ui(user, src, ui)
+ // Update the camera every SStgui tick in case it moves
+ update_active_camera_screen()
if(!ui)
+ // Register map objects
+ user.client.register_map_obj(cam_screen)
+ for(var/plane in cam_plane_masters)
+ user.client.register_map_obj(plane)
+ user.client.register_map_obj(cam_background)
+ // Setup UI
ui = new(user, src, "Communicator", name)
if(custom_state)
ui.set_state(custom_state)
@@ -188,6 +296,7 @@
data["target_feed"] = data["feeds"][newsfeed_channel]
else
data["target_feed"] = null
+ data["selfie_mode"] = selfie_mode
return data
@@ -200,6 +309,7 @@
if(data_core)
data_core.get_manifest_list()
data["manifest"] = PDA_Manifest
+ data["mapRef"] = map_name
return data
// Proc: tgui-act()
@@ -231,6 +341,9 @@
if("toggle_ringer")
ringer = !ringer
+ if("selfie_mode")
+ selfie_mode = !selfie_mode
+
if("add_hex")
var/hex = params["add_hex"]
add_to_EPv2(hex)
@@ -324,3 +437,4 @@
if("newsfeed")
newsfeed_channel = text2num(params["newsfeed"])
+#undef DEFAULT_MAP_SIZE
\ No newline at end of file
diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm
index 358ef3b61b..6adbbf811c 100644
--- a/code/game/objects/items/devices/communicator/communicator.dm
+++ b/code/game/objects/items/devices/communicator/communicator.dm
@@ -26,9 +26,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
show_messages = 1
origin_tech = list(TECH_ENGINEERING = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2, TECH_DATA = 2)
- matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10)
+ matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10, MAT_COPPER = 10)
- var/video_range = 4
+ var/video_range = 3
var/obj/machinery/camera/communicator/video_source // Their camera
var/obj/machinery/camera/communicator/camera // Our camera
@@ -72,6 +72,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
var/update_ticks = 0
var/newsfeed_channel = 0
+ // If you turn this on, it changes the way communicator video works. User configurable option.
+ var/selfie_mode = FALSE
+
// Proc: New()
// Parameters: None
// Description: Adds the new communicator to the global list of all communicators, sorts the list, obtains a reference to the Exonet node, then tries to
@@ -86,6 +89,8 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
camera.name = "[src] #[rand(100,999)]"
camera.c_tag = camera.name
+ setup_tgui_camera()
+
//This is a pretty terrible way of doing this.
addtimer(CALLBACK(src, .proc/register_to_holder), 5 SECONDS)
@@ -124,12 +129,9 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
/obj/item/device/communicator/examine(mob/user)
. = ..()
- if(Adjacent(user) && video_source)
- . += "It looks like it's on a video call: \[view\]"
-
for(var/mob/living/voice/voice in contents)
. += "On the screen, you can see a image feed of [voice]."
-
+
if(voice && voice.key)
switch(voice.stat)
if(CONSCIOUS)
@@ -142,17 +144,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
else
. += "The device doesn't appear to be transmitting any data."
-// Proc: Topic()
-// Parameters: href, href_list - Data from a link
-// Description: Used by the above examine.
-/obj/item/device/communicator/Topic(href, href_list)
- if(..())
- return 1
-
- if(href_list["watchvideo"])
- if(video_source)
- watch_video(usr)
-
// Proc: emp_act()
// Parameters: None
// Description: Drops all calls when EMPed, so the holder can then get murdered by the antagonist.
@@ -234,8 +225,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
alert_called = 0
update_icon()
tgui_interact(user)
- if(video_source)
- watch_video(user)
// Proc: MouseDrop()
//Same thing PDAs do
@@ -316,6 +305,11 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
QDEL_NULL(camera)
QDEL_NULL(exonet)
+ last_camera_turf = null
+ qdel(cam_screen)
+ QDEL_LIST(cam_plane_masters)
+ qdel(cam_background)
+
return ..()
// Proc: update_icon()
diff --git a/code/game/objects/items/devices/communicator/helper.dm b/code/game/objects/items/devices/communicator/helper.dm
index 5cf5eac2c2..aa17fd4bd6 100644
--- a/code/game/objects/items/devices/communicator/helper.dm
+++ b/code/game/objects/items/devices/communicator/helper.dm
@@ -40,7 +40,7 @@
var/list/feeds = list()
for(var/datum/feed_channel/channel in news_network.network_channels)
var/list/messages = list()
- if(!channel.censored)
+ if(!channel.censored && channel.channel_name != "Vir News Network") //Do not load the 'IC news' channel as it is simply too long.
var/index = 0
for(var/datum/feed_message/FM in channel.messages)
index++
diff --git a/code/game/objects/items/devices/communicator/phone.dm b/code/game/objects/items/devices/communicator/phone.dm
index 7075dbe958..bb25dce953 100644
--- a/code/game/objects/items/devices/communicator/phone.dm
+++ b/code/game/objects/items/devices/communicator/phone.dm
@@ -332,12 +332,15 @@
if(video_source) //Already in a video
to_chat(user, "You are already connected to a video call!")
+ return
if(user.blinded) //User is blinded
to_chat(user, "You cannot see well enough to do that!")
+ return
if(!(src in comm.communicating) || !comm.camera) //You called someone with a broken communicator or one that's fake or yourself or something
to_chat(user, "[bicon(src)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.")
+ return
to_chat(user, "[bicon(src)] Attempting to start video over existing call.")
sleep(30)
@@ -345,42 +348,16 @@
video_source = comm.camera
comm.visible_message("[bicon(src)] New video connection from [comm].")
- watch_video(user)
+ update_active_camera_screen()
+ GLOB.moved_event.register(video_source, src, .proc/update_active_camera_screen)
update_icon()
-// Proc: watch_video()
-// Parameters: user - the mob doing the viewing of video
-// Description: Moves a mob's eye to the far end for the duration of viewing the far end
-/obj/item/device/communicator/proc/watch_video(mob/user)
- if(!Adjacent(user) || !video_source) return
- user.set_machine(video_source)
- user.reset_view(video_source)
- to_chat(user, "Now viewing video session. To leave camera view, close the communicator window OR: OOC -> Cancel Camera View")
- to_chat(user, "To return to an active video session, use the communicator in your hand.")
- spawn(0)
- while(user.machine == video_source && Adjacent(user))
- var/turf/T = get_turf(video_source)
- if(!T || !is_on_same_plane_or_station(T.z, user.z) || !video_source.can_use())
- to_chat(user, "The screen bursts into static, then goes black.")
- video_cleanup(user)
- return
- sleep(10)
-
- video_cleanup(user)
-
-// Proc: video_cleanup()
-// Parameters: user - the mob who doesn't want to see video anymore
-// Description: Cleans up mob's client when they stop watching a video
-/obj/item/device/communicator/proc/video_cleanup(mob/user)
- if(!user) return
-
- user.reset_view(null)
- user.unset_machine()
-
// Proc: end_video()
// Parameters: reason - the text reason to print for why it ended
// Description: Ends the video call by clearing video_source
/obj/item/device/communicator/proc/end_video(var/reason)
+ GLOB.moved_event.unregister(video_source, src, .proc/update_active_camera_screen)
+ show_static()
video_source = null
. = "[bicon(src)] [reason ? reason : "Video session ended"]."
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 2247674f60..facc87ae64 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -33,7 +33,7 @@
var/cell_type = /obj/item/weapon/cell/device
/obj/item/device/flash/Initialize()
- ..()
+ . = ..()
power_supply = new cell_type(src)
/obj/item/device/flash/attackby(var/obj/item/W, var/mob/user)
diff --git a/code/game/objects/items/devices/floor_painter.dm b/code/game/objects/items/devices/floor_painter.dm
index d84f4bc3ca..c4c64f746c 100644
--- a/code/game/objects/items/devices/floor_painter.dm
+++ b/code/game/objects/items/devices/floor_painter.dm
@@ -1,5 +1,5 @@
/obj/item/device/floor_painter
- name = "floor painter"
+ name = "paint sprayer"
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "labeler1"
@@ -43,6 +43,10 @@
if(!proximity)
return
+ if(istype(A, /mob/living/silicon/robot/platform))
+ var/mob/living/silicon/robot/platform/robit = A
+ return robit.try_paint(src, user)
+
var/turf/simulated/floor/F = A
if(!istype(F))
to_chat(user, "\The [src] can only be used on station flooring.")
@@ -115,20 +119,20 @@
/obj/item/device/floor_painter/verb/choose_colour()
set name = "Choose Colour"
- set desc = "Choose a floor painter colour."
+ set desc = "Choose a paint colour."
set category = "Object"
set src in usr
if(usr.incapacitated())
return
- var/new_colour = input(usr, "Choose a colour.", "Floor painter", paint_colour) as color|null
+ var/new_colour = input(usr, "Choose a colour.", name, paint_colour) as color|null
if(new_colour && new_colour != paint_colour)
paint_colour = new_colour
to_chat(usr, "You set \the [src] to paint with a new colour.")
/obj/item/device/floor_painter/verb/choose_decal()
set name = "Choose Decal"
- set desc = "Choose a floor painter decal."
+ set desc = "Choose a painting decal."
set category = "Object"
set src in usr
@@ -142,7 +146,7 @@
/obj/item/device/floor_painter/verb/choose_direction()
set name = "Choose Direction"
- set desc = "Choose a floor painter direction."
+ set desc = "Choose a painting direction."
set category = "Object"
set src in usr
diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm
index e14a4c0edf..7621f09830 100644
--- a/code/game/objects/items/devices/gps.dm
+++ b/code/game/objects/items/devices/gps.dm
@@ -9,24 +9,124 @@ var/list/GPS_list = list()
slot_flags = SLOT_BELT
origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_MAGNET = 1)
matter = list(DEFAULT_WALL_MATERIAL = 500)
+
var/gps_tag = "GEN0"
var/emped = FALSE
- var/updating = TRUE // Lets users lock the UI so they don't have to deal with constantly shifting signals
var/tracking = FALSE // Will not show other signals or emit its own signal if false.
var/long_range = FALSE // If true, can see farther, depending on get_map_levels().
var/local_mode = FALSE // If true, only GPS signals of the same Z level are shown.
var/hide_signal = FALSE // If true, signal is not visible to other GPS devices.
var/can_hide_signal = FALSE // If it can toggle the above var.
+ var/mob/holder
+ var/is_in_processing_list = FALSE
+ var/list/tracking_devices
+ var/list/showing_tracked_names
+ var/obj/compass_holder/compass
+
/obj/item/device/gps/Initialize()
. = ..()
+ compass = new(src)
GPS_list += src
name = "global positioning system ([gps_tag])"
+ update_holder()
update_icon()
+/obj/item/device/gps/proc/check_visible_to_holder()
+ . = (holder && (holder.get_active_hand() == src || holder.get_inactive_hand() == src))
+
+/obj/item/device/gps/proc/update_holder()
+
+ if(holder && loc != holder)
+ GLOB.moved_event.unregister(holder, src)
+ GLOB.dir_set_event.unregister(holder, src)
+ holder.client?.screen -= compass
+ holder = null
+
+ if(istype(loc, /mob))
+ holder = loc
+ GLOB.moved_event.register(holder, src, .proc/update_compass)
+ GLOB.dir_set_event.register(holder, src, .proc/update_compass)
+
+ if(holder && tracking)
+ if(!is_in_processing_list)
+ START_PROCESSING(SSobj, src)
+ is_in_processing_list = TRUE
+ if(holder.client)
+ if(check_visible_to_holder())
+ holder.client.screen |= compass
+ else
+ holder.client.screen -= compass
+ else
+ STOP_PROCESSING(SSobj, src)
+ is_in_processing_list = FALSE
+ if(holder?.client)
+ holder.client.screen -= compass
+
+/obj/item/device/gps/pickup()
+ . = ..()
+ update_holder()
+
+/obj/item/device/gps/equipped_robot()
+ . = ..()
+ update_holder()
+
+/obj/item/device/gps/equipped()
+ . = ..()
+ update_holder()
+
+/obj/item/device/gps/dropped()
+ . = ..()
+ update_holder()
+
+/obj/item/device/gps/process()
+ if(!tracking)
+ is_in_processing_list = FALSE
+ return PROCESS_KILL
+ update_holder()
+ if(holder)
+ update_compass(TRUE)
+
/obj/item/device/gps/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ is_in_processing_list = FALSE
GPS_list -= src
- return ..()
+ . = ..()
+ update_holder()
+ QDEL_NULL(compass)
+
+/obj/item/device/gps/proc/can_track(var/obj/item/device/gps/other, var/reachable_z_levels)
+ if(!other.tracking || other.emped || other.hide_signal)
+ return FALSE
+ var/turf/origin = get_turf(src)
+ var/turf/target = get_turf(other)
+ if(!istype(origin) || !istype(target))
+ return FALSE
+ if(origin.z == target.z)
+ return TRUE
+ if(local_mode)
+ return FALSE
+ reachable_z_levels = reachable_z_levels || using_map.get_map_levels(origin.z, long_range)
+ return (target.z in reachable_z_levels)
+
+/obj/item/device/gps/proc/update_compass(var/update_compass_icon)
+ compass.hide_waypoints(FALSE)
+ var/turf/my_turf = get_turf(src)
+ for(var/thing in tracking_devices)
+ var/obj/item/device/gps/gps = locate(thing)
+ if(!istype(gps) || QDELETED(gps))
+ LAZYREMOVE(tracking_devices, thing)
+ LAZYREMOVE(showing_tracked_names, thing)
+ continue
+ var/turf/gps_turf = get_turf(gps)
+ var/gps_tag = LAZYACCESS(showing_tracked_names, thing) ? gps.gps_tag : null
+ if(istype(gps_turf))
+ compass.set_waypoint("\ref[gps]", gps_tag, gps_turf.x, gps_turf.y, gps_turf.z, LAZYACCESS(tracking_devices, "\ref[gps]"))
+ else
+ compass.set_waypoint("\ref[gps]", gps_tag, 0, 0, 0, LAZYACCESS(tracking_devices, "\ref[gps]"))
+ if(can_track(gps) && gps_turf && my_turf && gps_turf.z == my_turf.z)
+ compass.show_waypoint("\ref[gps]")
+ compass.rebuild_overlay_lists(update_compass_icon)
/obj/item/device/gps/AltClick(mob/user)
toggletracking(user)
@@ -37,14 +137,25 @@ var/list/GPS_list = list()
if(emped)
to_chat(user, "It's busted!")
return
+
+ toggle_tracking()
if(tracking)
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
- tracking = FALSE
- update_icon()
else
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
- tracking = TRUE
- update_icon()
+
+/obj/item/device/gps/proc/toggle_tracking()
+ tracking = !tracking
+ if(tracking)
+ if(!is_in_processing_list)
+ is_in_processing_list = TRUE
+ START_PROCESSING(SSobj, src)
+ else
+ is_in_processing_list = FALSE
+ STOP_PROCESSING(SSobj, src)
+ update_compass()
+ update_holder()
+ update_icon()
/obj/item/device/gps/emp_act(severity)
if(emped) // Without a fancy callback system, this will have to do.
@@ -67,11 +178,7 @@ var/list/GPS_list = list()
add_overlay("working")
/obj/item/device/gps/attack_self(mob/user)
- tgui_interact(user)
-
-/obj/item/device/gps/examine(mob/user)
- . = ..()
- . += display()
+ display(user)
// Compiles all the data not available directly from the GPS
// Like the positions and directions to all other GPS units
@@ -81,24 +188,17 @@ var/list/GPS_list = list()
var/turf/curr = get_turf(src)
var/area/my_area = get_area(src)
- dat["my_area_name"] = my_area.name
+ dat["my_area_name"] = strip_improper(my_area.name)
dat["curr_x"] = curr.x
dat["curr_y"] = curr.y
dat["curr_z"] = curr.z
- dat["curr_z_name"] = using_map.get_zlevel_name(curr.z)
+ dat["curr_z_name"] = strip_improper(using_map.get_zlevel_name(curr.z))
dat["gps_list"] = list()
dat["z_level_detection"] = using_map.get_map_levels(curr.z, long_range)
for(var/obj/item/device/gps/G in GPS_list - src)
- if(!G.tracking || G.emped || G.hide_signal)
- continue
- var/turf/T = get_turf(G)
- if(!T)
- continue
- if(local_mode && curr.z != T.z)
- continue
- if(!(T.z in dat["z_level_detection"]))
+ if(!can_track(G, dat["z_level_detection"]))
continue
var/gps_data[0]
@@ -106,9 +206,10 @@ var/list/GPS_list = list()
gps_data["gps_tag"] = G.gps_tag
var/area/A = get_area(G)
- gps_data["area_name"] = A.get_name()
+ gps_data["area_name"] = strip_improper(A.get_name())
- gps_data["z_name"] = using_map.get_zlevel_name(T.z)
+ var/turf/T = get_turf(G)
+ gps_data["z_name"] = strip_improper(using_map.get_zlevel_name(T.z))
gps_data["direction"] = get_adir(curr, T)
gps_data["degrees"] = round(Get_Angle(curr,T))
gps_data["distX"] = T.x - curr.x
@@ -122,37 +223,101 @@ var/list/GPS_list = list()
return dat
-/obj/item/device/gps/proc/display()
- if(!tracking)
- . = "The device is off. Alt-click it to turn it on."
- return
+/obj/item/device/gps/proc/display(mob/user)
+
if(emped)
- . = "It's busted!"
+ to_chat(user, SPAN_WARNING("It's busted!"))
return
var/list/dat = list()
var/list/gps_data = display_list()
- dat += "Current location: [gps_data["my_area_name"]] ([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])"
- dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. \[Change Tag\] \
- \[Toggle Scan Range\] \
- [can_hide_signal ? "\[Toggle Signal Visibility\]":""]"
-
- if(gps_data["gps_list"].len)
- dat += "Detected signals;"
- for(var/gps in gps_data["gps_list"])
- if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi))
- dat += " [gps["gps_tag"]]: [gps["area_name"]] - [gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "in \the [gps["z_name"]]"]"
- else
- dat += " [gps["gps_tag"]]: [gps["area_name"]], ([gps["x"]], [gps["y"]]) - [gps["local"] ? "[gps["direction"]] Dist: [gps["distX"] ? "[abs(round(gps["distX"], 1))]m [(gps["distX"] > 0) ? "E" : "W"], " : ""][gps["distY"] ? "[abs(round(gps["distY"], 1))]m [(gps["distY"] > 0) ? "N" : "S"]" : ""]" : "in \the [gps["z_name"]]"]"
+ dat += ""
+ if(!tracking)
+ dat += " | \[Switch On\] "
else
- dat += "No other signals detected."
+ dat += " | \[Switch Off\] "
+ dat += "| Current location | [gps_data["my_area_name"]] | ([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]]) | "
+ dat += "| [hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. | "
+ dat += "\[Change Tag\]\[Toggle Scan Range\][can_hide_signal ? "\[Toggle Signal Visibility\]":""] | "
- . = dat
+ if(gps_data["gps_list"].len)
+ dat += "| Detected signals | "
+ for(var/gps in gps_data["gps_list"])
+ dat += ""
+ var/gps_ref = "\ref[gps["ref"]]"
+ dat += "| [gps["gps_tag"]] | [gps["area_name"]] | "
+
+ if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi))
+ dat += "[gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "[gps["z_name"]]"] | "
+ else
+ dat += "([gps["x"]], [gps["y"]], [gps["z_name"]]) | "
+
+ if(gps["local"])
+ dat += "[gps["distance"]]m | [gps["direction"]] | "
+ else
+ dat += "Non-local signal. | "
+
+ if(LAZYACCESS(tracking_devices, gps_ref))
+ dat += "\[Stop Tracking\] \[Colour [color_square(hex = LAZYACCESS(tracking_devices, gps_ref))]\] Show/Hide Label | "
+ else
+ dat += "\[Start Tracking\] | "
+ dat += " "
+ else
+ dat += "| No other signals detected. | "
+ dat += " "
+
+ var/datum/browser/popup = new(user, "gps_\ref[src]", "Global Positioning System", 700, 1000)
+ popup.set_content(dat.Join(null))
+ popup.open()
/obj/item/device/gps/Topic(var/href, var/list/href_list)
if(..())
- return 1
+ return TRUE
+
+ if(href_list["toggle_power"])
+ toggle_tracking()
+ . = TRUE
+
+ if(href_list["track_label"])
+ var/gps_ref = href_list["track_label"]
+ var/obj/item/device/gps/gps = locate(gps_ref)
+ if(istype(gps) && !QDELETED(gps) && !LAZYACCESS(showing_tracked_names, gps_ref))
+ LAZYSET(showing_tracked_names, gps_ref, TRUE)
+ else
+ LAZYREMOVE(showing_tracked_names, gps_ref)
+ to_chat(usr, SPAN_NOTICE("\The [src] is [LAZYACCESS(showing_tracked_names, gps_ref) ? "now showing" : "no longer showing"] labels for [gps.gps_tag]."))
+
+ if(href_list["stop_track"])
+ var/gps_ref = href_list["stop_track"]
+ var/obj/item/device/gps/gps = locate(gps_ref)
+ compass.clear_waypoint(gps_ref)
+ LAZYREMOVE(tracking_devices, gps_ref)
+ LAZYREMOVE(showing_tracked_names, gps_ref)
+ if(istype(gps) && !QDELETED(gps))
+ to_chat(usr, SPAN_NOTICE("\The [src] is no longer tracking [gps.gps_tag]."))
+ update_compass()
+ . = TRUE
+
+ if(href_list["start_track"])
+ var/gps_ref = href_list["start_track"]
+ var/obj/item/device/gps/gps = locate(gps_ref)
+ if(istype(gps) && !QDELETED(gps))
+ LAZYSET(tracking_devices, gps_ref, "#00ffff")
+ LAZYSET(showing_tracked_names, gps_ref, TRUE)
+ to_chat(usr, SPAN_NOTICE("\The [src] is now tracking [gps.gps_tag]."))
+ update_compass()
+ . = TRUE
+
+ if(href_list["track_color"])
+ var/obj/item/device/gps/gps = locate(href_list["track_color"])
+ if(istype(gps) && !QDELETED(gps))
+ var/new_colour = input("Enter a new tracking color.", "GPS Waypoint Color") as color|null
+ if(new_colour && istype(gps) && !QDELETED(gps) && holder == usr && !usr.incapacitated())
+ to_chat(usr, SPAN_NOTICE("You adjust the colour \the [src] is using to highlight [gps.gps_tag]."))
+ LAZYSET(tracking_devices, href_list["track_color"], new_colour)
+ update_compass()
+ . = TRUE
if(href_list["tag"])
var/a = input("Please enter desired tag.", name, gps_tag) as text
@@ -161,95 +326,22 @@ var/list/GPS_list = list()
gps_tag = a
name = "global positioning system ([gps_tag])"
to_chat(usr, "You set your GPS's tag to '[gps_tag]'.")
+ . = TRUE
if(href_list["range"])
local_mode = !local_mode
to_chat(usr, "You set the signal receiver to [local_mode ? "'NARROW'" : "'BROAD'"].")
+ . = TRUE
if(href_list["hide"])
if(!can_hide_signal)
return
hide_signal = !hide_signal
to_chat(usr, "You set the device to [hide_signal ? "not " : ""]broadcast a signal while scanning for other signals.")
+ . = TRUE
-/obj/item/device/gps/tgui_interact(mob/user, datum/tgui/ui)
- if(emped)
- to_chat(user, "[src] fizzles weakly.")
- return
- ui = SStgui.try_update_ui(user, src, ui)
- if(!ui)
- ui = new(user, src, "Gps", name)
- ui.open()
- ui.set_autoupdate(updating)
-
-/obj/item/device/gps/tgui_data(mob/user)
- var/list/data = list()
- data["power"] = tracking
- data["tag"] = gps_tag
- data["updating"] = updating
- data["globalmode"] = !local_mode
- if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
- return data
-
- var/turf/curr = get_turf(src)
- data["currentArea"] = "[get_area_name(curr, TRUE)]"
- data["currentCoords"] = list(curr.x, curr.y, curr.z)
- data["currentCoordsText"] = "[curr.x], [curr.y], [using_map.get_zlevel_name(curr.z)]"
-
- data["zLevelDetection"] = using_map.get_map_levels(curr.z, long_range)
-
- var/list/signals = list()
- data["signals"] = list()
-
- for(var/obj/item/device/gps/G in GPS_list - src)
- if(!G.tracking || G.emped || G.hide_signal)
- continue
-
- var/turf/T = get_turf(G)
- if(!T)
- continue
- if(local_mode && curr.z != T.z)
- continue
- if(!(T.z in data["zLevelDetection"]))
- continue
-
- var/list/signal = list()
- signal["entrytag"] = G.gps_tag //Name or 'tag' of the GPS
- signal["coords"] = list(T.x, T.y, T.z)
- signal["coordsText"] = "[T.x], [T.y], [using_map.get_zlevel_name(T.z)]"
- if(T.z == curr.z) //Distance/Direction calculations for same z-level only
- signal["dist"] = max(get_dist(curr, T), 0) //Distance between the src and remote GPS turfs
- signal["degrees"] = round(Get_Angle(curr, T)) //0-360 degree directional bearing, for more precision.
- signals += list(signal) //Add this signal to the list of signals
- data["signals"] = signals
- return data
-
-/obj/item/device/gps/tgui_act(action, params)
- if(..())
- return TRUE
-
- switch(action)
- if("rename")
- var/a = stripped_input(usr, "Please enter desired tag.", name, gps_tag, 20)
-
- if(!a)
- return
-
- gps_tag = a
- name = "global positioning system ([gps_tag])"
- . = TRUE
-
- if("power")
- toggletracking(usr)
- . = TRUE
-
- if("updating")
- updating = !updating
- . = TRUE
-
- if("globalmode")
- local_mode = !local_mode
- . = TRUE
+ if(. && loc == usr)
+ display(usr)
/obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these.
tracking = TRUE
@@ -373,26 +465,42 @@ var/list/GPS_list = list()
can_hide_signal = TRUE
/obj/item/device/gps/syndie/display(mob/user)
- if(!tracking)
- . = "The device is off. Alt-click it to turn it on."
- return
+
if(emped)
- . = "It's busted!"
+ to_chat(user, "It's busted!")
return
var/list/dat = list()
var/list/gps_data = display_list()
- dat += "Current location: [gps_data["my_area_name"]] ([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])"
- dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. \[Change Tag\] \
- \[Toggle Scan Range\] \
- [can_hide_signal ? "\[Toggle Signal Visibility\]":""]"
-
- if(gps_data["gps_list"].len)
- dat += "Detected signals;"
- for(var/gps in gps_data["gps_list"])
- dat += " [gps["gps_tag"]]: [gps["area_name"]] ([gps["x"]], [gps["y"]], [gps["z_name"]]) [gps["local"] ? "Dist: [gps["distance"]]m Dir: [gps["degrees"]]° ([gps["direction"]])" :""]"
+ dat += ""
+
+ var/datum/browser/popup = new(user, "gps_\ref[src]", "Global Positioning System", 700, 1000)
+ popup.set_content(dat.Join(null))
+ popup.open()
diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm
index 810147dbc4..7ccad467f6 100644
--- a/code/game/objects/items/devices/laserpointer.dm
+++ b/code/game/objects/items/devices/laserpointer.dm
@@ -6,7 +6,7 @@
item_state = "pen"
var/pointer_icon_state
slot_flags = SLOT_BELT
- matter = list("glass" = 500,"metal" = 500)
+ matter = list("glass" = 500,"metal" = 500, MAT_COPPER = 10)
w_class = 2 //Increased to 2, because diodes are w_class 2. Conservation of matter.
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
var/turf/pointer_loc
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 837c6616f7..8ac7a07199 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -17,7 +17,7 @@
drop_sound = 'sound/items/drop/multitool.ogg'
pickup_sound = 'sound/items/pickup/multitool.ogg'
- matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
+ matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20, MAT_COPPER = 10)
var/mode_index = 1
var/toolmode = MULTITOOL_MODE_STANDARD
diff --git a/code/game/objects/items/devices/paicard_ch.dm b/code/game/objects/items/devices/paicard_ch.dm
new file mode 100644
index 0000000000..b6ce0d69d8
--- /dev/null
+++ b/code/game/objects/items/devices/paicard_ch.dm
@@ -0,0 +1,18 @@
+/obj/item/device/paicard/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ var/obj/item/weapon/card/id/ID = W.GetID()
+ if(ID)
+ if (src.pai.idaccessible == 1)
+ switch(alert(user, "Do you wish to add access to [src] or remove access from [src]?",,"Add Access","Remove Access", "Cancel"))
+ if("Add Access")
+ src.pai.idcard.access |= ID.access
+ to_chat(user, "You add the access from the [W] to [src].")
+ return
+ if("Remove Access")
+ src.pai.idcard.access = list()
+ to_chat(user, "You remove the access from [src].")
+ return
+ if("Cancel")
+ return
+ else if (istype(W, /obj/item/weapon/card/id) && src.pai.idaccessible == 0)
+ to_chat(user, "[src] is not accepting access modifcations at this time.")
+ return
\ No newline at end of file
diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm
index cc555f8073..55b79eaef3 100644
--- a/code/game/objects/items/devices/radio/electropack.dm
+++ b/code/game/objects/items/devices/radio/electropack.dm
@@ -11,7 +11,7 @@
slot_flags = SLOT_BACK
w_class = ITEMSIZE_HUGE
- matter = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 2500)
+ matter = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 2500, MAT_COPPER = 1550)
var/code = 2
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 21b7463637..7c64f1b203 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -8,7 +8,7 @@
subspace_transmission = 1
canhear_range = 0 // can't hear headsets from very far away
slot_flags = SLOT_EARS
- sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/ears.dmi')
+ sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/ears.dmi')
var/translate_binary = 0
var/translate_hive = 0
diff --git a/code/game/objects/items/devices/radio/headset_vr.dm b/code/game/objects/items/devices/radio/headset_vr.dm
index 9204c81dd1..8285fade75 100644
--- a/code/game/objects/items/devices/radio/headset_vr.dm
+++ b/code/game/objects/items/devices/radio/headset_vr.dm
@@ -22,7 +22,7 @@
icon_state = "nt_headset_alt"
/obj/item/device/radio/headset
- sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/ears.dmi',
+ sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/ears.dmi',
SPECIES_WEREBEAST = 'icons/mob/species/werebeast/ears.dmi')
/obj/item/device/radio/headset/mob_headset //Adminbus headset for simplemob shenanigans.
@@ -84,7 +84,6 @@
desc = "A headset used by pilots, has access to the explorer channel."
icon_state = "pilot_headset"
adhoc_fallback = TRUE
- ks2type = /obj/item/device/encryptionkey/pilot
/obj/item/device/radio/headset/pilot/alt
name = "pilot's bowman headset"
@@ -120,7 +119,7 @@
desc = "A headset used by volunteers to expedition teams, has access to the exploration channel."
icon_state = "pilot_headset"
adhoc_fallback = TRUE
- ks2type = /obj/item/device/encryptionkey/pilot
+ ks2type = /obj/item/device/encryptionkey/explorer
/obj/item/device/radio/headset/talon
name = "talon headset"
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index d2511038dc..88e957f76e 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -61,7 +61,7 @@ var/global/list/default_medbay_channels = list(
var/bs_tx_preload_id
var/bs_rx_preload_id
- matter = list("glass" = 25,DEFAULT_WALL_MATERIAL = 75)
+ matter = list("glass" = 25, DEFAULT_WALL_MATERIAL = 75, MAT_COPPER = 15)
var/const/FREQ_LISTENING = 1
var/list/internal_channels
@@ -297,7 +297,8 @@ var/global/list/default_medbay_channels = list(
playsound(src, "button", 10)
GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
-/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels) //BS12 EDIT
+
+/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels)
if(!GLOB.autospeaker)
return
var/datum/radio_frequency/connection = null
@@ -308,7 +309,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
else
connection = radio_connection
channel = null
- if (!istype(connection))
+ if(!istype(connection))
return
if(!LAZYLEN(zlevels))
@@ -507,7 +508,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
else if(adhoc_fallback) //Less huzzah, we have to fallback
to_chat(loc, "\The [src] pings as it falls back to local radio transmission.")
subspace_transmission = FALSE
-
+
else //Oh well
return FALSE
@@ -594,7 +595,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
/obj/item/device/radio/examine(mob/user)
. = ..()
-
+
if((in_range(src, user) || loc == user))
if(b_stat)
. += "\The [src] can be attached and modified!"
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index c949884c6f..291202f41f 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -21,7 +21,7 @@ HALOGEN COUNTER - Radcount on mobs
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
- matter = list(DEFAULT_WALL_MATERIAL = 200)
+ matter = list(DEFAULT_WALL_MATERIAL = 200, MAT_COPPER = 25)
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
var/mode = 1;
var/advscan = 0
diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm
index c4069be3ed..4c07229df7 100644
--- a/code/game/objects/items/devices/uplink.dm
+++ b/code/game/objects/items/devices/uplink.dm
@@ -1,5 +1,3 @@
-GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
-
// I placed this here because of how relevant it is.
// You place this in your uplinkable item to check if an uplink is active or not.
// If it is, it will display the uplink menu and return 1, else it'll return false.
@@ -14,29 +12,19 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
/obj/item/device/uplink
var/welcome = "Welcome, Operative" // Welcoming menu message
- var/uses // Numbers of crystals
var/list/ItemsCategory // List of categories with lists of items
var/list/ItemsReference // List of references with an associated item
var/list/nanoui_items // List of items for NanoUI use
var/faction = "" //Antag faction holder.
- var/list/purchase_log = new
- var/datum/mind/uplink_owner = null
- var/used_TC = 0
var/offer_time = 10 MINUTES //The time increment per discount offered
var/next_offer_time
var/datum/uplink_item/discount_item //The item to be discounted
var/discount_amount //The amount as a percent the item will be discounted by
var/compact_mode = FALSE
-/obj/item/device/uplink/Initialize(var/mapload, var/datum/mind/owner = null, var/telecrystals = DEFAULT_TELECRYSTAL_AMOUNT)
+/obj/item/device/uplink/Initialize(var/mapload)
. = ..()
- uplink_owner = owner
- purchase_log = list()
- if(owner)
- uses = owner.tcrystals
- else
- uses = telecrystals
addtimer(CALLBACK(src, .proc/next_offer), offer_time) //It seems like only the /hidden type actually makes use of this...
/obj/item/device/uplink/get_item_cost(var/item_type, var/item_cost)
@@ -85,7 +73,7 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
/obj/item/device/uplink/hidden/proc/trigger(mob/user as mob)
if(!active)
toggle()
- interact(user)
+ tgui_interact(user)
// Checks to see if the value meets the target. Like a frequency being a traitor_frequency, in order to unlock a headset.
// If true, it accesses trigger() and returns 1. If it fails, it returns false. Use this to see if you need to close the
@@ -93,8 +81,8 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
/obj/item/device/uplink/hidden/proc/check_trigger(mob/user as mob, var/value, var/target)
if(value == target)
trigger(user)
- return 1
- return 0
+ return TRUE
+ return FALSE
// Legacy
/obj/item/device/uplink/hidden/interact(mob/user)
@@ -107,12 +95,11 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
return loc
/obj/item/device/uplink/hidden/tgui_state(mob/user)
- return GLOB.tgui_inventory_state
+ return GLOB.tgui_deep_inventory_state
/obj/item/device/uplink/hidden/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
if(!active)
toggle()
- uses = user.mind.tcrystals
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Uplink", "Remote Uplink")
@@ -127,7 +114,7 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
var/list/data = ..()
- data["telecrystals"] = uses
+ data["telecrystals"] = user.mind.tcrystals
data["lockable"] = TRUE
data["compactMode"] = compact_mode
@@ -177,22 +164,19 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
data["categories"] = list()
for(var/datum/uplink_category/category in uplink.categories)
- if(category.can_view(src))
- var/list/cat = list(
+ var/list/cat = list(
"name" = category.name,
"items" = (category == selected_cat ? list() : null)
)
- for(var/datum/uplink_item/item in category.items)
- if(!item.can_view(src))
- continue
- var/cost = item.cost(uses, src) || "???"
- cat["items"] += list(list(
- "name" = item.name,
- "cost" = cost,
- "desc" = item.description(),
- "ref" = REF(item),
- ))
- data["categories"] += list(cat)
+ for(var/datum/uplink_item/item in category.items)
+ var/cost = item.cost(src, user) || "???"
+ cat["items"] += list(list(
+ "name" = item.name,
+ "cost" = cost,
+ "desc" = item.description(),
+ "ref" = REF(item),
+ ))
+ data["categories"] += list(cat)
return data
@@ -228,9 +212,9 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
//
// Includes normal radio uplink, multitool uplink,
// implant uplink (not the implant tool) and a preset headset uplink.
-/obj/item/device/radio/uplink/New(atom/loc, datum/mind/target_mind, telecrystals)
- ..(loc)
- hidden_uplink = new(src, target_mind, telecrystals)
+/obj/item/device/radio/uplink/New()
+ ..()
+ hidden_uplink = new(src)
icon_state = "radio"
/obj/item/device/radio/uplink/attack_self(mob/user as mob)
@@ -238,6 +222,7 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
hidden_uplink.trigger(user)
/obj/item/device/multitool/uplink/New()
+ ..()
hidden_uplink = new(src)
/obj/item/device/multitool/uplink/attack_self(mob/user as mob)
@@ -250,4 +235,3 @@ GLOBAL_LIST_BOILERPLATE(world_uplinks, /obj/item/device/uplink)
/obj/item/device/radio/headset/uplink/New()
..()
hidden_uplink = new(src)
- hidden_uplink.uses = DEFAULT_TELECRYSTAL_AMOUNT
diff --git a/code/game/objects/items/devices/uplink_random_lists.dm b/code/game/objects/items/devices/uplink_random_lists.dm
index de05f91013..89bfd5f004 100644
--- a/code/game/objects/items/devices/uplink_random_lists.dm
+++ b/code/game/objects/items/devices/uplink_random_lists.dm
@@ -34,11 +34,11 @@ var/datum/uplink_random_selection/all_uplink_selection = new/datum/uplink_random
if(!prob(RI.keep_probability))
continue
var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item]
- if(I.cost(telecrystals, U) > telecrystals)
+ if(I.cost(U) > telecrystals)
continue
if(bought_items && (I in bought_items) && !prob(RI.reselect_probability))
continue
- if(U && !I.can_buy(U))
+ if(U && !I.can_buy(U, telecrystals))
continue
return I
diff --git a/code/game/objects/items/pizza_voucher_vr.dm b/code/game/objects/items/pizza_voucher_vr.dm
index 1d48bc9cda..a4dad4720f 100644
--- a/code/game/objects/items/pizza_voucher_vr.dm
+++ b/code/game/objects/items/pizza_voucher_vr.dm
@@ -8,10 +8,11 @@
w_class = ITEMSIZE_SMALL
/obj/item/pizzavoucher/New()
+ ..()
var/list/descstrings = list("24/7 PIZZA PIE HEAVEN",
"WE ALWAYS DELIVER!",
"24-HOUR PIZZA PIE POWER!",
- "TOMATO SAUCE, CHEESE, WE'VE BOTH BOTH OF THESE!",
+ "TOMATO SAUCE, CHEESE, WE'VE BOTH OF THESE!",
"COOKED WITH LOVE INSIDE A BIG OVEN!",
"WHEN YOU NEED A SLICE OF JOY IN YOUR LIFE!",
"WHEN YOU NEED A DISK OF OVEN BAKED BLISS!",
diff --git a/code/game/objects/items/stacks/fifty_spawner.dm b/code/game/objects/items/stacks/fifty_spawner.dm
index 81dfce9691..e3ba667703 100644
--- a/code/game/objects/items/stacks/fifty_spawner.dm
+++ b/code/game/objects/items/stacks/fifty_spawner.dm
@@ -7,15 +7,12 @@
var/obj/item/stack/type_to_spawn = null
/obj/fiftyspawner/Initialize()
- ..() //We're not returning . because we're going to ask to be deleted.
-
+ ..()
var/turf/T = get_turf(src)
- var/obj/item/stack/M = new type_to_spawn(T)
+ var/obj/structure/closet/C = locate() in T
+ var/obj/item/stack/M = new type_to_spawn(C || T)
M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty
M.update_icon() // Some stacks have different sprites depending on how full they are.
- var/obj/structure/closet/C = locate() in T
- if(C)
- C.contents += M
return INITIALIZE_HINT_QDEL //Bye!
/obj/fiftyspawner/rods
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index 6ffa7100ca..9844ae1cba 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -14,6 +14,8 @@
max_amount = 60
attack_verb = list("hit", "bludgeoned", "whacked")
+ color = "#666666"
+
/obj/item/stack/rods/cyborg
name = "metal rod synthesizer"
desc = "A device that makes metal rods."
@@ -24,8 +26,8 @@
stacktype = /obj/item/stack/rods
no_variants = TRUE
-/obj/item/stack/rods/New()
- ..()
+/obj/item/stack/rods/Initialize()
+ . = ..()
recipes = rods_recipes
update_icon()
diff --git a/code/game/objects/items/stacks/sandbags.dm b/code/game/objects/items/stacks/sandbags.dm
index c4e755c485..6eff93bfc5 100644
--- a/code/game/objects/items/stacks/sandbags.dm
+++ b/code/game/objects/items/stacks/sandbags.dm
@@ -32,19 +32,15 @@
bag_material = MAT_SYNCLOTH
-/obj/item/stack/sandbags/New(var/newloc, var/amt, var/bag_mat)
- ..()
+/obj/item/stack/sandbags/Initialize(var/ml, var/amt, var/bag_mat)
+ . = ..(ml, amt)
recipes = sandbag_recipes
update_icon()
-
if(bag_mat)
bag_material = bag_mat
-
var/datum/material/M = get_material_by_name("[bag_material]")
if(!M)
- qdel(src)
- return
-
+ return INITIALIZE_HINT_QDEL
color = M.icon_colour
/obj/item/stack/sandbags/update_icon()
@@ -136,17 +132,13 @@ var/global/list/datum/stack_recipe/sandbag_recipes = list( \
var/bag_material = "cloth"
-/obj/item/stack/emptysandbag/New(var/newloc, var/amt, var/bag_mat)
- ..(newloc, amt)
-
+/obj/item/stack/emptysandbag/Initialize(var/ml, var/amt, var/bag_mat)
+ . = ..(ml, amt)
if(bag_mat)
bag_material = bag_mat
-
var/datum/material/M = get_material_by_name("[bag_material]")
if(!M)
- qdel(src)
- return
-
+ return INITIALIZE_HINT_QDEL
color = M.icon_colour
/obj/item/stack/emptysandbag/attack_self(var/mob/user)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index d42d6c0e56..f4b52f07aa 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -29,14 +29,13 @@
var/pass_color = FALSE // Will the item pass its own color var to the created item? Dyed cloth, wood, etc.
var/strict_color_stacking = FALSE // Will the stack merge with other stacks that are different colors? (Dyed cloth, wood, etc)
-/obj/item/stack/New(var/loc, var/amount=null)
- ..()
- if (!stacktype)
+/obj/item/stack/Initialize(var/ml, var/amount)
+ . = ..()
+ if(!stacktype)
stacktype = type
- if (amount)
+ if(amount)
src.amount = amount
update_icon()
- return
/obj/item/stack/Destroy()
if(uses_charge)
@@ -170,8 +169,37 @@
var/atom/O
if(recipe.use_material)
O = new recipe.result_type(user.loc, recipe.use_material)
+
+ if(istype(O, /obj))
+ var/obj/Ob = O
+
+ if(LAZYLEN(Ob.matter)) // Law of equivalent exchange.
+ Ob.matter.Cut()
+
+ else
+ Ob.matter = list()
+
+ var/mattermult = istype(Ob, /obj/item) ? min(2000, 400 * Ob.w_class) : 2000
+
+ Ob.matter[recipe.use_material] = mattermult / produced * required
+
else
O = new recipe.result_type(user.loc)
+
+ if(recipe.matter_material)
+ if(istype(O, /obj))
+ var/obj/Ob = O
+
+ if(LAZYLEN(Ob.matter)) // Law of equivalent exchange.
+ Ob.matter.Cut()
+
+ else
+ Ob.matter = list()
+
+ var/mattermult = istype(Ob, /obj/item) ? min(2000, 400 * Ob.w_class) : 2000
+
+ Ob.matter[recipe.use_material] = mattermult / produced * required
+
O.set_dir(user.dir)
O.add_fingerprint(user)
@@ -379,8 +407,9 @@
var/on_floor = 0
var/use_material
var/pass_color
+ var/matter_material // Material type used for recycling. Default, uses use_material. For non-material-based objects however, matter_material is needed.
-/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, supplied_material = null, pass_stack_color)
+/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, supplied_material = null, pass_stack_color, recycle_material = null)
src.title = title
src.result_type = result_type
src.req_amount = req_amount
@@ -392,6 +421,12 @@
src.use_material = supplied_material
src.pass_color = pass_stack_color
+ if(!recycle_material && src.use_material)
+ src.matter_material = src.use_material
+
+ else if(recycle_material)
+ src.matter_material = recycle_material
+
/*
* Recipe list datum
*/
diff --git a/code/game/objects/items/stacks/tickets.dm b/code/game/objects/items/stacks/tickets.dm
index 1d9cbf047e..6681934f7c 100644
--- a/code/game/objects/items/stacks/tickets.dm
+++ b/code/game/objects/items/stacks/tickets.dm
@@ -7,7 +7,7 @@
w_class = ITEMSIZE_TINY
max_amount = 30
-/obj/item/stack/arcadeticket/New(loc, amount = null)
+/obj/item/stack/arcadeticket/Initialize()
. = ..()
update_icon()
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 609400ca36..145a67816e 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -25,8 +25,8 @@
var/perunit = SHEET_MATERIAL_AMOUNT
var/apply_colour //CHOMPEDIT: End
-/obj/item/stack/tile/New()
- ..()
+/obj/item/stack/tile/Initialize()
+ . = ..()
randpixel_xy()
/*
diff --git a/code/game/objects/items/toys/toys.dm b/code/game/objects/items/toys/toys.dm
index 4391901918..ce75684b0d 100644
--- a/code/game/objects/items/toys/toys.dm
+++ b/code/game/objects/items/toys/toys.dm
@@ -419,6 +419,7 @@
desc = "A \"Space Life\" brand... wait, what the hell is this thing?"
icon = 'icons/obj/toy.dmi'
icon_state = "nuketoy"
+ w_class = ITEMSIZE_SMALL //chompstation add because WHY ARE THEY SO BIG
var/cooldown = 0
var/toysay = "What the fuck did you do?"
drop_sound = 'sound/items/drop/accessory.ogg'
diff --git a/code/game/objects/items/toys/toys_ch.dm b/code/game/objects/items/toys/toys_ch.dm
index 869c4cb180..8fe4f946b9 100644
--- a/code/game/objects/items/toys/toys_ch.dm
+++ b/code/game/objects/items/toys/toys_ch.dm
@@ -3,4 +3,17 @@
desc = "A \"Space Life\" brand bounty hunter action figure."
icon = 'icons/obj/toy_ch.dmi'
icon_state = "hunter"
- toysay = "The last greytide is in captivity. The station is at peace."
\ No newline at end of file
+ toysay = "The last greytide is in captivity. The station is at peace."
+
+/obj/item/toy/sif
+ name = "Sif planet model"
+ desc = "A \"Space Life\" brand planet model of Sif, it's oddly cold to the touch."
+ icon = 'icons/obj/toy_ch.dmi'
+ icon_state = "sif"
+
+/obj/item/toy/figure/station
+ name = "NLS Southern Cross action figure"
+ desc = "A \"Space Life\" brand figure of the NLS Southern Cross, the station you work in."
+ icon = 'icons/obj/toy_ch.dmi'
+ icon_state = "station"
+ toysay = "Attention! Alert level elevated to blue."
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/RPD_vr.dm b/code/game/objects/items/weapons/RPD_vr.dm
index d4650eb16a..d15236e7e7 100644
--- a/code/game/objects/items/weapons/RPD_vr.dm
+++ b/code/game/objects/items/weapons/RPD_vr.dm
@@ -24,6 +24,7 @@
throw_range = 5
w_class = ITEMSIZE_NORMAL
matter = list(MAT_STEEL = 50000, MAT_GLASS = 25000)
+ origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 2)
var/datum/effect/effect/system/spark_spread/spark_system
var/p_dir = NORTH // Next pipe will be built with this dir
var/p_flipped = FALSE // If the next pipe should be built flipped
diff --git a/code/game/objects/items/weapons/canes.dm b/code/game/objects/items/weapons/canes.dm
index 5b7f346684..48bf6454ca 100644
--- a/code/game/objects/items/weapons/canes.dm
+++ b/code/game/objects/items/weapons/canes.dm
@@ -22,11 +22,12 @@
/obj/item/weapon/cane/concealed
var/concealed_blade
-/obj/item/weapon/cane/concealed/New()
- ..()
+/obj/item/weapon/cane/concealed/Initialize()
+ . = ..()
var/obj/item/weapon/material/butterfly/switchblade/temp_blade = new(src)
concealed_blade = temp_blade
- temp_blade.attack_self()
+ temp_blade.active = TRUE
+ temp_blade.update_force()
/obj/item/weapon/cane/concealed/attack_self(var/mob/user)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index 2ac0098203..ab91eca500 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -484,34 +484,70 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/smokable/cigarette/joint
name = "joint"
- desc = "This probably shouldn't ever show up."
+ desc = "A joint lovingly rolled and crafted with care. Blaze it."
icon_state = "joint"
+ max_smoketime = 400
+ smoketime = 400
+ chem_volume = 25
+
+/obj/item/clothing/mask/smokable/cigarette/joint/blunt
+ name = "blunt"
+ desc = "A blunt lovingly rolled and crafted with care. Blaze it."
+ icon_state = "cigar"
max_smoketime = 500
smoketime = 500
- nicotine_amt = 0
+ nicotine_amt = 4
+ chem_volume = 45
-/obj/item/weapon/rollingpaper
+/obj/item/weapon/reagent_containers/rollingpaper
name = "rolling paper"
desc = "A small, thin piece of easily flammable paper, commonly used for rolling and smoking various dried plants."
description_fluff = "The legalization of certain substances propelled the sale of rolling papers through the roof. Now almost every Trans-stellar produces a variety, often of questionable quality."
icon = 'icons/obj/cigarettes.dmi'
icon_state = "cig paper"
+ volume = 25
+ var/obj/item/clothing/mask/smokable/cigarette/crafted_type = /obj/item/clothing/mask/smokable/cigarette/joint
-/obj/item/weapon/rollingpaper/attackby(obj/item/weapon/W as obj, mob/user as mob)
+/obj/item/weapon/reagent_containers/rollingpaper/blunt
+ name = "blunt wrap"
+ desc = "A small piece of easily flammable paper similar to that which encases cigars. It's made out of tobacco, bigger than a standard rolling paper, and will last longer."
+ icon_state = "blunt paper"
+ volume = 45
+ crafted_type = /obj/item/clothing/mask/smokable/cigarette/joint/blunt
+
+/obj/item/weapon/reagent_containers/rollingpaper/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/reagent_containers/food/snacks))
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = W
- if (!G.dry)
- to_chat(user, "[G] must be dried before you roll it into [src].")
+ if (!G.dry) //This prevents people from just stuffing cheeseburgers into their joint
+ to_chat(user, "[G.name] must be dried before you add it to [src].")
return
- var/obj/item/clothing/mask/smokable/cigarette/joint/J = new /obj/item/clothing/mask/smokable/cigarette/joint(user.loc)
- to_chat(usr, "You roll the [G.name] into a joint!")
- J.add_fingerprint(user)
+ if (G.reagents.total_volume + src.reagents.total_volume > src.reagents.maximum_volume) //Check that we don't have too much already in the paper before adding things
+ to_chat(user, "The [src] is too full to add [G.name].")
+ return
+ if (src.reagents.total_volume == 0)
+ if (istype(src, /obj/item/weapon/reagent_containers/rollingpaper/blunt)) //update the icon if this is the first thing we're adding to the paper
+ src.icon_state = "blunt_full"
+ else
+ src.icon_state = "paper_full"
+ to_chat(user, "You add the [G.name] to the [src.name].")
+ src.add_fingerprint(user)
if(G.reagents)
- G.reagents.trans_to_obj(J, G.reagents.total_volume)
- J.name = "[G.name] joint"
- J.desc = "A joint lovingly rolled and filled with [G.name]. Blaze it."
+ G.reagents.trans_to_obj(src, G.reagents.total_volume) //adds the reagents from the plant into the paper
+ user.drop_from_inventory(G)
qdel(G)
- qdel(src)
+
+/obj/item/weapon/reagent_containers/rollingpaper/attack_self(mob/living/user)
+ if(!src.reagents) //don't roll an empty joint
+ to_chat(user, "There is nothing in [src]. Add something to it first.")
+ return
+ var/obj/item/clothing/mask/smokable/cigarette/J = new crafted_type()
+ to_chat(user,"You roll the [src] into a blunt!")
+ J.add_fingerprint(user)
+ if(src.reagents)
+ src.reagents.trans_to_obj(J, src.reagents.total_volume)
+ user.drop_from_inventory(src)
+ user.put_in_hands(J)
+ qdel(src)
/////////
//ZIPPO//
diff --git a/code/game/objects/items/weapons/circuitboards/circuitboard.dm b/code/game/objects/items/weapons/circuitboards/circuitboard.dm
index 8b913eaf45..c8a3a672a7 100644
--- a/code/game/objects/items/weapons/circuitboards/circuitboard.dm
+++ b/code/game/objects/items/weapons/circuitboards/circuitboard.dm
@@ -23,6 +23,8 @@
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
+
//Called when the circuitboard is used to contruct a new machine.
/obj/item/weapon/circuitboard/proc/construct(var/obj/machinery/M)
if(istype(M, build_path))
diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm
index d91a25b631..bd1d057d37 100644
--- a/code/game/objects/items/weapons/circuitboards/frame.dm
+++ b/code/game/objects/items/weapons/circuitboards/frame.dm
@@ -10,37 +10,37 @@
name = T_BOARD("guestpass console")
build_path = /obj/machinery/computer/guestpass
board_type = new /datum/frame/frame_types/guest_pass_console
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/status_display
name = T_BOARD("status display")
build_path = /obj/machinery/status_display
board_type = new /datum/frame/frame_types/display
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/ai_status_display
name = T_BOARD("ai status display")
build_path = /obj/machinery/ai_status_display
board_type = new /datum/frame/frame_types/display
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/newscaster
name = T_BOARD("newscaster")
build_path = /obj/machinery/newscaster
board_type = new /datum/frame/frame_types/newscaster
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/atm
name = T_BOARD("atm")
build_path = /obj/machinery/atm
board_type = new /datum/frame/frame_types/atm
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/request
name = T_BOARD("request console")
build_path = /obj/machinery/requests_console
board_type = new /datum/frame/frame_types/supply_request_console
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
//Alarm
@@ -48,25 +48,25 @@
name = T_BOARD("fire alarm")
build_path = /obj/machinery/firealarm
board_type = new /datum/frame/frame_types/fire_alarm
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/airalarm
name = T_BOARD("air alarm")
build_path = /obj/machinery/alarm
board_type = new /datum/frame/frame_types/air_alarm
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/intercom
name = T_BOARD("intercom")
build_path = /obj/item/device/radio/intercom
board_type = new /datum/frame/frame_types/intercom
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/keycard_auth
name = T_BOARD("keycard authenticator")
build_path = /obj/machinery/keycard_auth
board_type = new /datum/frame/frame_types/keycard_authenticator
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
//Computer
@@ -74,7 +74,7 @@
name = T_BOARD("holopad")
build_path = /obj/machinery/hologram/holopad
board_type = new /datum/frame/frame_types/holopad
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/scanner_console
name = T_BOARD("body scanner console")
@@ -94,7 +94,7 @@
name = T_BOARD("photocopier")
build_path = /obj/machinery/photocopier
board_type = new /datum/frame/frame_types/photocopier
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/motor = 1,
@@ -105,7 +105,7 @@
name = T_BOARD("fax")
build_path = /obj/machinery/photocopier/faxmachine
board_type = new /datum/frame/frame_types/fax
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/motor = 1,
@@ -116,6 +116,7 @@
name = T_BOARD("conveyor")
build_path = /obj/machinery/conveyor
board_type = new /datum/frame/frame_types/conveyor
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/gear = 2,
/obj/item/weapon/stock_parts/motor = 2,
@@ -125,6 +126,7 @@
name = T_BOARD("recharger")
build_path = /obj/machinery/recharger
board_type = new /datum/frame/frame_types/recharger
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/stack/cable_coil = 5)
@@ -138,6 +140,7 @@
name = T_BOARD("heavy-duty cell charger")
build_path = /obj/machinery/cell_charger
board_type = new /datum/frame/frame_types/cell_charger
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/stack/cable_coil = 5)
@@ -146,7 +149,7 @@
name = T_BOARD("washing machine")
build_path = /obj/machinery/washing_machine
board_type = new /datum/frame/frame_types/washing_machine
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/motor = 1,
/obj/item/weapon/stock_parts/gear = 2)
@@ -155,6 +158,7 @@
name = T_BOARD("reagent grinder")
build_path = /obj/machinery/reagentgrinder
board_type = new /datum/frame/frame_types/grinder
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/motor = 1,
/obj/item/weapon/stock_parts/gear = 1,
@@ -163,6 +167,7 @@
/obj/item/weapon/circuitboard/distiller
build_path = /obj/machinery/portable_atmospherics/powered/reagent_distillery
board_type = new /datum/frame/frame_types/reagent_distillery
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/weapon/stock_parts/micro_laser = 1,
@@ -173,6 +178,7 @@
name = T_BOARD("teleporter hub")
build_path = /obj/machinery/teleport/hub
board_type = new /datum/frame/frame_types/machine //YWEdit makes buildable
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
// origin_tech = list(TECH_DATA = 2, TECH_BLUESPACE = 4)
//CHOMPedit Balance
req_components = list(
@@ -187,6 +193,7 @@
name = T_BOARD("teleporter station")
build_path = /obj/machinery/teleport/station
board_type = new /datum/frame/frame_types/machine //YWEdit makes buildable
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
// origin_tech = list(TECH_DATA = 2, TECH_BLUESPACE = 3)
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
@@ -198,6 +205,7 @@
build_path = /obj/machinery/bodyscanner
board_type = new /datum/frame/frame_types/medical_pod
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 3,
/obj/item/stack/material/glass/reinforced = 2)
@@ -206,6 +214,7 @@
name = T_BOARD("sleeper")
build_path = /obj/machinery/sleeper
board_type = new /datum/frame/frame_types/medical_pod
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
req_components = list(
/obj/item/weapon/stock_parts/manipulator = 1,
@@ -218,6 +227,7 @@
name = T_BOARD("VR sleeper")
build_path = /obj/machinery/vr_sleeper
board_type = new /datum/frame/frame_types/medical_pod
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 1,
@@ -227,6 +237,7 @@
name = T_BOARD("dna analyzer")
build_path = /obj/machinery/dnaforensics
board_type = new /datum/frame/frame_types/dna_analyzer
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2, TECH_DATA = 2)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 2,
@@ -237,6 +248,7 @@
name = T_BOARD("mass driver")
build_path = /obj/machinery/mass_driver
board_type = new /datum/frame/frame_types/mass_driver
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
req_components = list(
/obj/item/weapon/stock_parts/gear = 2,
/obj/item/weapon/stock_parts/motor = 2,
diff --git a/code/game/objects/items/weapons/circuitboards/mecha.dm b/code/game/objects/items/weapons/circuitboards/mecha.dm
index 777146f385..132cf65de6 100644
--- a/code/game/objects/items/weapons/circuitboards/mecha.dm
+++ b/code/game/objects/items/weapons/circuitboards/mecha.dm
@@ -8,6 +8,7 @@
icon = 'icons/obj/module.dmi'
icon_state = "std_mod"
board_type = "other"
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/mecha/ripley
origin_tech = list(TECH_DATA = 3)
diff --git a/code/game/objects/items/weapons/ecigs.dm b/code/game/objects/items/weapons/ecigs.dm
index 18e6062dba..5e26bd6e10 100644
--- a/code/game/objects/items/weapons/ecigs.dm
+++ b/code/game/objects/items/weapons/ecigs.dm
@@ -13,6 +13,7 @@
var/brightness_on = 1
chem_volume = 0 //ecig has no storage on its own but has reagent container created by parent obj
item_state = "ecigoff"
+ is_pipe = TRUE //to avoid a runtime in examine()
var/icon_off
var/icon_empty
var/ecig_colors = list(null, COLOR_DARK_GRAY, COLOR_RED_GRAY, COLOR_BLUE_GRAY, COLOR_GREEN_GRAY, COLOR_PURPLE_GRAY)
@@ -21,6 +22,28 @@
..()
ec_cartridge = new cartridge_type(src)
+/obj/item/clothing/mask/smokable/ecig/examine(mob/user)
+ . = ..()
+
+ if(active)
+ . += "It is turned on."
+ else
+ . += "It is turned off."
+ if(Adjacent(user))
+ if(ec_cartridge)
+ if(!ec_cartridge.reagents?.total_volume)
+ . += "Its cartridge is empty!"
+ else if (ec_cartridge.reagents.total_volume <= ec_cartridge.volume * 0.25)
+ . += "Its cartridge is almost empty!"
+ else if (ec_cartridge.reagents.total_volume <= ec_cartridge.volume * 0.66)
+ . += "Its cartridge is half full!"
+ else if (ec_cartridge.reagents.total_volume <= ec_cartridge.volume * 0.90)
+ . += "Its cartridge is almost full!"
+ else
+ . += "Its cartridge is full!"
+ else
+ . += "It has no cartridge."
+
/obj/item/clothing/mask/smokable/ecig/simple
name = "simple electronic cigarette"
desc = "A cheap Lucky 1337 electronic cigarette, styled like a traditional cigarette."
@@ -56,6 +79,7 @@
var/mob/living/carbon/human/C = loc
if (src == C.wear_mask && C.check_has_mouth()) // if it's in the human/monkey mouth, transfer reagents to the mob
if (!active || !ec_cartridge || !ec_cartridge.reagents.total_volume)//no cartridge
+ to_chat(C, "[src] turns off. ")
active=0//autodisable the cigarette
STOP_PROCESSING(SSobj, src)
update_icon()
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index f828b97b23..cd48a4a78a 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -77,7 +77,7 @@
/obj/item/weapon/lipstick/random,
/obj/item/weapon/grenade/smokebomb,
/obj/item/weapon/corncob,
- /obj/item/weapon/contraband/poster,
+ /obj/item/weapon/contraband/poster/custom,
/obj/item/weapon/book/manual/barman_recipes,
/obj/item/weapon/book/manual/chef_recipes,
/obj/item/weapon/bikehorn,
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 924d753c28..0f7405096d 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -19,7 +19,7 @@
var/cuff_sound = 'sound/weapons/handcuffs.ogg'
var/cuff_type = "handcuffs"
var/use_time = 30
- sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/handcuffs.dmi')
+ sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/handcuffs.dmi')
/obj/item/weapon/handcuffs/get_worn_icon_state(var/slot_name)
if(slot_name == slot_handcuffed_str)
@@ -214,7 +214,7 @@ var/last_chew = 0
origin_tech = list(TECH_MATERIAL = 1)
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
cuff_type = "legcuffs"
- sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/handcuffs.dmi')
+ sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/handcuffs.dmi')
elastic = 0
cuff_sound = 'sound/weapons/handcuffs.ogg' //This shold work for now.
diff --git a/code/game/objects/items/weapons/id cards/cards.dm b/code/game/objects/items/weapons/id cards/cards.dm
index fa56f6ccc1..e62268c2c1 100644
--- a/code/game/objects/items/weapons/id cards/cards.dm
+++ b/code/game/objects/items/weapons/id cards/cards.dm
@@ -13,19 +13,48 @@
*/
/obj/item/weapon/card
name = "card"
- desc = "Does card things."
- icon = 'icons/obj/card.dmi'
+ desc = "A tiny plaque of plastic. Does card things."
+ icon = 'icons/obj/card_new.dmi'
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
var/associated_account_number = 0
+ var/list/initial_sprite_stack = list("")
+ var/base_icon = 'icons/obj/card_new.dmi'
+ var/list/sprite_stack
+
var/list/files = list( )
drop_sound = 'sound/items/drop/card.ogg'
pickup_sound = 'sound/items/pickup/card.ogg'
+/obj/item/weapon/card/New()
+ . = ..()
+ reset_icon()
+
+/obj/item/weapon/card/proc/reset_icon()
+ sprite_stack = initial_sprite_stack
+ update_icon()
+
+/obj/item/weapon/card/update_icon()
+ if(!sprite_stack || !istype(sprite_stack) || sprite_stack == list(""))
+ icon = base_icon
+ icon_state = initial(icon_state)
+
+ var/icon/I = null
+ for(var/iconstate in sprite_stack)
+ if(!iconstate)
+ iconstate = icon_state
+ if(I)
+ var/icon/IC = new(base_icon, iconstate)
+ I.Blend(IC, ICON_OVERLAY)
+ else
+ I = new/icon(base_icon, iconstate)
+ if(I)
+ icon = I
+
/obj/item/weapon/card/data
- name = "data disk"
- desc = "A disk of data."
+ name = "data card"
+ desc = "A solid-state storage card, used to back up or transfer information. What knowledge could it contain?"
icon_state = "data"
var/function = "storage"
var/data = "null"
@@ -35,20 +64,20 @@
pickup_sound = 'sound/items/pickup/disk.ogg'
/obj/item/weapon/card/data/verb/label(t as text)
- set name = "Label Disk"
+ set name = "Label Card"
set category = "Object"
set src in usr
if (t)
- src.name = text("data disk- '[]'", t)
+ src.name = text("data card- '[]'", t)
else
- src.name = "data disk"
+ src.name = "data card"
src.add_fingerprint(usr)
return
/obj/item/weapon/card/data/clown
name = "\proper the coordinates to clown planet"
- icon_state = "data"
+ icon_state = "rainbow"
item_state = "card-id"
level = 2
desc = "This card contains coordinates to the fabled Clown Planet. Handle with care."
@@ -62,7 +91,7 @@
/obj/item/weapon/card/emag_broken
desc = "It's a card with a magnetic strip attached to some circuitry. It looks too busted to be used for anything but salvage."
name = "broken cryptographic sequencer"
- icon_state = "emag"
+ icon_state = "emag-spent"
item_state = "card-id"
origin_tech = list(TECH_MAGNET = 2, TECH_ILLEGAL = 2)
@@ -107,4 +136,4 @@
uses += T.amount/2 //Gives 5 uses per 10 TC
uses = CEILING(uses, 1) //Ensures no decimal uses nonsense, rounds up to be nice
to_chat(usr, "You add \the [O] to \the [src]. Increasing the uses of \the [src] to [uses].")
- qdel(O)
\ No newline at end of file
+ qdel(O)
diff --git a/code/game/objects/items/weapons/id cards/cards_vr.dm b/code/game/objects/items/weapons/id cards/cards_vr.dm
new file mode 100644
index 0000000000..c7abd117d6
--- /dev/null
+++ b/code/game/objects/items/weapons/id cards/cards_vr.dm
@@ -0,0 +1,10 @@
+/obj/item/weapon/card/emag/examine(mob/user)
+ . = ..()
+ . += "[uses] uses remaining."
+
+/obj/item/weapon/card/emag/used
+ uses = 1
+
+/obj/item/weapon/card/emag/used/Initialize()
+ . = ..()
+ uses = rand(1, 5)
diff --git a/code/game/objects/items/weapons/id cards/id_stacks.dm b/code/game/objects/items/weapons/id cards/id_stacks.dm
new file mode 100644
index 0000000000..495697da7b
--- /dev/null
+++ b/code/game/objects/items/weapons/id cards/id_stacks.dm
@@ -0,0 +1,148 @@
+// This is a defines file for card sprite stacks. If a new card set comes in, this file can just be disabled and a new one made to match the new sprites.
+// Generally, if the icon file is card_xxx.dmi, this filename should be sprite_stacks_xxx.dm
+// Please make sure that only the relevant sprite_stacks_xxx.file is included, if more are made.
+
+/obj/item/weapon/card
+ icon = 'icons/obj/card_new.dmi' // These are redefined here so that changing sprites is as easy as clicking the checkbox.
+ base_icon = 'icons/obj/card_new.dmi'
+
+ // New sprite stacks can be defined here. You could theoretically change icon-states as well but right now this file compiles before station_ids.dm so those wouldn't be affected.
+
+/*
+/obj/item/weapon/card/id/generic
+ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-silhouette", "clip")
+
+// CENTCOM
+/obj/item/weapon/card/id/centcom
+ initial_sprite_stack = list("base-stamp", "top-blue", "stamp-n", "pips-gold")
+
+/obj/item/weapon/card/id/centcom/vip
+ initial_sprite_stack = list("base-stamp-gold", "top-blue", "stamp-n", "pips-gold")
+
+/obj/item/weapon/card/id/centcom/ERT
+ initial_sprite_stack = list("base-stamp", "top-blue", "stamp-n", "pips-red", "stripe-red")
+
+// GENERIC COMMAND
+/obj/item/weapon/card/id/silver
+ initial_sprite_stack = list("base-stamp-silver", "top-mime", "stamp-n-generic")
+
+/obj/item/weapon/card/id/silver/secretary
+ initial_sprite_stack = list("base-stamp", "top-blue", "stamp-n")
+
+/obj/item/weapon/card/id/silver/hop
+ initial_sprite_stack = list("base-stamp", "top-blue", "stamp-n", "stripe-white")
+
+// MEDICAL
+/obj/item/weapon/card/id/medical
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n")
+
+/obj/item/weapon/card/id/medical/chemist
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "pips-orange")
+
+/obj/item/weapon/card/id/medical/geneticist
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "pips-purple")
+
+/obj/item/weapon/card/id/medical/psych
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "pips-purple")
+
+/obj/item/weapon/card/id/medical/emt
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "pips-blue")
+
+/obj/item/weapon/card/id/medical/head
+ initial_sprite_stack = list("base-stamp-silver", "top-medblu", "stamp-n", "stripe-gold")
+
+/obj/item/weapon/card/id/medical/sar
+ initial_sprite_stack = list("base-stamp", "top-darkgreen", "stamp-n", "pips-medblu")
+
+// SECURITY
+/obj/item/weapon/card/id/security
+ initial_sprite_stack = list("base-stamp", "top-red", "stamp-n")
+
+/obj/item/weapon/card/id/security/detective
+ initial_sprite_stack = list("base-stamp", "top-red", "stamp-n", "pips-brown")
+
+/obj/item/weapon/card/id/security/warden
+ initial_sprite_stack = list("base-stamp", "top-red", "stamp-n", "pips-white")
+
+/obj/item/weapon/card/id/security/head
+ initial_sprite_stack = list("base-stamp-silver", "top-red", "stamp-n", "stripe-gold")
+
+// ENGINEERING
+/obj/item/weapon/card/id/engineering
+ initial_sprite_stack = list("base-stamp", "top-orange", "stamp-n")
+
+/obj/item/weapon/card/id/engineering/atmos
+ initial_sprite_stack = list("base-stamp", "top-orange", "pips-medblu", "stamp-n")
+
+/obj/item/weapon/card/id/engineering/head
+ initial_sprite_stack = list("base-stamp-silver", "top-orange", "stamp-n", "stripe-gold")
+
+// SCIENCE
+/obj/item/weapon/card/id/science
+ initial_sprite_stack = list("base-stamp", "top-purple", "stamp-n")
+
+/obj/item/weapon/card/id/science/roboticist
+ initial_sprite_stack = list("base-stamp", "top-purple", "stamp-n", "pips-orange")
+
+/obj/item/weapon/card/id/science/explorer
+ initial_sprite_stack = list("base-stamp", "top-darkgreen", "stamp-n")
+
+/obj/item/weapon/card/id/science/head
+ initial_sprite_stack = list("base-stamp-silver", "top-purple", "stamp-n", "stripe-gold")
+
+/obj/item/weapon/card/id/science/head/pathfinder
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "dept-exploration", "stamp-n", "pips-gold")
+
+// CARGO
+/obj/item/weapon/card/id/cargo
+ initial_sprite_stack = list("base-stamp", "top-brown", "stamp-n")
+
+/obj/item/weapon/card/id/cargo/miner
+ initial_sprite_stack = list("base-stamp", "top-brown", "stamp-n", "pips-purple")
+
+/obj/item/weapon/card/id/cargo/head
+ initial_sprite_stack = list("base-stamp-silver", "top-brown", "stamp-n", "pips-gold")
+
+// CIVLIAN
+/obj/item/weapon/card/id/civilian
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n")
+
+/obj/item/weapon/card/id/civilian/chaplain
+ initial_sprite_stack = list("base-stamp-silver", "top-dark", "stamp-cross", "pips-white")
+
+/obj/item/weapon/card/id/civilian/internal_affairs
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n")
+
+/obj/item/weapon/card/id/civilian/botanist
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n", "pips-brown")
+
+/obj/item/weapon/card/id/civilian/bartender
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n", "pips-dark")
+
+/obj/item/weapon/card/id/civilian/chef
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n", "pips-white")
+
+/obj/item/weapon/card/id/civilian/janitor
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n", "pips-purple")
+
+/obj/item/weapon/card/id/civilian/journalist
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n")
+
+/obj/item/weapon/card/id/civilian/clown
+ initial_sprite_stack = list("base-stamp", "top-rainbow", "stamp-n")
+
+/obj/item/weapon/card/id/civilian/mime
+ initial_sprite_stack = list("base-stamp", "top-white", "stamp-n", "stripe-black")
+
+/obj/item/weapon/card/id/civilian/pilot
+ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n", "pips-blue")
+
+/obj/item/weapon/card/id/civilian/head
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "stamp-n", "stripe-white")
+
+/obj/item/weapon/card/id/syndicate
+ initial_sprite_stack = list("base-stamp-dark", "top-syndicate", "stamp-s")
+
+/obj/item/weapon/card/id/syndicate/officer
+ initial_sprite_stack = list("base-stamp-dark", "top-syndicate", "stamp-s", "pips-gold", "stripe-gold")
+*/
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/id cards/id_stacks_vr.dm b/code/game/objects/items/weapons/id cards/id_stacks_vr.dm
new file mode 100644
index 0000000000..7627d66cf3
--- /dev/null
+++ b/code/game/objects/items/weapons/id cards/id_stacks_vr.dm
@@ -0,0 +1,216 @@
+/obj/item/weapon/card
+ icon = 'icons/obj/card_new_vr.dmi'
+ base_icon = 'icons/obj/card_new_vr.dmi'
+
+//IDs
+
+/obj/item/weapon/card/id
+ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n")
+
+/obj/item/weapon/card/id/generic
+ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-silhouette", "clip")
+
+//Central
+
+/obj/item/weapon/card/id/centcom
+ initial_sprite_stack = list("base-stamp-silver", "top-darkgreen", "stamp-n", "pips-gold", "stripe-gold")
+
+/obj/item/weapon/card/id/centcom/vip
+ initial_sprite_stack = list("base-stamp-gold", "top-darkgreen", "stamp-n", "pips-gold", "stripe-gold")
+
+//ERT
+
+/obj/item/weapon/card/id/centcom/ERT
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "stamp-n", "pips-red", "stripe-red")
+
+/obj/item/weapon/card/id/centcom/ERT/medic
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "stamp-n", "pips-medblu", "stripe-medblu")
+
+/obj/item/weapon/card/id/centcom/ERT/commander
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "stamp-n", "pips-gold", "stripe-gold")
+
+/obj/item/weapon/card/id/centcom/ERT/engineer
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "stamp-n", "pips-orange", "stripe-orange")
+
+/obj/item/weapon/card/id/centcom/ERT/janitor
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "stamp-n", "pips-purple", "stripe-purple")
+
+//Silver
+
+/obj/item/weapon/card/id/silver
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "stamp-n")
+
+/obj/item/weapon/card/id/silver/secretary
+ initial_sprite_stack = list("base-stamp", "top-blue", "stamp-n")
+
+/obj/item/weapon/card/id/silver/hop
+ initial_sprite_stack = list("base-stamp-silver", "top-blue", "stamp-n", "pips-gold")
+
+//Gold
+
+/obj/item/weapon/card/id/gold
+ initial_sprite_stack = list("base-stamp-gold", "top-blue", "stamp-n")
+
+/obj/item/weapon/card/id/gold/captain
+ initial_sprite_stack = list("base-stamp-gold", "top-blue", "stamp-n", "pips-gold")
+
+/obj/item/weapon/card/id/gold/captain/spare
+ initial_sprite_stack = list("base-stamp-gold", "top-gold", "stamp-n")
+
+//Medical
+
+/obj/item/weapon/card/id/medical
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n")
+
+/obj/item/weapon/card/id/medical/chemist
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "stripe-orange")
+
+/obj/item/weapon/card/id/medical/geneticist
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "stripe-purple")
+
+/obj/item/weapon/card/id/medical/psych
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "stripe-brown")
+
+/obj/item/weapon/card/id/medical/virologist
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "stripe-green")
+
+/obj/item/weapon/card/id/medical/emt
+ initial_sprite_stack = list("base-stamp", "top-medblu", "stamp-n", "stripe-blue")
+
+/obj/item/weapon/card/id/medical/head
+ initial_sprite_stack = list("base-stamp-silver", "top-medblu", "stamp-n", "pips-gold")
+
+//Security
+
+/obj/item/weapon/card/id/security
+ initial_sprite_stack = list("base-stamp", "top-red", "stamp-n")
+
+/obj/item/weapon/card/id/security/detective
+ initial_sprite_stack = list("base-stamp", "top-red", "stamp-n", "stripe-brown")
+
+/obj/item/weapon/card/id/security/warden
+ initial_sprite_stack = list("base-stamp", "top-red", "stamp-n", "stripe-white")
+
+/obj/item/weapon/card/id/security/head
+ initial_sprite_stack = list("base-stamp-silver", "top-red", "stamp-n", "pips-gold")
+
+//Engineering
+
+/obj/item/weapon/card/id/engineering
+ initial_sprite_stack = list("base-stamp", "top-orange", "stamp-n")
+
+/obj/item/weapon/card/id/engineering/atmos
+ initial_sprite_stack = list("base-stamp", "top-orange", "stripe-medblu", "stamp-n")
+
+/obj/item/weapon/card/id/engineering/head
+ initial_sprite_stack = list("base-stamp-silver", "top-orange", "stamp-n", "pips-gold")
+
+//Science
+
+/obj/item/weapon/card/id/science
+ initial_sprite_stack = list("base-stamp", "top-purple", "stamp-n")
+
+/obj/item/weapon/card/id/science/roboticist
+ initial_sprite_stack = list("base-stamp", "top-purple", "stamp-n", "stripe-brown")
+
+/obj/item/weapon/card/id/science/xenobiologist
+ initial_sprite_stack = list("base-stamp", "top-purple", "stamp-n", "stripe-orange")
+
+/obj/item/weapon/card/id/science/xenobotanist
+ initial_sprite_stack = list("base-stamp", "top-purple", "stamp-n", "stripe-green")
+
+/obj/item/weapon/card/id/science/head
+ initial_sprite_stack = list("base-stamp-silver", "top-purple", "stamp-n", "pips-gold")
+
+//Cargo
+
+/obj/item/weapon/card/id/cargo
+ initial_sprite_stack = list("base-stamp", "top-brown", "stamp-n")
+
+/obj/item/weapon/card/id/cargo/miner
+ initial_sprite_stack = list("base-stamp", "top-brown", "stamp-n", "stripe-purple")
+
+/obj/item/weapon/card/id/cargo/head
+ initial_sprite_stack = list("base-stamp-silver", "top-brown", "stamp-n", "pips-white")
+
+//Civilian
+
+/obj/item/weapon/card/id/civilian
+ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n")
+
+/obj/item/weapon/card/id/civilian/chaplain
+ initial_sprite_stack = list("base-stamp-dark", "top-dark", "stamp-cross", "stripe-white")
+
+/obj/item/weapon/card/id/civilian/journalist
+ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n", "stripe-red")
+
+/obj/item/weapon/card/id/civilian/pilot
+ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n", "stripe-pink")
+
+/obj/item/weapon/card/id/civilian/entertainer
+ initial_sprite_stack = list("base-stamp", "top-generic", "stamp-n", "stripe-brown")
+
+/obj/item/weapon/card/id/civilian/clown
+ initial_sprite_stack = list("base-stamp", "top-rainbow", "stamp-n")
+
+/obj/item/weapon/card/id/civilian/mime
+ initial_sprite_stack = list("base-stamp", "top-white", "stamp-n", "stripe-black")
+
+/obj/item/weapon/card/id/civilian/internal_affairs
+ initial_sprite_stack = list("base-stamp", "top-blue", "stamp-n", "stripe-black")
+
+//Service
+
+/obj/item/weapon/card/id/civilian/service
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n")
+
+/obj/item/weapon/card/id/civilian/service/botanist
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n", "stripe-darkgreen")
+
+/obj/item/weapon/card/id/civilian/service/bartender
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n", "stripe-black")
+
+/obj/item/weapon/card/id/civilian/service/chef
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n", "stripe-white")
+
+/obj/item/weapon/card/id/civilian/service/janitor
+ initial_sprite_stack = list("base-stamp", "top-green", "stamp-n", "stripe-purple")
+
+//Exploration
+
+/obj/item/weapon/card/id/exploration
+ initial_sprite_stack = list("base-stamp", "top-pink", "stamp-n")
+
+/obj/item/weapon/card/id/exploration/fm
+ initial_sprite_stack = list("base-stamp", "top-pink", "stamp-n", "stripe-medblu")
+
+/obj/item/weapon/card/id/exploration/head
+ initial_sprite_stack = list("base-stamp-silver", "top-pink", "stamp-n", "pips-white")
+
+//Talon
+
+/obj/item/weapon/card/id/talon
+ initial_sprite_stack = list("base-stamp-dark", "top-dark", "stamp-silhouette")
+
+/obj/item/weapon/card/id/talon/doctor
+ initial_sprite_stack = list("base-stamp-dark", "top-dark", "stamp-silhouette", "pips-medblu", "stripe-medblu")
+
+/obj/item/weapon/card/id/talon/engineer
+ initial_sprite_stack = list("base-stamp-dark", "top-dark", "stamp-silhouette", "pips-orange", "stripe-orange")
+
+/obj/item/weapon/card/id/talon/officer
+ initial_sprite_stack = list("base-stamp-dark", "top-dark", "stamp-silhouette", "pips-red", "stripe-red")
+
+/obj/item/weapon/card/id/talon/pilot
+ initial_sprite_stack = list("base-stamp-dark", "top-dark", "stamp-silhouette", "pips-purple", "stripe-purple")
+
+/obj/item/weapon/card/id/talon/captain
+ initial_sprite_stack = list("base-stamp-dark", "top-dark", "stamp-silhouette", "pips-gold", "stripe-gold")
+
+//Antags
+
+/obj/item/weapon/card/id/syndicate
+ initial_sprite_stack = list("base-stamp-dark", "top-syndicate", "stamp-s")
+
+/obj/item/weapon/card/id/syndicate/officer
+ initial_sprite_stack = list("base-stamp-dark", "top-syndicate", "stamp-s", "pips-gold", "stripe-gold")
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm
index ffa33472b6..5a8fe7448d 100644
--- a/code/game/objects/items/weapons/id cards/station_ids.dm
+++ b/code/game/objects/items/weapons/id cards/station_ids.dm
@@ -1,11 +1,11 @@
/obj/item/weapon/card/id
name = "identification card"
desc = "A card used to provide ID and determine access across the station."
- icon_state = "id"
+ icon_state = "generic-nt"
item_state = "card-id"
sprite_sheets = list(
- SPECIES_TESHARI = 'icons/mob/species/seromi/id.dmi'
+ SPECIES_TESHARI = 'icons/mob/species/teshari/id.dmi'
)
var/access = list()
@@ -127,13 +127,13 @@
/obj/item/weapon/card/id/silver
name = "identification card"
desc = "A silver card which shows honour and dedication."
- icon_state = "silver"
+ icon_state = "silver-id"
item_state = "silver_id"
/obj/item/weapon/card/id/gold
name = "identification card"
desc = "A golden card which shows power and might."
- icon_state = "gold"
+ icon_state = "gold-id"
item_state = "gold_id"
preserve_item = 1
@@ -144,23 +144,36 @@
/obj/item/weapon/card/id/gold/captain/spare
name = "\improper Site Manager's spare ID"
desc = "The spare ID of the High Lord himself."
+ icon_state = "gold-id-alternate"
registered_name = "Site Manager"
/obj/item/weapon/card/id/synthetic
name = "\improper Synthetic ID"
desc = "Access module for NanoTrasen Synthetics"
icon_state = "id-robot"
- item_state = "tdgreen"
+ item_state = "idgreen"
assignment = "Synthetic"
/obj/item/weapon/card/id/synthetic/Initialize()
. = ..()
access = get_all_station_access().Copy() + access_synth
+/obj/item/weapon/card/id/platform
+ name = "\improper Support Platform ID"
+ desc = "Access module for support platforms."
+ icon_state = "id-robot"
+ item_state = "tdgreen"
+ assignment = "Synthetic"
+ access = list(
+ access_synth, access_mining, access_mining_station, access_mining_office, access_research,
+ access_xenoarch, access_xenobiology, access_external_airlocks, access_robotics, access_tox,
+ access_tox_storage, access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot
+ )
+
/obj/item/weapon/card/id/centcom
name = "\improper CentCom. ID"
desc = "An ID straight from Central Command."
- icon_state = "nanotrasen"
+ icon_state = "cc-id"
registered_name = "Central Command"
assignment = "General"
@@ -175,7 +188,7 @@
/obj/item/weapon/card/id/centcom/ERT
name = "\improper Emergency Response Team ID"
assignment = "Emergency Response Team"
- icon_state = "centcom"
+ icon_state = "ert-id"
/obj/item/weapon/card/id/centcom/ERT/Initialize()
. = ..()
@@ -185,14 +198,13 @@
/obj/item/weapon/card/id/medical
name = "identification card"
desc = "A card issued to station medical staff."
- icon_state = "med"
+ icon_state = "medical-id"
primary_color = rgb(189,237,237)
secondary_color = rgb(223,255,255)
/obj/item/weapon/card/id/medical/head
name = "identification card"
desc = "A card which represents care and compassion."
- icon_state = "medGold"
primary_color = rgb(189,237,237)
secondary_color = rgb(255,223,127)
assignment = "Chief Medical Officer"
@@ -201,14 +213,17 @@
/obj/item/weapon/card/id/security
name = "identification card"
desc = "A card issued to station security staff."
- icon_state = "sec"
+ icon_state = "security-id"
primary_color = rgb(189,47,0)
secondary_color = rgb(223,127,95)
+/obj/item/weapon/card/id/security/warden
+ assignment = "Warden"
+ rank = "Warden"
+
/obj/item/weapon/card/id/security/head
name = "identification card"
desc = "A card which represents honor and protection."
- icon_state = "secGold"
primary_color = rgb(189,47,0)
secondary_color = rgb(255,223,127)
assignment = "Head of Security"
@@ -217,14 +232,17 @@
/obj/item/weapon/card/id/engineering
name = "identification card"
desc = "A card issued to station engineering staff."
- icon_state = "eng"
+ icon_state = "engineering-id"
primary_color = rgb(189,94,0)
secondary_color = rgb(223,159,95)
+/obj/item/weapon/card/id/engineering/atmos
+ assignment = "Atmospheric Technician"
+ rank = "Atmospheric Technician"
+
/obj/item/weapon/card/id/engineering/head
name = "identification card"
desc = "A card which represents creativity and ingenuity."
- icon_state = "engGold"
primary_color = rgb(189,94,0)
secondary_color = rgb(255,223,127)
assignment = "Chief Engineer"
@@ -233,14 +251,13 @@
/obj/item/weapon/card/id/science
name = "identification card"
desc = "A card issued to station science staff."
- icon_state = "sci"
+ icon_state = "science-id"
primary_color = rgb(142,47,142)
secondary_color = rgb(191,127,191)
/obj/item/weapon/card/id/science/head
name = "identification card"
desc = "A card which represents knowledge and reasoning."
- icon_state = "sciGold"
primary_color = rgb(142,47,142)
secondary_color = rgb(255,223,127)
assignment = "Research Director"
@@ -249,14 +266,13 @@
/obj/item/weapon/card/id/cargo
name = "identification card"
desc = "A card issued to station cargo staff."
- icon_state = "cargo"
+ icon_state = "cargo-id"
primary_color = rgb(142,94,0)
secondary_color = rgb(191,159,95)
/obj/item/weapon/card/id/cargo/head
name = "identification card"
desc = "A card which represents service and planning."
- icon_state = "cargoGold"
primary_color = rgb(142,94,0)
secondary_color = rgb(255,223,127)
assignment = "Quartermaster"
@@ -269,7 +285,7 @@
/obj/item/weapon/card/id/civilian
name = "identification card"
desc = "A card issued to station civilian staff."
- icon_state = "civ"
+ icon_state = "civilian-id"
primary_color = rgb(0,94,142)
secondary_color = rgb(95,159,191)
assignment = "Civilian"
@@ -278,13 +294,12 @@
/obj/item/weapon/card/id/civilian/head //This is not the HoP. There's no position that uses this right now.
name = "identification card"
desc = "A card which represents common sense and responsibility."
- icon_state = "civGold"
primary_color = rgb(0,94,142)
secondary_color = rgb(255,223,127)
/obj/item/weapon/card/id/external
name = "identification card"
desc = "An identification card of some sort. It does not look like it is issued by NT."
- icon_state = "permit"
+ icon_state = "generic"
primary_color = rgb(142,94,0)
secondary_color = rgb(191,159,95)
diff --git a/code/game/objects/items/weapons/id cards/station_ids_vr.dm b/code/game/objects/items/weapons/id cards/station_ids_vr.dm
index 756ab3bc9c..0a9015145a 100644
--- a/code/game/objects/items/weapons/id cards/station_ids_vr.dm
+++ b/code/game/objects/items/weapons/id cards/station_ids_vr.dm
@@ -1,102 +1,273 @@
+/obj/item/weapon/card/id/event
+ var/configured = 0
+ var/accessset = 0
+ initial_sprite_stack = list()
+ var/list/title_strings = list()
+ var/preset_rank = FALSE
+
+/obj/item/weapon/card/id/event/attack_self(var/mob/user)
+ if(configured == 1)
+ return ..()
+
+ if(!preset_rank)
+ var/title
+ if(user.client.prefs.player_alt_titles[user.job])
+ title = user.client.prefs.player_alt_titles[user.job]
+ else
+ title = user.job
+ assignment = title
+ user.set_id_info(src)
+ if(user.mind && user.mind.initial_account)
+ associated_account_number = user.mind.initial_account.account_number
+ if(title_strings.len)
+ var/tempname = pick(title_strings)
+ name = tempname + " ([assignment])"
+ else
+ name = user.name + "'s ID card" + " ([assignment])"
+
+ configured = 1
+ to_chat(user, "Card settings set.")
+
+/obj/item/weapon/card/id/event/attackby(obj/item/I as obj, var/mob/user)
+ if(istype(I, /obj/item/weapon/card/id) && !accessset)
+ var/obj/item/weapon/card/id/O = I
+ access |= O.access
+ desc = I.desc
+ rank = O.rank
+ to_chat(user, "You copy the access from \the [I] to \the [src].")
+ user.drop_from_inventory(I)
+ qdel(I)
+ accessset = 1
+ ..()
+
+/obj/item/weapon/card/id/event/accessset
+ accessset = 1
+
+
+
/obj/item/weapon/card/id/gold/captain/spare/fakespare
rank = "null"
-/obj/item/weapon/card/id/itg
+/obj/item/weapon/card/id/event/accessset/itg
name = "identification card"
desc = "A small card designating affiliation with the Ironcrest Transport Group."
icon = 'icons/obj/card_vr.dmi'
+ base_icon = 'icons/obj/card_vr.dmi'
icon_state = "itg"
- item_state = "itg_id"
-/obj/item/weapon/card/id/itg/green
+/obj/item/weapon/card/id/event/accessset/itg/green
icon_state = "itg_green"
- item_state = "itg_green_id"
-/obj/item/weapon/card/id/itg/red
+/obj/item/weapon/card/id/event/accessset/itg/red
icon_state = "itg_red"
- item_state = "itg_red_id"
-/obj/item/weapon/card/id/itg/purple
+/obj/item/weapon/card/id/event/accessset/itg/purple
icon_state = "itg_purple"
- item_state = "itg_purple_id"
-/obj/item/weapon/card/id/itg/white
+/obj/item/weapon/card/id/event/accessset/itg/white
icon_state = "itg_white"
- item_state = "itg_white_id"
-/obj/item/weapon/card/id/itg/orange
+/obj/item/weapon/card/id/event/accessset/itg/orange
icon_state = "itg_orange"
- item_state = "itg_orange_id"
-/obj/item/weapon/card/id/itg/blue
+/obj/item/weapon/card/id/event/accessset/itg/blue
icon_state = "itg_blue"
- item_state = "itg_blue_id"
-/obj/item/weapon/card/id/itg/event
+/obj/item/weapon/card/id/event/accessset/itg/crew
name = "\improper ITG Crew ID"
assignment = "Crew"
rank = "Crew"
access = list(777)
+ preset_rank = TRUE
-/obj/item/weapon/card/id/itg/event/pilot
+/obj/item/weapon/card/id/event/accessset/itg/crew/pilot
name = "\improper ITG Pilot's ID"
desc = "An ID card belonging to the Pilot of an ITG vessel. The Pilot's responsibility is primarily to fly the ship. They may also be tasked to assist with cargo movement duties."
assignment = "Pilot"
rank = "Pilot"
-/obj/item/weapon/card/id/itg/event/service
+/obj/item/weapon/card/id/event/accessset/itg/crew/service
name = "\improper ITG Cook's ID"
desc = "An ID card belonging to the Cook of an ITG vessel. The Cook's responsibility is primarily to provide sustinence to the crew and passengers. The Cook answers to the Passenger Liason. In the absence of a Passenger Liason, the Cook is also responsible for tending to passenger related care and duties."
assignment = "Cook"
rank = "Cook"
icon_state = "itg_green"
- item_state = "itg_green_id"
-/obj/item/weapon/card/id/itg/event/security
+/obj/item/weapon/card/id/event/accessset/itg/crew/security
name = "\improper ITG Security's ID"
desc = "An ID card belonging to Security of an ITG vessel. Security's responsibility is primarily to protect the ship, cargo, or facility. They may also be tasked to assist with cargo movement duties and rescue operations. ITG Security is almost exclusively defensive. They should not start fights, but they are very capable of finishing them."
assignment = "Security"
rank = "Security"
icon_state = "itg_red"
- item_state = "itg_red_id"
-/obj/item/weapon/card/id/itg/event/research
+/obj/item/weapon/card/id/event/accessset/itg/crew/research
name = "\improper ITG Research's ID"
desc = "An ID card belonging to ITG Research staff. ITG Research staff primarily specializes in starship and starship engine design, and overcoming astronomic phenomena."
assignment = "Research"
rank = "Research"
icon_state = "itg_purple"
- item_state = "itg_purple_id"
-/obj/item/weapon/card/id/itg/event/medical
+/obj/item/weapon/card/id/event/accessset/itg/crew/medical
name = "\improper ITG Medic's ID"
desc = "An ID card belonging to the Medic of an ITG vessel. The Medic's responsibility is primarily to treat crew and passenger injuries. They may also be tasked with rescue operations."
assignment = "Medic"
rank = "Medic"
icon_state = "itg_white"
- item_state = "itg_white_id"
-/obj/item/weapon/card/id/itg/event/engineer
+/obj/item/weapon/card/id/event/accessset/itg/crew/engineer
name = "\improper ITG Engineer's ID"
desc = "An ID card belonging to the Engineer of an ITG vessel. The Engineer's responsibility is primarily to maintain the ship. They may also be tasked to assist with cargo movement duties."
assignment = "Engineer"
rank = "Engineer"
icon_state = "itg_orange"
- item_state = "itg_orange_id"
-/obj/item/weapon/card/id/itg/event/passengerliason
+/obj/item/weapon/card/id/event/accessset/itg/crew/passengerliason
name = "\improper ITG Passenger Liason's ID"
desc = "An ID card belonging to the Passenger Liason of an ITG vessel. The Passenger Liason's responsibility is primarily to manage and tend to passenger needs and maintain supplies and facilities for passenger use."
assignment = "Passenger Liason"
rank = "Passenger Liason"
icon_state = "itg_blue"
- item_state = "itg_blue_id"
-/obj/item/weapon/card/id/itg/event/captain
+/obj/item/weapon/card/id/event/accessset/itg/crew/captain
name = "\improper ITG Captain's ID"
desc = "An ID card belonging to the Captain of an ITG vessel. The Captain's responsibility is primarily to manage crew to ensure smooth ship operations. Captains often also often pilot the vessel when no dedicated pilot is assigned."
assignment = "Captain"
rank = "Captain"
icon_state = "itg_blue"
- item_state = "itg_blue_id"
- access = list(777, 778)
\ No newline at end of file
+ access = list(777, 778)
+
+/obj/item/weapon/card/id/event/altcard
+ icon = 'icons/obj/card_alt_vr.dmi'
+ base_icon = 'icons/obj/card_alt_vr.dmi'
+ icon_state = "id"
+
+/obj/item/weapon/card/id/event/altcard/spare
+ icon_state = "spare"
+
+/obj/item/weapon/card/id/event/altcard/clown
+ icon_state = "Clown"
+
+/obj/item/weapon/card/id/event/altcard/mime
+ icon_state = "Mime"
+
+/obj/item/weapon/card/id/event/altcard/centcom
+ icon_state = "CentCom Officer"
+
+/obj/item/weapon/card/id/event/altcard/ert
+ icon_state = "Emergency Responder"
+
+/obj/item/weapon/card/id/event/altcard/nt
+ icon_state = "nanotrasen"
+
+/obj/item/weapon/card/id/event/altcard/syndiegold
+ icon_state = "syndieGold"
+
+/obj/item/weapon/card/id/event/altcard/syndie
+ icon_state = "syndie"
+
+/obj/item/weapon/card/id/event/altcard/greengold
+ icon_state = "greenGold"
+
+/obj/item/weapon/card/id/event/altcard/pink
+ icon_state = "pink"
+
+/obj/item/weapon/card/id/event/altcard/pinkgold
+ icon_state = "pinkGold"
+
+/obj/item/weapon/card/id/event/polymorphic
+ var/base_icon_state
+
+/obj/item/weapon/card/id/event/polymorphic/digest_act(atom/movable/item_storage = null)
+ var/gimmeicon = icon
+ . = ..()
+ icon = gimmeicon
+ icon_state = base_icon_state + "_digested"
+
+/obj/item/weapon/card/id/event/polymorphic/altcard/attack_self(var/mob/user)
+ if(configured == 1)
+ return ..()
+ else
+ icon_state = user.job
+ base_icon_state = user.job
+ return ..()
+
+/obj/item/weapon/card/id/event/polymorphic/altcard
+ icon = 'icons/obj/card_alt_vr.dmi'
+ base_icon = 'icons/obj/card_alt_vr.dmi'
+ icon_state = "blank"
+ name = "contractor identification card"
+ desc = "An ID card typically used by contractors."
+
+/obj/item/weapon/card/id/event/polymorphic/itg/attack_self(var/mob/user)
+ if(!configured)
+ var/list/jobs_to_icon = list( //ITG only has a few kinds of icons so we have to group them up!
+ "Pilot" = "itg",
+ "Visitor" = "itg",
+ "Quartermaster" = "itg",
+ "Cargo Technician" = "itg",
+ "Shaft Miner" = "itg",
+ "Intern" = "itg",
+ "Talon Pilot" = "itg",
+ "Bartender" = "itg_green",
+ "Botanist" = "itg_green",
+ "Chef" = "itg_green",
+ "Janitor" = "itg_green",
+ "Chaplain" = "itg_green",
+ "Entertainer" = "itg_green",
+ "Janitor" = "itg_green",
+ "Librarian" = "itg_green",
+ "Warden" = "itg_red",
+ "Detective" = "itg_red",
+ "Security Officer" = "itg_red",
+ "Talon Guard" = "itg_red",
+ "Roboticist" = "itg_purple",
+ "Scientist" = "itg_purple",
+ "Xenobiologist" = "itg_purple",
+ "Xenobotanist" = "itg_purple",
+ "Pathfinder" = "itg_purple",
+ "Explorer" = "itg_purple",
+ "Chemist" = "itg_white",
+ "Medical Doctor" = "itg_white",
+ "Paramedic" = "itg_white",
+ "Psychiatrist" = "itg_white",
+ "Field Medic" = "itg_white",
+ "Talon Doctor" = "itg_white",
+ "Atmospheric Technician" = "itg_orange",
+ "Station Engineer" = "itg_orange",
+ "Off-duty Officer" = "itg_red",
+ "Off-duty Engineer" = "itg_orange",
+ "Off-duty Medic" = "itg_white",
+ "Off-duty Scientist" = "itg_purple",
+ "Off-duty Cargo" = "itg",
+ "Off-duty Explorer" = "itg_purple",
+ "Off-duty Worker" = "itg_green"
+ )
+ var/guess = jobs_to_icon[user.job]
+
+ if(!guess)
+ to_chat(user, "ITG Cards do not seem to be able to accept the access codes for your ID.")
+ return
+ else
+ icon_state = guess
+ base_icon_state = guess
+ . = ..()
+ name = user.name + "'s ITG ID card" + " ([assignment])"
+
+
+/obj/item/weapon/card/id/event/polymorphic/itg/attackby(obj/item/I as obj, var/mob/user)
+ if(istype(I, /obj/item/weapon/card/id) && !accessset)
+ var/obj/item/weapon/card/id/O = I
+ var/list/itgdont = list("Site Manager", "Head of Personnel", "Command Secretary", "Head of Security", "Chief Engineer", "Chief Medical Officer", "Research Director", "Clown", "Mime", "Talon Captain") //If you're in as one of these you probably aren't representing ITG
+ if(O.rank in itgdont)
+ to_chat(user, "ITG Cards do not seem to be able to accept the access codes for your ID.")
+ return
+ . = ..()
+ desc = "A small card designating affiliation with the Ironcrest Transport Group. It has a NanoTrasen insignia and a lot of very small print on the back to do with practices and regulations for contractors to use."
+
+
+/obj/item/weapon/card/id/event/polymorphic/itg
+ icon = 'icons/obj/card_vr.dmi'
+ base_icon = 'icons/obj/card_vr.dmi'
+ icon_state = "itg"
+ name = "\improper ITG identification card"
+ desc = "A small card designating affiliation with the Ironcrest Transport Group. It has a NanoTrasen insignia and a lot of very small print on the back to do with practices and regulations for contractors to use."
diff --git a/code/game/objects/items/weapons/id cards/syndicate_ids.dm b/code/game/objects/items/weapons/id cards/syndicate_ids.dm
index afb85ecb7a..01f6591104 100644
--- a/code/game/objects/items/weapons/id cards/syndicate_ids.dm
+++ b/code/game/objects/items/weapons/id cards/syndicate_ids.dm
@@ -1,6 +1,6 @@
/obj/item/weapon/card/id/syndicate
name = "agent card"
- icon_state = "syndicate"
+ icon_state = "generic-s"
assignment = "Agent"
origin_tech = list(TECH_ILLEGAL = 3)
var/electronic_warfare = 1
@@ -67,11 +67,12 @@
if(!id_card_states)
id_card_states = list()
for(var/path in typesof(/obj/item/weapon/card/id))
- var/obj/item/weapon/card/id/ID = path
+ var/obj/item/weapon/card/id/ID = new path()
var/datum/card_state/CS = new()
CS.icon_state = initial(ID.icon_state)
CS.item_state = initial(ID.item_state)
- CS.name = initial(ID.name) + " - " + initial(ID.icon_state)
+ CS.sprite_stack = ID.initial_sprite_stack
+ CS.name = initial(ID.name)
id_card_states += CS
id_card_states = dd_sortedObjectList(id_card_states)
@@ -81,6 +82,7 @@
var/name
var/icon_state
var/item_state
+ var/sprite_stack
/datum/card_state/dd_SortValue()
return name
@@ -89,5 +91,6 @@
name = "syndicate ID card"
desc = "An ID straight from the Syndicate."
registered_name = "Syndicate"
- assignment = "Syndicate Overlord"
- access = list(access_syndicate, access_external_airlocks)
\ No newline at end of file
+ assignment = "Syndicate Commander"
+ icon_state = "syndicate-id"
+ access = list(access_syndicate, access_external_airlocks)
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index 81d5bb8f04..b06e92cc4a 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -7,6 +7,8 @@
icon = 'icons/obj/device.dmi'
icon_state = "implant"
w_class = ITEMSIZE_TINY
+ show_messages = TRUE
+
var/implanted = null
var/mob/imp_in = null
var/obj/item/organ/external/part = null
@@ -14,7 +16,7 @@
var/allow_reagents = 0
var/malfunction = 0
var/initialize_loc = BP_TORSO
- show_messages = 1
+ var/known_implant = FALSE
/obj/item/weapon/implant/proc/trigger(emote, source as mob)
return
@@ -65,16 +67,17 @@
malfunction = MALFUNCTION_PERMANENT
/obj/item/weapon/implant/proc/implant_loadout(var/mob/living/carbon/human/H)
- if(H)
- if(handle_implant(H, initialize_loc))
- invisibility = initial(invisibility)
- post_implant(H)
+ . = istype(H) && handle_implant(H, initialize_loc)
+ if(.)
+ invisibility = initial(invisibility)
+ known_implant = TRUE
+ post_implant(H)
/obj/item/weapon/implant/Destroy()
if(part)
part.implants.Remove(src)
+ part = null
listening_objects.Remove(src)
- part = null
imp_in = null
return ..()
@@ -100,6 +103,7 @@ GLOBAL_LIST_BOILERPLATE(all_tracking_implants, /obj/item/weapon/implant/tracking
/obj/item/weapon/implant/tracking
name = "tracking implant"
desc = "An implant normally given to dangerous criminals. Allows security to track your location."
+ known_implant = TRUE
var/id = 1
var/degrade_time = 10 MINUTES //How long before the implant stops working outside of a living body.
@@ -348,6 +352,7 @@ GLOBAL_LIST_BOILERPLATE(all_chem_implants, /obj/item/weapon/implant/chem)
name = "chemical implant"
desc = "Injects things."
allow_reagents = 1
+ known_implant = TRUE
/obj/item/weapon/implant/chem/get_data()
var/dat = {"
@@ -418,6 +423,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
/obj/item/weapon/implant/loyalty
name = "loyalty implant"
desc = "Makes you loyal or such."
+ known_implant = TRUE
/obj/item/weapon/implant/loyalty/get_data()
var/dat = {"
@@ -491,6 +497,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
name = "death alarm implant"
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_DATA = 1)
+ known_implant = TRUE
var/mobname = "Will Robinson"
/obj/item/weapon/implant/death_alarm/get_data()
diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm
index c404089028..9162be15eb 100644
--- a/code/game/objects/items/weapons/implants/implantcase.dm
+++ b/code/game/objects/items/weapons/implants/implantcase.dm
@@ -299,3 +299,13 @@
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/blade( src )
..()
return
+
+/obj/item/weapon/implantcase/restrainingbolt
+ name = "glass case - 'Restraining Bolt'"
+ desc = "A case containing a restraining bolt."
+ icon_state = "implantcase-b"
+
+/obj/item/weapon/implantcase/restrainingbolt/New()
+ src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
+ ..()
+ return
diff --git a/code/game/objects/items/weapons/implants/implantdud.dm b/code/game/objects/items/weapons/implants/implantdud.dm
index 110051e58d..cabf5bc906 100644
--- a/code/game/objects/items/weapons/implants/implantdud.dm
+++ b/code/game/objects/items/weapons/implants/implantdud.dm
@@ -4,18 +4,6 @@
icon = 'icons/obj/device.dmi'
icon_state = "implant"
initialize_loc = BP_HEAD
- var/roundstart = TRUE
/obj/item/weapon/implant/dud/torso
- name = "unknown implant"
- desc = "A small device with small connector wires."
- icon = 'icons/obj/device.dmi'
- icon_state = "implant"
initialize_loc = BP_TORSO
-
-/obj/item/weapon/implant/dud/old
- name = "old implant"
- desc = "A small device with small connector wires."
- icon = 'icons/obj/device.dmi'
- icon_state = "implant"
- roundstart = FALSE
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm
index c1b0d5db8d..adb79364dc 100644
--- a/code/game/objects/items/weapons/implants/implanter.dm
+++ b/code/game/objects/items/weapons/implants/implanter.dm
@@ -150,3 +150,12 @@
S.remove_from_storage(A)
A.loc.contents.Remove(A)
update()
+
+/obj/item/weapon/implanter/restrainingbolt
+ name = "implanter (bolt)"
+
+/obj/item/weapon/implanter/restrainingbolt/New()
+ src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
+ ..()
+ update()
+ return
diff --git a/code/game/objects/items/weapons/implants/implantlanguage.dm b/code/game/objects/items/weapons/implants/implantlanguage.dm
index 6a0f2baea8..692cdd381f 100644
--- a/code/game/objects/items/weapons/implants/implantlanguage.dm
+++ b/code/game/objects/items/weapons/implants/implantlanguage.dm
@@ -5,6 +5,7 @@
/obj/item/weapon/implant/language
name = "GalCom language implant"
desc = "An implant allowing someone to speak the range of frequencies used in Galactic Common, as well as produce any phonemes that they usually cannot. Only helps with producing sounds, not understanding them."
+ known_implant = TRUE
var/list/languages = list(LANGUAGE_GALCOM) // List of languages that this assists with
/obj/item/weapon/implant/language/post_implant(mob/M) // Amends the mob's voice organ, then deletes itself
diff --git a/code/game/objects/items/weapons/implants/implantrestrainingbolt.dm b/code/game/objects/items/weapons/implants/implantrestrainingbolt.dm
new file mode 100644
index 0000000000..7f4a562297
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implantrestrainingbolt.dm
@@ -0,0 +1,5 @@
+
+/obj/item/weapon/implant/restrainingbolt
+ name = "\improper restraining bolt"
+ icon = 'icons/obj/device.dmi'
+ icon_state = "implant"
diff --git a/code/game/objects/items/weapons/manuals_ch.dm b/code/game/objects/items/weapons/manuals_ch.dm
new file mode 100644
index 0000000000..25637382f5
--- /dev/null
+++ b/code/game/objects/items/weapons/manuals_ch.dm
@@ -0,0 +1,24 @@
+/obj/item/weapon/book/manual/chemistry_guide
+ name = "Chemical Recipes and Refreshers"
+ desc = "A lengthy guide on the most commonly used chemicals on a modern orbital facility"
+ icon_state = "bookMedical"
+ icon = 'icons/obj/library.dmi'
+ author = "NanoTrasen"
+ title = "Chemical Recipes and Refreshers"
+
+/obj/item/weapon/book/manual/chemistry_guide/New()
+ ..()
+ dat = {"
+
+
+
+
+ ((https://wiki.chompstation13.net/index.php?title=Guide_to_Chemistry))
+ "}
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/manuals_vr.dm b/code/game/objects/items/weapons/manuals_vr.dm
index 302e19ab2a..c14cfc12a0 100644
--- a/code/game/objects/items/weapons/manuals_vr.dm
+++ b/code/game/objects/items/weapons/manuals_vr.dm
@@ -42,4 +42,303 @@
- "}
\ No newline at end of file
+ "}
+
+//accurate as of 2/17/21 Extra credit to document editting and proofreading editing to Luna
+/obj/item/weapon/book/manual/cook_guide
+ name = "Food for Dummies 2"
+ desc = "A helpful guide to the world of cooking."
+ icon_state = "cook-guide"
+ icon = 'icons/obj/library_vr.dmi'
+ author = "Ali Big"
+ title = "Food for Dummies 2"
+
+/obj/item/weapon/book/manual/cook_guide/New()
+ ..()
+ dat = {"
+
+
+
+
+
+
+ Food for Dummies 2
+ Penned by Ali Big
+ Hello Newbie, congratz on deciding to make food! This guide assumes you know absolutely nothing, so fret not, the information here will help you prepare food for your hungry crewmates!
+ Workspace prep:
+ This step is simple: merely go to the Grill, Oven, and Fryer and turn everything on so you do not need to wait for them to warm up later; they won’t start a fire unless food is left in them unchecked. It is also highly suggested to lay out at least a few Measuring Cups on the counters for ease of use.
+ Basic ingredient prep:
+ In the lockers and fridges, you have all your needed supplies for this guide, so look through them and familiarize yourself! This guide will only use ingredients you already have access to, so don't worry about missing items!
+ Part 1: How to Create Various Essential Ingredients with What You Have
+ Dough Creation:
+ The basis for a large quantity of meals. Simply take an Egg, crack it into a Beaker or Measuring Cup, and then add 10 units of Flour to create Dough.
+ Dough Creation part 2:
+ With Dough, you can make a wide variety of base ingredients. Flattening it with a Rolling Pin makes Flat Dough. Flat Dough can be cooked in a Microwave for Flatbread, or if one adds Water and Flour in with the Flat Dough in the Microwave you get a Tortilla. Water can be obtained by filling a Cup at the Sink or Soda Machine.
+ Dough Creation Part 3:
+ Alternatively, Flat Dough can be cut with a Knife to make Dough Slices, and those can be cut to make Spaghetti.
+ Cheese Creation:
+ A common topping. Take a bottle of Universal Enzyme, put it in a Beaker or Measuring Cup, and add Milk until a Cheese Wheel pops out. Then cut the Cheese Wheel with a Knife to make Cheese Wedges, all recipes use Wedges not the full Wheel.
+ Tofu Creation:
+ Same as cheese, but with Soymilk!
+ Meatball Creation:
+ Mix Animal protein and Flour, to create Animal Protein grind down some Meat in the grinder, then remove the beaker and add Flour.
+ Meat Uses:
+ Full pieces of Meat can be cut for Raw Cutlets, which can be cut once more to make Raw Bacon. Though be sure not to cut all of your meat, plenty of recipes need a full uncut piece!
+ Part 2: Putting It All Together
+ Now that you know the fundamentals of how to make the base ingredients, here are some fairly easy recipes to put them together into something enjoyable for the crew.
+ Warning: recipes are upscale able, so you can add multiple of the same ingredients in the same ratio to cook lots of food at once!
+ Warning: do not try and cook multiple recipes at once as it is very likely it will default to a different recipe or will just cook the one and just "grill, bake, etc." the rest of the ingredients.
+ Burgers:
+ The cornerstone of basic food: to prepare these, microwave a piece of Dough to get a bun and grab a piece of Meat. Open the Grill, remove the Rack, and add both Bun and Meat to the Rack. Then, place the Rack back into the Grill to cook and remove it once finished. If you feel fancy, you can add cheese afterwards for a cheeseburger.
+ Meat Pie:
+ Flat Dough and Meat in an Oven Pan, same way you use the Grill; take the Pan out, put the ingredients in, and place it back to cook. Simple, but very good looking and tasty!
+ Burritos:
+ Burritos: A personal favorite due to flexibility of options: Use a Tortilla as a base for all of these. For a Chili one, add 2 Meatballs and 1 Space Spice (found near the Flour) to the Microwave; very simple and filling! Add a Cheese Wedge instead of the spice to make a queso burrito. For a Breakfast Wrap, add a whole Egg, Cooked Bacon (Raw Bacon cooked in the Microwave), and Cheese in with the Tortilla. For Vegan Burritos, just cook a Tortilla and Tofu together in the Microwave.
+ Tacos:
+ Use a tortilla then 1 cooked Cutlet, and a Cheese Wedge. Very easy to mass produce, great in a pinch!
+ Cheesy Nachos:
+ Tortilla, Cheese and 1 unit of Salt in the microwave, the perfect Finger Food!
+ Spaghetti:
+ Without Tomato’s from Botany it's not going to be the flashiest, but one can make Boiled Spaghetti with Spaghetti and Water in the Microwave. Kitsune Udon can be made with Spaghetti, Egg Yolk (crack egg in beaker then add to microwave), and Tofu. Spaghetti and Meatballs can be made by doing the Boiled Spaghetti Recipe and adding 2 Meatballs; adding 4 Meatballs into the initial mix makes Spesslaw. Lastly, Spaghetti, Milk, and Cheese in the Oven makes Macaroni and Cheese.
+ Steak:
+ For the pure meat eaters, just add Meat, 1 Salt, and 1 Pepper into the grill for them, and try not to cry as they use up all your Meat quickly. (There's a second Meat Locker in the freezer room if you do run out!)
+ Donk Pockets:
+ Dough and Meatball in the Microwave, though we already have plenty lying around the station.
+ Eggs:
+ Fried Egg, 1 Egg 1 Salt, 1 Pepper in a Microwave. Bacon and Eggs if you combine Cooked Bacon and Fried Egg in the Microwave. Great way to start the shift!
+ Part 3: Final Notes
+ These recipes only scratch the surface, but it's all things that can be done with what is pre-provided. If you have a partner in Botany, feel free to request more meat or any other supplies to try new recipes!
+ The Fryer, CondiMaster3000, and other nearby devices have been deliberately left out of this guide; as you get more advanced feel free to experiment with them, though be careful with the Fryer especially as it's the #1 source of fires for learning chefs, myself included. The one other machine that is worth understanding is the Gibber in the freezer room. If you are delivered fish or such they can be gibbed for extra Meat, though you may need to butcher the parts with a Knife afterwards to get usable Meat! Though if the meat is purple or comes from Koi or Spacecarp do not directly serve it to crew! It contains toxins that are better taken care of by other departments.
+ Some wonderful websites share recipes and tips for learning chefs on the Extranet! Look on your PDA or preferred device at https://wiki.vore-station.net/Guide_to_Food_and_Drink and https://vore-station.net/infodump/recipes_food.html for further tips, though do note the latter is more accurate in regard to recipes. Happy cooking!
+ Pro Tips:
+ ((The Food Bags in the Chef's Closet are great for moving a lot of food at once!))
+ ((Stay out of the Freezer if you're Cold Blooded!))
+ ((The websites linked above are also on our stations wiki. Which is always in need of helping heads to fix it up. The recipes listed on the web link may not be fully accurate so please don't be afraid to pop into the discord wiki channel and lend a hand!))
+
+
+ "}
+
+//accurate as of 2/23/21
+/obj/item/weapon/book/manual/bar_guide
+ name = "How to Alcohol (And other Drinks)"
+ desc = "A helpful guide to the world of barkeeping."
+ icon_state = "bar-guide"
+ icon = 'icons/obj/library_vr.dmi'
+ author = "Ali Big"
+ title = "How to Alcohol (And other Drinks)"
+
+/obj/item/weapon/book/manual/bar_guide/New()
+ ..()
+ dat = {"
+
+
+
+
+
+ How to Alcohol (And other Drinks)
+ Penned by Ali Big
+ Hello, and congratulations on taking on the admirable, and often thankless task of making Drinks for your fellow crewmates (or perhaps yourself if you hopped the bar, how rude!).
+ This guide will walk through the essentials of drink making... don't worry, it's not too complex! Recipes have been placed at the top for ease of use, but further down there is an actual guide as to how to make drinks, so give it a read if you don't know how, or just want some tips!
+ Part 0: Recipes Quick Reference (Ordered by strength, non-exhaustive list)
+ Low Alcohol:
+ Grog :
+ 1 part Rum, 1 part Water
+ Sui Dream:
+ 1 part Space-Up, 1 part Miss Blue Curacao, 1 part Emeraldine Melon Liquor
+ Baloon:
+ 1 part Cream, 1 part Miss Blue Curacao
+ Gin and Tonic:
+ 1 part Gin, 1 part Tonic
+ Appletini:
+ 2 parts Apple Juice, 1 part Vodka
+ Medium Alcohol
+ Giant Beer:Chrysanthemum:
+ 1 part Sake, 1 part Emeraldine Melon Liquor
+ Barefoot:
+ 1 part Berry Juice, 1 part Cream, 1 part Vermouth.
+ Clover Club:
+ 1 part Berry Juice, 1 Part Lemon Juice, 3 parts Gin
+ Cold Front:
+ 1 part Iced Coffee, 1 part Whiskey, 1 part Mint (Allergy Warning: do not give to any species with less cold tolerance than Teshari, they will die if you do, if unsure do not serve)
+ Cuba Libre (Often called Rum and Coke):
+ 1 part Space Cola, 2 parts Rum.
+ Negroni Sbagliato:
+ 1 part Wine, 1 part Bermouth, 1 part Soda Water
+ Slow Comfortable Screw Against the Wall (Stop giggling!):
+ 3 parts Screwdriver, 1 part Rum, 1 part Whiskey, 1 part Gin
+ Space Bulldog:
+ 4 parts White Russian, 1 part Cola
+ Sweet Rush:
+ 1 part Sugar, 1 part Soda Water, 1 part Vodka.
+ Allies Cocktail:
+ 1 part Classic Martini, 1 part Vodka
+ Bahama Mama:
+ 1 part Ice, 2 parts Orange Juice, 1 part Lime Juice, 2 parts Rum
+ Classic Martini:
+ 2 parts Gin, 1 part Vermouth
+ Daiquiri:
+ 3 Rum, 2 Lime Juice, 1 Sugar
+ Ginza Mary:
+ 2 part Sake, 2 part Vodka, 1 part Tomato Juice
+ Irish Cream:
+ 2 parts Whiskey, 1 part Cream
+ Lotus:
+ 1 part Negroni Sbagliato, 1 part Sweet Rush
+ Tequila Sunrise:
+ 2 parts Tequila, 1 part Orange Juice
+ The Manly Dorf:
+ 1 part Beer, 2 parts Ale
+ Whiskey Cola:
+ 2 parts Whiskey, 1 part Space Cola
+ Binman Bliss:
+ 1 part Sake, 1 part Tequila
+
+ High Alcohol
+ Elysium Facepunch:
+ 1 part Kahlua, 1 part Lemon Juice
+ Italian Crisis:
+ 1 part Space Bulldog, 1 part Negroni Sbagliato
+ Whiskey Sour:
+ 2 Whiskey, 1 Lemon Juice, 1 Sugar
+ Aloe:
+ 1 part Cream, 1 part Watermelon Juice, 1 part Whiskey (in that order)
+ Andalusia:
+ 1 part Lemon Juice, 1 part Rum, 1 part Whiskey
+ Black Russian:
+ 2 part Vodka, 1 part Kahlua
+ Bloody Mary:
+ 3 parts Tomato Juice, 2 part Vodka, 1 part Lime Juice
+ Brave Bull:
+ 2 parts Tequila, 1 part Kahlua
+ Irish Car Bomb:
+ 1 part Ale, 1 part Irish Cream
+ Irish Coffee:
+ 1 parts Irish Cream, 1 parts Coffee
+ Manhattan:
+ 2 parts Whiskey, 1 part Vermouth
+ Margarita:
+ 2 parts Tequila, 1 part Lime Juice
+ Screwdriver:
+ 2 parts Vodka, 1 part Orange Juice
+ Sex On The Beach:
+ 3 part Orange Juice, 2 part Grenadine Syrup, 1 part Vodka
+ Vodka and Tonic:
+ 2 parts Vodka, 1 part Tonic
+ Whiskey Soda:
+ 2 parts Whiskey, 1 part Soda Water
+ White Russian:
+ 2 Black Russian, 1 part Cream
+ WND-Garita:
+ 3 Margarita, 2 Mountain Wind, 1 Emeraldine Melon Liquor
+ Mudslide:
+ 1 Black Russian, 1 Irish Cream
+
+ Very High Alcohol (Serve sparingly unless a patron proves they can handle a lot)
+ Anti-Freeze:
+ 1 part Cream, 1 part Ice, 1 parts Vodka (Feels cold but actually warms. Allergy Warning: Do not serve to Teshari or Promethians, or other heat vulnerable species, they will die if you do, if unsure do not serve)
+ B-52:
+ 1 part Irish Cream, 1 part Cognac, 1 part Kahlua
+ Long Island Iced Tea:
+ 3 part Cuba Libre, 1 part Vodka, 1 part Gin, 1 part Tequila
+ Vodka Martini:
+ 2 parts Vodka, 1 part Vermouth
+ Changeling Sting:
+ 1 part Screwdriver, 1 part Lemon Juice, 1 part Lime Juice
+ Deathbell:
+ 1 part Anti-Freeze, 1 part Pan-Galactic Gargle Blaster, 1 part Syndicate Bomb (Allergy Warning: Poisonous to Teshari and other heat vulnerable species. Literally explodes Promethians. Metabolizes very quickly so it can kill a liver easily, be very careful with this one.)
+ Erebus Moonrise:
+ 1 part Whiskey, 1 part Vodka, 1 part Tequila
+ Pan-Galactic Gargle Blaster:
+ 1 part Gin, 2 part Vodka, 1 part Whiskey, 1 part Cognac, 1 part Lime Juice (Causes halucinations, don't slip it into other drinks you animal)
+ Syndicate Bomb:
+ 1 part Whiskey Cola, 1 part Beer
+ Euphoria:
+ 1 part Special Blend Whiskey, 2 part Cognac
+ Screaming Viking:
+ Vodka, Vermouth, Lime Juice, Rum, Gin, and Tonic
+ Good Luck figuring out the order and ratio :)
+ Fire Punch:
+ 1 part Sugar, 2 part Rum (Technically the strongest thing you can make, but it metabolizes slowish so it's slightly less dangerous than some others)
+
+ Non Alcoholic Drinks
+ Appleade:
+ 1 part Apple Juice, 1 part Sugar, 1 part Soda Water
+ Arnold Palmer:
+ 1 Iced Tea, 1 Lemonade
+ Berry Cordial:
+ 4 Berry Juice, 1 unit Sugar, 1 Lemon Juice
+ Berry shake:
+ 1 part Milkshake, 1 part Berry Juice
+ Brown Star:
+ 2 parts Orange Juice, 1 part Space Cola
+ Cafe Latte:
+ 1 part Coffee, 1 part Milk
+ Coffee Milkshake:
+ 1 part Milkshake, 1 part Coffee
+ Driver's Punch:
+ 1 part Appleade, 1 part Orange Juice, 1 part Mint, 1 part Soda Water
+ Graveyard:
+ All 4 Sodas in your Soft Drink Dispenser in equal parts, haha it go woosh.
+ Grenadine Syrup:
+ 10 parts berry juice, 5 parts Universal Enzyme (Get Enzyme from Kitchen)
+ Iced Coffee:
+ 1 part Ice, 2 parts Coffee
+ Kira Special:
+ 1 part Orange Juice, 1 part Lime Juice, 1 part Soda Water
+ Lemonade:
+ 1 part Lemon juice, 1 part Sugar, 1 part Water
+ Melonade:
+ 1 part Watermelon Juice, 1 part Sugar, 1 part Soda Water
+ Milkshake:
+ 1 part Cream, 2 parts Ice, 2 parts Milk
+ Sweet Tea:
+ 2 parts Ice Tea, 1 part Sugar
+ Note: There are many more drinks you can mix, these are just ones using resources you will almost always have available, the Extranet has good websites to check found here: https://wiki.vore-station.net/Guide_to_Food_and_Drink ass well as here: https://vore-station.net/infodump/recipes_drinks.html
+
+ Part 1: The Basics
+ First and foremost, making drinks is about understanding measurements. Drinks are measured in units a pint is 60 units, a half pint 30, and ratios of those units can create certain drinks.
+ The ratios of these drinks are denoted in "Parts". For example, Grog is 1 part rum and 1 part water mixed in a container that holds liquid. This means 1 unit of Rum and 1 unit of Water can make Grog, as can 30 units of Rum and 30 units of Water. Ratios aren't picky, if you have 5 units of Rum and 10 of Water in a glass, it will turn as much as possible into Grog, and the rest will remain as water (In this case, 10 units of Grog and 5 units of Water will be in the glass). When mixing drinks, you may accidentally have extra of an ingredient such as in the previous example, but this can easily be rectified by placing the drink in one of the Dispensers, and using the interface at the bottom to remove however many units you put extra, so don't worry about sloppiness as long as you clean up your mistakes!
+ Actually mixing drinks is simple enough, the vast majority of mixing should be done in a Dispenser, it can be done by hand outside of one, but generally you only want to be doing so for when the Dispenser lacks an ingredient to make life easier. Drinks automatically mix when placed into a container together, so you don't have to do anything special, think of it like a chemical reaction, it even bubbles when it works!
+ Part 2: General Tips/FAQ
+ "I don't have X item for the drink my patron wants." - If it's on the quick reference, you probably do, just be sure to check the Booze-O-Mat if it cannot be found in the dispenser. If it's not in either Dispenser or in the Coffee Dispenser in the Surface 1 Bar (Such as Berry Juice). If you still lack the materials, you may need to ask another department (Cargo, Science, or perhaps Med usually) for a delivery of them.
+ "I don't want to run to the Surface 1 Bar every time to make this specific drink." - You don't have to! A good practice as a bartender if you want to make your life easier is to take a screwdriver, use it on the machine, and select the cartridges you want to have in your bar. If you do this you will remove them, and are free to insert them into your own machines, but do be considerate if there are more bartenders around, don't steal their supplies if they need them! Another good practice is to move, or have someone else move the machine up to your bar instead of removing the cartridges, ultimately the choice is yours as to how best set up your bar!
+ "How do I deal with a rowdy patron?" - Ask Security for help, just because you have a shotgun doesn't mean you are the law in your bar. Respect procedure!
+ "What does the Grinder do?" - What it says on the tin, if you get Iron, Uranium, or something else needed for a drink that isn't already liquefied, you have to grind it down first to add it!
+ "Do I have to wear the hat?" - No, but you can if it looks good on you!
+ "How do I unlock the good music on the Jukebox?" - Get a Screwdriver and use it on the Jukebox to open the hatch, then use Wirecutters and cut/remend wires until you cut the one that turns the Parental Guidance light off. Beware of shocks (Insulated Gloves Suggested)! Be sure to close it again after.
+ "How do I make my drinks look pretty?" - Use the Metamorphic Glasses, though do note some drinks don't look any different even in one.
+ "Oh god my patron is convulsing, what do I do?" - Rush them to Medbay. If they're too big to move get a rolling chair from the Library, or get medical staff to come to the Bar.
+ "My patron drank too much and is definitely going to start convulsing, what do I do?" - Either rush them to Medbay, or get Medbay to give you pills that neutralize alcohol, it's ok to be the fun police to save a life.
+ "Nobody wants to stay at my bar!" - Try adopting a gimmick to spruce things up! Everyone's will be different, but doing something fun is a good way to attract customers. Creating your own unique mixes is another fun way to distinguish yourself.
+ "I don't like the way the bar looks with the lights dimmed/I don't like the way the bar looks with the lights bright!" - Enable or disable the night lighting on the APC by the bar then!
+ "A patron said they don't drink, woe is me, my job is now useless!" - Have you tried offering them a non-alcoholic drink? Or just talking to them? As long as you're providing a good time, you're still doing great!
+ "Somebody messed with a drink I left lying out on the counter, I think it's been spiked!" - Don't leave drinks lying on the counter. Not only is it a spiking hazzard, but inevitably somebody is gonna try to chug them all. If you want to do a pretty display, make it non alcoholic, or on the back bar counter out of easy reach!
+ "My patrons are all hungry because we have no Chef!" - Well, you have access to the Kitchen if you feel like trying to solve that, I have a guide for that there too!
+ "I feel like a hamster in a wheel, running hopelessly but never quite getting anywhere. No matter what I do, things just don't seem to change, I don't seem to change, and I worry, that maybe... they won't." - Try drinking some of your own booze until that feeling goes away.
+ Part 3: Closing Remarks
+ This all may seem daunting at a glance; so many recipes to learn, and a "lot" to keep in mind. But really it's not - tending the Bar is mostly about going with the flow of things and providing a good times, and drinks just provide liquid courage to make a good time easier. Take a deep breath if you ever feel overwhelmed, and handle one order at a time. You can do it! Don't feel the need to know every recipe, just learn your favorites and go from there; the rest is here or online if someone asks for it! If somebody asks you to give them anything without a specific request, don't panic: evalulate their likes and tolerance level, and try your best to give them something nice!
+
+ "}
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm
index 678b77b622..78cd9c39e7 100644
--- a/code/game/objects/items/weapons/material/knives.dm
+++ b/code/game/objects/items/weapons/material/knives.dm
@@ -45,13 +45,15 @@
/obj/item/weapon/material/butterfly/attack_self(mob/user)
active = !active
- if(active)
- to_chat(user, "You flip out \the [src].")
- playsound(src, 'sound/weapons/flipblade.ogg', 15, 1)
- else
- to_chat(user, "\The [src] can now be concealed.")
update_force()
- add_fingerprint(user)
+
+ if(user)
+ if(active)
+ to_chat(user, "You flip out \the [src].")
+ playsound(src, 'sound/weapons/flipblade.ogg', 15, 1)
+ else
+ to_chat(user, "\The [src] can now be concealed.")
+ add_fingerprint(user)
/*
* Kitchen knives
@@ -138,6 +140,11 @@
slot_flags = SLOT_BELT
default_material = "plasteel" //VOREStation Edit
+/obj/item/weapon/material/knife/machete/cyborg
+ name = "integrated machete"
+ desc = "A sharp machete often found attached to robots."
+ unbreakable = TRUE
+
/obj/item/weapon/material/knife/tacknife/survival
name = "survival knife"
desc = "A hunting grade survival knife."
diff --git a/code/game/objects/items/weapons/material/material_armor.dm b/code/game/objects/items/weapons/material/material_armor.dm
index 3d3f7a3c38..96496d2f8f 100644
--- a/code/game/objects/items/weapons/material/material_armor.dm
+++ b/code/game/objects/items/weapons/material/material_armor.dm
@@ -31,7 +31,9 @@ Protectiveness | Armor %
var/applies_material_color = TRUE
var/unbreakable = FALSE
var/default_material = null // Set this to something else if you want material attributes on init.
- var/material_armor_modifer = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
+ var/material_armor_modifier = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
+ var/material_slowdown_modifier = 0
+ var/material_slowdown_multiplier = 1
/obj/item/clothing/New(var/newloc, var/material_key)
..(newloc)
@@ -138,7 +140,7 @@ Protectiveness | Armor %
return ..()
var/reflectchance = (40 * material.reflectivity) - round(damage/3)
- reflectchance *= material_armor_modifer
+ reflectchance *= material_armor_modifier
if(!(def_zone in list(BP_TORSO, BP_GROIN)))
reflectchance /= 2
if(P.starting && prob(reflectchance))
@@ -166,17 +168,17 @@ Protectiveness | Armor %
if(material)
var/melee_armor = 0, bullet_armor = 0, laser_armor = 0, energy_armor = 0, bomb_armor = 0
- melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifer)
+ melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifier)
- bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifer) * 0.7)
+ bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifier) * 0.7)
- laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifer) * 0.7)
+ laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifier) * 0.7)
if(material.opacity != 1)
laser_armor *= max(material.opacity - 0.3, 0) // Glass and such has an opacity of 0.3, but lasers should go through glass armor entirely.
- energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.4)
+ energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifier) * 0.4)
- bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.5)
+ bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifier) * 0.5)
// Makes sure the numbers stay capped.
for(var/number in list(melee_armor, bullet_armor, laser_armor, energy_armor, bomb_armor))
@@ -190,7 +192,12 @@ Protectiveness | Armor %
if(!isnull(material.conductivity))
siemens_coefficient = between(0, material.conductivity / 10, 10)
- slowdown = between(0, round(material.weight / 10, 0.1), 6)
+
+ var/slowdownModified = between(0, round(material.weight / 10, 0.1), 6)
+
+ var/slowdownUncapped = (material_slowdown_multiplier * slowdownModified) - material_slowdown_modifier
+
+ slowdown = max(slowdownUncapped, 0)
/obj/item/clothing/suit/armor/material
name = "armor"
@@ -201,6 +208,67 @@ Protectiveness | Armor %
desc = "This appears to be two 'sheets' of a material held together by cable. If the sheets are strong, this could be rather protective."
icon_state = "material_armor_makeshift"
+/obj/item/clothing/accessory/material/makeshift/light //Craftable with 4 material sheets, less slowdown, less armour
+ name = "light armor plate"
+ desc = "A thin plate of padded material, designed to fit into a plate carrier. Attaches to a plate carrier."
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_state = "armor_light"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO
+ slot = ACCESSORY_SLOT_ARMOR_C
+ material_armor_modifier = 0.8
+ material_slowdown_modifier = 0.5 //Subtracted from total slowdown
+ material_slowdown_multiplier = 0.8 //Multiplied by total slowdown
+
+/obj/item/clothing/accessory/material/makeshift/heavy //Craftable with 8 material sheets, more slowdown, more armour
+ name = "heavy armor plate"
+ desc = "A thick plate of padded material, designed to fit into a plate carrier. Attaches to a plate carrier."
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_state = "armor_medium"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO
+ slot = ACCESSORY_SLOT_ARMOR_C
+ material_armor_modifier = 1.2
+ material_slowdown_modifier = 0
+ material_slowdown_multiplier = 1
+
+/obj/item/clothing/accessory/material/custom //Not yet craftable, advanced version made with science!
+ name = "custom armor plate"
+ desc = "A composite plate of custom machined material, designed to fit into a plate carrier. Attaches to a plate carrier."
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_state = "armor_tactical"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO
+ slot = ACCESSORY_SLOT_ARMOR_C
+ material_armor_modifier = 1.2
+ material_slowdown_modifier = 0.5
+ material_slowdown_multiplier = 0.8
+
+/obj/item/clothing/accessory/material/makeshift/armguards
+ name = "arm guards"
+ desc = "A pair of arm pads reinforced with material. Attaches to a plate carrier."
+// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_override = 'icons/mob/modular_armor.dmi'
+ icon_state = "armguards_material"
+ gender = PLURAL
+ body_parts_covered = ARMS
+ slot = ACCESSORY_SLOT_ARMOR_A
+ material_armor_modifier = 0.8
+ material_slowdown_modifier = 0.8
+ material_slowdown_multiplier = 0.8
+
+/obj/item/clothing/accessory/material/makeshift/legguards
+ name = "leg guards"
+ desc = "A pair of leg guards reinforced with material. Attaches to a plate carrier."
+// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_override = 'icons/mob/modular_armor.dmi'
+ icon_state = "legguards_material"
+ gender = PLURAL
+ body_parts_covered = LEGS
+ slot = ACCESSORY_SLOT_ARMOR_L
+ material_armor_modifier = 0.8
+ material_slowdown_modifier = 0.8
+ material_slowdown_multiplier = 0.8
+
/obj/item/clothing/suit/armor/material/makeshift/durasteel
default_material = "durasteel"
@@ -218,6 +286,9 @@ Protectiveness | Armor %
thrown_force_divisor = 0.2
var/wired = FALSE
+/obj/item/weapon/material/armor_plating/insert
+ unbreakable = FALSE
+
/obj/item/weapon/material/armor_plating/attackby(var/obj/O, mob/user)
if(istype(O, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/S = O
@@ -249,6 +320,54 @@ Protectiveness | Armor %
else
..()
+//Make plating inserts for modular armour.
+/obj/item/weapon/material/armor_plating/insert/attackby(var/obj/O, mob/user)
+
+ . = ..()
+
+ if(istype(O, /obj/item/weapon/weldingtool))
+ var /obj/item/weapon/weldingtool/S = O
+ if(S.remove_fuel(0,user))
+ if(!src || !S.isOn()) return
+ to_chat(user, "You trim down the edges to size.")
+ user.drop_from_inventory(src)
+ var/obj/item/clothing/accessory/material/makeshift/light/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(src)
+ return
+
+ if(istype(O, /obj/item/weapon/material/armor_plating/insert))
+ var/obj/item/weapon/material/armor_plating/insert/second_plate = O
+ if(second_plate.material != src.material)
+ to_chat(user, "Both plates need to be the same type of material.")
+ return
+ to_chat(user, "You bond the two plates together.")
+ user.drop_from_inventory(src)
+ user.drop_from_inventory(second_plate)
+ var/obj/item/clothing/accessory/material/makeshift/heavy/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(second_plate)
+ qdel(src)
+ return
+
+ if(istype(O, /obj/item/weapon/tool/wirecutters))
+ to_chat(user, "You split the plate down the middle, and joint it at the elbow.")
+ user.drop_from_inventory(src)
+ var/obj/item/clothing/accessory/material/makeshift/armguards/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(src)
+ return
+
+ if(istype(O, /obj/item/stack/material))
+ var/obj/item/stack/material/S = O
+ if(S.material == get_material_by_name("leather"))
+ if(S.use(2))
+ to_chat(user, "You curve the plate inwards, and add a strap for adjustment.")
+ user.drop_from_inventory(src)
+ var/obj/item/clothing/accessory/material/makeshift/legguards/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(src)
+ return
// Used to craft the makeshift helmet
/obj/item/clothing/head/helmet/bucket
diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm
index d8906955a1..bfa8b61680 100644
--- a/code/game/objects/items/weapons/material/misc.dm
+++ b/code/game/objects/items/weapons/material/misc.dm
@@ -77,14 +77,14 @@
//visible_message("[user] has smashed the snowball in their hand!", "You smash the snowball in your hand.")
to_chat(user, "You smash the snowball in your hand.")
var/atom/S = new /obj/item/stack/material/snow(user.loc)
- del(src)
+ qdel(src)
user.put_in_hands(S)
else
//visible_message("[user] starts compacting the snowball.", "You start compacting the snowball.")
to_chat(user, "You start compacting the snowball.")
if(do_after(user, 2 SECONDS))
var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc)
- del(src)
+ qdel(src)
user.put_in_hands(S)
/obj/item/weapon/material/snow/snowball/reinforced
diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm
index 1c4ad40773..c45e7125f5 100644
--- a/code/game/objects/items/weapons/material/twohanded.dm
+++ b/code/game/objects/items/weapons/material/twohanded.dm
@@ -177,4 +177,15 @@
default_material = "DEFAULT_WALL_MATERIAL"
fragile = 0
sharp = 1
- edge = 0
\ No newline at end of file
+ edge = 0
+
+/obj/item/weapon/material/twohanded/riding_crop
+ name = "riding crop"
+ desc = "A rod, a little over a foot long with a widened grip and a thick, leather patch at the end. Used since the dawn of the West to control animals."
+ force_divisor = 0.05 //Required in order for the X attacks Y message to pop up.
+ unwielded_force_divisor = 1 // One here, too.
+ applies_material_colour = 1
+ unbreakable = 1
+ base_icon = "riding_crop"
+ icon_state = "riding_crop0"
+ attack_verb = list("cropped","spanked","swatted","smacked","peppered")
diff --git a/code/game/objects/items/weapons/material/twohanded_vr.dm b/code/game/objects/items/weapons/material/twohanded_vr.dm
new file mode 100644
index 0000000000..f21738dd80
--- /dev/null
+++ b/code/game/objects/items/weapons/material/twohanded_vr.dm
@@ -0,0 +1,9 @@
+//1R1S: Malady Blanche
+/obj/item/weapon/material/twohanded/riding_crop/malady
+ name = "Malady's riding crop"
+ icon = 'icons/vore/custom_items_vr.dmi'
+ item_icons = list(
+ slot_l_hand_str = 'icons/vore/custom_items_left_hand_vr.dmi',
+ slot_r_hand_str = 'icons/vore/custom_items_right_hand_vr.dmi',
+ )
+ desc = "An infernum made riding crop with Malady Blanche engraved in the shaft. It's a little worn from how many butts it has spanked."
diff --git a/code/game/objects/items/weapons/shields_vr.dm b/code/game/objects/items/weapons/shields_vr.dm
index a9bce1d548..514ecd15c9 100644
--- a/code/game/objects/items/weapons/shields_vr.dm
+++ b/code/game/objects/items/weapons/shields_vr.dm
@@ -65,7 +65,6 @@
light_applied = 0
update_icon(user)
user.update_action_buttons()
- light = !light
playsound(src, 'sound/weapons/empty.ogg', 15, 1, -3)
/obj/item/weapon/shield/riot/explorer/update_icon()
@@ -92,4 +91,4 @@
if(on)
icon_state = "explorer_shield_P_lighted"
else
- icon_state = "explorer_shield_P"
\ No newline at end of file
+ icon_state = "explorer_shield_P"
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index 5741387b7b..8660d8a673 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -8,7 +8,7 @@
icon = 'icons/obj/clothing/backpack.dmi'
icon_state = "backpack"
sprite_sheets = list(
- SPECIES_TESHARI = 'icons/mob/species/seromi/back.dmi'
+ SPECIES_TESHARI = 'icons/mob/species/teshari/back.dmi'
)
w_class = ITEMSIZE_LARGE
slot_flags = SLOT_BACK
diff --git a/code/game/objects/items/weapons/storage/backpack_vr.dm b/code/game/objects/items/weapons/storage/backpack_vr.dm
index b7485be674..ab83c87752 100644
--- a/code/game/objects/items/weapons/storage/backpack_vr.dm
+++ b/code/game/objects/items/weapons/storage/backpack_vr.dm
@@ -6,7 +6,7 @@
item_state = "saddlebag"
icon_state = "saddlebag"
max_storage_space = INVENTORY_DUFFLEBAG_SPACE //Saddlebags can hold more, like dufflebags
- slowdown = 1 //And are slower, too...Unless you're a macro, that is.
+ slowdown = 1 //And are slower, too...
var/taurtype = /datum/sprite_accessory/tail/taur/horse //Acceptable taur type to be wearing this
var/no_message = "You aren't the appropriate taur type to wear this!"
@@ -35,7 +35,7 @@
icon_state = "saddlebag"
var/icon_base = "saddlebag"
max_storage_space = INVENTORY_DUFFLEBAG_SPACE //Saddlebags can hold more, like dufflebags
- slowdown = 1 //And are slower, too...Unless you're a macro, that is.
+ slowdown = 1 //And are slower, too...
var/no_message = "You aren't the appropriate taur type to wear this!"
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
@@ -44,11 +44,6 @@
log_runtime("[H] was not a valid human!")
return
- if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? If yes, they get no slowdown.
- slowdown = 0
- else
- slowdown = initial(slowdown)
-
var/datum/sprite_accessory/tail/taur/TT = H.tail_style
item_state = "[icon_base]_[TT.icon_sprite_tag]" //icon_sprite_tag is something like "deer"
return 1
@@ -82,7 +77,7 @@
/obj/item/weapon/storage/backpack
sprite_sheets = list(
- SPECIES_TESHARI = 'icons/mob/species/seromi/back.dmi',
+ SPECIES_TESHARI = 'icons/mob/species/teshari/back.dmi',
SPECIES_WEREBEAST = 'icons/mob/species/werebeast/back.dmi')
/obj/item/weapon/storage/backpack/ert
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index cea6a3bf7b..1ca68b8d6b 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -186,6 +186,23 @@
else
stored_ore[O.name] = 1
+//CHOMPstation edit START
+/obj/item/weapon/storage/bag/ore/large
+ name = "large mining satchel"
+ desc = "This little bugger can be used to store and transport ores. Appears to have upgraded storage space, up to three times your normal satchel!"
+ icon = 'icons/obj/mining_ch.dmi'
+ icon_state = "satchel_large"
+ max_storage_space = ITEMSIZE_COST_NORMAL * 75 // triple storage size of original
+
+/obj/item/weapon/storage/bag/ore/holding
+ name = "satchel of holding"
+ desc = "An ore satchel that opens into a localized pocket of bluespace."
+ icon = 'icons/obj/mining_ch.dmi'
+ icon_state = "satchel_bspace"
+ max_storage_space = ITEMSIZE_COST_NORMAL * 250 // ten times storage size of original
+
+//CHOMPstation edit END
+
// -----------------------------
// Plant bag
// -----------------------------
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index c3dba166bc..5dc7f83da8 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -11,7 +11,7 @@
equip_sound = 'sound/items/toolbelt_equip.ogg'
drop_sound = 'sound/items/drop/toolbelt.ogg'
pickup_sound = 'sound/items/pickup/toolbelt.ogg'
- sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi')
+ sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/belt.dmi')
var/show_above_suit = 0
diff --git a/code/game/objects/items/weapons/storage/belt_vr.dm b/code/game/objects/items/weapons/storage/belt_vr.dm
index e726e30b9c..defdcc296b 100644
--- a/code/game/objects/items/weapons/storage/belt_vr.dm
+++ b/code/game/objects/items/weapons/storage/belt_vr.dm
@@ -1,6 +1,6 @@
/obj/item/weapon/storage/belt
sprite_sheets = list(
- SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi',
+ SPECIES_TESHARI = 'icons/mob/species/teshari/belt.dmi',
SPECIES_WEREBEAST = 'icons/mob/species/werebeast/belt.dmi')
/obj/item/weapon/storage/belt/explorer
diff --git a/code/game/objects/items/weapons/storage/egg_vr.dm b/code/game/objects/items/weapons/storage/egg_vr.dm
new file mode 100644
index 0000000000..f7849040db
--- /dev/null
+++ b/code/game/objects/items/weapons/storage/egg_vr.dm
@@ -0,0 +1,202 @@
+//Item type vorepanel egg release containers.
+
+/obj/item/weapon/storage/vore_egg
+ name = "egg"
+ desc = "It's an egg; it's smooth to the touch." //This is the default egg.
+ icon = 'icons/obj/egg_new_vr.dmi'
+ icon_state = "egg"
+ var/open_egg_icon = 'icons/obj/egg_open_vr.dmi'
+ item_icons = list(
+ slot_l_hand_str = 'icons/mob/items/lefthand_storage.dmi',
+ slot_r_hand_str = 'icons/mob/items/righthand_storage.dmi',
+ )
+ w_class = 2
+ max_w_class = 0
+ show_messages = 0
+ allow_quick_empty = TRUE
+ use_sound = 'sound/items/drop/flesh.ogg'
+
+/obj/item/weapon/storage/vore_egg/open(mob/user as mob)
+ icon = open_egg_icon
+ ..()
+
+/obj/item/weapon/storage/vore_egg/proc/hatch(mob/living/user as mob)
+ visible_message("\The [src] begins to shake as something pushes out from within!")
+ animate_shake()
+ if(do_after(user, 50))
+ if(use_sound)
+ playsound(src, src.use_sound, 50, 0, -5)
+ animate_shake()
+ drop_contents()
+ icon = open_egg_icon
+
+/obj/item/weapon/storage/vore_egg/proc/animate_shake()
+ var/init_px = pixel_x
+ var/shake_dir = pick(-1, 1)
+ animate(src, transform=turn(matrix(), 8*shake_dir), pixel_x=init_px + 2*shake_dir, time=1)
+ animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
+
+/obj/item/weapon/storage/vore_egg/unathi
+ name = "unathi egg"
+ desc = "Some species of Unathi apparently lay soft-shelled eggs!"
+ icon_state = "egg_unathi"
+
+/obj/item/weapon/storage/vore_egg/nevrean
+ name = "nevrean egg"
+ desc = "Most Nevreans lay hard-shelled eggs!"
+ icon_state = "egg_nevrean"
+
+/obj/item/weapon/storage/vore_egg/human
+ name = "human egg"
+ desc = "Some humans lay eggs that are--wait, what?"
+ icon_state = "egg_human"
+
+/obj/item/weapon/storage/vore_egg/tajaran
+ name = "tajaran egg"
+ desc = "Apparently that's what a Tajaran egg looks like. Weird."
+ icon_state = "egg_tajaran"
+
+/obj/item/weapon/storage/vore_egg/skrell
+ name = "skrell egg"
+ desc = "Its soft and squishy"
+ icon_state = "egg_skrell"
+
+/obj/item/weapon/storage/vore_egg/shark
+ name = "akula egg"
+ desc = "Its soft and slimy to the touch"
+ icon_state = "egg_akula"
+
+/obj/item/weapon/storage/vore_egg/sergal
+ name = "sergal egg"
+ desc = "An egg with a slightly fuzzy exterior, and a hard layer beneath."
+ icon_state = "egg_sergal"
+
+/obj/item/weapon/storage/vore_egg/slime
+ name = "slime egg"
+ desc = "An egg with a soft and squishy interior, coated with slime."
+ icon_state = "egg_slime"
+
+/obj/item/weapon/storage/vore_egg/special //Not actually used, but the sprites are in, and it's there in case any admins need to spawn in the egg for any specific reasons.
+ name = "special egg"
+ desc = "This egg has a very unique look to it."
+ icon_state = "egg_unique"
+
+/obj/item/weapon/storage/vore_egg/scree
+ name = "Chimera egg"
+ desc = "...You don't know what type of creature laid this egg."
+ icon_state = "egg_scree"
+
+/obj/item/weapon/storage/vore_egg/xenomorph
+ name = "Xenomorph egg"
+ desc = "Some type of pitch black egg. It has a slimy exterior coating."
+ icon_state = "egg_xenomorph"
+
+/obj/item/weapon/storage/vore_egg/chocolate
+ name = "chocolate egg"
+ desc = "Delicious. May contain a choking hazard."
+ icon_state = "egg_chocolate"
+
+/obj/item/weapon/storage/vore_egg/owlpellet
+ name = "boney egg"
+ desc = "Can an egg shell be made of bones and hair?"
+ icon_state = "egg_pellet"
+
+/obj/item/weapon/storage/vore_egg/slimeglob
+ name = "glob of slime"
+ desc = "Very squishy."
+ icon_state = "egg_slimeglob"
+
+/obj/item/weapon/storage/vore_egg/chicken
+ name = "chicken egg"
+ desc = "Looks like chickens come in all sizes and shapes."
+ icon_state = "egg_chicken"
+
+/obj/item/weapon/storage/vore_egg/synthetic
+ name = "synthetic egg"
+ desc = "Smells like Easter morning."
+ icon_state = "egg_synthetic"
+
+/obj/item/weapon/storage/vore_egg/escapepod
+ name = "small escape pod"
+ desc = "Someone left in a hurry."
+ icon_state = "egg_escapepod"
+
+/obj/item/weapon/storage/vore_egg/floppy
+ name = "blue space floppy disc"
+ desc = "Probably shouldn't copy THIS floppy."
+ icon_state = "egg_floppy"
+
+/obj/item/weapon/storage/vore_egg/cd
+ name = "blue space cd"
+ desc = "What could even be on this?!"
+ icon_state = "egg_cd"
+
+/obj/item/weapon/storage/vore_egg/file
+ name = "blue space file"
+ desc = "Gotta wonder how much is compressed in there."
+ icon_state = "egg_file"
+
+/obj/item/weapon/storage/vore_egg/badrecipe
+ name = "Burned mess"
+ desc = "Someone didn't cook this egg quite right..."
+ icon_state = "egg_badrecipe"
+
+/obj/item/weapon/storage/vore_egg/cocoon
+ name = "web cocoon"
+ desc = "It straight up smells like spiders in here."
+ icon_state = "egg_cocoon"
+
+/obj/item/weapon/storage/vore_egg/honeycomb
+ name = "honeycomb"
+ desc = "Smells delicious!"
+ icon_state = "egg_honeycomb"
+
+/obj/item/weapon/storage/vore_egg/bugcocoon
+ name = "bug cocoon"
+ desc = "Metamorphosis!"
+ icon_state = "egg_bugcocoon"
+
+/obj/item/weapon/storage/vore_egg/rock
+ name = "rock egg"
+ desc = "It looks like a small boulder."
+ icon_state = "egg_rock"
+
+/obj/item/weapon/storage/vore_egg/yellow
+ name = "yellow egg"
+ desc = "It is a nice yellow egg."
+ icon_state = "egg_yellow"
+
+/obj/item/weapon/storage/vore_egg/blue
+ name = "blue egg"
+ desc = "It is a nice blue egg."
+ icon_state = "egg_blue"
+
+/obj/item/weapon/storage/vore_egg/green
+ name = "green egg"
+ desc = "It is a nice green egg."
+ icon_state = "egg_green"
+
+/obj/item/weapon/storage/vore_egg/orange
+ name = "orange egg"
+ desc = "It is a nice orange egg."
+ icon_state = "egg_orange"
+
+/obj/item/weapon/storage/vore_egg/purple
+ name = "purple egg"
+ desc = "It is a nice purple egg."
+ icon_state = "egg_purple"
+
+/obj/item/weapon/storage/vore_egg/red
+ name = "red egg"
+ desc = "It is a nice red egg."
+ icon_state = "egg_red"
+
+/obj/item/weapon/storage/vore_egg/rainbow
+ name = "rainbow egg"
+ desc = "It looks so colorful."
+ icon_state = "egg_rainbow"
+
+/obj/item/weapon/storage/vore_egg/pinkspots
+ name = "spotted pink egg"
+ desc = "It is a cute pink egg with white spots."
+ icon_state = "egg_pinkspots"
diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm
index e1e6ecd23f..1c5e0e7464 100644
--- a/code/game/objects/items/weapons/storage/fancy.dm
+++ b/code/game/objects/items/weapons/storage/fancy.dm
@@ -354,8 +354,16 @@
throwforce = 2
slot_flags = SLOT_BELT
storage_slots = 14
- can_hold = list(/obj/item/weapon/rollingpaper)
- starts_with = list(/obj/item/weapon/rollingpaper = 14)
+ can_hold = list(/obj/item/weapon/reagent_containers/rollingpaper)
+ starts_with = list(/obj/item/weapon/reagent_containers/rollingpaper = 14)
+
+/obj/item/weapon/storage/rollingpapers/blunt
+ name = "blunt wrap pack"
+ desc = "A small cardboard pack containing several folded blunt wraps."
+ icon_state = "bluntbox"
+ storage_slots = 7
+ can_hold = list(/obj/item/weapon/reagent_containers/rollingpaper/blunt)
+ starts_with = list(/obj/item/weapon/reagent_containers/rollingpaper/blunt = 7)
/*
* Vial Box
diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm
index 277a083d54..1764b0d8be 100644
--- a/code/game/objects/items/weapons/tanks/tank_types.dm
+++ b/code/game/objects/items/weapons/tanks/tank_types.dm
@@ -174,7 +174,7 @@
gauge_icon = "indicator_emergency"
/obj/item/weapon/tank/emergency/nitrogen/Initialize()
- ..()
+ . = ..()
src.air_contents.adjust_gas("nitrogen", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/weapon/tank/emergency/nitrogen/double
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index 5f587fccf2..806d26c90b 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -8,7 +8,7 @@ var/list/global/tank_gauge_cache = list()
name = "tank"
icon = 'icons/obj/tank.dmi'
sprite_sheets = list(
- SPECIES_TESHARI = 'icons/mob/species/seromi/back.dmi'
+ SPECIES_TESHARI = 'icons/mob/species/teshari/back.dmi'
)
drop_sound = 'sound/items/drop/gascan.ogg'
pickup_sound = 'sound/items/pickup/gascan.ogg'
@@ -341,6 +341,8 @@ var/list/global/tank_gauge_cache = list()
return remove_air(moles_needed)
/obj/item/weapon/tank/process()
+ if(!air_contents)
+ return
//Allow for reactions
air_contents.react() //cooking up air tanks - add phoron and oxygen, then heat above PHORON_MINIMUM_BURN_TEMPERATURE
if(gauge_icon)
diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm
index 988f165361..ee9d065ecb 100644
--- a/code/game/objects/items/weapons/tools/weldingtool.dm
+++ b/code/game/objects/items/weapons/tools/weldingtool.dm
@@ -671,7 +671,7 @@
always_process = TRUE
/obj/item/weapon/weldingtool/electric/mounted/exosuit/Initialize()
- ..()
+ . = ..()
if(istype(loc, /obj/item/mecha_parts/mecha_equipment))
equip_mount = loc
diff --git a/code/game/objects/items/weapons/towels.dm b/code/game/objects/items/weapons/towels.dm
index 2b41ce5163..77e1c43960 100644
--- a/code/game/objects/items/weapons/towels.dm
+++ b/code/game/objects/items/weapons/towels.dm
@@ -15,11 +15,11 @@
..()
switch(slot)
if(slot_head)
- sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/head.dmi')
+ sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/head.dmi')
if(slot_wear_suit)
- sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/suit.dmi')
+ sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/suit.dmi')
if(slot_belt)
- sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi')
+ sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/belt.dmi')
/obj/item/weapon/towel/attack_self(mob/living/user as mob)
user.visible_message(text("[] uses [] to towel themselves off.", user, src))
diff --git a/code/game/objects/items/weapons/weldbackpack_ch.dm b/code/game/objects/items/weapons/weldbackpack_ch.dm
new file mode 100644
index 0000000000..0235e8403f
--- /dev/null
+++ b/code/game/objects/items/weapons/weldbackpack_ch.dm
@@ -0,0 +1,4 @@
+/obj/item/weapon/weldpack
+ sprite_sheets = list(
+ SPECIES_TESHARI = 'icons/mob/species/teshari/back.dmi'
+ )
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 688236eda8..046958a915 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -19,29 +19,11 @@
var/can_speak = 0 //For MMIs and admin trickery. If an object has a brainmob in its contents, set this to 1 to allow it to speak.
var/show_examine = TRUE // Does this pop up on a mob when the mob is examined?
- var/register_as_dangerous_object = FALSE // Should this tell its turf that it is dangerous automatically?
-
-/obj/Initialize()
- if(register_as_dangerous_object)
- register_dangerous_to_step()
- return ..()
/obj/Destroy()
STOP_PROCESSING(SSobj, src)
- if(register_as_dangerous_object)
- unregister_dangerous_to_step()
return ..()
-/obj/Moved(atom/oldloc)
- . = ..()
- if(register_as_dangerous_object)
- var/turf/old_turf = get_turf(oldloc)
- var/turf/new_turf = get_turf(src)
-
- if(old_turf != new_turf)
- old_turf.unregister_dangerous_object(src)
- new_turf.register_dangerous_object(src)
-
/obj/Topic(href, href_list, var/datum/tgui_state/state = GLOB.tgui_default_state)
if(usr && ..())
return 1
@@ -183,9 +165,6 @@
/obj/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
return
-/obj/proc/get_cell()
- return
-
// Used to mark a turf as containing objects that are dangerous to step onto.
/obj/proc/register_dangerous_to_step()
var/turf/T = get_turf(src)
diff --git a/code/game/objects/random/_random.dm b/code/game/objects/random/_random.dm
index 67f82ea155..7b9cc60617 100644
--- a/code/game/objects/random/_random.dm
+++ b/code/game/objects/random/_random.dm
@@ -8,7 +8,7 @@
// creates a new object and deletes itself
/obj/random/Initialize()
- . = ..()
+ ..()
if (!prob(spawn_nothing_percentage))
spawn_item()
return INITIALIZE_HINT_QDEL
diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm
index 13568c27e6..3881cf031b 100644
--- a/code/game/objects/random/misc.dm
+++ b/code/game/objects/random/misc.dm
@@ -262,7 +262,7 @@
prob(8);/obj/item/weapon/haircomb,
prob(4);/obj/item/weapon/storage/pill_bottle/happy,
prob(4);/obj/item/weapon/storage/pill_bottle/zoom,
- prob(10);/obj/item/weapon/contraband/poster,
+ prob(10);/obj/item/weapon/contraband/poster/custom,
prob(4);/obj/item/weapon/material/butterfly,
prob(6);/obj/item/weapon/material/butterflyblade,
prob(6);/obj/item/weapon/material/butterflyhandle,
@@ -362,6 +362,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/peppermintschnapps,
/obj/item/weapon/reagent_containers/food/drinks/bottle/peachschnapps,
/obj/item/weapon/reagent_containers/food/drinks/bottle/lemonadeschnapps,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/jager,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/litebeer,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer,
@@ -626,7 +627,12 @@
/obj/item/toy/figure/warden,
/obj/item/toy/figure/psychologist,
/obj/item/toy/figure/paramedic,
- /obj/item/toy/figure/ert)
+ /obj/item/toy/figure/ert,
+ //chompstation Add start
+ /obj/item/toy/figure/station,
+ /obj/item/toy/sif)
+ //chompstation Add end
+
/obj/random/plushie
name = "random plushie"
diff --git a/code/game/objects/structures/cliff.dm b/code/game/objects/structures/cliff.dm
index 66fb945988..ad4b23bdb8 100644
--- a/code/game/objects/structures/cliff.dm
+++ b/code/game/objects/structures/cliff.dm
@@ -1,236 +1,252 @@
-GLOBAL_LIST_EMPTY(cliff_icon_cache)
-
-/*
-Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
-
-Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
-where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
-
-Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
-
-Flying mobs can pass over all cliffs with no risk of falling.
-
-Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
-This makes fighting something that is on top of a cliff more challenging.
-
-As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
-
-When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
-two tiles on initialization, and which way a cliff is facing may change during maploading.
-*/
-
-/obj/structure/cliff
- name = "cliff"
- desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
- description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury. \
- You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff. \
- Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
- on top."
- icon = 'icons/obj/flora/rocks.dmi'
-
- anchored = TRUE
- density = TRUE
- opacity = FALSE
- climbable = TRUE
- climb_delay = 10 SECONDS
- block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
- register_as_dangerous_object = TRUE
-
- var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
- var/corner = FALSE // Used for icon things.
- var/ramp = FALSE // Ditto.
- var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
-
- var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
- var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
-
-// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
-/obj/structure/cliff/automatic
- icon_state = "cliffbuilder"
- dir = NORTH
-
-/obj/structure/cliff/automatic/corner
- icon_state = "cliffbuilder-corner"
- dir = NORTHEAST
- corner = TRUE
-
-// Tiny part that doesn't block, used for making 'ramps'.
-/obj/structure/cliff/automatic/ramp
- icon_state = "cliffbuilder-ramp"
- dir = NORTHEAST
- density = FALSE
- ramp = TRUE
-
-// Made automatically as needed by automatic cliffs.
-/obj/structure/cliff/bottom
- bottom = TRUE
-
-/obj/structure/cliff/automatic/Initialize()
- ..()
- return INITIALIZE_HINT_LATELOAD
-
-// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
-/obj/structure/cliff/automatic/LateInitialize()
- if(dir in GLOB.cardinal)
- icon_variant = pick("a", "b", "c")
-
- if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
- make_bottom()
-
- update_icon()
-
-/obj/structure/cliff/proc/make_bottom()
- // First, make sure there's room to put the bottom side.
- var/turf/T = locate(x, y - 1, z)
- if(!istype(T))
- return FALSE
-
- // Now make the bottom cliff have mostly the same variables.
- var/obj/structure/cliff/bottom/bottom = new(T)
- is_double_cliff = TRUE
- climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
-
- bottom.dir = dir
- bottom.is_double_cliff = TRUE
- bottom.climb_delay = climb_delay
- bottom.icon_variant = icon_variant
- bottom.corner = corner
- bottom.ramp = ramp
- bottom.layer = layer - 0.1
- bottom.density = density
- bottom.update_icon()
-
-/obj/structure/cliff/set_dir(new_dir)
- ..()
- update_icon()
-
-/obj/structure/cliff/update_icon()
- icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
-
- // Now for making the top-side look like a different turf.
- var/turf/T = get_step(src, dir)
- if(!istype(T))
- return
-
- var/subtraction_icon_state = "[icon_state]-subtract"
- var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
- if(T && subtraction_icon_state in cached_icon_states(icon))
- cut_overlays()
- // If we've made the same icon before, just recycle it.
- if(cache_string in GLOB.cliff_icon_cache)
- add_overlay(GLOB.cliff_icon_cache[cache_string])
-
- else // Otherwise make a new one, but only once.
- var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
- var/icon/subtract = icon(icon, subtraction_icon_state)
- underlying_ground.Blend(subtract, ICON_SUBTRACT)
- var/image/final = image(underlying_ground)
- final.layer = src.layer - 0.2
- GLOB.cliff_icon_cache[cache_string] = final
- add_overlay(final)
-
-
-// Movement-related code.
-
-/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
- if(isliving(mover))
- var/mob/living/L = mover
- if(L.hovering) // Flying mobs can always pass.
- return TRUE
- return ..()
-
- // Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
- else if(istype(mover, /obj))
- var/obj/O = mover
- if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
- if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
- return FALSE
- return TRUE
-
-/obj/structure/cliff/Bumped(atom/A)
- if(isliving(A))
- var/mob/living/L = A
- if(should_fall(L))
- fall_off_cliff(L)
- return
- ..()
-
-/obj/structure/cliff/proc/should_fall(mob/living/L)
- if(L.hovering)
- return FALSE
-
- var/turf/T = get_turf(L)
- if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
- return TRUE
- return FALSE
-
-/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
- if(!istype(L))
- return FALSE
- var/turf/T = get_step(src, reverse_dir[dir])
- var/displaced = FALSE
-
- if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
- for(var/i = 1 to 2)
- var/turf/new_T = locate(T.x, T.y - i, T.z)
- if(!new_T || locate(/obj/structure/cliff) in new_T)
- break
- T = new_T
- displaced = TRUE
-
- if(istype(T))
- visible_message(span("danger", "\The [L] falls off \the [src]!"))
- L.forceMove(T)
-
- // Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
- var/harm = !is_double_cliff ? 1 : 0.5
- if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
- var/obj/vehicle/vehicle = L.buckled
- vehicle.adjust_health(40 * harm)
- to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
- harm /= 2
-
- playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
- L.Weaken(5 * harm)
- var/fall_time = 3
- if(displaced) // Make the fall look more natural when falling sideways.
- L.pixel_z = 32 * 2
- animate(L, pixel_z = 0, time = fall_time)
- sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
- playsound(L, "punch", 70, 1)
- shake_camera(L, 1, 1)
- visible_message(span("danger", "\The [L] hits the ground!"))
-
- // The bigger they are, the harder they fall.
- // They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
- // This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
- var/damage = between(20, L.getMaxHealth() * 0.4, 100)
- var/target_zone = ran_zone()
- var/blocked = L.run_armor_check(target_zone, "melee") * harm
- var/soaked = L.get_armor_soak(target_zone, "melee") * harm
-
- L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
-
- // Now fall off more cliffs below this one if they exist.
- var/obj/structure/cliff/bottom_cliff = locate() in T
- if(bottom_cliff)
- visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
- sleep(5)
- bottom_cliff.fall_off_cliff(L)
-
-/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
- // Cliff climbing requires climbing gear.
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- var/obj/item/clothing/shoes/shoes = H.shoes
- if(shoes && shoes.rock_climbing)
- return ..() // Do the other checks too.
-
- to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
- return FALSE
-
-// This tells AI mobs to not be dumb and step off cliffs willingly.
-/obj/structure/cliff/is_safe_to_step(mob/living/L)
- if(should_fall(L))
- return FALSE
- return ..()
+GLOBAL_LIST_EMPTY(cliff_icon_cache)
+
+/*
+Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
+
+Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
+where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
+
+Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
+
+Flying mobs can pass over all cliffs with no risk of falling.
+
+Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
+This makes fighting something that is on top of a cliff more challenging.
+
+As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
+
+When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
+two tiles on initialization, and which way a cliff is facing may change during maploading.
+*/
+
+/obj/structure/cliff
+ name = "cliff"
+ desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
+ description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury. \
+ You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff. \
+ Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
+ on top."
+ icon = 'icons/obj/flora/rocks.dmi'
+
+ anchored = TRUE
+ density = TRUE
+ opacity = FALSE
+ climbable = TRUE
+ climb_delay = 10 SECONDS
+ block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
+
+ var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
+ var/corner = FALSE // Used for icon things.
+ var/ramp = FALSE // Ditto.
+ var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
+
+ var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
+ var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
+
+/obj/structure/cliff/Initialize()
+ . = ..()
+ register_dangerous_to_step()
+
+/obj/structure/cliff/Destroy()
+ unregister_dangerous_to_step()
+ . = ..()
+
+/obj/structure/cliff/Moved(atom/oldloc)
+ . = ..()
+ if(.)
+ var/turf/old_turf = get_turf(oldloc)
+ var/turf/new_turf = get_turf(src)
+ if(old_turf != new_turf)
+ old_turf.unregister_dangerous_object(src)
+ new_turf.register_dangerous_object(src)
+
+// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
+/obj/structure/cliff/automatic
+ icon_state = "cliffbuilder"
+ dir = NORTH
+
+/obj/structure/cliff/automatic/corner
+ icon_state = "cliffbuilder-corner"
+ dir = NORTHEAST
+ corner = TRUE
+
+// Tiny part that doesn't block, used for making 'ramps'.
+/obj/structure/cliff/automatic/ramp
+ icon_state = "cliffbuilder-ramp"
+ dir = NORTHEAST
+ density = FALSE
+ ramp = TRUE
+
+// Made automatically as needed by automatic cliffs.
+/obj/structure/cliff/bottom
+ bottom = TRUE
+
+/obj/structure/cliff/automatic/Initialize()
+ ..()
+ return INITIALIZE_HINT_LATELOAD
+
+// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
+/obj/structure/cliff/automatic/LateInitialize()
+ if(dir in GLOB.cardinal)
+ icon_variant = pick("a", "b", "c")
+
+ if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
+ make_bottom()
+
+ update_icon()
+
+/obj/structure/cliff/proc/make_bottom()
+ // First, make sure there's room to put the bottom side.
+ var/turf/T = locate(x, y - 1, z)
+ if(!istype(T))
+ return FALSE
+
+ // Now make the bottom cliff have mostly the same variables.
+ var/obj/structure/cliff/bottom/bottom = new(T)
+ is_double_cliff = TRUE
+ climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
+
+ bottom.dir = dir
+ bottom.is_double_cliff = TRUE
+ bottom.climb_delay = climb_delay
+ bottom.icon_variant = icon_variant
+ bottom.corner = corner
+ bottom.ramp = ramp
+ bottom.layer = layer - 0.1
+ bottom.density = density
+ bottom.update_icon()
+
+/obj/structure/cliff/set_dir(new_dir)
+ ..()
+ update_icon()
+
+/obj/structure/cliff/update_icon()
+ icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
+
+ // Now for making the top-side look like a different turf.
+ var/turf/T = get_step(src, dir)
+ if(!istype(T))
+ return
+
+ var/subtraction_icon_state = "[icon_state]-subtract"
+ var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
+ if(T && subtraction_icon_state in cached_icon_states(icon))
+ cut_overlays()
+ // If we've made the same icon before, just recycle it.
+ if(cache_string in GLOB.cliff_icon_cache)
+ add_overlay(GLOB.cliff_icon_cache[cache_string])
+
+ else // Otherwise make a new one, but only once.
+ var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
+ var/icon/subtract = icon(icon, subtraction_icon_state)
+ underlying_ground.Blend(subtract, ICON_SUBTRACT)
+ var/image/final = image(underlying_ground)
+ final.layer = src.layer - 0.2
+ GLOB.cliff_icon_cache[cache_string] = final
+ add_overlay(final)
+
+
+// Movement-related code.
+
+/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
+ if(isliving(mover))
+ var/mob/living/L = mover
+ if(L.hovering) // Flying mobs can always pass.
+ return TRUE
+ return ..()
+
+ // Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
+ else if(istype(mover, /obj))
+ var/obj/O = mover
+ if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
+ if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
+ return FALSE
+ return TRUE
+
+/obj/structure/cliff/Bumped(atom/A)
+ if(isliving(A))
+ var/mob/living/L = A
+ if(should_fall(L))
+ fall_off_cliff(L)
+ return
+ ..()
+
+/obj/structure/cliff/proc/should_fall(mob/living/L)
+ if(L.hovering)
+ return FALSE
+
+ var/turf/T = get_turf(L)
+ if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
+ return TRUE
+ return FALSE
+
+/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
+ if(!istype(L))
+ return FALSE
+ var/turf/T = get_step(src, reverse_dir[dir])
+ var/displaced = FALSE
+
+ if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
+ for(var/i = 1 to 2)
+ var/turf/new_T = locate(T.x, T.y - i, T.z)
+ if(!new_T || locate(/obj/structure/cliff) in new_T)
+ break
+ T = new_T
+ displaced = TRUE
+
+ if(istype(T))
+ visible_message(span("danger", "\The [L] falls off \the [src]!"))
+ L.forceMove(T)
+
+ // Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
+ var/harm = !is_double_cliff ? 1 : 0.5
+ if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
+ var/obj/vehicle/vehicle = L.buckled
+ vehicle.adjust_health(40 * harm)
+ to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
+ harm /= 2
+
+ playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
+ L.Weaken(5 * harm)
+ var/fall_time = 3
+ if(displaced) // Make the fall look more natural when falling sideways.
+ L.pixel_z = 32 * 2
+ animate(L, pixel_z = 0, time = fall_time)
+ sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
+ playsound(L, "punch", 70, 1)
+ shake_camera(L, 1, 1)
+ visible_message(span("danger", "\The [L] hits the ground!"))
+
+ // The bigger they are, the harder they fall.
+ // They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
+ // This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
+ var/damage = between(20, L.getMaxHealth() * 0.4, 100)
+ var/target_zone = ran_zone()
+ var/blocked = L.run_armor_check(target_zone, "melee") * harm
+ var/soaked = L.get_armor_soak(target_zone, "melee") * harm
+
+ L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
+
+ // Now fall off more cliffs below this one if they exist.
+ var/obj/structure/cliff/bottom_cliff = locate() in T
+ if(bottom_cliff)
+ visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
+ sleep(5)
+ bottom_cliff.fall_off_cliff(L)
+
+/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
+ // Cliff climbing requires climbing gear.
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ var/obj/item/clothing/shoes/shoes = H.shoes
+ if(shoes && shoes.rock_climbing)
+ return ..() // Do the other checks too.
+
+ to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
+ return FALSE
+
+// This tells AI mobs to not be dumb and step off cliffs willingly.
+/obj/structure/cliff/is_safe_to_step(mob/living/L)
+ if(should_fall(L))
+ return FALSE
+ return ..()
diff --git a/code/game/objects/structures/crates_lockers/__closets.dm b/code/game/objects/structures/crates_lockers/__closets.dm
index 2706e11bd3..64c865604e 100644
--- a/code/game/objects/structures/crates_lockers/__closets.dm
+++ b/code/game/objects/structures/crates_lockers/__closets.dm
@@ -37,7 +37,6 @@
/obj/structure/closet/Initialize()
..()
- // Closets need to come later because of spawners potentially creating objects during init.
return INITIALIZE_HINT_LATELOAD
/obj/structure/closet/LateInitialize()
@@ -47,7 +46,7 @@
starts_with = null
if(!opened) // if closed, any item at the crate's loc is put in the contents
- if(istype(loc, /mob/living)) return //VOREStation Edit - No collecting mob organs if spawned inside mob
+ if(istype(loc, /mob/living)) return
var/obj/item/I
for(I in loc)
if(I.density || I.anchored || I == src) continue
@@ -260,7 +259,20 @@
return
/obj/structure/closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(opened)
+ if(W.is_wrench())
+ if(opened)
+ if(anchored)
+ user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
+ else
+ user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
+ if(do_after(user, 20 * W.toolspeed))
+ if(!src) return
+ to_chat(user, "You [anchored? "un" : ""]secured \the [src]!")
+ anchored = !anchored
+ return
+ else
+ to_chat(user, "You can't reach the anchoring bolts when the door is closed!")
+ else if(opened)
if(istype(W, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = W
MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
@@ -316,17 +328,6 @@
update_icon()
for(var/mob/M in viewers(src))
M.show_message("[src] has been [sealed?"sealed":"unsealed"] by [user.name].", 3)
- else if(W.is_wrench())
- if(sealed)
- if(anchored)
- user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
- else
- user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
- playsound(src, W.usesound, 50)
- if(do_after(user, 20 * W.toolspeed))
- if(!src) return
- to_chat(user, "You [anchored? "un" : ""]secured \the [src]!")
- anchored = !anchored
else
attack_hand(user)
return
diff --git a/code/game/objects/structures/crates_lockers/closets/egg_vr.dm b/code/game/objects/structures/crates_lockers/closets/egg_vr.dm
index ba0809f638..dabc8fd88b 100644
--- a/code/game/objects/structures/crates_lockers/closets/egg_vr.dm
+++ b/code/game/objects/structures/crates_lockers/closets/egg_vr.dm
@@ -36,11 +36,11 @@
icon_opened = "egg_unathi_open"
/obj/structure/closet/secure_closet/egg/nevrean
- name = "nevarean egg"
- desc = "Most Nevareans lay hard-shelled eggs!"
- icon_state = "egg_nevarean"
- icon_closed = "egg_nevarean"
- icon_opened = "egg_nevarean_open"
+ name = "nevrean egg"
+ desc = "Most Nevreans lay hard-shelled eggs!"
+ icon_state = "egg_nevrean"
+ icon_closed = "egg_nevrean"
+ icon_opened = "egg_nevrean_open"
/obj/structure/closet/secure_closet/egg/human
name = "human egg"
diff --git a/code/game/objects/structures/crates_lockers/closets/misc_vr.dm b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm
index c76771d8ce..73f69ba4a5 100644
--- a/code/game/objects/structures/crates_lockers/closets/misc_vr.dm
+++ b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm
@@ -133,7 +133,6 @@
/obj/item/clothing/gloves/fingerless,
/obj/item/device/radio/headset/pilot,
/obj/item/device/radio/headset/pilot/alt,
- /obj/item/weapon/cartridge/explorer,
/obj/item/device/flashlight,
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
index e5fc47c64a..9fae830b44 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
@@ -54,7 +54,20 @@
to_chat(user, "Access Denied")
/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(opened)
+ if(W.is_wrench())
+ if(opened)
+ if(anchored)
+ user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
+ else
+ user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
+ if(do_after(user, 20 * W.toolspeed))
+ if(!src) return
+ to_chat(user, "You [anchored? "un" : ""]secured \the [src]!")
+ anchored = !anchored
+ return
+ else
+ to_chat(user, "You can't reach the anchoring bolts when the door is closed!")
+ else if(opened)
if(istype(W, /obj/item/weapon/storage/laundry_basket))
return ..(W,user)
if(istype(W, /obj/item/weapon/grab))
@@ -77,17 +90,6 @@
spark_system.start()
playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
playsound(src, "sparks", 50, 1)
- else if(W.is_wrench())
- if(sealed)
- if(anchored)
- user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
- else
- user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
- if(do_after(user, 20 * W.toolspeed))
- if(!src) return
- to_chat(user, "You [anchored? "un" : ""]secured \the [src]!")
- anchored = !anchored
- return
else if(istype(W,/obj/item/weapon/packageWrap) || istype(W,/obj/item/weapon/weldingtool))
return ..(W,user)
else
diff --git a/code/game/objects/structures/dancepole_vr.dm b/code/game/objects/structures/dancepole_vr.dm
new file mode 100644
index 0000000000..0c9397142d
--- /dev/null
+++ b/code/game/objects/structures/dancepole_vr.dm
@@ -0,0 +1,25 @@
+//Dance pole
+/obj/structure/dancepole
+ name = "dance pole"
+ desc = "Engineered for your entertainment"
+ icon = 'icons/obj/objects_vr.dmi'
+ icon_state = "dancepole"
+ density = 0
+ anchored = 1
+
+/obj/structure/dancepole/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(O.is_screwdriver())
+ anchored = !anchored
+ playsound(src, O.usesound, 50, 1)
+ if(anchored)
+ to_chat(user, "You secure \the [src].")
+ else
+ to_chat(user, "You unsecure \the [src].")
+ if(O.is_wrench())
+ playsound(src, O.usesound, 50, 1)
+ to_chat(user, "Now disassembling \the [src]...")
+ if(do_after(user, 30 * O.toolspeed))
+ if(!src) return
+ to_chat(user, "You dissasembled \the [src]!")
+ new /obj/item/stack/material/steel(src.loc, 1)
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm
index bccdcf56c3..f584fd8838 100644
--- a/code/game/objects/structures/fireaxe.dm
+++ b/code/game/objects/structures/fireaxe.dm
@@ -14,7 +14,7 @@
var/smashed = 0
/obj/structure/fireaxecabinet/Initialize()
- ..()
+ . = ..()
fireaxe = new /obj/item/weapon/material/twohanded/fireaxe()
/obj/structure/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
diff --git a/code/game/objects/structures/flora/flora.dm b/code/game/objects/structures/flora/flora.dm
index cc5c5b510f..e97c7b84bb 100644
--- a/code/game/objects/structures/flora/flora.dm
+++ b/code/game/objects/structures/flora/flora.dm
@@ -22,7 +22,7 @@
var/list/harvest_loot = null // Should be an associative list for things to spawn, and their weights. An example would be a branch from a tree.
/obj/structure/flora/Initialize()
- ..()
+ . = ..()
if(randomize_size)
icon_scale_x = rand(min_x_scale * 100, max_x_scale * 100) / 100
diff --git a/code/game/objects/structures/ghost_pods/event_vr.dm b/code/game/objects/structures/ghost_pods/event_vr.dm
index c724b9bd80..469f27f27e 100644
--- a/code/game/objects/structures/ghost_pods/event_vr.dm
+++ b/code/game/objects/structures/ghost_pods/event_vr.dm
@@ -21,6 +21,7 @@
"Jelly Blob" = /mob/living/simple_mob/animal/space/jelly,
"Wolf" = /mob/living/simple_mob/animal/wolf,
"Sect Queen" = /mob/living/simple_mob/vore/sect_queen,
+ "Sect Drone" = /mob/living/simple_mob/vore/sect_drone,
"Defanged Xenomorph" = /mob/living/simple_mob/vore/xeno_defanged,
)
@@ -37,7 +38,7 @@
break
if(choice)
- finalized = alert(M, "Are you sure you want to play as [choice]?","Confirmation","No","Yes")
+ finalized = alert(M, "Are you sure you want to play as [choice]? By clicking yes you should expect to be treated as vore predator and possibly killed. Do not attack other players. You will have minimal OOC pref protections.","Confirmation","No","Yes")
if(randomize)
choice = pick(possible_mobs)
@@ -98,4 +99,4 @@
qdel(src)
/obj/structure/ghost_pod/ghost_activated/morphspawn/no_announce
- announce_prob = 0
\ No newline at end of file
+ announce_prob = 0
diff --git a/code/game/objects/structures/ghost_pods/ghost_pods.dm b/code/game/objects/structures/ghost_pods/ghost_pods.dm
index 386d493d2d..7649c8573f 100644
--- a/code/game/objects/structures/ghost_pods/ghost_pods.dm
+++ b/code/game/objects/structures/ghost_pods/ghost_pods.dm
@@ -28,7 +28,7 @@
icon_state = icon_state_opened
if(needscharger)
new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc)
- del(src)
+ qdel(src)
return TRUE
else
return FALSE
diff --git a/code/game/objects/structures/ghost_pods/ghost_pods_vr.dm b/code/game/objects/structures/ghost_pods/ghost_pods_vr.dm
index 2d8f8198c5..08cb7c78ba 100644
--- a/code/game/objects/structures/ghost_pods/ghost_pods_vr.dm
+++ b/code/game/objects/structures/ghost_pods/ghost_pods_vr.dm
@@ -45,5 +45,5 @@
trigger()
/obj/structure/ghost_pod/ghost_activated/Initialize()
- ..()
+ . = ..()
ghostpod_startup(spawn_active)
\ No newline at end of file
diff --git a/code/game/objects/structures/ghost_pods/human.dm b/code/game/objects/structures/ghost_pods/human.dm
index 814db9cd75..f2b3291597 100644
--- a/code/game/objects/structures/ghost_pods/human.dm
+++ b/code/game/objects/structures/ghost_pods/human.dm
@@ -25,7 +25,7 @@
var/list/clothing_possibilities
/obj/structure/ghost_pod/ghost_activated/human/Initialize()
- ..()
+ . = ..()
handle_clothing_setup()
@@ -153,7 +153,7 @@
var/list/clothing_possibilities
/obj/structure/ghost_pod/manual/human/Initialize()
- ..()
+ . = ..()
handle_clothing_setup()
diff --git a/code/game/objects/structures/ghost_pods/silicon.dm b/code/game/objects/structures/ghost_pods/silicon.dm
index 32a26ce479..74f53e9204 100644
--- a/code/game/objects/structures/ghost_pods/silicon.dm
+++ b/code/game/objects/structures/ghost_pods/silicon.dm
@@ -89,7 +89,7 @@
qdel(src)
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/Initialize()
- ..()
+ . = ..()
var/turf/T = get_turf(src)
say_dead_object("A [drone_class] swarm drone shell is now available in \the [T.loc].", src)
diff --git a/code/game/objects/structures/loot_piles.dm b/code/game/objects/structures/loot_piles.dm
index 57c9832fde..01069b8e23 100644
--- a/code/game/objects/structures/loot_piles.dm
+++ b/code/game/objects/structures/loot_piles.dm
@@ -254,8 +254,8 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
/obj/item/stack/material/steel{amount = 5},
/obj/item/stack/material/cardboard{amount = 5},
/obj/item/weapon/contraband/poster,
+ /obj/item/weapon/contraband/poster/custom,
/obj/item/weapon/material/wirerod,
- /obj/item/weapon/contraband/poster,
/obj/item/weapon/newspaper,
/obj/item/weapon/paper/crumpled,
/obj/item/weapon/paper/crumpled/bloody
@@ -376,6 +376,7 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
/obj/item/weapon/tool/wrench,
/obj/item/weapon/tool/screwdriver,
/obj/item/weapon/tool/wirecutters,
+ /obj/item/weapon/mining_scanner/advanced,
/obj/item/device/multitool,
/obj/item/mecha_parts/mecha_equipment/generator,
/obj/item/mecha_parts/mecha_equipment/tool/cable_layer,
diff --git a/code/game/objects/structures/props/nest.dm b/code/game/objects/structures/props/nest.dm
index 4cb515fc36..ba16b0b055 100644
--- a/code/game/objects/structures/props/nest.dm
+++ b/code/game/objects/structures/props/nest.dm
@@ -20,7 +20,7 @@
var/total_creature_max //If set, it can spawn this many creatures, total, ever.
/obj/structure/prop/nest/Initialize()
- ..()
+ . = ..()
den_mobs = list()
START_PROCESSING(SSobj, src)
last_spawn = world.time
diff --git a/code/game/objects/structures/props/swarm.dm b/code/game/objects/structures/props/swarm.dm
index 128254a456..51f59072f4 100644
--- a/code/game/objects/structures/props/swarm.dm
+++ b/code/game/objects/structures/props/swarm.dm
@@ -23,7 +23,7 @@
return ..()
/obj/structure/cult/pylon/swarm/Initialize()
- ..()
+ . = ..()
active_beams = list()
/obj/structure/cult/pylon/swarm/Destroy()
diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm
index f93ceaf0a1..78384b0285 100644
--- a/code/game/objects/structures/signs.dm
+++ b/code/game/objects/structures/signs.dm
@@ -321,73 +321,344 @@
desc = "A warning sign which reads XENOBIOLOGY."
icon_state = "xenobio3"
+//direction signs presented by the order they appear in the dmi
/obj/structure/sign/directions
name = "direction sign"
- desc = "A direction sign, claiming to know the way."
+ desc = "A direction sign, claiming to know the way to... somewhere?"
icon_state = "direction"
+ icon = 'icons/obj/decals_directions.dmi'
+ //TODO: set up overlay systems, inc. interactions (e.g. vines clear w/ plantbgone or fire, snow can be brushed off or melted, and so on)
+//disabled this proc, it serves no purpose except to overwrite the description that already exists. may have been intended for making your own signs?
+//seems to defeat the point of having a generic directional sign that mappers could edit and use in POIs? left it here in case something breaks.
+/*
/obj/structure/sign/directions/New()
..()
- desc = "A direction sign, pointing out which way \the [src] is."
-
-/obj/structure/sign/directions/science
- name = "\improper Science department"
- desc = "A direction sign, pointing out which way the Science department is."
- icon_state = "direction_sci"
+ desc = "A direction sign, pointing out the way to \the [src]."
+*/
+//engineering signs
/obj/structure/sign/directions/engineering
- name = "\improper Engineering department"
- desc = "A direction sign, pointing out which way the Engineering department is."
+ name = "\improper Engineering Department"
+ desc = "A direction sign, pointing out the way to the Engineering Department."
icon_state = "direction_eng"
+/obj/structure/sign/directions/engineering/reactor
+ name = "\improper Reactor"
+ desc = "A direction sign, pointing out the way to the Reactor."
+ icon_state = "direction_core"
+
+/obj/structure/sign/directions/engineering/solars
+ name = "\improper Solar Array"
+ desc = "A direction sign, pointing out the way to the nearest Solar Array."
+ icon_state = "direction_solar"
+
+/obj/structure/sign/directions/engineering/atmospherics
+ name = "\improper Atmospherics Department"
+ desc = "A direction sign, pointing out the way to the Atmospherics Department."
+ icon_state = "direction_atmos"
+
+/obj/structure/sign/directions/engineering/gravgen
+ name = "\improper Gravity Generator"
+ desc = "A direction sign, pointing out the way to the Artificial Gravity Generator."
+ icon_state = "direction_grav"
+
+/obj/structure/sign/directions/engineering/engeqp
+ name = "\improper Engineering Equipment Storage"
+ desc = "A direction sign, pointing out the way to Engineering Equipment Storage."
+ icon_state = "direction_engeqp"
+
+//security signs
/obj/structure/sign/directions/security
- name = "\improper Security department"
- desc = "A direction sign, pointing out which way the Security department is."
+ name = "\improper Security Department"
+ desc = "A direction sign, pointing out the way to the Security Department."
icon_state = "direction_sec"
+/obj/structure/sign/directions/security/armory
+ name = "\improper Armory"
+ desc = "A direction sign, pointing out the way to the Armory."
+ icon_state = "direction_armory"
+
+/obj/structure/sign/directions/security/brig
+ name = "\improper Brig"
+ desc = "A direction sign, pointing out the way to the Brig."
+ icon_state = "direction_brig"
+
+/obj/structure/sign/directions/security/seceqp
+ name = "\improper Security Equipment Storage"
+ desc = "A direction sign, pointing out the way to Security Equipment Storage."
+ icon_state = "direction_seceqp"
+
+/obj/structure/sign/directions/security/internal_affairs
+ name = "\improper Internal Affairs Office"
+ desc = "A direction sign, pointing out the way to the Internal Affairs Office."
+ icon_state = "direction_intaff"
+
+/obj/structure/sign/directions/security/forensics
+ name = "\improper Forensics Lab"
+ desc = "A direction sign, pointing out the way to the Forensics Lab."
+ icon_state = "direction_forensics"
+
+/obj/structure/sign/directions/security/forensics/alt
+ icon_state = "direction_lab"
+
+/obj/structure/sign/directions/security/interrogation
+ name = "\improper Interrogations"
+ desc = "A direction sign, pointing out the way to Interrogations."
+ icon_state = "direction_interrogation"
+
+//science signs
+/obj/structure/sign/directions/science
+ name = "\improper Science Department"
+ desc = "A direction sign, pointing out the way to the Science Department."
+ icon_state = "direction_sci"
+
+/obj/structure/sign/directions/science/rnd
+ name = "\improper Research & Development"
+ desc = "A direction sign, pointing out the way to Research & Development."
+ icon_state = "direction_rnd"
+
+/obj/structure/sign/directions/science/toxins
+ name = "\improper Toxins Lab"
+ desc = "A direction sign, pointing out the way to the Toxins Lab."
+ icon_state = "direction_sci"
+
+/obj/structure/sign/directions/science/robotics
+ name = "\improper Robotics Workshop"
+ desc = "A direction sign, pointing out the way to the Robotics Workshop."
+ icon_state = "direction_robotics"
+
+/obj/structure/sign/directions/science/xenoarch
+ name = "\improper Xenoarchaeology Lab"
+ desc = "A direction sign, pointing out the way to the Xenoarchaeology Lab."
+ icon_state = "direction_xenoarch"
+
+/obj/structure/sign/directions/science/xenobiology
+ name = "\improper Xenobiology Lab"
+ desc = "A direction sign, pointing out the way to the Xenobiology Lab."
+ icon_state = "direction_xbio"
+
+/obj/structure/sign/directions/science/xenoflora
+ name = "\improper Xenoflora Lab"
+ desc = "A direction sign, pointing out the way to the Xenoflora Lab."
+ icon_state = "direction_xflora"
+
+/obj/structure/sign/directions/science/exploration
+ name = "\improper Exploration Department"
+ desc = "A direction sign, pointing out the way to the Exploration Department."
+ icon_state = "direction_explo"
+
+//medical signs
/obj/structure/sign/directions/medical
name = "\improper Medical Bay"
- desc = "A direction sign, pointing out which way the Medical Bay is."
+ desc = "A direction sign, pointing out the way to the Medical Bay."
icon_state = "direction_med"
+/obj/structure/sign/directions/medical/chemlab
+ name = "\improper Chemistry Lab"
+ desc = "A direction sign, pointing out the way to the Chemistry Lab."
+ icon_state = "direction_med"
+
+/obj/structure/sign/directions/medical/surgery
+ name = "\improper Surgery"
+ desc = "A direction sign, pointing out the way to Surgery."
+ icon_state = "direction_surgery"
+
+/obj/structure/sign/directions/medical/operating_1
+ name = "\improper Operating Theatre 1"
+ desc = "A direction sign, pointing out the way to Operating Theatre 1."
+ icon_state = "direction_op1"
+
+/obj/structure/sign/directions/medical/operating_2
+ name = "\improper Operating Theatre 2"
+ desc = "A direction sign, pointing out the way to Operating Theatre 2."
+ icon_state = "direction_op2"
+
+/obj/structure/sign/directions/medical/virology
+ name = "\improper Virology"
+ desc = "A direction sign, pointing out the way to the Virology Lab."
+ icon_state = "direction_viro"
+
+/obj/structure/sign/directions/medical/medeqp
+ name = "\improper Medical Equipment Storage"
+ desc = "A direction sign, pointing out the way to Medical Equipment Storage."
+ icon_state = "direction_medeqp"
+
+/obj/structure/sign/directions/medical/morgue
+ name = "\improper Morgue"
+ desc = "A direction sign, pointing out the way to the Morgue."
+ icon_state = "direction_morgue"
+
+/obj/structure/sign/directions/medical/cloning
+ name = "\improper Cloning Lab"
+ desc = "A direction sign, pointing out the way to the Cloning Lab."
+ icon_state = "direction_cloning"
+
+/obj/structure/sign/directions/medical/resleeving
+ name = "\improper Resleeving Lab"
+ desc = "A direction sign, pointing out the way to the Resleeving Lab."
+ icon_state = "direction_resleeve"
+
+//special signs
/obj/structure/sign/directions/evac
name = "\improper Evacuation"
- desc = "A direction sign, pointing out which way the Escape Shuttle dock is."
+ desc = "A direction sign, pointing out the way to the Escape Shuttle Dock."
icon_state = "direction_evac"
+/obj/structure/sign/directions/eva
+ name = "\improper Extra-Vehicular Activity"
+ desc = "A direction sign, pointing out the way to the EVA Bay."
+ icon_state = "direction_eva"
+
+//command signs
+/obj/structure/sign/directions/ai_core
+ name = "\improper AI Core"
+ desc = "A direction sign, pointing out the way to the AI Core."
+ icon_state = "direction_ai_core"
+
/obj/structure/sign/directions/bridge
name = "\improper Bridge"
+ desc = "A direction sign, pointing out the way to the Bridge."
icon_state = "direction_bridge"
+/obj/structure/sign/directions/command
+ name = "\improper Command"
+ desc = "A direction sign, pointing out the way to the Command Center."
+ icon_state = "direction_command"
+
+/obj/structure/sign/directions/teleporter
+ name = "\improper Teleporter"
+ desc = "A direction sign, pointing out the way to the Teleporter."
+ icon_state = "direction_teleport"
+
+/obj/structure/sign/directions/telecomms
+ name = "\improper Telecommunications Hub"
+ desc = "A direction sign, pointing out the way to the Telecommunications Hub."
+ icon_state = "direction_tcomms"
+
+//cargonia signs
/obj/structure/sign/directions/cargo
- name = "\improper Cargo department"
- desc = "A direction sign, pointing out which way the Cargo department is."
+ name = "\improper Cargo Department"
+ desc = "A direction sign, pointing out the way to the Cargo Department."
icon_state = "direction_crg"
-// VOREStation Edit - New signs for us
-/obj/structure/sign/directions/command
- icon = 'icons/obj/decals_vr.dmi'
- name = "\improper Command department"
- desc = "A direction sign, pointing out which way the Command department is."
- icon_state = "direction_cmd"
+/obj/structure/sign/directions/cargo/mining
+ name = "\improper Mining Department"
+ desc = "A direction sign, pointing out the way to the Mining Department."
+ icon_state = "direction_mining"
-/obj/structure/sign/directions/elevator
- icon = 'icons/obj/decals_vr.dmi'
- name = "\improper Space Elevator"
- desc = "A direction sign, pointing out which way the Space Elevator is."
- icon_state = "direction_elv"
-// VOREStation Edit End
-
-/obj/structure/sign/directions/cryo
- name = "\improper Cryogenic Storage"
- desc = "A direction sign, pointing out which way cryogenic storage is."
- icon_state = "direction_cry"
+/obj/structure/sign/directions/cargo/refinery
+ name = "\improper Refinery"
+ desc = "A direction sign, pointing out the way to the Refinery."
+ icon_state = "direction_refinery"
+//civilian/misc signs
/obj/structure/sign/directions/roomnum
name = "room number"
desc = "A sign detailing the number of the room beside it."
icon_state = "roomnum"
+/obj/structure/sign/directions/cryo
+ name = "\improper Cryogenic Storage"
+ desc = "A direction sign, pointing out the way to Cryogenic Storage."
+ icon_state = "direction_cry"
+
+/obj/structure/sign/directions/elevator
+ name = "\improper Elevator"
+ desc = "A direction sign, pointing out the way to the nearest elevator."
+ icon_state = "direction_elv"
+
+/obj/structure/sign/directions/bar
+ name = "\improper Bar"
+ desc = "A direction sign, pointing out the way to the nearest watering hole."
+ icon_state = "direction_bar"
+
+/obj/structure/sign/directions/kitchen
+ name = "\improper Kitchen"
+ desc = "A pictographic direction sign with a knife, plate, and fork, pointing out the way to the nearest dining establishment."
+ icon_state = "direction_kitchen"
+
+/obj/structure/sign/directions/tram
+ name = "\improper Public Transit Station"
+ desc = "A direction sign, pointing out the way to the nearest public transit station."
+ icon_state = "direction_tram"
+
+/obj/structure/sign/directions/janitor
+ name = "\improper Custodial Closet"
+ desc = "A direction sign, pointing out the way to the Custodial Closet."
+ icon_state = "direction_janitor"
+
+/obj/structure/sign/directions/chapel
+ name = "\improper Chapel"
+ desc = "A direction sign, pointing out the way to the Chapel."
+ icon_state = "direction_chapel"
+
+/obj/structure/sign/directions/dorms
+ name = "\improper Dormitories"
+ desc = "A direction sign, pointing out the way to the Dormitories."
+ icon_state = "direction_dorms"
+
+/obj/structure/sign/directions/library
+ name = "\improper Library"
+ desc = "A direction sign, pointing out the way to the Library."
+ icon_state = "direction_library"
+
+/obj/structure/sign/directions/dock
+ name = "\improper Dock"
+ desc = "A direction sign, pointing out the way to the nearest docking area."
+ icon_state = "direction_dock"
+
+/obj/structure/sign/directions/gym
+ name = "\improper Gym"
+ desc = "A direction sign, pointing out the way to the Gym."
+ icon_state = "direction_gym"
+
+/obj/structure/sign/directions/pool
+ name = "\improper Pool"
+ desc = "A direction sign, pointing out the way to the Pool."
+ icon_state = "direction_pool"
+
+/obj/structure/sign/directions/recreation
+ name = "\improper Recreation Area"
+ desc = "A direction sign, pointing out the way to the nearest Recreation Area."
+ icon_state = "direction_recreation"
+
+/obj/structure/sign/directions/stairwell
+ name = "\improper Stairwell"
+ desc = "A direction sign with stairs and a door, pointing out the way to the nearest stairwell."
+ icon_state = "stairwell"
+
+/obj/structure/sign/directions/stairs_up
+ name = "\improper Stairs Up"
+ desc = "A direction sign with stairs and an upward-slanted arrow, pointing out the way to the nearest set of stairs that go up."
+ icon_state = "stairs_up"
+
+/obj/structure/sign/directions/stairs_down
+ name = "\improper Stairs Down"
+ desc = "A direction sign with stairs and a downward-slanted arrow, pointing out the way to the nearest set of stairs that go down."
+ icon_state = "stairs_down"
+
+/obj/structure/sign/directions/ladderwell
+ name = "\improper Access Shaft"
+ desc = "A direction sign with a ladder and a door, pointing out the way to the nearest access shaft."
+ icon_state = "ladderwell"
+
+/obj/structure/sign/directions/ladder_up
+ name = "\improper Ladder Up"
+ desc = "A direction sign with a ladder and an upward arrow, pointing out the way to the nearest ladder that goes up."
+ icon_state = "ladder_up"
+
+/obj/structure/sign/directions/ladder_down
+ name = "\improper Ladder Down"
+ desc = "A direction sign with a ladder and a downward arrow, pointing out the way to the nearest ladder that goes down."
+ icon_state = "ladder_down"
+
+/obj/structure/sign/directions/exit
+ name = "\improper Emergency Exit"
+ desc = "A lurid green sign that unmistakably identifies that the door it's next to as an emergency exit route."
+ icon_state = "exit_sign"
+
+//OTHER STUFF
/obj/structure/sign/christmas/lights
name = "Christmas lights"
desc = "Flashy and pretty."
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 089e65fc04..7459fcab6c 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -1,26 +1,59 @@
/obj/structure/bed/chair/wheelchair
name = "wheelchair"
desc = "You sit in this. Either by will or force."
+ icon = 'icons/obj/wheelchair.dmi'
icon_state = "wheelchair"
anchored = 0
buckle_movable = 1
+ var/folded_type = /obj/item/wheelchair
var/driving = 0
var/mob/living/pulling = null
var/bloodiness
+ var/min_mob_buckle_size = MOB_SMALL
+ var/max_mob_buckle_size = MOB_LARGE
+
+/obj/structure/bed/chair/wheelchair/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/structure/bed/chair/wheelchair/motor
+ name = "electric wheelchair"
+ desc = "A motorized wheelchair controlled with a joystick on one armrest"
+ icon_state = "motorchair"
+ folded_type = /obj/item/wheelchair/motor
+
+/obj/structure/bed/chair/wheelchair/smallmotor
+ name = "small electric wheelchair"
+ desc = "A small motorized wheelchair, it looks around the right size for a Teshari"
+ icon_state = "teshchair"
+ min_mob_buckle_size = MOB_SMALL
+ max_mob_buckle_size = MOB_MEDIUM
+ folded_type = /obj/item/wheelchair/motor/small
+
+/obj/structure/bed/chair/wheelchair/can_buckle_check(mob/living/M, forced = FALSE)
+ . = ..()
+ if(.)
+ if(M.mob_size < min_mob_buckle_size)
+ to_chat(M, SPAN_WARNING("You are too small to use \the [src]."))
+ . = FALSE
+ else if(M.mob_size >= max_mob_buckle_size)
+ to_chat(M, SPAN_WARNING("You are too large to use \the [src]."))
+ . = FALSE
/obj/structure/bed/chair/wheelchair/update_icon()
- return
+ cut_overlays()
+ var/image/O = image(icon = icon, icon_state = "[icon_state]_overlay", layer = ABOVE_MOB_LAYER)
+ O.plane = MOB_PLANE
+ add_overlay(O)
/obj/structure/bed/chair/wheelchair/set_dir()
- ..()
- cut_overlays()
- var/image/O = image(icon = 'icons/obj/furniture.dmi', icon_state = "w_overlay", layer = FLY_LAYER, dir = src.dir)
- add_overlay(O)
- if(has_buckled_mobs())
- for(var/A in buckled_mobs)
- var/mob/living/L = A
- L.set_dir(dir)
+ . = ..()
+ if(.)
+ if(has_buckled_mobs())
+ for(var/A in buckled_mobs)
+ var/mob/living/L = A
+ L.set_dir(dir)
/obj/structure/bed/chair/wheelchair/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.is_wrench() || W.is_wirecutter() || istype(W,/obj/item/stack))
@@ -93,8 +126,6 @@
/obj/structure/bed/chair/wheelchair/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
-
- cut_overlays()
playsound(src, 'sound/effects/roll.ogg', 75, 1)
if(has_buckled_mobs())
for(var/A in buckled_mobs)
@@ -203,28 +234,13 @@
usr.pulledby = null
..()
-/obj/item/wheelchair
- name = "wheelchair"
- desc = "A folded wheelchair that can be carried around."
- icon = 'icons/obj/furniture.dmi'
- icon_state = "wheelchair_folded"
- item_state = "wheelchair"
- w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well.
-
-/obj/item/wheelchair/attack_self(mob/user)
- var/obj/structure/bed/chair/wheelchair/R = new /obj/structure/bed/chair/wheelchair(user.loc)
- R.add_fingerprint(user)
- R.name = src.name
- R.color = src.color
- qdel(src)
-
/obj/structure/bed/chair/wheelchair/MouseDrop(over_object, src_location, over_location)
..()
if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
if(!ishuman(usr)) return
if(has_buckled_mobs()) return 0
visible_message("[usr] collapses \the [src.name].")
- var/obj/item/wheelchair/R = new/obj/item/wheelchair(get_turf(src))
+ var/obj/item/wheelchair/R = new folded_type(get_turf(src))
R.name = src.name
R.color = src.color
spawn(0)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair_item.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair_item.dm
new file mode 100644
index 0000000000..d18a9a88f1
--- /dev/null
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair_item.dm
@@ -0,0 +1,29 @@
+/obj/item/wheelchair
+ name = "wheelchair"
+ desc = "A folded wheelchair that can be carried around."
+ icon = 'icons/obj/wheelchair.dmi'
+ icon_state = "wheelchair_folded"
+ item_state = "wheelchair"
+ w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well.
+ var/unfolded_type = /obj/structure/bed/chair/wheelchair
+
+/obj/item/wheelchair/attack_self(mob/user)
+ var/obj/structure/bed/chair/wheelchair/R = new unfolded_type(user.loc)
+ R.add_fingerprint(user)
+ R.name = src.name
+ R.color = src.color
+ qdel(src)
+
+/obj/item/wheelchair/motor
+ name = "electric wheelchair"
+ desc = "A motorized wheelchair controlled with a joystick on one armrest"
+ icon_state = "motorchair_folded"
+ item_state = "motorchair"
+ unfolded_type = /obj/structure/bed/chair/wheelchair/motor
+
+/obj/item/wheelchair/motor/small
+ name = "small electric wheelchair"
+ desc = "A small motorized wheelchair, it looks around the right size for a Teshari."
+ icon_state = "teshchair_folded"
+ item_state = "teshchair"
+ unfolded_type = /obj/structure/bed/chair/wheelchair/smallmotor
diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm
index 60326d9bbf..593a961e4a 100644
--- a/code/game/objects/structures/trash_pile_vr.dm
+++ b/code/game/objects/structures/trash_pile_vr.dm
@@ -181,6 +181,7 @@
prob(2);/obj/item/clothing/shoes/galoshes,
prob(2);/obj/item/clothing/under/pants/camo,
prob(2);/obj/item/clothing/under/syndicate/tacticool,
+ prob(2);/obj/item/clothing/under/hyperfiber,
prob(2);/obj/item/device/camera,
prob(2);/obj/item/device/flashlight/flare,
prob(2);/obj/item/device/flashlight/glowstick,
@@ -242,6 +243,7 @@
prob(2);/obj/item/weapon/handcuffs/legcuffs/fuzzy,
prob(2);/obj/item/weapon/storage/box/syndie_kit/spy,
prob(2);/obj/item/weapon/grenade/anti_photon,
+ prob(2);/obj/item/clothing/under/hyperfiber/bluespace,
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
prob(1);/obj/item/device/nif/bad,
prob(1);/obj/item/device/radio_jammer,
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index a7037105d2..282a10f9e0 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -215,82 +215,14 @@
L.fire_stacks = -20 //Douse ourselves with water to avoid fire more easily
if(iscarbon(O))
- var/mob/living/carbon/M = O
- if(M.r_hand)
- M.r_hand.clean_blood()
- if(M.l_hand)
- M.l_hand.clean_blood()
- if(M.back)
- if(M.back.clean_blood())
- M.update_inv_back(0)
-
//flush away reagents on the skin
+ var/mob/living/carbon/M = O
if(M.touching)
var/remove_amount = M.touching.maximum_volume * M.reagent_permeability() //take off your suit first
M.touching.remove_any(remove_amount)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- var/washgloves = 1
- var/washshoes = 1
- var/washmask = 1
- var/washears = 1
- var/washglasses = 1
-
- if(H.wear_suit)
- washgloves = !(H.wear_suit.flags_inv & HIDEGLOVES)
- washshoes = !(H.wear_suit.flags_inv & HIDESHOES)
-
- if(H.head)
- washmask = !(H.head.flags_inv & HIDEMASK)
- washglasses = !(H.head.flags_inv & HIDEEYES)
- washears = !(H.head.flags_inv & HIDEEARS)
-
- if(H.wear_mask)
- if (washears)
- washears = !(H.wear_mask.flags_inv & HIDEEARS)
- if (washglasses)
- washglasses = !(H.wear_mask.flags_inv & HIDEEYES)
-
- if(H.head)
- if(H.head.clean_blood())
- H.update_inv_head(0)
- if(H.wear_suit)
- if(H.wear_suit.clean_blood())
- H.update_inv_wear_suit(0)
- else if(H.w_uniform)
- if(H.w_uniform.clean_blood())
- H.update_inv_w_uniform(0)
- if(H.gloves && washgloves)
- if(H.gloves.clean_blood())
- H.update_inv_gloves(0)
- if(H.shoes && washshoes)
- if(H.shoes.clean_blood())
- H.update_inv_shoes(0)
- if(H.wear_mask && washmask)
- if(H.wear_mask.clean_blood())
- H.update_inv_wear_mask(0)
- if(H.glasses && washglasses)
- if(H.glasses.clean_blood())
- H.update_inv_glasses(0)
- if(H.l_ear && washears)
- if(H.l_ear.clean_blood())
- H.update_inv_ears(0)
- if(H.r_ear && washears)
- if(H.r_ear.clean_blood())
- H.update_inv_ears(0)
- if(H.belt)
- if(H.belt.clean_blood())
- H.update_inv_belt(0)
- H.clean_blood(washshoes)
- else
- if(M.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags
- if(M.wear_mask.clean_blood())
- M.update_inv_wear_mask(0)
- M.clean_blood()
- else
- O.clean_blood()
-
+ M.clean_blood()
+
if(isturf(loc))
var/turf/tile = loc
for(var/obj/effect/E in tile)
diff --git a/code/game/objects/structures/watercloset_vr.dm b/code/game/objects/structures/watercloset_vr.dm
new file mode 100644
index 0000000000..7e8790fbcc
--- /dev/null
+++ b/code/game/objects/structures/watercloset_vr.dm
@@ -0,0 +1,41 @@
+//Flushable toilets on station levels. Flushing sends stuff directly to a trashpit landmark without stinking up the cargo office.
+//Only on-station toilets are affected and only if the trashpit landmark also exists. Otherwise toilets will stay normal.
+
+/obj/structure/toilet
+ var/teleplumbed = FALSE
+ var/exit_landmark
+
+/obj/structure/toilet/Initialize()
+ if(z in global.using_map.map_levels)
+ teleplumbed = TRUE
+ exit_landmark = locate(/obj/effect/landmark/teleplumb_exit)
+ if(teleplumbed && exit_landmark)
+ desc = "The BS-500, a bluespace rift-rotation-based waste disposal unit for small matter. This one seems remarkably clean."
+ return ..()
+
+/obj/structure/toilet/attack_hand(mob/living/user as mob)
+ if(open && teleplumbed && exit_landmark)
+ var/list/bowl_contents = list()
+ for(var/obj/item/I in loc.contents)
+ if(istype(I) && !I.anchored)
+ bowl_contents += I
+ if(bowl_contents.len)
+ user.visible_message("[user] flushes the toilet.", "You flush the toilet.")
+ playsound(src, 'sound/vore/death7.ogg', 50, 1) //Got lazy about getting new sound files. Have a sick remix lmao.
+ playsound(src, 'sound/effects/bubbles.ogg', 50, 1)
+ playsound(src, 'sound/mecha/powerup.ogg', 30, 1)
+ for(var/obj/item/F in bowl_contents)
+ F.forceMove(get_turf(exit_landmark))
+ bowl_contents -= F
+ return
+ return ..()
+
+/obj/structure/toilet/attack_ai(mob/user as mob)
+ if(isrobot(user))
+ if(user.client && user.client.eye == user)
+ return attack_hand(user)
+ else
+ return attack_hand(user)
+
+/obj/effect/landmark/teleplumb_exit
+ name = "teleplumbing exit"
diff --git a/code/game/objects/structures/window_spawner.dm b/code/game/objects/structures/window_spawner.dm
index bb8b5cff6b..dfeecb7be7 100644
--- a/code/game/objects/structures/window_spawner.dm
+++ b/code/game/objects/structures/window_spawner.dm
@@ -27,11 +27,10 @@
return FALSE
/obj/effect/wingrille_spawn/Initialize()
- . = ..()
- if(!win_path)
- return
- if(ticker && ticker.current_state < GAME_STATE_PLAYING)
+ if(win_path && ticker && ticker.current_state < GAME_STATE_PLAYING)
activate()
+ ..()
+ return INITIALIZE_HINT_QDEL
/obj/effect/wingrille_spawn/proc/activate()
if(activated) return
@@ -58,7 +57,8 @@
activated = 1
for(var/obj/effect/wingrille_spawn/other in neighbours)
if(!other.activated) other.activate()
- qdel(src)
+ if(initialized && !QDELETED(src))
+ qdel(src)
/obj/effect/wingrille_spawn/proc/handle_window_spawn(var/obj/structure/window/W)
return
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 415a26c78c..5b1214c675 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -4,6 +4,9 @@
return
var/turf/turf_source = get_turf(source)
+ if(!turf_source)
+ return
+ var/area/area_source = turf_source.loc
//allocate a channel if necessary now so its the same for everyone
channel = channel || open_sound_channel()
@@ -19,6 +22,11 @@
if(!M || !M.client)
continue
var/turf/T = get_turf(M)
+ if(!T)
+ continue
+ var/area/A = T.loc
+ if((A.soundproofed || area_source.soundproofed) && (A != area_source))
+ continue
var/distance = get_dist(T, turf_source)
if(distance <= maxdistance)
diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm
index 1d989c7099..31c8168a1c 100644
--- a/code/game/turfs/flooring/flooring_decals.dm
+++ b/code/game/turfs/flooring/flooring_decals.dm
@@ -12,9 +12,13 @@ var/list/floor_decals = list()
/obj/effect/floor_decal/New(var/newloc, var/newdir, var/newcolour)
supplied_dir = newdir
- if(newcolour) color = newcolour
+ if(newcolour)
+ color = newcolour
..(newloc)
+// TODO: identify what is causing these atoms to be qdeleted in New()/Initialize()
+// somewhere in this chain. Alternatively repath to /obj/floor_decal or some other
+// abstract handler that explicitly doesn't invoke any obj behavior.
/obj/effect/floor_decal/Initialize()
add_to_turf_decals()
initialized = TRUE
@@ -42,11 +46,11 @@ var/list/floor_decals = list()
name = "reset marker"
/obj/effect/floor_decal/reset/Initialize()
+ ..()
var/turf/T = get_turf(src)
if(T.decals && T.decals.len)
T.decals.Cut()
T.update_icon()
- initialized = TRUE
return INITIALIZE_HINT_QDEL
/obj/effect/floor_decal/corner
diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm
index 5dc017addd..c47a94d09c 100644
--- a/code/game/turfs/flooring/flooring_premade.dm
+++ b/code/game/turfs/flooring/flooring_premade.dm
@@ -317,7 +317,6 @@
name = "tiles"
icon_state = "freezer"
initial_flooring = /decl/flooring/tiling/freezer
- temperature = T0C - 5 // VOREStation Edit: Chillier Freezer Tiles on-start
/turf/simulated/floor/lino
name = "lino"
diff --git a/code/game/turfs/flooring/flooring_vr.dm b/code/game/turfs/flooring/flooring_vr.dm
index 2567ffd1a6..787c6bd10c 100644
--- a/code/game/turfs/flooring/flooring_vr.dm
+++ b/code/game/turfs/flooring/flooring_vr.dm
@@ -23,4 +23,7 @@
/decl/flooring/grass/outdoors/forest
icon = 'icons/turf/outdoors.dmi'
- icon_base = "grass-dark"
\ No newline at end of file
+ icon_base = "grass-dark"
+
+/turf/simulated/floor/tiled/freezer/cold
+ temperature = T0C - 5
\ No newline at end of file
diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm
index 151efd819c..437912b4d2 100644
--- a/code/game/turfs/simulated/floor_types.dm
+++ b/code/game/turfs/simulated/floor_types.dm
@@ -86,7 +86,7 @@
var/static/list/antilight_cache
/turf/simulated/shuttle/Initialize(mapload)
- ..()
+ . = ..()
if(!antilight_cache)
antilight_cache = list()
for(var/diag in cornerdirs)
diff --git a/code/game/turfs/simulated/floor_types_eris.dm b/code/game/turfs/simulated/floor_types_eris.dm
index bfc9945678..1cd067b957 100644
--- a/code/game/turfs/simulated/floor_types_eris.dm
+++ b/code/game/turfs/simulated/floor_types_eris.dm
@@ -1014,10 +1014,3 @@
oxygen = 0
nitrogen = 0
temperature = TCMB
-
-/*
-/turf/simulated/floor/hull/New()
- if(icon_state != "hullcenter0")
- overrided_icon_state = icon_state
- ..()
-*/
\ No newline at end of file
diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm
index d6f1d178aa..6db2961d4b 100644
--- a/code/game/turfs/simulated/outdoors/snow.dm
+++ b/code/game/turfs/simulated/outdoors/snow.dm
@@ -31,7 +31,8 @@
to_chat(user, "You begin to remove \the [src] with your [W].")
if(do_after(user, 4 SECONDS * W.toolspeed))
to_chat(user, "\The [src] has been dug up, and now lies in a pile nearby.")
- new /obj/item/stack/material/snow(src)
+ var/obj/item/stack/material/snow/S = new(src)
+ S.amount = 10
demote()
else
to_chat(user, "You decide to not finish removing \the [src].")
diff --git a/code/game/turfs/space/cracked_asteroid.dm b/code/game/turfs/space/cracked_asteroid.dm
index ca77a8cd2c..224997ca8d 100644
--- a/code/game/turfs/space/cracked_asteroid.dm
+++ b/code/game/turfs/space/cracked_asteroid.dm
@@ -11,9 +11,3 @@
/turf/space/cracked_asteroid/is_space() // So people don't start floating when standing on it.
return FALSE
-
-// u wot m8? ~Leshana
-// /turf/space/cracked_asteroid/New()
-// ..()
-// spawn(2 SECONDS)
-// overlays.Cut()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 43dffc352b..17bc2aee51 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -67,6 +67,17 @@
return 1
/turf/attack_hand(mob/user)
+ //QOL feature, clicking on turf can toggle doors, unless pulling something
+ if(!user.pulling)
+ var/obj/machinery/door/airlock/AL = locate(/obj/machinery/door/airlock) in src.contents
+ if(AL)
+ AL.attack_hand(user)
+ return TRUE
+ var/obj/machinery/door/firedoor/FD = locate(/obj/machinery/door/firedoor) in src.contents
+ if(FD)
+ FD.attack_hand(user)
+ return TRUE
+
if(!(user.canmove) || user.restrained() || !(user.pulling))
return 0
if(user.pulling.anchored || !isturf(user.pulling.loc))
diff --git a/code/game/turfs/unsimulated.dm b/code/game/turfs/unsimulated.dm
index 584137ff45..39c217a006 100644
--- a/code/game/turfs/unsimulated.dm
+++ b/code/game/turfs/unsimulated.dm
@@ -2,7 +2,13 @@
name = "command"
oxygen = MOLES_O2STANDARD
nitrogen = MOLES_N2STANDARD
- initialized = TRUE // Don't call init on unsimulated turfs (at least not yet)
+ var/skip_init = TRUE // Don't call down the chain, apparently for performance when loading maps at runtime.
+
+/turf/unsimulated/Initialize(mapload)
+ if(skip_init)
+ initialized = TRUE
+ return INITIALIZE_HINT_NORMAL
+ . = ..()
//VOREStation Add
/turf/unsimulated/fake_space
diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm
index c5338b3db9..b1841dadad 100644
--- a/code/game/turfs/unsimulated/beach.dm
+++ b/code/game/turfs/unsimulated/beach.dm
@@ -14,7 +14,7 @@
/turf/unsimulated/beach/water
name = "Water"
icon_state = "water"
- initialized = FALSE
+ skip_init = FALSE
movement_cost = 4 // Water should slow you down, just like simulated turf.
/turf/unsimulated/beach/water/Initialize()
diff --git a/code/game/turfs/unsimulated/planetary.dm b/code/game/turfs/unsimulated/planetary.dm
index 4fb26f16b6..9fe487410f 100644
--- a/code/game/turfs/unsimulated/planetary.dm
+++ b/code/game/turfs/unsimulated/planetary.dm
@@ -9,7 +9,6 @@
density = 1
alpha = 0
blocks_air = 0
- initialized = FALSE
// Set these to get your desired planetary atmosphere.
oxygen = 0
@@ -17,6 +16,7 @@
carbon_dioxide = 0
phoron = 0
temperature = T20C
+ skip_init = FALSE
/turf/unsimulated/wall/planetary/Initialize()
. = ..()
diff --git a/code/game/verbs/advanced_who.dm b/code/game/verbs/advanced_who.dm
index eff1f02636..4762280a73 100644
--- a/code/game/verbs/advanced_who.dm
+++ b/code/game/verbs/advanced_who.dm
@@ -86,6 +86,7 @@
entry += " - In Lobby "
else
entry += " - Playing "
+
Lines += entry
msg += ""
@@ -95,4 +96,4 @@
msg += "Total Players: [length(Lines)]"
msg = "" + msg + ""
to_chat(src, msg)
-YW EDIT STOP*/
\ No newline at end of file
+YW EDIT STOP*/
diff --git a/code/game/verbs/character_directory.dm b/code/game/verbs/character_directory.dm
index 99f95700b8..e6e1bc3911 100644
--- a/code/game/verbs/character_directory.dm
+++ b/code/game/verbs/character_directory.dm
@@ -1,61 +1,139 @@
+GLOBAL_DATUM(character_directory, /datum/character_directory)
+
/client/verb/show_character_directory()
set name = "Character Directory"
set category = "OOC"
set desc = "Shows a listing of all active characters, along with their associated OOC notes, flavor text, and more."
- if(mob.next_move >= world.time) //This is primarily to stop malicious users from trying to lag the server by spamming this verb
+ // This is primarily to stop malicious users from trying to lag the server by spamming this verb
+ if(!usr.checkMoveCooldown())
+ to_chat(usr, "Don't spam character directory refresh.")
return
+ usr.setMoveCooldown(10)
- mob.next_move = world.time + 10
+ if(!GLOB.character_directory)
+ GLOB.character_directory = new
+ GLOB.character_directory.tgui_interact(mob)
- var/html = ""
- var/curID = 0
+// This is a global singleton. Keep in mind that all operations should occur on usr, not src.
+/datum/character_directory
+/datum/character_directory/tgui_state(mob/user)
+ return GLOB.tgui_always_state
+
+/datum/character_directory/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "CharacterDirectory", "Character Directory")
+ ui.open()
+
+/datum/character_directory/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
+ var/list/data = ..()
+
+ data["personalVisibility"] = user?.client?.prefs?.show_in_directory
+ data["personalTag"] = user?.client?.prefs?.directory_tag || "Unset"
+ data["personalErpTag"] = user?.client?.prefs?.directory_erptag || "Unset"
+
+ return data
+
+/datum/character_directory/tgui_static_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
+ var/list/data = ..()
+
+ var/list/directory_mobs = list()
for(var/client/C in GLOB.clients)
- if(C.prefs && !C.prefs.show_in_directory)
+ // Allow opt-out.
+ if(!C?.prefs?.show_in_directory)
continue
+
+ // These are the three vars we're trying to find
+ // The approach differs based on the mob the client is controlling
+ var/name = null
+ var/ooc_notes = null
+ var/flavor_text = null
+ var/tag = C.prefs.directory_tag || "Unset"
+ var/erptag = C.prefs.directory_erptag || "Unset"
+ var/character_ad = C.prefs.directory_ad
+
if(ishuman(C.mob))
var/mob/living/carbon/human/H = C.mob
if(data_core && data_core.general)
if(!find_general_record("name", H.real_name))
if(!find_record("name", H.real_name, data_core.hidden_general))
continue
- curID++
- html += ""
- html += " [H.real_name]"
- if(H.flavor_texts["general"])
- html += " Flavor text"
- html += " [H.flavor_texts["general"]] "
- if(H.ooc_notes)
- html += " OOC notes"
- html += " [H.ooc_notes] "
- html += " "
+ name = H.real_name
+ ooc_notes = H.ooc_notes
+ flavor_text = H.flavor_texts["general"]
+
if(isAI(C.mob))
var/mob/living/silicon/ai/A = C.mob
- curID++
- html += ""
- html += " [A.name] (Artificial Intelligence)"
- if(A.ooc_notes)
- html += " OOC notes"
- html += " [A.ooc_notes] "
- html += " "
+ name = "[A.name] (Artificial Intelligence)"
+ ooc_notes = A.ooc_notes
+ flavor_text = null // No flavor text for AIs :c
+
if(isrobot(C.mob))
var/mob/living/silicon/robot/R = C.mob
if(R.scrambledcodes || (R.module && R.module.hide_on_manifest))
continue
- curID++
- html += ""
- html += " [R.name] ([R.modtype] [R.braintype])"
- if(R.flavor_text)
- html += " Flavor text"
- html += " [R.flavor_text] "
- if(R.ooc_notes)
- html += " OOC notes"
- html += " [R.ooc_notes] "
- html += " "
- if(!curID)
- html += "404: Station not found "
+ name = "[R.name] ([R.modtype] [R.braintype])"
+ ooc_notes = R.ooc_notes
+ flavor_text = R.flavor_text
- var/datum/browser/popup = new(mob, "chardir", "Character Directory", 640, 480)
- popup.set_content(html)
- popup.open()
+ // It's okay if we fail to find OOC notes and flavor text
+ // But if we can't find the name, they must be using a non-compatible mob type currently.
+ if(!name)
+ continue
+
+ directory_mobs.Add(list(list(
+ "name" = name,
+ "ooc_notes" = ooc_notes,
+ "tag" = tag,
+ "erptag" = erptag,
+ "character_ad" = character_ad,
+ "flavor_text" = flavor_text,
+ )))
+
+ data["directory"] = directory_mobs
+
+ return data
+
+
+/datum/character_directory/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
+ . = ..()
+ if(.)
+ return
+
+ switch(action)
+ if("refresh")
+ // This is primarily to stop malicious users from trying to lag the server by spamming this verb
+ if(!usr.checkMoveCooldown())
+ to_chat(usr, "Don't spam character directory refresh.")
+ return
+ usr.setMoveCooldown(10)
+ update_tgui_static_data(usr, ui)
+ return TRUE
+ if("setTag")
+ var/list/new_tag = input(usr, "Pick a new Vore tag for the character directory", "Character Tag", usr?.client?.prefs?.directory_tag) as null|anything in GLOB.char_directory_tags
+ if(!new_tag)
+ return
+ usr?.client?.prefs?.directory_tag = new_tag
+ return TRUE
+ if("setErpTag")
+ var/list/new_erptag = input(usr, "Pick a new ERP tag for the character directory", "Character ERP Tag", usr?.client?.prefs?.directory_erptag) as null|anything in GLOB.char_directory_erptags
+ if(!new_erptag)
+ return
+ usr?.client?.prefs?.directory_erptag = new_erptag
+ return TRUE
+ if("setVisible")
+ usr?.client?.prefs?.show_in_directory = !usr?.client?.prefs?.show_in_directory
+ to_chat(usr, "You are now [usr.client.prefs.show_in_directory ? "shown" : "not shown"] in the directory.")
+ return TRUE
+ if("editAd")
+ if(!usr?.client?.prefs)
+ return
+
+ var/current_ad = usr.client.prefs.directory_ad
+ var/new_ad = sanitize(input(usr, "Change your character ad", "Character Ad", current_ad) as message|null, extra = 0)
+ if(isnull(new_ad))
+ return
+ usr.client.prefs.directory_ad = new_ad
+ return TRUE
\ No newline at end of file
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index ce0b82df9b..cd4a90354e 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -73,9 +73,9 @@
return
log_and_message_admins("[key_name(src)] commited suicide")
-
+
var/datum/gender/T = gender_datums[get_visible_gender()]
-
+
var/suicidemsg
suicidemsg = pick("[src] is attempting to bite [T.his] tongue off! It looks like [T.he] [T.is] trying to commit suicide.", \
"[src] is jamming [T.his] thumbs into [T.his] eye sockets! It looks like [T.he] [T.is] trying to commit suicide.", \
@@ -152,6 +152,7 @@
adjustOxyLoss(max(getMaxHealth() * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
updatehealth()
+/* CHOMP EDIT START: Removing PAI suicide, literally no one needs this.
/mob/living/silicon/pai/verb/suicide()
set category = "pAI Commands"
set desc = "Kill yourself and become a ghost (You will receive a confirmation prompt)"
@@ -166,3 +167,5 @@
death(0)
else
to_chat(src, "Aborting suicide attempt.")
+
+*/
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
index be062aef6f..6cec049ed2 100644
--- a/code/game/verbs/who.dm
+++ b/code/game/verbs/who.dm
@@ -1,4 +1,3 @@
-
/client/verb/who()
set name = "Who"
set category = "OOC"
@@ -206,3 +205,4 @@
msg += "\nAdminhelps are also sent to Discord. If no admins are available in game try anyway and an admin on Discord may see it and respond."
return msg
+
diff --git a/code/game/world.dm b/code/game/world.dm
index 92f0359913..867301f989 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -57,12 +57,8 @@
// Create robolimbs for chargen.
populate_robolimb_list()
- //Must be done now, otherwise ZAS zones and lighting overlays need to be recreated.
- //createRandomZlevel() //VOREStation Removal: Deprecated
-
master_controller = new /datum/controller/game_controller()
-
- Master.Initialize(10, FALSE, TRUE)
+ Master.Initialize(10, FALSE)
spawn(1)
master_controller.setup()
@@ -171,42 +167,57 @@ var/world_topic_spam_protect_time = world.timeofday
var/real_rank = make_list_rank(t.fields["real_rank"])
var/department = 0
+ var/active = 0 //CHOMPStation Edit Begin
+ for(var/mob/M in player_list)
+ if(M.real_name == name && M.client && M.client.inactivity <= 10 MINUTES)
+ active = 1
+ break
+ var/isactive = active ? "Active" : "Inactive"
for(var/k in set_names)
if(real_rank in set_names[k])
if(!positions[k])
positions[k] = list()
- positions[k][name] = rank
+ positions[k][name] = list(rank,isactive)
department = 1
if(!department)
if(!positions["misc"])
positions["misc"] = list()
- positions["misc"][name] = rank
+ positions["misc"][name] = list(rank,isactive)
for(var/datum/data/record/t in data_core.hidden_general)
var/name = t.fields["name"]
var/rank = t.fields["rank"]
var/real_rank = make_list_rank(t.fields["real_rank"])
+ var/active = 0 //CHOMPStation Edit Begin
+ for(var/mob/M in player_list)
+ if(M.real_name == name && M.client && M.client.inactivity <= 10 MINUTES)
+ active = 1
+ break
+ var/isactive = active ? "Active" : "Inactive"
+
var/datum/job/J = SSjob.get_job(real_rank)
if(J?.offmap_spawn)
if(!positions["off"])
positions["off"] = list()
- positions["off"][name] = rank
+ positions["off"][name] = list(rank,isactive)
// Synthetics don't have actual records, so we will pull them from here.
for(var/mob/living/silicon/ai/ai in mob_list)
+ var/isactive = (ai.client && ai.client.inactivity <= 10 MINUTES) ? "Active" : "Inactive"
if(!positions["bot"])
positions["bot"] = list()
- positions["bot"][ai.name] = "Artificial Intelligence"
+ positions["bot"][ai.name] = list("Artificial Intelligence",isactive)
for(var/mob/living/silicon/robot/robot in mob_list)
// No combat/syndicate cyborgs, no drones, and no AI shells.
+ var/isactive = (robot.client && robot.client.inactivity <= 10 MINUTES) ? "Active" : "Inactive"
if(robot.shell)
continue
- if(robot.module && robot.module.hide_on_manifest)
+ if(robot.module && robot.module.hide_on_manifest())
continue
if(!positions["bot"])
positions["bot"] = list()
- positions["bot"][robot.name] = "[robot.modtype] [robot.braintype]"
+ positions["bot"][robot.name] = list("[robot.modtype] [robot.braintype]",isactive) //CHOMPEdit end
for(var/k in positions)
positions[k] = list2params(positions[k]) // converts positions["heads"] = list("Bob"="Captain", "Bill"="CMO") into positions["heads"] = "Bob=Captain&Bill=CMO"
@@ -408,7 +419,6 @@ var/world_topic_spam_protect_time = world.timeofday
to_world("Rebooting world immediately due to host request")
else
Master.Shutdown() //run SS shutdowns
- //processScheduler.stop() //VOREStation Removal
for(var/client/C in GLOB.clients)
if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[config.server]")
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 3d169758f5..92a1d78508 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -407,7 +407,7 @@ proc/admin_notice(var/message, var/rights)
dat+="ERROR: Could not submit Feed story to Network.
"
if(src.admincaster_feed_channel.channel_name=="")
dat+="•Invalid receiving channel name. "
- if(src.admincaster_feed_message.body == "" || src.admincaster_feed_message.body == "\[REDACTED\]")
+ if(src.admincaster_feed_message.body == "" || src.admincaster_feed_message.body == "\[REDACTED\]" || admincaster_feed_message.title == "")
dat+="•Invalid message body. "
dat+=" Return "
if(7)
@@ -436,11 +436,14 @@ proc/admin_notice(var/message, var/rights)
var/i = 0
for(var/datum/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
i++
- dat+="-[MESSAGE.body] "
+ //dat+="-[MESSAGE.body] "
+ var/pic_data
if(MESSAGE.img)
usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
- dat+="
"
- dat+="\[Story by [MESSAGE.author]\] "
+ pic_data+=" "
+ dat+= get_newspaper_content(MESSAGE.title, MESSAGE.body, MESSAGE.author,"#d4cec1", pic_data)
+ dat+=" "
+ dat+="\[Story by [MESSAGE.author] - [MESSAGE.time_stamp]\] "
dat+={"
Refresh
Back
@@ -948,7 +951,7 @@ var/datum/announcement/minor/admin_min_announcer = new
log_admin("[key_name(usr)] toggled persistence to [config.persistence_disabled ? "Off" : "On"].")
world.update_status()
feedback_add_details("admin_verb","TPD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
+
/datum/admins/proc/togglemaploadpersistence()
set category = "Server"
set desc="Whether mapload persistent data will be saved from now on."
@@ -1426,6 +1429,11 @@ var/datum/announcement/minor/admin_min_announcer = new
return 1
if(tomob.client) //No need to ghostize if there is no client
tomob.ghostize(0)
+ if(frommob.mind && frommob.mind.current) //Preserve teleop for original body when adminghosting.
+ var/mob/body = frommob.mind.current
+ if(body)
+ if(body.teleop)
+ body.teleop = tomob
message_admins("[key_name_admin(usr)] has put [frommob.ckey] in control of [tomob.name].")
log_admin("[key_name(usr)] stuffed [frommob.ckey] into [tomob.name].")
feedback_add_details("admin_verb","CGD")
diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm
index 1342fc2f5f..65c8afb298 100644
--- a/code/modules/admin/admin_investigate.dm
+++ b/code/modules/admin/admin_investigate.dm
@@ -23,7 +23,7 @@
if(!message) return
var/F = investigate_subject2file(subject)
if(!F) return
- to_chat(F, "[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z]) || [src] [message] ")
+ to_file(F, "[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z]) || [src] [message] ")
//ADMINVERBS
/client/proc/investigate_show( subject in list("hrefs","notes","singulo","telesci") )
diff --git a/code/modules/admin/admin_tools.dm b/code/modules/admin/admin_tools.dm
index 42ab6aae9a..2d9ae2cdd4 100644
--- a/code/modules/admin/admin_tools.dm
+++ b/code/modules/admin/admin_tools.dm
@@ -76,9 +76,4 @@
onclose(usr, "admin_dialogue_log")
- feedback_add_details("admin_verb","PDL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-// Used to get `atom/O as obj|mob|turf in view()` to match against strings containing apostrophes immediately after substrings that match to other objects. Somehow. - Ater
-/proc/admin_atom_validate(atom/A)
- return view()
\ No newline at end of file
+ feedback_add_details("admin_verb","PDL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
\ No newline at end of file
diff --git a/code/modules/admin/admin_verb_lists.dm b/code/modules/admin/admin_verb_lists.dm
index a33611b459..2772597162 100644
--- a/code/modules/admin/admin_verb_lists.dm
+++ b/code/modules/admin/admin_verb_lists.dm
@@ -60,6 +60,7 @@ var/list/admin_verbs_admin = list(
/client/proc/check_ai_laws, //shows AI and borg laws,
/client/proc/rename_silicon, //properly renames silicons,
/client/proc/manage_silicon_laws, // Allows viewing and editing silicon laws. ,
+ /client/proc/shuttle_panel, // Allows controlling all shuttles remotely.
/client/proc/check_antagonists,
/client/proc/admin_memo, //admin memo system. show/delete/write. +SERVER needed to delete admin memos of others,
/client/proc/dsay, //talk in deadchat using our ckey/fakekey,
@@ -105,7 +106,6 @@ var/list/admin_verbs_admin = list(
/datum/admins/proc/paralyze_mob,
/client/proc/fixatmos,
/datum/admins/proc/quick_nif, //VOREStation Add,
- /datum/admins/proc/quick_authentic_nif, //CHOMPStation add
/datum/admins/proc/sendFax,
/client/proc/despawn_player,
/datum/admins/proc/view_feedback,
@@ -360,7 +360,6 @@ var/list/admin_verbs_mod = list(
/datum/admins/proc/view_persistent_data,
/datum/admins/proc/view_txt_log, //shows the server log (diary) for today,
/datum/admins/proc/quick_nif, //CHOMPEdit
- /datum/admins/proc/quick_authentic_nif, //CHOMPEdit
/client/proc/admin_teleport, //CHOMPEdit
/datum/admins/proc/view_atk_log //shows the server combat-log, doesn't do anything presently,
)
@@ -452,6 +451,7 @@ var/list/admin_verbs_event_manager = list(
/client/proc/check_ai_laws, //shows AI and borg laws,
/client/proc/rename_silicon, //properly renames silicons,
/client/proc/manage_silicon_laws, // Allows viewing and editing silicon laws. ,
+ /client/proc/shuttle_panel, // Allows controlling all shuttles remotely.
/client/proc/check_antagonists,
/client/proc/admin_memo, //admin memo system. show/delete/write. +SERVER needed to delete admin memos of others,
/client/proc/dsay, //talk in deadchat using our ckey/fakekey,
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 6635b07061..d8deb0dce6 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -437,6 +437,17 @@
set_security_level(sec_level)
log_admin("[key_name(usr)] changed the security level to code [sec_level].")
+/client/proc/shuttle_panel()
+ set name = "Shuttle Control Panel"
+ set category = "Admin"
+
+ if(!check_rights(R_ADMIN | R_EVENT))
+ return
+
+ var/datum/tgui_module/admin_shuttle_controller/A = new(src)
+ A.tgui_interact(usr)
+ log_and_message_admins("has opened the shuttle panel.")
+ feedback_add_details("admin_verb","SHCP")
//---- bs12 verbs ----
@@ -525,4 +536,4 @@
T.spell_list += new S
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
- message_admins("[key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1)
+ message_admins("[key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1)
\ No newline at end of file
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 3fe1f52465..d92b3be0cb 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1742,16 +1742,20 @@
src.admincaster_feed_channel.channel_name = sanitizeSafe(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels )
src.access_news_network()
+ else if(href_list["ac_set_new_title"])
+ src.admincaster_feed_message.title = sanitize(input(usr, "Enter the Feed title", "Network Channel Handler", ""))
+ src.access_news_network()
+
else if(href_list["ac_set_new_message"])
- src.admincaster_feed_message.body = sanitize(input(usr, "Write your Feed story", "Network Channel Handler", ""))
+ src.admincaster_feed_message.body = sanitize(input(usr, "Write your Feed story", "Network Channel Handler", "") as message)
src.access_news_network()
else if(href_list["ac_submit_new_message"])
- if(src.admincaster_feed_message.body =="" || src.admincaster_feed_message.body =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" )
+ if(src.admincaster_feed_message.body =="" || admincaster_feed_message.title == "" || admincaster_feed_message.body =="\[REDACTED\]" || admincaster_feed_channel.channel_name == "" )
src.admincaster_screen = 6
else
feedback_inc("newscaster_stories",1)
- news_network.SubmitArticle(src.admincaster_feed_message.body, src.admincaster_signature, src.admincaster_feed_channel.channel_name, null, 1)
+ news_network.SubmitArticle(admincaster_feed_message.body, admincaster_signature, admincaster_feed_channel.channel_name, null, 1, "", admincaster_feed_message.title)
src.admincaster_screen=4
log_admin("[key_name_admin(usr)] submitted a feed story to channel: [src.admincaster_feed_channel.channel_name]!")
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index c9aabc4749..9d89d54fc5 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -1,6 +1,25 @@
/client/var/datum/admin_help/current_ticket //the current ticket the (usually) not-admin client is dealing with
-//
+//CHOMPEdit Begin
+/proc/get_ahelp_channel()
+ var/datum/tgs_api/v5/api = TGS_READ_GLOBAL(tgs)
+ if(istype(api) && config.ahelp_channel_tag)
+ for(var/datum/tgs_chat_channel/channel in api.chat_channels)
+ if(channel.custom_tag == config.ahelp_channel_tag)
+ return list(channel)
+ return 0
+
+/proc/ahelp_discord_message(var/message)
+ if(!message)
+ return
+ if(config.discord_ahelps_disabled)
+ return
+ var/datum/tgs_chat_channel/ahelp_channel = get_ahelp_channel()
+ if(ahelp_channel)
+ world.TgsChatBroadcast(message,ahelp_channel)
+ else
+ world.TgsTargetedChatBroadcast(message,TRUE)
+//CHOMPEdit End
//TICKET MANAGER
//
@@ -190,9 +209,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
var/list/activemins = adm["present"]
var activeMins = activemins.len
if(is_bwoink)
- world.TgsTargetedChatBroadcast("ADMINHELP: FROM: [key_name_admin(usr)] TO [initiator_ckey]/[initiator_key_name] - MSG: **[msg]** - Heard by [activeMins] NON-AFK staff members.", TRUE)
+ ahelp_discord_message("ADMINHELP: FROM: [key_name_admin(usr)] TO [initiator_ckey]/[initiator_key_name] - MSG: **[msg]** - Heard by [activeMins] NON-AFK staff members.") //CHOMPEdit
else
- world.TgsTargetedChatBroadcast("ADMINHELP: FROM: [initiator_ckey]/[initiator_key_name] - MSG: **[msg]** - Heard by [activeMins] NON-AFK staff members.", TRUE)
+ ahelp_discord_message("ADMINHELP: FROM: [initiator_ckey]/[initiator_key_name] - MSG: **[msg]** - Heard by [activeMins] NON-AFK staff members.") //CHOMPEdit
//YW EDIT END
GLOB.ahelp_tickets.active_tickets += src
@@ -203,7 +222,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
return ..()
/datum/admin_help/proc/AddInteraction(formatted_message)
- _interactions += "[gameTimestamp()]: [formatted_message]"
+ var/curinteraction = "[gameTimestamp()]: [formatted_message]"
+ if(config.discord_ahelps_all) //CHOMPEdit
+ ahelp_discord_message("ADMINHELP: TICKETID:[id] [strip_html_properly(curinteraction)]") //CHOMPEdit
+ _interactions += curinteraction
//private
/datum/admin_help/proc/FullMonty(ref_src)
diff --git a/code/modules/admin/verbs/change_appearance.dm b/code/modules/admin/verbs/change_appearance.dm
index 2f7166a2c0..94c5170347 100644
--- a/code/modules/admin/verbs/change_appearance.dm
+++ b/code/modules/admin/verbs/change_appearance.dm
@@ -92,15 +92,7 @@
var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female", "Neuter")
if (new_gender)
- if(new_gender == "Male")
- M.gender = MALE
- M.dna.SetUIState(DNA_UI_GENDER, FALSE)
- else if (new_gender == "Female")
- M.gender = FEMALE
- M.dna.SetUIState(DNA_UI_GENDER, TRUE)
- else
- M.gender = NEUTER
- M.dna.SetUIState(DNA_UI_GENDER, FALSE)
+ M.set_gender(new_gender)
M.update_dna(M)
M.update_hair(FALSE)
diff --git a/code/modules/admin/verbs/debug_ch.dm b/code/modules/admin/verbs/debug_ch.dm
deleted file mode 100644
index b33604b7ea..0000000000
--- a/code/modules/admin/verbs/debug_ch.dm
+++ /dev/null
@@ -1,32 +0,0 @@
-/datum/admins/proc/quick_authentic_nif()
- set category = "Fun"
- set name = "Quick Auth NIF"
- set desc = "Spawns an authentic NIF into someone in quick-implant mode."
-
- if(!check_rights(R_ADMIN|R_EVENT|R_DEBUG)) //CHOMPStation Edit TFF 24/4/19: Allow Devs to use Quick-NIF verb.
- return
-
- var/mob/living/carbon/human/H = input("Pick a mob with a player","Quick Authentic NIF") as null|anything in player_list
-
- if(!H)
- return
-
- if(!istype(H))
- to_chat(usr,"That mob type ([H.type]) doesn't support NIFs, sorry.")
- return
-
- if(!H.get_organ(BP_HEAD))
- to_chat(usr,"Target is unsuitable.")
- return
-
- if(H.nif)
- to_chat(usr,"Target already has a NIF.")
- return
-
- if(H.species.flags & NO_SCAN)
- new /obj/item/device/nif/authenticbio(H)
- else
- new /obj/item/device/nif/authentic(H)
-
- log_and_message_admins("[key_name(src)] Quick Authentic NIF'd [H.real_name].")
- feedback_add_details("admin_verb","QANIF") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 2e59ce752c..1916c1d880 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -523,6 +523,12 @@ Traitors and the like can also be revived with the previous role mostly intact.
new_character.add_language(lang)
//VOREStation Add End
+ for(var/lang in picked_client.prefs.alternate_languages)
+ var/datum/language/chosen_language = GLOB.all_languages[lang]
+ if(chosen_language)
+ if(is_lang_whitelisted(src,chosen_language) || (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
+ new_character.add_language(lang)
+
//If desired, apply equipment.
if(equipment)
if(charjob)
@@ -629,7 +635,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("[key_name_admin(src)] has created a command report", 1)
feedback_add_details("admin_verb","CCR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in admin_atom_validate(O)) // I don't understand precisely how this fixes the string matching against a substring, but it does - Ater
+/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in _validate_atom(O)) // I don't understand precisely how this fixes the string matching against a substring, but it does - Ater
set category = "Admin"
set name = "Delete"
diff --git a/code/modules/ai/ai_holder.dm b/code/modules/ai/ai_holder.dm
index d99247fe58..7358a7790f 100644
--- a/code/modules/ai/ai_holder.dm
+++ b/code/modules/ai/ai_holder.dm
@@ -46,6 +46,7 @@
// mob to stay still (e.g. delayed attacking). If you need the mob to be inactive for an extended period of time,
// consider sleeping the AI instead.
var/process_flags = 0 // Where we're processing, see flag defines.
+ var/list/snapshot = null // A list used in mass-editing of AI datums, holding a snapshot of the 'before' state
var/list/static/fastprocess_stances = list(
STANCE_ALERT,
STANCE_APPROACH,
@@ -69,6 +70,143 @@
hostile = TRUE
retaliate = TRUE
+/datum/ai_holder/vv_get_dropdown()
+ . = ..()
+ if(snapshot)
+ VV_DROPDOWN_OPTION("mass_edit_finish", "End Mass Edit")
+ else
+ VV_DROPDOWN_OPTION("mass_edit_start", "Begin Mass Edit")
+
+/datum/ai_holder/vv_do_topic(list/href_list)
+ . = ..()
+ IF_VV_OPTION("mass_edit_start")
+ if(!check_rights(R_ADMIN))
+ return
+ if(snapshot)
+ to_chat(usr, "Someone (or you) may have started a mass edit on this AI datum already. Refresh the VV window to get the option to end the mass edit instead.")
+ href_list["datumrefresh"] = "\ref[src]"
+ return
+ snapshot = vars.Copy() //'vars' appears to be special in that vars.Copy produces a flat list of keys with no values. It seems that 'vars[key]' is handled somewhere in the byond engine differently than normal lists.
+
+ // Remove things that may change without admin input during editing. If they aren't present in the snapshot, they aren't eligible for the diff.
+ snapshot -= list(
+ //other
+ "datum_flags",
+ "active_timers",
+ //main
+ "snapshot",
+ "stance",
+ "process_flags",
+ //targeting
+ "target",
+ "preferred_target",
+ "target_last_seen_turf",
+ "attackers",
+ "lose_target_time",
+ //pathfinding
+ "path",
+ "obstacles",
+ "failed_steps",
+ //movement
+ "destination",
+ "failed_breakthroughs",
+ "faction_friends",
+ //communication
+ "threatening",
+ "last_conflict_time",
+ "last_threaten_time",
+ "last_target_time"
+ )
+
+ for(var/key in snapshot)
+ var/thing = vars[key]
+ if(islist(thing)) // This is just too dangerous to do. Maybe in the future we can have a whitelist of lists that are fine to edit.
+ thing = null
+ snapshot[key] = thing
+
+ VARSET_IN(src, snapshot, null, 2 MINUTES) // Safety
+ to_chat(usr, "Variable snapshot saved. Begin editing the datum, and end the mass edit from the dropdown menu within 2 minutes. Note that editing the contents of lists is not supported.")
+ href_list["datumrefresh"] = "\ref[src]"
+
+ IF_VV_OPTION("mass_edit_finish")
+ if(!check_rights(R_ADMIN))
+ return
+
+ var/list/before = snapshot //This PROBABLY works, right?
+ snapshot = null
+ var/list/after = vars.Copy() //'vars' appears to be special in that vars.Copy produces a flat list of keys with no values. It seems that 'vars[key]' is handled somewhere in the byond engine differently than normal lists.
+ after &= before //Ignore any dangerous keys. Not a big deal, because just 'before' being safe is enough to exclude the dangerous ones from the diff, but why not
+ for(var/key in after)
+ var/thing = vars[key]
+ if(islist(thing)) // This is just too dangerous to do. Maybe in the future we can have a whitelist of lists that are fine to edit.
+ thing = null
+ after[key] = thing
+
+ var/list/diff = list()
+ for(var/key in before)
+ if(before[key] == after[key])
+ continue
+ diff += key
+
+ if(!diff.len)
+ to_chat(usr, "You don't appear to have changed anything on the AI datum you were editing.")
+ href_list["datumrefresh"] = "\ref[src]"
+ else
+ var/message = "These differences were detected in your varedit. If you notice any that you didn't change, please redo your edit: "
+ for(var/key in diff)
+ message += "- [key]: [before[key]] => [after[key]] "
+ message += ""
+ to_chat(usr,message)
+
+ var/original_type = holder.type
+ var/list/levels_working = GetConnectedZlevels(holder.z)
+
+ var/list/types = list()
+ var/list/split = splittext("[original_type]", "/")
+ split -= "" // The first / creates an empty string at the start as it tries to split on [nothing]/mob/living etc
+ var/typestring = "/"
+ for(var/el in split)
+ typestring += el
+
+ types += text2path(typestring)
+ typestring += "/"
+
+ var/list/searching = living_mob_list // Started/seeded with this
+ var/list/choices = list()
+ for(var/typechoice in types)
+ var/list/found = list()
+ for(var/mob in searching) // Isnt't there a helper for this, maybe? I forget.
+ var/atom/M = mob
+ if(!(M.z in levels_working))
+ continue
+ if(!istype(mob,typechoice))
+ continue
+ found += M
+ choices["[typechoice] ([found.len])"] = found // Prettified name for the user input below)
+ searching = found // Now we only search the list we just made, because of the order of our types list, each subsequent list will be a subset of the one we just finished
+
+ var/choice = input(usr,"Based on your AI holder's mob location, we'll edit mobs on Z [levels_working.Join(",")]. What types do you want to alter?") as null|anything in choices
+ if(!choice)
+ href_list["datumrefresh"] = "\ref[src]"
+ return
+ var/list/selected = choices[choice]
+ for(var/mob in selected)
+ var/mob/living/L = mob
+ if(!istype(L))
+ to_chat(usr,"Skipping incompatible mob: [L] [ADMIN_COORDJMP(L)]")
+ continue
+ if(!L.ai_holder)
+ to_chat(usr,"Skipping due to no AI: [L] [ADMIN_COORDJMP(L)]")
+ continue
+ for(var/newvar in diff)
+ if(newvar in L.ai_holder.vars)
+ L.ai_holder.vars[newvar] = after[newvar]
+ else
+ to_chat(usr,"Skipping unavailable var '[newvar]' on: [L] [ADMIN_COORDJMP(L)]")
+
+ to_chat(usr,"Mass AI edit done.")
+ href_list["datumrefresh"] = "\ref[src]"
+
/datum/ai_holder/New(var/new_holder)
ASSERT(new_holder)
holder = new_holder
diff --git a/code/modules/ai/ai_holder_combat.dm b/code/modules/ai/ai_holder_combat.dm
index 075a9196d8..e2e1ecbdea 100644
--- a/code/modules/ai/ai_holder_combat.dm
+++ b/code/modules/ai/ai_holder_combat.dm
@@ -9,7 +9,7 @@
var/violent_breakthrough = TRUE // If false, the AI is not allowed to destroy things like windows or other structures in the way. Requires above var to be true.
var/stand_ground = FALSE // If true, the AI won't try to get closer to an enemy if out of range.
-
+
// This does the actual attacking.
/datum/ai_holder/proc/engage_target()
ai_log("engage_target() : Entering.", AI_LOG_DEBUG)
@@ -293,7 +293,7 @@
// Kill common obstacle in the way like tables.
var/obj/structure/obstacle = locate(/obj/structure, problem_turf)
- if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
+ if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille) || istype(obstacle, /obj/effect/weaversilk/wall)) //VOREStation Edit: spdr
ai_log("destroy_surroundings() : Attacking generic structure.", AI_LOG_INFO)
return melee_attack(obstacle)
diff --git a/code/modules/artifice/cursedform.dm b/code/modules/artifice/cursedform.dm
index 17f8fbf618..43acac8bf3 100644
--- a/code/modules/artifice/cursedform.dm
+++ b/code/modules/artifice/cursedform.dm
@@ -2,7 +2,7 @@
name = "Form - Inventory Requisition r10.7.1E"
/obj/item/weapon/paper/carbon/cursedform/Initialize()
- ..()
+ . = ..()
info = {" Form - Inventory Requisition r10.7.1E General Request Form
General
Name: Department: Departmental Rank: Organization(If not Nanotrasen): Date:
Requested Item(s): Quantity: Reason for request: Is this replacement equipment?: If `Yes`; above, specify equiment and reason for replacement:
Authorization
Authorizing Department: Authorizing Dept. Head:
Contact and Delivery
EPv2 Address of requesting party(Do not leave blank): Delivery location or department:
Nanotrasen Employee Identification Number: Signature of Requester and Date
Authorizor`s Nanotrasen Employee Identification Number: Authorizing Signature and Date(Include authorizing department`s stamp below)
Shipping Department Only (Do not write below this line) Nanotrasen Purchasing Approval Code: Nanotrasen Employee Identification Number: Receiving Shipping Employee: Signature and Date
"}
info_links = {" Form - Inventory Requisition r10.7.1E General Request Form
General
Name: write Department: write Departmental Rank: write Organization(If not Nanotrasen): write Date: write
Requested Item(s): write Quantity: write Reason for request: write Is this replacement equipment?: write If `Yes` above, specify equiment and reason for replacement: write
Authorization
Authorizing Department: write Authorizing Dept. Head: write
Contact and Delivery
EPv2 Address of requesting party(Do not leave blank): write Delivery location or department: write
Nanotrasen Employee Identification Number: write Signature of Requester and Date
write
Authorizor`s Nanotrasen Employee Identification Number: write Authorizing Signature and Date(Include authorizing department`s stamp below)
write
Shipping Department Only (Do not write below this line) Nanotrasen Purchasing Approval Code: write Nanotrasen Employee Identification Number: write Receiving Shipping Employee: write Signature and Date
write write"}
diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm
index 5344d4b15b..5a673280ce 100644
--- a/code/modules/assembly/igniter.dm
+++ b/code/modules/assembly/igniter.dm
@@ -3,7 +3,7 @@
desc = "A small electronic device able to ignite combustable substances."
icon_state = "igniter"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
+ matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, MAT_COPPER = 10, "waste" = 10)
secured = 1
wires = WIRE_RECEIVE
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 853f2f230b..3a7952ecfe 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -5,7 +5,7 @@
desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted."
icon_state = "infrared"
origin_tech = list(TECH_MAGNET = 2)
- matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500, "waste" = 100)
+ matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500, MAT_COPPER = 10, "waste" = 100)
wires = WIRE_PULSE
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index b292d3f753..de764c5011 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -3,7 +3,7 @@
desc = "Used for scanning and alerting when someone enters a certain proximity."
icon_state = "prox"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 800, "glass" = 200, "waste" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 800, "glass" = 200, MAT_COPPER = 10, "waste" = 50)
wires = WIRE_PULSE
secured = 0
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index e98ff5372c..392a7efdfe 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -4,7 +4,7 @@
icon_state = "signaller"
item_state = "signaler"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 200, "waste" = 100)
+ matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 200, MAT_COPPER = 10, "waste" = 100)
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE
secured = TRUE
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index fa8b783815..144a21bcd0 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -3,7 +3,7 @@
desc = "Used to time things. Works well with contraptions which has to count down. Tick tock."
icon_state = "timer"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
+ matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, MAT_COPPER = 10, "waste" = 10)
wires = WIRE_PULSE
diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm
index 8990e01d63..c608db5ff1 100644
--- a/code/modules/assembly/voice.dm
+++ b/code/modules/assembly/voice.dm
@@ -3,7 +3,7 @@
desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated."
icon_state = "voice"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
+ matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, MAT_COPPER = 10, "waste" = 10)
var/listening = 0
var/recorded //the activation message
diff --git a/code/modules/awaymissions/loot.dm b/code/modules/awaymissions/loot.dm
index 1c1d901161..530358940c 100644
--- a/code/modules/awaymissions/loot.dm
+++ b/code/modules/awaymissions/loot.dm
@@ -8,18 +8,14 @@
/obj/effect/spawner/lootdrop/Initialize()
..()
var/list/things = params2list(loot)
-
if(things && things.len)
for(var/i = lootcount, i > 0, i--)
if(!things.len)
return
-
var/loot_spawn = pick(things)
var/loot_path = text2path(loot_spawn)
-
if(!loot_path || !lootdoubles)
things.Remove(loot_spawn)
continue
-
new loot_path(get_turf(src))
return INITIALIZE_HINT_QDEL
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index 6121bedb22..5c10eae367 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -26,6 +26,7 @@
var/datum/chatOutput/chatOutput
var/datum/volume_panel/volume_panel = null // Initialized by /client/verb/volume_panel()
var/chatOutputLoadedAt
+ var/seen_news = 0
var/adminhelped = 0
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 7db4d9393a..e7946e833a 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -45,7 +45,6 @@
if( findtext(href," |