mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-30 15:37:36 +01:00
Merge branch 'master' into client-data-loading
This commit is contained in:
+3010
-4624
File diff suppressed because it is too large
Load Diff
+3728
-4494
File diff suppressed because it is too large
Load Diff
@@ -1620,6 +1620,7 @@
|
||||
/obj/structure/sign/securearea{
|
||||
pixel_x = -32
|
||||
},
|
||||
/obj/machinery/suit_storage_unit/gamma,
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/gamma/space)
|
||||
"fW" = (
|
||||
@@ -3547,6 +3548,12 @@
|
||||
/obj/structure/flora/ausbushes/sparsegrass,
|
||||
/turf/simulated/floor/grass,
|
||||
/area/centcom/control)
|
||||
"nb" = (
|
||||
/obj/machinery/autolathe/upgraded/gamma,
|
||||
/obj/item/stack/sheet/glass/fifty,
|
||||
/obj/item/stack/sheet/metal/fifty,
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/gamma/space)
|
||||
"nc" = (
|
||||
/obj/machinery/door/airlock/centcom{
|
||||
name = "Gamma Armory";
|
||||
@@ -4076,18 +4083,12 @@
|
||||
/area/centcom/gamma)
|
||||
"oJ" = (
|
||||
/obj/structure/closet/secure_closet/guncabinet,
|
||||
/obj/item/ammo_box/magazine/m10mm,
|
||||
/obj/item/ammo_box/magazine/m10mm,
|
||||
/obj/item/ammo_box/magazine/m10mm,
|
||||
/obj/item/gun/projectile/automatic/pistol{
|
||||
name = "pistol"
|
||||
},
|
||||
/obj/item/gun/projectile/automatic/pistol{
|
||||
name = "pistol"
|
||||
},
|
||||
/obj/item/gun/projectile/automatic/pistol{
|
||||
name = "pistol"
|
||||
},
|
||||
/obj/item/ammo_box/magazine/smgm9mm,
|
||||
/obj/item/ammo_box/magazine/smgm9mm,
|
||||
/obj/item/ammo_box/magazine/smgm9mm,
|
||||
/obj/item/gun/projectile/automatic/proto,
|
||||
/obj/item/gun/projectile/automatic/proto,
|
||||
/obj/item/gun/projectile/automatic/proto,
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/gamma/space)
|
||||
"oN" = (
|
||||
@@ -4258,14 +4259,6 @@
|
||||
/obj/structure/flora/ausbushes,
|
||||
/turf/simulated/floor/grass,
|
||||
/area/centcom/specops)
|
||||
"pk" = (
|
||||
/obj/structure/closet/secure_closet/guncabinet,
|
||||
/obj/item/ammo_casing/rocket,
|
||||
/obj/item/ammo_casing/rocket,
|
||||
/obj/item/ammo_casing/rocket,
|
||||
/obj/item/gun/rocketlauncher,
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/gamma/space)
|
||||
"pl" = (
|
||||
/obj/structure/window/reinforced{
|
||||
dir = 1
|
||||
@@ -4317,9 +4310,7 @@
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/gamma/space)
|
||||
"pu" = (
|
||||
/obj/mecha/combat/durand/loaded{
|
||||
operation_req_access = list(1)
|
||||
},
|
||||
/obj/mecha/combat/marauder/ares/loaded,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -4527,6 +4518,11 @@
|
||||
},
|
||||
/turf/simulated/floor/plasteel/dark,
|
||||
/area/centcom/specops)
|
||||
"qf" = (
|
||||
/obj/structure/closet/secure_closet/guncabinet,
|
||||
/obj/item/gun/medbeam,
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/gamma/space)
|
||||
"qh" = (
|
||||
/obj/structure/holowindow,
|
||||
/turf/simulated/floor/holofloor{
|
||||
@@ -9964,6 +9960,12 @@
|
||||
icon_state = "red"
|
||||
},
|
||||
/area/holodeck/source_knightarena)
|
||||
"LN" = (
|
||||
/obj/machinery/recharger/wallcharger{
|
||||
pixel_x = -24
|
||||
},
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/gamma/space)
|
||||
"LO" = (
|
||||
/obj/machinery/autolathe/upgraded{
|
||||
hacked = 1
|
||||
@@ -25459,8 +25461,8 @@ th
|
||||
fm
|
||||
of
|
||||
oB
|
||||
pf
|
||||
pf
|
||||
LN
|
||||
nb
|
||||
pf
|
||||
fV
|
||||
of
|
||||
@@ -25717,7 +25719,7 @@ fm
|
||||
of
|
||||
oJ
|
||||
pf
|
||||
pk
|
||||
po
|
||||
pf
|
||||
pq
|
||||
of
|
||||
@@ -25974,7 +25976,7 @@ fm
|
||||
of
|
||||
oW
|
||||
pf
|
||||
po
|
||||
qf
|
||||
pf
|
||||
pu
|
||||
of
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
/datum/controller/subsystem/##X/New(){\
|
||||
NEW_SS_GLOBAL(SS##X);\
|
||||
PreInit();\
|
||||
ss_id=#X;\
|
||||
}\
|
||||
/datum/controller/subsystem/##X
|
||||
|
||||
@@ -73,5 +74,6 @@
|
||||
/datum/controller/subsystem/processing/##X/New(){\
|
||||
NEW_SS_GLOBAL(SS##X);\
|
||||
PreInit();\
|
||||
ss_id="processing_[#X]";\
|
||||
}\
|
||||
/datum/controller/subsystem/processing/##X
|
||||
|
||||
@@ -118,5 +118,8 @@
|
||||
#define SPLASHSCREEN_LAYER 23
|
||||
#define SPLASHSCREEN_PLANE 23
|
||||
|
||||
// This should always be on top.
|
||||
#define HUD_PLANE_BUILDMODE 30
|
||||
|
||||
///Plane master controller keys
|
||||
#define PLANE_MASTERS_GAME "plane_masters_game"
|
||||
|
||||
@@ -130,6 +130,8 @@
|
||||
#define SOUTH_OF_TURF(T) locate(T.x, T.y - 1, T.z)
|
||||
#define WEST_OF_TURF(T) locate(T.x - 1, T.y, T.z)
|
||||
|
||||
#define ATOM_COORDS(A) list(A.x, A.y, A.z)
|
||||
|
||||
#define MIN_SUPPLIED_LAW_NUMBER 15
|
||||
#define MAX_SUPPLIED_LAW_NUMBER 50
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
#define INIT_ORDER_PROFILER 101
|
||||
#define INIT_ORDER_TITLE 100 // Load this quickly so people dont see a blank lobby screen
|
||||
#define INIT_ORDER_QUEUE 100 // Load this quickly so people cant queue skip
|
||||
#define INIT_ORDER_TITLE 99 // Load this quickly so people dont see a blank lobby screen
|
||||
#define INIT_ORDER_GARBAGE 21
|
||||
#define INIT_ORDER_DBCORE 20
|
||||
#define INIT_ORDER_BLACKBOX 19
|
||||
|
||||
@@ -203,5 +203,6 @@ GLOBAL_VAR_INIT(midnight_rollovers, 0)
|
||||
GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0)
|
||||
/proc/update_midnight_rollover()
|
||||
if(world.timeofday < GLOB.rollovercheck_last_timeofday) //TIME IS GOING BACKWARDS!
|
||||
return GLOB.midnight_rollovers++
|
||||
GLOB.midnight_rollovers++
|
||||
GLOB.rollovercheck_last_timeofday = world.timeofday
|
||||
return GLOB.midnight_rollovers
|
||||
|
||||
@@ -43,9 +43,9 @@
|
||||
return num
|
||||
|
||||
//Returns the hex value of a number given a value assumed to be a base-ten value
|
||||
/proc/num2hex(num, placeholder)
|
||||
if(!isnum(num)) return
|
||||
if(placeholder == null) placeholder = 2
|
||||
/proc/num2hex(num, placeholder = 2)
|
||||
if(!isnum(num) || num < 0)
|
||||
return
|
||||
|
||||
var/hex = ""
|
||||
while(num)
|
||||
|
||||
@@ -50,8 +50,6 @@ GLOBAL_VAR_INIT(copier_items_printed_logged, FALSE)
|
||||
|
||||
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) // Station datacore, manifest, etc
|
||||
|
||||
GLOBAL_VAR_INIT(panic_bunker_enabled, FALSE) // Is the panic bunker enabled
|
||||
|
||||
GLOBAL_LIST_EMPTY(ability_verbs) // Create-level abilities
|
||||
GLOBAL_LIST_INIT(pipe_colors, list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE))
|
||||
|
||||
|
||||
@@ -176,8 +176,3 @@
|
||||
//1 = standard hud
|
||||
//2 = reduced hud (just hands and intent switcher)
|
||||
//3 = no hud (for screenshots)
|
||||
|
||||
|
||||
#define HUD_LAYER_SCREEN 20
|
||||
|
||||
#define HUD_LAYER_BUILDMODE 30
|
||||
|
||||
@@ -32,7 +32,9 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
var/datum/configuration_section/logging_configuration/logging
|
||||
/// Holder for the MC configuration datum
|
||||
var/datum/configuration_section/mc_configuration/mc
|
||||
/// Holder for the MC configuration datum
|
||||
/// Holder for the metrics configuration datum
|
||||
var/datum/configuration_section/metrics_configuration/metrics
|
||||
/// Holder for the movement configuration datum
|
||||
var/datum/configuration_section/movement_configuration/movement
|
||||
/// Holder for the overflow configuration datum
|
||||
var/datum/configuration_section/overflow_configuration/overflow
|
||||
@@ -71,6 +73,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
jobs = new()
|
||||
logging = new()
|
||||
mc = new()
|
||||
metrics = new()
|
||||
movement = new()
|
||||
overflow = new()
|
||||
ruins = new()
|
||||
@@ -99,6 +102,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
jobs.load_data(raw_config_data["job_configuration"])
|
||||
logging.load_data(raw_config_data["logging_configuration"])
|
||||
mc.load_data(raw_config_data["mc_configuration"])
|
||||
metrics.load_data(raw_config_data["metrics_configuration"])
|
||||
movement.load_data(raw_config_data["movement_configuration"])
|
||||
overflow.load_data(raw_config_data["overflow_configuration"])
|
||||
ruins.load_data(raw_config_data["ruin_configuration"])
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
var/lobby_time = 240
|
||||
/// Ban all Guest BYOND accounts
|
||||
var/guest_ban = TRUE
|
||||
/// Player threshold to automatically enable panic bunker
|
||||
var/panic_bunker_threshold = 150
|
||||
/// Allow players to use AntagHUD?
|
||||
var/allow_antag_hud = TRUE
|
||||
/// Forbid players from rejoining if they use AntagHUD?
|
||||
@@ -121,7 +119,6 @@
|
||||
|
||||
// Numbers
|
||||
CONFIG_LOAD_NUM(lobby_time, data["lobby_time"])
|
||||
CONFIG_LOAD_NUM(panic_bunker_threshold, data["panic_bunker_threshold"])
|
||||
CONFIG_LOAD_NUM(base_loadout_points, data["base_loadout_points"])
|
||||
CONFIG_LOAD_NUM(cryo_penalty_period, data["cryo_penalty_period"])
|
||||
CONFIG_LOAD_NUM(minimum_client_build, data["minimum_client_build"])
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/// Config holder for stuff relating to metrics management
|
||||
/datum/configuration_section/metrics_configuration
|
||||
// NO EDITS OR READS TO THIS EVER
|
||||
protection_state = PROTECTION_PRIVATE
|
||||
/// Are metrics enabled or disabled
|
||||
var/enable_metrics = FALSE
|
||||
/// Endpoint to send metrics to, including protocol
|
||||
var/metrics_endpoint = null
|
||||
/// Endpoint authorisation API key
|
||||
var/metrics_api_token = null
|
||||
|
||||
/datum/configuration_section/metrics_configuration/load_data(list/data)
|
||||
// Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
|
||||
CONFIG_LOAD_BOOL(enable_metrics, data["enable_metrics"])
|
||||
|
||||
CONFIG_LOAD_STR(metrics_endpoint, data["metrics_endpoint"])
|
||||
CONFIG_LOAD_STR(metrics_api_token, data["metrics_api_token"])
|
||||
@@ -2,6 +2,8 @@
|
||||
/datum/controller/subsystem
|
||||
// Metadata; you should define these.
|
||||
name = "fire codertrain" //name of the subsystem
|
||||
/// Subsystem ID. Used for when we need a technical name for the SS
|
||||
var/ss_id = "fire_codertrain_again"
|
||||
var/init_order = INIT_ORDER_DEFAULT //order of initialization. Higher numbers are initialized first, lower numbers later. Use defines in __DEFINES/subsystems.dm for easy understanding of order.
|
||||
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
|
||||
var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
|
||||
@@ -227,3 +229,17 @@
|
||||
if("queued_priority") //editing this breaks things.
|
||||
return 0
|
||||
. = ..()
|
||||
|
||||
/**
|
||||
* Returns the metrics for the subsystem.
|
||||
*
|
||||
* This can be overriden on subtypes for variables that could affect tick usage
|
||||
* Example: ATs on SSair
|
||||
*/
|
||||
/datum/controller/subsystem/proc/get_metrics()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
var/list/out = list()
|
||||
out["cost"] = cost
|
||||
out["tick_usage"] = tick_usage
|
||||
out["custom"] = list() // Override as needed on child
|
||||
return out
|
||||
|
||||
@@ -11,6 +11,11 @@ SUBSYSTEM_DEF(acid)
|
||||
/datum/controller/subsystem/acid/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
|
||||
/datum/controller/subsystem/acid/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/acid/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
|
||||
@@ -66,6 +66,12 @@ SUBSYSTEM_DEF(air)
|
||||
msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
|
||||
..(msg)
|
||||
|
||||
/datum/controller/subsystem/air/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["active_turfs"] = length(active_turfs)
|
||||
cust["hotspots"] = length(hotspots)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/air/Initialize(timeofday)
|
||||
setup_overlays() // Assign icons and such for gas-turf-overlays
|
||||
|
||||
@@ -12,6 +12,12 @@ SUBSYSTEM_DEF(fires)
|
||||
..("P:[processing.len]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/fires/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/fires/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
|
||||
@@ -61,6 +61,22 @@ SUBSYSTEM_DEF(garbage)
|
||||
msg += " | Fail:[fail_counts.Join(",")]"
|
||||
..(msg)
|
||||
|
||||
/datum/controller/subsystem/garbage/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
if((delslasttick + gcedlasttick) == 0) // Account for DIV0
|
||||
cust["gcr"] = 0
|
||||
else
|
||||
cust["gcr"] = (gcedlasttick / (delslasttick + gcedlasttick))
|
||||
cust["total_harddels"] = totaldels
|
||||
cust["total_softdels"] = totalgcs
|
||||
var/i = 0
|
||||
for(var/list/L in queues)
|
||||
i++
|
||||
cust["queue_[i]"] = length(L)
|
||||
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/garbage/Shutdown()
|
||||
//Adds the del() log to the qdel log file
|
||||
var/list/dellog = list()
|
||||
|
||||
@@ -11,6 +11,14 @@ SUBSYSTEM_DEF(lighting)
|
||||
/datum/controller/subsystem/lighting/stat_entry()
|
||||
..("L:[length(sources_queue)]|C:[length(corners_queue)]|O:[length(objects_queue)]")
|
||||
|
||||
/datum/controller/subsystem/lighting/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["sources_queue"] = length(sources_queue)
|
||||
cust["corners_queue"] = length(corners_queue)
|
||||
cust["objects_queue"] = length(objects_queue)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
||||
if(!initialized)
|
||||
if(GLOB.configuration.general.starlight)
|
||||
|
||||
@@ -20,6 +20,12 @@ SUBSYSTEM_DEF(machines)
|
||||
fire()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/machines/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/machines/proc/makepowernets()
|
||||
for(var/datum/powernet/PN in powernets)
|
||||
qdel(PN)
|
||||
|
||||
@@ -62,7 +62,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
log_startup_progress("Populating lavaland...")
|
||||
var/lavaland_setup_timer = start_watch()
|
||||
seedRuins(list(level_name_to_num(MINING)), GLOB.configuration.ruins.lavaland_ruin_budget, /area/lavaland/surface/outdoors/unexplored, GLOB.lava_ruins_templates)
|
||||
spawn_rivers(list(level_name_to_num(MINING)))
|
||||
spawn_rivers(level_name_to_num(MINING))
|
||||
log_startup_progress("Successfully populated lavaland in [stop_watch(lavaland_setup_timer)]s.")
|
||||
|
||||
// Now we make a list of areas for teleport locs
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
SUBSYSTEM_DEF(metrics)
|
||||
name = "Metrics"
|
||||
wait = 30 SECONDS
|
||||
offline_implications = "Server metrics will no longer be ingested into monitoring systems. No immediate action is needed."
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME // ALL THE LEVELS
|
||||
flags = SS_KEEP_TIMING // This needs to ingest every 30 IRL seconds, not ingame seconds.
|
||||
/// The real time of day the server started. Used to calculate time drift
|
||||
var/world_init_time = 0 // Not set in here. Set in world/New()
|
||||
|
||||
/datum/controller/subsystem/metrics/Initialize(start_timeofday)
|
||||
if(!GLOB.configuration.metrics.enable_metrics)
|
||||
flags |= SS_NO_FIRE // Disable firing to save CPU
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/metrics/fire(resumed)
|
||||
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, GLOB.configuration.metrics.metrics_endpoint, get_metrics_json(), list(
|
||||
"Authorization" = "ApiKey [GLOB.configuration.metrics.metrics_api_token]",
|
||||
"Content-Type" = "application/json"
|
||||
))
|
||||
|
||||
/datum/controller/subsystem/metrics/proc/get_metrics_json()
|
||||
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["elapsed_processed"] = world.time
|
||||
out["elapsed_real"] = (REALTIMEOFDAY - world_init_time)
|
||||
out["client_count"] = length(GLOB.clients)
|
||||
out["round_id"] = text2num(GLOB.round_id) // This is so we can filter the metrics by a single round ID
|
||||
|
||||
// Funnel in all SS metrics
|
||||
var/list/ss_data = list()
|
||||
for(var/datum/controller/subsystem/SS in Master.subsystems)
|
||||
ss_data[SS.ss_id] = SS.get_metrics()
|
||||
|
||||
out["subsystems"] = ss_data
|
||||
// And send it all
|
||||
return json_encode(out)
|
||||
|
||||
/*
|
||||
|
||||
// Uncomment this if you add new metrics to verify how the JSON formats
|
||||
|
||||
/client/verb/debugmetricts()
|
||||
usr << browse(SSmetrics.get_metrics_json(), "window=aadebug")
|
||||
*/
|
||||
@@ -12,6 +12,12 @@ SUBSYSTEM_DEF(mobs)
|
||||
/// The amount of giant spiders that exist in the world. Used for mob capping.
|
||||
var/giant_spiders = 0
|
||||
|
||||
/datum/controller/subsystem/mobs/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(GLOB.mob_living_list)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/mobs/stat_entry()
|
||||
..("P:[GLOB.mob_living_list.len]")
|
||||
|
||||
|
||||
@@ -14,6 +14,12 @@ SUBSYSTEM_DEF(processing)
|
||||
/datum/controller/subsystem/processing/stat_entry()
|
||||
..("[stat_tag]:[processing.len]")
|
||||
|
||||
/datum/controller/subsystem/processing/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/processing/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
currentrun = processing.Copy()
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(radiation)
|
||||
name = "Radiation"
|
||||
flags = SS_NO_INIT | SS_BACKGROUND
|
||||
flags = SS_BACKGROUND | SS_NO_INIT
|
||||
wait = 1 SECONDS
|
||||
offline_implications = "Radiation will no longer function; power generation may not happen. A restart may or may not be required, depending on the situation."
|
||||
var/list/warned_atoms = list()
|
||||
// Cache radiation levels for each turf so it doesn't need to be done iteratively
|
||||
// turf_rad_cache is the state in the current loop, and may not be 100% representative
|
||||
// until processing is complete.
|
||||
// prev_rad_cache is the fully evaluated radiation state cache from the previous tick.
|
||||
var/list/turf_rad_cache = list()
|
||||
var/list/prev_rad_cache = list()
|
||||
|
||||
|
||||
/datum/controller/subsystem/processing/radiation/proc/warn(datum/component/radioactive/contamination)
|
||||
if(!contamination || QDELETED(contamination))
|
||||
@@ -16,3 +23,26 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
|
||||
SSblackbox.record_feedback("tally", "contaminated", 1, master.type)
|
||||
var/msg = "has become contaminated with enough radiation to contaminate other objects. || Source: [contamination.source] || Strength: [contamination.strength]"
|
||||
master.investigate_log(msg, "radiation")
|
||||
|
||||
/datum/controller/subsystem/processing/radiation/fire(resumed)
|
||||
refresh_rad_cache()
|
||||
. = ..()
|
||||
|
||||
/datum/controller/subsystem/processing/radiation/proc/get_turf_radiation(turf/place)
|
||||
if (prev_rad_cache[place])
|
||||
return prev_rad_cache[place]
|
||||
else
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/processing/radiation/proc/update_rad_cache(datum/component/radioactive/thing)
|
||||
var/atom/owner = thing.parent
|
||||
var/turf/place = get_turf(owner)
|
||||
if (turf_rad_cache[place])
|
||||
turf_rad_cache[place] += thing.strength
|
||||
else
|
||||
turf_rad_cache[place] = thing.strength
|
||||
|
||||
|
||||
/datum/controller/subsystem/processing/radiation/proc/refresh_rad_cache()
|
||||
prev_rad_cache = turf_rad_cache.Copy()
|
||||
turf_rad_cache = list()
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#define QUEUE_DATA_FILE "data/queue_data.json"
|
||||
// These are defines for the sake of making sure we get the right keys
|
||||
#define QUEUE_DATA_FILE_THRESHOLD_KEY "threshold"
|
||||
#define QUEUE_DATA_FILE_ENABLED_KEY "enabled"
|
||||
#define QUEUE_DATA_FILE_PERSISTENT_KEY "persistent"
|
||||
|
||||
SUBSYSTEM_DEF(queue)
|
||||
name = "Server Queue"
|
||||
init_order = INIT_ORDER_QUEUE // 100
|
||||
flags = SS_NO_FIRE
|
||||
/// Threshold of players to queue new people
|
||||
var/queue_threshold = 0
|
||||
/// Whether the queue is enabled or not
|
||||
var/queue_enabled = FALSE
|
||||
/// Whether to persist these settings over multiple rounds
|
||||
var/persist_queue = FALSE
|
||||
/// List of ckeys allowed to bypass queue this round
|
||||
var/list/queue_bypass_list = list()
|
||||
/// Last world.time we let a ckey in. 3 second delay between each letin to avoid a mass bubble
|
||||
var/last_letin_time = 0
|
||||
|
||||
/datum/controller/subsystem/queue/Initialize(start_timeofday)
|
||||
if(fexists(QUEUE_DATA_FILE))
|
||||
try
|
||||
var/F = file2text(QUEUE_DATA_FILE)
|
||||
var/list/data = json_decode(F)
|
||||
queue_threshold = data[QUEUE_DATA_FILE_THRESHOLD_KEY]
|
||||
queue_enabled = data[QUEUE_DATA_FILE_ENABLED_KEY]
|
||||
persist_queue = data[QUEUE_DATA_FILE_PERSISTENT_KEY]
|
||||
catch
|
||||
stack_trace("Failed to load [QUEUE_DATA_FILE] from disk due to malformed JSON. You may need to setup the queue again.")
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/queue/Shutdown()
|
||||
// Save if persistent
|
||||
if(persist_queue)
|
||||
if(fexists(QUEUE_DATA_FILE))
|
||||
fdel(QUEUE_DATA_FILE)
|
||||
var/data = list()
|
||||
data[QUEUE_DATA_FILE_THRESHOLD_KEY] = queue_threshold
|
||||
data[QUEUE_DATA_FILE_ENABLED_KEY] = queue_enabled
|
||||
data[QUEUE_DATA_FILE_PERSISTENT_KEY] = persist_queue
|
||||
var/json_data = json_encode(data)
|
||||
text2file(json_data, QUEUE_DATA_FILE)
|
||||
@@ -12,6 +12,11 @@ SUBSYSTEM_DEF(spacedrift)
|
||||
/datum/controller/subsystem/spacedrift/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
|
||||
/datum/controller/subsystem/spacedrift/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/spacedrift/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
|
||||
@@ -27,6 +27,13 @@ SUBSYSTEM_DEF(tgui)
|
||||
/datum/controller/subsystem/tgui/stat_entry()
|
||||
..("P:[processing_uis.len]")
|
||||
|
||||
/datum/controller/subsystem/tgui/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing_uis)
|
||||
.["custom"] = cust
|
||||
|
||||
|
||||
/datum/controller/subsystem/tgui/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = processing_uis.Copy()
|
||||
@@ -119,7 +126,7 @@ SUBSYSTEM_DEF(tgui)
|
||||
* Close all UIs attached to src_object.
|
||||
* Returns the number of UIs closed.
|
||||
*
|
||||
* * datum/src_objectThe object/datum which owns the UIs.
|
||||
* * datum/src_object - The object/datum which owns the UIs.
|
||||
*/
|
||||
/datum/controller/subsystem/tgui/proc/close_uis(datum/src_object)
|
||||
if(!src_object.unique_datum_id) // First check if the datum has an UID set
|
||||
|
||||
@@ -15,6 +15,12 @@ SUBSYSTEM_DEF(throwing)
|
||||
/datum/controller/subsystem/throwing/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
|
||||
/datum/controller/subsystem/throwing/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/throwing/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
src.currentrun = processing.Copy()
|
||||
|
||||
@@ -3,6 +3,7 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets
|
||||
/datum/controller/subsystem/tickets/mentor_tickets/New()
|
||||
NEW_SS_GLOBAL(SSmentor_tickets)
|
||||
PreInit()
|
||||
ss_id = "mentor_tickets"
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets
|
||||
name = "Mentor Tickets"
|
||||
|
||||
@@ -41,6 +41,12 @@ SUBSYSTEM_DEF(tickets)
|
||||
|
||||
var/ticketCounter = 1
|
||||
|
||||
/datum/controller/subsystem/tickets/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["tickets"] = length(allTickets) // Not a perf metric but I want to see a graph where SSair usage spikes and 20 tickets come in
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/tickets/Initialize()
|
||||
if(!close_messages)
|
||||
close_messages = list("<font color='red' size='4'><b>- [ticket_name] Rejected! -</b></font>",
|
||||
|
||||
@@ -37,6 +37,12 @@ SUBSYSTEM_DEF(timer)
|
||||
/datum/controller/subsystem/timer/stat_entry(msg)
|
||||
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
|
||||
|
||||
/datum/controller/subsystem/timer/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["bucket_count"] = bucket_count
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/timer/fire(resumed = FALSE)
|
||||
var/lit = last_invoke_tick
|
||||
var/last_check = world.time - TICKS2DS(BUCKET_LEN*1.5)
|
||||
|
||||
@@ -9,11 +9,17 @@ SUBSYSTEM_DEF(weather)
|
||||
flags = SS_BACKGROUND
|
||||
wait = 10
|
||||
runlevels = RUNLEVEL_GAME
|
||||
offline_implications = "Ash storms will no longer trigger. No immediate action is needed."
|
||||
offline_implications = "Ash storms will no longer trigger. No immediate action is needed."
|
||||
var/list/processing = list()
|
||||
var/list/eligible_zlevels = list()
|
||||
var/list/next_hit_by_zlevel = list() //Used by barometers to know when the next storm is coming
|
||||
|
||||
/datum/controller/subsystem/weather/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing)
|
||||
.["custom"] = cust
|
||||
|
||||
/datum/controller/subsystem/weather/fire()
|
||||
// process active weather
|
||||
for(var/V in processing)
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
if(!hl3_release_date)
|
||||
return
|
||||
strength -= strength / hl3_release_date
|
||||
SSradiation.update_rad_cache(src)
|
||||
if(strength <= RAD_BACKGROUND_RADIATION)
|
||||
qdel(src)
|
||||
return PROCESS_KILL
|
||||
|
||||
@@ -36,6 +36,14 @@
|
||||
if(prob(2))
|
||||
affected_mob.visible_message("<span class='danger'>[affected_mob] coughs up butterflies!</span>", \
|
||||
"<span class='userdanger'>You cough up butterflies!</span>")
|
||||
new /mob/living/simple_animal/butterfly(affected_mob.loc)
|
||||
new /mob/living/simple_animal/butterfly(affected_mob.loc)
|
||||
return
|
||||
for(var/i in 1 to 2)
|
||||
var/mob/living/simple_animal/butterfly/B = new(affected_mob.loc)
|
||||
addtimer(CALLBACK(B, /mob/living/simple_animal/butterfly/.proc/decompose), rand(5, 25) SECONDS)
|
||||
|
||||
/**
|
||||
* Made so severe anxiety does not overload the SSmob while keeping it's effect
|
||||
*/
|
||||
/mob/living/simple_animal/butterfly/proc/decompose()
|
||||
visible_message("<span class='notice'>[src] decomposes due to being outside of its original habitat for too long!</span>",
|
||||
"<span class='userdanger'>You decompose for being too long out of your habitat!</span>")
|
||||
melt()
|
||||
|
||||
@@ -49,6 +49,18 @@
|
||||
..()
|
||||
D.set_light(4)
|
||||
|
||||
/datum/dog_fashion/head/hardhat
|
||||
name = "Engineer REAL_NAME"
|
||||
desc = "Trust him, he's an engineer."
|
||||
|
||||
/datum/dog_fashion/head/hardhat/white
|
||||
name = "Chief engineer REAL_NAME"
|
||||
desc = "Hasn't delamed the engine once."
|
||||
|
||||
/datum/dog_fashion/head/hardhat/red
|
||||
name = "Fire chief REAL_NAME"
|
||||
desc = "Some days you're the dog, some days you're the hydrant."
|
||||
|
||||
/datum/dog_fashion/head/helmet
|
||||
name = "Sergeant REAL_NAME"
|
||||
desc = "The ever-loyal, the ever-vigilant."
|
||||
|
||||
@@ -558,11 +558,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list))
|
||||
if(show_message)
|
||||
to_chat(user, "<span class='warning'>You shouldn't have this spell! Something's wrong.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/turf/T = get_turf(user)
|
||||
if(is_admin_level(T.z) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
|
||||
return 0
|
||||
if(!centcom_cancast) //Certain spells are not allowed on the centcom zlevel
|
||||
var/turf/T = get_turf(user)
|
||||
if(T && is_admin_level(T.z))
|
||||
return FALSE
|
||||
|
||||
if(!holy_area_cancast && user.holy_check())
|
||||
return FALSE
|
||||
@@ -573,21 +574,21 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell))
|
||||
if(charge_counter < charge_max)
|
||||
if(show_message)
|
||||
to_chat(user, still_recharging_msg)
|
||||
return 0
|
||||
return FALSE
|
||||
if("charges")
|
||||
if(!charge_counter)
|
||||
if(show_message)
|
||||
to_chat(user, "<span class='notice'>[name] has no charges left.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(!ghost)
|
||||
if(user.stat && !stat_allowed)
|
||||
if(show_message)
|
||||
to_chat(user, "<span class='notice'>You can't cast this spell while incapacitated.</span>")
|
||||
return 0
|
||||
return FALSE
|
||||
if(ishuman(user) && (invocation_type == "whisper" || invocation_type == "shout") && user.is_muzzled())
|
||||
if(show_message)
|
||||
to_chat(user, "Mmmf mrrfff!")
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
@@ -56,8 +56,7 @@
|
||||
qdel(holder)
|
||||
if(!QDELETED(target))
|
||||
if(mobloc.density)
|
||||
for(var/direction in GLOB.alldirs)
|
||||
var/turf/T = get_step(mobloc, direction)
|
||||
for(var/turf/T in orange(7))
|
||||
if(T)
|
||||
if(target.Move(T))
|
||||
break
|
||||
|
||||
@@ -11,7 +11,7 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
|
||||
name = "changeling"
|
||||
config_tag = "changeling"
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation Brigadier General")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation General")
|
||||
protected_species = list("Machine")
|
||||
required_players = 15
|
||||
required_enemies = 1
|
||||
|
||||
@@ -48,7 +48,7 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
/datum/game_mode/cult
|
||||
name = "cult"
|
||||
config_tag = "cult"
|
||||
restricted_jobs = list("Chaplain", "AI", "Cyborg", "Internal Affairs Agent", "Security Officer", "Warden", "Detective", "Security Pod Pilot", "Head of Security", "Captain", "Head of Personnel", "Blueshield", "Nanotrasen Representative", "Magistrate", "Brig Physician", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation Brigadier General")
|
||||
restricted_jobs = list("Chaplain", "AI", "Cyborg", "Internal Affairs Agent", "Security Officer", "Warden", "Detective", "Security Pod Pilot", "Head of Security", "Captain", "Head of Personnel", "Blueshield", "Nanotrasen Representative", "Magistrate", "Brig Physician", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation General")
|
||||
protected_jobs = list()
|
||||
required_players = 30
|
||||
required_enemies = 3
|
||||
|
||||
@@ -948,11 +948,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
V.Grant(ghost)
|
||||
//GM.Grant(ghost)
|
||||
while(!QDELETED(user))
|
||||
if(!(user in T))
|
||||
user.visible_message("<span class='warning'>A spectral tendril wraps around [user] and pulls [user.p_them()] back to the rune!</span>")
|
||||
Beam(user, icon_state = "drainbeam", time = 2)
|
||||
user.forceMove(get_turf(src)) //NO ESCAPE :^)
|
||||
if(user.key)
|
||||
if(user.key || QDELETED(src))
|
||||
user.visible_message("<span class='warning'>[user] slowly relaxes, the glow around [user.p_them()] dimming.</span>",
|
||||
"<span class='danger'>You are re-united with your physical form. [src] releases its hold over you.</span>")
|
||||
user.Weaken(3)
|
||||
@@ -960,12 +956,16 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
if(user.health <= 10)
|
||||
to_chat(ghost, "<span class='cultitalic'>Your body can no longer sustain the connection!</span>")
|
||||
break
|
||||
if(!(user in T))
|
||||
user.visible_message("<span class='warning'>A spectral tendril wraps around [user] and pulls [user.p_them()] back to the rune!</span>")
|
||||
Beam(user, icon_state = "drainbeam", time = 2)
|
||||
user.forceMove(get_turf(src)) //NO ESCAPE :^)
|
||||
sleep(5)
|
||||
CM.Remove(ghost)
|
||||
V.Remove(ghost)
|
||||
//GM.Remove(ghost)
|
||||
if(user.grab_ghost())
|
||||
CM.Remove(ghost)
|
||||
V.Remove(ghost)
|
||||
//GM.Remove(ghost)
|
||||
user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
|
||||
user.grab_ghost()
|
||||
user = null
|
||||
rune_in_use = FALSE
|
||||
|
||||
|
||||
@@ -358,6 +358,7 @@
|
||||
item_state = "alienpistol"
|
||||
origin_tech = "combat=4;magnets=7;powerstorage=3;abductor=3"
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/paper/abductor
|
||||
name = "Dissection Guide"
|
||||
|
||||
@@ -389,7 +389,7 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective)
|
||||
|
||||
steal_target = O
|
||||
explanation_text = "Steal [steal_target]. One was last seen in [get_location()]. "
|
||||
if(length(O.protected_jobs))
|
||||
if(length(O.protected_jobs) && O.job_possession)
|
||||
explanation_text += "It may also be in the possession of the [english_list(O.protected_jobs, and_text = " or ")]."
|
||||
if(steal_target.special_equipment)
|
||||
give_kit(steal_target.special_equipment)
|
||||
|
||||
@@ -74,7 +74,7 @@ Made by Xhuis
|
||||
required_enemies = 2
|
||||
recommended_enemies = 2
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Head of Personnel", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation Brigadier General")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Head of Personnel", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation General")
|
||||
|
||||
/datum/game_mode/shadowling/announce()
|
||||
to_chat(world, "<b>The current game mode is - Shadowling!</b>")
|
||||
@@ -123,7 +123,7 @@ Made by Xhuis
|
||||
..()
|
||||
|
||||
/datum/game_mode/proc/greet_shadow(datum/mind/shadow)
|
||||
to_chat(shadow.current, "<b>Currently, you are disguised as an employee aboard [world.name].</b>")
|
||||
to_chat(shadow.current, "<b>Currently, you are disguised as an employee aboard [station_name()].</b>")
|
||||
to_chat(shadow.current, "<b>In your limited state, you have two abilities: Hatch and Shadowling Hivemind (:8).</b>")
|
||||
to_chat(shadow.current, "<b>Any other shadowlings are your allies. You must assist them as they shall assist you.</b>")
|
||||
to_chat(shadow.current, "<span class='motd'>For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Shadowling)</span>")
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
var/location_override
|
||||
/// Do we have a special item we give to somewhen when they get this objective?
|
||||
var/special_equipment = null
|
||||
/// If a steal objective has forbidden jobs, and the forbidden jobs would not be in the possession of this item, set this to false
|
||||
var/job_possession = TRUE
|
||||
|
||||
/datum/theft_objective/proc/check_completion(datum/mind/owner)
|
||||
if(!owner.current)
|
||||
@@ -143,14 +145,15 @@
|
||||
/datum/theft_objective/supermatter_sliver
|
||||
name = "a supermatter sliver"
|
||||
typepath = /obj/item/nuke_core/supermatter_sliver
|
||||
protected_jobs = list("Chief Engineer", "Engineer", "Atmospheric Technician") //Unlike other steal objectives, all jobs in the department have easy access, and would not be noticed at all stealing this
|
||||
protected_jobs = list("Chief Engineer", "Station Engineer", "Life Support Specialist") //Unlike other steal objectives, all jobs in the department have easy access, and would not be noticed at all stealing this
|
||||
location_override = "Engineering. You can use the box and instructions provided to harvest the sliver."
|
||||
special_equipment = /obj/item/storage/box/syndie_kit/supermatter
|
||||
job_possession = FALSE //The CE / engineers / atmos techs do not carry around supermater slivers.
|
||||
|
||||
/datum/theft_objective/plutonium_core
|
||||
name = "the plutonium core from the stations nuclear device"
|
||||
typepath = /obj/item/nuke_core/plutonium
|
||||
location_override = "the Vault. You can use the box and instructions provided to remove the core, with some extra tools."
|
||||
location_override = "the Vault. You can use the box and instructions provided to remove the core, with some extra tools"
|
||||
special_equipment = /obj/item/storage/box/syndie_kit/nuke
|
||||
|
||||
/datum/theft_objective/number
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
name = "traitor"
|
||||
config_tag = "traitor"
|
||||
restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Internal Affairs Agent", "Brig Physician", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation Brigadier General")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Internal Affairs Agent", "Brig Physician", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation General")
|
||||
required_players = 0
|
||||
required_enemies = 1
|
||||
recommended_enemies = 4
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "traitor+vampire"
|
||||
config_tag = "traitorvamp"
|
||||
traitors_possible = 3 //hard limit on traitors if scaling is turned off
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Chaplain", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Solar Federation Brigadier General")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Chaplain", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Solar Federation General")
|
||||
restricted_jobs = list("Cyborg")
|
||||
secondary_restricted_jobs = list("AI")
|
||||
required_players = 10
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
name = "vampire"
|
||||
config_tag = "vampire"
|
||||
restricted_jobs = list("AI", "Cyborg")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Chaplain", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation Brigadier General")
|
||||
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Chaplain", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation General")
|
||||
protected_species = list("Machine")
|
||||
required_players = 15
|
||||
required_enemies = 1
|
||||
|
||||
@@ -218,9 +218,13 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/mob_aoe/glare/cast(list/targets, mob/user = usr)
|
||||
user.visible_message("<span class='warning'>[user]'s eyes emit a blinding flash!</span>")
|
||||
if(istype(user:glasses, /obj/item/clothing/glasses/sunglasses/blindfold))
|
||||
to_chat(user, "<span class='warning'>You're blindfolded!</span>")
|
||||
return
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/sunglasses/blindfold))
|
||||
var/obj/item/clothing/glasses/sunglasses/blindfold/B = H.glasses
|
||||
if(B.tint)
|
||||
to_chat(user, "<span class='warning'>You're blindfolded!</span>")
|
||||
return
|
||||
for(var/mob/living/target in targets)
|
||||
if(!affects(target))
|
||||
continue
|
||||
@@ -453,8 +457,7 @@
|
||||
flick("mist_reappear", animation)
|
||||
sleep(5)
|
||||
if(!user.Move(mobloc))
|
||||
for(var/direction in list(1,2,4,8,5,6,9,10))
|
||||
var/turf/T = get_step(mobloc, direction)
|
||||
for(var/turf/T in orange(7, mobloc))
|
||||
if(T)
|
||||
if(user.Move(T))
|
||||
break
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
return get_all_centcom_access() + get_all_accesses()
|
||||
if("Special Operations Officer")
|
||||
return get_all_centcom_access() + get_all_accesses()
|
||||
if("Solar Federation Brigadier General")
|
||||
if("Solar Federation General")
|
||||
return get_all_centcom_access() + get_all_accesses()
|
||||
if("Nanotrasen Navy Representative")
|
||||
return get_all_centcom_access() + get_all_accesses()
|
||||
@@ -403,7 +403,7 @@
|
||||
return list("VIP Guest","Custodian","Thunderdome Overseer","Emergency Response Team Member","Emergency Response Team Leader","Intel Officer","Medical Officer","Death Commando","Research Officer","Deathsquad Officer","Special Operations Officer","Nanotrasen Navy Representative","Nanotrasen Navy Officer","Nanotrasen Navy Captain","Supreme Commander")
|
||||
|
||||
/proc/get_all_solgov_jobs()
|
||||
return list("Solar Federation Lieutenant","Solar Federation Specops Lieutenant","Solar Federation Marine","Solar Federation Specops Marine","Solar Federation Representative","Sol Trader","Solar Federation Brigadier General")
|
||||
return list("Solar Federation Lieutenant","Solar Federation Specops Lieutenant","Solar Federation Marine","Solar Federation Specops Marine","Solar Federation Representative","Sol Trader","Solar Federation General")
|
||||
|
||||
//gets the actual job rank (ignoring alt titles)
|
||||
//this is used solely for sechuds
|
||||
|
||||
@@ -106,11 +106,11 @@
|
||||
H.mind.offstation_role = TRUE
|
||||
|
||||
/datum/job/ntspecops/solgovspecops
|
||||
title = "Solar Federation Brigadier General"
|
||||
title = "Solar Federation General"
|
||||
outfit = /datum/outfit/job/ntspecops/solgovspecops
|
||||
|
||||
/datum/outfit/job/ntspecops/solgovspecops
|
||||
name = "Solar Federation Brigadier General"
|
||||
name = "Solar Federation General"
|
||||
uniform = /obj/item/clothing/under/rank/centcom/captain/solgov
|
||||
suit = /obj/item/clothing/suit/space/deathsquad/officer/solgov
|
||||
head = /obj/item/clothing/head/helmet/space/deathsquad/beret/solgov
|
||||
|
||||
@@ -66,6 +66,21 @@
|
||||
component_parts += new /obj/item/stack/sheet/glass(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/autolathe/upgraded/gamma/New()
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/autolathe(null)
|
||||
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
|
||||
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
|
||||
component_parts += new /obj/item/stock_parts/matter_bin/super(null)
|
||||
component_parts += new /obj/item/stock_parts/manipulator/pico(null)
|
||||
component_parts += new /obj/item/stack/sheet/glass(null)
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/autolathe/upgraded/gamma/Initialize()
|
||||
. = ..()
|
||||
adjust_hacked(TRUE)
|
||||
|
||||
/obj/machinery/autolathe/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
|
||||
@@ -253,7 +253,10 @@
|
||||
/obj/item/key,
|
||||
/obj/item/door_remote,
|
||||
/obj/item/autopsy_scanner,
|
||||
/obj/item/holosign_creator/atmos
|
||||
/obj/item/holosign_creator/atmos,
|
||||
/obj/item/clothing/gloves/color/black/forensics,
|
||||
/obj/item/rcd,
|
||||
/obj/item/rpd
|
||||
)
|
||||
// These items will NOT be preserved
|
||||
var/list/do_not_preserve_items = list (
|
||||
@@ -341,21 +344,23 @@
|
||||
return CRYO_PRESERVE
|
||||
return CRYO_DESTROY
|
||||
|
||||
// This function can not be undone; do not call this unless you are sure
|
||||
// Also make sure there is a valid control computer
|
||||
|
||||
/obj/machinery/cryopod/proc/handle_contents(obj/item/I)
|
||||
if(length(I.contents)) //Make sure we catch anything not handled by qdel() on the items.
|
||||
if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation
|
||||
return
|
||||
for(var/obj/item/O in I.contents)
|
||||
if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck!
|
||||
continue
|
||||
handle_contents(O)
|
||||
O.forceMove(src)
|
||||
|
||||
/obj/machinery/cryopod/proc/despawn_occupant()
|
||||
//Drop all items into the pod.
|
||||
for(var/obj/item/I in occupant)
|
||||
occupant.unEquip(I)
|
||||
I.forceMove(src)
|
||||
|
||||
if(I.contents.len) //Make sure we catch anything not handled by qdel() on the items.
|
||||
if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation
|
||||
continue
|
||||
for(var/obj/item/O in I.contents)
|
||||
if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck!
|
||||
continue
|
||||
O.forceMove(src)
|
||||
handle_contents(I)
|
||||
|
||||
for(var/obj/machinery/computer/cloning/cloner in GLOB.machines)
|
||||
for(var/datum/dna2/record/R in cloner.records)
|
||||
|
||||
@@ -851,10 +851,16 @@ About the new airlock wires panel:
|
||||
/obj/machinery/door/airlock/proc/toggle_bolt(mob/user)
|
||||
if(wires.is_cut(WIRE_DOOR_BOLTS))
|
||||
to_chat(user, "<span class='warning'>The door bolt control wire has been cut - Door bolts permanently dropped.</span>")
|
||||
else if(lock())
|
||||
to_chat(user, "<span class='notice'>The door bolts have been dropped.</span>")
|
||||
else if(unlock())
|
||||
return
|
||||
|
||||
if(unlock()) // Trying to unbolt
|
||||
to_chat(user, "<span class='notice'>The door bolts have been raised.</span>")
|
||||
return
|
||||
|
||||
if(lock()) // Trying to bolt
|
||||
to_chat(user, "<span class='notice'>The door bolts have been dropped.</span>")
|
||||
user.create_log(MISC_LOG, "Bolted", src)
|
||||
add_hiddenprint(user)
|
||||
|
||||
/obj/machinery/door/airlock/proc/toggle_emergency_status(mob/user)
|
||||
emergency = !emergency
|
||||
|
||||
@@ -110,6 +110,15 @@
|
||||
/obj/machinery/suit_storage_unit/security/hos/secure
|
||||
secure = TRUE
|
||||
|
||||
/obj/machinery/suit_storage_unit/gamma
|
||||
name = "gamma shielded suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/shielded/gamma
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer/swat
|
||||
req_access = list(ACCESS_SECURITY)
|
||||
|
||||
/obj/machinery/suit_storage_unit/gamma/secure
|
||||
secure = TRUE
|
||||
|
||||
/obj/machinery/suit_storage_unit/atmos
|
||||
name = "atmospherics suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"Emergency Response Team Officer" = "dsquadradio",
|
||||
"Nanotrasen Navy Officer" = "dsquadradio",
|
||||
"Special Operations Officer" = "dsquadradio",
|
||||
"Solar Federation Brigadier General" = "dsquadradio",
|
||||
"Solar Federation General" = "dsquadradio",
|
||||
"Solar Federation Specops Lieutenant" = "dsquadradio",
|
||||
"Solar Federation Specops Marine" = "dsquadradio",
|
||||
"Solar Federation Lieutenant" = "dsquadradio",
|
||||
@@ -124,7 +124,7 @@
|
||||
/// List of ERT jobs
|
||||
var/list/ert_jobs = list("Emergency Response Team Officer", "Emergency Response Team Engineer", "Emergency Response Team Medic", "Emergency Response Team Leader", "Emergency Response Team Member")
|
||||
/// List of CentComm jobs
|
||||
var/list/cc_jobs = list("Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation Brigadier General")
|
||||
var/list/cc_jobs = list("Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation General")
|
||||
/// List of SolGov Marine jobs
|
||||
var/list/tsf_jobs = list("Solar Federation Specops Lieutenant", "Solar Federation Specops Marine", "Solar Federation Lieutenant", "Solar Federation Marine")
|
||||
// Defined so code compiles and incase someone has a non-standard job
|
||||
|
||||
@@ -44,6 +44,29 @@
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/combat/marauder/ares
|
||||
name = "Ares"
|
||||
desc = "Heavy-duty, combat exosuit, adapted from rejected early versions of the Marauder to serve as a biohazard containment exosuit. This model, albeit rare, can be found among civilian populations."
|
||||
icon_state = "ares"
|
||||
initial_icon = "ares"
|
||||
operation_req_access = list(ACCESS_SECURITY)
|
||||
max_integrity = 450
|
||||
armor = list(melee = 50, bullet = 40, laser = 20, energy = 20, bomb = 20, bio = 100, rad = 60, fire = 100, acid = 100)
|
||||
max_temperature = 40000
|
||||
wreckage = /obj/structure/mecha_wreckage/ares
|
||||
max_equip = 4
|
||||
|
||||
/obj/mecha/combat/marauder/ares/loaded/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/xray(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster(src)
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/combat/marauder/seraph
|
||||
desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
|
||||
name = "Seraph"
|
||||
|
||||
@@ -128,6 +128,11 @@
|
||||
name = "\improper Marauder wreckage"
|
||||
icon_state = "marauder-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/ares
|
||||
name = "\improper Ares wreckage"
|
||||
icon_state = "ares-broken"
|
||||
desc = "The truth is you lost an expensive piece of Nanotrasen-issue equipment. That suit is going to come out of your pay, and you will remain in this corporation until you are five hundred and ten years old, which is the number of years it will take for you to pay for an Ares Biohazard Containment Exosuit you have lost!"
|
||||
|
||||
/obj/structure/mecha_wreckage/mauler
|
||||
name = "\improper Mauler wreckage"
|
||||
icon_state = "mauler-broken"
|
||||
|
||||
@@ -83,7 +83,9 @@
|
||||
if(!mapload)
|
||||
log_world("### MAP WARNING, [src] spawned outside of mapload!")
|
||||
return
|
||||
var/obj/machinery/door/door = locate(/obj/machinery/door) in loc
|
||||
var/obj/machinery/door/door = locate(/obj/machinery/door/airlock) in loc
|
||||
if(!door)
|
||||
door = locate(/obj/machinery/door/window) in loc
|
||||
if(door)
|
||||
door.unres_sides ^= dir
|
||||
else
|
||||
|
||||
@@ -43,14 +43,14 @@
|
||||
|
||||
/obj/effect/temp_visual/ratvar/window
|
||||
icon_state = "ratvarwindowglow"
|
||||
layer = ABOVE_OBJ_LAYER
|
||||
layer = ABOVE_WINDOW_LAYER
|
||||
|
||||
/obj/effect/temp_visual/ratvar/window/single
|
||||
icon_state = "ratvarwindowglow_s"
|
||||
|
||||
/obj/effect/temp_visual/ratvar/gear
|
||||
icon_state = "ratvargearglow"
|
||||
layer = BELOW_OBJ_LAYER
|
||||
layer = ABOVE_OBJ_LAYER
|
||||
|
||||
/obj/effect/temp_visual/ratvar/grille
|
||||
icon_state = "ratvargrilleglow"
|
||||
|
||||
@@ -16,12 +16,21 @@
|
||||
GLOBAL_LIST_INIT(metal_recipes, list(
|
||||
new /datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("barstool", /obj/structure/chair/stool/bar, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("chair", /obj/structure/chair, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("chair (dark)", /obj/structure/chair, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("chair (light)", /obj/structure/chair/light, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("shuttle seat", /obj/structure/chair/comfy/shuttle, 2, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/right, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("sofa (corner)", /obj/structure/chair/sofa/corner, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe_list("sofas", list(
|
||||
new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, 1, one_per_turf = TRUE, on_floor = TRUE),
|
||||
new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, 1, one_per_turf = TRUE, on_floor = TRUE),
|
||||
new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/right, 1, one_per_turf = TRUE, on_floor = TRUE),
|
||||
new /datum/stack_recipe("sofa (corner)", /obj/structure/chair/sofa/corner, 1, one_per_turf = TRUE, on_floor = TRUE)
|
||||
)), \
|
||||
new /datum/stack_recipe_list("corporate sofas", list( \
|
||||
new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa/corp, 1, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/corp/left, 1, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/corp/right, 1, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("sofa (corner)", /obj/structure/chair/sofa/corp/corner, 1, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
)), \
|
||||
new /datum/stack_recipe("barber chair", /obj/structure/chair/barber, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("wheelchair", /obj/structure/chair/wheelchair, 15, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1),
|
||||
@@ -176,6 +185,11 @@ GLOBAL_LIST_INIT(wood_recipes, list(
|
||||
new /datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20),
|
||||
new /datum/stack_recipe("wood table frame", /obj/structure/table_frame/wood, 2, time = 10), \
|
||||
new /datum/stack_recipe("wooden chair", /obj/structure/chair/wood, 3, time = 10, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe_list("pews", list(
|
||||
new /datum/stack_recipe("pew (middle)", /obj/structure/chair/sofa/pew, 1, one_per_turf = TRUE, on_floor = TRUE),
|
||||
new /datum/stack_recipe("pew (left)", /obj/structure/chair/sofa/pew/left, 1, one_per_turf = TRUE, on_floor = TRUE),
|
||||
new /datum/stack_recipe("pew (right)", /obj/structure/chair/sofa/pew/right, 1, one_per_turf = TRUE, on_floor = TRUE),
|
||||
)), \
|
||||
new /datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("bookcase", /obj/structure/bookcase, 5, time = 50, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("dresser", /obj/structure/dresser, 30, time = 50, one_per_turf = 1, on_floor = 1),
|
||||
@@ -241,6 +255,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
new/datum/stack_recipe("white beanie", /obj/item/clothing/head/beanie, 2), \
|
||||
null, \
|
||||
new/datum/stack_recipe("blindfold", /obj/item/clothing/glasses/sunglasses/blindfold, 3), \
|
||||
new/datum/stack_recipe("tattered blindfold", /obj/item/clothing/glasses/sunglasses/blindfold/fake, 2), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/cloth
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
item_state = "plutoniumcore"
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
flags_2 = RAD_NO_CONTAMINATE_2 //Don't have the item itself become irradiated when it makes radiation.
|
||||
var/pulse = 0
|
||||
var/cooldown = 0
|
||||
var/pulseicon = "plutonium_core_pulse"
|
||||
|
||||
@@ -49,14 +48,42 @@
|
||||
icon = 'icons/obj/nuke_tools.dmi'
|
||||
icon_state = "core_container_empty"
|
||||
item_state = "metal"
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //Don't want people trying to break it open with acid, then destroying the core.
|
||||
var/obj/item/nuke_core/plutonium/core
|
||||
var/dented = FALSE
|
||||
var/cracked = FALSE
|
||||
|
||||
/obj/item/nuke_core_container/Destroy()
|
||||
QDEL_NULL(core)
|
||||
return ..()
|
||||
|
||||
/obj/item/nuke_core_container/ex_act(severity)
|
||||
switch(severity)
|
||||
if(EXPLODE_DEVASTATE)
|
||||
if(!cracked)
|
||||
crack_open()
|
||||
if(EXPLODE_HEAVY)
|
||||
if(!dented)
|
||||
dented = TRUE
|
||||
|
||||
/obj/item/nuke_core_container/examine(mob/user)
|
||||
. = ..()
|
||||
if(cracked) // Cracked open.
|
||||
. += "<span class='warning'>It is broken, and can no longer store objects safely.</span>"
|
||||
else if(dented) // Not cracked, but dented.
|
||||
. += "<span class='notice'>[src] looks dented. Perhaps a bigger explosion may break it.</span>"
|
||||
else // Not cracked or dented.
|
||||
. += "Fine print on the box reads \"Cybersun Industries secure container, guaranteed thermite proof, assistant proof, and explosive resistant.\""
|
||||
|
||||
/obj/item/nuke_core_container/attack_hand(mob/user)
|
||||
if(cracked && core)
|
||||
unload(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/nuke_core_container/proc/load(obj/item/nuke_core/plutonium/new_core, mob/user)
|
||||
if(core || !istype(new_core))
|
||||
if(core || !istype(new_core) || cracked)
|
||||
return
|
||||
new_core.forceMove(src)
|
||||
core = new_core
|
||||
@@ -64,6 +91,12 @@
|
||||
to_chat(user, "<span class='warning'>Container is sealing...</span>")
|
||||
addtimer(CALLBACK(src, .proc/seal), 10 SECONDS)
|
||||
|
||||
/obj/item/nuke_core_container/proc/unload(mob/user)
|
||||
core.add_fingerprint(user)
|
||||
user.put_in_active_hand(core)
|
||||
core = null
|
||||
icon_state = "core_container_cracked_empty"
|
||||
|
||||
/obj/item/nuke_core_container/proc/seal()
|
||||
if(!QDELETED(core))
|
||||
STOP_PROCESSING(SSobj, core)
|
||||
@@ -73,7 +106,7 @@
|
||||
to_chat(loc, "<span class='warning'>[src] is permanently sealed, [core]'s radiation is contained.</span>")
|
||||
|
||||
/obj/item/nuke_core_container/attackby(obj/item/nuke_core/plutonium/core, mob/user)
|
||||
if(!istype(core))
|
||||
if(!istype(core) || cracked)
|
||||
return ..()
|
||||
|
||||
if(!user.drop_item())
|
||||
@@ -82,9 +115,20 @@
|
||||
else
|
||||
load(core, user)
|
||||
|
||||
/obj/item/nuke_core_container/proc/crack_open()
|
||||
visible_message("<span class='boldnotice'>[src] bursts open!</span>")
|
||||
if(core)
|
||||
START_PROCESSING(SSobj, core)
|
||||
icon_state = "core_container_cracked_loaded"
|
||||
else
|
||||
icon_state = "core_container_cracked_empty"
|
||||
name = "broken nuke core container"
|
||||
cracked = TRUE
|
||||
|
||||
/obj/item/paper/guides/antag/nuke_instructions
|
||||
info = "How to break into a Nanotrasen nuclear device and remove its plutonium core:<br>\
|
||||
<ul>\
|
||||
<li>Acquire some clothing that protects you from radiation, due to the radioactivity of the core.</li>\
|
||||
<li>Use a screwdriver with a very thin tip (provided) to unscrew the terminal's front panel.</li>\
|
||||
<li>Dislodge and remove the front panel with a crowbar.</li>\
|
||||
<li>Cut the inner metal plate with a welding tool.</li>\
|
||||
@@ -99,7 +143,7 @@
|
||||
/obj/item/paper/guides/antag/supermatter_sliver
|
||||
info = "How to safely extract a supermatter sliver:<br>\
|
||||
<ul>\
|
||||
<li>Approach an active supermatter crystal with radiation shielded personal protective equipment. DO NOT MAKE PHYSICAL CONTACT.</li>\
|
||||
<li>Approach an active supermatter crystal with radiation shielded personal protective equipment, and active magboots. DO NOT MAKE PHYSICAL CONTACT.</li>\
|
||||
<li>Use a supermatter scalpel (provided) to slice off a sliver of the crystal.</li>\
|
||||
<li>Use supermatter extraction tongs (also provided) to safely pick up the sliver you sliced off.</li>\
|
||||
<li>Physical contact of any object with the sliver will dust the object, as well as yourself.</li>\
|
||||
@@ -183,7 +227,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/nuke_core_container/supermatter/load(obj/item/retractor/supermatter/I, mob/user)
|
||||
if(!istype(I) || !I.sliver)
|
||||
if(!istype(I) || !I.sliver || sliver)
|
||||
return
|
||||
I.sliver.forceMove(src)
|
||||
sliver = I.sliver
|
||||
@@ -202,13 +246,56 @@
|
||||
if(ismob(loc))
|
||||
to_chat(loc, "<span class='warning'>[src] is permanently sealed, [sliver] is safely contained.</span>")
|
||||
|
||||
/obj/item/nuke_core_container/supermatter/unload(obj/item/retractor/supermatter/I, mob/user)
|
||||
if(!istype(I) || I.sliver)
|
||||
return
|
||||
sliver.forceMove(I)
|
||||
I.sliver = sliver
|
||||
sliver = null
|
||||
I.icon_state = "supermatter_tongs_loaded"
|
||||
I.item_state = "supermatter_tongs_loaded"
|
||||
icon_state = "core_container_cracked_empty"
|
||||
to_chat(user, "<span class='notice'>You carefully pick up [I.sliver] with [I].</span>")
|
||||
|
||||
/obj/item/nuke_core_container/supermatter/attackby(obj/item/retractor/supermatter/tongs, mob/user)
|
||||
if(istype(tongs))
|
||||
//try to load shard into core
|
||||
load(tongs, user)
|
||||
if(cracked)
|
||||
//lets take that shard out
|
||||
unload(tongs, user)
|
||||
else
|
||||
//try to load shard into core
|
||||
load(tongs, user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/nuke_core_container/supermatter/attack_hand(mob/user)
|
||||
if(cracked && sliver) //What did we say about touching the shard...
|
||||
if(!isliving(user) || user.status_flags & GODMODE)
|
||||
return FALSE
|
||||
user.visible_message("<span class='danger'>[user] reaches out and tries to pick up [sliver]. [user.p_their()] body starts to glow and bursts into flames before flashing into dust!</span>",
|
||||
"<span class='userdanger'>You reach for [sliver] with your hands. That was dumb.</span>",
|
||||
"<span class='italics'>Everything suddenly goes silent.</span>")
|
||||
radiation_pulse(user, 500, 2)
|
||||
playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE)
|
||||
message_admins("[sliver] has consumed [key_name_admin(user)] [ADMIN_JMP(src)].")
|
||||
investigate_log("has consumed [key_name(user)].", "supermatter")
|
||||
user.dust()
|
||||
icon_state = "core_container_cracked_empty"
|
||||
qdel(sliver)
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/nuke_core_container/supermatter/crack_open()
|
||||
visible_message("<span class='boldnotice'>[src] bursts open!</span>")
|
||||
if(sliver)
|
||||
START_PROCESSING(SSobj, sliver)
|
||||
icon_state = "supermatter_container_cracked_loaded"
|
||||
else
|
||||
icon_state = "core_container_cracked_empty"
|
||||
name = "broken supermatter bin"
|
||||
cracked = TRUE
|
||||
|
||||
/obj/item/scalpel/supermatter
|
||||
name = "supermatter scalpel"
|
||||
desc = "A scalpel with a fragile tip of condensed hyper-noblium gas, searingly cold to the touch, that can safely shave a sliver off a supermatter crystal."
|
||||
@@ -267,6 +354,8 @@
|
||||
investigate_log("has irradiated [key_name(victim)].", "supermatter")
|
||||
else if(istype(AM, /obj/singularity))
|
||||
return
|
||||
else if(istype(AM, /obj/item/nuke_core_container))
|
||||
return
|
||||
else
|
||||
investigate_log("has consumed [AM].", "supermatter")
|
||||
qdel(AM)
|
||||
|
||||
@@ -97,9 +97,8 @@
|
||||
"<span class='danger'>May the power of [deity_name] compel you to be healed!</span>")
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
else
|
||||
if(!istype(H.head, /obj/item/clothing/head/helmet))
|
||||
M.adjustBrainLoss(10)
|
||||
to_chat(M, "<span class='warning'>You feel dumber.</span>")
|
||||
M.adjustBrainLoss(10)
|
||||
to_chat(M, "<span class='warning'>You feel dumber.</span>")
|
||||
H.visible_message("<span class='danger'>[user] beats [H == user ? "[user.p_them()]self" : "[H]"] over the head with [src]!</span>")
|
||||
playsound(src.loc, "punch", 25, 1, -1)
|
||||
else
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
/obj/item/storage/firstaid/toxin/Initialize(mapload)
|
||||
. = ..()
|
||||
icon_state = pick("antitoxin", "antitoxfirstaid", "antitoxfirstaid2", "antitoxfirstaid3")
|
||||
icon_state = pick("antitoxin", "antitoxfirstaid", "antitoxfirstaid2")
|
||||
|
||||
/obj/item/storage/firstaid/toxin/populate_contents()
|
||||
for(var/I in 1 to 3)
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
to_chat(user, "<span class='notice'>You no longer deflect objects thrown at you. You can attack during this time</span>")
|
||||
deflectmode = FALSE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to wait until you can deflect again. The ability will be ready in [time2text(lastdeflect - world.time, "m:ss")]</span>")
|
||||
to_chat(user, "<span class='warning'>You need to wait until you can deflect again. The ability will be ready in [time2text(lastdeflect - world.time, "mm:ss")]</span>")
|
||||
return ..()
|
||||
if(homerun_ready)
|
||||
to_chat(user, "<span class='notice'>You're already ready to do a home run!</span>")
|
||||
|
||||
@@ -137,6 +137,12 @@
|
||||
rotate()
|
||||
|
||||
// Chair types
|
||||
/obj/structure/chair/light
|
||||
name = "chair"
|
||||
icon_state = "chair_greyscale"
|
||||
resistance_flags = FLAMMABLE
|
||||
item_chair = /obj/item/chair/light
|
||||
|
||||
/obj/structure/chair/wood
|
||||
name = "wooden chair"
|
||||
desc = "Old is never too old to not be in fashion."
|
||||
@@ -268,6 +274,33 @@
|
||||
anchored = TRUE
|
||||
item_chair = null
|
||||
buildstackamount = 1
|
||||
var/image/armrest = null
|
||||
|
||||
/obj/structure/chair/sofa/Initialize(mapload)
|
||||
armrest = GetArmrest()
|
||||
armrest.layer = ABOVE_MOB_LAYER
|
||||
return ..()
|
||||
|
||||
/obj/structure/chair/sofa/proc/GetArmrest()
|
||||
return mutable_appearance('icons/obj/chairs.dmi', "[icon_state]_armrest")
|
||||
|
||||
/obj/structure/chair/sofa/Destroy()
|
||||
QDEL_NULL(armrest)
|
||||
return ..()
|
||||
|
||||
/obj/structure/chair/sofa/post_buckle_mob(mob/living/M)
|
||||
. = ..()
|
||||
update_armrest()
|
||||
|
||||
/obj/structure/chair/sofa/post_unbuckle_mob(mob/living/M)
|
||||
. = ..()
|
||||
update_armrest()
|
||||
|
||||
/obj/structure/chair/sofa/proc/update_armrest()
|
||||
if(has_buckled_mobs())
|
||||
add_overlay(armrest)
|
||||
else
|
||||
cut_overlay(armrest)
|
||||
|
||||
/obj/structure/chair/sofa/left
|
||||
icon_state = "sofaend_left"
|
||||
@@ -278,6 +311,31 @@
|
||||
/obj/structure/chair/sofa/corner
|
||||
icon_state = "sofacorner"
|
||||
|
||||
/obj/structure/chair/sofa/corp
|
||||
name = "sofa"
|
||||
desc = "Soft and cushy."
|
||||
icon_state = "corp_sofamiddle"
|
||||
|
||||
/obj/structure/chair/sofa/corp/left
|
||||
icon_state = "corp_sofaend_left"
|
||||
|
||||
/obj/structure/chair/sofa/corp/right
|
||||
icon_state = "corp_sofaend_right"
|
||||
|
||||
/obj/structure/chair/sofa/corp/corner
|
||||
icon_state = "corp_sofacorner"
|
||||
|
||||
/obj/structure/chair/sofa/pew
|
||||
name = "pew"
|
||||
desc = "Rigid and uncomfortable, perfect for keeping you awake and alert."
|
||||
icon_state = "pewmiddle"
|
||||
|
||||
/obj/structure/chair/sofa/pew/left
|
||||
icon_state = "pewend_left"
|
||||
|
||||
/obj/structure/chair/sofa/pew/right
|
||||
icon_state = "pewend_right"
|
||||
|
||||
/obj/structure/chair/stool
|
||||
name = "stool"
|
||||
desc = "Apply butt."
|
||||
@@ -309,6 +367,10 @@
|
||||
var/break_chance = 5 //Likely hood of smashing the chair.
|
||||
var/obj/structure/chair/origin_type = /obj/structure/chair
|
||||
|
||||
/obj/item/chair/light
|
||||
icon_state = "chair_greyscale_toppled"
|
||||
origin_type = /obj/structure/chair/light
|
||||
|
||||
/obj/item/chair/stool
|
||||
name = "stool"
|
||||
icon = 'icons/obj/chairs.dmi'
|
||||
|
||||
@@ -408,6 +408,10 @@
|
||||
return
|
||||
if(!isliving(AM))
|
||||
return
|
||||
var/mob/living/L = AM
|
||||
if(L.incorporeal_move || L.flying || L.floating)
|
||||
return
|
||||
|
||||
// Don't break if they're just flying past
|
||||
if(AM.throwing)
|
||||
addtimer(CALLBACK(src, .proc/throw_check, AM), 5)
|
||||
|
||||
@@ -702,21 +702,17 @@
|
||||
reinf = FALSE
|
||||
var/made_glow = FALSE
|
||||
|
||||
/obj/structure/window/reinforced/clockwork/Initialize(mapload, direct)
|
||||
. = ..()
|
||||
if(fulltile)
|
||||
made_glow = TRUE
|
||||
if(fulltile)
|
||||
new /obj/effect/temp_visual/ratvar/window(get_turf(src))
|
||||
|
||||
/obj/structure/window/reinforced/clockwork/spawnDebris(location)
|
||||
. = list()
|
||||
. += new /obj/item/stack/tile/brass(location, (fulltile ? 2 : 1))
|
||||
|
||||
/obj/structure/window/reinforced/clockwork/setDir(direct)
|
||||
if(!made_glow)
|
||||
var/obj/effect/E = new /obj/effect/temp_visual/ratvar/window/single(get_turf(src))
|
||||
E.setDir(direct)
|
||||
if(fulltile)
|
||||
new /obj/effect/temp_visual/ratvar/window(get_turf(src))
|
||||
else
|
||||
var/obj/effect/E = new /obj/effect/temp_visual/ratvar/window/single(get_turf(src))
|
||||
E.setDir(direct)
|
||||
made_glow = TRUE
|
||||
..()
|
||||
|
||||
|
||||
@@ -52,9 +52,8 @@
|
||||
hardness = 10
|
||||
slicing_duration = 80
|
||||
sheet_type = /obj/item/stack/tile/brass
|
||||
sheet_amount = 1
|
||||
sheet_amount = 2
|
||||
girder_type = /obj/structure/clockwork/wall_gear
|
||||
baseturf = /turf/simulated/floor/clockwork/reebe
|
||||
var/heated
|
||||
var/obj/effect/clockwork/overlay/wall/realappearance
|
||||
|
||||
@@ -77,25 +76,6 @@
|
||||
animate(src, color = previouscolor, time = 8)
|
||||
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8)
|
||||
|
||||
/turf/simulated/wall/clockwork/dismantle_wall(devastated=0, explode=0)
|
||||
if(devastated)
|
||||
devastate_wall()
|
||||
ChangeTurf(baseturf)
|
||||
else
|
||||
playsound(src, 'sound/items/welder.ogg', 100, 1)
|
||||
var/newgirder = break_wall()
|
||||
if(newgirder) //maybe we want a gear!
|
||||
transfer_fingerprints_to(newgirder)
|
||||
ChangeTurf(baseturf)
|
||||
|
||||
for(var/obj/O in src) //Eject contents!
|
||||
if(istype(O, /obj/structure/sign/poster))
|
||||
var/obj/structure/sign/poster/P = O
|
||||
P.roll_and_drop(src)
|
||||
else
|
||||
O.forceMove(src)
|
||||
return TRUE
|
||||
|
||||
/turf/simulated/wall/clockwork/devastate_wall()
|
||||
for(var/i in 1 to 2)
|
||||
new/obj/item/clockwork/alloy_shards/large(src)
|
||||
@@ -116,4 +96,3 @@
|
||||
if(heated)
|
||||
to_chat(M.occupant, "<span class='userdanger'>The wall's intense heat completely reflects your [M.name]'s attack!</span>")
|
||||
M.take_damage(20, BURN)
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ GLOBAL_LIST_INIT(map_transition_config, list(CC_TRANSITION_CONFIG))
|
||||
// Right off the bat
|
||||
enable_auxtools_debugger()
|
||||
|
||||
SSmetrics.world_init_time = REALTIMEOFDAY
|
||||
|
||||
// Do sanity checks to ensure RUST actually exists
|
||||
if(!fexists(RUST_G))
|
||||
DIRECT_OUTPUT(world.log, "ERROR: RUSTG was not found and is required for the game to function. Server will now exit.")
|
||||
|
||||
@@ -97,10 +97,9 @@
|
||||
qdel(exist_query)
|
||||
else
|
||||
if(!exist_query.NextRow()) // If there isnt a row, they aint been seen before
|
||||
if(GLOB.panic_bunker_enabled)
|
||||
if(SSqueue?.queue_enabled && (length(GLOB.clients) > SSqueue.queue_threshold) && !(ckey in SSqueue.queue_bypass_list))
|
||||
qdel(exist_query)
|
||||
var/threshold = GLOB.configuration.general.panic_bunker_threshold
|
||||
return list("reason" = "panic bunker", "desc" = "Server is not accepting connections from never-before-seen players until player count is less than [threshold]. Please try again later.")
|
||||
return list("reason" = "server queue", "desc" = "You seem to have managed to skip the server queue, possibly due to connecting during a restart. Please reconnect in 10 minutes. If you still cannot connect, please inform the server host.")
|
||||
|
||||
qdel(exist_query)
|
||||
|
||||
|
||||
@@ -137,7 +137,9 @@ GLOBAL_LIST_INIT(admin_verbs_server, list(
|
||||
/client/proc/toggle_antagHUD_restrictions,
|
||||
/client/proc/set_ooc,
|
||||
/client/proc/reset_ooc,
|
||||
/client/proc/set_next_map
|
||||
/client/proc/set_next_map,
|
||||
/client/proc/manage_queue,
|
||||
/client/proc/add_queue_server_bypass
|
||||
))
|
||||
GLOBAL_LIST_INIT(admin_verbs_debug, list(
|
||||
/client/proc/cmd_admin_list_open_jobs,
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/client/proc/manage_queue()
|
||||
set name = "Manage Queue Server"
|
||||
set desc = "Manage the queue server and its settings"
|
||||
set category = "Server"
|
||||
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
|
||||
var/list/choices = list("Show Status", "Toggle Queue Server", "Set Threshold", "Toggle Setting Persistence")
|
||||
var/choice = input(usr, "Please, select an option", "Queue Server Manipulation") as null|anything in choices
|
||||
|
||||
switch(choice)
|
||||
if("Show Status")
|
||||
to_chat(usr, "<b>Queue Server Status</b>")
|
||||
to_chat(usr, "Enabled: <b>[SSqueue.queue_enabled ? "<font color='green'>Yes</font>" : "<font color='red'>No</font>"]</b>")
|
||||
to_chat(usr, "Queue Threshold: <b>[SSqueue.queue_threshold]</b>")
|
||||
to_chat(usr, "Setting Persistence: <b>[SSqueue.persist_queue ? "<font color='green'>Yes</font>" : "<font color='red'>No</font>"]</b>")
|
||||
if("Toggle Queue Server")
|
||||
SSqueue.queue_enabled = !SSqueue.queue_enabled
|
||||
to_chat(usr, "Queue server is now <b>[SSqueue.queue_enabled ? "<font color='green'>Enabled</font>" : "<font color='red'>Disabled</font>"]</b>")
|
||||
message_admins("[key_name_admin(usr)] has [SSqueue.queue_enabled ? "enabled" : "disabled"] the server queue.")
|
||||
log_admin("[key_name(usr)] has [SSqueue.queue_enabled ? "enabled" : "disabled"] the server queue.")
|
||||
SSdiscord.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[usr.ckey]` has now **[SSqueue.queue_enabled ? "enabled" : "disabled"]** the queue server.")
|
||||
if("Set Threshold")
|
||||
var/new_threshold = input(usr, "Enter new threshold", "Queue Server Manipulation", SSqueue.queue_threshold) as num|null
|
||||
if(!new_threshold)
|
||||
return
|
||||
SSqueue.queue_threshold = new_threshold
|
||||
to_chat(usr, "Queue threshold is now <b>[SSqueue.queue_threshold]</b>")
|
||||
message_admins("[key_name_admin(usr)] has set the queue threshold to [SSqueue.queue_threshold].")
|
||||
log_admin("[key_name(usr)] has set the queue threshold to [SSqueue.queue_threshold].")
|
||||
SSdiscord.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[usr.ckey]` has set the queue threshold to **[SSqueue.queue_threshold]**.")
|
||||
if("Toggle Setting Persistence")
|
||||
SSqueue.persist_queue = !SSqueue.persist_queue
|
||||
to_chat(usr, "Queue server setting persistence is now <b>[SSqueue.persist_queue ? "<font color='green'>Enabled</font>" : "<font color='red'>Disabled</font>"]</b>")
|
||||
message_admins("[key_name_admin(usr)] has [SSqueue.persist_queue ? "enabled" : "disabled"] the server queue settings persistence.")
|
||||
log_admin("[key_name(usr)] has [SSqueue.persist_queue ? "enabled" : "disabled"] the server queue settings persistence.")
|
||||
SSdiscord.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[usr.ckey]` has now **[SSqueue.persist_queue ? "enabled" : "disabled"]** server queue settings persistence.")
|
||||
|
||||
/client/proc/add_queue_server_bypass()
|
||||
set name = "Add Queue Server Bypass"
|
||||
set desc = "Allow a ckey to bypass the server queue"
|
||||
set category = "Server"
|
||||
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
|
||||
var/bypass_ckey = input(usr, "Please, enter a ckey", "Queue Server Bypass")
|
||||
|
||||
if(!bypass_ckey)
|
||||
return
|
||||
|
||||
var/clean_ckey = ckey(bypass_ckey)
|
||||
|
||||
if(!clean_ckey)
|
||||
to_chat(usr, "Invalid ckey supplied")
|
||||
return
|
||||
|
||||
SSqueue.queue_bypass_list.Add(clean_ckey)
|
||||
message_admins("[key_name_admin(usr)] has added the ckey [clean_ckey] to the queue bypass list.")
|
||||
log_admin("[key_name(usr)] has added the ckey [clean_ckey] to the queue bypass list.")
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
/datum/contractor_hub/ui_act(action, list/params)
|
||||
/datum/contractor_hub/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
if(..())
|
||||
return
|
||||
|
||||
@@ -44,7 +43,6 @@
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Contractor", "Syndicate Contractor Uplink", 500, 600, master_ui, state)
|
||||
ui.open()
|
||||
ui.set_autoupdate(FALSE)
|
||||
|
||||
/datum/contractor_hub/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
@@ -67,6 +65,7 @@
|
||||
|
||||
switch(page)
|
||||
if(HUB_PAGE_CONTRACTS)
|
||||
var/contract_target
|
||||
var/list/contracts_out = list()
|
||||
data["contracts"] = contracts_out
|
||||
for(var/c in contracts)
|
||||
@@ -99,15 +98,26 @@
|
||||
contract_data["dead_extraction"] = C.dead_extraction
|
||||
if(CONTRACT_STATUS_FAILED)
|
||||
contract_data["fail_reason"] = C.fail_reason
|
||||
|
||||
if(C.contract.extraction_zone)
|
||||
contract_target = C.contract.target?.current
|
||||
var/area/A = get_area(user)
|
||||
contract_data["objective"] = list(
|
||||
extraction_zone = C.contract.extraction_zone.map_name,
|
||||
reward_tc = C.reward_tc[C.chosen_difficulty],
|
||||
reward_credits = C.reward_credits,
|
||||
extraction_name = C.contract.extraction_zone.map_name,
|
||||
locs = list(
|
||||
user_area_id = A.uid,
|
||||
user_coords = ATOM_COORDS(user),
|
||||
target_area_id = C.contract.extraction_zone.uid,
|
||||
target_coords = ATOM_COORDS(C.contract.extraction_zone),
|
||||
),
|
||||
rewards = list(tc = C.reward_tc[C.chosen_difficulty], credits = C.reward_credits)
|
||||
)
|
||||
contracts_out += list(contract_data)
|
||||
|
||||
data["can_extract"] = current_contract?.contract.can_start_extraction_process(ui_host(), usr) || FALSE
|
||||
data["can_extract"] = FALSE
|
||||
if(contract_target)
|
||||
data["can_extract"] = current_contract?.contract.can_start_extraction_process(user, contract_target)
|
||||
|
||||
if(HUB_PAGE_SHOP)
|
||||
var/list/buyables = list()
|
||||
for(var/p in purchases)
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
|
||||
for(var/A in loc)
|
||||
var/atom/item = A
|
||||
if(item && item != src) // It's possible that the item is deleted in temperature_expose
|
||||
if(!QDELETED(item) && item != src) // It's possible that the item is deleted in temperature_expose
|
||||
item.fire_act(null, temperature, volume)
|
||||
|
||||
color = heat2color(temperature)
|
||||
@@ -250,7 +250,7 @@
|
||||
var/turf/T = open[1]
|
||||
var/dist = open[T]
|
||||
open -= T
|
||||
closed += T
|
||||
closed[T] = TRUE
|
||||
|
||||
if(isspaceturf(T))
|
||||
continue
|
||||
@@ -305,9 +305,7 @@
|
||||
|
||||
if(T.density)
|
||||
continue
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
continue
|
||||
|
||||
if(dist == max_dist)
|
||||
continue
|
||||
|
||||
@@ -315,10 +313,11 @@
|
||||
var/turf/link = get_step(T, dir)
|
||||
if (!link)
|
||||
continue
|
||||
var/dx = link.x - Ce.x
|
||||
var/dy = link.y - Ce.y
|
||||
var/target_dist = max((dist + 1 + sqrt(dx * dx + dy * dy)) / 2, dist)
|
||||
if(!(link in closed))
|
||||
// Check if it wasn't already visited and if you can get to that turf
|
||||
if(!closed[link] && T.CanAtmosPass(link))
|
||||
var/dx = link.x - Ce.x
|
||||
var/dy = link.y - Ce.y
|
||||
var/target_dist = max((dist + 1 + sqrt(dx * dx + dy * dy)) / 2, dist)
|
||||
if(link in open)
|
||||
if(open[link] > target_dist)
|
||||
open[link] = target_dist
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
/obj/machinery/atmospherics/unary/heat_exchanger
|
||||
icon = 'icons/obj/atmospherics/heat_exchanger.dmi'
|
||||
icon_state = "intact"
|
||||
density = 1
|
||||
|
||||
name = "heat exchanger"
|
||||
desc = "Exchanges heat between two input gases. Setup for fast heat transfer"
|
||||
|
||||
can_unwrench = 1
|
||||
can_unwrench = TRUE
|
||||
|
||||
var/obj/machinery/atmospherics/unary/heat_exchanger/partner = null
|
||||
var/update_cycle
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/screen/buildmode
|
||||
icon = 'icons/misc/buildmode.dmi'
|
||||
var/datum/click_intercept/buildmode/bd
|
||||
layer = HUD_LAYER_BUILDMODE
|
||||
plane = HUD_PLANE_BUILDMODE
|
||||
|
||||
/obj/screen/buildmode/New(bld)
|
||||
bd = bld
|
||||
|
||||
@@ -406,21 +406,13 @@
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
|
||||
// Update the state of the panic bunker based on current playercount
|
||||
var/threshold = GLOB.configuration.general.panic_bunker_threshold
|
||||
|
||||
if((playercount > threshold) && (GLOB.panic_bunker_enabled == FALSE))
|
||||
GLOB.panic_bunker_enabled = TRUE
|
||||
message_admins("Panic bunker has been automatically enabled due to playercount rising above [threshold]")
|
||||
|
||||
if((playercount < threshold) && (GLOB.panic_bunker_enabled == TRUE))
|
||||
GLOB.panic_bunker_enabled = FALSE
|
||||
message_admins("Panic bunker has been automatically disabled due to playercount dropping below [threshold]")
|
||||
|
||||
// Tell clients about active testmerges
|
||||
if(world.TgsAvailable() && length(GLOB.revision_info.testmerges))
|
||||
to_chat(src, GLOB.revision_info.get_testmerge_chatmessage(TRUE))
|
||||
|
||||
if(check_rights(R_ADMIN, FALSE, mob)) // Mob is required. Dont even try without it.
|
||||
to_chat(src, "The queue server is currently [SSqueue.queue_enabled ? "<font color='green'>enabled</font>" : "<font color='disabled'>disabled</font>"], with a threshold of <b>[SSqueue.queue_threshold]</b>. This <b>[SSqueue.persist_queue ? "will" : "will not"]</b> persist through rounds.")
|
||||
|
||||
|
||||
/client/proc/is_connecting_from_localhost()
|
||||
var/localhost_addresses = list("127.0.0.1", "::1") // Adresses
|
||||
|
||||
@@ -66,30 +66,10 @@
|
||||
if(MODE_RAD)
|
||||
show_rads()
|
||||
|
||||
|
||||
/obj/item/clothing/glasses/meson/engine/proc/show_rads()
|
||||
var/mob/living/carbon/human/user = loc
|
||||
var/list/rad_places = list()
|
||||
for(var/datum/component/radioactive/thing in SSradiation.processing)
|
||||
var/atom/owner = thing.parent
|
||||
var/turf/place = get_turf(owner)
|
||||
if(rad_places[place])
|
||||
rad_places[place] += thing.strength
|
||||
else
|
||||
rad_places[place] = thing.strength
|
||||
|
||||
for(var/i in rad_places)
|
||||
var/turf/place = i
|
||||
if(get_dist(user, place) >= range * 5) //Rads are easier to see than wires under the floor
|
||||
continue
|
||||
var/strength = round(rad_places[i] / 1000, 0.1)
|
||||
var/image/pic = image(loc = place)
|
||||
var/mutable_appearance/MA = new()
|
||||
MA.maptext = MAPTEXT("[strength]k")
|
||||
MA.color = "#04e604"
|
||||
MA.layer = RAD_TEXT_LAYER
|
||||
MA.plane = GAME_PLANE
|
||||
pic.appearance = MA
|
||||
flick_overlay(pic, list(user.client), 10)
|
||||
user.show_rads(range * 5) // Rads are easier to see than wires under the floor
|
||||
|
||||
/obj/item/clothing/glasses/meson/engine/update_icon()
|
||||
icon_state = "trayson-[mode]"
|
||||
|
||||
@@ -395,6 +395,12 @@
|
||||
tint = 3 //to make them blind
|
||||
prescription_upgradable = 0
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/blindfold/fake
|
||||
name = "tattered blindfold"
|
||||
desc = "A see-through blindfold perfect for cheating at games like pin the stunbaton on the clown."
|
||||
flash_protect = 0
|
||||
tint = 0
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/prescription
|
||||
prescription = 1
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
desc = "WARNING! Offers no real protection, or luminosity, but it is damn fancy!"
|
||||
icon_state = "hardhat0_yellow"
|
||||
item_state = "hardhat0_yellow"
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
dog_fashion = /datum/dog_fashion/head/hardhat
|
||||
|
||||
/obj/item/clothing/head/collectable/HoS
|
||||
name = "collectable HoS hat"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
dog_fashion = /datum/dog_fashion/head/hardhat/red
|
||||
|
||||
/obj/item/clothing/head/hardhat/white
|
||||
icon_state = "hardhat0_white"
|
||||
@@ -76,7 +77,7 @@
|
||||
max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
dog_fashion = /datum/dog_fashion/head/hardhat
|
||||
dog_fashion = /datum/dog_fashion/head/hardhat/white
|
||||
|
||||
/obj/item/clothing/head/hardhat/dblue
|
||||
icon_state = "hardhat0_dblue"
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
|
||||
|
||||
dog_fashion = null
|
||||
|
||||
sprite_sheets = list(
|
||||
"Grey" = 'icons/mob/species/grey/head.dmi'
|
||||
|
||||
@@ -711,3 +711,24 @@
|
||||
item_state = "syndie_helm"
|
||||
item_color = "syndi"
|
||||
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
|
||||
|
||||
|
||||
//////Security Version (Gamma armory only)
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/shielded/gamma
|
||||
name = "shielded security hardsuit"
|
||||
desc = "A more advanced version of the normal security hardsuit. Comes with built in energy shielding."
|
||||
icon_state = "hardsuit-sec"
|
||||
item_state = "sec-hardsuit"
|
||||
armor = list("melee" = 35, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
|
||||
allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/baton,/obj/item/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/restraints/handcuffs)
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/gamma
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/shielded/gamma
|
||||
name = "shielded security hardsuit helmet"
|
||||
desc = "A more advanced version of the normal security hardsuit helmet. Comes with built in energy shielding."
|
||||
icon_state = "hardsuit0-sec"
|
||||
item_state = "sec_helm"
|
||||
item_color = "sec"
|
||||
armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL // so it doesn't fit in pockets
|
||||
|
||||
/obj/item/clothing/accessory/holster/Destroy()
|
||||
QDEL_NULL(holstered)
|
||||
if(holstered?.loc == src) // Gun still in the holster
|
||||
holstered.forceMove(loc)
|
||||
holstered = null
|
||||
return ..()
|
||||
|
||||
//subtypes can override this to specify what can be holstered
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
name = "meatbread slice"
|
||||
desc = "A slice of delicious meatbread."
|
||||
icon_state = "meatbreadslice"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#FF7575"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/sliceable/xenomeatbread
|
||||
@@ -34,7 +33,6 @@
|
||||
name = "xenomeatbread slice"
|
||||
desc = "A slice of delicious meatbread. Extra Heretical."
|
||||
icon_state = "xenobreadslice"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#8AFF75"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/sliceable/spidermeatbread
|
||||
@@ -49,8 +47,7 @@
|
||||
/obj/item/reagent_containers/food/snacks/spidermeatbreadslice
|
||||
name = "spider meat bread slice"
|
||||
desc = "A slice of meatloaf made from an animal that most likely still wants you dead."
|
||||
icon_state = "xenobreadslice"
|
||||
trash = /obj/item/trash/plate
|
||||
icon_state = "spidermeatslice"
|
||||
list_reagents = list("toxin" = 2)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/sliceable/bananabread
|
||||
@@ -67,7 +64,6 @@
|
||||
name = "banana-nut bread slice"
|
||||
desc = "A slice of delicious banana bread."
|
||||
icon_state = "bananabreadslice"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#EDE5AD"
|
||||
tastes = list("bread" = 10)
|
||||
|
||||
@@ -85,7 +81,6 @@
|
||||
name = "tofubread slice"
|
||||
desc = "A slice of delicious tofubread."
|
||||
icon_state = "tofubreadslice"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#F7FFE0"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/sliceable/bread
|
||||
@@ -102,7 +97,6 @@
|
||||
name = "bread slice"
|
||||
desc = "A slice of home."
|
||||
icon_state = "breadslice"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#D27332"
|
||||
list_reagents = list("nutriment" = 2, "bread" = 5)
|
||||
tastes = list("bread" = 10)
|
||||
@@ -121,7 +115,6 @@
|
||||
name = "cream cheese bread slice"
|
||||
desc = "A slice of yum!"
|
||||
icon_state = "creamcheesebreadslice"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#FFF896"
|
||||
list_reagents = list("nutriment" = 4, "vitamin" = 1)
|
||||
tastes = list("bread" = 10, "cheese" = 10)
|
||||
@@ -140,7 +133,6 @@
|
||||
name = "banarnarbread slice"
|
||||
desc = "A slice of delicious mah'weyh pleggh at e'ntrath!"
|
||||
icon_state = "banarnarbreadslice"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#6F0000"
|
||||
list_reagents = list("nutriment" = 4, "vitamin" = 1)
|
||||
tastes = list("heresy" = 10, "banana" = 10)
|
||||
@@ -171,6 +163,8 @@
|
||||
name = "baguette"
|
||||
desc = "Bon appetit!"
|
||||
icon_state = "baguette"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
filling_color = "#E3D796"
|
||||
bitesize = 3
|
||||
list_reagents = list("nutriment" = 6, "vitamin" = 1)
|
||||
@@ -198,7 +192,6 @@
|
||||
name = "jellied toast"
|
||||
desc = "A slice of bread covered with delicious jam."
|
||||
icon_state = "jellytoast"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#B572AB"
|
||||
bitesize = 3
|
||||
tastes = list("toast" = 1, "jelly" = 1)
|
||||
|
||||
@@ -165,7 +165,6 @@
|
||||
name = "sandwich"
|
||||
desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce! Arthur Dent would be proud."
|
||||
icon_state = "sandwich"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#D9BE29"
|
||||
list_reagents = list("nutriment" = 6, "vitamin" = 1)
|
||||
tastes = list("meat" = 2, "cheese" = 1, "bread" = 2, "lettuce" = 1)
|
||||
@@ -174,7 +173,6 @@
|
||||
name = "toasted sandwich"
|
||||
desc = "Now if you only had a pepper bar."
|
||||
icon_state = "toastedsandwich"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#D9BE29"
|
||||
list_reagents = list("nutriment" = 6, "carbon" = 2)
|
||||
tastes = list("toast" = 1)
|
||||
@@ -183,7 +181,6 @@
|
||||
name = "grilled cheese sandwich"
|
||||
desc = "Goes great with tomato soup!"
|
||||
icon_state = "toastedsandwich"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#D9BE29"
|
||||
list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value?
|
||||
tastes = list("toast" = 1, "grilled cheese" = 1)
|
||||
@@ -192,7 +189,6 @@
|
||||
name = "jelly sandwich"
|
||||
desc = "You wish you had some peanut butter to go with this..."
|
||||
icon_state = "jellysandwich"
|
||||
trash = /obj/item/trash/plate
|
||||
filling_color = "#9E3A78"
|
||||
bitesize = 3
|
||||
tastes = list("toast" = 1, "jelly" = 1)
|
||||
|
||||
@@ -289,8 +289,15 @@
|
||||
/obj/item/CQC_manual/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user) || !user)
|
||||
return
|
||||
to_chat(user, "<span class='boldannounce'>You remember the basics of CQC.</span>")
|
||||
if(user.mind) //Prevents changelings and vampires from being able to learn it
|
||||
if(user.mind.changeling) //Changelings
|
||||
to_chat(user, "<span class='warning'>We try multiple times, but we simply cannot grasp the basics of CQC!</span>")
|
||||
return
|
||||
else if(user.mind.vampire) //Vampires
|
||||
to_chat(user, "<span class='warning'>Your blood lust distracts you from the basics of CQC!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='boldannounce'>You remember the basics of CQC.</span>")
|
||||
var/datum/martial_art/cqc/CQC = new(null)
|
||||
CQC.teach(user)
|
||||
user.drop_item()
|
||||
|
||||
@@ -26,6 +26,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
|
||||
var/ghostvision = TRUE //is the ghost able to see things humans can't?
|
||||
var/seedarkness = TRUE
|
||||
var/seerads = FALSE // can the ghost see radiation?
|
||||
/// Defines from __DEFINES/hud.dm go here based on which huds the ghost has activated.
|
||||
var/list/data_hud_seen = list()
|
||||
var/ghost_orbit = GHOST_ORBIT_CIRCLE
|
||||
@@ -98,6 +99,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
if(orbit_menu)
|
||||
SStgui.close_uis(orbit_menu)
|
||||
QDEL_NULL(orbit_menu)
|
||||
if (seerads)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/mob/dead/observer/examine(mob/user)
|
||||
@@ -105,6 +108,10 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
if(!invisibility)
|
||||
. += "It seems extremely obvious."
|
||||
|
||||
/mob/dead/observer/process()
|
||||
if(seerads)
|
||||
show_rads(5)
|
||||
|
||||
// This seems stupid, but it's the easiest way to avoid absolutely ridiculous shit from happening
|
||||
// Copying an appearance directly from a mob includes it's verb list, it's invisibility, it's alpha, and it's density
|
||||
// You might recognize these things as "fucking ridiculous to put in an appearance"
|
||||
@@ -341,6 +348,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
for(var/datum/atom_hud/antag/H in GLOB.huds)
|
||||
H.add_hud_to(src)
|
||||
|
||||
/mob/dead/observer/proc/set_radiation_view(enabled)
|
||||
if (enabled)
|
||||
seerads = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
seerads = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/mob/dead/observer/verb/set_dnr()
|
||||
set name = "Set DNR"
|
||||
set category = "Ghost"
|
||||
@@ -732,6 +747,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(mind)
|
||||
mind.active = TRUE
|
||||
mind.transfer_to(new_char)
|
||||
if(mind.vampire)
|
||||
mind.vampire.owner = new_char
|
||||
mind.vampire.powers.Cut()
|
||||
mind.vampire.check_vampire_upgrade(FALSE)
|
||||
else
|
||||
new_char.key = key
|
||||
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
|
||||
// Type 1 (Visual) emotes are sent to anyone in view of the item
|
||||
if(m_type & EMOTE_VISUAL)
|
||||
var/runechat_text = input
|
||||
if(length(input) > 100)
|
||||
runechat_text = "[copytext(input, 1, 101)]..."
|
||||
var/list/can_see = get_mobs_in_view(1,src) //Allows silicon & mmi mobs carried around to see the emotes of the person carrying them around.
|
||||
can_see |= viewers(src,null)
|
||||
for(var/mob/O in can_see)
|
||||
@@ -91,7 +94,7 @@
|
||||
|
||||
O.show_message(message, m_type)
|
||||
if(O.client?.prefs.toggles2 & PREFTOGGLE_2_RUNECHAT)
|
||||
O.create_chat_message(src, input, symbol = RUNECHAT_SYMBOL_EMOTE)
|
||||
O.create_chat_message(src, runechat_text, symbol = RUNECHAT_SYMBOL_EMOTE)
|
||||
|
||||
// Type 2 (Audible) emotes are sent to anyone in hear range
|
||||
// of the *LOCATION* -- this is important for pAIs to be heard
|
||||
|
||||
@@ -1459,6 +1459,27 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
|
||||
/mob/proc/update_runechat_msg_location()
|
||||
return
|
||||
|
||||
|
||||
/**
|
||||
* Show an overlay of radiation levels on radioactive objects.
|
||||
*/
|
||||
/mob/proc/show_rads(range)
|
||||
for(var/turf/place in range(range, src))
|
||||
var/rads = SSradiation.get_turf_radiation(place)
|
||||
if (rads < RAD_BACKGROUND_RADIATION)
|
||||
continue
|
||||
|
||||
var/strength = round(rads / 1000, 0.1)
|
||||
var/image/pic = image(loc = place)
|
||||
var/mutable_appearance/MA = new()
|
||||
MA.maptext = MAPTEXT("[strength]k")
|
||||
MA.color = "#04e604"
|
||||
MA.layer = RAD_TEXT_LAYER
|
||||
MA.plane = GAME_PLANE
|
||||
pic.appearance = MA
|
||||
flick_overlay(pic, list(client), 10)
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(holy_areas, typecacheof(list(
|
||||
/area/chapel
|
||||
)))
|
||||
|
||||
@@ -10,6 +10,7 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
|
||||
icon = 'icons/obj/library.dmi'
|
||||
icon_state = "fax"
|
||||
insert_anim = "faxsend"
|
||||
var/receive_anim = "faxsend"
|
||||
pass_flags = PASSTABLE
|
||||
var/fax_network = "Local Fax Network"
|
||||
/// If true, prevents fax machine from sending messages to NT machines
|
||||
@@ -51,11 +52,17 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
|
||||
|
||||
/obj/machinery/photocopier/faxmachine/longrange
|
||||
name = "long range fax machine"
|
||||
icon_state = "longfax"
|
||||
insert_anim = "longfaxsend"
|
||||
receive_anim = "longfaxreceive"
|
||||
fax_network = "Central Command Quantum Entanglement Network"
|
||||
long_range_enabled = TRUE
|
||||
|
||||
/obj/machinery/photocopier/faxmachine/longrange/syndie
|
||||
name = "syndicate long range fax machine"
|
||||
icon_state = "fax"
|
||||
insert_anim = "faxsend"
|
||||
receive_anim = "faxsend"
|
||||
emagged = TRUE
|
||||
syndie_restricted = TRUE
|
||||
req_one_access = list(ACCESS_SYNDICATE)
|
||||
@@ -293,7 +300,7 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
|
||||
if(department == "Unknown")
|
||||
return FALSE //You can't send faxes to "Unknown"
|
||||
|
||||
flick("faxreceive", src)
|
||||
flick(receive_anim, src)
|
||||
|
||||
playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1)
|
||||
|
||||
|
||||
@@ -471,7 +471,7 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
// Definitions
|
||||
////////////////////////////////
|
||||
|
||||
GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restraints", /obj/item/restraints/handcuffs/cable, 15)))
|
||||
GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe/cable_restraints("cable restraints", /obj/item/restraints/handcuffs/cable, 15)))
|
||||
|
||||
/obj/item/stack/cable_coil
|
||||
name = "cable coil"
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
var/knife_x_offset = 0
|
||||
var/knife_y_offset = 0
|
||||
|
||||
var/can_holster = TRUE
|
||||
var/can_holster = FALSE // Anything that can be holstered should be manually set
|
||||
|
||||
var/list/upgrades = list()
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update
|
||||
actions_types = list(/datum/action/item_action/toggle_gunlight)
|
||||
shaded_charge = FALSE
|
||||
can_holster = TRUE // Pistol sized, so it should fit into a holster
|
||||
|
||||
/obj/item/gun/energy/gun/mini/Initialize(mapload, ...)
|
||||
gun_light = new /obj/item/flashlight/seclite(src)
|
||||
@@ -57,6 +58,7 @@
|
||||
ammo_x_offset = 4
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
shaded_charge = FALSE
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/gun/blueshield
|
||||
name = "advanced stun revolver"
|
||||
@@ -67,6 +69,7 @@
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos)
|
||||
ammo_x_offset = 1
|
||||
shaded_charge = TRUE
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/gun/blueshield/pdw9
|
||||
name = "PDW-9 taser pistol"
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
origin_tech = "combat=4;materials=4;biotech=5;plasmatech=6"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/declone)
|
||||
ammo_x_offset = 1
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/decloner/update_icon()
|
||||
..()
|
||||
@@ -56,6 +57,7 @@
|
||||
modifystate = 1
|
||||
ammo_x_offset = 1
|
||||
selfcharge = 1
|
||||
can_holster = TRUE
|
||||
|
||||
// Meteor Gun //
|
||||
/obj/item/gun/energy/meteorgun
|
||||
@@ -109,6 +111,7 @@
|
||||
can_flashlight = 0
|
||||
max_mod_capacity = 0
|
||||
empty_state = null
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/crossbow/detailed_examine()
|
||||
return "This is an energy weapon. To fire the weapon, have your gun mode set to 'fire', \
|
||||
@@ -159,6 +162,7 @@
|
||||
force = 12
|
||||
sharp = 1
|
||||
can_charge = 0
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/plasmacutter/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -297,6 +301,7 @@
|
||||
clumsy_check = 0
|
||||
selfcharge = 1
|
||||
ammo_x_offset = 3
|
||||
can_holster = TRUE // you'll never see it coming
|
||||
|
||||
/obj/item/gun/energy/toxgun
|
||||
name = "plasma pistol"
|
||||
@@ -308,6 +313,7 @@
|
||||
origin_tech = "combat=4;magnets=4;powerstorage=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/toxplasma)
|
||||
shaded_charge = 1
|
||||
can_holster = TRUE
|
||||
|
||||
// Energy Sniper //
|
||||
/obj/item/gun/energy/sniperrifle
|
||||
@@ -636,6 +642,7 @@
|
||||
selfcharge = 1
|
||||
ammo_x_offset = 3
|
||||
var/mimic_type = /obj/item/gun/projectile/automatic/pistol //Setting this to the mimicgun type does exactly what you think it will.
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/mimicgun/newshot()
|
||||
var/obj/item/ammo_casing/energy/mimic/M = ammo_type[select]
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/electrode)
|
||||
ammo_x_offset = 3
|
||||
can_holster = TRUE // Pistol size
|
||||
|
||||
/obj/item/gun/energy/shock_revolver
|
||||
name = "tesla revolver"
|
||||
@@ -16,6 +17,8 @@
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/shock_revolver)
|
||||
can_flashlight = 0
|
||||
shaded_charge = FALSE
|
||||
can_holster = TRUE
|
||||
|
||||
|
||||
/obj/item/gun/energy/gun/advtaser
|
||||
name = "hybrid taser"
|
||||
@@ -26,6 +29,7 @@
|
||||
ammo_x_offset = 2
|
||||
flight_x_offset = 15
|
||||
shaded_charge = FALSE
|
||||
can_holster = TRUE // Pistol size
|
||||
|
||||
/obj/item/gun/energy/gun/advtaser/detailed_examine()
|
||||
return "This is an energy weapon. To recharge this weapon, use a weapon recharger. \
|
||||
@@ -49,6 +53,7 @@
|
||||
origin_tech = "combat=3"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/disabler)
|
||||
ammo_x_offset = 3
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/disabler/cyborg
|
||||
name = "cyborg disabler"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
origin_tech = null
|
||||
clumsy_check = 0
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses magic instead
|
||||
can_holster = FALSE // Nothing here is a gun, and therefore shouldn't really fit into a holster
|
||||
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' //not really a gun and some toys use these inhands
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
var/select = 1
|
||||
can_tactical = TRUE
|
||||
can_suppress = 1
|
||||
can_holster = FALSE
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
@@ -79,7 +78,7 @@
|
||||
//Saber SMG//
|
||||
/obj/item/gun/projectile/automatic/proto
|
||||
name = "\improper Nanotrasen Saber SMG"
|
||||
desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors."
|
||||
desc = "A rejected prototype three-round burst 9mm submachine gun, designated 'SABR'. Surplus of this model are bouncing around armories of Nanotrasen Space Stations. Has a threaded barrel for suppressors."
|
||||
icon_state = "saber"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm9mm
|
||||
origin_tech = "combat=4;materials=2"
|
||||
@@ -143,6 +142,7 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/uzim9mm
|
||||
fire_sound = 'sound/weapons/gunshots/gunshot_pistol.ogg'
|
||||
burst_size = 2
|
||||
can_holster = TRUE // it's a mini-uzi after all
|
||||
|
||||
//M-90gl Carbine//
|
||||
/obj/item/gun/projectile/automatic/m90
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user