mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-24 04:27:35 +01:00
Please don't break
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
+4
-7
@@ -1,8 +1,5 @@
|
||||
{
|
||||
"workbench.editorAssociations": [
|
||||
{
|
||||
"filenamePattern": "*.dmi",
|
||||
"viewType": "imagePreview.previewEditor"
|
||||
}
|
||||
]
|
||||
}
|
||||
"workbench.editorAssociations": {
|
||||
"*.dmi": "imagePreview.previewEditor"
|
||||
}
|
||||
}
|
||||
@@ -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`),
|
||||
@@ -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;
|
||||
|
||||
@@ -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`),
|
||||
@@ -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,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;
|
||||
@@ -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
@@ -2388,7 +2388,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 +4114,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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -11168,6 +11168,9 @@
|
||||
icon_state = "tube1";
|
||||
tag = "icon-tube1 (WEST)"
|
||||
},
|
||||
/obj/structure/chair/comfy/shuttle{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/specops)
|
||||
"QL" = (
|
||||
|
||||
@@ -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
|
||||
@@ -363,7 +363,7 @@
|
||||
#define INVESTIGATE_BOMB "bombs"
|
||||
|
||||
// The SQL version required by this version of the code
|
||||
#define SQL_VERSION 23
|
||||
#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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -514,6 +514,7 @@
|
||||
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>"
|
||||
@@ -653,6 +654,62 @@
|
||||
// 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
|
||||
*
|
||||
@@ -671,3 +728,4 @@
|
||||
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"
|
||||
@@ -152,8 +152,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
|
||||
|
||||
@@ -2072,7 +2072,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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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,9 +86,6 @@ 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
|
||||
|
||||
@@ -45,7 +45,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 +56,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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]'")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -429,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -640,6 +640,7 @@
|
||||
if(istype(I))
|
||||
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
|
||||
@@ -783,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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 /////////////////////////////////////////
|
||||
|
||||
@@ -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"
|
||||
@@ -1425,7 +1426,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 = ""
|
||||
|
||||
@@ -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
|
||||
@@ -1310,15 +1293,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
|
||||
/area/medical/robotics
|
||||
name = "Robotics"
|
||||
icon_state = "medresearch"
|
||||
icon_state = "research"
|
||||
|
||||
/area/medical/research
|
||||
name = "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 = "Virology"
|
||||
@@ -1459,10 +1438,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
+4
-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.
|
||||
|
||||
|
||||
@@ -178,12 +178,10 @@
|
||||
/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/mob/dead/observer/ghost = get_ghost(TRUE)
|
||||
if(stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH))
|
||||
var/revivable
|
||||
if(ghost && !ghost.can_reenter_corpse) // DNR or AntagHUD
|
||||
if(!ghost_can_reenter()) // DNR or AntagHUD
|
||||
revivable = FALSE
|
||||
else if(timeofdeath && (round(world.time - timeofdeath) < DEFIB_TIME_LIMIT))
|
||||
revivable = TRUE
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -128,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.")
|
||||
@@ -173,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)
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -195,6 +195,7 @@
|
||||
GLOBAL_LIST_INIT(blacklisted_pylon_turfs, typecacheof(list(
|
||||
/turf/simulated/floor/engine/cult,
|
||||
/turf/space,
|
||||
/turf/simulated/wall/indestructible,
|
||||
/turf/simulated/floor/plating/lava,
|
||||
/turf/simulated/floor/chasm,
|
||||
/turf/simulated/wall/cult,
|
||||
|
||||
@@ -366,6 +366,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
return
|
||||
|
||||
var/sacrifice_fulfilled
|
||||
var/worthless = FALSE
|
||||
var/datum/game_mode/gamemode = SSticker.mode
|
||||
if(offering.mind)
|
||||
GLOB.sacrificed += offering.mind
|
||||
@@ -379,13 +380,16 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
if(sacrifice_fulfilled)
|
||||
to_chat(M, "<span class='cultlarge'>\"Yes! This is the one I desire! You have done well.\"</span>")
|
||||
else
|
||||
if(ishuman(offering) || isrobot(offering))
|
||||
if(ishuman(offering) && offering.mind.offstation_role && offering.mind.special_role != SPECIAL_ROLE_ERT) //If you try it on a ghost role, you get nothing
|
||||
to_chat(M, "<span class='cultlarge'>\"This soul is of no use to either of us.\"</span>")
|
||||
worthless = TRUE
|
||||
else if(ishuman(offering) || isrobot(offering))
|
||||
to_chat(M, "<span class='cultlarge'>\"I accept this sacrifice.\"</span>")
|
||||
else
|
||||
to_chat(M, "<span class='cultlarge'>\"I accept this meager sacrifice.\"</span>")
|
||||
playsound(offering, 'sound/misc/demon_consume.ogg', 100, TRUE)
|
||||
|
||||
if((ishuman(offering) || isrobot(offering) || isbrain(offering)) && offering.mind)
|
||||
if(((ishuman(offering) || isrobot(offering) || isbrain(offering)) && offering.mind) && !worthless)
|
||||
var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src))
|
||||
stone.invisibility = INVISIBILITY_MAXIMUM // So it's not picked up during transfer_soul()
|
||||
stone.transfer_soul("FORCE", offering, user) // If it cannot be added
|
||||
@@ -591,7 +595,8 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
return
|
||||
sacrifices_used += SOULS_TO_REVIVE
|
||||
mob_to_revive.revive()
|
||||
mob_to_revive.grab_ghost()
|
||||
if(mob_to_revive.ghost_can_reenter())
|
||||
mob_to_revive.grab_ghost()
|
||||
|
||||
if(!mob_to_revive.client || mob_to_revive.client.is_afk())
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
if(target.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[target] will not fit into [src] because [target.p_they()] [target.p_have()] a slime latched onto [target.p_their()] head.</span>")
|
||||
return
|
||||
visible_message("[user] puts [target] into the [src].")
|
||||
visible_message("<span class='notice'>[user] puts [target] into [src].</span>")
|
||||
|
||||
target.forceMove(src)
|
||||
occupant = target
|
||||
@@ -187,12 +187,12 @@
|
||||
if(isabductor(grabbed.affecting))
|
||||
return
|
||||
if(occupant)
|
||||
to_chat(user, "<span class='notice'>The [src] is already occupied!</span>")
|
||||
to_chat(user, "<span class='notice'>[src] is already occupied!</span>")
|
||||
return
|
||||
if(grabbed.affecting.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[grabbed.affecting] will not fit into [src] because [grabbed.affecting.p_they()] [grabbed.affecting.p_have()] a slime latched onto [grabbed.affecting.p_their()] head.</span>")
|
||||
return
|
||||
visible_message("[user] puts [grabbed.affecting] into the [src].")
|
||||
visible_message("<span class='notice'>[user] puts [grabbed.affecting] into [src].</span>")
|
||||
var/mob/living/carbon/human/H = grabbed.affecting
|
||||
H.forceMove(src)
|
||||
occupant = H
|
||||
|
||||
@@ -332,6 +332,14 @@
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/fans/tiny/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/holosign/barrier/atmos/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/tcomms/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>This communications relay should be preserved, it will be a useful resource to our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
/obj/item/guardian_bomb/proc/detonate(mob/living/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
to_chat(user, "<span class='danger'>The [src] was boobytrapped!</span>")
|
||||
to_chat(user, "<span class='danger'>[src] was boobytrapped!</span>")
|
||||
if(istype(spawner, /mob/living/simple_animal/hostile/guardian))
|
||||
var/mob/living/simple_animal/hostile/guardian/G = spawner
|
||||
if(user == G.summoner)
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
F.icon = 'icons/turf/floors.dmi'
|
||||
F.name = "bluespace recieving pad"
|
||||
F.desc = "A recieving zone for bluespace teleportations. Building a wall over it should disable it."
|
||||
F.icon_state = "light_on-w"
|
||||
F.icon_state = "light_on"
|
||||
to_chat(src, "<span class='danger'>Beacon placed! You may now warp targets to it, including your user, via Alt+Click. </span>")
|
||||
if(beacon)
|
||||
beacon.ChangeTurf(/turf/simulated/floor/plating)
|
||||
|
||||
@@ -108,18 +108,23 @@
|
||||
var/agent_number = 1
|
||||
var/spawnpos = 1
|
||||
|
||||
var/obj/machinery/nuclearbomb/syndicate/the_bomb
|
||||
if(nuke_spawn && length(synd_spawn))
|
||||
the_bomb = new /obj/machinery/nuclearbomb/syndicate(nuke_spawn.loc)
|
||||
the_bomb.r_code = nuke_code
|
||||
|
||||
for(var/datum/mind/synd_mind in syndicates)
|
||||
if(spawnpos > synd_spawn.len)
|
||||
spawnpos = 2
|
||||
synd_mind.current.loc = synd_spawn[spawnpos]
|
||||
synd_mind.offstation_role = TRUE
|
||||
forge_syndicate_objectives(synd_mind)
|
||||
create_syndicate(synd_mind)
|
||||
create_syndicate(synd_mind, the_bomb)
|
||||
greet_syndicate(synd_mind)
|
||||
equip_syndicate(synd_mind.current)
|
||||
|
||||
if(!leader_selected)
|
||||
prepare_syndicate_leader(synd_mind, nuke_code)
|
||||
prepare_syndicate_leader(synd_mind, the_bomb)
|
||||
leader_selected = 1
|
||||
else
|
||||
synd_mind.current.real_name = "[syndicate_name()] Operative #[agent_number]"
|
||||
@@ -131,9 +136,6 @@
|
||||
|
||||
scale_telecrystals()
|
||||
share_telecrystals()
|
||||
if(nuke_spawn && synd_spawn.len > 0)
|
||||
var/obj/machinery/nuclearbomb/syndicate/the_bomb = new /obj/machinery/nuclearbomb/syndicate(nuke_spawn.loc)
|
||||
the_bomb.r_code = nuke_code
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -160,7 +162,7 @@
|
||||
U.hidden_uplink.uses++
|
||||
remainder--
|
||||
|
||||
/datum/game_mode/proc/create_syndicate(datum/mind/synd_mind) // So we don't have inferior species as ops - randomize a human
|
||||
/datum/game_mode/proc/create_syndicate(datum/mind/synd_mind, obj/machinery/nuclearbomb/syndicate/the_bomb) // So we don't have inferior species as ops - randomize a human
|
||||
var/mob/living/carbon/human/M = synd_mind.current
|
||||
|
||||
M.set_species(/datum/species/human, TRUE)
|
||||
@@ -186,7 +188,14 @@
|
||||
M.regenerate_icons()
|
||||
M.update_body()
|
||||
|
||||
/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code)
|
||||
if(!the_bomb)
|
||||
the_bomb = locate(/obj/machinery/nuclearbomb/syndicate) in GLOB.poi_list
|
||||
|
||||
if(the_bomb)
|
||||
synd_mind.store_memory("<B>Syndicate [the_bomb.name] Code</B>: [the_bomb.r_code]")
|
||||
to_chat(synd_mind.current, "The code for \the [the_bomb.name] is: <B>[the_bomb.r_code]</B>")
|
||||
|
||||
/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, obj/machinery/nuclearbomb/syndicate/the_bomb)
|
||||
var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")
|
||||
synd_mind.current.real_name = "[syndicate_name()] Team [leader_title]"
|
||||
to_chat(synd_mind.current, "<B>You are the Syndicate leader for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.</B>")
|
||||
@@ -198,11 +207,9 @@
|
||||
|
||||
update_syndicate_id(synd_mind, leader_title, TRUE)
|
||||
|
||||
if(nuke_code)
|
||||
synd_mind.store_memory("<B>Syndicate Nuclear Bomb Code</B>: [nuke_code]", 0, 0)
|
||||
to_chat(synd_mind.current, "The nuclear authorization code is: <B>[nuke_code]</B>")
|
||||
if(the_bomb)
|
||||
var/obj/item/paper/P = new
|
||||
P.info = "The nuclear authorization code is: <b>[nuke_code]</b>"
|
||||
P.info = "The code for \the [the_bomb.name] is: <B>[the_bomb.r_code]</B>"
|
||||
P.name = "nuclear bomb code"
|
||||
var/obj/item/stamp/syndicate/stamp = new
|
||||
P.stamp(stamp)
|
||||
@@ -216,8 +223,6 @@
|
||||
H.equip_to_slot_or_del(P, slot_r_store, 0)
|
||||
H.update_icons()
|
||||
|
||||
else
|
||||
nuke_code = "code will be provided later"
|
||||
|
||||
/datum/game_mode/proc/update_syndicate_id(datum/mind/synd_mind, is_leader = FALSE)
|
||||
var/list/found_ids = synd_mind.current.search_contents_for(/obj/item/card/id)
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
for(var/obj/machinery/computer/shuttle/syndicate/S in GLOB.machines)
|
||||
S.challenge = TRUE
|
||||
S.challenge_time = world.time
|
||||
|
||||
// No. of player - Min. Player to dec, divided by player per bonus, then multipled by TC per bonus. Rounded.
|
||||
total_tc = CHALLENGE_TELECRYSTALS + round((((GLOB.player_list.len - CHALLENGE_MIN_PLAYERS)/CHALLENGE_SCALE_PLAYER) * CHALLENGE_SCALE_BONUS))
|
||||
|
||||
@@ -465,7 +465,7 @@ GLOBAL_VAR(bomb_set)
|
||||
else if(off_station == 2)
|
||||
to_chat(world, "<b>A nuclear device was set off, but the device was not on the station!</b>")
|
||||
else
|
||||
to_chat(world, "<b>The station was destoyed by the nuclear blast!</b>")
|
||||
to_chat(world, "<b>The station was destroyed by the nuclear blast!</b>")
|
||||
|
||||
SSticker.mode.station_was_nuked = (off_station < 2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated.
|
||||
//kinda shit but I couldn't get permission to do what I wanted to do.
|
||||
@@ -483,12 +483,12 @@ GLOBAL_VAR(bomb_set)
|
||||
if(safety == 1)
|
||||
if(!is_syndicate)
|
||||
set_security_level(previous_level)
|
||||
visible_message("<span class='notice'>The [src] quiets down.</span>")
|
||||
visible_message("<span class='notice'>[src] quiets down.</span>")
|
||||
if(!lighthack)
|
||||
if(icon_state == "nuclearbomb2")
|
||||
icon_state = "nuclearbomb1"
|
||||
else
|
||||
visible_message("<span class='notice'>The [src] emits a quiet whirling noise!</span>")
|
||||
visible_message("<span class='notice'>[src] emits a quiet whirling noise!</span>")
|
||||
|
||||
//==========DAT FUKKEN DISK===============
|
||||
/obj/item/disk/nuclear
|
||||
|
||||
@@ -513,7 +513,7 @@
|
||||
target_apc.operating = 0
|
||||
target_apc.update()
|
||||
target_apc.update_icon()
|
||||
target_apc.visible_message("<span class='warning'>The [target_apc] flickers and begins to grow dark.</span>")
|
||||
target_apc.visible_message("<span class='warning'>[target_apc] flickers and begins to grow dark.</span>")
|
||||
|
||||
to_chat(user, "<span class='shadowling'>You dim the APC's screen and carefully begin siphoning its power into the void.</span>")
|
||||
if(!do_after(user, 200, target=target_apc))
|
||||
@@ -522,7 +522,7 @@
|
||||
target_apc.operating = 1
|
||||
target_apc.update()
|
||||
target_apc.update_icon()
|
||||
target_apc.visible_message("<span class='warning'>The [target_apc] begins glowing brightly!</span>")
|
||||
target_apc.visible_message("<span class='warning'>[target_apc] begins glowing brightly!</span>")
|
||||
else
|
||||
//We did it!
|
||||
to_chat(user, "<span class='shadowling'>You sent the APC's power to the void while overloading all it's lights!</span>")
|
||||
|
||||
@@ -290,7 +290,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
|
||||
draining = null
|
||||
return
|
||||
add_attack_logs(owner, H, "vampirebit & is draining their blood.", ATKLOG_ALMOSTALL)
|
||||
owner.visible_message("<span class='danger'>[owner] grabs [H]'s neck harshly and sinks in [owner.p_their()] fangs!</span>", "<span class='danger'>You sink your fangs into [H] and begin to drain [owner.p_their()] blood.</span>", "<span class='notice'>You hear a soft puncture and a wet sucking noise.</span>")
|
||||
owner.visible_message("<span class='danger'>[owner] grabs [H]'s neck harshly and sinks in [owner.p_their()] fangs!</span>", "<span class='danger'>You sink your fangs into [H] and begin to drain [H.p_their()] blood.</span>", "<span class='notice'>You hear a soft puncture and a wet sucking noise.</span>")
|
||||
if(!iscarbon(owner))
|
||||
H.LAssailant = null
|
||||
else
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
action_background_icon_state = "bg_vampire"
|
||||
var/required_blood = 0
|
||||
var/gain_desc = null
|
||||
var/deduct_blood_on_cast = TRUE //Do we want to take the blood when this is cast, or at a later point?
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/New()
|
||||
..()
|
||||
@@ -99,6 +100,8 @@
|
||||
var/datum/vampire/vampire = usr.mind.vampire
|
||||
|
||||
if(required_blood <= vampire.bloodusable)
|
||||
if(!deduct_blood_on_cast) //don't take the blood yet if this is false!
|
||||
return
|
||||
vampire.bloodusable -= required_blood
|
||||
else
|
||||
// stop!!
|
||||
@@ -288,8 +291,10 @@
|
||||
gain_desc = "You have gained the Enthrall ability which at a heavy blood cost allows you to enslave a human that is not loyal to any other for a random period of time."
|
||||
action_icon_state = "vampire_enthrall"
|
||||
required_blood = 300
|
||||
deduct_blood_on_cast = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/targetted/enthrall/cast(list/targets, mob/user = usr)
|
||||
var/datum/vampire/vampire = user.mind.vampire
|
||||
for(var/mob/living/target in targets)
|
||||
user.visible_message("<span class='warning'>[user] bites [target]'s neck!</span>", "<span class='warning'>You bite [target]'s neck and begin the flow of power.</span>")
|
||||
to_chat(target, "<span class='warning'>You feel the tendrils of evil invade your mind.</span>")
|
||||
@@ -299,6 +304,7 @@
|
||||
if(do_mob(user, target, 50))
|
||||
if(can_enthrall(user, target))
|
||||
handle_enthrall(user, target)
|
||||
vampire.bloodusable -= required_blood //we take the blood after enthralling, not before
|
||||
else
|
||||
revert_cast(user)
|
||||
to_chat(user, "<span class='warning'>You or your target either moved or you dont have enough usable blood.</span>")
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
new /obj/effect/particle_effect/smoke(H.loc)
|
||||
var/mob/living/carbon/human/M = new/mob/living/carbon/human(H.loc)
|
||||
M.key = C.key
|
||||
to_chat(M, "<B>You are the [H.real_name]'s apprentice! You are bound by magic contract to follow [H.p_their()] orders and help [H.p_them()] in accomplishing their goals.")
|
||||
to_chat(M, "<B>You are [H.real_name]'s apprentice! You are bound by magic contract to follow [H.p_their()] orders and help [H.p_them()] in accomplishing their goals.")
|
||||
switch(href_list["school"])
|
||||
if("destruction")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
|
||||
@@ -293,7 +293,7 @@ GLOBAL_LIST_EMPTY(multiverse)
|
||||
|
||||
/obj/item/multisword/attack(mob/living/M as mob, mob/living/user as mob) //to prevent accidental friendly fire or out and out grief.
|
||||
if(M.real_name == user.real_name)
|
||||
to_chat(user, "<span class='warning'>The [src] detects benevolent energies in your target and redirects your attack!</span>")
|
||||
to_chat(user, "<span class='warning'>[src] detects benevolent energies in your target and redirects your attack!</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -856,7 +856,7 @@ GLOBAL_LIST_EMPTY(multiverse)
|
||||
if(link)
|
||||
target = null
|
||||
link.loc = get_turf(src)
|
||||
to_chat(user, "<span class='notice'>You remove the [link] from the doll.</span>")
|
||||
to_chat(user, "<span class='notice'>You remove [link] from the doll.</span>")
|
||||
link = null
|
||||
update_targets()
|
||||
return
|
||||
|
||||
@@ -95,6 +95,10 @@
|
||||
to_chat(user, "<span class='cultlarge'>\"Come now, do not capture your fellow's soul.\"</span>")
|
||||
return ..()
|
||||
|
||||
if(M.mind.offstation_role && M.mind.special_role != SPECIAL_ROLE_ERT)
|
||||
to_chat(user, "<span class='warning'>This being's soul seems worthless. Not even the stone will absorb it.</span>")
|
||||
return ..()
|
||||
|
||||
if(optional)
|
||||
if(!M.ckey)
|
||||
to_chat(user, "<span class='warning'>They have no soul!</span>")
|
||||
@@ -253,17 +257,18 @@
|
||||
return ..()
|
||||
|
||||
////////////////////////////Proc for moving soul in and out off stone//////////////////////////////////////
|
||||
|
||||
// this whole proc is pain
|
||||
/obj/item/soulstone/proc/transfer_soul(choice, target, mob/user)
|
||||
switch(choice)
|
||||
if("FORCE")
|
||||
var/mob/living/T = target
|
||||
if(T.client != null)
|
||||
T.grab_ghost(FALSE) // If they haven't DC'd or ahudded, put them back in their body
|
||||
if(T.client) // If there's someone in the body
|
||||
init_shade(T, user)
|
||||
else
|
||||
else // Poll ghosts
|
||||
to_chat(user, "<span class='userdanger'>Capture failed!</span> The soul has already fled its mortal frame. You attempt to bring it back...")
|
||||
T.Paralyse(20)
|
||||
if(!get_cult_ghost(T, user))
|
||||
if(!get_cult_ghost(T, user, TRUE))
|
||||
T.dust() //If we can't get a ghost, kill the sacrifice anyway.
|
||||
|
||||
if("VICTIM")
|
||||
@@ -276,7 +281,7 @@
|
||||
else
|
||||
if(T.client == null)
|
||||
to_chat(user, "<span class='userdanger'>Capture failed!</span> The soul has already fled its mortal frame. You attempt to bring it back...")
|
||||
get_cult_ghost(T, user)
|
||||
get_cult_ghost(T, user, get_new_player = !T.ghost_can_reenter())
|
||||
else
|
||||
if(length(contents))
|
||||
to_chat(user, "<span class='danger'>Capture failed!</span> The soul stone is full! Use or free an existing soul to make room.")
|
||||
@@ -312,9 +317,9 @@
|
||||
"Wraith" = /mob/living/simple_animal/hostile/construct/wraith,
|
||||
"Artificer" = /mob/living/simple_animal/hostile/construct/builder)
|
||||
/// Custom construct icons for different cults
|
||||
var/list/construct_icons = list("Juggernaut" = image(icon = 'icons/mob/mob.dmi', icon_state = SSticker.cultdat.get_icon("juggernaut")),
|
||||
"Wraith" = image(icon = 'icons/mob/mob.dmi', icon_state = SSticker.cultdat.get_icon("wraith")),
|
||||
"Artificer" = image(icon = 'icons/mob/mob.dmi', icon_state = SSticker.cultdat.get_icon("builder")))
|
||||
var/list/construct_icons = list("Juggernaut" = image(icon = 'icons/mob/cult.dmi', icon_state = SSticker.cultdat.get_icon("juggernaut")),
|
||||
"Wraith" = image(icon = 'icons/mob/cult.dmi', icon_state = SSticker.cultdat.get_icon("wraith")),
|
||||
"Artificer" = image(icon = 'icons/mob/cult.dmi', icon_state = SSticker.cultdat.get_icon("builder")))
|
||||
|
||||
if(shade)
|
||||
var/construct_choice = show_radial_menu(user, shell, construct_icons, custom_check = CALLBACK(src, .proc/radial_check, user), require_near = TRUE)
|
||||
@@ -413,13 +418,14 @@
|
||||
return /mob/living/simple_animal/shade/holy
|
||||
return /mob/living/simple_animal/shade/cult
|
||||
|
||||
/obj/item/soulstone/proc/get_cult_ghost(mob/living/M, mob/user)
|
||||
/obj/item/soulstone/proc/get_cult_ghost(mob/living/M, mob/user, get_new_player = FALSE)
|
||||
var/mob/dead/observer/chosen_ghost
|
||||
|
||||
for(var/mob/dead/observer/ghost in GLOB.player_list) // We put them back in their body
|
||||
if(ghost.mind && ghost.mind.current == M && ghost.client)
|
||||
chosen_ghost = ghost
|
||||
break
|
||||
if(!get_new_player)
|
||||
for(var/mob/dead/observer/ghost in GLOB.player_list) // We put them back in their body
|
||||
if(ghost.mind && ghost.mind.current == M && ghost.client)
|
||||
chosen_ghost = ghost
|
||||
break
|
||||
|
||||
if(!chosen_ghost) // Failing that, we grab a ghost
|
||||
var/list/consenting_candidates
|
||||
|
||||
@@ -783,7 +783,7 @@
|
||||
owner = user
|
||||
return
|
||||
if(user != owner)
|
||||
to_chat(user, "<span class='warning'>The [name] does not recognize you as it's owner and refuses to open!</span>")
|
||||
to_chat(user, "<span class='warning'>[src] does not recognize you as it's owner and refuses to open!</span>")
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = ""
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
storedpda.desc = colorlist[P]
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The [src] is empty.</span>")
|
||||
to_chat(user, "<span class='notice'>[src] is empty.</span>")
|
||||
|
||||
|
||||
/obj/machinery/pdapainter/verb/ejectpda()
|
||||
@@ -120,7 +120,7 @@
|
||||
storedpda = null
|
||||
update_icon()
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>The [src] is empty.</span>")
|
||||
to_chat(usr, "<span class='notice'>[src] is empty.</span>")
|
||||
|
||||
|
||||
/obj/machinery/pdapainter/power_change()
|
||||
|
||||
@@ -481,7 +481,7 @@
|
||||
|
||||
if(unknown_body || e.hidden)
|
||||
imp += "Unknown body present:"
|
||||
if(!AN && !open && !infected & !imp)
|
||||
if(!AN && !open && !infected && !imp)
|
||||
AN = "None:"
|
||||
dat += "<td>[e.name]</td><td>[e.burn_dam]</td><td>[e.brute_dam]</td><td>[robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured][dead]</td>"
|
||||
dat += "</tr>"
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
return FALSE
|
||||
if(status)
|
||||
SSalarm.triggerAlarm("Motion", get_area(src), list(UID()), src)
|
||||
visible_message("<span class='warning'>A red light flashes on the [src]!</span>")
|
||||
visible_message("<span class='warning'>A red light flashes on [src]!</span>")
|
||||
detectTime = -1
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
|
||||
if(!silent)
|
||||
var/obj/oldobj = obj
|
||||
visible_message("The [oldobj.name] fades away!")
|
||||
visible_message("[oldobj] fades away!")
|
||||
qdel(obj)
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/proc/checkInteg(area/A)
|
||||
@@ -505,12 +505,12 @@
|
||||
return
|
||||
G.affecting.loc = src.loc
|
||||
G.affecting.Weaken(5)
|
||||
visible_message("<span class='warning'>[G.assailant] dunks [G.affecting] into the [src]!</span>")
|
||||
visible_message("<span class='warning'>[G.assailant] dunks [G.affecting] into [src]!</span>")
|
||||
qdel(W)
|
||||
return
|
||||
else if(istype(W, /obj/item) && get_dist(src,user)<2)
|
||||
user.drop_item(src)
|
||||
visible_message("<span class='notice'>[user] dunks [W] into the [src]!</span>")
|
||||
visible_message("<span class='notice'>[user] dunks [W] into [src]!</span>")
|
||||
return
|
||||
|
||||
/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
|
||||
@@ -59,10 +59,7 @@
|
||||
return TRUE
|
||||
if("toggle_bolts" in href_list)
|
||||
bolts = !bolts
|
||||
if(bolts)
|
||||
visible_message("You hear a quite click as the [src] bolts to the floor", "You hear a quite click")
|
||||
else
|
||||
visible_message("You hear a quite click as the [src]'s floor bolts raise", "You hear a quite click")
|
||||
visible_message("<span class='notice'>You hear a quiet click as [src][bolts ? " bolts to the floor" : "'s bolts raise"].</span>", "<span class='notice>You hear a quiet click.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/air_sensor/attackby(obj/item/W as obj, mob/user as mob)
|
||||
@@ -71,7 +68,7 @@
|
||||
return 1
|
||||
if(istype(W, /obj/item/wrench))
|
||||
if(bolts)
|
||||
to_chat(usr, "The [src] is bolted to the floor! You can't detach it like this.")
|
||||
to_chat(usr, "[src] is bolted to the floor! You can't detach it like this.")
|
||||
return 1
|
||||
playsound(loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
|
||||
@@ -392,7 +392,7 @@
|
||||
/obj/item/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob, params)
|
||||
if(istype(I,/obj/item/card/id)||istype(I, /obj/item/pda))
|
||||
if(allowed(user))
|
||||
user.visible_message("<span class='notice'>\the [user] waves [user.p_their()] ID past the [src]'s access protocol scanner.</span>", "<span class='notice'>You swipe your ID past the [src]'s access protocol scanner.</span>")
|
||||
user.visible_message("<span class='notice'>[user] waves [user.p_their()] ID past [src]'s access protocol scanner.</span>", "<span class='notice'>You swipe your ID past [src]'s access protocol scanner.</span>")
|
||||
var/console_choice = input(user, "What do you want to configure the access to?", "Access Modification", "R&D Core") as null|anything in access_types
|
||||
if(console_choice == null)
|
||||
return
|
||||
@@ -477,11 +477,11 @@
|
||||
return
|
||||
if(istype(P, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = P
|
||||
if(C.amount >= 5)
|
||||
if(C.get_amount() >= 5)
|
||||
playsound(loc, C.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add cables to the frame.</span>")
|
||||
if(do_after(user, 20 * C.toolspeed, target = src))
|
||||
if(state == 2 && C.amount >= 5 && C.use(5))
|
||||
if(state == 2 && C.get_amount() >= 5 && C.use(5))
|
||||
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
|
||||
state = 3
|
||||
icon_state = "3"
|
||||
@@ -502,11 +502,11 @@
|
||||
return
|
||||
if(istype(P, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = P
|
||||
if(G.amount >= 2)
|
||||
if(G.get_amount() >= 2)
|
||||
playsound(loc, G.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add the glass panel to the frame.</span>")
|
||||
if(do_after(user, 20 * G.toolspeed, target = src))
|
||||
if(state == 3 && G.amount >= 2 && G.use(2))
|
||||
if(state == 3 && G.get_amount() >= 2 && G.use(2))
|
||||
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
|
||||
state = 4
|
||||
icon_state = "4"
|
||||
@@ -608,11 +608,11 @@
|
||||
icon_state = "1"
|
||||
if(istype(P, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = P
|
||||
if(C.amount >= 5)
|
||||
if(C.get_amount() >= 5)
|
||||
playsound(loc, C.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add cables to the frame.</span>")
|
||||
if(do_after(user, 20 * C.toolspeed, target = src))
|
||||
if(state == 2 && C.amount >= 5 && C.use(5))
|
||||
if(state == 2 && C.get_amount() >= 5 && C.use(5))
|
||||
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
|
||||
state = 3
|
||||
icon_state = "3"
|
||||
@@ -633,11 +633,11 @@
|
||||
|
||||
if(istype(P, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = P
|
||||
if(G.amount >= 2)
|
||||
if(G.get_amount() >= 2)
|
||||
playsound(loc, G.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add the glass panel to the frame.</span>")
|
||||
if(do_after(user, 20 * G.toolspeed, target = src))
|
||||
if(state == 3 && G.amount >= 2 && G.use(2))
|
||||
if(state == 3 && G.get_amount() >= 2 && G.use(2))
|
||||
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
|
||||
state = 4
|
||||
icon_state = "4"
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
message_cooldown = world.time + 600 //One minute
|
||||
|
||||
if("callshuttle")
|
||||
var/input = clean_input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","")
|
||||
var/input = input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.") as null|message
|
||||
if(!input || ..() || !is_authenticated(usr))
|
||||
return
|
||||
call_shuttle_proc(usr, input)
|
||||
@@ -410,7 +410,7 @@
|
||||
else
|
||||
menu_state=value
|
||||
|
||||
/proc/call_shuttle_proc(mob/user, reason)
|
||||
/proc/call_shuttle_proc(mob/user, reason, sanitized = FALSE)
|
||||
if(GLOB.sent_strike_team == 1)
|
||||
to_chat(user, "<span class='warning'>Central Command will not allow the shuttle to be called. Consider all contracts terminated.</span>")
|
||||
return
|
||||
@@ -427,6 +427,9 @@
|
||||
to_chat(user, "<span class='warning'>Under directive 7-10, [station_name()] is quarantined until further notice.</span>")
|
||||
return
|
||||
|
||||
if(!sanitized)
|
||||
reason = trim_strip_html_properly(reason, allow_lines = TRUE)
|
||||
|
||||
SSshuttle.requestEvac(user, reason)
|
||||
log_game("[key_name(user)] has called the shuttle.")
|
||||
message_admins("[key_name_admin(user)] has called the shuttle.", 1)
|
||||
|
||||
@@ -225,5 +225,6 @@
|
||||
log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] emagged [key_name_admin(R)] using robotic console!</span>")
|
||||
R.emagged = TRUE
|
||||
R.module.rebuild_modules()
|
||||
to_chat(R, "<span class='notice'>Failsafe protocols overriden. New tools available.</span>")
|
||||
. = TRUE
|
||||
|
||||
@@ -75,11 +75,11 @@
|
||||
if(1)
|
||||
if(istype(P, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = P
|
||||
if(C.amount >= 5)
|
||||
if(C.get_amount() >= 5)
|
||||
playsound(src.loc, C.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add cables to the frame.</span>")
|
||||
if(do_after(user, 20 * C.toolspeed, target = src))
|
||||
if(state == 1 && C.amount >= 5 && C.use(5))
|
||||
if(state == 1 && C.get_amount() >= 5 && C.use(5))
|
||||
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
|
||||
state = 2
|
||||
icon_state = "box_1"
|
||||
@@ -193,8 +193,8 @@
|
||||
playsound(src.loc, P.usesound, 50, 1)
|
||||
if(istype(P, /obj/item/stack))
|
||||
var/obj/item/stack/S = P
|
||||
var/camt = min(S.amount, req_components[I])
|
||||
var/obj/item/stack/NS = new P.type(src)
|
||||
var/camt = min(S.get_amount(), req_components[I])
|
||||
var/obj/item/stack/NS = new S.merge_type(src)
|
||||
NS.amount = camt
|
||||
NS.update_icon()
|
||||
S.use(camt)
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
else
|
||||
. += "<span class='notice'>Its locking clamps can be [clamps_locked ? "dis" : ""]engaged by swiping an ID with access.</span>"
|
||||
else
|
||||
. += "<span class='notice'>There are a pair of <b>bolts</b> in the defib unit housing securing the [src] to the wall.<span>"
|
||||
. += "<span class='notice'>There are a pair of <b>bolts</b> in the defibrillator unit housing, securing [src] to the wall.<span>"
|
||||
|
||||
/obj/machinery/defibrillator_mount/process()
|
||||
if(defib && defib.cell && defib.cell.charge < defib.cell.maxcharge && is_operational())
|
||||
@@ -117,7 +117,7 @@
|
||||
/obj/machinery/defibrillator_mount/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(defib)
|
||||
to_chat(user, "<span class='warning'>The [defib] is blocking access to the bolts!</span>")
|
||||
to_chat(user, "<span class='warning'>[defib] is blocking access to the bolts!</span>")
|
||||
return
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
|
||||
@@ -195,11 +195,6 @@
|
||||
/obj/machinery/door/window/narsie_act()
|
||||
color = NARSIE_WINDOW_COLOUR
|
||||
|
||||
/obj/machinery/door/window/ratvar_act()
|
||||
var/obj/machinery/door/window/clockwork/C = new(loc, dir)
|
||||
C.name = name
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/door/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(exposed_temperature > T0C + (reinf ? 1600 : 800))
|
||||
@@ -358,9 +353,6 @@
|
||||
if(prob(80/severity))
|
||||
open()
|
||||
|
||||
/obj/machinery/door/window/clockwork/ratvar_act()
|
||||
obj_integrity = max_integrity
|
||||
|
||||
/obj/machinery/door/window/clockwork/hasPower()
|
||||
return TRUE //yup that's power all right
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
if(istype(I, /obj/item/hair_dye_bottle))
|
||||
var/obj/item/hair_dye_bottle/HD = I
|
||||
user.visible_message("<span class='notice'>[user] fills the [HD] up with some dye.</span>","<span class='notice'>You fill the [HD] up with some hair dye.</span>")
|
||||
user.visible_message("<span class='notice'>[user] fills [HD] up with some dye.</span>","<span class='notice'>You fill [HD] up with some hair dye.</span>")
|
||||
HD.dye_color = dye_color
|
||||
HD.update_dye_overlay()
|
||||
return
|
||||
@@ -52,7 +52,7 @@
|
||||
//Hair Dye Bottle
|
||||
|
||||
/obj/item/hair_dye_bottle
|
||||
name = "Hair Dye Bottle"
|
||||
name = "hair dye bottle"
|
||||
desc = "A refillable bottle used for holding hair dyes of all sorts of colors."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "hairdyebottle"
|
||||
|
||||
@@ -69,7 +69,7 @@ FIRE ALARM
|
||||
if(!emagged)
|
||||
emagged = TRUE
|
||||
if(user)
|
||||
user.visible_message("<span class='warning'>Sparks fly out of the [src]!</span>",
|
||||
user.visible_message("<span class='warning'>Sparks fly out of [src]!</span>",
|
||||
"<span class='notice'>You emag [src], disabling its thermal sensors.</span>")
|
||||
playsound(loc, 'sound/effects/sparks4.ogg', 50, 1)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
return 1
|
||||
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
to_chat(user, "You begin to unscrew the bolts off the [src]...")
|
||||
to_chat(user, "<span class='notice'>You begin to unscrew the bolts off [src]...</span>")
|
||||
playsound(get_turf(src), W.usesound, 50, 1)
|
||||
if(do_after(user, 30 * W.toolspeed, target = src))
|
||||
var/obj/machinery/mass_driver_frame/F = new(get_turf(src))
|
||||
@@ -126,7 +126,7 @@
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
to_chat(user, "You start adding cables to \the [src]...")
|
||||
playsound(get_turf(src), C.usesound, 50, 1)
|
||||
if(do_after(user, 20 * C.toolspeed, target = src) && (C.amount >= 2) && (build == 2))
|
||||
if(do_after(user, 20 * C.toolspeed, target = src) && (C.get_amount() >= 2) && (build == 2))
|
||||
C.use(2)
|
||||
to_chat(user, "<span class='notice'>You've added cables to \the [src].</span>")
|
||||
build++
|
||||
@@ -146,7 +146,7 @@
|
||||
var/obj/item/stack/rods/R = W
|
||||
to_chat(user, "You begin to complete \the [src]...")
|
||||
playsound(get_turf(src), R.usesound, 50, 1)
|
||||
if(do_after(user, 20 * R.toolspeed, target = src) && (R.amount >= 2) && (build == 3))
|
||||
if(do_after(user, 20 * R.toolspeed, target = src) && (R.get_amount() >= 2) && (build == 3))
|
||||
R.use(2)
|
||||
to_chat(user, "<span class='notice'>You've added the grille to \the [src].</span>")
|
||||
build++
|
||||
|
||||
@@ -145,6 +145,8 @@
|
||||
else if(our_rpd.mode == RPD_FLIP_MODE)
|
||||
flip()
|
||||
else if(our_rpd.mode == RPD_DELETE_MODE)
|
||||
if(pipe_type == PIPE_CIRCULATOR) //Skip TEG heat circulators, they aren't really pipes
|
||||
return ..()
|
||||
our_rpd.delete_single_pipe(user, src)
|
||||
else
|
||||
return ..()
|
||||
@@ -499,13 +501,11 @@
|
||||
P.on_construction(dir, pipe_dir, color)
|
||||
|
||||
user.visible_message( \
|
||||
"[user] fastens the [src].", \
|
||||
"<span class='notice'>You have fastened the [src].</span>", \
|
||||
"You hear ratchet.")
|
||||
"<span class='notice'>[user] fastens [src].</span>",
|
||||
"<span class='notice'>You fasten [src].</span>",
|
||||
"<span class='notice'>You hear a ratchet.</span>")
|
||||
qdel(src) // remove the pipe item
|
||||
|
||||
return
|
||||
|
||||
/obj/item/pipe_meter
|
||||
name = "meter"
|
||||
desc = "A meter that can be laid on pipes"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
M.set_multitool_buffer(user, src)
|
||||
else
|
||||
linked_pad = M.buffer
|
||||
to_chat(user, "<span class='notice'>You link the [src] to the one in the [I.name]'s buffer.</span>")
|
||||
to_chat(user, "<span class='notice'>You link [src] to the one in [I]'s buffer.</span>")
|
||||
|
||||
/obj/machinery/quantumpad/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
|
||||
@@ -7,11 +7,18 @@
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 1000
|
||||
/// A reference to the occupant currently sitting inside the recharger.
|
||||
var/mob/occupant = null
|
||||
/// What type of circuit board is required to build this machine.
|
||||
var/circuitboard = /obj/item/circuitboard/cyborgrecharger
|
||||
/// How fast the recharger can give charge to the occupants energy cell. Based on capacitors and the cell the recharger has.
|
||||
var/recharge_speed
|
||||
/// How much nutrition is given to the occupant. Based on capacitors and the cell the recharger has. Only relevent for IPCs.
|
||||
var/recharge_speed_nutrition
|
||||
/// How much the occupant is repaired every cycle. Based on what manipulator the recharger has.
|
||||
var/repairs
|
||||
/// How efficiently the recharger is able to recharge consumable items such as metal, glass, chemicals in sprays, welding tool fuel, etc.
|
||||
var/consumable_recharge_coeff
|
||||
|
||||
/obj/machinery/recharge_station/Destroy()
|
||||
go_out()
|
||||
@@ -42,6 +49,7 @@
|
||||
recharge_speed = 0
|
||||
recharge_speed_nutrition = 0
|
||||
repairs = 0
|
||||
// The recharge_speed can be anywhere from 200 to 3200, depending on the capacitors and the cell.
|
||||
for(var/obj/item/stock_parts/capacitor/C in component_parts)
|
||||
recharge_speed += C.rating * 100
|
||||
recharge_speed_nutrition += C.rating * 10
|
||||
@@ -52,11 +60,14 @@
|
||||
recharge_speed *= multiplier
|
||||
recharge_speed_nutrition *= multiplier
|
||||
|
||||
// This coefficient can be anywhere from 1, to 16.
|
||||
consumable_recharge_coeff = max(1, recharge_speed / 200)
|
||||
|
||||
/obj/machinery/recharge_station/process()
|
||||
if(!(NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
if(src.occupant)
|
||||
if(occupant)
|
||||
process_occupant()
|
||||
|
||||
for(var/mob/M as mob in src) // makes sure that simple mobs don't get stuck inside a sleeper when they resist out of occupant's grasp
|
||||
@@ -133,20 +144,20 @@
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/recharge_station/proc/process_occupant()
|
||||
if(src.occupant)
|
||||
if(istype(occupant, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = occupant
|
||||
restock_modules()
|
||||
if(repairs)
|
||||
R.heal_overall_damage(repairs, repairs)
|
||||
if(R.cell)
|
||||
R.cell.charge = min(R.cell.charge + recharge_speed, R.cell.maxcharge)
|
||||
else if(istype(occupant, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
if(H.get_int_organ(/obj/item/organ/internal/cell) && H.nutrition < 450)
|
||||
H.set_nutrition(min(H.nutrition + recharge_speed_nutrition, 450))
|
||||
if(repairs)
|
||||
H.heal_overall_damage(repairs, repairs, TRUE, 0, 1)
|
||||
if(isrobot(occupant))
|
||||
var/mob/living/silicon/robot/R = occupant
|
||||
if(R.module)
|
||||
R.module.recharge_consumables(R, consumable_recharge_coeff) // This will handle all of a cyborg's items.
|
||||
if(repairs)
|
||||
R.heal_overall_damage(repairs, repairs)
|
||||
if(R.cell)
|
||||
R.cell.charge = min(R.cell.charge + recharge_speed, R.cell.maxcharge)
|
||||
else if(ishuman(occupant))
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
if(H.get_int_organ(/obj/item/organ/internal/cell) && H.nutrition < 450)
|
||||
H.set_nutrition(min(H.nutrition + recharge_speed_nutrition, 450))
|
||||
if(repairs)
|
||||
H.heal_overall_damage(repairs, repairs, TRUE, 0, 1)
|
||||
|
||||
/obj/machinery/recharge_station/proc/go_out()
|
||||
if(!occupant)
|
||||
@@ -157,74 +168,6 @@
|
||||
use_power = IDLE_POWER_USE
|
||||
return
|
||||
|
||||
/obj/machinery/recharge_station/proc/restock_modules()
|
||||
if(src.occupant)
|
||||
if(istype(occupant, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = occupant
|
||||
var/coeff = recharge_speed / 200
|
||||
if(R.module && R.module.modules)
|
||||
var/list/um = R.contents|R.module.modules
|
||||
// ^ makes sinle list of active (R.contents) and inactive modules (R.module.modules)
|
||||
for(var/obj/O in um)
|
||||
// Engineering
|
||||
if(istype(O,/obj/item/stack/sheet))
|
||||
var/obj/item/stack/sheet/S = O
|
||||
if(S.amount < S.max_amount)
|
||||
S.amount += round(min(1 * coeff, S.max_amount - S.amount))
|
||||
// Security
|
||||
if(istype(O,/obj/item/flash))
|
||||
var/obj/item/flash/F = O
|
||||
if(F.broken)
|
||||
F.broken = 0
|
||||
F.times_used = 0
|
||||
F.icon_state = "flash"
|
||||
if(istype(O,/obj/item/gun/energy))
|
||||
var/obj/item/gun/energy/D = O
|
||||
if(D.cell.charge < D.cell.maxcharge)
|
||||
var/obj/item/ammo_casing/energy/E = D.ammo_type[D.select]
|
||||
D.cell.give(E.e_cost)
|
||||
D.on_recharge()
|
||||
D.update_icon()
|
||||
else
|
||||
D.charge_tick = 0
|
||||
if(istype(O,/obj/item/melee/baton))
|
||||
var/obj/item/melee/baton/B = O
|
||||
if(B.cell)
|
||||
B.cell.charge = B.cell.maxcharge
|
||||
//Service
|
||||
if(istype(O,/obj/item/reagent_containers/food/condiment/enzyme))
|
||||
if(O.reagents.get_reagent_amount("enzyme") < 50)
|
||||
O.reagents.add_reagent("enzyme", 2 * coeff)
|
||||
//Janitor
|
||||
if(istype(O, /obj/item/lightreplacer))
|
||||
var/obj/item/lightreplacer/LR = O
|
||||
var/i = 1
|
||||
for(1, i <= coeff, i++)
|
||||
LR.Charge(occupant)
|
||||
//Fire extinguisher
|
||||
if(istype(O, /obj/item/extinguisher))
|
||||
var/obj/item/extinguisher/ext = O
|
||||
ext.reagents.check_and_add("water", ext.max_water, 5 * coeff)
|
||||
//Welding tools
|
||||
if(istype(O, /obj/item/weldingtool))
|
||||
var/obj/item/weldingtool/weld = O
|
||||
weld.reagents.check_and_add("fuel", weld.maximum_fuel, 2 * coeff)
|
||||
if(R)
|
||||
if(R.module)
|
||||
R.module.respawn_consumable(R)
|
||||
|
||||
//Emagged items for janitor and medical borg
|
||||
if(R.module.emag)
|
||||
if(istype(R.module.emag, /obj/item/reagent_containers/spray))
|
||||
var/obj/item/reagent_containers/spray/S = R.module.emag
|
||||
if(S.name == "polyacid spray")
|
||||
S.reagents.add_reagent("facid", 2 * coeff)
|
||||
if(S.name == "lube spray")
|
||||
S.reagents.add_reagent("lube", 2 * coeff)
|
||||
else if(S.name == "acid synthesizer")
|
||||
S.reagents.add_reagent("facid", 2 * coeff)
|
||||
S.reagents.add_reagent("sacid", 2 * coeff)
|
||||
|
||||
/obj/machinery/recharge_station/verb/move_eject()
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
emergency_mode = FALSE
|
||||
update_icon()
|
||||
playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
to_chat(user, "<span class='notice'>You use the cryptographic sequencer on the [name].</span>")
|
||||
to_chat(user, "<span class='notice'>You use the cryptographic sequencer on [src].</span>")
|
||||
|
||||
/obj/machinery/recycler/update_icon()
|
||||
..()
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
return visible
|
||||
|
||||
/obj/machinery/shieldgen
|
||||
name = "Emergency shield projector"
|
||||
name = "emergency shield projector"
|
||||
desc = "Used to seal minor hull breaches."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "shieldoff"
|
||||
@@ -160,7 +160,12 @@
|
||||
for(var/turf/target_tile in range(2, src))
|
||||
if(istype(target_tile,/turf/space) && !(locate(/obj/machinery/shield) in target_tile))
|
||||
if(malfunction && prob(33) || !malfunction)
|
||||
deployed_shields += new /obj/machinery/shield(target_tile)
|
||||
var/obj/machinery/shield/new_shield = new(target_tile)
|
||||
RegisterSignal(new_shield, COMSIG_PARENT_QDELETING, .proc/remove_shield) // Ensures they properly GC
|
||||
deployed_shields += new_shield
|
||||
|
||||
/obj/machinery/shieldgen/proc/remove_shield(obj/machinery/shield/S)
|
||||
deployed_shields -= S
|
||||
|
||||
/obj/machinery/shieldgen/proc/shields_down()
|
||||
if(!active)
|
||||
@@ -169,15 +174,12 @@
|
||||
active = 0
|
||||
update_icon()
|
||||
|
||||
for(var/obj/machinery/shield/shield_tile in deployed_shields)
|
||||
qdel(shield_tile)
|
||||
QDEL_LIST(deployed_shields)
|
||||
|
||||
/obj/machinery/shieldgen/process()
|
||||
if(malfunction && active)
|
||||
if(deployed_shields.len && prob(5))
|
||||
qdel(pick(deployed_shields))
|
||||
|
||||
return
|
||||
if(length(deployed_shields) && prob(5))
|
||||
qdel(pick_n_take(deployed_shields))
|
||||
|
||||
/obj/machinery/shieldgen/proc/checkhp()
|
||||
if(health <= 30)
|
||||
@@ -251,7 +253,7 @@
|
||||
health = max_health
|
||||
malfunction = TRUE
|
||||
playsound(loc, coil.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You repair the [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You repair [src]!</span>")
|
||||
update_icon()
|
||||
|
||||
else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
|
||||
@@ -407,7 +409,7 @@
|
||||
active = 2
|
||||
if(active >= 1)
|
||||
if(power == 0)
|
||||
visible_message("<span class='warning'>The [name] shuts down due to lack of power!</span>", \
|
||||
visible_message("<span class='warning'>[name] shuts down due to lack of power!</span>", \
|
||||
"You hear heavy droning fade out")
|
||||
icon_state = "Shield_Gen"
|
||||
active = 0
|
||||
|
||||
@@ -315,7 +315,7 @@
|
||||
if(store_item(I, user))
|
||||
update_icon()
|
||||
SStgui.update_uis(src)
|
||||
to_chat(user, "<span class='notice'>You load the [I] into the storage compartment.</span>")
|
||||
to_chat(user, "<span class='notice'>You load [I] into the storage compartment.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't fit [I] into [src]!</span>")
|
||||
return
|
||||
@@ -382,10 +382,10 @@
|
||||
return
|
||||
var/mob/living/target = A
|
||||
if(!state_open)
|
||||
to_chat(user, "<span class='warning'>The [src]'s doors are shut!</span>")
|
||||
to_chat(user, "<span class='warning'>[src]'s doors are shut!</span>")
|
||||
return
|
||||
if(!is_operational())
|
||||
to_chat(user, "<span class='warning'>The [src] is not operational!</span>")
|
||||
to_chat(user, "<span class='warning'>[src] is not operational!</span>")
|
||||
return
|
||||
if(occupant || helmet || suit || storage)
|
||||
to_chat(user, "<span class='warning'>It's too cluttered inside to fit in!</span>")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user