mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 02:54:41 +01:00
Merge remote-tracking branch 'upstream/master' into just-defibrillator-things
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
<!-- You can view Contributing.MD for a detailed description of the pull request process. -->
|
||||
|
||||
## What Does This PR Do
|
||||
<!-- Include a small to medium description of what your PR changes. Document every changes or this may delay review or even discourage maintainers from merging your PR! -->
|
||||
<!-- Include a small to medium description of what your PR changes. Document all changes, as not doing this may delay reviews or even discourage maintainers from merging your PR! -->
|
||||
|
||||
## Why It's Good For The Game
|
||||
<!-- Please add a short description of why you think these changes would benefit the game. If you can't justify it in words, it might not be worth adding. -->
|
||||
<!-- Add a short description of why you think these changes would benefit the game. If you can't justify it in words, it might not be worth adding. -->
|
||||
|
||||
## Images of changes
|
||||
<!-- If you did not make a map or sprite edit, you may delete this section. You may include a gif of your feature if you want -->
|
||||
<!-- If you did not make a map or sprite edit, you may delete this section. You may include a gif or mp4 of your feature if you want. -->
|
||||
|
||||
## Changelog
|
||||
:cl:
|
||||
@@ -27,3 +27,4 @@ experiment: Added an experimental thingy
|
||||
|
||||
<!-- Both :cl:'s are required for the changelog to work! You can put your name to the right of the first :cl: if you want to overwrite your GitHub username as author ingame. -->
|
||||
<!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. -->
|
||||
<!-- If a PR has no impact on players (i.e. a code refactor that does not change functionality) then the entire Changelog heading and contents can be removed. -->
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
tools/ci/install_byond.sh
|
||||
source $HOME/BYOND/byond/bin/byondsetup
|
||||
tools/ci/generate_maplist.sh
|
||||
tools/ci/dm.sh -Mci_map_testing paradise.dme
|
||||
tools/ci/dm.sh -DCIMAP paradise.dme
|
||||
|
||||
unit_tests_and_sql:
|
||||
name: Unit Tests + SQL Validation
|
||||
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"workbench.editorAssociations": {
|
||||
"*.dmi": "imagePreview.previewEditor"
|
||||
}
|
||||
}
|
||||
+22
-8
@@ -99,7 +99,7 @@ CREATE TABLE `customuseritems` (
|
||||
`cuiJobMask` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `cuiCKey` (`cuiCKey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -126,7 +126,7 @@ CREATE TABLE `death` (
|
||||
`fireloss` int(11) NOT NULL,
|
||||
`oxyloss` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -241,7 +241,7 @@ CREATE TABLE `feedback` (
|
||||
`version` tinyint(3) UNSIGNED NOT NULL,
|
||||
`json` LONGTEXT NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -277,6 +277,7 @@ CREATE TABLE `player` (
|
||||
`fupdate` smallint(4) DEFAULT '0',
|
||||
`parallax` tinyint(1) DEFAULT '8',
|
||||
`byond_date` DATE DEFAULT NULL,
|
||||
`2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`),
|
||||
KEY `lastseen` (`lastseen`),
|
||||
@@ -321,7 +322,7 @@ CREATE TABLE `karma` (
|
||||
`spenderip` text NOT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -338,7 +339,7 @@ CREATE TABLE `karmatotals` (
|
||||
`karmaspent` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `byondkey` (`byondkey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -359,7 +360,7 @@ CREATE TABLE `library` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`),
|
||||
KEY `flagged` (`flagged`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -375,7 +376,7 @@ CREATE TABLE `legacy_population` (
|
||||
`admincount` int(11) DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -392,7 +393,7 @@ CREATE TABLE `whitelist` (
|
||||
`species` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
@@ -585,3 +586,16 @@ CREATE TABLE `round` (
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table `2fa_secrets`
|
||||
--
|
||||
CREATE TABLE `2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`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;
|
||||
|
||||
@@ -98,7 +98,7 @@ CREATE TABLE `SS13_customuseritems` (
|
||||
`cuiPropAdjust` text,
|
||||
`cuiJobMask` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4;
|
||||
ALTER TABLE `SS13_customuseritems` ADD INDEX(`cuiCKey`);
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
@@ -126,7 +126,7 @@ CREATE TABLE `SS13_death` (
|
||||
`fireloss` int(11) NOT NULL,
|
||||
`oxyloss` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -240,7 +240,7 @@ CREATE TABLE `SS13_feedback` (
|
||||
`version` tinyint(3) UNSIGNED NOT NULL,
|
||||
`json` LONGTEXT NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -276,6 +276,7 @@ CREATE TABLE `SS13_player` (
|
||||
`fupdate` smallint(4) DEFAULT '0',
|
||||
`parallax` tinyint(1) DEFAULT '8',
|
||||
`byond_date` DATE DEFAULT NULL,
|
||||
`2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`),
|
||||
KEY `lastseen` (`lastseen`),
|
||||
@@ -320,7 +321,7 @@ CREATE TABLE `SS13_karma` (
|
||||
`spenderip` text NOT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -337,7 +338,7 @@ CREATE TABLE `SS13_karmatotals` (
|
||||
`karmaspent` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `byondkey` (`byondkey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -358,7 +359,7 @@ CREATE TABLE `SS13_library` (
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`),
|
||||
KEY `flagged` (`flagged`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -374,7 +375,7 @@ CREATE TABLE `SS13_legacy_population` (
|
||||
`admincount` int(11) DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
@@ -391,7 +392,7 @@ CREATE TABLE `SS13_whitelist` (
|
||||
`species` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
@@ -582,3 +583,15 @@ CREATE TABLE `SS13_round` (
|
||||
`station_name` VARCHAR(80) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
--
|
||||
-- Table structure for table `2fa_secrets`
|
||||
--
|
||||
CREATE TABLE `SS13_2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`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;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Updating SQL from version 22 to 23 -AffectedArc07
|
||||
# Converts existing MyISAM tables to InnoDB
|
||||
|
||||
ALTER TABLE `customuseritems` ENGINE=InnoDB;
|
||||
ALTER TABLE `death` ENGINE=InnoDB;
|
||||
ALTER TABLE `feedback` ENGINE=InnoDB;
|
||||
ALTER TABLE `karma` ENGINE=InnoDB;
|
||||
ALTER TABLE `karmatotals` ENGINE=InnoDB;
|
||||
ALTER TABLE `legacy_population` ENGINE=InnoDB;
|
||||
ALTER TABLE `library` ENGINE=InnoDB;
|
||||
ALTER TABLE `whitelist` ENGINE=InnoDB;
|
||||
@@ -0,0 +1,13 @@
|
||||
# Updates DB from 23 to 24 -AffectedArc07
|
||||
# Add new column to player table for 2FA status
|
||||
ALTER TABLE `player` ADD COLUMN `2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' AFTER `byond_date`;
|
||||
|
||||
# Create new table for 2FA tokens
|
||||
CREATE TABLE `2fa_secrets` (
|
||||
`ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`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;
|
||||
+32
-6
@@ -1,12 +1,38 @@
|
||||
[langserver]
|
||||
dreamchecker = true
|
||||
|
||||
# Keep the keys in this file alphabetical please
|
||||
[code_standards]
|
||||
disallow_relative_type_definitions = true
|
||||
disallow_relative_proc_definitions = true
|
||||
disallow_relative_type_definitions = true
|
||||
|
||||
[debugger]
|
||||
engine = "auxtools"
|
||||
|
||||
[dmdoc]
|
||||
use_typepath_names = true
|
||||
|
||||
[debugger]
|
||||
engine = "auxtools"
|
||||
[langserver]
|
||||
dreamchecker = true
|
||||
|
||||
[map_renderer]
|
||||
hide_invisible = [
|
||||
"/obj/effect/landmark",
|
||||
"/obj/effect/mapping_helpers",
|
||||
"/obj/effect/spawner/random_barrier",
|
||||
"/obj/effect/spawner/random_spawners",
|
||||
]
|
||||
|
||||
[map_renderer.fancy_layers]
|
||||
# -10
|
||||
"/turf/simulated/floor/plating" = -10
|
||||
"/turf/space" = -10
|
||||
# -2
|
||||
"/turf/simulated/floor/bluegrid" = -2
|
||||
"/turf/simulated/floor/carpet" = -2
|
||||
"/turf/simulated/floor/engine" = -2
|
||||
"/turf/simulated/floor/plasteel" = -2
|
||||
"/turf/simulated/floor/wood" = -2
|
||||
"/turf/simulated/wall" = -2
|
||||
|
||||
[map_renderer.render_passes]
|
||||
icon-smoothing = false
|
||||
icon-smoothing-2016 = true
|
||||
smart-cables = false
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "map_files\generic\centcomm.dmm"
|
||||
#define CC_TRANSITION_CONFIG DECLARE_LEVEL(CENTCOMM, SELFLOOPING, list(ADMIN_LEVEL, BLOCK_TELEPORT, IMPEDES_MAGIC))
|
||||
#ifdef CIMAP
|
||||
#include "ci_map_testing.dm"
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
All z-levels should be identical in size. Their numbers should not matter.
|
||||
The order of z-levels should not matter as long as their attributes are properly defined at MAP_TRANSITION_CONFIG.
|
||||
Old code checked for the number of the z-level (for example whether there are any revheads on Z1),
|
||||
currently it should check for the define (for example whether there are any revheads on any z-levels defined as STATION_LEVEL).
|
||||
z1 = centcomm
|
||||
z2 = station
|
||||
z3 = lavaland
|
||||
*/
|
||||
|
||||
#if !defined(USING_MAP_DATUM)
|
||||
#include "map_files\generic\centcomm.dmm"
|
||||
#include "map_files\cyberiad\cyberiad.dmm"
|
||||
#include "map_files\generic\Lavaland.dmm"
|
||||
|
||||
#define MAP_TRANSITION_CONFIG list(\
|
||||
DECLARE_LEVEL(CENTCOMM, SELFLOOPING, list(ADMIN_LEVEL, BLOCK_TELEPORT, IMPEDES_MAGIC)),\
|
||||
DECLARE_LEVEL(MAIN_STATION, CROSSLINKED, list(STATION_LEVEL, STATION_CONTACT, REACHABLE, AI_OK)),\
|
||||
DECLARE_LEVEL(MINING, SELFLOOPING, list(ORE_LEVEL, REACHABLE, STATION_CONTACT, HAS_WEATHER, AI_OK)))
|
||||
|
||||
#define USING_MAP_DATUM /datum/map/cyberiad
|
||||
|
||||
#elif !defined(MAP_OVERRIDE)
|
||||
|
||||
#warn a map has already been included, ignoring Cyberiad.
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
All z-levels should be identical in size. Their numbers should not matter.
|
||||
The order of z-levels should not matter as long as their attributes are properly defined at MAP_TRANSITION_CONFIG.
|
||||
Old code checked for the number of the z-level (for example whether there are any revheads on Z1),
|
||||
currently it should check for the define (for example whether there are any revheads on any z-levels defined as STATION_LEVEL).
|
||||
z1 = centcomm
|
||||
z2 = station
|
||||
z3 = lavaland
|
||||
|
||||
Original design by Okand37 of TG Station
|
||||
Lovingly ported by Purpose2 to Paradise
|
||||
*/
|
||||
|
||||
#if !defined(USING_MAP_DATUM)
|
||||
#include "map_files\generic\centcomm.dmm"
|
||||
#include "map_files\delta\delta.dmm"
|
||||
#include "map_files\generic\Lavaland.dmm"
|
||||
|
||||
#define MAP_TRANSITION_CONFIG list(\
|
||||
DECLARE_LEVEL(CENTCOMM, SELFLOOPING, list(ADMIN_LEVEL, BLOCK_TELEPORT, IMPEDES_MAGIC)),\
|
||||
DECLARE_LEVEL(MAIN_STATION, CROSSLINKED, list(STATION_LEVEL, STATION_CONTACT, REACHABLE, AI_OK)),\
|
||||
DECLARE_LEVEL(MINING, SELFLOOPING, list(ORE_LEVEL, REACHABLE, STATION_CONTACT, HAS_WEATHER, AI_OK)))
|
||||
|
||||
#define USING_MAP_DATUM /datum/map/delta
|
||||
|
||||
#elif !defined(MAP_OVERRIDE)
|
||||
|
||||
#warn a map has already been included, ignoring Delta.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
// See code/modules/mapping for map datums
|
||||
+10494
-17177
File diff suppressed because it is too large
Load Diff
@@ -132,7 +132,7 @@
|
||||
/area/ruin/powered/beach)
|
||||
"ax" = (
|
||||
/obj/machinery/disco/immobile,
|
||||
/turf/simulated/floor/light/colour_cycle,
|
||||
/turf/simulated/floor/light,
|
||||
/area/ruin/powered/beach)
|
||||
"ay" = (
|
||||
/obj/machinery/door/airlock/sandstone{
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
/turf/simulated/floor/plating/airless,
|
||||
/area/space/nearstation)
|
||||
"F" = (
|
||||
/obj/structure/computerframe/HONKputer,
|
||||
/obj/structure/computerframe,
|
||||
/turf/simulated/floor/plasteel/airless,
|
||||
/area/space/nearstation)
|
||||
"G" = (
|
||||
|
||||
@@ -1,4 +1,78 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"aa" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
pixel_y = 0;
|
||||
tag = ""
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4;
|
||||
level = 1
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/fans/tiny,
|
||||
/obj/machinery/door/poddoor{
|
||||
id_tag = "SSBtestchamber";
|
||||
name = "Syndicate Test Lab Blast Door"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ab" = (
|
||||
/obj/machinery/door_control{
|
||||
id = "SSBtestchamber";
|
||||
name = "Blast Door Control"
|
||||
},
|
||||
/turf/simulated/wall/mineral/plastitanium/nodiagonal,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ac" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/fans/tiny,
|
||||
/obj/machinery/door/poddoor{
|
||||
id_tag = "SSBtestchamber";
|
||||
name = "Syndicate Test Lab Blast Door"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ad" = (
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/machinery/camera/emp_proof{
|
||||
c_tag = "Test Lab West";
|
||||
dir = 4;
|
||||
network = list("SyndicateTestLab")
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ae" = (
|
||||
/obj/machinery/camera/emp_proof{
|
||||
c_tag = "Test Lab East";
|
||||
dir = 9;
|
||||
network = list("SyndicateTestLab")
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"aj" = (
|
||||
/obj/effect/spawner/window/reinforced,
|
||||
/turf/simulated/floor/plasteel{
|
||||
@@ -1191,18 +1265,6 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/telecomms)
|
||||
"mE" = (
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/fans/tiny,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"mP" = (
|
||||
/obj/machinery/power/generator,
|
||||
/obj/structure/cable/yellow,
|
||||
@@ -1404,14 +1466,6 @@
|
||||
icon_state = "brown"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/cargo)
|
||||
"ol" = (
|
||||
/obj/machinery/light{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/turf/simulated/floor/engine,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ow" = (
|
||||
/obj/structure/closet/crate/medical,
|
||||
/obj/item/storage/firstaid/fire{
|
||||
@@ -1861,32 +1915,6 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/main)
|
||||
"un" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8";
|
||||
pixel_y = 0;
|
||||
tag = ""
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4;
|
||||
level = 1
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/fans/tiny,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"uq" = (
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "freezerfloor"
|
||||
@@ -2388,7 +2416,7 @@
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/main)
|
||||
"yf" = (
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "Engine Grid Power Monitoring Computer"
|
||||
},
|
||||
/obj/structure/cable/yellow,
|
||||
@@ -4114,7 +4142,7 @@
|
||||
icon_state = "0-2";
|
||||
pixel_y = 1
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "Output Grid Power Monitoring Computer"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
@@ -4926,6 +4954,13 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/ruin/unpowered/syndicate_space_base/main)
|
||||
"ZG" = (
|
||||
/obj/machinery/computer/security/telescreen{
|
||||
name = "Test Lab Monitor";
|
||||
network = list("SyndicateTestLab")
|
||||
},
|
||||
/turf/simulated/wall/mineral/plastitanium/nodiagonal,
|
||||
/area/ruin/unpowered/syndicate_space_base/testlab)
|
||||
"ZR" = (
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
@@ -6837,8 +6872,8 @@ TD
|
||||
TD
|
||||
rr
|
||||
CM
|
||||
TD
|
||||
TD
|
||||
ZG
|
||||
ab
|
||||
TD
|
||||
CM
|
||||
ZR
|
||||
@@ -6897,13 +6932,13 @@ ia
|
||||
ia
|
||||
ia
|
||||
TD
|
||||
un
|
||||
aa
|
||||
TD
|
||||
ia
|
||||
ia
|
||||
ia
|
||||
TD
|
||||
mE
|
||||
ac
|
||||
TD
|
||||
AV
|
||||
AV
|
||||
@@ -7022,7 +7057,7 @@ fH
|
||||
fH
|
||||
RC
|
||||
uN
|
||||
ol
|
||||
ad
|
||||
RF
|
||||
RF
|
||||
dH
|
||||
@@ -7952,7 +7987,7 @@ qv
|
||||
Vl
|
||||
Vl
|
||||
Vl
|
||||
Vl
|
||||
ae
|
||||
Vl
|
||||
Vl
|
||||
Vl
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
},
|
||||
/area/derelict/bridge)
|
||||
"av" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 1;
|
||||
icon_state = "darkblue"
|
||||
@@ -3697,7 +3697,7 @@
|
||||
name = "Derelict Annex"
|
||||
})
|
||||
"hD" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "caution";
|
||||
dir = 5
|
||||
@@ -6735,7 +6735,7 @@
|
||||
})
|
||||
"nS" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/reagent_containers/food/snacks/beetsoup,
|
||||
/obj/item/reagent_containers/food/snacks/soup/beetsoup,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "bar"
|
||||
},
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
},
|
||||
/turf/simulated/floor/beach/away/water/deep/sand_floor,
|
||||
/area/awaymission/undersea)
|
||||
"af" = (
|
||||
/obj/structure/constructshell,
|
||||
/turf/simulated/floor/beach/away/water/deep/wood_floor,
|
||||
/area/awaymission/undersea)
|
||||
"ag" = (
|
||||
/obj/structure/chair/wood/wings,
|
||||
/turf/simulated/floor/beach/away/water/deep/wood_floor,
|
||||
@@ -46312,7 +46308,7 @@ ad
|
||||
ad
|
||||
ad
|
||||
ah
|
||||
af
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ar
|
||||
@@ -46823,7 +46819,7 @@ av
|
||||
av
|
||||
ad
|
||||
ad
|
||||
af
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
@@ -48108,7 +48104,7 @@ av
|
||||
av
|
||||
ad
|
||||
ad
|
||||
af
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
@@ -48625,7 +48621,7 @@ ad
|
||||
ad
|
||||
ad
|
||||
ah
|
||||
af
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
ah
|
||||
|
||||
@@ -2536,7 +2536,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/effect/decal/warning_stripes/west,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/awaymission/BMPship/Aft)
|
||||
|
||||
@@ -2785,7 +2785,7 @@
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "yellow"
|
||||
},
|
||||
|
||||
@@ -1308,7 +1308,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -5160,7 +5160,7 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/awaycontent/a7)
|
||||
"hm" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/obj/structure/cable,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/awaycontent/a7)
|
||||
|
||||
@@ -666,7 +666,7 @@
|
||||
/area/awaymission/spacebattle/cruiser)
|
||||
"cS" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/reagent_containers/food/snacks/stew,
|
||||
/obj/item/reagent_containers/food/snacks/soup/stew,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "cafeteria";
|
||||
dir = 2
|
||||
|
||||
@@ -7975,7 +7975,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/sign/nosmoking_2{
|
||||
@@ -10652,7 +10652,7 @@
|
||||
/turf/simulated/floor/plating/asteroid/airless,
|
||||
/area/awaymission/UO71/outside)
|
||||
"vV" = (
|
||||
/obj/machinery/computer/monitor,
|
||||
/obj/machinery/computer/monitor/secret,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/awaymission/UO71/bridge)
|
||||
"vW" = (
|
||||
@@ -11805,7 +11805,7 @@
|
||||
},
|
||||
/area/awaymission/UO71/eng)
|
||||
"yc" = (
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/cable,
|
||||
|
||||
@@ -11078,7 +11078,7 @@
|
||||
icon_state = "0-4";
|
||||
d2 = 4
|
||||
},
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/sign/nosmoking_2{
|
||||
@@ -15909,7 +15909,7 @@
|
||||
name = "UO45 Engineering"
|
||||
})
|
||||
"xg" = (
|
||||
/obj/machinery/computer/monitor{
|
||||
/obj/machinery/computer/monitor/secret{
|
||||
name = "primary power monitoring console"
|
||||
},
|
||||
/obj/structure/cable,
|
||||
|
||||
@@ -1217,7 +1217,7 @@
|
||||
},
|
||||
/area/awaymission/wwgov)
|
||||
"dy" = (
|
||||
/obj/item/reagent_containers/food/snacks/stew,
|
||||
/obj/item/reagent_containers/food/snacks/soup/stew,
|
||||
/turf/simulated/floor/plasteel{
|
||||
tag = "icon-stage_bleft";
|
||||
icon_state = "stage_bleft"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
All z-levels should be identical in size. Their numbers should not matter.
|
||||
The order of z-levels should not matter as long as their attributes are properly defined at MAP_TRANSITION_CONFIG.
|
||||
Old code checked for the number of the z-level (for example whether there are any revheads on Z1),
|
||||
currently it should check for the define (for example whether there are any revheads on any z-levels defined as STATION_LEVEL).
|
||||
z1 = centcomm
|
||||
z2 = station
|
||||
z3 = lavaland
|
||||
*/
|
||||
|
||||
#if !defined(USING_MAP_DATUM)
|
||||
#include "map_files\generic\centcomm.dmm"
|
||||
#include "map_files\MetaStation\MetaStation.dmm"
|
||||
#include "map_files\generic\Lavaland.dmm"
|
||||
|
||||
#define MAP_TRANSITION_CONFIG list(\
|
||||
DECLARE_LEVEL(CENTCOMM, SELFLOOPING, list(ADMIN_LEVEL, BLOCK_TELEPORT, IMPEDES_MAGIC)),\
|
||||
DECLARE_LEVEL(MAIN_STATION, CROSSLINKED, list(STATION_LEVEL, STATION_CONTACT, REACHABLE, AI_OK)),\
|
||||
DECLARE_LEVEL(MINING, SELFLOOPING, list(ORE_LEVEL, REACHABLE, STATION_CONTACT, HAS_WEATHER, AI_OK)))
|
||||
|
||||
#define USING_MAP_DATUM /datum/map/metastation
|
||||
|
||||
#elif !defined(MAP_OVERRIDE)
|
||||
|
||||
#warn a map has already been included, ignoring MetaStation.
|
||||
|
||||
#endif
|
||||
@@ -32,7 +32,6 @@
|
||||
#define SPECIAL_ROLE_FREE_GOLEM "Free Golem"
|
||||
#define SPECIAL_ROLE_GOLEM "Golem"
|
||||
#define SPECIAL_ROLE_HEAD_REV "Head Revolutionary"
|
||||
#define SPECIAL_ROLE_HONKSQUAD "Honksquad"
|
||||
#define SPECIAL_ROLE_REV "Revolutionary"
|
||||
#define SPECIAL_ROLE_MORPH "Morph"
|
||||
#define SPECIAL_ROLE_MULTIVERSE "Multiverse Traveller"
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
#define iseffect(A) (istype(A, /obj/effect))
|
||||
|
||||
#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
|
||||
|
||||
#define isclothing(A) (istype(A, /obj/item/clothing))
|
||||
|
||||
#define is_pen(W) (istype(W, /obj/item/pen))
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
#define INVESTIGATE_BOMB "bombs"
|
||||
|
||||
// The SQL version required by this version of the code
|
||||
#define SQL_VERSION 22
|
||||
#define SQL_VERSION 24
|
||||
|
||||
// Vending machine stuff
|
||||
#define CAT_NORMAL 1
|
||||
|
||||
@@ -55,8 +55,9 @@
|
||||
// Yes I know this being an "enable to disable" is misleading, but it avoids having to tweak all existing pref entries
|
||||
#define PREFTOGGLE_2_REVERB_DISABLE 512
|
||||
#define PREFTOGGLE_2_FORCE_WHITE_RUNECHAT 1024
|
||||
#define PREFTOGGLE_2_SIMPLE_STAT_PANEL 2048
|
||||
|
||||
#define TOGGLES_2_TOTAL 2047 // 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 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_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE)
|
||||
|
||||
@@ -94,7 +95,7 @@
|
||||
#define EXP_TYPE_SERVICE "Service"
|
||||
#define EXP_TYPE_WHITELIST "Whitelist"
|
||||
|
||||
#define EXP_DEPT_TYPE_LIST list(EXP_TYPE_SERVICE, EXP_TYPE_MEDICAL, EXP_TYPE_ENGINEERING, EXP_TYPE_SCIENCE, EXP_TYPE_SECURITY, EXP_TYPE_COMMAND, EXP_TYPE_SILICON, EXP_TYPE_SPECIAL)
|
||||
#define EXP_DEPT_TYPE_LIST list(EXP_TYPE_SUPPLY, EXP_TYPE_SERVICE, EXP_TYPE_MEDICAL, EXP_TYPE_ENGINEERING, EXP_TYPE_SCIENCE, EXP_TYPE_SECURITY, EXP_TYPE_COMMAND, EXP_TYPE_SILICON, EXP_TYPE_SPECIAL, EXP_TYPE_GHOST)
|
||||
|
||||
// Defines just for parallax because its levels make storing it in the regular prefs a pain in the ass
|
||||
// These dont need to be bitflags because there isnt going to be more than one at a time of these active
|
||||
@@ -104,3 +105,12 @@
|
||||
#define PARALLAX_MED 4
|
||||
#define PARALLAX_HIGH 8
|
||||
#define PARALLAX_INSANE 16
|
||||
|
||||
// 2FA Defines. These are the same as the schema DB enums //
|
||||
|
||||
/// Client has 2FA disabled
|
||||
#define _2FA_DISABLED "DISABLED"
|
||||
/// Client will be prompted for 2FA on IP changes
|
||||
#define _2FA_ENABLED_IP "ENABLED_IP"
|
||||
/// Client will be prompted for 2FA always
|
||||
#define _2FA_ENABLED_ALWAYS "ENABLED_ALWAYS"
|
||||
|
||||
@@ -134,9 +134,6 @@ GLOBAL_PROTECT(log_end)
|
||||
/proc/log_href(text)
|
||||
rustg_log_write(GLOB.world_href_log, "HREF: [html_decode(text)][GLOB.log_end]")
|
||||
|
||||
/proc/log_asset(text)
|
||||
rustg_log_write(GLOB.world_asset_log, "ASSET: [text][GLOB.log_end]")
|
||||
|
||||
/proc/log_runtime_summary(text)
|
||||
rustg_log_write(GLOB.runtime_summary_log, "[text][GLOB.log_end]")
|
||||
|
||||
@@ -147,6 +144,9 @@ GLOBAL_PROTECT(log_end)
|
||||
rustg_log_write(GLOB.sql_log, "[text][GLOB.log_end]")
|
||||
SEND_TEXT(world.log, text) // Redirect it to DD too
|
||||
|
||||
/proc/log_chat_debug(text)
|
||||
rustg_log_write(GLOB.chat_debug_log, "[text][GLOB.log_end]")
|
||||
|
||||
// A logging proc that only outputs after setup is done, to
|
||||
// help devs test initialization stuff that happens a lot
|
||||
/proc/log_after_setup(message)
|
||||
|
||||
@@ -15,9 +15,9 @@ GLOBAL_VAR(church_name)
|
||||
|
||||
return name
|
||||
|
||||
GLOBAL_VAR(command_name)
|
||||
// TODO: Remove this. Its always gonna be NAS Trurl
|
||||
/proc/command_name()
|
||||
return GLOB.using_map.dock_name
|
||||
return "NAS Trurl"
|
||||
|
||||
GLOBAL_VAR(religion_name)
|
||||
/proc/religion_name()
|
||||
@@ -31,11 +31,8 @@ GLOBAL_VAR(religion_name)
|
||||
|
||||
return capitalize(name)
|
||||
|
||||
/proc/system_name()
|
||||
return GLOB.using_map.starsys_name
|
||||
|
||||
/proc/station_name()
|
||||
return GLOB.using_map.station_name
|
||||
return SSmapping.map_datum.fluff_name
|
||||
|
||||
/proc/new_station_name()
|
||||
var/random = rand(1,5)
|
||||
|
||||
@@ -513,6 +513,8 @@
|
||||
text = replacetext(text, "\[cell\]", "<td>")
|
||||
text = replacetext(text, "\[logo\]", "​<img src = ntlogo.png>")
|
||||
text = replacetext(text, "\[time\]", "[station_time_timestamp()]") // TO DO
|
||||
text = replacetext(text, "\[date\]", "[GLOB.current_date_string]")
|
||||
text = replacetext(text, "\[station\]", "[SSmapping.map_datum.fluff_name]")
|
||||
if(!no_font)
|
||||
if(P)
|
||||
text = "<font face=\"[deffont]\" color=[P ? P.colour : "black"]>[text]</font>"
|
||||
@@ -651,3 +653,79 @@
|
||||
|
||||
// return the split html object to the caller
|
||||
return s
|
||||
|
||||
//Used for applying byonds text macros to strings that are loaded at runtime
|
||||
/proc/apply_text_macros(string)
|
||||
var/next_backslash = findtext(string, "\\")
|
||||
if(!next_backslash)
|
||||
return string
|
||||
|
||||
var/leng = length(string)
|
||||
|
||||
var/next_space = findtext(string, " ", next_backslash + length(string[next_backslash]))
|
||||
if(!next_space)
|
||||
next_space = leng - next_backslash
|
||||
|
||||
if(!next_space) //trailing bs
|
||||
return string
|
||||
|
||||
var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash)
|
||||
var/macro = lowertext(copytext(string, next_backslash + length(string[next_backslash]), next_space))
|
||||
var/rest = next_backslash > leng ? "" : copytext(string, next_space + length(string[next_space]))
|
||||
|
||||
//See https://secure.byond.com/docs/ref/info.html#/DM/text/macros
|
||||
switch(macro)
|
||||
//prefixes/agnostic
|
||||
if("the")
|
||||
rest = text("\the []", rest)
|
||||
if("a")
|
||||
rest = text("\a []", rest)
|
||||
if("an")
|
||||
rest = text("\an []", rest)
|
||||
if("proper")
|
||||
rest = text("\proper []", rest)
|
||||
if("improper")
|
||||
rest = text("\improper []", rest)
|
||||
if("roman")
|
||||
rest = text("\roman []", rest)
|
||||
//postfixes
|
||||
if("th")
|
||||
base = text("[]\th", rest)
|
||||
if("s")
|
||||
base = text("[]\s", rest)
|
||||
if("he")
|
||||
base = text("[]\he", rest)
|
||||
if("she")
|
||||
base = text("[]\she", rest)
|
||||
if("his")
|
||||
base = text("[]\his", rest)
|
||||
if("himself")
|
||||
base = text("[]\himself", rest)
|
||||
if("herself")
|
||||
base = text("[]\herself", rest)
|
||||
if("hers")
|
||||
base = text("[]\hers", rest)
|
||||
|
||||
. = base
|
||||
if(rest)
|
||||
. += .(rest)
|
||||
|
||||
/**
|
||||
* Proc to generate a "rank colour" from a client
|
||||
*
|
||||
* This takes the client and looks at various factors in order, such as patreon status, staff rank, and more
|
||||
* Arguments:
|
||||
* * C - The client were looking up
|
||||
*/
|
||||
/proc/client2rankcolour(client/C)
|
||||
// First check if end user is an admin
|
||||
if(C.holder)
|
||||
if(C.holder.rank in GLOB.rank_colour_map)
|
||||
// Return their rank colour if they are in here
|
||||
return GLOB.rank_colour_map[C.holder.rank]
|
||||
|
||||
// If they arent an admin, see if they are a patreon. Just accept any level
|
||||
if(C.donator_level)
|
||||
return "#e67e22" // Patreon orange
|
||||
return null
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
Remember to update _globalvars/traits.dm if you're adding/removing/renaming traits.
|
||||
*/
|
||||
|
||||
//mob traits
|
||||
//***** MOB TRAITS *****//
|
||||
#define TRAIT_BLIND "blind"
|
||||
#define TRAIT_MUTE "mute"
|
||||
#define TRAIT_DEAF "deaf"
|
||||
@@ -119,6 +119,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_XENO_HOST "xeno_host" //Tracks whether we're gonna be a baby alien's mummy.
|
||||
#define TRAIT_SHOCKIMMUNE "shock_immunity"
|
||||
#define TRAIT_TESLA_SHOCKIMMUNE "tesla_shock_immunity"
|
||||
#define TRAIT_TELEKINESIS "telekinesis"
|
||||
#define TRAIT_RESISTHEAT "resist_heat"
|
||||
#define TRAIT_RESISTHEATHANDS "resist_heat_handsonly" //For when you want to be able to touch hot things, but still want fire to be an issue.
|
||||
#define TRAIT_RESISTCOLD "resist_cold"
|
||||
@@ -152,8 +153,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_NOEXAMINE "no_examine"
|
||||
#define TRAIT_NOPAIN "no_pain"
|
||||
|
||||
/// Blowing kisses actually does damage to the victim
|
||||
#define TRAIT_KISS_OF_DEATH "kiss_of_death"
|
||||
//***** ITEM TRAITS *****//
|
||||
/// Show what machine/door wires do when held.
|
||||
#define TRAIT_SHOW_WIRE_INFO "show_wire_info"
|
||||
|
||||
//
|
||||
// common trait sources
|
||||
|
||||
+12
-15
@@ -31,19 +31,20 @@
|
||||
return 1
|
||||
|
||||
|
||||
/proc/Get_Angle(atom/movable/start,atom/movable/end)//For beams.
|
||||
if(!start || !end) return 0
|
||||
/proc/get_angle(atom/movable/start, atom/movable/end)//For beams.
|
||||
if(!start || !end)
|
||||
return 0
|
||||
var/dy
|
||||
var/dx
|
||||
dy=(32*end.y+end.pixel_y)-(32*start.y+start.pixel_y)
|
||||
dx=(32*end.x+end.pixel_x)-(32*start.x+start.pixel_x)
|
||||
dy = (32 * end.y + end.pixel_y) - (32 * start.y + start.pixel_y)
|
||||
dx = (32 * end.x + end.pixel_x) - (32 * start.x + start.pixel_x)
|
||||
if(!dy)
|
||||
return (dx>=0)?90:270
|
||||
.=arctan(dx/dy)
|
||||
if(dy<0)
|
||||
.+=180
|
||||
else if(dx<0)
|
||||
.+=360
|
||||
return (dx >= 0) ? 90 : 270
|
||||
. = arctan(dx / dy)
|
||||
if(dy < 0)
|
||||
. += 180
|
||||
else if(dx < 0)
|
||||
. += 360
|
||||
|
||||
//Returns location. Returns null if no location was found.
|
||||
/proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = 0, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0)
|
||||
@@ -1246,10 +1247,6 @@ GLOBAL_LIST_INIT(wall_items, typecacheof(list(/obj/machinery/power/apc, /obj/mac
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/proc/get_angle(atom/a, atom/b)
|
||||
return atan2(b.y - a.y, b.x - a.x)
|
||||
|
||||
/proc/atan2(x, y)
|
||||
if(!x && !y) return 0
|
||||
return y >= 0 ? arccos(x / sqrt(x * x + y * y)) : -arccos(x / sqrt(x * x + y * y))
|
||||
@@ -2072,7 +2069,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
return _list
|
||||
|
||||
/// Waits at a line of code until X is true
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
#define UNTIL(X) while(!(X)) sleep(world.tick_lag)
|
||||
|
||||
// Check if the source atom contains another atom
|
||||
/atom/proc/contains(atom/location)
|
||||
|
||||
@@ -30,7 +30,8 @@ GLOBAL_LIST_INIT(restricted_camera_networks, list(
|
||||
"UO45",
|
||||
"UO45R",
|
||||
"UO71",
|
||||
"Xeno"
|
||||
"Xeno",
|
||||
"SyndicateTestLab"
|
||||
)) //Those networks can only be accessed by preexisting terminals. AIs and new terminals can't use them.
|
||||
|
||||
GLOBAL_LIST_INIT(ruin_landmarks, list())
|
||||
@@ -54,4 +55,7 @@ GLOBAL_LIST_INIT(cooking_recipes, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN =
|
||||
GLOBAL_LIST_INIT(cooking_ingredients, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN = list(), RECIPE_GRILL = list(), RECIPE_CANDY = list()))
|
||||
GLOBAL_LIST_INIT(cooking_reagents, list(RECIPE_MICROWAVE = list(), RECIPE_OVEN = list(), RECIPE_GRILL = list(), RECIPE_CANDY = list()))
|
||||
|
||||
/// Associative list of admin rank to colour. Set in config/rank_colours.txt
|
||||
GLOBAL_LIST_EMPTY(rank_colour_map)
|
||||
|
||||
#define EGG_LAYING_MESSAGES list("lays an egg.", "squats down and croons.", "begins making a huge racket.", "begins clucking raucously.")
|
||||
|
||||
@@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(cell_logs, list())
|
||||
GLOBAL_LIST_INIT(navigation_computers, list())
|
||||
|
||||
GLOBAL_LIST_INIT(all_areas, list())
|
||||
GLOBAL_LIST_INIT(all_unique_areas, list()) // List of all unique areas. AKA areas with there_can_be_many = FALSE
|
||||
GLOBAL_LIST_INIT(machines, list())
|
||||
GLOBAL_LIST_INIT(rcd_list, list()) //list of Rapid Construction Devices.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ GLOBAL_LIST_INIT(drinks, list("beer2","hot_coco","orangejuice","tomatojuice","li
|
||||
"booger","bloodymary","gargleblaster","bravebull","tequilasunrise","toxinsspecial",
|
||||
"beepskysmash","salglu_solution","irishcream","manlydorf","longislandicedtea",
|
||||
"moonshine","b52","irishcoffee","margarita","blackrussian","manhattan",
|
||||
"manhattan_proj","whiskeysoda","antifreeze","barefoot","snowwhite","demonsblood",
|
||||
"manhattan_proj","whiskeysoda","adminfreeze","antifreeze","barefoot","snowwhite","demonsblood",
|
||||
"vodkatonic","ginfizz","bahama_mama","singulo","sbiten","devilskiss","red_mead",
|
||||
"mead","iced_beer","grog","aloe","andalusia","alliescocktail","soy_latte",
|
||||
"cafe_latte","acidspit","amasec","neurotoxin","hippiesdelight","bananahonk",
|
||||
|
||||
@@ -11,8 +11,6 @@ GLOBAL_VAR(world_qdel_log)
|
||||
GLOBAL_PROTECT(world_qdel_log)
|
||||
GLOBAL_VAR(world_href_log)
|
||||
GLOBAL_PROTECT(world_href_log)
|
||||
GLOBAL_VAR(world_asset_log)
|
||||
GLOBAL_PROTECT(world_asset_log)
|
||||
GLOBAL_VAR(runtime_summary_log)
|
||||
GLOBAL_PROTECT(runtime_summary_log)
|
||||
GLOBAL_VAR(tgui_log)
|
||||
@@ -21,6 +19,8 @@ GLOBAL_VAR(http_log)
|
||||
GLOBAL_PROTECT(http_log)
|
||||
GLOBAL_VAR(sql_log)
|
||||
GLOBAL_PROTECT(sql_log)
|
||||
GLOBAL_VAR(chat_debug_log)
|
||||
GLOBAL_PROTECT(chat_debug_log)
|
||||
GLOBAL_VAR(round_id)
|
||||
GLOBAL_PROTECT(round_id)
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, S
|
||||
GLOBAL_LIST_INIT(alldirs2, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, NORTH, SOUTH, EAST, WEST))
|
||||
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
|
||||
|
||||
// This must exist early on or shit breaks bad
|
||||
GLOBAL_DATUM_INIT(using_map, /datum/map, new USING_MAP_DATUM)
|
||||
|
||||
GLOBAL_LIST(global_map) // This is the array of zlevels | list(list(1,5),list(4,3)) | becomes a 2D array of zlevels
|
||||
//Resulting sector map looks like
|
||||
//|_1_|_4_|
|
||||
|
||||
@@ -86,13 +86,9 @@ GLOBAL_VAR_INIT(copier_items_printed, 0)
|
||||
GLOBAL_VAR_INIT(copier_max_items, 300)
|
||||
GLOBAL_VAR_INIT(copier_items_printed_logged, FALSE)
|
||||
|
||||
|
||||
GLOBAL_VAR(map_name) // Self explanatory
|
||||
|
||||
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) // Station datacore, manifest, etc
|
||||
|
||||
GLOBAL_VAR_INIT(panic_bunker_enabled, FALSE) // Is the panic bunker enabled
|
||||
GLOBAL_VAR_INIT(pending_server_update, FALSE)
|
||||
|
||||
GLOBAL_LIST_EMPTY(ability_verbs) // Create-level abilities
|
||||
GLOBAL_LIST_INIT(pipe_colors, list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE))
|
||||
|
||||
@@ -24,6 +24,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_XENO_HOST" = TRAIT_XENO_HOST,
|
||||
"TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE,
|
||||
"TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE,
|
||||
"TRAIT_TELEKINESIS" = TRAIT_TELEKINESIS,
|
||||
"TRAIT_RESISTHEAT" = TRAIT_RESISTHEAT,
|
||||
"TRAIT_RESISTHEATHANDS" = TRAIT_RESISTHEATHANDS,
|
||||
"TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD,
|
||||
@@ -45,7 +46,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_DWARF" = TRAIT_DWARF,
|
||||
"TRAIT_SILENT_FOOTSTEPS" = TRAIT_SILENT_FOOTSTEPS,
|
||||
"TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE,
|
||||
"TRAIT_KISS_OF_DEATH" = TRAIT_KISS_OF_DEATH,
|
||||
|
||||
"TRAIT_COMIC_SANS" = TRAIT_COMIC_SANS,
|
||||
"TRAIT_NOFINGERPRINTS" = TRAIT_NOFINGERPRINTS,
|
||||
@@ -57,7 +57,12 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_NOGERMS" = TRAIT_NOGERMS,
|
||||
"TRAIT_NODECAY" = TRAIT_NODECAY,
|
||||
"TRAIT_NOEXAMINE" = TRAIT_NOEXAMINE,
|
||||
"TRAIT_NOPAIN" = TRAIT_NOPAIN)))
|
||||
"TRAIT_NOPAIN" = TRAIT_NOPAIN
|
||||
),
|
||||
/obj/item = list(
|
||||
"TRAIT_SHOW_WIRE_INFO" = TRAIT_SHOW_WIRE_INFO
|
||||
)
|
||||
))
|
||||
|
||||
/// value -> trait name, generated on use from trait_by_type global
|
||||
GLOBAL_LIST(trait_name_map)
|
||||
|
||||
@@ -215,11 +215,3 @@
|
||||
if(!ai_control_check(user))
|
||||
return
|
||||
toggle_light(user)
|
||||
|
||||
// AI-CONTROLLED SLIP GENERATOR IN AI CORE
|
||||
|
||||
/obj/machinery/ai_slipper/AICtrlClick(mob/living/silicon/ai/user) //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/AIAltClick() //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
|
||||
/obj/item/badminBook/attack_self(mob/living/user as mob)
|
||||
if(user.middleClickOverride)
|
||||
to_chat(user, "<span class='warning'>You try to draw power from the [src], but you cannot hold the power at this time!</span>")
|
||||
to_chat(user, "<span class='warning'>You try to draw power from [src], but you cannot hold the power at this time!</span>")
|
||||
return
|
||||
user.middleClickOverride = clickBehavior
|
||||
to_chat(user, "<span class='notice'>You draw a bit of power from the [src], you can use <b>middle click</b> or <b>alt click</b> to release the power!</span>")
|
||||
to_chat(user, "<span class='notice'>You draw a bit of power from [src], you can use <b>middle click</b> or <b>alt click</b> to release the power!</span>")
|
||||
|
||||
/datum/middleClickOverride/badminClicker
|
||||
var/summon_path = /obj/item/reagent_containers/food/snacks/cookie
|
||||
|
||||
@@ -169,16 +169,6 @@
|
||||
/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
|
||||
AICtrlClick(user)
|
||||
|
||||
|
||||
// AI SLIPPER
|
||||
|
||||
/obj/machinery/ai_slipper/BorgCtrlClick(mob/living/silicon/robot/user) //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/BorgAltClick(mob/living/silicon/robot/user) //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
|
||||
// TURRETCONTROL
|
||||
|
||||
/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
|
||||
|
||||
@@ -122,12 +122,12 @@
|
||||
icon_state = "too_much_oxy"
|
||||
|
||||
/obj/screen/alert/not_enough_nitro
|
||||
name = "Choking (No N)"
|
||||
name = "Choking (No N2)"
|
||||
desc = "You're not getting enough nitrogen. Find some good air before you pass out!"
|
||||
icon_state = "not_enough_nitro"
|
||||
|
||||
/obj/screen/alert/too_much_nitro
|
||||
name = "Choking (N)"
|
||||
name = "Choking (N2)"
|
||||
desc = "There's too much nitrogen in the air, and you're breathing it in! Find some good air before you pass out!"
|
||||
icon_state = "too_much_nitro"
|
||||
|
||||
|
||||
@@ -132,6 +132,8 @@
|
||||
if(isovermind(usr))
|
||||
var/mob/camera/blob/B = usr
|
||||
B.split_consciousness()
|
||||
if(B.split_used) // Destroys split proc if the split is succesfully used
|
||||
qdel(src)
|
||||
|
||||
/datum/hud/blob_overmind/New(mob/user)
|
||||
..()
|
||||
@@ -194,6 +196,8 @@
|
||||
using.screen_loc = ui_storage2
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/blob/Split()
|
||||
using.screen_loc = ui_acti
|
||||
static_inventory += using
|
||||
var/mob/camera/blob/B = user
|
||||
if(!B.is_offspring) // Checks if the blob is an offspring, to not create split button if it is
|
||||
using = new /obj/screen/blob/Split()
|
||||
using.screen_loc = ui_acti
|
||||
static_inventory += using
|
||||
|
||||
@@ -78,15 +78,6 @@
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
R.toggle_ionpulse()
|
||||
|
||||
/obj/screen/robot/panel
|
||||
name = "installed modules"
|
||||
icon_state = "panel"
|
||||
|
||||
/obj/screen/robot/panel/Click()
|
||||
if(issilicon(usr))
|
||||
var/mob/living/silicon/robot/R = usr
|
||||
R.installed_modules()
|
||||
|
||||
/obj/screen/robot/mov_intent
|
||||
name = "fast/slow toggle"
|
||||
icon_state = "running"
|
||||
@@ -224,16 +215,6 @@
|
||||
var/x = -4 //Start at CENTER-4,SOUTH+1
|
||||
var/y = 1
|
||||
|
||||
//Unfortunately adding the emag module to the list of modules has to be here. This is because a borg can
|
||||
//be emagged before they actually select a module. - or some situation can cause them to get a new module
|
||||
// - or some situation might cause them to get de-emagged or something.
|
||||
if(R.emagged || R.weapons_unlock)
|
||||
if(!(R.module.emag in R.module.modules))
|
||||
R.module.modules.Add(R.module.emag)
|
||||
else
|
||||
if(R.module.emag in R.module.modules)
|
||||
R.module.modules.Remove(R.module.emag)
|
||||
|
||||
for(var/atom/movable/A in R.module.modules)
|
||||
if( (A != R.module_state_1) && (A != R.module_state_2) && (A != R.module_state_3) )
|
||||
//Module is not currently active
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
if(HAS_TRAIT(src, TRAIT_LASEREYES) && a_intent == INTENT_HARM)
|
||||
LaserEyes(A)
|
||||
|
||||
if(dna.GetSEState(GLOB.teleblock))
|
||||
if(HAS_TRAIT(src, TRAIT_TELEKINESIS))
|
||||
A.attack_tk(src)
|
||||
|
||||
if(isturf(A) && get_dist(src, A) <= 1)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
/obj/item/attack_tk(mob/user)
|
||||
if(user.stat || !isturf(loc))
|
||||
return
|
||||
if(user.dna?.GetSEState(GLOB.teleblock) && !user.get_active_hand()) // both should already be true to get here
|
||||
if(HAS_TRAIT(user, TRAIT_TELEKINESIS) && !user.get_active_hand()) // both should already be true to get here
|
||||
var/obj/item/tk_grab/O = new(src)
|
||||
O.form_grab(user, src)
|
||||
else
|
||||
@@ -109,7 +109,7 @@
|
||||
if(!host || host != user)
|
||||
qdel(src)
|
||||
return
|
||||
if(!host.dna?.GetSEState(GLOB.teleblock))
|
||||
if(!HAS_TRAIT(host, TRAIT_TELEKINESIS))
|
||||
qdel(src)
|
||||
return
|
||||
if(isobj(target) && !isturf(target.loc))
|
||||
@@ -139,6 +139,12 @@
|
||||
|
||||
|
||||
else
|
||||
if(focus.buckled_mobs)
|
||||
to_chat(user, "<span class='notice'>This object is too heavy to move with something buckled to it!</span>")
|
||||
return
|
||||
if(length(focus.client_mobs_in_contents))
|
||||
to_chat(user, "<span class='notice'>This object is too heavy to move with something inside of it!</span>")
|
||||
return
|
||||
apply_focus_overlay()
|
||||
focus.throw_at(target, 10, 1, user)
|
||||
last_throw = world.time
|
||||
|
||||
@@ -275,6 +275,12 @@
|
||||
/// Enable auto profiler of rounds
|
||||
var/auto_profile = FALSE
|
||||
|
||||
// Enable map voting
|
||||
var/map_voting_enabled = FALSE
|
||||
|
||||
// 2FA auth host
|
||||
var/_2fa_auth_host = null
|
||||
|
||||
/datum/configuration/New()
|
||||
for(var/T in subtypesof(/datum/game_mode))
|
||||
var/datum/game_mode/M = T
|
||||
@@ -770,6 +776,10 @@
|
||||
max_client_cid_history = text2num(value)
|
||||
if("enable_auto_profiler")
|
||||
auto_profile = TRUE
|
||||
if("enable_map_voting")
|
||||
map_voting_enabled = TRUE
|
||||
if("2fa_host")
|
||||
_2fa_auth_host = value
|
||||
else
|
||||
log_config("Unknown setting in configuration: '[name]'")
|
||||
|
||||
@@ -925,3 +935,34 @@
|
||||
runnable_modes[M] = probabilities[M.config_tag]
|
||||
// to_chat(world, "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]")
|
||||
return runnable_modes
|
||||
|
||||
/datum/configuration/proc/load_rank_colour_map()
|
||||
var/list/lines = file2list("config/rank_colours.txt")
|
||||
|
||||
for(var/line in lines)
|
||||
// Skip newlines
|
||||
if(!length(line))
|
||||
continue
|
||||
// Skip comments
|
||||
if(line[1] == "#")
|
||||
continue
|
||||
|
||||
//Split the line at every " - "
|
||||
var/list/split_holder = splittext(line, " - ")
|
||||
if(!length(split_holder))
|
||||
continue
|
||||
|
||||
// Rank is before the " - "
|
||||
var/rank = split_holder[1]
|
||||
if(!rank)
|
||||
continue
|
||||
|
||||
// Color is after the " - "
|
||||
var/colour = ""
|
||||
if(length(split_holder) >= 2)
|
||||
colour = split_holder[2]
|
||||
|
||||
if(rank && colour)
|
||||
GLOB.rank_colour_map[rank] = colour
|
||||
else
|
||||
stack_trace("Invalid colour for rank '[rank]' in config/rank_colours.txt")
|
||||
|
||||
@@ -65,7 +65,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
sqlversion = versions[FV.key]
|
||||
|
||||
var/datum/db_query/query_feedback_save = SSdbcore.NewQuery({"
|
||||
INSERT DELAYED IGNORE INTO [format_table_name("feedback")] (datetime, round_id, key_name, key_type, version, json)
|
||||
INSERT IGNORE INTO [format_table_name("feedback")] (datetime, round_id, key_name, key_type, version, json)
|
||||
VALUES (NOW(), :rid, :keyname, :keytype, :version, :json)"}, list(
|
||||
"rid" = text2num(GLOB.round_id),
|
||||
"keyname" = FV.key,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
SUBSYSTEM_DEF(chat_pings)
|
||||
name = "Chat Pings"
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_INIT | RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME // ALL OF THEM
|
||||
wait = 30 SECONDS // Chat pings every 30 seconds
|
||||
/// List of all held chat datums
|
||||
var/list/datum/chatOutput/chat_datums = list() // Do NOT put this in Initialize(). You will cause issues.
|
||||
|
||||
/datum/controller/subsystem/chat_pings/fire(resumed)
|
||||
for(var/datum/chatOutput/CO as anything in chat_datums)
|
||||
CO.updatePing()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/chat_pings/stat_entry()
|
||||
..("P: [length(chat_datums)]")
|
||||
@@ -193,7 +193,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
if(!IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_round_end = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result, station_name = :station_name WHERE id = :round_id",
|
||||
"UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result WHERE id = :round_id",
|
||||
list("game_mode_result" = SSticker.mode_result, "station_name" = station_name(), "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_end.Execute()
|
||||
|
||||
@@ -12,8 +12,11 @@ SUBSYSTEM_DEF(http)
|
||||
/// Total requests the SS has processed in a round
|
||||
var/total_requests
|
||||
|
||||
/datum/controller/subsystem/http/Initialize(start_timeofday)
|
||||
/datum/controller/subsystem/http/PreInit()
|
||||
. = ..()
|
||||
rustg_create_async_http_client() // Open the door
|
||||
|
||||
/datum/controller/subsystem/http/Initialize(start_timeofday)
|
||||
active_async_requests = list()
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -1,31 +1,51 @@
|
||||
SUBSYSTEM_DEF(mapping)
|
||||
name = "Mapping"
|
||||
init_order = INIT_ORDER_MAPPING // 9
|
||||
flags = SS_NO_FIRE
|
||||
name = "Mapping"
|
||||
init_order = INIT_ORDER_MAPPING // 9
|
||||
flags = SS_NO_FIRE
|
||||
/// What map datum are we using
|
||||
var/datum/map/map_datum
|
||||
/// What map will be used next round
|
||||
var/datum/map/next_map
|
||||
|
||||
// This has to be here because world/New() uses [station_name()], which looks this datum up
|
||||
/datum/controller/subsystem/mapping/PreInit()
|
||||
. = ..()
|
||||
if(map_datum) // Dont do this again if we are recovering
|
||||
return
|
||||
if(fexists("data/next_map.txt"))
|
||||
var/list/lines = file2list("data/next_map.txt")
|
||||
// Check its valid
|
||||
try
|
||||
map_datum = text2path(lines[1])
|
||||
map_datum = new map_datum
|
||||
catch
|
||||
map_datum = new /datum/map/cyberiad // Assume cyberiad if non-existent
|
||||
fdel("data/next_map.txt") // Remove to avoid the same map existing forever
|
||||
else
|
||||
map_datum = new /datum/map/cyberiad // Assume cyberiad if non-existent
|
||||
|
||||
/datum/controller/subsystem/mapping/Shutdown()
|
||||
if(next_map) // Save map for next round
|
||||
var/F = file("data/next_map.txt")
|
||||
F << next_map.type
|
||||
|
||||
/datum/controller/subsystem/mapping/Initialize(timeofday)
|
||||
// Load all Z level templates
|
||||
preloadTemplates()
|
||||
|
||||
// Load the station
|
||||
loadStation()
|
||||
|
||||
// Load lavaland
|
||||
loadLavaland()
|
||||
|
||||
// Pick a random away mission.
|
||||
if(!config.disable_away_missions)
|
||||
load_away_mission()
|
||||
|
||||
// Seed space ruins
|
||||
if(!config.disable_space_ruins)
|
||||
// load in extra levels of space ruins
|
||||
var/load_zlevels_timer = start_watch()
|
||||
log_startup_progress("Creating random space levels...")
|
||||
var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max)
|
||||
for(var/i = 1, i <= num_extra_space, i++)
|
||||
GLOB.space_manager.add_new_zlevel("Ruin Area #[i]", linkage = CROSSLINKED, traits = list(REACHABLE, SPAWN_RUINS))
|
||||
log_startup_progress("Loaded random space levels in [stop_watch(load_zlevels_timer)]s.")
|
||||
|
||||
// Now spawn ruins, random budget between 20 and 30 for all zlevels combined.
|
||||
// While this may seem like a high number, the amount of ruin Z levels can be anywhere between 3 and 7.
|
||||
// Note that this budget is not split evenly accross all zlevels
|
||||
log_startup_progress("Seeding ruins...")
|
||||
var/seed_ruins_timer = start_watch()
|
||||
seedRuins(levels_by_trait(SPAWN_RUINS), rand(20, 30), /area/space, GLOB.space_ruins_templates)
|
||||
log_startup_progress("Successfully seeded ruins in [stop_watch(seed_ruins_timer)]s.")
|
||||
handleRuins()
|
||||
|
||||
// Makes a blank space level for the sake of randomness
|
||||
GLOB.space_manager.add_new_zlevel("Empty Area", linkage = CROSSLINKED, traits = list(REACHABLE))
|
||||
@@ -63,12 +83,6 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
GLOB.ghostteleportlocs = sortAssoc(GLOB.ghostteleportlocs)
|
||||
|
||||
// Map name. Break these down into SSmapping controller vars instaed of GLOBs at some point
|
||||
if(GLOB.using_map && GLOB.using_map.name)
|
||||
GLOB.map_name = "[GLOB.using_map.name]"
|
||||
else
|
||||
GLOB.map_name = "Unknown"
|
||||
|
||||
// World name
|
||||
if(config && config.server_name)
|
||||
world.name = "[config.server_name]: [station_name()]"
|
||||
@@ -77,6 +91,56 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
return ..()
|
||||
|
||||
// Do not confuse with seedRuins()
|
||||
/datum/controller/subsystem/mapping/proc/handleRuins()
|
||||
// load in extra levels of space ruins
|
||||
var/load_zlevels_timer = start_watch()
|
||||
log_startup_progress("Creating random space levels...")
|
||||
var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max)
|
||||
for(var/i in 1 to num_extra_space)
|
||||
GLOB.space_manager.add_new_zlevel("Ruin Area #[i]", linkage = CROSSLINKED, traits = list(REACHABLE, SPAWN_RUINS))
|
||||
log_startup_progress("Loaded random space levels in [stop_watch(load_zlevels_timer)]s.")
|
||||
|
||||
// Now spawn ruins, random budget between 20 and 30 for all zlevels combined.
|
||||
// While this may seem like a high number, the amount of ruin Z levels can be anywhere between 3 and 7.
|
||||
// Note that this budget is not split evenly accross all zlevels
|
||||
log_startup_progress("Seeding ruins...")
|
||||
var/seed_ruins_timer = start_watch()
|
||||
seedRuins(levels_by_trait(SPAWN_RUINS), rand(20, 30), /area/space, GLOB.space_ruins_templates)
|
||||
log_startup_progress("Successfully seeded ruins in [stop_watch(seed_ruins_timer)]s.")
|
||||
|
||||
// Loads in the station
|
||||
/datum/controller/subsystem/mapping/proc/loadStation()
|
||||
ASSERT(map_datum.map_path)
|
||||
if(!fexists(map_datum.map_path))
|
||||
// Make a VERY OBVIOUS error
|
||||
to_chat(world, "<span class='narsie'>ERROR: The path specified for the map to load is invalid. No station has been loaded!</span>")
|
||||
return
|
||||
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading [map_datum.fluff_name]...")
|
||||
// This should always be Z2, but you never know
|
||||
var/map_z_level = GLOB.space_manager.add_new_zlevel(MAIN_STATION, linkage = CROSSLINKED, traits = list(STATION_LEVEL, STATION_CONTACT, REACHABLE, AI_OK))
|
||||
GLOB.maploader.load_map(file(map_datum.map_path), z_offset = map_z_level)
|
||||
log_startup_progress("Loaded [map_datum.fluff_name] in [stop_watch(watch)]s")
|
||||
|
||||
// Save station name in the DB
|
||||
if(!SSdbcore.IsConnected())
|
||||
return
|
||||
var/datum/db_query/query_set_map = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET start_datetime=NOW(), map_name=:mapname, station_name=:stationname WHERE id=:round_id",
|
||||
list("mapname" = map_datum.technical_name, "stationname" = map_datum.fluff_name, "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_set_map.Execute(async = FALSE) // This happens during a time of intense server lag, so should be non-async
|
||||
qdel(query_set_map)
|
||||
|
||||
// Loads in lavaland
|
||||
/datum/controller/subsystem/mapping/proc/loadLavaland()
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading Lavaland...")
|
||||
var/lavaland_z_level = GLOB.space_manager.add_new_zlevel(MINING, linkage = SELFLOOPING, traits = list(ORE_LEVEL, REACHABLE, STATION_CONTACT, HAS_WEATHER, AI_OK))
|
||||
GLOB.maploader.load_map(file("_maps/map_files/generic/Lavaland.dmm"), z_offset = lavaland_z_level)
|
||||
log_startup_progress("Loaded Lavaland in [stop_watch(watch)]s")
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins)
|
||||
if(!z_levels || !z_levels.len)
|
||||
|
||||
@@ -135,8 +135,6 @@ SUBSYSTEM_DEF(shuttle)
|
||||
to_chat(user, "The emergency shuttle has been disabled by Centcom.")
|
||||
return
|
||||
|
||||
call_reason = trim(html_encode(call_reason))
|
||||
|
||||
if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH)
|
||||
to_chat(user, "Reason is too short. [CALL_SHUTTLE_REASON_LENGTH] character minimum.")
|
||||
return
|
||||
|
||||
@@ -16,8 +16,6 @@ SUBSYSTEM_DEF(title)
|
||||
else if(L.len > 1)
|
||||
if(use_rare_screens && lowertext(L[1]) == "rare")
|
||||
title_screens += S
|
||||
else if(GLOB.using_map && (lowertext(L[1]) == lowertext(GLOB.using_map.name)))
|
||||
title_screens += S
|
||||
|
||||
if(!isemptylist(title_screens))
|
||||
if(length(title_screens) > 1)
|
||||
|
||||
@@ -177,6 +177,16 @@ SUBSYSTEM_DEF(vote)
|
||||
if("crew_transfer")
|
||||
if(. == "Initiate Crew Transfer")
|
||||
init_shift_change(null, 1)
|
||||
if("map")
|
||||
// Find target map.
|
||||
var/datum/map/top_voted_map
|
||||
for(var/x in subtypesof(/datum/map))
|
||||
var/datum/map/M = x
|
||||
// Set top voted map
|
||||
if(. == "[initial(M.fluff_name)] ([initial(M.technical_name)])")
|
||||
top_voted_map = M
|
||||
to_chat(world, "<font color='purple'>Map for next round: [initial(top_voted_map.fluff_name)] ([initial(top_voted_map.technical_name)])</font>")
|
||||
SSmapping.next_map = new top_voted_map
|
||||
|
||||
|
||||
if(restart)
|
||||
@@ -197,7 +207,7 @@ SUBSYSTEM_DEF(vote)
|
||||
return vote
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key)
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, code_invoked = FALSE)
|
||||
if(!mode)
|
||||
if(started_time != null && !check_rights(R_ADMIN))
|
||||
var/next_allowed_time = (started_time + config.vote_delay)
|
||||
@@ -223,6 +233,14 @@ SUBSYSTEM_DEF(vote)
|
||||
return 0
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
if("map")
|
||||
if(!(check_rights(R_SERVER) || code_invoked))
|
||||
return FALSE
|
||||
question = "Map for next round"
|
||||
for(var/x in subtypesof(/datum/map))
|
||||
var/datum/map/M = x
|
||||
choices.Add("[initial(M.fluff_name)] ([initial(M.technical_name)])")
|
||||
|
||||
if("custom")
|
||||
question = html_encode(input(usr,"What is the vote for?") as text|null)
|
||||
if(!question) return 0
|
||||
@@ -248,11 +266,7 @@ SUBSYSTEM_DEF(vote)
|
||||
<a href='?src=[UID()];vote=open'>Click here or type vote to place your vote.</a>
|
||||
You have [config.vote_period/10] seconds to vote.</font>"})
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
|
||||
if("gamemode")
|
||||
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
|
||||
if("custom")
|
||||
if("crew_transfer", "gamemode", "custom", "map")
|
||||
SEND_SOUND(world, sound('sound/ambience/alarm4.ogg'))
|
||||
if(mode == "gamemode" && SSticker.ticker_going)
|
||||
SSticker.ticker_going = FALSE
|
||||
@@ -321,6 +335,12 @@ SUBSYSTEM_DEF(vote)
|
||||
if(admin)
|
||||
dat += "\t(<a href='?src=[UID()];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
|
||||
|
||||
dat += "</li><li>"
|
||||
if(admin)
|
||||
dat += "<a href='?src=[UID()];vote=map'>Map</a>"
|
||||
else
|
||||
dat += "<font color='grey'>Map (Disallowed)</font>"
|
||||
|
||||
dat += "</li>"
|
||||
//custom
|
||||
if(admin)
|
||||
@@ -381,6 +401,9 @@ SUBSYSTEM_DEF(vote)
|
||||
if("gamemode")
|
||||
if(config.allow_vote_mode || admin)
|
||||
initiate_vote("gamemode",usr.key)
|
||||
if("map")
|
||||
if(admin)
|
||||
initiate_vote("map", usr.key)
|
||||
if("crew_transfer")
|
||||
if(config.allow_vote_restart || admin)
|
||||
initiate_vote("crew_transfer",usr.key)
|
||||
|
||||
@@ -383,6 +383,9 @@
|
||||
/datum/action/item_action/hands_free/activate
|
||||
name = "Activate"
|
||||
|
||||
/datum/action/item_action/hands_free/activate/always
|
||||
check_flags = null
|
||||
|
||||
/datum/action/item_action/toggle_research_scanner
|
||||
name = "Toggle Research Scanner"
|
||||
button_icon_state = "scan_mode"
|
||||
@@ -426,6 +429,7 @@
|
||||
desc = "Activates the jump boot's internal propulsion system, allowing the user to dash over 4-wide gaps."
|
||||
icon_icon = 'icons/mob/actions/actions.dmi'
|
||||
button_icon_state = "jetboot"
|
||||
use_itemicon = FALSE
|
||||
|
||||
///prset for organ actions
|
||||
/datum/action/item_action/organ_action
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/beam/proc/Draw()
|
||||
var/Angle = round(Get_Angle(origin,target))
|
||||
var/Angle = round(get_angle(origin, target))
|
||||
|
||||
var/matrix/rot_matrix = matrix()
|
||||
rot_matrix.Turn(Angle)
|
||||
|
||||
@@ -130,13 +130,13 @@
|
||||
|
||||
/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt, multiplier = 1)
|
||||
if(isnull(amt))
|
||||
amt = S.amount
|
||||
amt = S.get_amount()
|
||||
|
||||
if(amt <= 0)
|
||||
return FALSE
|
||||
|
||||
if(amt > S.amount)
|
||||
amt = S.amount
|
||||
if(amt > S.get_amount())
|
||||
amt = S.get_amount()
|
||||
|
||||
var/material_amt = get_item_material_amount(S)
|
||||
if(!material_amt)
|
||||
|
||||
@@ -5,129 +5,6 @@
|
||||
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
|
||||
var/list/locked = list()
|
||||
|
||||
/datum/datacore/proc/get_manifest(monochrome, OOC)
|
||||
var/list/heads = new()
|
||||
var/list/sec = new()
|
||||
var/list/eng = new()
|
||||
var/list/med = new()
|
||||
var/list/sci = new()
|
||||
var/list/ser = new()
|
||||
var/list/sup = new()
|
||||
var/list/bot = new()
|
||||
var/list/misc = new()
|
||||
var/list/isactive = new()
|
||||
var/dat = {"
|
||||
<head><style>
|
||||
.manifest {border-collapse:collapse;}
|
||||
.manifest td, th {border:1px solid [monochrome?"black":"#DEF; background-color:white; color:black"]; padding:.25em}
|
||||
.manifest th {height: 2em; [monochrome?"border-top-width: 3px":"background-color: #48C; color:white"]}
|
||||
.manifest tr.head th { [monochrome?"border-top-width: 1px":"background-color: #488;"] }
|
||||
.manifest td:first-child {text-align:right}
|
||||
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: #DEF"]}
|
||||
</style></head>
|
||||
<table class="manifest" width='350px'>
|
||||
<tr class='head'><th>Name</th><th>Rank</th><th>Activity</th></tr>
|
||||
"}
|
||||
var/even = 0
|
||||
// sort mobs
|
||||
for(var/datum/data/record/t in GLOB.data_core.general)
|
||||
var/name = t.fields["name"]
|
||||
var/rank = t.fields["rank"]
|
||||
var/real_rank = t.fields["real_rank"]
|
||||
if(OOC)
|
||||
var/activetext = "Inactive"
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.real_name != name)
|
||||
continue
|
||||
if(H.client && H.client.inactivity <= 6000)
|
||||
activetext = "Active"
|
||||
break
|
||||
if(isLivingSSD(H))
|
||||
activetext = "SSD"
|
||||
break
|
||||
isactive[name] = activetext
|
||||
else
|
||||
isactive[name] = t.fields["p_stat"]
|
||||
var/department = 0
|
||||
if(real_rank in GLOB.command_positions)
|
||||
heads[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.security_positions)
|
||||
sec[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.engineering_positions)
|
||||
eng[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.medical_positions)
|
||||
med[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.science_positions)
|
||||
sci[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.service_positions)
|
||||
ser[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.supply_positions)
|
||||
sup[name] = rank
|
||||
department = 1
|
||||
if(real_rank in GLOB.nonhuman_positions)
|
||||
bot[name] = rank
|
||||
department = 1
|
||||
if(!department && !(name in heads))
|
||||
misc[name] = rank
|
||||
if(heads.len > 0)
|
||||
dat += "<tr><th colspan=3>Heads</th></tr>"
|
||||
for(var/name in heads)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[heads[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sec.len > 0)
|
||||
dat += "<tr><th colspan=3>Security</th></tr>"
|
||||
for(var/name in sec)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sec[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(eng.len > 0)
|
||||
dat += "<tr><th colspan=3>Engineering</th></tr>"
|
||||
for(var/name in eng)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[eng[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(med.len > 0)
|
||||
dat += "<tr><th colspan=3>Medical</th></tr>"
|
||||
for(var/name in med)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[med[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sci.len > 0)
|
||||
dat += "<tr><th colspan=3>Science</th></tr>"
|
||||
for(var/name in sci)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sci[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(ser.len > 0)
|
||||
dat += "<tr><th colspan=3>Service</th></tr>"
|
||||
for(var/name in ser)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[ser[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(sup.len > 0)
|
||||
dat += "<tr><th colspan=3>Supply</th></tr>"
|
||||
for(var/name in sup)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[sup[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(bot.len > 0)
|
||||
dat += "<tr><th colspan=3>Silicon</th></tr>"
|
||||
for(var/name in bot)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[bot[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
if(misc.len > 0)
|
||||
dat += "<tr><th colspan=3>Miscellaneous</th></tr>"
|
||||
for(var/name in misc)
|
||||
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[misc[name]]</td><td>[isactive[name]]</td></tr>"
|
||||
even = !even
|
||||
|
||||
dat += "</table>"
|
||||
dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
|
||||
dat = replacetext(dat, "\t", "")
|
||||
return dat
|
||||
|
||||
|
||||
/*
|
||||
We can't just insert in HTML into the TGUI so we need the raw data to play with.
|
||||
Instead of creating this list over and over when someone leaves their PDA open to the page
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
var/list/stage3 = list("You feel utterly plain.")
|
||||
var/list/stage4 = list("You feel white bread.")
|
||||
var/list/stage5 = list("Oh the humanity!")
|
||||
var/transformation_text = null
|
||||
var/new_form = /mob/living/carbon/human
|
||||
|
||||
/datum/disease/transformation/stage_act()
|
||||
@@ -44,6 +45,8 @@
|
||||
return
|
||||
if(affected_mob.notransform)
|
||||
return
|
||||
if(transformation_text)
|
||||
to_chat(affected_mob, transformation_text)
|
||||
affected_mob.notransform = 1
|
||||
affected_mob.canmove = 0
|
||||
affected_mob.icon = null
|
||||
@@ -243,4 +246,5 @@
|
||||
stage3 = list("<span class='danger'>Your appendages are melting away.</span>", "<span class='danger'>Your limbs begin to lose their shape.</span>")
|
||||
stage4 = list("<span class='danger'>You're ravenous.</span>")
|
||||
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
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
/datum/construction/proc/custom_action(step, used_atom, user)
|
||||
if(istype(used_atom, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = used_atom
|
||||
if(C.amount<4)
|
||||
if(C.get_amount() < 4)
|
||||
to_chat(user, ("<span class='warning'>There's not enough cable to finish the task.</span>"))
|
||||
return 0
|
||||
else
|
||||
@@ -55,7 +55,7 @@
|
||||
playsound(holder, C.usesound, 50, 1)
|
||||
else if(istype(used_atom, /obj/item/stack))
|
||||
var/obj/item/stack/S = used_atom
|
||||
if(S.amount < 5)
|
||||
if(S.get_amount() < 5)
|
||||
to_chat(user, ("<span class='warning'>There's not enough material in this stack.</span>"))
|
||||
return 0
|
||||
else
|
||||
@@ -113,7 +113,7 @@
|
||||
// STACKS
|
||||
if(istype(used_atom,/obj/item/stack))
|
||||
var/obj/item/stack/stack=used_atom
|
||||
if(stack.amount < amount)
|
||||
if(stack.get_amount() < amount)
|
||||
to_chat(user, "<span class='warning'>You don't have enough [stack]! You need at least [amount].</span>")
|
||||
return 0
|
||||
stack.use(amount)
|
||||
|
||||
+12
-38
@@ -1375,46 +1375,20 @@
|
||||
switch(href_list["silicon"])
|
||||
if("unemag")
|
||||
var/mob/living/silicon/robot/R = current
|
||||
if(istype(R))
|
||||
R.emagged = 0
|
||||
if(R.module)
|
||||
if(R.activated(R.module.emag))
|
||||
R.module_active = null
|
||||
if(R.module_state_1 == R.module.emag)
|
||||
R.module_state_1 = null
|
||||
R.contents -= R.module.emag
|
||||
else if(R.module_state_2 == R.module.emag)
|
||||
R.module_state_2 = null
|
||||
R.contents -= R.module.emag
|
||||
else if(R.module_state_3 == R.module.emag)
|
||||
R.module_state_3 = null
|
||||
R.contents -= R.module.emag
|
||||
R.clear_supplied_laws()
|
||||
R.laws = new /datum/ai_laws/crewsimov
|
||||
log_admin("[key_name(usr)] has un-emagged [key_name(current)]")
|
||||
message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]")
|
||||
if(!istype(R))
|
||||
return
|
||||
R.unemag()
|
||||
log_admin("[key_name(usr)] has un-emagged [key_name(current)]")
|
||||
message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]")
|
||||
|
||||
if("unemagcyborgs")
|
||||
if(isAI(current))
|
||||
var/mob/living/silicon/ai/ai = current
|
||||
for(var/mob/living/silicon/robot/R in ai.connected_robots)
|
||||
R.emagged = 0
|
||||
if(R.module)
|
||||
if(R.activated(R.module.emag))
|
||||
R.module_active = null
|
||||
if(R.module_state_1 == R.module.emag)
|
||||
R.module_state_1 = null
|
||||
R.contents -= R.module.emag
|
||||
else if(R.module_state_2 == R.module.emag)
|
||||
R.module_state_2 = null
|
||||
R.contents -= R.module.emag
|
||||
else if(R.module_state_3 == R.module.emag)
|
||||
R.module_state_3 = null
|
||||
R.contents -= R.module.emag
|
||||
R.clear_supplied_laws()
|
||||
R.laws = new /datum/ai_laws/crewsimov
|
||||
log_admin("[key_name(usr)] has unemagged [key_name(ai)]'s cyborgs")
|
||||
message_admins("[key_name_admin(usr)] has unemagged [key_name_admin(ai)]'s cyborgs")
|
||||
if(!isAI(current))
|
||||
return
|
||||
var/mob/living/silicon/ai/ai = current
|
||||
for(var/mob/living/silicon/robot/R in ai.connected_robots)
|
||||
R.unemag()
|
||||
log_admin("[key_name(usr)] has unemagged [key_name(ai)]'s cyborgs")
|
||||
message_admins("[key_name_admin(usr)] has unemagged [key_name_admin(ai)]'s cyborgs")
|
||||
|
||||
else if(href_list["common"])
|
||||
switch(href_list["common"])
|
||||
|
||||
@@ -111,6 +111,8 @@
|
||||
|
||||
for(var/path in backpack_contents)
|
||||
var/number = backpack_contents[path]
|
||||
if(!number)
|
||||
number = 1
|
||||
for(var/i in 1 to number)
|
||||
H.equip_or_collect(new path(H), slot_in_backpack)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/datum/outfit/admin/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(!visualsOnly)
|
||||
if(!visualsOnly && H.mind)
|
||||
H.mind.assigned_role = name
|
||||
H.job = name
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
shoes = /obj/item/clothing/shoes/magboots/syndie
|
||||
r_pocket = /obj/item/radio/uplink/nuclear
|
||||
l_pocket = /obj/item/pinpointer/advpinpointer
|
||||
l_hand = /obj/item/tank/jetpack/oxygen/harness
|
||||
l_hand = /obj/item/tank/internals/oxygen/red
|
||||
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/survival_syndi = 1,
|
||||
@@ -627,6 +627,10 @@
|
||||
/obj/item/implanter/death_alarm = 1,
|
||||
)
|
||||
|
||||
implants = list(/obj/item/implant/mindshield,
|
||||
/obj/item/implant/death_alarm
|
||||
)
|
||||
|
||||
/datum/outfit/admin/solgov_rep/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(visualsOnly)
|
||||
@@ -634,33 +638,44 @@
|
||||
|
||||
var/obj/item/card/id/I = H.wear_id
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, get_all_accesses(), name, "lifetimeid")
|
||||
apply_to_card(I, H, get_all_centcom_access(), name, "lifetimeid")
|
||||
I.assignment = "Solar Federation Representative"
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
|
||||
/datum/outfit/admin/solgov
|
||||
name = "Solar Federation Marine"
|
||||
|
||||
uniform = /obj/item/clothing/under/solgov
|
||||
suit = /obj/item/clothing/suit/armor/bulletproof
|
||||
back = /obj/item/storage/backpack/security
|
||||
belt = /obj/item/storage/belt/military/assault
|
||||
head = /obj/item/clothing/head/soft/solgov
|
||||
glasses = /obj/item/clothing/glasses/hud/security/night
|
||||
belt = /obj/item/storage/belt/military/assault/marines/full
|
||||
head = /obj/item/clothing/head/soft/solgov/marines
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
l_ear = /obj/item/radio/headset/ert
|
||||
id = /obj/item/card/id
|
||||
l_hand = /obj/item/gun/projectile/automatic/ar
|
||||
l_hand = /obj/item/gun/projectile/automatic/shotgun/bulldog
|
||||
suit_store = /obj/item/gun/projectile/automatic/pistol/m1911
|
||||
r_pocket = /obj/item/flashlight/seclite
|
||||
pda = /obj/item/pda
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/responseteam = 1,
|
||||
/obj/item/ammo_box/magazine/m556 = 3,
|
||||
/obj/item/clothing/shoes/magboots = 1,
|
||||
/obj/item/gun/projectile/automatic/pistol/m1911 = 1,
|
||||
/obj/item/ammo_box/magazine/m45 = 2
|
||||
/obj/item/whetstone = 1,
|
||||
/obj/item/clothing/mask/gas/explorer/marines = 1,
|
||||
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1
|
||||
)
|
||||
var/is_tsf_lieutenant = FALSE
|
||||
cybernetic_implants = list(
|
||||
/obj/item/organ/internal/cyberimp/arm/flash,
|
||||
/obj/item/organ/internal/cyberimp/chest/nutriment,
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/security
|
||||
)
|
||||
implants = list(/obj/item/implant/mindshield,
|
||||
/obj/item/implant/death_alarm
|
||||
)
|
||||
|
||||
var/is_solgov_lieutenant = FALSE
|
||||
|
||||
|
||||
/datum/outfit/admin/solgov/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
@@ -668,31 +683,80 @@
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
if(is_tsf_lieutenant)
|
||||
if(is_solgov_lieutenant)
|
||||
H.real_name = "Lieutenant [pick(GLOB.last_names)]"
|
||||
else
|
||||
H.real_name = "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(GLOB.last_names)]"
|
||||
H.name = H.real_name
|
||||
var/obj/item/card/id/I = H.wear_id
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, get_all_accesses(), name, "lifetimeid")
|
||||
I.assignment = name
|
||||
if(istype(I) && is_solgov_lieutenant)
|
||||
apply_to_card(I, H, get_centcom_access("Emergency Response Team Leader"), name, "lifetimeid")
|
||||
else if(istype(I))
|
||||
apply_to_card(I, H, get_centcom_access("Emergency Response Team Member"), name, "lifetimeid")
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
/datum/outfit/admin/solgov/lieutenant
|
||||
name = "Solar Federation Lieutenant"
|
||||
|
||||
uniform = /obj/item/clothing/under/solgov/command
|
||||
head = /obj/item/clothing/head/soft/solgov/command
|
||||
head = /obj/item/clothing/head/beret/solgov/command
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
back = /obj/item/storage/backpack/satchel
|
||||
l_ear = /obj/item/radio/headset/ert/alt/commander
|
||||
l_hand = null
|
||||
belt = /obj/item/melee/baton/loaded
|
||||
suit_store = /obj/item/gun/projectile/automatic/pistol/deagle
|
||||
l_pocket = /obj/item/pinpointer/advpinpointer
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/responseteam = 1,
|
||||
/obj/item/melee/classic_baton/telescopic = 1,
|
||||
/obj/item/storage/box/handcuffs = 1,
|
||||
/obj/item/clothing/shoes/magboots/advance = 1,
|
||||
/obj/item/gun/projectile/automatic/pistol/deagle = 1,
|
||||
/obj/item/ammo_box/magazine/m50 = 2
|
||||
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1,
|
||||
/obj/item/clothing/mask/gas/explorer/marines = 1,
|
||||
/obj/item/ammo_box/magazine/m50 = 3
|
||||
)
|
||||
is_tsf_lieutenant = TRUE
|
||||
is_solgov_lieutenant = TRUE
|
||||
|
||||
/datum/outfit/admin/solgov/elite
|
||||
name = "Solar Federation Specops Marine"
|
||||
uniform = /obj/item/clothing/under/solgov/elite
|
||||
head = /obj/item/clothing/head/soft/solgov/marines/elite
|
||||
belt = /obj/item/storage/belt/military/assault/marines/elite/full
|
||||
l_hand = /obj/item/gun/projectile/automatic/ar
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/responseteam = 1,
|
||||
/obj/item/clothing/shoes/magboots/advance = 1,
|
||||
/obj/item/whetstone = 1,
|
||||
/obj/item/clothing/mask/gas/explorer/marines = 1,
|
||||
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1
|
||||
)
|
||||
cybernetic_implants = list(
|
||||
/obj/item/organ/internal/cyberimp/eyes/hud/security,
|
||||
/obj/item/organ/internal/cyberimp/chest/nutriment,
|
||||
/obj/item/organ/internal/cyberimp/brain/anti_stun/hardened,
|
||||
/obj/item/organ/internal/cyberimp/arm/flash,
|
||||
/obj/item/organ/internal/eyes/cybernetic/shield
|
||||
)
|
||||
/datum/outfit/admin/solgov/elite/lieutenant
|
||||
name = "Solar Federation Specops Lieutenant"
|
||||
uniform = /obj/item/clothing/under/solgov/command/elite
|
||||
head = /obj/item/clothing/head/beret/solgov/command/elite
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
back = /obj/item/storage/backpack/satchel
|
||||
belt = /obj/item/melee/baton/loaded
|
||||
l_hand = null
|
||||
suit_store = /obj/item/gun/projectile/automatic/pistol/deagle
|
||||
l_pocket = /obj/item/pinpointer/advpinpointer
|
||||
l_ear = /obj/item/radio/headset/ert/alt/commander
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/responseteam = 1,
|
||||
/obj/item/storage/box/handcuffs = 1,
|
||||
/obj/item/clothing/shoes/magboots/advance = 1,
|
||||
/obj/item/clothing/mask/gas/explorer/marines = 1,
|
||||
/obj/item/reagent_containers/hypospray/autoinjector/survival = 1,
|
||||
/obj/item/ammo_box/magazine/m50 = 3
|
||||
)
|
||||
is_solgov_lieutenant = TRUE
|
||||
|
||||
/datum/outfit/admin/sol_trader
|
||||
name = "Sol Trader"
|
||||
@@ -720,6 +784,7 @@
|
||||
var/obj/item/card/id/I = H.wear_id
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, list(ACCESS_TRADE_SOL, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS), name)
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
/datum/outfit/admin/chrono
|
||||
name = "Chrono Legionnaire"
|
||||
@@ -1158,3 +1223,68 @@
|
||||
var/obj/item/radio/headset/R = H.l_ear
|
||||
if(istype(R))
|
||||
R.flags |= NODROP
|
||||
|
||||
/datum/outfit/admin/honksquad
|
||||
name = "Honksquad"
|
||||
|
||||
uniform = /obj/item/clothing/under/rank/clown
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat
|
||||
back = /obj/item/storage/backpack/clown
|
||||
id = /obj/item/card/id/clown
|
||||
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/survival = 1,
|
||||
/obj/item/bikehorn = 1,
|
||||
/obj/item/stamp/clown = 1,
|
||||
/obj/item/toy/crayon/rainbow = 1,
|
||||
/obj/item/reagent_containers/spray/waterflower = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana = 1,
|
||||
)
|
||||
|
||||
shoes = /obj/item/clothing/shoes/clown_shoes
|
||||
suit = /obj/item/clothing/suit/storage/det_suit
|
||||
pda = /obj/item/pda/clown
|
||||
l_ear = /obj/item/radio/headset
|
||||
r_pocket = /obj/item/reagent_containers/food/pill/patch/jestosterone
|
||||
|
||||
/datum/outfit/admin/honksquad/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(H.gender == FEMALE)
|
||||
uniform = /obj/item/clothing/under/rank/clown/sexy
|
||||
mask = /obj/item/clothing/mask/gas/clown_hat/sexy
|
||||
|
||||
if(prob(50))
|
||||
// You have to do it like this to make it work with assoc lists without a runtime.
|
||||
// Trust me.
|
||||
backpack_contents.Add(/obj/item/gun/energy/clown)
|
||||
backpack_contents[/obj/item/gun/energy/clown] = 1 // Amount. Not boolean. Do not TRUE this. You turkey.
|
||||
else
|
||||
backpack_contents.Add(/obj/item/gun/throw/piecannon)
|
||||
backpack_contents[/obj/item/gun/throw/piecannon] = 1
|
||||
|
||||
/datum/outfit/admin/honksquad/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
// Setup their clumsy gene
|
||||
H.dna.SetSEState(GLOB.clumsyblock, TRUE)
|
||||
H.check_mutations = TRUE
|
||||
|
||||
// Setup their headset
|
||||
var/obj/item/radio/R = H.l_ear
|
||||
if(istype(R))
|
||||
R.set_frequency(DTH_FREQ) // Clowns can be part of "special operations"
|
||||
|
||||
// And their PDA
|
||||
var/obj/item/pda/P = H.wear_pda
|
||||
if(istype(P))
|
||||
P.owner = H.real_name
|
||||
P.ownjob = "Clown"
|
||||
P.name = "PDA-[H.real_name] ([P.ownjob])"
|
||||
|
||||
// And their ID
|
||||
var/obj/item/card/id/I = H.wear_id
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, list(ACCESS_CLOWN), "Clown")
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone
|
||||
name = "Summon Soulstone"
|
||||
desc = "This spell reaches into Nar'Sie's realm, summoning one of the legendary fragments across time and space"
|
||||
desc = "This spell reaches into Redspace, summoning one of the legendary fragments across time and space"
|
||||
action_icon_state = "summonsoulstone"
|
||||
action_background_icon_state = "bg_cult"
|
||||
school = "conjuration"
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/pylon
|
||||
name = "Cult Pylon"
|
||||
desc = "This spell conjures a fragile crystal from Nar'Sie's realm. Makes for a convenient light source."
|
||||
desc = "This spell conjures a fragile crystal from Redspace. Makes for a convenient light source."
|
||||
action_icon_state = "pylon"
|
||||
action_background_icon_state = "bg_cult"
|
||||
school = "conjuration"
|
||||
@@ -118,7 +118,12 @@
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/do_jaunt(mob/living/target)
|
||||
target.set_light(0)
|
||||
..()
|
||||
target.set_light(2, 3, l_color = SSticker.cultdat ? SSticker.cultdat.construct_glow : LIGHT_COLOR_BLOOD_MAGIC)
|
||||
if(isconstruct(target))
|
||||
var/mob/living/simple_animal/hostile/construct/C = target
|
||||
if(C.holy)
|
||||
C.set_light(3, 5, LIGHT_COLOR_DARK_BLUE)
|
||||
else
|
||||
C.set_light(2, 3, l_color = SSticker.cultdat ? SSticker.cultdat.construct_glow : LIGHT_COLOR_BLOOD_MAGIC)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/jaunt_steam(mobloc)
|
||||
return
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
if((ABSTRACT in item.flags) || (NODROP in item.flags))
|
||||
continue
|
||||
marked_item = item
|
||||
to_chat(M, "<span class='warning'>You begin to focus your very being into the [item.name]...</span>")
|
||||
to_chat(M, "<span class='warning'>You begin to focus your very being into [item]...</span>")
|
||||
break
|
||||
|
||||
if(!marked_item)
|
||||
@@ -104,7 +104,7 @@
|
||||
|
||||
spawn(50)
|
||||
if(marked_item.loc != M) //I changed my mind I don't want to put my soul in a cheeseburger!
|
||||
to_chat(M, "<span class='warning'>Your soul snaps back to your body as you drop the [marked_item.name]!</span>")
|
||||
to_chat(M, "<span class='warning'>Your soul snaps back to your body as you drop [marked_item]!</span>")
|
||||
marked_item = null
|
||||
return
|
||||
name = "RISE!"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a wall is in front of [usr.p_them()]."
|
||||
invocation = "<B>[usr.name]</B> looks as if a wall is in front of [usr.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
@@ -86,7 +86,7 @@
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a blockade is in front of [usr.p_them()]."
|
||||
invocation = "<B>[usr.name]</B> looks as if a blockade is in front of [usr.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
var/obj/item/organ/external/part = X
|
||||
if(item_to_retrieve in part.embedded_objects)
|
||||
part.embedded_objects -= item_to_retrieve
|
||||
to_chat(C, "<span class='warning'>The [item_to_retrieve] that was embedded in your [part] has mysteriously vanished. How fortunate!</span>")
|
||||
to_chat(C, "<span class='warning'>\The [item_to_retrieve] that was embedded in your [part] has mysteriously vanished. How fortunate!</span>")
|
||||
if(!C.has_embedded_objects())
|
||||
C.clear_alert("embeddedobject")
|
||||
break
|
||||
@@ -99,7 +99,7 @@
|
||||
if(!item_to_retrieve)
|
||||
return
|
||||
|
||||
item_to_retrieve.loc.visible_message("<span class='warning'>The [item_to_retrieve.name] suddenly disappears!</span>")
|
||||
item_to_retrieve.loc.visible_message("<span class='warning'>\The [item_to_retrieve] suddenly disappears!</span>")
|
||||
|
||||
|
||||
if(target.hand) //left active hand
|
||||
@@ -112,10 +112,10 @@
|
||||
butterfingers = 1
|
||||
if(butterfingers)
|
||||
item_to_retrieve.loc = target.loc
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>The [item_to_retrieve.name] suddenly appears!</span>")
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>\The [item_to_retrieve] suddenly appears!</span>")
|
||||
playsound(get_turf(target),'sound/magic/summonitems_generic.ogg',50,1)
|
||||
else
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>The [item_to_retrieve.name] suddenly appears in [target]'s hand!</span>")
|
||||
item_to_retrieve.loc.visible_message("<span class='caution'>\The [item_to_retrieve] suddenly appears in [target]'s hand!</span>")
|
||||
playsound(get_turf(target),'sound/magic/summonitems_generic.ogg',50,1)
|
||||
|
||||
if(message)
|
||||
|
||||
@@ -374,7 +374,7 @@
|
||||
|
||||
for(var/am in thrownatoms)
|
||||
var/atom/movable/AM = am
|
||||
if(AM == user || AM.anchored)
|
||||
if(AM == user || AM.anchored || AM.move_resist == INFINITY)
|
||||
continue
|
||||
|
||||
throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
|
||||
|
||||
@@ -935,6 +935,14 @@ GLOBAL_LIST_INIT(all_supply_groups, list(SUPPLY_EMERGENCY,SUPPLY_SECURITY,SUPPLY
|
||||
containername = "surgery crate"
|
||||
access = ACCESS_MEDICAL
|
||||
|
||||
/datum/supply_packs/medical/gloves
|
||||
name = "Nitrile Glove Crate"
|
||||
contains = list(/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile,
|
||||
/obj/item/clothing/gloves/color/latex/nitrile)
|
||||
cost = 50
|
||||
containername = "nitrile glove crate"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Science /////////////////////////////////////////
|
||||
|
||||
@@ -1,39 +1,53 @@
|
||||
/// Will our restart be slower?
|
||||
GLOBAL_VAR_INIT(slower_restart, FALSE)
|
||||
|
||||
/proc/server_announce_global(announcement_text)
|
||||
to_chat(world, "<span style='color: #ff00ff'>\[Server] [announcement_text]</span>")
|
||||
|
||||
/proc/server_announce_adminonly(announcement_text)
|
||||
to_chat(GLOB.admins, "<span style='color: #ff00ff'>\[Server] \[Admin] [announcement_text]</span>")
|
||||
|
||||
/datum/tgs_event_handler/impl
|
||||
var/datum/timedevent/reattach_timer
|
||||
|
||||
|
||||
/datum/tgs_event_handler/impl/HandleEvent(event_code, ...)
|
||||
switch(event_code)
|
||||
if(TGS_EVENT_REBOOT_MODE_CHANGE)
|
||||
var/list/reboot_mode_lookup = list ("[TGS_REBOOT_MODE_NORMAL]" = "be normal", "[TGS_REBOOT_MODE_SHUTDOWN]" = "shutdown the server", "[TGS_REBOOT_MODE_RESTART]" = "hard restart the server")
|
||||
var/old_reboot_mode = args[2]
|
||||
var/new_reboot_mode = args[3]
|
||||
message_admins("\[Server]\[Info] Reboot will no longer [reboot_mode_lookup["[old_reboot_mode]"]], it will instead [reboot_mode_lookup["[new_reboot_mode]"]]")
|
||||
if(new_reboot_mode == TGS_REBOOT_MODE_SHUTDOWN)
|
||||
GLOB.slower_restart = TRUE
|
||||
else
|
||||
GLOB.slower_restart = FALSE
|
||||
server_announce_adminonly("\[Info] Reboot will no longer [reboot_mode_lookup["[old_reboot_mode]"]], it will instead [reboot_mode_lookup["[new_reboot_mode]"]]")
|
||||
if(TGS_EVENT_PORT_SWAP)
|
||||
message_admins("\[Server]\[Info] Changing port from [world.port] to [args[2]]")
|
||||
server_announce_adminonly("\[Info] Changing port from [world.port] to [args[2]]")
|
||||
if(TGS_EVENT_INSTANCE_RENAMED)
|
||||
message_admins("\[Server]\[Info] Instance renamed to from [world.TgsInstanceName()] to [args[2]]")
|
||||
server_announce_adminonly("\[Info] Instance renamed to from [world.TgsInstanceName()] to [args[2]]")
|
||||
if(TGS_EVENT_COMPILE_START)
|
||||
message_admins("\[Server]\[Info] Code deployment started, new game version incoming next round...")
|
||||
server_announce_adminonly("\[Info] Code deployment started, new game version incoming next round...")
|
||||
if(TGS_EVENT_COMPILE_CANCELLED)
|
||||
message_admins("\[Server]\[Warning] Code deployment cancelled!")
|
||||
server_announce_adminonly("\[Warning] Code deployment cancelled! Consult a maintainer/host to see if this was intentional!")
|
||||
if(TGS_EVENT_COMPILE_FAILURE)
|
||||
message_admins("\[Server]\[Error] Code deployment failed! Inform a maintainer/host immediately!")
|
||||
server_announce_adminonly("\[Error] Code deployment failed! Inform a maintainer/host immediately!")
|
||||
if(TGS_EVENT_DEPLOYMENT_COMPLETE)
|
||||
message_admins("\[Server]\[Info] Code deployment complete!")
|
||||
to_chat(world, "<span class='boldannounce'>Server updated, changes will be applied on the next round...</span>")
|
||||
server_announce_adminonly("\[Info] Code deployment complete!")
|
||||
server_announce_global("Server update complete. Changes will be applied on the next round.")
|
||||
if(TGS_EVENT_WATCHDOG_DETACH)
|
||||
message_admins("\[Server]\[Info] Server manager restarting...")
|
||||
server_announce_adminonly("\[Info] Server manager restarting...")
|
||||
reattach_timer = addtimer(CALLBACK(src, .proc/LateOnReattach), 1 MINUTES, TIMER_STOPPABLE)
|
||||
if(TGS_EVENT_WATCHDOG_REATTACH)
|
||||
var/datum/tgs_version/old_version = world.TgsVersion()
|
||||
var/datum/tgs_version/new_version = args[2]
|
||||
if(!old_version.Equals(new_version))
|
||||
message_admins("\[Server]\[Info] Manager back online. TGS has been updated to v[new_version.deprefixed_parameter]")
|
||||
server_announce_adminonly("\[Info] Server manager back online. TGS has been updated to v[new_version.deprefixed_parameter]")
|
||||
else
|
||||
message_admins("\[Server]\[Info] Manager back online")
|
||||
server_announce_adminonly("\[Info] Server manager back online")
|
||||
if(reattach_timer)
|
||||
deltimer(reattach_timer)
|
||||
reattach_timer = null
|
||||
|
||||
/datum/tgs_event_handler/impl/proc/LateOnReattach()
|
||||
message_admins("\[Server]\[Warning] TGS hasn't notified us of it coming back for a full minute! Is there a problem?")
|
||||
server_announce_adminonly("\[Warning] TGS hasn't notified us of it coming back for a full minute! Is there a problem?")
|
||||
|
||||
@@ -864,6 +864,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "CQC"
|
||||
item = /obj/item/CQC_manual
|
||||
cost = 13
|
||||
cant_discount = TRUE
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/cameraflash
|
||||
name = "Camera Flash"
|
||||
@@ -1016,6 +1017,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 11
|
||||
surplus = 0
|
||||
cant_discount = TRUE
|
||||
hijack_only = TRUE
|
||||
|
||||
/datum/uplink_item/explosives/emp_bomb
|
||||
name = "EMP bomb"
|
||||
@@ -1425,7 +1427,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
name = "Power Sink"
|
||||
desc = "When screwed to wiring attached to an electric grid, then activated, this large device places excessive load on the grid, causing a stationwide blackout. The sink cannot be carried because of its excessive size. Ordering this sends you a small beacon that will teleport the power sink to your location on activation."
|
||||
reference = "PS"
|
||||
item = /obj/item/powersink
|
||||
item = /obj/item/radio/beacon/syndicate/power_sink
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/device_tools/singularity_beacon
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
/**
|
||||
* Proc called to determine if the user can see wire define information, such as "Contraband", "Door Bolts", etc.
|
||||
*
|
||||
* If the user is an admin, or has a multitool which reveals wire information in their active hand, the proc returns TRUE.
|
||||
* If the user is an admin, or has an item which reveals wire information in their active hand, the proc returns TRUE.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - the mob who is interacting with the wires.
|
||||
@@ -217,10 +217,9 @@
|
||||
/datum/wires/proc/can_see_wire_info(mob/user)
|
||||
if(user.can_admin_interact())
|
||||
return TRUE
|
||||
else if(istype(user.get_active_hand(), /obj/item/multitool))
|
||||
var/obj/item/multitool/M = user.get_active_hand()
|
||||
if(M.shows_wire_information)
|
||||
return TRUE
|
||||
var/obj/item/held_item = user.get_active_hand()
|
||||
if(istype(held_item) && HAS_TRAIT(held_item, TRAIT_SHOW_WIRE_INFO))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,6 +75,12 @@
|
||||
///Used to decide what the maximum time between ambience is
|
||||
var/max_ambience_cooldown = 90 SECONDS
|
||||
|
||||
/area/New(loc, ...)
|
||||
if(!there_can_be_many) // Has to be done in New else the maploader will fuck up and find subtypes for the parent
|
||||
GLOB.all_unique_areas[type] = src
|
||||
..()
|
||||
|
||||
|
||||
/area/Initialize(mapload)
|
||||
GLOB.all_areas += src
|
||||
icon_state = ""
|
||||
|
||||
+81
-124
@@ -607,53 +607,75 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fpmaint
|
||||
name = "EVA Maintenance"
|
||||
name = "Fore-Port Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fpmaint2
|
||||
name = "Arrivals North Maintenance"
|
||||
name = "Fore-Port Secondary Maintenance"
|
||||
icon_state = "fpmaint"
|
||||
|
||||
/area/maintenance/fsmaint
|
||||
name = "Dormitory Maintenance"
|
||||
name = "Fore-Starboard Maintenance"
|
||||
icon_state = "fsmaint"
|
||||
|
||||
/area/maintenance/fsmaint2
|
||||
name = "Bar Maintenance"
|
||||
name = "Fore-Starboard Secondary Maintenance"
|
||||
icon_state = "fsmaint"
|
||||
|
||||
/area/maintenance/asmaint
|
||||
name = "Medbay Maintenance"
|
||||
name = "Aft-Starboard Maintenance"
|
||||
icon_state = "asmaint"
|
||||
|
||||
/area/maintenance/asmaint2
|
||||
name = "Science Maintenance"
|
||||
name = "Aft-Starboard Secondary Maintenance"
|
||||
icon_state = "asmaint"
|
||||
|
||||
/area/maintenance/apmaint
|
||||
name = "Cargo Maintenance"
|
||||
name = "Aft-Port Maintenance"
|
||||
icon_state = "apmaint"
|
||||
|
||||
/area/maintenance/apmaint2
|
||||
name = "Aft-Port Secondary Maintenance"
|
||||
icon_state = "apmaint"
|
||||
|
||||
/area/maintenance/maintcentral
|
||||
name = "Bridge Maintenance"
|
||||
name = "Central Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
|
||||
/area/maintenance/maintcentral2
|
||||
name = "Central Secondary Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
/area/maintenance/fore
|
||||
name = "Fore Maintenance"
|
||||
icon_state = "fmaint"
|
||||
|
||||
/area/maintenance/fore2
|
||||
name = "Fore Secondary Maintenance"
|
||||
icon_state = "fmaint"
|
||||
|
||||
/area/maintenance/aft
|
||||
name = "Aft Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/aft2
|
||||
name = "Aft Secondary Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/starboard
|
||||
name = "Starboard Maintenance"
|
||||
icon_state = "smaint"
|
||||
|
||||
/area/maintenance/starboard2
|
||||
name = "Starboard Secondary Maintenance"
|
||||
icon_state = "smaint"
|
||||
|
||||
/area/maintenance/port
|
||||
name = "Locker Room Maintenance"
|
||||
name = "Port Maintenance"
|
||||
icon_state = "pmaint"
|
||||
|
||||
/area/maintenance/aft
|
||||
name = "Engineering Maintenance"
|
||||
icon_state = "amaint"
|
||||
|
||||
/area/maintenance/port2
|
||||
name = "Port Secondary Maintenance"
|
||||
icon_state = "pmaint"
|
||||
/area/maintenance/storage
|
||||
name = "Atmospherics Maintenance"
|
||||
icon_state = "green"
|
||||
@@ -677,18 +699,18 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/electrical
|
||||
name = "Electrical Maintenance"
|
||||
icon_state = "yellow"
|
||||
icon_state = "elec"
|
||||
|
||||
/area/maintenance/abandonedbar
|
||||
name = "Maintenance Bar"
|
||||
icon_state = "yellow"
|
||||
icon_state = "oldbar"
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
power_environ = 0
|
||||
|
||||
/area/maintenance/electrical_shop
|
||||
name ="Electronics Den"
|
||||
icon_state = "yellow"
|
||||
icon_state = "elec"
|
||||
|
||||
/area/maintenance/gambling_den
|
||||
name = "Gambling Den"
|
||||
@@ -696,7 +718,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/maintenance/consarea
|
||||
name = "Alternate Construction Area"
|
||||
icon_state = "yellow"
|
||||
icon_state = "construction"
|
||||
|
||||
|
||||
//Hallway
|
||||
@@ -836,7 +858,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/comms
|
||||
name = "\improper Communications Relay"
|
||||
icon_state = "tcomsatcham"
|
||||
icon_state = "tcomms"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/server
|
||||
@@ -846,11 +868,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/ntrep
|
||||
name = "\improper Nanotrasen Representative's Office"
|
||||
icon_state = "bluenew"
|
||||
icon_state = "ntrep"
|
||||
|
||||
/area/blueshield
|
||||
name = "\improper Blueshield's Office"
|
||||
icon_state = "blueold"
|
||||
icon_state = "blueshield"
|
||||
|
||||
/area/centcomdocks
|
||||
name = "\improper Central Command Docks"
|
||||
@@ -919,7 +941,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/crew_quarters/bar
|
||||
name = "\improper Bar"
|
||||
icon_state = "bar"
|
||||
icon_state = "barstation"
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
/area/crew_quarters/bar/atrium
|
||||
@@ -1048,45 +1070,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/holodeck/source_knightarena
|
||||
name = "\improper Holodeck - Knight Arena"
|
||||
|
||||
|
||||
//Embassies
|
||||
/area/embassy/
|
||||
name = "\improper Embassy Hallway"
|
||||
|
||||
/area/embassy/tajaran
|
||||
name = "\improper Tajaran Embassy"
|
||||
icon_state = "tajaran"
|
||||
|
||||
/area/embassy/skrell
|
||||
name = "\improper Skrell Embassy"
|
||||
icon_state = "skrell"
|
||||
|
||||
/area/embassy/unathi
|
||||
name = "\improper Unathi Embassy"
|
||||
icon_state = "unathi"
|
||||
|
||||
/area/embassy/kidan
|
||||
name = "\improper Kidan Embassy"
|
||||
icon_state = "kidan"
|
||||
|
||||
/area/embassy/diona
|
||||
name = "\improper Diona Embassy"
|
||||
icon_state = "diona"
|
||||
|
||||
/area/embassy/slime
|
||||
name = "\improper Slime Person Embassy"
|
||||
icon_state = "slime"
|
||||
|
||||
/area/embassy/grey
|
||||
name = "\improper Grey Embassy"
|
||||
icon_state = "grey"
|
||||
|
||||
/area/embassy/vox
|
||||
name = "\improper Vox Embassy"
|
||||
icon_state = "vox"
|
||||
|
||||
|
||||
|
||||
//Engineering
|
||||
/area/engine
|
||||
ambientsounds = ENGINEERING_SOUNDS
|
||||
@@ -1108,7 +1091,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/engine/equipmentstorage
|
||||
name = "\improper Engineering Equipment Storage"
|
||||
name = "Engineering Equipment Storage"
|
||||
icon_state = "storage"
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
@@ -1260,7 +1243,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
|
||||
/area/medical/biostorage
|
||||
name = "\improper Medical Storage"
|
||||
name = "Medical Storage"
|
||||
icon_state = "medbaysecstorage"
|
||||
|
||||
/area/medical/reception
|
||||
@@ -1285,19 +1268,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "patientsward"
|
||||
|
||||
/area/medical/patient_a
|
||||
name = "\improper Isolation A"
|
||||
name = "Isolation A"
|
||||
icon_state = "medbayisoa"
|
||||
|
||||
/area/medical/patient_b
|
||||
name = "\improper Isolation B"
|
||||
name = "Isolation B"
|
||||
icon_state = "medbayisob"
|
||||
|
||||
/area/medical/patient_c
|
||||
name = "\improper Isolation C"
|
||||
name = "Isolation C"
|
||||
icon_state = "medbayisoc"
|
||||
|
||||
/area/medical/iso_access
|
||||
name = "\improper Isolation Access"
|
||||
name = "Isolation Access"
|
||||
icon_state = "medbayisoaccess"
|
||||
|
||||
/area/medical/cmo
|
||||
@@ -1305,23 +1288,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "CMO"
|
||||
|
||||
/area/medical/cmostore
|
||||
name = "\improper Medical Secondary Storage"
|
||||
name = "Medical Secondary Storage"
|
||||
icon_state = "medbaysecstorage"
|
||||
|
||||
/area/medical/robotics
|
||||
name = "\improper Robotics"
|
||||
icon_state = "medresearch"
|
||||
name = "Robotics"
|
||||
icon_state = "research"
|
||||
|
||||
/area/medical/research
|
||||
name = "\improper Medical Research"
|
||||
icon_state = "medresearch"
|
||||
|
||||
/area/medical/research_shuttle_dock
|
||||
name = "\improper Research Shuttle Dock"
|
||||
icon_state = "medresearch"
|
||||
name = "Research Division"
|
||||
icon_state = "research"
|
||||
|
||||
/area/medical/virology
|
||||
name = "\improper Virology"
|
||||
name = "Virology"
|
||||
icon_state = "virology"
|
||||
|
||||
/area/medical/virology/lab
|
||||
@@ -1336,7 +1315,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/medical/chemistry
|
||||
name = "\improper Chemistry"
|
||||
name = "Chemistry"
|
||||
icon_state = "chem"
|
||||
|
||||
/area/medical/surgery
|
||||
@@ -1344,19 +1323,19 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "surgery"
|
||||
|
||||
/area/medical/surgery1
|
||||
name = "\improper Surgery 1"
|
||||
name = "Surgery 1"
|
||||
icon_state = "surgery1"
|
||||
|
||||
/area/medical/surgery2
|
||||
name = "\improper Surgery 2"
|
||||
name = "Surgery 2"
|
||||
icon_state = "surgery2"
|
||||
|
||||
/area/medical/surgeryobs
|
||||
name = "\improper Surgery Observation"
|
||||
name = "Surgery Observation"
|
||||
icon_state = "surgery"
|
||||
|
||||
/area/medical/cryo
|
||||
name = "\improper Cryogenics"
|
||||
name = "Cryogenics"
|
||||
icon_state = "cryo"
|
||||
|
||||
/area/medical/exam_room
|
||||
@@ -1376,7 +1355,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "exam_room"
|
||||
|
||||
/area/medical/paramedic
|
||||
name = "\improper Paramedic"
|
||||
name = "Paramedic"
|
||||
icon_state = "medbay"
|
||||
|
||||
//Security
|
||||
@@ -1441,35 +1420,31 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "brig"
|
||||
|
||||
/area/security/execution
|
||||
name = "\improper Execution"
|
||||
name = "Execution"
|
||||
icon_state = "execution"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/processing
|
||||
name = "\improper Prisoner Processing"
|
||||
name = "Prisoner Processing"
|
||||
icon_state = "prisonerprocessing"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/interrogation
|
||||
name = "\improper Interrogation"
|
||||
name = "Interrogation"
|
||||
icon_state = "interrogation"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/seceqstorage
|
||||
name = "\improper Security Equipment Storage"
|
||||
name = "Security Equipment Storage"
|
||||
icon_state = "securityequipmentstorage"
|
||||
|
||||
/area/security/interrogationhallway
|
||||
name = "\improper Interrogation Hallway"
|
||||
icon_state = "interrogationhall"
|
||||
|
||||
/area/security/courtroomdandp
|
||||
name = "\improper Courtroom Defense and Prosecution"
|
||||
icon_state = "seccourt"
|
||||
sound_environment = SOUND_AREA_LARGE_ENCLOSED
|
||||
|
||||
/area/security/interrogationobs
|
||||
name = "\improper Interrogation Observation"
|
||||
name = "Interrogation Observation"
|
||||
icon_state = "security"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
@@ -1505,7 +1480,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "secarmory"
|
||||
|
||||
/area/security/securehallway
|
||||
name = "\improper Security Secure Hallway"
|
||||
name = "\improper Brig Secure Hallway"
|
||||
icon_state = "securehall"
|
||||
|
||||
/area/security/hos
|
||||
@@ -1530,11 +1505,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "nuke_storage"
|
||||
|
||||
/area/security/customs
|
||||
name = "\improper Customs"
|
||||
name = "Customs"
|
||||
icon_state = "checkpoint1"
|
||||
|
||||
/area/security/customs2
|
||||
name = "\improper Customs"
|
||||
name = "Customs"
|
||||
icon_state = "security"
|
||||
|
||||
/area/security/checkpoint
|
||||
@@ -1601,7 +1576,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "mining"
|
||||
|
||||
/area/quartermaster/miningstorage
|
||||
name = "\improper Mining Storage"
|
||||
name = "Mining Storage"
|
||||
icon_state = "green"
|
||||
|
||||
/area/quartermaster/mechbay
|
||||
@@ -1614,7 +1589,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/hydroponics
|
||||
name = "\improper Hydroponics"
|
||||
name = "Hydroponics"
|
||||
icon_state = "hydro"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
@@ -1629,7 +1604,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
|
||||
/area/toxins/lab
|
||||
name = "\improper Research and Development"
|
||||
name = "Research and Development"
|
||||
icon_state = "toxlab"
|
||||
|
||||
/area/toxins/hallway
|
||||
@@ -1650,7 +1625,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
xenobiology_compatible = TRUE
|
||||
|
||||
/area/toxins/xenobiology/xenoflora_storage
|
||||
name = "\improper Xenoflora Storage"
|
||||
name = "Xenoflora Storage"
|
||||
icon_state = "toxlab"
|
||||
|
||||
/area/toxins/xenobiology/xenoflora
|
||||
@@ -1658,7 +1633,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "toxlab"
|
||||
|
||||
/area/toxins/storage
|
||||
name = "\improper Toxins Storage"
|
||||
name = "Toxins Storage"
|
||||
icon_state = "toxstorage"
|
||||
|
||||
/area/toxins/test_area
|
||||
@@ -1671,7 +1646,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "toxmix"
|
||||
|
||||
/area/toxins/launch
|
||||
name = "Toxins Launch Room"
|
||||
name = "\improper Toxins Launch Room"
|
||||
icon_state = "toxlaunch"
|
||||
|
||||
/area/toxins/misc_lab
|
||||
@@ -1739,7 +1714,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
icon_state = "auxstorage"
|
||||
|
||||
/area/storage/office
|
||||
name = "\improper Office Supplies"
|
||||
name = "Office Supplies"
|
||||
icon_state = "office_supplies"
|
||||
|
||||
// ENGIE OUTPOST
|
||||
@@ -2061,45 +2036,27 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/tcommsat/chamber
|
||||
name = "\improper Telecoms Central Compartment"
|
||||
icon_state = "tcomsatcham"
|
||||
icon_state = "tcomms"
|
||||
|
||||
// These areas are needed for MetaStation's AI sat
|
||||
/area/turret_protected/tcomsat
|
||||
name = "\improper Telecoms Satellite"
|
||||
icon_state = "tcomsatlob"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomfoyer
|
||||
name = "\improper Telecoms Foyer"
|
||||
icon_state = "tcomsatentrance"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomwest
|
||||
name = "\improper Telecoms West Wing"
|
||||
icon_state = "tcomsatwest"
|
||||
icon_state = "tcomms"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/turret_protected/tcomeast
|
||||
name = "\improper Telecoms East Wing"
|
||||
icon_state = "tcomsateast"
|
||||
icon_state = "tcomms"
|
||||
ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg')
|
||||
|
||||
/area/tcommsat/computer
|
||||
name = "\improper Telecoms Control Room"
|
||||
icon_state = "tcomsatcomp"
|
||||
icon_state = "tcomms"
|
||||
sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR
|
||||
|
||||
/area/tcommsat/server
|
||||
name = "\improper Telecoms Server Room"
|
||||
icon_state = "tcomsatcham"
|
||||
|
||||
/area/tcommsat/lounge
|
||||
name = "\improper Telecoms Lounge"
|
||||
icon_state = "tcomsatlounge"
|
||||
|
||||
/area/tcommsat/powercontrol
|
||||
name = "\improper Telecoms Power Control"
|
||||
icon_state = "tcomsatwest"
|
||||
icon_state = "tcomms"
|
||||
|
||||
// Away Missions
|
||||
/area/awaymission
|
||||
|
||||
+12
-4
@@ -413,6 +413,9 @@
|
||||
/atom/proc/emag_act()
|
||||
return
|
||||
|
||||
/atom/proc/unemag()
|
||||
return
|
||||
|
||||
/**
|
||||
* Respond to a radioactive wave hitting this atom
|
||||
*
|
||||
@@ -941,9 +944,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
/atom/proc/narsie_act()
|
||||
return
|
||||
|
||||
/atom/proc/ratvar_act()
|
||||
return
|
||||
|
||||
/**
|
||||
* Respond to an electric bolt action on our item
|
||||
*
|
||||
@@ -1072,7 +1072,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
Returning TRUE here will override the above proc's result.
|
||||
*/
|
||||
/atom/proc/CanAStarPassTo(ID, dir, obj/destination)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/** Call this when you want to present a renaming prompt to the user.
|
||||
|
||||
@@ -1139,3 +1139,11 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
else
|
||||
name = "[prefix][t]"
|
||||
return t
|
||||
|
||||
/atom/proc/set_angle(degrees)
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(degrees)
|
||||
// If we aint 0, make it NN transform
|
||||
if(degrees)
|
||||
appearance_flags |= PIXEL_SCALE
|
||||
transform = M
|
||||
|
||||
@@ -178,14 +178,19 @@
|
||||
/mob/living/carbon/med_hud_set_status()
|
||||
var/image/holder = hud_list[STATUS_HUD]
|
||||
var/mob/living/simple_animal/borer/B = has_brain_worms()
|
||||
var/dead = stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH)
|
||||
// To the right of health bar
|
||||
if(dead)
|
||||
var/revivable = timeofdeath && (round(world.time - timeofdeath) < DEFIB_TIME_LIMIT)
|
||||
if(stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH))
|
||||
var/revivable
|
||||
if(!ghost_can_reenter()) // DNR or AntagHUD
|
||||
revivable = FALSE
|
||||
else if(timeofdeath && (round(world.time - timeofdeath) < DEFIB_TIME_LIMIT))
|
||||
revivable = TRUE
|
||||
|
||||
if(revivable)
|
||||
holder.icon_state = "hudflatline"
|
||||
else
|
||||
holder.icon_state = "huddead"
|
||||
|
||||
else if(HAS_TRAIT(src, TRAIT_XENO_HOST))
|
||||
holder.icon_state = "hudxeno"
|
||||
else if(B && B.controlling)
|
||||
|
||||
@@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(assigned_mutation_blocks, new(DNA_SE_LENGTH))
|
||||
// Used to determine what each block means (admin hax and species stuff on /vg/, mostly)
|
||||
GLOBAL_LIST_INIT(assigned_blocks, new(DNA_SE_LENGTH))
|
||||
|
||||
/// Assoc list. Key = type of the mutation, value = the mutation
|
||||
GLOBAL_LIST_EMPTY(dna_mutations)
|
||||
|
||||
GLOBAL_LIST_EMPTY(good_blocks)
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
// M: Mob to mess with
|
||||
// flags: See below, bitfield.
|
||||
/proc/domutcheck(mob/living/M, flags = 0)
|
||||
for(var/datum/mutation/mutation in GLOB.dna_mutations)
|
||||
for(var/mutation_type in GLOB.dna_mutations)
|
||||
var/datum/mutation/mutation = GLOB.dna_mutations[mutation_type]
|
||||
if(!M || !M.dna)
|
||||
return
|
||||
if(!mutation.block)
|
||||
@@ -32,7 +33,7 @@
|
||||
var/mutation_active = M.dna.GetSEState(mutation.block)
|
||||
|
||||
// Sanity checks, don't skip.
|
||||
if(!mutation.can_activate(M, flags) && mutation_active)
|
||||
if(mutation_active && !mutation.can_activate(M, flags))
|
||||
//testing("[M] - Failed to activate [gene.name] (can_activate fail).")
|
||||
return FALSE
|
||||
|
||||
@@ -46,11 +47,7 @@
|
||||
if(mutation_active)
|
||||
//testing("[gene.name] activated!")
|
||||
mutation.activate(M)
|
||||
if(M)
|
||||
M.active_mutations |= mutation.type
|
||||
// If Gene is NOT active:
|
||||
else
|
||||
//testing("[gene.name] deactivated!")
|
||||
mutation.deactivate(M)
|
||||
if(M)
|
||||
M.active_mutations -= mutation.type
|
||||
|
||||
@@ -150,16 +150,16 @@
|
||||
if(usr.incapacitated() || usr.buckled) //are you cuffed, dying, lying, stunned or other
|
||||
return
|
||||
if(!ishuman(usr)) //Make sure they're a mob that has dna
|
||||
to_chat(usr, "<span class='notice'>Try as you might, you can not climb up into the [src].</span>")
|
||||
to_chat(usr, "<span class='notice'>Try as you might, you can not climb up into [src].</span>")
|
||||
return
|
||||
if(occupant)
|
||||
to_chat(usr, "<span class='boldnotice'>The [src] is already occupied!</span>")
|
||||
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>")
|
||||
return
|
||||
if(usr.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(usr, "<span class='warning'>[usr] will not fit into the [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.</span>")
|
||||
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>")
|
||||
return
|
||||
usr.stop_pulling()
|
||||
usr.forceMove(src)
|
||||
@@ -188,7 +188,7 @@
|
||||
if(!istype(user.loc, /turf) || !istype(O.loc, /turf)) // are you in a container/closet/pod/etc?
|
||||
return
|
||||
if(occupant)
|
||||
to_chat(user, "<span class='boldnotice'>The [src] is already occupied!</span>")
|
||||
to_chat(user, "<span class='boldnotice'>[src] is already occupied!</span>")
|
||||
return
|
||||
var/mob/living/L = O
|
||||
if(!istype(L) || L.buckled)
|
||||
@@ -200,9 +200,9 @@
|
||||
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>")
|
||||
return
|
||||
if(L == user)
|
||||
visible_message("[user] climbs into the [src].")
|
||||
visible_message("<span class='notice'>[user] climbs into [src].</span>")
|
||||
else
|
||||
visible_message("[user] puts [L.name] into the [src].")
|
||||
visible_message("<span class='notice'>[user] puts [L.name] into [src].</span>")
|
||||
put_in(L)
|
||||
if(user.pulling == L)
|
||||
user.stop_pulling()
|
||||
@@ -235,7 +235,7 @@
|
||||
to_chat(user, "<span class='boldnotice'>Subject cannot have abiotic items on.</span>")
|
||||
return
|
||||
if(G.affecting.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>will not fit into the [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.</span>")
|
||||
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>")
|
||||
return
|
||||
if(panel_open)
|
||||
to_chat(usr, "<span class='boldnotice'>Close the maintenance panel first.</span>")
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
|
||||
// Called when the gene activates. Do your magic here.
|
||||
/datum/mutation/proc/activate(mob/living/M)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
M.gene_stability -= instability
|
||||
M.active_mutations |= type // |= is probably not required but just in case
|
||||
for(var/thing in traits_to_add)
|
||||
ADD_TRAIT(M, thing, GENETIC_MUTATION)
|
||||
if(length(activation_messages))
|
||||
@@ -42,7 +44,9 @@
|
||||
// Called when the gene deactivates. Undo your magic here.
|
||||
// Only called when the block is deactivated.
|
||||
/datum/mutation/proc/deactivate(mob/living/M)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
M.gene_stability += instability
|
||||
M.active_mutations -= type
|
||||
for(var/thing in traits_to_add)
|
||||
REMOVE_TRAIT(M, thing, GENETIC_MUTATION)
|
||||
if(length(deactivation_messages))
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
return ishuman(M)
|
||||
|
||||
/datum/mutation/monkey/activate(mob/living/carbon/human/H)
|
||||
..()
|
||||
if(!istype(H))
|
||||
return
|
||||
if(issmall(H))
|
||||
@@ -42,6 +43,7 @@
|
||||
return H
|
||||
|
||||
/datum/mutation/monkey/deactivate(mob/living/carbon/human/H)
|
||||
..()
|
||||
if(!istype(H))
|
||||
return
|
||||
if(!issmall(H))
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
/datum/mutation/noprints
|
||||
name = "No Prints"
|
||||
activation_messages = list("Your fingers feel numb.")
|
||||
deactivation_messages = list("your fingers no longer feel numb.")
|
||||
deactivation_messages = list("Your fingers no longer feel numb.")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
traits_to_add = list(TRAIT_NOFINGERPRINTS)
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
/datum/mutation/xray
|
||||
name = "X-Ray Vision"
|
||||
activation_messages = list("The walls suddenly disappear.")
|
||||
deactivation_messages = list("the walls around you re-appear.")
|
||||
deactivation_messages = list("The walls around you re-appear.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
traits_to_add = list(TRAIT_XRAY_VISION)
|
||||
activation_prob = 15
|
||||
@@ -185,6 +185,7 @@
|
||||
activation_messages = list("You feel smarter.")
|
||||
deactivation_messages = list("You feel dumber.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
traits_to_add = list(TRAIT_TELEKINESIS)
|
||||
activation_prob = 15
|
||||
|
||||
/datum/mutation/tk/New()
|
||||
|
||||
@@ -15,7 +15,6 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
recommended_enemies = 1
|
||||
restricted_jobs = list("Cyborg", "AI")
|
||||
|
||||
var/declared = 0
|
||||
var/burst = 0
|
||||
|
||||
var/cores_to_spawn = 1
|
||||
@@ -75,8 +74,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
log_game("[key_name(blob)] has been selected as a Blob")
|
||||
greet_blob(blobmind)
|
||||
to_chat(blob, "<span class='userdanger'>You feel very tired and bloated! You don't have long before you burst!</span>")
|
||||
spawn(600)
|
||||
burst_blob(blobmind)
|
||||
addtimer(CALLBACK(src, .proc/burst_blob, blobmind), 60 SECONDS)
|
||||
return 1
|
||||
|
||||
/datum/game_mode/blob/proc/make_blobs(count)
|
||||
@@ -103,6 +101,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
to_chat(blob.current, "<b>Find a good location to spawn the core and then take control and overwhelm the station!</b>")
|
||||
to_chat(blob.current, "<b>When you have found a location, wait until you spawn; this will happen automatically and you cannot speed up the process.</b>")
|
||||
to_chat(blob.current, "<b>If you go outside of the station level, or in space, then you will die; make sure your location has lots of ground to cover.</b>")
|
||||
to_chat(blob.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Blob)</span>")
|
||||
SEND_SOUND(blob.current, sound('sound/magic/mutate.ogg'))
|
||||
return
|
||||
|
||||
@@ -127,8 +126,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
if(!warned)
|
||||
to_chat(C, "<span class='userdanger'>You feel ready to burst, but this isn't an appropriate place! You must return to the station!</span>")
|
||||
message_admins("[key_name_admin(C)] was in space when the blobs burst, and will die if [C.p_they()] [C.p_do()] not return to the station.")
|
||||
spawn(300)
|
||||
burst_blob(blob, 1)
|
||||
addtimer(CALLBACK(src, .proc/burst_blob, blob, 1), 30 SECONDS)
|
||||
else
|
||||
burst++
|
||||
log_admin("[key_name(C)] was in space when attempting to burst as a blob.")
|
||||
@@ -172,33 +170,22 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
|
||||
show_message("<span class='userdanger'>You feel like you are about to burst.</span>")
|
||||
|
||||
sleep(wait_time / 2)
|
||||
|
||||
burst_blobs()
|
||||
|
||||
// Stage 0
|
||||
sleep(wait_time)
|
||||
stage(0)
|
||||
addtimer(CALLBACK(src, .proc/burst_blobs), (wait_time / 2))
|
||||
|
||||
// Stage 1
|
||||
sleep(wait_time)
|
||||
stage(1)
|
||||
addtimer(CALLBACK(src, .proc/stage, 1), (wait_time * 2 + wait_time / 2))
|
||||
|
||||
// Stage 2
|
||||
sleep(30000)
|
||||
stage(2)
|
||||
addtimer(CALLBACK(src, .proc/stage, 2), 50 MINUTES)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/blob/proc/stage(stage)
|
||||
switch(stage)
|
||||
if(0)
|
||||
send_intercept(1)
|
||||
declared = 1
|
||||
if(1)
|
||||
GLOB.event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
|
||||
if(2)
|
||||
send_intercept(2)
|
||||
send_intercept(1)
|
||||
|
||||
/datum/game_mode/proc/update_blob_icons_added(datum/mind/mob_mind)
|
||||
var/datum/atom_hud/antag/antaghud = GLOB.huds[ANTAG_HUD_BLOB]
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
to_chat(world, "<FONT size = 3><B>The staff has won!</B></FONT>")
|
||||
to_chat(world, "<B>The alien organism has been eradicated from the station</B>")
|
||||
log_game("Blob mode completed with a crew victory.")
|
||||
to_chat(world, "<span class='notice'>Rebooting in 30s</span>")
|
||||
..()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -5,19 +5,6 @@
|
||||
if(0)
|
||||
return
|
||||
if(1)
|
||||
interceptname = "Level 5-6 Biohazard Response Procedures"
|
||||
intercepttext += "<FONT size = 3><B>Nanotrasen Update</B>: Biohazard Alert.</FONT><HR>"
|
||||
intercepttext += "Reports indicate the probable transfer of a biohazardous agent onto [station_name()] during the last crew deployment cycle.<BR>"
|
||||
intercepttext += "Preliminary analysis of the organism classifies it as a level 5 biohazard. Its origin is unknown.<BR>"
|
||||
intercepttext += "Nanotrasen has issued a directive 7-10 for [station_name()]. The station is to be considered quarantined.<BR>"
|
||||
intercepttext += "Orders for all [station_name()] personnel follows:<BR>"
|
||||
intercepttext += " 1. Do not leave the quarantine area.<BR>"
|
||||
intercepttext += " 2. Locate any outbreaks of the organism on the station.<BR>"
|
||||
intercepttext += " 3. If found, use any neccesary means to contain the organism.<BR>"
|
||||
intercepttext += " 4. Avoid damage to the capital infrastructure of the station.<BR>"
|
||||
intercepttext += "<BR>Note in the event of a quarantine breach or uncontrolled spread of the biohazard, the directive 7-10 may be upgraded to a directive 7-12.<BR>"
|
||||
intercepttext += "Message ends."
|
||||
if(2)
|
||||
var/nukecode = rand(10000, 99999)
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
|
||||
if(bomb && bomb.r_code)
|
||||
|
||||
@@ -117,13 +117,13 @@
|
||||
|
||||
if(C && !QDELETED(src))
|
||||
var/mob/camera/blob/B = new(loc)
|
||||
B.is_offspring = is_offspring
|
||||
B.key = C.key
|
||||
B.blob_core = src
|
||||
overmind = B
|
||||
color = overmind.blob_reagent_datum.color
|
||||
if(B.mind && !B.mind.special_role)
|
||||
B.mind.make_Overmind()
|
||||
B.is_offspring = is_offspring
|
||||
|
||||
/obj/structure/blob/core/proc/lateblobtimer()
|
||||
addtimer(CALLBACK(src, .proc/lateblobcheck), 50)
|
||||
|
||||
@@ -147,6 +147,7 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
|
||||
for(var/datum/objective/objective in changeling.objectives)
|
||||
to_chat(changeling.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
|
||||
obj_count++
|
||||
to_chat(changeling.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Changeling)</span>")
|
||||
return
|
||||
|
||||
/datum/game_mode/proc/remove_changeling(datum/mind/changeling_mind)
|
||||
|
||||
@@ -93,5 +93,7 @@ the same goes for Remove(). if you override Remove(), call parent or else your p
|
||||
/datum/action/changeling/proc/transform_dna(mob/living/carbon/human/H, datum/dna/D)
|
||||
if(!D)
|
||||
return
|
||||
|
||||
H.change_dna(D, TRUE)
|
||||
var/changesSpecies = TRUE
|
||||
if (H.dna.species.name == D.species.name)
|
||||
changesSpecies = FALSE
|
||||
H.change_dna(D, changesSpecies)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/datum/action/changeling/digitalcamo
|
||||
name = "Digital Camouflage"
|
||||
desc = "By evolving the ability to distort our form and proprotions, we defeat common altgorithms used to detect lifeforms on cameras."
|
||||
helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us... uncanny."
|
||||
helptext = "We cannot be tracked by camera while using this skill."
|
||||
button_icon_state = "digital_camo"
|
||||
dna_cost = 1
|
||||
|
||||
//Prevents AIs tracking you but makes you easily detectable to the human-eye.
|
||||
//Prevents AIs tracking you.
|
||||
/datum/action/changeling/digitalcamo/sting_action(mob/user)
|
||||
|
||||
if(user.digitalcamo)
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
to_chat(user, "<span class='notice'>We stealthily stab [target] with a minor proboscis...</span>")
|
||||
to_chat(target, "<span class='userdanger'>You experience a stabbing sensation and your ears begin to ring...</span>")
|
||||
if(3)
|
||||
to_chat(user, "<span class='notice'>You mold the [target]'s mind like clay, [target.p_they()] can now speak in the hivemind!</span>")
|
||||
to_chat(user, "<span class='notice'>You mold [target]'s mind like clay, [target.p_they()] can now speak in the hivemind!</span>")
|
||||
to_chat(target, "<span class='userdanger'>A migraine throbs behind your eyes, you hear yourself screaming - but your mouth has not opened!</span>")
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(GLOB.all_languages["Changeling"] in M.languages)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/datum/action/changeling/weapon/sting_action(mob/user)
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "The [user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!")
|
||||
to_chat(user, "[user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!")
|
||||
return
|
||||
var/obj/item/W = new weapon_type(user, silent)
|
||||
user.put_in_hands(W)
|
||||
@@ -173,8 +173,11 @@
|
||||
name = "Tentacle"
|
||||
desc = "We ready a tentacle to grab items or victims with. Costs 10 chemicals."
|
||||
helptext = "We can use it once to retrieve a distant item. If used on living creatures, the effect depends on the intent: \
|
||||
Help will simply drag them closer, Disarm will grab whatever they are holding instead of them, Grab will put the victim in our hold after catching it, \
|
||||
and Harm will stun it, and stab it if we are also holding a sharp weapon. Cannot be used while in lesser form."
|
||||
Help will drag the target closer. \
|
||||
Disarm will grab whatever the target is holding. \
|
||||
Grab will put the target in our grip after we catch it. \
|
||||
Harm will drag the target closer and stab it if we are holding a sharp weapon in our other hand. \
|
||||
Cannot be used while in our lesser form."
|
||||
button_icon_state = "tentacle"
|
||||
chemical_cost = 10
|
||||
dna_cost = 2
|
||||
@@ -209,7 +212,7 @@
|
||||
to_chat(loc, "<span class='notice'>You prepare to extend a tentacle.</span>")
|
||||
|
||||
/obj/item/gun/magic/tentacle/shoot_with_empty_chamber(mob/living/user as mob|obj)
|
||||
to_chat(user, "<span class='warning'>The [name] is not ready yet.</span>")
|
||||
to_chat(user, "<span class='warning'>[src] is not ready yet.</span>")
|
||||
|
||||
/obj/item/gun/magic/tentacle/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] coils [src] tightly around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
/datum/action/innate/cult/blood_spell/horror/Destroy()
|
||||
var/obj/effect/proc_holder/horror/destroy = PH
|
||||
. = ..()
|
||||
if(destroy && !QDELETED(destroy))
|
||||
if(!QDELETED(destroy))
|
||||
QDEL_NULL(destroy)
|
||||
|
||||
/datum/action/innate/cult/blood_spell/horror/Activate()
|
||||
@@ -264,7 +264,7 @@
|
||||
/obj/effect/proc_holder/horror/Destroy()
|
||||
var/datum/action/innate/cult/blood_spell/AA = attached_action
|
||||
. = ..()
|
||||
if(AA && !QDELETED(AA))
|
||||
if(!QDELETED(AA))
|
||||
QDEL_NULL(AA)
|
||||
|
||||
/obj/effect/proc_holder/horror/proc/toggle(mob/user)
|
||||
@@ -464,9 +464,15 @@
|
||||
var/list/potential_runes = list()
|
||||
var/list/teleportnames = list()
|
||||
var/list/duplicaterunecount = list()
|
||||
var/atom/movable/teleportee
|
||||
if(!iscultist(target) || !proximity)
|
||||
to_chat(user, "<span class='warning'>You can only teleport adjacent cultists with this spell!</span>")
|
||||
return
|
||||
if(user != target) // So that the teleport effect shows on the correct mob
|
||||
teleportee = target
|
||||
else
|
||||
teleportee = user
|
||||
|
||||
for(var/R in GLOB.teleport_runes)
|
||||
var/obj/effect/rune/teleport/T = R
|
||||
var/resultkey = T.listkey
|
||||
@@ -487,16 +493,15 @@
|
||||
log_game("Teleport spell failed - user in away mission")
|
||||
return
|
||||
|
||||
var/mob/living/L = target
|
||||
var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked
|
||||
var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to?
|
||||
if(!src || QDELETED(src) || !user || user.l_hand != src && user.r_hand != src || user.incapacitated() || !actual_selected_rune)
|
||||
if(QDELETED(src) || !user || user.l_hand != src && user.r_hand != src || user.incapacitated() || !actual_selected_rune)
|
||||
return
|
||||
uses--
|
||||
|
||||
var/turf/origin = get_turf(user)
|
||||
var/turf/origin = get_turf(teleportee)
|
||||
var/turf/destination = get_turf(actual_selected_rune)
|
||||
INVOKE_ASYNC(actual_selected_rune, /obj/effect/rune/.proc/teleport_effect, user, origin, destination)
|
||||
INVOKE_ASYNC(actual_selected_rune, /obj/effect/rune/.proc/teleport_effect, teleportee, origin, destination)
|
||||
|
||||
if(is_mining_level(user.z) && !is_mining_level(destination.z)) //No effect if you stay on lavaland
|
||||
actual_selected_rune.handle_portal("lava")
|
||||
@@ -510,7 +515,7 @@
|
||||
target.visible_message("<span class='warning'>Dust flows from [user]'s hand, and [target] disappears in a flash of red light!</span>", \
|
||||
"<span class='cultitalic'>You suddenly find yourself somewhere else!</span>")
|
||||
destination.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
|
||||
L.forceMove(destination)
|
||||
teleportee.forceMove(destination)
|
||||
return ..()
|
||||
|
||||
//Shackles
|
||||
@@ -658,7 +663,7 @@
|
||||
/obj/item/melee/blood_magic/empower/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(proximity_flag)
|
||||
|
||||
//Shielded suit
|
||||
// Shielded suit
|
||||
if(istype(target, /obj/item/clothing/suit/hooded/cultrobes/cult_shield))
|
||||
var/obj/item/clothing/suit/hooded/cultrobes/cult_shield/C = target
|
||||
if(C.current_charges < 3)
|
||||
@@ -672,7 +677,7 @@
|
||||
to_chat(user, "<span class='warning'>[target] is already at full charge!</span>")
|
||||
return
|
||||
|
||||
//Plasteel to runed metal
|
||||
// Veil Shifter
|
||||
else if(istype(target, /obj/item/cult_shift))
|
||||
var/obj/item/cult_shift/S = target
|
||||
if(S.uses < 4)
|
||||
@@ -843,42 +848,13 @@
|
||||
uses += max(1, temp)
|
||||
|
||||
/obj/item/melee/blood_magic/manipulator/attack_self(mob/living/user)
|
||||
var/list/options = list("Blood Orb (50)", "Blood Recharge (75)", "Blood Spear (150)", "Blood Bolt Barrage (300)")
|
||||
var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options
|
||||
var/list/options = list("Blood Orb (50)" = image(icon = 'icons/obj/cult.dmi', icon_state = "summoning_orb"),
|
||||
"Blood Recharge (75)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "blood_charge"),
|
||||
"Blood Spear (150)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "bloodspear"),
|
||||
"Blood Bolt Barrage (300)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "blood_barrage"))
|
||||
var/choice = show_radial_menu(user, src, options)
|
||||
|
||||
switch(choice)
|
||||
if("Blood Spear (150)")
|
||||
if(uses < BLOOD_SPEAR_COST)
|
||||
to_chat(user, "<span class='warning'>You need [BLOOD_SPEAR_COST] charges to perform this rite.</span>")
|
||||
else
|
||||
uses -= BLOOD_SPEAR_COST
|
||||
var/turf/T = get_turf(user)
|
||||
qdel(src)
|
||||
var/datum/action/innate/cult/spear/S = new(user)
|
||||
var/obj/item/twohanded/cult_spear/rite = new(T)
|
||||
S.Grant(user, rite)
|
||||
rite.spear_act = S
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>", \
|
||||
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
|
||||
|
||||
if("Blood Bolt Barrage (300)")
|
||||
if(uses < BLOOD_BARRAGE_COST)
|
||||
to_chat(user, "<span class='cultitalic'>You need [BLOOD_BARRAGE_COST] charges to perform this rite.</span>")
|
||||
else
|
||||
var/obj/rite = new /obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/blood()
|
||||
uses -= BLOOD_BARRAGE_COST
|
||||
qdel(src)
|
||||
user.swap_hand()
|
||||
user.drop_item()
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>Both of your hands glow with power!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
|
||||
uses += BLOOD_BARRAGE_COST // Refund the charges
|
||||
qdel(rite)
|
||||
|
||||
if("Blood Orb (50)")
|
||||
if(uses < BLOOD_ORB_COST)
|
||||
to_chat(user, "<span class='warning'>You need [BLOOD_ORB_COST] charges to perform this rite.</span>")
|
||||
@@ -898,7 +874,7 @@
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>", \
|
||||
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>",
|
||||
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
|
||||
|
||||
if("Blood Recharge (75)")
|
||||
@@ -914,3 +890,36 @@
|
||||
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
|
||||
uses += BLOOD_RECHARGE_COST // Refund the charges
|
||||
qdel(rite)
|
||||
|
||||
if("Blood Spear (150)")
|
||||
if(uses < BLOOD_SPEAR_COST)
|
||||
to_chat(user, "<span class='warning'>You need [BLOOD_SPEAR_COST] charges to perform this rite.</span>")
|
||||
else
|
||||
uses -= BLOOD_SPEAR_COST
|
||||
var/turf/T = get_turf(user)
|
||||
qdel(src)
|
||||
var/datum/action/innate/cult/spear/S = new(user)
|
||||
var/obj/item/twohanded/cult_spear/rite = new(T)
|
||||
S.Grant(user, rite)
|
||||
rite.spear_act = S
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>A [rite.name] appears in your hand!</span>")
|
||||
else
|
||||
user.visible_message("<span class='warning'>A [rite.name] appears at [user]'s feet!</span>",
|
||||
"<span class='cult'>A [rite.name] materializes at your feet.</span>")
|
||||
|
||||
if("Blood Bolt Barrage (300)")
|
||||
if(uses < BLOOD_BARRAGE_COST)
|
||||
to_chat(user, "<span class='cultitalic'>You need [BLOOD_BARRAGE_COST] charges to perform this rite.</span>")
|
||||
else
|
||||
var/obj/rite = new /obj/item/gun/projectile/shotgun/boltaction/enchanted/arcane_barrage/blood()
|
||||
uses -= BLOOD_BARRAGE_COST
|
||||
qdel(src)
|
||||
user.swap_hand()
|
||||
user.drop_item()
|
||||
if(user.put_in_hands(rite))
|
||||
to_chat(user, "<span class='cult'>Both of your hands glow with power!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need a free hand for this rite!</span>")
|
||||
uses += BLOOD_BARRAGE_COST // Refund the charges
|
||||
qdel(rite)
|
||||
|
||||
@@ -85,6 +85,9 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
to_chat(cult_mind.current, CULT_GREETING)
|
||||
equip_cultist(cult_mind.current)
|
||||
cult_mind.current.faction |= "cult"
|
||||
var/datum/objective/servecult/obj = new
|
||||
obj.owner = cult_mind
|
||||
cult_mind.objectives += obj
|
||||
|
||||
if(cult_mind.assigned_role == "Clown")
|
||||
to_chat(cult_mind.current, "<span class='cultitalic'>A dark power has allowed you to overcome your clownish nature, letting you wield weapons without harming yourself.</span>")
|
||||
@@ -96,54 +99,11 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
add_cult_actions(cult_mind)
|
||||
update_cult_icons_added(cult_mind)
|
||||
cult_objs.study(cult_mind.current)
|
||||
to_chat(cult_mind.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Cultist)</span>")
|
||||
cult_threshold_check()
|
||||
addtimer(CALLBACK(src, .proc/cult_threshold_check), 2 MINUTES) // Check again in 2 minutes for latejoiners
|
||||
..()
|
||||
|
||||
/**
|
||||
* Decides at the start of the round how many conversions are needed to rise/ascend.
|
||||
*
|
||||
* The number is decided by (Percentage * (Players - Cultists)), so for example at 110 players it would be 11 conversions for rise. (0.1 * (110 - 4))
|
||||
* These values change based on population because 20 cultists are MUCH more powerful if there's only 50 players, compared to 120.
|
||||
*
|
||||
* Below 100 players, [CULT_RISEN_LOW] and [CULT_ASCENDANT_LOW] are used.
|
||||
* Above 100 players, [CULT_RISEN_HIGH] and [CULT_ASCENDANT_HIGH] are used.
|
||||
*/
|
||||
/datum/game_mode/proc/cult_threshold_check()
|
||||
var/players = length(GLOB.player_list)
|
||||
var/cultists = get_cultists() // Don't count the starting cultists towards the number of needed conversions
|
||||
if(players >= CULT_POPULATION_THRESHOLD)
|
||||
// Highpop
|
||||
ascend_percent = CULT_ASCENDANT_HIGH
|
||||
rise_number = round(CULT_RISEN_HIGH * (players - cultists))
|
||||
ascend_number = round(CULT_ASCENDANT_HIGH * (players - cultists))
|
||||
else
|
||||
// Lowpop
|
||||
ascend_percent = CULT_ASCENDANT_LOW
|
||||
rise_number = round(CULT_RISEN_LOW * (players - cultists))
|
||||
ascend_number = round(CULT_ASCENDANT_LOW * (players - cultists))
|
||||
|
||||
/**
|
||||
* Returns the current number of cultists and constructs.
|
||||
*
|
||||
* Returns the number of cultists and constructs in a list ([1] = Cultists, [2] = Constructs), or as one combined number.
|
||||
*
|
||||
* * separate - Should the number be returned in two separate values (Humans and Constructs) or as one?
|
||||
*/
|
||||
/datum/game_mode/proc/get_cultists(separate = FALSE)
|
||||
var/cultists = 0
|
||||
var/constructs = 0
|
||||
for(var/I in cult)
|
||||
var/datum/mind/M = I
|
||||
if(ishuman(M.current) && !M.current.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST))
|
||||
cultists++
|
||||
else if(isconstruct(M.current))
|
||||
constructs++
|
||||
if(separate)
|
||||
return list(cultists, constructs)
|
||||
else
|
||||
return cultists + constructs
|
||||
|
||||
/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/H, metal = TRUE)
|
||||
if(!istype(H))
|
||||
return
|
||||
@@ -207,8 +167,84 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
ascend(cult_mind.current)
|
||||
check_cult_size()
|
||||
cult_objs.study(cult_mind.current)
|
||||
to_chat(cult_mind.current, "<span class='motd'>For more information, check the wiki page: ([config.wikiurl]/index.php/Cultist)</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = TRUE, remove_gear = FALSE)
|
||||
if(!(cult_mind in cult)) // Not actually a cultist in the first place
|
||||
return
|
||||
|
||||
var/mob/cultist = cult_mind.current
|
||||
cult -= cult_mind
|
||||
cultist.faction -= "cult"
|
||||
cult_mind.special_role = null
|
||||
for(var/datum/objective/servecult/S in cult_mind.objectives)
|
||||
cult_mind.objectives -= S
|
||||
qdel(S)
|
||||
for(var/datum/action/innate/cult/C in cultist.actions)
|
||||
qdel(C)
|
||||
update_cult_icons_removed(cult_mind)
|
||||
|
||||
if(ishuman(cultist))
|
||||
var/mob/living/carbon/human/H = cultist
|
||||
REMOVE_TRAIT(H, CULT_EYES, null)
|
||||
H.change_eye_color(H.original_eye_color, FALSE)
|
||||
H.update_eyes()
|
||||
H.remove_overlay(HALO_LAYER)
|
||||
H.update_body()
|
||||
if(remove_gear) // No flagellants robe for non-cultists
|
||||
for(var/I in H.contents)
|
||||
if(is_type_in_list(I, CULT_CLOTHING))
|
||||
H.unEquip(I)
|
||||
check_cult_size()
|
||||
if(show_message)
|
||||
cultist.visible_message("<span class='cult'>[cultist] looks like [cultist.p_they()] just reverted to [cultist.p_their()] old faith!</span>",
|
||||
"<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of [SSticker.cultdat ? SSticker.cultdat.entity_title1 : "Nar'Sie"] and the memories of your time as their servant with it.</span>")
|
||||
|
||||
|
||||
/**
|
||||
* Decides at the start of the round how many conversions are needed to rise/ascend.
|
||||
*
|
||||
* The number is decided by (Percentage * (Players - Cultists)), so for example at 110 players it would be 11 conversions for rise. (0.1 * (110 - 4))
|
||||
* These values change based on population because 20 cultists are MUCH more powerful if there's only 50 players, compared to 120.
|
||||
*
|
||||
* Below 100 players, [CULT_RISEN_LOW] and [CULT_ASCENDANT_LOW] are used.
|
||||
* Above 100 players, [CULT_RISEN_HIGH] and [CULT_ASCENDANT_HIGH] are used.
|
||||
*/
|
||||
/datum/game_mode/proc/cult_threshold_check()
|
||||
var/players = length(GLOB.player_list)
|
||||
var/cultists = get_cultists() // Don't count the starting cultists towards the number of needed conversions
|
||||
if(players >= CULT_POPULATION_THRESHOLD)
|
||||
// Highpop
|
||||
ascend_percent = CULT_ASCENDANT_HIGH
|
||||
rise_number = round(CULT_RISEN_HIGH * (players - cultists))
|
||||
ascend_number = round(CULT_ASCENDANT_HIGH * (players - cultists))
|
||||
else
|
||||
// Lowpop
|
||||
ascend_percent = CULT_ASCENDANT_LOW
|
||||
rise_number = round(CULT_RISEN_LOW * (players - cultists))
|
||||
ascend_number = round(CULT_ASCENDANT_LOW * (players - cultists))
|
||||
|
||||
/**
|
||||
* Returns the current number of cultists and constructs.
|
||||
*
|
||||
* Returns the number of cultists and constructs in a list ([1] = Cultists, [2] = Constructs), or as one combined number.
|
||||
*
|
||||
* * separate - Should the number be returned as a list with two separate values (Humans and Constructs) or as one number.
|
||||
*/
|
||||
/datum/game_mode/proc/get_cultists(separate = FALSE)
|
||||
var/cultists = 0
|
||||
var/constructs = 0
|
||||
for(var/I in cult)
|
||||
var/datum/mind/M = I
|
||||
if(ishuman(M.current) && !M.current.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST))
|
||||
cultists++
|
||||
else if(isconstruct(M.current))
|
||||
constructs++
|
||||
if(separate)
|
||||
return list(cultists, constructs)
|
||||
else
|
||||
return cultists + constructs
|
||||
|
||||
/datum/game_mode/proc/check_cult_size()
|
||||
if(cult_ascendant)
|
||||
@@ -238,6 +274,8 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
/datum/game_mode/proc/rise(cultist)
|
||||
if(ishuman(cultist) && iscultist(cultist))
|
||||
var/mob/living/carbon/human/H = cultist
|
||||
if(!H.original_eye_color)
|
||||
H.original_eye_color = H.get_eye_color()
|
||||
H.change_eye_color(BLOODCULT_EYE, FALSE)
|
||||
H.update_eyes()
|
||||
ADD_TRAIT(H, CULT_EYES, CULT_TRAIT)
|
||||
@@ -249,29 +287,6 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(H), H.dir)
|
||||
H.update_halo_layer()
|
||||
|
||||
|
||||
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = TRUE)
|
||||
if(cult_mind in cult)
|
||||
var/mob/cultist = cult_mind.current
|
||||
cult -= cult_mind
|
||||
cultist.faction -= "cult"
|
||||
cult_mind.special_role = null
|
||||
for(var/datum/action/innate/cult/C in cultist.actions)
|
||||
qdel(C)
|
||||
update_cult_icons_removed(cult_mind)
|
||||
|
||||
if(ishuman(cultist))
|
||||
var/mob/living/carbon/human/H = cultist
|
||||
REMOVE_TRAIT(H, CULT_EYES, null)
|
||||
H.change_eye_color(H.original_eye_color, FALSE)
|
||||
H.update_eyes()
|
||||
H.remove_overlay(HALO_LAYER)
|
||||
H.update_body()
|
||||
check_cult_size()
|
||||
if(show_message)
|
||||
cultist.visible_message("<span class='cult'>[cultist] looks like [cultist.p_they()] just reverted to [cultist.p_their()] old faith!</span>",
|
||||
"<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of [SSticker.cultdat ? SSticker.cultdat.entity_title1 : "Nar'Sie"] and the memories of your time as their servant with it.</span>")
|
||||
|
||||
/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind)
|
||||
var/datum/atom_hud/antag/culthud = GLOB.huds[ANTAG_HUD_CULT]
|
||||
if(cult_mind.current)
|
||||
|
||||
@@ -316,7 +316,8 @@
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.pulling)
|
||||
var/atom/movable/pulled = C.pulling
|
||||
pulled.forceMove(T)
|
||||
var/turf/turf_behind = get_turf(get_step(T, turn(C.dir, 180)))
|
||||
pulled.forceMove(turf_behind)
|
||||
. = pulled
|
||||
|
||||
/obj/item/cult_shift/attack_self(mob/user)
|
||||
@@ -324,7 +325,7 @@
|
||||
to_chat(user, "<span class='warning'>[src] is dull and unmoving in your hands.</span>")
|
||||
return
|
||||
if(!iscultist(user))
|
||||
user.unEquip(src, 1)
|
||||
user.unEquip(src, TRUE)
|
||||
step(src, pick(GLOB.alldirs))
|
||||
to_chat(user, "<span class='warning'>[src] flickers out of your hands, too eager to move!</span>")
|
||||
return
|
||||
@@ -332,36 +333,31 @@
|
||||
var/outer_tele_radius = 9
|
||||
|
||||
var/mob/living/carbon/C = user
|
||||
var/turf/mobloc = get_turf(C)
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in range(user, outer_tele_radius))
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in orange(user, outer_tele_radius))
|
||||
if(!is_teleport_allowed(T.z))
|
||||
break
|
||||
if(get_dir(C, T) != C.dir)
|
||||
if(get_dir(C, T) != C.dir) // This seems like a very bad way to do this
|
||||
continue
|
||||
if(T == mobloc)
|
||||
continue
|
||||
if(istype(T, /turf/space))
|
||||
if(isspaceturf(T))
|
||||
continue
|
||||
if(T.x > world.maxx-outer_tele_radius || T.x < outer_tele_radius)
|
||||
continue //putting them at the edge is dumb
|
||||
if(T.y > world.maxy-outer_tele_radius || T.y < outer_tele_radius)
|
||||
continue
|
||||
|
||||
turfs += T
|
||||
|
||||
if(turfs)
|
||||
if(length(turfs))
|
||||
uses--
|
||||
var/turf/mobloc = get_turf(C)
|
||||
var/turf/destination = pick(turfs)
|
||||
if(uses <= 0)
|
||||
icon_state ="shifter_drained"
|
||||
playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
icon_state = "shifter_drained"
|
||||
playsound(src, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
new /obj/effect/temp_visual/dir_setting/cult/phase/out(mobloc, C.dir)
|
||||
|
||||
var/atom/movable/pulled = handle_teleport_grab(destination, C)
|
||||
handle_teleport_grab(destination, C)
|
||||
C.forceMove(destination)
|
||||
if(pulled)
|
||||
C.start_pulling(pulled) //forcemove resets pulls, so we need to re-pull
|
||||
|
||||
new /obj/effect/temp_visual/dir_setting/cult/phase(destination, C.dir)
|
||||
playsound(destination, 'sound/effects/phasein.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user