Merge remote-tracking branch 'ParadiseSS13/master' into depot_loot_fix

This commit is contained in:
Kyep
2020-03-07 23:25:20 -08:00
514 changed files with 14823 additions and 6822 deletions
+1 -1
View File
@@ -7,4 +7,4 @@ assignees: ''
---
Please place all features requests here: https://nanotrasen.se/forum/60-suggestions/
Please place all features requests here: https://www.paradisestation.org/forum/60-suggestions/
-1
View File
@@ -15,7 +15,6 @@
add: Added new things
del: Removed old things
tweak: tweaked a few things
balance: rebalanced something
fix: fixed a few things
wip: added a few works in progress
soundadd: added a new sound thingy
+15 -1
View File
@@ -21,4 +21,18 @@ data/
*.db
stddef.dm
.atom-build.json
*.vscode/*
*.vscode/*
!/.vscode/extensions.json
# ignore DMI tool build cache
/tools/dmitool/bin/
/tools/dmitool/.gradle/
/tools/dmitool/.settings/
/tools/dmitool/.classpath
/tools/dmitool/.project
# ignore midi2piano build cache
/tools/midi2piano/obj/*
+3 -3
View File
@@ -18,8 +18,8 @@ addons:
env:
global:
- BYOND_MAJOR="512"
- BYOND_MINOR="1454"
- BYOND_MAJOR="513"
- BYOND_MINOR="1505"
- BYOND_MACRO_COUNT=4
matrix:
- DM_MAPFILE="cyberiad"
@@ -69,4 +69,4 @@ jobs:
- npm install --loglevel=error
before_script:
script:
- gulp
- node node_modules/gulp/bin/gulp.js --require less-loader
+6
View File
@@ -0,0 +1,6 @@
{
"recommendations": [
"gbasood.byond-dm-language-support",
"platymuus.dm-langclient"
]
}
+2 -2
View File
@@ -8,7 +8,7 @@
[![forthebadge](http://forthebadge.com/images/badges/contains-technical-debt.svg)](http://forthebadge.com)
[![forthebadge](http://forthebadge.com/images/badges/fuck-it-ship-it.svg)](http://forthebadge.com)
[Website](https://nanotrasen.se/) - [Code](https://github.com/ParadiseSS13/Paradise) - [Discord](https://discordapp.com/invite/YJDsXFE)
[Website](https://www.paradisestation.org/) - [Code](https://github.com/ParadiseSS13/Paradise) - [Discord](https://discordapp.com/invite/YJDsXFE)
---
@@ -104,7 +104,7 @@ Your server details go in /config/dbconfig.txt,
and the SQL schema is in /SQL/paradise_schema.sql or /SQL/paradise_schema_prefix.sql,
depending on if you want table prefixes.
More detailed setup instructions are located on our wiki:
https://nanotrasen.se/wiki/index.php/Setting_up_the_Database
https://www.paradisestation.org/wiki/index.php/Setting_up_the_Database
---
+53 -23
View File
@@ -97,7 +97,7 @@ CREATE TABLE `customuseritems` (
`cuiPropAdjust` text,
`cuiJobMask` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -124,7 +124,7 @@ CREATE TABLE `death` (
`fireloss` int(11) NOT NULL,
`oxyloss` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=166546 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -160,7 +160,7 @@ CREATE TABLE `admin` (
`level` int(2) NOT NULL DEFAULT '0',
`flags` int(16) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=latin1;
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -177,7 +177,7 @@ CREATE TABLE `admin_log` (
`adminip` varchar(18) NOT NULL,
`log` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -212,7 +212,7 @@ CREATE TABLE `ban` (
`unbanned_computerid` varchar(32) DEFAULT NULL,
`unbanned_ip` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10685 DEFAULT CHARSET=latin1;
) ENGINE=InnoDB AUTO_INCREMENT=10685 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -230,7 +230,7 @@ CREATE TABLE `feedback` (
`var_value` int(16) DEFAULT NULL,
`details` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=257638 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -272,7 +272,7 @@ CREATE TABLE `player` (
`parallax` tinyint(1) DEFAULT '8',
PRIMARY KEY (`id`),
UNIQUE KEY `ckey` (`ckey`)
) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1;
) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -293,7 +293,7 @@ CREATE TABLE `poll_option` (
`descmid` varchar(32) DEFAULT NULL,
`descmax` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -314,7 +314,7 @@ CREATE TABLE `poll_question` (
`createdby_ckey` varchar(45) NULL DEFAULT NULL,
`createdby_ip` varchar(45) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -333,7 +333,7 @@ CREATE TABLE `poll_textreply` (
`replytext` text NOT NULL,
`adminrank` varchar(32) NOT NULL DEFAULT 'Player',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -353,7 +353,7 @@ CREATE TABLE `poll_vote` (
`adminrank` varchar(32) NOT NULL,
`rating` int(2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -369,7 +369,7 @@ CREATE TABLE `privacy` (
`consent` bit(1) NOT NULL,
PRIMARY KEY (`ckey`),
UNIQUE KEY `ckey_UNIQUE` (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -391,7 +391,7 @@ CREATE TABLE `karma` (
`spenderip` text NOT NULL,
`time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=73614 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -407,7 +407,7 @@ CREATE TABLE `karmatotals` (
`karma` int(11) NOT NULL,
`karmaspent` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6765 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=6765 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -426,7 +426,7 @@ CREATE TABLE `library` (
`ckey` varchar(45) NOT NULL,
`flagged` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=929 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=929 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -442,7 +442,7 @@ CREATE TABLE `legacy_population` (
`admincount` int(11) DEFAULT NULL,
`time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2550 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -458,7 +458,7 @@ CREATE TABLE `whitelist` (
`job` text,
`species` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=877 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=877 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@@ -485,7 +485,7 @@ CREATE TABLE `watch` (
`last_editor` varchar(32),
`edits` text,
PRIMARY KEY (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -505,8 +505,9 @@ CREATE TABLE `notes` (
`last_editor` varchar(32),
`edits` text,
`server` varchar(50) NOT NULL,
`crew_playtime` mediumint(8) UNSIGNED DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -523,7 +524,7 @@ CREATE TABLE `memo` (
`last_editor` varchar(32),
`edits` text,
PRIMARY KEY (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -537,7 +538,7 @@ CREATE TABLE `ipintel` (
`date` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL,
`intel` real NOT NULL DEFAULT '0',
PRIMARY KEY (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -550,7 +551,7 @@ CREATE TABLE `vpn_whitelist` (
`ckey` varchar(32) NOT NULL,
`reason` text,
PRIMARY KEY (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -563,5 +564,34 @@ CREATE TABLE `oauth_tokens` (
`ckey` varchar(32) NOT NULL,
`token` varchar(32) NOT NULL,
PRIMARY KEY (`token`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `playtime_history`
--
DROP TABLE IF EXISTS `playtime_history`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `playtime_history` (
`ckey` varchar(32) NOT NULL,
`date` DATE NOT NULL,
`time_living` SMALLINT NOT NULL,
`time_ghost` SMALLINT NOT NULL,
PRIMARY KEY (`ckey`, `date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Table structure for table `connection_log`
--
DROP TABLE IF EXISTS `connection_log`;
CREATE TABLE `connection_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`ckey` varchar(32) NOT NULL,
`ip` varchar(32) NOT NULL,
`computerid` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+51 -23
View File
@@ -97,7 +97,7 @@ CREATE TABLE `SS13_customuseritems` (
`cuiPropAdjust` text,
`cuiJobMask` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -124,7 +124,7 @@ CREATE TABLE `SS13_death` (
`fireloss` int(11) NOT NULL,
`oxyloss` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=166546 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -159,7 +159,7 @@ CREATE TABLE `SS13_admin` (
`level` int(2) NOT NULL DEFAULT '0',
`flags` int(16) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=latin1;
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -176,7 +176,7 @@ CREATE TABLE `SS13_admin_log` (
`adminip` varchar(18) NOT NULL,
`log` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -211,7 +211,7 @@ CREATE TABLE `SS13_ban` (
`unbanned_computerid` varchar(32) DEFAULT NULL,
`unbanned_ip` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10685 DEFAULT CHARSET=latin1;
) ENGINE=InnoDB AUTO_INCREMENT=10685 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -229,7 +229,7 @@ CREATE TABLE `SS13_feedback` (
`var_value` int(16) DEFAULT NULL,
`details` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=257638 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -271,7 +271,7 @@ CREATE TABLE `SS13_player` (
`parallax` tinyint(1) DEFAULT '8',
PRIMARY KEY (`id`),
UNIQUE KEY `ckey` (`ckey`)
) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1;
) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -292,7 +292,7 @@ CREATE TABLE `SS13_poll_option` (
`descmid` varchar(32) DEFAULT NULL,
`descmax` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -313,7 +313,7 @@ CREATE TABLE `SS13_poll_question` (
`createdby_ckey` varchar(45) NULL DEFAULT NULL,
`createdby_ip` varchar(45) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -332,7 +332,7 @@ CREATE TABLE `SS13_poll_textreply` (
`replytext` text NOT NULL,
`adminrank` varchar(32) NOT NULL DEFAULT 'Player',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -352,7 +352,7 @@ CREATE TABLE `SS13_poll_vote` (
`adminrank` varchar(32) NOT NULL,
`rating` int(2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -368,7 +368,7 @@ CREATE TABLE `ss13_privacy` (
`consent` bit(1) NOT NULL,
PRIMARY KEY (`ckey`),
UNIQUE KEY `ckey_UNIQUE` (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -390,7 +390,7 @@ CREATE TABLE `SS13_karma` (
`spenderip` text NOT NULL,
`time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=73614 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -406,7 +406,7 @@ CREATE TABLE `SS13_karmatotals` (
`karma` int(11) NOT NULL,
`karmaspent` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6765 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=6765 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -425,7 +425,7 @@ CREATE TABLE `SS13_library` (
`ckey` varchar(45) NOT NULL,
`flagged` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=929 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=929 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -441,7 +441,7 @@ CREATE TABLE `SS13_legacy_population` (
`admincount` int(11) DEFAULT NULL,
`time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2550 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -457,7 +457,7 @@ CREATE TABLE `SS13_whitelist` (
`job` text,
`species` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=877 DEFAULT CHARSET=latin1;
) ENGINE=MyISAM AUTO_INCREMENT=877 DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@@ -484,7 +484,7 @@ CREATE TABLE `SS13_watch` (
`last_editor` varchar(32),
`edits` text,
PRIMARY KEY (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
@@ -504,8 +504,9 @@ CREATE TABLE `SS13_notes` (
`last_editor` varchar(32),
`edits` text,
`server` varchar(50) NOT NULL,
`crew_playtime` mediumint(8) UNSIGNED DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -522,7 +523,7 @@ CREATE TABLE `SS13_memo` (
`last_editor` varchar(32),
`edits` text,
PRIMARY KEY (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -536,7 +537,7 @@ CREATE TABLE `SS13_ipintel` (
`date` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL,
`intel` real NOT NULL DEFAULT '0',
PRIMARY key (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -549,7 +550,7 @@ CREATE TABLE `SS13_vpn_whitelist` (
`ckey` varchar(32) NOT NULL,
`reason` text,
PRIMARY KEY (`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -562,5 +563,32 @@ CREATE TABLE `SS13_oauth_tokens` (
`ckey` varchar(32) NOT NULL,
`token` varchar(32) NOT NULL,
PRIMARY KEY (`token`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `SS13_playtime_history`
--
DROP TABLE IF EXISTS `SS13_playtime_history`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `SS13_playtime_history` (
`ckey` varchar(32) NOT NULL,
`date` DATE NOT NULL,
`time_living` SMALLINT NOT NULL,
`time_ghost` SMALLINT NOT NULL,
PRIMARY KEY (`ckey`, `date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Table structure for table `SS13_connection_log`
--
DROP TABLE IF EXISTS `SS13_connection_log`;
CREATE TABLE `SS13_connection_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`ckey` varchar(32) NOT NULL,
`ip` varchar(32) NOT NULL,
`computerid` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+41
View File
@@ -0,0 +1,41 @@
# Updating SQL from ver 10 to 11
# Changes tables from latin1 to utf8mb4
# Based on: https://github.com/BeeStation/BeeStation-Hornet/pull/1074/files
# -Kyet
# Generation (not necessary to run unless your DB has extra tables)
SELECT CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") AS ExecuteTheString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="feedback"
AND TABLE_TYPE="BASE TABLE";
# Actual table conversion stuff
ALTER TABLE feedback.admin CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.admin_log CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.ban CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.characters CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.connection_log CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.customuseritems CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.death CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.donators CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.erro_privacy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.feedback CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.ipintel CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.karma CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.karmatotals CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.legacy_population CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.library CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.memo CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.notes CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.oauth_tokens CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.player CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.playtime_history CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.poll_option CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.poll_question CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.poll_textreply CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.poll_vote CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.population CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.privacy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.vpn_whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.watch CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE feedback.whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+24
View File
@@ -0,0 +1,24 @@
# Updating SQL from ver 9 to 10 - Kyet
# Add the 'playtime_history' table that tracks playtime per player per day
CREATE TABLE `playtime_history` (
`ckey` varchar(32) NOT NULL,
`date` DATE NOT NULL,
`time_living` SMALLINT NOT NULL,
`time_ghost` SMALLINT NOT NULL,
PRIMARY KEY (`ckey`, `date`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
# Add the 'connection_log' table, which is used to log all connections to the server
DROP TABLE IF EXISTS `connection_log`;
CREATE TABLE `connection_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`ckey` varchar(32) NOT NULL,
`ip` varchar(32) NOT NULL,
`computerid` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
# Add the 'crew_playtime' field to the 'notes' table, which gives admins some idea of how many hours have passed for a player since they got a note
ALTER TABLE `notes` ADD `crew_playtime` mediumint(8) UNSIGNED DEFAULT '0' AFTER `server`;
+1 -1
View File
@@ -72015,7 +72015,7 @@
dir = 8;
layer = 2.9
},
/obj/item/circuitboard/rdconsole/public{
/obj/item/circuitboard/rdconsole{
pixel_x = -4
},
/obj/item/circuitboard/rdserver{
+2 -2
View File
@@ -64,8 +64,8 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
// Icons/overlays/underlays
/obj/machinery/atmospherics/update_icon()
var/turf/T = loc
if(level == 2 || !T.intact)
var/turf/T = get_turf(loc)
if(!T || level == 2 || !T.intact)
plane = GAME_PLANE
else
plane = FLOOR_PLANE
@@ -98,16 +98,16 @@
else
return "South"
/obj/machinery/atmospherics/binary/circulator/attackby(obj/item/W as obj, mob/user as mob, params)
if(ismultitool(W))
if(side_inverted == 0)
side_inverted = 1
else
side_inverted = 0
to_chat(user, "<span class='notice'>You reverse the circulator's valve settings. The inlet of the circulator is now on the [get_inlet_side(dir)] side.</span>")
desc = "A gas circulator pump and heat exchanger. Its input port is on the [get_inlet_side(dir)] side, and its output port is on the [get_outlet_side(dir)] side."
/obj/machinery/atmospherics/binary/circulator/multitool_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(!side_inverted)
side_inverted = TRUE
else
return ..()
side_inverted = FALSE
to_chat(user, "<span class='notice'>You reverse the circulator's valve settings. The inlet of the circulator is now on the [get_inlet_side(dir)] side.</span>")
desc = "A gas circulator pump and heat exchanger. Its input port is on the [get_inlet_side(dir)] side, and its output port is on the [get_outlet_side(dir)] side."
/obj/machinery/atmospherics/binary/circulator/update_icon()
..()
@@ -344,27 +344,6 @@
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, TRUE)
/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0,user))
to_chat(user, "<span class='notice'>Now welding the vent.</span>")
if(do_after(user, 20 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
playsound(src.loc, WT.usesound, 50, 1)
if(!welded)
user.visible_message("[user] welds the vent shut.", "You weld the vent shut.", "You hear welding.")
welded = 1
update_icon()
else
user.visible_message("[user] unwelds the vent.", "You unweld the vent.", "You hear welding.")
welded = 0
update_icon()
else
to_chat(user, "<span class='notice'>The welding tool needs to be on to start this task.</span>")
return 1
else
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return 1
if(istype(W, /obj/item/screwdriver))
if(!welded)
if(open)
@@ -400,6 +379,23 @@
return ..()
/obj/machinery/atmospherics/unary/vent_pump/welder_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_use_check(user, 0))
return
WELDER_ATTEMPT_WELD_MESSAGE
if(I.use_tool(src, user, 20, volume = I.tool_volume))
if(!welded)
welded = TRUE
visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
"<span class='notice'>You weld [src] shut!</span>")
else
welded = FALSE
visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
"<span class='notice'>You unweld [src]!</span>")
update_icon()
/obj/machinery/atmospherics/unary/vent_pump/attack_hand()
if(!welded)
if(open)
@@ -393,27 +393,6 @@
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, TRUE)
/obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/W as obj, var/mob/user as mob, params)
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0,user))
to_chat(user, "<span class='notice'>Now welding the scrubber.</span>")
if(do_after(user, 20 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
playsound(get_turf(src), WT.usesound, 50, 1)
if(!welded)
user.visible_message("[user] welds the scrubber shut.", "You weld the vent scrubber.", "You hear welding.")
welded = 1
update_icon()
else
user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.")
welded = 0
update_icon()
else
to_chat(user, "<span class='notice'>The welding tool needs to be on to start this task.</span>")
return 1
else
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return 1
if(istype(W, /obj/item/multitool))
update_multitool_menu(user)
return 1
@@ -423,3 +402,19 @@
return 1
return ..()
/obj/machinery/atmospherics/unary/vent_scrubber/welder_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_use_check(user, 0))
return
WELDER_ATTEMPT_WELD_MESSAGE
if(I.use_tool(src, user, 20, volume = I.tool_volume))
if(!welded)
welded = TRUE
visible_message("<span class='notice'>[user] welds [src] shut!</span>",\
"<span class='notice'>You weld [src] shut!</span>")
else
welded = FALSE
visible_message("<span class='notice'>[user] unwelds [src]!</span>",\
"<span class='notice'>You unweld [src]!</span>")
update_icon()
+1 -1
View File
@@ -486,7 +486,7 @@ turf/simulated/proc/consider_superconductivity(starting)
turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space
if(temperature > T0C) //Considering 0 degC as te break even point for radiation in and out
var/delta_temperature = (temperature_archived - 2.7) //hardcoded space temperature
var/delta_temperature = (temperature_archived - TCMB) //hardcoded space temperature
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
var/heat = thermal_conductivity*delta_temperature* \
+1
View File
@@ -107,6 +107,7 @@
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)
#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable)
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable)
#define COMSIG_CROSSED_MOVABLE "crossed_movable" //when we cross over something (calling Crossed() on that atom)
#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable)
#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable)
#define COMPONENT_MOVABLE_BLOCK_UNCROSS 1
+2 -2
View File
@@ -319,7 +319,7 @@
#define INVESTIGATE_BOMB "bombs"
// The SQL version required by this version of the code
#define SQL_VERSION 9
#define SQL_VERSION 11
// Vending machine stuff
#define CAT_NORMAL 1
@@ -384,7 +384,7 @@
#define EXPLOSIVE_WALL_GROUP_SYNDICATE_BASE "syndicate_base"
// Filters
#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, border=4, color="#04080FAA")
#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, color="#04080FAA")
//Fullscreen overlay resolution in tiles.
#define FULLSCREEN_OVERLAY_RESOLUTION_X 15
-1
View File
@@ -10,7 +10,6 @@
// justice if someone's abusing your role
#define ROLE_SYNDICATE "Syndicate"
#define ROLE_TRAITOR "traitor"
#define ROLE_MINDSLAVE "mindslave"
#define ROLE_OPERATIVE "operative"
#define ROLE_CHANGELING "changeling"
#define ROLE_WIZARD "wizard"
+46
View File
@@ -0,0 +1,46 @@
#define TOOL_CROWBAR "crowbar"
#define TOOL_MULTITOOL "multitool"
#define TOOL_SCREWDRIVER "screwdriver"
#define TOOL_WIRECUTTER "wirecutter"
#define TOOL_WRENCH "wrench"
#define TOOL_WELDER "welder"
#define MIN_TOOL_SOUND_DELAY 20
//Crowbar messages
#define CROWBAR_ATTEMPT_PRY_CIRCUIT_MESSAGE user.visible_message("<span class='notice'>[user] begins removing the circuit board from [src]...</span>", "<span class='notice'>You begin removing the circuit board from [src]...</span>", "<span class='warning'>You hear prying noises.</span>")
#define CROWBAR_PRY_CIRCUIT_SUCCESS_MESSAGE user.visible_message("<span class='notice'>[user] pries out the circuit board from [src]!</span>", "<span class='notice'>You pry out the circuit board from [src]!</span>", "<span class='warning'>You hear prying noises.</span>")
//Screwdriver messages
#define SCREWDRIVER_SCREW_MESSAGE user.visible_message("<span class='notice'>[user] tightens the screws on [src]!</span>", "<span class='notice'>You tighten the screws on [src]!</span>", "<span class='warning'>You hear a screwdriver.</span>")
#define SCREWDRIVER_UNSCREW_MESSAGE user.visible_message("<span class='notice'>[user] loosens the screws on [src]!</span>", "<span class='notice'>You loosen the screws on [src]!</span>", "<span class='warning'>You hear a screwdriver.</span>")
#define SCREWDRIVER_OPEN_PANEL_MESSAGE user.visible_message("<span class='notice'>[user] opens the panel on [src]!</span>", "<span class='notice'>You open the panel on [src]!</span>", "<span class='warning'>You hear a screwdriver.</span>")
#define SCREWDRIVER_CLOSE_PANEL_MESSAGE user.visible_message("<span class='notice'>[user] closes the panel on [src]!</span>", "<span class='notice'>You close the panel on [src]!</span>", "<span class='warning'>You hear a screwdriver.</span>")
//Wirecutter messages
#define WIRECUTTER_SNIP_MESSAGE user.visible_message("<span class='notice'>[user] cuts the wires from [src]!</span>", "<span class='notice'>You cut the wires from [src]!</span>", "<span class='warning'>You hear snipping.</span>")
#define WIRECUTTER_ATTEMPT_DISMANTLE_MESSAGE user.visible_message("<span class='notice'>[user] begins cutting [src] apart... </span>", "<span class='notice'>You begin cutting [src] apart...</span>", "<span class='warning'>You hear snipping.</span>")
#define WIRECUTTER_DISMANTLE_SUCCESS_MESSAGE user.visible_message("<span class='notice'>[user] cuts [src] apart!</span>", "<span class='notice'>You cut [src] apart!</span>", "<span class='warning'>You hear snipping.</span>")
//Welder messages and other stuff
#define HEALPERWELD 15
#define WELDER_ATTEMPT_WELD_MESSAGE user.visible_message("<span class='notice'>[user] begins welding [src]...</span>", "<span class='notice'>You begin welding [src]...</span>", "<span class='warning'>You hear welding.</span>")
#define WELDER_WELD_SUCCESS_MESSAGE to_chat(user, "<span class='notice'>You finish welding [src]!</span>")
#define WELDER_ATTEMPT_REPAIR_MESSAGE user.visible_message("<span class='notice'>[user] begins repairing the damage on [src]...</span>", "<span class='notice'>You begin repairing [src]...</span>", "<span class='warning'>You hear welding.</span>")
#define WELDER_REPAIR_SUCCESS_MESSAGE to_chat(user, "<span class='notice'>You repair the damage on [src]!</span>")
#define WELDER_ATTEMPT_SLICING_MESSAGE user.visible_message("<span class='notice'>[user] begins slicing through [src]...</span>", "<span class='notice'>You begin slicing through [src]...</span>", "<span class='warning'>You hear welding.</span>")
#define WELDER_SLICING_SUCCESS_MESSAGE to_chat(user, "<span class='notice'>You slice clean through [src]!</span>")
#define WELDER_ATTEMPT_FLOOR_SLICE_MESSAGE user.visible_message("<span class='notice'>[user] begins slicing [src] free from [get_turf(src)]...</span>", "<span class='notice'>You begin slicing [src] free from [get_turf(src)]...</span>", "<span class='warning'>You hear welding.</span>")
#define WELDER_FLOOR_SLICE_SUCCESS_MESSAGE to_chat(user, "<span class='notice'>You slice [src] clear of [get_turf(src)]!</span>")
#define WELDER_ATTEMPT_FLOOR_WELD_MESSAGE user.visible_message("<span class='notice'>[user] begins welding [src] to [get_turf(src)]...</span>", "<span class='notice'>You begin welding [src] to [get_turf(src)]...</span>", "<span class='warning'>You hear welding.</span>")
#define WELDER_FLOOR_WELD_SUCCESS_MESSAGE to_chat(user, "<span class='notice'>You weld [src] to [get_turf(src)]!</span>")
//Wrench messages
#define WRENCH_ANCHOR_MESSAGE user.visible_message("<span class='notice'>[user] tightens the bolts on [src]!</span>", "<span class='notice'>You tighten the bolts on [src]!</span>", "<span class='warning'>You hear ratcheting.</span>")
#define WRENCH_UNANCHOR_MESSAGE user.visible_message("<span class='notice'>[user] loosens the bolts on [src]!</span>", "<span class='notice'>You loosen the bolts on [src]!</span>", "<span class='warning'>You hear ratcheting.</span>")
#define WRENCH_UNANCHOR_WALL_MESSAGE user.visible_message("<span class='notice'>[user] unwrenches [src] from the wall!</span>", "<span class='notice'>You unwrench [src] from the wall!</span>", "<span class='warning'>You hear ratcheting.</span>")
#define WRENCH_ANCHOR_TO_WALL_MESSAGE user.visible_message("<span class='notice'>[user] affixes [src] to the wall!</span>", "<span class='notice'>You affix [src] to the wall!</span>", "<span class='warning'>You hear ratcheting.</span>")
//Generic tool messages that don't correspond to any particular tool
#define TOOL_ATTEMPT_DISMANTLE_MESSAGE user.visible_message("<span class='notice'>[user] begins to disassemble [src] with [I]...</span>", "<span class='notice'>You begin to disassemble [src] with [I]...</span>", "<span class='warning'>You hear someone using some kind of tool.</span>")
#define TOOL_DISMANTLE_SUCCESS_MESSAGE user.visible_message("<span class='notice'>[user] dismantles [src]!</span>", "<span class='notice'>You dismantle [src]!</span>", "<span class='warning'>You hear someone using some kind of tool.</span>")
+1 -1
View File
@@ -2,5 +2,5 @@
#define TYPEID_NULL "0"
#define TYPEID_NORMAL_LIST "f"
//helper macros
#define GET_TYPEID(ref) ( ( (lentext(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, lentext(ref) - 6) ) )
#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, length(ref) - 6) ) )
#define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST)
+4 -1
View File
@@ -1,5 +1,5 @@
//location of the rust-g library
#define RUST_G "rust_g"
#define RUST_G (world.system_type == UNIX ? "./librust_g.so" : "./rust_g.dll")
// On Linux/Unix systems the line endings are LF, on windows it's CRLF, admins that don't use notepad++
// will get logs that are one big line if the system is Linux and they are using notepad. This solves it by adding CR to every line ending
@@ -140,6 +140,9 @@
/proc/log_asset(text)
WRITE_LOG(GLOB.world_asset_log, "ASSET: [text]")
/proc/log_runtime_summary(text)
WRITE_LOG(GLOB.runtime_summary_log, "[text]")
/**
* Standardized method for tracking startup times.
*/
+4 -1
View File
@@ -478,7 +478,10 @@ proc/pollCandidates(Question, be_special_type, antag_age_check = FALSE, poll_tim
G << 'sound/misc/notice2.ogg'//Alerting them to their consideration
if(flashwindow)
window_flash(G.client)
switch(alert(G,Question,"Please answer in [poll_time/10] seconds!","No","Yes","Not This Round"))
var/ans = alert(G,Question,"Please answer in [poll_time/10] seconds!","No","Yes","Not This Round")
if(!G?.client)
return
switch(ans)
if("Yes")
to_chat(G, "<span class='notice'>Choice registered: Yes.</span>")
if((world.time-time_passed)>poll_time)//If more than 30 game seconds passed.
-5
View File
@@ -69,11 +69,6 @@
return list[index]
return
/proc/islist(list/list)
if(istype(list))
return 1
return 0
//Return either pick(list) or null if list is not of type /list or is empty
/proc/safepick(list/list)
if(!islist(list) || !list.len)
+11 -12
View File
@@ -20,7 +20,7 @@
if(!istext(t))
t = "[t]" // Just quietly assume any non-texts are supposed to be text
var/sqltext = dbcon.Quote(t);
return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that
return copytext(sqltext, 2, length(sqltext));//Quote() adds quotes around input, we already do that
/proc/format_table_name(table as text)
return sqlfdbktableprefix + table
@@ -108,11 +108,10 @@
// Used to get a sanitized input.
/proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE)
var/name = input(user, message, title, default) as text|null
if(no_trim)
return copytext(html_encode(name), 1, max_length)
else
return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into &lt;)
var/name = html_encode(input(user, message, title, default) as text|null)
if(!no_trim)
name = trim(name) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into &lt;)
return copytext(name, 1, max_length)
// Uses client.typing to check if the popup should appear or not
/proc/typing_input(mob/user, message = "", title = "", default = "")
@@ -333,9 +332,9 @@ proc/checkhtml(var/t)
//is in the other string at the same spot (assuming it is not a replace char).
//This is used for fingerprints
var/newtext = text
if(lentext(text) != lentext(compare))
if(length(text) != length(compare))
return 0
for(var/i = 1, i < lentext(text), i++)
for(var/i = 1, i < length(text), i++)
var/a = copytext(text,i,i+1)
var/b = copytext(compare,i,i+1)
//if it isn't both the same letter, or if they are both the replacement character
@@ -355,7 +354,7 @@ proc/checkhtml(var/t)
if(!text || !character)
return 0
var/count = 0
for(var/i = 1, i <= lentext(text), i++)
for(var/i = 1, i <= length(text), i++)
var/a = copytext(text,i,i+1)
if(a == character)
count++
@@ -400,8 +399,8 @@ proc/checkhtml(var/t)
//Used in preferences' SetFlavorText and human's set_flavor verb
//Previews a string of len or less length
/proc/TextPreview(var/string,var/len=40)
if(lentext(string) <= len)
if(!lentext(string))
if(length(string) <= len)
if(!length(string))
return "\[...\]"
else
return html_encode(string) //NO DECODED HTML YOU CHUCKLEFUCKS
@@ -541,7 +540,7 @@ proc/checkhtml(var/t)
text = "<font face=\"[deffont]\" color=[P ? P.colour : "black"]>[text]</font>"
else
text = "<font face=\"[deffont]\">[text]</font>"
text = copytext(text, 1, MAX_PAPER_MESSAGE_LEN)
return text
+51
View File
@@ -0,0 +1,51 @@
//Quick type checks for some tools
/proc/iswrench(O)
if(istype(O, /obj/item/wrench))
return TRUE
return FALSE
/proc/iswelder(O)
if(istype(O, /obj/item/weldingtool))
return TRUE
return FALSE
/proc/iswirecutter(O)
if(istype(O, /obj/item/wirecutters))
return TRUE
return FALSE
/proc/isscrewdriver(O)
if(istype(O, /obj/item/screwdriver))
return TRUE
return FALSE
/proc/ismultitool(O)
if(istype(O, /obj/item/multitool))
return TRUE
return FALSE
/proc/iscrowbar(O)
if(istype(O, /obj/item/crowbar))
return TRUE
return FALSE
/proc/iscoil(O)
if(istype(O, /obj/item/stack/cable_coil))
return TRUE
return FALSE
/proc/ispowertool(O)//used to check if a tool can force powered doors
if(istype(O, /obj/item/crowbar/power) || istype(O, /obj/item/mecha_parts/mecha_equipment/medical/rescue_jaw))
return TRUE
return FALSE
/proc/is_surgery_tool(obj/item/W as obj)
return ( \
istype(W, /obj/item/scalpel) || \
istype(W, /obj/item/hemostat) || \
istype(W, /obj/item/retractor) || \
istype(W, /obj/item/cautery) || \
istype(W, /obj/item/bonegel) || \
istype(W, /obj/item/bonesetter)
)
+1
View File
@@ -62,6 +62,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
//mob traits
#define TRAIT_PACIFISM "pacifism"
#define TRAIT_WATERBREATH "waterbreathing"
// common trait sources
#define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention
+14 -74
View File
@@ -540,9 +540,20 @@ Returns 1 if the chain up to the area contains the given typepath
/proc/between(var/low, var/middle, var/high)
return max(min(middle, high), low)
proc/arctan(x)
#if DM_VERSION > 513
#warn 513 is definitely stable now, remove this
#endif
#if DM_VERSION < 513
/proc/arctan(x)
var/y=arcsin(x/sqrt(1+x*x))
return y
/proc/islist(list/list)
if(istype(list))
return 1
return 0
#endif
//returns random gauss number
proc/GaussRand(var/sigma)
@@ -1131,70 +1142,9 @@ var/list/can_embed_types = typecacheof(list(
if(is_type_in_typecache(W, can_embed_types))
return 1
//Quick type checks for some tools
var/global/list/common_tools = list(
/obj/item/stack/cable_coil,
/obj/item/wrench,
/obj/item/weldingtool,
/obj/item/screwdriver,
/obj/item/wirecutters,
/obj/item/multitool,
/obj/item/crowbar)
/proc/istool(O)
if(O && is_type_in_list(O, common_tools))
return 1
return 0
/proc/iswrench(O)
if(istype(O, /obj/item/wrench))
return 1
return 0
/proc/iswelder(O)
if(istype(O, /obj/item/weldingtool))
return 1
return 0
/proc/iscoil(O)
if(istype(O, /obj/item/stack/cable_coil))
return 1
return 0
/proc/iswirecutter(O)
if(istype(O, /obj/item/wirecutters))
return 1
return 0
/proc/isscrewdriver(O)
if(istype(O, /obj/item/screwdriver))
return 1
return 0
/proc/ismultitool(O)
if(istype(O, /obj/item/multitool))
return 1
return 0
/proc/iscrowbar(O)
if(istype(O, /obj/item/crowbar))
return 1
return 0
/proc/ispowertool(O)//used to check if a tool can force powered doors
if(istype(O, /obj/item/crowbar/power) || istype(O, /obj/item/mecha_parts/mecha_equipment/medical/rescue_jaw))
return TRUE
return FALSE
/proc/iswire(O)
if(istype(O, /obj/item/stack/cable_coil))
return 1
return 0
/proc/is_hot(obj/item/W as obj)
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/O = W
if(O.isOn())
if(W.tool_behaviour == TOOL_WELDER)
if(W.tool_enabled)
return 2500
else
return 0
@@ -1249,16 +1199,6 @@ var/global/list/common_tools = list(
return 1
return 0
/proc/is_surgery_tool(obj/item/W as obj)
return ( \
istype(W, /obj/item/scalpel) || \
istype(W, /obj/item/hemostat) || \
istype(W, /obj/item/retractor) || \
istype(W, /obj/item/cautery) || \
istype(W, /obj/item/bonegel) || \
istype(W, /obj/item/bonesetter)
)
/proc/reverse_direction(var/dir)
switch(dir)
if(NORTH)
+1 -1
View File
@@ -32,7 +32,7 @@ var/Debug = 0 // global debug switch
var/Debug2 = 1 // enables detailed job debug file in secrets
//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage
var/MAX_EX_DEVESTATION_RANGE = 3
var/MAX_EX_DEVASTATION_RANGE = 3
var/MAX_EX_HEAVY_RANGE = 7
var/MAX_EX_LIGHT_RANGE = 14
var/MAX_EX_FLASH_RANGE = 14
+2
View File
@@ -12,6 +12,8 @@ GLOBAL_VAR(world_href_log)
GLOBAL_PROTECT(world_href_log)
GLOBAL_VAR(world_asset_log)
GLOBAL_PROTECT(world_asset_log)
GLOBAL_VAR(runtime_summary_log)
GLOBAL_PROTECT(runtime_summary_log)
var/list/jobMax = list()
var/list/admin_log = list ( )
+2 -2
View File
@@ -42,8 +42,8 @@
if(control_disabled || stat)
return
var/turf/pixel_turf = get_turf_pixel(A)
var/turf/pixel_turf = isturf(A) ? A : get_turf_pixel(A)
if(isnull(pixel_turf))
return
if(!can_see(A))
+1 -1
View File
@@ -16,7 +16,7 @@
filters += filter(type = "outline", size = _size, color = _color)
/obj/screen/plane_master/proc/shadow(_size, _border, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA")
filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset, border = _border)
filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset)
/obj/screen/plane_master/proc/clear_filters()
filters = list()
+12 -10
View File
@@ -1,10 +1,17 @@
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
if(pre_attackby(target, user, params))
if(!tool_attack_chain(user, target) && pre_attackby(target, user, params))
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
var/resolved = target.attackby(src, user, params)
if(!resolved && target && !QDELETED(src))
afterattack(target, user, 1, params) // 1: clicking something Adjacent
//Checks if the item can work as a tool, calling the appropriate tool behavior on the target
//Note that if tool_act returns TRUE, then the tool won't call attack_by.
/obj/item/proc/tool_attack_chain(mob/user, atom/target)
if(!tool_behaviour)
return FALSE
return target.tool_act(user, src, tool_behaviour)
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
/obj/item/proc/attack_self(mob/user)
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_NO_INTERACT)
@@ -50,17 +57,12 @@
return 0
else
return 1
if(isscrewdriver(src) && ismachine(M) && user.a_intent == INTENT_HELP)
var/obj/item/organ/external/O = M.get_organ(user.zone_selected)
if((is_sharp(src) || (isscrewdriver(src) && O.is_robotic())) && user.a_intent == INTENT_HELP)
if(!attempt_initiate_surgery(src, M, user))
return 0
return FALSE
else
return 1
if(is_sharp(src) && user.a_intent == INTENT_HELP)
if(!attempt_initiate_surgery(src, M, user))
return 0
else
return 1
return TRUE
if(force && HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='warning'>You don't want to harm other living beings!</span>")
+2
View File
@@ -61,6 +61,8 @@
// health + cyborg analyzer for ghosts
/mob/living/attack_ghost(mob/dead/observer/user)
if(!istype(user)) // Make sure user is actually an observer. Revenents also use attack_ghost, but do not have the health_scan var.
return
if(user.client && user.health_scan)
if(issilicon(src) || ismachine(src))
robot_healthscan(user, src)
+11 -3
View File
@@ -79,7 +79,7 @@
var/auto_cryo_ssd_mins = 0
var/ssd_warning = 0
var/list_afk_minimum = 5 // How long people have to be AFK before it's listed on the "List AFK players" verb
var/traitor_objectives_amount = 2
@@ -102,6 +102,7 @@
var/donationsurl = "http://example.org"
var/repositoryurl = "http://example.org"
var/discordurl = "http://example.org"
var/discordforumurl = "http://example.org"
var/overflow_server_url
var/forbid_singulo_possession = 0
@@ -144,6 +145,7 @@
var/ipintel_detailsurl = "https://iphub.info/?ip="
var/forum_link_url
var/forum_playerinfo_url
var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt
var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
@@ -244,7 +246,7 @@
//cube monkey limit
var/cubemonkeycap = 20
// Makes gamemodes respect player limits
var/enable_gamemode_player_limit = 0
@@ -354,6 +356,9 @@
if("forum_link_url")
config.forum_link_url = value
if("forum_playerinfo_url")
config.forum_playerinfo_url = value
if("log_ooc")
config.log_ooc = 1
@@ -483,6 +488,9 @@
if("discordurl")
config.discordurl = value
if("discordforumurl")
config.discordforumurl = value
if("donationsurl")
config.donationsurl = value
@@ -777,7 +785,7 @@
if(BombCap > 128)
BombCap = 128
MAX_EX_DEVESTATION_RANGE = round(BombCap/4)
MAX_EX_DEVASTATION_RANGE = round(BombCap/4)
MAX_EX_HEAVY_RANGE = round(BombCap/2)
MAX_EX_LIGHT_RANGE = BombCap
MAX_EX_FLASH_RANGE = BombCap
+2 -1
View File
@@ -11,7 +11,8 @@ SUBSYSTEM_DEF(chat)
/datum/controller/subsystem/chat/fire()
for(var/i in payload)
var/client/C = i
C << output(payload[C], "browseroutput:output")
if(C)
C << output(payload[C], "browseroutput:output")
payload -= C
if(MC_TICK_CHECK)
@@ -29,6 +29,7 @@ SUBSYSTEM_DEF(idlenpcpool)
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
--currentrun.len
if(!SA)
log_debug("idlenpcpool encountered an invalid entry, resumed: [resumed], SA [SA], type of SA [SA?.type], null [SA == null], qdelled [QDELETED(SA)], SA in AI_IDLE list: [SA in GLOB.simple_animals[AI_IDLE]]")
GLOB.simple_animals[AI_IDLE] -= SA
continue
+11 -11
View File
@@ -421,25 +421,25 @@ SUBSYSTEM_DEF(jobs)
to_chat(H, "<B>You are the [alt_title ? alt_title : rank].</B>")
to_chat(H, "<b>As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.</b>")
to_chat(H, "<b>For more information on how the station works, see <a href=\"https://nanotrasen.se/wiki/index.php/Standard_Operating_Procedure\">Standard Operating Procedure (SOP)</a></b>")
to_chat(H, "<b>For more information on how the station works, see <a href=\"https://www.paradisestation.org/wiki/index.php/Standard_Operating_Procedure\">Standard Operating Procedure (SOP)</a></b>")
if(job.is_service)
to_chat(H, "<b>As a member of Service, make sure to read up on your <a href=\"https://nanotrasen.se/wiki/index.php/Standard_Operating_Procedure_&#40;Service&#41\">Department SOP</a></b>")
to_chat(H, "<b>As a member of Service, make sure to read up on your <a href=\"https://www.paradisestation.org/wiki/index.php/Standard_Operating_Procedure_&#40;Service&#41\">Department SOP</a></b>")
if(job.is_supply)
to_chat(H, "<b>As a member of Supply, make sure to read up on your <a href=\"https://nanotrasen.se/wiki/index.php/Standard_Operating_Procedure_&#40;Supply&#41\">Department SOP</a></b>")
to_chat(H, "<b>As a member of Supply, make sure to read up on your <a href=\"https://www.paradisestation.org/wiki/index.php/Standard_Operating_Procedure_&#40;Supply&#41\">Department SOP</a></b>")
if(job.is_command)
to_chat(H, "<b>As an important member of Command, read up on your <a href=\"https://nanotrasen.se/wiki/index.php/Standard_Operating_Procedure_&#40;Command&#41\">Department SOP</a></b>")
to_chat(H, "<b>As an important member of Command, read up on your <a href=\"https://www.paradisestation.org/wiki/index.php/Standard_Operating_Procedure_&#40;Command&#41\">Department SOP</a></b>")
if(job.is_legal)
to_chat(H, "<b>Your job requires complete knowledge of <a href=\"https://nanotrasen.se/wiki/index.php/Space_law\">Space Law</a> and <a href=\"https://nanotrasen.se/wiki/index.php/Legal_Standard_Operating_Procedure\">Legal Standard Operating Procedure</a></b>")
to_chat(H, "<b>Your job requires complete knowledge of <a href=\"https://www.paradisestation.org/wiki/index.php/Space_law\">Space Law</a> and <a href=\"https://www.paradisestation.org/wiki/index.php/Legal_Standard_Operating_Procedure\">Legal Standard Operating Procedure</a></b>")
if(job.is_engineering)
to_chat(H, "<b>As a member of Engineering, make sure to read up on your <a href=\"https://nanotrasen.se/wiki/index.php/Standard_Operating_Procedure_&#40;Engineering&#41\">Department SOP</a></b>")
to_chat(H, "<b>As a member of Engineering, make sure to read up on your <a href=\"https://www.paradisestation.org/wiki/index.php/Standard_Operating_Procedure_&#40;Engineering&#41\">Department SOP</a></b>")
if(job.is_medical)
to_chat(H, "<b>As a member of Medbay, make sure to read up on your <a href=\"https://nanotrasen.se/wiki/index.php/Standard_Operating_Procedure_&#40;Medical&#41\">Department SOP</a></b>")
to_chat(H, "<b>As a member of Medbay, make sure to read up on your <a href=\"https://www.paradisestation.org/wiki/index.php/Standard_Operating_Procedure_&#40;Medical&#41\">Department SOP</a></b>")
if(job.is_science)
to_chat(H, "<b>As a member of Science, make sure to read up on your <a href=\"https://nanotrasen.se/wiki/index.php/Standard_Operating_Procedure_&#40;Science&#41\">Department SOP</a></b>")
to_chat(H, "<b>As a member of Science, make sure to read up on your <a href=\"https://www.paradisestation.org/wiki/index.php/Standard_Operating_Procedure_&#40;Science&#41\">Department SOP</a></b>")
if(job.is_security)
to_chat(H, "<b>As a member of Security, you are to know <a href=\"https://nanotrasen.se/wiki/index.php/Space_law\">Space Law</a>, <a href=\"https://nanotrasen.se/wiki/index.php/Legal_Standard_Operating_Procedure\">Legal Standard Operating Procedure</a>, as well as your <a href=\"https://nanotrasen.se/wiki/index.php/Standard_Operating_Procedure_&#40;Security&#41\">Department SOP</a></b>")
to_chat(H, "<b>As a member of Security, you are to know <a href=\"https://www.paradisestation.org/wiki/index.php/Space_law\">Space Law</a>, <a href=\"https://www.paradisestation.org/wiki/index.php/Legal_Standard_Operating_Procedure\">Legal Standard Operating Procedure</a>, as well as your <a href=\"https://www.paradisestation.org/wiki/index.php/Standard_Operating_Procedure_&#40;Security&#41\">Department SOP</a></b>")
if(job.req_admin_notify)
to_chat(H, "<b>You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.</b>")
to_chat(H, "<b>You are playing a job that is important for the game progression. If you have to disconnect, please go to cryo and inform command. If you are unable to do so, please notify the admins via adminhelp.</b>")
return H
/datum/controller/subsystem/jobs/proc/EquipRank(mob/living/carbon/human/H, rank, joined_late = 0) // Equip and put them in an area
@@ -690,4 +690,4 @@ SUBSYSTEM_DEF(jobs)
.++
new_id_change_records["[id_change_counter]"] = thisrecord
id_change_counter++
id_change_records = new_id_change_records
id_change_records = new_id_change_records
+4
View File
@@ -21,6 +21,10 @@ SUBSYSTEM_DEF(npcpool)
while(currentrun.len)
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
--currentrun.len
if(!SA)
log_debug("npcpool encountered an invalid entry, resumed: [resumed], SA [SA], type of SA [SA?.type], null [SA == null], qdelled [QDELETED(SA)], SA in AI_ON list: [SA in GLOB.simple_animals[AI_ON]]")
GLOB.simple_animals[AI_ON] -= SA
continue
if(!SA.ckey && !SA.notransform)
if(SA.stat != DEAD)
@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(tickets)
flags = SS_BACKGROUND
var/list/allTickets
var/list/allTickets = list() //make it here because someone might ahelp before the system has initialized
var/ticketCounter = 1
@@ -31,7 +31,6 @@ SUBSYSTEM_DEF(tickets)
close_messages = list("<font color='red' size='4'><b>- [ticket_name] Rejected! -</b></font>",
"<span class='boldmessage'>Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.</span>",
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
LAZYINITLIST(allTickets)
return ..()
/datum/controller/subsystem/tickets/fire()
+1 -1
View File
@@ -52,7 +52,7 @@ SUBSYSTEM_DEF(vote)
voting.Cut()
current_votes.Cut()
if(auto_muted && !config.ooc_allowed)
if(auto_muted && !config.ooc_allowed && !(config.auto_toggle_ooc_during_round && SSticker.current_state == GAME_STATE_PLAYING))
auto_muted = 0
config.ooc_allowed = !( config.ooc_allowed )
to_chat(world, "<b>The OOC channel has been automatically enabled due to vote end.</b>")
+4
View File
@@ -41,6 +41,10 @@
use_delay = use_delay_override
/datum/component/squeak/proc/play_squeak()
if(ismob(parent))
var/mob/M = parent
if(M.stat == DEAD)
return
if(prob(squeak_chance))
if(!override_squeak_sounds)
playsound(parent, pickweight(default_squeak_sounds), volume, 1, -1)
+1 -1
View File
@@ -548,7 +548,7 @@
to_chat(usr, "This can only be used on instances of type /mob")
return
var/new_name = reject_bad_name(sanitize(copytext(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null,1,MAX_NAME_LEN)))
var/new_name = reject_bad_name(sanitize(copytext(input(usr, "What would you like to name this mob?", "Input a name", M.real_name) as text|null, 1, MAX_NAME_LEN)), allow_numbers = TRUE)
if( !new_name || !M ) return
message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].")
+33 -40
View File
@@ -1,5 +1,6 @@
#define FORWARD -1
#define BACKWARD 1
#define CONSTRUCTION_TOOL_BEHAVIOURS list(TOOL_CROWBAR, TOOL_SCREWDRIVER, TOOL_WELDER, TOOL_WRENCH)
/datum/construction
var/list/steps
@@ -38,30 +39,13 @@
/datum/construction/proc/is_right_key(atom/used_atom) // returns current step num if used_atom is of the right type.
var/list/L = steps[steps.len]
if(istype(used_atom, L["key"]))
if(do_tool_or_atom_check(used_atom, L["key"]))
return steps.len
return 0
/datum/construction/proc/custom_action(step, used_atom, user)
if(istype(used_atom, /obj/item/weldingtool))
var/obj/item/weldingtool/W = used_atom
if(W.remove_fuel(0, user))
playsound(holder, W.usesound, 50, 1)
else
return 0
else if(istype(used_atom, /obj/item/wrench))
var/obj/item/wrench/W = used_atom
playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/screwdriver))
var/obj/item/screwdriver/S = used_atom
playsound(holder, S.usesound, 50, 1)
else if(istype(used_atom, /obj/item/wirecutters))
var/obj/item/wirecutters/W = used_atom
playsound(holder, W.usesound, 50, 1)
else if(istype(used_atom, /obj/item/stack/cable_coil))
if(istype(used_atom, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = used_atom
if(C.amount<4)
to_chat(user, ("<span class='warning'>There's not enough cable to finish the task.</span>"))
@@ -76,18 +60,22 @@
return 0
else
S.use(5)
else if(isitem(used_atom))
var/obj/item/I = used_atom
if(I.tool_behaviour in CONSTRUCTION_TOOL_BEHAVIOURS)
if(!I.use_tool(holder, user, 0, volume = I.tool_volume))
return 0
return 1
/datum/construction/proc/check_all_steps(atom/used_atom,mob/user as mob) //check all steps, remove matching one.
for(var/i=1;i<=steps.len;i++)
var/list/L = steps[i];
if(istype(used_atom, L["key"]))
if(custom_action(i, used_atom, user))
steps[i]=null;//stupid byond list from list removal...
listclearnulls(steps);
if(!steps.len)
spawn_result(user)
return 1
if(do_tool_or_atom_check(used_atom, L["key"]) && custom_action(i, used_atom, user))
steps[i]=null;//stupid byond list from list removal...
listclearnulls(steps);
if(!steps.len)
spawn_result(user)
return 1
return 0
@@ -116,15 +104,12 @@
if(!coil.use(amount))
to_chat(user, "<span class='warning'>You don't have enough cable! You need at least [amount] coils.</span>")
return 0
// WELDER
if(istype(used_atom,/obj/item/weldingtool))
var/obj/item/weldingtool/welder=used_atom
if(!welder.isOn())
to_chat(user, "<span class='notice'>You tap the [src] with your unlit welder. [pick("Ding","Dong")].</span>")
return 0
if(!welder.remove_fuel(amount,user))
to_chat(user, "<span class='warning'>You don't have enough fuel!</span>")
return 0
// TOOLS
if(isitem(used_atom))
var/obj/item/I = used_atom
if(I.tool_behaviour in CONSTRUCTION_TOOL_BEHAVIOURS)
if(!I.use(amount))
return 0
// STACKS
if(istype(used_atom,/obj/item/stack))
var/obj/item/stack/stack=used_atom
@@ -134,6 +119,14 @@
stack.use(amount)
return 1
/datum/construction/proc/do_tool_or_atom_check(used_atom, thing_to_check) //Checks if an atom is either a required thing; or if it's a required tool
if(istype(used_atom, thing_to_check))
return TRUE
else if(isitem(used_atom))
var/obj/item/I = used_atom
if(I.tool_behaviour == thing_to_check)
return TRUE
/datum/construction/reversible
var/index
@@ -152,9 +145,9 @@
/datum/construction/reversible/is_right_key(atom/used_atom) // returns index step
var/list/L = steps[index]
if(istype(used_atom, L["key"]))
if(do_tool_or_atom_check(used_atom, L["key"]))
return FORWARD //to the first step -> forward
else if(L["backkey"] && istype(used_atom, L["backkey"]))
else if(L["backkey"] && do_tool_or_atom_check(used_atom, L["backkey"]))
return BACKWARD //to the last step -> backwards
return 0
@@ -198,13 +191,13 @@
var/list/state = steps[index]
if(state_next in state)
var/list/step = state[state_next]
if(istype(used_atom, step["key"]))
if(do_tool_or_atom_check(used_atom, step["key"]))
//if(L["consume"] && !try_consume(used_atom,L["consume"]))
// return 0
return FORWARD //to the first step -> forward
else if(state_prev in state)
var/list/step = state[state_prev]
if(istype(used_atom, step["key"]))
if(do_tool_or_atom_check(used_atom, step["key"]))
//if(L["consume"] && !try_consume(used_atom,L["consume"]))
// return 0
return BACKWARD //to the first step -> forward
+1 -3
View File
@@ -225,9 +225,7 @@
/datum/mind/proc/memory_edit_cult(mob/living/carbon/human/H)
. = _memory_edit_header("cult")
if(ismindshielded(H))
. += "<B>NO</B>|cultist"
else if(src in SSticker.mode.cult)
if(src in SSticker.mode.cult)
. += "<a href='?src=[UID()];cult=clear'>no</a>|<b><font color='red'>CULTIST</font></b>"
. += "<br>Give <a href='?src=[UID()];cult=tome'>tome</a>|<a href='?src=[UID()];cult=equip'>equip</a>."
else
+4 -1
View File
@@ -25,10 +25,13 @@
var/A = null
if(!randomise_selection)
A = input("Area to teleport to", "Teleport", A) in teleportlocs
A = input("Area to teleport to", "Teleport", A) as null|anything in teleportlocs
else
A = pick(teleportlocs)
if(!A)
return
var/area/thearea = teleportlocs[A]
if(thearea.tele_proof && !istype(thearea, /area/wizard_station))
+1 -1
View File
@@ -17,7 +17,7 @@
var/obj/item/organ/internal/brain/cluwne/idiot_brain = new
idiot_brain.insert(src, make_cluwne = 0)
idiot_brain.dna = dna.Clone()
setBrainLoss(80)
setBrainLoss(80, use_brain_mod = FALSE)
set_nutrition(9000)
overeatduration = 9000
Confused(30)
+28 -30
View File
@@ -52,73 +52,71 @@
marked_item = null
else //Getting previously marked item
var/obj/item_to_retrive = marked_item
var/obj/item_to_retrieve = marked_item
var/infinite_recursion = 0 //I don't want to know how someone could put something inside itself but these are wizards so let's be safe
while(!isturf(item_to_retrive.loc) && infinite_recursion < 10) //if it's in something you get the whole thing.
if(ismob(item_to_retrive.loc)) //If its on someone, properly drop it
var/mob/M = item_to_retrive.loc
while(!isturf(item_to_retrieve.loc) && infinite_recursion < 10) //if it's in something you get the whole thing.
if(ismob(item_to_retrieve.loc)) //If its on someone, properly drop it
var/mob/M = item_to_retrieve.loc
if(issilicon(M)) //Items in silicons warp the whole silicon
M.loc.visible_message("<span class='warning'>[M] suddenly disappears!</span>")
M.loc = target.loc
if(issilicon(M) || !M.unEquip(item_to_retrieve)) //Items in silicons warp the whole silicon
M.visible_message("<span class='warning'>[M] suddenly disappears!</span>", "<span class='danger'>A force suddenly pulls you away!</span>")
M.forceMove(target.loc)
M.loc.visible_message("<span class='caution'>[M] suddenly appears!</span>")
item_to_retrive = null
item_to_retrieve = null
break
M.unEquip(item_to_retrive)
if(ishuman(M)) //Edge case housekeeping
var/mob/living/carbon/human/C = M
/*if(C.internal_bodyparts_by_name && item_to_retrive in C.internal_bodyparts_by_name ) //This won't work, as we use organ datums instead of objects. --DZD
C.internal_bodyparts_by_name -= item_to_retrive
/*if(C.internal_bodyparts_by_name && item_to_retrieve in C.internal_bodyparts_by_name ) //This won't work, as we use organ datums instead of objects. --DZD
C.internal_bodyparts_by_name -= item_to_retrieve
if(istype(marked_item, /obj/item/brain)) //If this code ever runs I will be happy
var/obj/item/brain/B = new /obj/item/brain(target.loc)
B.transfer_identity(C)
C.death()
add_attack_logs(target, C, "Magically debrained INTENT: [uppertext(target.a_intent)]")*/
if(C.stomach_contents && item_to_retrive in C.stomach_contents)
C.stomach_contents -= item_to_retrive
if(C.stomach_contents && item_to_retrieve in C.stomach_contents)
C.stomach_contents -= item_to_retrieve
for(var/X in C.bodyparts)
var/obj/item/organ/external/part = X
if(item_to_retrive in part.embedded_objects)
part.embedded_objects -= item_to_retrive
to_chat(C, "<span class='warning'>The [item_to_retrive] that was embedded in your [part] has mysteriously vanished. How fortunate!</span>")
if(item_to_retrieve in part.embedded_objects)
part.embedded_objects -= item_to_retrieve
to_chat(C, "<span class='warning'>The [item_to_retrieve] that was embedded in your [part] has mysteriously vanished. How fortunate!</span>")
if(!C.has_embedded_objects())
C.clear_alert("embeddedobject")
break
else
if(istype(item_to_retrive.loc,/obj/machinery/portable_atmospherics/)) //Edge cases for moved machinery
var/obj/machinery/portable_atmospherics/P = item_to_retrive.loc
if(istype(item_to_retrieve.loc,/obj/machinery/portable_atmospherics/)) //Edge cases for moved machinery
var/obj/machinery/portable_atmospherics/P = item_to_retrieve.loc
P.disconnect()
P.update_icon()
if(istype(item_to_retrive.loc, /obj/structure/disposalholder) || istype(item_to_retrive.loc, /obj/machinery/disposal))//fixes the breaking of disposals. No more bluespace connected disposal bins!
if(istype(item_to_retrieve.loc, /obj/structure/disposalholder) || istype(item_to_retrieve.loc, /obj/machinery/disposal))//fixes the breaking of disposals. No more bluespace connected disposal bins!
break
item_to_retrive = item_to_retrive.loc
item_to_retrieve = item_to_retrieve.loc
infinite_recursion += 1
if(!item_to_retrive)
if(!item_to_retrieve)
return
item_to_retrive.loc.visible_message("<span class='warning'>The [item_to_retrive.name] suddenly disappears!</span>")
item_to_retrieve.loc.visible_message("<span class='warning'>The [item_to_retrieve.name] suddenly disappears!</span>")
if(target.hand) //left active hand
if(!target.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1))
if(!target.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1))
if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_l_hand, 0, 1, 1))
if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_r_hand, 0, 1, 1))
butterfingers = 1
else //right active hand
if(!target.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1))
if(!target.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1))
if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_r_hand, 0, 1, 1))
if(!target.equip_to_slot_if_possible(item_to_retrieve, slot_l_hand, 0, 1, 1))
butterfingers = 1
if(butterfingers)
item_to_retrive.loc = target.loc
item_to_retrive.loc.visible_message("<span class='caution'>The [item_to_retrive.name] suddenly appears!</span>")
item_to_retrieve.loc = target.loc
item_to_retrieve.loc.visible_message("<span class='caution'>The [item_to_retrieve.name] suddenly appears!</span>")
playsound(get_turf(target),'sound/magic/summonitems_generic.ogg',50,1)
else
item_to_retrive.loc.visible_message("<span class='caution'>The [item_to_retrive.name] suddenly appears in [target]'s hand!</span>")
item_to_retrieve.loc.visible_message("<span class='caution'>The [item_to_retrieve.name] suddenly appears in [target]'s hand!</span>")
playsound(get_turf(target),'sound/magic/summonitems_generic.ogg',50,1)
if(message)
+1 -2
View File
@@ -54,8 +54,7 @@ var/const/AALARM_WIRE_AALARM = 16
// to_chat(world, "Power wire cut")
if(AALARM_WIRE_AI_CONTROL)
if(A.aidisabled == !mended)
A.aidisabled = mended
A.aidisabled = !mended
// to_chat(world, "AI Control Wire Cut")
if(AALARM_WIRE_SYPHON)
-6
View File
@@ -5,12 +5,6 @@
#define MAX_FLAG 65535
/proc/is_wire_tool(obj/item/I)
if(ismultitool(I))
return TRUE
if(iswirecutter(I))
return TRUE
var/list/same_wires = list()
// 12 colours, if you're adding more than 12 wires then add more colours here
var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink")
+41
View File
@@ -332,6 +332,47 @@
if(reagents)
reagents.temperature_reagents(exposed_temperature)
/atom/proc/tool_act(mob/living/user, obj/item/I, tool_type)
switch(tool_type)
if(TOOL_CROWBAR)
return crowbar_act(user, I)
if(TOOL_MULTITOOL)
return multitool_act(user, I)
if(TOOL_SCREWDRIVER)
return screwdriver_act(user, I)
if(TOOL_WRENCH)
return wrench_act(user, I)
if(TOOL_WIRECUTTER)
return wirecutter_act(user, I)
if(TOOL_WELDER)
return welder_act(user, I)
// Tool-specific behavior procs. To be overridden in subtypes.
/atom/proc/crowbar_act(mob/living/user, obj/item/I)
return
/atom/proc/multitool_act(mob/living/user, obj/item/I)
return
//Check if the multitool has an item in its data buffer
/atom/proc/multitool_check_buffer(user, silent = FALSE)
if(!silent)
to_chat(user, "<span class='warning'>[src] has no data buffer!</span>")
return FALSE
/atom/proc/screwdriver_act(mob/living/user, obj/item/I)
return
/atom/proc/wrench_act(mob/living/user, obj/item/I)
return
/atom/proc/wirecutter_act(mob/living/user, obj/item/I)
return
/atom/proc/welder_act(mob/living/user, obj/item/I)
return
/atom/proc/emag_act()
return
+1
View File
@@ -220,6 +220,7 @@
// This is automatically called when something enters your square
/atom/movable/Crossed(atom/movable/AM, oldloc)
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM)
SEND_SIGNAL(AM, COMSIG_CROSSED_MOVABLE, src)
/atom/movable/Bump(atom/A, yes) //the "yes" arg is to differentiate our Bump proc from byond's, without it every Bump() call would become a double Bump().
if(A && yes)
+12 -13
View File
@@ -205,21 +205,8 @@
user.stop_pulling()
/obj/machinery/dna_scannernew/attackby(var/obj/item/item as obj, var/mob/user as mob, params)
if(istype(item, /obj/item/screwdriver))
if(occupant)
to_chat(user, "<span class='notice'>The maintenance panel is locked.</span>")
return
default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", item)
return
if(exchange_parts(user, item))
return
if(istype(item, /obj/item/crowbar))
if(panel_open)
for(var/obj/I in contents) // in case there is something in the scanner
I.forceMove(src.loc)
default_deconstruction_crowbar(item)
return
else if(istype(item, /obj/item/reagent_containers/glass))
if(beaker)
to_chat(user, "<span class='warning'>A beaker is already loaded into the machine.</span>")
@@ -255,6 +242,18 @@
return
return ..()
/obj/machinery/dna_scannernew/crowbar_act(mob/user, obj/item/I)
if(default_deconstruction_crowbar(user, I))
for(var/obj/thing in contents) // in case there is something in the scanner
thing.forceMove(src.loc)
/obj/machinery/dna_scannernew/screwdriver_act(mob/user, obj/item/I)
if(occupant)
to_chat(user, "<span class='notice'>The maintenance panel is locked.</span>")
return TRUE
if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", I))
return TRUE
/obj/machinery/dna_scannernew/relaymove(mob/user as mob)
if(user.incapacitated())
return 0 //maybe they should be able to get out with cuffs, but whatever
@@ -52,7 +52,7 @@
if(!traitor || !istype(traitor))
pre_traitors.Remove(traitor)
continue
if(istype(traitor))
if(istype(traitor))
traitor.special_role = SPECIAL_ROLE_TRAITOR
traitor.restricted_roles = restricted_jobs
@@ -186,6 +186,7 @@
else
adjustBruteLoss(0.2) // If you are at full health, you won't lose health. You'll need it. However the moment anybody sneezes on you, the decaying will begin.
adjustFireLoss(0.2)
..()
/mob/living/simple_animal/hostile/blob/blobbernaut/New()
..()
+3 -2
View File
@@ -48,13 +48,14 @@
update_health_hud()
/mob/camera/blob/update_health_hud()
if(blob_core)
if(blob_core && hud_used)
hud_used.blobhealthdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#e36600'>[round(blob_core.obj_integrity)]</font></div>"
/mob/camera/blob/proc/add_points(var/points)
if(points != 0)
blob_points = Clamp(blob_points + points, 0, max_blob_points)
hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(src.blob_points)]</font></div>"
if(hud_used)
hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(src.blob_points)]</font></div>"
/mob/camera/blob/say(var/message)
if(!message)
@@ -40,7 +40,7 @@
name = "protective membranes"
desc = "These variable transparency organic membranes will protect you from welders and flashes and heal your eye damage."
icon_state = "ling_eyeshield"
eye_colour = null
eye_colour = "#000000"
implant_overlay = null
slot = "eye_ling"
status = 0
@@ -61,7 +61,7 @@
name = "heat receptors"
desc = "These heat receptors dramatically increases eyes light sensing ability."
icon_state = "ling_thermal"
eye_colour = null
eye_colour = "#000000"
implant_overlay = null
slot = "eye_ling"
status = 0
+14 -10
View File
@@ -9,24 +9,28 @@ var/global/list/all_cults = list()
/proc/is_convertable_to_cult(datum/mind/mind)
if(!mind)
return 0
return FALSE
if(!mind.current)
return 0
return FALSE
if(iscultist(mind.current))
return 1 //If they're already in the cult, assume they are convertable
return TRUE //If they're already in the cult, assume they are convertable
if(ishuman(mind.current) && (mind.assigned_role in list("Captain", "Chaplain")))
return 0
return FALSE
if(ishuman(mind.current))
var/mob/living/carbon/human/H = mind.current
if(ismindshielded(H))
return 0
if(ismindshielded(H)) //mindshield protects against conversions unless removed
return FALSE
// if(mind.offstation_role) cant convert offstation roles such as ghost spawns
// return FALSE Commented out until we can figure out why offstation_role is getting set to TRUE on normal crew
if(issilicon(mind.current))
return 0 //can't convert machines, that's ratvar's thing
return FALSE //can't convert machines, that's ratvar's thing
if(isguardian(mind.current))
var/mob/living/simple_animal/hostile/guardian/G = mind.current
if(!iscultist(G.summoner))
return 0 //can't convert it unless the owner is converted
return 1
return FALSE //can't convert it unless the owner is converted
if(isgolem(mind.current))
return FALSE
return TRUE
/proc/is_sacrifice_target(datum/mind/mind)
if(SSticker.mode.name == "cult")
@@ -178,7 +182,7 @@ var/global/list/all_cults = list()
if(!istype(cult_mind))
return 0
var/datum/game_mode/cult/cult_mode = SSticker.mode
if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind))
if(!(cult_mind in cult))
cult += cult_mind
cult_mind.current.faction |= "cult"
var/datum/action/innate/cultcomm/C = new()
+2 -2
View File
@@ -198,7 +198,7 @@ var/list/blacklisted_pylon_turfs = typecacheof(list(
if(last_heal <= world.time)
last_heal = world.time + heal_delay
for(var/mob/living/L in range(5, src))
if(iscultist(L) || istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct))
if(iscultist(L) || iswizard(L) || istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct))
if(L.health != L.maxHealth)
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
if(ishuman(L))
@@ -226,7 +226,7 @@ var/list/blacklisted_pylon_turfs = typecacheof(list(
if(istype(T, /turf/simulated/floor))
T.ChangeTurf(/turf/simulated/floor/engine/cult)
if(istype(T, /turf/simulated/wall))
T.ChangeTurf(/turf/simulated/wall/cult)
T.ChangeTurf(/turf/simulated/wall/cult/artificer)
else
var/turf/simulated/floor/engine/cult/F = safepick(cultturfs)
if(F)
+71 -114
View File
@@ -340,144 +340,100 @@ var/list/teleport_runes = list()
fail_invoke()
//Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby.
//Rite of Offering: Converts a normal crewmember to the cult or sacrifices mindshielded and sacrifice targets.
/obj/effect/rune/convert
cultist_name = "Rite of Enlightenment"
cultist_desc = "converts a normal crewmember on top of it to the cult. Does not work on mindshielded crew."
cultist_name = "Rite of Offering"
cultist_desc = "Offers a non-cultists on top of it to your deity, either converting or sacrificing them."
invocation = "Mah'weyh pleggh at e'ntrath!"
icon_state = "3"
req_cultists = 2
req_cultists = 1
allow_excess_invokers = TRUE
rune_in_use = FALSE
/obj/effect/rune/convert/do_invoke_glow()
return
/obj/effect/rune/convert/invoke(var/list/invokers)
var/list/convertees = list()
var/turf/T = get_turf(src)
for(var/mob/living/M in T.contents)
if(!iscultist(M) && !ismindshielded(M) && !isgolem(M) && ishuman(M))
convertees.Add(M)
if(!convertees.len)
fail_invoke()
log_game("Convert rune failed - no eligible convertees")
return
var/mob/living/new_cultist = pick(convertees)
if(!is_convertable_to_cult(new_cultist.mind) || new_cultist.null_rod_check())
for(var/M in invokers)
to_chat(M, "<span class='warning'>Something is shielding [new_cultist]'s mind!</span>")
if(is_sacrifice_target(new_cultist.mind))
to_chat(M, "<span class='cultlarge'>\"I desire this one for myself. <i>SACRIFICE THEM!</i>\"</span>")
fail_invoke()
log_game("Convert rune failed - convertee could not be converted")
return
..()
new_cultist.visible_message("<span class='warning'>[new_cultist] writhes in pain as the markings below them glow a bloody red!</span>", \
"<span class='cultlarge'><i>AAAAAAAAAAAAAA-</i></span>")
SSticker.mode.add_cultist(new_cultist.mind, 1)
new /obj/item/tome(get_turf(src))
new_cultist.mind.special_role = "Cultist"
to_chat(new_cultist, "<span class='cultitalic'><b>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \
and something evil takes root.</b></span>")
to_chat(new_cultist, "<span class='cultitalic'><b>Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve [SSticker.cultdat.entity_title3] above all else. Bring it back.\
</b></span>")
//Rite of Tribute: Sacrifices a crew member to Nar-Sie. Places them into a soul shard if they're in their body.
/obj/effect/rune/sacrifice
cultist_name = "Rite of Tribute"
cultist_desc = "sacrifices a crew member to your god. May place them into a soul shard if their spirit remains in their body."
icon_state = "3"
allow_excess_invokers = 1
invocation = "Barhah hra zar'garis!"
rune_in_use = 0
/obj/effect/rune/sacrifice/New()
..()
cultist_desc = "sacrifices a crew member to [SSticker.cultdat.entity_title3]. May place them into a soul shard if their spirit remains in their body."
/obj/effect/rune/sacrifice/invoke(var/list/invokers)
if(rune_in_use)
return
rune_in_use = 1
var/mob/living/user = invokers[1] //the first invoker is always the user
var/list/myriad_targets = list()
var/turf/T = get_turf(src)
var/list/possible_targets = list()
for(var/mob/living/M in T.contents)
if(M.mind)
if(M.mind in sacrificed)
continue
for(var/mob/living/M in T)
if(!iscultist(M))
possible_targets.Add(M)
var/mob/offering
if(possible_targets.len > 1) //If there's more than one target, allow choice
offering = input(user, "Choose an offering to sacrifice.", "Unholy Tribute") as null|anything in possible_targets
if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated())
return
else if(possible_targets.len) //Otherwise, if there's a target at all, pick the only one
offering = possible_targets[possible_targets.len]
if(!offering)
rune_in_use = 0
myriad_targets |= M
if(!myriad_targets.len)
fail_invoke()
log_game("Offer rune failed - no eligible targets")
rune_in_use = FALSE
return
rune_in_use = TRUE
var/mob/living/new_cultist = pick(myriad_targets)
if(is_convertable_to_cult(new_cultist.mind) && !new_cultist.null_rod_check() && !is_sacrifice_target(new_cultist.mind) && new_cultist.stat != DEAD && new_cultist.client != null)
invocation = "Mah'weyh pleggh at e'ntrath!"
..()
do_convert(new_cultist, invokers)
else
invocation = "Barhah hra zar'garis!"
..()
do_sacrifice(new_cultist, invokers)
rune_in_use = FALSE
/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers)
if(invokers.len < 2)
fail_invoke()
for(var/I in invokers)
to_chat(I, "<span class='warning'>You need at least two invokers to convert!</span>")
return
else
convertee.visible_message("<span class='warning'>[convertee] writhes in pain as the markings below them glow a bloody red!</span>", \
"<span class='cultlarge'><i>AAAAAAAAAAAAAA-</i></span>")
SSticker.mode.add_cultist(convertee.mind, 1)
new /obj/item/tome(get_turf(src))
convertee.mind.special_role = "Cultist"
to_chat(convertee, "<span class='cultitalic'><b>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \
and something evil takes root.</b></span>")
to_chat(convertee, "<span class='cultitalic'><b>Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve [SSticker.cultdat.entity_title3] above all else. Bring it back.\
</b></span>")
return
/obj/effect/rune/convert/proc/do_sacrifice(mob/living/offering, list/invokers)
var/mob/living/user = invokers[1] //the first invoker is always the user
if(((ishuman(offering) || isrobot(offering)) && offering.stat != DEAD) || is_sacrifice_target(offering.mind)) //Requires three people to sacrifice living targets
if(invokers.len < 3)
for(var/M in invokers)
to_chat(M, "<span class='cultitalic'>[offering] is too greatly linked to the world! You need three acolytes!</span>")
fail_invoke()
log_game("Sacrifice rune failed - not enough acolytes and target is living")
rune_in_use = 0
return
visible_message("<span class='warning'>[src] pulses blood red!</span>")
color = rgb(126, 23, 23)
..()
sac(invokers, offering)
color = initial(color)
/obj/effect/rune/sacrifice/proc/sac(var/list/invokers, mob/living/T)
var/sacrifice_fulfilled
var/datum/game_mode/cult/cult_mode = SSticker.mode
if(T)
if(isdog(T)) // Doggos are the best, but not cats
for(var/M in invokers)
var/mob/living/L = M
to_chat(L, "<span class='cultlarge'>\"Even I have standards, such as they are!\"</span>")
if(L.reagents)
L.reagents.add_reagent("hell_water", 2)
if(T.mind)
sacrificed.Add(T.mind)
if(is_sacrifice_target(T.mind))
sacrifice_fulfilled = 1
new /obj/effect/temp_visual/cult/sac(loc)
if(SSticker && SSticker.mode && SSticker.mode.name == "cult")
cult_mode.harvested++
for(var/M in invokers)
if(sacrifice_fulfilled)
to_chat(M, "<span class='cultlarge'>\"Yes! This is the one I desire! You have done well.\"</span>")
cult_mode.additional_phase()
else
if(ishuman(T) || isrobot(T))
to_chat(M, "<span class='cultlarge'>\"I accept this sacrifice.\"</span>")
else
to_chat(M, "<span class='cultlarge'>\"I accept this meager sacrifice.\"</span>")
if(T.mind)
var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src))
stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul()
if(!stone.transfer_soul("VICTIM", T, usr)) //If it cannot be added
qdel(stone)
if(stone)
stone.invisibility = 0
if(!T)
rune_in_use = 0
return
if(isrobot(T))
playsound(T, 'sound/effects/EMPulse.ogg', 100, 1)
T.dust() //To prevent the MMI from remaining
if(offering.mind)
sacrificed.Add(offering.mind)
if(is_sacrifice_target(offering.mind))
sacrifice_fulfilled = TRUE
new /obj/effect/temp_visual/cult/sac(loc)
if(SSticker && SSticker.mode && SSticker.mode.name == "cult")
cult_mode.harvested++
for(var/M in invokers)
if(sacrifice_fulfilled)
to_chat(M, "<span class='cultlarge'>\"Yes! This is the one I desire! You have done well.\"</span>")
cult_mode.additional_phase()
else
playsound(T, 'sound/magic/disintegrate.ogg', 100, 1)
T.gib()
rune_in_use = 0
if(ishuman(offering) || isrobot(offering))
to_chat(M, "<span class='cultlarge'>\"I accept this sacrifice.\"</span>")
else
to_chat(M, "<span class='cultlarge'>\"I accept this meager sacrifice.\"</span>")
playsound(offering, 'sound/misc/demon_consume.ogg', 100, 1)
if((ishuman(offering) || isrobot(offering)) && offering.client_mobs_in_contents?.len)
var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src))
stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul()
stone.transfer_soul("FORCE", offering, user) //If it cannot be added
stone.invisibility = 0
else
offering.dust()
//Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station.
/obj/effect/rune/narsie
@@ -707,6 +663,7 @@ var/list/teleport_runes = list()
/obj/effect/rune/raise_dead/fail_invoke()
..()
rune_in_use = FALSE
for(var/mob/living/M in range(1,src))
if(M.stat == DEAD)
M.visible_message("<span class='warning'>[M] twitches.</span>")
@@ -244,6 +244,7 @@
anchored = 1
density = 1
atom_say_verb = "blares"
speed_process = TRUE // Disgusting fix. Please remove once #12952 is merged
var/timing = 0
var/default_timer = 4500
var/detonation_timer
@@ -184,7 +184,7 @@
var/obj/machinery/abductor/console/con = get_team_console(team_number)
var/datum/objective/objective = team_objectives[team_number]
if(con.experiment.points >= objective.target_amount)
SSshuttle.emergency.request(null, 0.5)
SSshuttle.emergency.request(null, 0.5, reason = "Large amount of abnormal thought patterns detected. All crew are recalled for mandatory evaluation and reconditioning.")
SSshuttle.emergency.canRecall = FALSE
finished = 1
return ..()
@@ -208,12 +208,14 @@
text += "<br><span class='big'><b>The abductors were:</b></span><br>"
for(var/datum/mind/abductor_mind in abductors)
text += printplayer(abductor_mind)
text += "<br>"
text += printobjectives(abductor_mind)
text += "<br>"
if(abductees.len)
text += "<br><span class='big'><b>The abductees were:</b></span><br>"
for(var/datum/mind/abductee_mind in abductees)
text += printplayer(abductee_mind)
text += "<br>"
text += printobjectives(abductee_mind)
text += "<br>"
to_chat(world, text)
@@ -587,10 +587,8 @@ Congratulations! You are now trained for invasive xenobiology research!"}
..()
make_syndie()
/obj/item/radio/headset/abductor/attackby(obj/item/I, mob/user, params)
if(isscrewdriver(I))
return // Stops humans from disassembling abductor headsets.
return ..()
/obj/item/radio/headset/abductor/screwdriver_act()
return// Stops humans from disassembling abductor headsets.
/obj/item/scalpel/alien
name = "alien scalpel"
@@ -683,15 +681,6 @@ Congratulations! You are now trained for invasive xenobiology research!"}
density = TRUE
/obj/structure/table_frame/abductor/attackby(obj/item/I, mob/user, params)
if(iswrench(I))
to_chat(user, "<span class='notice'>You start disassembling [src]...</span>")
playsound(loc, I.usesound, 50, 1)
if(do_after(user, 30*I.toolspeed, target = src))
playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
for(var/i = 1, i <= framestackamount, i++)
new framestack(get_turf(src))
qdel(src)
return
if(istype(I, /obj/item/stack/sheet/mineral/abductor))
var/obj/item/stack/sheet/P = I
if(P.get_amount() < 1)
@@ -41,15 +41,17 @@
return
to_chat(user, "<span class='notice'>Picking up the swarmer may cause it to activate. You should be careful about this.</span>")
/obj/effect/mob_spawn/swarmer/attackby(obj/item/I, mob/user, params)
if(isscrewdriver(I) && user.a_intent != INTENT_HARM)
user.visible_message("<span class='warning'>[usr.name] deactivates [src].</span>",
"<span class='notice'>After some fiddling, you find a way to disable [src]'s power source.</span>",
"<span class='italics'>You hear clicking.</span>")
new /obj/item/deactivated_swarmer(get_turf(src))
qdel(src)
else
return ..()
/obj/effect/mob_spawn/swarmer/screwdriver_act(mob/user, obj/item/I)
if(user.a_intent == INTENT_HARM)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
user.visible_message("<span class='warning'>[usr.name] deactivates [src].</span>",
"<span class='notice'>After some fiddling, you find a way to disable [src]'s power source.</span>",
"<span class='italics'>You hear clicking.</span>")
new /obj/item/deactivated_swarmer(get_turf(src))
qdel(src)
////The Mob itself////
@@ -162,7 +162,7 @@
to_chat(src, "<b>You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.</b>")
to_chat(src, "<b>To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.</b>")
to_chat(src, "<b><i>You do not remember anything of your past lives, nor will you remember anything about this one after your death.</i></b>")
to_chat(src, "<b>Be sure to read the wiki page at http://nanotrasen.se/wiki/index.php/Revenant to learn more.</b>")
to_chat(src, "<b>Be sure to read the wiki page at http://www.paradisestation.org/wiki/index.php/Revenant to learn more.</b>")
var/datum/objective/revenant/objective = new
objective.owner = mind
mind.objectives += objective
+116 -99
View File
@@ -1,3 +1,10 @@
#define NUKE_INTACT 0
#define NUKE_COVER_OFF 1
#define NUKE_COVER_OPEN 2
#define NUKE_SEALANT_OPEN 3
#define NUKE_UNWRENCHED 4
#define NUKE_MOBILE 5
var/bomb_set
/obj/machinery/nuclearbomb
@@ -17,7 +24,7 @@ var/bomb_set
var/yes_code = 0
var/safety = 1
var/obj/item/disk/nuclear/auth = null
var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open, 3 is sealant open, 4 is unwrenched, 5 is removed from bolts.
var/removal_stage = NUKE_INTACT
var/lastentered
var/is_syndicate = 0
use_power = NO_POWER_USE
@@ -50,33 +57,6 @@ var/bomb_set
return
/obj/machinery/nuclearbomb/attackby(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/screwdriver))
add_fingerprint(user)
if(auth)
if(panel_open == 0)
panel_open = 1
overlays += image(icon, "npanel_open")
to_chat(user, "You unscrew the control panel of [src].")
playsound(src, O.usesound, 50, 1)
else
panel_open = 0
overlays -= image(icon, "npanel_open")
to_chat(user, "You screw the control panel of [src] back on.")
playsound(src, O.usesound, 50, 1)
else
if(panel_open == 0)
to_chat(user, "[src] emits a buzzing noise, the panel staying locked in.")
if(panel_open == 1)
panel_open = 0
overlays -= image(icon, "npanel_open")
to_chat(user, "You screw the control panel of [src] back on.")
playsound(src, O.usesound, 50, 1)
flick("nuclearbombc", src)
return
if(panel_open && (istype(O, /obj/item/multitool) || istype(O, /obj/item/wirecutters)))
return attack_hand(user)
if(istype(O, /obj/item/disk/nuclear))
if(extended)
if(!user.drop_item())
@@ -89,77 +69,107 @@ var/bomb_set
else
to_chat(user, "<span class='notice'>You need to deploy \the [src] first. Right click on the sprite, select 'Make Deployable' then click on \the [src] with an empty hand.</span>")
return
if(anchored)
switch(removal_stage)
if(0)
if(istype(O,/obj/item/weldingtool))
var/obj/item/weldingtool/WT = O
if(!WT.isOn()) return
if(WT.get_fuel() < 5) // uses up 5 fuel.
to_chat(user, "<span class='warning'>You need more fuel to complete this task.</span>")
return
user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [O]...")
if(do_after(user,40, target = src))
if(!src || !user || !WT.remove_fuel(5, user)) return
user.visible_message("[user] cuts through the bolt covers on [src].", "You cut through the bolt cover.")
removal_stage = 1
return
if(1)
if(istype(O,/obj/item/crowbar))
user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [O]...")
if(do_after(user,15, target = src))
if(!src || !user) return
user.visible_message("[user] forces open the bolt covers on [src].", "You force open the bolt covers.")
removal_stage = 2
return
if(2)
if(istype(O,/obj/item/weldingtool))
var/obj/item/weldingtool/WT = O
if(!WT.isOn()) return
if(WT.get_fuel() < 5) // uses up 5 fuel.
to_chat(user, "<span class='warning'>You need more fuel to complete this task.</span>")
return
user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [O]...")
if(do_after(user,40, target = src))
if(!src || !user || !WT.remove_fuel(5, user)) return
user.visible_message("[user] cuts apart the anchoring system sealant on [src].", "You cut apart the anchoring system's sealant.")
removal_stage = 3
return
if(3)
if(istype(O,/obj/item/wrench))
user.visible_message("[user] begins unwrenching the anchoring bolts on [src].", "You begin unwrenching the anchoring bolts...")
if(do_after(user,50, target = src))
if(!src || !user) return
user.visible_message("[user] unwrenches the anchoring bolts on [src].", "You unwrench the anchoring bolts.")
removal_stage = 4
return
if(4)
if(istype(O,/obj/item/crowbar))
user.visible_message("[user] begins lifting [src] off of the anchors.", "You begin lifting the device off the anchors...")
if(do_after(user,80, target = src))
if(!src || !user) return
user.visible_message("[user] crowbars [src] off of the anchors. It can now be moved.", "You jam the crowbar under the nuclear device and lift it off its anchors. You can now move it!")
anchored = 0
removal_stage = 5
return
return
return ..()
/obj/machinery/nuclearbomb/crowbar_act(mob/user, obj/item/I)
if(!anchored)
return
if(removal_stage != NUKE_UNWRENCHED && removal_stage != NUKE_COVER_OFF)
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
if(removal_stage == NUKE_COVER_OFF)
user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [I]...")
if(!I.use_tool(src, user, 15, volume = I.tool_volume) || removal_stage != NUKE_COVER_OFF)
return
user.visible_message("[user] forces open the bolt covers on [src].", "You force open the bolt covers.")
removal_stage = NUKE_COVER_OPEN
else
user.visible_message("[user] begins lifting [src] off of the anchors.", "You begin lifting the device off the anchors...")
if(!I.use_tool(src, user, 80, volume = I.tool_volume) || removal_stage != NUKE_UNWRENCHED)
return
user.visible_message("[user] crowbars [src] off of the anchors. It can now be moved.", "You jam the crowbar under the nuclear device and lift it off its anchors. You can now move it!")
anchored = FALSE
removal_stage = NUKE_MOBILE
/obj/machinery/nuclearbomb/wrench_act(mob/user, obj/item/I)
if(!anchored)
return
if(removal_stage != NUKE_SEALANT_OPEN)
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
user.visible_message("[user] begins unwrenching the anchoring bolts on [src].", "You begin unwrenching the anchoring bolts...")
if(!I.use_tool(src, user, 50, volume = I.tool_volume) || removal_stage != NUKE_SEALANT_OPEN)
return
user.visible_message("[user] unwrenches the anchoring bolts on [src].", "You unwrench the anchoring bolts.")
removal_stage = NUKE_UNWRENCHED
/obj/machinery/nuclearbomb/multitool_act(mob/user, obj/item/I)
if(!panel_open)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
attack_hand(user)
/obj/machinery/nuclearbomb/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(auth)
if(!panel_open)
panel_open = TRUE
overlays += image(icon, "npanel_open")
to_chat(user, "You unscrew the control panel of [src].")
else
panel_open = FALSE
overlays -= image(icon, "npanel_open")
to_chat(user, "You screw the control panel of [src] back on.")
else
if(!panel_open)
to_chat(user, "[src] emits a buzzing noise, the panel staying locked in.")
if(panel_open == TRUE)
panel_open = FALSE
overlays -= image(icon, "npanel_open")
to_chat(user, "You screw the control panel of [src] back on.")
flick("nuclearbombc", src)
/obj/machinery/nuclearbomb/wirecutter_act(mob/user, obj/item/I)
if(!panel_open)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
attack_hand(user)
/obj/machinery/nuclearbomb/welder_act(mob/user, obj/item/I)
. = TRUE
if(removal_stage != NUKE_INTACT && removal_stage != NUKE_COVER_OPEN)
return
if(!I.tool_use_check(user, 0))
return
if(removal_stage == NUKE_INTACT)
visible_message("<span class='notice'>[user] starts cutting loose the anchoring bolt covers on [src].</span>",\
"<span class='notice'>You start cutting loose the anchoring bolt covers with [I]...</span>",\
"<span class='warning'>You hear welding.</span>")
if(!I.use_tool(src, user, 40, 5, volume = I.tool_volume) || removal_stage != NUKE_INTACT)
return
visible_message("<span class='notice'>[user] cuts through the bolt covers on [src].</span>",\
"<span class='notice'>You cut through the bolt cover.</span>")
removal_stage = NUKE_COVER_OFF
else if(removal_stage == NUKE_COVER_OPEN)
visible_message("<span class='notice'>[user] starts cutting apart the anchoring system sealant on [src].</span>",\
"<span class='notice'>You start cutting apart the anchoring system's sealant with [I]...</span>",\
"<span class='warning'>You hear welding.</span>")
if(!I.use_tool(src, user, 40, 5, volume = I.tool_volume) || removal_stage != NUKE_COVER_OPEN)
return
visible_message("<span class='notice'>[user] cuts apart the anchoring system sealant on [src].</span>",\
"<span class='notice'>You cut apart the anchoring system's sealant.</span></span>")
removal_stage = NUKE_SEALANT_OPEN
/obj/machinery/nuclearbomb/attack_ghost(mob/user as mob)
if(extended)
attack_hand(user)
@@ -171,7 +181,7 @@ var/bomb_set
else
ui_interact(user)
else if(deployable)
if(removal_stage < 5)
if(removal_stage != NUKE_MOBILE)
anchored = 1
visible_message("<span class='warning'>With a steely snap, bolts slide out of [src] and anchor it to the flooring!</span>")
else
@@ -317,7 +327,7 @@ var/bomb_set
timing = 0
bomb_set = 0
if(href_list["anchor"])
if(removal_stage == 5)
if(removal_stage == NUKE_MOBILE)
anchored = 0
visible_message("<span class='warning'>\The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.</span>")
SSnanoui.update_uis(src)
@@ -453,3 +463,10 @@ var/bomb_set
else
error("[src] was supposed to be destroyed, but we were unable to locate a blobstart landmark to spawn a new one.")
return QDEL_HINT_LETMELIVE // Cancel destruction unless forced.
#undef NUKE_INTACT
#undef NUKE_COVER_OFF
#undef NUKE_COVER_OPEN
#undef NUKE_SEALANT_OPEN
#undef NUKE_UNWRENCHED
#undef NUKE_MOBILE
+4 -4
View File
@@ -1,4 +1,4 @@
var/global/list/all_objectives = list()
GLOBAL_LIST_EMPTY(all_objectives)
var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datum/theft_objective/steal - /datum/theft_objective/number - /datum/theft_objective/unique
@@ -10,13 +10,13 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu
var/completed = 0 //currently only used for custom objectives.
var/martyr_compatible = 0 //If the objective is compatible with martyr objective, i.e. if you can still do it while dead.
/datum/objective/New(var/text)
all_objectives |= src
/datum/objective/New(text)
GLOB.all_objectives += src
if(text)
explanation_text = text
/datum/objective/Destroy()
all_objectives -= src
GLOB.all_objectives -= src
return ..()
/datum/objective/proc/check_completion()
+1 -1
View File
@@ -126,7 +126,7 @@ Made by Xhuis
to_chat(shadow.current, "<b>Currently, you are disguised as an employee aboard [world.name].</b>")
to_chat(shadow.current, "<b>In your limited state, you have two abilities: Hatch and Shadowling Hivemind (:8).</b>")
to_chat(shadow.current, "<b>Any other shadowlings are your allies. You must assist them as they shall assist you.</b>")
to_chat(shadow.current, "<b>If you are new to shadowling, or want to read about abilities, check the wiki page at http://nanotrasen.se/wiki/index.php/Shadowling</b><br>")
to_chat(shadow.current, "<b>If you are new to shadowling, or want to read about abilities, check the wiki page at https://www.paradisestation.org/wiki/index.php/Shadowling</b><br>")
+63 -84
View File
@@ -205,24 +205,19 @@
/obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob)
switch(choice)
if("FORCE")
var/obj/item/soulstone/C = src
if(!iscarbon(target)) //TODO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul
return 0
if(contents.len)
return 0
var/mob/living/carbon/T = target
var/obj/item/soulstone/SS = src
var/mob/living/T = target
if(T.client != null)
for(var/obj/item/W in T)
T.unEquip(W)
C.init_shade(T, U)
return 1
SS.init_shade(T, U)
else
to_chat(U, "<span class='userdanger'>Capture failed!</span>: The soul has already fled its mortal frame. You attempt to bring it back...")
return C.getCultGhost(T,U)
T.Paralyse(20)
if(!SS.getCultGhost(T,U))
T.dust() //If we can't get a ghost, kill the sacrifice anyway.
if("VICTIM")
var/mob/living/carbon/human/T = target
var/obj/item/soulstone/C = src
var/obj/item/soulstone/SS = src
if(T.stat == 0)
to_chat(U, "<span class='danger'>Capture failed!</span>: Kill or maim the victim first!")
else
@@ -231,94 +226,70 @@
else
if(T.client == null)
to_chat(U, "<span class='userdanger'>Capture failed!</span>: The soul has already fled its mortal frame. You attempt to bring it back...")
C.getCultGhost(T,U)
SS.getCultGhost(T,U)
else
if(C.contents.len)
if(SS.contents.len)
to_chat(U, "<span class='danger'>Capture failed!</span>: The soul stone is full! Use or free an existing soul to make room.")
else
for(var/obj/item/W in T)
T.unEquip(W)
C.init_shade(T, U, vic = 1)
qdel(T)
SS.init_shade(T, U, vic = 1)
if("SHADE")
var/mob/living/simple_animal/shade/T = target
var/obj/item/soulstone/C = src
if(!C.can_use(U))
var/obj/item/soulstone/SS = src
if(!SS.can_use(U))
U.Paralyse(5)
to_chat(U, "<span class='userdanger'>Your body is wracked with debilitating pain!</span>")
return
if(T.stat == DEAD)
to_chat(U, "<span class='danger'>Capture failed!</span>: The shade has already been banished!")
else
if(C.contents.len)
if(SS.contents.len)
to_chat(U, "<span class='danger'>Capture failed!</span>: The soul stone is full! Use or free an existing soul to make room.")
else
T.loc = C //put shade in stone
T.loc = SS //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
T.faction |= "\ref[U]"
C.icon_state = "soulstone2"
SS.icon_state = "soulstone2"
to_chat(T, "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form")
to_chat(U, "<span class='notice'>Capture successful!</span>: [T.name]'s has been recaptured and stored within the soul stone.")
if("CONSTRUCT")
var/obj/structure/constructshell/T = target
var/obj/item/soulstone/C = src
var/mob/living/simple_animal/shade/A = locate() in C
if(A)
var/obj/item/soulstone/SS = src
var/mob/living/simple_animal/shade/SH = locate() in SS
if(SH)
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
switch(construct_class)
if("Juggernaut")
var/mob/living/simple_animal/hostile/construct/armoured/Z = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc))
Z.key = A.key
Z.faction |= "\ref[U]"
if(iscultist(U))
if(SSticker.mode.name == "cult")
SSticker.mode:add_cultist(Z.mind)
else
SSticker.mode.cult+=Z.mind
SSticker.mode.update_cult_icons_added(Z.mind)
qdel(T)
to_chat(Z, "<B>You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.</B>")
Z.cancel_camera()
qdel(C)
var/mob/living/simple_animal/hostile/construct/armoured/C = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc))
to_chat(C, "<B>You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.</B>")
init_construct(C,SH,SS,T)
if("Wraith")
var/mob/living/simple_animal/hostile/construct/wraith/Z = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc))
Z.key = A.key
Z.faction |= "\ref[U]"
if(iscultist(U))
if(SSticker.mode.name == "cult")
SSticker.mode:add_cultist(Z.mind)
else
SSticker.mode.cult+=Z.mind
SSticker.mode.update_cult_icons_added(Z.mind)
qdel(T)
to_chat(Z, "<B>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.</B>")
Z.cancel_camera()
qdel(C)
var/mob/living/simple_animal/hostile/construct/wraith/C = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc))
to_chat(C, "<B>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</B>")
init_construct(C,SH,SS,T)
if("Artificer")
var/mob/living/simple_animal/hostile/construct/builder/Z = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc))
Z.key = A.key
Z.faction |= "\ref[U]"
if(iscultist(U))
if(SSticker.mode.name == "cult")
SSticker.mode:add_cultist(Z.mind)
else
SSticker.mode.cult+=Z.mind
SSticker.mode.update_cult_icons_added(Z.mind)
qdel(T)
to_chat(Z, "<B>You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), </B><I>and most important of all create new constructs</I><B> (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).</B>")
to_chat(Z, "<B>You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.</B>")
Z.cancel_camera()
qdel(C)
var/mob/living/simple_animal/hostile/construct/builder/C = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc))
to_chat(C, "<B>You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), </B><I>and most important of all create new constructs</I><B> (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).</B>")
init_construct(C,SH,SS,T)
else
to_chat(U, "<span class='danger'>Creation failed!</span>: The soul stone is empty! Go kill someone!")
return
/proc/init_construct(mob/living/simple_animal/hostile/construct/C, mob/living/simple_animal/shade/SH, obj/item/soulstone/SS, obj/structure/constructshell/T)
SH.mind.transfer_to(C)
if(iscultist(C))
var/datum/action/innate/cultcomm/CC = new()
CC.Grant(C) //We have to grant the cult comms again because they're lost during the mind transfer.
qdel(T)
qdel(SH)
to_chat(C, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
C.cancel_camera()
qdel(SS)
/proc/makeNewConstruct(var/mob/living/simple_animal/hostile/construct/ctype, var/mob/target, var/mob/stoner = null, cultoverride = 0)
if(jobban_isbanned(target, "cultist") || jobban_isbanned(target, "Syndicate"))
return
@@ -332,14 +303,14 @@
SSticker.mode.cult+=newstruct.mind
SSticker.mode.update_cult_icons_added(newstruct.mind)
if(stoner && iswizard(stoner))
to_chat(newstruct, "<B>You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.</B>")
to_chat(newstruct, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
else if(stoner && iscultist(stoner))
to_chat(newstruct, "<B>You are still bound to serve the cult, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.</B>")
to_chat(newstruct, "<B>You are still bound to serve the cult, follow their orders and help them complete their goals at all costs.</B>")
else
to_chat(newstruct, "<B>You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.</B>")
to_chat(newstruct, "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>")
newstruct.cancel_camera()
/obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0)
/obj/item/soulstone/proc/init_shade(mob/living/T, mob/U, vic = 0)
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
T.invisibility = 101
var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc )
@@ -355,19 +326,30 @@
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
S.key = T.key
if(U)
S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation
if(U && iscultist(U))
SSticker.mode.add_cultist(S.mind, 0)
S.cancel_camera()
name = "soulstone: Shade of [T.real_name]"
icon_state = "soulstone2"
if(U && iswizard(U))
to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help [U.p_them()] succeed in their goals at all costs.")
else if(U && iscultist(U))
to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help [U.p_them()] succeed in their goals at all costs.")
if(U)
S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation
if(iswizard(U))
SSticker.mode.update_wiz_icons_added(S.mind)
S.mind.special_role = SPECIAL_ROLE_WIZARD_APPRENTICE
if(iscultist(U))
SSticker.mode.add_cultist(S.mind, 0)
S.mind.special_role = SPECIAL_ROLE_CULTIST
S.mind.store_memory("<b>Serve the cult's will.</b>")
to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.")
else
S.mind.store_memory("<b>Serve [U.real_name], your creator.</b>")
to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs.")
if(vic && U)
to_chat(U, "<span class='info'><b>Capture successful!</b>:</span> [T.real_name]'s soul has been ripped from [U.p_their()] body and stored within the soul stone.")
if(isrobot(T))//Robots have to dust or else they spill out an empty robot brain, and unequiping them spills robot components that shouldn't spawn.
T.dust()
else
for(var/obj/item/W in T)
T.unEquip(W)
qdel(T)
/obj/item/soulstone/proc/get_shade_type()
return /mob/living/simple_animal/shade/cult
@@ -375,7 +357,7 @@
/obj/item/soulstone/anybody/get_shade_type()
return /mob/living/simple_animal/shade
/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U)
/obj/item/soulstone/proc/getCultGhost(mob/living/T, mob/U)
var/mob/dead/observer/chosen_ghost
for(var/mob/dead/observer/ghost in GLOB.player_list) //We put them back in their body
@@ -395,8 +377,5 @@
if(contents.len) //If they used the soulstone on someone else in the meantime
return 0
T.ckey = chosen_ghost.ckey
for(var/obj/item/W in T)
T.unEquip(W)
init_shade(T, U)
qdel(T)
return 1
+1 -1
View File
@@ -66,7 +66,7 @@
/datum/outfit/job/ntspecops
name = "Special Operations Officer"
jobtype = /datum/job/ntspecops
uniform = /obj/item/clothing/under/rank/centcom_commander
uniform = /obj/item/clothing/under/rank/centcom/captain
suit = /obj/item/clothing/suit/space/deathsquad/officer
back = /obj/item/storage/backpack/security
belt = /obj/item/storage/belt/military/assault
+13 -3
View File
@@ -263,8 +263,11 @@ var/global/list/role_playtime_requirements = list(
myrole = mob.mind.playtime_role
else if(mob.mind.assigned_role)
myrole = mob.mind.assigned_role
var/added_living = 0
var/added_ghost = 0
if(mob.stat == CONSCIOUS && myrole)
play_records[EXP_TYPE_LIVING] += minutes
added_living += minutes
if(announce_changes)
to_chat(mob,"<span class='notice'>You got: [minutes] Living EXP!")
for(var/category in exp_jobsmap)
@@ -279,6 +282,7 @@ var/global/list/role_playtime_requirements = list(
to_chat(mob,"<span class='notice'>You got: [minutes] Special EXP!")
else if(isobserver(mob))
play_records[EXP_TYPE_GHOST] += minutes
added_ghost += minutes
if(announce_changes)
to_chat(mob,"<span class='notice'>You got: [minutes] Ghost EXP!")
else
@@ -286,9 +290,15 @@ var/global/list/role_playtime_requirements = list(
var/new_exp = list2params(play_records)
prefs.exp = new_exp
new_exp = sanitizeSQL(new_exp)
var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("player")] SET exp = '[new_exp]' WHERE ckey='[ckey]'")
var/DBQuery/update_query = dbcon.NewQuery("UPDATE [format_table_name("player")] SET exp = '[new_exp]',lastseen = Now() WHERE ckey='[ckey]'")
if(!update_query.Execute())
var/err = update_query.ErrorMsg()
log_game("SQL ERROR during exp_update_client write. Error : \[[err]\]\n")
message_admins("SQL ERROR during exp_update_client write. Error : \[[err]\]\n")
log_game("SQL ERROR during exp_update_client write 1. Error : \[[err]\]\n")
message_admins("SQL ERROR during exp_update_client write 1. Error : \[[err]\]\n")
return
var/DBQuery/update_query_history = dbcon.NewQuery("INSERT INTO [format_table_name("playtime_history")] (ckey, date, time_living, time_ghost) VALUES ('[ckey]',CURDATE(),[added_living],[added_ghost]) ON DUPLICATE KEY UPDATE time_living=time_living+VALUES(time_living),time_ghost=time_ghost+VALUES(time_ghost)")
if(!update_query_history.Execute())
var/err = update_query_history.ErrorMsg()
log_game("SQL ERROR during exp_update_client write 2. Error : \[[err]\]\n")
message_admins("SQL ERROR during exp_update_client write 2. Error : \[[err]\]\n")
return
+56 -49
View File
@@ -8,6 +8,7 @@
use_power = IDLE_POWER_USE
current_heat_capacity = 1000
layer = 3
plane = GAME_PLANE
max_integrity = 300
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30)
@@ -50,36 +51,39 @@
..(dir,dir)
/obj/machinery/atmospherics/unary/cold_sink/freezer/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "freezer-o", "freezer", I))
on = 0
update_icon()
return
if(exchange_parts(user, I))
return
if(default_deconstruction_crowbar(I))
return
if(iswrench(I))
if(!panel_open)
to_chat(user, "<span class='notice'>Open the maintenance panel first.</span>")
return
var/list/choices = list("West" = WEST, "East" = EAST, "South" = SOUTH, "North" = NORTH)
var/selected = input(user,"Select a direction for the connector.", "Connector Direction") in choices
dir = choices[selected]
playsound(src.loc, I.usesound, 50, 1)
var/node_connect = dir
initialize_directions = dir
for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
node = target
break
build_network()
update_icon()
return
return ..()
/obj/machinery/atmospherics/unary/cold_sink/freezer/crowbar_act(mob/user, obj/item/I)
if(default_deconstruction_crowbar(user, I))
return TRUE
/obj/machinery/atmospherics/unary/cold_sink/freezer/screwdriver_act(mob/user, obj/item/I)
if(default_deconstruction_screwdriver(user, "freezer-o", "freezer", I))
on = FALSE
update_icon()
return TRUE
/obj/machinery/atmospherics/unary/cold_sink/freezer/wrench_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(!panel_open)
to_chat(user, "<span class='notice'>Open the maintenance panel first.</span>")
return
var/list/choices = list("West" = WEST, "East" = EAST, "South" = SOUTH, "North" = NORTH)
var/selected = input(user,"Select a direction for the connector.", "Connector Direction") in choices
dir = choices[selected]
var/node_connect = dir
initialize_directions = dir
for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
node = target
break
build_network()
update_icon()
/obj/machinery/atmospherics/unary/cold_sink/freezer/update_icon()
if(panel_open)
icon_state = "freezer-o"
@@ -217,35 +221,38 @@
current_heat_capacity = 1000 * ((H - 1) ** 2)
/obj/machinery/atmospherics/unary/heat_reservoir/heater/attackby(obj/item/I, mob/user, params)
if(exchange_parts(user, I))
return
return ..()
/obj/machinery/atmospherics/unary/heat_reservoir/heater/crowbar_act(mob/user, obj/item/I)
if(default_deconstruction_crowbar(user, I))
return TRUE
/obj/machinery/atmospherics/unary/heat_reservoir/heater/screwdriver_act(mob/user, obj/item/I)
if(default_deconstruction_screwdriver(user, "heater-o", "heater", I))
on = 0
update_icon()
return
return TRUE
if(exchange_parts(user, I))
/obj/machinery/atmospherics/unary/heat_reservoir/heater/wrench_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(default_deconstruction_crowbar(I))
if(!panel_open)
to_chat(user, "<span class='notice'>Open the maintenance panel first.</span>")
return
if(iswrench(I))
if(!panel_open)
to_chat(user, "<span class='notice'>Open the maintenance panel first.</span>")
return
var/list/choices = list("West" = WEST, "East" = EAST, "South" = SOUTH, "North" = NORTH)
var/selected = input(user,"Select a direction for the connector.", "Connector Direction") in choices
dir = choices[selected]
playsound(src.loc, I.usesound, 50, 1)
var/node_connect = dir
initialize_directions = dir
for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
node = target
break
build_network()
update_icon()
return
return ..()
var/list/choices = list("West" = WEST, "East" = EAST, "South" = SOUTH, "North" = NORTH)
var/selected = input(user,"Select a direction for the connector.", "Connector Direction") in choices
dir = choices[selected]
var/node_connect = dir
initialize_directions = dir
for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
node = target
break
build_network()
update_icon()
/obj/machinery/atmospherics/unary/heat_reservoir/heater/update_icon()
if(panel_open)
+9 -6
View File
@@ -131,15 +131,18 @@
if(iscarbon(G.affecting))
take_victim(G.affecting, user)
qdel(G)
if(iswrench(I))
playsound(loc, I.usesound, 50, 1)
if(do_after(user, 20 * I.toolspeed, target = src))
to_chat(user, "<span class='notice'>You deconstruct the table.</span>")
new /obj/item/stack/sheet/plasteel(loc, 5)
qdel(src)
else
return ..()
/obj/machinery/optable/wrench_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_start_check(user, 0))
return
if(I.use_tool(src, user, 20, volume = I.tool_volume))
to_chat(user, "<span class='notice'>You deconstruct the table.</span>")
new /obj/item/stack/sheet/plasteel(loc, 5)
qdel(src)
/obj/machinery/optable/proc/check_table(mob/living/carbon/patient as mob)
if(src.victim && get_turf(victim) == get_turf(src) && victim.lying)
to_chat(usr, "<span class='notice'>The table is already occupied!</span>")
+6 -18
View File
@@ -75,27 +75,15 @@
P.forceMove(src)
P.add_fingerprint(user)
update_icon()
else if(iswelder(I) && user.a_intent != INTENT_HARM)
var/obj/item/weldingtool/WT = I
if(stat & BROKEN)
if(WT.remove_fuel(0,user))
user.visible_message("[user] is repairing [src].", \
"<span class='notice'>You begin repairing [src]...</span>", \
"<span class='italics'>You hear welding.</span>")
playsound(loc, WT.usesound, 40, 1)
if(do_after(user,40*WT.toolspeed, 1, target = src))
if(!WT.isOn() || !(stat & BROKEN))
return
to_chat(user, "<span class='notice'>You repair [src].</span>")
playsound(loc, 'sound/items/welder2.ogg', 50, 1)
stat &= ~BROKEN
obj_integrity = max_integrity
update_icon()
else
to_chat(user, "<span class='notice'>[src] does not need repairs.</span>")
else
return ..()
/obj/machinery/pdapainter/welder_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_use_check(user, 0))
return
default_welder_repair(user, I)
/obj/machinery/pdapainter/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
if(!(stat & BROKEN))
+28 -26
View File
@@ -280,35 +280,9 @@
to_chat(user, "<span class='warning'>The sleeper has a beaker already.</span>")
return
if(isscrewdriver(I))
if(occupant)
to_chat(user, "<span class='notice'>The maintenance panel is locked.</span>")
return
default_deconstruction_screwdriver(user, "[base_icon]-o", "[base_icon]-open", I)
return
if(iswrench(I))
if(occupant)
to_chat(user, "<span class='notice'>The scanner is occupied.</span>")
return
if(panel_open)
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
return
if(dir == EAST)
orient = "LEFT"
setDir(WEST)
else
orient = "RIGHT"
setDir(EAST)
playsound(loc, I.usesound, 50, 1)
return
if(exchange_parts(user, I))
return
if(default_deconstruction_crowbar(I))
return
if(istype(I, /obj/item/grab))
var/obj/item/grab/G = I
if(panel_open)
@@ -343,6 +317,34 @@
return ..()
/obj/machinery/sleeper/crowbar_act(mob/user, obj/item/I)
if(default_deconstruction_crowbar(user, I))
return TRUE
/obj/machinery/sleeper/screwdriver_act(mob/user, obj/item/I)
if(occupant)
to_chat(user, "<span class='notice'>The maintenance panel is locked.</span>")
return TRUE
if(default_deconstruction_screwdriver(user, "[base_icon]-o", "[base_icon]-open", I))
return TRUE
/obj/machinery/sleeper/wrench_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(occupant)
to_chat(user, "<span class='notice'>The scanner is occupied.</span>")
return
if(panel_open)
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
return
if(dir == EAST)
orient = "LEFT"
setDir(WEST)
else
orient = "RIGHT"
setDir(EAST)
/obj/machinery/sleeper/ex_act(severity)
if(filtering)
toggle_filter()
+22 -24
View File
@@ -40,33 +40,9 @@
RefreshParts()
/obj/machinery/bodyscanner/attackby(obj/item/I, mob/user)
if(isscrewdriver(I))
if(occupant)
to_chat(user, "<span class='notice'>The maintenance panel is locked.</span>")
return
default_deconstruction_screwdriver(user, "bodyscanner-o", "bodyscanner-open", I)
return
if(iswrench(I))
if(occupant)
to_chat(user, "<span class='notice'>The scanner is occupied.</span>")
return
if(panel_open)
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
return
if(dir == EAST)
setDir(WEST)
else
setDir(EAST)
playsound(loc, I.usesound, 50, 1)
return
if(exchange_parts(user, I))
return
if(default_deconstruction_crowbar(I))
return
if(istype(I, /obj/item/grab))
var/obj/item/grab/TYPECAST_YOUR_SHIT = I
if(panel_open)
@@ -93,6 +69,28 @@
return ..()
/obj/machinery/bodyscanner/crowbar_act(mob/user, obj/item/I)
if(default_deconstruction_crowbar(user, I))
return TRUE
/obj/machinery/bodyscanner/screwdriver_act(mob/user, obj/item/I)
if(default_deconstruction_screwdriver(user, "bodyscanner-o", "bodyscanner-open", I))
return TRUE
/obj/machinery/bodyscanner/wrench_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(occupant)
to_chat(user, "<span class='notice'>The scanner is occupied.</span>")
return
if(panel_open)
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
return
if(dir == EAST)
setDir(WEST)
else
setDir(EAST)
/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/human/H, mob/user)
if(!istype(H))
+73 -41
View File
@@ -62,6 +62,10 @@
#define MAX_TEMPERATURE 363.15 // 90C
#define MIN_TEMPERATURE 233.15 // -40C
#define AIR_ALARM_FRAME 0
#define AIR_ALARM_BUILDING 1
#define AIR_ALARM_READY 2
//all air alarms in area are connected via magic
/area
var/obj/machinery/alarm/master_air_alarm
@@ -111,7 +115,7 @@
var/danger_level = ATMOS_ALARM_NONE
var/alarmActivated = 0 // Manually activated (independent from danger level)
var/buildstage = 2 //2 is built, 1 is building, 0 is frame.
var/buildstage = AIR_ALARM_READY
var/target_temperature = T20C
var/regulating_temperature = 0
@@ -948,24 +952,6 @@
switch(buildstage)
if(2)
if(isscrewdriver(I)) // Opening that Air Alarm up.
wiresexposed = !wiresexposed
to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"]")
update_icon()
return
if(iswirecutter(I)) // cutting the wires out
if(wires.wires_status == 31) // all wires cut
var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil()
new_coil.amount = 5
new_coil.forceMove(user.loc)
buildstage = 1
update_icon()
return
if(wiresexposed && ((ismultitool(I) || iswirecutter(I))))
return attack_hand(user)
if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))// trying to unlock the interface with an ID card
if(stat & (NOPOWER|BROKEN))
to_chat(user, "It does nothing")
@@ -980,7 +966,7 @@
return
if(1)
if(istype(I, /obj/item/stack/cable_coil))
if(iscoil(I))
var/obj/item/stack/cable_coil/coil = I
if(coil.amount < 5)
to_chat(user, "You need more cable for this!")
@@ -996,19 +982,6 @@
update_icon()
first_run()
return
else if(iscrowbar(I))
to_chat(user, "You start prying out the circuit.")
playsound(get_turf(src), I.usesound, 50, 1)
if(do_after(user, 20 * I.toolspeed, target = src))
if(buildstage != 1)
return
to_chat(user, "You pry out the circuit!")
var/obj/item/airalarm_electronics/circuit = new /obj/item/airalarm_electronics()
circuit.forceMove(user.loc)
buildstage = 0
update_icon()
return
if(0)
if(istype(I, /obj/item/airalarm_electronics))
to_chat(user, "You insert the circuit!")
@@ -1017,16 +990,70 @@
buildstage = 1
update_icon()
return
else if(iswrench(I))
to_chat(user, "You remove the fire alarm assembly from the wall!")
new /obj/item/mounted/frame/alarm_frame(get_turf(user))
playsound(get_turf(src), I.usesound, 50, 1)
qdel(src)
return
return ..()
/obj/machinery/alarm/crowbar_act(mob/user, obj/item/I)
if(buildstage != AIR_ALARM_BUILDING)
return
. = TRUE
if(!I.tool_start_check(user, 0))
return
to_chat(user, "You start prying out the circuit.")
if(!I.use_tool(src, user, 20, volume = I.tool_volume))
return
if(buildstage != AIR_ALARM_BUILDING)
return
to_chat(user, "You pry out the circuit!")
new /obj/item/airalarm_electronics(user.drop_location())
buildstage = AIR_ALARM_FRAME
update_icon()
/obj/machinery/alarm/multitool_act(mob/user, obj/item/I)
if(buildstage != AIR_ALARM_READY)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(wiresexposed)
attack_hand(user)
/obj/machinery/alarm/screwdriver_act(mob/user, obj/item/I)
if(buildstage != AIR_ALARM_READY)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
wiresexposed = !wiresexposed
update_icon()
if(wiresexposed)
SCREWDRIVER_OPEN_PANEL_MESSAGE
else
SCREWDRIVER_CLOSE_PANEL_MESSAGE
/obj/machinery/alarm/wirecutter_act(mob/user, obj/item/I)
if(buildstage != AIR_ALARM_READY)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(wires.wires_status == 31) // all wires cut
var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil(user.drop_location())
new_coil.amount = 5
buildstage = AIR_ALARM_BUILDING
update_icon()
if(wiresexposed)
wires.Interact(user)
/obj/machinery/alarm/wrench_act(mob/user, obj/item/I)
if(buildstage != AIR_ALARM_FRAME)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
new /obj/item/mounted/frame/alarm_frame(get_turf(user))
WRENCH_UNANCHOR_WALL_MESSAGE
qdel(src)
/obj/machinery/alarm/power_change()
if(powered(power_channel))
stat &= ~NOPOWER
@@ -1076,3 +1103,8 @@ Just an object used in constructing air alarms
origin_tech = "engineering=2;programming=1"
toolspeed = 1
usesound = 'sound/items/deconstruct.ogg'
#undef AIR_ALARM_FRAME
#undef AIR_ALARM_BUILDING
#undef AIR_ALARM_READY
+11 -35
View File
@@ -78,7 +78,6 @@ var/datum/canister_icons/canister_icon_container = new()
use_power = NO_POWER_USE
interact_offline = 1
var/release_log = ""
var/busy = 0
var/update_flag = 0
/obj/machinery/portable_atmospherics/canister/New()
@@ -264,22 +263,6 @@ update_flag
return
canister_break()
/obj/machinery/portable_atmospherics/canister/attackby(obj/item/I, mob/user, params)
if(user.a_intent != INTENT_HARM && iswelder(I))
var/obj/item/weldingtool/WT = I
if(stat & BROKEN)
if(!WT.remove_fuel(0, user))
return
playsound(loc, WT.usesound, 40, 1)
to_chat(user, "<span class='notice'>You begin cutting [src] apart...</span>")
if(do_after(user, 30, target = src))
deconstruct(TRUE)
else
to_chat(user, "<span class='notice'>You cannot slice [src] apart when it isn't broken.</span>")
return TRUE
else
return ..()
/obj/machinery/portable_atmospherics/canister/proc/canister_break()
disconnect()
var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles())
@@ -610,21 +593,14 @@ update_flag
src.update_icon() // Otherwise new canisters do not have their icon updated with the pressure light, likely want to add this to the canister class constructor, avoiding at current time to refrain from screwing up code for other canisters. --DZD
return 1
/obj/machinery/portable_atmospherics/canister/proc/weld(var/obj/item/weldingtool/WT, var/mob/user)
if(busy)
return 0
if(!WT.remove_fuel(0, user))
return 0
// Do after stuff here
to_chat(user, "<span class='notice'>You start to slice away at \the [src]...</span>")
playsound(src.loc, WT.usesound, 50, 1)
busy = 1
if(do_after(user, 50 * WT.toolspeed, target = src))
busy = 0
if(!WT.isOn())
return 0
return 1
busy = 0
return 0
/obj/machinery/portable_atmospherics/canister/welder_act(mob/user, obj/item/I)
if(!(stat & BROKEN))
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
WELDER_ATTEMPT_SLICING_MESSAGE
if(I.use_tool(src, user, 50, volume = I.tool_volume))
to_chat(user, "<span class='notice'>You salvage whats left of [src]!</span>")
new /obj/item/stack/sheet/metal(drop_location(), 3)
qdel(src)
@@ -126,30 +126,32 @@
src.holding = T
update_icon()
return
else if(istype(W, /obj/item/wrench))
if(connected_port)
disconnect()
to_chat(user, "<span class='notice'>You disconnect [name] from the port.</span>")
update_icon()
return
else
var/obj/machinery/atmospherics/unary/portables_connector/possible_port = locate(/obj/machinery/atmospherics/unary/portables_connector/) in loc
if(possible_port)
if(connect(possible_port))
to_chat(user, "<span class='notice'>You connect [name] to the port.</span>")
update_icon()
return
else
to_chat(user, "<span class='notice'>[name] failed to connect to the port.</span>")
return
else
to_chat(user, "<span class='notice'>Nothing happens.</span>")
return
if((istype(W, /obj/item/analyzer)) && get_dist(user, src) <= 1)
atmosanalyzer_scan(air_contents, user)
return
return ..()
/obj/machinery/portable_atmospherics/wrench_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(connected_port)
disconnect()
to_chat(user, "<span class='notice'>You disconnect [name] from the port.</span>")
update_icon()
else
var/obj/machinery/atmospherics/unary/portables_connector/possible_port = locate(/obj/machinery/atmospherics/unary/portables_connector/) in loc
if(possible_port)
if(connect(possible_port))
to_chat(user, "<span class='notice'>You connect [src] to the port.</span>")
update_icon()
return
else
to_chat(user, "<span class='notice'>[src] failed to connect to the port.</span>")
return
else
to_chat(user, "<span class='notice'>Nothing happens.</span>")
/obj/machinery/portable_atmospherics/attacked_by(obj/item/I, mob/user)
if(I.force < 10 && !(stat & BROKEN))
take_damage(0)
+44 -13
View File
@@ -174,21 +174,8 @@
if(busy)
to_chat(user, "<span class='alert'>The autolathe is busy. Please wait for completion of previous operation.</span>")
return 1
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O))
SSnanoui.update_uis(src)
return
if(exchange_parts(user, O))
return
if(panel_open)
if(istype(O, /obj/item/crowbar))
default_deconstruction_crowbar(O)
return 1
else
attack_hand(user)
return 1
if(stat)
return 1
@@ -215,6 +202,50 @@
return ..()
/obj/machinery/autolathe/crowbar_act(mob/user, obj/item/I)
if(!I.use_tool(src, user, 0, volume = 0))
return
. = TRUE
if(busy)
to_chat(user, "<span class='alert'>The autolathe is busy. Please wait for completion of previous operation.</span>")
return
if(panel_open)
default_deconstruction_crowbar(user, I)
I.play_tool_sound(user, I.tool_volume)
/obj/machinery/autolathe/screwdriver_act(mob/user, obj/item/I)
if(!I.use_tool(src, user, 0, volume = 0))
return
. = TRUE
if(busy)
to_chat(user, "<span class='alert'>The autolathe is busy. Please wait for completion of previous operation.</span>")
return
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", I))
SSnanoui.update_uis(src)
I.play_tool_sound(user, I.tool_volume)
/obj/machinery/autolathe/wirecutter_act(mob/user, obj/item/I)
if(!panel_open)
return
if(!I.use_tool(src, user, 0, volume = 0))
return
. = TRUE
if(busy)
to_chat(user, "<span class='alert'>The autolathe is busy. Please wait for completion of previous operation.</span>")
return
interact(user)
/obj/machinery/autolathe/multitool_act(mob/user, obj/item/I)
if(!panel_open)
return
if(!I.use_tool(src, user, 0, volume = 0))
return
. = TRUE
if(busy)
to_chat(user, "<span class='alert'>The autolathe is busy. Please wait for completion of previous operation.</span>")
return
interact(user)
/obj/machinery/autolathe/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
switch(id_inserted)
if(MAT_METAL)
+35 -21
View File
@@ -127,27 +127,7 @@
var/msg = "<span class='notice'>You attach [I] into the assembly inner circuits.</span>"
var/msg2 = "<span class='notice'>The camera already has that upgrade!</span>"
// DECONSTRUCTION
if(isscrewdriver(I))
panel_open = !panel_open
to_chat(user, "<span class='notice'>You screw the camera's panel [panel_open ? "open" : "closed"].</span>")
playsound(loc, I.usesound, 50, 1)
else if((iswirecutter(I) || ismultitool(I)) && panel_open)
wires.Interact(user)
else if(iswelder(I) && panel_open && wires.CanDeconstruct())
var/obj/item/weldingtool/WT = I
if(!WT.remove_fuel(0, user))
return
to_chat(user, "<span class='notice'>You start to weld [src]...</span>")
playsound(loc, WT.usesound, 50, 1)
if(do_after(user, 100 * WT.toolspeed, target = src))
user.visible_message("<span class='warning'>[user] unwelds [src], leaving it as just a frame bolted to the wall.</span>",
"<span class='warning'>You unweld [src], leaving it as just a frame bolted to the wall</span>")
deconstruct(TRUE)
else if(istype(I, /obj/item/analyzer) && panel_open) //XRay
if(istype(I, /obj/item/analyzer) && panel_open) //XRay
if(!user.drop_item())
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return
@@ -233,6 +213,40 @@
else
return ..()
/obj/machinery/camera/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
panel_open = !panel_open
to_chat(user, "<span class='notice'>You screw [src]'s panel [panel_open ? "open" : "closed"].</span>")
/obj/machinery/camera/wirecutter_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = 0))
return
if(panel_open)
wires.Interact(user)
/obj/machinery/camera/multitool_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = 0))
return
if(panel_open)
wires.Interact(user)
/obj/machinery/camera/welder_act(mob/user, obj/item/I)
if(!panel_open || !wires.CanDeconstruct())
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
WELDER_ATTEMPT_WELD_MESSAGE
if(I.use_tool(src, user, 100, volume = I.tool_volume))
visible_message("<span class='warning'>[user] unwelds [src], leaving it as just a frame bolted to the wall.</span>",
"<span class='warning'>You unweld [src], leaving it as just a frame bolted to the wall</span>")
deconstruct(TRUE)
/obj/machinery/camera/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
if(stat & BROKEN)
return damage_amount
+120 -127
View File
@@ -3,6 +3,7 @@
#define ASSEMBLY_WELDED 2 // Welded in place
#define ASSEMBLY_WIRED 3 // Wires attached (Upgradable now)
#define ASSEMBLY_BUILT 4 // Fully built (incl panel closed)
#define HEY_IM_WORKING_HERE 666 //So nobody can mess with the camera while we're inputting settings
/obj/item/camera_assembly
name = "camera assembly"
@@ -16,7 +17,6 @@
var/list/obj/item/possible_upgrades = list(/obj/item/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/analyzer)
var/list/upgrades = list()
var/state = ASSEMBLY_UNBUILT
var/busy = FALSE
/obj/item/camera_assembly/Destroy()
@@ -24,106 +24,18 @@
return ..()
/obj/item/camera_assembly/attackby(obj/item/I, mob/living/user, params)
switch(state)
if(ASSEMBLY_UNBUILT)
// State 0
if(iswrench(I) && isturf(loc))
playsound(loc, I.usesound, 50, 1)
to_chat(user, "<span class='notice'>You wrench the assembly into place.</span>")
anchored = 1
state = ASSEMBLY_WRENCHED
update_icon()
auto_turn()
return
if(ASSEMBLY_WRENCHED)
// State 1
if(iswelder(I))
if(weld(I, user))
to_chat(user, "<span class='notice'>You weld the assembly securely into place.</span>")
anchored = TRUE
state = ASSEMBLY_WELDED
return
else if(iswrench(I))
playsound(loc, I.usesound, 50, 1)
to_chat(user, "<span class='notice'>You unattach the assembly from it's place.</span>")
anchored = FALSE
update_icon()
state = ASSEMBLY_UNBUILT
return
if(ASSEMBLY_WELDED)
if(iscoil(I))
var/obj/item/stack/cable_coil/C = I
if(C.use(2))
to_chat(user, "<span class='notice'>You add wires to the assembly.</span>")
playsound(loc, I.usesound, 50, 1)
state = ASSEMBLY_WIRED
else
to_chat(user, "<span class='warning'>You need 2 coils of wire to wire the assembly.</span>")
return
else if(iswelder(I))
if(weld(I, user))
to_chat(user, "<span class='notice'>You unweld the assembly from it's place.</span>")
state = ASSEMBLY_WRENCHED
anchored = TRUE
return
if(ASSEMBLY_WIRED)
if(isscrewdriver(I))
playsound(loc, I.usesound, 50, 1)
var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13"))
if(!input)
to_chat(usr, "<span class='warning'>No input found please hang up and try your call again.</span>")
return
var/list/tempnetwork = splittext(input, ",")
if(tempnetwork.len < 1)
to_chat(usr, "<span class='warning'>No network found please hang up and try your call again.</span>")
return
var/area/camera_area = get_area(src)
var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])"
input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag))
state = ASSEMBLY_BUILT
var/obj/machinery/camera/C = new(loc)
loc = C
C.assembly = src
C.auto_turn()
C.network = uniquelist(tempnetwork)
tempnetwork = difflist(C.network,GLOB.restricted_camera_networks)
if(!tempnetwork.len) // Camera isn't on any open network - remove its chunk from AI visibility.
cameranet.removeCamera(C)
C.c_tag = input
for(var/i = 5; i >= 0; i -= 1)
var/direct = input(user, "Direction?", "Assembling Camera", null) in list("LEAVE IT", "NORTH", "EAST", "SOUTH", "WEST" )
if(direct != "LEAVE IT")
C.dir = text2dir(direct)
if(i != 0)
var/confirm = alert(user, "Is this what you want? Chances Remaining: [i]", "Confirmation", "Yes", "No")
if(confirm == "Yes")
break
return
else if(iswirecutter(I))
new/obj/item/stack/cable_coil(get_turf(src), 2)
playsound(loc, I.usesound, 50, 1)
to_chat(user, "<span class='notice'>You cut the wires from the circuits.</span>")
state = ASSEMBLY_WELDED
return
if(state == ASSEMBLY_WELDED && iscoil(I))
var/obj/item/stack/cable_coil/C = I
if(C.use(2))
to_chat(user, "<span class='notice'>You add wires to the assembly.</span>")
playsound(loc, I.usesound, 50, 1)
state = ASSEMBLY_WIRED
else
to_chat(user, "<span class='warning'>You need 2 coils of wire to wire the assembly.</span>")
return
// Upgrades!
if(is_type_in_list(I, possible_upgrades) && !is_type_in_list(I, upgrades)) // Is a possible upgrade and isn't in the camera already.
else if(is_type_in_list(I, possible_upgrades) && !is_type_in_list(I, upgrades)) // Is a possible upgrade and isn't in the camera already.
if(!user.unEquip(I))
to_chat(user, "<span class='warning'>[I] is stuck!</span>")
return
@@ -132,20 +44,117 @@
user.drop_item()
I.loc = src
return
// Taking out upgrades
else if(iscrowbar(I) && upgrades.len)
var/obj/U = locate(/obj) in upgrades
if(U)
to_chat(user, "<span class='notice'>You unattach an upgrade from the assembly.</span>")
playsound(loc, I.usesound, 50, 1)
U.loc = get_turf(src)
upgrades -= U
return
else
return ..()
/obj/item/camera_assembly/crowbar_act(mob/user, obj/item/I)
if(!upgrades.len)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
var/obj/U = locate(/obj) in upgrades
if(U)
to_chat(user, "<span class='notice'>You unattach an upgrade from the assembly.</span>")
playsound(loc, I.usesound, 50, 1)
U.loc = get_turf(src)
upgrades -= U
/obj/item/camera_assembly/screwdriver_act(mob/user, obj/item/I)
if(state != ASSEMBLY_WIRED)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
state = HEY_IM_WORKING_HERE
var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13"))
if(!input)
state = ASSEMBLY_WIRED
to_chat(usr, "<span class='warning'>No input found please hang up and try your call again.</span>")
return
var/list/tempnetwork = splittext(input, ",")
if(tempnetwork.len < 1)
state = ASSEMBLY_WIRED
to_chat(usr, "<span class='warning'>No network found please hang up and try your call again.</span>")
return
var/area/camera_area = get_area(src)
var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])"
input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag))
state = ASSEMBLY_BUILT
var/obj/machinery/camera/C = new(loc)
loc = C
C.assembly = src
C.auto_turn()
C.network = uniquelist(tempnetwork)
tempnetwork = difflist(C.network,GLOB.restricted_camera_networks)
if(!tempnetwork.len) // Camera isn't on any open network - remove its chunk from AI visibility.
cameranet.removeCamera(C)
C.c_tag = input
for(var/i = 5; i >= 0; i -= 1)
var/direct = input(user, "Direction?", "Assembling Camera", null) in list("LEAVE IT", "NORTH", "EAST", "SOUTH", "WEST" )
if(direct != "LEAVE IT")
C.dir = text2dir(direct)
if(i != 0)
var/confirm = alert(user, "Is this what you want? Chances Remaining: [i]", "Confirmation", "Yes", "No")
if(confirm == "Yes")
break
/obj/item/camera_assembly/wirecutter_act(mob/user, obj/item/I)
if(state != ASSEMBLY_WIRED)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
new/obj/item/stack/cable_coil(get_turf(src), 2)
WIRECUTTER_SNIP_MESSAGE
state = ASSEMBLY_WELDED
return
/obj/item/camera_assembly/wrench_act(mob/user, obj/item/I)
if(state != ASSEMBLY_UNBUILT && state != ASSEMBLY_WRENCHED)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(state == ASSEMBLY_UNBUILT && isturf(loc))
WRENCH_ANCHOR_TO_WALL_MESSAGE
anchored = TRUE
state = ASSEMBLY_WRENCHED
update_icon()
auto_turn()
else if(state == ASSEMBLY_WRENCHED)
WRENCH_UNANCHOR_WALL_MESSAGE
anchored = FALSE
update_icon()
state = ASSEMBLY_UNBUILT
else
to_chat(user, "<span class='warning'>[src] can't fit here!</span>")
/obj/item/camera_assembly/welder_act(mob/user, obj/item/I)
if(state == ASSEMBLY_UNBUILT)
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
WELDER_ATTEMPT_WELD_MESSAGE
if(state == ASSEMBLY_WRENCHED)
if(!I.use_tool(src, user, 50, volume = I.tool_volume))
return
to_chat(user, "<span class='notice'>You weld [src] into place.</span>")
state = ASSEMBLY_WELDED
else if(state == ASSEMBLY_WELDED)
if(!I.use_tool(src, user, 50, volume = I.tool_volume))
return
to_chat(user, "<span class='notice'>You unweld [src] from its place.</span>")
state = ASSEMBLY_WRENCHED
/obj/item/camera_assembly/update_icon()
if(anchored)
icon_state = "camera1"
@@ -156,23 +165,6 @@
if(!anchored)
..()
/obj/item/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user)
if(busy)
return FALSE
if(!WT.remove_fuel(0, user))
return FALSE
to_chat(user, "<span class='notice'>You start to weld the [src]...</span>")
playsound(loc, WT.usesound, 50, 1)
busy = TRUE
if(do_after(user, 20 * WT.toolspeed, target = src))
busy = FALSE
if(!WT.isOn())
return FALSE
return TRUE
busy = FALSE
return FALSE
/obj/item/camera_assembly/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
new /obj/item/stack/sheet/metal(loc)
@@ -184,3 +176,4 @@
#undef ASSEMBLY_WELDED
#undef ASSEMBLY_WIRED
#undef ASSEMBLY_BUILT
#undef HEY_IM_WORKING_HERE
+13 -8
View File
@@ -68,17 +68,22 @@
user.visible_message("[user] inserts a cell into the charger.", "<span class='notice'>You insert a cell into the charger.</span>")
chargelevel = -1
updateicon()
else if(iswrench(I))
if(charging)
to_chat(user, "<span class='warning'>Remove the cell first!</span>")
return
anchored = !anchored
to_chat(user, "<span class='notice'>You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground</span>")
playsound(src.loc, I.usesound, 75, 1)
else
return ..()
/obj/machinery/cell_charger/wrench_act(mob/user, obj/item/I)
. = TRUE
if(charging)
to_chat(user, "<span class='warning'>Remove the cell first!</span>")
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
anchored = !anchored
if(anchored)
WRENCH_ANCHOR_MESSAGE
else
WRENCH_UNANCHOR_MESSAGE
/obj/machinery/cell_charger/proc/removecell()
charging.update_icon()
+35 -27
View File
@@ -126,6 +126,7 @@
read_only = 1
/obj/item/disk/data/demo/New()
..()
initialize()
buf.types=DNA2_BUF_UE|DNA2_BUF_UI
//data = "066000033000000000AF00330660FF4DB002690"
@@ -145,6 +146,7 @@
read_only = 1
/obj/item/disk/data/monkey/New()
..()
initialize()
buf.types=DNA2_BUF_SE
var/list/new_SE=list(0x098,0x3E8,0x403,0x44C,0x39F,0x4B0,0x59D,0x514,0x5FC,0x578,0x5DC,0x640,0x6A4)
@@ -363,16 +365,9 @@
//Let's unlock this early I guess. Might be too early, needs tweaking.
/obj/machinery/clonepod/attackby(obj/item/I, mob/user, params)
if(!(occupant || mess))
if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", I))
return
if(exchange_parts(user, I))
return
if(default_deconstruction_crowbar(I))
return
if(I.GetID())
if(!check_access(I))
to_chat(user, "<span class='danger'>Access Denied.</span>")
@@ -392,29 +387,42 @@
to_chat(user, "<span class='notice'>[src] processes [I].</span>")
biomass += BIOMASS_MEAT_AMOUNT
qdel(I)
else if(iswrench(I))
if(occupant)
to_chat(user, "<span class='warning'>Can not do that while [src] is in use.</span>")
else
if(anchored)
anchored = FALSE
connected.pods -= src
connected = null
else
anchored = TRUE
playsound(loc, I.usesound, 100, 1)
if(anchored)
user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.")
else
user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.")
else if(ismultitool(I))
var/obj/item/multitool/M = I
M.buffer = src
to_chat(user, "<span class='notice'>You load connection data from [src] to [M].</span>")
return
else
return ..()
/obj/machinery/clonepod/crowbar_act(mob/user, obj/item/I)
. = TRUE
default_deconstruction_crowbar(user, I)
/obj/machinery/clonepod/multitool_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(!I.multitool_check_buffer(user))
return
var/obj/item/multitool/M = I
M.set_multitool_buffer(user, src)
/obj/machinery/clonepod/screwdriver_act(mob/user, obj/item/I)
. = TRUE
default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", I)
/obj/machinery/clonepod/wrench_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(occupant)
to_chat(user, "<span class='warning'>Can not do that while [src] is in use.</span>")
return
if(anchored)
WRENCH_UNANCHOR_MESSAGE
anchored = FALSE
connected.pods -= src
connected = null
else
WRENCH_ANCHOR_MESSAGE
anchored = TRUE
/obj/machinery/clonepod/emag_act(user)
if(isnull(occupant))
return
@@ -415,9 +415,11 @@
var/active = 0
/obj/item/holo/esword/green/New()
..()
item_color = "green"
/obj/item/holo/esword/red/New()
..()
item_color = "red"
/obj/item/holo/esword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
@@ -426,6 +428,7 @@
return 0
/obj/item/holo/esword/New()
..()
item_color = pick("red","blue","green","purple")
/obj/item/holo/esword/attack_self(mob/living/user as mob)
+174 -174
View File
@@ -17,197 +17,185 @@
return ..()
/obj/structure/AIcore/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/wrench))
return default_unfasten_wrench(user, P, 20)
if(!anchored)
if(iswelder(P))
if(state != EMPTY_CORE)
to_chat(user, "<span class='warning'>The core must be empty to deconstruct it!</span>")
switch(state)
if(EMPTY_CORE)
if(istype(P, /obj/item/circuitboard/aicore))
if(!user.drop_item())
return
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You place the circuit board inside the frame.</span>")
update_icon()
state = CIRCUIT_CORE
P.forceMove(src)
circuit = P
return
var/obj/item/weldingtool/WT = P
if(!WT.isOn())
to_chat(user, "<span class='warning'>The welder must be on for this task!</span>")
return
playsound(loc, WT.usesound, 50, 1)
to_chat(user, "<span class='notice'>You start to deconstruct the frame...</span>")
if(do_after(user, 20*P.toolspeed, target = src) && src && state == EMPTY_CORE && WT && WT.remove_fuel(0, user))
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
deconstruct(TRUE)
return
else
switch(state)
if(EMPTY_CORE)
if(istype(P, /obj/item/circuitboard/aicore))
if(!user.drop_item())
return
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You place the circuit board inside the frame.</span>")
update_icon()
state = CIRCUIT_CORE
P.forceMove(src)
circuit = P
return
if(CIRCUIT_CORE)
if(isscrewdriver(P))
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You screw the circuit board into place.</span>")
state = SCREWED_CORE
update_icon()
return
if(iscrowbar(P))
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You remove the circuit board.</span>")
state = EMPTY_CORE
update_icon()
circuit.forceMove(loc)
circuit = null
return
if(SCREWED_CORE)
if(iswirecutter(P) && circuit)
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
state = CIRCUIT_CORE
update_icon()
return
if(istype(P, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = P
if(C.get_amount() >= 5)
playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You start to add cables to the frame...</span>")
if(do_after(user, 20, target = src) && state == SCREWED_CORE && C.use(5))
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
state = CABLED_CORE
update_icon()
else
to_chat(user, "<span class='warning'>You need five lengths of cable to wire the AI core!</span>")
return
if(CABLED_CORE)
if(iswirecutter(P))
if(brain)
to_chat(user, "<span class='warning'>Get that [brain.name] out of there first!</span>")
else
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You remove the cables.</span>")
state = SCREWED_CORE
if(SCREWED_CORE)
if(istype(P, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = P
if(C.get_amount() >= 5)
playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You start to add cables to the frame...</span>")
if(do_after(user, 20, target = src) && state == SCREWED_CORE && C.use(5))
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
state = CABLED_CORE
update_icon()
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc )
A.amount = 5
else
to_chat(user, "<span class='warning'>You need five lengths of cable to wire the AI core!</span>")
return
if(CABLED_CORE)
if(istype(P, /obj/item/stack/sheet/rglass))
var/obj/item/stack/sheet/rglass/G = P
if(G.get_amount() >= 2)
playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You start to put in the glass panel...</span>")
if(do_after(user, 20, target = src) && state == CABLED_CORE && G.use(2))
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
state = GLASS_CORE
update_icon()
else
to_chat(user, "<span class='warning'>You need two sheets of reinforced glass to insert them into the AI core!</span>")
return
if(istype(P, /obj/item/aiModule/purge))
laws.clear_inherent_laws()
to_chat(usr, "<span class='notice'>Law module applied.</span>")
return
if(istype(P, /obj/item/aiModule/freeform))
var/obj/item/aiModule/freeform/M = P
laws.add_inherent_law(M.newFreeFormLaw)
to_chat(usr, "<span class='notice'>Added a freeform law.</span>")
return
if(istype(P, /obj/item/aiModule))
var/obj/item/aiModule/M = P
if(!M.laws)
to_chat(usr, "<span class='warning'>This AI module can not be applied directly to AI cores.</span>")
return
laws = M.laws
if(istype(P, /obj/item/mmi) && !brain)
var/obj/item/mmi/M = P
if(!M.brainmob)
to_chat(user, "<span class='warning'>Sticking an empty [P] into the frame would sort of defeat the purpose.</span>")
return
if(M.brainmob.stat == DEAD)
to_chat(user, "<span class='warning'>Sticking a dead [P] into the frame would sort of defeat the purpose.</span>")
return
if(istype(P, /obj/item/stack/sheet/rglass))
var/obj/item/stack/sheet/rglass/G = P
if(G.get_amount() >= 2)
playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You start to put in the glass panel...</span>")
if(do_after(user, 20, target = src) && state == CABLED_CORE && G.use(2))
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
state = GLASS_CORE
update_icon()
else
to_chat(user, "<span class='warning'>You need two sheets of reinforced glass to insert them into the AI core!</span>")
if(!M.brainmob.client)
to_chat(user, "<span class='warning'>Sticking an inactive [M.name] into the frame would sort of defeat the purpose.</span>")
return
if(istype(P, /obj/item/aiModule/purge))
laws.clear_inherent_laws()
to_chat(usr, "<span class='notice'>Law module applied.</span>")
if(jobban_isbanned(M.brainmob, "AI") || jobban_isbanned(M.brainmob, "nonhumandept"))
to_chat(user, "<span class='warning'>This [P] does not seem to fit.</span>")
return
if(istype(P, /obj/item/aiModule/freeform))
var/obj/item/aiModule/freeform/M = P
laws.add_inherent_law(M.newFreeFormLaw)
to_chat(usr, "<span class='notice'>Added a freeform law.</span>")
if(!M.brainmob.mind)
to_chat(user, "<span class='warning'>This [M.name] is mindless!</span>")
return
if(istype(P, /obj/item/aiModule))
var/obj/item/aiModule/M = P
if(!M.laws)
to_chat(usr, "<span class='warning'>This AI module can not be applied directly to AI cores.</span>")
return
laws = M.laws
if(istype(P, /obj/item/mmi) && !brain)
var/obj/item/mmi/M = P
if(!M.brainmob)
to_chat(user, "<span class='warning'>Sticking an empty [P] into the frame would sort of defeat the purpose.</span>")
return
if(M.brainmob.stat == DEAD)
to_chat(user, "<span class='warning'>Sticking a dead [P] into the frame would sort of defeat the purpose.</span>")
return
if(!M.brainmob.client)
to_chat(user, "<span class='warning'>Sticking an inactive [M.name] into the frame would sort of defeat the purpose.</span>")
return
if(jobban_isbanned(M.brainmob, "AI") || jobban_isbanned(M.brainmob, "nonhumandept"))
to_chat(user, "<span class='warning'>This [P] does not seem to fit.</span>")
return
if(!M.brainmob.mind)
to_chat(user, "<span class='warning'>This [M.name] is mindless!</span>")
return
if(istype(P, /obj/item/mmi/syndie))
to_chat(user, "<span class='warning'>This MMI does not seem to fit!</span>")
return
if(!user.drop_item())
return
M.forceMove(src)
brain = M
to_chat(user, "<span class='notice'>You add [M.name] to the frame.</span>")
update_icon()
if(istype(P, /obj/item/mmi/syndie))
to_chat(user, "<span class='warning'>This MMI does not seem to fit!</span>")
return
if(iscrowbar(P) && brain)
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You remove the brain.</span>")
brain.forceMove(loc)
brain = null
update_icon()
if(!user.drop_item())
return
if(GLASS_CORE)
if(istype(P, /obj/item/crowbar))
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
state = CABLED_CORE
update_icon()
new /obj/item/stack/sheet/rglass(loc, 2)
return
M.forceMove(src)
brain = M
to_chat(user, "<span class='notice'>You add [M.name] to the frame.</span>")
update_icon()
return
if(isscrewdriver(P))
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
if(!brain)
var/open_for_latejoin = alert(user, "Would you like this core to be open for latejoining AIs?", "Latejoin", "Yes", "Yes", "No") == "Yes"
var/obj/structure/AIcore/deactivated/D = new(loc)
if(open_for_latejoin)
empty_playable_ai_cores += D
else
if(brain.brainmob.mind)
SSticker.mode.remove_cultist(brain.brainmob.mind, 1)
SSticker.mode.remove_revolutionary(brain.brainmob.mind, 1)
var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(loc, laws, brain)
if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created
A.rename_self("AI", 1)
feedback_inc("cyborg_ais_created",1)
qdel(src)
if(AI_READY_CORE)
if(istype(P, /obj/item/aicard))
P.transfer_ai("INACTIVE", "AICARD", src, user)
return
if(isscrewdriver(P))
playsound(loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You disconnect the monitor.</span>")
state = GLASS_CORE
update_icon()
return
if(AI_READY_CORE)
if(istype(P, /obj/item/aicard))
P.transfer_ai("INACTIVE", "AICARD", src, user)
return
return ..()
/obj/structure/AIcore/crowbar_act(mob/living/user, obj/item/I)
if(state !=CIRCUIT_CORE || state != GLASS_CORE || !(state == CABLED_CORE && brain))
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
switch(state)
if(CIRCUIT_CORE)
to_chat(user, "<span class='notice'>You remove the circuit board.</span>")
state = EMPTY_CORE
circuit.forceMove(loc)
circuit = null
return
if(GLASS_CORE)
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
state = CABLED_CORE
new /obj/item/stack/sheet/rglass(loc, 2)
return
if(CABLED_CORE)
if(brain)
to_chat(user, "<span class='notice'>You remove the brain.</span>")
brain.forceMove(loc)
brain = null
update_icon()
/obj/structure/AIcore/screwdriver_act(mob/living/user, obj/item/I)
if(!(state in list(SCREWED_CORE, CIRCUIT_CORE, GLASS_CORE, AI_READY_CORE)))
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
switch(state)
if(SCREWED_CORE)
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
state = CIRCUIT_CORE
if(CIRCUIT_CORE)
to_chat(user, "<span class='notice'>You screw the circuit board into place.</span>")
state = SCREWED_CORE
if(GLASS_CORE)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
if(!brain)
var/open_for_latejoin = alert(user, "Would you like this core to be open for latejoining AIs?", "Latejoin", "Yes", "Yes", "No") == "Yes"
var/obj/structure/AIcore/deactivated/D = new(loc)
if(open_for_latejoin)
empty_playable_ai_cores += D
else
if(brain.brainmob.mind)
SSticker.mode.remove_cultist(brain.brainmob.mind, 1)
SSticker.mode.remove_revolutionary(brain.brainmob.mind, 1)
var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(loc, laws, brain)
if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created
A.rename_self("AI", 1)
feedback_inc("cyborg_ais_created",1)
qdel(src)
if(AI_READY_CORE)
to_chat(user, "<span class='notice'>You disconnect the monitor.</span>")
state = GLASS_CORE
update_icon()
/obj/structure/AIcore/wirecutter_act(mob/living/user, obj/item/I)
if(state != CABLED_CORE)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(brain)
to_chat(user, "<span class='warning'>Get that [brain.name] out of there first!</span>")
else
to_chat(user, "<span class='notice'>You remove the cables.</span>")
state = SCREWED_CORE
update_icon()
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc )
A.amount = 5
/obj/structure/AIcore/wrench_act(mob/living/user, obj/item/I)
. = TRUE
if(!I.tool_use_check(user, 0))
return
default_unfasten_wrench(user, I, 20)
/obj/structure/AIcore/update_icon()
switch(state)
if(EMPTY_CORE)
@@ -237,6 +225,18 @@
new /obj/item/stack/sheet/plasteel(loc, 4)
qdel(src)
/obj/structure/AIcore/welder_act(mob/user, obj/item/I)
if(!state)
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
WELDER_ATTEMPT_WELD_MESSAGE
if(I.use_tool(src, user, 20, volume = I.tool_volume))
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
new /obj/item/stack/sheet/plasteel(drop_location(), 4)
qdel(src)
/obj/structure/AIcore/deactivated
name = "inactive AI"
icon_state = "ai-empty"
+12 -22
View File
@@ -454,17 +454,6 @@
anchored = 1
state = 1
return
if(istype(P, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = P
if(!WT.remove_fuel(0, user))
to_chat(user, "<span class='warning'>The welding tool must be on to complete this task.</span>")
return
playsound(loc, WT.usesound, 50, 1)
if(do_after(user, 20 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
deconstruct(TRUE)
return
if(1)
if(istype(P, /obj/item/wrench))
playsound(loc, P.usesound, 50, 1)
@@ -573,6 +562,18 @@
return ..()
/obj/structure/computerframe/welder_act(mob/user, obj/item/I)
if(state)
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
WELDER_ATTEMPT_SLICING_MESSAGE
if(I.use_tool(src, user, 50, volume = I.tool_volume) && !state)
to_chat(user, "<span class='notice'>You deconstruct [src].</span>")
deconstruct(TRUE)
/obj/structure/computerframe/HONKputer
name = "Bananium Computer-frame"
@@ -588,17 +589,6 @@
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
anchored = 1
state = 1
if(istype(P, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = P
if(!WT.remove_fuel(0, user))
to_chat(user, "<span class='warning'>The welding tool must be on to complete this task.</span>")
return
playsound(loc, WT.usesound, 50, 1)
if(do_after(user, 20 * WT.toolspeed, target = src))
if(!src || !WT.isOn()) return
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
deconstruct(TRUE)
return
if(1)
if(istype(P, /obj/item/wrench))
playsound(loc, P.usesound, 50, 1)
+18 -18
View File
@@ -79,24 +79,24 @@
ui_interact(user)
/obj/machinery/computer/security/telescreen/attackby(obj/item/I, mob/user, params)
if(ismultitool(I))
var/direction = input(user, "Which direction?", "Select direction!") as null|anything in list("North", "East", "South", "West", "Centre")
if(!direction || !Adjacent(user))
return
pixel_x = 0
pixel_y = 0
switch(direction)
if("North")
pixel_y = 32
if("East")
pixel_x = 32
if("South")
pixel_y = -32
if("West")
pixel_x = -32
else
return ..()
/obj/machinery/computer/security/telescreen/multitool_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
var/direction = input(user, "Which direction?", "Select direction!") as null|anything in list("North", "East", "South", "West", "Centre")
if(!direction || !Adjacent(user))
return
pixel_x = 0
pixel_y = 0
switch(direction)
if("North")
pixel_y = 32
if("East")
pixel_x = 32
if("South")
pixel_y = -32
if("West")
pixel_x = -32
/obj/machinery/computer/security/emag_act(user as mob)
if(!emagged)
+6 -6
View File
@@ -133,10 +133,10 @@
if(istype(user, /mob/dead/observer)) return 0
return ..()
/obj/machinery/computer/attackby(obj/item/I, mob/user, params)
if(isscrewdriver(I) && circuit && !(flags & NODECONSTRUCT))
playsound(loc, I.usesound, 50, TRUE)
if(do_after(user, 20 * I.toolspeed, target = src))
deconstruct(TRUE, user)
/obj/machinery/computer/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_start_check(user, 0))
return
return ..()
if(circuit && !(flags & NODECONSTRUCT))
if(I.use_tool(src, user, 20, volume = I.tool_volume))
deconstruct(TRUE, user)
+2 -5
View File
@@ -35,11 +35,8 @@
light_color = LIGHT_COLOR_DARKGREEN
/obj/machinery/computer/message_monitor/attackby(obj/item/O as obj, mob/living/user as mob, params)
if(!istype(user))
return
if(isscrewdriver(O) && emag)
//Stops people from just unscrewing the monitor and putting it back to get the console working again.
/obj/machinery/computer/message_monitor/screwdriver_act(mob/user, obj/item/I)
if(emag) //Stops people from just unscrewing the monitor and putting it back to get the console working again.
to_chat(user, "<span class='warning'>It is too hot to mess with!</span>")
return
return ..()
+2 -2
View File
@@ -71,8 +71,8 @@
health_display = "DEAD"
else if(total_loss)
health_display = "HURT ([total_loss])"
if(is_station_level(M.z) && !istype(M.loc, /turf/space))
loc_display = "[get_area(M)]"
if(is_station_level(Tr.z) && !istype(Tr.loc, /turf/space))
loc_display = "[get_area(Tr)]"
dat += "ID: [T.id] <BR>Subject: [M] <BR>Location: [loc_display] <BR>Health: [health_display] <BR>"
dat += "<A href='?src=[UID()];warn=\ref[T]'>(<font color=red><i>Message Holder</i></font>)</A> |<BR>"
dat += "********************************<BR>"
+26 -24
View File
@@ -257,18 +257,20 @@ to destroy them and players will be able to make replacements.
/obj/machinery/vending/modularpc = "Deluxe Silicate Selections",
/obj/machinery/vending/crittercare = "CritterCare")
/obj/item/circuitboard/vendor/attackby(obj/item/I, mob/user, params)
if(isscrewdriver(I))
var/static/list/display_vending_names_paths
if(!display_vending_names_paths)
display_vending_names_paths = list()
for(var/path in vending_names_paths)
display_vending_names_paths[vending_names_paths[path]] = path
var/choice = input(user, "Choose a new brand","Select an Item") as null|anything in display_vending_names_paths
set_type(display_vending_names_paths[choice])
else
return ..()
/obj/item/circuitboard/vendor/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
var/static/list/display_vending_names_paths
if(!display_vending_names_paths)
display_vending_names_paths = list()
for(var/path in vending_names_paths)
display_vending_names_paths[vending_names_paths[path]] = path
var/choice = input(user, "Choose a new brand","Select an Item") as null|anything in display_vending_names_paths
if(loc != user)
to_chat(user, "<span class='notice'>You need to keep [src] in your hands while doing that!</span>")
return
set_type(display_vending_names_paths[choice])
/obj/item/circuitboard/vendor/proc/set_type(obj/machinery/vending/typepath)
build_path = typepath
@@ -583,20 +585,20 @@ to destroy them and players will be able to make replacements.
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/sheet/glass = 1)
/obj/item/circuitboard/chem_master/attackby(obj/item/I, mob/user, params)
if(isscrewdriver(I))
var/new_name = "ChemMaster"
var/new_path = /obj/machinery/chem_master
/obj/item/circuitboard/chem_master/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
var/new_name = "ChemMaster"
var/new_path = /obj/machinery/chem_master
if(build_path == /obj/machinery/chem_master)
new_name = "CondiMaster"
new_path = /obj/machinery/chem_master/condimaster
if(build_path == /obj/machinery/chem_master)
new_name = "CondiMaster"
new_path = /obj/machinery/chem_master/condimaster
build_path = new_path
name = "circuit board ([new_name] 3000)"
to_chat(user, "<span class='notice'>You change the circuit board setting to \"[new_name]\".</span>")
else
return ..()
build_path = new_path
name = "circuit board ([new_name] 3000)"
to_chat(user, "<span class='notice'>You change the circuit board setting to \"[new_name]\".</span>")
/obj/item/circuitboard/chem_master/condi_master
name = "circuit board (CondiMaster 3000)"
+11 -11
View File
@@ -302,20 +302,9 @@
user.visible_message("[user] adds \a [B] to [src]!", "You add \a [B] to [src]!")
return
if(istype(G, /obj/item/screwdriver))
if(occupant || on)
to_chat(user, "<span class='notice'>The maintenance panel is locked.</span>")
return
default_deconstruction_screwdriver(user, "pod0-o", "pod0", G)
return
if(exchange_parts(user, G))
return
if(default_deconstruction_crowbar(G))
return
if(istype(G, /obj/item/grab))
var/obj/item/grab/GG = G
if(panel_open)
@@ -332,6 +321,17 @@
return
return ..()
/obj/machinery/atmospherics/unary/cryo_cell/crowbar_act(mob/user, obj/item/I)
if(default_deconstruction_crowbar(user, I))
return
/obj/machinery/atmospherics/unary/cryo_cell/screwdriver_act(mob/user, obj/item/I)
if(occupant || on)
to_chat(user, "<span class='notice'>The maintenance panel is locked.</span>")
return TRUE
if(default_deconstruction_screwdriver(user, "pod0-o", "pod0", I))
return TRUE
/obj/machinery/atmospherics/unary/cryo_cell/update_icon()
handle_update_icon()
+3 -2
View File
@@ -380,7 +380,7 @@
cult_mode.bypass_phase()
//Update any existing objectives involving this mob.
for(var/datum/objective/O in all_objectives)
for(var/datum/objective/O in GLOB.all_objectives)
// We don't want revs to get objectives that aren't for heads of staff. Letting
// them win or lose based on cryo is silly so we remove the objective.
if(istype(O,/datum/objective/mutiny) && O.target == occupant.mind)
@@ -395,9 +395,10 @@
if(!O) return
O.find_target()
if(!(O.target))
all_objectives -= O
GLOB.all_objectives -= O
O.owner.objectives -= O
qdel(O)
O.owner.announce_objectives()
if(occupant.mind && occupant.mind.assigned_role)
//Handle job slot/tater cleanup.
var/job = occupant.mind.assigned_role
+12 -11
View File
@@ -57,18 +57,19 @@
STOP_PROCESSING(SSobj, src)
return ..()
/obj/machinery/disco/attackby(obj/item/O, mob/user, params)
if(!active)
if(iswrench(O))
if(!anchored && !isinspace())
to_chat(user,"<span class='notice'>You secure [src] to the floor.</span>")
anchored = TRUE
else if(anchored)
to_chat(user,"<span class='notice'>You unsecure and disconnect [src].</span>")
anchored = FALSE
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
/obj/machinery/disco/wrench_act(mob/user, obj/item/I)
if(active)
return
return ..()
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
if(!anchored && !isinspace())
anchored = TRUE
WRENCH_ANCHOR_MESSAGE
else if(anchored)
anchored = FALSE
WRENCH_UNANCHOR_MESSAGE
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
/obj/machinery/disco/update_icon()
if(active)
+11 -10
View File
@@ -98,16 +98,6 @@
else if(defib && I == defib.paddles)
user.drop_item()
return
else if(iswrench(I))
if(!defib)
user.visible_message("<span class='notice'>[user] unwrenches [src] from the wall!</span>", \
"<span class='notice'>You unwrench [src]!</span>")
new /obj/item/mounted/frame/defib_mount(get_turf(user))
playsound(get_turf(src), I.usesound, 50, 1)
qdel(src)
return
to_chat(user, "<span class='warning'>The [defib] is blocking access to the bolts!</span>")
return
var/obj/item/card/id = I.GetID()
if(id)
if(check_access(id) || security_level >= SEC_LEVEL_RED) //anyone can toggle the clamps in red alert!
@@ -122,6 +112,17 @@
return
return ..()
/obj/machinery/defibrillator_mount/wrench_act(mob/user, obj/item/I)
. = TRUE
if(defib)
to_chat(user, "<span class='warning'>The [defib] is blocking access to the bolts!</span>")
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
WRENCH_UNANCHOR_WALL_MESSAGE
new /obj/item/mounted/frame/defib_mount(get_turf(user))
qdel(src)
/obj/machinery/defibrillator_mount/AltClick(mob/living/carbon/user)
if(!istype(user))
return
+14 -11
View File
@@ -29,17 +29,20 @@
if(stacktype)
new stacktype(get_turf(src), drop_amount)
/obj/structure/barricade/attackby(obj/item/I, mob/user, params)
if(iswelder(I) && user.a_intent != INTENT_HARM && bar_material == METAL)
var/obj/item/weldingtool/WT = I
if(obj_integrity < max_integrity)
if(WT.remove_fuel(0, user))
to_chat(user, "<span class='notice'>You begin repairing [src]...</span>")
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40 * I.toolspeed, target = src))
obj_integrity = Clamp(obj_integrity + 20, 0, max_integrity)
else
return ..()
/obj/structure/barricade/welder_act(mob/user, obj/item/I)
if(obj_integrity >= max_integrity)
to_chat(user, "<span class='notice'>[src] does not need repairs.</span>")
return
if(user.a_intent == INTENT_HARM)
return
if(!I.tool_use_check(user, 0))
return
WELDER_ATTEMPT_REPAIR_MESSAGE
if(I.use_tool(src, user, 40, volume = I.tool_volume))
WELDER_REPAIR_SUCCESS_MESSAGE
obj_integrity = Clamp(obj_integrity + 20, 0, max_integrity)
update_icon()
return TRUE
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
if(locate(/obj/structure/barricade) in get_turf(mover))
+196 -197
View File
@@ -37,6 +37,7 @@
#define AIRLOCK_INTEGRITY_MULTIPLIER 1.5 // How much reinforced doors health increases
#define AIRLOCK_DAMAGE_DEFLECTION_N 21 // Normal airlock damage deflection
#define AIRLOCK_DAMAGE_DEFLECTION_R 30 // Reinforced airlock damage deflection
var/list/airlock_overlays = list()
/obj/machinery/door/airlock
@@ -823,14 +824,9 @@ About the new airlock wires panel:
return 1
/obj/machinery/door/airlock/attackby(obj/item/C, mob/user, params)
if(shock_user(user, 75))
return
add_fingerprint(user)
if(headbutt_airlock(user))//See if the user headbutts the airlock
if(!headbutt_shock_check(user))
return
if(panel_open)
switch(security_level)
if(AIRLOCK_SECURITY_NONE)
@@ -864,116 +860,7 @@ About the new airlock wires panel:
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_R
update_icon()
return
if(AIRLOCK_SECURITY_METAL)
if(iswelder(C))
var/obj/item/weldingtool/WT = C
if(!WT.remove_fuel(2, user))
return
to_chat(user, "<span class='notice'>You begin cutting the panel's shielding...</span>")
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40 * WT.toolspeed, 1, target = src))
if(!panel_open || !WT.isOn())
return
playsound(loc, WT.usesound, 50, 1)
user.visible_message("<span class='notice'>[user] cuts through \the [src]'s shielding.</span>",
"<span class='notice'>You cut through \the [src]'s shielding.</span>",
"<span class='italics'>You hear welding.</span>")
security_level = AIRLOCK_SECURITY_NONE
spawn_atom_to_turf(/obj/item/stack/sheet/metal, user.loc, 2)
update_icon()
return
if(AIRLOCK_SECURITY_PLASTEEL_I_S)
if(iscrowbar(C))
var/obj/item/crowbar/W = C
to_chat(user, "<span class='notice'>You start removing the inner layer of shielding...</span>")
playsound(src, W.usesound, 100, 1)
if(do_after(user, 40 * W.toolspeed, 1, target = src))
if(!panel_open)
return
if(security_level != AIRLOCK_SECURITY_PLASTEEL_I_S)
return
user.visible_message("<span class='notice'>[user] remove \the [src]'s shielding.</span>",
"<span class='notice'>You remove \the [src]'s inner shielding.</span>")
security_level = AIRLOCK_SECURITY_NONE
modify_max_integrity(normal_integrity)
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_N
spawn_atom_to_turf(/obj/item/stack/sheet/plasteel, user.loc, 1)
update_icon()
return
if(AIRLOCK_SECURITY_PLASTEEL_I)
if(iswelder(C))
var/obj/item/weldingtool/WT = C
if(!WT.remove_fuel(2, user))
return
to_chat(user, "<span class='notice'>You begin cutting the inner layer of shielding...</span>")
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40 * WT.toolspeed, 1, target = src))
if(!panel_open || !WT.isOn())
return
playsound(loc, WT.usesound, 50, 1)
user.visible_message("<span class='notice'>[user] cuts through \the [src]'s shielding.</span>",
"<span class='notice'>You cut through \the [src]'s shielding.</span>",
"<span class='italics'>You hear welding.</span>")
security_level = AIRLOCK_SECURITY_PLASTEEL_I_S
return
if(AIRLOCK_SECURITY_PLASTEEL_O_S)
if(iscrowbar(C))
var/obj/item/crowbar/W = C
to_chat(user, "<span class='notice'>You start removing outer layer of shielding...</span>")
playsound(src, W.usesound, 100, 1)
if(do_after(user, 40 * W.toolspeed, 1, target = src))
if(!panel_open)
return
if(security_level != AIRLOCK_SECURITY_PLASTEEL_O_S)
return
user.visible_message("<span class='notice'>[user] remove \the [src]'s shielding.</span>",
"<span class='notice'>You remove \the [src]'s shielding.</span>")
security_level = AIRLOCK_SECURITY_PLASTEEL_I
spawn_atom_to_turf(/obj/item/stack/sheet/plasteel, user.loc, 1)
return
if(AIRLOCK_SECURITY_PLASTEEL_O)
if(iswelder(C))
var/obj/item/weldingtool/WT = C
if(!WT.remove_fuel(2, user))
return
to_chat(user, "<span class='notice'>You begin cutting the outer layer of shielding...</span>")
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40 * WT.toolspeed, 1, target = src))
if(!panel_open || !WT.isOn())
return
playsound(loc, WT.usesound, 50, 1)
user.visible_message("<span class='notice'>[user] cuts through \the [src]'s shielding.</span>",
"<span class='notice'>You cut through \the [src]'s shielding.</span>",
"<span class='italics'>You hear welding.</span>")
security_level = AIRLOCK_SECURITY_PLASTEEL_O_S
return
if(AIRLOCK_SECURITY_PLASTEEL)
if(iswirecutter(C))
var/obj/item/wirecutters/W = C
if(arePowerSystemsOn() && shock(user, 60)) // Protective grille of wiring is electrified
return
to_chat(user, "<span class='notice'>You start cutting through the outer grille.</span>")
playsound(src, W.usesound, 100, 1)
if(do_after(user, 10 * W.toolspeed, 1, target = src))
if(!panel_open)
return
user.visible_message("<span class='notice'>[user] cut through \the [src]'s outer grille.</span>",
"<span class='notice'>You cut through \the [src]'s outer grille.</span>")
security_level = AIRLOCK_SECURITY_PLASTEEL_O
return
if(isscrewdriver(C))
panel_open = !panel_open
to_chat(user, "<span class='notice'>You [panel_open ? "open":"close"] the maintenance panel of the airlock.</span>")
playsound(loc, C.usesound, 50, 1)
update_icon()
else if(iswirecutter(C))
if(note)
remove_airlock_note(user, TRUE)
else
return interact_with_panel(user)
else if(ismultitool(C))
return interact_with_panel(user)
else if(istype(C, /obj/item/assembly/signaler))
return interact_with_panel(user)
else if(istype(C, /obj/item/pai_cable)) // -- TLE
@@ -993,102 +880,214 @@ About the new airlock wires panel:
else
return ..()
/obj/machinery/door/airlock/try_to_weld(obj/item/weldingtool/W, mob/user)
if(!operating && density)
if(user.a_intent != INTENT_HELP)
if(W.remove_fuel(0, user))
/obj/machinery/door/airlock/screwdriver_act(mob/user, obj/item/I)
if(!headbutt_shock_check(user))
return
if(user.a_intent == INTENT_HARM)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
panel_open = !panel_open
to_chat(user, "<span class='notice'>You [panel_open ? "open":"close"] [src]'s maintenance panel.</span>")
update_icon()
/obj/machinery/door/airlock/crowbar_act(mob/user, obj/item/I)
if(!headbutt_shock_check(user))
return
if(user.a_intent == INTENT_HARM)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = 0))
return
if(panel_open && security_level == AIRLOCK_SECURITY_PLASTEEL_I_S)
to_chat(user, "<span class='notice'>You start removing the inner layer of shielding...</span>")
if(I.use_tool(src, user, 40, volume = I.tool_volume))
if(!panel_open || security_level != AIRLOCK_SECURITY_PLASTEEL_I_S)
return
user.visible_message("<span class='notice'>[user] remove \the [src]'s shielding.</span>",
"<span class='notice'>You remove \the [src]'s inner shielding.</span>")
security_level = AIRLOCK_SECURITY_NONE
modify_max_integrity(normal_integrity)
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_N
spawn_atom_to_turf(/obj/item/stack/sheet/plasteel, user.loc, 1)
update_icon()
else if(panel_open && security_level == AIRLOCK_SECURITY_PLASTEEL_O_S)
to_chat(user, "<span class='notice'>You start removing outer layer of shielding...</span>")
if(I.use_tool(src, user, 40, volume = I.tool_volume))
if(!panel_open || security_level != AIRLOCK_SECURITY_PLASTEEL_O_S)
return
user.visible_message("<span class='notice'>[user] remove \the [src]'s shielding.</span>",
"<span class='notice'>You remove \the [src]'s shielding.</span>")
security_level = AIRLOCK_SECURITY_PLASTEEL_I
spawn_atom_to_turf(/obj/item/stack/sheet/plasteel, user.loc, 1)
else
try_to_crowbar(user, I)
/obj/machinery/door/airlock/wirecutter_act(mob/user, obj/item/I)
if(!headbutt_shock_check(user))
return
if(!panel_open || user.a_intent == INTENT_HARM)
return
. = TRUE
if(!I.tool_start_check(user, 0))
return
if(security_level == AIRLOCK_SECURITY_PLASTEEL)
if(arePowerSystemsOn() && shock(user, 60)) // Protective grille of wiring is electrified
return
to_chat(user, "<span class='notice'>You start cutting through the outer grille.</span>")
if(I.use_tool(src, user, 10, volume = I.tool_volume))
if(!panel_open || security_level != AIRLOCK_SECURITY_PLASTEEL)
return
user.visible_message("<span class='notice'>[user] cut through \the [src]'s outer grille.</span>",
"<span class='notice'>You cut through \the [src]'s outer grille.</span>")
security_level = AIRLOCK_SECURITY_PLASTEEL_O
return
if(note)
remove_airlock_note(user, TRUE)
else
return interact_with_panel(user)
/obj/machinery/door/airlock/multitool_act(mob/user, obj/item/I)
if(!headbutt_shock_check(user))
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
interact_with_panel(user)
/obj/machinery/door/airlock/welder_act(mob/user, obj/item/I) //This is god awful but I don't care
if(!headbutt_shock_check(user))
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
switch(security_level)
if(AIRLOCK_SECURITY_METAL)
to_chat(user, "<span class='notice'>You begin cutting the panel's shielding...</span>")
if(!I.use_tool(src, user, 40, volume = I.tool_volume))
return
if(!panel_open)
return
visible_message("<span class='notice'>[user] cuts through \the [src]'s shielding.</span>",
"<span class='notice'>You cut through \the [src]'s shielding.</span>",
"<span class='italics'>You hear welding.</span>")
security_level = AIRLOCK_SECURITY_NONE
spawn_atom_to_turf(/obj/item/stack/sheet/metal, user.loc, 2)
if(AIRLOCK_SECURITY_PLASTEEL_O)
to_chat(user, "<span class='notice'>You begin cutting the outer layer of shielding...</span>")
if(!I.use_tool(src, user, 40, volume = I.tool_volume))
return
if(!panel_open)
return
visible_message("<span class='notice'>[user] cuts through \the [src]'s shielding.</span>",
"<span class='notice'>You cut through \the [src]'s shielding.</span>",
"<span class='italics'>You hear welding.</span>")
security_level = AIRLOCK_SECURITY_PLASTEEL_O_S
if(AIRLOCK_SECURITY_PLASTEEL_I)
to_chat(user, "<span class='notice'>You begin cutting the inner layer of shielding...</span>")
if(!I.use_tool(src, user, 40, volume = I.tool_volume))
return
if(!panel_open)
return
user.visible_message("<span class='notice'>[user] cuts through \the [src]'s shielding.</span>",
"<span class='notice'>You cut through \the [src]'s shielding.</span>",
"<span class='italics'>You hear welding.</span>")
security_level = AIRLOCK_SECURITY_PLASTEEL_I_S
else
if(user.a_intent != INTENT_HELP)
user.visible_message("[user] is [welded ? "unwelding":"welding"] the airlock.", \
"<span class='notice'>You begin [welded ? "unwelding":"welding"] the airlock...</span>", \
"<span class='italics'>You hear welding.</span>")
playsound(loc, W.usesound, 40, 1)
if(do_after(user, 40 * W.toolspeed, 1, target = src, extra_checks = CALLBACK(src, .proc/weld_checks, W, user)))
playsound(loc, 'sound/items/welder2.ogg', 50, 1)
"<span class='notice'>You begin [welded ? "unwelding":"welding"] the airlock...</span>", \
"<span class='italics'>You hear welding.</span>")
if(I.use_tool(src, user, 40, volume = I.tool_volume, extra_checks = CALLBACK(src, .proc/weld_checks, I, user)))
if(!density && !welded)
return
welded = !welded
user.visible_message("[user.name] has [welded? "welded shut":"unwelded"] [src].", \
"<span class='notice'>You [welded ? "weld the airlock shut":"unweld the airlock"].</span>")
"<span class='notice'>You [welded ? "weld the airlock shut":"unweld the airlock"].</span>")
update_icon()
else
if(obj_integrity < max_integrity)
if(W.remove_fuel(0, user))
user.visible_message("[user] is welding the airlock.", \
"<span class='notice'>You begin repairing the airlock...</span>", \
"<span class='italics'>You hear welding.</span>")
playsound(loc, W.usesound, 40, 1)
if(do_after(user, 40 * W.toolspeed, 1, target = src, extra_checks = CALLBACK(src, .proc/weld_checks, W, user)))
playsound(loc, 'sound/items/welder2.ogg', 50, 1)
obj_integrity = max_integrity
stat &= ~BROKEN
user.visible_message("[user.name] has repaired [src].", \
"<span class='notice'>You finish repairing the airlock.</span>")
update_icon()
else if(obj_integrity < max_integrity)
user.visible_message("[user] is welding the airlock.", \
"<span class='notice'>You begin repairing the airlock...</span>", \
"<span class='italics'>You hear welding.</span>")
if(I.use_tool(src, user, 40, volume = I.tool_volume, extra_checks = CALLBACK(src, .proc/weld_checks, I, user)))
obj_integrity = max_integrity
stat &= ~BROKEN
user.visible_message("[user.name] has repaired [src].", \
"<span class='notice'>You finish repairing the airlock.</span>")
update_icon()
else
to_chat(user, "<span class='notice'>The airlock doesn't need repairing.</span>")
update_icon()
/obj/machinery/door/airlock/proc/weld_checks(obj/item/weldingtool/W, mob/user)
return !operating && density && user && W && W.isOn() && user.loc
/obj/machinery/door/airlock/proc/weld_checks(obj/item/I, mob/user)
return !operating && density && user && I && I.tool_use_check() && user.loc
/obj/machinery/door/airlock/try_to_crowbar(obj/item/I, mob/living/user)
var/beingcrowbarred = null
if(iscrowbar(I))
beingcrowbarred = 1
else
beingcrowbarred = 0
if(beingcrowbarred && panel_open && ((emagged) || (density && welded && !operating && !arePowerSystemsOn() && !locked)))
playsound(loc, I.usesound, 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", \
"<span class='notice'>You start to remove electronics from the airlock assembly...</span>")
if(do_after(user, 40 * I.toolspeed, target = src))
deconstruct(TRUE, user)
return
else if(arePowerSystemsOn())
to_chat(user, "<span class='warning'>The airlock's motors resist your efforts to force it!</span>")
else if(locked)
to_chat(user, "<span class='warning'>The airlock's bolts prevent it from being forced!</span>")
else if(!welded && !operating)
if(istype(I, /obj/item/twohanded/fireaxe)) //let's make this more specific
var/obj/item/twohanded/fireaxe/F = I
if(F.wielded)
spawn(0)
if(density)
open(1)
else
close(1)
else
to_chat(user, "<span class='warning'>You need to be wielding the fire axe to do that!</span>")
else
/obj/machinery/door/airlock/proc/headbutt_shock_check(mob/user)
if(shock_user(user, 75))
return
if(headbutt_airlock(user))//See if the user headbutts the airlock
return
return TRUE
/obj/machinery/door/airlock/try_to_crowbar(mob/living/user, obj/item/I) //*scream
if(operating)
return
if(istype(I, /obj/item/twohanded/fireaxe)) //let's make this more specific //FUCK YOU
var/obj/item/twohanded/fireaxe/F = I
if(F.wielded)
spawn(0)
if(density)
open(1)
else
close(1)
if(ispowertool(I)) //jaws of life and rescue claw
if(isElectrified())
shock(user, 100)//it's like sticking a forck in a power socket
return
if(!density)//already open
return
if(locked)
to_chat(user, "<span class='warning'>The bolts are down, it won't budge!</span>")
return
if(welded)
to_chat(user, "<span class='warning'>It's welded, it won't budge!</span>")
return
var/time_to_open = 5
if(arePowerSystemsOn() && !prying_so_hard)
time_to_open = 50
playsound(src, 'sound/machines/airlock_alien_prying.ogg', 100, 1) //is it aliens or just the CE being a dick?
prying_so_hard = TRUE
var/result = do_after(user, time_to_open, target = src)
prying_so_hard = FALSE
if(result)
else
to_chat(user, "<span class='warning'>You need to be wielding the fire axe to do that!</span>")
return
var/beingcrowbarred = FALSE
if(I.tool_behaviour == TOOL_CROWBAR && I.tool_use_check(user, 0))
beingcrowbarred = TRUE
if(beingcrowbarred && panel_open && (emagged || (density && welded && !operating && !arePowerSystemsOn() && !locked)))
user.visible_message("[user] removes the electronics from the airlock assembly.", \
"<span class='notice'>You start to remove electronics from the airlock assembly...</span>")
if(I.use_tool(src, user, 40, volume = I.tool_volume))
deconstruct(TRUE, user)
return
if(welded)
to_chat(user, "<span class='warning'>[src] is welded shut!</span>")
return
if(locked)
to_chat(user, "<span class='warning'>The airlock's bolts prevent it from being forced!</span>")
return
else if(!arePowerSystemsOn())
spawn(0)
if(density)
open(1)
if(density && !open(1))
to_chat(user, "<span class='warning'>Despite your attempts, [src] refuses to open.</span>")
else
close(1)
return
else if(!ispowertool(I))
to_chat(user, "<span class='warning'>The airlock's motors resist your efforts to force it!</span>")
return
if(isElectrified())
shock(user, 100)//it's like sticking a forck in a power socket
return
if(!density)//already open
return
var/time_to_open = 5
if(!prying_so_hard)
time_to_open = 50
playsound(src, 'sound/machines/airlock_alien_prying.ogg', 100, 1) //is it aliens or just the CE being a dick?
prying_so_hard = TRUE
var/result = do_after(user, time_to_open, target = src)
prying_so_hard = FALSE
if(result)
open(1)
if(density && !open(1))
to_chat(user, "<span class='warning'>Despite your attempts, [src] refuses to open.</span>")
/obj/machinery/door/airlock/open(forced=0)
if(operating || welded || locked || emagged)
+30 -16
View File
@@ -379,14 +379,20 @@
return
add_fingerprint(user)
if((iswelder(C) && !operating && density))
var/obj/item/weldingtool/W = C
if(W.remove_fuel(0,user))
welded = !welded
update_icon()
return
else
return
/obj/machinery/door/airlock/hatch/gamma/welder_act(mob/user, obj/item/I)
if(shock_user(user, 75))
return
if(operating || !density)
return
. = TRUE
if(!I.use_tool(src, user, 0, amount = 0, volume = I.tool_volume))
return
welded = !welded
visible_message("<span class='notice'>[user] [welded ? null : "un"]welds [src]!</span>",\
"<span class='notice'>You [welded ? null : "un"]weld [src]!</span>",\
"<span class='warning'>You hear welding.</span>")
update_icon()
/obj/machinery/door/airlock/maintenance_hatch
name = "maintenance hatch"
@@ -424,14 +430,22 @@
return
add_fingerprint(user)
if((iswelder(C) && !operating && density))
var/obj/item/weldingtool/W = C
if(W.remove_fuel(0,user))
welded = !welded
update_icon()
return
else
return
/obj/machinery/door/airlock/highsecurity/red/welder_act(mob/user, obj/item/I)
if(shock_user(user, 75))
return
if(operating || !density)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
welded = !welded
visible_message("<span class='notice'>[user] [welded ? null : "un"]welds [src]!</span>",\
"<span class='notice'>You [welded ? null : "un"]weld [src]!</span>",\
"<span class='warning'>You hear welding.</span>")
update_icon()
//////////////////////////////////
/*
+1 -1
View File
@@ -444,7 +444,7 @@
//Stolen from status_display
/obj/machinery/door_timer/proc/texticon(tn, px = 0, py = 0)
var/image/I = image('icons/obj/status_display.dmi', "blank")
var/len = lentext(tn)
var/len = length(tn)
for(var/d = 1 to len)
var/char = copytext(tn, len-d+1, len-d+2)

Some files were not shown because too many files have changed in this diff Show More