Merge branch 'master' into upstream-merge-30554
This commit is contained in:
+43
-15
@@ -1,13 +1,52 @@
|
||||
Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255.
|
||||
|
||||
The latest database version is 3.1; The query to update the schema revision table is:
|
||||
The latest database version is 3.4; The query to update the schema revision table is:
|
||||
|
||||
INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 1);
|
||||
INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 4);
|
||||
or
|
||||
INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 1);
|
||||
INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 4);
|
||||
|
||||
In any query remember to add a prefix to the table names if you use one.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
28 August 2017, by MrStonedOne
|
||||
Modified table 'messages', adding a deleted column and editing all indexes to include it
|
||||
|
||||
ALTER TABLE `messages`
|
||||
ADD COLUMN `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0' AFTER `edits`,
|
||||
DROP INDEX `idx_msg_ckey_time`,
|
||||
DROP INDEX `idx_msg_type_ckeys_time`,
|
||||
DROP INDEX `idx_msg_type_ckey_time_odr`,
|
||||
ADD INDEX `idx_msg_ckey_time` (`targetckey`,`timestamp`, `deleted`),
|
||||
ADD INDEX `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`, `deleted`),
|
||||
ADD INDEX `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`, `deleted`);
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
25 August 2017, by Jordie0608
|
||||
|
||||
Modified tables 'connection_log', 'legacy_population', 'library', 'messages' and 'player' to add additional 'round_id' tracking in various forms and 'server_ip' and 'server_port' to the table 'messages'.
|
||||
|
||||
ALTER TABLE `connection_log` ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
|
||||
ALTER TABLE `legacy_population` ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
|
||||
ALTER TABLE `library` ADD COLUMN `round_id_created` INT(11) UNSIGNED NOT NULL AFTER `deleted`;
|
||||
ALTER TABLE `messages` ADD COLUMN `server_ip` INT(10) UNSIGNED NOT NULL AFTER `server`, ADD COLUMN `server_port` SMALLINT(5) UNSIGNED NOT NULL AFTER `server_ip`, ADD COLUMN `round_id` INT(11) UNSIGNED NOT NULL AFTER `server_port`;
|
||||
ALTER TABLE `player` ADD COLUMN `firstseen_round_id` INT(11) UNSIGNED NOT NULL AFTER `firstseen`, ADD COLUMN `lastseen_round_id` INT(11) UNSIGNED NOT NULL AFTER `lastseen`;
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
18 August 2017, by Cyberboss and nfreader
|
||||
|
||||
Modified table 'death', adding the columns `last_words` and 'suicide'.
|
||||
|
||||
ALTER TABLE `death`
|
||||
ADD COLUMN `last_words` varchar(255) DEFAULT NULL AFTER `staminaloss`,
|
||||
ADD COLUMN `suicide` tinyint(0) NOT NULL DEFAULT '0' AFTER `last_words`;
|
||||
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
20th July 2017, by Shadowlight213
|
||||
Added role_time table to track time spent playing departments.
|
||||
@@ -17,21 +56,10 @@ CREATE TABLE `role_time` ( `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT
|
||||
|
||||
ALTER TABLE `player` ADD `flags` INT NOT NULL default '0' AFTER `accountjoindate`;
|
||||
|
||||
|
||||
UPDATE `schema_revision` SET minor = 1;
|
||||
Remember to add a prefix to the table name if you use them.
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255.
|
||||
|
||||
The latest database version is 3.0; The query to update the schema revision table is:
|
||||
|
||||
INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0);
|
||||
or
|
||||
INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 0);
|
||||
|
||||
----------------------------------------------------
|
||||
28 June 2017, by oranges
|
||||
Added schema_revision to store the current db revision, why start at 3.0?
|
||||
|
||||
@@ -336,4 +364,4 @@ UPDATE erro_library SET deleted = 1 WHERE id = someid
|
||||
|
||||
(Replace someid with the id of the book you want to soft delete.)
|
||||
|
||||
----------------------------------------------------
|
||||
----------------------------------------------------
|
||||
@@ -12,4 +12,4 @@ ALTER TABLE erro_poll_option RENAME TO SS13_poll_option;
|
||||
ALTER TABLE erro_poll_question RENAME TO SS13_poll_question;
|
||||
ALTER TABLE erro_poll_textreply RENAME TO SS13_poll_textreply;
|
||||
ALTER TABLE erro_poll_vote RENAME TO SS13_poll_vote;
|
||||
ALTER TABLE erro_watch RENAME TO SS13_watch;
|
||||
ALTER TABLE erro_watch RENAME TO SS13_watch;
|
||||
@@ -38,7 +38,7 @@ Take note some columns have been renamed, removed or changed type. Any services
|
||||
----------------------------------------------------*/
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `feedback`.`ban`
|
||||
ALTER TABLE `ban`
|
||||
DROP COLUMN `rounds`
|
||||
, CHANGE COLUMN `bantype` `bantype` ENUM('PERMABAN', 'TEMPBAN', 'JOB_PERMABAN', 'JOB_TEMPBAN', 'ADMIN_PERMABAN', 'ADMIN_TEMPBAN') NOT NULL
|
||||
, CHANGE COLUMN `reason` `reason` VARCHAR(2048) NOT NULL
|
||||
@@ -51,14 +51,14 @@ ALTER TABLE `feedback`.`ban`
|
||||
, ADD COLUMN `a_ipTEMP` INT UNSIGNED NOT NULL AFTER `a_ip`
|
||||
, ADD COLUMN `unbanned_ipTEMP` INT UNSIGNED NULL DEFAULT NULL AFTER `unbanned_ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `feedback`.`ban`
|
||||
UPDATE `ban`
|
||||
SET `server_ip` = INET_ATON(SUBSTRING_INDEX(IF(`serverip` = '', '0', IF(SUBSTRING_INDEX(`serverip`, ':', 1) LIKE '%_._%', `serverip`, '0')), ':', 1))
|
||||
, `server_port` = IF(`serverip` LIKE '%:_%', CAST(SUBSTRING_INDEX(`serverip`, ':', -1) AS UNSIGNED), '0')
|
||||
, `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'))
|
||||
, `a_ipTEMP` = INET_ATON(IF(`a_ip` LIKE '%_._%', `a_ip`, '0'))
|
||||
, `unbanned_ipTEMP` = INET_ATON(IF(`unbanned_ip` LIKE '%_._%', `unbanned_ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `feedback`.`ban`
|
||||
ALTER TABLE `ban`
|
||||
DROP COLUMN `unbanned_ip`
|
||||
, DROP COLUMN `a_ip`
|
||||
, DROP COLUMN `ip`
|
||||
@@ -69,17 +69,17 @@ ALTER TABLE `feedback`.`ban`
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `feedback`.`connection_log`
|
||||
ALTER TABLE `connection_log`
|
||||
ADD COLUMN `server_ip` INT UNSIGNED NOT NULL AFTER `serverip`
|
||||
, ADD COLUMN `server_port` SMALLINT UNSIGNED NOT NULL AFTER `server_ip`
|
||||
, ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `feedback`.`connection_log`
|
||||
UPDATE `connection_log`
|
||||
SET `server_ip` = INET_ATON(SUBSTRING_INDEX(IF(`serverip` = '', '0', IF(SUBSTRING_INDEX(`serverip`, ':', 1) LIKE '%_._%', `serverip`, '0')), ':', 1))
|
||||
, `server_port` = IF(`serverip` LIKE '%:_%', CAST(SUBSTRING_INDEX(`serverip`, ':', -1) AS UNSIGNED), '0')
|
||||
, `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `feedback`.`connection_log`
|
||||
ALTER TABLE `connection_log`
|
||||
DROP COLUMN `ip`
|
||||
, DROP COLUMN `serverip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL;
|
||||
@@ -87,12 +87,12 @@ COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `feedback`.`death`
|
||||
UPDATE `death`
|
||||
SET `bruteloss` = LEAST(`bruteloss`, 65535)
|
||||
, `brainloss` = LEAST(`brainloss`, 65535)
|
||||
, `fireloss` = LEAST(`fireloss`, 65535)
|
||||
, `oxyloss` = LEAST(`oxyloss`, 65535);
|
||||
ALTER TABLE `feedback`.`death`
|
||||
ALTER TABLE `death`
|
||||
CHANGE COLUMN `pod` `pod` VARCHAR(50) NOT NULL
|
||||
, CHANGE COLUMN `coord` `coord` VARCHAR(32) NOT NULL
|
||||
, CHANGE COLUMN `mapname` `mapname` VARCHAR(32) NOT NULL
|
||||
@@ -109,39 +109,39 @@ ALTER TABLE `feedback`.`death`
|
||||
, CHANGE COLUMN `oxyloss` `oxyloss` SMALLINT UNSIGNED NOT NULL
|
||||
, ADD COLUMN `server_ip` INT UNSIGNED NOT NULL AFTER `server`
|
||||
, ADD COLUMN `server_port` SMALLINT UNSIGNED NOT NULL AFTER `server_ip`;
|
||||
UPDATE `feedback`.`death`
|
||||
UPDATE `death`
|
||||
SET `server_ip` = INET_ATON(SUBSTRING_INDEX(IF(`server` = '', '0', IF(SUBSTRING_INDEX(`server`, ':', 1) LIKE '%_._%', `server`, '0')), ':', 1))
|
||||
, `server_port` = IF(`server` LIKE '%:_%', CAST(SUBSTRING_INDEX(`server`, ':', -1) AS UNSIGNED), '0');
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `feedback`.`death`
|
||||
ALTER TABLE `death`
|
||||
DROP COLUMN `server`;
|
||||
COMMIT;
|
||||
|
||||
ALTER TABLE `feedback`.`library`
|
||||
ALTER TABLE `library`
|
||||
CHANGE COLUMN `category` `category` ENUM('Any', 'Fiction', 'Non-Fiction', 'Adult', 'Reference', 'Religion') NOT NULL
|
||||
, CHANGE COLUMN `ckey` `ckey` VARCHAR(32) NOT NULL DEFAULT 'LEGACY'
|
||||
, CHANGE COLUMN `datetime` `datetime` DATETIME NOT NULL
|
||||
, CHANGE COLUMN `deleted` `deleted` TINYINT(1) UNSIGNED NULL DEFAULT NULL;
|
||||
|
||||
ALTER TABLE `feedback`.`messages`
|
||||
ALTER TABLE `messages`
|
||||
CHANGE COLUMN `type` `type` ENUM('memo', 'message', 'message sent', 'note', 'watchlist entry') NOT NULL
|
||||
, CHANGE COLUMN `text` `text` VARCHAR(2048) NOT NULL
|
||||
, CHANGE COLUMN `secret` `secret` TINYINT(1) UNSIGNED NOT NULL;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `feedback`.`player`
|
||||
ALTER TABLE `player`
|
||||
ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `feedback`.`player`
|
||||
UPDATE `player`
|
||||
SET `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `feedback`.`player`
|
||||
ALTER TABLE `player`
|
||||
DROP COLUMN `ip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `feedback`.`poll_question`
|
||||
ALTER TABLE `poll_question`
|
||||
CHANGE COLUMN `polltype` `polltype` ENUM('OPTION', 'TEXT', 'NUMVAL', 'MULTICHOICE', 'IRV') NOT NULL
|
||||
, CHANGE COLUMN `adminonly` `adminonly` TINYINT(1) UNSIGNED NOT NULL
|
||||
, CHANGE COLUMN `createdby_ckey` `createdby_ckey` VARCHAR(32) NULL DEFAULT NULL
|
||||
@@ -149,36 +149,36 @@ ALTER TABLE `feedback`.`poll_question`
|
||||
, ADD COLUMN `createdby_ipTEMP` INT UNSIGNED NOT NULL AFTER `createdby_ip`
|
||||
, DROP COLUMN `for_trialmin`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `feedback`.`poll_question`
|
||||
UPDATE `poll_question`
|
||||
SET `createdby_ipTEMP` = INET_ATON(IF(`createdby_ip` LIKE '%_._%', `createdby_ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `feedback`.`poll_question`
|
||||
ALTER TABLE `poll_question`
|
||||
DROP COLUMN `createdby_ip`
|
||||
, CHANGE COLUMN `createdby_ipTEMP` `createdby_ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `feedback`.`poll_textreply`
|
||||
ALTER TABLE `poll_textreply`
|
||||
CHANGE COLUMN `replytext` `replytext` VARCHAR(2048) NOT NULL
|
||||
, ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `feedback`.`poll_textreply`
|
||||
UPDATE `poll_textreply`
|
||||
SET `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `feedback`.`poll_textreply`
|
||||
ALTER TABLE `poll_textreply`
|
||||
DROP COLUMN `ip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
|
||||
START TRANSACTION;
|
||||
ALTER TABLE `feedback`.`poll_vote`
|
||||
ALTER TABLE `poll_vote`
|
||||
CHANGE COLUMN `ckey` `ckey` VARCHAR(32) NOT NULL
|
||||
, ADD COLUMN `ipTEMP` INT UNSIGNED NOT NULL AFTER `ip`;
|
||||
SET SQL_SAFE_UPDATES = 0;
|
||||
UPDATE `feedback`.`poll_vote`
|
||||
UPDATE `poll_vote`
|
||||
SET `ipTEMP` = INET_ATON(IF(`ip` LIKE '%_._%', `ip`, '0'));
|
||||
SET SQL_SAFE_UPDATES = 1;
|
||||
ALTER TABLE `feedback`.`poll_vote`
|
||||
ALTER TABLE `poll_vote`
|
||||
DROP COLUMN `ip`
|
||||
, CHANGE COLUMN `ipTEMP` `ip` INT(10) UNSIGNED NOT NULL;
|
||||
COMMIT;
|
||||
@@ -191,39 +191,39 @@ You may find it helpful to modify or create your own indexes if you utilise addi
|
||||
|
||||
----------------------------------------------------*/
|
||||
|
||||
ALTER TABLE `feedback`.`ban`
|
||||
ALTER TABLE `ban`
|
||||
ADD INDEX `idx_ban_checkban` (`ckey` ASC, `bantype` ASC, `expiration_time` ASC, `unbanned` ASC, `job` ASC)
|
||||
, ADD INDEX `idx_ban_isbanned` (`ckey` ASC, `ip` ASC, `computerid` ASC, `bantype` ASC, `expiration_time` ASC, `unbanned` ASC)
|
||||
, ADD INDEX `idx_ban_count` (`id` ASC, `a_ckey` ASC, `bantype` ASC, `expiration_time` ASC, `unbanned` ASC);
|
||||
|
||||
ALTER TABLE `feedback`.`ipintel`
|
||||
ALTER TABLE `ipintel`
|
||||
ADD INDEX `idx_ipintel` (`ip` ASC, `intel` ASC, `date` ASC);
|
||||
|
||||
ALTER TABLE `feedback`.`library`
|
||||
ALTER TABLE `library`
|
||||
ADD INDEX `idx_lib_id_del` (`id` ASC, `deleted` ASC)
|
||||
, ADD INDEX `idx_lib_del_title` (`deleted` ASC, `title` ASC)
|
||||
, ADD INDEX `idx_lib_search` (`deleted` ASC, `author` ASC, `title` ASC, `category` ASC);
|
||||
|
||||
ALTER TABLE `feedback`.`messages`
|
||||
ALTER TABLE `messages`
|
||||
ADD INDEX `idx_msg_ckey_time` (`targetckey` ASC, `timestamp` ASC)
|
||||
, ADD INDEX `idx_msg_type_ckeys_time` (`type` ASC, `targetckey` ASC, `adminckey` ASC, `timestamp` ASC)
|
||||
, ADD INDEX `idx_msg_type_ckey_time_odr` (`type` ASC, `targetckey` ASC, `timestamp` ASC);
|
||||
|
||||
ALTER TABLE `feedback`.`player`
|
||||
ALTER TABLE `player`
|
||||
ADD INDEX `idx_player_cid_ckey` (`computerid` ASC, `ckey` ASC)
|
||||
, ADD INDEX `idx_player_ip_ckey` (`ip` ASC, `ckey` ASC);
|
||||
|
||||
ALTER TABLE `feedback`.`poll_option`
|
||||
ALTER TABLE `poll_option`
|
||||
ADD INDEX `idx_pop_pollid` (`pollid` ASC);
|
||||
|
||||
ALTER TABLE `feedback`.`poll_question`
|
||||
ALTER TABLE `poll_question`
|
||||
ADD INDEX `idx_pquest_question_time_ckey` (`question` ASC, `starttime` ASC, `endtime` ASC, `createdby_ckey` ASC, `createdby_ip` ASC)
|
||||
, ADD INDEX `idx_pquest_time_admin` (`starttime` ASC, `endtime` ASC, `adminonly` ASC)
|
||||
, ADD INDEX `idx_pquest_id_time_type_admin` (`id` ASC, `starttime` ASC, `endtime` ASC, `polltype` ASC, `adminonly` ASC);
|
||||
|
||||
ALTER TABLE `feedback`.`poll_vote`
|
||||
ALTER TABLE `poll_vote`
|
||||
ADD INDEX `idx_pvote_pollid_ckey` (`pollid` ASC, `ckey` ASC)
|
||||
, ADD INDEX `idx_pvote_optionid_ckey` (`optionid` ASC, `ckey` ASC);
|
||||
|
||||
ALTER TABLE `feedback`.`poll_textreply`
|
||||
ADD INDEX `idx_ptext_pollid_ckey` (`pollid` ASC, `ckey` ASC);
|
||||
ALTER TABLE `poll_textreply`
|
||||
ADD INDEX `idx_ptext_pollid_ckey` (`pollid` ASC, `ckey` ASC);
|
||||
@@ -254,10 +254,11 @@ CREATE TABLE `messages` (
|
||||
`secret` tinyint(1) unsigned NOT NULL,
|
||||
`lasteditor` varchar(32) DEFAULT NULL,
|
||||
`edits` text,
|
||||
`deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_msg_ckey_time` (`targetckey`,`timestamp`),
|
||||
KEY `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`),
|
||||
KEY `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`)
|
||||
KEY `idx_msg_ckey_time` (`targetckey`,`timestamp`, `deleted`),
|
||||
KEY `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`, `deleted`),
|
||||
KEY `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`, `deleted`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
@@ -430,4 +431,4 @@ CREATE TABLE `schema_revision` (
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
@@ -1,9 +0,0 @@
|
||||
diff a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql (rejected hunks)
|
||||
@@ -268,7 +283,6 @@ CREATE TABLE `player` (
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`computerid` varchar(32) NOT NULL,
|
||||
`lastadminrank` varchar(32) NOT NULL DEFAULT 'Player',
|
||||
- `exp` mediumtext,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`),
|
||||
KEY `idx_player_cid_ckey` (`computerid`,`ckey`),
|
||||
@@ -31,7 +31,7 @@ CREATE TABLE `SS13_admin` (
|
||||
-- Table structure for table `SS13_admin_log`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `SS13_dmin_log`;
|
||||
DROP TABLE IF EXISTS `SS13_admin_log`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `SS13_admin_log` (
|
||||
@@ -254,10 +254,11 @@ CREATE TABLE `SS13_messages` (
|
||||
`secret` tinyint(1) unsigned NOT NULL,
|
||||
`lasteditor` varchar(32) DEFAULT NULL,
|
||||
`edits` text,
|
||||
`deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_msg_ckey_time` (`targetckey`,`timestamp`),
|
||||
KEY `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`),
|
||||
KEY `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`)
|
||||
KEY `idx_msg_ckey_time` (`targetckey`,`timestamp`, `deleted`),
|
||||
KEY `idx_msg_type_ckeys_time` (`type`,`targetckey`,`adminckey`,`timestamp`, `deleted`),
|
||||
KEY `idx_msg_type_ckey_time_odr` (`type`,`targetckey`,`timestamp`, `deleted`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
@@ -430,4 +431,4 @@ CREATE TABLE `SS13_schema_revision` (
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
@@ -1,9 +0,0 @@
|
||||
diff a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql (rejected hunks)
|
||||
@@ -268,7 +297,6 @@ CREATE TABLE `SS13_player` (
|
||||
`ip` int(10) unsigned NOT NULL,
|
||||
`computerid` varchar(32) NOT NULL,
|
||||
`lastadminrank` varchar(32) NOT NULL DEFAULT 'Player',
|
||||
- `exp` mediumtext,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`),
|
||||
KEY `idx_player_cid_ckey` (`computerid`,`ckey`),
|
||||
@@ -24458,7 +24458,7 @@
|
||||
/area/crew_quarters/heads/captain)
|
||||
"bfE" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/pinpointer,
|
||||
/obj/item/pinpointer/nuke,
|
||||
/obj/item/disk/nuclear,
|
||||
/obj/item/storage/secure/safe{
|
||||
pixel_x = 35;
|
||||
|
||||
@@ -53210,7 +53210,7 @@
|
||||
/area/tcommsat/server)
|
||||
"bYo" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/pinpointer,
|
||||
/obj/item/pinpointer/nuke,
|
||||
/obj/item/disk/nuclear,
|
||||
/obj/item/device/radio/intercom{
|
||||
name = "Station Intercom";
|
||||
|
||||
@@ -29108,7 +29108,7 @@
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/pinpointer,
|
||||
/obj/item/pinpointer/nuke,
|
||||
/obj/item/disk/nuclear,
|
||||
/turf/open/floor/carpet,
|
||||
/area/crew_quarters/heads/captain/private)
|
||||
|
||||
@@ -1187,7 +1187,7 @@
|
||||
pixel_x = 32;
|
||||
pixel_y = 24
|
||||
},
|
||||
/obj/item/pinpointer,
|
||||
/obj/item/pinpointer/nuke,
|
||||
/obj/item/disk/nuclear,
|
||||
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
|
||||
dir = 10
|
||||
|
||||
@@ -13917,7 +13917,7 @@
|
||||
/area/storage/primary)
|
||||
"aEx" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/pinpointer,
|
||||
/obj/item/pinpointer/nuke,
|
||||
/obj/item/disk/nuclear,
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
|
||||
+148
-74
@@ -1,74 +1,148 @@
|
||||
//A set of constants used to determine which type of mute an admin wishes to apply:
|
||||
//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1)
|
||||
//Therefore there needs to be a gap between the flags_1 for the automute flags_1
|
||||
#define MUTE_IC 1
|
||||
#define MUTE_OOC 2
|
||||
#define MUTE_PRAY 4
|
||||
#define MUTE_ADMINHELP 8
|
||||
#define MUTE_DEADCHAT 16
|
||||
#define MUTE_ALL 31
|
||||
|
||||
//Some constants for DB_Ban
|
||||
#define BANTYPE_PERMA 1
|
||||
#define BANTYPE_TEMP 2
|
||||
#define BANTYPE_JOB_PERMA 3
|
||||
#define BANTYPE_JOB_TEMP 4
|
||||
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
|
||||
|
||||
#define BANTYPE_ADMIN_PERMA 7
|
||||
#define BANTYPE_ADMIN_TEMP 8
|
||||
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
|
||||
|
||||
//Please don't edit these values without speaking to Errorage first ~Carn
|
||||
//Admin Permissions
|
||||
#define R_BUILDMODE 1
|
||||
#define R_ADMIN 2
|
||||
#define R_BAN 4
|
||||
#define R_FUN 8
|
||||
#define R_SERVER 16
|
||||
#define R_DEBUG 32
|
||||
#define R_POSSESS 64
|
||||
#define R_PERMISSIONS 128
|
||||
#define R_STEALTH 256
|
||||
#define R_POLL 512
|
||||
#define R_VAREDIT 1024
|
||||
#define R_SOUNDS 2048
|
||||
#define R_SPAWN 4096
|
||||
|
||||
#if DM_VERSION > 512
|
||||
#error Remove the flag below , its been long enough
|
||||
#endif
|
||||
//legacy , remove post 512, it was replaced by R_POLL
|
||||
#define R_REJUVINATE 2
|
||||
|
||||
#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
|
||||
|
||||
#define ADMIN_QUE(user) "(<a href='?_src_=holder;adminmoreinfo=\ref[user]'>?</a>)"
|
||||
#define ADMIN_FLW(user) "(<a href='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</a>)"
|
||||
#define ADMIN_PP(user) "(<a href='?_src_=holder;adminplayeropts=\ref[user]'>PP</a>)"
|
||||
#define ADMIN_VV(atom) "(<a href='?_src_=vars;Vars=\ref[atom]'>VV</a>)"
|
||||
#define ADMIN_SM(user) "(<a href='?_src_=holder;subtlemessage=\ref[user]'>SM</a>)"
|
||||
#define ADMIN_TP(user) "(<a href='?_src_=holder;traitor=\ref[user]'>TP</a>)"
|
||||
#define ADMIN_KICK(user) "(<a href='?_src_=holder;boot2=\ref[user]'>KICK</a>)"
|
||||
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;CentComReply=\ref[user]'>RPLY</a>)"
|
||||
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;SyndicateReply=\ref[user]'>RPLY</a>)"
|
||||
#define ADMIN_SC(user) "(<a href='?_src_=holder;adminspawncookie=\ref[user]'>SC</a>)"
|
||||
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;adminsmite=\ref[user]'>SMITE</a>)"
|
||||
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
|
||||
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
|
||||
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;set_selfdestruct_code=1'>SETCODE</a>)"
|
||||
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]"
|
||||
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
|
||||
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
|
||||
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
|
||||
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
|
||||
#define ADMIN_INDIVIDUALLOG(user) "(<a href='?_src_=holder;individuallog=\ref[user]'>LOGS</a>)"
|
||||
|
||||
#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt"
|
||||
#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage"
|
||||
#define ADMIN_PUNISHMENT_GIB "Gib"
|
||||
#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device"
|
||||
|
||||
#define AHELP_ACTIVE 1
|
||||
#define AHELP_CLOSED 2
|
||||
#define AHELP_RESOLVED 3
|
||||
//A set of constants used to determine which type of mute an admin wishes to apply:
|
||||
//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1)
|
||||
//Therefore there needs to be a gap between the flags_1 for the automute flags_1
|
||||
#define MUTE_IC 1
|
||||
#define MUTE_OOC 2
|
||||
#define MUTE_PRAY 4
|
||||
#define MUTE_ADMINHELP 8
|
||||
#define MUTE_DEADCHAT 16
|
||||
#define MUTE_ALL 31
|
||||
|
||||
//Some constants for DB_Ban
|
||||
#define BANTYPE_PERMA 1
|
||||
#define BANTYPE_TEMP 2
|
||||
#define BANTYPE_JOB_PERMA 3
|
||||
#define BANTYPE_JOB_TEMP 4
|
||||
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
|
||||
|
||||
#define BANTYPE_ADMIN_PERMA 7
|
||||
#define BANTYPE_ADMIN_TEMP 8
|
||||
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
|
||||
|
||||
//Please don't edit these values without speaking to Errorage first ~Carn
|
||||
//Admin Permissions
|
||||
#define R_BUILDMODE 1
|
||||
#define R_ADMIN 2
|
||||
#define R_BAN 4
|
||||
#define R_FUN 8
|
||||
#define R_SERVER 16
|
||||
#define R_DEBUG 32
|
||||
#define R_POSSESS 64
|
||||
#define R_PERMISSIONS 128
|
||||
#define R_STEALTH 256
|
||||
#define R_POLL 512
|
||||
#define R_VAREDIT 1024
|
||||
#define R_SOUNDS 2048
|
||||
#define R_SPAWN 4096
|
||||
|
||||
#if DM_VERSION > 512
|
||||
#error Remove the flag below , its been long enough
|
||||
#endif
|
||||
//legacy , remove post 512, it was replaced by R_POLL
|
||||
#define R_REJUVINATE 2
|
||||
|
||||
#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
|
||||
|
||||
#define ADMIN_QUE(user) "(<a href='?_src_=holder;adminmoreinfo=\ref[user]'>?</a>)"
|
||||
#define ADMIN_FLW(user) "(<a href='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</a>)"
|
||||
#define ADMIN_PP(user) "(<a href='?_src_=holder;adminplayeropts=\ref[user]'>PP</a>)"
|
||||
#define ADMIN_VV(atom) "(<a href='?_src_=vars;Vars=\ref[atom]'>VV</a>)"
|
||||
#define ADMIN_SM(user) "(<a href='?_src_=holder;subtlemessage=\ref[user]'>SM</a>)"
|
||||
#define ADMIN_TP(user) "(<a href='?_src_=holder;traitor=\ref[user]'>TP</a>)"
|
||||
#define ADMIN_KICK(user) "(<a href='?_src_=holder;boot2=\ref[user]'>KICK</a>)"
|
||||
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;CentComReply=\ref[user]'>RPLY</a>)"
|
||||
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;SyndicateReply=\ref[user]'>RPLY</a>)"
|
||||
#define ADMIN_SC(user) "(<a href='?_src_=holder;adminspawncookie=\ref[user]'>SC</a>)"
|
||||
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;adminsmite=\ref[user]'>SMITE</a>)"
|
||||
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
|
||||
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
|
||||
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;set_selfdestruct_code=1'>SETCODE</a>)"
|
||||
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]"
|
||||
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
|
||||
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
|
||||
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
|
||||
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
|
||||
#define ADMIN_INDIVIDUALLOG(user) "(<a href='?_src_=holder;individuallog=\ref[user]'>LOGS</a>)"
|
||||
|
||||
#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt"
|
||||
#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage"
|
||||
#define ADMIN_PUNISHMENT_GIB "Gib"
|
||||
#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device"
|
||||
|
||||
#define AHELP_ACTIVE 1
|
||||
#define AHELP_CLOSED 2
|
||||
#define AHELP_RESOLVED 3
|
||||
//A set of constants used to determine which type of mute an admin wishes to apply:
|
||||
//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1)
|
||||
//Therefore there needs to be a gap between the flags for the automute flags
|
||||
#define MUTE_IC 1
|
||||
#define MUTE_OOC 2
|
||||
#define MUTE_PRAY 4
|
||||
#define MUTE_ADMINHELP 8
|
||||
#define MUTE_DEADCHAT 16
|
||||
#define MUTE_ALL 31
|
||||
|
||||
//Some constants for DB_Ban
|
||||
#define BANTYPE_PERMA 1
|
||||
#define BANTYPE_TEMP 2
|
||||
#define BANTYPE_JOB_PERMA 3
|
||||
#define BANTYPE_JOB_TEMP 4
|
||||
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
|
||||
|
||||
#define BANTYPE_ADMIN_PERMA 7
|
||||
#define BANTYPE_ADMIN_TEMP 8
|
||||
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
|
||||
|
||||
//Please don't edit these values without speaking to Errorage first ~Carn
|
||||
//Admin Permissions
|
||||
#define R_BUILDMODE 1
|
||||
#define R_ADMIN 2
|
||||
#define R_BAN 4
|
||||
#define R_FUN 8
|
||||
#define R_SERVER 16
|
||||
#define R_DEBUG 32
|
||||
#define R_POSSESS 64
|
||||
#define R_PERMISSIONS 128
|
||||
#define R_STEALTH 256
|
||||
#define R_POLL 512
|
||||
#define R_VAREDIT 1024
|
||||
#define R_SOUNDS 2048
|
||||
#define R_SPAWN 4096
|
||||
|
||||
#if DM_VERSION > 512
|
||||
#error Remove the flag below , its been long enough
|
||||
#endif
|
||||
//legacy , remove post 512, it was replaced by R_POLL
|
||||
#define R_REJUVINATE 2
|
||||
|
||||
#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
|
||||
|
||||
#define ADMIN_QUE(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminmoreinfo=\ref[user]'>?</a>)"
|
||||
#define ADMIN_FLW(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminplayerobservefollow=\ref[user]'>FLW</a>)"
|
||||
#define ADMIN_PP(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminplayeropts=\ref[user]'>PP</a>)"
|
||||
#define ADMIN_VV(atom) "(<a href='?_src_=vars;[HrefToken(TRUE)];Vars=\ref[atom]'>VV</a>)"
|
||||
#define ADMIN_SM(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];subtlemessage=\ref[user]'>SM</a>)"
|
||||
#define ADMIN_TP(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];traitor=\ref[user]'>TP</a>)"
|
||||
#define ADMIN_KICK(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];boot2=\ref[user]'>KICK</a>)"
|
||||
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];CentComReply=\ref[user]'>RPLY</a>)"
|
||||
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];SyndicateReply=\ref[user]'>RPLY</a>)"
|
||||
#define ADMIN_SC(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminspawncookie=\ref[user]'>SC</a>)"
|
||||
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminsmite=\ref[user]'>SMITE</a>)"
|
||||
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
|
||||
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
|
||||
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;[HrefToken(TRUE)];set_selfdestruct_code=1'>SETCODE</a>)"
|
||||
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]"
|
||||
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
|
||||
#define ADMIN_JMP(src) "(<a href='?_src_=holder;[HrefToken(TRUE)];adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
|
||||
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
|
||||
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
|
||||
#define ADMIN_INDIVIDUALLOG(user) "(<a href='?_src_=holder;[HrefToken(TRUE)];individuallog=\ref[user]'>LOGS</a>)"
|
||||
|
||||
#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt"
|
||||
#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage"
|
||||
#define ADMIN_PUNISHMENT_GIB "Gib"
|
||||
#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device"
|
||||
|
||||
#define AHELP_ACTIVE 1
|
||||
#define AHELP_CLOSED 2
|
||||
#define AHELP_RESOLVED 3
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// How multiple components of the exact same type are handled in the same datum
|
||||
|
||||
#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
|
||||
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
|
||||
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
|
||||
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
|
||||
|
||||
// All signals. Format:
|
||||
@@ -16,3 +16,9 @@
|
||||
#define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: ()
|
||||
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable, atom)
|
||||
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable)
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from the base of atom/attackby: (obj/item, mob/living, params)
|
||||
#define COMSIG_PARENT_EXAMINE "atom_examine" //from the base of atom/examine: (mob)
|
||||
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable, atom)
|
||||
#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target)
|
||||
#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size)
|
||||
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable)
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#define islava(A) (istype(A, /turf/open/lava))
|
||||
|
||||
#define isplatingturf(A) (istype(A, /turf/open/floor/plating))
|
||||
|
||||
//Mobs
|
||||
#define isliving(A) (istype(A, /mob/living))
|
||||
|
||||
|
||||
@@ -458,3 +458,8 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define SHELLEO_ERRORLEVEL 1
|
||||
#define SHELLEO_STDOUT 2
|
||||
#define SHELLEO_STDERR 3
|
||||
|
||||
//server security mode
|
||||
#define SECURITY_SAFE 1
|
||||
#define SECURITY_ULTRASAFE 2
|
||||
#define SECURITY_TRUSTED 3
|
||||
|
||||
@@ -2,6 +2,3 @@
|
||||
#define TRACK_NUKE_DISK 1 //We track the nuclear authentication disk, either to protect it or steal it
|
||||
#define TRACK_MALF_AI 2 //We track the malfunctioning AI, so we can prevent it from blowing us all up
|
||||
#define TRACK_INFILTRATOR 3 //We track the Syndicate infiltrator, so we can get back to ship when the nuke's armed
|
||||
#define TRACK_OPERATIVES 4 //We track the closest operative, so we can regroup when we need to
|
||||
#define TRACK_ATOM 5 //We track a specified atom, so admins can make us function for events
|
||||
#define TRACK_COORDINATES 6 //We point towards the specified coordinates on our z-level, so we can navigate
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
//keep these in sync with TGS3
|
||||
#define SERVICE_WORLD_PARAM "server_service"
|
||||
#define SERVICE_PR_TEST_JSON "..\\..\\prtestjob.json"
|
||||
#define SERVICE_VERSION_PARAM "server_service_version"
|
||||
#define SERVICE_PR_TEST_JSON "prtestjob.json"
|
||||
#define SERVICE_PR_TEST_JSON_OLD "..\\..\\[SERVICE_PR_TEST_JSON]"
|
||||
|
||||
#define SERVICE_CMD_HARD_REBOOT "hard_reboot"
|
||||
#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown"
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
flags_1 = NOBLUDGEON_1
|
||||
|
||||
|
||||
/*Inferno707*/
|
||||
|
||||
/obj/item/clothing/neck/cloak/inferno
|
||||
name = "Kiara's Cloak"
|
||||
desc = "The design on this seems a little too familiar."
|
||||
@@ -19,6 +22,16 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
body_parts_covered = CHEST|GROIN|LEGS|ARMS
|
||||
|
||||
/obj/item/clothing/neck/petcollar/inferno
|
||||
name = "Kiara's Collar"
|
||||
desc = "A soft black collar that seems to stretch to fit whoever wears it."
|
||||
icon_state = "infcollar"
|
||||
item_state = "infcollar"
|
||||
item_color = null
|
||||
tagname = null
|
||||
|
||||
/*DirtyOldHarry*/
|
||||
|
||||
/obj/item/lighter/gold
|
||||
name = "\improper Engraved Zippo"
|
||||
desc = "A shiny and relatively expensive zippo lighter. There's a small etched in verse on the bottom that reads, 'No Gods, No Masters, Only Man.'"
|
||||
@@ -30,4 +43,14 @@
|
||||
slot_flags = SLOT_BELT
|
||||
heat = 1500
|
||||
resistance_flags = FIRE_PROOF
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
|
||||
|
||||
/*Zombierobin*/
|
||||
|
||||
/obj/item/clothing/neck/scarf/zomb //Default white color, same functionality as beanies.
|
||||
name = "A special scarf"
|
||||
icon_state = "zombscarf"
|
||||
desc = "A fashionable collar"
|
||||
item_color = "zombscarf"
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
@@ -108,6 +108,8 @@ GLOBAL_PROTECT(config_dir)
|
||||
var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
|
||||
var/use_account_age_for_jobs = 0 //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected.
|
||||
var/see_own_notes = 0 //Can players see their own admin notes (read-only)? Config option in config.txt
|
||||
var/note_fresh_days
|
||||
var/note_stale_days
|
||||
|
||||
var/use_exp_tracking = FALSE
|
||||
var/use_exp_restrictions_heads = FALSE
|
||||
@@ -280,6 +282,8 @@ GLOBAL_PROTECT(config_dir)
|
||||
|
||||
var/list/policies = list()
|
||||
|
||||
var/debug_admin_hrefs = FALSE //turns off admin href token protection for debugging purposes
|
||||
|
||||
/datum/configuration/New()
|
||||
gamemode_cache = typecacheof(/datum/game_mode,TRUE)
|
||||
for(var/T in gamemode_cache)
|
||||
@@ -484,6 +488,10 @@ GLOBAL_PROTECT(config_dir)
|
||||
showircname = 1
|
||||
if("see_own_notes")
|
||||
see_own_notes = 1
|
||||
if("note_fresh_days")
|
||||
note_fresh_days = text2num(value)
|
||||
if("note_stale_days")
|
||||
note_stale_days = text2num(value)
|
||||
if("soft_popcap")
|
||||
soft_popcap = text2num(value)
|
||||
if("hard_popcap")
|
||||
@@ -563,6 +571,8 @@ GLOBAL_PROTECT(config_dir)
|
||||
error_msg_delay = text2num(value)
|
||||
if("irc_announce_new_game")
|
||||
irc_announce_new_game = TRUE
|
||||
if("debug_admin_hrefs")
|
||||
debug_admin_hrefs = TRUE
|
||||
else
|
||||
#if DM_VERSION > 511
|
||||
#error Replace the line below with WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
|
||||
|
||||
@@ -116,6 +116,8 @@ SUBSYSTEM_DEF(events)
|
||||
|
||||
//allows a client to trigger an event
|
||||
//aka Badmin Central
|
||||
// > Not in modules/admin
|
||||
// REEEEEEEEE
|
||||
/client/proc/forceEvent()
|
||||
set name = "Trigger Event"
|
||||
set category = "Fun"
|
||||
@@ -131,7 +133,7 @@ SUBSYSTEM_DEF(events)
|
||||
var/magic = ""
|
||||
var/holiday = ""
|
||||
for(var/datum/round_event_control/E in SSevents.control)
|
||||
dat = "<BR><A href='?src=\ref[src];forceevent=\ref[E]'>[E]</A>"
|
||||
dat = "<BR><A href='?src=\ref[src];[HrefToken()];forceevent=\ref[E]'>[E]</A>"
|
||||
if(E.holidayID)
|
||||
holiday += dat
|
||||
else if(E.wizardevent)
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/datum/component/archaeology
|
||||
dupe_type = COMPONENT_DUPE_UNIQUE
|
||||
var/list/archdrops
|
||||
var/prob2drop
|
||||
var/dug
|
||||
|
||||
/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list())
|
||||
prob2drop = Clamp(_prob2drop, 0, 100)
|
||||
archdrops = _archdrops
|
||||
RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig)
|
||||
RegisterSignal(COMSIG_ATOM_EX_ACT, .proc/BombDig)
|
||||
RegisterSignal(COMSIG_ATOM_SING_PULL, .proc/SingDig)
|
||||
|
||||
/datum/component/archaeology/InheritComponent(datum/component/archaeology/A, i_am_original)
|
||||
var/list/other_archdrops = A.archdrops
|
||||
var/list/_archdrops = archdrops
|
||||
for(var/I in other_archdrops)
|
||||
_archdrops[I] += other_archdrops[I]
|
||||
|
||||
/datum/component/archaeology/proc/Dig(mob/user, obj/item/W)
|
||||
if(dug)
|
||||
to_chat(user, "<span class='notice'>Looks like someone has dug here already.</span>")
|
||||
return FALSE
|
||||
else
|
||||
var/digging_speed
|
||||
if (istype(W, /obj/item/shovel))
|
||||
var/obj/item/shovel/S = W
|
||||
digging_speed = S.digspeed
|
||||
else if (istype(W, /obj/item/pickaxe))
|
||||
var/obj/item/pickaxe/P = W
|
||||
digging_speed = P.digspeed
|
||||
|
||||
if (digging_speed && isturf(user.loc))
|
||||
to_chat(user, "<span class='notice'>You start digging...</span>")
|
||||
playsound(parent, 'sound/effects/shovel_dig.ogg', 50, 1)
|
||||
|
||||
if(do_after(user, digging_speed, target = parent))
|
||||
to_chat(user, "<span class='notice'>You dig a hole.</span>")
|
||||
gets_dug()
|
||||
dug = TRUE
|
||||
SSblackbox.add_details("pick_used_mining",W.type)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/component/archaeology/proc/gets_dug()
|
||||
if(dug)
|
||||
return
|
||||
else
|
||||
var/turf/open/OT = get_turf(parent)
|
||||
for(var/thing in archdrops)
|
||||
var/maxtodrop = archdrops[thing]
|
||||
for(var/i in 1 to maxtodrop)
|
||||
if(prob(prob2drop)) // can't win them all!
|
||||
new thing(OT)
|
||||
|
||||
if(isopenturf(OT))
|
||||
if(OT.postdig_icon_change)
|
||||
if(istype(OT, /turf/open/floor/plating/asteroid/) && !OT.postdig_icon)
|
||||
var/turf/open/floor/plating/asteroid/AOT = parent
|
||||
AOT.icon_plating = "[AOT.environment_type]_dug"
|
||||
AOT.icon_state = "[AOT.environment_type]_dug"
|
||||
else
|
||||
if(isplatingturf(OT))
|
||||
var/turf/open/floor/plating/POT = parent
|
||||
POT.icon_plating = "[POT.postdig_icon]"
|
||||
OT.icon_state = "[OT.postdig_icon]"
|
||||
|
||||
if(OT.slowdown) //Things like snow slow you down until you dig them.
|
||||
OT.slowdown = 0
|
||||
dug = TRUE
|
||||
|
||||
/datum/component/archaeology/proc/SingDig(S, current_size)
|
||||
switch(current_size)
|
||||
if(STAGE_THREE)
|
||||
if(prob(30))
|
||||
gets_dug()
|
||||
if(STAGE_FOUR)
|
||||
if(prob(50))
|
||||
gets_dug()
|
||||
else
|
||||
if(current_size >= STAGE_FIVE && prob(70))
|
||||
gets_dug()
|
||||
|
||||
/datum/component/archaeology/proc/BombDig(severity, target)
|
||||
switch(severity)
|
||||
if(3)
|
||||
return
|
||||
if(2)
|
||||
if(prob(20))
|
||||
gets_dug()
|
||||
if(1)
|
||||
gets_dug()
|
||||
+1159
-1138
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,14 @@
|
||||
var/date
|
||||
|
||||
/datum/getrev/New()
|
||||
if(world.RunningService() && fexists(SERVICE_PR_TEST_JSON))
|
||||
testmerge = json_decode(file2text(SERVICE_PR_TEST_JSON))
|
||||
if(world.RunningService())
|
||||
var/file_name
|
||||
if(ServiceVersion()) //will return null for versions < 3.0.91.0
|
||||
file_name = SERVICE_PR_TEST_JSON_OLD
|
||||
else
|
||||
file_name = SERVICE_PR_TEST_JSON
|
||||
if(fexists(file_name))
|
||||
testmerge = json_decode(file2text(file_name))
|
||||
#ifdef SERVERTOOLS
|
||||
else if(!world.RunningService() && fexists("../prtestjob.lk")) //tgs2 support
|
||||
var/list/tmp = world.file2list("..\\prtestjob.lk")
|
||||
|
||||
+1
-1
@@ -311,7 +311,7 @@
|
||||
traitor_mob.mind.store_memory("<B>Radio Frequency:</B> [format_frequency(R.traitor_frequency)] ([R.name]).")
|
||||
|
||||
else if(uplink_loc == PDA)
|
||||
PDA.lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
|
||||
PDA.lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
|
||||
if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
|
||||
traitor_mob.mind.store_memory("<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name]).")
|
||||
|
||||
+7
-6
@@ -304,6 +304,7 @@
|
||||
/atom/proc/ex_act(severity, target)
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
SendSignal(COMSIG_ATOM_EX_ACT, severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
@@ -468,8 +469,8 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
/atom/proc/singularity_act()
|
||||
return
|
||||
|
||||
/atom/proc/singularity_pull()
|
||||
return
|
||||
/atom/proc/singularity_pull(obj/singularity/S, current_size)
|
||||
SendSignal(COMSIG_ATOM_SING_PULL, S, current_size)
|
||||
|
||||
/atom/proc/acid_act(acidpwr, acid_volume)
|
||||
return
|
||||
@@ -613,10 +614,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
. += "---"
|
||||
var/turf/curturf = get_turf(src)
|
||||
if (curturf)
|
||||
.["Jump to"] = "?_src_=holder;adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]"
|
||||
.["Add reagent"] = "?_src_=vars;addreagent=\ref[src]"
|
||||
.["Trigger EM pulse"] = "?_src_=vars;emp=\ref[src]"
|
||||
.["Trigger explosion"] = "?_src_=vars;explode=\ref[src]"
|
||||
.["Jump to"] = "?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]"
|
||||
.["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=\ref[src]"
|
||||
.["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=\ref[src]"
|
||||
.["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=\ref[src]"
|
||||
|
||||
/atom/proc/drop_location()
|
||||
var/atom/L = loc
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
//to differentiate it, naturally everyone forgot about this immediately and so some things
|
||||
//would bump twice, so now it's called Collide
|
||||
/atom/movable/proc/Collide(atom/A)
|
||||
if((A))
|
||||
if(A)
|
||||
if(throwing)
|
||||
throwing.hit_atom(A)
|
||||
. = 1
|
||||
@@ -497,7 +497,7 @@
|
||||
/atom/movable/vv_get_dropdown()
|
||||
. = ..()
|
||||
. -= "Jump to"
|
||||
.["Follow"] = "?_src_=holder;adminplayerobservefollow=\ref[src]"
|
||||
.["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[src]"
|
||||
|
||||
/atom/movable/proc/ex_check(ex_id)
|
||||
if(!ex_id)
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
to_chat(src, "<i>Node Blobs</i> are blobs which grow, like the core. Like the core it can activate resource and factory blobs.")
|
||||
to_chat(src, "<b>In addition to the buttons on your HUD, there are a few click shortcuts to speed up expansion and defense.</b>")
|
||||
to_chat(src, "<b>Shortcuts:</b> Click = Expand Blob <b>|</b> Middle Mouse Click = Rally Spores <b>|</b> Ctrl Click = Create Shield Blob <b>|</b> Alt Click = Remove Blob")
|
||||
to_chat(src, "Attempting to talk will send a message to all other GLOB.overminds, allowing you to coordinate with them.")
|
||||
to_chat(src, "Attempting to talk will send a message to all other overminds, allowing you to coordinate with them.")
|
||||
if(!placed && autoplace_max_time <= world.time)
|
||||
to_chat(src, "<span class='big'><font color=\"#EE4000\">You will automatically place your blob core in [round((autoplace_max_time - world.time)/600, 0.5)] minutes.</font></span>")
|
||||
to_chat(src, "<span class='big'><font color=\"#EE4000\">You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.</font></span>")
|
||||
|
||||
@@ -90,8 +90,10 @@
|
||||
/obj/structure/blob/proc/Life()
|
||||
return
|
||||
|
||||
/obj/structure/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||
src.Be_Pulsed()
|
||||
/obj/structure/blob/proc/Pulse_Area(mob/camera/blob/pulsing_overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
|
||||
if(QDELETED(pulsing_overmind))
|
||||
pulsing_overmind = overmind
|
||||
Be_Pulsed()
|
||||
var/expanded = FALSE
|
||||
if(prob(70) && expand())
|
||||
expanded = TRUE
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
to_chat(user, "<span class='inathneq'>An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used.</span>")
|
||||
else
|
||||
var/efficiency = get_efficiency_mod(TRUE)
|
||||
to_chat(user, "<span class='inathneq_small'>It requires at least <b>[get_delay_cost()]W</b> of power to attempt to delay the arrival of an emergency shuttle by <b>[2 * efficiency]</b> minutes.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>This cost increases by <b>[delay_cost_increase]W</b> for every previous activation.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>It requires at least <b>[DisplayPower(get_delay_cost())]</b> of power to attempt to delay the arrival of an emergency shuttle by <b>[2 * efficiency]</b> minutes.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>This cost increases by <b>[DisplayPower(delay_cost_increase)]</b> for every previous activation.</span>")
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects)
|
||||
if(active)
|
||||
@@ -126,7 +126,7 @@
|
||||
if(!hex_combo)
|
||||
hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
|
||||
else
|
||||
hex_combo.overlays += mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
|
||||
hex_combo.add_overlay(mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER))
|
||||
if(hex_combo) //YOU BUILT A HEXAGON
|
||||
hex_combo.pixel_x = -16
|
||||
hex_combo.pixel_y = -16
|
||||
|
||||
@@ -309,8 +309,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
owner_AI.nuking = TRUE
|
||||
owner_AI.doomsday_device = DOOM
|
||||
owner_AI.doomsday_device.start()
|
||||
for(var/pinpointer in GLOB.pinpointer_list)
|
||||
var/obj/item/pinpointer/P = pinpointer
|
||||
for(var/obj/item/pinpointer/nuke/P in GLOB.pinpointer_list)
|
||||
P.switch_mode_to(TRACK_MALF_AI) //Pinpointers start tracking the AI wherever it goes
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
diff a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm (rejected hunks)
|
||||
@@ -309,8 +309,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
owner_AI.nuking = TRUE
|
||||
owner_AI.doomsday_device = DOOM
|
||||
owner_AI.doomsday_device.start()
|
||||
- for(var/pinpointer in GLOB.pinpointer_list)
|
||||
- var/obj/item/weapon/pinpointer/P = pinpointer
|
||||
+ for(var/obj/item/weapon/pinpointer/nuke/P in GLOB.pinpointer_list)
|
||||
P.switch_mode_to(TRACK_MALF_AI) //Pinpointers start tracking the AI wherever it goes
|
||||
qdel(src)
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
var/list/abductee_minds
|
||||
var/flash = " - || - "
|
||||
var/obj/machinery/abductor/console/console
|
||||
var/message_cooldown = 0
|
||||
var/breakout_time = 0.75
|
||||
|
||||
/obj/machinery/abductor/experiment/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
|
||||
@@ -40,25 +42,23 @@
|
||||
/obj/machinery/abductor/experiment/relaymove(mob/user)
|
||||
if(user.stat != CONSCIOUS)
|
||||
return
|
||||
container_resist(user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/abductor/experiment/container_resist(mob/living/user)
|
||||
var/breakout_time = 600
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about a minute.)</span>")
|
||||
user.visible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>")
|
||||
|
||||
if(do_after(user,(breakout_time), target = src))
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H)
|
||||
var/icon/photo = null
|
||||
var/g = (H.gender == FEMALE) ? "f" : "m"
|
||||
|
||||
@@ -325,7 +325,7 @@
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
back = /obj/item/storage/backpack
|
||||
ears = /obj/item/device/radio/headset/syndicate/alt
|
||||
l_pocket = /obj/item/pinpointer/syndicate
|
||||
l_pocket = /obj/item/pinpointer/nuke/syndicate
|
||||
id = /obj/item/card/id/syndicate
|
||||
belt = /obj/item/gun/ballistic/automatic/pistol
|
||||
backpack_contents = list(/obj/item/storage/box/syndie=1)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm (rejected hunks)
|
||||
@@ -325,7 +325,7 @@
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
ears = /obj/item/device/radio/headset/syndicate/alt
|
||||
- l_pocket = /obj/item/weapon/pinpointer/syndicate
|
||||
+ l_pocket = /obj/item/weapon/pinpointer/nuke/syndicate
|
||||
id = /obj/item/weapon/card/id/syndicate
|
||||
belt = /obj/item/weapon/gun/ballistic/automatic/pistol
|
||||
backpack_contents = list(/obj/item/weapon/storage/box/syndie=1)
|
||||
@@ -362,9 +362,9 @@
|
||||
if(safety)
|
||||
if(timing)
|
||||
set_security_level(previous_level)
|
||||
for(var/obj/item/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(initial(S.mode))
|
||||
S.nuke_warning = FALSE
|
||||
S.alert = FALSE
|
||||
timing = FALSE
|
||||
bomb_set = TRUE
|
||||
detonation_timer = null
|
||||
@@ -381,16 +381,16 @@
|
||||
bomb_set = TRUE
|
||||
set_security_level("delta")
|
||||
detonation_timer = world.time + (timer_set * 10)
|
||||
for(var/obj/item/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(TRACK_INFILTRATOR)
|
||||
countdown.start()
|
||||
else
|
||||
bomb_set = FALSE
|
||||
detonation_timer = null
|
||||
set_security_level(previous_level)
|
||||
for(var/obj/item/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(initial(S.mode))
|
||||
S.nuke_warning = FALSE
|
||||
S.alert = FALSE
|
||||
countdown.stop()
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
diff a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm (rejected hunks)
|
||||
@@ -362,9 +362,9 @@
|
||||
if(safety)
|
||||
if(timing)
|
||||
set_security_level(previous_level)
|
||||
- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
+ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(initial(S.mode))
|
||||
- S.nuke_warning = FALSE
|
||||
+ S.alert = FALSE
|
||||
timing = FALSE
|
||||
bomb_set = TRUE
|
||||
detonation_timer = null
|
||||
@@ -381,16 +381,16 @@
|
||||
bomb_set = TRUE
|
||||
set_security_level("delta")
|
||||
detonation_timer = world.time + (timer_set * 10)
|
||||
- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
+ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(TRACK_INFILTRATOR)
|
||||
countdown.start()
|
||||
else
|
||||
bomb_set = FALSE
|
||||
detonation_timer = null
|
||||
set_security_level(previous_level)
|
||||
- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
+ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(initial(S.mode))
|
||||
- S.nuke_warning = FALSE
|
||||
+ S.alert = FALSE
|
||||
countdown.stop()
|
||||
update_icon()
|
||||
|
||||
@@ -1,56 +1,7 @@
|
||||
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
|
||||
/obj/item/pinpointer
|
||||
name = "pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinoff"
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/active = FALSE
|
||||
var/atom/movable/target = null //The thing we're searching for
|
||||
var/atom/movable/constant_target = null //The thing we're always focused on, if we're in the right mode
|
||||
var/target_x = 0 //The target coordinates if we're tracking those
|
||||
var/target_y = 0
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/nuke_warning = FALSE // If we've set off a miniature alarm about an armed nuke
|
||||
var/mode = TRACK_NUKE_DISK //What are we looking for?
|
||||
/obj/item/pinpointer/nuke
|
||||
var/mode = TRACK_NUKE_DISK
|
||||
|
||||
/obj/item/pinpointer/New()
|
||||
..()
|
||||
GLOB.pinpointer_list += src
|
||||
|
||||
/obj/item/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
icon_state = "pin[active ? "onnull" : "off"]"
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/item/pinpointer/attackby(obj/item/I, mob/living/user, params)
|
||||
if(mode != TRACK_ATOM)
|
||||
return ..()
|
||||
user.visible_message("<span class='notice'>[user] tunes [src] to [I].</span>", "<span class='notice'>You fine-tune [src]'s tracking to track [I].</span>")
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
constant_target = I
|
||||
|
||||
/obj/item/pinpointer/examine(mob/user)
|
||||
/obj/item/pinpointer/nuke/examine(mob/user)
|
||||
..()
|
||||
var/msg = "Its tracking indicator reads "
|
||||
switch(mode)
|
||||
@@ -60,12 +11,6 @@
|
||||
msg += "\"01000001 01001001\"."
|
||||
if(TRACK_INFILTRATOR)
|
||||
msg += "\"vasvygengbefuvc\"."
|
||||
if(TRACK_OPERATIVES)
|
||||
msg += "\"[target ? "Operative [target]" : "friends"]\"."
|
||||
if(TRACK_ATOM)
|
||||
msg += "\"[initial(constant_target.name)]\"."
|
||||
if(TRACK_COORDINATES)
|
||||
msg += "\"([target_x], [target_y])\"."
|
||||
else
|
||||
msg = "Its tracking indicator is blank."
|
||||
to_chat(user, msg)
|
||||
@@ -73,22 +18,20 @@
|
||||
if(bomb.timing)
|
||||
to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.get_time_left()]")
|
||||
|
||||
/obj/item/pinpointer/process()
|
||||
if(!active)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
scan_for_target()
|
||||
point_to_target()
|
||||
my_god_jc_a_bomb()
|
||||
addtimer(CALLBACK(src, .proc/refresh_target), 50, TIMER_UNIQUE)
|
||||
/obj/item/pinpointer/nuke/process()
|
||||
..()
|
||||
if(active) // If shit's going down
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.nuke_list)
|
||||
if(bomb.timing)
|
||||
if(!alert)
|
||||
alert = TRUE
|
||||
playsound(src, 'sound/items/nuke_toy_lowpower.ogg', 50, 0)
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='userdanger'>Your [name] vibrates and lets out a tinny alarm. Uh oh.</span>")
|
||||
|
||||
/obj/item/pinpointer/proc/scan_for_target() //Looks for whatever it's tracking
|
||||
if(target)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat == DEAD)
|
||||
target = null
|
||||
return
|
||||
/obj/item/pinpointer/nuke/scan_for_target()
|
||||
target = null
|
||||
switch(mode)
|
||||
if(TRACK_NUKE_DISK)
|
||||
var/obj/item/disk/nuclear/N = locate() in GLOB.poi_list
|
||||
@@ -104,76 +47,36 @@
|
||||
target = A
|
||||
if(TRACK_INFILTRATOR)
|
||||
target = SSshuttle.getShuttle("syndicate")
|
||||
if(TRACK_OPERATIVES)
|
||||
var/list/possible_targets = list()
|
||||
var/turf/here = get_turf(src)
|
||||
for(var/V in SSticker.mode.syndicates)
|
||||
var/datum/mind/M = V
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
possible_targets |= M.current
|
||||
var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here)
|
||||
if(closest_operative)
|
||||
target = closest_operative
|
||||
if(TRACK_ATOM)
|
||||
if(constant_target)
|
||||
target = constant_target
|
||||
if(TRACK_COORDINATES)
|
||||
var/turf/T = get_turf(src)
|
||||
target = locate(target_x, target_y, T.z)
|
||||
..()
|
||||
|
||||
/obj/item/pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction
|
||||
if(!active)
|
||||
return
|
||||
if(!target || (mode == TRACK_ATOM && !constant_target))
|
||||
icon_state = "pinon[nuke_warning ? "alert" : ""]null"
|
||||
return
|
||||
var/turf/here = get_turf(src)
|
||||
var/turf/there = get_turf(target)
|
||||
if(here.z != there.z)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : ""]null"
|
||||
return
|
||||
if(get_dist_euclidian(here,there)<=minimum_range)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : ""]direct"
|
||||
else
|
||||
setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : "close"]"
|
||||
if(9 to 16)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : "medium"]"
|
||||
if(16 to INFINITY)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : "far"]"
|
||||
|
||||
/obj/item/pinpointer/proc/my_god_jc_a_bomb() //If we should get the hell back to the ship
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.nuke_list)
|
||||
if(bomb.timing)
|
||||
if(!nuke_warning)
|
||||
nuke_warning = TRUE
|
||||
playsound(src, 'sound/items/nuke_toy_lowpower.ogg', 50, 0)
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='userdanger'>Your [name] vibrates and lets out a tinny alarm. Uh oh.</span>")
|
||||
|
||||
/obj/item/pinpointer/proc/switch_mode_to(new_mode) //If we shouldn't be tracking what we are
|
||||
/obj/item/pinpointer/nuke/proc/switch_mode_to(new_mode)
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='userdanger'>Your [name] beeps as it reconfigures its tracking algorithms.</span>")
|
||||
playsound(L, 'sound/machines/triple_beep.ogg', 50, 1)
|
||||
mode = new_mode
|
||||
target = null //Switch modes so we can find the new target
|
||||
scan_for_target()
|
||||
|
||||
/obj/item/pinpointer/proc/refresh_target() //Periodically removes the target to allow the pinpointer to update (i.e. malf AI shunts, an operative dies)
|
||||
target = null
|
||||
|
||||
/obj/item/pinpointer/syndicate //Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
|
||||
/obj/item/pinpointer/nuke/syndicate // Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
|
||||
name = "syndicate pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals. It's configured to switch tracking modes once it detects the activation signal of a nuclear device."
|
||||
icon_state = "pinpointer_syndicate"
|
||||
|
||||
/obj/item/pinpointer/syndicate/cyborg //Cyborg pinpointers just look for a random operative.
|
||||
/obj/item/pinpointer/syndicate_cyborg // Cyborg pinpointers just look for a random operative.
|
||||
name = "cyborg syndicate pinpointer"
|
||||
desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives."
|
||||
mode = TRACK_OPERATIVES
|
||||
flags_1 = NODROP_1
|
||||
|
||||
|
||||
/obj/item/pinpointer/syndicate_cyborg/scan_for_target()
|
||||
target = null
|
||||
var/list/possible_targets = list()
|
||||
var/turf/here = get_turf(src)
|
||||
for(var/V in SSticker.mode.syndicates)
|
||||
var/datum/mind/M = V
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
possible_targets |= M.current
|
||||
var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here)
|
||||
if(closest_operative)
|
||||
target = closest_operative
|
||||
..()
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
diff a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm (rejected hunks)
|
||||
@@ -30,7 +30,6 @@
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='userdanger'>Your [name] vibrates and lets out a tinny alarm. Uh oh.</span>")
|
||||
|
||||
-
|
||||
/obj/item/pinpointer/nuke/scan_for_target()
|
||||
target = null
|
||||
switch(mode)
|
||||
@@ -58,10 +57,10 @@
|
||||
mode = new_mode
|
||||
scan_for_target()
|
||||
|
||||
-
|
||||
/obj/item/pinpointer/nuke/syndicate // Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
|
||||
name = "syndicate pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals. It's configured to switch tracking modes once it detects the activation signal of a nuclear device."
|
||||
+ icon_state = "pinpointer_syndicate"
|
||||
|
||||
/obj/item/pinpointer/syndicate_cyborg // Cyborg pinpointers just look for a random operative.
|
||||
name = "cyborg syndicate pinpointer"
|
||||
@@ -186,7 +186,7 @@
|
||||
return ..()
|
||||
|
||||
//Old ninja objectives.
|
||||
/datum/objective_item/special/pinpointer
|
||||
/datum/objective_item/special/pinpointer/nuke
|
||||
name = "the captain's pinpointer."
|
||||
targetitem = /obj/item/pinpointer
|
||||
difficulty = 10
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm (rejected hunks)
|
||||
@@ -158,7 +158,7 @@
|
||||
difficulty = 10
|
||||
|
||||
//Old ninja objectives.
|
||||
-/datum/objective_item/special/pinpointer
|
||||
+/datum/objective_item/special/pinpointer/nuke
|
||||
name = "the captain's pinpointer."
|
||||
targetitem = /obj/item/pinpointer
|
||||
difficulty = 10
|
||||
@@ -392,6 +392,9 @@
|
||||
QDEL_IN(mob_occupant, 40)
|
||||
|
||||
/obj/machinery/clonepod/relaymove(mob/user)
|
||||
container_resist()
|
||||
|
||||
/obj/machinery/clonepod/container_resist(mob/living/user)
|
||||
if(user.stat == CONSCIOUS)
|
||||
go_out()
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
var/damage_coeff
|
||||
var/scan_level
|
||||
var/precision_coeff
|
||||
var/message_cooldown
|
||||
var/breakout_time = 2
|
||||
|
||||
/obj/machinery/dna_scannernew/RefreshParts()
|
||||
scan_level = 0
|
||||
@@ -65,23 +67,20 @@
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/dna_scannernew/container_resist(mob/living/user)
|
||||
var/breakout_time = 2
|
||||
if(state_open || !locked) //Open and unlocked, no need to escape
|
||||
state_open = TRUE
|
||||
if(!locked)
|
||||
open_machine()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [breakout_time] minutes.)</span>")
|
||||
user.visible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>")
|
||||
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked)
|
||||
return
|
||||
|
||||
locked = FALSE
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/dna_scannernew/proc/locate_computer(type_)
|
||||
@@ -122,10 +121,11 @@
|
||||
|
||||
/obj/machinery/dna_scannernew/relaymove(mob/user as mob)
|
||||
if(user.stat || locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
|
||||
open_machine()
|
||||
return
|
||||
|
||||
/obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params)
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ The console is located at computer/gulag_teleporter.dm
|
||||
active_power_usage = 5000
|
||||
circuit = /obj/item/circuitboard/machine/gulag_teleporter
|
||||
var/locked = FALSE
|
||||
var/message_cooldown
|
||||
var/breakout_time = 1
|
||||
var/jumpsuit_type = /obj/item/clothing/under/rank/prisoner
|
||||
var/shoes_type = /obj/item/clothing/shoes/sneakers/orange
|
||||
var/obj/machinery/gulag_item_reclaimer/linked_reclaimer
|
||||
@@ -46,7 +48,7 @@ The console is located at computer/gulag_teleporter.dm
|
||||
|
||||
/obj/machinery/gulag_teleporter/interact(mob/user)
|
||||
if(locked)
|
||||
to_chat(user, "[src] is locked.")
|
||||
to_chat(user, "<span class='warning'>[src] is locked!</span>")
|
||||
return
|
||||
toggle_open()
|
||||
|
||||
@@ -89,28 +91,27 @@ The console is located at computer/gulag_teleporter.dm
|
||||
if(user.stat != CONSCIOUS)
|
||||
return
|
||||
if(locked)
|
||||
to_chat(user, "[src] is locked!")
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/gulag_teleporter/container_resist(mob/living/user)
|
||||
var/breakout_time = 600
|
||||
if(!locked)
|
||||
open_machine()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about a minute.)</span>")
|
||||
user.visible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>")
|
||||
|
||||
if(do_after(user,(breakout_time), target = src))
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked)
|
||||
return
|
||||
|
||||
locked = FALSE
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/gulag_teleporter/proc/locate_reclaimer()
|
||||
|
||||
@@ -1,379 +1,406 @@
|
||||
// SUIT STORAGE UNIT /////////////////
|
||||
/obj/machinery/suit_storage_unit
|
||||
name = "suit storage unit"
|
||||
desc = "An industrial unit made to hold space suits. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit."
|
||||
icon = 'icons/obj/suitstorage.dmi'
|
||||
icon_state = "close"
|
||||
// SUIT STORAGE UNIT /////////////////
|
||||
/obj/machinery/suit_storage_unit
|
||||
name = "suit storage unit"
|
||||
desc = "An industrial unit made to hold space suits. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit."
|
||||
icon = 'icons/obj/suitstorage.dmi'
|
||||
icon_state = "close"
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
max_integrity = 250
|
||||
|
||||
var/obj/item/clothing/suit/space/suit = null
|
||||
var/obj/item/clothing/head/helmet/space/helmet = null
|
||||
var/obj/item/clothing/mask/mask = null
|
||||
var/obj/item/storage = null
|
||||
|
||||
var/suit_type = null
|
||||
var/helmet_type = null
|
||||
var/mask_type = null
|
||||
var/storage_type = null
|
||||
|
||||
state_open = FALSE
|
||||
var/locked = FALSE
|
||||
panel_open = FALSE
|
||||
var/safeties = TRUE
|
||||
|
||||
var/uv = FALSE
|
||||
var/uv_super = FALSE
|
||||
var/uv_cycles = 6
|
||||
|
||||
/obj/machinery/suit_storage_unit/standard_unit
|
||||
suit_type = /obj/item/clothing/suit/space/eva
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/eva
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/captain
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/captain
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/captain
|
||||
|
||||
/obj/machinery/suit_storage_unit/engine
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/ce
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type= /obj/item/clothing/shoes/magboots/advance
|
||||
|
||||
/obj/machinery/suit_storage_unit/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
|
||||
/obj/machinery/suit_storage_unit/hos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
storage_type = /obj/item/tank/internals/oxygen
|
||||
|
||||
/obj/machinery/suit_storage_unit/atmos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos
|
||||
mask_type = /obj/item/clothing/mask/gas
|
||||
storage_type = /obj/item/watertank/atmos
|
||||
|
||||
/obj/machinery/suit_storage_unit/mining
|
||||
suit_type = /obj/item/clothing/suit/hooded/explorer
|
||||
mask_type = /obj/item/clothing/mask/gas/explorer
|
||||
|
||||
/obj/machinery/suit_storage_unit/mining/eva
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/cmo
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/medical
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/rd
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/rd
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/syndicate
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
mask_type = /obj/item/clothing/mask/gas/syndicate
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/harness
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/command
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/sec
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/engineer
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engi
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/medical
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/med
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
max_integrity = 250
|
||||
|
||||
var/obj/item/clothing/suit/space/suit = null
|
||||
var/obj/item/clothing/head/helmet/space/helmet = null
|
||||
var/obj/item/clothing/mask/mask = null
|
||||
var/obj/item/storage = null
|
||||
|
||||
var/suit_type = null
|
||||
var/helmet_type = null
|
||||
var/mask_type = null
|
||||
var/storage_type = null
|
||||
|
||||
state_open = FALSE
|
||||
var/locked = FALSE
|
||||
panel_open = FALSE
|
||||
var/safeties = TRUE
|
||||
|
||||
var/uv = FALSE
|
||||
var/uv_super = FALSE
|
||||
var/uv_cycles = 6
|
||||
var/message_cooldown
|
||||
var/breakout_time = 0.5
|
||||
|
||||
/obj/machinery/suit_storage_unit/standard_unit
|
||||
suit_type = /obj/item/clothing/suit/space/eva
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/eva
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/captain
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/captain
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/captain
|
||||
|
||||
/obj/machinery/suit_storage_unit/engine
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/ce
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type= /obj/item/clothing/shoes/magboots/advance
|
||||
|
||||
/obj/machinery/suit_storage_unit/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
|
||||
/obj/machinery/suit_storage_unit/hos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
storage_type = /obj/item/tank/internals/oxygen
|
||||
|
||||
/obj/machinery/suit_storage_unit/atmos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos
|
||||
mask_type = /obj/item/clothing/mask/gas
|
||||
storage_type = /obj/item/watertank/atmos
|
||||
|
||||
/obj/machinery/suit_storage_unit/mining
|
||||
suit_type = /obj/item/clothing/suit/hooded/explorer
|
||||
mask_type = /obj/item/clothing/mask/gas/explorer
|
||||
|
||||
/obj/machinery/suit_storage_unit/mining/eva
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/cmo
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/medical
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/rd
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/rd
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/syndicate
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
mask_type = /obj/item/clothing/mask/gas/syndicate
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/harness
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/command
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/sec
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/engineer
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engi
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/medical
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/med
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/Initialize()
|
||||
. = ..()
|
||||
wires = new /datum/wires/suit_storage_unit(src)
|
||||
if(suit_type)
|
||||
suit = new suit_type(src)
|
||||
if(helmet_type)
|
||||
helmet = new helmet_type(src)
|
||||
if(mask_type)
|
||||
mask = new mask_type(src)
|
||||
if(storage_type)
|
||||
storage = new storage_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/suit_storage_unit/Destroy()
|
||||
wires = new /datum/wires/suit_storage_unit(src)
|
||||
if(suit_type)
|
||||
suit = new suit_type(src)
|
||||
if(helmet_type)
|
||||
helmet = new helmet_type(src)
|
||||
if(mask_type)
|
||||
mask = new mask_type(src)
|
||||
if(storage_type)
|
||||
storage = new storage_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/suit_storage_unit/Destroy()
|
||||
QDEL_NULL(suit)
|
||||
QDEL_NULL(helmet)
|
||||
QDEL_NULL(mask)
|
||||
QDEL_NULL(storage)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/suit_storage_unit/update_icon()
|
||||
cut_overlays()
|
||||
|
||||
if(uv)
|
||||
if(uv_super)
|
||||
add_overlay("super")
|
||||
else if(occupant)
|
||||
add_overlay("uvhuman")
|
||||
else
|
||||
add_overlay("uv")
|
||||
else if(state_open)
|
||||
if(stat & BROKEN)
|
||||
add_overlay("broken")
|
||||
else
|
||||
add_overlay("open")
|
||||
if(suit)
|
||||
add_overlay("suit")
|
||||
if(helmet)
|
||||
add_overlay("helm")
|
||||
if(storage)
|
||||
add_overlay("storage")
|
||||
else if(occupant)
|
||||
add_overlay("human")
|
||||
|
||||
/obj/machinery/suit_storage_unit/power_change()
|
||||
..()
|
||||
if(!is_operational() && state_open)
|
||||
open_machine()
|
||||
dump_contents()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/dump_contents()
|
||||
dropContents()
|
||||
helmet = null
|
||||
suit = null
|
||||
mask = null
|
||||
storage = null
|
||||
occupant = null
|
||||
|
||||
/obj/machinery/suit_storage_unit/deconstruct(disassembled = TRUE)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/suit_storage_unit/update_icon()
|
||||
cut_overlays()
|
||||
|
||||
if(uv)
|
||||
if(uv_super)
|
||||
add_overlay("super")
|
||||
else if(occupant)
|
||||
add_overlay("uvhuman")
|
||||
else
|
||||
add_overlay("uv")
|
||||
else if(state_open)
|
||||
if(stat & BROKEN)
|
||||
add_overlay("broken")
|
||||
else
|
||||
add_overlay("open")
|
||||
if(suit)
|
||||
add_overlay("suit")
|
||||
if(helmet)
|
||||
add_overlay("helm")
|
||||
if(storage)
|
||||
add_overlay("storage")
|
||||
else if(occupant)
|
||||
add_overlay("human")
|
||||
|
||||
/obj/machinery/suit_storage_unit/power_change()
|
||||
..()
|
||||
if(!is_operational() && state_open)
|
||||
open_machine()
|
||||
dump_contents()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/dump_contents()
|
||||
dropContents()
|
||||
helmet = null
|
||||
suit = null
|
||||
mask = null
|
||||
storage = null
|
||||
occupant = null
|
||||
|
||||
/obj/machinery/suit_storage_unit/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
open_machine()
|
||||
dump_contents()
|
||||
new /obj/item/stack/sheet/metal (loc, 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A))
|
||||
return
|
||||
var/mob/living/target = A
|
||||
if(!state_open)
|
||||
to_chat(user, "<span class='warning'>The unit's doors are shut!</span>")
|
||||
return
|
||||
if(!is_operational())
|
||||
to_chat(user, "<span class='warning'>The unit is not operational!</span>")
|
||||
return
|
||||
if(occupant || helmet || suit || storage)
|
||||
to_chat(user, "<span class='warning'>It's too cluttered inside to fit in!</span>")
|
||||
return
|
||||
|
||||
if(target == user)
|
||||
user.visible_message("<span class='warning'>[user] starts squeezing into [src]!</span>", "<span class='notice'>You start working your way into [src]...</span>")
|
||||
else
|
||||
target.visible_message("<span class='warning'>[user] starts shoving [target] into [src]!</span>", "<span class='userdanger'>[user] starts shoving you into [src]!</span>")
|
||||
|
||||
if(do_mob(user, target, 30))
|
||||
if(occupant || helmet || suit || storage)
|
||||
return
|
||||
if(target == user)
|
||||
user.visible_message("<span class='warning'>[user] slips into [src] and closes the door behind them!</span>", "<span class=notice'>You slip into [src]'s cramped space and shut its door.</span>")
|
||||
else
|
||||
target.visible_message("<span class='warning'>[user] pushes [target] into [src] and shuts its door!<span>", "<span class='userdanger'>[user] shoves you into [src] and shuts the door!</span>")
|
||||
close_machine(target)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/cook()
|
||||
if(uv_cycles)
|
||||
uv_cycles--
|
||||
uv = TRUE
|
||||
locked = TRUE
|
||||
update_icon()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(uv_super)
|
||||
mob_occupant.adjustFireLoss(rand(20, 36))
|
||||
else
|
||||
mob_occupant.adjustFireLoss(rand(10, 16))
|
||||
mob_occupant.emote("scream")
|
||||
addtimer(CALLBACK(src, .proc/cook), 50)
|
||||
else
|
||||
uv_cycles = initial(uv_cycles)
|
||||
uv = FALSE
|
||||
locked = FALSE
|
||||
if(uv_super)
|
||||
visible_message("<span class='warning'>[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.</span>")
|
||||
playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1)
|
||||
helmet = null
|
||||
qdel(helmet)
|
||||
suit = null
|
||||
qdel(suit) // Delete everything but the occupant.
|
||||
mask = null
|
||||
qdel(mask)
|
||||
storage = null
|
||||
qdel(storage)
|
||||
// The wires get damaged too.
|
||||
wires.cut_all()
|
||||
else
|
||||
if(!occupant)
|
||||
visible_message("<span class='notice'>[src]'s door slides open. The glowing yellow lights dim to a gentle green.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src]'s door slides open, barraging you with the nauseating smell of charred flesh.</span>")
|
||||
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
|
||||
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
|
||||
I.clean_blood()
|
||||
I.fingerprints = list()
|
||||
open_machine(FALSE)
|
||||
if(occupant)
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb)
|
||||
if(!prob(prb))
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
if(electrocute_mob(user, src, src, 1, TRUE))
|
||||
return 1
|
||||
|
||||
/obj/machinery/suit_storage_unit/relaymove(mob/user)
|
||||
container_resist(user)
|
||||
|
||||
/obj/machinery/suit_storage_unit/container_resist(mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if(locked)
|
||||
visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", "<span class='notice'>You start kicking against the doors...</span>")
|
||||
addtimer(CALLBACK(src, .proc/resist_open, user), 300)
|
||||
else
|
||||
open_machine()
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/resist_open(mob/user)
|
||||
if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here.
|
||||
visible_message("<span class='notice'>You see [user] bursts out of [src]!</span>", "<span class='notice'>You escape the cramped confines of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params)
|
||||
if(state_open && is_operational())
|
||||
if(istype(I, /obj/item/clothing/suit/space))
|
||||
if(suit)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a suit!.</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
suit = I
|
||||
else if(istype(I, /obj/item/clothing/head/helmet))
|
||||
if(helmet)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a helmet!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
helmet = I
|
||||
else if(istype(I, /obj/item/clothing/mask))
|
||||
if(mask)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a mask!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
mask = I
|
||||
else
|
||||
if(storage)
|
||||
to_chat(user, "<span class='warning'>The auxiliary storage compartment is full!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
storage = I
|
||||
|
||||
I.loc = src
|
||||
visible_message("<span class='notice'>[user] inserts [I] into [src]</span>", "<span class='notice'>You load [I] into [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(panel_open && is_wire_tool(I))
|
||||
wires.interact(user)
|
||||
if(!state_open)
|
||||
if(default_deconstruction_screwdriver(user, "panel", "close", I))
|
||||
return
|
||||
if(default_pry_open(I))
|
||||
dump_contents()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
open_machine()
|
||||
dump_contents()
|
||||
new /obj/item/stack/sheet/metal (loc, 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A))
|
||||
return
|
||||
var/mob/living/target = A
|
||||
if(!state_open)
|
||||
to_chat(user, "<span class='warning'>The unit's doors are shut!</span>")
|
||||
return
|
||||
if(!is_operational())
|
||||
to_chat(user, "<span class='warning'>The unit is not operational!</span>")
|
||||
return
|
||||
if(occupant || helmet || suit || storage)
|
||||
to_chat(user, "<span class='warning'>It's too cluttered inside to fit in!</span>")
|
||||
return
|
||||
|
||||
if(target == user)
|
||||
user.visible_message("<span class='warning'>[user] starts squeezing into [src]!</span>", "<span class='notice'>You start working your way into [src]...</span>")
|
||||
else
|
||||
target.visible_message("<span class='warning'>[user] starts shoving [target] into [src]!</span>", "<span class='userdanger'>[user] starts shoving you into [src]!</span>")
|
||||
|
||||
if(do_mob(user, target, 30))
|
||||
if(occupant || helmet || suit || storage)
|
||||
return
|
||||
if(target == user)
|
||||
user.visible_message("<span class='warning'>[user] slips into [src] and closes the door behind them!</span>", "<span class=notice'>You slip into [src]'s cramped space and shut its door.</span>")
|
||||
else
|
||||
target.visible_message("<span class='warning'>[user] pushes [target] into [src] and shuts its door!<span>", "<span class='userdanger'>[user] shoves you into [src] and shuts the door!</span>")
|
||||
close_machine(target)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/cook()
|
||||
if(uv_cycles)
|
||||
uv_cycles--
|
||||
uv = TRUE
|
||||
locked = TRUE
|
||||
update_icon()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(uv_super)
|
||||
mob_occupant.adjustFireLoss(rand(20, 36))
|
||||
else
|
||||
mob_occupant.adjustFireLoss(rand(10, 16))
|
||||
mob_occupant.emote("scream")
|
||||
addtimer(CALLBACK(src, .proc/cook), 50)
|
||||
else
|
||||
uv_cycles = initial(uv_cycles)
|
||||
uv = FALSE
|
||||
locked = FALSE
|
||||
if(uv_super)
|
||||
visible_message("<span class='warning'>[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.</span>")
|
||||
playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1)
|
||||
helmet = null
|
||||
qdel(helmet)
|
||||
suit = null
|
||||
qdel(suit) // Delete everything but the occupant.
|
||||
mask = null
|
||||
qdel(mask)
|
||||
storage = null
|
||||
qdel(storage)
|
||||
// The wires get damaged too.
|
||||
wires.cut_all()
|
||||
else
|
||||
if(!occupant)
|
||||
visible_message("<span class='notice'>[src]'s door slides open. The glowing yellow lights dim to a gentle green.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src]'s door slides open, barraging you with the nauseating smell of charred flesh.</span>")
|
||||
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
|
||||
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
|
||||
I.clean_blood()
|
||||
I.fingerprints = list()
|
||||
open_machine(FALSE)
|
||||
if(occupant)
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb)
|
||||
if(!prob(prb))
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
if(electrocute_mob(user, src, src, 1, TRUE))
|
||||
return 1
|
||||
|
||||
/obj/machinery/suit_storage_unit/relaymove(mob/user)
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
open_machine()
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/container_resist(mob/living/user)
|
||||
if(!locked)
|
||||
open_machine()
|
||||
dump_contents()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", \
|
||||
"<span class='notice'>You start kicking against the doors... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a thump from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
dump_contents()
|
||||
|
||||
add_fingerprint(user)
|
||||
if(locked)
|
||||
visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", \
|
||||
"<span class='notice'>You start kicking against the doors...</span>")
|
||||
addtimer(CALLBACK(src, .proc/resist_open, user), 300)
|
||||
else
|
||||
open_machine()
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/resist_open(mob/user)
|
||||
if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here.
|
||||
visible_message("<span class='notice'>You see [user] bursts out of [src]!</span>", \
|
||||
"<span class='notice'>You escape the cramped confines of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params)
|
||||
if(state_open && is_operational())
|
||||
if(istype(I, /obj/item/clothing/suit/space))
|
||||
if(suit)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a suit!.</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
suit = I
|
||||
else if(istype(I, /obj/item/clothing/head/helmet))
|
||||
if(helmet)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a helmet!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
helmet = I
|
||||
else if(istype(I, /obj/item/clothing/mask))
|
||||
if(mask)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a mask!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
mask = I
|
||||
else
|
||||
if(storage)
|
||||
to_chat(user, "<span class='warning'>The auxiliary storage compartment is full!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
storage = I
|
||||
|
||||
I.loc = src
|
||||
visible_message("<span class='notice'>[user] inserts [I] into [src]</span>", "<span class='notice'>You load [I] into [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(panel_open && is_wire_tool(I))
|
||||
wires.interact(user)
|
||||
if(!state_open)
|
||||
if(default_deconstruction_screwdriver(user, "panel", "close", I))
|
||||
return
|
||||
if(default_pry_open(I))
|
||||
dump_contents()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "suit_storage_unit", name, 400, 305, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_data()
|
||||
var/list/data = list()
|
||||
data["locked"] = locked
|
||||
data["open"] = state_open
|
||||
data["safeties"] = safeties
|
||||
data["uv_active"] = uv
|
||||
data["uv_super"] = uv_super
|
||||
if(helmet)
|
||||
data["helmet"] = helmet.name
|
||||
if(suit)
|
||||
data["suit"] = suit.name
|
||||
if(mask)
|
||||
data["mask"] = mask.name
|
||||
if(storage)
|
||||
data["storage"] = storage.name
|
||||
if(occupant)
|
||||
data["occupied"] = 1
|
||||
return data
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_act(action, params)
|
||||
if(..() || uv)
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine(0)
|
||||
if(occupant)
|
||||
dump_contents() // Dump out contents if someone is in there.
|
||||
. = TRUE
|
||||
if("lock")
|
||||
locked = !locked
|
||||
. = TRUE
|
||||
if("uv")
|
||||
if(occupant && safeties)
|
||||
return
|
||||
else if(!helmet && !mask && !suit && !storage && !occupant)
|
||||
return
|
||||
else
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
to_chat(mob_occupant, "<span class='userdanger'>[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!</span>")
|
||||
cook()
|
||||
. = TRUE
|
||||
if("dispense")
|
||||
if(!state_open)
|
||||
return
|
||||
|
||||
var/static/list/valid_items = list("helmet", "suit", "mask", "storage")
|
||||
var/item_name = params["item"]
|
||||
if(item_name in valid_items)
|
||||
var/obj/item/I = vars[item_name]
|
||||
vars[item_name] = null
|
||||
if(I)
|
||||
I.forceMove(loc)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "suit_storage_unit", name, 400, 305, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_data()
|
||||
var/list/data = list()
|
||||
data["locked"] = locked
|
||||
data["open"] = state_open
|
||||
data["safeties"] = safeties
|
||||
data["uv_active"] = uv
|
||||
data["uv_super"] = uv_super
|
||||
if(helmet)
|
||||
data["helmet"] = helmet.name
|
||||
if(suit)
|
||||
data["suit"] = suit.name
|
||||
if(mask)
|
||||
data["mask"] = mask.name
|
||||
if(storage)
|
||||
data["storage"] = storage.name
|
||||
if(occupant)
|
||||
data["occupied"] = 1
|
||||
return data
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_act(action, params)
|
||||
if(..() || uv)
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine(0)
|
||||
if(occupant)
|
||||
dump_contents() // Dump out contents if someone is in there.
|
||||
. = TRUE
|
||||
if("lock")
|
||||
locked = !locked
|
||||
. = TRUE
|
||||
if("uv")
|
||||
if(occupant && safeties)
|
||||
return
|
||||
else if(!helmet && !mask && !suit && !storage && !occupant)
|
||||
return
|
||||
else
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
to_chat(mob_occupant, "<span class='userdanger'>[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!</span>")
|
||||
cook()
|
||||
. = TRUE
|
||||
if("dispense")
|
||||
if(!state_open)
|
||||
return
|
||||
|
||||
var/static/list/valid_items = list("helmet", "suit", "mask", "storage")
|
||||
var/item_name = params["item"]
|
||||
if(item_name in valid_items)
|
||||
var/obj/item/I = vars[item_name]
|
||||
vars[item_name] = null
|
||||
if(I)
|
||||
I.forceMove(loc)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
@@ -869,7 +869,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/stack/medical/gauze = 8, /obj/item/reagent_containers/pill/patch/styptic = 5, /obj/item/reagent_containers/pill/insulin = 10,
|
||||
/obj/item/reagent_containers/pill/patch/silver_sulf = 5, /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/spray/medical/sterilizer = 1,
|
||||
/obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/salglu_solution = 3,
|
||||
/obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/device/healthanalyzer = 4, /obj/item/device/sensor_device = 2)
|
||||
/obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/device/healthanalyzer = 4, /obj/item/device/sensor_device = 2, /obj/item/pinpointer/crew = 2)
|
||||
contraband = list(/obj/item/reagent_containers/pill/tox = 3, /obj/item/reagent_containers/pill/morphine = 4, /obj/item/reagent_containers/pill/charcoal = 6)
|
||||
premium = list(/obj/item/storage/box/hug/medical = 1, /obj/item/reagent_containers/hypospray/medipen = 3, /obj/item/storage/belt/medical = 3, /obj/item/wrench/medical = 1)
|
||||
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
|
||||
|
||||
@@ -58,7 +58,9 @@
|
||||
/turf/open/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
for(var/turf/open/floor/plating/asteroid/M in range(1, drill.chassis))
|
||||
if(get_dir(drill.chassis,M)&drill.chassis.dir)
|
||||
M.gets_dug()
|
||||
for(var/I in GetComponents(/datum/component/archaeology))
|
||||
var/datum/component/archaeology/archy = I
|
||||
archy.gets_dug()
|
||||
drill.log_message("Drilled through [src]")
|
||||
drill.move_ores()
|
||||
|
||||
|
||||
@@ -549,9 +549,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
transfer_blood = 0
|
||||
|
||||
/obj/item/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FOUR)
|
||||
throw_at(S,14,3, spin=0)
|
||||
else ..()
|
||||
else return
|
||||
|
||||
/obj/item/throw_impact(atom/A)
|
||||
if(A && !QDELETED(A))
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
return
|
||||
if(!isnull(target) && !target.toff)
|
||||
charges--
|
||||
var/lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
|
||||
var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
to_chat(U, "<span class='notice'>Virus Sent! The unlock code to the target is: [lock_code]</span>")
|
||||
if(!target.hidden_uplink)
|
||||
var/obj/item/device/uplink/uplink = new(target)
|
||||
|
||||
@@ -428,7 +428,7 @@
|
||||
|
||||
/obj/item/device/flashlight/glowstick/update_icon()
|
||||
item_state = "glowstick"
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(!fuel)
|
||||
icon_state = "glowstick-empty"
|
||||
cut_overlays()
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
|
||||
/obj/item/weapon/pinpointer
|
||||
name = "pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinpointer"
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/active = FALSE
|
||||
var/atom/movable/target = null //The thing we're searching for
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/alert = FALSE // TRUE to display things more seriously
|
||||
|
||||
/obj/item/weapon/pinpointer/New()
|
||||
..()
|
||||
GLOB.pinpointer_list += src
|
||||
|
||||
/obj/item/weapon/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/process()
|
||||
if(!active)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
scan_for_target()
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/proc/scan_for_target()
|
||||
return
|
||||
|
||||
/obj/item/weapon/pinpointer/proc/update_pointer_overlay()
|
||||
cut_overlays()
|
||||
if(!active)
|
||||
return
|
||||
if(!target)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
var/turf/here = get_turf(src)
|
||||
var/turf/there = get_turf(target)
|
||||
if(here.z != there.z)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
return
|
||||
if(get_dist_euclidian(here,there) <= minimum_range)
|
||||
add_overlay("pinon[alert ? "alert" : ""]direct")
|
||||
else
|
||||
setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
add_overlay("pinon[alert ? "alert" : "close"]")
|
||||
if(9 to 16)
|
||||
add_overlay("pinon[alert ? "alert" : "medium"]")
|
||||
if(16 to INFINITY)
|
||||
add_overlay("pinon[alert ? "alert" : "far"]")
|
||||
|
||||
/obj/item/weapon/pinpointer/crew // A replacement for the old crew monitoring consoles
|
||||
name = "crew pinpointer"
|
||||
desc = "A handheld tracking device that points to crew suit sensors."
|
||||
icon_state = "pinpointer_crew"
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
|
||||
var/turf/here = get_turf(src)
|
||||
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
|
||||
// Suit sensors must be on maximum.
|
||||
if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
|
||||
return FALSE
|
||||
|
||||
var/turf/there = get_turf(H)
|
||||
return (H.z != 0 || (there && there.z == H.z))
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/attack_self(mob/living/user)
|
||||
if(active)
|
||||
active = FALSE
|
||||
user.visible_message("<span class='notice'>[user] deactivates their pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
return
|
||||
|
||||
var/list/name_counts = list()
|
||||
var/list/names = list()
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
if(!trackable(H))
|
||||
continue
|
||||
|
||||
var/name = "Unknown"
|
||||
if(H.wear_id)
|
||||
var/obj/item/weapon/card/id/I = H.wear_id.GetID()
|
||||
name = I.registered_name
|
||||
|
||||
while(name in name_counts)
|
||||
name_counts[name]++
|
||||
name = text("[] ([])", name, name_counts[name])
|
||||
names[name] = H
|
||||
name_counts[name] = 1
|
||||
|
||||
if(!names.len)
|
||||
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
|
||||
return
|
||||
|
||||
var/A = input(user, "Person to track", "Pinpoint") in names
|
||||
if(!src || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !A)
|
||||
return
|
||||
|
||||
target = names[A]
|
||||
active = TRUE
|
||||
user.visible_message("<span class='notice'>[user] activates their pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/scan_for_target()
|
||||
if(target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!trackable(H))
|
||||
target = null
|
||||
if(!target)
|
||||
active = FALSE
|
||||
|
||||
/obj/item/weapon/pinpointer/process()
|
||||
if(!active)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
scan_for_target()
|
||||
update_pointer_overlay()
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
icon_state = null
|
||||
active = TRUE
|
||||
if(tile_overlay)
|
||||
loc.overlays += tile_overlay
|
||||
loc.add_overlay(tile_overlay)
|
||||
else
|
||||
if(crossed)
|
||||
trigger() //no cheesing.
|
||||
|
||||
@@ -1,187 +1,188 @@
|
||||
/obj/machinery/implantchair
|
||||
name = "mindshield implanter"
|
||||
desc = "Used to implant occupants with mindshield implants."
|
||||
icon = 'icons/obj/machines/implantchair.dmi'
|
||||
icon_state = "implantchair"
|
||||
density = TRUE
|
||||
opacity = 0
|
||||
anchored = TRUE
|
||||
|
||||
var/ready = TRUE
|
||||
var/replenishing = FALSE
|
||||
|
||||
var/ready_implants = 5
|
||||
var/max_implants = 5
|
||||
var/injection_cooldown = 600
|
||||
var/replenish_cooldown = 6000
|
||||
var/implant_type = /obj/item/implant/mindshield
|
||||
var/auto_inject = FALSE
|
||||
var/auto_replenish = TRUE
|
||||
var/special = FALSE
|
||||
var/special_name = "special function"
|
||||
|
||||
/obj/machinery/implantchair/Initialize()
|
||||
. = ..()
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
data["open"] = state_open
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["special_name"] = special ? special_name : null
|
||||
data["ready_implants"] = ready_implants
|
||||
data["ready"] = ready
|
||||
data["replenishing"] = replenishing
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/implantchair/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("implant")
|
||||
implant(occupant,usr)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user)
|
||||
if (!istype(M))
|
||||
return
|
||||
if(!ready_implants || !ready)
|
||||
return
|
||||
if(implant_action(M,user))
|
||||
ready_implants--
|
||||
if(!replenishing && auto_replenish)
|
||||
replenishing = TRUE
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
if(injection_cooldown > 0)
|
||||
ready = FALSE
|
||||
addtimer(CALLBACK(src,"set_ready"),injection_cooldown)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/proc/implant_action(mob/living/M)
|
||||
var/obj/item/implant/I = new implant_type
|
||||
if(I.implant(M))
|
||||
visible_message("<span class='warning'>[M] has been implanted by the [name].</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair/update_icon()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "_open"
|
||||
if(occupant)
|
||||
icon_state += "_occupied"
|
||||
if(ready)
|
||||
add_overlay("ready")
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
/obj/machinery/implantchair/proc/replenish()
|
||||
if(ready_implants < max_implants)
|
||||
ready_implants++
|
||||
if(ready_implants < max_implants)
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
else
|
||||
replenishing = FALSE
|
||||
|
||||
/obj/machinery/implantchair/proc/set_ready()
|
||||
ready = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/container_resist(mob/living/user)
|
||||
if(state_open)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about about a minute.)</span>")
|
||||
audible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>",hearing_distance = 2)
|
||||
|
||||
if(do_after(user, 600, target = src))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/implantchair/relaymove(mob/user)
|
||||
container_resist(user)
|
||||
|
||||
/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/implantchair/close_machine(mob/living/user)
|
||||
if((isnull(user) || istype(user)) && state_open)
|
||||
..(user)
|
||||
if(auto_inject && ready && ready_implants > 0)
|
||||
implant(user,null)
|
||||
|
||||
/obj/machinery/implantchair/genepurge
|
||||
name = "Genetic purifier"
|
||||
desc = "Used to purge human genome of foreign influences"
|
||||
special = TRUE
|
||||
special_name = "Purge genome"
|
||||
injection_cooldown = 0
|
||||
replenish_cooldown = 300
|
||||
|
||||
/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user)
|
||||
if(!istype(H))
|
||||
return 0
|
||||
H.set_species(/datum/species/human, 1)//lizards go home
|
||||
purrbation_remove(H)//remove cats
|
||||
H.dna.remove_all_mutations()//hulks out
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/implantchair/brainwash
|
||||
name = "Neural Imprinter"
|
||||
desc = "Used to <s>indoctrinate</s> rehabilitate hardened recidivists."
|
||||
special_name = "Imprint"
|
||||
injection_cooldown = 3000
|
||||
auto_inject = FALSE
|
||||
auto_replenish = FALSE
|
||||
special = TRUE
|
||||
var/objective = "Obey the law. Praise Nanotrasen."
|
||||
var/custom = FALSE
|
||||
|
||||
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
|
||||
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
|
||||
return 0
|
||||
if(custom)
|
||||
if(!user || !user.Adjacent(src))
|
||||
return 0
|
||||
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
|
||||
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
var/datum/objective/custom_objective = new/datum/objective(objective)
|
||||
custom_objective.owner = C.mind
|
||||
C.mind.objectives += custom_objective
|
||||
C.mind.announce_objectives()
|
||||
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair
|
||||
name = "mindshield implanter"
|
||||
desc = "Used to implant occupants with mindshield implants."
|
||||
icon = 'icons/obj/machines/implantchair.dmi'
|
||||
icon_state = "implantchair"
|
||||
density = TRUE
|
||||
opacity = 0
|
||||
anchored = TRUE
|
||||
|
||||
var/ready = TRUE
|
||||
var/replenishing = FALSE
|
||||
|
||||
var/ready_implants = 5
|
||||
var/max_implants = 5
|
||||
var/injection_cooldown = 600
|
||||
var/replenish_cooldown = 6000
|
||||
var/implant_type = /obj/item/implant/mindshield
|
||||
var/auto_inject = FALSE
|
||||
var/auto_replenish = TRUE
|
||||
var/special = FALSE
|
||||
var/special_name = "special function"
|
||||
var/message_cooldown
|
||||
var/breakout_time = 1
|
||||
|
||||
/obj/machinery/implantchair/Initialize()
|
||||
. = ..()
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
data["open"] = state_open
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["special_name"] = special ? special_name : null
|
||||
data["ready_implants"] = ready_implants
|
||||
data["ready"] = ready
|
||||
data["replenishing"] = replenishing
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/implantchair/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("implant")
|
||||
implant(occupant,usr)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user)
|
||||
if (!istype(M))
|
||||
return
|
||||
if(!ready_implants || !ready)
|
||||
return
|
||||
if(implant_action(M,user))
|
||||
ready_implants--
|
||||
if(!replenishing && auto_replenish)
|
||||
replenishing = TRUE
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
if(injection_cooldown > 0)
|
||||
ready = FALSE
|
||||
addtimer(CALLBACK(src,"set_ready"),injection_cooldown)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/proc/implant_action(mob/living/M)
|
||||
var/obj/item/implant/I = new implant_type
|
||||
if(I.implant(M))
|
||||
visible_message("<span class='warning'>[M] has been implanted by the [name].</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair/update_icon()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "_open"
|
||||
if(occupant)
|
||||
icon_state += "_occupied"
|
||||
if(ready)
|
||||
add_overlay("ready")
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
/obj/machinery/implantchair/proc/replenish()
|
||||
if(ready_implants < max_implants)
|
||||
ready_implants++
|
||||
if(ready_implants < max_implants)
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
else
|
||||
replenishing = FALSE
|
||||
|
||||
/obj/machinery/implantchair/proc/set_ready()
|
||||
ready = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/container_resist(mob/living/user)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/implantchair/relaymove(mob/user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/implantchair/close_machine(mob/living/user)
|
||||
if((isnull(user) || istype(user)) && state_open)
|
||||
..(user)
|
||||
if(auto_inject && ready && ready_implants > 0)
|
||||
implant(user,null)
|
||||
|
||||
/obj/machinery/implantchair/genepurge
|
||||
name = "Genetic purifier"
|
||||
desc = "Used to purge human genome of foreign influences"
|
||||
special = TRUE
|
||||
special_name = "Purge genome"
|
||||
injection_cooldown = 0
|
||||
replenish_cooldown = 300
|
||||
|
||||
/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user)
|
||||
if(!istype(H))
|
||||
return 0
|
||||
H.set_species(/datum/species/human, 1)//lizards go home
|
||||
purrbation_remove(H)//remove cats
|
||||
H.dna.remove_all_mutations()//hulks out
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/implantchair/brainwash
|
||||
name = "Neural Imprinter"
|
||||
desc = "Used to <s>indoctrinate</s> rehabilitate hardened recidivists."
|
||||
special_name = "Imprint"
|
||||
injection_cooldown = 3000
|
||||
auto_inject = FALSE
|
||||
auto_replenish = FALSE
|
||||
special = TRUE
|
||||
var/objective = "Obey the law. Praise Nanotrasen."
|
||||
var/custom = FALSE
|
||||
|
||||
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
|
||||
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
|
||||
return 0
|
||||
if(custom)
|
||||
if(!user || !user.Adjacent(src))
|
||||
return 0
|
||||
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
|
||||
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
var/datum/objective/custom_objective = new/datum/objective(objective)
|
||||
custom_objective.owner = C.mind
|
||||
C.mind.objectives += custom_objective
|
||||
C.mind.announce_objectives()
|
||||
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
return 1
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
|
||||
/obj/item/pinpointer
|
||||
name = "pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinpointer"
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/active = FALSE
|
||||
var/atom/movable/target //The thing we're searching for
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/alert = FALSE // TRUE to display things more seriously
|
||||
|
||||
/obj/item/pinpointer/Initialize()
|
||||
. = ..()
|
||||
GLOB.pinpointer_list += src
|
||||
|
||||
/obj/item/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/process()
|
||||
if(!active)
|
||||
return PROCESS_KILL
|
||||
scan_for_target()
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/proc/scan_for_target()
|
||||
return
|
||||
|
||||
/obj/item/pinpointer/update_icon()
|
||||
cut_overlays()
|
||||
if(!active)
|
||||
return
|
||||
if(!target)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
var/turf/here = get_turf(src)
|
||||
var/turf/there = get_turf(target)
|
||||
if(here.z != there.z)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
return
|
||||
if(get_dist_euclidian(here,there) <= minimum_range)
|
||||
add_overlay("pinon[alert ? "alert" : ""]direct")
|
||||
else
|
||||
setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
add_overlay("pinon[alert ? "alert" : "close"]")
|
||||
if(9 to 16)
|
||||
add_overlay("pinon[alert ? "alert" : "medium"]")
|
||||
if(16 to INFINITY)
|
||||
add_overlay("pinon[alert ? "alert" : "far"]")
|
||||
|
||||
/obj/item/pinpointer/crew // A replacement for the old crew monitoring consoles
|
||||
name = "crew pinpointer"
|
||||
desc = "A handheld tracking device that points to crew suit sensors."
|
||||
icon_state = "pinpointer_crew"
|
||||
|
||||
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
|
||||
var/turf/here = get_turf(src)
|
||||
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
|
||||
// Suit sensors must be on maximum.
|
||||
if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
|
||||
return FALSE
|
||||
|
||||
var/turf/there = get_turf(H)
|
||||
return (H.z != 0 || (there && there.z == H.z))
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/pinpointer/crew/attack_self(mob/living/user)
|
||||
if(active)
|
||||
active = FALSE
|
||||
user.visible_message("<span class='notice'>[user] deactivates their pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
var/list/name_counts = list()
|
||||
var/list/names = list()
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
if(!trackable(H))
|
||||
continue
|
||||
|
||||
var/crewmember_name = "Unknown"
|
||||
if(H.wear_id)
|
||||
var/obj/item/card/id/I = H.wear_id.GetID()
|
||||
crewmember_name = I.registered_name
|
||||
|
||||
while(crewmember_name in name_counts)
|
||||
name_counts[crewmember_name]++
|
||||
crewmember_name = text("[] ([])", crewmember_name, name_counts[crewmember_name])
|
||||
names[crewmember_name] = H
|
||||
name_counts[crewmember_name] = 1
|
||||
|
||||
if(!names.len)
|
||||
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
|
||||
return
|
||||
|
||||
var/A = input(user, "Person to track", "Pinpoint") in names
|
||||
if(!A || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated())
|
||||
return
|
||||
|
||||
target = names[A]
|
||||
active = TRUE
|
||||
user.visible_message("<span class='notice'>[user] activates their pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/crew/scan_for_target()
|
||||
if(target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!trackable(H))
|
||||
target = null
|
||||
if(!target) //target can be set to null from above code, or elsewhere
|
||||
active = FALSE
|
||||
|
||||
/obj/item/pinpointer/process()
|
||||
if(!active)
|
||||
return PROCESS_KILL
|
||||
scan_for_target()
|
||||
update_icon()
|
||||
|
||||
@@ -1,27 +1,201 @@
|
||||
/obj/item/banner
|
||||
name = "banner"
|
||||
desc = "A banner with Nanotrasen's logo on it."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "banner"
|
||||
item_state = "banner"
|
||||
force = 8
|
||||
attack_verb = list("forcefully inspired", "violently encouraged", "relentlessly galvanized")
|
||||
lefthand_file = 'icons/mob/inhands/equipment/banners_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/banners_righthand.dmi'
|
||||
desc = "A banner with Nanotrasen's logo on it."
|
||||
var/moralecooldown = 0
|
||||
var/moralewait = 600
|
||||
var/inspiration_available = TRUE //If this banner can be used to inspire crew
|
||||
var/morale_time = 0
|
||||
var/morale_cooldown = 600 //How many deciseconds between uses
|
||||
var/list/job_loyalties //Mobs with any of these assigned roles will be inspired
|
||||
var/list/role_loyalties //Mobs with any of these special roles will be inspired
|
||||
var/warcry
|
||||
|
||||
/obj/item/banner/examine(mob/user)
|
||||
..()
|
||||
if(inspiration_available)
|
||||
to_chat(user, "<span class='notice'>Activate it in your hand to inspire nearby allies of this banner's allegiance!</span>")
|
||||
|
||||
/obj/item/banner/attack_self(mob/living/carbon/human/user)
|
||||
if(moralecooldown + moralewait > world.time)
|
||||
if(!inspiration_available)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You increase the morale of your fellows!</span>")
|
||||
moralecooldown = world.time
|
||||
if(morale_time > world.time)
|
||||
to_chat(user, "<span class='warning'>You aren't feeling inspired enough to flourish [src] again yet.</span>")
|
||||
return
|
||||
user.visible_message("<span class='big notice'>[user] flourishes [src]!</span>", \
|
||||
"<span class='notice'>You raise [src] skywards, inspiring your allies!</span>")
|
||||
playsound(src, "rustle", 100, FALSE)
|
||||
if(warcry)
|
||||
user.say("[warcry]")
|
||||
var/old_transform = user.transform
|
||||
user.transform *= 1.2
|
||||
animate(user, transform = old_transform, time = 10)
|
||||
morale_time = world.time + morale_cooldown
|
||||
|
||||
for(var/mob/living/carbon/human/H in range(4,get_turf(src)))
|
||||
to_chat(H, "<span class='notice'>Your morale is increased by [user]'s banner!</span>")
|
||||
H.adjustBruteLoss(-15)
|
||||
H.adjustFireLoss(-15)
|
||||
H.AdjustStun(-40)
|
||||
H.AdjustKnockdown(-40)
|
||||
H.AdjustUnconscious(-40)
|
||||
var/list/inspired = list()
|
||||
var/has_job_loyalties = LAZYLEN(job_loyalties)
|
||||
var/has_role_loyalties = LAZYLEN(role_loyalties)
|
||||
inspired += user //The user is always inspired, regardless of loyalties
|
||||
for(var/mob/living/carbon/human/H in range(4, get_turf(src)))
|
||||
if(H.stat == DEAD || H == user)
|
||||
continue
|
||||
if(H.mind && (has_job_loyalties || has_role_loyalties))
|
||||
if(has_job_loyalties && H.mind.assigned_role in job_loyalties)
|
||||
inspired += H
|
||||
else if(has_role_loyalties && H.mind.special_role in role_loyalties)
|
||||
inspired += H
|
||||
else if(check_inspiration(H))
|
||||
inspired += H
|
||||
|
||||
for(var/V in inspired)
|
||||
var/mob/living/carbon/human/H = V
|
||||
if(H != user)
|
||||
to_chat(H, "<span class='notice'>Your confidence surges as [user] flourishes [user.p_their()] [name]!</span>")
|
||||
inspiration(H)
|
||||
special_inspiration(H)
|
||||
|
||||
/obj/item/banner/proc/check_inspiration(mob/living/carbon/human/H) //Banner-specific conditions for being eligible
|
||||
return
|
||||
|
||||
/obj/item/banner/proc/inspiration(mob/living/carbon/human/H)
|
||||
H.adjustBruteLoss(-15)
|
||||
H.adjustFireLoss(-15)
|
||||
H.AdjustStun(-40)
|
||||
H.AdjustKnockdown(-40)
|
||||
H.AdjustUnconscious(-40)
|
||||
playsound(H, 'sound/magic/staff_healing.ogg', 25, FALSE)
|
||||
|
||||
/obj/item/banner/proc/special_inspiration(mob/living/carbon/human/H) //Any banner-specific inspiration effects go here
|
||||
return
|
||||
|
||||
/obj/item/banner/security
|
||||
name = "securistan banner"
|
||||
desc = "The banner of Securistan, ruling the station with an iron fist."
|
||||
icon_state = "banner_security"
|
||||
job_loyalties = list("Security Officer", "Warden", "Detective", "Head of Security")
|
||||
warcry = "EVERYONE DOWN ON THE GROUND!!"
|
||||
|
||||
/obj/item/banner/security/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/datum/crafting_recipe/security_banner
|
||||
name = "Securistan Banner"
|
||||
result = /obj/item/banner/security/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/security = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/medical
|
||||
name = "meditopia banner"
|
||||
desc = "The banner of Meditopia, generous benefactors that cure wounds and shelter the weak."
|
||||
icon_state = "banner_medical"
|
||||
job_loyalties = list("Medical Doctor", "Chemist", "Geneticist", "Virologist", "Chief Medical Officer")
|
||||
warcry = "No wounds cannot be healed!"
|
||||
|
||||
/obj/item/banner/medical/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/medical/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.stat //Meditopia is moved to help those in need
|
||||
|
||||
/datum/crafting_recipe/medical_banner
|
||||
name = "Meditopia Banner"
|
||||
result = /obj/item/banner/medical/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/medical = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
|
||||
H.adjustToxLoss(-15)
|
||||
H.setOxyLoss(0)
|
||||
H.reagents.add_reagent("inaprovaline", 5)
|
||||
|
||||
/obj/item/banner/science
|
||||
name = "sciencia banner"
|
||||
desc = "The banner of Sciencia, bold and daring thaumaturges and researchers that take the path less traveled."
|
||||
icon_state = "banner_science"
|
||||
job_loyalties = list("Scientist", "Roboticist", "Research Director")
|
||||
warcry = "For Cuban Pete!"
|
||||
|
||||
/obj/item/banner/science/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/science/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.on_fire //Sciencia is pleased by dedication to the art of Toxins
|
||||
|
||||
/datum/crafting_recipe/science_banner
|
||||
name = "Sciencia Banner"
|
||||
result = /obj/item/banner/science/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/scientist = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/cargo
|
||||
name = "cargonia banner"
|
||||
desc = "The banner of the eternal Cargonia, with the mystical power of conjuring any object into existence."
|
||||
icon_state = "banner_cargo"
|
||||
job_loyalties = list("Cargo Technician", "Shaft Miner", "Quartermaster")
|
||||
warcry = "Hail Cargonia!"
|
||||
|
||||
/obj/item/banner/cargo/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/datum/crafting_recipe/cargo_banner
|
||||
name = "Cargonia Banner"
|
||||
result = /obj/item/banner/cargo/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/cargotech = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/engineering
|
||||
name = "engitopia banner"
|
||||
desc = "The banner of Engitopia, wielders of limitless power."
|
||||
icon_state = "banner_engineering"
|
||||
job_loyalties = list("Station Engineer", "Atmospheric Technician", "Chief Engineer")
|
||||
warcry = "All hail lord Singuloth!!"
|
||||
|
||||
/obj/item/banner/engineering/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/engineering/special_inspiration(mob/living/carbon/human/H)
|
||||
H.radiation = 0
|
||||
|
||||
/datum/crafting_recipe/engineering_banner
|
||||
name = "Engitopia Banner"
|
||||
result = /obj/item/banner/engineering/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/engineer = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/command
|
||||
name = "command banner"
|
||||
desc = "The banner of Command, a staunch and ancient line of bueraucratic kings and queens."
|
||||
//No icon state here since the default one is the NT banner
|
||||
job_loyalties = list("Captain", "Head of Personnel", "Chief Engineer", "Head of Security", "Research Director", "Chief Medical Officer")
|
||||
warcry = "Hail Nanotrasen!"
|
||||
|
||||
/obj/item/banner/command/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.isloyal() //Command is stalwart but rewards their allies.
|
||||
|
||||
/datum/crafting_recipe/command_banner
|
||||
name = "Command Banner"
|
||||
result = /obj/item/banner/command/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/captainparade = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/red
|
||||
name = "red banner"
|
||||
|
||||
+790
-790
File diff suppressed because it is too large
Load Diff
@@ -487,7 +487,7 @@
|
||||
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 13
|
||||
var/force_on = 21
|
||||
var/force_on = 24
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
throwforce = 13
|
||||
throw_speed = 2
|
||||
|
||||
+586
-586
File diff suppressed because it is too large
Load Diff
@@ -169,6 +169,7 @@
|
||||
return
|
||||
|
||||
/obj/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(!anchored || current_size >= STAGE_FIVE)
|
||||
step_towards(src,S)
|
||||
|
||||
@@ -198,7 +199,7 @@
|
||||
|
||||
/obj/vv_get_dropdown()
|
||||
. = ..()
|
||||
.["Delete all of type"] = "?_src_=vars;delall=\ref[src]"
|
||||
.["Delete all of type"] = "?_src_=vars;[HrefToken()];delall=\ref[src]"
|
||||
|
||||
/obj/examine(mob/user)
|
||||
..()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
integrity_failure = 50
|
||||
armor = list(melee = 20, bullet = 10, laser = 10, energy = 0, bomb = 10, bio = 0, rad = 0, fire = 70, acid = 60)
|
||||
var/breakout_time = 2
|
||||
var/lastbang
|
||||
var/message_cooldown
|
||||
var/can_weld_shut = TRUE
|
||||
var/horizontal = FALSE
|
||||
var/allow_objects = FALSE
|
||||
@@ -300,14 +300,12 @@
|
||||
/obj/structure/closet/relaymove(mob/user)
|
||||
if(user.stat || !isturf(loc) || !isliving(user))
|
||||
return
|
||||
var/mob/living/L = user
|
||||
if(!open())
|
||||
if(L.last_special <= world.time)
|
||||
container_resist(L)
|
||||
if(world.time > lastbang+5)
|
||||
lastbang = world.time
|
||||
for(var/mob/M in get_hearers_in_view(src, null))
|
||||
M.show_message("<FONT size=[max(0, 5 - get_dist(src, M))]>BANG, bang!</FONT>", 2)
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
container_resist()
|
||||
|
||||
/obj/structure/closet/attack_hand(mob/user)
|
||||
..()
|
||||
@@ -367,9 +365,10 @@
|
||||
//okay, so the closet is either welded or locked... resist!!!
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open.</span>")
|
||||
visible_message("<span class='warning'>[src] begins to shake violently!</span>")
|
||||
if(do_after(user,(breakout_time * 60 * 10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
user.visible_message("<span class='warning'>[src] begins to shake violently!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear banging from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
|
||||
return
|
||||
//we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
|
||||
@@ -388,7 +387,7 @@
|
||||
|
||||
/obj/structure/closet/AltClick(mob/user)
|
||||
..()
|
||||
if(!user.canUseTopic(src, be_close=TRUE))
|
||||
if(!user.canUseTopic(src, be_close=TRUE) || !isturf(loc))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(opened || !secure)
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
new /obj/item/storage/belt/security/full(src)
|
||||
new /obj/item/gun/energy/e_gun/hos(src)
|
||||
new /obj/item/device/flashlight/seclite(src)
|
||||
new /obj/item/pinpointer(src)
|
||||
new /obj/item/pinpointer/nuke(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/warden
|
||||
name = "\proper warden's locker"
|
||||
@@ -108,6 +108,7 @@
|
||||
new /obj/item/clothing/gloves/krav_maga/sec(src)
|
||||
new /obj/item/door_remote/head_of_security(src)
|
||||
new /obj/item/gun/ballistic/shotgun/automatic/combat/compact(src)
|
||||
new /obj/item/pinpointer/crew(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/security
|
||||
name = "security officer's locker"
|
||||
@@ -183,6 +184,7 @@
|
||||
new /obj/item/reagent_containers/spray/pepper(src)
|
||||
new /obj/item/clothing/suit/armor/vest/det_suit(src)
|
||||
new /obj/item/storage/belt/holster/full(src)
|
||||
new /obj/item/pinpointer/crew(src)
|
||||
new /obj/item/device/mass_spectrometer(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/injection
|
||||
|
||||
@@ -118,5 +118,13 @@
|
||||
else
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
/obj/structure/ladder/unbreakable/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/structure/ladder/auto_connect //They will connect to ladders with the same X and Y without needing to share an ID
|
||||
auto_connect = TRUE
|
||||
auto_connect = TRUE
|
||||
|
||||
|
||||
/obj/structure/ladder/singularity_pull()
|
||||
visible_message("<span class='danger'>[src] is torn to pieces by the gravitational pull!</span>")
|
||||
qdel(src)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/lattice/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FOUR)
|
||||
deconstruct()
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
var/obj/structure/tray/connected = null
|
||||
var/locked = FALSE
|
||||
var/opendir = SOUTH
|
||||
var/message_cooldown
|
||||
var/breakout_time = 1
|
||||
|
||||
/obj/structure/bodycontainer/Destroy()
|
||||
open()
|
||||
@@ -41,6 +43,11 @@
|
||||
/obj/structure/bodycontainer/relaymove(mob/user)
|
||||
if(user.stat || !isturf(loc))
|
||||
return
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/attack_paw(mob/user)
|
||||
@@ -84,11 +91,20 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/bodycontainer/container_resist(mob/living/user)
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/relay_container_resist(mob/living/user, obj/O)
|
||||
to_chat(user, "<span class='notice'>You slam yourself into the side of [O].</span>")
|
||||
container_resist(user)
|
||||
if(!locked)
|
||||
open()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message(null, \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the tray open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/proc/open()
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/transit_tube/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
|
||||
@@ -62,10 +62,14 @@
|
||||
AM.ex_act(severity, target)
|
||||
|
||||
/obj/structure/transit_tube_pod/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
/obj/structure/transit_tube_pod/container_resist(mob/living/user)
|
||||
if(!user.incapacitated())
|
||||
empty_pod()
|
||||
return
|
||||
if(!moving)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/window/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
var/wet = 0
|
||||
var/wet_time = 0 // Time in seconds that this floor will be wet for.
|
||||
var/mutable_appearance/wet_overlay
|
||||
var/postdig_icon_change = FALSE
|
||||
var/postdig_icon
|
||||
var/list/archdrops
|
||||
|
||||
/turf/open/indestructible
|
||||
name = "floor"
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
return make_plating()
|
||||
|
||||
/turf/open/floor/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size == STAGE_THREE)
|
||||
if(prob(30))
|
||||
if(floor_tile)
|
||||
|
||||
@@ -269,6 +269,7 @@
|
||||
narsie_act(force, ignore_mobs, probability)
|
||||
|
||||
/turf/open/floor/vines/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(50))
|
||||
ChangeTurf(src.baseturf)
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "asteroid"
|
||||
icon_plating = "asteroid"
|
||||
postdig_icon_change = TRUE
|
||||
var/environment_type = "asteroid"
|
||||
var/turf_type = /turf/open/floor/plating/asteroid //Because caves do whacky shit to revert to normal
|
||||
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
|
||||
var/sand_type = /obj/item/ore/glass
|
||||
var/floor_variance = 20 //probability floor has a different icon state
|
||||
archdrops = list(/obj/item/ore/glass = 5)
|
||||
|
||||
/turf/open/floor/plating/asteroid/Initialize()
|
||||
var/proper_name = name
|
||||
@@ -22,6 +22,9 @@
|
||||
if(prob(floor_variance))
|
||||
icon_state = "[environment_type][rand(0,12)]"
|
||||
|
||||
if(LAZYLEN(archdrops))
|
||||
AddComponent(/datum/component/archaeology, 100, archdrops)
|
||||
|
||||
/turf/open/floor/plating/asteroid/burn_tile()
|
||||
return
|
||||
|
||||
@@ -31,46 +34,7 @@
|
||||
/turf/open/floor/plating/asteroid/MakeDry(wet_setting = TURF_WET_WATER)
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/ex_act(severity, target)
|
||||
contents_explosion(severity, target)
|
||||
switch(severity)
|
||||
if(3)
|
||||
return
|
||||
if(2)
|
||||
if(prob(20))
|
||||
src.gets_dug()
|
||||
if(1)
|
||||
src.gets_dug()
|
||||
|
||||
/turf/open/floor/plating/asteroid/attackby(obj/item/W, mob/user, params)
|
||||
//note that this proc does not call ..()
|
||||
if(!W || !user)
|
||||
return 0
|
||||
var/digging_speed = 0
|
||||
if (istype(W, /obj/item/shovel))
|
||||
var/obj/item/shovel/S = W
|
||||
digging_speed = S.digspeed
|
||||
else if (istype(W, /obj/item/pickaxe))
|
||||
var/obj/item/pickaxe/P = W
|
||||
digging_speed = P.digspeed
|
||||
if (digging_speed)
|
||||
var/turf/T = user.loc
|
||||
if(!isturf(T))
|
||||
return
|
||||
|
||||
if (dug)
|
||||
to_chat(user, "<span class='warning'>This area has already been dug!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You start digging...</span>")
|
||||
playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
|
||||
|
||||
if(do_after(user, digging_speed, target = src))
|
||||
if(istype(src, /turf/open/floor/plating/asteroid))
|
||||
to_chat(user, "<span class='notice'>You dig a hole.</span>")
|
||||
gets_dug()
|
||||
SSblackbox.add_details("pick_used_mining","[W.type]")
|
||||
|
||||
if(istype(W, /obj/item/storage/bag/ore))
|
||||
var/obj/item/storage/bag/ore/S = W
|
||||
if(S.collection_mode == 1)
|
||||
@@ -88,37 +52,16 @@
|
||||
var/turf/open/floor/light/F = T
|
||||
F.state = L.state
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
|
||||
/turf/open/floor/plating/asteroid/proc/gets_dug()
|
||||
if(dug)
|
||||
return
|
||||
for(var/i in 1 to 5)
|
||||
new sand_type(src)
|
||||
dug = 1
|
||||
icon_plating = "[environment_type]_dug"
|
||||
icon_state = "[environment_type]_dug"
|
||||
slowdown = 0
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/turf/open/floor/plating/asteroid/singularity_act()
|
||||
if(turf_z_is_planet(src))
|
||||
return ..()
|
||||
ChangeTurf(/turf/open/space)
|
||||
|
||||
/turf/open/floor/plating/asteroid/singularity_pull(S, current_size)
|
||||
if(dug)
|
||||
return
|
||||
switch(current_size)
|
||||
if(STAGE_THREE)
|
||||
if(!prob(30))
|
||||
gets_dug()
|
||||
if(STAGE_FOUR)
|
||||
if(prob(50))
|
||||
gets_dug()
|
||||
else
|
||||
if(current_size >= STAGE_FIVE && prob(70))
|
||||
gets_dug()
|
||||
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt
|
||||
name = "volcanic floor"
|
||||
@@ -127,7 +70,7 @@
|
||||
icon_state = "basalt"
|
||||
icon_plating = "basalt"
|
||||
environment_type = "basalt"
|
||||
sand_type = /obj/item/ore/glass/basalt
|
||||
archdrops = list(/obj/item/ore/glass/basalt = 5)
|
||||
floor_variance = 15
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/lava //lava underneath
|
||||
@@ -147,10 +90,10 @@
|
||||
if("basalt5", "basalt9")
|
||||
B.set_light(1.4, 0.6, LIGHT_COLOR_LAVA) //barely anything!
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/gets_dug()
|
||||
if(!dug)
|
||||
set_light(0)
|
||||
/turf/open/floor/plating/asteroid/basalt/ComponentActivated(datum/component/C)
|
||||
..()
|
||||
if(istype(C, /datum/component/archaeology))
|
||||
set_light(0)
|
||||
|
||||
|
||||
///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground.
|
||||
@@ -340,8 +283,8 @@
|
||||
initial_gas_mix = "TEMP=180"
|
||||
slowdown = 2
|
||||
environment_type = "snow"
|
||||
sand_type = /obj/item/stack/sheet/mineral/snow
|
||||
flags_1 = NONE
|
||||
archdrops = list(/obj/item/stack/sheet/mineral/snow = 5)
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/airless
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
make_plating(1)
|
||||
|
||||
/turf/open/floor/engine/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(floor_tile)
|
||||
if(prob(30))
|
||||
|
||||
@@ -247,6 +247,7 @@
|
||||
icon_state = "r_wall"
|
||||
|
||||
/turf/closed/wall/r_wall/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(30))
|
||||
dismantle_wall()
|
||||
|
||||
@@ -245,6 +245,7 @@
|
||||
QDEL_IN(O, 50)
|
||||
|
||||
/turf/closed/wall/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(50))
|
||||
dismantle_wall()
|
||||
|
||||
@@ -524,12 +524,12 @@
|
||||
|
||||
/turf/proc/photograph(limit=20)
|
||||
var/image/I = new()
|
||||
I.overlays += src
|
||||
I.add_overlay(src)
|
||||
for(var/V in contents)
|
||||
var/atom/A = V
|
||||
if(A.invisibility)
|
||||
continue
|
||||
I.overlays += A
|
||||
I.add_overlay(A)
|
||||
if(limit)
|
||||
limit--
|
||||
else
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
GLOBAL_VAR(security_mode)
|
||||
GLOBAL_PROTECT(security_mode)
|
||||
|
||||
/world/New()
|
||||
log_world("World loaded at [time_stamp()]")
|
||||
|
||||
@@ -5,6 +8,8 @@
|
||||
|
||||
GLOB.config_error_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = file("data/logs/config_error.log") //temporary file used to record errors with loading config, moved to log directory once logging is set bl
|
||||
|
||||
CheckSecurityMode()
|
||||
|
||||
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
|
||||
|
||||
config = new
|
||||
@@ -94,6 +99,20 @@
|
||||
if(GLOB.round_id)
|
||||
log_game("Round ID: [GLOB.round_id]")
|
||||
|
||||
/world/proc/CheckSecurityMode()
|
||||
//try to write to data
|
||||
if(!text2file("The world is running at least safe mode", "data/server_security_check.lock"))
|
||||
GLOB.security_mode = SECURITY_ULTRASAFE
|
||||
warning("/tg/station 13 is not supported in ultrasafe security mode. Everything will break!")
|
||||
return
|
||||
|
||||
//try to shell
|
||||
if(shell("echo \"The world is running in trusted mode\"") != null)
|
||||
GLOB.security_mode = SECURITY_TRUSTED
|
||||
else
|
||||
GLOB.security_mode = SECURITY_SAFE
|
||||
warning("/tg/station 13 uses many file operations, a few shell()s, and some external call()s. Trusted mode is recommended. You can download our source code for your own browsing and compilation at https://github.com/tgstation/tgstation")
|
||||
|
||||
/world/Topic(T, addr, master, key)
|
||||
var/list/input = params2list(T)
|
||||
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
open_machine()
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/container_resist(mob/living/user)
|
||||
open_machine()
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/Destroy()
|
||||
open_machine()
|
||||
cleanup_vr_human()
|
||||
|
||||
@@ -414,7 +414,7 @@
|
||||
if(bancount > bansperpage)
|
||||
output += "<br><b>Page: </b>"
|
||||
while(bancount > 0)
|
||||
output+= "|<a href='?_src_=holder;dbsearchckey=[playerckey];dbsearchadmin=[adminckey];dbsearchpage=[pagecount]'>[pagecount == page ? "<b>\[[pagecount]\]</b>" : "\[[pagecount]\]"]</a>"
|
||||
output+= "|<a href='?_src_=holder;[HrefToken()];dbsearchckey=[playerckey];dbsearchadmin=[adminckey];dbsearchpage=[pagecount]'>[pagecount == page ? "<b>\[[pagecount]\]</b>" : "\[[pagecount]\]"]</a>"
|
||||
bancount -= bansperpage
|
||||
pagecount++
|
||||
output += "|"
|
||||
@@ -462,25 +462,25 @@
|
||||
if("PERMABAN")
|
||||
typedesc = "<font color='red'><b>PERMABAN</b></font>"
|
||||
if("TEMPBAN")
|
||||
typedesc = "<b>TEMPBAN</b><br><font size='2'>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]</font>"
|
||||
typedesc = "<b>TEMPBAN</b><br><font size='2'>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]</font>"
|
||||
if("JOB_PERMABAN")
|
||||
typedesc = "<b>JOBBAN</b><br><font size='2'>([job])"
|
||||
if("JOB_TEMPBAN")
|
||||
typedesc = "<b>TEMP JOBBAN</b><br><font size='2'>([job])<br>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]"
|
||||
typedesc = "<b>TEMP JOBBAN</b><br><font size='2'>([job])<br>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]"
|
||||
if("ADMIN_PERMABAN")
|
||||
typedesc = "<b>ADMIN PERMABAN</b>"
|
||||
if("ADMIN_TEMPBAN")
|
||||
typedesc = "<b>ADMIN TEMPBAN</b><br><font size='2'>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]</font>"
|
||||
typedesc = "<b>ADMIN TEMPBAN</b><br><font size='2'>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]</font>"
|
||||
|
||||
output += "<tr bgcolor='[dcolor]'>"
|
||||
output += "<td align='center'>[typedesc]</td>"
|
||||
output += "<td align='center'><b>[ckey]</b></td>"
|
||||
output += "<td align='center'>[bantime]</td>"
|
||||
output += "<td align='center'><b>[ackey]</b></td>"
|
||||
output += "<td align='center'>[(unbanned) ? "" : "<b><a href=\"byond://?src=\ref[src];dbbanedit=unban;dbbanid=[banid]\">Unban</a></b>"]</td>"
|
||||
output += "<td align='center'>[(unbanned) ? "" : "<b><a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=unban;dbbanid=[banid]\">Unban</a></b>"]</td>"
|
||||
output += "</tr>"
|
||||
output += "<tr bgcolor='[lcolor]'>"
|
||||
output += "<td align='center' colspan='5'><b>Reason: [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];dbbanedit=reason;dbbanid=[banid]\">Edit</a>)"]</b> <cite>\"[reason]\"</cite></td>"
|
||||
output += "<td align='center' colspan='5'><b>Reason: [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=reason;dbbanid=[banid]\">Edit</a>)"]</b> <cite>\"[reason]\"</cite></td>"
|
||||
output += "</tr>"
|
||||
if(edits)
|
||||
output += "<tr bgcolor='[dcolor]'>"
|
||||
|
||||
+128
-130
@@ -30,68 +30,68 @@
|
||||
body += "<body>Options panel for <b>[M]</b>"
|
||||
if(M.client)
|
||||
body += " played by <b>[M.client]</b> "
|
||||
body += "\[<A href='?_src_=holder;editrights=rank;ckey=[M.ckey]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\]"
|
||||
body += "\[<A href='?_src_=holder;[HrefToken()];editrights=rank;ckey=[M.ckey]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\]"
|
||||
if(config.use_exp_tracking)
|
||||
body += "\[<A href='?_src_=holder;getplaytimewindow=\ref[M]'>" + M.client.get_exp_living() + "</a>\]"
|
||||
body += "\[<A href='?_src_=holder;[HrefToken()];getplaytimewindow=\ref[M]'>" + M.client.get_exp_living() + "</a>\]"
|
||||
|
||||
if(isnewplayer(M))
|
||||
body += " <B>Hasn't Entered Game</B> "
|
||||
else
|
||||
body += " \[<A href='?_src_=holder;revive=\ref[M]'>Heal</A>\] "
|
||||
body += " \[<A href='?_src_=holder;[HrefToken()];revive=\ref[M]'>Heal</A>\] "
|
||||
|
||||
if(M.client)
|
||||
body += "<br>\[<b>First Seen:</b> [M.client.player_join_date]\]\[<b>Byond account registered on:</b> [M.client.account_join_date]\]"
|
||||
body += "<br><br><b>Show related accounts by:</b> "
|
||||
body += "\[ <a href='?_src_=holder;showrelatedacc=cid;client=\ref[M.client]'>CID</a> | "
|
||||
body += "<a href='?_src_=holder;showrelatedacc=ip;client=\ref[M.client]'>IP</a> \]"
|
||||
body += "\[ <a href='?_src_=holder;[HrefToken()];showrelatedacc=cid;client=\ref[M.client]'>CID</a> | "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];showrelatedacc=ip;client=\ref[M.client]'>IP</a> \]"
|
||||
|
||||
|
||||
body += "<br><br>\[ "
|
||||
body += "<a href='?_src_=vars;Vars=\ref[M]'>VV</a> - "
|
||||
body += "<a href='?_src_=holder;traitor=\ref[M]'>TP</a> - "
|
||||
body += "<a href='?_src_=vars;[HrefToken()];Vars=\ref[M]'>VV</a> - "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];traitor=\ref[M]'>TP</a> - "
|
||||
body += "<a href='?priv_msg=[M.ckey]'>PM</a> - "
|
||||
body += "<a href='?_src_=holder;subtlemessage=\ref[M]'>SM</a> - "
|
||||
body += "<a href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a> - "
|
||||
body += "<a href='?_src_=holder;individuallog=\ref[M]'>LOGS</a>\] <br>"
|
||||
body += "<a href='?_src_=holder;[HrefToken()];subtlemessage=\ref[M]'>SM</a> - "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a> - "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];individuallog=\ref[M]'>LOGS</a>\] <br>"
|
||||
|
||||
body += "<b>Mob type</b> = [M.type]<br><br>"
|
||||
|
||||
body += "<A href='?_src_=holder;boot2=\ref[M]'>Kick</A> | "
|
||||
body += "<A href='?_src_=holder;newban=\ref[M]'>Ban</A> | "
|
||||
body += "<A href='?_src_=holder;jobban2=\ref[M]'>Jobban</A> | "
|
||||
body += "<A href='?_src_=holder;appearanceban=\ref[M]'>Identity Ban</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];boot2=\ref[M]'>Kick</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];newban=\ref[M]'>Ban</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];jobban2=\ref[M]'>Jobban</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];appearanceban=\ref[M]'>Identity Ban</A> | "
|
||||
if(jobban_isbanned(M, "OOC"))
|
||||
body+= "<A href='?_src_=holder;jobban3=OOC;jobban4=\ref[M]'><font color=red>OOCBan</font></A> | "
|
||||
body+= "<A href='?_src_=holder;[HrefToken()];jobban3=OOC;jobban4=\ref[M]'><font color=red>OOCBan</font></A> | "
|
||||
else
|
||||
body+= "<A href='?_src_=holder;jobban3=OOC;jobban4=\ref[M]'>OOCBan</A> | "
|
||||
body+= "<A href='?_src_=holder;[HrefToken()];jobban3=OOC;jobban4=\ref[M]'>OOCBan</A> | "
|
||||
if(jobban_isbanned(M, "emote"))
|
||||
body+= "<A href='?_src_=holder;jobban3=emote;jobban4=\ref[M]'><font color=red>EmoteBan</font></A> | "
|
||||
body+= "<A href='?_src_=holder;[HrefToken()];jobban3=emote;jobban4=\ref[M]'><font color=red>EmoteBan</font></A> | "
|
||||
else
|
||||
body+= "<A href='?_src_=holder;jobban3=emote;jobban4=\ref[M]'>Emoteban</A> | "
|
||||
body+= "<A href='?_src_=holder;[HrefToken()];jobban3=emote;jobban4=\ref[M]'>Emoteban</A> | "
|
||||
|
||||
body += "<A href='?_src_=holder;showmessageckey=[M.ckey]'>Notes | Messages | Watchlist</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];showmessageckey=[M.ckey]'>Notes | Messages | Watchlist</A> | "
|
||||
if(M.client)
|
||||
body += "| <A href='?_src_=holder;sendtoprison=\ref[M]'>Prison</A> | "
|
||||
body += "\ <A href='?_src_=holder;sendbacktolobby=\ref[M]'>Send back to Lobby</A> | "
|
||||
body += "| <A href='?_src_=holder;[HrefToken()];sendtoprison=\ref[M]'>Prison</A> | "
|
||||
body += "\ <A href='?_src_=holder;[HrefToken()];sendbacktolobby=\ref[M]'>Send back to Lobby</A> | "
|
||||
var/muted = M.client.prefs.muted
|
||||
body += "<br><b>Mute: </b> "
|
||||
body += "\[<A href='?_src_=holder;mute=[M.ckey];mute_type=[MUTE_IC]'><font color='[(muted & MUTE_IC)?"red":"blue"]'>IC</font></a> | "
|
||||
body += "<A href='?_src_=holder;mute=[M.ckey];mute_type=[MUTE_OOC]'><font color='[(muted & MUTE_OOC)?"red":"blue"]'>OOC</font></a> | "
|
||||
body += "<A href='?_src_=holder;mute=[M.ckey];mute_type=[MUTE_PRAY]'><font color='[(muted & MUTE_PRAY)?"red":"blue"]'>PRAY</font></a> | "
|
||||
body += "<A href='?_src_=holder;mute=[M.ckey];mute_type=[MUTE_ADMINHELP]'><font color='[(muted & MUTE_ADMINHELP)?"red":"blue"]'>ADMINHELP</font></a> | "
|
||||
body += "<A href='?_src_=holder;mute=[M.ckey];mute_type=[MUTE_DEADCHAT]'><font color='[(muted & MUTE_DEADCHAT)?"red":"blue"]'>DEADCHAT</font></a>\]"
|
||||
body += "(<A href='?_src_=holder;mute=[M.ckey];mute_type=[MUTE_ALL]'><font color='[(muted & MUTE_ALL)?"red":"blue"]'>toggle all</font></a>)"
|
||||
body += "\[<A href='?_src_=holder[HrefToken()];;mute=[M.ckey];mute_type=[MUTE_IC]'><font color='[(muted & MUTE_IC)?"red":"blue"]'>IC</font></a> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;mute=[M.ckey];mute_type=[MUTE_OOC]'><font color='[(muted & MUTE_OOC)?"red":"blue"]'>OOC</font></a> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;mute=[M.ckey];mute_type=[MUTE_PRAY]'><font color='[(muted & MUTE_PRAY)?"red":"blue"]'>PRAY</font></a> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;mute=[M.ckey];mute_type=[MUTE_ADMINHELP]'><font color='[(muted & MUTE_ADMINHELP)?"red":"blue"]'>ADMINHELP</font></a> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;mute=[M.ckey];mute_type=[MUTE_DEADCHAT]'><font color='[(muted & MUTE_DEADCHAT)?"red":"blue"]'>DEADCHAT</font></a>\]"
|
||||
body += "(<A href='?_src_=holder[HrefToken()];;mute=[M.ckey];mute_type=[MUTE_ALL]'><font color='[(muted & MUTE_ALL)?"red":"blue"]'>toggle all</font></a>)"
|
||||
|
||||
body += "<br><br>"
|
||||
body += "<A href='?_src_=holder;jumpto=\ref[M]'><b>Jump to</b></A> | "
|
||||
body += "<A href='?_src_=holder;getmob=\ref[M]'>Get</A> | "
|
||||
body += "<A href='?_src_=holder;sendmob=\ref[M]'>Send To</A>"
|
||||
body += "<A href='?_src_=holder[HrefToken()];;jumpto=\ref[M]'><b>Jump to</b></A> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;getmob=\ref[M]'>Get</A> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;sendmob=\ref[M]'>Send To</A>"
|
||||
|
||||
body += "<br><br>"
|
||||
body += "<A href='?_src_=holder;traitor=\ref[M]'>Traitor panel</A> | "
|
||||
body += "<A href='?_src_=holder;narrateto=\ref[M]'>Narrate to</A> | "
|
||||
body += "<A href='?_src_=holder;subtlemessage=\ref[M]'>Subtle message</A> | "
|
||||
body += "<A href='?_src_=holder;languagemenu=\ref[M]'>Language Menu</A>"
|
||||
body += "<A href='?_src_=holder[HrefToken()];;traitor=\ref[M]'>Traitor panel</A> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;narrateto=\ref[M]'>Narrate to</A> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;subtlemessage=\ref[M]'>Subtle message</A> | "
|
||||
body += "<A href='?_src_=holder[HrefToken()];;languagemenu=\ref[M]'>Language Menu</A>"
|
||||
|
||||
if (M.client)
|
||||
if(!isnewplayer(M))
|
||||
@@ -103,73 +103,71 @@
|
||||
if(ishuman(M))
|
||||
body += "<B>Human</B> | "
|
||||
else
|
||||
body += "<A href='?_src_=holder;humanone=\ref[M]'>Humanize</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];humanone=\ref[M]'>Humanize</A> | "
|
||||
|
||||
//Monkey
|
||||
if(ismonkey(M))
|
||||
body += "<B>Monkeyized</B> | "
|
||||
else
|
||||
body += "<A href='?_src_=holder;monkeyone=\ref[M]'>Monkeyize</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];monkeyone=\ref[M]'>Monkeyize</A> | "
|
||||
|
||||
//Corgi
|
||||
if(iscorgi(M))
|
||||
body += "<B>Corgized</B> | "
|
||||
else
|
||||
body += "<A href='?_src_=holder;corgione=\ref[M]'>Corgize</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];corgione=\ref[M]'>Corgize</A> | "
|
||||
|
||||
//AI / Cyborg
|
||||
if(isAI(M))
|
||||
body += "<B>Is an AI</B> "
|
||||
else if(ishuman(M))
|
||||
body += "<A href='?_src_=holder;makeai=\ref[M]'>Make AI</A> | "
|
||||
body += "<A href='?_src_=holder;makerobot=\ref[M]'>Make Robot</A> | "
|
||||
body += "<A href='?_src_=holder;makealien=\ref[M]'>Make Alien</A> | "
|
||||
body += "<A href='?_src_=holder;makeslime=\ref[M]'>Make Slime</A> | "
|
||||
body += "<A href='?_src_=holder;makeblob=\ref[M]'>Make Blob</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];makeai=\ref[M]'>Make AI</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];makerobot=\ref[M]'>Make Robot</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];makealien=\ref[M]'>Make Alien</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];makeslime=\ref[M]'>Make Slime</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];makeblob=\ref[M]'>Make Blob</A> | "
|
||||
|
||||
//Simple Animals
|
||||
if(isanimal(M))
|
||||
body += "<A href='?_src_=holder;makeanimal=\ref[M]'>Re-Animalize</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];makeanimal=\ref[M]'>Re-Animalize</A> | "
|
||||
else
|
||||
body += "<A href='?_src_=holder;makeanimal=\ref[M]'>Animalize</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];makeanimal=\ref[M]'>Animalize</A> | "
|
||||
|
||||
body += "<br><br>"
|
||||
body += "<b>Rudimentary transformation:</b><font size=2><br>These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.</font><br>"
|
||||
body += "<A href='?_src_=holder;simplemake=observer;mob=\ref[M]'>Observer</A> | "
|
||||
body += "\[ Alien: <A href='?_src_=holder;simplemake=drone;mob=\ref[M]'>Drone</A>, "
|
||||
body += "<A href='?_src_=holder;simplemake=hunter;mob=\ref[M]'>Hunter</A>, "
|
||||
body += "<A href='?_src_=holder;simplemake=sentinel;mob=\ref[M]'>Sentinel</A>, "
|
||||
body += "<A href='?_src_=holder;simplemake=praetorian;mob=\ref[M]'>Praetorian</A>, "
|
||||
body += "<A href='?_src_=holder;simplemake=queen;mob=\ref[M]'>Queen</A>, "
|
||||
body += "<A href='?_src_=holder;simplemake=larva;mob=\ref[M]'>Larva</A> \] "
|
||||
body += "<A href='?_src_=holder;simplemake=human;mob=\ref[M]'>Human</A> "
|
||||
body += "\[ slime: <A href='?_src_=holder;simplemake=slime;mob=\ref[M]'>Baby</A>, "
|
||||
body += "<A href='?_src_=holder;simplemake=adultslime;mob=\ref[M]'>Adult</A> \] "
|
||||
body += "<A href='?_src_=holder;simplemake=monkey;mob=\ref[M]'>Monkey</A> | "
|
||||
body += "<A href='?_src_=holder;simplemake=robot;mob=\ref[M]'>Cyborg</A> | "
|
||||
body += "<A href='?_src_=holder;simplemake=cat;mob=\ref[M]'>Cat</A> | "
|
||||
body += "<A href='?_src_=holder;simplemake=runtime;mob=\ref[M]'>Runtime</A> | "
|
||||
body += "<A href='?_src_=holder;simplemake=corgi;mob=\ref[M]'>Corgi</A> | "
|
||||
body += "<A href='?_src_=holder;simplemake=ian;mob=\ref[M]'>Ian</A> | "
|
||||
body += "<A href='?_src_=holder;simplemake=crab;mob=\ref[M]'>Crab</A> | "
|
||||
body += "<A href='?_src_=holder;simplemake=coffee;mob=\ref[M]'>Coffee</A> | "
|
||||
//body += "<A href='?_src_=holder;simplemake=parrot;mob=\ref[M]'>Parrot</A> | "
|
||||
//body += "<A href='?_src_=holder;simplemake=polyparrot;mob=\ref[M]'>Poly</A> | "
|
||||
body += "\[ Construct: <A href='?_src_=holder;simplemake=constructarmored;mob=\ref[M]'>Juggernaut</A> , "
|
||||
body += "<A href='?_src_=holder;simplemake=constructbuilder;mob=\ref[M]'>Artificer</A> , "
|
||||
body += "<A href='?_src_=holder;simplemake=constructwraith;mob=\ref[M]'>Wraith</A> \] "
|
||||
body += "<A href='?_src_=holder;simplemake=shade;mob=\ref[M]'>Shade</A>"
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=observer;mob=\ref[M]'>Observer</A> | "
|
||||
body += "\[ Alien: <A href='?_src_=holder;[HrefToken()];simplemake=drone;mob=\ref[M]'>Drone</A>, "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=hunter;mob=\ref[M]'>Hunter</A>, "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=sentinel;mob=\ref[M]'>Sentinel</A>, "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=praetorian;mob=\ref[M]'>Praetorian</A>, "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=queen;mob=\ref[M]'>Queen</A>, "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=larva;mob=\ref[M]'>Larva</A> \] "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=human;mob=\ref[M]'>Human</A> "
|
||||
body += "\[ slime: <A href='?_src_=holder;[HrefToken()];simplemake=slime;mob=\ref[M]'>Baby</A>, "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=adultslime;mob=\ref[M]'>Adult</A> \] "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=monkey;mob=\ref[M]'>Monkey</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=robot;mob=\ref[M]'>Cyborg</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=cat;mob=\ref[M]'>Cat</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=runtime;mob=\ref[M]'>Runtime</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=corgi;mob=\ref[M]'>Corgi</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=ian;mob=\ref[M]'>Ian</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=crab;mob=\ref[M]'>Crab</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=coffee;mob=\ref[M]'>Coffee</A> | "
|
||||
body += "\[ Construct: <A href='?_src_=holder;[HrefToken()];simplemake=constructarmored;mob=\ref[M]'>Juggernaut</A> , "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=constructbuilder;mob=\ref[M]'>Artificer</A> , "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=constructwraith;mob=\ref[M]'>Wraith</A> \] "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];simplemake=shade;mob=\ref[M]'>Shade</A>"
|
||||
body += "<br>"
|
||||
|
||||
if (M.client)
|
||||
body += "<br><br>"
|
||||
body += "<b>Other actions:</b>"
|
||||
body += "<br>"
|
||||
body += "<A href='?_src_=holder;forcespeech=\ref[M]'>Forcesay</A> | "
|
||||
body += "<A href='?_src_=holder;tdome1=\ref[M]'>Thunderdome 1</A> | "
|
||||
body += "<A href='?_src_=holder;tdome2=\ref[M]'>Thunderdome 2</A> | "
|
||||
body += "<A href='?_src_=holder;tdomeadmin=\ref[M]'>Thunderdome Admin</A> | "
|
||||
body += "<A href='?_src_=holder;tdomeobserve=\ref[M]'>Thunderdome Observer</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];forcespeech=\ref[M]'>Forcesay</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];tdome1=\ref[M]'>Thunderdome 1</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];tdome2=\ref[M]'>Thunderdome 2</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];tdomeadmin=\ref[M]'>Thunderdome Admin</A> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];tdomeobserve=\ref[M]'>Thunderdome Observer</A> | "
|
||||
|
||||
body += "<br>"
|
||||
body += "</body></html>"
|
||||
@@ -197,19 +195,19 @@
|
||||
dat += "<BR>Feed channels and stories entered through here will be uneditable and handled as official news by the rest of the units."
|
||||
dat += "<BR>Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things!</FONT>"
|
||||
if(GLOB.news_network.wanted_issue.active)
|
||||
dat+= "<HR><A href='?src=\ref[src];ac_view_wanted=1'>Read Wanted Issue</A>"
|
||||
dat+= "<HR><BR><A href='?src=\ref[src];ac_create_channel=1'>Create Feed Channel</A>"
|
||||
dat+= "<BR><A href='?src=\ref[src];ac_view=1'>View Feed Channels</A>"
|
||||
dat+= "<BR><A href='?src=\ref[src];ac_create_feed_story=1'>Submit new Feed story</A>"
|
||||
dat+= "<BR><BR><A href='?src=\ref[usr];mach_close=newscaster_main'>Exit</A>"
|
||||
dat+= "<HR><A href='?src=\ref[src];[HrefToken()];ac_view_wanted=1'>Read Wanted Issue</A>"
|
||||
dat+= "<HR><BR><A href='?src=\ref[src];[HrefToken()];ac_create_channel=1'>Create Feed Channel</A>"
|
||||
dat+= "<BR><A href='?src=\ref[src];[HrefToken()];ac_view=1'>View Feed Channels</A>"
|
||||
dat+= "<BR><A href='?src=\ref[src];[HrefToken()];ac_create_feed_story=1'>Submit new Feed story</A>"
|
||||
dat+= "<BR><BR><A href='?src=\ref[usr];[HrefToken()];mach_close=newscaster_main'>Exit</A>"
|
||||
var/wanted_already = 0
|
||||
if(GLOB.news_network.wanted_issue.active)
|
||||
wanted_already = 1
|
||||
dat+="<HR><B>Feed Security functions:</B><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_menu_wanted=1'>[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_menu_censor_story=1'>Censor Feed Stories</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_menu_censor_channel=1'>Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel).</A>"
|
||||
dat+="<BR><HR><A href='?src=\ref[src];ac_set_signature=1'>The newscaster recognises you as:<BR> <FONT COLOR='green'>[src.admin_signature]</FONT></A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_menu_wanted=1'>[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_menu_censor_story=1'>Censor Feed Stories</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_menu_censor_channel=1'>Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel).</A>"
|
||||
dat+="<BR><HR><A href='?src=\ref[src];[HrefToken()];ac_set_signature=1'>The newscaster recognises you as:<BR> <FONT COLOR='green'>[src.admin_signature]</FONT></A>"
|
||||
if(1)
|
||||
dat+= "Station Feed Channels<HR>"
|
||||
if( isemptylist(GLOB.news_network.network_channels) )
|
||||
@@ -219,34 +217,34 @@
|
||||
if(CHANNEL.is_admin_channel)
|
||||
dat+="<B><FONT style='BACKGROUND-COLOR: LightGreen'><A href='?src=\ref[src];ac_show_channel=\ref[CHANNEL]'>[CHANNEL.channel_name]</A></FONT></B><BR>"
|
||||
else
|
||||
dat+="<B><A href='?src=\ref[src];ac_show_channel=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR></B>"
|
||||
dat+="<BR><HR><A href='?src=\ref[src];ac_refresh=1'>Refresh</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Back</A>"
|
||||
dat+="<B><A href='?src=\ref[src];[HrefToken()];ac_show_channel=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR></B>"
|
||||
dat+="<BR><HR><A href='?src=\ref[src];[HrefToken()];ac_refresh=1'>Refresh</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Back</A>"
|
||||
if(2)
|
||||
dat+="Creating new Feed Channel..."
|
||||
dat+="<HR><B><A href='?src=\ref[src];ac_set_channel_name=1'>Channel Name</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>"
|
||||
dat+="<B><A href='?src=\ref[src];ac_set_signature=1'>Channel Author</A>:</B> <FONT COLOR='green'>[src.admin_signature]</FONT><BR>"
|
||||
dat+="<B><A href='?src=\ref[src];ac_set_channel_lock=1'>Will Accept Public Feeds</A>:</B> [(src.admincaster_feed_channel.locked) ? ("NO") : ("YES")]<BR><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_submit_new_channel=1'>Submit</A><BR><BR><A href='?src=\ref[src];ac_setScreen=[0]'>Cancel</A><BR>"
|
||||
dat+="<HR><B><A href='?src=\ref[src];[HrefToken()];ac_set_channel_name=1'>Channel Name</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>"
|
||||
dat+="<B><A href='?src=\ref[src];[HrefToken()];ac_set_signature=1'>Channel Author</A>:</B> <FONT COLOR='green'>[src.admin_signature]</FONT><BR>"
|
||||
dat+="<B><A href='?src=\ref[src];[HrefToken()];ac_set_channel_lock=1'>Will Accept Public Feeds</A>:</B> [(src.admincaster_feed_channel.locked) ? ("NO") : ("YES")]<BR><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_submit_new_channel=1'>Submit</A><BR><BR><A href='?src=\ref[src];ac_setScreen=[0]'>Cancel</A><BR>"
|
||||
if(3)
|
||||
dat+="Creating new Feed Message..."
|
||||
dat+="<HR><B><A href='?src=\ref[src];ac_set_channel_receiving=1'>Receiving Channel</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>" //MARK
|
||||
dat+="<HR><B><A href='?src=\ref[src];[HrefToken()];ac_set_channel_receiving=1'>Receiving Channel</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>" //MARK
|
||||
dat+="<B>Message Author:</B> <FONT COLOR='green'>[src.admin_signature]</FONT><BR>"
|
||||
dat+="<B><A href='?src=\ref[src];ac_set_new_message=1'>Message Body</A>:</B> [src.admincaster_feed_message.returnBody(-1)] <BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_submit_new_message=1'>Submit</A><BR><BR><A href='?src=\ref[src];ac_setScreen=[0]'>Cancel</A><BR>"
|
||||
dat+="<B><A href='?src=\ref[src];[HrefToken()];ac_set_new_message=1'>Message Body</A>:</B> [src.admincaster_feed_message.returnBody(-1)] <BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_submit_new_message=1'>Submit</A><BR><BR><A href='?src=\ref[src];ac_setScreen=[0]'>Cancel</A><BR>"
|
||||
if(4)
|
||||
dat+="Feed story successfully submitted to [src.admincaster_feed_channel.channel_name].<BR><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Return</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
|
||||
if(5)
|
||||
dat+="Feed Channel [src.admincaster_feed_channel.channel_name] created successfully.<BR><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Return</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
|
||||
if(6)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed story to Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_feed_channel.channel_name=="")
|
||||
dat+="<FONT COLOR='maroon'>Invalid receiving channel name.</FONT><BR>"
|
||||
if(src.admincaster_feed_message.returnBody(-1) == "" || src.admincaster_feed_message.returnBody(-1) == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid message body.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[3]'>Return</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[3]'>Return</A><BR>"
|
||||
if(7)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed Channel to Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
|
||||
@@ -258,7 +256,7 @@
|
||||
break
|
||||
if(check)
|
||||
dat+="<FONT COLOR='maroon'>Channel name already in use.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[2]'>Return</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[2]'>Return</A><BR>"
|
||||
if(9)
|
||||
dat+="<B>[admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[created by: <FONT COLOR='maroon'>[admincaster_feed_channel.returnAuthor(-1)]</FONT>\]</FONT><HR>"
|
||||
if(src.admincaster_feed_channel.censored)
|
||||
@@ -280,8 +278,8 @@
|
||||
for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
|
||||
dat+="[comment.body]<br><font size=1>[comment.author] [comment.time_stamp]</font><br>"
|
||||
dat+="<br>"
|
||||
dat+="<BR><HR><A href='?src=\ref[src];ac_refresh=1'>Refresh</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[1]'>Back</A>"
|
||||
dat+="<BR><HR><A href='?src=\ref[src];[HrefToken()];ac_refresh=1'>Refresh</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[1]'>Back</A>"
|
||||
if(10)
|
||||
dat+="<B>Nanotrasen Feed Censorship Tool</B><BR>"
|
||||
dat+="<FONT SIZE=1>NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.<BR>"
|
||||
@@ -291,8 +289,8 @@
|
||||
dat+="<I>No feed channels found active...</I><BR>"
|
||||
else
|
||||
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
|
||||
dat+="<A href='?src=\ref[src];ac_pick_censor_channel=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Cancel</A>"
|
||||
dat+="<A href='?src=\ref[src];[HrefToken()];ac_pick_censor_channel=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Cancel</A>"
|
||||
if(11)
|
||||
dat+="<B>Nanotrasen D-Notice Handler</B><HR>"
|
||||
dat+="<FONT SIZE=1>A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
|
||||
@@ -302,26 +300,26 @@
|
||||
dat+="<I>No feed channels found active...</I><BR>"
|
||||
else
|
||||
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
|
||||
dat+="<A href='?src=\ref[src];ac_pick_d_notice=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR>"
|
||||
dat+="<A href='?src=\ref[src];[HrefToken()];ac_pick_d_notice=\ref[CHANNEL]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR>"
|
||||
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Back</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Back</A>"
|
||||
if(12)
|
||||
dat+="<B>[src.admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[ created by: <FONT COLOR='maroon'>[src.admincaster_feed_channel.returnAuthor(-1)]</FONT> \]</FONT><BR>"
|
||||
dat+="<FONT SIZE=2><A href='?src=\ref[src];ac_censor_channel_author=\ref[src.admincaster_feed_channel]'>[(src.admincaster_feed_channel.authorCensor) ? ("Undo Author censorship") : ("Censor channel Author")]</A></FONT><HR>"
|
||||
dat+="<FONT SIZE=2><A href='?src=\ref[src];[HrefToken()];ac_censor_channel_author=\ref[src.admincaster_feed_channel]'>[(src.admincaster_feed_channel.authorCensor) ? ("Undo Author censorship") : ("Censor channel Author")]</A></FONT><HR>"
|
||||
|
||||
if( isemptylist(src.admincaster_feed_channel.messages) )
|
||||
dat+="<I>No feed messages found in channel...</I><BR>"
|
||||
else
|
||||
for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
|
||||
dat+="-[MESSAGE.returnBody(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.returnAuthor(-1)]</FONT>\]</FONT><BR>"
|
||||
dat+="<FONT SIZE=2><A href='?src=\ref[src];ac_censor_channel_story_body=\ref[MESSAGE]'>[(MESSAGE.bodyCensor) ? ("Undo story censorship") : ("Censor story")]</A> - <A href='?src=\ref[src];ac_censor_channel_story_author=\ref[MESSAGE]'>[(MESSAGE.authorCensor) ? ("Undo Author Censorship") : ("Censor message Author")]</A></FONT><BR>"
|
||||
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]: <a href='?src=\ref[src];ac_lock_comment=\ref[MESSAGE]'>[MESSAGE.locked ? "Unlock" : "Lock"]</a><br>"
|
||||
dat+="<FONT SIZE=2><A href='?src=\ref[src];[HrefToken()];ac_censor_channel_story_body=\ref[MESSAGE]'>[(MESSAGE.bodyCensor) ? ("Undo story censorship") : ("Censor story")]</A> - <A href='?src=\ref[src];ac_censor_channel_story_author=\ref[MESSAGE]'>[(MESSAGE.authorCensor) ? ("Undo Author Censorship") : ("Censor message Author")]</A></FONT><BR>"
|
||||
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]: <a href='?src=\ref[src];[HrefToken()];ac_lock_comment=\ref[MESSAGE]'>[MESSAGE.locked ? "Unlock" : "Lock"]</a><br>"
|
||||
for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
|
||||
dat+="[comment.body] <a href='?src=\ref[src];ac_del_comment=\ref[comment];ac_del_comment_msg=\ref[MESSAGE]'>X</a><br><font size=1>[comment.author] [comment.time_stamp]</font><br>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[10]'>Back</A>"
|
||||
dat+="[comment.body] <a href='?src=\ref[src];[HrefToken()];ac_del_comment=\ref[comment];ac_del_comment_msg=\ref[MESSAGE]'>X</a><br><font size=1>[comment.author] [comment.time_stamp]</font><br>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[10]'>Back</A>"
|
||||
if(13)
|
||||
dat+="<B>[src.admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[ created by: <FONT COLOR='maroon'>[src.admincaster_feed_channel.returnAuthor(-1)]</FONT> \]</FONT><BR>"
|
||||
dat+="Channel messages listed below. If you deem them dangerous to the station, you can <A href='?src=\ref[src];ac_toggle_d_notice=\ref[src.admincaster_feed_channel]'>Bestow a D-Notice upon the channel</A>.<HR>"
|
||||
dat+="Channel messages listed below. If you deem them dangerous to the station, you can <A href='?src=\ref[src];[HrefToken()];ac_toggle_d_notice=\ref[src.admincaster_feed_channel]'>Bestow a D-Notice upon the channel</A>.<HR>"
|
||||
if(src.admincaster_feed_channel.censored)
|
||||
dat+="<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.<BR>"
|
||||
dat+="No further feed story additions are allowed while the D-Notice is in effect.</FONT><BR><BR>"
|
||||
@@ -331,7 +329,7 @@
|
||||
else
|
||||
for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
|
||||
dat+="-[MESSAGE.returnBody(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.returnAuthor(-1)]</FONT>\]</FONT><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[11]'>Back</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[11]'>Back</A>"
|
||||
if(14)
|
||||
dat+="<B>Wanted Issue Handler:</B>"
|
||||
var/wanted_already = 0
|
||||
@@ -342,29 +340,29 @@
|
||||
if(wanted_already)
|
||||
dat+="<FONT SIZE=2><BR><I>A wanted issue is already in Feed Circulation. You can edit or cancel it below.</FONT></I>"
|
||||
dat+="<HR>"
|
||||
dat+="<A href='?src=\ref[src];ac_set_wanted_name=1'>Criminal Name</A>: [src.admincaster_wanted_message.criminal] <BR>"
|
||||
dat+="<A href='?src=\ref[src];ac_set_wanted_desc=1'>Description</A>: [src.admincaster_wanted_message.body] <BR>"
|
||||
dat+="<A href='?src=\ref[src];[HrefToken()];ac_set_wanted_name=1'>Criminal Name</A>: [src.admincaster_wanted_message.criminal] <BR>"
|
||||
dat+="<A href='?src=\ref[src];[HrefToken()];ac_set_wanted_desc=1'>Description</A>: [src.admincaster_wanted_message.body] <BR>"
|
||||
if(wanted_already)
|
||||
dat+="<B>Wanted Issue created by:</B><FONT COLOR='green'>[GLOB.news_network.wanted_issue.scannedUser]</FONT><BR>"
|
||||
else
|
||||
dat+="<B>Wanted Issue will be created under prosecutor:</B><FONT COLOR='green'>[src.admin_signature]</FONT><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_submit_wanted=[end_param]'>[(wanted_already) ? ("Edit Issue") : ("Submit")]</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_submit_wanted=[end_param]'>[(wanted_already) ? ("Edit Issue") : ("Submit")]</A>"
|
||||
if(wanted_already)
|
||||
dat+="<BR><A href='?src=\ref[src];ac_cancel_wanted=1'>Take down Issue</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Cancel</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_cancel_wanted=1'>Take down Issue</A>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Cancel</A>"
|
||||
if(15)
|
||||
dat+="<FONT COLOR='green'>Wanted issue for [src.admincaster_wanted_message.criminal] is now in Network Circulation.</FONT><BR><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Return</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
|
||||
if(16)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Wanted Issue rejected by Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_wanted_message.criminal =="" || src.admincaster_wanted_message.criminal == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid name for person wanted.</FONT><BR>"
|
||||
if(src.admincaster_wanted_message.body == "" || src.admincaster_wanted_message.body == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid description.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Return</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
|
||||
if(17)
|
||||
dat+="<B>Wanted Issue successfully deleted from Circulation</B><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Return</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
|
||||
if(18)
|
||||
dat+="<B><FONT COLOR ='maroon'>-- STATIONWIDE WANTED ISSUE --</B></FONT><BR><FONT SIZE=2>\[Submitted by: <FONT COLOR='green'>[GLOB.news_network.wanted_issue.scannedUser]</FONT>\]</FONT><HR>"
|
||||
dat+="<B>Criminal</B>: [GLOB.news_network.wanted_issue.criminal]<BR>"
|
||||
@@ -375,10 +373,10 @@
|
||||
dat+="<BR><img src='tmp_photow.png' width = '180'>"
|
||||
else
|
||||
dat+="None"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Back</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Back</A><BR>"
|
||||
if(19)
|
||||
dat+="<FONT COLOR='green'>Wanted issue for [src.admincaster_wanted_message.criminal] successfully edited.</FONT><BR><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Return</A><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
|
||||
else
|
||||
dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
|
||||
|
||||
@@ -394,21 +392,21 @@
|
||||
|
||||
var/dat = {"
|
||||
<center><B>Game Panel</B></center><hr>\n
|
||||
<A href='?src=\ref[src];c_mode=1'>Change Game Mode</A><br>
|
||||
<A href='?src=\ref[src];[HrefToken()];c_mode=1'>Change Game Mode</A><br>
|
||||
"}
|
||||
if(GLOB.master_mode == "secret")
|
||||
dat += "<A href='?src=\ref[src];f_secret=1'>(Force Secret Mode)</A><br>"
|
||||
dat += "<A href='?src=\ref[src];[HrefToken()];f_secret=1'>(Force Secret Mode)</A><br>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<A href='?src=\ref[src];create_object=1'>Create Object</A><br>
|
||||
<A href='?src=\ref[src];quick_create_object=1'>Quick Create Object</A><br>
|
||||
<A href='?src=\ref[src];create_turf=1'>Create Turf</A><br>
|
||||
<A href='?src=\ref[src];create_mob=1'>Create Mob</A><br>
|
||||
<A href='?src=\ref[src];[HrefToken()];create_object=1'>Create Object</A><br>
|
||||
<A href='?src=\ref[src];[HrefToken()];quick_create_object=1'>Quick Create Object</A><br>
|
||||
<A href='?src=\ref[src];[HrefToken()];create_turf=1'>Create Turf</A><br>
|
||||
<A href='?src=\ref[src];[HrefToken()];create_mob=1'>Create Mob</A><br>
|
||||
"}
|
||||
|
||||
if(marked_datum && istype(marked_datum, /atom))
|
||||
dat += "<A href='?src=\ref[src];dupe_marked_datum=1'>Duplicate Marked Datum</A><br>"
|
||||
dat += "<A href='?src=\ref[src];[HrefToken()];dupe_marked_datum=1'>Duplicate Marked Datum</A><br>"
|
||||
|
||||
usr << browse(dat, "window=admin2;size=210x200")
|
||||
return
|
||||
@@ -755,14 +753,14 @@
|
||||
dat += " (Cannot Late Join)<br>"
|
||||
continue
|
||||
if(job.total_positions >= 0)
|
||||
dat += " <A href='?src=\ref[src];addjobslot=[job.title]'>Add</A> | "
|
||||
dat += " <A href='?src=\ref[src];[HrefToken()];addjobslot=[job.title]'>Add</A> | "
|
||||
if(job.total_positions > job.current_positions)
|
||||
dat += "<A href='?src=\ref[src];removejobslot=[job.title]'>Remove</A> | "
|
||||
dat += "<A href='?src=\ref[src];[HrefToken()];removejobslot=[job.title]'>Remove</A> | "
|
||||
else
|
||||
dat += "Remove | "
|
||||
dat += "<A href='?src=\ref[src];unlimitjobslot=[job.title]'>Unlimit</A>"
|
||||
dat += "<A href='?src=\ref[src];[HrefToken()];unlimitjobslot=[job.title]'>Unlimit</A>"
|
||||
else
|
||||
dat += " <A href='?src=\ref[src];limitjobslot=[job.title]'>Limit</A>"
|
||||
dat += " <A href='?src=\ref[src];[HrefToken()];limitjobslot=[job.title]'>Limit</A>"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "</body>"
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
return 0
|
||||
|
||||
/proc/jobban_buildcache(client/C)
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
if(C && istype(C))
|
||||
C.jobbancache = list()
|
||||
var/datum/DBQuery/query_jobban_build_cache = SSdbcore.NewQuery("SELECT job, reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(C.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
|
||||
/datum/admins/proc/create_mob(mob/user)
|
||||
var/static/create_mob_html
|
||||
if (!create_mob_html)
|
||||
var/mobjs = null
|
||||
mobjs = jointext(typesof(/mob), ";")
|
||||
create_mob_html = file2text('html/create_object.html')
|
||||
create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")
|
||||
|
||||
user << browse(replacetext(create_mob_html, "/* ref src */", "\ref[src]"), "window=create_mob;size=425x475")
|
||||
|
||||
/proc/randomize_human(mob/living/carbon/human/H)
|
||||
H.gender = pick(MALE, FEMALE)
|
||||
H.real_name = random_unique_name(H.gender)
|
||||
H.name = H.real_name
|
||||
H.underwear = random_underwear(H.gender)
|
||||
H.skin_tone = random_skin_tone()
|
||||
H.hair_style = random_hair_style(H.gender)
|
||||
H.facial_hair_style = random_facial_hair_style(H.gender)
|
||||
H.hair_color = random_short_color()
|
||||
H.facial_hair_color = H.hair_color
|
||||
H.eye_color = random_eye_color()
|
||||
H.dna.blood_type = random_blood_type()
|
||||
H.update_body()
|
||||
H.update_hair()
|
||||
H.update_body_parts()
|
||||
/datum/admins/proc/create_mob(mob/user)
|
||||
var/static/create_mob_html
|
||||
if (!create_mob_html)
|
||||
var/mobjs = null
|
||||
mobjs = jointext(typesof(/mob), ";")
|
||||
create_mob_html = file2text('html/create_object.html')
|
||||
create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")
|
||||
|
||||
user << browse(replacetext(create_mob_html, "/* ref src */", "\ref[src];[HrefToken()]"), "window=create_mob;size=425x475")
|
||||
|
||||
/proc/randomize_human(mob/living/carbon/human/H)
|
||||
H.gender = pick(MALE, FEMALE)
|
||||
H.real_name = random_unique_name(H.gender)
|
||||
H.name = H.real_name
|
||||
H.underwear = random_underwear(H.gender)
|
||||
H.skin_tone = random_skin_tone()
|
||||
H.hair_style = random_hair_style(H.gender)
|
||||
H.facial_hair_style = random_facial_hair_style(H.gender)
|
||||
H.hair_color = random_short_color()
|
||||
H.facial_hair_color = H.hair_color
|
||||
H.eye_color = random_eye_color()
|
||||
H.dna.blood_type = random_blood_type()
|
||||
H.update_body()
|
||||
H.update_hair()
|
||||
H.update_body_parts()
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/datum/admins/proc/create_object(mob/user)
|
||||
var/static/create_object_html = null
|
||||
if (!create_object_html)
|
||||
var/objectjs = null
|
||||
objectjs = jointext(typesof(/obj), ";")
|
||||
create_object_html = file2text('html/create_object.html')
|
||||
create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
|
||||
|
||||
user << browse(replacetext(create_object_html, "/* ref src */", "\ref[src]"), "window=create_object;size=425x475")
|
||||
|
||||
/datum/admins/proc/quick_create_object(mob/user)
|
||||
var/static/list/create_object_forms = list(
|
||||
/obj, /obj/structure, /obj/machinery, /obj/effect,
|
||||
/obj/item, /obj/item/clothing, /obj/item/stack, /obj/item/device,
|
||||
/obj/item/weapon, /obj/item/reagent_containers, /obj/item/gun)
|
||||
|
||||
var/path = input("Select the path of the object you wish to create.", "Path", /obj) in create_object_forms
|
||||
var/html_form = create_object_forms[path]
|
||||
|
||||
if (!html_form)
|
||||
var/objectjs = jointext(typesof(path), ";")
|
||||
html_form = file2text('html/create_object.html')
|
||||
html_form = replacetext(html_form, "null /* object types */", "\"[objectjs]\"")
|
||||
create_object_forms[path] = html_form
|
||||
|
||||
user << browse(replacetext(html_form, "/* ref src */", "\ref[src]"), "window=qco[path];size=425x475")
|
||||
/datum/admins/proc/create_object(mob/user)
|
||||
var/static/create_object_html = null
|
||||
if (!create_object_html)
|
||||
var/objectjs = null
|
||||
objectjs = jointext(typesof(/obj), ";")
|
||||
create_object_html = file2text('html/create_object.html')
|
||||
create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
|
||||
|
||||
user << browse(replacetext(create_object_html, "/* ref src */", "\ref[src];[HrefToken()]"), "window=create_object;size=425x475")
|
||||
|
||||
/datum/admins/proc/quick_create_object(mob/user)
|
||||
var/static/list/create_object_forms = list(
|
||||
/obj, /obj/structure, /obj/machinery, /obj/effect,
|
||||
/obj/item, /obj/item/clothing, /obj/item/stack, /obj/item/device,
|
||||
/obj/item/reagent_containers, /obj/item/gun)
|
||||
|
||||
var/path = input("Select the path of the object you wish to create.", "Path", /obj) in create_object_forms
|
||||
var/html_form = create_object_forms[path]
|
||||
|
||||
if (!html_form)
|
||||
var/objectjs = jointext(typesof(path), ";")
|
||||
html_form = file2text('html/create_object.html')
|
||||
html_form = replacetext(html_form, "null /* object types */", "\"[objectjs]\"")
|
||||
create_object_forms[path] = html_form
|
||||
|
||||
user << browse(replacetext(html_form, "/* ref src */", "\ref[src];[HrefToken()]"), "window=qco[path];size=425x475")
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/datum/admins/proc/create_turf(mob/user)
|
||||
var/static/create_turf_html
|
||||
if (!create_turf_html)
|
||||
var/turfjs = null
|
||||
turfjs = jointext(typesof(/turf), ";")
|
||||
create_turf_html = file2text('html/create_object.html')
|
||||
create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")
|
||||
|
||||
user << browse(replacetext(create_turf_html, "/* ref src */", "\ref[src]"), "window=create_turf;size=425x475")
|
||||
/datum/admins/proc/create_turf(mob/user)
|
||||
var/static/create_turf_html
|
||||
if (!create_turf_html)
|
||||
var/turfjs = null
|
||||
turfjs = jointext(typesof(/turf), ";")
|
||||
create_turf_html = file2text('html/create_object.html')
|
||||
create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")
|
||||
|
||||
user << browse(replacetext(create_turf_html, "/* ref src */", "\ref[src];[HrefToken()]"), "window=create_turf;size=425x475")
|
||||
|
||||
+126
-105
@@ -1,105 +1,126 @@
|
||||
GLOBAL_LIST_EMPTY(admin_datums)
|
||||
GLOBAL_PROTECT(admin_datums)
|
||||
|
||||
/datum/admins
|
||||
var/datum/admin_rank/rank
|
||||
|
||||
var/client/owner = null
|
||||
var/fakekey = null
|
||||
|
||||
var/datum/marked_datum
|
||||
|
||||
var/spamcooldown = 0
|
||||
|
||||
var/admincaster_screen = 0 //TODO: remove all these 5 variables, they are completly unacceptable
|
||||
var/datum/newscaster/feed_message/admincaster_feed_message = new /datum/newscaster/feed_message
|
||||
var/datum/newscaster/wanted_message/admincaster_wanted_message = new /datum/newscaster/wanted_message
|
||||
var/datum/newscaster/feed_channel/admincaster_feed_channel = new /datum/newscaster/feed_channel
|
||||
var/admin_signature
|
||||
|
||||
/datum/admins/New(datum/admin_rank/R, ckey)
|
||||
if(!ckey)
|
||||
QDEL_IN(src, 0)
|
||||
throw EXCEPTION("Admin datum created without a ckey")
|
||||
return
|
||||
if(!istype(R))
|
||||
QDEL_IN(src, 0)
|
||||
throw EXCEPTION("Admin datum created without a rank")
|
||||
return
|
||||
rank = R
|
||||
admin_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
|
||||
GLOB.admin_datums[ckey] = src
|
||||
|
||||
/datum/admins/proc/associate(client/C)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = " has tried to elevate permissions!"
|
||||
message_admins("[key_name_admin(usr)][msg]")
|
||||
log_admin_private("[key_name(usr)][msg]")
|
||||
return
|
||||
if(istype(C))
|
||||
owner = C
|
||||
owner.holder = src
|
||||
owner.add_admin_verbs() //TODO
|
||||
owner.verbs -= /client/proc/readmin
|
||||
GLOB.admins |= C
|
||||
|
||||
/datum/admins/proc/disassociate()
|
||||
if(owner)
|
||||
GLOB.admins -= owner
|
||||
owner.remove_admin_verbs()
|
||||
owner.holder = null
|
||||
owner = null
|
||||
|
||||
/datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other)
|
||||
if(!other)
|
||||
return 1 //they have no rights
|
||||
if(rank.rights == 65535)
|
||||
return 1 //we have all the rights
|
||||
if(src == other)
|
||||
return 1 //you always have more rights than yourself
|
||||
if(rank.rights != other.rank.rights)
|
||||
if( (rank.rights & other.rank.rights) == other.rank.rights )
|
||||
return 1 //we have all the rights they have and more
|
||||
return 0
|
||||
|
||||
/datum/admins/vv_edit_var(var_name, var_value)
|
||||
return FALSE //nice try trialmin
|
||||
|
||||
/*
|
||||
checks if usr is an admin with at least ONE of the flags_1 in rights_required. (Note, they don't need all the flags_1)
|
||||
if rights_required == 0, then it simply checks if they are an admin.
|
||||
if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
|
||||
generally it would be used like so:
|
||||
|
||||
/proc/admin_proc()
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
to_chat(world, "you have enough rights!")
|
||||
|
||||
NOTE: it checks usr! not src! So if you're checking somebody's rank in a proc which they did not call
|
||||
you will have to do something like if(client.rights & R_ADMIN) yourself.
|
||||
*/
|
||||
/proc/check_rights(rights_required, show_msg=1)
|
||||
if(usr && usr.client)
|
||||
if (check_rights_for(usr.client, rights_required))
|
||||
return 1
|
||||
else
|
||||
if(show_msg)
|
||||
to_chat(usr, "<font color='red'>Error: You do not have sufficient rights to do that. You require one of the following flags_1:[rights2text(rights_required," ")].</font>")
|
||||
return 0
|
||||
|
||||
//probably a bit iffy - will hopefully figure out a better solution
|
||||
/proc/check_if_greater_rights_than(client/other)
|
||||
if(usr && usr.client)
|
||||
if(usr.client.holder)
|
||||
if(!other || !other.holder)
|
||||
return 1
|
||||
return usr.client.holder.check_if_greater_rights_than_holder(other.holder)
|
||||
return 0
|
||||
|
||||
//This proc checks whether subject has at least ONE of the rights specified in rights_required.
|
||||
/proc/check_rights_for(client/subject, rights_required)
|
||||
if(subject && subject.holder && subject.holder.rank)
|
||||
if(rights_required && !(rights_required & subject.holder.rank.rights))
|
||||
return 0
|
||||
return 1
|
||||
return 0
|
||||
GLOBAL_LIST_EMPTY(admin_datums)
|
||||
GLOBAL_PROTECT(admin_datums)
|
||||
|
||||
GLOBAL_VAR_INIT(href_token, GenerateToken())
|
||||
GLOBAL_PROTECT(href_token)
|
||||
|
||||
/datum/admins
|
||||
var/datum/admin_rank/rank
|
||||
|
||||
var/client/owner = null
|
||||
var/fakekey = null
|
||||
|
||||
var/datum/marked_datum
|
||||
|
||||
var/spamcooldown = 0
|
||||
|
||||
var/admincaster_screen = 0 //TODO: remove all these 5 variables, they are completly unacceptable
|
||||
var/datum/newscaster/feed_message/admincaster_feed_message = new /datum/newscaster/feed_message
|
||||
var/datum/newscaster/wanted_message/admincaster_wanted_message = new /datum/newscaster/wanted_message
|
||||
var/datum/newscaster/feed_channel/admincaster_feed_channel = new /datum/newscaster/feed_channel
|
||||
var/admin_signature
|
||||
var/href_token
|
||||
|
||||
/datum/admins/New(datum/admin_rank/R, ckey)
|
||||
if(!ckey)
|
||||
QDEL_IN(src, 0)
|
||||
throw EXCEPTION("Admin datum created without a ckey")
|
||||
return
|
||||
if(!istype(R))
|
||||
QDEL_IN(src, 0)
|
||||
throw EXCEPTION("Admin datum created without a rank")
|
||||
return
|
||||
rank = R
|
||||
admin_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
|
||||
href_token = GenerateToken()
|
||||
GLOB.admin_datums[ckey] = src
|
||||
|
||||
/proc/GenerateToken()
|
||||
. = ""
|
||||
for(var/I in 1 to 32)
|
||||
. += "[rand(10)]"
|
||||
|
||||
/proc/HrefToken(forceGlobal = FALSE)
|
||||
var/tok = GLOB.href_token
|
||||
if(!forceGlobal && usr)
|
||||
var/client/C = usr.client
|
||||
if(!C)
|
||||
CRASH("No client for HrefToken()!")
|
||||
var/datum/admins/holder = C.holder
|
||||
if(holder)
|
||||
tok = holder.href_token
|
||||
return "admin_token=[tok]"
|
||||
|
||||
/datum/admins/proc/associate(client/C)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = " has tried to elevate permissions!"
|
||||
message_admins("[key_name_admin(usr)][msg]")
|
||||
log_admin_private("[key_name(usr)][msg]")
|
||||
return
|
||||
if(istype(C))
|
||||
owner = C
|
||||
owner.holder = src
|
||||
owner.add_admin_verbs() //TODO
|
||||
owner.verbs -= /client/proc/readmin
|
||||
GLOB.admins |= C
|
||||
|
||||
/datum/admins/proc/disassociate()
|
||||
if(owner)
|
||||
GLOB.admins -= owner
|
||||
owner.remove_admin_verbs()
|
||||
owner.holder = null
|
||||
owner = null
|
||||
|
||||
/datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other)
|
||||
if(!other)
|
||||
return 1 //they have no rights
|
||||
if(rank.rights == 65535)
|
||||
return 1 //we have all the rights
|
||||
if(src == other)
|
||||
return 1 //you always have more rights than yourself
|
||||
if(rank.rights != other.rank.rights)
|
||||
if( (rank.rights & other.rank.rights) == other.rank.rights )
|
||||
return 1 //we have all the rights they have and more
|
||||
return 0
|
||||
|
||||
/datum/admins/vv_edit_var(var_name, var_value)
|
||||
return FALSE //nice try trialmin
|
||||
|
||||
/*
|
||||
checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags)
|
||||
if rights_required == 0, then it simply checks if they are an admin.
|
||||
if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
|
||||
generally it would be used like so:
|
||||
|
||||
/proc/admin_proc()
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
to_chat(world, "you have enough rights!")
|
||||
|
||||
NOTE: it checks usr! not src! So if you're checking somebody's rank in a proc which they did not call
|
||||
you will have to do something like if(client.rights & R_ADMIN) yourself.
|
||||
*/
|
||||
/proc/check_rights(rights_required, show_msg=1)
|
||||
if(usr && usr.client)
|
||||
if (check_rights_for(usr.client, rights_required))
|
||||
return 1
|
||||
else
|
||||
if(show_msg)
|
||||
to_chat(usr, "<font color='red'>Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")].</font>")
|
||||
return 0
|
||||
|
||||
//probably a bit iffy - will hopefully figure out a better solution
|
||||
/proc/check_if_greater_rights_than(client/other)
|
||||
if(usr && usr.client)
|
||||
if(usr.client.holder)
|
||||
if(!other || !other.holder)
|
||||
return 1
|
||||
return usr.client.holder.check_if_greater_rights_than_holder(other.holder)
|
||||
return 0
|
||||
|
||||
//This proc checks whether subject has at least ONE of the rights specified in rights_required.
|
||||
/proc/check_rights_for(client/subject, rights_required)
|
||||
if(subject && subject.holder && subject.holder.rank)
|
||||
if(rights_required && !(rights_required & subject.holder.rank.rights))
|
||||
return 0
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<body onload='selectTextField();updateSearch();'>
|
||||
<div id='main'><table id='searchable' cellspacing='0'>
|
||||
<tr class='title'>
|
||||
<th style='width:125px;text-align:right;'>CKEY <a class='small' href='?src=\ref[src];editrights=add'>\[+\]</a></th>
|
||||
<th style='width:125px;text-align:right;'>CKEY <a class='small' href='?src=\ref[src];[HrefToken()];editrights=add'>\[+\]</a></th>
|
||||
<th style='width:125px;'>RANK</th>
|
||||
<th style='width:375px;'>PERMISSIONS</th>
|
||||
<th style='width:100%;'>VERB-OVERRIDES</th>
|
||||
@@ -36,10 +36,10 @@
|
||||
if(!rights) rights = "*none*"
|
||||
|
||||
output += "<tr>"
|
||||
output += "<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=\ref[src];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>"
|
||||
output += "<td><a href='?src=\ref[src];editrights=rank;ckey=[adm_ckey]'>[D.rank.name]</a></td>"
|
||||
output += "<td><a class='small' href='?src=\ref[src];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></td>"
|
||||
output += "<td><a class='small' href='?src=\ref[src];editrights=permissions;ckey=[adm_ckey]'>[rights2text(0," ",D.rank.adds,D.rank.subs)]</a></td>"
|
||||
output += "<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=\ref[src];[HrefToken()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>"
|
||||
output += "<td><a href='?src=\ref[src];[HrefToken()];editrights=rank;ckey=[adm_ckey]'>[D.rank.name]</a></td>"
|
||||
output += "<td><a class='small' href='?src=\ref[src];[HrefToken()];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></td>"
|
||||
output += "<td><a class='small' href='?src=\ref[src];[HrefToken()];editrights=permissions;ckey=[adm_ckey]'>[rights2text(0," ",D.rank.adds,D.rank.subs)]</a></td>"
|
||||
output += "</tr>"
|
||||
|
||||
output += {"
|
||||
|
||||
@@ -75,16 +75,16 @@
|
||||
|
||||
body += "</td><td align='center'>";
|
||||
|
||||
body += "<a href='?_src_=holder;adminplayeropts="+ref+"'>PP</a> - "
|
||||
body += "<a href='?_src_=holder;showmessageckey="+ckey+"'>N</a> - "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];adminplayeropts="+ref+"'>PP</a> - "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];showmessageckey="+ckey+"'>N</a> - "
|
||||
body += "<a href='?_src_=vars;Vars="+ref+"'>VV</a> - "
|
||||
body += "<a href='?_src_=holder;traitor="+ref+"'>TP</a> - "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];traitor="+ref+"'>TP</a> - "
|
||||
body += "<a href='?priv_msg="+ckey+"'>PM</a> - "
|
||||
body += "<a href='?_src_=holder;subtlemessage="+ref+"'>SM</a> - "
|
||||
body += "<a href='?_src_=holder;adminplayerobservefollow="+ref+"'>FLW</a> - "
|
||||
body += "<a href='?_src_=holder;individuallog="+ref+"'>LOGS</a><br>"
|
||||
body += "<a href='?_src_=holder;[HrefToken()];subtlemessage="+ref+"'>SM</a> - "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];adminplayerobservefollow="+ref+"'>FLW</a> - "
|
||||
body += "<a href='?_src_=holder;[HrefToken()];individuallog="+ref+"'>LOGS</a><br>"
|
||||
if(antagonist > 0)
|
||||
body += "<font size='2'><a href='?_src_=holder;secrets=check_antagonist'><font color='red'><b>Antagonist</b></font></a></font>";
|
||||
body += "<font size='2'><a href='?_src_=holder;[HrefToken()];secrets=check_antagonist'><font color='red'><b>Antagonist</b></font></a></font>";
|
||||
|
||||
body += "</td></tr></table>";
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
<tr id='title_tr'>
|
||||
<td align='center'>
|
||||
<font size='5'><b>Player panel</b></font><br>
|
||||
Hover over a line to see more information - <a href='?_src_=holder;check_antagonist=1'>Check antagonists</a> - Kick <a href='?_src_=holder;kick_all_from_lobby=1;afkonly=0'>everyone</a>/<a href='?_src_=holder;kick_all_from_lobby=1;afkonly=1'>AFKers</a> in lobby
|
||||
Hover over a line to see more information - <a href='?_src_=holder;[HrefToken()];check_antagonist=1'>Check antagonists</a> - Kick <a href='?_src_=holder;[HrefToken()];kick_all_from_lobby=1;afkonly=0'>everyone</a>/<a href='?_src_=holder;[HrefToken()];kick_all_from_lobby=1;afkonly=1'>AFKers</a> in lobby
|
||||
<p>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -320,26 +320,26 @@
|
||||
dat += "Round Duration: <B>[round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B><BR>"
|
||||
dat += "<B>Emergency shuttle</B><BR>"
|
||||
if(EMERGENCY_IDLE_OR_RECALLED)
|
||||
dat += "<a href='?_src_=holder;call_shuttle=1'>Call Shuttle</a><br>"
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];call_shuttle=1'>Call Shuttle</a><br>"
|
||||
else
|
||||
var/timeleft = SSshuttle.emergency.timeLeft()
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
|
||||
dat += "ETA: <a href='?_src_=holder;edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
|
||||
dat += "<a href='?_src_=holder;call_shuttle=2'>Send Back</a><br>"
|
||||
dat += "ETA: <a href='?_src_=holder;[HrefToken()];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];call_shuttle=2'>Send Back</a><br>"
|
||||
else
|
||||
dat += "ETA: <a href='?_src_=holder;edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
|
||||
dat += "ETA: <a href='?_src_=holder;[HrefToken()];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
|
||||
dat += "<B>Continuous Round Status</B><BR>"
|
||||
dat += "<a href='?_src_=holder;toggle_continuous=1'>[config.continuous[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]</a>"
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];toggle_continuous=1'>[config.continuous[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]</a>"
|
||||
if(config.continuous[SSticker.mode.config_tag])
|
||||
dat += ", <a href='?_src_=holder;toggle_midround_antag=1'>[config.midround_antag[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]</a><BR>"
|
||||
dat += ", <a href='?_src_=holder;[HrefToken()];toggle_midround_antag=1'>[config.midround_antag[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]</a><BR>"
|
||||
else
|
||||
dat += "<BR>"
|
||||
if(config.midround_antag[SSticker.mode.config_tag])
|
||||
dat += "Time limit: <a href='?_src_=holder;alter_midround_time_limit=1'>[config.midround_antag_time_check] minutes into round</a><BR>"
|
||||
dat += "Living crew limit: <a href='?_src_=holder;alter_midround_life_limit=1'>[config.midround_antag_life_check * 100]% of crew alive</a><BR>"
|
||||
dat += "If limits past: <a href='?_src_=holder;toggle_noncontinuous_behavior=1'>[SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]</a><BR>"
|
||||
dat += "<a href='?_src_=holder;end_round=\ref[usr]'>End Round Now</a><br>"
|
||||
dat += "<a href='?_src_=holder;delay_round_end=1'>[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]</a>"
|
||||
dat += "Time limit: <a href='?_src_=holder;[HrefToken()];alter_midround_time_limit=1'>[config.midround_antag_time_check] minutes into round</a><BR>"
|
||||
dat += "Living crew limit: <a href='?_src_=holder;[HrefToken()];alter_midround_life_limit=1'>[config.midround_antag_life_check * 100]% of crew alive</a><BR>"
|
||||
dat += "If limits past: <a href='?_src_=holder;[HrefToken()];toggle_noncontinuous_behavior=1'>[SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]</a><BR>"
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];end_round=\ref[usr]'>End Round Now</a><br>"
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];delay_round_end=1'>[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]</a>"
|
||||
var/connected_players = GLOB.clients.len
|
||||
var/lobby_players = 0
|
||||
var/observers = 0
|
||||
@@ -389,11 +389,11 @@
|
||||
for(var/datum/mind/N in SSticker.mode.syndicates)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><i><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a> Nuclear Operative Body destroyed!</i></td>"
|
||||
dat += "<tr><td><i><a href='?_src_=vars;[HrefToken()];Vars=\ref[N]'>[N.name]([N.key])</a> Nuclear Operative Body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||
dat += "</table><br><table><tr><td><B>Nuclear Disk(s)</B></td></tr>"
|
||||
for(var/obj/item/disk/nuclear/N in GLOB.poi_list)
|
||||
@@ -402,7 +402,7 @@
|
||||
while(!isturf(disk_loc))
|
||||
if(ismob(disk_loc))
|
||||
var/mob/M = disk_loc
|
||||
dat += "carried by <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> "
|
||||
dat += "carried by <a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a> "
|
||||
if(isobj(disk_loc))
|
||||
var/obj/O = disk_loc
|
||||
dat += "in \a [O.name] "
|
||||
@@ -415,29 +415,29 @@
|
||||
for(var/datum/mind/N in SSticker.mode.head_revolutionaries)
|
||||
var/mob/M = N.current
|
||||
if(!M)
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Head Revolutionary body destroyed!</i></td>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[N]'>[N.name]([N.key])</a><i>Head Revolutionary body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
for(var/datum/mind/N in SSticker.mode.revolutionaries)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
|
||||
for(var/datum/mind/N in SSticker.mode.get_living_heads())
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
var/turf/mob_loc = get_turf(M)
|
||||
dat += "<td>[mob_loc.loc]</td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Head body destroyed!</i></td>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[N]'>[N.name]([N.key])</a><i>Head body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -464,12 +464,12 @@
|
||||
for(var/datum/mind/changeling in SSticker.mode.changelings)
|
||||
var/mob/M = changeling.current
|
||||
if(M)
|
||||
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[changeling]'>[changeling.name]([changeling.key])</a><i>Changeling body destroyed!</i></td>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[changeling]'>[changeling.name]([changeling.key])</a><i>Changeling body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[changeling.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -478,12 +478,12 @@
|
||||
for(var/datum/mind/wizard in SSticker.mode.wizards)
|
||||
var/mob/M = wizard.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[wizard]'>[wizard.name]([wizard.key])</a><i>Wizard body destroyed!</i></td></tr>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[wizard]'>[wizard.name]([wizard.key])</a><i>Wizard body destroyed!</i></td></tr>"
|
||||
dat += "<td><A href='?priv_msg=[wizard.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -492,12 +492,12 @@
|
||||
for(var/datum/mind/apprentice in SSticker.mode.apprentices)
|
||||
var/mob/M = apprentice.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[apprentice]'>[apprentice.name]([apprentice.key])</a><i>Apprentice body destroyed!!</i></td></tr>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[apprentice]'>[apprentice.name]([apprentice.key])</a><i>Apprentice body destroyed!!</i></td></tr>"
|
||||
dat += "<td><A href='?priv_msg=[apprentice.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -506,9 +506,9 @@
|
||||
for(var/datum/mind/N in SSticker.mode.cult)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[N.has_antag_datum(ANTAG_DATUM_CULT_MASTER) ? "<i><font color=red> \[Master\]</font></i>" : ""][M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[N.has_antag_datum(ANTAG_DATUM_CULT_MASTER) ? "<i><font color=red> \[Master\]</font></i>" : ""][M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
if(SSticker.mode.servants_of_ratvar.len)
|
||||
@@ -516,9 +516,9 @@
|
||||
for(var/datum/mind/N in SSticker.mode.servants_of_ratvar)
|
||||
var/mob/M = N.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
if(SSticker.mode.traitors.len > 0)
|
||||
@@ -526,12 +526,12 @@
|
||||
for(var/datum/mind/traitor in SSticker.mode.traitors)
|
||||
var/mob/M = traitor.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[traitor]'>[traitor.name]([traitor.key])</a><i>Traitor body destroyed!</i></td>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[traitor]'>[traitor.name]([traitor.key])</a><i>Traitor body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[traitor.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -540,12 +540,12 @@
|
||||
for(var/datum/mind/abductor in SSticker.mode.abductors)
|
||||
var/mob/M = abductor.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[abductor]'>[abductor.name]([abductor.key])</a><i>Abductor body destroyed!</i></td></tr>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[abductor]'>[abductor.name]([abductor.key])</a><i>Abductor body destroyed!</i></td></tr>"
|
||||
dat += "<td><A href='?priv_msg=[abductor.key]'>PM</A></td>"
|
||||
dat += "</table>"
|
||||
dat += "<br><table cellspacing=5><tr><td><B>Abductees</B></td><td></td><td></td></tr>"
|
||||
@@ -553,12 +553,12 @@
|
||||
for(var/datum/mind/abductee in E.abductee_minds)
|
||||
var/mob/M = abductee.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder[HrefToken()];;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[abductee]'>[abductee.name]([abductee.key])</a><i>Abductee body destroyed!</i></td>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[abductee]'>[abductee.name]([abductee.key])</a><i>Abductee body destroyed!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[abductee.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -569,12 +569,12 @@
|
||||
var/mob/M = devil.current
|
||||
var/datum/antagonist/devil/devilinfo = devil.has_antag_datum(ANTAG_DATUM_DEVIL)
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devilinfo.truename]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name] : [devilinfo.truename]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A HREF='?_src_=holder;admincheckdevilinfo=\ref[M]'>Show all devil info</A></td></tr>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];admincheckdevilinfo=\ref[M]'>Show all devil info</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[devil]'>[devil.name] : [devilinfo.truename] ([devil.key])</a><i>devil body destroyed!</i></td></tr>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[devil]'>[devil.name] : [devilinfo.truename] ([devil.key])</a><i>devil body destroyed!</i></td></tr>"
|
||||
dat += "<td><A href='?priv_msg=[devil.key]'>PM</A></td>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -584,11 +584,11 @@
|
||||
var/datum/mind/sintouched = X
|
||||
var/mob/M = sintouched.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
dat += "<td><A HREF='?_src_=holder;[HrefToken()];traitor=\ref[M]'>Show Objective</A></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[sintouched]'>[sintouched.name]([sintouched.key])</a><i>sintouched body destroyed!</i></td></tr>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[sintouched]'>[sintouched.name]([sintouched.key])</a><i>sintouched body destroyed!</i></td></tr>"
|
||||
dat += "<td><A href='?priv_msg=[sintouched.key]'>PM</A></td>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -606,11 +606,11 @@
|
||||
for(var/datum/mind/blob in blob_minds)
|
||||
var/mob/M = blob.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[blob]'>[blob.name]([blob.key])</a><i>Blob not found!</i></td>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[blob]'>[blob.name]([blob.key])</a><i>Blob not found!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[blob.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
@@ -622,11 +622,11 @@
|
||||
for(var/datum/mind/eek in mode.ape_infectees)
|
||||
var/mob/M = eek.current
|
||||
if(M)
|
||||
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
|
||||
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
|
||||
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[eek]'>[eek.name]([eek.key])</a><i>Monkey not found!</i></td>"
|
||||
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[eek]'>[eek.name]([eek.key])</a><i>Monkey not found!</i></td>"
|
||||
dat += "<td><A href='?priv_msg=[eek.key]'>PM</A></td></tr>"
|
||||
dat += "</table>"
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
dat +={"
|
||||
<B>General Secrets</B><BR>
|
||||
<BR>
|
||||
<A href='?src=\ref[src];secrets=list_job_debug'>Show Job Debug</A><BR>
|
||||
<A href='?src=\ref[src];secrets=admin_log'>Admin Log</A><BR>
|
||||
<A href='?src=\ref[src];secrets=show_admins'>Show Admin List</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=list_job_debug'>Show Job Debug</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=admin_log'>Admin Log</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=show_admins'>Show Admin List</A><BR>
|
||||
<BR>
|
||||
"}
|
||||
|
||||
@@ -17,27 +17,27 @@
|
||||
dat += {"
|
||||
<B>Admin Secrets</B><BR>
|
||||
<BR>
|
||||
<A href='?src=\ref[src];secrets=clear_virus'>Cure all diseases currently in existence</A><BR>
|
||||
<A href='?src=\ref[src];secrets=list_bombers'>Bombing List</A><BR>
|
||||
<A href='?src=\ref[src];secrets=check_antagonist'>Show current traitors and objectives</A><BR>
|
||||
<A href='?src=\ref[src];secrets=list_signalers'>Show last [length(GLOB.lastsignalers)] signalers</A><BR>
|
||||
<A href='?src=\ref[src];secrets=list_lawchanges'>Show last [length(GLOB.lawchanges)] law changes</A><BR>
|
||||
<A href='?src=\ref[src];secrets=showailaws'>Show AI Laws</A><BR>
|
||||
<A href='?src=\ref[src];secrets=showgm'>Show Game Mode</A><BR>
|
||||
<A href='?src=\ref[src];secrets=manifest'>Show Crew Manifest</A><BR>
|
||||
<A href='?src=\ref[src];secrets=DNA'>List DNA (Blood)</A><BR>
|
||||
<A href='?src=\ref[src];secrets=fingerprints'>List Fingerprints</A><BR>
|
||||
<A href='?src=\ref[src];secrets=ctfbutton'>Enable/Disable CTF</A><BR><BR>
|
||||
<A href='?src=\ref[src];secrets=tdomereset'>Reset Thunderdome to default state</A><BR>
|
||||
<A href='?src=\ref[src];secrets=set_name'>Rename Station Name</A><BR>
|
||||
<A href='?src=\ref[src];secrets=reset_name'>Reset Station Name</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=clear_virus'>Cure all diseases currently in existence</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=list_bombers'>Bombing List</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=check_antagonist'>Show current traitors and objectives</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=list_signalers'>Show last [length(GLOB.lastsignalers)] signalers</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=list_lawchanges'>Show last [length(GLOB.lawchanges)] law changes</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=showailaws'>Show AI Laws</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=showgm'>Show Game Mode</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=manifest'>Show Crew Manifest</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=DNA'>List DNA (Blood)</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=fingerprints'>List Fingerprints</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=ctfbutton'>Enable/Disable CTF</A><BR><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=tdomereset'>Reset Thunderdome to default state</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=set_name'>Rename Station Name</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=reset_name'>Reset Station Name</A><BR>
|
||||
<BR>
|
||||
<B>Shuttles</B><BR>
|
||||
<BR>
|
||||
<A href='?src=\ref[src];secrets=moveferry'>Move Ferry</A><BR>
|
||||
<A href='?src=\ref[src];secrets=togglearrivals'>Toggle Arrivals Ferry</A><BR>
|
||||
<A href='?src=\ref[src];secrets=moveminingshuttle'>Move Mining Shuttle</A><BR>
|
||||
<A href='?src=\ref[src];secrets=movelaborshuttle'>Move Labor Shuttle</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=moveferry'>Move Ferry</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=togglearrivals'>Toggle Arrivals Ferry</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=moveminingshuttle'>Move Mining Shuttle</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=movelaborshuttle'>Move Labor Shuttle</A><BR>
|
||||
<BR>
|
||||
"}
|
||||
|
||||
@@ -45,31 +45,33 @@
|
||||
dat += {"
|
||||
<B>Fun Secrets</B><BR>
|
||||
<BR>
|
||||
<<<<<<< HEAD
|
||||
|
||||
<A href='?src=\ref[src];secrets=virus'>Trigger a Virus Outbreak</A><BR>
|
||||
<A href='?src=\ref[src];secrets=monkey'>Turn all humans into monkeys</A><BR>
|
||||
<A href='?src=\ref[src];secrets=anime'>Chinese Cartoons</A><BR>
|
||||
<A href='?src=\ref[src];secrets=allspecies'>Change the species of all humans</A><BR>
|
||||
<A href='?src=\ref[src];secrets=power'>Make all areas powered</A><BR>
|
||||
<A href='?src=\ref[src];secrets=unpower'>Make all areas unpowered</A><BR>
|
||||
<A href='?src=\ref[src];secrets=quickpower'>Power all SMES</A><BR>
|
||||
<A href='?src=\ref[src];secrets=tripleAI'>Triple AI mode (needs to be used in the lobby)</A><BR>
|
||||
<A href='?src=\ref[src];secrets=traitor_all'>Everyone is the traitor</A><BR>
|
||||
<A href='?src=\ref[src];secrets=guns'>Summon Guns</A><BR>
|
||||
<A href='?src=\ref[src];secrets=magic'>Summon Magic</A><BR>
|
||||
<A href='?src=\ref[src];secrets=events'>Summon Events (Toggle)</A><BR>
|
||||
<A href='?src=\ref[src];secrets=onlyone'>There can only be one!</A><BR>
|
||||
<A href='?src=\ref[src];secrets=delayed_onlyone'>There can only be one! (40-second delay)</A><BR>
|
||||
<A href='?src=\ref[src];secrets=onlyme'>There can only be me!</A><BR>
|
||||
<A href='?src=\ref[src];secrets=retardify'>Make all players retarded</A><BR>
|
||||
<A href='?src=\ref[src];secrets=eagles'>Egalitarian Station Mode</A><BR>
|
||||
<A href='?src=\ref[src];secrets=blackout'>Break all lights</A><BR>
|
||||
<A href='?src=\ref[src];secrets=whiteout'>Fix all lights</A><BR>
|
||||
<A href='?src=\ref[src];secrets=floorlava'>The floor is lava! (DANGEROUS: extremely lame)</A><BR>
|
||||
=======
|
||||
>>>>>>> 6e5ebf9c41fc97d5ee0daf4fd22536844438ace0
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=virus'>Trigger a Virus Outbreak</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=monkey'>Turn all humans into monkeys</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=anime'>Chinese Cartoons</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=allspecies'>Change the species of all humans</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=power'>Make all areas powered</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=unpower'>Make all areas unpowered</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=quickpower'>Power all SMES</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=tripleAI'>Triple AI mode (needs to be used in the lobby)</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=traitor_all'>Everyone is the traitor</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=guns'>Summon Guns</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=magic'>Summon Magic</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=events'>Summon Events (Toggle)</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=onlyone'>There can only be one!</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=delayed_onlyone'>There can only be one! (40-second delay)</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=retardify'>Make all players retarded</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=eagles'>Egalitarian Station Mode</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=blackout'>Break all lights</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=whiteout'>Fix all lights</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=floorlava'>The floor is lava! (DANGEROUS: extremely lame)</A><BR>
|
||||
<BR>
|
||||
<A href='?src=\ref[src];secrets=changebombcap'>Change bomb cap</A><BR>
|
||||
<A href='?src=\ref[src];secrets=masspurrbation'>Mass Purrbation</A><BR>
|
||||
<A href='?src=\ref[src];secrets=massremovepurrbation'>Mass Remove Purrbation</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=changebombcap'>Change bomb cap</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=masspurrbation'>Mass Purrbation</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=massremovepurrbation'>Mass Remove Purrbation</A><BR>
|
||||
"}
|
||||
|
||||
dat += "<BR>"
|
||||
@@ -78,9 +80,9 @@
|
||||
dat += {"
|
||||
<B>Security Level Elevated</B><BR>
|
||||
<BR>
|
||||
<A href='?src=\ref[src];secrets=maint_access_engiebrig'>Change all maintenance doors to engie/brig access only</A><BR>
|
||||
<A href='?src=\ref[src];secrets=maint_access_brig'>Change all maintenance doors to brig access only</A><BR>
|
||||
<A href='?src=\ref[src];secrets=infinite_sec'>Remove cap on security officers</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=maint_access_engiebrig'>Change all maintenance doors to engie/brig access only</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=maint_access_brig'>Change all maintenance doors to brig access only</A><BR>
|
||||
<A href='?src=\ref[src];[HrefToken()];secrets=infinite_sec'>Remove cap on security officers</A><BR>
|
||||
<BR>
|
||||
"}
|
||||
|
||||
@@ -526,12 +528,6 @@
|
||||
usr.client.only_one_delayed()
|
||||
sound_to_playing_players('sound/misc/highlander_delayed.ogg')
|
||||
|
||||
if("onlyme")
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
SSblackbox.add_details("admin_secrets_fun_used","There Can Be Only Me")
|
||||
only_me()
|
||||
|
||||
if("maint_access_brig")
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
if(browse)
|
||||
browse_messages("[type]")
|
||||
else
|
||||
browse_messages(target_ckey = target_ckey)
|
||||
browse_messages(target_ckey = target_ckey, agegate = TRUE)
|
||||
|
||||
/proc/delete_message(message_id, logged = 1, browse)
|
||||
if(!SSdbcore.Connect())
|
||||
@@ -68,14 +68,14 @@
|
||||
var/type
|
||||
var/target_ckey
|
||||
var/text
|
||||
var/datum/DBQuery/query_find_del_message = SSdbcore.NewQuery("SELECT type, targetckey, adminckey, text FROM [format_table_name("messages")] WHERE id = [message_id]")
|
||||
var/datum/DBQuery/query_find_del_message = SSdbcore.NewQuery("SELECT type, targetckey, adminckey, text FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
|
||||
if(!query_find_del_message.warn_execute())
|
||||
return
|
||||
if(query_find_del_message.NextRow())
|
||||
type = query_find_del_message.item[1]
|
||||
target_ckey = query_find_del_message.item[2]
|
||||
text = query_find_del_message.item[4]
|
||||
var/datum/DBQuery/query_del_message = SSdbcore.NewQuery("DELETE FROM [format_table_name("messages")] WHERE id = [message_id]")
|
||||
var/datum/DBQuery/query_del_message = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET deleted = 1 WHERE id = [message_id]")
|
||||
if(!query_del_message.warn_execute())
|
||||
return
|
||||
if(logged)
|
||||
@@ -84,7 +84,7 @@
|
||||
if(browse)
|
||||
browse_messages("[type]")
|
||||
else
|
||||
browse_messages(target_ckey = target_ckey)
|
||||
browse_messages(target_ckey = target_ckey, agegate = TRUE)
|
||||
|
||||
/proc/edit_message(message_id, browse)
|
||||
if(!SSdbcore.Connect())
|
||||
@@ -93,7 +93,7 @@
|
||||
message_id = text2num(message_id)
|
||||
if(!message_id)
|
||||
return
|
||||
var/datum/DBQuery/query_find_edit_message = SSdbcore.NewQuery("SELECT type, targetckey, adminckey, text FROM [format_table_name("messages")] WHERE id = [message_id]")
|
||||
var/datum/DBQuery/query_find_edit_message = SSdbcore.NewQuery("SELECT type, targetckey, adminckey, text FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
|
||||
if(!query_find_edit_message.warn_execute())
|
||||
return
|
||||
if(query_find_edit_message.NextRow())
|
||||
@@ -107,7 +107,7 @@
|
||||
return
|
||||
new_text = sanitizeSQL(new_text)
|
||||
var/edit_text = sanitizeSQL("Edited by [editor_ckey] on [SQLtime()] from<br>[old_text]<br>to<br>[new_text]<hr>")
|
||||
var/datum/DBQuery/query_edit_message = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET text = '[new_text]', lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id]")
|
||||
var/datum/DBQuery/query_edit_message = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET text = '[new_text]', lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id] AND deleted = 0")
|
||||
if(!query_edit_message.warn_execute())
|
||||
return
|
||||
log_admin_private("[key_name(usr)] has edited a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""] made by [admin_ckey] from [old_text] to [new_text]")
|
||||
@@ -115,7 +115,7 @@
|
||||
if(browse)
|
||||
browse_messages("[type]")
|
||||
else
|
||||
browse_messages(target_ckey = target_ckey)
|
||||
browse_messages(target_ckey = target_ckey, agegate = TRUE)
|
||||
|
||||
/proc/toggle_message_secrecy(message_id)
|
||||
if(!SSdbcore.Connect())
|
||||
@@ -124,7 +124,7 @@
|
||||
message_id = text2num(message_id)
|
||||
if(!message_id)
|
||||
return
|
||||
var/datum/DBQuery/query_find_message_secret = SSdbcore.NewQuery("SELECT type, targetckey, adminckey, secret FROM [format_table_name("messages")] WHERE id = [message_id]")
|
||||
var/datum/DBQuery/query_find_message_secret = SSdbcore.NewQuery("SELECT type, targetckey, adminckey, secret FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
|
||||
if(!query_find_message_secret.warn_execute())
|
||||
return
|
||||
if(query_find_message_secret.NextRow())
|
||||
@@ -139,18 +139,18 @@
|
||||
return
|
||||
log_admin_private("[key_name(usr)] has toggled [target_ckey]'s [type] made by [admin_ckey] to [secret ? "not secret" : "secret"]")
|
||||
message_admins("[key_name_admin(usr)] has toggled [target_ckey]'s [type] made by [admin_ckey] to [secret ? "not secret" : "secret"]")
|
||||
browse_messages(target_ckey = target_ckey)
|
||||
browse_messages(target_ckey = target_ckey, agegate = TRUE)
|
||||
|
||||
/proc/browse_messages(type, target_ckey, index, linkless = 0, filter)
|
||||
/proc/browse_messages(type, target_ckey, index, linkless = FALSE, filter, agegate = FALSE)
|
||||
if(!SSdbcore.Connect())
|
||||
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
|
||||
return
|
||||
var/output
|
||||
var/ruler = "<hr style='background:#000000; border:0; height:3px'>"
|
||||
var/navbar = "<a href='?_src_=holder;nonalpha=1'>\[All\]</a>|<a href='?_src_=holder;nonalpha=2'>\[#\]</a>"
|
||||
var/navbar = "<a href='?_src_=holder;[HrefToken()];nonalpha=1'>\[All\]</a>|<a href='?_src_=holder;nonalpha=2'>\[#\]</a>"
|
||||
for(var/letter in GLOB.alphabet)
|
||||
navbar += "|<a href='?_src_=holder;showmessages=[letter]'>\[[letter]\]</a>"
|
||||
navbar += "|<a href='?_src_=holder;showmemo=1'>\[Memos\]</a>|<a href='?_src_=holder;showwatch=1'>\[Watchlist\]</a>"
|
||||
navbar += "|<a href='?_src_=holder;[HrefToken()];showmessages=[letter]'>\[[letter]\]</a>"
|
||||
navbar += "|<a href='?_src_=holder;[HrefToken()];showmemo=1'>\[Memos\]</a>|<a href='?_src_=holder;showwatch=1'>\[Watchlist\]</a>"
|
||||
navbar += "<br><form method='GET' name='search' action='?'>\
|
||||
<input type='hidden' name='_src_' value='holder'>\
|
||||
<input type='text' name='searchmessages' value='[index]'>\
|
||||
@@ -160,16 +160,16 @@
|
||||
if(type == "memo" || type == "watchlist entry")
|
||||
if(type == "memo")
|
||||
output += "<h2><center>Admin memos</h2>"
|
||||
output += "<a href='?_src_=holder;addmemo=1'>\[Add memo\]</a></center>"
|
||||
output += "<a href='?_src_=holder;[HrefToken()];addmemo=1'>\[Add memo\]</a></center>"
|
||||
else if(type == "watchlist entry")
|
||||
output += "<h2><center>Watchlist entries</h2>"
|
||||
output += "<a href='?_src_=holder;addwatchempty=1'>\[Add watchlist entry\]</a>"
|
||||
output += "<a href='?_src_=holder;[HrefToken()];addwatchempty=1'>\[Add watchlist entry\]</a>"
|
||||
if(filter)
|
||||
output += "|<a href='?_src_=holder;showwatch=1'>\[Unfilter clients\]</a></center>"
|
||||
output += "|<a href='?_src_=holder;[HrefToken()];showwatch=1'>\[Unfilter clients\]</a></center>"
|
||||
else
|
||||
output += "|<a href='?_src_=holder;showwatchfilter=1'>\[Filter offline clients\]</a></center>"
|
||||
output += "|<a href='?_src_=holder;[HrefToken()];showwatchfilter=1'>\[Filter offline clients\]</a></center>"
|
||||
output += ruler
|
||||
var/datum/DBQuery/query_get_type_messages = SSdbcore.NewQuery("SELECT id, targetckey, adminckey, text, timestamp, server, lasteditor FROM [format_table_name("messages")] WHERE type = '[type]'")
|
||||
var/datum/DBQuery/query_get_type_messages = SSdbcore.NewQuery("SELECT id, targetckey, adminckey, text, timestamp, server, lasteditor FROM [format_table_name("messages")] WHERE type = '[type]' AND deleted = 0")
|
||||
if(!query_get_type_messages.warn_execute())
|
||||
return
|
||||
while(query_get_type_messages.NextRow())
|
||||
@@ -186,19 +186,20 @@
|
||||
if(type == "watchlist entry")
|
||||
output += "[t_ckey] | "
|
||||
output += "[timestamp] | [server] | [admin_ckey]</b>"
|
||||
output += " <a href='?_src_=holder;deletemessageempty=[id]'>\[Delete\]</a>"
|
||||
output += " <a href='?_src_=holder;editmessageempty=[id]'>\[Edit\]</a>"
|
||||
output += " <a href='?_src_=holder;[HrefToken()];deletemessageempty=[id]'>\[Delete\]</a>"
|
||||
output += " <a href='?_src_=holder;[HrefToken()];editmessageempty=[id]'>\[Edit\]</a>"
|
||||
if(editor_ckey)
|
||||
output += " <font size='2'>Last edit by [editor_ckey] <a href='?_src_=holder;messageedits=[id]'>(Click here to see edit log)</a></font>"
|
||||
output += " <font size='2'>Last edit by [editor_ckey] <a href='?_src_=holder;[HrefToken()];messageedits=[id]'>(Click here to see edit log)</a></font>"
|
||||
output += "<br>[text]<hr style='background:#000000; border:0; height:1px'>"
|
||||
if(target_ckey)
|
||||
target_ckey = sanitizeSQL(target_ckey)
|
||||
var/datum/DBQuery/query_get_messages = SSdbcore.NewQuery("SELECT type, secret, id, adminckey, text, timestamp, server, lasteditor FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey = '[target_ckey]' ORDER BY timestamp DESC")
|
||||
var/datum/DBQuery/query_get_messages = SSdbcore.NewQuery("SELECT type, secret, id, adminckey, text, timestamp, server, lasteditor, DATEDIFF(NOW(), timestamp) AS `age` FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey = '[target_ckey]' AND deleted = 0 ORDER BY timestamp DESC")
|
||||
if(!query_get_messages.warn_execute())
|
||||
return
|
||||
var/messagedata
|
||||
var/watchdata
|
||||
var/notedata
|
||||
var/skipped = 0
|
||||
while(query_get_messages.NextRow())
|
||||
type = query_get_messages.item[1]
|
||||
if(type == "memo")
|
||||
@@ -212,21 +213,34 @@
|
||||
var/timestamp = query_get_messages.item[6]
|
||||
var/server = query_get_messages.item[7]
|
||||
var/editor_ckey = query_get_messages.item[8]
|
||||
var/age = text2num(query_get_messages.item[9])
|
||||
var/alphatext = ""
|
||||
if (agegate && type == "note" && isnum(config.note_stale_days) && isnum(config.note_fresh_days) && config.note_stale_days > config.note_fresh_days)
|
||||
var/alpha = Clamp(100 - (age - config.note_fresh_days) * (85 / (config.note_stale_days - config.note_fresh_days)), 15, 100)
|
||||
if (alpha < 100)
|
||||
if (alpha <= 15)
|
||||
if (skipped)
|
||||
skipped++
|
||||
continue
|
||||
alpha = 10
|
||||
skipped = TRUE
|
||||
alphatext = "filter: alpha(opacity=[alpha]); opacity: [alpha/100];"
|
||||
|
||||
var/data
|
||||
data += "<b>[timestamp] | [server] | [admin_ckey]</b>"
|
||||
data += "<p style='margin:0px;[alphatext]'> <b>[timestamp] | [server] | [admin_ckey]</b>"
|
||||
if(!linkless)
|
||||
data += " <a href='?_src_=holder;deletemessage=[id]'>\[Delete\]</a>"
|
||||
data += " <a href='?_src_=holder;[HrefToken()];deletemessage=[id]'>\[Delete\]</a>"
|
||||
if(type == "note")
|
||||
data += " <a href='?_src_=holder;secretmessage=[id]'>[secret ? "<b>\[Secret\]</b>" : "\[Not secret\]"]</a>"
|
||||
data += " <a href='?_src_=holder;[HrefToken()];secretmessage=[id]'>[secret ? "<b>\[Secret\]</b>" : "\[Not secret\]"]</a>"
|
||||
if(type == "message sent")
|
||||
data += " <font size='2'>Message has been sent</font>"
|
||||
if(editor_ckey)
|
||||
data += "|"
|
||||
else
|
||||
data += " <a href='?_src_=holder;editmessage=[id]'>\[Edit\]</a>"
|
||||
data += " <a href='?_src_=holder;[HrefToken()];editmessage=[id]'>\[Edit\]</a>"
|
||||
if(editor_ckey)
|
||||
data += " <font size='2'>Last edit by [editor_ckey] <a href='?_src_=holder;messageedits=[id]'>(Click here to see edit log)</a></font>"
|
||||
data += "<br>[text]<hr style='background:#000000; border:0; height:1px'>"
|
||||
data += " <font size='2'>Last edit by [editor_ckey] <a href='?_src_=holder;[HrefToken()];messageedits=[id]'>(Click here to see edit log)</a></font>"
|
||||
data += "<br>[text]</p><hr style='background:#000000; border:0; height:1px; [alphatext]'>"
|
||||
switch(type)
|
||||
if("message")
|
||||
messagedata += data
|
||||
@@ -238,12 +252,12 @@
|
||||
notedata += data
|
||||
output += "<h2><center>[target_ckey]</center></h2><center>"
|
||||
if(!linkless)
|
||||
output += "<a href='?_src_=holder;addnote=[target_ckey]'>\[Add note\]</a>"
|
||||
output += " <a href='?_src_=holder;addmessage=[target_ckey]'>\[Add message\]</a>"
|
||||
output += " <a href='?_src_=holder;addwatch=[target_ckey]'>\[Add to watchlist\]</a>"
|
||||
output += " <a href='?_src_=holder;showmessageckey=[target_ckey]'>\[Refresh page\]</a></center>"
|
||||
output += "<a href='?_src_=holder;[HrefToken()];addnote=[target_ckey]'>\[Add note\]</a>"
|
||||
output += " <a href='?_src_=holder;[HrefToken()];addmessage=[target_ckey]'>\[Add message\]</a>"
|
||||
output += " <a href='?_src_=holder;[HrefToken()];addwatch=[target_ckey]'>\[Add to watchlist\]</a>"
|
||||
output += " <a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey]'>\[Refresh page\]</a></center>"
|
||||
else
|
||||
output += " <a href='?_src_=holder;showmessageckeylinkless=[target_ckey]'>\[Refresh page\]</a></center>"
|
||||
output += " <a href='?_src_=holder;[HrefToken()];showmessageckeylinkless=[target_ckey]'>\[Refresh page\]</a></center>"
|
||||
output += ruler
|
||||
if(messagedata)
|
||||
output += "<h4>Messages</h4>"
|
||||
@@ -254,10 +268,19 @@
|
||||
if(notedata)
|
||||
output += "<h4>Notes</h4>"
|
||||
output += notedata
|
||||
if(!linkless)
|
||||
if (agegate)
|
||||
if (skipped) //the first skipped message is still shown so that we can put this link over it.
|
||||
output += " <center><a href='?_src_=holder;showmessageckey=[target_ckey];showall=1' style='position: relative; top: -3em;'>\[Show [skipped] hidden messages\]</center>"
|
||||
else
|
||||
output += " <center><a href='?_src_=holder;showmessageckey=[target_ckey];showall=1'>\[Show All\]</center>"
|
||||
|
||||
else
|
||||
output += " <center><a href='?_src_=holder;showmessageckey=[target_ckey]'>\[Hide Old\]</center>"
|
||||
if(index)
|
||||
var/index_ckey
|
||||
var/search
|
||||
output += "<center><a href='?_src_=holder;addmessageempty=1'>\[Add message\]</a><a href='?_src_=holder;addwatchempty=1'>\[Add watchlist entry\]</a><a href='?_src_=holder;addnoteempty=1'>\[Add note\]</a></center>"
|
||||
output += "<center><a href='?_src_=holder;[HrefToken()];addmessageempty=1'>\[Add message\]</a><a href='?_src_=holder;[HrefToken()];addwatchempty=1'>\[Add watchlist entry\]</a><a href='?_src_=holder;[HrefToken()];addnoteempty=1'>\[Add note\]</a></center>"
|
||||
output += ruler
|
||||
if(!isnum(index))
|
||||
index = sanitizeSQL(index)
|
||||
@@ -268,16 +291,16 @@
|
||||
search = "^\[^\[:alpha:\]\]"
|
||||
else
|
||||
search = "^[index]"
|
||||
var/datum/DBQuery/query_list_messages = SSdbcore.NewQuery("SELECT DISTINCT targetckey FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey REGEXP '[search]' ORDER BY targetckey")
|
||||
var/datum/DBQuery/query_list_messages = SSdbcore.NewQuery("SELECT DISTINCT targetckey FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey REGEXP '[search]' AND deleted = 0 ORDER BY targetckey")
|
||||
if(!query_list_messages.warn_execute())
|
||||
return
|
||||
while(query_list_messages.NextRow())
|
||||
index_ckey = query_list_messages.item[1]
|
||||
output += "<a href='?_src_=holder;showmessageckey=[index_ckey]'>[index_ckey]</a><br>"
|
||||
output += "<a href='?_src_=holder;[HrefToken()];showmessageckey=[index_ckey]'>[index_ckey]</a><br>"
|
||||
else if(!type && !target_ckey && !index)
|
||||
output += "<center></a> <a href='?_src_=holder;addmessageempty=1'>\[Add message\]</a><a href='?_src_=holder;addwatchempty=1'>\[Add watchlist entry\]</a><a href='?_src_=holder;addnoteempty=1'>\[Add note\]</a></center>"
|
||||
output += "<center></a> <a href='?_src_=holder;[HrefToken()];addmessageempty=1'>\[Add message\]</a><a href='?_src_=holder;[HrefToken()];addwatchempty=1'>\[Add watchlist entry\]</a><a href='?_src_=holder;[HrefToken()];addnoteempty=1'>\[Add note\]</a></center>"
|
||||
output += ruler
|
||||
usr << browse(output, "window=browse_messages;size=900x500")
|
||||
usr << browse({"<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /></head><body>[output]</body></html>"}, "window=browse_messages;size=900x500")
|
||||
|
||||
proc/get_message_output(type, target_ckey)
|
||||
if(!SSdbcore.Connect())
|
||||
@@ -288,7 +311,7 @@ proc/get_message_output(type, target_ckey)
|
||||
var/output
|
||||
if(target_ckey)
|
||||
target_ckey = sanitizeSQL(target_ckey)
|
||||
var/query = "SELECT id, adminckey, text, timestamp, lasteditor FROM [format_table_name("messages")] WHERE type = '[type]'"
|
||||
var/query = "SELECT id, adminckey, text, timestamp, lasteditor FROM [format_table_name("messages")] WHERE type = '[type]' AND deleted = 0"
|
||||
if(type == "message" || type == "watchlist entry")
|
||||
query += " AND targetckey = '[target_ckey]'"
|
||||
var/datum/DBQuery/query_get_message_output = SSdbcore.NewQuery(query)
|
||||
@@ -313,7 +336,7 @@ proc/get_message_output(type, target_ckey)
|
||||
if("memo")
|
||||
output += "<span class='memo'>Memo by <span class='prefix'>[admin_ckey]</span> on [timestamp]"
|
||||
if(editor_ckey)
|
||||
output += "<br><span class='memoedit'>Last edit by [editor_ckey] <A href='?_src_=holder;messageedits=[message_id]'>(Click here to see edit log)</A></span>"
|
||||
output += "<br><span class='memoedit'>Last edit by [editor_ckey] <A href='?_src_=holder;[HrefToken()];messageedits=[message_id]'>(Click here to see edit log)</A></span>"
|
||||
output += "<br>[text]</span><br>"
|
||||
return output
|
||||
|
||||
|
||||
@@ -152,11 +152,11 @@
|
||||
|
||||
/datum/admins/proc/stickyban_gethtml(ckey, ban)
|
||||
. = {"
|
||||
<a href='?_src_=holder;stickyban=remove&ckey=[ckey]'>\[-\]</a>
|
||||
<a href='?_src_=holder;stickyban=revert&ckey=[ckey]'>\[revert\]</a>
|
||||
<a href='?_src_=holder;[HrefToken()];stickyban=remove&ckey=[ckey]'>\[-\]</a>
|
||||
<a href='?_src_=holder;[HrefToken()];stickyban=revert&ckey=[ckey]'>\[revert\]</a>
|
||||
<b>[ckey]</b>
|
||||
<br />"
|
||||
[ban["message"]] <b><a href='?_src_=holder;stickyban=edit&ckey=[ckey]'>\[Edit\]</a></b><br />
|
||||
[ban["message"]] <b><a href='?_src_=holder;[HrefToken()];stickyban=edit&ckey=[ckey]'>\[Edit\]</a></b><br />
|
||||
"}
|
||||
if (ban["admin"])
|
||||
. += "[ban["admin"]]<br />"
|
||||
@@ -166,7 +166,7 @@
|
||||
for (var/key in ban["keys"])
|
||||
if (ckey(key) == ckey)
|
||||
continue
|
||||
. += "<li><a href='?_src_=holder;stickyban=remove_alt&ckey=[ckey]&alt=[ckey(key)]'>\[-\]</a>[key]</li>"
|
||||
. += "<li><a href='?_src_=holder;[HrefToken()];stickyban=remove_alt&ckey=[ckey]&alt=[ckey(key)]'>\[-\]</a>[key]</li>"
|
||||
. += "</ol>\n"
|
||||
|
||||
/datum/admins/proc/stickyban_show()
|
||||
@@ -185,7 +185,7 @@
|
||||
<title>Sticky Bans</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>All Sticky Bans:</h2> <a href='?_src_=holder;stickyban=add'>\[+\]</a><br>
|
||||
<h2>All Sticky Bans:</h2> <a href='?_src_=holder;[HrefToken()];stickyban=add'>\[+\]</a><br>
|
||||
[banhtml]
|
||||
</body>
|
||||
"}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
message_admins("Debug mode enabled, call not blocked. Please ask your coders to review this round's logs.")
|
||||
log_world("UAH: [href]")
|
||||
return TRUE
|
||||
log_admin_private("[key_name(usr)] clicked an href with [msg] authorization key! [href]")
|
||||
|
||||
log_admin_private("[key_name(usr)] clicked an href with [msg] authorization key! [href]")
|
||||
|
||||
/datum/admins/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
message_admins("[usr.key] has attempted to override the admin panel!")
|
||||
log_admin("[key_name(usr)] tried to use the admin panel without authorization.")
|
||||
return
|
||||
|
||||
if(!CheckAdminHref(href, href_list))
|
||||
return
|
||||
|
||||
if(href_list["ahelp"])
|
||||
if(!check_rights(R_ADMIN, TRUE))
|
||||
return
|
||||
@@ -1120,7 +1124,10 @@
|
||||
|
||||
else if(href_list["showmessageckey"])
|
||||
var/target = href_list["showmessageckey"]
|
||||
browse_messages(target_ckey = target)
|
||||
var/agegate = TRUE
|
||||
if (href_list["showall"])
|
||||
agegate = FALSE
|
||||
browse_messages(target_ckey = target, agegate = agegate)
|
||||
|
||||
else if(href_list["showmessageckeylinkless"])
|
||||
var/target = href_list["showmessageckeylinkless"]
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
|
||||
/proc/SDQL_gen_vv_href(t)
|
||||
var/text = ""
|
||||
text += "<A HREF='?_src_=vars;Vars=\ref[t]'>\ref[t]</A>"
|
||||
text += "<A HREF='?_src_=vars;[HrefToken()];Vars=\ref[t]'>\ref[t]</A>"
|
||||
if(istype(t, /atom))
|
||||
var/atom/a = t
|
||||
var/turf/T = a.loc
|
||||
|
||||
@@ -80,10 +80,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
if(!l2b)
|
||||
return
|
||||
var/list/dat = list("<html><head><title>[title]</title></head>")
|
||||
dat += "<A HREF='?_src_=holder;ahelp_tickets=[state]'>Refresh</A><br><br>"
|
||||
dat += "<A href='?_src_=holder;[HrefToken()];ahelp_tickets=[state]'>Refresh</A><br><br>"
|
||||
for(var/I in l2b)
|
||||
var/datum/admin_help/AH = I
|
||||
dat += "<span class='adminnotice'><span class='adminhelp'>Ticket #[AH.id]</span>: <A HREF='?_src_=holder;ahelp=\ref[AH];ahelp_action=ticket'>[AH.initiator_key_name]: [AH.name]</A></span><br>"
|
||||
dat += "<span class='adminnotice'><span class='adminhelp'>Ticket #[AH.id]</span>: <A href='?_src_=holder;[HrefToken()];ahelp=\ref[AH];ahelp_action=ticket'>[AH.initiator_key_name]: [AH.name]</A></span><br>"
|
||||
|
||||
usr << browse(dat.Join(), "window=ahelp_list[state];size=600x480")
|
||||
|
||||
@@ -228,22 +228,22 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
/datum/admin_help/proc/ClosureLinks(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
. = " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=reject'>REJT</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=icissue'>IC</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=close'>CLOSE</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=resolve'>RSLVE</A>)"
|
||||
. = " (<A HREF='?_src_=holder;[HrefToken(TRUE)];ahelp=[ref_src];ahelp_action=reject'>REJT</A>)"
|
||||
. += " (<A HREF='?_src_=holder;[HrefToken(TRUE)];ahelp=[ref_src];ahelp_action=icissue'>IC</A>)"
|
||||
. += " (<A HREF='?_src_=holder;[HrefToken(TRUE)];ahelp=[ref_src];ahelp_action=close'>CLOSE</A>)"
|
||||
. += " (<A HREF='?_src_=holder;[HrefToken(TRUE)];ahelp=[ref_src];ahelp_action=resolve'>RSLVE</A>)"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/LinkedReplyName(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
return "<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=reply'>[initiator_key_name]</A>"
|
||||
return "<A HREF='?_src_=holder;[HrefToken()];ahelp=[ref_src];ahelp_action=reply'>[initiator_key_name]</A>"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/TicketHref(msg, ref_src, action = "ticket")
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
return "<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=[action]'>[msg]</A>"
|
||||
return "<A HREF='?_src_=holder;[HrefToken()];ahelp=[ref_src];ahelp_action=[action]'>[msg]</A>"
|
||||
|
||||
//message from the initiator without a target, all admins will see this
|
||||
//won't bug irc
|
||||
@@ -675,7 +675,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
if(found.mind && found.mind.special_role)
|
||||
is_antag = 1
|
||||
founds += "Name: [found.name]([found.real_name]) Ckey: [found.ckey] [is_antag ? "(Antag)" : null] "
|
||||
msg += "[original_word]<font size='1' color='[is_antag ? "red" : "black"]'>(<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;adminplayerobservefollow=\ref[found]'>F</A>)</font> "
|
||||
msg += "[original_word]<font size='1' color='[is_antag ? "red" : "black"]'>(<A HREF='?_src_=holder;[HrefToken()];adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[found]'>F</A>)</font> "
|
||||
continue
|
||||
msg += "[original_word] "
|
||||
if(irc)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
log_talk(mob,"[key_name(src)] : [msg]",LOGASAY)
|
||||
msg = keywords_lookup(msg)
|
||||
if(check_rights(R_ADMIN,0))
|
||||
msg = "<span class='admin'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> (<a href='?_src_=holder;adminplayerobservefollow=\ref[mob]'>FLW</A>): <span class='message'>[msg]</span></span>"
|
||||
msg = "<span class='admin'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message'>[msg]</span></span>"
|
||||
to_chat(GLOB.admins, msg)
|
||||
else
|
||||
msg = "<span class='adminobserver'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]:</EM> <span class='message'>[msg]</span></span>"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/proc/show_individual_logging_panel(mob/M, type = INDIVIDUAL_ATTACK_LOG)
|
||||
if(!M || !ismob(M))
|
||||
return
|
||||
var/dat = "<center><a href='?_src_=holder;individuallog=\ref[M];log_type=[INDIVIDUAL_ATTACK_LOG]'>Attack log</a> | "
|
||||
dat += "<a href='?_src_=holder;individuallog=\ref[M];log_type=[INDIVIDUAL_SAY_LOG]'>Say log</a> | "
|
||||
dat += "<a href='?_src_=holder;individuallog=\ref[M];log_type=[INDIVIDUAL_EMOTE_LOG]'>Emote log</a> | "
|
||||
dat += "<a href='?_src_=holder;individuallog=\ref[M];log_type=[INDIVIDUAL_OOC_LOG]'>OOC log</a> | "
|
||||
dat += "<a href='?_src_=holder;individuallog=\ref[M];log_type=[INDIVIDUAL_SHOW_ALL_LOG]'>Show all</a> | "
|
||||
dat += "<a href='?_src_=holder;individuallog=\ref[M];log_type=[type]'>Refresh</a></center>"
|
||||
var/dat = "<center><a href='?_src_=holder;[HrefToken()];individuallog=\ref[M];log_type=[INDIVIDUAL_ATTACK_LOG]'>Attack log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=\ref[M];log_type=[INDIVIDUAL_SAY_LOG]'>Say log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=\ref[M];log_type=[INDIVIDUAL_EMOTE_LOG]'>Emote log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=\ref[M];log_type=[INDIVIDUAL_OOC_LOG]'>OOC log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=\ref[M];log_type=[INDIVIDUAL_SHOW_ALL_LOG]'>Show all</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=\ref[M];log_type=[type]'>Refresh</a></center>"
|
||||
|
||||
dat += "<hr style='background:#000000; border:0; height:1px'>"
|
||||
|
||||
|
||||
@@ -11,18 +11,17 @@
|
||||
/datum/admins/proc/one_click_antag()
|
||||
|
||||
var/dat = {"
|
||||
<a href='?src=\ref[src];makeAntag=traitors'>Make Traitors</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=changelings'>Make Changelings</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=revs'>Make Revs</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=cult'>Make Cult</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=clockcult'>Make Clockwork Cult</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=blob'>Make Blob</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=gangs'>Make Gangsters</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=wizard'>Make Wizard (Requires Ghosts)</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=nukeops'>Make Nuke Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=centcom'>Make CentCom Response Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=abductors'>Make Abductor Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=\ref[src];makeAntag=revenant'>Make Revenant (Requires Ghost)</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=traitors'>Make Traitors</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=changelings'>Make Changelings</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=revs'>Make Revs</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=cult'>Make Cult</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=clockcult'>Make Clockwork Cult</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=blob'>Make Blob</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=wizard'>Make Wizard (Requires Ghosts)</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=nukeops'>Make Nuke Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=centcom'>Make CentCom Response Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=abductors'>Make Abductor Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=\ref[src];[HrefToken()];makeAntag=revenant'>Make Revenant (Requires Ghost)</a><br>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(usr, "oneclickantag", "Quick-Create Antagonist", 400, 400)
|
||||
@@ -358,7 +357,6 @@
|
||||
|
||||
return
|
||||
|
||||
|
||||
/datum/admins/proc/makeGangsters()
|
||||
|
||||
var/datum/game_mode/gang/temp = new
|
||||
@@ -395,6 +393,7 @@
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/datum/admins/proc/makeOfficial()
|
||||
var/mission = input("Assign a task for the official", "Assign Task", "Conduct a routine preformance review of [station_name()] and its Captain.")
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered to be a CentCom Official?", "deathsquad")
|
||||
|
||||
@@ -50,8 +50,8 @@ GLOBAL_VAR_INIT(highlander, FALSE)
|
||||
equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(src), slot_ears)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(src), slot_head)
|
||||
equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(src), slot_shoes)
|
||||
equip_to_slot_or_del(new /obj/item/pinpointer(src), slot_l_store)
|
||||
for(var/obj/item/pinpointer/P in src)
|
||||
equip_to_slot_or_del(new /obj/item/pinpointer/nuke(src), slot_l_store)
|
||||
for(var/obj/item/pinpointer/nuke/P in src)
|
||||
P.attack_self(src)
|
||||
var/obj/item/card/id/W = new(src)
|
||||
W.icon_state = "centcom"
|
||||
|
||||
@@ -135,4 +135,7 @@
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client)
|
||||
SEND_SOUND(M, sound(null))
|
||||
var/client/C = M.client
|
||||
if(C && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded)
|
||||
C.chatOutput.sendMusic(" ")
|
||||
SSblackbox.add_details("admin_verb","Stop All Playing Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -1147,8 +1147,8 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
/datum/admins/proc/modify_goals()
|
||||
var/dat = ""
|
||||
for(var/datum/station_goal/S in SSticker.mode.station_goals)
|
||||
dat += "[S.name] - <a href='?src=\ref[S];announce=1'>Announce</a> | <a href='?src=\ref[S];remove=1'>Remove</a><br>"
|
||||
dat += "<br><a href='?src=\ref[src];add_station_goal=1'>Add New Goal</a>"
|
||||
dat += "[S.name] - <a href='?src=\ref[S];[HrefToken()];announce=1'>Announce</a> | <a href='?src=\ref[S];[HrefToken()];remove=1'>Remove</a><br>"
|
||||
dat += "<br><a href='?src=\ref[src];[HrefToken()];add_station_goal=1'>Add New Goal</a>"
|
||||
usr << browse(dat, "window=goals;size=400x400")
|
||||
|
||||
|
||||
@@ -1219,7 +1219,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
var/list/msg = list()
|
||||
msg += "<html><head><title>Playtime Report</title></head><body>Playtime:<BR><UL>"
|
||||
for(var/client/C in GLOB.clients)
|
||||
msg += "<LI> - [key_name_admin(C)]: <A href='?_src_=holder;getplaytimewindow=\ref[C.mob]'>" + C.get_exp_living() + "</a></LI>"
|
||||
msg += "<LI> - [key_name_admin(C)]: <A href='?_src_=holder;[HrefToken()];getplaytimewindow=\ref[C.mob]'>" + C.get_exp_living() + "</a></LI>"
|
||||
msg += "</UL></BODY></HTML>"
|
||||
src << browse(msg.Join(), "window=Player_playtime_check")
|
||||
|
||||
@@ -1233,7 +1233,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
var/list/body = list()
|
||||
body += "<html><head><title>Playtime for [C.key]</title></head><BODY><BR>Playtime:"
|
||||
body += C.get_exp_report()
|
||||
body += "<A href='?_src_=holder;toggleexempt=\ref[C]'>Toggle Exempt status</a>"
|
||||
body += "<A href='?_src_=holder;[HrefToken()];toggleexempt=\ref[C]'>Toggle Exempt status</a>"
|
||||
body += "</BODY></HTML>"
|
||||
usr << browse(body.Join(), "window=playerplaytime[C.ckey];size=550x615")
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
build_network()
|
||||
|
||||
/obj/machinery/atmospherics/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
var/running_bob_anim = FALSE
|
||||
|
||||
var/escape_in_progress = FALSE
|
||||
var/message_cooldown
|
||||
var/breakout_time = 0.5
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/Initialize()
|
||||
. = ..()
|
||||
@@ -219,7 +221,9 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/user)
|
||||
container_resist(user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine(drop = 0)
|
||||
if(!state_open && !panel_open)
|
||||
@@ -239,16 +243,17 @@
|
||||
return occupant
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/living/user)
|
||||
if(escape_in_progress)
|
||||
to_chat(user, "<span class='notice'>You are already trying to exit (This will take around 30 seconds)</span>")
|
||||
return
|
||||
escape_in_progress = TRUE
|
||||
to_chat(user, "<span class='notice'>You struggle inside the cryotube, kicking the release with your foot... (This will take around 30 seconds.)</span>")
|
||||
audible_message("<span class='notice'>You hear a thump from [src].</span>")
|
||||
if(do_after(user, 300))
|
||||
if(occupant == user) // Check they're still here.
|
||||
open_machine()
|
||||
escape_in_progress = FALSE
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the glass of [src]!</span>", \
|
||||
"<span class='notice'>You struggle inside [src], kicking the release with your foot... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a thump from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user)
|
||||
..()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user