mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-28 06:27:26 +01:00
Merge remote-tracking branch 'upstream/master' into bnuuy
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
### AffectedArc07
|
||||
# Actual Code
|
||||
/code/controllers/subsystem/instancing.dm @AffectedArc07
|
||||
/code/controllers/subsystem/mapping.dm @AffectedArc07
|
||||
/code/controllers/subsystem/ticker.dm @AffectedArc07
|
||||
/tgui/ @AffectedArc07
|
||||
|
||||
+12
-5
@@ -38,6 +38,11 @@ actual development.
|
||||
of a pull request needs to be removed/changed, you may simply modify that single commit.
|
||||
Due to limitations of the engine, this may not always be possible; but do try your best.
|
||||
|
||||
* Keep your pull requests small and reviewable whenever possible. Do not bundle unrelated
|
||||
fixes even if not bundling them generates more pull requests. In case of mapping PRs that add features -
|
||||
consult a maintainer on whether it would be appropriate to split up the PR to add the
|
||||
feature to multiple maps individually.
|
||||
|
||||
* Document and explain your pull requests thoroughly. Failure to do so will delay a PR as
|
||||
we question why changes were made. This is especially important if you're porting a PR
|
||||
from another codebase (i.e. TG) and divert from the original. Explaining with single
|
||||
@@ -460,7 +465,7 @@ SS13 has a lot of legacy code that's never been updated. Here are some examples
|
||||
```DM
|
||||
//Bad
|
||||
var/datum/db_query/query_watch = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey='[target_ckey]'")
|
||||
|
||||
|
||||
//Good
|
||||
var/datum/db_query/query_watch = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey=:target_ckey", list(
|
||||
"target_ckey" = target_ckey
|
||||
@@ -497,11 +502,13 @@ in the SQL/updates folder.
|
||||
* Queries must never specify the database, be it in code, or in text files in the repo.
|
||||
|
||||
### Mapping Standards
|
||||
* For map edit PRs, we do not accept 'change for the sake of change' remaps, unless you have very good reasoning to do so. Maintainers reserve the right to close your PR if we disagree with your reasoning.
|
||||
|
||||
* Map Merge
|
||||
* The following guideline for map merging applies to people who are **NOT** using StrongDMM, please see the StrongDMM section if you are.
|
||||
* You **MUST** run Map Merge prior to opening your PR when updating existing maps to minimize the change differences (even when using third party mapping programs such as FastDMM.)
|
||||
* Failure to run Map Merge on a map after using third party mapping programs (such as FastDMM) greatly increases the risk of the map's key dictionary becoming corrupted by future edits after running map merge. Resolving the corruption issue involves rebuilding the map's key dictionary;
|
||||
|
||||
|
||||
* StrongDMM
|
||||
* When using StrongDMM, the following options **MUST** be enabled to avoid file bloat. They can be found under `File > Preferences > Save Options` in SDMM.
|
||||
* Map save format: This **MUST** be set to **TGM** if you do not want to run Map Merge. Enabling this setting means SDMM will automatically map merge, letting you skip manual merging.
|
||||
@@ -521,10 +528,10 @@ in the SQL/updates folder.
|
||||
* NEVER run cables under wall turfs.
|
||||
* Keep floor turf variations to a minimum. Generally, more than 3 floor turf types in one room is bad design.
|
||||
* Run air pipes together where possible. The first example below is to be avoided, the second is optimal:
|
||||
|
||||
|
||||
 
|
||||
* Pipe layouts should be logical and predictable, easy to understand at a glance. Always avoid complex layouts like in this example:
|
||||
|
||||
* Pipe layouts should be logical and predictable, easy to understand at a glance. Always avoid complex layouts like in this example:
|
||||
|
||||

|
||||
|
||||
* Decals are to be used sparingly. Good map design does not require warning tape around everything. Decal overuse contributes to maptick slowdown.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
patreon: ParadiseStation
|
||||
@@ -55,6 +55,9 @@ jobs:
|
||||
unit_tests_and_sql:
|
||||
name: Unit Tests + SQL Validation
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
maptype: ['/datum/map/cyberiad', '/datum/map/delta', '/datum/map/metastation']
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:latest
|
||||
@@ -86,6 +89,7 @@ jobs:
|
||||
tools/ci/install_byond.sh
|
||||
source $HOME/BYOND/byond/bin/byondsetup
|
||||
tools/ci/dm.sh -DCIBUILDING paradise.dme
|
||||
echo '${{ matrix.maptype }}' > data/next_map.txt
|
||||
tools/ci/run_server.sh
|
||||
|
||||
windows_dll_tests:
|
||||
|
||||
@@ -2,7 +2,8 @@ name: Generate Documentation
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Every day at the very start of the day
|
||||
- cron: "0 0 * * *" # Every day at the very start of the day. Except it happens an hour and a half later because actions backlog
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
generate_docs:
|
||||
@@ -14,10 +15,11 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 1
|
||||
ref: master
|
||||
|
||||
- name: 'Install DMDOC'
|
||||
run: bash tools/ci/install_dmdoc.sh
|
||||
- name: 'Generate Documentation'
|
||||
run: |
|
||||
./tools/github-actions/doc-generator
|
||||
~/dmdoc
|
||||
touch dmdoc/.nojekyll
|
||||
# Nojekyll is important to disable jeykll syntax, which can mess with files that start with underscores
|
||||
|
||||
|
||||
+32
-2
@@ -114,6 +114,7 @@ CREATE TABLE `death` (
|
||||
`pod` text NOT NULL COMMENT 'Place of death',
|
||||
`coord` text NOT NULL COMMENT 'X, Y, Z POD',
|
||||
`tod` datetime NOT NULL COMMENT 'Time of death',
|
||||
`server_id` TEXT NULL DEFAULT NULL,
|
||||
`job` text NOT NULL,
|
||||
`special` text NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
@@ -197,6 +198,7 @@ CREATE TABLE `ban` (
|
||||
`bantime` datetime NOT NULL,
|
||||
`ban_round_id` INT(11) NULL DEFAULT NULL,
|
||||
`serverip` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`server_id` VARCHAR(50) NULL DEFAULT NULL COLLATE utf8mb4_general_ci,
|
||||
`bantype` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`reason` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`job` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
@@ -320,6 +322,7 @@ CREATE TABLE `karma` (
|
||||
`receiverspecial` text,
|
||||
`isnegative` tinyint(1) DEFAULT NULL,
|
||||
`spenderip` text NOT NULL,
|
||||
`server_id` TEXT NULL DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
@@ -374,6 +377,7 @@ CREATE TABLE `legacy_population` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`playercount` int(11) DEFAULT NULL,
|
||||
`admincount` int(11) DEFAULT NULL,
|
||||
`server_id` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
@@ -532,6 +536,7 @@ CREATE TABLE `connection_log` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`ip` varchar(32) NOT NULL,
|
||||
`computerid` varchar(32) NOT NULL,
|
||||
`server_id` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`result` ENUM('ESTABLISHED','DROPPED - IPINTEL','DROPPED - BANNED','DROPPED - INVALID') NOT NULL DEFAULT 'ESTABLISHED' COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`),
|
||||
@@ -584,6 +589,7 @@ CREATE TABLE `round` (
|
||||
`shuttle_name` VARCHAR(64) NULL,
|
||||
`map_name` VARCHAR(32) NULL,
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
`server_id` VARCHAR(50) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
@@ -597,5 +603,29 @@ CREATE TABLE `2fa_secrets` (
|
||||
`date_setup` DATETIME NOT NULL DEFAULT current_timestamp(),
|
||||
`last_time` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`ckey`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
|
||||
--
|
||||
-- Table structure for table `pai_saves`
|
||||
--
|
||||
CREATE TABLE `pai_saves` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`pai_name` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`description` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`preferred_role` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`ooc_comments` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `ckey` (`ckey`) USING BTREE
|
||||
) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
|
||||
--
|
||||
-- Table structure for table `instance_data_cache`
|
||||
--
|
||||
CREATE TABLE `instance_data_cache` (
|
||||
`server_id` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`key_name` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`key_value` VARCHAR(12345) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`last_updated` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`server_id`, `key_name`) USING HASH
|
||||
) COLLATE='utf8mb4_general_ci' ENGINE=MEMORY;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Updates DB from 25-25, -AffectedArc07
|
||||
# Adds a pAI saves table to the DB
|
||||
|
||||
CREATE TABLE `pai_saves` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`pai_name` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`description` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`preferred_role` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`ooc_comments` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `ckey` (`ckey`) USING BTREE
|
||||
) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB;
|
||||
@@ -0,0 +1,32 @@
|
||||
# Updates DB from 26 to 27 -AffectedArc07
|
||||
# Adds a new table for instance data caching, and server_id fields on other tables
|
||||
|
||||
CREATE TABLE `instance_data_cache` (
|
||||
`server_id` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`key_name` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`key_value` VARCHAR(12345) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`last_updated` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`server_id`, `key_name`) USING HASH
|
||||
) COLLATE='utf8mb4_general_ci' ENGINE=MEMORY;
|
||||
|
||||
ALTER TABLE `ban`
|
||||
ADD COLUMN `server_id` VARCHAR(50) NULL DEFAULT NULL AFTER `serverip`;
|
||||
|
||||
ALTER TABLE `connection_log`
|
||||
ADD COLUMN `server_id` VARCHAR(50) NULL DEFAULT NULL AFTER `computerid`;
|
||||
|
||||
ALTER TABLE `death`
|
||||
ADD COLUMN `server_id` TEXT NULL AFTER `tod`;
|
||||
|
||||
ALTER TABLE `karma`
|
||||
ADD COLUMN `server_id` TEXT NULL AFTER `spenderip`;
|
||||
|
||||
ALTER TABLE `legacy_population`
|
||||
ADD COLUMN `server_id` VARCHAR(50) NULL DEFAULT NULL AFTER `admincount`;
|
||||
|
||||
# Notes already has a column for this
|
||||
ALTER TABLE `notes`
|
||||
CHANGE COLUMN `server` `server` VARCHAR(50) NULL COLLATE 'utf8mb4_general_ci' AFTER `edits`;
|
||||
|
||||
ALTER TABLE `round`
|
||||
ADD COLUMN `server_id` VARCHAR(50) NULL DEFAULT NULL AFTER `station_name`;
|
||||
@@ -1,9 +1,9 @@
|
||||
# This file has all the information on what versions of libraries are thrown into the code
|
||||
# For dreamchecker
|
||||
export SPACEMANDMM_TAG=suite-1.6
|
||||
export SPACEMANDMM_TAG=suite-1.7.1
|
||||
# For TGUI
|
||||
export NODE_VERSION=12
|
||||
# Byond Major
|
||||
export BYOND_MAJOR=513
|
||||
export BYOND_MAJOR=514
|
||||
# Byond Minor
|
||||
export BYOND_MINOR=1528
|
||||
export BYOND_MINOR=1566
|
||||
|
||||
+11072
-12572
File diff suppressed because it is too large
Load Diff
+1195
-2157
File diff suppressed because it is too large
Load Diff
@@ -362,12 +362,6 @@
|
||||
"bf" = (
|
||||
/turf/simulated/wall/mineral/plastitanium/nodiagonal,
|
||||
/area/syndicate_depot/outer)
|
||||
"bg" = (
|
||||
/obj/effect/spawner/random_spawners/syndicate/layout/spacepod,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/syndicate_depot/core)
|
||||
"bh" = (
|
||||
/obj/machinery/light{
|
||||
dir = 1;
|
||||
@@ -1758,7 +1752,7 @@ aD
|
||||
aM
|
||||
at
|
||||
aD
|
||||
bg
|
||||
aD
|
||||
bn
|
||||
bu
|
||||
bz
|
||||
|
||||
@@ -290,8 +290,13 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/shuttle/abandoned)
|
||||
"by" = (
|
||||
/obj/structure/spacepoddoor,
|
||||
/turf/simulated/floor/plating,
|
||||
/obj/machinery/door_control{
|
||||
id = "whiteshippoddoor";
|
||||
name = "Pod Door Control";
|
||||
pixel_x = -24;
|
||||
pixel_y = 24
|
||||
},
|
||||
/turf/simulated/floor/mineral/titanium,
|
||||
/area/shuttle/abandoned)
|
||||
"bz" = (
|
||||
/obj/machinery/door/airlock/public/glass{
|
||||
@@ -304,11 +309,10 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/shuttle/abandoned)
|
||||
"bC" = (
|
||||
/obj/structure/spacepoddoor,
|
||||
/obj/machinery/door/poddoor/multi_tile/two_tile_ver{
|
||||
id_tag = "whiteshippoddoor"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/turf/simulated/floor/mineral/titanium,
|
||||
/area/shuttle/abandoned)
|
||||
"bD" = (
|
||||
/obj/machinery/door_control{
|
||||
|
||||
+1531
-2379
File diff suppressed because it is too large
Load Diff
@@ -886,7 +886,7 @@
|
||||
},
|
||||
/obj/effect/decal/cleanable/cobweb,
|
||||
/obj/machinery/computer/prisoner{
|
||||
dir = 1
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 6
|
||||
@@ -4371,6 +4371,7 @@
|
||||
"sO" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/computer/security{
|
||||
dir = 4;
|
||||
network = list("Labor Camp")
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
@@ -5275,7 +5276,7 @@
|
||||
/area/mine/production)
|
||||
"VJ" = (
|
||||
/obj/machinery/computer/secure_data{
|
||||
dir = 1
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 1;
|
||||
|
||||
@@ -651,7 +651,9 @@
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/administration)
|
||||
"cH" = (
|
||||
/obj/machinery/computer/shuttle/ferry,
|
||||
/obj/machinery/computer/shuttle/ferry{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/centcom/evac)
|
||||
"cI" = (
|
||||
@@ -661,7 +663,9 @@
|
||||
/turf/simulated/floor/plating/airless,
|
||||
/area/shuttle/specops)
|
||||
"cK" = (
|
||||
/obj/machinery/computer/shuttle/admin,
|
||||
/obj/machinery/computer/shuttle/admin{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/centcom/evac)
|
||||
"cL" = (
|
||||
@@ -1387,7 +1391,9 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/syndicate_mothership)
|
||||
"fi" = (
|
||||
/obj/machinery/computer/shuttle/syndicate/recall,
|
||||
/obj/machinery/computer/shuttle/syndicate/recall{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/wood,
|
||||
/area/syndicate_mothership)
|
||||
"fj" = (
|
||||
@@ -1411,8 +1417,8 @@
|
||||
/turf/simulated/wall/indestructible/riveted,
|
||||
/area/centcom/gamma)
|
||||
"fn" = (
|
||||
/obj/machinery/computer/library/checkout,
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/computer/library/checkout,
|
||||
/turf/simulated/floor/engine/cult,
|
||||
/area/wizard_station)
|
||||
"fo" = (
|
||||
@@ -2028,7 +2034,9 @@
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/syndicate_mothership)
|
||||
"hP" = (
|
||||
/obj/machinery/computer/communications,
|
||||
/obj/machinery/computer/communications{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/administration)
|
||||
"hQ" = (
|
||||
@@ -3500,7 +3508,9 @@
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/centcom/control)
|
||||
"mP" = (
|
||||
/obj/machinery/computer/pod/deathsquad,
|
||||
/obj/machinery/computer/pod/deathsquad{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel/dark{
|
||||
dir = 1;
|
||||
icon_state = "vault"
|
||||
@@ -3523,7 +3533,9 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/centcom/control)
|
||||
"mV" = (
|
||||
/obj/machinery/computer/card/centcom,
|
||||
/obj/machinery/computer/card/centcom{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/wood,
|
||||
/area/centcom/control)
|
||||
"mW" = (
|
||||
@@ -3588,7 +3600,9 @@
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/centcom/control)
|
||||
"nh" = (
|
||||
/obj/machinery/computer/communications,
|
||||
/obj/machinery/computer/communications{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/centcom/control)
|
||||
"nj" = (
|
||||
@@ -4013,9 +4027,9 @@
|
||||
/area/syndicate_mothership)
|
||||
"oB" = (
|
||||
/obj/structure/closet/secure_closet/guncabinet,
|
||||
/obj/item/ammo_box/shotgun/buck,
|
||||
/obj/item/ammo_box/shotgun/buck,
|
||||
/obj/item/ammo_box/shotgun/buck,
|
||||
/obj/item/ammo_box/shotgun/beanbag,
|
||||
/obj/item/ammo_box/shotgun/beanbag,
|
||||
/obj/item/ammo_box/shotgun/beanbag,
|
||||
/obj/item/gun/projectile/shotgun/automatic/combat,
|
||||
/obj/item/gun/projectile/shotgun/automatic/combat,
|
||||
/obj/item/gun/projectile/shotgun/automatic/combat,
|
||||
@@ -4306,7 +4320,9 @@
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/computer/mech_bay_power_console,
|
||||
/obj/machinery/computer/mech_bay_power_console{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/gamma/space)
|
||||
"pu" = (
|
||||
@@ -4417,12 +4433,12 @@
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/centcom/specops)
|
||||
"pP" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/computer/security/telescreen{
|
||||
desc = "Used for watching the Special Ops.";
|
||||
name = "Special Ops. Monitor";
|
||||
network = list("ERT")
|
||||
},
|
||||
/obj/structure/table/wood,
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/centcom/specops)
|
||||
"pQ" = (
|
||||
@@ -4430,10 +4446,12 @@
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/centcom/specops)
|
||||
"pR" = (
|
||||
/obj/machinery/computer/station_alert,
|
||||
/obj/structure/sign/poster/official/nanotrasen_logo{
|
||||
pixel_x = 32
|
||||
},
|
||||
/obj/machinery/computer/station_alert{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 5;
|
||||
icon_state = "darkyellow"
|
||||
@@ -4940,7 +4958,9 @@
|
||||
},
|
||||
/area/centcom/evac)
|
||||
"rz" = (
|
||||
/obj/machinery/computer/communications,
|
||||
/obj/machinery/computer/communications{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/centcom/specops)
|
||||
"rA" = (
|
||||
@@ -5185,10 +5205,12 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/centcom/evac)
|
||||
"sy" = (
|
||||
/obj/machinery/computer/secure_data,
|
||||
/obj/machinery/light/spot{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/computer/secure_data{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/centcom/evac)
|
||||
"sz" = (
|
||||
@@ -6168,7 +6190,9 @@
|
||||
/turf/simulated/floor/plasteel/grimy,
|
||||
/area/centcom/specops)
|
||||
"vf" = (
|
||||
/obj/machinery/computer/secure_data,
|
||||
/obj/machinery/computer/secure_data{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/centcom/control)
|
||||
"vg" = (
|
||||
@@ -6185,7 +6209,9 @@
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"vi" = (
|
||||
/obj/machinery/computer/med_data,
|
||||
/obj/machinery/computer/med_data{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/centcom/control)
|
||||
"vj" = (
|
||||
@@ -6235,11 +6261,11 @@
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"vp" = (
|
||||
/obj/machinery/computer/mech_bay_power_console,
|
||||
/obj/structure/cable{
|
||||
d2 = 2;
|
||||
icon_state = "0-2"
|
||||
},
|
||||
/obj/machinery/computer/mech_bay_power_console,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"vr" = (
|
||||
@@ -6257,24 +6283,33 @@
|
||||
/area/admin)
|
||||
"vs" = (
|
||||
/obj/machinery/computer/security{
|
||||
dir = 1;
|
||||
network = list("SS13","Telecomms","Research Outpost","Mining Outpost","ERT","CentComm","Thunderdome")
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/centcom/control)
|
||||
"vt" = (
|
||||
/obj/machinery/computer/station_alert,
|
||||
/obj/machinery/computer/station_alert{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/centcom/control)
|
||||
"vu" = (
|
||||
/obj/machinery/computer/communications,
|
||||
/obj/machinery/computer/communications{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/centcom/control)
|
||||
"vv" = (
|
||||
/obj/machinery/computer/robotics,
|
||||
/obj/machinery/computer/robotics{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/centcom/control)
|
||||
"vw" = (
|
||||
/obj/machinery/computer/crew,
|
||||
/obj/machinery/computer/crew{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/centcom/control)
|
||||
"vx" = (
|
||||
@@ -6852,8 +6887,10 @@
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/admin)
|
||||
"wS" = (
|
||||
/obj/machinery/computer/secure_data,
|
||||
/obj/item/paper/sop,
|
||||
/obj/machinery/computer/secure_data{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/admin)
|
||||
"wT" = (
|
||||
@@ -6881,11 +6918,15 @@
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/admin)
|
||||
"wY" = (
|
||||
/obj/machinery/computer/communications,
|
||||
/obj/machinery/computer/communications{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/admin)
|
||||
"wZ" = (
|
||||
/obj/machinery/computer/med_data,
|
||||
/obj/machinery/computer/med_data{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/admin)
|
||||
"xa" = (
|
||||
@@ -7363,7 +7404,9 @@
|
||||
},
|
||||
/area/trader_station/sol)
|
||||
"yJ" = (
|
||||
/obj/machinery/computer/communications,
|
||||
/obj/machinery/computer/communications{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"yK" = (
|
||||
@@ -7380,7 +7423,9 @@
|
||||
},
|
||||
/area/trader_station/sol)
|
||||
"yP" = (
|
||||
/obj/machinery/computer/atmos_alert,
|
||||
/obj/machinery/computer/atmos_alert{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"yQ" = (
|
||||
@@ -7390,12 +7435,15 @@
|
||||
},
|
||||
/area/centcom/evac)
|
||||
"yR" = (
|
||||
/obj/machinery/computer/message_monitor,
|
||||
/obj/item/paper/monitorkey,
|
||||
/obj/machinery/computer/message_monitor{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"yS" = (
|
||||
/obj/machinery/computer/account_database{
|
||||
dir = 1;
|
||||
name = "Admin Accounts Database"
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
@@ -7407,7 +7455,9 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/centcom/evac)
|
||||
"yU" = (
|
||||
/obj/machinery/computer/secure_data,
|
||||
/obj/machinery/computer/secure_data{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"yV" = (
|
||||
@@ -7452,7 +7502,9 @@
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"zc" = (
|
||||
/obj/machinery/computer/arcade,
|
||||
/obj/machinery/computer/arcade{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/centcom/evac)
|
||||
"zd" = (
|
||||
@@ -7473,7 +7525,9 @@
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/admin)
|
||||
"zh" = (
|
||||
/obj/machinery/computer/card,
|
||||
/obj/machinery/computer/card{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/centcom/evac)
|
||||
"zi" = (
|
||||
@@ -7944,7 +7998,9 @@
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"AS" = (
|
||||
/obj/machinery/computer/teleporter,
|
||||
/obj/machinery/computer/teleporter{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/admin)
|
||||
"AT" = (
|
||||
@@ -8000,11 +8056,15 @@
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/syndicate_mothership)
|
||||
"Bb" = (
|
||||
/obj/machinery/computer/crew,
|
||||
/obj/machinery/computer/crew{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/centcom/evac)
|
||||
"Bc" = (
|
||||
/obj/machinery/computer/communications,
|
||||
/obj/machinery/computer/communications{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/centcom/evac)
|
||||
"Bd" = (
|
||||
@@ -8040,6 +8100,7 @@
|
||||
/area/centcom/evac)
|
||||
"Bj" = (
|
||||
/obj/machinery/computer{
|
||||
dir = 1;
|
||||
name = "EMERGENCY SHUTTLE COMPUTER"
|
||||
},
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
@@ -8100,7 +8161,9 @@
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/syndicate_mothership)
|
||||
"Bv" = (
|
||||
/obj/machinery/computer/camera_advanced,
|
||||
/obj/machinery/computer/camera_advanced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/syndicate_mothership)
|
||||
"Bw" = (
|
||||
@@ -8117,6 +8180,7 @@
|
||||
/area/syndicate_mothership)
|
||||
"By" = (
|
||||
/obj/machinery/computer/shuttle/syndicate{
|
||||
dir = 1;
|
||||
name = "Nuclear Operatives Shuttle Console"
|
||||
},
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
@@ -9000,7 +9064,9 @@
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/shuttle/supply)
|
||||
"FJ" = (
|
||||
/obj/machinery/computer/secure_data,
|
||||
/obj/machinery/computer/secure_data{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 10;
|
||||
icon_state = "darkred"
|
||||
@@ -9043,7 +9109,9 @@
|
||||
},
|
||||
/area/shuttle/escape)
|
||||
"Ga" = (
|
||||
/obj/machinery/computer/shuttle/ert,
|
||||
/obj/machinery/computer/shuttle/ert{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/centcom/specops)
|
||||
"Gd" = (
|
||||
@@ -9119,7 +9187,9 @@
|
||||
/turf/simulated/wall/mineral/plastitanium,
|
||||
/area/shuttle/syndicate_sit)
|
||||
"GD" = (
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/sst,
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/sst{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/syndicate_elite)
|
||||
"GJ" = (
|
||||
@@ -9376,10 +9446,12 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/tdome/tdome2)
|
||||
"Il" = (
|
||||
/obj/machinery/computer/communications,
|
||||
/obj/item/radio/intercom/specops{
|
||||
pixel_y = -28
|
||||
},
|
||||
/obj/machinery/computer/communications{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/specops)
|
||||
"Io" = (
|
||||
@@ -9622,7 +9694,9 @@
|
||||
/turf/simulated/floor/mineral/plastitanium/red/nitrogen,
|
||||
/area/shuttle/vox)
|
||||
"JH" = (
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/sit,
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/sit{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/syndicate_sit)
|
||||
"JM" = (
|
||||
@@ -9636,6 +9710,7 @@
|
||||
/area/shuttle/administration)
|
||||
"JO" = (
|
||||
/obj/machinery/computer/security{
|
||||
dir = 1;
|
||||
network = list("SS13","Research Outpost","Mining Outpost")
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
@@ -10628,7 +10703,9 @@
|
||||
},
|
||||
/area/shuttle/escape)
|
||||
"PU" = (
|
||||
/obj/machinery/computer/shuttle/sit,
|
||||
/obj/machinery/computer/shuttle/sit{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/syndicate_sit)
|
||||
"PX" = (
|
||||
@@ -11190,12 +11267,13 @@
|
||||
},
|
||||
/area/holodeck/source_thunderdomecourt)
|
||||
"TA" = (
|
||||
/obj/machinery/computer/security{
|
||||
network = list("SS13","Research Outpost","Mining Outpost","Telecomms")
|
||||
},
|
||||
/obj/structure/sign/poster/official/nanotrasen_logo{
|
||||
pixel_x = -32
|
||||
},
|
||||
/obj/machinery/computer/security{
|
||||
dir = 4;
|
||||
network = list("SS13","Research Outpost","Mining Outpost","Telecomms")
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 9;
|
||||
icon_state = "darkred"
|
||||
@@ -11379,7 +11457,9 @@
|
||||
},
|
||||
/area/holodeck/source_knightarena)
|
||||
"UJ" = (
|
||||
/obj/machinery/computer/shuttle/sst,
|
||||
/obj/machinery/computer/shuttle/sst{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/syndicate_elite)
|
||||
"UK" = (
|
||||
@@ -11495,6 +11575,7 @@
|
||||
/area/shuttle/escape)
|
||||
"Vr" = (
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/admin{
|
||||
dir = 8;
|
||||
name = "NTV Argos shuttle navigation computer"
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
@@ -11568,7 +11649,9 @@
|
||||
},
|
||||
/area/shuttle/escape)
|
||||
"VS" = (
|
||||
/obj/machinery/computer/atmos_alert,
|
||||
/obj/machinery/computer/atmos_alert{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 6;
|
||||
icon_state = "darkyellow"
|
||||
@@ -11600,6 +11683,7 @@
|
||||
/area/shuttle/vox)
|
||||
"Wc" = (
|
||||
/obj/machinery/computer/shuttle/admin{
|
||||
dir = 8;
|
||||
name = "NTV Argos shuttle console"
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
@@ -12043,7 +12127,6 @@
|
||||
},
|
||||
/area/shuttle/escape)
|
||||
"YV" = (
|
||||
/obj/machinery/computer/shuttle/trade/sol,
|
||||
/obj/machinery/door_control{
|
||||
id = "soltrader_south";
|
||||
name = "Trade Deposits Door";
|
||||
@@ -12057,6 +12140,9 @@
|
||||
pixel_x = 24;
|
||||
pixel_y = -8
|
||||
},
|
||||
/obj/machinery/computer/shuttle/trade/sol{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/shuttle/trade/sol)
|
||||
"YW" = (
|
||||
|
||||
@@ -565,11 +565,11 @@
|
||||
layer = 2.9
|
||||
},
|
||||
/obj/structure/rack,
|
||||
/obj/item/gun/projectile/shotgun/riot/buckshot{
|
||||
/obj/item/gun/projectile/shotgun/riot{
|
||||
pixel_x = -3;
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/item/gun/projectile/shotgun/riot/buckshot,
|
||||
/obj/item/gun/projectile/shotgun/riot,
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/administration)
|
||||
"Gx" = (
|
||||
@@ -705,11 +705,11 @@
|
||||
layer = 2.9
|
||||
},
|
||||
/obj/structure/rack,
|
||||
/obj/item/gun/projectile/shotgun/riot/buckshot{
|
||||
/obj/item/gun/projectile/shotgun/riot{
|
||||
pixel_x = -3;
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/item/gun/projectile/shotgun/riot/buckshot,
|
||||
/obj/item/gun/projectile/shotgun/riot,
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/administration)
|
||||
"Ns" = (
|
||||
@@ -914,11 +914,11 @@
|
||||
/obj/structure/window/reinforced{
|
||||
dir = 4
|
||||
},
|
||||
/obj/item/gun/projectile/shotgun/riot/buckshot{
|
||||
/obj/item/gun/projectile/shotgun/riot{
|
||||
pixel_x = -3;
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/item/gun/projectile/shotgun/riot/buckshot,
|
||||
/obj/item/gun/projectile/shotgun/riot,
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/administration)
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/// Version of RUST-G that this codebase wants
|
||||
#define RUST_G_VERSION "0.5.0-P"
|
||||
@@ -66,8 +66,8 @@
|
||||
#define ACCESS_PARAMEDIC 66
|
||||
#define ACCESS_BLUESHIELD 67
|
||||
#define ACCESS_SALVAGE_CAPTAIN 69 // Salvage ship captain's quarters
|
||||
#define ACCESS_MECHANIC 70
|
||||
#define ACCESS_PILOT 71
|
||||
// #define ACCESS_MECHANIC 70 // AA07 2021-10-02 - Removed: Kept for history sake
|
||||
// #define ACCESS_PILOT 71 // AA07 2021-10-02 - Removed: Kept for history sake
|
||||
#define ACCESS_NTREP 73
|
||||
#define ACCESS_MAGISTRATE 74
|
||||
#define ACCESS_MINISAT 75
|
||||
|
||||
@@ -114,3 +114,12 @@
|
||||
#define PIPE_COLOR_GREEN "#00ff00"
|
||||
#define PIPE_COLOR_YELLOW "#ffcc00"
|
||||
#define PIPE_COLOR_PURPLE "#5c1ec0"
|
||||
|
||||
///Main colors for UI themes
|
||||
#define COLOR_THEME_MIDNIGHT "#6086A0"
|
||||
#define COLOR_THEME_PLASMAFIRE "#FFB200"
|
||||
#define COLOR_THEME_RETRO "#24CA00"
|
||||
#define COLOR_THEME_SLIMECORE "#4FB259"
|
||||
#define COLOR_THEME_OPERATIVE "#B8221F"
|
||||
#define COLOR_THEME_GLASS "#75A4C4"
|
||||
#define COLOR_THEME_CLOCKWORK "#CFBA47"
|
||||
|
||||
@@ -10,6 +10,18 @@
|
||||
#define STAMINA "stamina"
|
||||
#define BRAIN "brain"
|
||||
|
||||
//damage flags
|
||||
#define MELEE "melee"
|
||||
#define BULLET "bullet"
|
||||
#define LASER "laser"
|
||||
#define ENERGY "energy"
|
||||
#define BOMB "bomb"
|
||||
#define BIO "bio"
|
||||
#define RAD "rad"
|
||||
#define FIRE "fire"
|
||||
#define ACID "acid"
|
||||
#define MAGIC "magic"
|
||||
|
||||
#define STUN "stun"
|
||||
#define WEAKEN "weaken"
|
||||
#define PARALYZE "paralize"
|
||||
@@ -112,6 +124,17 @@
|
||||
#define WEAPON_MEDIUM 2
|
||||
#define WEAPON_HEAVY 3
|
||||
|
||||
//His Grace.
|
||||
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
|
||||
#define HIS_GRACE_PECKISH 20 //Slightly hungry.
|
||||
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20.
|
||||
#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped.
|
||||
#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30.
|
||||
#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive.
|
||||
#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets.
|
||||
|
||||
#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill.
|
||||
|
||||
#define EXPLODE_NONE 0 //Don't even ask me why we need this.
|
||||
#define EXPLODE_DEVASTATE 1
|
||||
#define EXPLODE_HEAVY 2
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
#define PASSBLOB 8
|
||||
#define PASSMOB 16
|
||||
#define LETPASSTHROW 32
|
||||
#define PASSFENCE 64
|
||||
|
||||
//turf-only flags
|
||||
#define NOJAUNT 1
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
#define FOOTSTEP_WATER "water"
|
||||
#define FOOTSTEP_LAVA "lava"
|
||||
#define FOOTSTEP_MEAT "meat"
|
||||
#define FOOTSTEP_GLASS "glass"
|
||||
//barefoot sounds
|
||||
#define FOOTSTEP_WOOD_BAREFOOT "woodbarefoot"
|
||||
#define FOOTSTEP_WOOD_CLAW "woodclaw"
|
||||
#define FOOTSTEP_HARD_BAREFOOT "hardbarefoot"
|
||||
#define FOOTSTEP_HARD_CLAW "hardclaw"
|
||||
#define FOOTSTEP_CARPET_BAREFOOT "carpetbarefoot"
|
||||
#define FOOTSTEP_GLASS_BAREFOOT "glassbarefoot"
|
||||
//misc footstep sounds
|
||||
#define FOOTSTEP_GENERIC_HEAVY "heavy"
|
||||
|
||||
@@ -83,7 +85,11 @@ GLOBAL_LIST_INIT(footstep, list(
|
||||
'sound/effects/footstep/lava2.ogg',
|
||||
'sound/effects/footstep/lava3.ogg'), 100, 0),
|
||||
FOOTSTEP_MEAT = list(list(
|
||||
'sound/effects/meatslap.ogg'), 100, 0)
|
||||
'sound/effects/meatslap.ogg'), 100, 0),
|
||||
FOOTSTEP_GLASS = list(list(
|
||||
'sound/effects/footstep/glass1.ogg',
|
||||
'sound/effects/footstep/glass2.ogg',
|
||||
'sound/effects/footstep/glass3.ogg'), 100, 1),
|
||||
))
|
||||
//bare footsteps lists
|
||||
GLOBAL_LIST_INIT(barefootstep, list(
|
||||
@@ -127,6 +133,10 @@ GLOBAL_LIST_INIT(barefootstep, list(
|
||||
'sound/effects/footstep/lava3.ogg'), 100, 0),
|
||||
FOOTSTEP_MEAT = list(list(
|
||||
'sound/effects/meatslap.ogg'), 100, 0),
|
||||
FOOTSTEP_GLASS_BAREFOOT = list(list(
|
||||
'sound/effects/footstep/glassbarefoot1.ogg',
|
||||
'sound/effects/footstep/glassbarefoot2.ogg',
|
||||
'sound/effects/footstep/glassbarefoot3.ogg'), 100, 1),
|
||||
))
|
||||
|
||||
//claw footsteps lists
|
||||
@@ -171,6 +181,10 @@ GLOBAL_LIST_INIT(clawfootstep, list(
|
||||
'sound/effects/footstep/lava3.ogg'), 100, 0),
|
||||
FOOTSTEP_MEAT = list(list(
|
||||
'sound/effects/meatslap.ogg'), 100, 0),
|
||||
FOOTSTEP_GLASS_BAREFOOT = list(list(
|
||||
'sound/effects/footstep/glassbarefoot1.ogg',
|
||||
'sound/effects/footstep/glassbarefoot2.ogg',
|
||||
'sound/effects/footstep/glassbarefoot3.ogg'), 100, 1),
|
||||
))
|
||||
|
||||
//heavy footsteps list
|
||||
|
||||
@@ -74,7 +74,6 @@
|
||||
|
||||
//Species traits.
|
||||
#define NO_BLOOD "no_blood"
|
||||
#define NOTRANSSTING "no_trans_sting"
|
||||
#define IS_WHITELISTED "whitelisted"
|
||||
#define LIPS "lips"
|
||||
#define EXOTIC_COLOR "exotic_blood_color"
|
||||
|
||||
@@ -25,8 +25,9 @@
|
||||
#define PLANT_PEST_HUD "20"// Pest level
|
||||
#define PLANT_WEED_HUD "21"// Weed level
|
||||
#define DIAG_TRACK_HUD "22"// Mech tracking beacon
|
||||
#define DIAG_PATH_HUD "23"//Bot path indicators
|
||||
#define GLAND_HUD "24"//Gland indicators for abductors
|
||||
#define DIAG_AIRLOCK_HUD "23" // Airlock shock overlay
|
||||
#define DIAG_PATH_HUD "24"//Bot path indicators
|
||||
#define GLAND_HUD "25"//Gland indicators for abductors
|
||||
|
||||
//by default everything in the hud_list of an atom is an image
|
||||
//a value in hud_list with one of these will change that behavior
|
||||
@@ -38,7 +39,7 @@
|
||||
#define DATA_HUD_SECURITY_ADVANCED 2
|
||||
#define DATA_HUD_MEDICAL_BASIC 3
|
||||
#define DATA_HUD_MEDICAL_ADVANCED 4
|
||||
#define DATA_HUD_DIAGNOSTIC 5
|
||||
#define DATA_HUD_DIAGNOSTIC_BASIC 5
|
||||
#define DATA_HUD_DIAGNOSTIC_ADVANCED 6
|
||||
#define DATA_HUD_HYDROPONIC 7
|
||||
//antag HUD defines
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
#define ismecha(A) (istype(A, /obj/mecha))
|
||||
|
||||
#define isspacepod(A) (istype(A, /obj/spacepod))
|
||||
|
||||
#define iseffect(A) (istype(A, /obj/effect))
|
||||
|
||||
#define isclothing(A) (istype(A, /obj/item/clothing))
|
||||
|
||||
+26
-25
@@ -7,58 +7,59 @@
|
||||
|
||||
#define JOBCAT_ENGSEC (1<<0)
|
||||
|
||||
#define JOB_CAPTAIN (1<<0)
|
||||
#define JOB_HOS (1<<1)
|
||||
#define JOB_WARDEN (1<<2)
|
||||
#define JOB_CAPTAIN (1<<0)
|
||||
#define JOB_HOS (1<<1)
|
||||
#define JOB_WARDEN (1<<2)
|
||||
#define JOB_DETECTIVE (1<<3)
|
||||
#define JOB_OFFICER (1<<4)
|
||||
#define JOB_OFFICER (1<<4)
|
||||
#define JOB_CHIEF (1<<5)
|
||||
#define JOB_ENGINEER (1<<6)
|
||||
#define JOB_ATMOSTECH (1<<7)
|
||||
#define JOB_AI (1<<8)
|
||||
#define JOB_CYBORG (1<<9)
|
||||
#define JOB_CENTCOM (1<<10)
|
||||
#define JOB_AI (1<<8)
|
||||
#define JOB_CYBORG (1<<9)
|
||||
#define JOB_CENTCOM (1<<10)
|
||||
#define JOB_SYNDICATE (1<<11)
|
||||
#define JOB_JUDGE (1<<12)
|
||||
|
||||
#define JOBCAT_MEDSCI (1<<1)
|
||||
|
||||
#define JOB_RD (1<<0)
|
||||
#define JOB_RD (1<<0)
|
||||
#define JOB_SCIENTIST (1<<1)
|
||||
#define JOB_CHEMIST (1<<2)
|
||||
#define JOB_CMO (1<<3)
|
||||
#define JOB_DOCTOR (1<<4)
|
||||
#define JOB_GENETICIST (1<<5)
|
||||
#define JOB_VIROLOGIST (1<<6)
|
||||
#define JOB_CHEMIST (1<<2)
|
||||
#define JOB_CMO (1<<3)
|
||||
#define JOB_DOCTOR (1<<4)
|
||||
#define JOB_GENETICIST (1<<5)
|
||||
#define JOB_VIROLOGIST (1<<6)
|
||||
#define JOB_PSYCHIATRIST (1<<7)
|
||||
#define JOB_ROBOTICIST (1<<8)
|
||||
#define JOB_ROBOTICIST (1<<8)
|
||||
#define JOB_PARAMEDIC (1<<9)
|
||||
#define JOB_CORONER (1<<10)
|
||||
#define JOB_CORONER (1<<10)
|
||||
|
||||
|
||||
#define JOBCAT_SUPPORT (1<<2)
|
||||
|
||||
#define JOB_HOP (1<<0)
|
||||
#define JOB_HOP (1<<0)
|
||||
#define JOB_BARTENDER (1<<1)
|
||||
#define JOB_BOTANIST (1<<2)
|
||||
#define JOB_CHEF (1<<3)
|
||||
#define JOB_JANITOR (1<<4)
|
||||
#define JOB_JANITOR (1<<4)
|
||||
#define JOB_LIBRARIAN (1<<5)
|
||||
#define JOB_QUARTERMASTER (1<<6)
|
||||
#define JOB_CARGOTECH (1<<7)
|
||||
#define JOB_MINER (1<<8)
|
||||
#define JOB_LAWYER (1<<9)
|
||||
#define JOB_LAWYER (1<<9)
|
||||
#define JOB_CHAPLAIN (1<<10)
|
||||
#define JOB_CLOWN (1<<11)
|
||||
#define JOB_MIME (1<<12)
|
||||
#define JOB_CIVILIAN (1<<13)
|
||||
#define JOB_EXPLORER (1<<14)
|
||||
|
||||
#define JOBCAT_KARMA (1<<3)
|
||||
#define JOBCAT_KARMA (1<<3)
|
||||
|
||||
#define JOB_NANO (1<<0)
|
||||
#define JOB_BLUESHIELD (1<<1)
|
||||
#define JOB_BARBER (1<<3)
|
||||
#define JOB_MECHANIC (1<<4)
|
||||
#define JOB_BRIGDOC (1<<5)
|
||||
#define JOB_JUDGE (1<<6)
|
||||
#define JOB_PILOT (1<<7)
|
||||
#define JOB_BLUESHIELD (1<<1)
|
||||
#define JOB_BARBER (1<<3)
|
||||
// #define JOB_MECHANIC (1<<4) // AA07 2021-10-02 - Removed: Kept for history sake
|
||||
#define JOB_BRIGDOC (1<<5)
|
||||
// #define JOB_JUDGE (1<<6) // AA07 2021-10-09 - Moved to ENGSEC (Non karma): Define kept for history sake
|
||||
// #define JOB_PILOT (1<<7) // AA07 2021-10-02 - Removed: Kept for history sake
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
#define DISPOSAL_PIPE_LAYER 2.3
|
||||
#define GAS_PIPE_HIDDEN_LAYER 2.35
|
||||
#define WIRE_LAYER 2.4
|
||||
#define TRANSPARENT_TURF_LAYER 2.41
|
||||
#define WIRE_TERMINAL_LAYER 2.45
|
||||
#define GAS_SCRUBBER_LAYER 2.46
|
||||
#define GAS_PIPE_VISIBLE_LAYER 2.47
|
||||
#define GAS_FILTER_LAYER 2.48
|
||||
#define GAS_PUMP_LAYER 2.49
|
||||
#define HOLOPAD_LAYER 2.491
|
||||
#define CONVEYOR_LAYER 2.495
|
||||
#define LOW_OBJ_LAYER 2.5
|
||||
#define LOW_SIGIL_LAYER 2.52
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define AUTOLATHE 4 //Uses glass/metal only.
|
||||
#define CRAFTLATHE 8 //Uses fuck if I know. For use eventually.
|
||||
#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
|
||||
#define PODFAB 32 //Used by the spacepod part fabricator. Same idea as the mechfab
|
||||
// #define PODFAB 32 //Used by the spacepod part fabricator. Same idea as the mechfab // AA 2021-10-02 - Removed. Kept for flag consistency.
|
||||
#define BIOGENERATOR 64 //Uses biomass
|
||||
#define SMELTER 128 //uses various minerals
|
||||
//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable.
|
||||
|
||||
@@ -365,7 +365,7 @@
|
||||
#define INVESTIGATE_BOMB "bombs"
|
||||
|
||||
// The SQL version required by this version of the code
|
||||
#define SQL_VERSION 25
|
||||
#define SQL_VERSION 27
|
||||
|
||||
// Vending machine stuff
|
||||
#define CAT_NORMAL 1
|
||||
|
||||
@@ -56,10 +56,11 @@
|
||||
#define PREFTOGGLE_2_REVERB_DISABLE 512
|
||||
#define PREFTOGGLE_2_FORCE_WHITE_RUNECHAT 1024
|
||||
#define PREFTOGGLE_2_SIMPLE_STAT_PANEL 2048
|
||||
#define PREFTOGGLE_2_SEE_ITEM_OUTLINES 4096
|
||||
|
||||
#define TOGGLES_2_TOTAL 4095 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
#define TOGGLES_2_TOTAL 8191 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
|
||||
#define TOGGLES_2_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE)
|
||||
#define TOGGLES_2_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE|PREFTOGGLE_2_SEE_ITEM_OUTLINES)
|
||||
|
||||
// Sanity checks
|
||||
#if TOGGLES_TOTAL > 16777215
|
||||
@@ -114,3 +115,11 @@
|
||||
#define _2FA_ENABLED_IP "ENABLED_IP"
|
||||
/// Client will be prompted for 2FA always
|
||||
#define _2FA_ENABLED_ALWAYS "ENABLED_ALWAYS"
|
||||
|
||||
|
||||
#define MAX_SAVE_SLOTS 30 // Save slots for regular players
|
||||
#define MAX_SAVE_SLOTS_MEMBER 30 // Save slots for BYOND members
|
||||
|
||||
#define TAB_CHAR 0
|
||||
#define TAB_GAME 1
|
||||
#define TAB_GEAR 2
|
||||
|
||||
+102
-41
@@ -1,80 +1,130 @@
|
||||
// rust_g.dm - DM API for rust_g extension library
|
||||
//
|
||||
// To configure, create a `rust_g.config.dm` and set what you care about from
|
||||
// the following options:
|
||||
//
|
||||
// #define RUST_G "path/to/rust_g"
|
||||
// Override the .dll/.so detection logic with a fixed path or with detection
|
||||
// logic of your own.
|
||||
//
|
||||
// #define RUSTG_OVERRIDE_BUILTINS
|
||||
// Enable replacement rust-g functions for certain builtins. Off by default.
|
||||
|
||||
#ifndef RUST_G
|
||||
/// Locator for the RUSTG DLL or SO depending on system type. Override if needed.
|
||||
#define RUST_G (world.system_type == UNIX ? "./librust_g.so" : "./rust_g.dll")
|
||||
// Default automatic RUST_G detection.
|
||||
// On Windows, looks in the standard places for `rust_g.dll`.
|
||||
// On Linux, looks in `.`, `$LD_LIBRARY_PATH`, and `~/.byond/bin` for either of
|
||||
// `librust_g.so` (preferred) or `rust_g` (old).
|
||||
|
||||
/* This comment bypasses grep checks */ /var/__rust_g
|
||||
|
||||
/proc/__detect_rust_g()
|
||||
if (world.system_type == UNIX)
|
||||
if (fexists("./librust_g.so"))
|
||||
// No need for LD_LIBRARY_PATH badness.
|
||||
return __rust_g = "./librust_g.so"
|
||||
else if (fexists("./rust_g"))
|
||||
// Old dumb filename.
|
||||
return __rust_g = "./rust_g"
|
||||
else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/rust_g"))
|
||||
// Old dumb filename in `~/.byond/bin`.
|
||||
return __rust_g = "rust_g"
|
||||
else
|
||||
// It's not in the current directory, so try others
|
||||
return __rust_g = "librust_g.so"
|
||||
else
|
||||
return __rust_g = "rust_g.dll"
|
||||
|
||||
#define RUST_G (__rust_g || __detect_rust_g())
|
||||
#endif
|
||||
|
||||
// Gets the version of RUSTG
|
||||
/// Gets the version of rust_g
|
||||
/proc/rustg_get_version() return call(RUST_G, "get_version")()
|
||||
|
||||
// Defines for internal job subsystem //
|
||||
#define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET"
|
||||
#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB"
|
||||
#define RUSTG_JOB_ERROR "JOB PANICKED"
|
||||
// Cellular Noise Operations //
|
||||
|
||||
// DMI related operations //
|
||||
/**
|
||||
* This proc generates a cellular automata noise grid which can be used in procedural generation methods.
|
||||
*
|
||||
* Returns a single string that goes row by row, with values of 1 representing an alive cell, and a value of 0 representing a dead cell.
|
||||
*
|
||||
* Arguments:
|
||||
* * percentage: The chance of a turf starting closed
|
||||
* * smoothing_iterations: The amount of iterations the cellular automata simulates before returning the results
|
||||
* * birth_limit: If the number of neighboring cells is higher than this amount, a cell is born
|
||||
* * death_limit: If the number of neighboring cells is lower than this amount, a cell dies
|
||||
* * width: The width of the grid.
|
||||
* * height: The height of the grid.
|
||||
*/
|
||||
#define rustg_cnoise_generate(percentage, smoothing_iterations, birth_limit, death_limit, width, height) \
|
||||
call(RUST_G, "cnoise_generate")(percentage, smoothing_iterations, birth_limit, death_limit, width, height)
|
||||
|
||||
// DMI Operations //
|
||||
#define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname)
|
||||
#define rustg_dmi_create_png(path, width, height, data) call(RUST_G, "dmi_create_png")(path, width, height, data)
|
||||
#define rustg_dmi_resize_png(path, width, height, resizetype) call(RUST_G, "dmi_resize_png")(path, width, height, resizetype)
|
||||
|
||||
// Noise related operations //
|
||||
#define rustg_noise_get_at_coordinates(seed, x, y) call(RUST_G, "noise_get_at_coordinates")(seed, x, y)
|
||||
|
||||
// File related operations //
|
||||
// File Operations //
|
||||
#define rustg_file_read(fname) call(RUST_G, "file_read")(fname)
|
||||
#define rustg_file_exists(fname) call(RUST_G, "file_exists")(fname)
|
||||
#define rustg_file_write(text, fname) call(RUST_G, "file_write")(text, fname)
|
||||
#define rustg_file_append(text, fname) call(RUST_G, "file_append")(text, fname)
|
||||
|
||||
#ifdef RUSTG_OVERRIDE_BUILTINS
|
||||
#define file2text(fname) rustg_file_read(fname)
|
||||
#define text2file(text, fname) rustg_file_append(text, fname)
|
||||
#define file2text(fname) rustg_file_read("[fname]")
|
||||
#define text2file(text, fname) rustg_file_append(text, "[fname]")
|
||||
#endif
|
||||
|
||||
// Git related operations //
|
||||
// Git Operations //
|
||||
#define rustg_git_revparse(rev) call(RUST_G, "rg_git_revparse")(rev)
|
||||
#define rustg_git_commit_date(rev) call(RUST_G, "rg_git_commit_date")(rev)
|
||||
|
||||
// Hash related operations //
|
||||
// Hashing Operations //
|
||||
#define rustg_hash_string(algorithm, text) call(RUST_G, "hash_string")(algorithm, text)
|
||||
#define rustg_hash_file(algorithm, fname) call(RUST_G, "hash_file")(algorithm, fname)
|
||||
#define rustg_hash_generate_totp(seed) call(RUST_G, "generate_totp")(seed)
|
||||
#define rustg_hash_generate_totp_tolerance(seed, tolerance) call(RUST_G, "generate_totp_tolerance")(seed, tolerance)
|
||||
|
||||
#define RUSTG_HASH_MD5 "md5"
|
||||
#define RUSTG_HASH_SHA1 "sha1"
|
||||
#define RUSTG_HASH_SHA256 "sha256"
|
||||
#define RUSTG_HASH_SHA512 "sha512"
|
||||
#define RUSTG_HASH_XXH64 "xxh64"
|
||||
#define RUSTG_HASH_BASE64 "base64"
|
||||
|
||||
#ifdef RUSTG_OVERRIDE_BUILTINS
|
||||
#define md5(thing) (isfile(thing) ? rustg_hash_file(RUSTG_HASH_MD5, "[thing]") : rustg_hash_string(RUSTG_HASH_MD5, thing))
|
||||
#define md5(thing) (isfile(thing) ? rustg_hash_file(RUSTG_HASH_MD5, "[thing]") : rustg_hash_string(RUSTG_HASH_MD5, thing))
|
||||
#endif
|
||||
|
||||
// Logging stuff //
|
||||
#define rustg_log_write(fname, text) call(RUST_G, "log_write")(fname, text)
|
||||
/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")()
|
||||
|
||||
// URL encoding stuff
|
||||
#define rustg_url_encode(text) call(RUST_G, "url_encode")(text)
|
||||
#define rustg_url_decode(text) call(RUST_G, "url_decode")(text)
|
||||
|
||||
#ifdef RUSTG_OVERRIDE_BUILTINS
|
||||
#define url_encode(text) rustg_url_encode(text)
|
||||
#define url_decode(text) rustg_url_decode(text)
|
||||
#endif
|
||||
|
||||
// HTTP library stuff //
|
||||
// HTTP Operations //
|
||||
#define RUSTG_HTTP_METHOD_GET "get"
|
||||
#define RUSTG_HTTP_METHOD_PUT "put"
|
||||
#define RUSTG_HTTP_METHOD_DELETE "delete"
|
||||
#define RUSTG_HTTP_METHOD_PATCH "patch"
|
||||
#define RUSTG_HTTP_METHOD_HEAD "head"
|
||||
#define RUSTG_HTTP_METHOD_POST "post"
|
||||
|
||||
// Commented out because this thing locks up the entire DD process when you use it
|
||||
// DO NOT USE FOR THE LOVE OF GOD
|
||||
// #define rustg_http_request_blocking(method, url, body, headers) call(RUST_G, "http_request_blocking")(method, url, body, headers)
|
||||
#define rustg_http_request_async(method, url, body, headers) call(RUST_G, "http_request_async")(method, url, body, headers)
|
||||
#define rustg_http_request_blocking(method, url, body, headers, options) call(RUST_G, "http_request_blocking")(method, url, body, headers, options)
|
||||
#define rustg_http_request_async(method, url, body, headers, options) call(RUST_G, "http_request_async")(method, url, body, headers, options)
|
||||
#define rustg_http_check_request(req_id) call(RUST_G, "http_check_request")(req_id)
|
||||
/proc/rustg_create_async_http_client() return call(RUST_G, "start_http_client")()
|
||||
/proc/rustg_close_async_http_client() return call(RUST_G, "shutdown_http_client")()
|
||||
|
||||
// SQL stuff //
|
||||
// Jobs Subsystem Operations //
|
||||
#define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET"
|
||||
#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB"
|
||||
#define RUSTG_JOB_ERROR "JOB PANICKED"
|
||||
|
||||
// JSON Operations //
|
||||
#define rustg_json_is_valid(text) (call(RUST_G, "json_is_valid")(text) == "true")
|
||||
|
||||
// Logging Operations //
|
||||
#define rustg_log_write(fname, text) call(RUST_G, "log_write")(fname, text)
|
||||
/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")()
|
||||
|
||||
// Noise Operations //
|
||||
#define rustg_noise_get_at_coordinates(seed, x, y) call(RUST_G, "noise_get_at_coordinates")(seed, x, y)
|
||||
|
||||
// SQL Opeartions //
|
||||
#define rustg_sql_connect_pool(options) call(RUST_G, "sql_connect_pool")(options)
|
||||
#define rustg_sql_query_async(handle, query, params) call(RUST_G, "sql_query_async")(handle, query, params)
|
||||
#define rustg_sql_query_blocking(handle, query, params) call(RUST_G, "sql_query_blocking")(handle, query, params)
|
||||
@@ -82,8 +132,19 @@
|
||||
#define rustg_sql_disconnect_pool(handle) call(RUST_G, "sql_disconnect_pool")(handle)
|
||||
#define rustg_sql_check_query(job_id) call(RUST_G, "sql_check_query")("[job_id]")
|
||||
|
||||
// toml2json stuff //
|
||||
#define rustg_toml2json(tomlfile) call(RUST_G, "toml2json")(tomlfile)
|
||||
// TOML Operations //
|
||||
#define rustg_read_toml_file(path) json_decode(call(RUST_G, "toml_file_to_json")(path) || "null")
|
||||
|
||||
// Unzip Operations //
|
||||
#define rustg_unzip_download_async(url, unzip_directory) call(RUST_G, "unzip_download_async")(url, unzip_directory)
|
||||
#define rustg_unzip_check(job_id) call(RUST_G, "unzip_check")("[job_id]")
|
||||
|
||||
// URL Encoder/Decoder Operations //
|
||||
#define rustg_url_encode(text) call(RUST_G, "url_encode")("[text]")
|
||||
#define rustg_url_decode(text) call(RUST_G, "url_decode")(text)
|
||||
|
||||
#ifdef RUSTG_OVERRIDE_BUILTINS
|
||||
#define url_encode(text) rustg_url_encode(text)
|
||||
#define url_decode(text) rustg_url_decode(text)
|
||||
#endif
|
||||
|
||||
// RUSTG Version //
|
||||
#define RUST_G_VERSION "0.4.5-P3"
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
// BUFFS //
|
||||
///////////
|
||||
|
||||
#define STATUS_EFFECT_HISGRACE /datum/status_effect/his_grace //His Grace.
|
||||
|
||||
#define STATUS_EFFECT_SHADOW_MEND /datum/status_effect/shadow_mend //Quick, powerful heal that deals damage afterwards. Heals 15 brute/burn every second for 3 seconds.
|
||||
#define STATUS_EFFECT_VOID_PRICE /datum/status_effect/void_price //The price of healing yourself with void energy. Deals 3 brute damage every 3 seconds for 30 seconds.
|
||||
#define STATUS_EFFECT_EXERCISED /datum/status_effect/exercised //Prevents heart disease
|
||||
@@ -27,7 +29,6 @@
|
||||
|
||||
//#define STATUS_EFFECT_POWERREGEN /datum/status_effect/cyborg_power_regen //Regenerates power on a given cyborg over time
|
||||
|
||||
//#define STATUS_EFFECT_HISGRACE /datum/status_effect/his_grace //His Grace.
|
||||
|
||||
//#define STATUS_EFFECT_WISH_GRANTERS_GIFT /datum/status_effect/wish_granters_gift //If you're currently resurrecting with the Wish Granter
|
||||
|
||||
@@ -53,7 +54,7 @@
|
||||
//#define MAX_MANIA_SEVERITY 100 //how high the mania severity can go
|
||||
//#define MANIA_DAMAGE_TO_CONVERT 90 //how much damage is required before it'll convert affected targets
|
||||
|
||||
//#define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath.
|
||||
#define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath.
|
||||
|
||||
#define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost: can see dead people, can't manifest more ghosts
|
||||
|
||||
|
||||
@@ -188,3 +188,21 @@
|
||||
animate(A, transform = matrix(punchstr, MATRIX_ROTATE), pixel_y = 16, time = 2, color = "#eeeeee", easing = BOUNCE_EASING)
|
||||
animate(transform = matrix(-punchstr, MATRIX_ROTATE), pixel_y = original_y, time = 2, color = "#ffffff", easing = BOUNCE_EASING)
|
||||
animate(transform = null, time = 3, easing = BOUNCE_EASING)
|
||||
|
||||
/proc/animate_rumble(atom/A)
|
||||
var/static/list/transforms
|
||||
if(!transforms)
|
||||
var/matrix/M1 = matrix()
|
||||
var/matrix/M2 = matrix()
|
||||
var/matrix/M3 = matrix()
|
||||
var/matrix/M4 = matrix()
|
||||
M1.Translate(-1, 0)
|
||||
M2.Translate(0, 1)
|
||||
M3.Translate(1, 0)
|
||||
M4.Translate(0, -1)
|
||||
transforms = list(M1, M2, M3, M4)
|
||||
|
||||
animate(A, transform = transforms[1], time = 0.2, loop = -1)
|
||||
animate(transform = transforms[2], time = 0.1)
|
||||
animate(transform = transforms[3], time = 0.2)
|
||||
animate(transform = transforms[4], time = 0.3)
|
||||
|
||||
@@ -51,3 +51,6 @@
|
||||
return A.plane - B.plane
|
||||
else
|
||||
return A.layer - B.layer
|
||||
|
||||
/proc/cmp_login_processor_priority(datum/client_login_processor/A, datum/client_login_processor/B)
|
||||
return A.priority - B.priority
|
||||
|
||||
@@ -77,13 +77,12 @@
|
||||
for(var/geartype in subtypesof(/datum/gear))
|
||||
var/datum/gear/G = geartype
|
||||
|
||||
var/use_name = initial(G.display_name)
|
||||
var/use_category = initial(G.sort_category)
|
||||
|
||||
if(G == initial(G.subtype_path))
|
||||
if(G == initial(G.main_typepath))
|
||||
continue
|
||||
|
||||
if(!use_name)
|
||||
if(!initial(G.display_name))
|
||||
stack_trace("Loadout - Missing display name: [G]")
|
||||
continue
|
||||
if(!initial(G.cost))
|
||||
@@ -96,8 +95,8 @@
|
||||
if(!GLOB.loadout_categories[use_category])
|
||||
GLOB.loadout_categories[use_category] = new /datum/loadout_category(use_category)
|
||||
var/datum/loadout_category/LC = GLOB.loadout_categories[use_category]
|
||||
GLOB.gear_datums[use_name] = new geartype
|
||||
LC.gear[use_name] = GLOB.gear_datums[use_name]
|
||||
GLOB.gear_datums[geartype] = new geartype
|
||||
LC.gear[geartype] = GLOB.gear_datums[geartype]
|
||||
|
||||
GLOB.loadout_categories = sortAssoc(GLOB.loadout_categories)
|
||||
for(var/loadout_category in GLOB.loadout_categories)
|
||||
@@ -128,6 +127,13 @@
|
||||
continue
|
||||
GLOB.world_topic_handlers[wth.topic_key] = topic_handler_type
|
||||
|
||||
// Setup client login processors.
|
||||
for(var/processor_type in subtypesof(/datum/client_login_processor))
|
||||
var/datum/client_login_processor/CLP = new processor_type
|
||||
GLOB.client_login_processors += CLP
|
||||
// Sort them by priority, lowest first
|
||||
sortTim(GLOB.client_login_processors, /proc/cmp_login_processor_priority)
|
||||
|
||||
/* // Uncomment to debug chemical reaction list.
|
||||
/client/verb/debug_chemical_list()
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Turn(.) //BYOND handles cases such as -270, 360, 540 etc. DOES NOT HANDLE 180 TURNS WELL, THEY TWEEN AND LOOK LIKE SHIT
|
||||
|
||||
|
||||
/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3)
|
||||
/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE)
|
||||
if(!segments)
|
||||
return
|
||||
var/segment = 360/segments
|
||||
@@ -19,7 +19,10 @@
|
||||
|
||||
speed /= segments
|
||||
|
||||
animate(src, transform = matrices[1], time = speed, loops)
|
||||
if(parallel)
|
||||
animate(src, transform = matrices[1], time = speed, loops , flags = ANIMATION_PARALLEL)
|
||||
else
|
||||
animate(src, transform = matrices[1], time = speed, loops)
|
||||
for(var/i in 2 to segments) //2 because 1 is covered above
|
||||
animate(transform = matrices[i], time = speed)
|
||||
//doesn't have an object argument because this is "Stacking" with the animate call above
|
||||
|
||||
+14
-10
@@ -272,15 +272,19 @@
|
||||
update_all_mob_security_hud()
|
||||
return 1
|
||||
|
||||
/*
|
||||
Proc for attack log creation, because really why not
|
||||
1 argument is the actor
|
||||
2 argument is the target of action
|
||||
3 is the full description of the action
|
||||
4 is whether or not to message admins
|
||||
This is always put in the attack log.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates attack (old and new) logs for the user and defense logs for the target.
|
||||
* Will message admins depending on the custom_level, user and target.
|
||||
*
|
||||
* custom_level will determine the log level set. Unless the target is SSD and there is a user doing it
|
||||
* If custom_level is not set then the log level will be determined using the user and the target.
|
||||
*
|
||||
* * Arguments:
|
||||
* * user - The thing doing it. Can be null
|
||||
* * target - The target of the attack
|
||||
* * what_done - What has happened
|
||||
* * custom_level - The log level override
|
||||
*/
|
||||
/proc/add_attack_logs(atom/user, target, what_done, custom_level)
|
||||
if(islist(target)) // Multi-victim adding
|
||||
var/list/targets = target
|
||||
@@ -323,7 +327,7 @@ This is always put in the attack log.
|
||||
loglevel = ATKLOG_ALMOSTALL
|
||||
else
|
||||
loglevel = ATKLOG_ALL // Hitting an object. Not a mob
|
||||
if(isLivingSSD(target)) // Attacks on SSDs are shown to admins with any log level except ATKLOG_NONE. Overrides custom level
|
||||
if(user && isLivingSSD(target)) // Attacks on SSDs are shown to admins with any log level except ATKLOG_NONE. Overrides custom level
|
||||
loglevel = ATKLOG_FEW
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
if(default) return default
|
||||
if(List && List.len)return pick(List)
|
||||
|
||||
/proc/sanitize_json(json_input)
|
||||
if(length(json_input) && istext(json_input))
|
||||
return json_decode(json_input)
|
||||
return list()
|
||||
|
||||
|
||||
//more specialised stuff
|
||||
|
||||
@@ -164,6 +164,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_BLOODCRAWL_EAT "bloodcrawl_eat"
|
||||
#define TRAIT_DWARF "dwarf"
|
||||
#define TRAIT_SILENT_FOOTSTEPS "silent_footsteps" //makes your footsteps completely silent
|
||||
#define TRAIT_MESON_VISION "meson_vision"
|
||||
#define TRAIT_FLASH_PROTECTION "flash_protection"
|
||||
#define TRAIT_NIGHT_VISION "night_vision"
|
||||
|
||||
#define TRAIT_COMIC_SANS "comic_sans"
|
||||
#define TRAIT_NOFINGERPRINTS "no_fingerprints"
|
||||
|
||||
+12
-28
@@ -464,12 +464,15 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
if(GLOB.stealthminID[P] == txt)
|
||||
return P
|
||||
|
||||
// Returns the atom sitting on the turf.
|
||||
// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
|
||||
/proc/get_atom_on_turf(atom/movable/M)
|
||||
//Returns the atom sitting on the turf.
|
||||
//For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
|
||||
//Optional arg 'type' to stop once it reaches a specific type instead of a turf.
|
||||
/proc/get_atom_on_turf(atom/movable/M, stop_type)
|
||||
var/atom/loc = M
|
||||
while(loc && loc.loc && !istype(loc.loc, /turf/))
|
||||
while(loc?.loc && !isturf(loc.loc))
|
||||
loc = loc.loc
|
||||
if(stop_type && istype(loc, stop_type))
|
||||
break
|
||||
return loc
|
||||
|
||||
/*
|
||||
@@ -1536,7 +1539,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
shift.Translate(0,radius)
|
||||
transform = shift
|
||||
|
||||
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
|
||||
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE)
|
||||
|
||||
while(orbiting && orbiting == A && A.loc)
|
||||
var/targetloc = get_turf(A)
|
||||
@@ -1551,7 +1554,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
if(orbiting == A) //make sure we haven't started orbiting something else.
|
||||
orbiting = null
|
||||
SpinAnimation(0, 0)
|
||||
SpinAnimation(0, 0, parallel = FALSE)
|
||||
transform = cached_transform
|
||||
|
||||
|
||||
@@ -1774,8 +1777,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
/obj/item/robot_parts = "ROBOT_PARTS",
|
||||
/obj/item/seeds = "SEED",
|
||||
/obj/item/slime_extract = "SLIME_CORE",
|
||||
/obj/item/spacepod_equipment/weaponry = "POD_WEAPON",
|
||||
/obj/item/spacepod_equipment = "POD_EQUIP",
|
||||
/obj/item/stack/sheet/mineral = "MINERAL",
|
||||
/obj/item/stack/sheet = "SHEET",
|
||||
/obj/item/stack/tile = "TILE",
|
||||
@@ -1926,24 +1927,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
return pois
|
||||
|
||||
/proc/flash_color(mob_or_client, flash_color="#960000", flash_time=20)
|
||||
var/client/C
|
||||
if(istype(mob_or_client, /mob))
|
||||
var/mob/M = mob_or_client
|
||||
if(M.client)
|
||||
C = M.client
|
||||
else
|
||||
return
|
||||
else if(istype(mob_or_client, /client))
|
||||
C = mob_or_client
|
||||
|
||||
if(!istype(C))
|
||||
return
|
||||
|
||||
C.color = flash_color
|
||||
spawn(0)
|
||||
animate(C, color = initial(C.color), time = flash_time)
|
||||
|
||||
#define RANDOM_COLOUR (rgb(rand(0,255),rand(0,255),rand(0,255)))
|
||||
|
||||
/proc/make_bit_triplet()
|
||||
@@ -2078,11 +2061,12 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
/proc/log_connection(ckey, ip, cid, connection_type)
|
||||
ASSERT(connection_type in list(CONNECTION_TYPE_ESTABLISHED, CONNECTION_TYPE_DROPPED_IPINTEL, CONNECTION_TYPE_DROPPED_BANNED, CONNECTION_TYPE_DROPPED_INVALID))
|
||||
var/datum/db_query/query_accesslog = SSdbcore.NewQuery("INSERT INTO connection_log (`datetime`, `ckey`, `ip`, `computerid`, `result`) VALUES(Now(), :ckey, :ip, :cid, :result)", list(
|
||||
var/datum/db_query/query_accesslog = SSdbcore.NewQuery("INSERT INTO connection_log (`datetime`, `ckey`, `ip`, `computerid`, `result`, `server_id`) VALUES(Now(), :ckey, :ip, :cid, :result, :server_id)", list(
|
||||
"ckey" = ckey,
|
||||
"ip" = "[ip ? ip : ""]", // This is important. NULL is not the same as "", and if you directly open the `.dmb` file, you get a NULL IP.
|
||||
"cid" = cid,
|
||||
"result" = connection_type
|
||||
"result" = connection_type,
|
||||
"server_id" = GLOB.configuration.system.instance_id
|
||||
))
|
||||
query_accesslog.warn_execute()
|
||||
qdel(query_accesslog)
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
#define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE))))
|
||||
|
||||
//Update this whenever you need to take advantage of more recent byond features
|
||||
#define MIN_COMPILER_VERSION 513
|
||||
#define MIN_COMPILER_BUILD 1514
|
||||
#define MIN_COMPILER_VERSION 514
|
||||
#define MIN_COMPILER_BUILD 1554
|
||||
#if DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD
|
||||
//Don't forget to update this part
|
||||
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
|
||||
#error You need version 513.1514 or higher
|
||||
#error You need version 514.1554 or higher
|
||||
#endif
|
||||
|
||||
// Macros that must exist before world.dm
|
||||
|
||||
@@ -5,7 +5,6 @@ GLOBAL_VAR_INIT(deafblock, 0)
|
||||
GLOBAL_VAR_INIT(hulkblock, 0)
|
||||
GLOBAL_VAR_INIT(teleblock, 0)
|
||||
GLOBAL_VAR_INIT(fireblock, 0)
|
||||
GLOBAL_VAR_INIT(xrayblock, 0)
|
||||
GLOBAL_VAR_INIT(clumsyblock, 0)
|
||||
GLOBAL_VAR_INIT(fakeblock, 0)
|
||||
GLOBAL_VAR_INIT(coughblock, 0)
|
||||
@@ -30,6 +29,9 @@ GLOBAL_VAR_INIT(hallucinationblock, 0)
|
||||
GLOBAL_VAR_INIT(noprintsblock, 0)
|
||||
GLOBAL_VAR_INIT(shockimmunityblock, 0)
|
||||
GLOBAL_VAR_INIT(smallsizeblock, 0)
|
||||
GLOBAL_VAR_INIT(mesonblock, 0)
|
||||
GLOBAL_VAR_INIT(noflashblock, 0)
|
||||
GLOBAL_VAR_INIT(nightvisionblock, 0)
|
||||
|
||||
///////////////////////////////
|
||||
// Goon Stuff
|
||||
|
||||
@@ -56,3 +56,5 @@ GLOBAL_LIST_INIT(cooking_ingredients, list(RECIPE_MICROWAVE = list(), RECIPE_OVE
|
||||
GLOBAL_LIST_INIT(cooking_reagents, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN = list(), RECIPE_GRILL = list(), RECIPE_CANDY = list()))
|
||||
|
||||
#define EGG_LAYING_MESSAGES list("lays an egg.", "squats down and croons.", "begins making a huge racket.", "begins clucking raucously.")
|
||||
|
||||
GLOBAL_LIST_EMPTY(client_login_processors)
|
||||
|
||||
@@ -6,7 +6,6 @@ GLOBAL_LIST_INIT(landmarks_list, list()) //list of all landmarks created
|
||||
GLOBAL_LIST_INIT(surgery_steps, list()) //list of all surgery steps |BS12
|
||||
GLOBAL_LIST_INIT(side_effects, list()) //list of all medical sideeffects types by thier names |BS12
|
||||
GLOBAL_LIST_INIT(mechas_list, list()) //list of all mechs. Used by hostile mobs target tracking.
|
||||
GLOBAL_LIST_INIT(spacepods_list, list()) //list of all space pods. Used by hostile mobs target tracking.
|
||||
GLOBAL_LIST_INIT(joblist, list()) //list of all jobstypes, minus borg and AI
|
||||
GLOBAL_LIST_INIT(airlocks, list()) //list of all airlocks
|
||||
GLOBAL_LIST_INIT(singularities, list()) //list of all singularities
|
||||
|
||||
@@ -46,6 +46,9 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_DWARF" = TRAIT_DWARF,
|
||||
"TRAIT_SILENT_FOOTSTEPS" = TRAIT_SILENT_FOOTSTEPS,
|
||||
"TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE,
|
||||
"TRAIT_MESON_VISION" = TRAIT_MESON_VISION,
|
||||
"TRAIT_FLASH_PROTECTION" = TRAIT_FLASH_PROTECTION,
|
||||
"TRAIT_NIGHT_VISION" = TRAIT_NIGHT_VISION,
|
||||
|
||||
"TRAIT_COMIC_SANS" = TRAIT_COMIC_SANS,
|
||||
"TRAIT_NOFINGERPRINTS" = TRAIT_NOFINGERPRINTS,
|
||||
|
||||
@@ -622,6 +622,13 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
stone = null
|
||||
return ..()
|
||||
|
||||
/obj/screen/alert/notify_mapvote
|
||||
name = "Map Vote"
|
||||
desc = "Vote on which map you would like to play on next!"
|
||||
icon_state = "map_vote"
|
||||
|
||||
/obj/screen/alert/notify_mapvote/Click()
|
||||
SSvote.browse_to(usr.client)
|
||||
|
||||
//OBJECT-BASED
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
/obj/attacked_by(obj/item/I, mob/living/user)
|
||||
if(I.force)
|
||||
user.visible_message("<span class='danger'>[user] has hit [src] with [I]!</span>", "<span class='danger'>You hit [src] with [I]!</span>")
|
||||
take_damage(I.force, I.damtype, "melee", 1)
|
||||
take_damage(I.force, I.damtype, MELEE, 1)
|
||||
|
||||
/mob/living/attacked_by(obj/item/I, mob/living/user, def_zone)
|
||||
send_item_attack_message(I, user)
|
||||
|
||||
@@ -46,6 +46,8 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
var/datum/configuration_section/url_configuration/url
|
||||
/// Holder for the voting configuration datum
|
||||
var/datum/configuration_section/vote_configuration/vote
|
||||
/// Raw data. Stored here to avoid passing data between procs constantly
|
||||
var/list/raw_data = list()
|
||||
|
||||
|
||||
/datum/server_configuration/Destroy(force)
|
||||
@@ -53,6 +55,16 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
// This is going to stay existing. I dont care.
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
/datum/server_configuration/vv_get_var(var_name)
|
||||
if(var_name == "raw_data") // NO!
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/datum/server_configuration/vv_edit_var(var_name, var_value)
|
||||
if(var_name == "raw_data") // NO!
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/datum/server_configuration/CanProcCall(procname)
|
||||
return FALSE // No thanks
|
||||
|
||||
@@ -85,34 +97,66 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
var/config_file = "config/config.toml"
|
||||
if(!fexists(config_file))
|
||||
config_file = "config/example/config.toml" // Fallback to example if user hasnt setup config properly
|
||||
var/raw_json = rustg_toml2json(config_file)
|
||||
var/list/raw_config_data = json_decode(raw_json)
|
||||
raw_data = rustg_read_toml_file(config_file)
|
||||
|
||||
// Now pass through all our stuff
|
||||
admin.load_data(raw_config_data["admin_configuration"])
|
||||
afk.load_data(raw_config_data["afk_configuration"])
|
||||
custom_sprites.load_data(raw_config_data["custom_sprites_configuration"])
|
||||
database.load_data(raw_config_data["database_configuration"])
|
||||
discord.load_data(raw_config_data["discord_configuration"])
|
||||
event.load_data(raw_config_data["event_configuration"])
|
||||
gamemode.load_data(raw_config_data["gamemode_configuration"])
|
||||
gateway.load_data(raw_config_data["gateway_configuration"])
|
||||
general.load_data(raw_config_data["general_configuration"])
|
||||
ipintel.load_data(raw_config_data["ipintel_configuration"])
|
||||
jobs.load_data(raw_config_data["job_configuration"])
|
||||
logging.load_data(raw_config_data["logging_configuration"])
|
||||
mc.load_data(raw_config_data["mc_configuration"])
|
||||
metrics.load_data(raw_config_data["metrics_configuration"])
|
||||
movement.load_data(raw_config_data["movement_configuration"])
|
||||
overflow.load_data(raw_config_data["overflow_configuration"])
|
||||
ruins.load_data(raw_config_data["ruin_configuration"])
|
||||
system.load_data(raw_config_data["system_configuration"])
|
||||
url.load_data(raw_config_data["url_configuration"])
|
||||
vote.load_data(raw_config_data["voting_configuration"])
|
||||
load_all_sections()
|
||||
|
||||
// Clear our list to save RAM
|
||||
raw_data = list()
|
||||
|
||||
// And report the load
|
||||
DIRECT_OUTPUT(world.log, "Config loaded in [stop_watch(start)]s")
|
||||
|
||||
/datum/server_configuration/proc/load_all_sections()
|
||||
safe_load(admin, "admin_configuration")
|
||||
safe_load(afk, "afk_configuration")
|
||||
safe_load(custom_sprites, "custom_sprites_configuration")
|
||||
safe_load(database, "database_configuration")
|
||||
safe_load(discord, "discord_configuration")
|
||||
safe_load(event, "event_configuration")
|
||||
safe_load(gamemode, "gamemode_configuration")
|
||||
safe_load(gateway, "gateway_configuration")
|
||||
safe_load(general, "general_configuration")
|
||||
safe_load(ipintel, "ipintel_configuration")
|
||||
safe_load(jobs, "job_configuration")
|
||||
safe_load(logging, "logging_configuration")
|
||||
safe_load(mc, "mc_configuration")
|
||||
safe_load(metrics, "metrics_configuration")
|
||||
safe_load(movement, "movement_configuration")
|
||||
safe_load(overflow, "overflow_configuration")
|
||||
safe_load(ruins, "ruin_configuration")
|
||||
safe_load(system, "system_configuration")
|
||||
safe_load(url, "url_configuration")
|
||||
safe_load(vote, "voting_configuration")
|
||||
|
||||
// Proc to load up instance-specific overrides
|
||||
/datum/server_configuration/proc/load_overrides()
|
||||
var/override_file = "config/overrides_[world.port].toml"
|
||||
if(!fexists(override_file))
|
||||
DIRECT_OUTPUT(world.log, "Overrides not found for this instance.")
|
||||
return
|
||||
|
||||
DIRECT_OUTPUT(world.log, "Overrides found for this instance. Loading them.")
|
||||
var/start = start_watch() // Time tracking
|
||||
|
||||
raw_data = rustg_read_toml_file(override_file)
|
||||
|
||||
// Now safely load our overrides.
|
||||
// Due to the nature of config wrappers, only vars that exist in the config file are applied to the config datums.
|
||||
// This means that an override missing a key doesnt null it out from the main server
|
||||
load_all_sections()
|
||||
|
||||
// Clear our list to save RAM
|
||||
raw_data = list()
|
||||
|
||||
// And report the load
|
||||
DIRECT_OUTPUT(world.log, "Config overrides loaded in [stop_watch(start)]s")
|
||||
|
||||
// Only loads the data for a config section if that key exists in the JSON
|
||||
/datum/server_configuration/proc/safe_load(datum/configuration_section/CS, section)
|
||||
if(!isnull(raw_data[section]))
|
||||
CS.load_data(raw_data[section])
|
||||
|
||||
/datum/configuration_section
|
||||
/// See __config_defines.dm
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
var/forward_all_ahelps = TRUE
|
||||
/// Admin role to ping if no admins are online. Disables if empty string
|
||||
var/admin_role_id = ""
|
||||
/// Mentor role to ping if no mentors are online. Disables if empty string
|
||||
var/mentor_role_id = ""
|
||||
/// List of all URLs for the main webhooks
|
||||
var/list/main_webhook_urls = list()
|
||||
/// List of all URLs for the admin webhooks
|
||||
@@ -21,6 +23,7 @@
|
||||
CONFIG_LOAD_BOOL(webhooks_enabled, data["enable_discord_webhooks"])
|
||||
CONFIG_LOAD_BOOL(forward_all_ahelps, data["forward_all_ahelps"])
|
||||
CONFIG_LOAD_STR(admin_role_id, data["admin_role_id"])
|
||||
CONFIG_LOAD_STR(mentor_role_id, data["mentor_role_id"])
|
||||
CONFIG_LOAD_LIST(main_webhook_urls, data["main_webhook_urls"])
|
||||
CONFIG_LOAD_LIST(mentor_webhook_urls, data["mentor_webhook_urls"])
|
||||
CONFIG_LOAD_LIST(admin_webhook_urls, data["admin_webhook_urls"])
|
||||
|
||||
@@ -10,16 +10,23 @@
|
||||
var/medal_hub_password = null
|
||||
/// Do we want the server to kill on reboot instead of keeping the same DD session
|
||||
var/shutdown_on_reboot = FALSE
|
||||
/// Is this server a production server (Has higher security and requires 2FA)
|
||||
var/is_production = FALSE
|
||||
/// If above is true, you can run a shell command
|
||||
var/shutdown_shell_command = null
|
||||
/// 2FA backend server host
|
||||
var/_2fa_auth_host = null
|
||||
/// List of IP addresses which bypass world topic rate limiting
|
||||
var/list/topic_ip_ratelimit_bypass = list()
|
||||
/// Server instance ID
|
||||
var/instance_id = "paradise_main"
|
||||
/// Server internal IP
|
||||
var/internal_ip = "127.0.0.1"
|
||||
|
||||
/datum/configuration_section/system_configuration/load_data(list/data)
|
||||
// Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
|
||||
CONFIG_LOAD_BOOL(shutdown_on_reboot, data["shutdown_on_reboot"])
|
||||
CONFIG_LOAD_BOOL(is_production, data["is_production"])
|
||||
|
||||
CONFIG_LOAD_STR(topic_key, data["communications_password"])
|
||||
CONFIG_LOAD_STR(medal_hub_address, data["medal_hub_address"])
|
||||
@@ -28,3 +35,6 @@
|
||||
CONFIG_LOAD_STR(_2fa_auth_host, data["_2fa_auth_host"])
|
||||
|
||||
CONFIG_LOAD_LIST(topic_ip_ratelimit_bypass, data["topic_ip_ratelimit_bypass"])
|
||||
|
||||
CONFIG_LOAD_STR(instance_id, data["instance_id"])
|
||||
CONFIG_LOAD_STR(internal_ip, data["internal_ip"])
|
||||
|
||||
@@ -62,7 +62,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
/// For scheduling different subsystems for different stages of the round
|
||||
var/current_runlevel
|
||||
/// Do we want to sleep until players log in?
|
||||
var/sleep_offline_after_initializations = TRUE
|
||||
var/sleep_offline_after_initializations = FALSE // No we dont
|
||||
|
||||
var/static/restart_clear = 0
|
||||
var/static/restart_timeout = 0
|
||||
|
||||
@@ -287,8 +287,8 @@ SUBSYSTEM_DEF(blackbox)
|
||||
lakey = L.lastattackerckey
|
||||
|
||||
var/datum/db_query/deathquery = SSdbcore.NewQuery({"
|
||||
INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord)
|
||||
VALUES (:name, :key, :job, :special, :pod, NOW(), :laname, :lakey, :gender, :bruteloss, :fireloss, :brainloss, :oxyloss, :coord)"},
|
||||
INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord, server_id)
|
||||
VALUES (:name, :key, :job, :special, :pod, NOW(), :laname, :lakey, :gender, :bruteloss, :fireloss, :brainloss, :oxyloss, :coord, :server_id)"},
|
||||
list(
|
||||
"name" = L.real_name,
|
||||
"key" = L.key,
|
||||
@@ -302,7 +302,8 @@ SUBSYSTEM_DEF(blackbox)
|
||||
"fireloss" = L.getFireLoss(),
|
||||
"brainloss" = L.getBrainLoss(),
|
||||
"oxyloss" = L.getOxyLoss(),
|
||||
"coord" = "[L.x], [L.y], [L.z]"
|
||||
"coord" = "[L.x], [L.y], [L.z]",
|
||||
"server_id" = GLOB.configuration.system.instance_id
|
||||
)
|
||||
)
|
||||
deathquery.warn_execute()
|
||||
|
||||
@@ -54,9 +54,8 @@ SUBSYSTEM_DEF(changelog)
|
||||
/datum/controller/subsystem/changelog/proc/UpdatePlayerChangelogDate(client/C)
|
||||
if(!ss_ready)
|
||||
return // Only return here, we dont have to worry about a queue list because this will be called from ShowChangelog()
|
||||
// Technically this is only for the date but we can also do the UI button at the same time
|
||||
var/datum/preferences/P = GLOB.preferences_datums[C.ckey]
|
||||
if(P.toggles & PREFTOGGLE_UI_DARKMODE)
|
||||
|
||||
if(C.prefs.toggles & PREFTOGGLE_UI_DARKMODE)
|
||||
winset(C, "rpane.changelog", "background-color=#40628a;font-color=#ffffff;font-style=none")
|
||||
else
|
||||
winset(C, "rpane.changelog", "background-color=none;font-style=none")
|
||||
|
||||
@@ -160,8 +160,8 @@ SUBSYSTEM_DEF(dbcore)
|
||||
if(!IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_round_initialize = SSdbcore.NewQuery(
|
||||
"INSERT INTO round (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(:internet_address), :port)",
|
||||
list("internet_address" = world.internet_address || "0", "port" = "[world.port]")
|
||||
"INSERT INTO round (initialize_datetime, server_ip, server_port, server_id) VALUES (Now(), INET_ATON(:internet_address), :port, :server_id)",
|
||||
list("internet_address" = world.internet_address || "0", "port" = "[world.port]", "server_id" = GLOB.configuration.system.instance_id)
|
||||
)
|
||||
query_round_initialize.Execute(async = FALSE)
|
||||
GLOB.round_id = "[query_round_initialize.last_insert_id]"
|
||||
|
||||
@@ -5,6 +5,8 @@ SUBSYSTEM_DEF(discord)
|
||||
var/enabled = FALSE
|
||||
/// Last time the administrator ping was dropped. This ensures administrators cannot be mass pinged if a large chunk of ahelps go off at once (IE: tesloose)
|
||||
var/last_administration_ping = 0
|
||||
/// Last time the mentor ping was dropped. This ensures mentors cannot be mass pinged if a large chunk of mhelps go off at once.
|
||||
var/last_mentor_ping = 0
|
||||
|
||||
/datum/controller/subsystem/discord/Initialize(start_timeofday)
|
||||
if(GLOB.configuration.discord.webhooks_enabled)
|
||||
@@ -25,7 +27,7 @@ SUBSYSTEM_DEF(discord)
|
||||
webhook_urls = GLOB.configuration.discord.mentor_webhook_urls
|
||||
|
||||
var/datum/discord_webhook_payload/dwp = new()
|
||||
dwp.webhook_content = content
|
||||
dwp.webhook_content = "**\[[GLOB.configuration.system.instance_id]]** [content]"
|
||||
for(var/url in webhook_urls)
|
||||
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, url, dwp.serialize2json(), list("content-type" = "application/json"))
|
||||
|
||||
@@ -71,10 +73,31 @@ SUBSYSTEM_DEF(discord)
|
||||
var/message = "[content] [alerttext] [add_ping ? handle_administrator_ping() : ""]"
|
||||
|
||||
var/datum/discord_webhook_payload/dwp = new()
|
||||
dwp.webhook_content = message
|
||||
dwp.webhook_content = "**\[[GLOB.configuration.system.instance_id]]** [message]"
|
||||
for(var/url in GLOB.configuration.discord.admin_webhook_urls)
|
||||
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, url, dwp.serialize2json(), list("content-type" = "application/json"))
|
||||
|
||||
/datum/controller/subsystem/discord/proc/send2discord_simple_mentor(content)
|
||||
var/alerttext
|
||||
var/list/mentorcounter = staff_countup(R_MENTOR)
|
||||
var/active_mentors = mentorcounter[1]
|
||||
var/inactive_mentors = mentorcounter[3]
|
||||
var/add_ping = FALSE
|
||||
|
||||
if(active_mentors <= 0)
|
||||
add_ping = TRUE
|
||||
if(inactive_mentors)
|
||||
alerttext = "| **ALL MENTORS AFK**"
|
||||
else
|
||||
alerttext = "| **NO MENTORS ONLINE**"
|
||||
|
||||
var/message = "[content] [alerttext][add_ping ? handle_mentor_ping() : ""]"
|
||||
|
||||
var/datum/discord_webhook_payload/dwp = new()
|
||||
dwp.webhook_content = "**\[[GLOB.configuration.system.instance_id]]** [message]"
|
||||
for(var/url in GLOB.configuration.discord.mentor_webhook_urls)
|
||||
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, url, dwp.serialize2json(), list("content-type" = "application/json"))
|
||||
|
||||
// Helper to make administrator ping easier
|
||||
/datum/controller/subsystem/discord/proc/handle_administrator_ping()
|
||||
// Check if a role is even set
|
||||
@@ -86,3 +109,13 @@ SUBSYSTEM_DEF(discord)
|
||||
return "<@&[GLOB.configuration.discord.admin_role_id]>"
|
||||
|
||||
return ""
|
||||
|
||||
/datum/controller/subsystem/discord/proc/handle_mentor_ping()
|
||||
if(GLOB.configuration.discord.mentor_role_id)
|
||||
if(last_mentor_ping > world.time)
|
||||
return " *(Role pinged recently)*"
|
||||
|
||||
last_mentor_ping = world.time + 60 SECONDS
|
||||
return " <@&[GLOB.configuration.discord.mentor_role_id]>"
|
||||
|
||||
return ""
|
||||
|
||||
@@ -36,7 +36,7 @@ SUBSYSTEM_DEF(fires)
|
||||
|
||||
if(O.resistance_flags & ON_FIRE) //in case an object is extinguished while still in currentrun
|
||||
if(!(O.resistance_flags & FIRE_PROOF))
|
||||
O.take_damage(20, BURN, "fire", 0)
|
||||
O.take_damage(20, BURN, FIRE, 0)
|
||||
else
|
||||
O.extinguish()
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
SUBSYSTEM_DEF(instancing)
|
||||
name = "Instancing"
|
||||
runlevels = RUNLEVEL_INIT | RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
wait = 30 SECONDS
|
||||
flags = SS_KEEP_TIMING
|
||||
|
||||
/datum/controller/subsystem/instancing/Initialize(start_timeofday)
|
||||
// Dont even bother if we arent connected
|
||||
if(!SSdbcore.IsConnected())
|
||||
flags |= SS_NO_FIRE
|
||||
return ..()
|
||||
update_heartbeat() // Make sure you do this before announcing to peers, or no one will hear your announcement
|
||||
var/startup_msg = "The server <code>[GLOB.configuration.general.server_name]</code> is now starting up. The map is [SSmapping.map_datum.fluff_name] ([SSmapping.map_datum.technical_name]). You can connect with the <code>Switch Server</code> verb."
|
||||
message_all_peers(startup_msg)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/instancing/fire(resumed)
|
||||
update_heartbeat()
|
||||
update_playercache()
|
||||
|
||||
/**
|
||||
* Playercache updater
|
||||
*
|
||||
* Updates the player cache in the DB. Different from heartbeat so we can force invoke it on player operations
|
||||
*/
|
||||
/datum/controller/subsystem/instancing/proc/update_playercache(optional_ckey)
|
||||
// You may be wondering, why the fuck is an "optional ckey" variable here
|
||||
// Well, this is invoked in client/New(), and needs to read from GLOB.clients
|
||||
// However, this proc sleeps, and if you sleep during client/New() once the client is in GLOB.clients, stuff breaks bad
|
||||
// (See my comment rambling in client/New())
|
||||
// By passing the ckey through, we can sleep in this proc and still get the data
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
// First iterate clients to get ckeys
|
||||
var/list/ckeys = list()
|
||||
for(var/client/C in GLOB.clients) // No code review. I am not doing the `as anything` bullshit, because we *do* need the type checks here to avoid null clients which do happen sometimes
|
||||
ckeys += C.ckey
|
||||
// Add our optional
|
||||
if(optional_ckey)
|
||||
ckeys += optional_ckey
|
||||
// Note: We dont have to sort the list here. The only time this is read for is a search,
|
||||
// and order doesnt matter for that.
|
||||
var/ckey_json = json_encode(ckeys)
|
||||
|
||||
// Yes I care about performance savings this much here to mass execute this shit
|
||||
var/list/datum/db_query/queries = list()
|
||||
queries += SSdbcore.NewQuery("UPDATE instance_data_cache SET key_value=:json WHERE key_name='playerlist' AND server_id=:sid", list(
|
||||
"json" = ckey_json,
|
||||
"sid" = GLOB.configuration.system.instance_id
|
||||
))
|
||||
queries += SSdbcore.NewQuery("UPDATE instance_data_cache SET key_value=:count WHERE key_name='playercount' AND server_id=:sid", list(
|
||||
"count" = length(ckeys),
|
||||
"sid" = GLOB.configuration.system.instance_id
|
||||
))
|
||||
|
||||
SSdbcore.MassExecute(queries, TRUE, TRUE, FALSE, FALSE)
|
||||
|
||||
/**
|
||||
* Heartbeat updater
|
||||
*
|
||||
* Updates the heartbeat in the DB. Used so other servers can see when this one was alive
|
||||
*/
|
||||
/datum/controller/subsystem/instancing/proc/update_heartbeat()
|
||||
// this could probably just go in fire() but clean code and profiler ease who cares
|
||||
var/datum/db_query/dbq = SSdbcore.NewQuery("UPDATE instance_data_cache SET key_value=NOW() WHERE key_name='heartbeat' AND server_id=:sid", list(
|
||||
"sid" = GLOB.configuration.system.instance_id
|
||||
))
|
||||
dbq.warn_execute()
|
||||
qdel(dbq)
|
||||
|
||||
/**
|
||||
* Seed data
|
||||
*
|
||||
* Seeds all our data into the DB for other servers to discover from.
|
||||
* This is called during world/New() instead of on initialize so it can be done *instantly*
|
||||
*/
|
||||
/datum/controller/subsystem/instancing/proc/seed_data()
|
||||
// We need to seed a lot of keys, so lets just use a key-value-pair-map to do this easily
|
||||
var/list/kvp_map = list()
|
||||
kvp_map["server_name"] = GLOB.configuration.general.server_name // Name of the server
|
||||
kvp_map["server_port"] = world.port // Server port (used for redirection and topics)
|
||||
kvp_map["topic_key"] = GLOB.configuration.system.topic_key // Server topic key (used for topics)
|
||||
kvp_map["internal_ip"] = GLOB.configuration.system.internal_ip // Server internal IP (used for topics)
|
||||
kvp_map["playercount"] = length(GLOB.clients) // Server client count (used for status info)
|
||||
kvp_map["playerlist"] = json_encode(list()) // Server client list. Used for dupe login checks. This gets filled in later
|
||||
kvp_map["heartbeat"] = SQLtime() // SQL timestamp for heartbeat purposes. Any server without a heartbeat in the last 60 seconds can be considered dead
|
||||
// Also note for above. You may say "But AA you dont need to JSON encode it, just use "\[]"."
|
||||
// Well to that I say, no. This is meant to be JSON regardless, and it should represent that. This proc is ran once during world/New()
|
||||
// An extra nanosecond of load will make zero difference.
|
||||
|
||||
for(var/key in kvp_map)
|
||||
var/datum/db_query/dbq = SSdbcore.NewQuery("INSERT INTO instance_data_cache (server_id, key_name, key_value) VALUES (:sid, :kn, :kv) ON DUPLICATE KEY UPDATE key_value=:kv2", // Is this necessary? Who knows!
|
||||
list(
|
||||
"sid" = GLOB.configuration.system.instance_id,
|
||||
"kn" = key,
|
||||
"kv" = "[kvp_map[key]]", // String encoding IS necessary since these tables use strings, not ints
|
||||
"kv2" = "[kvp_map[key]]", // Dont know if I need the second but better to be safe
|
||||
)
|
||||
)
|
||||
dbq.warn_execute(FALSE) // Do NOT async execute here because world/New() shouldnt sleep. EVER. You get issues if you do.
|
||||
qdel(dbq)
|
||||
|
||||
|
||||
/**
|
||||
* Message all peers
|
||||
*
|
||||
* Wrapper for [topic_all_peers] to format the input into a message topic. Will send a server-wide announcement to the other servers
|
||||
*
|
||||
* Arguments:
|
||||
* * message - Message to send to the other servers
|
||||
*/
|
||||
/datum/controller/subsystem/instancing/proc/message_all_peers(message)
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
var/topic_string = "instance_announce&msg=[url_encode(message)]"
|
||||
topic_all_peers(topic_string)
|
||||
|
||||
/**
|
||||
* Sends a topic to all peers
|
||||
*
|
||||
* Sends a raw topic to the other servers. WILL APPEND &key=[commskey] ON THE END. PLEASE ACCOUNT FOR THIS.
|
||||
*
|
||||
* Arguments:
|
||||
* * raw_topic - The raw topic to send to the other servers
|
||||
*/
|
||||
/datum/controller/subsystem/instancing/proc/topic_all_peers(raw_topic)
|
||||
// Someone here is going to say "AA you shouldnt put load on the DB server you can do sorting in BYOND"
|
||||
// Well let me put it this way. The DB server is an entirely different machine to BYOND, with this entire dataset being stored in its RAM, not even on disk
|
||||
// By making the DB server do the work, we can offload from BYOND, which is already strained
|
||||
var/datum/db_query/dbq1 = SSdbcore.NewQuery({"
|
||||
SELECT server_id, key_name, key_value FROM instance_data_cache WHERE server_id IN
|
||||
(SELECT server_id FROM instance_data_cache WHERE server_id !=:sid AND
|
||||
key_name='heartbeat' AND last_updated BETWEEN NOW() - INTERVAL 60 SECOND AND NOW())
|
||||
AND key_name IN ("topic_key", "internal_ip", "server_port")"}, list(
|
||||
"sid" = GLOB.configuration.system.instance_id
|
||||
))
|
||||
if(!dbq1.warn_execute())
|
||||
qdel(dbq1)
|
||||
return
|
||||
|
||||
var/servers_outer = list()
|
||||
while(dbq1.NextRow())
|
||||
if(!servers_outer[dbq1.item[1]])
|
||||
servers_outer[dbq1.item[1]] = list()
|
||||
|
||||
servers_outer[dbq1.item[1]][dbq1.item[2]] = dbq1.item[3] // This should assoc load our data
|
||||
|
||||
qdel(dbq1)
|
||||
|
||||
for(var/server in servers_outer)
|
||||
var/server_data = servers_outer[server]
|
||||
world.Export("byond://[server_data["internal_ip"]]:[server_data["server_port"]]?[raw_topic]&key=[server_data["topic_key"]]")
|
||||
|
||||
|
||||
/**
|
||||
* Player checker
|
||||
*
|
||||
* Check all connected peers to see if a player exists in the player cache
|
||||
* This is used to make sure players dont log into 2 servers at once
|
||||
* Arguments:
|
||||
* ckey - The ckey to check if they are logged into another server
|
||||
*/
|
||||
/datum/controller/subsystem/instancing/proc/check_player(ckey)
|
||||
// Please see above rant on L127
|
||||
var/datum/db_query/dbq1 = SSdbcore.NewQuery({"
|
||||
SELECT server_id, key_value FROM instance_data_cache WHERE server_id IN
|
||||
(SELECT server_id FROM instance_data_cache WHERE server_id != :sid AND
|
||||
key_name='heartbeat' AND last_updated BETWEEN NOW() - INTERVAL 60 SECOND AND NOW())
|
||||
AND key_name IN ("playerlist")"}, list(
|
||||
"sid" = GLOB.configuration.system.instance_id
|
||||
))
|
||||
if(!dbq1.warn_execute())
|
||||
qdel(dbq1)
|
||||
return
|
||||
|
||||
while(dbq1.NextRow())
|
||||
var/list/other_server_cache = json_decode(dbq1.item[2])
|
||||
if(ckey in other_server_cache)
|
||||
var/target_server = dbq1.item[1] // Yes. This var is necessary.
|
||||
qdel(dbq1)
|
||||
return target_server
|
||||
|
||||
qdel(dbq1)
|
||||
return null // If we are here, it means we didnt find our player on another server
|
||||
@@ -65,7 +65,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
return type_occupations[jobtype]
|
||||
|
||||
/datum/controller/subsystem/jobs/proc/GetPlayerAltTitle(mob/new_player/player, rank)
|
||||
return player.client.prefs.GetPlayerAltTitle(GetJob(rank))
|
||||
return player.client.prefs.active_character.GetPlayerAltTitle(GetJob(rank))
|
||||
|
||||
/datum/controller/subsystem/jobs/proc/AssignRole(mob/new_player/player, rank, latejoin = 0)
|
||||
Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
|
||||
@@ -121,7 +121,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
|
||||
var/list/candidates = list()
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] AvInPlaytime: [job.available_in_playtime(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]")
|
||||
Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] AvInPlaytime: [job.available_in_playtime(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.active_character.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]")
|
||||
if(jobban_isbanned(player, job.title))
|
||||
Debug("FOC isbanned failed, Player: [player]")
|
||||
continue
|
||||
@@ -140,7 +140,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
if(player.mind && (job.title in player.mind.restricted_roles))
|
||||
Debug("FOC incompatbile with antagonist role, Player: [player]")
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
if(player.client.prefs.active_character.GetJobDepartment(job, level) & job.flag)
|
||||
Debug("FOC pass, Player: [player], Level:[level]")
|
||||
candidates += player
|
||||
return candidates
|
||||
@@ -367,12 +367,12 @@ SUBSYSTEM_DEF(jobs)
|
||||
continue
|
||||
|
||||
// If the player wants that job on this level, then try give it to him.
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
if(player.client.prefs.active_character.GetJobDepartment(job, level) & job.flag)
|
||||
|
||||
// If the job isn't filled
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
Debug("DO pass, Player: [player], Level:[level], Job:[job.title]")
|
||||
Debug(" - Job Flag: [job.flag] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Current Pos: [job.current_positions] Job Spawn Positions = [job.spawn_positions]")
|
||||
Debug(" - Job Flag: [job.flag] Job Department: [player.client.prefs.active_character.GetJobDepartment(job, level)] Job Current Pos: [job.current_positions] Job Spawn Positions = [job.spawn_positions]")
|
||||
AssignRole(player, job.title)
|
||||
unassigned -= player
|
||||
break
|
||||
@@ -380,7 +380,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
// Hand out random jobs to the people who didn't get any in the last check
|
||||
// Also makes sure that they got their preference correct
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == GET_RANDOM_JOB)
|
||||
if(player.client.prefs.active_character.alternate_option == GET_RANDOM_JOB)
|
||||
GiveRandomJob(player)
|
||||
|
||||
Debug("DO, Standard Check end")
|
||||
@@ -390,7 +390,7 @@ SUBSYSTEM_DEF(jobs)
|
||||
// Antags, who have to get in, come first
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.mind.special_role)
|
||||
if(player.client.prefs.alternate_option != BE_ASSISTANT)
|
||||
if(player.client.prefs.active_character.alternate_option != BE_ASSISTANT)
|
||||
GiveRandomJob(player)
|
||||
if(player in unassigned)
|
||||
AssignRole(player, "Civilian")
|
||||
@@ -399,10 +399,10 @@ SUBSYSTEM_DEF(jobs)
|
||||
|
||||
// Then we assign what we can to everyone else.
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == BE_ASSISTANT)
|
||||
if(player.client.prefs.active_character.alternate_option == BE_ASSISTANT)
|
||||
Debug("AC2 Assistant located, Player: [player]")
|
||||
AssignRole(player, "Civilian")
|
||||
else if(player.client.prefs.alternate_option == RETURN_TO_LOBBY)
|
||||
else if(player.client.prefs.active_character.alternate_option == RETURN_TO_LOBBY)
|
||||
player.ready = 0
|
||||
unassigned -= player
|
||||
|
||||
@@ -564,11 +564,11 @@ SUBSYSTEM_DEF(jobs)
|
||||
if(job.barred_by_disability(player.client))
|
||||
disabled++
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
|
||||
if(player.client.prefs.active_character.GetJobDepartment(job, 1) & job.flag)
|
||||
high++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
|
||||
else if(player.client.prefs.active_character.GetJobDepartment(job, 2) & job.flag)
|
||||
medium++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag)
|
||||
else if(player.client.prefs.active_character.GetJobDepartment(job, 3) & job.flag)
|
||||
low++
|
||||
else never++ //not selected
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/list/teleportlocs
|
||||
/// List of all areas that can be accessed via IC and OOC means
|
||||
var/list/ghostteleportlocs
|
||||
///List of areas that exist on the station this shift
|
||||
var/list/existing_station_areas
|
||||
|
||||
// This has to be here because world/New() uses [station_name()], which looks this datum up
|
||||
/datum/controller/subsystem/mapping/PreInit()
|
||||
@@ -89,6 +91,13 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
ghostteleportlocs = sortAssoc(ghostteleportlocs)
|
||||
|
||||
// Now we make a list of areas that exist on the station. Good for if you don't want to select areas that exist for one station but not others. Directly references
|
||||
existing_station_areas = list()
|
||||
for(var/area/AR in world)
|
||||
var/turf/picked = safepick(get_area_turfs(AR.type))
|
||||
if(picked && is_station_level(picked.z))
|
||||
existing_station_areas += AR
|
||||
|
||||
// World name
|
||||
if(GLOB.configuration.general.server_name)
|
||||
world.name = "[GLOB.configuration.general.server_name]: [station_name()]"
|
||||
|
||||
@@ -23,11 +23,12 @@ SUBSYSTEM_DEF(metrics)
|
||||
var/list/out = list()
|
||||
out["@timestamp"] = time_stamp() // This is required by ElasticSearch, complete with this name. DO NOT REMOVE THIS.
|
||||
out["cpu"] = world.cpu
|
||||
// out["maptick"] = world.map_cpu // TODO: 514
|
||||
out["maptick"] = world.map_cpu
|
||||
out["elapsed_processed"] = world.time
|
||||
out["elapsed_real"] = (REALTIMEOFDAY - world_init_time)
|
||||
out["client_count"] = length(GLOB.clients)
|
||||
out["round_id"] = text2num(GLOB.round_id) // This is so we can filter the metrics by a single round ID
|
||||
out["server_id"] = GLOB.configuration.system.instance_id // And this is so we can filter by instance ID
|
||||
|
||||
// Funnel in all SS metrics
|
||||
var/list/ss_data = list()
|
||||
|
||||
@@ -18,10 +18,11 @@ SUBSYSTEM_DEF(statistics)
|
||||
return
|
||||
else
|
||||
var/datum/db_query/statquery = SSdbcore.NewQuery(
|
||||
"INSERT INTO legacy_population (playercount, admincount, time) VALUES (:playercount, :admincount, NOW())",
|
||||
"INSERT INTO legacy_population (playercount, admincount, time, server_id) VALUES (:playercount, :admincount, NOW(), :server_id)",
|
||||
list(
|
||||
"playercount" = length(GLOB.clients),
|
||||
"admincount" = length(GLOB.admins)
|
||||
"admincount" = length(GLOB.admins),
|
||||
"server_id" = GLOB.configuration.system.instance_id
|
||||
)
|
||||
)
|
||||
statquery.warn_execute()
|
||||
|
||||
@@ -287,7 +287,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
else
|
||||
log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - keeping standard job config")
|
||||
|
||||
SSnightshift.check_nightshift()
|
||||
SSnightshift.check_nightshift(TRUE)
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
RunUnitTests()
|
||||
@@ -408,12 +408,65 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(player.mind.assigned_role != player.mind.special_role)
|
||||
SSjobs.AssignRank(player, player.mind.assigned_role, FALSE)
|
||||
SSjobs.EquipRank(player, player.mind.assigned_role, FALSE)
|
||||
EquipCustomItems(player)
|
||||
equip_cuis(player)
|
||||
|
||||
if(captainless)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!isnewplayer(M))
|
||||
to_chat(M, "Captainship not forced on anyone.")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/equip_cuis(mob/living/carbon/human/H)
|
||||
if(!H.client)
|
||||
return // If they are spawning without a client (somehow), they *cant* have a CUI list
|
||||
for(var/datum/custom_user_item/cui in H.client.cui_entries)
|
||||
// Skip items with invalid character names
|
||||
if((cui.characer_name != H.real_name) && !cui.all_characters_allowed)
|
||||
continue
|
||||
|
||||
var/ok = FALSE
|
||||
|
||||
if(!cui.all_jobs_allowed)
|
||||
var/alt_blocked = FALSE
|
||||
if(H.mind.role_alt_title)
|
||||
if(!(H.mind.role_alt_title in cui.allowed_jobs))
|
||||
alt_blocked = TRUE
|
||||
if(!(H.mind.assigned_role in cui.allowed_jobs) || alt_blocked)
|
||||
continue
|
||||
|
||||
var/obj/item/I = new cui.object_typepath()
|
||||
var/name_override = cui.item_name_override
|
||||
var/desc_override = cui.item_desc_override
|
||||
|
||||
if(name_override)
|
||||
I.name = name_override
|
||||
if(desc_override)
|
||||
I.desc = desc_override
|
||||
|
||||
if(istype(H.back, /obj/item/storage)) // Try to place it in something on the mob's back
|
||||
var/obj/item/storage/S = H.back
|
||||
if(length(S.contents) < S.storage_slots)
|
||||
I.forceMove(H.back)
|
||||
ok = TRUE
|
||||
to_chat(H, "<span class='notice'>Your [I.name] has been added to your [H.back.name].</span>")
|
||||
|
||||
if(!ok)
|
||||
for(var/obj/item/storage/S in H.contents) // Try to place it in any item that can store stuff, on the mob.
|
||||
if(length(S.contents) < S.storage_slots)
|
||||
I.forceMove(S)
|
||||
ok = TRUE
|
||||
to_chat(H, "<span class='notice'>Your [I.name] has been added to your [S.name].</span>")
|
||||
break
|
||||
|
||||
if(!ok) // Finally, since everything else failed, place it on the ground
|
||||
var/turf/T = get_turf(H)
|
||||
if(T)
|
||||
I.forceMove(T)
|
||||
to_chat(H, "<span class='notice'>Your [I.name] is on the [T.name] below you.</span>")
|
||||
else
|
||||
to_chat(H, "<span class='notice'>Your [I.name] couldnt spawn anywhere on you or even on the floor below you. Please file a bug report.</span>")
|
||||
qdel(I)
|
||||
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
|
||||
var/m
|
||||
if(selected_tip)
|
||||
|
||||
@@ -209,7 +209,7 @@ SUBSYSTEM_DEF(vote)
|
||||
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, code_invoked = FALSE)
|
||||
if(!mode)
|
||||
if(started_time != null && !check_rights(R_ADMIN))
|
||||
if(usr && started_time != null && !check_rights(R_ADMIN)) // Allow the game to call votes whenever. But check other callers
|
||||
var/next_allowed_time = (started_time + GLOB.configuration.vote.vote_delay)
|
||||
if(next_allowed_time > world.time)
|
||||
return 0
|
||||
@@ -266,8 +266,12 @@ SUBSYSTEM_DEF(vote)
|
||||
<a href='?src=[UID()];vote=open'>Click here or type vote to place your vote.</a>
|
||||
You have [GLOB.configuration.vote.vote_time / 10] seconds to vote.</font>"})
|
||||
switch(vote_type)
|
||||
if("crew transfer", "gamemode", "custom", "map")
|
||||
if("crew transfer", "gamemode", "custom")
|
||||
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
|
||||
if("map")
|
||||
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
M.throw_alert("Map Vote", /obj/screen/alert/notify_mapvote, timeout_override = GLOB.configuration.vote.vote_time)
|
||||
if(mode == "gamemode" && SSticker.ticker_going)
|
||||
SSticker.ticker_going = FALSE
|
||||
to_chat(world, "<font color='red'><b>Round start has been delayed.</b></font>")
|
||||
|
||||
@@ -423,6 +423,13 @@
|
||||
/datum/action/item_action/remove_badge
|
||||
name = "Remove Holobadge"
|
||||
|
||||
|
||||
// Clown Acrobat Shoes
|
||||
/datum/action/item_action/slipping
|
||||
name = "Tactical Slip"
|
||||
desc = "Activates the clown shoes' ankle-stimulating module, allowing the user to do a short slip forward going under anyone."
|
||||
button_icon_state = "clown"
|
||||
|
||||
// Jump boots
|
||||
/datum/action/item_action/bhop
|
||||
name = "Activate Jump Boots"
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
return vars[rating]
|
||||
|
||||
/datum/armor/proc/getList()
|
||||
return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid, "magic" = magic)
|
||||
return list(MELEE = melee, BULLET = bullet, LASER = laser, ENERGY = energy, BOMB = bomb, BIO = bio, RAD = rad, FIRE = fire, ACID = acid, MAGIC = magic)
|
||||
|
||||
/datum/armor/proc/attachArmor(datum/armor/AA)
|
||||
return getArmor(melee + AA.melee, bullet + AA.bullet, laser + AA.laser, energy + AA.energy, bomb + AA.bomb, bio + AA.bio, rad + AA.rad, fire + AA.fire, acid + AA.acid, magic + AA.magic)
|
||||
|
||||
Vendored
+1
-1
@@ -57,7 +57,7 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new())
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_TRACKING)
|
||||
var/area/A = get_area(H)
|
||||
crewmemberData["area"] = sanitize(A.name)
|
||||
crewmemberData["area"] = sanitize_simple(A.name)
|
||||
crewmemberData["x"] = pos.x
|
||||
crewmemberData["y"] = pos.y
|
||||
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
var/mat_path = possible_mats[id]
|
||||
materials[id] = new mat_path()
|
||||
|
||||
/datum/component/material_container/Destroy(force, silent)
|
||||
QDEL_LIST_ASSOC_VAL(materials)
|
||||
return ..()
|
||||
|
||||
/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list)
|
||||
if(show_on_examine)
|
||||
for(var/I in materials)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* # Custom User Item
|
||||
*
|
||||
* Holder for CUIs
|
||||
*
|
||||
* This datum is a holder that is essentially a "model" of the `customuseritems`
|
||||
* database table, and is used for giving people their CUIs on spawn.
|
||||
* It is instanced as part of the client data loading framework on the client.
|
||||
*
|
||||
*/
|
||||
/datum/custom_user_item
|
||||
/// Can this be used on all characters?
|
||||
var/all_characters_allowed = FALSE
|
||||
/// Name of the character that can have this item.
|
||||
var/characer_name
|
||||
/// Are all jobs allowed?
|
||||
var/all_jobs_allowed = FALSE
|
||||
/// List of allowed jobs
|
||||
var/list/allowed_jobs = list()
|
||||
/// Custom item typepath
|
||||
var/object_typepath
|
||||
/// Custom item name override
|
||||
var/item_name_override
|
||||
/// Custom item description override
|
||||
var/item_desc_override
|
||||
/// Raw job mask
|
||||
var/raw_job_mask
|
||||
|
||||
|
||||
/**
|
||||
* CUI Info Parser
|
||||
*
|
||||
* Parses all the raw info into usable stuff, and also does validity checks
|
||||
* Returns TRUE if its a valid item, and FALSE if not
|
||||
*
|
||||
* Arguments:
|
||||
* * owning_ckey - Player who owns this item. Used for logging purposes.
|
||||
*/
|
||||
/datum/custom_user_item/proc/parse_info(owning_ckey)
|
||||
. = FALSE // Setting this here means it will return false even if it runtimes
|
||||
|
||||
// Sort path
|
||||
if(!object_typepath || !ispath(object_typepath))
|
||||
stack_trace("Incorrect database entry found in table 'customuseritems' path value is [object_typepath ? object_typepath : "(NULL)"], which doesnt exist. Ask the host to look at CUI entries for [owning_ckey]")
|
||||
return
|
||||
|
||||
// Sort job mask
|
||||
if(raw_job_mask == "*")
|
||||
all_jobs_allowed = TRUE
|
||||
else
|
||||
var/list/local_allowed_jobs = splittext(raw_job_mask, ",")
|
||||
for(var/i in 1 to length(local_allowed_jobs))
|
||||
if(istext(local_allowed_jobs[i]))
|
||||
local_allowed_jobs[i] = trim(local_allowed_jobs[i])
|
||||
|
||||
allowed_jobs = local_allowed_jobs
|
||||
|
||||
// Sort character name
|
||||
if(characer_name == "*")
|
||||
all_characters_allowed = TRUE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/custom_user_item/vv_edit_var(var_name, var_value)
|
||||
return FALSE // fuck off
|
||||
@@ -461,10 +461,6 @@ GLOBAL_VAR_INIT(record_id_num, 1001)
|
||||
clothes_s = new /icon('icons/mob/clothing/uniform.dmi', "detective_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "brown"), ICON_UNDERLAY)
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "detective"), ICON_OVERLAY)
|
||||
if("Security Pod Pilot")
|
||||
clothes_s = new /icon('icons/mob/clothing/uniform.dmi', "secred_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "jackboots"), ICON_UNDERLAY)
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/suit.dmi', "bomber"), ICON_OVERLAY)
|
||||
if("Brig Physician")
|
||||
clothes_s = new /icon('icons/mob/clothing/uniform.dmi', "medical_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "white"), ICON_UNDERLAY)
|
||||
@@ -484,10 +480,6 @@ GLOBAL_VAR_INIT(record_id_num, 1001)
|
||||
clothes_s = new /icon('icons/mob/clothing/uniform.dmi', "atmos_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY)
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "utility"), ICON_OVERLAY)
|
||||
if("Mechanic")
|
||||
clothes_s = new /icon('icons/mob/clothing/uniform.dmi', "mechanic_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "orange"), ICON_UNDERLAY)
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/belt.dmi', "utility"), ICON_OVERLAY)
|
||||
if("Roboticist")
|
||||
clothes_s = new /icon('icons/mob/clothing/uniform.dmi', "robotics_s")
|
||||
clothes_s.Blend(new /icon('icons/mob/clothing/feet.dmi', "black"), ICON_UNDERLAY)
|
||||
|
||||
@@ -893,10 +893,10 @@
|
||||
if(!result || !A)
|
||||
return TRUE
|
||||
|
||||
A.armor = A.armor.setRating(armorlist["melee"], armorlist["bullet"], armorlist["laser"], armorlist["energy"], armorlist["bomb"], armorlist["bio"], armorlist["rad"], armorlist["fire"], armorlist["acid"], armorlist["magic"])
|
||||
A.armor = A.armor.setRating(armorlist[MELEE], armorlist[BULLET], armorlist[LASER], armorlist[ENERGY], armorlist[BOMB], armorlist[BIO], armorlist[RAD], armorlist[FIRE], armorlist[ACID], armorlist[MAGIC])
|
||||
|
||||
log_admin("[key_name(usr)] modified the armor on [A] to: melee = [armorlist["melee"]], bullet = [armorlist["bullet"]], laser = [armorlist["laser"]], energy = [armorlist["energy"]], bomb = [armorlist["bomb"]], bio = [armorlist["bio"]], rad = [armorlist["rad"]], fire = [armorlist["fire"]], acid = [armorlist["acid"]], magic = [armorlist["magic"]]")
|
||||
message_admins("<span class='notice'>[key_name(usr)] modified the armor on [A] to: melee = [armorlist["melee"]], bullet = [armorlist["bullet"]], laser = [armorlist["laser"]], energy = [armorlist["energy"]], bomb = [armorlist["bomb"]], bio = [armorlist["bio"]], rad = [armorlist["rad"]], fire = [armorlist["fire"]], acid = [armorlist["acid"]], magic = [armorlist["magic"]]")
|
||||
log_admin("[key_name(usr)] modified the armor on [A] to: melee = [armorlist[MELEE]], bullet = [armorlist[BULLET]], laser = [armorlist[LASER]], energy = [armorlist[ENERGY]], bomb = [armorlist[BOMB]], bio = [armorlist[BIO]], rad = [armorlist[RAD]], fire = [armorlist[FIRE]], acid = [armorlist[ACID]], magic = [armorlist[MAGIC]]")
|
||||
message_admins("<span class='notice'>[key_name(usr)] modified the armor on [A] to: melee = [armorlist[MELEE]], bullet = [armorlist[BULLET]], laser = [armorlist[LASER]], energy = [armorlist[ENERGY]], bomb = [armorlist[BOMB]], bio = [armorlist[BIO]], rad = [armorlist[RAD]], fire = [armorlist[FIRE]], acid = [armorlist[ACID]], magic = [armorlist[MAGIC]]")
|
||||
return TRUE
|
||||
|
||||
else if(href_list["addreagent"]) /* Made on /TG/, credit to them. */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/list/stage5 = list("Oh the humanity!")
|
||||
var/transformation_text = null
|
||||
var/new_form = /mob/living/carbon/human
|
||||
var/job_role = null
|
||||
|
||||
/datum/disease/transformation/stage_act()
|
||||
..()
|
||||
@@ -40,8 +41,8 @@
|
||||
if(istype(affected_mob, /mob/living/carbon) && affected_mob.stat != DEAD)
|
||||
if(stage5)
|
||||
to_chat(affected_mob, pick(stage5))
|
||||
if(jobban_isbanned(affected_mob, new_form))
|
||||
affected_mob.death(1)
|
||||
if(jobban_isbanned(affected_mob, job_role))
|
||||
affected_mob.death()
|
||||
return
|
||||
if(affected_mob.notransform)
|
||||
return
|
||||
@@ -133,6 +134,7 @@
|
||||
stage4 = list("<span class='danger'>Your skin feels very loose.</span>", "<span class='danger'>You can feel... something...inside you.</span>")
|
||||
stage5 = list("<span class='danger'>Your skin feels as if it's about to burst off!</span>")
|
||||
new_form = /mob/living/silicon/robot
|
||||
job_role = "Cyborg"
|
||||
|
||||
|
||||
/datum/disease/transformation/robot/stage_act()
|
||||
@@ -165,6 +167,7 @@
|
||||
stage4 = list("<span class='danger'>Your skin feels very tight.</span>", "<span class='danger'>Your blood boils!</span>", "<span class='danger'>You can feel... something...inside you.</span>")
|
||||
stage5 = list("<span class='danger'>Your skin feels as if it's about to burst off!</span>")
|
||||
new_form = /mob/living/carbon/alien/humanoid/hunter
|
||||
job_role = ROLE_ALIEN
|
||||
|
||||
/datum/disease/transformation/xeno/stage_act()
|
||||
..()
|
||||
@@ -248,3 +251,4 @@
|
||||
stage5 = list("<span class='danger'>You have become a morph.</span>")
|
||||
transformation_text = "<span class='userdanger'>This transformation does NOT make you an antagonist if you were not one already. If you were not an antagonist, you should not eat any steal objectives or the contents of the armory.</span>"
|
||||
new_form = /mob/living/simple_animal/hostile/morph
|
||||
job_role = ROLE_MORPH
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
var/list/steps
|
||||
var/atom/holder
|
||||
var/result
|
||||
var/index
|
||||
var/list/steps_desc
|
||||
var/taskpath = null // Path of job objective completed.
|
||||
|
||||
@@ -128,7 +129,6 @@
|
||||
return TRUE
|
||||
|
||||
/datum/construction/reversible
|
||||
var/index
|
||||
|
||||
/datum/construction/reversible/New(atom)
|
||||
..()
|
||||
@@ -168,7 +168,6 @@
|
||||
#define state_prev "prev"
|
||||
|
||||
/datum/construction/reversible2
|
||||
var/index
|
||||
var/base_icon = "durand"
|
||||
|
||||
/datum/construction/reversible2/New(atom)
|
||||
|
||||
+16
-3
@@ -19,6 +19,8 @@
|
||||
var/headers
|
||||
/// URL that the request is being sent to
|
||||
var/url
|
||||
/// If present, response body will be saved to this file.
|
||||
var/output_file
|
||||
/// The raw response, which will be decoeded into a [/datum/http_response]
|
||||
var/_raw_response
|
||||
/// Callback for executing after async requests. Will be called with an argument of [/datum/http_response] as first argument
|
||||
@@ -42,7 +44,7 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
|
||||
* * _body - The body of the request, if applicable
|
||||
* * _headers - Associative list of HTTP headers to send, if applicab;e
|
||||
*/
|
||||
/datum/http_request/proc/prepare(_method, _url, _body = "", list/_headers)
|
||||
/datum/http_request/proc/prepare(_method, _url, _body = "", list/_headers, _output_file)
|
||||
if(!length(_headers))
|
||||
headers = ""
|
||||
else
|
||||
@@ -51,6 +53,7 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
|
||||
method = _method
|
||||
url = _url
|
||||
body = _body
|
||||
output_file = _output_file
|
||||
|
||||
/**
|
||||
* Blocking executor
|
||||
@@ -60,7 +63,7 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
|
||||
*/
|
||||
/datum/http_request/proc/execute_blocking()
|
||||
CRASH("Attempted to execute a blocking HTTP request")
|
||||
// _raw_response = rustg_http_request_blocking(method, url, body, headers)
|
||||
// _raw_response = rustg_http_request_blocking(method, url, body, headers, build_options())
|
||||
|
||||
/**
|
||||
* Async execution starter
|
||||
@@ -73,7 +76,7 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
|
||||
if(in_progress)
|
||||
CRASH("Attempted to re-use a request object.")
|
||||
|
||||
id = rustg_http_request_async(method, url, body, headers)
|
||||
id = rustg_http_request_async(method, url, body, headers, build_options())
|
||||
|
||||
if(isnull(text2num(id)))
|
||||
_raw_response = "Proc error: [id]"
|
||||
@@ -81,6 +84,16 @@ THE METHODS IN THIS FILE ARE TO BE USED BY THE SUBSYSTEM AS A MANGEMENT HUB
|
||||
else
|
||||
in_progress = TRUE
|
||||
|
||||
/**
|
||||
* Options builder
|
||||
*
|
||||
* Builds options for if we want to download files with SShttp
|
||||
*/
|
||||
/datum/http_request/proc/build_options()
|
||||
if(output_file)
|
||||
return json_encode(list("output_filename" = output_file, "body_filename" = null))
|
||||
return null
|
||||
|
||||
/**
|
||||
* Async completion checker
|
||||
*
|
||||
|
||||
+22
-22
@@ -2,28 +2,28 @@
|
||||
GLOBAL_LIST_EMPTY(all_huds)
|
||||
|
||||
///GLOBAL HUD LIST
|
||||
GLOBAL_LIST_INIT(huds, list( \
|
||||
DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(), \
|
||||
DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), \
|
||||
DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), \
|
||||
DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), \
|
||||
DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(), \
|
||||
DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), \
|
||||
DATA_HUD_HYDROPONIC = new/datum/atom_hud/data/hydroponic(), \
|
||||
ANTAG_HUD_CULT = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_REV = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_OPS = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), \
|
||||
ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_VAMPIRE = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),\
|
||||
DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(),\
|
||||
ANTAG_HUD_EVENTMISC = new/datum/atom_hud/antag/hidden(),\
|
||||
ANTAG_HUD_BLOB = new/datum/atom_hud/antag/hidden()\
|
||||
))
|
||||
GLOBAL_LIST_INIT(huds, list(
|
||||
DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(),
|
||||
DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(),
|
||||
DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(),
|
||||
DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(),
|
||||
DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(),
|
||||
DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(),
|
||||
DATA_HUD_HYDROPONIC = new/datum/atom_hud/data/hydroponic(),
|
||||
ANTAG_HUD_CULT = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_REV = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_OPS = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_WIZ = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(),
|
||||
ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_VAMPIRE = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),
|
||||
DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(),
|
||||
ANTAG_HUD_EVENTMISC = new/datum/atom_hud/antag/hidden(),
|
||||
ANTAG_HUD_BLOB = new/datum/atom_hud/antag/hidden()
|
||||
))
|
||||
|
||||
/datum/atom_hud
|
||||
var/list/atom/hudatoms = list() //list of all atoms which display this hud
|
||||
|
||||
@@ -85,6 +85,10 @@
|
||||
original = null
|
||||
return ..()
|
||||
|
||||
/datum/mind/proc/get_display_key()
|
||||
var/clientKey = current?.client?.get_display_key()
|
||||
return clientKey ? clientKey : key
|
||||
|
||||
/datum/mind/proc/transfer_to(mob/living/new_character)
|
||||
var/datum/atom_hud/antag/hud_to_transfer = antag_hud //we need this because leave_hud() will clear this list
|
||||
var/mob/living/old_current = current
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
EXCEPTION("Invalid target given")
|
||||
if(goal_number)
|
||||
goal = goal_number
|
||||
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0", HUD_LAYER)
|
||||
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0", ABOVE_HUD_LAYER)
|
||||
bar.alpha = 0
|
||||
bar.plane = HUD_PLANE
|
||||
bar.plane = ABOVE_HUD_PLANE
|
||||
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
user = User
|
||||
if(user)
|
||||
|
||||
@@ -55,12 +55,17 @@
|
||||
sleep(jaunt_in_time)
|
||||
qdel(holder)
|
||||
if(!QDELETED(target))
|
||||
if(mobloc.density)
|
||||
if(!(target.Move(mobloc)))
|
||||
for(var/turf/T in orange(7))
|
||||
if(T)
|
||||
if(target.Move(T))
|
||||
break
|
||||
target.canmove = 1
|
||||
if(isspaceturf(T))
|
||||
continue
|
||||
if(T && target.Move(T))
|
||||
target.canmove = TRUE
|
||||
return
|
||||
for(var/turf/space/S in orange(7)) //loop for space turfs in case there were no normal ones last loop
|
||||
if(S && target.Move(S))
|
||||
break
|
||||
target.canmove = TRUE //if there are no valid tiles in a range of 7, just let them spawn wherever they are currently
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/jaunt_steam(mobloc)
|
||||
var/datum/effect_system/steam_spread/steam = new /datum/effect_system/steam_spread()
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead
|
||||
magichead.flags |= NODROP | DROPDEL //curses!
|
||||
magichead.flags_inv = null //so you can still see their face
|
||||
magichead.voicechange = 1 //NEEEEIIGHH
|
||||
magichead.voicechange = TRUE //NEEEEIIGHH
|
||||
target.visible_message( "<span class='danger'>[target]'s face lights up in fire, and after the event a horse's head takes its place!</span>", \
|
||||
"<span class='danger'>Your face burns up, and shortly after the fire you realise you have the face of a horse!</span>")
|
||||
if(!target.unEquip(target.wear_mask))
|
||||
|
||||
@@ -96,10 +96,10 @@
|
||||
invocation_type = "none"
|
||||
action_icon_state = "vampire_bats"
|
||||
|
||||
shapeshift_type = /mob/living/simple_animal/hostile/scarybat/batswarm
|
||||
current_shapes = list(/mob/living/simple_animal/hostile/scarybat/batswarm)
|
||||
shapeshift_type = /mob/living/simple_animal/hostile/scarybat/adminvampire
|
||||
current_shapes = list(/mob/living/simple_animal/hostile/scarybat/adminvampire)
|
||||
current_casters = list()
|
||||
possible_shapes = list(/mob/living/simple_animal/hostile/scarybat/batswarm)
|
||||
possible_shapes = list(/mob/living/simple_animal/hostile/scarybat/adminvampire)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/shapeshift/hellhound
|
||||
name = "Lesser Hellhound Form"
|
||||
|
||||
@@ -1,5 +1,58 @@
|
||||
//Largely beneficial effects go here, even if they have drawbacks. An example is provided in Shadow Mend.
|
||||
|
||||
/datum/status_effect/his_grace
|
||||
id = "his_grace"
|
||||
duration = -1
|
||||
tick_interval = 4
|
||||
alert_type = /obj/screen/alert/status_effect/his_grace
|
||||
var/bloodlust = 0
|
||||
|
||||
/obj/screen/alert/status_effect/his_grace
|
||||
name = "His Grace"
|
||||
desc = "His Grace hungers, and you must feed Him."
|
||||
icon_state = "his_grace"
|
||||
alerttooltipstyle = "hisgrace"
|
||||
|
||||
/obj/screen/alert/status_effect/his_grace/MouseEntered(location, control, params)
|
||||
desc = initial(desc)
|
||||
var/datum/status_effect/his_grace/HG = attached_effect
|
||||
desc += "<br><font size=3><b>Current Bloodthirst: [HG.bloodlust]</b></font>\
|
||||
<br>Becomes undroppable at <b>[HIS_GRACE_FAMISHED]</b>\
|
||||
<br>Will consume you at <b>[HIS_GRACE_CONSUME_OWNER]</b>"
|
||||
..()
|
||||
|
||||
/datum/status_effect/his_grace/on_apply()
|
||||
add_attack_logs(owner, owner, "gained His Grace's stun immunity", ATKLOG_ALL)
|
||||
owner.add_stun_absorption("hisgrace", INFINITY, 3, null, "His Grace protects you from the stun!")
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/his_grace/tick()
|
||||
bloodlust = 0
|
||||
var/graces = 0
|
||||
var/list/held_items = list()
|
||||
held_items += owner.l_hand
|
||||
held_items += owner.r_hand
|
||||
for(var/obj/item/his_grace/HG in held_items)
|
||||
if(HG.bloodthirst > bloodlust)
|
||||
bloodlust = HG.bloodthirst
|
||||
if(HG.awakened)
|
||||
graces++
|
||||
if(!graces)
|
||||
owner.apply_status_effect(STATUS_EFFECT_HISWRATH)
|
||||
qdel(src)
|
||||
return
|
||||
var/grace_heal = bloodlust * 0.05
|
||||
owner.adjustBruteLoss(-grace_heal)
|
||||
owner.adjustFireLoss(-grace_heal)
|
||||
owner.adjustToxLoss(-grace_heal)
|
||||
owner.adjustOxyLoss(-(grace_heal * 2))
|
||||
owner.adjustCloneLoss(-grace_heal)
|
||||
|
||||
/datum/status_effect/his_grace/on_remove()
|
||||
add_attack_logs(owner, owner, "lost His Grace's stun immunity", ATKLOG_ALL)
|
||||
if(islist(owner.stun_absorption) && owner.stun_absorption["hisgrace"])
|
||||
owner.stun_absorption -= "hisgrace"
|
||||
|
||||
/datum/status_effect/shadow_mend
|
||||
id = "shadow_mend"
|
||||
duration = 30
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
//OTHER DEBUFFS
|
||||
|
||||
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
|
||||
id = "his_wrath"
|
||||
duration = -1
|
||||
tick_interval = 4
|
||||
alert_type = /obj/screen/alert/status_effect/his_wrath
|
||||
|
||||
/obj/screen/alert/status_effect/his_wrath
|
||||
name = "His Wrath"
|
||||
desc = "You fled from His Grace instead of feeding Him, and now you suffer."
|
||||
icon_state = "his_grace"
|
||||
alerttooltipstyle = "hisgrace"
|
||||
|
||||
/datum/status_effect/his_wrath/tick()
|
||||
var/list/held_items = list()
|
||||
held_items += owner.l_hand
|
||||
held_items += owner.r_hand
|
||||
for(var/obj/item/his_grace/HG in held_items)
|
||||
qdel(src)
|
||||
return
|
||||
owner.adjustBruteLoss(0.1)
|
||||
owner.adjustFireLoss(0.1)
|
||||
owner.adjustToxLoss(0.2)
|
||||
|
||||
/datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
|
||||
id = "cult_ghost"
|
||||
duration = -1
|
||||
|
||||
+50
-30
@@ -193,14 +193,6 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
containername = "special ops crate"
|
||||
hidden = 1
|
||||
|
||||
/datum/supply_packs/emergency/syndicate
|
||||
name = "ERROR_NULL_ENTRY"
|
||||
contains = list(/obj/item/storage/box/syndicate)
|
||||
cost = 140
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "crate"
|
||||
hidden = 1
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Security ////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -228,6 +220,13 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
contains = list(/obj/item/vending_refill/security)
|
||||
containername = "SecTech supply crate"
|
||||
|
||||
/datum/supply_packs/security/vending/clothingvendor
|
||||
name = "Security Clothing Vendors Crate"
|
||||
cost = 40
|
||||
contains = list(/obj/item/vending_refill/secdrobe,
|
||||
/obj/item/vending_refill/detdrobe)
|
||||
containername = "security clothing vendor crate"
|
||||
|
||||
////// Armor: Basic
|
||||
|
||||
/datum/supply_packs/security/helmets
|
||||
@@ -405,28 +404,6 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
cost = 80
|
||||
containername = "combat shotgun crate"
|
||||
|
||||
/datum/supply_packs/security/armory/buckshotammo
|
||||
name = "Buckshot Ammo Crate"
|
||||
contains = list(/obj/item/ammo_box/shotgun/buck,
|
||||
/obj/item/storage/box/buck,
|
||||
/obj/item/storage/box/buck,
|
||||
/obj/item/storage/box/buck,
|
||||
/obj/item/storage/box/buck,
|
||||
/obj/item/storage/box/buck)
|
||||
cost = 45
|
||||
containername = "buckshot ammo crate"
|
||||
|
||||
/datum/supply_packs/security/armory/slugammo
|
||||
name = "Slug Ammo Crate"
|
||||
contains = list(/obj/item/ammo_box/shotgun,
|
||||
/obj/item/storage/box/slug,
|
||||
/obj/item/storage/box/slug,
|
||||
/obj/item/storage/box/slug,
|
||||
/obj/item/storage/box/slug,
|
||||
/obj/item/storage/box/slug)
|
||||
cost = 45
|
||||
containername = "slug ammo crate"
|
||||
|
||||
/datum/supply_packs/security/armory/expenergy
|
||||
name = "Energy Guns Crate"
|
||||
contains = list(/obj/item/gun/energy/gun,
|
||||
@@ -578,6 +555,13 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
/obj/item/vending_refill/youtool)
|
||||
containername = "engineering supply crate"
|
||||
|
||||
/datum/supply_packs/engineering/vending/clothingvendor
|
||||
name = "Engineering Clothing Vendors Crate"
|
||||
cost = 20
|
||||
contains = list(/obj/item/vending_refill/engidrobe,
|
||||
/obj/item/vending_refill/atmosdrobe)
|
||||
containername = "engineering clothing vendor crate"
|
||||
|
||||
/datum/supply_packs/engineering/powergamermitts
|
||||
name = "Insulated Gloves Crate"
|
||||
contains = list(/obj/item/clothing/gloves/color/yellow,
|
||||
@@ -896,6 +880,14 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
/obj/item/vending_refill/wallmed)
|
||||
containername = "medical vending crate"
|
||||
|
||||
/datum/supply_packs/medical/vending/clothingvendor
|
||||
name = "Medical Clothing Vendors Crate"
|
||||
cost = 20
|
||||
contains = list(/obj/item/vending_refill/medidrobe,
|
||||
/obj/item/vending_refill/chemdrobe,
|
||||
/obj/item/vending_refill/virodrobe)
|
||||
containername = "medical clothing vendors crate"
|
||||
|
||||
/datum/supply_packs/medical/bloodpacks
|
||||
name = "Blood Pack Variety Crate"
|
||||
contains = list(/obj/item/reagent_containers/iv_bag,
|
||||
@@ -1043,6 +1035,14 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
containertype = /obj/structure/largecrate
|
||||
containername = "oil tank crate"
|
||||
|
||||
/datum/supply_packs/science/vending/clothingvendor
|
||||
name = "Science Clothing Vendors Crate"
|
||||
cost = 20
|
||||
contains = list(/obj/item/vending_refill/scidrobe,
|
||||
/obj/item/vending_refill/robodrobe,
|
||||
/obj/item/vending_refill/genedrobe,)
|
||||
containername = "science clothing vendor crate"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Organic /////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1462,6 +1462,12 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "shaft miner starter kit"
|
||||
|
||||
/datum/supply_packs/misc/carpet
|
||||
name = "Carpet Crate"
|
||||
cost = 20
|
||||
contains = list(/obj/item/stack/tile/carpet/twenty)
|
||||
containername = "carpet crate"
|
||||
|
||||
|
||||
///////////// Paper Work
|
||||
|
||||
@@ -1820,6 +1826,20 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
cost = 15
|
||||
containername = "boxing supply crate"
|
||||
|
||||
/datum/supply_packs/misc/vending/clothingvendor
|
||||
name = "Service Clothing Vendors Crate"
|
||||
cost = 20
|
||||
contains = list(/obj/item/vending_refill/bardrobe,
|
||||
/obj/item/vending_refill/chefdrobe,
|
||||
/obj/item/vending_refill/hydrodrobe)
|
||||
containername = "service clothing vendor crate"
|
||||
|
||||
/datum/supply_packs/misc/vending/clothingvendor/cargo
|
||||
name = "Cargo Clothing Vendors Crate"
|
||||
cost = 20
|
||||
contains = list(/obj/item/vending_refill/cargodrobe)
|
||||
containername = "cargo clothing vendor crate"
|
||||
|
||||
///////////// Station Goals
|
||||
|
||||
/datum/supply_packs/misc/station_goal
|
||||
|
||||
+24
-11
@@ -167,18 +167,19 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
//Clown
|
||||
/datum/uplink_item/jobspecific/clowngrenade
|
||||
name = "Banana Grenade"
|
||||
desc = "A grenade that explodes into HONK! brand banana peels that are genetically modified to be extra slippery and extrude caustic acid when stepped on"
|
||||
desc = "A grenade that explodes into HONK! brand banana peels that are genetically modified to be extra slippery and extrude caustic acid when stepped on."
|
||||
reference = "BG"
|
||||
item = /obj/item/grenade/clown_grenade
|
||||
cost = 5
|
||||
job = list("Clown")
|
||||
|
||||
/datum/uplink_item/jobspecific/clownmagboots
|
||||
name = "Clown Magboots"
|
||||
desc = "A pair of modified clown shoes fitted with an advanced magnetic traction system. Look and sound exactly like regular clown shoes unless closely inspected."
|
||||
reference = "CM"
|
||||
item = /obj/item/clothing/shoes/magboots/clown
|
||||
/datum/uplink_item/jobspecific/clownslippers
|
||||
name = "Clown Acrobatic Shoes"
|
||||
desc = "A pair of modified clown shoes fitted with a built-in propulsion system that allows the user to perform a short slip below anyone. Turning on the waddle dampeners removes the slowdown on the shoes."
|
||||
reference = "CAS"
|
||||
item = /obj/item/clothing/shoes/clown_shoes/slippers
|
||||
cost = 3
|
||||
surplus = 75
|
||||
job = list("Clown")
|
||||
|
||||
/datum/uplink_item/jobspecific/trick_revolver
|
||||
@@ -257,10 +258,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
job = list("Chaplain")
|
||||
|
||||
/datum/uplink_item/jobspecific/artistic_toolbox
|
||||
name = "Artistic Toolbox"
|
||||
desc = "An accursed toolbox that grants its followers extreme power at the cost of requiring repeated sacrifices to it. If sacrifices are not provided, it will turn on its follower."
|
||||
reference = "HGAT"
|
||||
item = /obj/item/storage/toolbox/green/memetic
|
||||
name = "His Grace"
|
||||
desc = "An incredibly dangerous weapon recovered from a station overcome by the grey tide. Once activated, He will thirst for blood and must be used to kill to sate that thirst. \
|
||||
His Grace grants gradual regeneration and complete stun immunity to His wielder, but be wary: if He gets too hungry, He will become impossible to drop and eventually kill you if not fed. \
|
||||
However, if left alone for long enough, He will fall back to slumber. \
|
||||
To activate His Grace, simply unlatch Him."
|
||||
reference = "HG"
|
||||
item = /obj/item/his_grace
|
||||
cost = 20
|
||||
job = list("Chaplain")
|
||||
surplus = 0 //No lucky chances from the crate; if you get this, this is ALL you're getting
|
||||
@@ -1171,6 +1175,15 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 4
|
||||
excludefrom = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/voice_modulator
|
||||
name = "Chameleon Voice Modulator Mask"
|
||||
desc = "A syndicate tactical mask equipped with chameleon technology and a sound modulator for disguising your voice. \
|
||||
While the mask is active, your voice will sound unrecognizable to others"
|
||||
reference = "CVMM"
|
||||
item = /obj/item/clothing/mask/gas/voice_modulator/chameleon
|
||||
cost = 1
|
||||
excludefrom = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/chameleon/nuke
|
||||
reference = "NCHAM"
|
||||
cost = 6
|
||||
@@ -1524,7 +1537,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/implants/freedom
|
||||
name = "Freedom Implant"
|
||||
desc = "An implant injected into the body and later activated manually to break out of any restraints. Can be activated up to 4 times."
|
||||
desc = "An implant injected into the body and later activated manually to break out of any restraints or grabs. Can be activated up to 4 times."
|
||||
reference = "FI"
|
||||
item = /obj/item/implanter/freedom
|
||||
cost = 5
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
|
||||
/datum/weather/rad_storm/weather_act(mob/living/L)
|
||||
var/resist = L.getarmor(null, "rad")
|
||||
var/resist = L.getarmor(null, RAD)
|
||||
if(prob(40))
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
|
||||
@@ -44,12 +44,13 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event
|
||||
title = "Security Announcement"
|
||||
announcement_type = "Security Announcement"
|
||||
|
||||
/datum/announcement/proc/Announce(message as text, new_title = "", new_sound = null, do_newscast = newscast, msg_sanitized = 0, from, msg_language)
|
||||
/datum/announcement/proc/Announce(message as text, new_title = "", new_sound = null, do_newscast = newscast, msg_sanitized = 0, from, msg_language, new_sound2 = null)
|
||||
if(!message)
|
||||
return
|
||||
|
||||
var/message_title = new_title ? new_title : title
|
||||
var/message_sound = new_sound ? sound(new_sound) : sound
|
||||
var/message_sound2 = new_sound2 ? sound(new_sound2) : sound
|
||||
|
||||
if(!msg_sanitized)
|
||||
message = trim_strip_html_properly(message, allow_lines = 1)
|
||||
@@ -74,6 +75,7 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event
|
||||
NewsCast(message, message_title)
|
||||
|
||||
Sound(message_sound, combined_receivers[1] + combined_receivers[2])
|
||||
Sound(message_sound2, combined_receivers[1] + combined_receivers[2])
|
||||
Log(message, message_title)
|
||||
|
||||
/datum/announcement/proc/Get_Receivers(datum/language/message_language)
|
||||
|
||||
@@ -147,13 +147,6 @@
|
||||
detected_mech = TRUE
|
||||
increase_alert("Hostile mecha detected: [E]")
|
||||
|
||||
/area/syndicate_depot/core/proc/saw_pod(obj/spacepod/P)
|
||||
if(detected_pod)
|
||||
return
|
||||
detected_pod = TRUE
|
||||
if(!called_backup)
|
||||
increase_alert("Hostile spacepod detected: [P]")
|
||||
|
||||
/area/syndicate_depot/core/proc/saw_double_agent(mob/living/M)
|
||||
if(detected_double_agent)
|
||||
return
|
||||
|
||||
@@ -1112,14 +1112,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "\improper Chief Engineer's office"
|
||||
icon_state = "engine_control"
|
||||
|
||||
/area/engine/mechanic_workshop
|
||||
name = "\improper Mechanic Workshop"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/engine/mechanic_workshop/hanger
|
||||
name = "\improper Hanger Bay"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/engine/supermatter
|
||||
name = "\improper Supermatter Engine"
|
||||
icon_state = "engine"
|
||||
@@ -1488,10 +1480,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "\improper Head of Security's Office"
|
||||
icon_state = "sec_hos"
|
||||
|
||||
/area/security/podbay
|
||||
name = "\improper Security Podbay"
|
||||
icon_state = "securitypodbay"
|
||||
|
||||
/area/security/detectives_office
|
||||
name = "\improper Detective's Office"
|
||||
icon_state = "detective"
|
||||
@@ -1544,7 +1532,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/security/vacantoffice2
|
||||
name = "\improper Vacant Office"
|
||||
icon_state = "security"
|
||||
|
||||
|
||||
/area/security/permasolitary
|
||||
name = "Solitary Confinement"
|
||||
icon_state = "solitary"
|
||||
|
||||
+37
-40
@@ -657,9 +657,6 @@
|
||||
|
||||
GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
|
||||
/atom/proc/blood_splatter_index()
|
||||
return "\ref[initial(icon)]-[initial(icon_state)]"
|
||||
|
||||
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
|
||||
/mob/living/proc/get_blood_dna_list()
|
||||
if(get_blood_id() != "blood")
|
||||
@@ -726,56 +723,52 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
return add_blood(blood_dna, bloodcolor)
|
||||
|
||||
//to add blood onto something, with blood dna info to include.
|
||||
/atom/proc/add_blood(list/blood_dna, color)
|
||||
/atom/proc/add_blood(list/blood_dna, b_color)
|
||||
return FALSE
|
||||
|
||||
/obj/add_blood(list/blood_dna, color)
|
||||
/obj/add_blood(list/blood_dna, b_color)
|
||||
return transfer_blood_dna(blood_dna)
|
||||
|
||||
/obj/item/add_blood(list/blood_dna, color)
|
||||
var/blood_count = !blood_DNA ? 0 : blood_DNA.len
|
||||
/obj/item/add_blood(list/blood_dna, b_color)
|
||||
var/blood_count = !blood_DNA ? 0 : length(blood_DNA)
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(!blood_count)//apply the blood-splatter overlay if it isn't already in there
|
||||
add_blood_overlay(color)
|
||||
blood_color = b_color // update the blood color
|
||||
if(!blood_count) //apply the blood-splatter overlay if it isn't already in there
|
||||
add_blood_overlay()
|
||||
return TRUE //we applied blood to the item
|
||||
|
||||
/obj/item/clothing/gloves/add_blood(list/blood_dna, color)
|
||||
/obj/item/clothing/gloves/add_blood(list/blood_dna, b_color)
|
||||
. = ..()
|
||||
transfer_blood = rand(2, 4)
|
||||
|
||||
/turf/add_blood(list/blood_dna, color)
|
||||
/turf/add_blood(list/blood_dna, b_color)
|
||||
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
|
||||
if(!B)
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(src)
|
||||
B.transfer_blood_dna(blood_dna) //give blood info to the blood decal.
|
||||
B.basecolor = color
|
||||
B.basecolor = b_color
|
||||
return TRUE //we bloodied the floor
|
||||
|
||||
/mob/living/carbon/human/add_blood(list/blood_dna, color)
|
||||
/mob/living/carbon/human/add_blood(list/blood_dna, b_color)
|
||||
if(wear_suit)
|
||||
wear_suit.add_blood(blood_dna, color)
|
||||
wear_suit.blood_color = color
|
||||
wear_suit.add_blood(blood_dna, b_color)
|
||||
update_inv_wear_suit()
|
||||
else if(w_uniform)
|
||||
w_uniform.add_blood(blood_dna, color)
|
||||
w_uniform.blood_color = color
|
||||
w_uniform.add_blood(blood_dna, b_color)
|
||||
update_inv_w_uniform()
|
||||
if(head)
|
||||
head.add_blood(blood_dna, color)
|
||||
head.blood_color = color
|
||||
head.add_blood(blood_dna, b_color)
|
||||
update_inv_head()
|
||||
if(glasses)
|
||||
glasses.add_blood(blood_dna, color)
|
||||
glasses.blood_color = color
|
||||
glasses.add_blood(blood_dna, b_color)
|
||||
update_inv_glasses()
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
G.add_blood(blood_dna, color)
|
||||
G.blood_color = color
|
||||
G.add_blood(blood_dna, b_color)
|
||||
verbs += /mob/living/carbon/human/proc/bloody_doodle
|
||||
else
|
||||
hand_blood_color = color
|
||||
hand_blood_color = b_color
|
||||
bloody_hands = rand(2, 4)
|
||||
transfer_blood_dna(blood_dna)
|
||||
verbs += /mob/living/carbon/human/proc/bloody_doodle
|
||||
@@ -783,21 +776,13 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
update_inv_gloves() //handles bloody hands overlays and updating
|
||||
return TRUE
|
||||
|
||||
/obj/item/proc/add_blood_overlay(color)
|
||||
/obj/item/proc/add_blood_overlay()
|
||||
if(initial(icon) && initial(icon_state))
|
||||
//try to find a pre-processed blood-splatter. otherwise, make a new one
|
||||
var/index = blood_splatter_index()
|
||||
var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index]
|
||||
if(!blood_splatter_icon)
|
||||
blood_splatter_icon = icon(initial(icon), initial(icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
|
||||
blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
|
||||
blood_splatter_icon.Blend(icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
|
||||
blood_splatter_icon = fcopy_rsc(blood_splatter_icon)
|
||||
GLOB.blood_splatter_icons[index] = blood_splatter_icon
|
||||
|
||||
blood_overlay = image(blood_splatter_icon)
|
||||
blood_overlay.color = color
|
||||
overlays += blood_overlay
|
||||
var/list/params = GLOB.blood_splatter_icons["[blood_color]"]
|
||||
if(!params)
|
||||
params = layering_filter(icon = icon('icons/effects/blood.dmi', "itemblood"), color = blood_color, blend_mode = BLEND_INSET_OVERLAY)
|
||||
GLOB.blood_splatter_icons["[blood_color]"] = params
|
||||
add_filter("blood_splatter", 1, params)
|
||||
|
||||
/atom/proc/clean_blood(radiation_clean = FALSE)
|
||||
germ_level = 0
|
||||
@@ -828,8 +813,8 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
/obj/item/clean_blood(radiation_clean = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(blood_overlay)
|
||||
overlays -= blood_overlay
|
||||
if(initial(icon) && initial(icon_state))
|
||||
remove_filter("blood_splatter")
|
||||
|
||||
/obj/item/clothing/gloves/clean_blood(radiation_clean = FALSE)
|
||||
. = ..()
|
||||
@@ -1153,3 +1138,15 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
if(degrees)
|
||||
appearance_flags |= PIXEL_SCALE
|
||||
transform = M
|
||||
|
||||
/*
|
||||
Setter for the `density` variable.
|
||||
Arguments:
|
||||
* new_value - the new density you would want it to set.
|
||||
Returns: Either null if identical to existing density, or the new density if different.
|
||||
*/
|
||||
/atom/proc/set_density(new_value)
|
||||
if(density == new_value)
|
||||
return
|
||||
. = density
|
||||
density = new_value
|
||||
|
||||
@@ -90,13 +90,11 @@
|
||||
|
||||
/atom/movable/proc/stop_pulling()
|
||||
if(pulling)
|
||||
pulling.pulledby = null
|
||||
var/mob/living/ex_pulled = pulling
|
||||
pulling.pulledby = null
|
||||
pulling = null
|
||||
pulledby = null
|
||||
if(isliving(ex_pulled))
|
||||
var/mob/living/L = ex_pulled
|
||||
L.update_canmove()// mob gets up if it was lyng down in a chokehold
|
||||
if(!QDELETED(ex_pulled) && istype(ex_pulled))
|
||||
ex_pulled.update_canmove()// mob gets up if it was lyng down in a chokehold
|
||||
|
||||
/atom/movable/proc/check_pulling()
|
||||
if(pulling)
|
||||
@@ -420,6 +418,7 @@
|
||||
if(spin && !no_spin && !no_spin_thrown)
|
||||
SpinAnimation(5, 1)
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_POST_THROW, TT, spin)
|
||||
SSthrowing.processing[src] = TT
|
||||
TT.tick()
|
||||
|
||||
|
||||
+14
-2
@@ -44,10 +44,12 @@
|
||||
hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPMINDSHIELD_HUD, IMPCHEM_HUD, WANTED_HUD)
|
||||
|
||||
/datum/atom_hud/data/diagnostic
|
||||
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD)
|
||||
|
||||
/datum/atom_hud/data/diagnostic/basic
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD)
|
||||
|
||||
/datum/atom_hud/data/diagnostic/advanced
|
||||
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_PATH_HUD)
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_PATH_HUD)
|
||||
|
||||
/datum/atom_hud/data/bot_path
|
||||
hud_icons = list(DIAG_PATH_HUD)
|
||||
@@ -473,6 +475,16 @@
|
||||
return
|
||||
holder.icon_state = "hudweed[RoundPlantBar(weedlevel/10)]"
|
||||
|
||||
/*~~~~~~~~~~~~
|
||||
Airlocks!
|
||||
~~~~~~~~~~~~~*/
|
||||
/obj/machinery/door/airlock/proc/diag_hud_set_electrified()
|
||||
var/image/holder = hud_list[DIAG_AIRLOCK_HUD]
|
||||
if(isElectrified())
|
||||
holder.icon_state = "electrified"
|
||||
else
|
||||
holder.icon_state = ""
|
||||
|
||||
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
I'll just put this somewhere near the end...
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
to_chat(usr, "<span class='boldnotice'>[src] is already occupied!</span>")
|
||||
return
|
||||
if(usr.abiotic())
|
||||
to_chat(usr, "<span class='boldnotice'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(usr, "<span class='boldnotice'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(usr.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(usr, "<span class='warning'>[usr] will not fit into [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.</span>")
|
||||
@@ -194,7 +194,7 @@
|
||||
if(!istype(L) || L.buckled)
|
||||
return
|
||||
if(L.abiotic())
|
||||
to_chat(user, "<span class='danger'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='danger'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(L.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.</span>")
|
||||
@@ -232,7 +232,7 @@
|
||||
to_chat(user, "<span class='boldnotice'>The scanner is already occupied!</span>")
|
||||
return
|
||||
if(G.affecting.abiotic())
|
||||
to_chat(user, "<span class='boldnotice'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='boldnotice'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(G.affecting.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[G] will not fit into [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.</span>")
|
||||
@@ -315,7 +315,7 @@
|
||||
if(HAS_TRAIT(occupant, TRAIT_GENELESS))
|
||||
return TRUE
|
||||
|
||||
var/radiation_protection = occupant.run_armor_check(null, "rad")
|
||||
var/radiation_protection = occupant.run_armor_check(null, RAD)
|
||||
if(radiation_protection > NEGATE_MUTATION_THRESHOLD)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -140,12 +140,16 @@
|
||||
/datum/mutation/disability/colourblindness/activate(mob/M)
|
||||
..()
|
||||
M.update_client_colour() //Handle the activation of the colourblindness on the mob.
|
||||
M.update_icons() //Apply eyeshine as needed.
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_misc_effects()
|
||||
|
||||
/datum/mutation/disability/colourblindness/deactivate(mob/M)
|
||||
..()
|
||||
M.update_client_colour() //Handle the deactivation of the colourblindness on the mob.
|
||||
M.update_icons() //Remove eyeshine as needed.
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_misc_effects()
|
||||
|
||||
/datum/mutation/disability/deaf
|
||||
name = "Deafness"
|
||||
|
||||
@@ -158,28 +158,6 @@
|
||||
M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH //temporary fix until the problem can be solved.
|
||||
to_chat(M, "<span class='danger'>You suddenly feel very weak.</span>")
|
||||
|
||||
/datum/mutation/xray
|
||||
name = "X-Ray Vision"
|
||||
activation_messages = list("The walls suddenly disappear.")
|
||||
deactivation_messages = list("The walls around you re-appear.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
traits_to_add = list(TRAIT_XRAY_VISION)
|
||||
activation_prob = 15
|
||||
|
||||
/datum/mutation/xray/New()
|
||||
..()
|
||||
block = GLOB.xrayblock
|
||||
|
||||
/datum/mutation/xray/activate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
M.update_icons() //Apply eyeshine as needed.
|
||||
|
||||
/datum/mutation/xray/deactivate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
M.update_icons() //Remove eyeshine as needed.
|
||||
|
||||
/datum/mutation/tk
|
||||
name = "Telekenesis"
|
||||
activation_messages = list("You feel smarter.")
|
||||
@@ -1181,3 +1159,58 @@
|
||||
else
|
||||
H.remoteview_target = null
|
||||
H.reset_perspective()
|
||||
|
||||
/datum/mutation/meson_vision
|
||||
name = "Meson Vision"
|
||||
activation_messages = list("More information seems to reach your eyes...")
|
||||
deactivation_messages = list("The amount of information reaching your eyes fades...")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
traits_to_add = list(TRAIT_MESON_VISION)
|
||||
|
||||
/datum/mutation/meson_vision/New()
|
||||
..()
|
||||
block = GLOB.mesonblock
|
||||
|
||||
/datum/mutation/meson_vision/activate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
|
||||
/datum/mutation/meson_vision/deactivate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
|
||||
/datum/mutation/night_vision
|
||||
name = "Night Vision"
|
||||
activation_messages = list("Were the lights always that bright?")
|
||||
deactivation_messages = list("The ambient light level returns to normal...")
|
||||
instability = GENE_INSTABILITY_MODERATE
|
||||
traits_to_add = list(TRAIT_NIGHT_VISION)
|
||||
|
||||
/datum/mutation/night_vision/New()
|
||||
..()
|
||||
block = GLOB.nightvisionblock
|
||||
|
||||
/datum/mutation/night_vision/activate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_misc_effects()
|
||||
|
||||
/datum/mutation/night_vision/deactivate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_misc_effects()
|
||||
|
||||
/datum/mutation/flash_protection
|
||||
name = "Flash Protection"
|
||||
activation_messages = list("You stop noticing the glare from lights...")
|
||||
deactivation_messages = list("Lights begin glaring again...")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
traits_to_add = list(TRAIT_FLASH_PROTECTION)
|
||||
|
||||
/datum/mutation/flash_protection/New()
|
||||
..()
|
||||
block = GLOB.noflashblock
|
||||
|
||||
@@ -91,8 +91,8 @@
|
||||
is_zombie = TRUE
|
||||
if(H.wear_suit)
|
||||
var/obj/item/clothing/suit/armor/A = H.wear_suit
|
||||
if(A.armor && A.armor.getRating("melee"))
|
||||
maxHealth += A.armor.getRating("melee") //That zombie's got armor, I want armor!
|
||||
if(A.armor && A.armor.getRating(MELEE))
|
||||
maxHealth += A.armor.getRating(MELEE) //That zombie's got armor, I want armor!
|
||||
maxHealth += 40
|
||||
health = maxHealth
|
||||
name = "blob zombie"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blank_blob"
|
||||
max_integrity = 400
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 90)
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 75, ACID = 90)
|
||||
fire_resist = 2
|
||||
point_return = -1
|
||||
var/overmind_get_delay = 0 // we don't want to constantly try to find an overmind, do it every 5 minutes
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/obj/structure/blob/core/ex_act(severity)
|
||||
var/damage = 50 - 10 * severity //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity
|
||||
take_damage(damage, BRUTE, "bomb", 0)
|
||||
take_damage(damage, BRUTE, BOMB, 0)
|
||||
|
||||
/obj/structure/blob/core/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, overmind_reagent_trigger = 1)
|
||||
. = ..()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blank_blob"
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 65, "acid" = 90)
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 65, ACID = 90)
|
||||
point_return = 18
|
||||
|
||||
/obj/structure/blob/node/Initialize(mapload)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
brute_resist = 0.25
|
||||
explosion_block = 3
|
||||
atmosblock = TRUE
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90)
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 90)
|
||||
|
||||
/obj/structure/blob/shield/core
|
||||
point_return = 0
|
||||
|
||||
@@ -66,10 +66,10 @@
|
||||
return
|
||||
|
||||
if(src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "You cannot send IC messages (muted).")
|
||||
return
|
||||
if(src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
if(src.client.handle_spam_prevention(message, MUTE_IC))
|
||||
return
|
||||
|
||||
if(stat)
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
blobber.AIStatus = AI_OFF
|
||||
blobber.LoseTarget()
|
||||
spawn()
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a blobbernaut?", ROLE_BLOB, TRUE, 10 SECONDS, source = blobber)
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a blobbernaut?", ROLE_BLOB, TRUE, 10 SECONDS, source = blobber, role_cleanname = "blobbernaut")
|
||||
if(length(candidates) && !QDELETED(blobber))
|
||||
var/mob/C = pick(candidates)
|
||||
if(C)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user