mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 11:05:03 +01:00
Merge remote-tracking branch 'upstream/master' into departmental-clothing-vendors
This commit is contained in:
@@ -0,0 +1 @@
|
||||
patreon: ParadiseStation
|
||||
@@ -1,9 +1,9 @@
|
||||
# This file has all the information on what versions of libraries are thrown into the code
|
||||
# For dreamchecker
|
||||
export SPACEMANDMM_TAG=suite-1.6
|
||||
export SPACEMANDMM_TAG=suite-1.7
|
||||
# For TGUI
|
||||
export NODE_VERSION=12
|
||||
# Byond Major
|
||||
export BYOND_MAJOR=513
|
||||
export BYOND_MAJOR=514
|
||||
# Byond Minor
|
||||
export BYOND_MINOR=1528
|
||||
export BYOND_MINOR=1566
|
||||
|
||||
@@ -10168,10 +10168,6 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 1;
|
||||
icon_state = "pipe-c"
|
||||
},
|
||||
/obj/structure/disposalpipe/sortjunction{
|
||||
dir = 4;
|
||||
icon_state = "pipe-j2s";
|
||||
@@ -24092,7 +24088,7 @@
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/door/airlock/engineering/glass{
|
||||
name = "Engineering";
|
||||
req_access_txt = "32"
|
||||
req_one_access_txt = "32;70"
|
||||
},
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 4;
|
||||
@@ -27172,13 +27168,14 @@
|
||||
},
|
||||
/area/storage/tech)
|
||||
"bhK" = (
|
||||
/obj/structure/reagent_dispensers/spacecleanertank{
|
||||
pixel_y = 30
|
||||
},
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 2;
|
||||
icon_state = "pipe-c"
|
||||
},
|
||||
/obj/structure/closet/jcloset,
|
||||
/obj/machinery/light_switch{
|
||||
pixel_x = 23
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/janitor)
|
||||
"bhL" = (
|
||||
@@ -27726,8 +27723,7 @@
|
||||
/area/hallway/primary/central)
|
||||
"biY" = (
|
||||
/obj/structure/reagent_dispensers/watertank,
|
||||
/obj/machinery/light_switch{
|
||||
pixel_x = 8;
|
||||
/obj/structure/reagent_dispensers/spacecleanertank{
|
||||
pixel_y = 30
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
@@ -28629,7 +28625,7 @@
|
||||
"bkL" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 9
|
||||
dir = 5
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/janitor)
|
||||
@@ -28639,6 +28635,9 @@
|
||||
d2 = 4;
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "floorgrime"
|
||||
},
|
||||
@@ -29570,13 +29569,13 @@
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 5
|
||||
},
|
||||
/mob/living/simple_animal/lizard{
|
||||
name = "Wags-His-Tail";
|
||||
real_name = "Wags-His-Tail"
|
||||
},
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "floorgrime"
|
||||
},
|
||||
@@ -29590,9 +29589,6 @@
|
||||
/obj/effect/landmark/start{
|
||||
name = "Janitor"
|
||||
},
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "floorgrime"
|
||||
},
|
||||
@@ -29743,14 +29739,12 @@
|
||||
pixel_x = -24
|
||||
},
|
||||
/obj/structure/table,
|
||||
/obj/item/clothing/gloves/color/orange,
|
||||
/obj/item/storage/box/mousetraps,
|
||||
/obj/item/storage/box/mousetraps,
|
||||
/obj/structure/cable/yellow{
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/obj/item/key/janitor,
|
||||
/obj/item/reagent_containers/spray/cleaner,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "floorgrime"
|
||||
},
|
||||
@@ -30503,6 +30497,8 @@
|
||||
/obj/item/grenade/chem_grenade/cleaner,
|
||||
/obj/item/grenade/chem_grenade/cleaner,
|
||||
/obj/item/grenade/chem_grenade/cleaner,
|
||||
/obj/item/storage/box/mousetraps,
|
||||
/obj/item/storage/box/mousetraps,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "floorgrime"
|
||||
},
|
||||
@@ -30670,13 +30666,11 @@
|
||||
"boN" = (
|
||||
/obj/item/restraints/legcuffs/beartrap,
|
||||
/obj/item/restraints/legcuffs/beartrap,
|
||||
/obj/structure/table,
|
||||
/obj/machinery/requests_console{
|
||||
department = "Janitorial";
|
||||
departmentType = 1;
|
||||
pixel_x = -29
|
||||
},
|
||||
/obj/item/reagent_containers/spray/cleaner,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Custodial Closet";
|
||||
dir = 4
|
||||
@@ -30684,9 +30678,12 @@
|
||||
/obj/machinery/light/small{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on{
|
||||
dir = 4
|
||||
/obj/item/mop,
|
||||
/obj/item/reagent_containers/glass/bucket,
|
||||
/obj/structure/rack{
|
||||
dir = 1
|
||||
},
|
||||
/obj/item/clothing/gloves/color/orange,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "floorgrime"
|
||||
},
|
||||
@@ -31247,8 +31244,6 @@
|
||||
dir = 4;
|
||||
pixel_x = 11
|
||||
},
|
||||
/obj/item/reagent_containers/glass/bucket,
|
||||
/obj/item/mop,
|
||||
/obj/machinery/firealarm{
|
||||
dir = 4;
|
||||
pixel_x = 24
|
||||
@@ -35714,7 +35709,6 @@
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/structure/disposalpipe/sortjunction{
|
||||
dir = 1;
|
||||
name = "Custodial Junction";
|
||||
@@ -36158,7 +36152,7 @@
|
||||
"byV" = (
|
||||
/obj/machinery/door/airlock/maintenance{
|
||||
name = "Engineering Foyer Maintenance";
|
||||
req_one_access_txt = "32;19"
|
||||
req_one_access_txt = "32;19;70"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/engine/break_room)
|
||||
@@ -49728,7 +49722,6 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 5
|
||||
},
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/structure/disposalpipe/sortjunction{
|
||||
dir = 1;
|
||||
icon_state = "pipe-j2s";
|
||||
@@ -82360,14 +82353,6 @@
|
||||
icon_state = "redfull"
|
||||
},
|
||||
/area/security/main)
|
||||
"vgQ" = (
|
||||
/obj/docking_port/stationary/whiteship{
|
||||
dir = 8;
|
||||
id = "whiteship_cyberiad";
|
||||
name = "North of Cerebron"
|
||||
},
|
||||
/turf/space,
|
||||
/area/space)
|
||||
"vjp" = (
|
||||
/obj/effect/decal/warning_stripes/west,
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on{
|
||||
@@ -136762,7 +136747,7 @@ aaa
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
vgQ
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
|
||||
@@ -6,6 +6,19 @@
|
||||
/obj/structure/lattice,
|
||||
/turf/space,
|
||||
/area/space/nearstation)
|
||||
"aac" = (
|
||||
/obj/machinery/alarm{
|
||||
pixel_y = 22
|
||||
},
|
||||
/obj/structure/table,
|
||||
/obj/item/radio/electropack,
|
||||
/obj/item/assembly/signaler,
|
||||
/obj/item/healthanalyzer,
|
||||
/obj/item/hand_labeler,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "white"
|
||||
},
|
||||
/area/toxins/misc_lab)
|
||||
"aaQ" = (
|
||||
/obj/docking_port/stationary/whiteship{
|
||||
dir = 8;
|
||||
@@ -64134,18 +64147,6 @@
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/engine/controlroom)
|
||||
"cBZ" = (
|
||||
/obj/machinery/alarm{
|
||||
pixel_y = 22
|
||||
},
|
||||
/obj/structure/table,
|
||||
/obj/item/radio/electropack,
|
||||
/obj/item/assembly/signaler,
|
||||
/obj/item/healthanalyzer,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "white"
|
||||
},
|
||||
/area/toxins/misc_lab)
|
||||
"cCa" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
@@ -133899,7 +133900,7 @@ cuQ
|
||||
bGG
|
||||
cyR
|
||||
cAP
|
||||
cBZ
|
||||
aac
|
||||
cDw
|
||||
cDb
|
||||
cEt
|
||||
|
||||
@@ -114,3 +114,12 @@
|
||||
#define PIPE_COLOR_GREEN "#00ff00"
|
||||
#define PIPE_COLOR_YELLOW "#ffcc00"
|
||||
#define PIPE_COLOR_PURPLE "#5c1ec0"
|
||||
|
||||
///Main colors for UI themes
|
||||
#define COLOR_THEME_MIDNIGHT "#6086A0"
|
||||
#define COLOR_THEME_PLASMAFIRE "#FFB200"
|
||||
#define COLOR_THEME_RETRO "#24CA00"
|
||||
#define COLOR_THEME_SLIMECORE "#4FB259"
|
||||
#define COLOR_THEME_OPERATIVE "#B8221F"
|
||||
#define COLOR_THEME_GLASS "#75A4C4"
|
||||
#define COLOR_THEME_CLOCKWORK "#CFBA47"
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
#define PASSBLOB 8
|
||||
#define PASSMOB 16
|
||||
#define LETPASSTHROW 32
|
||||
#define PASSFENCE 64
|
||||
|
||||
//turf-only flags
|
||||
#define NOJAUNT 1
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
#define FOOTSTEP_WATER "water"
|
||||
#define FOOTSTEP_LAVA "lava"
|
||||
#define FOOTSTEP_MEAT "meat"
|
||||
#define FOOTSTEP_GLASS "glass"
|
||||
//barefoot sounds
|
||||
#define FOOTSTEP_WOOD_BAREFOOT "woodbarefoot"
|
||||
#define FOOTSTEP_WOOD_CLAW "woodclaw"
|
||||
#define FOOTSTEP_HARD_BAREFOOT "hardbarefoot"
|
||||
#define FOOTSTEP_HARD_CLAW "hardclaw"
|
||||
#define FOOTSTEP_CARPET_BAREFOOT "carpetbarefoot"
|
||||
#define FOOTSTEP_GLASS_BAREFOOT "glassbarefoot"
|
||||
//misc footstep sounds
|
||||
#define FOOTSTEP_GENERIC_HEAVY "heavy"
|
||||
|
||||
@@ -83,7 +85,11 @@ GLOBAL_LIST_INIT(footstep, list(
|
||||
'sound/effects/footstep/lava2.ogg',
|
||||
'sound/effects/footstep/lava3.ogg'), 100, 0),
|
||||
FOOTSTEP_MEAT = list(list(
|
||||
'sound/effects/meatslap.ogg'), 100, 0)
|
||||
'sound/effects/meatslap.ogg'), 100, 0),
|
||||
FOOTSTEP_GLASS = list(list(
|
||||
'sound/effects/footstep/glass1.ogg',
|
||||
'sound/effects/footstep/glass2.ogg',
|
||||
'sound/effects/footstep/glass3.ogg'), 100, 1),
|
||||
))
|
||||
//bare footsteps lists
|
||||
GLOBAL_LIST_INIT(barefootstep, list(
|
||||
@@ -127,6 +133,10 @@ GLOBAL_LIST_INIT(barefootstep, list(
|
||||
'sound/effects/footstep/lava3.ogg'), 100, 0),
|
||||
FOOTSTEP_MEAT = list(list(
|
||||
'sound/effects/meatslap.ogg'), 100, 0),
|
||||
FOOTSTEP_GLASS_BAREFOOT = list(list(
|
||||
'sound/effects/footstep/glassbarefoot1.ogg',
|
||||
'sound/effects/footstep/glassbarefoot2.ogg',
|
||||
'sound/effects/footstep/glassbarefoot3.ogg'), 100, 1),
|
||||
))
|
||||
|
||||
//claw footsteps lists
|
||||
@@ -171,6 +181,10 @@ GLOBAL_LIST_INIT(clawfootstep, list(
|
||||
'sound/effects/footstep/lava3.ogg'), 100, 0),
|
||||
FOOTSTEP_MEAT = list(list(
|
||||
'sound/effects/meatslap.ogg'), 100, 0),
|
||||
FOOTSTEP_GLASS = list(list(
|
||||
'sound/effects/footstep/glassbarefoot1.ogg',
|
||||
'sound/effects/footstep/glassbarefoot2.ogg',
|
||||
'sound/effects/footstep/glassbarefoot3.ogg'), 100, 1),
|
||||
))
|
||||
|
||||
//heavy footsteps list
|
||||
|
||||
@@ -74,7 +74,6 @@
|
||||
|
||||
//Species traits.
|
||||
#define NO_BLOOD "no_blood"
|
||||
#define NOTRANSSTING "no_trans_sting"
|
||||
#define IS_WHITELISTED "whitelisted"
|
||||
#define LIPS "lips"
|
||||
#define EXOTIC_COLOR "exotic_blood_color"
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
#define DISPOSAL_PIPE_LAYER 2.3
|
||||
#define GAS_PIPE_HIDDEN_LAYER 2.35
|
||||
#define WIRE_LAYER 2.4
|
||||
#define TRANSPARENT_TURF_LAYER 2.41
|
||||
#define WIRE_TERMINAL_LAYER 2.45
|
||||
#define GAS_SCRUBBER_LAYER 2.46
|
||||
#define GAS_PIPE_VISIBLE_LAYER 2.47
|
||||
#define GAS_FILTER_LAYER 2.48
|
||||
#define GAS_PUMP_LAYER 2.49
|
||||
#define HOLOPAD_LAYER 2.491
|
||||
#define CONVEYOR_LAYER 2.495
|
||||
#define LOW_OBJ_LAYER 2.5
|
||||
#define LOW_SIGIL_LAYER 2.52
|
||||
|
||||
@@ -56,10 +56,11 @@
|
||||
#define PREFTOGGLE_2_REVERB_DISABLE 512
|
||||
#define PREFTOGGLE_2_FORCE_WHITE_RUNECHAT 1024
|
||||
#define PREFTOGGLE_2_SIMPLE_STAT_PANEL 2048
|
||||
#define PREFTOGGLE_2_SEE_ITEM_OUTLINES 4096
|
||||
|
||||
#define TOGGLES_2_TOTAL 4095 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
#define TOGGLES_2_TOTAL 8191 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined.
|
||||
|
||||
#define TOGGLES_2_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE)
|
||||
#define TOGGLES_2_DEFAULT (PREFTOGGLE_2_FANCYUI|PREFTOGGLE_2_ITEMATTACK|PREFTOGGLE_2_WINDOWFLASHING|PREFTOGGLE_2_RUNECHAT|PREFTOGGLE_2_DEATHMESSAGE|PREFTOGGLE_2_EMOTE_BUBBLE|PREFTOGGLE_2_SEE_ITEM_OUTLINES)
|
||||
|
||||
// Sanity checks
|
||||
#if TOGGLES_TOTAL > 16777215
|
||||
|
||||
+14
-10
@@ -272,15 +272,19 @@
|
||||
update_all_mob_security_hud()
|
||||
return 1
|
||||
|
||||
/*
|
||||
Proc for attack log creation, because really why not
|
||||
1 argument is the actor
|
||||
2 argument is the target of action
|
||||
3 is the full description of the action
|
||||
4 is whether or not to message admins
|
||||
This is always put in the attack log.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates attack (old and new) logs for the user and defense logs for the target.
|
||||
* Will message admins depending on the custom_level, user and target.
|
||||
*
|
||||
* custom_level will determine the log level set. Unless the target is SSD and there is a user doing it
|
||||
* If custom_level is not set then the log level will be determined using the user and the target.
|
||||
*
|
||||
* * Arguments:
|
||||
* * user - The thing doing it. Can be null
|
||||
* * target - The target of the attack
|
||||
* * what_done - What has happened
|
||||
* * custom_level - The log level override
|
||||
*/
|
||||
/proc/add_attack_logs(atom/user, target, what_done, custom_level)
|
||||
if(islist(target)) // Multi-victim adding
|
||||
var/list/targets = target
|
||||
@@ -323,7 +327,7 @@ This is always put in the attack log.
|
||||
loglevel = ATKLOG_ALMOSTALL
|
||||
else
|
||||
loglevel = ATKLOG_ALL // Hitting an object. Not a mob
|
||||
if(isLivingSSD(target)) // Attacks on SSDs are shown to admins with any log level except ATKLOG_NONE. Overrides custom level
|
||||
if(user && isLivingSSD(target)) // Attacks on SSDs are shown to admins with any log level except ATKLOG_NONE. Overrides custom level
|
||||
loglevel = ATKLOG_FEW
|
||||
|
||||
|
||||
|
||||
@@ -164,6 +164,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_BLOODCRAWL_EAT "bloodcrawl_eat"
|
||||
#define TRAIT_DWARF "dwarf"
|
||||
#define TRAIT_SILENT_FOOTSTEPS "silent_footsteps" //makes your footsteps completely silent
|
||||
#define TRAIT_MESON_VISION "meson_vision"
|
||||
#define TRAIT_FLASH_PROTECTION "flash_protection"
|
||||
#define TRAIT_NIGHT_VISION "night_vision"
|
||||
|
||||
#define TRAIT_COMIC_SANS "comic_sans"
|
||||
#define TRAIT_NOFINGERPRINTS "no_fingerprints"
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
#define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE))))
|
||||
|
||||
//Update this whenever you need to take advantage of more recent byond features
|
||||
#define MIN_COMPILER_VERSION 513
|
||||
#define MIN_COMPILER_BUILD 1514
|
||||
#define MIN_COMPILER_VERSION 514
|
||||
#define MIN_COMPILER_BUILD 1554
|
||||
#if DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD
|
||||
//Don't forget to update this part
|
||||
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
|
||||
#error You need version 513.1514 or higher
|
||||
#error You need version 514.1554 or higher
|
||||
#endif
|
||||
|
||||
// Macros that must exist before world.dm
|
||||
|
||||
@@ -5,7 +5,6 @@ GLOBAL_VAR_INIT(deafblock, 0)
|
||||
GLOBAL_VAR_INIT(hulkblock, 0)
|
||||
GLOBAL_VAR_INIT(teleblock, 0)
|
||||
GLOBAL_VAR_INIT(fireblock, 0)
|
||||
GLOBAL_VAR_INIT(xrayblock, 0)
|
||||
GLOBAL_VAR_INIT(clumsyblock, 0)
|
||||
GLOBAL_VAR_INIT(fakeblock, 0)
|
||||
GLOBAL_VAR_INIT(coughblock, 0)
|
||||
@@ -30,6 +29,9 @@ GLOBAL_VAR_INIT(hallucinationblock, 0)
|
||||
GLOBAL_VAR_INIT(noprintsblock, 0)
|
||||
GLOBAL_VAR_INIT(shockimmunityblock, 0)
|
||||
GLOBAL_VAR_INIT(smallsizeblock, 0)
|
||||
GLOBAL_VAR_INIT(mesonblock, 0)
|
||||
GLOBAL_VAR_INIT(noflashblock, 0)
|
||||
GLOBAL_VAR_INIT(nightvisionblock, 0)
|
||||
|
||||
///////////////////////////////
|
||||
// Goon Stuff
|
||||
|
||||
@@ -46,6 +46,9 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_DWARF" = TRAIT_DWARF,
|
||||
"TRAIT_SILENT_FOOTSTEPS" = TRAIT_SILENT_FOOTSTEPS,
|
||||
"TRAIT_ALCOHOL_TOLERANCE" = TRAIT_ALCOHOL_TOLERANCE,
|
||||
"TRAIT_MESON_VISION" = TRAIT_MESON_VISION,
|
||||
"TRAIT_FLASH_PROTECTION" = TRAIT_FLASH_PROTECTION,
|
||||
"TRAIT_NIGHT_VISION" = TRAIT_NIGHT_VISION,
|
||||
|
||||
"TRAIT_COMIC_SANS" = TRAIT_COMIC_SANS,
|
||||
"TRAIT_NOFINGERPRINTS" = TRAIT_NOFINGERPRINTS,
|
||||
|
||||
@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(metrics)
|
||||
var/list/out = list()
|
||||
out["@timestamp"] = time_stamp() // This is required by ElasticSearch, complete with this name. DO NOT REMOVE THIS.
|
||||
out["cpu"] = world.cpu
|
||||
// out["maptick"] = world.map_cpu // TODO: 514
|
||||
out["maptick"] = world.map_cpu
|
||||
out["elapsed_processed"] = world.time
|
||||
out["elapsed_real"] = (REALTIMEOFDAY - world_init_time)
|
||||
out["client_count"] = length(GLOB.clients)
|
||||
|
||||
@@ -287,7 +287,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
else
|
||||
log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - keeping standard job config")
|
||||
|
||||
SSnightshift.check_nightshift()
|
||||
SSnightshift.check_nightshift(TRUE)
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
RunUnitTests()
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
var/mat_path = possible_mats[id]
|
||||
materials[id] = new mat_path()
|
||||
|
||||
/datum/component/material_container/Destroy(force, silent)
|
||||
QDEL_LIST_ASSOC_VAL(materials)
|
||||
return ..()
|
||||
|
||||
/datum/component/material_container/proc/OnExamine(datum/source, mob/user, list/examine_list)
|
||||
if(show_on_examine)
|
||||
for(var/I in materials)
|
||||
|
||||
@@ -44,12 +44,13 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event
|
||||
title = "Security Announcement"
|
||||
announcement_type = "Security Announcement"
|
||||
|
||||
/datum/announcement/proc/Announce(message as text, new_title = "", new_sound = null, do_newscast = newscast, msg_sanitized = 0, from, msg_language)
|
||||
/datum/announcement/proc/Announce(message as text, new_title = "", new_sound = null, do_newscast = newscast, msg_sanitized = 0, from, msg_language, new_sound2 = null)
|
||||
if(!message)
|
||||
return
|
||||
|
||||
var/message_title = new_title ? new_title : title
|
||||
var/message_sound = new_sound ? sound(new_sound) : sound
|
||||
var/message_sound2 = new_sound2 ? sound(new_sound2) : sound
|
||||
|
||||
if(!msg_sanitized)
|
||||
message = trim_strip_html_properly(message, allow_lines = 1)
|
||||
@@ -74,6 +75,7 @@ GLOBAL_DATUM_INIT(event_announcement, /datum/announcement/priority/command/event
|
||||
NewsCast(message, message_title)
|
||||
|
||||
Sound(message_sound, combined_receivers[1] + combined_receivers[2])
|
||||
Sound(message_sound2, combined_receivers[1] + combined_receivers[2])
|
||||
Log(message, message_title)
|
||||
|
||||
/datum/announcement/proc/Get_Receivers(datum/language/message_language)
|
||||
|
||||
@@ -1153,3 +1153,15 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
if(degrees)
|
||||
appearance_flags |= PIXEL_SCALE
|
||||
transform = M
|
||||
|
||||
/*
|
||||
Setter for the `density` variable.
|
||||
Arguments:
|
||||
* new_value - the new density you would want it to set.
|
||||
Returns: Either null if identical to existing density, or the new density if different.
|
||||
*/
|
||||
/atom/proc/set_density(new_value)
|
||||
if(density == new_value)
|
||||
return
|
||||
. = density
|
||||
density = new_value
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
to_chat(usr, "<span class='boldnotice'>[src] is already occupied!</span>")
|
||||
return
|
||||
if(usr.abiotic())
|
||||
to_chat(usr, "<span class='boldnotice'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(usr, "<span class='boldnotice'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(usr.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(usr, "<span class='warning'>[usr] will not fit into [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head.</span>")
|
||||
@@ -194,7 +194,7 @@
|
||||
if(!istype(L) || L.buckled)
|
||||
return
|
||||
if(L.abiotic())
|
||||
to_chat(user, "<span class='danger'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='danger'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(L.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.</span>")
|
||||
@@ -232,7 +232,7 @@
|
||||
to_chat(user, "<span class='boldnotice'>The scanner is already occupied!</span>")
|
||||
return
|
||||
if(G.affecting.abiotic())
|
||||
to_chat(user, "<span class='boldnotice'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='boldnotice'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(G.affecting.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[G] will not fit into [src] because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.</span>")
|
||||
|
||||
@@ -140,12 +140,16 @@
|
||||
/datum/mutation/disability/colourblindness/activate(mob/M)
|
||||
..()
|
||||
M.update_client_colour() //Handle the activation of the colourblindness on the mob.
|
||||
M.update_icons() //Apply eyeshine as needed.
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_misc_effects()
|
||||
|
||||
/datum/mutation/disability/colourblindness/deactivate(mob/M)
|
||||
..()
|
||||
M.update_client_colour() //Handle the deactivation of the colourblindness on the mob.
|
||||
M.update_icons() //Remove eyeshine as needed.
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_misc_effects()
|
||||
|
||||
/datum/mutation/disability/deaf
|
||||
name = "Deafness"
|
||||
|
||||
@@ -158,28 +158,6 @@
|
||||
M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH //temporary fix until the problem can be solved.
|
||||
to_chat(M, "<span class='danger'>You suddenly feel very weak.</span>")
|
||||
|
||||
/datum/mutation/xray
|
||||
name = "X-Ray Vision"
|
||||
activation_messages = list("The walls suddenly disappear.")
|
||||
deactivation_messages = list("The walls around you re-appear.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
traits_to_add = list(TRAIT_XRAY_VISION)
|
||||
activation_prob = 15
|
||||
|
||||
/datum/mutation/xray/New()
|
||||
..()
|
||||
block = GLOB.xrayblock
|
||||
|
||||
/datum/mutation/xray/activate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
M.update_icons() //Apply eyeshine as needed.
|
||||
|
||||
/datum/mutation/xray/deactivate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
M.update_icons() //Remove eyeshine as needed.
|
||||
|
||||
/datum/mutation/tk
|
||||
name = "Telekenesis"
|
||||
activation_messages = list("You feel smarter.")
|
||||
@@ -1181,3 +1159,58 @@
|
||||
else
|
||||
H.remoteview_target = null
|
||||
H.reset_perspective()
|
||||
|
||||
/datum/mutation/meson_vision
|
||||
name = "Meson Vision"
|
||||
activation_messages = list("More information seems to reach your eyes...")
|
||||
deactivation_messages = list("The amount of information reaching your eyes fades...")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
traits_to_add = list(TRAIT_MESON_VISION)
|
||||
|
||||
/datum/mutation/meson_vision/New()
|
||||
..()
|
||||
block = GLOB.mesonblock
|
||||
|
||||
/datum/mutation/meson_vision/activate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
|
||||
/datum/mutation/meson_vision/deactivate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
|
||||
/datum/mutation/night_vision
|
||||
name = "Night Vision"
|
||||
activation_messages = list("Were the lights always that bright?")
|
||||
deactivation_messages = list("The ambient light level returns to normal...")
|
||||
instability = GENE_INSTABILITY_MODERATE
|
||||
traits_to_add = list(TRAIT_NIGHT_VISION)
|
||||
|
||||
/datum/mutation/night_vision/New()
|
||||
..()
|
||||
block = GLOB.nightvisionblock
|
||||
|
||||
/datum/mutation/night_vision/activate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_misc_effects()
|
||||
|
||||
/datum/mutation/night_vision/deactivate(mob/living/M)
|
||||
..()
|
||||
M.update_sight()
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_misc_effects()
|
||||
|
||||
/datum/mutation/flash_protection
|
||||
name = "Flash Protection"
|
||||
activation_messages = list("You stop noticing the glare from lights...")
|
||||
deactivation_messages = list("Lights begin glaring again...")
|
||||
instability = GENE_INSTABILITY_MINOR
|
||||
traits_to_add = list(TRAIT_FLASH_PROTECTION)
|
||||
|
||||
/datum/mutation/flash_protection/New()
|
||||
..()
|
||||
block = GLOB.noflashblock
|
||||
|
||||
@@ -66,10 +66,10 @@
|
||||
return
|
||||
|
||||
if(src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "You cannot send IC messages (muted).")
|
||||
return
|
||||
if(src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
if(src.client.handle_spam_prevention(message, MUTE_IC))
|
||||
return
|
||||
|
||||
if(stat)
|
||||
|
||||
@@ -10,20 +10,19 @@
|
||||
|
||||
//Recover from stuns.
|
||||
/datum/action/changeling/epinephrine/sting_action(mob/living/user)
|
||||
|
||||
if(user.lying)
|
||||
to_chat(user, "<span class='notice'>We arise.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Adrenaline rushes through us.</span>")
|
||||
user.SetSleeping(0)
|
||||
user.stat = 0
|
||||
user.WakeUp()
|
||||
user.SetParalysis(0)
|
||||
user.SetStunned(0)
|
||||
user.SetWeakened(0)
|
||||
user.lying = 0
|
||||
user.lying = FALSE
|
||||
user.update_canmove()
|
||||
user.reagents.add_reagent("synaptizine", 20)
|
||||
user.adjustStaminaLoss(-75)
|
||||
|
||||
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]"))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
@@ -66,60 +66,6 @@
|
||||
add_attack_logs(user, target, "Unsuccessful sting (changeling)")
|
||||
return 1
|
||||
|
||||
/datum/action/changeling/sting/transformation
|
||||
name = "Transformation Sting"
|
||||
desc = "We silently sting a human, injecting a retrovirus that forces them to transform. Costs 50 chemicals."
|
||||
helptext = "The victim will transform much like a changeling would. The effects will be obvious to the victim, and the process will damage our genomes."
|
||||
button_icon_state = "sting_transform"
|
||||
sting_icon = "sting_transform"
|
||||
chemical_cost = 50
|
||||
dna_cost = 3
|
||||
genetic_damage = 100
|
||||
var/datum/dna/selected_dna = null
|
||||
|
||||
/datum/action/changeling/sting/transformation/Trigger()
|
||||
var/mob/user = usr
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
if(changeling.chosen_sting)
|
||||
unset_sting(user)
|
||||
return
|
||||
selected_dna = changeling.select_dna("Select the target DNA: ", "Target DNA")
|
||||
if(!selected_dna)
|
||||
return
|
||||
if((NOTRANSSTING in selected_dna.species.species_traits) || selected_dna.species.is_small)
|
||||
to_chat(user, "<span class='warning'>The selected DNA is incompatible with our sting.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
/datum/action/changeling/sting/transformation/can_sting(mob/user, mob/target)
|
||||
if(!..())
|
||||
return
|
||||
if(HAS_TRAIT(target, TRAIT_HUSK) || !ishuman(target) || (NOTRANSSTING in target.dna.species.species_traits))
|
||||
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
|
||||
return FALSE
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(HAS_TRAIT(H, TRAIT_GENELESS))
|
||||
to_chat(user, "<span class='warning'>This won't work on a creature without DNA.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/changeling/sting/transformation/sting_action(mob/user, mob/target)
|
||||
add_attack_logs(user, target, "Transformation sting (changeling) (new identity is [selected_dna.real_name])")
|
||||
if(issmall(target))
|
||||
to_chat(user, "<span class='notice'>Our genes cry out as we sting [target.name]!</span>")
|
||||
|
||||
if(iscarbon(target) && (target.status_flags & CANWEAKEN))
|
||||
var/mob/living/carbon/C = target
|
||||
C.do_jitter_animation(500)
|
||||
|
||||
target.visible_message("<span class='danger'>[target] begins to violenty convulse!</span>","<span class='userdanger'>You feel a tiny prick and a begin to uncontrollably convulse!</span>")
|
||||
|
||||
spawn(10)
|
||||
transform_dna(target,selected_dna)//target is always human so no problem here
|
||||
SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]"))
|
||||
return TRUE
|
||||
|
||||
/datum/action/changeling/sting/extract_dna
|
||||
name = "Extract DNA Sting"
|
||||
desc = "We stealthily sting a target and extract their DNA. Costs 25 chemicals."
|
||||
|
||||
@@ -73,6 +73,9 @@
|
||||
var/airlock_unruned_icon_file = 'icons/obj/doors/airlocks/cult/unruned/cult.dmi'
|
||||
var/airlock_unruned_overlays_file = 'icons/obj/doors/airlocks/cult/unruned/cult-overlays.dmi'
|
||||
|
||||
/// Are cultist mirror shields active yet?
|
||||
var/mirror_shields_active = FALSE
|
||||
|
||||
|
||||
/datum/cult_info/fire
|
||||
name = "Cult of Kha'Rin"
|
||||
|
||||
@@ -444,6 +444,11 @@
|
||||
* The illusion has a 60% chance to be hostile and attack non-cultists, and a 40% chance to just run away from the user.
|
||||
*/
|
||||
/obj/item/shield/mirror/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
// Incase they get one by some magic
|
||||
if(!SSticker.cultdat.mirror_shields_active)
|
||||
to_chat(owner, "<span class='warning'>This shield is powerless! You must perform the required sacrifice to empower it!</span>")
|
||||
return
|
||||
|
||||
if(iscultist(owner) && !owner.holy_check()) // Cultist holding the shield
|
||||
|
||||
// Hit by a projectile
|
||||
|
||||
@@ -86,8 +86,10 @@
|
||||
to_chat(user, "<span class='cultitalic'>The magic in [src] is weak, it will be ready to use again in [get_ETA()].</span>")
|
||||
return
|
||||
|
||||
var/choice = show_radial_menu(user, src, choosable_items, require_near = TRUE)
|
||||
var/picked_type = choosable_items[choice]
|
||||
|
||||
var/list/pickable_items = get_choosable_items()
|
||||
var/choice = show_radial_menu(user, src, pickable_items, require_near = TRUE)
|
||||
var/picked_type = pickable_items[choice]
|
||||
if(!QDELETED(src) && picked_type && Adjacent(user) && !user.incapacitated() && cooldowntime <= world.time)
|
||||
cooldowntime = world.time + creation_delay
|
||||
var/obj/O = new picked_type
|
||||
@@ -95,6 +97,14 @@
|
||||
O.forceMove(get_turf(src))
|
||||
to_chat(user, replacetext("[creation_message]", "%ITEM%", "[O.name]"))
|
||||
|
||||
/**
|
||||
* Returns the items the cult can craft from this forge.
|
||||
*
|
||||
* Override on children for logic regarding game state.
|
||||
*/
|
||||
/obj/structure/cult/functional/proc/get_choosable_items()
|
||||
return choosable_items.Copy() // Copied incase its modified on children
|
||||
|
||||
/**
|
||||
* Returns the cooldown time in minutes and seconds
|
||||
*/
|
||||
@@ -159,8 +169,15 @@
|
||||
selection_prompt = "You study the schematics etched on the forge..."
|
||||
selection_title = "Forge"
|
||||
creation_message = "<span class='cultitalic'>You work the forge as dark knowledge guides your hands, creating a %ITEM%!</span>"
|
||||
choosable_items = list("Shielded Robe" = /obj/item/clothing/suit/hooded/cultrobes/cult_shield, "Flagellant's Robe" = /obj/item/clothing/suit/hooded/cultrobes/flagellant_robe,
|
||||
"Mirror Shield" = /obj/item/shield/mirror)
|
||||
choosable_items = list("Shielded Robe" = /obj/item/clothing/suit/hooded/cultrobes/cult_shield, "Flagellant's Robe" = /obj/item/clothing/suit/hooded/cultrobes/flagellant_robe)
|
||||
|
||||
/obj/structure/cult/functional/forge/get_choosable_items()
|
||||
. = ..()
|
||||
if(SSticker.cultdat.mirror_shields_active)
|
||||
// Both lines here are needed. If you do it without, youll get issues.
|
||||
. += "Mirror Shield"
|
||||
.["Mirror Shield"] = /obj/item/shield/mirror
|
||||
|
||||
|
||||
/obj/structure/cult/functional/forge/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -384,6 +384,9 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
for(var/M in invokers)
|
||||
if(sacrifice_fulfilled)
|
||||
to_chat(M, "<span class='cultlarge'>\"Yes! This is the one I desire! You have done well.\"</span>")
|
||||
if(!SSticker.cultdat.mirror_shields_active) // Only show once
|
||||
to_chat(M, "<span class='cultitalic'>You are now able to construct mirror shields inside the daemon forge.</span>")
|
||||
SSticker.cultdat.mirror_shields_active = TRUE
|
||||
else
|
||||
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>")
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#define NUKE_INTACT 0
|
||||
#define NUKE_CORE_MISSING 1
|
||||
#define NUKE_MISSING 2
|
||||
/*
|
||||
* GAMEMODES (by Rastaf0)
|
||||
*
|
||||
@@ -434,6 +437,15 @@
|
||||
nukecode = bomb.r_code
|
||||
return nukecode
|
||||
|
||||
/proc/get_nuke_status()
|
||||
var/nuke_status = NUKE_MISSING
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
|
||||
if(is_station_level(bomb.z))
|
||||
nuke_status = NUKE_CORE_MISSING
|
||||
if(bomb.core)
|
||||
nuke_status = NUKE_INTACT
|
||||
return nuke_status
|
||||
|
||||
/datum/game_mode/proc/replace_jobbanned_player(mob/living/M, role_type)
|
||||
var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as a [role_type]?", role_type, FALSE, 10 SECONDS)
|
||||
var/mob/dead/observer/theghost = null
|
||||
@@ -534,3 +546,7 @@
|
||||
var/datum/atom_hud/antag/antaghud = GLOB.huds[ANTAG_HUD_EVENTMISC]
|
||||
antaghud.leave_hud(mob_mind.current)
|
||||
set_antag_hud(mob_mind.current, null)
|
||||
|
||||
#undef NUKE_INTACT
|
||||
#undef NUKE_CORE_MISSING
|
||||
#undef NUKE_MISSING
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
|
||||
/datum/action/innate/ai/nuke_station/proc/set_us_up_the_bomb()
|
||||
to_chat(owner_AI, "<span class='notice'>Nuclear device armed.</span>")
|
||||
GLOB.event_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg')
|
||||
GLOB.event_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg')
|
||||
set_security_level("delta")
|
||||
owner_AI.nuking = TRUE
|
||||
var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(owner_AI)
|
||||
@@ -280,7 +280,7 @@
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
|
||||
SSshuttle.emergency.mode = SHUTTLE_DOCKED
|
||||
SSshuttle.emergency.timer = world.time
|
||||
GLOB.priority_announcement.Announce("Hostile environment resolved. You have 3 minutes to board the Emergency Shuttle.", "Priority Announcement", 'sound/AI/shuttledock.ogg')
|
||||
GLOB.priority_announcement.Announce("Hostile environment resolved. You have 3 minutes to board the Emergency Shuttle.", "Priority Announcement", 'sound/AI/eshuttle_dock.ogg')
|
||||
return ..()
|
||||
|
||||
/obj/machinery/doomsday_device/proc/start()
|
||||
@@ -300,7 +300,7 @@
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
|
||||
SSshuttle.emergency.mode = SHUTTLE_DOCKED
|
||||
SSshuttle.emergency.timer = world.time
|
||||
GLOB.priority_announcement.Announce("Hostile environment resolved. You have 3 minutes to board the Emergency Shuttle.", "Priority Announcement", 'sound/AI/shuttledock.ogg')
|
||||
GLOB.priority_announcement.Announce("Hostile environment resolved. You have 3 minutes to board the Emergency Shuttle.", "Priority Announcement", 'sound/AI/eshuttle_dock.ogg')
|
||||
qdel(src)
|
||||
if(!timing)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
/mob/living/captive_brain/say(message)
|
||||
if(client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='warning'>You cannot speak in IC (muted).</span>")
|
||||
return
|
||||
if(client.handle_spam_prevention(message,MUTE_IC))
|
||||
if(client.handle_spam_prevention(message, MUTE_IC))
|
||||
return
|
||||
|
||||
if(istype(loc,/mob/living/simple_animal/borer))
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
|
||||
SSshuttle.emergency.mode = SHUTTLE_DOCKED
|
||||
SSshuttle.emergency.timer = world.time
|
||||
GLOB.command_announcement.Announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg')
|
||||
GLOB.command_announcement.Announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/eshuttle_dock.ogg')
|
||||
return ..()
|
||||
if(finished != 0)
|
||||
return TRUE
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
GLOB.hulkblock = getAssignedBlock("HULK", numsToAssign, DNA_HARD_BOUNDS, good=1)
|
||||
GLOB.teleblock = getAssignedBlock("TELE", numsToAssign, DNA_HARD_BOUNDS, good=1)
|
||||
GLOB.fireblock = getAssignedBlock("FIRE", numsToAssign, DNA_HARDER_BOUNDS, good=1)
|
||||
GLOB.xrayblock = getAssignedBlock("XRAY", numsToAssign, DNA_HARDER_BOUNDS, good=1)
|
||||
GLOB.clumsyblock = getAssignedBlock("CLUMSY", numsToAssign)
|
||||
GLOB.fakeblock = getAssignedBlock("FAKE", numsToAssign)
|
||||
GLOB.coughblock = getAssignedBlock("COUGH", numsToAssign)
|
||||
@@ -49,6 +48,10 @@
|
||||
GLOB.twitchblock = getAssignedBlock("TWITCH", numsToAssign)
|
||||
GLOB.nervousblock = getAssignedBlock("NERVOUS", numsToAssign)
|
||||
GLOB.wingdingsblock = getAssignedBlock("WINGDINGS", numsToAssign)
|
||||
GLOB.mesonblock = getAssignedBlock("MESONS", numsToAssign, good=1)
|
||||
GLOB.noflashblock = getAssignedBlock("NOFLASH", numsToAssign, DNA_HARDER_BOUNDS, good=1)
|
||||
GLOB.nightvisionblock = getAssignedBlock("NIGHTVISION", numsToAssign, DNA_HARDER_BOUNDS, good=1)
|
||||
|
||||
|
||||
// Bay muts
|
||||
GLOB.breathlessblock = getAssignedBlock("BREATHLESS", numsToAssign, DNA_HARD_BOUNDS, good=1)
|
||||
@@ -62,7 +65,6 @@
|
||||
GLOB.noprintsblock = getAssignedBlock("NOPRINTS", numsToAssign, DNA_HARD_BOUNDS, good=1)
|
||||
GLOB.shockimmunityblock = getAssignedBlock("SHOCKIMMUNITY", numsToAssign, good=1)
|
||||
GLOB.smallsizeblock = getAssignedBlock("SMALLSIZE", numsToAssign, DNA_HARD_BOUNDS, good=1)
|
||||
|
||||
//
|
||||
// Goon muts
|
||||
/////////////////////////////////////////////
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
return 0
|
||||
|
||||
/datum/theft_objective/defib
|
||||
name = "a compact defibrillator"
|
||||
typepath = /obj/item/defibrillator/compact
|
||||
name = "the chief medical officer's advanced compact defibrillator"
|
||||
typepath = /obj/item/defibrillator/compact/advanced
|
||||
protected_jobs = list("Chief Medical Officer", "Paramedic")
|
||||
location_override = "the Chief Medical Officer's Office"
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
name = "Bluespace Gigabeacon"
|
||||
desc = "A device that draws power from bluespace and creates a permanent tracking beacon."
|
||||
level = 1 // underfloor
|
||||
layer = 2.5
|
||||
layer = WIRE_LAYER
|
||||
plane = FLOOR_PLANE
|
||||
anchored = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 0
|
||||
@@ -26,7 +27,8 @@
|
||||
Beacon.syndicate = syndicate
|
||||
Beacon.area_bypass = area_bypass
|
||||
Beacon.cc_beacon = cc_beacon
|
||||
hide(T.intact)
|
||||
if(!T.transparent_floor)
|
||||
hide(T.intact)
|
||||
|
||||
/obj/machinery/bluespace_beacon/proc/destroy_beacon()
|
||||
QDEL_NULL(Beacon)
|
||||
|
||||
@@ -512,7 +512,7 @@
|
||||
if(!istype(L) || L.buckled)
|
||||
return
|
||||
if(L.abiotic())
|
||||
to_chat(user, "<span class='boldnotice'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='boldnotice'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(L.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.</span>")
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
return
|
||||
var/mob/living/carbon/human/M = TYPECAST_YOUR_SHIT.affecting
|
||||
if(M.abiotic())
|
||||
to_chat(user, "<span class='notice'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='notice'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
M.forceMove(src)
|
||||
occupant = M
|
||||
@@ -122,7 +122,7 @@
|
||||
if(H.buckled)
|
||||
return FALSE
|
||||
if(H.abiotic())
|
||||
to_chat(user, "<span class='notice'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='notice'>Subject may not hold anything in their hands.</span>")
|
||||
return FALSE
|
||||
if(H.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[H] will not fit into [src] because [H.p_they()] [H.p_have()] a slime latched onto [H.p_their()] head.</span>")
|
||||
|
||||
@@ -100,6 +100,7 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\
|
||||
/obj/machinery/clonepod/Destroy()
|
||||
if(connected)
|
||||
connected.pods -= src
|
||||
connected = null
|
||||
if(clonemind)
|
||||
UnregisterSignal(clonemind.current, COMSIG_LIVING_REVIVE)
|
||||
UnregisterSignal(clonemind, COMSIG_MIND_TRANSER_TO)
|
||||
|
||||
@@ -456,11 +456,11 @@
|
||||
return
|
||||
|
||||
if(seclevel2num(get_security_level()) >= SEC_LEVEL_RED) // There is a serious threat we gotta move no time to give them five minutes.
|
||||
SSshuttle.emergency.canRecall = FALSE
|
||||
SSshuttle.emergency.request(null, 0.5, null, " Automatic Crew Transfer", 1)
|
||||
SSshuttle.emergency.canRecall = FALSE
|
||||
else
|
||||
SSshuttle.emergency.request(null, 1, null, " Automatic Crew Transfer", 0)
|
||||
SSshuttle.emergency.canRecall = FALSE
|
||||
SSshuttle.emergency.request(null, 1, null, " Automatic Crew Transfer", 0)
|
||||
if(user)
|
||||
log_game("[key_name(user)] has called the shuttle.")
|
||||
message_admins("[key_name_admin(user)] has called the shuttle - [formatJumpTo(user)].", 1)
|
||||
|
||||
@@ -34,6 +34,24 @@
|
||||
|
||||
light_color = LIGHT_COLOR_DARKGREEN
|
||||
|
||||
/obj/machinery/computer/message_monitor/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD // Give the message server time to initialize
|
||||
|
||||
/obj/machinery/computer/message_monitor/LateInitialize()
|
||||
//If the monitor isn't linked to a server, and there's a server available, default it to the first one in the list.
|
||||
if(!linkedServer && length(GLOB.message_servers))
|
||||
linkedServer = GLOB.message_servers[1]
|
||||
RegisterSignal(linkedServer, COMSIG_PARENT_QDELETING, .proc/unlink_server)
|
||||
|
||||
/obj/machinery/computer/message_monitor/proc/unlink_server()
|
||||
SIGNAL_HANDLER
|
||||
linkedServer = null
|
||||
|
||||
/obj/machinery/computer/message_monitor/Destroy()
|
||||
customrecepient = null
|
||||
linkedServer = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/message_monitor/screwdriver_act(mob/user, obj/item/I)
|
||||
if(emag) //Stops people from just unscrewing the monitor and putting it back to get the console working again.
|
||||
@@ -71,14 +89,6 @@
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/message_monitor/Initialize()
|
||||
..()
|
||||
//Is the server isn't linked to a server, and there's a server available, default it to the first one in the list.
|
||||
if(!linkedServer)
|
||||
if(GLOB.message_servers && GLOB.message_servers.len > 0)
|
||||
linkedServer = GLOB.message_servers[1]
|
||||
return
|
||||
|
||||
/obj/machinery/computer/message_monitor/attack_hand(mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
@@ -490,18 +500,18 @@
|
||||
|
||||
|
||||
/obj/item/paper/monitorkey
|
||||
//..()
|
||||
name = "Monitor Decryption Key"
|
||||
var/obj/machinery/message_server/server = null
|
||||
|
||||
/obj/item/paper/monitorkey/New()
|
||||
/obj/item/paper/monitorkey/Initialize(mapload)
|
||||
..()
|
||||
spawn(10)
|
||||
if(GLOB.message_servers)
|
||||
for(var/obj/machinery/message_server/server in GLOB.message_servers)
|
||||
if(!isnull(server))
|
||||
if(!isnull(server.decryptkey))
|
||||
info = "<center><h2>Daily Key Reset</h2></center>\n\t<br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
|
||||
info_links = info
|
||||
overlays += "paper_words"
|
||||
break
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/item/paper/monitorkey/LateInitialize()
|
||||
for(var/obj/machinery/message_server/server in GLOB.message_servers)
|
||||
if(!isnull(server))
|
||||
if(!isnull(server.decryptkey))
|
||||
info = "<center><h2>Daily Key Reset</h2></center>\n\t<br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
|
||||
info_links = info
|
||||
overlays += "paper_words"
|
||||
break
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
if(building)
|
||||
set_pixel_offsets_from_dir(30, -30, 30, -30)
|
||||
|
||||
/obj/machinery/defibrillator_mount/loaded/New() //loaded subtype for mapping use
|
||||
..()
|
||||
/obj/machinery/defibrillator_mount/loaded/Initialize(mapload) //loaded subtype for mapping use
|
||||
. = ..()
|
||||
defib = new/obj/item/defibrillator/loaded(src)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ GLOBAL_LIST_EMPTY(holopads)
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
layer = TURF_LAYER+0.1 //Preventing mice and drones from sneaking under them.
|
||||
layer = HOLOPAD_LAYER //Preventing mice and drones from sneaking under them.
|
||||
plane = FLOOR_PLANE
|
||||
max_integrity = 300
|
||||
armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
name = "Electromagnetic Generator"
|
||||
desc = "A device that uses station power to create points of magnetic energy."
|
||||
level = 1 // underfloor
|
||||
layer = 2.5
|
||||
layer = WIRE_LAYER+0.001
|
||||
anchored = 1
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 50
|
||||
@@ -32,7 +32,8 @@
|
||||
/obj/machinery/magnetic_module/New()
|
||||
..()
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
if(!T.transparent_floor)
|
||||
hide(T.intact)
|
||||
center = T
|
||||
|
||||
spawn(10) // must wait for map loading to finish
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
name = "navigation beacon"
|
||||
desc = "A radio beacon used for bot navigation."
|
||||
level = 1 // underfloor
|
||||
layer = 2.5
|
||||
layer = WIRE_LAYER
|
||||
plane = FLOOR_PLANE
|
||||
anchored = 1
|
||||
max_integrity = 500
|
||||
armor = list(melee = 70, bullet = 70, laser = 70, energy = 70, bomb = 0, bio = 0, rad = 0, fire = 80, acid = 80)
|
||||
@@ -26,7 +27,8 @@
|
||||
set_codes()
|
||||
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
if(!T.transparent_floor)
|
||||
hide(T.intact)
|
||||
if(!codes || !codes.len)
|
||||
log_runtime(EXCEPTION("Empty codes datum at ([x],[y],[z])"), src, list("codes_txt: '[codes_txt]'"))
|
||||
if("patrol" in codes)
|
||||
|
||||
@@ -337,12 +337,18 @@
|
||||
fixdir()
|
||||
|
||||
var/pipe_dir = get_pipe_dir()
|
||||
var/turf/T = get_turf(loc)
|
||||
|
||||
for(var/obj/machinery/atmospherics/M in src.loc)
|
||||
if((M.initialize_directions & pipe_dir) && M.check_connect_types_construction(M,src)) // matches at least one direction on either type of pipe
|
||||
to_chat(user, "<span class='warning'>There is already a pipe of the same type at this location.</span>")
|
||||
return 1
|
||||
|
||||
if(pipe_type in list(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT, PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT, PIPE_HE_STRAIGHT, PIPE_HE_BENT, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_UVENT, PIPE_SUPPLY_CAP, PIPE_SCRUBBERS_CAP, PIPE_PASV_VENT, PIPE_DP_VENT, PIPE_PASSIVE_GATE))
|
||||
if(T.transparent_floor) //stops jank with transparent floors and pipes
|
||||
to_chat(user, "<span class='warning'>You can only fix simple pipes and devices over glass floors!</span>")
|
||||
return 1
|
||||
|
||||
switch(pipe_type) //What kind of heartless person thought of doing this?
|
||||
if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT)
|
||||
var/obj/machinery/atmospherics/pipe/simple/P = new( src.loc )
|
||||
|
||||
@@ -42,11 +42,11 @@
|
||||
user.mind.add_antag_datum(/datum/antagonist/wishgranter)
|
||||
|
||||
to_chat(user, "You have a very bad feeling about this.")
|
||||
|
||||
|
||||
/obj/machinery/wish_granter/super
|
||||
name = "super wish granter"
|
||||
var/list/types = list()
|
||||
|
||||
|
||||
/obj/machinery/wish_granter/super/attack_hand(mob/living/carbon/user)
|
||||
. = ..()
|
||||
|
||||
@@ -60,9 +60,9 @@
|
||||
if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, ROLE_SYNDICATE))
|
||||
to_chat(user, "<span class='warning'>Something instinctual makes you pull away.</span>")
|
||||
return TRUE
|
||||
|
||||
|
||||
to_chat(user, "<span class='notice'>Your touch makes the Wish Granter stir. Are you really sure you want to do this?</span>")
|
||||
|
||||
|
||||
for(var/supname in GLOB.all_superheroes)
|
||||
types += supname
|
||||
|
||||
@@ -85,6 +85,6 @@
|
||||
|
||||
playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1)
|
||||
visible_message("<span class='notice'>The wishgranter fades into mist..</span>")
|
||||
add_attack_logs(null, user, "Became [GLOB.all_superheroes[wish]]")
|
||||
add_attack_logs(user, user, "Became [GLOB.all_superheroes[wish]]")
|
||||
notify_ghosts("[GLOB.all_superheroes[wish]] has appeared in [get_area(user)].", source = user)
|
||||
qdel(src)
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
if(istype(firer, /mob))
|
||||
add_attack_logs(firer, M, "Mecha-shot with <b>[src]</b>")
|
||||
else
|
||||
add_attack_logs(null, M, "Mecha-shot with <b>[src]</b>")
|
||||
add_attack_logs(src, M, "Mecha-shot with <b>[src]</b> (no firer)")
|
||||
if(life <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -59,6 +59,12 @@
|
||||
window_to_spawn_regular = /obj/structure/window/reinforced/tinted
|
||||
window_to_spawn_full = /obj/structure/window/full/reinforced/tinted
|
||||
|
||||
/obj/effect/spawner/window/reinforced/polarized
|
||||
name = "electrochromic reinforced window spawner"
|
||||
icon_state = "pwindow_spawner"
|
||||
window_to_spawn_regular = /obj/structure/window/reinforced/polarized
|
||||
window_to_spawn_full = /obj/structure/window/full/reinforced/polarized
|
||||
|
||||
/obj/effect/spawner/window/shuttle
|
||||
name = "shuttle window spawner"
|
||||
icon_state = "swindow_spawner"
|
||||
|
||||
@@ -117,6 +117,12 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
var/in_inventory = FALSE //is this item equipped into an inventory slot or hand of a mob?
|
||||
var/tip_timer = 0
|
||||
|
||||
// item hover FX
|
||||
/// Is this item inside a storage object?
|
||||
var/in_storage = FALSE
|
||||
/// Holder var for the item outline filter, null when no outline filter on the item.
|
||||
var/outline_filter
|
||||
|
||||
/obj/item/New()
|
||||
..()
|
||||
for(var/path in actions_types)
|
||||
@@ -131,6 +137,11 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
if(!move_resist)
|
||||
determine_move_resist()
|
||||
|
||||
/obj/item/Initialize(mapload)
|
||||
. = ..()
|
||||
if(istype(loc, /obj/item/storage)) //marks all items in storage as being such
|
||||
in_storage = TRUE
|
||||
|
||||
/obj/item/proc/determine_move_resist()
|
||||
switch(w_class)
|
||||
if(WEIGHT_CLASS_TINY)
|
||||
@@ -406,6 +417,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
if((flags & NODROP) && !(initial(flags) & NODROP)) //Remove NODROP is dropped
|
||||
flags &= ~NODROP
|
||||
in_inventory = FALSE
|
||||
remove_outline()
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
|
||||
if(!silent)
|
||||
playsound(src, drop_sound, DROP_SOUND_VOLUME, ignore_walls = FALSE)
|
||||
@@ -418,10 +430,12 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
|
||||
// called when this item is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
|
||||
/obj/item/proc/on_exit_storage(obj/item/storage/S as obj)
|
||||
in_storage = FALSE
|
||||
return
|
||||
|
||||
// called when this item is added into a storage item, which is passed on as S. The loc variable is already set to the storage item.
|
||||
/obj/item/proc/on_enter_storage(obj/item/storage/S as obj)
|
||||
in_storage = TRUE
|
||||
return
|
||||
|
||||
/**
|
||||
@@ -691,14 +705,24 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
openToolTip(user, src, params, title = name, content = "[desc]", theme = "")
|
||||
|
||||
/obj/item/MouseEntered(location, control, params)
|
||||
if(in_inventory)
|
||||
if(in_inventory || in_storage)
|
||||
var/timedelay = 8
|
||||
var/user = usr
|
||||
var/mob/user = usr
|
||||
tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, user), timedelay, TIMER_STOPPABLE)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
var/mob/living/L = user
|
||||
if(!(user.client.prefs.toggles2 & PREFTOGGLE_2_SEE_ITEM_OUTLINES))
|
||||
return
|
||||
if(istype(L) && L.incapacitated(ignore_lying = TRUE))
|
||||
apply_outline(L, COLOR_RED_GRAY) //if they're dead or handcuffed, let's show the outline as red to indicate that they can't interact with that right now
|
||||
else
|
||||
apply_outline(L) //if the player's alive and well we send the command with no color set, so it uses the theme's color
|
||||
|
||||
/obj/item/MouseExited()
|
||||
deltimer(tip_timer) //delete any in-progress timer if the mouse is moved off the item before it finishes
|
||||
closeToolTip(usr)
|
||||
remove_outline()
|
||||
|
||||
/obj/item/MouseDrop_T(obj/item/I, mob/user)
|
||||
if(!user || user.incapacitated(ignore_lying = TRUE) || src == I)
|
||||
@@ -707,6 +731,41 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
if(loc && I.loc == loc && istype(loc, /obj/item/storage) && loc.Adjacent(user)) // Are we trying to swap two items in the storage?
|
||||
var/obj/item/storage/S = loc
|
||||
S.swap_items(src, I, user)
|
||||
remove_outline() //get rid of the hover effect in case the mouse exit isn't called if someone drags and drops an item and somthing goes wrong
|
||||
|
||||
/obj/item/proc/apply_outline(mob/user, outline_color = null)
|
||||
if(!(in_inventory || in_storage) || QDELETED(src) || isobserver(user)) //cancel if the item isn't in an inventory, is being deleted, or if the person hovering is a ghost (so that people spectating you don't randomly make your items glow)
|
||||
return
|
||||
var/theme = lowertext(user.client.prefs.UI_style)
|
||||
if(!outline_color) //if we weren't provided with a color, take the theme's color
|
||||
switch(theme) //yeah it kinda has to be this way
|
||||
if("midnight")
|
||||
outline_color = COLOR_THEME_MIDNIGHT
|
||||
if("plasmafire")
|
||||
outline_color = COLOR_THEME_PLASMAFIRE
|
||||
if("retro")
|
||||
outline_color = COLOR_THEME_RETRO //just as garish as the rest of this theme
|
||||
if("slimecore")
|
||||
outline_color = COLOR_THEME_SLIMECORE
|
||||
if("operative")
|
||||
outline_color = COLOR_THEME_OPERATIVE
|
||||
if("clockwork")
|
||||
outline_color = COLOR_THEME_CLOCKWORK //if you want free gbp go fix the fact that clockwork's tooltip css is glass'
|
||||
if("glass")
|
||||
outline_color = COLOR_THEME_GLASS
|
||||
else //this should never happen, hopefully
|
||||
outline_color = COLOR_WHITE
|
||||
if(color)
|
||||
outline_color = COLOR_WHITE //if the item is recolored then the outline will be too, let's make the outline white so it becomes the same color instead of some ugly mix of the theme and the tint
|
||||
if(outline_filter)
|
||||
filters -= outline_filter
|
||||
outline_filter = filter(type = "outline", size = 1, color = outline_color)
|
||||
filters += outline_filter
|
||||
|
||||
/obj/item/proc/remove_outline()
|
||||
if(outline_filter)
|
||||
filters -= outline_filter
|
||||
outline_filter = null
|
||||
|
||||
// Returns a numeric value for sorting items used as parts in machines, so they can be replaced by the rped
|
||||
/obj/item/proc/get_part_rating()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TATER!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "FOR THE SYNDICATE!")
|
||||
|
||||
/obj/item/megaphone/attack_self(mob/living/user as mob)
|
||||
if(user.client && (user.client.prefs.muted & MUTE_IC))
|
||||
if(check_mute(user.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='warning'>You cannot speak in IC (muted).</span>")
|
||||
return
|
||||
if(!ishuman(user))
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(P)
|
||||
if(P.level < 2 && T.level == 1 && T.intact)
|
||||
to_chat(user, "<span class='warning'>You must remove the plating first.</span>")
|
||||
if(P.level < 2 && T.level == 1 && T.intact && !T.transparent_floor)
|
||||
to_chat(user, "<span class='warning'>You must remove the flooring first.</span>")
|
||||
return
|
||||
|
||||
P.change_color(GLOB.pipe_colors[paint_setting])
|
||||
|
||||
@@ -21,3 +21,11 @@
|
||||
/obj/item/mounted/frame/light_switch/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/light_switch(get_turf(user), get_dir(user, on_wall))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/mounted/frame/light_switch/windowtint
|
||||
name = "window tint control button frame"
|
||||
desc = "Used for repairing or building window tint control buttons"
|
||||
|
||||
/obj/item/mounted/frame/light_switch/windowtint/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/button/windowtint(get_turf(user), get_dir(user, on_wall))
|
||||
qdel(src)
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
null,
|
||||
new /datum/stack_recipe("railing", /obj/structure/railing, 3, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("railing corner", /obj/structure/railing/corner, 3, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
null,
|
||||
new /datum/stack_recipe_list("chainlink fence", list( \
|
||||
new /datum/stack_recipe("chainlink fence", /obj/structure/fence, 5, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("chainlink fence post", /obj/structure/fence/post, 5, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("chainlink fence corner", /obj/structure/fence/corner, 5, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("chainlink fence door", /obj/structure/fence/door, 10, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new /datum/stack_recipe("chainlink fence end", /obj/structure/fence/end, 3, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
)), \
|
||||
))
|
||||
|
||||
/obj/item/stack/rods
|
||||
|
||||
@@ -89,7 +89,10 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
null, \
|
||||
new/datum/stack_recipe/window("directional reinforced window", /obj/structure/window/reinforced, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/reinforced, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
|
||||
new/datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/reinforced, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
null, \
|
||||
new/datum/stack_recipe/window("directional electrochromic window", /obj/structure/window/reinforced/polarized, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile electrochromic window", /obj/structure/window/full/reinforced/polarized, 4, time = 0, on_floor = TRUE, window_checks = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/rglass
|
||||
|
||||
@@ -92,6 +92,7 @@ GLOBAL_LIST_INIT(metal_recipes, list(
|
||||
null,
|
||||
new /datum/stack_recipe("mass driver button frame", /obj/item/mounted/frame/driver_button, 1, time = 50, one_per_turf = 0, on_floor = 1),
|
||||
new /datum/stack_recipe("light switch frame", /obj/item/mounted/frame/light_switch, 1, time = 50, one_per_turf = 0, on_floor = 1),
|
||||
new /datum/stack_recipe("window tint control button frame", /obj/item/mounted/frame/light_switch/windowtint, 1, time = 50, one_per_turf = 0, on_floor = 1),
|
||||
null,
|
||||
new /datum/stack_recipe("grenade casing", /obj/item/grenade/chem_grenade),
|
||||
new /datum/stack_recipe("light fixture frame", /obj/item/mounted/frame/light_fixture, 2),
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
/obj/item/defibrillator
|
||||
name = "defibrillator"
|
||||
desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients."
|
||||
icon = 'icons/obj/defib.dmi'
|
||||
icon_state = "defibunit"
|
||||
item_state = "defibunit"
|
||||
slot_flags = SLOT_BACK
|
||||
@@ -17,27 +18,27 @@
|
||||
)
|
||||
|
||||
var/paddles_on_defib = TRUE //if the paddles are on the defib (TRUE)
|
||||
var/safety = TRUE //if you can zap people with the defibs on harm mode
|
||||
var/powered = FALSE //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise
|
||||
var/obj/item/twohanded/shockpaddles/paddles
|
||||
var/obj/item/stock_parts/cell/high/cell = null
|
||||
var/safety = TRUE //if you can zap people with the defibs on harm mode
|
||||
var/combat = FALSE //can we revive through space suits?
|
||||
var/heart_attack = FALSE //can it give instant heart attacks when zapped on harm intent with combat?
|
||||
var/base_icon_state = "defibpaddles"
|
||||
var/obj/item/twohanded/shockpaddles/paddle_type = /obj/item/twohanded/shockpaddles
|
||||
|
||||
/obj/item/defibrillator/get_cell()
|
||||
return cell
|
||||
|
||||
/obj/item/defibrillator/New() //starts without a cell for rnd
|
||||
..()
|
||||
paddles = make_paddles()
|
||||
/obj/item/defibrillator/Initialize(mapload) //starts without a cell for rnd
|
||||
. = ..()
|
||||
paddles = new paddle_type(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/defibrillator/loaded/New() //starts with hicap
|
||||
..()
|
||||
paddles = make_paddles()
|
||||
/obj/item/defibrillator/loaded/Initialize(mapload) //starts with hicap
|
||||
. = ..()
|
||||
cell = new(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/defibrillator/update_icon()
|
||||
update_power()
|
||||
@@ -158,9 +159,6 @@
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/defibrillator/proc/make_paddles()
|
||||
return new /obj/item/twohanded/shockpaddles(src)
|
||||
|
||||
/obj/item/defibrillator/equipped(mob/user, slot)
|
||||
..()
|
||||
if(slot != slot_back)
|
||||
@@ -214,38 +212,68 @@
|
||||
|
||||
/obj/item/defibrillator/compact
|
||||
name = "compact defibrillator"
|
||||
desc = "A belt-equipped defibrillator that can be rapidly deployed."
|
||||
desc = "A belt-mounted defibrillator that can be rapidly deployed."
|
||||
icon_state = "defibcompact"
|
||||
item_state = "defibcompact"
|
||||
sprite_sheets = null //Because Vox had the belt defibrillator sprites in back.dm
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "biotech=5"
|
||||
|
||||
/obj/item/defibrillator/compact/loaded/Initialize(mapload)
|
||||
. = ..()
|
||||
cell = new(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user)
|
||||
if(slot == slot_belt)
|
||||
return TRUE
|
||||
|
||||
/obj/item/defibrillator/compact/loaded/New()
|
||||
..()
|
||||
paddles = make_paddles()
|
||||
cell = new(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/defibrillator/compact/combat
|
||||
name = "combat defibrillator"
|
||||
desc = "A belt-equipped blood-red defibrillator that can be rapidly deployed. Does not have the restrictions or safeties of conventional defibrillators and can revive through space suits."
|
||||
desc = "A belt-mounted blood-red defibrillator that can be rapidly deployed. Does not have the restrictions or safeties of conventional defibrillators and can revive through space suits."
|
||||
icon_state = "defibcombat"
|
||||
item_state = "defibcombat"
|
||||
paddle_type = /obj/item/twohanded/shockpaddles/syndicate
|
||||
combat = TRUE
|
||||
safety = FALSE
|
||||
|
||||
/obj/item/defibrillator/compact/combat/loaded/New()
|
||||
..()
|
||||
paddles = make_paddles()
|
||||
/obj/item/defibrillator/compact/combat/loaded/Initialize(mapload)
|
||||
. = ..()
|
||||
cell = new(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/defibrillator/compact/combat/attackby(obj/item/W, mob/user, params)
|
||||
/obj/item/defibrillator/compact/advanced
|
||||
name = "advanced compact defibrillator"
|
||||
desc = "A belt-mounted state-of-the-art defibrillator that can be rapidly deployed in all environments. Uses an experimental self-charging cell, meaning that it will (probably) never stop working. Can be used to defibrillate through space suits. It is impossible to damage."
|
||||
icon_state = "defibnt"
|
||||
item_state = "defibnt"
|
||||
paddle_type = /obj/item/twohanded/shockpaddles/advanced
|
||||
combat = TRUE
|
||||
safety = TRUE
|
||||
heart_attack = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //Objective item, better not have it destroyed.
|
||||
|
||||
var/next_emp_message //to prevent spam from the emagging message on the advanced defibrillator
|
||||
|
||||
/obj/item/defibrillator/compact/advanced/attackby(obj/item/W, mob/user, params)
|
||||
if(W == paddles)
|
||||
paddles.unwield()
|
||||
toggle_paddles()
|
||||
update_icon()
|
||||
|
||||
/obj/item/defibrillator/compact/advanced/loaded/Initialize(mapload)
|
||||
. = ..()
|
||||
cell = new /obj/item/stock_parts/cell/bluespace/charging(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/defibrillator/compact/advanced/emp_act(severity)
|
||||
if(world.time > next_emp_message)
|
||||
atom_say("Warning: Electromagnetic pulse detected. Integrated shielding prevented all potential hardware damage.")
|
||||
playsound(src, 'sound/machines/defib_saftyon.ogg', 50)
|
||||
next_emp_message = world.time + 5 SECONDS
|
||||
|
||||
/obj/item/defibrillator/compact/advanced/attackby(obj/item/W, mob/user, params)
|
||||
if(W == paddles)
|
||||
paddles.unwield()
|
||||
toggle_paddles()
|
||||
@@ -257,6 +285,7 @@
|
||||
/obj/item/twohanded/shockpaddles
|
||||
name = "defibrillator paddles"
|
||||
desc = "A pair of plastic-gripped paddles with flat metal surfaces that are used to deliver powerful electric shocks."
|
||||
icon = 'icons/obj/defib.dmi'
|
||||
icon_state = "defibpaddles"
|
||||
item_state = "defibpaddles"
|
||||
force = 0
|
||||
@@ -268,6 +297,7 @@
|
||||
var/revivecost = 1000
|
||||
var/cooldown = FALSE
|
||||
var/busy = FALSE
|
||||
var/base_icon_state = "defibpaddles"
|
||||
var/obj/item/defibrillator/defib
|
||||
|
||||
/obj/item/twohanded/shockpaddles/New(mainunit)
|
||||
@@ -280,10 +310,10 @@
|
||||
return
|
||||
|
||||
/obj/item/twohanded/shockpaddles/update_icon()
|
||||
icon_state = "defibpaddles[wielded]"
|
||||
item_state = "defibpaddles[wielded]"
|
||||
icon_state = "[base_icon_state][wielded]"
|
||||
item_state = "[base_icon_state][wielded]"
|
||||
if(cooldown)
|
||||
icon_state = "defibpaddles[wielded]_cooldown"
|
||||
icon_state = "[base_icon_state][wielded]_cooldown"
|
||||
|
||||
/obj/item/twohanded/shockpaddles/suicide_act(mob/user)
|
||||
user.visible_message("<span class='danger'>[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
@@ -336,7 +366,7 @@
|
||||
to_chat(user, "<span class='notice'>[defib] is recharging.</span>")
|
||||
return
|
||||
if(!ishuman(M))
|
||||
to_chat(user, "<span class='notice'>The instructions on [defib] don't mention how to revive that...</span>")
|
||||
to_chat(user, "<span class='notice'>The instructions on [defib] don't mention how to defibrillate that...</span>")
|
||||
return
|
||||
else
|
||||
if(user.a_intent == INTENT_HARM && !defib.safety)
|
||||
@@ -347,7 +377,7 @@
|
||||
H.Weaken(5)
|
||||
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
H.emote("gasp")
|
||||
if(!H.undergoing_cardiac_arrest() && (prob(10) || defib.combat)) // Your heart explodes.
|
||||
if(!H.undergoing_cardiac_arrest() && (prob(10) || (defib.combat && !defib.heart_attack) || prob(10) && (defib.combat && defib.heart_attack))) // Your heart explodes.
|
||||
H.set_heartattack(TRUE)
|
||||
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK, 100)
|
||||
add_attack_logs(user, M, "Stunned with [src]")
|
||||
@@ -470,7 +500,8 @@
|
||||
|
||||
/obj/item/borg_defib
|
||||
name = "defibrillator paddles"
|
||||
desc = "A pair of mounted paddles with flat metal surfaces that are used to deliver powerful electric shocks."
|
||||
desc = "A pair of paddles with flat metal surfaces that are used to deliver powerful electric shocks."
|
||||
icon = 'icons/obj/defib.dmi'
|
||||
icon_state = "defibpaddles0"
|
||||
item_state = "defibpaddles0"
|
||||
force = 0
|
||||
@@ -590,3 +621,17 @@
|
||||
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
|
||||
busy = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/syndicate
|
||||
name = "combat defibrillator paddles"
|
||||
desc = "A pair of high-tech paddles with flat plasteel surfaces to revive deceased operatives (unless they exploded). They possess both the ability to penetrate armor and to deliver powerful or disabling shocks offensively."
|
||||
icon_state = "syndiepaddles0"
|
||||
item_state = "syndiepaddles0"
|
||||
base_icon_state = "syndiepaddles"
|
||||
|
||||
/obj/item/twohanded/shockpaddles/advanced
|
||||
name = "advanced defibrillator paddles"
|
||||
desc = "A pair of high-tech paddles with flat plasteel surfaces that are used to deliver powerful electric shocks. They possess the ability to penetrate armor to deliver shock."
|
||||
icon_state = "ntpaddles0"
|
||||
item_state = "ntpaddles0"
|
||||
base_icon_state = "ntpaddles"
|
||||
|
||||
@@ -170,28 +170,6 @@
|
||||
block = GLOB.hulkblock
|
||||
..()
|
||||
|
||||
/obj/item/dnainjector/xraymut
|
||||
name = "DNA-Injector (Xray)"
|
||||
desc = "Finally you can see what the Captain does."
|
||||
datatype = DNA2_BUF_SE
|
||||
value = 0xFFF
|
||||
forcedmutation = TRUE
|
||||
|
||||
/obj/item/dnainjector/xraymut/Initialize()
|
||||
block = GLOB.xrayblock
|
||||
..()
|
||||
|
||||
/obj/item/dnainjector/antixray
|
||||
name = "DNA-Injector (Anti-Xray)"
|
||||
desc = "It will make you see harder."
|
||||
datatype = DNA2_BUF_SE
|
||||
value = 0x001
|
||||
forcedmutation = TRUE
|
||||
|
||||
/obj/item/dnainjector/antixray/Initialize()
|
||||
block = GLOB.xrayblock
|
||||
..()
|
||||
|
||||
/obj/item/dnainjector/firemut
|
||||
name = "DNA-Injector (Fire)"
|
||||
desc = "Gives you fire."
|
||||
|
||||
@@ -716,7 +716,6 @@
|
||||
new /obj/item/stack/cable_coil(src)
|
||||
|
||||
new /obj/item/restraints/handcuffs(src)
|
||||
new /obj/item/dnainjector/xraymut(src)
|
||||
new /obj/item/dnainjector/firemut(src)
|
||||
new /obj/item/dnainjector/telemut(src)
|
||||
new /obj/item/dnainjector/hulkmut(src)
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
/obj/blob_act(obj/structure/blob/B)
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
if(T.intact && level == 1) //the blob doesn't destroy thing below the floor
|
||||
if((T.intact && level == 1) || T.transparent_floor) //the blob doesn't destroy thing below the floor
|
||||
return
|
||||
take_damage(400, BRUTE, "melee", 0, get_dir(src, B))
|
||||
|
||||
@@ -199,7 +199,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
/obj/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
if(T.intact && level == 1) //fire can't damage things hidden below the floor.
|
||||
if((T.intact && level == 1) || T.transparent_floor) //fire can't damage things hidden below the floor.
|
||||
return
|
||||
..()
|
||||
if(exposed_temperature && !(resistance_flags & FIRE_PROOF))
|
||||
|
||||
@@ -59,30 +59,31 @@
|
||||
|
||||
/obj/structure/proc/do_climb(mob/living/user)
|
||||
if(!can_touch(user) || !climbable)
|
||||
return
|
||||
return FALSE
|
||||
var/blocking_object = density_check()
|
||||
if(blocking_object)
|
||||
to_chat(user, "<span class='warning'>You cannot climb [src], as it is blocked by \a [blocking_object]!</span>")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
var/turf/T = src.loc
|
||||
if(!T || !istype(T)) return
|
||||
if(!T || !istype(T)) return FALSE
|
||||
|
||||
usr.visible_message("<span class='warning'>[user] starts climbing onto \the [src]!</span>")
|
||||
climber = user
|
||||
if(!do_after(user, 50, target = src))
|
||||
climber = null
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(!can_touch(user) || !climbable)
|
||||
climber = null
|
||||
return
|
||||
return FALSE
|
||||
|
||||
usr.loc = get_turf(src)
|
||||
if(get_turf(user) == get_turf(src))
|
||||
usr.visible_message("<span class='warning'>[user] climbs onto \the [src]!</span>")
|
||||
|
||||
climber = null
|
||||
return TRUE
|
||||
|
||||
/obj/structure/proc/structure_shaken()
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
new /obj/item/clothing/shoes/brown (src)
|
||||
new /obj/item/radio/headset/heads/cmo(src)
|
||||
new /obj/item/clothing/gloves/color/latex/nitrile(src)
|
||||
new /obj/item/defibrillator/compact/loaded(src)
|
||||
new /obj/item/defibrillator/compact/advanced/loaded(src)
|
||||
new /obj/item/handheld_defibrillator(src)
|
||||
new /obj/item/storage/belt/medical(src)
|
||||
new /obj/item/flash(src)
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
//Chain link fences
|
||||
//Sprites ported from /VG/
|
||||
|
||||
#define CUT_TIME 100
|
||||
#define CLIMB_TIME 150
|
||||
|
||||
#define NO_HOLE 0 //section is intact
|
||||
#define MEDIUM_HOLE 1 //medium hole in the section - can climb through
|
||||
#define LARGE_HOLE 2 //large hole in the section - can walk through
|
||||
#define MAX_HOLE_SIZE LARGE_HOLE
|
||||
#define HOLE_REPAIR (hole_size * 2) //How many rods to fix these sections
|
||||
|
||||
/obj/structure/fence
|
||||
name = "fence"
|
||||
desc = "A chain link fence. Not as effective as a wall, but generally it keeps people out."
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
|
||||
icon = 'icons/obj/fence.dmi'
|
||||
icon_state = "straight"
|
||||
|
||||
var/cuttable = TRUE
|
||||
var/hole_size = NO_HOLE
|
||||
var/invulnerable = FALSE
|
||||
var/shock_cooldown = FALSE
|
||||
|
||||
/obj/structure/fence/Initialize()
|
||||
. = ..()
|
||||
update_cut_status()
|
||||
|
||||
/obj/structure/fence/examine(mob/user)
|
||||
. = ..()
|
||||
switch(hole_size)
|
||||
if(MEDIUM_HOLE)
|
||||
. += "There is a large hole in \the [src]."
|
||||
if(LARGE_HOLE)
|
||||
. += "\The [src] has been completely cut through."
|
||||
|
||||
/obj/structure/fence/end
|
||||
icon_state = "end"
|
||||
cuttable = FALSE
|
||||
|
||||
/obj/structure/fence/corner
|
||||
icon_state = "corner"
|
||||
cuttable = FALSE
|
||||
|
||||
/obj/structure/fence/post
|
||||
icon_state = "post"
|
||||
cuttable = FALSE
|
||||
|
||||
/obj/structure/fence/cut/medium
|
||||
icon_state = "straight_cut2"
|
||||
hole_size = MEDIUM_HOLE
|
||||
climbable = TRUE
|
||||
|
||||
/obj/structure/fence/cut/large
|
||||
icon_state = "straight_cut3"
|
||||
hole_size = LARGE_HOLE
|
||||
|
||||
/obj/structure/fence/CanPass(atom/movable/mover, turf/target)
|
||||
if(istype(mover) && mover.checkpass(PASSFENCE))
|
||||
return TRUE
|
||||
if(istype(mover, /obj/item/projectile))
|
||||
return TRUE
|
||||
if(!density)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
Shock user with probability prb (if all connections & power are working)
|
||||
Returns TRUE if shocked, FALSE otherwise
|
||||
Totally not stolen from code\game\objects\structures\grille.dm
|
||||
*/
|
||||
/obj/structure/fence/proc/shock(mob/user, prb)
|
||||
if(!prob(prb))
|
||||
return FALSE
|
||||
if(!in_range(src, user)) //To prevent TK and mech users from getting shocked
|
||||
return FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/structure/cable/C = T.get_cable_node()
|
||||
if(C)
|
||||
if(electrocute_mob(user, C, src, 1, TRUE))
|
||||
do_sparks(3, 1, src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/structure/fence/wirecutter_act(mob/living/user, obj/item/W)
|
||||
. = TRUE
|
||||
if(shock(user, 100))
|
||||
return
|
||||
if(!cuttable)
|
||||
to_chat(user, "<span class='warning'>This section of the fence can't be cut!</span>")
|
||||
return
|
||||
if(invulnerable)
|
||||
to_chat(user, "<span class='warning'>This fence is too strong to cut through!</span>")
|
||||
return
|
||||
var/current_stage = hole_size
|
||||
user.visible_message("<span class='danger'>\The [user] starts cutting through \the [src] with \the [W].</span>",\
|
||||
"<span class='danger'>You start cutting through \the [src] with \the [W].</span>")
|
||||
if(W.use_tool(src, user, CUT_TIME * W.toolspeed, volume = W.tool_volume))
|
||||
if(current_stage == hole_size)
|
||||
switch(hole_size)
|
||||
if(NO_HOLE)
|
||||
visible_message("<span class='notice'>\The [user] cuts into \the [src] some more.</span>")
|
||||
to_chat(user, "<span class='info'>You could probably fit yourself through that hole now. Although climbing through would be much faster if you made it even bigger.</span>")
|
||||
hole_size = MEDIUM_HOLE
|
||||
if(MEDIUM_HOLE)
|
||||
visible_message("<span class='notice'>\The [user] completely cuts through \the [src].</span>")
|
||||
to_chat(user, "<span class='info'>The hole in \the [src] is now big enough to walk through.</span>")
|
||||
hole_size = LARGE_HOLE
|
||||
if(LARGE_HOLE)
|
||||
visible_message("<span class='notice'>\The [user] completely dismantles \the [src].</span>")
|
||||
to_chat(user, "<span class='info'>You completely take apart \the [src].</span>")
|
||||
qdel(src)
|
||||
return
|
||||
update_cut_status()
|
||||
|
||||
/obj/structure/fence/attackby(obj/item/C, mob/user)
|
||||
if(shock(user, 90))
|
||||
return
|
||||
if(istype(C, /obj/item/stack/rods))
|
||||
if(hole_size == NO_HOLE)
|
||||
return
|
||||
var/obj/item/stack/rods/R = C
|
||||
if(R.get_amount() < HOLE_REPAIR)
|
||||
to_chat(user, "<span class='warning'>You need [HOLE_REPAIR] rods to fix this fence!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin repairing the fence...</span>")
|
||||
if(do_after(user, 3 SECONDS * C.toolspeed, target = src) && hole_size != NO_HOLE && R.use(HOLE_REPAIR))
|
||||
playsound(src, C.usesound, 80, 1)
|
||||
hole_size = NO_HOLE
|
||||
obj_integrity = max_integrity
|
||||
to_chat(user, "<span class='notice'>You repair the fence.</span>")
|
||||
update_cut_status()
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/structure/fence/Bumped(atom/user)
|
||||
if(!ismob(user))
|
||||
return
|
||||
if(shock_cooldown)
|
||||
return
|
||||
shock(user, 70)
|
||||
shock_cooldown = TRUE // We do not want bump shock spam!
|
||||
addtimer(CALLBACK(src, .proc/shock_cooldown), 1 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
|
||||
|
||||
/obj/structure/fence/proc/shock_cooldown()
|
||||
shock_cooldown = FALSE
|
||||
|
||||
/obj/structure/fence/attack_animal(mob/user)
|
||||
. = ..()
|
||||
if(. && !QDELETED(src) && !shock(user, 70))
|
||||
take_damage(rand(5,10), BRUTE, "melee", 1)
|
||||
|
||||
/obj/structure/fence/proc/update_cut_status()
|
||||
if(!cuttable)
|
||||
return
|
||||
var/new_density = TRUE
|
||||
switch(hole_size)
|
||||
if(NO_HOLE)
|
||||
icon_state = initial(icon_state)
|
||||
climbable = FALSE
|
||||
if(MEDIUM_HOLE)
|
||||
icon_state = "straight_cut2"
|
||||
climbable = TRUE
|
||||
if(LARGE_HOLE)
|
||||
icon_state = "straight_cut3"
|
||||
new_density = FALSE
|
||||
climbable = FALSE
|
||||
set_density(new_density)
|
||||
|
||||
//FENCE DOORS
|
||||
|
||||
/obj/structure/fence/door
|
||||
name = "fence door"
|
||||
desc = "Not very useful without a real lock."
|
||||
icon_state = "door_closed"
|
||||
cuttable = FALSE
|
||||
var/open = FALSE
|
||||
|
||||
/obj/structure/fence/door/Initialize()
|
||||
. = ..()
|
||||
update_door_status()
|
||||
|
||||
/obj/structure/fence/door/opened
|
||||
icon_state = "door_opened"
|
||||
open = TRUE
|
||||
density = TRUE
|
||||
|
||||
/obj/structure/fence/door/attack_hand(mob/user, list/modifiers)
|
||||
shock(user, 70)
|
||||
if(can_open(user))
|
||||
toggle(user)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/fence/door/proc/toggle(mob/user)
|
||||
open = !open
|
||||
visible_message("<span class='notice'>\The [user] [open ? "opens" : "closes"] \the [src].</span>")
|
||||
update_door_status()
|
||||
playsound(src, 'sound/machines/door_open.ogg', 100, TRUE)
|
||||
|
||||
/obj/structure/fence/door/proc/update_door_status()
|
||||
set_density(!open)
|
||||
icon_state = open ? "door_opened" : "door_closed"
|
||||
|
||||
/obj/structure/fence/door/proc/can_open(mob/user)
|
||||
return TRUE
|
||||
|
||||
#undef CUT_TIME
|
||||
#undef CLIMB_TIME
|
||||
|
||||
#undef NO_HOLE
|
||||
#undef MEDIUM_HOLE
|
||||
#undef LARGE_HOLE
|
||||
#undef MAX_HOLE_SIZE
|
||||
#undef HOLE_REPAIR
|
||||
@@ -0,0 +1,136 @@
|
||||
/obj/structure/railing
|
||||
name = "railing"
|
||||
desc = "Basic railing meant to protect idiots like you from falling."
|
||||
icon = 'icons/obj/fence.dmi'
|
||||
icon_state = "railing"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
pass_flags = LETPASSTHROW
|
||||
climbable = TRUE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
var/currently_climbed = FALSE
|
||||
|
||||
/obj/structure/railing/corner //aesthetic corner sharp edges hurt oof ouch
|
||||
icon_state = "railing_corner"
|
||||
density = FALSE
|
||||
climbable = FALSE
|
||||
|
||||
/obj/structure/railing/attackby(obj/item/I, mob/living/user, params)
|
||||
..()
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/structure/railing/welder_act(mob/living/user, obj/item/I)
|
||||
if(user.intent != INTENT_HELP)
|
||||
return
|
||||
if(obj_integrity >= max_integrity)
|
||||
to_chat(user, "<span class='warning'>[src] is already in good condition!</span>")
|
||||
return
|
||||
if(!I.tool_start_check(user, amount = 0))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin repairing [src]...</span>")
|
||||
if(I.use_tool(src, user, 40, volume = 50))
|
||||
obj_integrity = max_integrity
|
||||
to_chat(user, "<span class='notice'>You repair [src].</span>")
|
||||
|
||||
/obj/structure/railing/wirecutter_act(mob/living/user, obj/item/I)
|
||||
if(anchored)
|
||||
return
|
||||
to_chat(user, "<span class='warning'>You cut apart the railing.</span>")
|
||||
I.play_tool_sound(src, 100)
|
||||
deconstruct()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/deconstruct(disassembled)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
var/obj/item/stack/rods/rod = new /obj/item/stack/rods(drop_location(), 3)
|
||||
transfer_fingerprints_to(rod)
|
||||
return ..()
|
||||
|
||||
///Implements behaviour that makes it possible to unanchor the railing.
|
||||
/obj/structure/railing/wrench_act(mob/living/user, obj/item/I)
|
||||
if(flags & NODECONSTRUCT)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin to [anchored ? "unfasten the railing from":"fasten the railing to"] the floor...</span>")
|
||||
if(I.use_tool(src, user, volume = 75, extra_checks = CALLBACK(src, .proc/check_anchored, anchored)))
|
||||
anchored = !anchored
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "fasten the railing to":"unfasten the railing from"] the floor.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/corner/CanPass()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/corner/CheckExit()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/CanPass(atom/movable/mover, turf/target)
|
||||
if(istype(mover) && mover.checkpass(PASSFENCE))
|
||||
return TRUE
|
||||
if(istype(mover, /obj/item/projectile))
|
||||
return TRUE
|
||||
if(ismob(mover))
|
||||
var/mob/M = mover
|
||||
if(M.flying)
|
||||
return TRUE
|
||||
if(mover.throwing)
|
||||
return TRUE
|
||||
if(get_dir(loc, target) != dir)
|
||||
return density
|
||||
return FALSE
|
||||
|
||||
/obj/structure/railing/CheckExit(atom/movable/O, target)
|
||||
var/mob/living/M = O
|
||||
if(istype(O) && O.checkpass(PASSFENCE))
|
||||
return TRUE
|
||||
if(istype(O, /obj/item/projectile))
|
||||
return TRUE
|
||||
if(ismob(O))
|
||||
if(M.flying || M.floating)
|
||||
return TRUE
|
||||
if(O.throwing)
|
||||
return TRUE
|
||||
if(O.move_force >= MOVE_FORCE_EXTREMELY_STRONG)
|
||||
return TRUE
|
||||
if(currently_climbed)
|
||||
return TRUE
|
||||
if(get_dir(O.loc, target) == dir)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/do_climb(mob/living/user)
|
||||
var/initial_mob_loc = get_turf(user)
|
||||
. = ..()
|
||||
if(.)
|
||||
currently_climbed = TRUE
|
||||
if(initial_mob_loc != get_turf(src)) // If we are on the railing, we want to move in the same dir as the railing. Otherwise we get put on the railing
|
||||
currently_climbed = FALSE
|
||||
return
|
||||
user.Move(get_step(user, dir), TRUE)
|
||||
currently_climbed = FALSE
|
||||
|
||||
/obj/structure/railing/proc/can_be_rotated(mob/user)
|
||||
if(anchored)
|
||||
to_chat(user, "<span class='warning'>[src] cannot be rotated while it is fastened to the floor!</span>")
|
||||
return FALSE
|
||||
|
||||
var/target_dir = turn(dir, -90)
|
||||
|
||||
if(!valid_window_location(loc, target_dir)) //Expanded to include rails, as well!
|
||||
to_chat(user, "<span class='warning'>[src] cannot be rotated in that direction!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/proc/check_anchored(checked_anchored)
|
||||
if(anchored == checked_anchored)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/proc/after_rotation(mob/user)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/structure/railing/AltClick(mob/user)
|
||||
if(user.incapacitated())
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(!Adjacent(user))
|
||||
return
|
||||
if(can_be_rotated(user))
|
||||
setDir(turn(dir, 90))
|
||||
@@ -368,7 +368,8 @@ GLOBAL_LIST_EMPTY(safes)
|
||||
/obj/structure/safe/floor/Initialize()
|
||||
. = ..()
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
if(!T.transparent_floor)
|
||||
hide(T.intact)
|
||||
|
||||
/obj/structure/safe/floor/hide(intact)
|
||||
invisibility = intact ? INVISIBILITY_MAXIMUM : 0
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
var/real_explosion_block //ignore this, just use explosion_block
|
||||
var/breaksound = "shatter"
|
||||
var/hitsound = 'sound/effects/Glasshit.ogg'
|
||||
/// Used to restore colours from polarised glass
|
||||
var/old_color
|
||||
|
||||
/obj/structure/window/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -69,6 +71,17 @@
|
||||
|
||||
air_update_turf(TRUE)
|
||||
|
||||
/obj/structure/window/proc/toggle_polarization()
|
||||
if(opacity)
|
||||
if(!old_color)
|
||||
old_color = "#FFFFFF"
|
||||
animate(src, color = old_color, time = 0.5 SECONDS)
|
||||
set_opacity(FALSE)
|
||||
else
|
||||
old_color = color
|
||||
animate(src, color = "#222222", time = 0.5 SECONDS)
|
||||
set_opacity(TRUE)
|
||||
|
||||
/obj/structure/window/narsie_act()
|
||||
color = NARSIE_WINDOW_COLOUR
|
||||
|
||||
@@ -497,14 +510,6 @@
|
||||
desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it."
|
||||
var/id
|
||||
|
||||
/obj/structure/window/reinforced/polarized/proc/toggle()
|
||||
if(opacity)
|
||||
animate(src, color="#FFFFFF", time=5)
|
||||
set_opacity(0)
|
||||
else
|
||||
animate(src, color="#222222", time=5)
|
||||
set_opacity(1)
|
||||
|
||||
/obj/machinery/button/windowtint
|
||||
name = "window tint control"
|
||||
icon = 'icons/obj/power.dmi'
|
||||
@@ -514,12 +519,35 @@
|
||||
var/id = 0
|
||||
var/active = 0
|
||||
|
||||
/obj/machinery/button/windowtint/Initialize(mapload, w_dir = null)
|
||||
. = ..()
|
||||
switch(w_dir)
|
||||
if(NORTH)
|
||||
pixel_y = 25
|
||||
if(SOUTH)
|
||||
pixel_y = -25
|
||||
if(EAST)
|
||||
pixel_x = 25
|
||||
if(WEST)
|
||||
pixel_x = -25
|
||||
|
||||
/obj/machinery/button/windowtint/attack_hand(mob/user)
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
toggle_tint()
|
||||
|
||||
/obj/machinery/button/windowtint/wrench_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] starts unwrenching [src] from the wall...</span>", "<span class='notice'>You are unwrenching [src] from the wall...</span>", "<span class='warning'>You hear ratcheting.</span>")
|
||||
if(!I.use_tool(src, user, 50, volume = I.tool_volume))
|
||||
return
|
||||
WRENCH_UNANCHOR_WALL_MESSAGE
|
||||
new /obj/item/mounted/frame/light_switch/windowtint(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/button/windowtint/proc/toggle_tint()
|
||||
use_power(5)
|
||||
|
||||
@@ -528,9 +556,11 @@
|
||||
|
||||
for(var/obj/structure/window/reinforced/polarized/W in range(src,range))
|
||||
if(W.id == src.id || !W.id)
|
||||
spawn(0)
|
||||
W.toggle()
|
||||
return
|
||||
W.toggle_polarization()
|
||||
|
||||
for(var/obj/structure/window/full/reinforced/polarized/W in range(src, range))
|
||||
if(W.id == id || !W.id)
|
||||
W.toggle_polarization()
|
||||
|
||||
/obj/machinery/button/windowtint/power_change()
|
||||
..()
|
||||
@@ -589,7 +619,7 @@
|
||||
icon_state = "window"
|
||||
max_integrity = 50
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced, /turf/simulated/wall/indestructible/fakeglass)
|
||||
canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/polarized, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced, /turf/simulated/wall/indestructible/fakeglass)
|
||||
|
||||
/obj/structure/window/full/plasmabasic
|
||||
name = "plasma window"
|
||||
@@ -602,7 +632,7 @@
|
||||
heat_resistance = 32000
|
||||
max_integrity = 300
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced, /turf/simulated/wall/indestructible/fakeglass)
|
||||
canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/polarized, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced, /turf/simulated/wall/indestructible/fakeglass)
|
||||
explosion_block = 1
|
||||
armor = list("melee" = 75, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100)
|
||||
rad_insulation = RAD_NO_INSULATION
|
||||
@@ -616,7 +646,7 @@
|
||||
shardtype = /obj/item/shard/plasma
|
||||
glass_type = /obj/item/stack/sheet/plasmarglass
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced, /turf/simulated/wall/indestructible/fakeglass)
|
||||
canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/polarized, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced, /turf/simulated/wall/indestructible/fakeglass)
|
||||
reinf = TRUE
|
||||
max_integrity = 1000
|
||||
explosion_block = 2
|
||||
@@ -632,7 +662,7 @@
|
||||
icon = 'icons/obj/smooth_structures/reinforced_window.dmi'
|
||||
icon_state = "r_window"
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced, /turf/simulated/wall/indestructible/fakeglass)
|
||||
canSmoothWith = list(/obj/structure/window/full/basic, /obj/structure/window/full/reinforced, /obj/structure/window/full/reinforced/polarized, /obj/structure/window/full/reinforced/tinted, /obj/structure/window/full/plasmabasic, /obj/structure/window/full/plasmareinforced, /turf/simulated/wall/indestructible/fakeglass)
|
||||
max_integrity = 100
|
||||
reinf = TRUE
|
||||
heat_resistance = 1600
|
||||
@@ -641,6 +671,11 @@
|
||||
explosion_block = 1
|
||||
glass_type = /obj/item/stack/sheet/rglass
|
||||
|
||||
/obj/structure/window/full/reinforced/polarized
|
||||
name = "electrochromic window"
|
||||
desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it."
|
||||
var/id
|
||||
|
||||
/obj/structure/window/full/reinforced/tinted
|
||||
name = "tinted window"
|
||||
desc = "It looks rather strong and opaque. Might take a few good hits to shatter it."
|
||||
|
||||
@@ -27,6 +27,7 @@ GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","dama
|
||||
var/list/broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5")
|
||||
var/list/burnt_states = list("floorscorched1", "floorscorched2")
|
||||
var/list/prying_tool_list = list(TOOL_CROWBAR) //What tool/s can we use to pry up the tile?
|
||||
var/keep_dir = TRUE //When false, resets dir to default on changeturf()
|
||||
|
||||
var/footstep = FOOTSTEP_FLOOR
|
||||
var/barefootstep = FOOTSTEP_HARD_BAREFOOT
|
||||
@@ -124,11 +125,18 @@ GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","dama
|
||||
|
||||
var/turf/simulated/floor/W = ..()
|
||||
|
||||
var/obj/machinery/atmospherics/R
|
||||
|
||||
if(keep_icon)
|
||||
W.icon_regular_floor = old_icon
|
||||
W.icon_plating = old_plating
|
||||
if(W.keep_dir)
|
||||
W.dir = old_dir
|
||||
|
||||
if(W.transparent_floor)
|
||||
for(R in W)
|
||||
R.update_icon()
|
||||
for(R in W)
|
||||
R.update_underlays()
|
||||
W.update_icon()
|
||||
return W
|
||||
|
||||
|
||||
@@ -70,6 +70,35 @@
|
||||
to_chat(user, "<span class='warning'>This section is too damaged to support a tile! Use a welder to fix the damage.</span>")
|
||||
return TRUE
|
||||
|
||||
else if(is_glass_sheet(C))
|
||||
if(broken || burnt)
|
||||
to_chat(user, "<span class='warning'>Repair the plating first!</span>")
|
||||
return TRUE
|
||||
var/obj/item/stack/sheet/R = C
|
||||
if(R.get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need two sheets to build a [C.name] floor!</span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You begin swapping the plating for [C]...</span>")
|
||||
if(do_after(user, 3 SECONDS * C.toolspeed, target = src))
|
||||
if(R.get_amount() >= 2 && !transparent_floor)
|
||||
if(istype(C, /obj/item/stack/sheet/plasmaglass)) //So, what type of glass floor do we want today?
|
||||
ChangeTurf(/turf/simulated/floor/transparent/glass/plasma)
|
||||
else if(istype(C, /obj/item/stack/sheet/plasmarglass))
|
||||
ChangeTurf(/turf/simulated/floor/transparent/glass/reinforced/plasma)
|
||||
else if(istype(C, /obj/item/stack/sheet/glass))
|
||||
ChangeTurf(/turf/simulated/floor/transparent/glass)
|
||||
else if(istype(C, /obj/item/stack/sheet/rglass))
|
||||
ChangeTurf(/turf/simulated/floor/transparent/glass/reinforced)
|
||||
else if(istype(C, /obj/item/stack/sheet/titaniumglass))
|
||||
ChangeTurf(/turf/simulated/floor/transparent/glass/titanium)
|
||||
else if(istype(C, /obj/item/stack/sheet/plastitaniumglass))
|
||||
ChangeTurf(/turf/simulated/floor/transparent/glass/titanium/plasma)
|
||||
playsound(src, C.usesound, 80, TRUE)
|
||||
R.use(2)
|
||||
to_chat(user, "<span class='notice'>You swap the plating for [C].</span>")
|
||||
new /obj/item/stack/sheet/metal(src, 2)
|
||||
return TRUE
|
||||
|
||||
/turf/simulated/floor/plating/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/turf/simulated/floor/transparent/glass
|
||||
name = "glass floor"
|
||||
desc = "Don't jump on it... Or do, I'm not your mom."
|
||||
icon = 'icons/turf/floors/glass.dmi'
|
||||
icon_state = "unsmooth"
|
||||
baseturf = /turf/space
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = list(/turf/simulated/floor/transparent/glass, /turf/simulated/floor/transparent/glass/reinforced, /turf/simulated/floor/transparent/glass/plasma, /turf/simulated/floor/transparent/glass/reinforced/plasma)
|
||||
footstep = FOOTSTEP_GLASS
|
||||
barefootstep = FOOTSTEP_GLASS_BAREFOOT
|
||||
clawfootstep = FOOTSTEP_GLASS_BAREFOOT
|
||||
heavyfootstep = FOOTSTEP_GLASS_BAREFOOT
|
||||
light_power = 0.25
|
||||
light_range = 2
|
||||
layer = TRANSPARENT_TURF_LAYER
|
||||
keep_dir = FALSE
|
||||
intact = FALSE
|
||||
transparent_floor = TRUE
|
||||
heat_capacity = 800
|
||||
|
||||
/turf/simulated/floor/transparent/glass/Initialize(mapload)
|
||||
. = ..()
|
||||
var/image/I = image('icons/turf/space.dmi', src, SPACE_ICON_STATE)
|
||||
I.plane = PLANE_SPACE
|
||||
underlays += I
|
||||
dir = SOUTH //dirs that are not 2/south cause smoothing jank
|
||||
icon_state = "" //Prevents default icon appearing behind the glass
|
||||
|
||||
/turf/simulated/floor/transparent/glass/welder_act(mob/user, obj/item/I)
|
||||
if(!broken && !burnt)
|
||||
return
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
if(I.use_tool(src, user, volume = I.tool_volume))
|
||||
to_chat(user, "<span class='notice'>You fix some cracks in the glass.</span>")
|
||||
overlays -= current_overlay
|
||||
current_overlay = null
|
||||
burnt = FALSE
|
||||
broken = FALSE
|
||||
update_icon()
|
||||
|
||||
/turf/simulated/floor/transparent/glass/crowbar_act(mob/user, obj/item/I)
|
||||
if(!I || !user)
|
||||
return
|
||||
var/obj/item/stack/R = user.get_inactive_hand()
|
||||
if(istype(R, /obj/item/stack/sheet/metal))
|
||||
if(R.get_amount() < 2) //not enough metal in the stack
|
||||
to_chat(user, "<span class='danger'>You also need to hold two sheets of metal to dismantle [src]!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You begin replacing [src]...</span>")
|
||||
playsound(src, I.usesound, 80, TRUE)
|
||||
if(do_after(user, 3 SECONDS * I.toolspeed, target = src))
|
||||
if(R.get_amount() < 2 || !transparent_floor)
|
||||
return
|
||||
else //not holding metal at all
|
||||
to_chat(user, "<span class='danger'>You also need to hold two sheets of metal to dismantle \the [src]!</span>")
|
||||
return
|
||||
switch(type) //What material is returned? Depends on the turf
|
||||
if(/turf/simulated/floor/transparent/glass/reinforced)
|
||||
new /obj/item/stack/sheet/rglass(src, 2)
|
||||
if(/turf/simulated/floor/transparent/glass)
|
||||
new /obj/item/stack/sheet/glass(src, 2)
|
||||
if(/turf/simulated/floor/transparent/glass/plasma)
|
||||
new /obj/item/stack/sheet/plasmaglass(src, 2)
|
||||
if(/turf/simulated/floor/transparent/glass/reinforced/plasma)
|
||||
new /obj/item/stack/sheet/plasmarglass(src, 2)
|
||||
if(/turf/simulated/floor/transparent/glass/titanium)
|
||||
new /obj/item/stack/sheet/titaniumglass(src, 2)
|
||||
if(/turf/simulated/floor/transparent/glass/titanium/plasma)
|
||||
new /obj/item/stack/sheet/plastitaniumglass(src, 2)
|
||||
R.use(2)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 80, TRUE)
|
||||
ChangeTurf(/turf/simulated/floor/plating)
|
||||
|
||||
|
||||
/turf/simulated/floor/transparent/glass/reinforced
|
||||
name = "reinforced glass floor"
|
||||
desc = "Jump on it, it can cope. Promise..."
|
||||
icon = 'icons/turf/floors/reinf_glass.dmi'
|
||||
thermal_conductivity = 0.035
|
||||
heat_capacity = 1600
|
||||
|
||||
/turf/simulated/floor/transparent/glass/reinforced/acid_act(acidpwr, acid_volume)
|
||||
acidpwr = min(acidpwr, 50)
|
||||
. = ..()
|
||||
|
||||
/turf/simulated/floor/transparent/glass/plasma
|
||||
name = "plasma glass floor"
|
||||
desc = "Wait, was space always that color?"
|
||||
icon = 'icons/turf/floors/plasmaglass.dmi'
|
||||
thermal_conductivity = 0.030
|
||||
heat_capacity = 32000
|
||||
|
||||
/turf/simulated/floor/transparent/glass/reinforced/plasma
|
||||
name = "reinforced plasma glass floor"
|
||||
desc = "For when you REALLY don't want your floor choice to suffocate everyone."
|
||||
icon = 'icons/turf/floors/reinf_plasmaglass.dmi'
|
||||
thermal_conductivity = 0.025
|
||||
heat_capacity = 325000
|
||||
|
||||
/turf/simulated/floor/transparent/glass/titanium
|
||||
name = "titanium glass floor"
|
||||
desc = "Stylish AND strong!"
|
||||
icon = 'icons/turf/floors/titaniumglass.dmi'
|
||||
canSmoothWith = list(/turf/simulated/floor/transparent/glass/titanium, /turf/simulated/floor/transparent/glass/titanium/plasma)
|
||||
thermal_conductivity = 0.025
|
||||
heat_capacity = 1600
|
||||
|
||||
/turf/simulated/floor/transparent/glass/titanium/plasma
|
||||
name = "plastitanium glass floor"
|
||||
icon = 'icons/turf/floors/plastitaniumglass.dmi'
|
||||
@@ -6,6 +6,7 @@
|
||||
var/intact = TRUE
|
||||
var/turf/baseturf = /turf/space
|
||||
var/slowdown = 0 //negative for faster, positive for slower
|
||||
var/transparent_floor = FALSE //used to check if pipes should be visible under the turf or not
|
||||
|
||||
///Properties for open tiles (/floor)
|
||||
/// All the gas vars, on the turf, are meant to be utilized for initializing a gas datum and setting its first gas values; the turf vars are never further modified at runtime; it is never directly used for calculations by the atmospherics system.
|
||||
|
||||
@@ -25,7 +25,7 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
|
||||
if(!GLOB.dooc_enabled && (mob.stat == DEAD))
|
||||
to_chat(usr, "<span class='danger'>OOC for dead mobs has been turned off.</span>")
|
||||
return
|
||||
if(prefs.muted & MUTE_OOC)
|
||||
if(check_mute(ckey, MUTE_OOC))
|
||||
to_chat(src, "<span class='danger'>You cannot use OOC (muted).</span>")
|
||||
return
|
||||
|
||||
@@ -181,7 +181,7 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
|
||||
if(!GLOB.dooc_enabled && (mob.stat == DEAD))
|
||||
to_chat(usr, "<span class='danger'>LOOC for dead mobs has been turned off.</span>")
|
||||
return
|
||||
if(prefs.muted & MUTE_OOC)
|
||||
if(check_mute(ckey, MUTE_OOC))
|
||||
to_chat(src, "<span class='danger'>You cannot use LOOC (muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -122,7 +122,6 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
|
||||
if(M.ckey)
|
||||
body += "<A href='?_src_=holder;boot2=[M.UID()]'>Kick</A> | "
|
||||
body += "<A href='?_src_=holder;warn=[M.ckey]'>Warn</A> | "
|
||||
body += "<A href='?_src_=holder;newban=[M.UID()];dbbanaddckey=[M.ckey]'>Ban</A> | "
|
||||
body += "<A href='?_src_=holder;jobban2=[M.UID()];dbbanaddckey=[M.ckey]'>Jobban</A> | "
|
||||
body += "<A href='?_src_=holder;appearanceban=[M.UID()];dbbanaddckey=[M.ckey]'>Appearance Ban</A> | "
|
||||
@@ -141,14 +140,13 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
body += "\ <A href='?_src_=holder;sendbacktolobby=[M.UID()]'>Send back to Lobby</A> | "
|
||||
body += "\ <A href='?_src_=holder;eraseflavortext=[M.UID()]'>Erase Flavor Text</A> | "
|
||||
body += "\ <A href='?_src_=holder;userandomname=[M.UID()]'>Use Random Name</A> | "
|
||||
var/muted = M.client.prefs.muted
|
||||
body += {"<br><b>Mute: </b>
|
||||
\[<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_IC]'><font color='[(muted & MUTE_IC)?"red":"#6685f5"]'>IC</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_OOC]'><font color='[(muted & MUTE_OOC)?"red":"#6685f5"]'>OOC</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_PRAY]'><font color='[(muted & MUTE_PRAY)?"red":"#6685f5"]'>PRAY</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ADMINHELP]'><font color='[(muted & MUTE_ADMINHELP)?"red":"#6685f5"]'>ADMINHELP</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_DEADCHAT]'><font color='[(muted & MUTE_DEADCHAT)?"red":"#6685f5"]'>DEADCHAT</font></a>\]
|
||||
(<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ALL]'><font color='[(muted & MUTE_ALL)?"red":"#6685f5"]'>toggle all</font></a>)
|
||||
\[<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_IC]'><font color='[check_mute(M.client.ckey, MUTE_IC) ? "red" : "#6685f5"]'>IC</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_OOC]'><font color='[check_mute(M.client.ckey, MUTE_OOC) ? "red" : "#6685f5"]'>OOC</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_PRAY]'><font color='[check_mute(M.client.ckey, MUTE_PRAY) ? "red" : "#6685f5"]'>PRAY</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ADMINHELP]'><font color='[check_mute(M.client.ckey, MUTE_ADMINHELP) ? "red" : "#6685f5"]'>ADMINHELP</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_DEADCHAT]'><font color='[check_mute(M.client.ckey, MUTE_DEADCHAT) ?" red" : "#6685f5"]'>DEADCHAT</font></a>]
|
||||
(<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ALL]'><font color='[check_mute(M.client.ckey, MUTE_ALL) ? "red" : "#6685f5"]'>toggle all</font></a>)
|
||||
"}
|
||||
|
||||
var/jumptoeye = ""
|
||||
|
||||
@@ -492,51 +492,6 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list(
|
||||
log_admin("[key_name(usr)] has turned BB mode [holder.fakekey ? "ON" : "OFF"]")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Big Brother Mode")
|
||||
|
||||
#define MAX_WARNS 3
|
||||
#define AUTOBANTIME 10
|
||||
|
||||
/client/proc/warn(warned_ckey)
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(!warned_ckey || !istext(warned_ckey)) return
|
||||
if(warned_ckey in GLOB.admin_datums)
|
||||
to_chat(usr, "<font color='red'>Error: warn(): You can't warn admins.</font>")
|
||||
return
|
||||
|
||||
var/datum/preferences/D
|
||||
var/client/C = GLOB.directory[warned_ckey]
|
||||
if(C) D = C.prefs
|
||||
else D = GLOB.preferences_datums[warned_ckey]
|
||||
|
||||
if(!D)
|
||||
to_chat(src, "<font color='red'>Error: warn(): No such ckey found.</font>")
|
||||
return
|
||||
|
||||
if(++D.warns >= MAX_WARNS) //uh ohhhh...you'reee iiiiin trouuuubble O:)
|
||||
if(C)
|
||||
message_admins("[key_name_admin(src)] has warned [key_name_admin(C)] resulting in a [AUTOBANTIME] minute ban")
|
||||
log_admin("[key_name(src)] has warned [key_name(C)] resulting in a [AUTOBANTIME] minute ban")
|
||||
to_chat(C, "<font color='red'><BIG><B>You have been autobanned due to a warning by [ckey].</B></BIG><br>This is a temporary ban, it will be removed in [AUTOBANTIME] minutes.")
|
||||
qdel(C)
|
||||
else
|
||||
message_admins("[key_name_admin(src)] has warned [warned_ckey] resulting in a [AUTOBANTIME] minute ban")
|
||||
log_admin("[key_name(src)] has warned [warned_ckey] resulting in a [AUTOBANTIME] minute ban")
|
||||
AddBan(warned_ckey, D.last_id, "Autobanning due to too many formal warnings", ckey, 1, AUTOBANTIME)
|
||||
else
|
||||
if(C)
|
||||
to_chat(C, "<font color='red'><BIG><B>You have been formally warned by an administrator.</B></BIG><br>Further warnings will result in an autoban.</font>")
|
||||
message_admins("[key_name_admin(src)] has warned [key_name_admin(C)]. They have [MAX_WARNS-D.warns] strikes remaining.")
|
||||
log_admin("[key_name(src)] has warned [key_name(C)]. They have [MAX_WARNS-D.warns] strikes remaining.")
|
||||
else
|
||||
message_admins("[key_name_admin(src)] has warned [warned_ckey] (DC). They have [MAX_WARNS-D.warns] strikes remaining.")
|
||||
log_admin("[key_name(src)] has warned [warned_ckey] (DC). They have [MAX_WARNS-D.warns] strikes remaining.")
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Warning") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
#undef MAX_WARNS
|
||||
#undef AUTOBANTIME
|
||||
|
||||
/client/proc/drop_bomb() // Some admin dickery that can probably be done better -- TLE
|
||||
set category = "Event"
|
||||
set name = "Drop Bomb"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/// Associative list of people who are muted via admin mutes
|
||||
GLOBAL_LIST_EMPTY(admin_mutes_assoc)
|
||||
|
||||
/proc/check_mute(ckey, muteflag)
|
||||
if(isnull(GLOB.admin_mutes_assoc[ckey]))
|
||||
return FALSE
|
||||
|
||||
if(GLOB.admin_mutes_assoc[ckey] & muteflag)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/proc/toggle_mute(ckey, muteflag)
|
||||
if(isnull(GLOB.admin_mutes_assoc[ckey]))
|
||||
GLOB.admin_mutes_assoc[ckey] = 0
|
||||
|
||||
if(GLOB.admin_mutes_assoc[ckey] & muteflag)
|
||||
GLOB.admin_mutes_assoc[ckey] &= ~muteflag
|
||||
else
|
||||
GLOB.admin_mutes_assoc[ckey] |= muteflag
|
||||
|
||||
/proc/force_add_mute(ckey, muteflag)
|
||||
if(isnull(GLOB.admin_mutes_assoc[ckey]))
|
||||
GLOB.admin_mutes_assoc[ckey] = 0
|
||||
|
||||
GLOB.admin_mutes_assoc[ckey] |= muteflag
|
||||
|
||||
/proc/force_remove_mute(ckey, muteflag)
|
||||
if(isnull(GLOB.admin_mutes_assoc[ckey]))
|
||||
GLOB.admin_mutes_assoc[ckey] = 0
|
||||
|
||||
GLOB.admin_mutes_assoc[ckey] &= ~muteflag
|
||||
|
||||
@@ -446,9 +446,6 @@
|
||||
alert(usr, "This ban has already been lifted / does not exist.", "Error", "Ok")
|
||||
unbanpanel()
|
||||
|
||||
else if(href_list["warn"])
|
||||
usr.client.warn(href_list["warn"])
|
||||
|
||||
else if(href_list["unbane"])
|
||||
if(!check_rights(R_BAN)) return
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown", "the", "a", "an", "of"
|
||||
set name = "Adminhelp"
|
||||
|
||||
//handle muting and automuting
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
if(check_mute(ckey, MUTE_ADMINHELP))
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: You cannot send adminhelps (Muted).</font>")
|
||||
return
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM.
|
||||
//Fetching a message if needed. src is the sender and C is the target client
|
||||
/client/proc/cmd_admin_pm(whom, msg, type = "PM")
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
if(check_mute(ckey, MUTE_ADMINHELP))
|
||||
to_chat(src, "<span class='danger'>Error: Private-Message: You are unable to use PM-s (muted).</span>")
|
||||
return
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
return
|
||||
|
||||
/client/proc/cmd_admin_discord_pm()
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
if(check_mute(ckey, MUTE_ADMINHELP))
|
||||
to_chat(src, "<span class='danger'>Error: Private-Message: You are unable to use PMs (muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
|
||||
log_mentorsay(msg, src)
|
||||
mob.create_log(OOC_LOG, "MSAY: [msg]")
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
if(!src.mob)
|
||||
return
|
||||
|
||||
if(prefs.muted & MUTE_DEADCHAT)
|
||||
if(check_mute(ckey, MUTE_DEADCHAT))
|
||||
to_chat(src, "<span class='warning'>You cannot send DSAY messages (muted).</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
#define NUKE_INTACT 0
|
||||
#define NUKE_CORE_MISSING 1
|
||||
#define NUKE_MISSING 2
|
||||
|
||||
/mob/living/verb/pray(msg as text)
|
||||
set category = "IC"
|
||||
set name = "Pray"
|
||||
@@ -7,7 +11,7 @@
|
||||
return
|
||||
|
||||
if(usr.client)
|
||||
if(usr.client.prefs.muted & MUTE_PRAY)
|
||||
if(check_mute(client.ckey, MUTE_PRAY))
|
||||
to_chat(usr, "<span class='warning'>You cannot pray (muted).</span>")
|
||||
return
|
||||
if(client.handle_spam_prevention(msg, MUTE_PRAY, OOC_COOLDOWN))
|
||||
@@ -72,11 +76,21 @@
|
||||
|
||||
/proc/Nuke_request(text , mob/Sender)
|
||||
var/nuke_code = get_nuke_code()
|
||||
var/nuke_status = get_nuke_status()
|
||||
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
|
||||
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST: </font>[key_name(Sender)] ([ADMIN_PP(Sender,"PP")]) ([ADMIN_VV(Sender,"VV")]) ([ADMIN_TP(Sender,"TP")]) ([ADMIN_SM(Sender,"SM")]) ([admin_jump_link(Sender)]) ([ADMIN_BSA(Sender,"BSA")]) ([ADMIN_CENTCOM_REPLY(Sender,"RPLY")]):</b> [msg]</span>"
|
||||
for(var/client/X in GLOB.admins)
|
||||
if(check_rights(R_EVENT,0,X.mob))
|
||||
to_chat(X, msg)
|
||||
to_chat(X, "<span class='adminnotice'><b>The nuke code is [nuke_code].</b></span>")
|
||||
if(nuke_status == NUKE_MISSING)
|
||||
to_chat(X, "<span class='userdanger'>The nuclear device is not on station!</span>")
|
||||
else
|
||||
to_chat(X, "<b>The nuke code is [nuke_code].</b>")
|
||||
if(nuke_status == NUKE_CORE_MISSING)
|
||||
to_chat(X, "<span class='userdanger'>The nuclear device does not have a core, and will not arm!</span>")
|
||||
if(X.prefs.sound & SOUND_ADMINHELP)
|
||||
SEND_SOUND(X, sound('sound/effects/adminhelp.ogg'))
|
||||
|
||||
#undef NUKE_INTACT
|
||||
#undef NUKE_CORE_MISSING
|
||||
#undef NUKE_MISSING
|
||||
|
||||
@@ -230,19 +230,19 @@
|
||||
|
||||
if(automute)
|
||||
muteunmute = "auto-muted"
|
||||
M.client.prefs.muted |= mute_type
|
||||
force_add_mute(M.client.ckey, mute_type)
|
||||
log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(M)] from [mute_string]")
|
||||
message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(M)] from [mute_string].", 1)
|
||||
to_chat(M, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Automute") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
if(M.client.prefs.muted & mute_type)
|
||||
muteunmute = "unmuted"
|
||||
M.client.prefs.muted &= ~mute_type
|
||||
else
|
||||
toggle_mute(M.client.ckey, mute_type)
|
||||
|
||||
if(check_mute(M.client.ckey, mute_type))
|
||||
muteunmute = "muted"
|
||||
M.client.prefs.muted |= mute_type
|
||||
else
|
||||
muteunmute = "unmuted"
|
||||
|
||||
log_admin("[key_name(usr)] has [muteunmute] [key_name(M)] from [mute_string]")
|
||||
message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(M)] from [mute_string].", 1)
|
||||
@@ -606,7 +606,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
"Custom" = "Cryptic Message")
|
||||
|
||||
var/list/MsgSound = list("Beep" = 'sound/misc/notice2.ogg',
|
||||
"Enemy Communications Intercepted" = 'sound/AI/intercept2.ogg',
|
||||
"Enemy Communications Intercepted" = 'sound/AI/intercept.ogg',
|
||||
"New Command Report Created" = 'sound/AI/commandreport.ogg')
|
||||
|
||||
var/type = input(usr, "Pick a type of report to send", "Report Type", "") as anything in MsgType
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
H.dna.SetSEState(GLOB.hulkblock, TRUE)
|
||||
singlemutcheck(H, GLOB.hulkblock, MUTCHK_FORCED)
|
||||
|
||||
H.dna.SetSEState(GLOB.xrayblock, TRUE)
|
||||
singlemutcheck(H, GLOB.xrayblock, MUTCHK_FORCED)
|
||||
|
||||
H.dna.SetSEState(GLOB.fireblock, TRUE)
|
||||
singlemutcheck(H, GLOB.fireblock, MUTCHK_FORCED)
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/obj/effect/nanomob
|
||||
name = "Nano-Mob Avatar" //will be overridden by the mob datum name value when created
|
||||
desc = "A wild Nano-Mob appeared! Hit it with your PDA with the game open to attempt to capture it!"
|
||||
@@ -12,17 +11,29 @@
|
||||
var/list/clients_encountered = list() //tracks who has already interacted with us, so they can't attempt a second capture
|
||||
var/image/avatar
|
||||
|
||||
/obj/effect/nanomob/New(loc, datum/mob_hunt/new_info)
|
||||
..()
|
||||
/obj/effect/nanomob/Initialize(mapload, datum/mob_hunt/new_info)
|
||||
. = ..()
|
||||
if(!new_info)
|
||||
qdel(src)
|
||||
return
|
||||
return INITIALIZE_HINT_QDEL
|
||||
mob_info = new_info
|
||||
RegisterSignal(mob_info, COMSIG_PARENT_QDELETING, .proc/delete_wrapper)
|
||||
update_self()
|
||||
forceMove(mob_info.spawn_point)
|
||||
if(!mob_info.is_trap)
|
||||
addtimer(CALLBACK(src, .proc/despawn), mob_info.lifetime)
|
||||
|
||||
/obj/effect/nanomob/Destroy()
|
||||
SSmob_hunt.trap_spawns -= src
|
||||
SSmob_hunt.normal_spawns -= src
|
||||
mob_info = null // Can't delete this since multiple players can get the exact same /datum/mob_hunt. (This should be refactored)
|
||||
clients_encountered.Cut()
|
||||
QDEL_NULL(avatar)
|
||||
return ..()
|
||||
|
||||
/obj/effect/nanomob/proc/delete_wrapper()
|
||||
SIGNAL_HANDLER
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/nanomob/proc/update_self()
|
||||
if(!mob_info)
|
||||
return
|
||||
@@ -132,12 +143,6 @@
|
||||
icon_state = "placeholder"
|
||||
var/obj/machinery/computer/mob_battle_terminal/my_terminal
|
||||
|
||||
/obj/effect/nanomob/battle/New(loc, datum/mob_hunt/new_info)
|
||||
. = ..()
|
||||
if(new_info)
|
||||
mob_info = new_info
|
||||
update_self()
|
||||
|
||||
/obj/effect/nanomob/battle/update_self()
|
||||
if(!mob_info)
|
||||
name = "Nano-Mob Battle Avatar"
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
var/life_cycles = 0
|
||||
var/life_cap = 20
|
||||
anchored = TRUE
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSFENCE
|
||||
|
||||
|
||||
/obj/effect/beam/i_beam/proc/hit()
|
||||
|
||||
@@ -71,10 +71,13 @@ Pipelines + Other Objects -> Pipe network
|
||||
// Icons/overlays/underlays
|
||||
/obj/machinery/atmospherics/update_icon()
|
||||
var/turf/T = get_turf(loc)
|
||||
if(!T || level == 2 || !T.intact)
|
||||
plane = GAME_PLANE
|
||||
else
|
||||
if(T && T.transparent_floor)
|
||||
plane = FLOOR_PLANE
|
||||
else
|
||||
if(!T || level == 2 || !T.intact)
|
||||
plane = GAME_PLANE
|
||||
else
|
||||
plane = FLOOR_PLANE
|
||||
|
||||
/obj/machinery/atmospherics/proc/update_pipe_image()
|
||||
pipe_image = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) //the 20 puts it above Byond's darkness (not its opacity view)
|
||||
@@ -95,15 +98,18 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
/obj/machinery/atmospherics/proc/add_underlay(turf/T, obj/machinery/atmospherics/node, direction, icon_connect_type)
|
||||
if(node)
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe) && !T.transparent_floor)
|
||||
//underlays += SSair.icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node))
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
|
||||
else
|
||||
//underlays += SSair.icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node))
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
//underlays += SSair.icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color)
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type)
|
||||
if(T.transparent_floor) //we want to keep pipes under transparent floors connected normally
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
//underlays += SSair.icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color)
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type)
|
||||
|
||||
/obj/machinery/atmospherics/proc/update_underlays()
|
||||
if(check_icon_cache())
|
||||
@@ -166,11 +172,14 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
//(De)construction
|
||||
/obj/machinery/atmospherics/attackby(obj/item/W, mob/user)
|
||||
var/turf/T = get_turf(src)
|
||||
if(can_unwrench && istype(W, /obj/item/wrench))
|
||||
var/turf/T = get_turf(src)
|
||||
if(T.transparent_floor && istype(src, /obj/machinery/atmospherics/pipe) && layer != GAS_PIPE_VISIBLE_LAYER) //pipes on GAS_PIPE_VISIBLE_LAYER are above the transparent floor and should be interactable
|
||||
to_chat(user, "<span class='danger'>You can't interact with something that's under the floor!</span>")
|
||||
return
|
||||
if(level == 1 && isturf(T) && T.intact)
|
||||
to_chat(user, "<span class='danger'>You must remove the plating first.</span>")
|
||||
return 1
|
||||
return
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
add_fingerprint(user)
|
||||
@@ -184,14 +193,14 @@ Pipelines + Other Objects -> Pipe network
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if(internal_pressure > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?</span>")
|
||||
to_chat(user, "<span class='warning'>As you begin unwrenching \the [src] a gust of air blows in your face... maybe you should reconsider?</span>")
|
||||
unsafe_wrenching = TRUE //Oh dear oh dear
|
||||
|
||||
if(do_after(user, 40 * W.toolspeed, target = src) && !QDELETED(src))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"<span class='italics'>You hear ratchet.</span>")
|
||||
"<span class='italics'>You hear ratcheting.</span>")
|
||||
investigate_log("was <span class='warning'>REMOVED</span> by [key_name(usr)]", "atmos")
|
||||
|
||||
for(var/obj/item/clothing/shoes/magboots/usermagboots in user.get_equipped_items())
|
||||
@@ -206,6 +215,9 @@ Pipelines + Other Objects -> Pipe network
|
||||
unsafe_pressure_release(user,internal_pressure)
|
||||
deconstruct(TRUE)
|
||||
else
|
||||
if(T.transparent_floor)
|
||||
to_chat(user, "<span class='danger'>You can't interact with something that's under the floor!</span>")
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
//Called when an atmospherics object is unwrenched while having a large pressure difference
|
||||
@@ -240,7 +252,12 @@ Pipelines + Other Objects -> Pipe network
|
||||
dir = D
|
||||
initialize_directions = P
|
||||
var/turf/T = loc
|
||||
level = T.intact ? 2 : 1
|
||||
if(!T.transparent_floor)
|
||||
level = T.intact ? 2 : 1
|
||||
else
|
||||
level = 2
|
||||
plane = GAME_PLANE
|
||||
layer = GAS_PIPE_VISIBLE_LAYER
|
||||
add_fingerprint(usr)
|
||||
if(!SSair.initialized) //If there's no atmos subsystem, we can't really initialize pipenets
|
||||
SSair.machinery_to_construct.Add(src)
|
||||
@@ -337,12 +354,15 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
/obj/machinery/atmospherics/proc/add_underlay_adapter(turf/T, obj/machinery/atmospherics/node, direction, icon_connect_type) //modified from add_underlay, does not make exposed underlays
|
||||
if(node)
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe) && !T.transparent_floor)
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
|
||||
else
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type)
|
||||
if(T.transparent_floor) //we want to keep pipes under transparent floors connected normally
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
underlays += SSair.icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type)
|
||||
|
||||
/obj/machinery/atmospherics/singularity_pull(S, current_size)
|
||||
if(current_size >= STAGE_FIVE)
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
if(!istype(L) || L.buckled)
|
||||
return
|
||||
if(L.abiotic())
|
||||
to_chat(user, "<span class='danger'>Subject cannot have abiotic items on.</span>")
|
||||
to_chat(user, "<span class='danger'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(L.has_buckled_mobs()) //mob attached to us
|
||||
to_chat(user, "<span class='warning'>[L] will not fit into [src] because [L.p_they()] [L.p_have()] a slime latched onto [L.p_their()] head.</span>")
|
||||
@@ -462,7 +462,7 @@
|
||||
to_chat(usr, "<span class='danger'>The cryo cell is already occupied!</span>")
|
||||
return
|
||||
if(M.abiotic())
|
||||
to_chat(usr, "<span class='warning'>Subject may not have abiotic items on.</span>")
|
||||
to_chat(usr, "<span class='warning'>Subject may not hold anything in their hands.</span>")
|
||||
return
|
||||
if(!node)
|
||||
to_chat(usr, "<span class='warning'>The cell is not correctly connected to its pipe network!</span>")
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
icon = 'icons/atmos/vent_pump.dmi'
|
||||
icon_state = "map_vent"
|
||||
plane = FLOOR_PLANE
|
||||
layer = GAS_SCRUBBER_LAYER
|
||||
name = "passive vent"
|
||||
desc = "A large air vent"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/machinery/atmospherics/unary/tank
|
||||
icon = 'icons/atmos/tank.dmi'
|
||||
icon_state = "air_map"
|
||||
|
||||
layer = GAS_PIPE_VISIBLE_LAYER
|
||||
name = "pressure tank"
|
||||
desc = "A large vessel containing pressurized gas."
|
||||
|
||||
|
||||
@@ -159,9 +159,9 @@
|
||||
var/cache_name = state
|
||||
|
||||
for(var/D in GLOB.cardinal)
|
||||
var/image/I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D))
|
||||
var/image/I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D), layer = GAS_PIPE_HIDDEN_LAYER)
|
||||
underlays[cache_name + "[D]"] = I
|
||||
for(var/pipe_color in GLOB.pipe_colors)
|
||||
I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D))
|
||||
I = image(icon('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D), layer = GAS_PIPE_HIDDEN_LAYER)
|
||||
I.color = GLOB.pipe_colors[pipe_color]
|
||||
underlays[state + "[D]" + "[GLOB.pipe_colors[pipe_color]]"] = I
|
||||
|
||||
@@ -79,7 +79,8 @@
|
||||
break
|
||||
|
||||
var/turf/T = get_turf(src) // hide if turf is not intact
|
||||
if(!istype(T)) return
|
||||
if(!istype(T) || T.transparent_floor)
|
||||
return
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
node3 = target
|
||||
break
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(T.transparent_floor)
|
||||
return
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -165,7 +165,8 @@
|
||||
break
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(!T.transparent_floor)
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible
|
||||
|
||||
@@ -46,10 +46,6 @@
|
||||
if(istype(W, /obj/item/analyzer))
|
||||
atmosanalyzer_scan(parent.air, user)
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/painter))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/proc/pipeline_expansion()
|
||||
|
||||
@@ -68,7 +68,8 @@
|
||||
break
|
||||
|
||||
var/turf/T = loc // hide if turf is not intact
|
||||
hide(T.intact)
|
||||
if(!T.transparent_floor)
|
||||
hide(T.intact)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/check_pressure(pressure)
|
||||
|
||||
@@ -79,8 +79,6 @@
|
||||
ADD_TRAIT(user, TRAIT_LASEREYES, "ww_wishgranter")
|
||||
user.dna.SetSEState(GLOB.fireblock, TRUE)
|
||||
singlemutcheck(user, GLOB.fireblock, MUTCHK_FORCED)
|
||||
user.dna.SetSEState(GLOB.xrayblock, TRUE)
|
||||
singlemutcheck(user, GLOB.xrayblock, MUTCHK_FORCED)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human = user
|
||||
if(!isshadowperson(human))
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#define UPLOAD_LIMIT 10485760 //Restricts client uploads to the server to 10MB //Boosted this thing. What's the worst that can happen?
|
||||
#define MIN_CLIENT_VERSION 513 // Minimum byond major version required to play.
|
||||
//I would just like the code ready should it ever need to be used.
|
||||
#define SUGGESTED_CLIENT_VERSION 513 // only integers (e.g: 513, 514) are useful here. This is the part BEFORE the ".", IE 513 out of 513.1542
|
||||
#define SUGGESTED_CLIENT_BUILD 1542 // only integers (e.g: 1542, 1543) are useful here. This is the part AFTER the ".", IE 1542 out of 513.1542
|
||||
#define SUGGESTED_CLIENT_VERSION 514 // only integers (e.g: 513, 514) are useful here. This is the part BEFORE the ".", IE 513 out of 513.1542
|
||||
#define SUGGESTED_CLIENT_BUILD 1566 // only integers (e.g: 1542, 1543) are useful here. This is the part AFTER the ".", IE 1542 out of 513.1542
|
||||
|
||||
#define SSD_WARNING_TIMER 30 // cycles, not seconds, so 30=60s
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
if(!holder && received_discord_pm < world.time - 6000) // Worse they can do is spam discord for 10 minutes
|
||||
to_chat(usr, "<span class='warning'>You are no longer able to use this, it's been more then 10 minutes since an admin on Discord has responded to you</span>")
|
||||
return
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
if(check_mute(ckey, MUTE_ADMINHELP))
|
||||
to_chat(usr, "<span class='warning'>You cannot use this as your client has been muted from sending messages to the admins on Discord</span>")
|
||||
return
|
||||
cmd_admin_discord_pm()
|
||||
|
||||
@@ -71,8 +71,6 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
var/max_gear_slots = 0
|
||||
|
||||
//non-preference stuff
|
||||
var/warns = 0
|
||||
var/muted = 0
|
||||
var/last_ip
|
||||
var/last_id
|
||||
|
||||
|
||||
@@ -356,3 +356,11 @@
|
||||
prefs.toggles2 ^= PREFTOGGLE_2_SIMPLE_STAT_PANEL
|
||||
prefs.save_preferences(src)
|
||||
to_chat(src, "You will [(prefs.toggles2 & PREFTOGGLE_2_SIMPLE_STAT_PANEL) ? "no longer" : "now"] get detailed information on the status panel.")
|
||||
|
||||
/client/verb/toggle_item_outlines()
|
||||
set name = "Toggle Item Outlines"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles seeing item outlines on hover."
|
||||
prefs.toggles2 ^= PREFTOGGLE_2_SEE_ITEM_OUTLINES
|
||||
prefs.save_preferences(src)
|
||||
to_chat(usr, "You will [(prefs.toggles2 & PREFTOGGLE_2_SEE_ITEM_OUTLINES) ? "now" : "no longer"] see item outlines on hover.")
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
|
||||
/datum/event/anomaly/proc/findEventArea()
|
||||
var/static/list/allowed_areas
|
||||
var/static/list/existing_areas
|
||||
if(!existing_areas)
|
||||
existing_areas = list()
|
||||
for(var/area/AR in world)
|
||||
var/turf/picked = safepick(get_area_turfs(AR.type))
|
||||
if(picked && is_station_level(picked.z))
|
||||
existing_areas += AR
|
||||
if(!allowed_areas)
|
||||
//Places that shouldn't explode
|
||||
var/list/safe_area_types = typecacheof(list(
|
||||
@@ -20,10 +27,16 @@
|
||||
)
|
||||
|
||||
//Subtypes from the above that actually should explode.
|
||||
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
|
||||
var/list/unsafe_area_subtypes = typecacheof(list(
|
||||
/area/engine/break_room,
|
||||
/area/engine/equipmentstorage,
|
||||
/area/engine/chiefs_office,
|
||||
/area/engine/controlroom,
|
||||
/area/engine/mechanic_workshop
|
||||
))
|
||||
|
||||
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.all_areas, allowed_areas)
|
||||
allowed_areas = typecacheof(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
var/list/possible_areas = typecache_filter_list(existing_areas, allowed_areas)
|
||||
if(length(possible_areas))
|
||||
return pick(possible_areas)
|
||||
|
||||
@@ -36,7 +49,7 @@
|
||||
CRASH("Anomaly: No valid turfs found for [impact_area] - [impact_area.type]")
|
||||
|
||||
/datum/event/anomaly/announce()
|
||||
GLOB.event_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
|
||||
GLOB.event_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert", 'sound/AI/anomaly_flux.ogg')
|
||||
|
||||
/datum/event/anomaly/start()
|
||||
var/turf/T = pick(get_area_turfs(impact_area))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user