Merge branch 'master' into client-data-loading

This commit is contained in:
AffectedArc07
2021-08-29 20:56:41 +01:00
committed by GitHub
152 changed files with 7816 additions and 9426 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+29 -27
View File
@@ -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
+2
View File
@@ -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
+3
View File
@@ -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"
+2
View File
@@ -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
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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
+3 -3
View File
@@ -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)
-2
View File
@@ -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))
-5
View File
@@ -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"])
+16
View File
@@ -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
+5
View File
@@ -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)
+6
View File
@@ -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
+6
View File
@@ -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()
+16
View File
@@ -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()
+8
View File
@@ -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)
+6
View File
@@ -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)
+1 -1
View File
@@ -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
+47
View File
@@ -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")
*/
+6
View File
@@ -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()
+31 -1
View File
@@ -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)
+5
View 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)
+8 -1
View File
@@ -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
+6
View File
@@ -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>",
+6
View File
@@ -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)
+7 -1
View File
@@ -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)
+1
View File
@@ -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
+11 -3
View File
@@ -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()
+12
View File
@@ -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."
+9 -8
View File
@@ -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
+1 -2
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+9 -9
View File
@@ -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"
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -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>")
+5 -2
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+15
View File
@@ -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)
+16 -11
View File
@@ -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)
+9 -3
View File
@@ -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
+9
View File
@@ -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
+2 -2
View File
@@ -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
+23
View File
@@ -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"
+5
View File
@@ -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"
+3 -1
View File
@@ -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
+96 -7
View File
@@ -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)
+1 -1
View File
@@ -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)
+5 -9
View File
@@ -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
..()
+1 -22
View File
@@ -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)
+2
View File
@@ -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.")
+2 -3
View File
@@ -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)
+3 -1
View File
@@ -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,
+61
View File
@@ -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 -1
View File
@@ -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
+3 -11
View File
@@ -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]"
+6
View File
@@ -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
+1 -1
View File
@@ -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"
+2 -1
View File
@@ -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"
+1 -1
View File
@@ -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)
+8 -1
View File
@@ -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
+4 -1
View File
@@ -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
+21
View File
@@ -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
)))
+8 -1
View File
@@ -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)
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
+1
View File
@@ -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