This commit is contained in:
izac112
2023-06-21 19:03:35 +02:00
346 changed files with 5621 additions and 4174 deletions
+74
View File
@@ -0,0 +1,74 @@
#if DM_VERSION >= 515
#error PLEASE MAKE SURE THAT 515 IS PROPERLY TESTED AND WORKS. ESPECIALLY THE SAVE-FILES HAVE TO WORK.
#error Additionally: Make sure that the GitHub Workflow was updated to BYOND 515 as well.
#endif
// These defines are from __513_compatibility.dm -- Please Sort
#define CLAMP(CLVALUE, CLMIN, CLMAX) clamp(CLVALUE, CLMIN, CLMAX)
#define TAN(x) tan(x)
#define ATAN2(x, y) arctan(x, y)
#define between(x, y, z) clamp(y, x, z)
// This file contains defines allowing targeting byond versions newer than the supported
//Update this whenever you need to take advantage of more recent byond features
#define MIN_COMPILER_VERSION 514
#define MIN_COMPILER_BUILD 1556
#if (DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD) && !defined(SPACEMAN_DMM)
//Don't forget to update this part
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
#error You need version 514.1556 or higher
#endif
#if (DM_VERSION == 514 && DM_BUILD > 1575 && DM_BUILD <= 1577)
#error Your version of BYOND currently has a crashing issue that will prevent you from running Dream Daemon test servers.
#error We require developers to test their content, so an inability to test means we cannot allow the compile.
#error Please consider downgrading to 514.1575 or lower.
#endif
// Keep savefile compatibilty at minimum supported level
#if DM_VERSION >= 515
/savefile/byond_version = MIN_COMPILER_VERSION
#endif
// 515 split call for external libraries into call_ext
#if DM_VERSION < 515
#define LIBCALL call
#else
#define LIBCALL call_ext
#endif
// So we want to have compile time guarantees these methods exist on local type, unfortunately 515 killed the .proc/procname and .verb/verbname syntax so we have to use nameof()
// For the record: GLOBAL_VERB_REF would be useless as verbs can't be global.
#if DM_VERSION < 515
/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (.proc/##X)
/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
#define VERB_REF(X) (.verb/##X)
/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (##TYPE.proc/##X)
/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
#define TYPE_VERB_REF(TYPE, X) (##TYPE.verb/##X)
/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)
#else
/// Call by name proc references, checks if the proc exists on either this type or as a global proc.
#define PROC_REF(X) (nameof(.proc/##X))
/// Call by name verb references, checks if the verb exists on either this type or as a global verb.
#define VERB_REF(X) (nameof(.verb/##X))
/// Call by name proc reference, checks if the proc exists on either the given type or as a global proc
#define TYPE_PROC_REF(TYPE, X) (nameof(##TYPE.proc/##X))
/// Call by name verb reference, checks if the verb exists on either the given type or as a global verb
#define TYPE_VERB_REF(TYPE, X) (nameof(##TYPE.verb/##X))
/// Call by name proc reference, checks if the proc is an existing global proc
#define GLOBAL_PROC_REF(X) (/proc/##X)
#endif
-33
View File
@@ -1,33 +0,0 @@
#if DM_VERSION < 513
#define ismovable(A) (istype(A, /atom/movable))
#define islist(L) (istype(L, /list))
#define CLAMP01(x) (CLAMP(x, 0, 1))
#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
#define ATAN2(x, y) ( !(x) && !(y) ? 0 : (y) >= 0 ? arccos((x) / sqrt((x)*(x) + (y)*(y))) : -arccos((x) / sqrt((x)*(x) + (y)*(y))) )
#define TAN(x) (sin(x) / cos(x))
#define arctan(x) (arcsin(x/sqrt(1+x*x)))
#define between(x, y, z) max(min(y, z), x)
//////////////////////////////////////////////////
#else
#define CLAMP01(x) clamp(x, 0, 1)
#define CLAMP(CLVALUE, CLMIN, CLMAX) clamp(CLVALUE, CLMIN, CLMAX)
#define TAN(x) tan(x)
#define ATAN2(x, y) arctan(x, y)
#define between(x, y, z) clamp(y, x, z)
#endif
@@ -1,8 +0,0 @@
//Update this whenever you need to take advantage of more recent byond features
#define MIN_COMPILER_VERSION 514
#define MIN_COMPILER_BUILD 1556
#if (DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD) && !defined(SPACEMAN_DMM)
//Don't forget to update this part
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
#error You need version 514.1556 or higher
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
#define isdatum(D) istype(D, /datum)
#define isweakref(A) istype(A, /weakref)
#define isweakref(A) istype(A, /datum/weakref)
//#define islist(D) istype(D, /list) //Built in
+1
View File
@@ -16,6 +16,7 @@
#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(world.tick_usage - starting_tickusage))
#define PERCENT(val) (round((val)*100, 0.1))
#define CLAMP01(x) clamp(x, 0, 1)
//time of day but automatically adjusts to the server going into the next day within the same round.
//for when you need a reliable time number that doesn't depend on byond time.
+1
View File
@@ -32,6 +32,7 @@
#define SPECIES_XENOCHIMERA "Xenochimera"
#define SPECIES_ZORREN_HIGH "Zorren"
#define SPECIES_CUSTOM "Custom Species"
#define SPECIES_TAJARAN "Tajara"
//monkey species
#define SPECIES_MONKEY_AKULA "Sobaka"
#define SPECIES_MONKEY_NEVREAN "Sparra"
+3 -3
View File
@@ -37,13 +37,13 @@
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
//Qdel helper macros.
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE)
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), item), time, TIMER_STOPPABLE)
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
#define QDEL_NULL(item) if(item) {qdel(item); item = null}
#define QDEL_NULL_LIST QDEL_LIST_NULL
#define QDEL_LIST_NULL(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE)
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(______qdel_list_wrapper), L), time, TIMER_STOPPABLE)
#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); }
#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }
+25 -25
View File
@@ -42,26 +42,26 @@
#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB"
#define RUSTG_JOB_ERROR "JOB PANICKED"
#define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname)
#define rustg_dmi_create_png(path, width, height, data) call(RUST_G, "dmi_create_png")(path, width, height, data)
#define rustg_dmi_strip_metadata(fname) LIBCALL(RUST_G, "dmi_strip_metadata")(fname)
#define rustg_dmi_create_png(path, width, height, data) LIBCALL(RUST_G, "dmi_create_png")(path, width, height, data)
#define rustg_noise_get_at_coordinates(seed, x, y) call(RUST_G, "noise_get_at_coordinates")(seed, x, y)
#define rustg_noise_get_at_coordinates(seed, x, y) LIBCALL(RUST_G, "noise_get_at_coordinates")(seed, x, y)
#define rustg_file_read(fname) call(RUST_G, "file_read")(fname)
#define rustg_file_exists(fname) call(RUST_G, "file_exists")(fname)
#define rustg_file_write(text, fname) call(RUST_G, "file_write")(text, fname)
#define rustg_file_append(text, fname) call(RUST_G, "file_append")(text, fname)
#define rustg_file_read(fname) LIBCALL(RUST_G, "file_read")(fname)
#define rustg_file_exists(fname) LIBCALL(RUST_G, "file_exists")(fname)
#define rustg_file_write(text, fname) LIBCALL(RUST_G, "file_write")(text, fname)
#define rustg_file_append(text, fname) LIBCALL(RUST_G, "file_append")(text, fname)
#ifdef RUSTG_OVERRIDE_BUILTINS
#define file2text(fname) rustg_file_read("[fname]")
#define text2file(text, fname) rustg_file_append(text, "[fname]")
#endif
#define rustg_git_revparse(rev) call(RUST_G, "rg_git_revparse")(rev)
#define rustg_git_commit_date(rev) call(RUST_G, "rg_git_commit_date")(rev)
#define rustg_git_revparse(rev) LIBCALL(RUST_G, "rg_git_revparse")(rev)
#define rustg_git_commit_date(rev) LIBCALL(RUST_G, "rg_git_commit_date")(rev)
#define rustg_hash_string(algorithm, text) call(RUST_G, "hash_string")(algorithm, text)
#define rustg_hash_file(algorithm, fname) call(RUST_G, "hash_file")(algorithm, fname)
#define rustg_hash_string(algorithm, text) LIBCALL(RUST_G, "hash_string")(algorithm, text)
#define rustg_hash_file(algorithm, fname) LIBCALL(RUST_G, "hash_file")(algorithm, fname)
#define RUSTG_HASH_MD5 "md5"
#define RUSTG_HASH_SHA1 "sha1"
@@ -72,13 +72,13 @@
#define md5(thing) (isfile(thing) ? rustg_hash_file(RUSTG_HASH_MD5, "[thing]") : rustg_hash_string(RUSTG_HASH_MD5, thing))
#endif
#define rustg_json_is_valid(text) (call(RUST_G, "json_is_valid")(text) == "true")
#define rustg_json_is_valid(text) (LIBCALL(RUST_G, "json_is_valid")(text) == "true")
#define rustg_log_write(fname, text, format) call(RUST_G, "log_write")(fname, text, format)
/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")()
#define rustg_log_write(fname, text, format) LIBCALL(RUST_G, "log_write")(fname, text, format)
/proc/rustg_log_close_all() return LIBCALL(RUST_G, "log_close_all")()
#define rustg_url_encode(text) call(RUST_G, "url_encode")(text)
#define rustg_url_decode(text) call(RUST_G, "url_decode")(text)
#define rustg_url_encode(text) LIBCALL(RUST_G, "url_encode")(text)
#define rustg_url_decode(text) LIBCALL(RUST_G, "url_decode")(text)
#ifdef RUSTG_OVERRIDE_BUILTINS
#define url_encode(text) rustg_url_encode(text)
@@ -91,13 +91,13 @@
#define RUSTG_HTTP_METHOD_PATCH "patch"
#define RUSTG_HTTP_METHOD_HEAD "head"
#define RUSTG_HTTP_METHOD_POST "post"
#define rustg_http_request_blocking(method, url, body, headers) call(RUST_G, "http_request_blocking")(method, url, body, headers)
#define rustg_http_request_async(method, url, body, headers) call(RUST_G, "http_request_async")(method, url, body, headers)
#define rustg_http_check_request(req_id) call(RUST_G, "http_check_request")(req_id)
#define rustg_http_request_blocking(method, url, body, headers) LIBCALL(RUST_G, "http_request_blocking")(method, url, body, headers)
#define rustg_http_request_async(method, url, body, headers) LIBCALL(RUST_G, "http_request_async")(method, url, body, headers)
#define rustg_http_check_request(req_id) LIBCALL(RUST_G, "http_check_request")(req_id)
#define rustg_sql_connect_pool(options) call(RUST_G, "sql_connect_pool")(options)
#define rustg_sql_query_async(handle, query, params) call(RUST_G, "sql_query_async")(handle, query, params)
#define rustg_sql_query_blocking(handle, query, params) call(RUST_G, "sql_query_blocking")(handle, query, params)
#define rustg_sql_connected(handle) call(RUST_G, "sql_connected")(handle)
#define rustg_sql_disconnect_pool(handle) call(RUST_G, "sql_disconnect_pool")(handle)
#define rustg_sql_check_query(job_id) call(RUST_G, "sql_check_query")("[job_id]")
#define rustg_sql_connect_pool(options) LIBCALL(RUST_G, "sql_connect_pool")(options)
#define rustg_sql_query_async(handle, query, params) LIBCALL(RUST_G, "sql_query_async")(handle, query, params)
#define rustg_sql_query_blocking(handle, query, params) LIBCALL(RUST_G, "sql_query_blocking")(handle, query, params)
#define rustg_sql_connected(handle) LIBCALL(RUST_G, "sql_connected")(handle)
#define rustg_sql_disconnect_pool(handle) LIBCALL(RUST_G, "sql_disconnect_pool")(handle)
#define rustg_sql_check_query(job_id) LIBCALL(RUST_G, "sql_check_query")("[job_id]")
+33
View File
@@ -0,0 +1,33 @@
/// Define that just has the current in-universe year for use in whatever context you might want to display that in. (For example, 2022 -> 2562 given a 540 year offset)
#define CURRENT_STATION_YEAR (GLOB.year_integer + STATION_YEAR_OFFSET)
/// In-universe, SS13 is set 300 years in the future from the real-world day, hence this number for determining the year-offset for the in-game year.
#define STATION_YEAR_OFFSET 300
#define MILISECOND * 0.01
#define MILLISECONDS * 0.01
#define DECISECONDS *1 //the base unit all of these defines are scaled by, because byond uses that as a unit of measurement for some reason
#define SECOND *10
#define SECONDS *10
#define MINUTE *600
#define MINUTES *600
#define HOUR *36000
#define HOURS *36000
#define DAY *864000
#define DAYS *864000
#define TICK *world.tick_lag
#define TICKS *world.tick_lag
#define DS2TICKS(DS) ((DS)/world.tick_lag)
#define TICKS2DS(T) ((T) TICKS)
#define MS2DS(T) ((T) MILLISECONDS)
#define DS2MS(T) ((T) * 100)
+2
View File
@@ -55,3 +55,5 @@
// /atom
#define VV_HK_ATOM_EXPLODE "turf_explode"
#define VV_HK_ATOM_EMP "turf_emp"
#define VV_HK_WEAKREF_RESOLVE "weakref_resolve"
+1 -1
View File
@@ -9,5 +9,5 @@ GLOBAL_LIST_EMPTY(wire_name_directory) // This is an associative list
GLOBAL_LIST_EMPTY(tagger_locations)
GLOBAL_LIST_INIT(char_directory_tags, list("Pred", "Pred-Pref", "Prey", "Prey-Pref", "Switch", "Non-Vore", "Unset"))
GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset"))
GLOBAL_LIST_INIT(char_directory_erptags, list("Dominant", "Dom-Pref", "Submissive", "Sub-Pref", "Switch", "No ERP", "Unset"))
GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes
+2
View File
@@ -0,0 +1,2 @@
GLOBAL_VAR_INIT(year, time2text(world.realtime,"YYYY"))
GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013???
+3 -3
View File
@@ -206,7 +206,7 @@ GLOBAL_LIST_EMPTY(mannequins)
GLOB.all_species[S.name] = S
//Shakey shakey shake
sortTim(GLOB.all_species, /proc/cmp_species, associative = TRUE)
sortTim(GLOB.all_species, GLOBAL_PROC_REF(cmp_species), associative = TRUE)
//Split up the rest
for(var/speciesname in GLOB.all_species)
@@ -238,7 +238,7 @@ GLOBAL_LIST_EMPTY(mannequins)
for(var/oretype in paths)
var/ore/OD = new oretype()
GLOB.ore_data[OD.name] = OD
paths = subtypesof(/datum/alloy)
for(var/alloytype in paths)
GLOB.alloy_data += new alloytype()
@@ -310,7 +310,7 @@ GLOBAL_LIST_EMPTY(mannequins)
/proc/init_crafting_recipes(list/crafting_recipes)
for(var/path in subtypesof(/datum/crafting_recipe))
var/datum/crafting_recipe/recipe = new path()
recipe.reqs = sortList(recipe.reqs, /proc/cmp_crafting_req_priority)
recipe.reqs = sortList(recipe.reqs, GLOBAL_PROC_REF(cmp_crafting_req_priority))
crafting_recipes += recipe
return crafting_recipes
/* // Uncomment to debug chemical reaction list.
+1 -1
View File
@@ -541,7 +541,7 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
all_traits[path] = instance
// Shakey shakey shake
sortTim(all_traits, /proc/cmp_trait_datums_name, associative = TRUE)
sortTim(all_traits, GLOBAL_PROC_REF(cmp_trait_datums_name), associative = TRUE)
// Split 'em up
for(var/traitpath in all_traits)
+5 -5
View File
@@ -215,7 +215,7 @@
break
layers[current] = current_layer
//sortTim(layers, /proc/cmp_image_layer_asc)
//sortTim(layers, GLOBAL_PROC_REF(cmp_image_layer_asc))
var/icon/add // Icon of overlay being added
@@ -384,15 +384,15 @@ GLOBAL_LIST_EMPTY(icon_state_lists)
GLOBAL_LIST_EMPTY(cached_examine_icons)
/proc/set_cached_examine_icon(var/atom/A, var/icon/I, var/expiry = 12000)
GLOB.cached_examine_icons[weakref(A)] = I
GLOB.cached_examine_icons[WEAKREF(A)] = I
if(expiry)
addtimer(CALLBACK(GLOBAL_PROC, .proc/uncache_examine_icon, weakref(A)), expiry, TIMER_UNIQUE)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(uncache_examine_icon), WEAKREF(A)), expiry, TIMER_UNIQUE)
/proc/get_cached_examine_icon(var/atom/A)
var/weakref/WR = weakref(A)
var/datum/weakref/WR = WEAKREF(A)
return GLOB.cached_examine_icons[WR]
/proc/uncache_examine_icon(var/weakref/WR)
/proc/uncache_examine_icon(var/datum/weakref/WR)
GLOB.cached_examine_icons -= WR
/proc/adjust_brightness(var/color, var/value)
+169 -193
View File
@@ -1,193 +1,169 @@
#define MILISECOND * 0.01
#define MILLISECONDS * 0.01
#define SECOND *10
#define SECONDS *10
#define MINUTE *600
#define MINUTES *600
#define HOUR *36000
#define HOURS *36000
#define DAY *864000
#define DAYS *864000
#define TimeOfGame (get_game_time())
#define TimeOfTick (TICK_USAGE*0.01*world.tick_lag)
#define TICK *world.tick_lag
#define TICKS *world.tick_lag
#define DS2TICKS(DS) ((DS)/world.tick_lag) // Convert deciseconds to ticks
#define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds
#define DS2NEARESTTICK(DS) TICKS2DS(-round(-(DS2TICKS(DS))))
#define MS2DS(T) ((T) MILLISECONDS)
#define DS2MS(T) ((T) * 100)
var/world_startup_time
/proc/get_game_time()
var/global/time_offset = 0
var/global/last_time = 0
var/global/last_usage = 0
var/wtime = world.time
var/wusage = TICK_USAGE * 0.01
if(last_time < wtime && last_usage > 1)
time_offset += last_usage - 1
last_time = wtime
last_usage = wusage
return wtime + (time_offset + wusage) * world.tick_lag
GLOBAL_VAR_INIT(roundstart_hour, pick(2,7,12,17))
var/station_date = ""
var/next_station_date_change = 1 DAY
#define duration2stationtime(time) time2text(station_time_in_ds + time, "hh:mm")
#define roundstart_delay_time (world.time - round_duration_in_ds)
#define world_time_in_ds(time) (GLOB.roundstart_hour HOURS + time - roundstart_delay_time)
#define round_duration_in_ds (GLOB.round_start_time ? REALTIMEOFDAY - GLOB.round_start_time : 0)
#define station_time_in_ds (GLOB.roundstart_hour HOURS + round_duration_in_ds)
/proc/stationtime2text()
return time2text(station_time_in_ds + GLOB.timezoneOffset, "hh:mm")
/proc/worldtime2stationtime(time)
return time2text(world_time_in_ds(time) + GLOB.timezoneOffset, "hh:mm")
/proc/stationdate2text()
var/update_time = FALSE
if(station_time_in_ds > next_station_date_change)
next_station_date_change += 1 DAY
update_time = TRUE
if(!station_date || update_time)
station_date = num2text((text2num(time2text(REALTIMEOFDAY, "YYYY"))+544)) + "-" + time2text(REALTIMEOFDAY, "MM-DD") //YW EDIT
return station_date
//ISO 8601
/proc/time_stamp()
var/date_portion = time2text(world.timeofday, "YYYY-MM-DD")
var/time_portion = time2text(world.timeofday, "hh:mm:ss")
return "[date_portion]T[time_portion]"
/proc/get_timezone_offset()
var/midnight_gmt_here = text2num(time2text(0,"hh")) * 36000
if(midnight_gmt_here > 12 HOURS)
return 24 HOURS - midnight_gmt_here
else
return midnight_gmt_here
/proc/gameTimestamp(format = "hh:mm:ss", wtime=null)
if(!wtime)
wtime = world.time
return time2text(wtime - GLOB.timezoneOffset, format)
/* Returns 1 if it is the selected month and day */
/proc/isDay(var/month, var/day)
if(isnum(month) && isnum(day))
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
if(month == MM && day == DD)
return 1
// Uncomment this out when debugging!
//else
//return 1
var/next_duration_update = 0
var/last_round_duration = 0
GLOBAL_VAR_INIT(round_start_time, 0)
/hook/roundstart/proc/start_timer()
GLOB.round_start_time = REALTIMEOFDAY
return 1
/proc/roundduration2text()
if(!GLOB.round_start_time)
return "00:00"
if(last_round_duration && world.time < next_duration_update)
return last_round_duration
var/mills = round_duration_in_ds // 1/10 of a second, not real milliseconds but whatever
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
var/mins = round((mills % 36000) / 600)
var/hours = round(mills / 36000)
mins = mins < 10 ? add_zero(mins, 1) : mins
hours = hours < 10 ? add_zero(hours, 1) : hours
last_round_duration = "[hours]:[mins]"
next_duration_update = world.time + 1 MINUTES
return last_round_duration
/var/midnight_rollovers = 0
/var/rollovercheck_last_timeofday = 0
/var/rollover_safety_date = 0 // set in world/New to the server startup day-of-month
/proc/update_midnight_rollover()
// Day has wrapped (world.timeofday drops to 0 at the start of each real day)
if (world.timeofday < rollovercheck_last_timeofday)
// If the day started/last wrap was < 12 hours ago, this is spurious
if(rollover_safety_date < world.realtime - (12 HOURS))
midnight_rollovers++
rollover_safety_date = world.realtime
else
warning("Time rollover error: world.timeofday decreased from previous check, but the day or last rollover is less than 12 hours old. System clock?")
rollovercheck_last_timeofday = world.timeofday
return midnight_rollovers
//Increases delay as the server gets more overloaded,
//as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful
#define DELTA_CALC max(((max(TICK_USAGE, world.cpu) / 100) * max(Master.sleep_delta-1,1)), 1)
//returns the number of ticks slept
/proc/stoplag(initial_delay)
if (!Master || !(Master.current_runlevel & RUNLEVELS_DEFAULT))
sleep(world.tick_lag)
return 1
if (!initial_delay)
initial_delay = world.tick_lag
. = 0
var/i = DS2TICKS(initial_delay)
do
. += CEILING(i*DELTA_CALC, 1)
sleep(i*world.tick_lag*DELTA_CALC)
i *= 2
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))
#undef DELTA_CALC
//Takes a value of time in deciseconds.
//Returns a text value of that number in hours, minutes, or seconds.
/proc/DisplayTimeText(time_value, round_seconds_to = 0.1)
var/second = round(time_value * 0.1, round_seconds_to)
if(!second)
return "right now"
if(second < 60)
return "[second] second[(second != 1)? "s":""]"
var/minute = FLOOR(second / 60, 1)
second = MODULUS(second, 60)
var/secondT
if(second)
secondT = " and [second] second[(second != 1)? "s":""]"
if(minute < 60)
return "[minute] minute[(minute != 1)? "s":""][secondT]"
var/hour = FLOOR(minute / 60, 1)
minute = MODULUS(minute, 60)
var/minuteT
if(minute)
minuteT = " and [minute] minute[(minute != 1)? "s":""]"
if(hour < 24)
return "[hour] hour[(hour != 1)? "s":""][minuteT][secondT]"
var/day = FLOOR(hour / 24, 1)
hour = MODULUS(hour, 24)
var/hourT
if(hour)
hourT = " and [hour] hour[(hour != 1)? "s":""]"
return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]"
#define TimeOfGame (get_game_time())
#define TimeOfTick (TICK_USAGE*0.01*world.tick_lag)
#define DS2NEARESTTICK(DS) TICKS2DS(-round(-(DS2TICKS(DS))))
var/world_startup_time
/proc/get_game_time()
var/global/time_offset = 0
var/global/last_time = 0
var/global/last_usage = 0
var/wtime = world.time
var/wusage = TICK_USAGE * 0.01
if(last_time < wtime && last_usage > 1)
time_offset += last_usage - 1
last_time = wtime
last_usage = wusage
return wtime + (time_offset + wusage) * world.tick_lag
GLOBAL_VAR_INIT(roundstart_hour, pick(2,7,12,17))
var/station_date = ""
var/next_station_date_change = 1 DAY
#define duration2stationtime(time) time2text(station_time_in_ds + time, "hh:mm")
#define roundstart_delay_time (world.time - round_duration_in_ds)
#define world_time_in_ds(time) (GLOB.roundstart_hour HOURS + time - roundstart_delay_time)
#define round_duration_in_ds (GLOB.round_start_time ? REALTIMEOFDAY - GLOB.round_start_time : 0)
#define station_time_in_ds (GLOB.roundstart_hour HOURS + round_duration_in_ds)
/proc/stationtime2text()
return time2text(station_time_in_ds + GLOB.timezoneOffset, "hh:mm")
/proc/worldtime2stationtime(time)
return time2text(world_time_in_ds(time) + GLOB.timezoneOffset, "hh:mm")
/proc/stationdate2text()
var/update_time = FALSE
if(station_time_in_ds > next_station_date_change)
next_station_date_change += 1 DAY
update_time = TRUE
if(!station_date || update_time)
station_date = num2text((text2num(time2text(REALTIMEOFDAY, "YYYY"))+544)) + "-" + time2text(REALTIMEOFDAY, "MM-DD") //YW EDIT
return station_date
//ISO 8601
/proc/time_stamp()
var/date_portion = time2text(world.timeofday, "YYYY-MM-DD")
var/time_portion = time2text(world.timeofday, "hh:mm:ss")
return "[date_portion]T[time_portion]"
/proc/get_timezone_offset()
var/midnight_gmt_here = text2num(time2text(0,"hh")) * 36000
if(midnight_gmt_here > 12 HOURS)
return 24 HOURS - midnight_gmt_here
else
return midnight_gmt_here
/proc/gameTimestamp(format = "hh:mm:ss", wtime=null)
if(!wtime)
wtime = world.time
return time2text(wtime - GLOB.timezoneOffset, format)
/* Returns 1 if it is the selected month and day */
/proc/isDay(var/month, var/day)
if(isnum(month) && isnum(day))
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
if(month == MM && day == DD)
return 1
// Uncomment this out when debugging!
//else
//return 1
var/next_duration_update = 0
var/last_round_duration = 0
GLOBAL_VAR_INIT(round_start_time, 0)
/hook/roundstart/proc/start_timer()
GLOB.round_start_time = REALTIMEOFDAY
return 1
/proc/roundduration2text()
if(!GLOB.round_start_time)
return "00:00"
if(last_round_duration && world.time < next_duration_update)
return last_round_duration
var/mills = round_duration_in_ds // 1/10 of a second, not real milliseconds but whatever
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
var/mins = round((mills % 36000) / 600)
var/hours = round(mills / 36000)
mins = mins < 10 ? add_zero(mins, 1) : mins
hours = hours < 10 ? add_zero(hours, 1) : hours
last_round_duration = "[hours]:[mins]"
next_duration_update = world.time + 1 MINUTES
return last_round_duration
/var/midnight_rollovers = 0
/var/rollovercheck_last_timeofday = 0
/var/rollover_safety_date = 0 // set in world/New to the server startup day-of-month
/proc/update_midnight_rollover()
// Day has wrapped (world.timeofday drops to 0 at the start of each real day)
if (world.timeofday < rollovercheck_last_timeofday)
// If the day started/last wrap was < 12 hours ago, this is spurious
if(rollover_safety_date < world.realtime - (12 HOURS))
midnight_rollovers++
rollover_safety_date = world.realtime
else
warning("Time rollover error: world.timeofday decreased from previous check, but the day or last rollover is less than 12 hours old. System clock?")
rollovercheck_last_timeofday = world.timeofday
return midnight_rollovers
//Increases delay as the server gets more overloaded,
//as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful
#define DELTA_CALC max(((max(TICK_USAGE, world.cpu) / 100) * max(Master.sleep_delta-1,1)), 1)
//returns the number of ticks slept
/proc/stoplag(initial_delay)
if (!Master || !(Master.current_runlevel & RUNLEVELS_DEFAULT))
sleep(world.tick_lag)
return 1
if (!initial_delay)
initial_delay = world.tick_lag
. = 0
var/i = DS2TICKS(initial_delay)
do
. += CEILING(i*DELTA_CALC, 1)
sleep(i*world.tick_lag*DELTA_CALC)
i *= 2
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))
#undef DELTA_CALC
//Takes a value of time in deciseconds.
//Returns a text value of that number in hours, minutes, or seconds.
/proc/DisplayTimeText(time_value, round_seconds_to = 0.1)
var/second = round(time_value * 0.1, round_seconds_to)
if(!second)
return "right now"
if(second < 60)
return "[second] second[(second != 1)? "s":""]"
var/minute = FLOOR(second / 60, 1)
second = MODULUS(second, 60)
var/secondT
if(second)
secondT = " and [second] second[(second != 1)? "s":""]"
if(minute < 60)
return "[minute] minute[(minute != 1)? "s":""][secondT]"
var/hour = FLOOR(minute / 60, 1)
minute = MODULUS(minute, 60)
var/minuteT
if(minute)
minuteT = " and [minute] minute[(minute != 1)? "s":""]"
if(hour < 24)
return "[hour] hour[(hour != 1)? "s":""][minuteT][secondT]"
var/day = FLOOR(hour / 24, 1)
hour = MODULUS(hour, 24)
var/hourT
if(hour)
hourT = " and [hour] hour[(hour != 1)? "s":""]"
return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]"
+3 -3
View File
@@ -626,7 +626,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
//Returns: all the areas in the world, sorted.
/proc/return_sorted_areas()
return sortTim(return_areas(), /proc/cmp_text_asc)
return sortTim(return_areas(), GLOBAL_PROC_REF(cmp_text_asc))
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all turfs in areas of that type of that type in the world.
@@ -1350,9 +1350,9 @@ var/mob/dview/dview_mob = new
//datum may be null, but it does need to be a typed var
#define NAMEOF(datum, X) (#X || ##datum.##X)
#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##target, ##var_name, ##var_value)
#define VARSET_LIST_CALLBACK(target, var_name, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), ##target, ##var_name, ##var_value)
//dupe code because dm can't handle 3 level deep macros
#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, /proc/___callbackvarset, ##datum, NAMEOF(##datum, ##var), ##var_value)
#define VARSET_CALLBACK(datum, var, var_value) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___callbackvarset), ##datum, NAMEOF(##datum, ##var), ##var_value)
//we'll see about those 3-level deep macros
#define VARSET_IN(datum, var, var_value, time) addtimer(VARSET_CALLBACK(datum, var, var_value), time)
+1 -1
View File
@@ -302,7 +302,7 @@ GLOBAL_LIST_INIT(master_filter_info, list(
/atom/proc/update_filters()
filters = null
filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE)
filter_data = sortTim(filter_data, GLOBAL_PROC_REF(cmp_filter_data_priority), TRUE)
for(var/f in filter_data)
var/list/data = filter_data[f]
var/list/arguments = data.Copy()
+2 -2
View File
@@ -21,7 +21,7 @@
if(!Adjacent(usr) || !over.Adjacent(usr))
return // should stop you from dragging through windows
INVOKE_ASYNC(over, /atom/.proc/MouseDrop_T, src, usr, src_location, over_location, src_control, over_control, params)
INVOKE_ASYNC(over, TYPE_PROC_REF(/atom, MouseDrop_T), src, usr, src_location, over_location, src_control, over_control, params)
/atom/proc/MouseDrop_T(atom/dropping, mob/user, src_location, over_location, src_control, over_control, params)
return
return
+2 -2
View File
@@ -53,7 +53,7 @@
animate(alert, transform = matrix(), time = 2.5, easing = CUBIC_EASING)
if(alert.timeout)
addtimer(CALLBACK(src, .proc/alert_timeout, alert, category), alert.timeout)
addtimer(CALLBACK(src, PROC_REF(alert_timeout), alert, category), alert.timeout)
alert.timeout = world.time + alert.timeout - world.tick_lag
return alert
@@ -436,7 +436,7 @@ so as to remain in compliance with the most up-to-date laws."
if(alert.icon_state in cached_icon_states(ui_style))
alert.icon = ui_style
else if(!alert.no_underlay)
var/image/I = image(icon = ui_style, icon_state = "template")
I.color = ui_color
+6 -6
View File
@@ -68,7 +68,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
qdel(Master)
else
var/list/subsytem_types = subtypesof(/datum/controller/subsystem)
sortTim(subsytem_types, /proc/cmp_subsystem_init)
sortTim(subsytem_types, GLOBAL_PROC_REF(cmp_subsystem_init))
for(var/I in subsytem_types)
_subsystems += new I
Master = src
@@ -83,7 +83,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
/datum/controller/master/Shutdown()
processing = FALSE
sortTim(subsystems, /proc/cmp_subsystem_init)
sortTim(subsystems, GLOBAL_PROC_REF(cmp_subsystem_init))
reverseRange(subsystems)
for(var/datum/controller/subsystem/ss in subsystems)
log_world("Shutting down [ss.name] subsystem...")
@@ -173,7 +173,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
to_chat(world, "<span class='boldannounce'>MC: Initializing subsystems...</span>")
// Sort subsystems by init_order, so they initialize in the correct order.
sortTim(subsystems, /proc/cmp_subsystem_init)
sortTim(subsystems, GLOBAL_PROC_REF(cmp_subsystem_init))
var/start_timeofday = REALTIMEOFDAY
// Initialize subsystems.
@@ -199,7 +199,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
GLOB.revdata = new // It can load revdata now, from tgs or .git or whatever
// Sort subsystems by display setting for easy access.
sortTim(subsystems, /proc/cmp_subsystem_display)
sortTim(subsystems, GLOBAL_PROC_REF(cmp_subsystem_display))
// Set world options.
#ifdef UNIT_TEST
world.sleep_offline = 0
@@ -279,9 +279,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
queue_tail = null
//these sort by lower priorities first to reduce the number of loops needed to add subsequent SS's to the queue
//(higher subsystems will be sooner in the queue, adding them later in the loop means we don't have to loop thru them next queue add)
sortTim(tickersubsystems, /proc/cmp_subsystem_priority)
sortTim(tickersubsystems, GLOBAL_PROC_REF(cmp_subsystem_priority))
for(var/I in runlevel_sorted_subsystems)
sortTim(runlevel_sorted_subsystems, /proc/cmp_subsystem_priority)
sortTim(runlevel_sorted_subsystems, GLOBAL_PROC_REF(cmp_subsystem_priority))
I += tickersubsystems
var/cached_runlevel = current_runlevel
+2 -2
View File
@@ -14,5 +14,5 @@ SUBSYSTEM_DEF(assets)
preload = cache.Copy() //don't preload assets generated during the round
for(var/client/C in GLOB.clients)
addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
return ..()
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(getFilesSlow), C, preload, FALSE), 10)
return ..()
+5 -5
View File
@@ -37,11 +37,11 @@ SUBSYSTEM_DEF(job)
if(LAZYLEN(job.departments))
add_to_departments(job)
sortTim(occupations, /proc/cmp_job_datums)
sortTim(occupations, GLOBAL_PROC_REF(cmp_job_datums))
for(var/D in department_datums)
var/datum/department/dept = department_datums[D]
sortTim(dept.jobs, /proc/cmp_job_datums, TRUE)
sortTim(dept.primary_jobs, /proc/cmp_job_datums, TRUE)
sortTim(dept.jobs, GLOBAL_PROC_REF(cmp_job_datums), TRUE)
sortTim(dept.primary_jobs, GLOBAL_PROC_REF(cmp_job_datums), TRUE)
return TRUE
@@ -69,7 +69,7 @@ SUBSYSTEM_DEF(job)
var/datum/department/D = new t()
department_datums[D.name] = D
sortTim(department_datums, /proc/cmp_department_datums, TRUE)
sortTim(department_datums, GLOBAL_PROC_REF(cmp_department_datums), TRUE)
/datum/controller/subsystem/job/proc/get_all_department_datums()
var/list/dept_datums = list()
@@ -140,4 +140,4 @@ SUBSYSTEM_DEF(job)
/datum/controller/subsystem/job/proc/job_debug_message(message)
if(debug_messages)
log_debug("JOB DEBUG: [message]")
log_debug("JOB DEBUG: [message]")
+42 -16
View File
@@ -30,60 +30,86 @@ SUBSYSTEM_DEF(lighting)
MC_SPLIT_TICK_INIT(3)
if(!init_tick_checks)
MC_SPLIT_TICK
var/list/queue = sources_queue
var/i = 0
for (i in 1 to length(queue))
var/datum/light_source/L = queue[i]
// UPDATE SOURCE QUEUE
queue = sources_queue
while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration
i += 1
var/datum/light_source/L = queue[i]
L.update_corners()
L.needs_update = LIGHTING_NO_UPDATE
if(!QDELETED(L))
L.needs_update = LIGHTING_NO_UPDATE
else
i -= 1 // update_corners() has removed L from the list, move back so we don't overflow or skip the next element
// We unroll TICK_CHECK here so we can clear out the queue to ensure any removals/additions when sleeping don't fuck us
if(init_tick_checks)
CHECK_TICK
if(!TICK_CHECK)
continue
queue.Cut(1, i + 1)
i = 0
stoplag()
else if (MC_TICK_CHECK)
break
if (i)
queue.Cut(1, i+1)
queue.Cut(1, i + 1)
i = 0
if(!init_tick_checks)
MC_SPLIT_TICK
// UPDATE CORNERS QUEUE
queue = corners_queue
for (i in 1 to length(queue))
var/datum/lighting_corner/C = queue[i]
while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration
i += 1
var/datum/lighting_corner/C = queue[i]
C.needs_update = FALSE //update_objects() can call qdel if the corner is storing no data
C.update_objects()
// We unroll TICK_CHECK here so we can clear out the queue to ensure any removals/additions when sleeping don't fuck us
if(init_tick_checks)
CHECK_TICK
if(!TICK_CHECK)
continue
queue.Cut(1, i + 1)
i = 0
stoplag()
else if (MC_TICK_CHECK)
break
if (i)
queue.Cut(1, i+1)
queue.Cut(1, i + 1)
i = 0
if(!init_tick_checks)
MC_SPLIT_TICK
// UPDATE OBJECTS QUEUE
queue = objects_queue
for (i in 1 to length(queue))
var/datum/lighting_object/O = queue[i]
while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration
i += 1
var/datum/lighting_object/O = queue[i]
if (QDELETED(O))
continue
O.update()
O.needs_update = FALSE
// We unroll TICK_CHECK here so we can clear out the queue to ensure any removals/additions when sleeping don't fuck us
if(init_tick_checks)
CHECK_TICK
if(!TICK_CHECK)
continue
queue.Cut(1, i + 1)
i = 0
stoplag()
else if (MC_TICK_CHECK)
break
if (i)
queue.Cut(1, i+1)
queue.Cut(1, i + 1)
/datum/controller/subsystem/lighting/Recover()
+26 -26
View File
@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(media_tracks)
name = "Media Tracks"
flags = SS_NO_FIRE
init_order = INIT_ORDER_MEDIA_TRACKS
/// Every track, including secret
var/list/all_tracks = list()
/// Non-secret jukebox tracks
@@ -18,19 +18,19 @@ SUBSYSTEM_DEF(media_tracks)
/datum/controller/subsystem/media_tracks/proc/load_tracks()
for(var/filename in config.jukebox_track_files)
report_progress("Loading jukebox track: [filename]")
if(!fexists(filename))
error("File not found: [filename]")
continue
var/list/jsonData = json_decode(file2text(filename))
if(!istype(jsonData))
error("Failed to read tracks from [filename], json_decode failed.")
continue
for(var/entry in jsonData)
// Critical problems that will prevent the track from working
if(!istext(entry["url"]))
error("Jukebox entry in [filename]: bad or missing 'url'. Tracks must have a URL.")
@@ -47,21 +47,21 @@ SUBSYSTEM_DEF(media_tracks)
warning("Jukebox entry in [filename], [entry["title"]]: bad or missing 'artist'. Please consider crediting the artist.")
if(!istext(entry["genre"]))
warning("Jukebox entry in [filename], [entry["title"]]: bad or missing 'genre'. Please consider adding a genre.")
var/datum/track/T = new(entry["url"], entry["title"], entry["duration"], entry["artist"], entry["genre"])
T.secret = entry["secret"] ? 1 : 0
T.lobby = entry["lobby"] ? 1 : 0
all_tracks += T
/datum/controller/subsystem/media_tracks/proc/sort_tracks()
report_progress("Sorting media tracks...")
sortTim(all_tracks, /proc/cmp_media_track_asc)
sortTim(all_tracks, GLOBAL_PROC_REF(cmp_media_track_asc))
jukebox_tracks.Cut()
lobby_tracks.Cut()
for(var/datum/track/T in all_tracks)
if(!T.secret)
jukebox_tracks += T
@@ -72,7 +72,7 @@ SUBSYSTEM_DEF(media_tracks)
var/client/C = usr.client
if(!check_rights(R_DEBUG|R_FUN))
return
// Required
var/url = tgui_input_text(C, "REQUIRED: Provide URL for track, or paste JSON if you know what you're doing. See code comments.", "Track URL", multiline = TRUE)
if(!url)
@@ -95,7 +95,7 @@ SUBSYSTEM_DEF(media_tracks)
* "secret": only on hacked jukeboxes (true/false)
* "lobby": plays in the lobby (true/false)
*/
if(islist(json))
for(var/song in json)
if(!islist(song))
@@ -104,18 +104,18 @@ SUBSYSTEM_DEF(media_tracks)
var/list/songdata = song
if(!songdata["url"] || !songdata["title"] || !songdata["duration"])
to_chat(C, "<span class='warning'>URL, Title, or Duration was missing from a song. Skipping.</span>")
continue
continue
var/datum/track/T = new(songdata["url"], songdata["title"], songdata["duration"], songdata["artist"], songdata["genre"], songdata["secret"], songdata["lobby"])
all_tracks += T
report_progress("New media track added by [C]: [T.title]")
sort_tracks()
return
var/title = tgui_input_text(C, "REQUIRED: Provide title for track", "Track Title")
if(!title)
return
var/duration = tgui_input_number(C, "REQUIRED: Provide duration for track (in deciseconds, aka seconds*10)", "Track Duration")
if(!duration)
return
@@ -124,11 +124,11 @@ SUBSYSTEM_DEF(media_tracks)
var/artist = tgui_input_text(C, "Optional: Provide artist for track", "Track Artist")
if(isnull(artist)) // Cancel rather than empty string
return
var/genre = tgui_input_text(C, "Optional: Provide genre for track (try to match an existing one)", "Track Genre")
if(isnull(genre)) // Cancel rather than empty string
return
var/secret = tgui_alert(C, "Optional: Mark track as secret?", "Track Secret", list("Yes", "Cancel", "No"))
if(secret == "Cancel")
return
@@ -136,7 +136,7 @@ SUBSYSTEM_DEF(media_tracks)
secret = TRUE
else
secret = FALSE
var/lobby = tgui_alert(C, "Optional: Mark track as lobby music?", "Track Lobby", list("Yes", "Cancel", "No"))
if(lobby == "Cancel")
return
@@ -146,12 +146,12 @@ SUBSYSTEM_DEF(media_tracks)
secret = FALSE
var/datum/track/T = new(url, title, duration, artist, genre)
T.secret = secret
T.lobby = lobby
all_tracks += T
report_progress("New media track added by [C]: [title]")
sort_tracks()
@@ -163,7 +163,7 @@ SUBSYSTEM_DEF(media_tracks)
var/track = tgui_input_text(C, "Input track title or URL to remove (must be exact)", "Remove Track")
if(!track)
return
for(var/datum/track/T in all_tracks)
if(T.title == track || T.url == track)
all_tracks -= T
@@ -171,7 +171,7 @@ SUBSYSTEM_DEF(media_tracks)
report_progress("Media track removed by [C]: [track]")
sort_tracks()
return
to_chat(C, "<span class='warning>Couldn't find a track matching the specified parameters.</span>")
/datum/controller/subsystem/media_tracks/vv_get_dropdown()
+2 -1
View File
@@ -27,6 +27,7 @@ SUBSYSTEM_DEF(tgui)
var/polyfill = file2text('tgui/public/tgui-polyfill.min.js')
polyfill = "<script>\n[polyfill]\n</script>"
basehtml = replacetextEx(basehtml, "<!-- tgui:inline-polyfill -->", polyfill)
basehtml = replacetextEx(basehtml, "<!-- tgui:nt-copyright -->", "Nanotrasen (c) 2284-[CURRENT_STATION_YEAR]")
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
@@ -344,4 +345,4 @@ SUBSYSTEM_DEF(tgui)
target.tgui_open_uis.Add(ui)
// Clear the old list.
source.tgui_open_uis.Cut()
return TRUE
return TRUE
+1 -1
View File
@@ -227,7 +227,7 @@ var/global/datum/controller/subsystem/ticker/ticker
end_game_state = END_GAME_READY_TO_END
current_state = GAME_STATE_FINISHED
Master.SetRunLevel(RUNLEVEL_POSTGAME)
INVOKE_ASYNC(src, .proc/declare_completion)
INVOKE_ASYNC(src, PROC_REF(declare_completion))
else if (mode_finished && (end_game_state < END_GAME_MODE_FINISHED))
end_game_state = END_GAME_MODE_FINISHED // Only do this cleanup once!
mode.cleanup()
+2 -2
View File
@@ -256,7 +256,7 @@ SUBSYSTEM_DEF(timer)
if (!length(alltimers))
return
sortTim(alltimers, /proc/cmp_timer)
sortTim(alltimers, GLOBAL_PROC_REF(cmp_timer))
var/datum/timedevent/head = alltimers[1]
@@ -516,4 +516,4 @@ SUBSYSTEM_DEF(timer)
#undef BUCKET_LEN
#undef BUCKET_POS
#undef TIMER_MAX
#undef TIMER_ID_MAX
#undef TIMER_ID_MAX
+1 -1
View File
@@ -290,7 +290,7 @@
winset(user, "mapwindow", "focus=true")
break
if (timeout)
addtimer(CALLBACK(src, .proc/close), timeout)
addtimer(CALLBACK(src, PROC_REF(close)), timeout)
/datum/browser/modal/proc/wait()
while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time))
+4 -4
View File
@@ -44,7 +44,7 @@
var/datum/object = GLOBAL_PROC
var/delegate
var/list/arguments
var/weakref/user
var/datum/weakref/user
/datum/callback/New(thingtocall, proctocall, ...)
if (thingtocall)
@@ -53,7 +53,7 @@
if (length(args) > 2)
arguments = args.Copy(3)
if(usr)
user = weakref(usr)
user = WEAKREF(usr)
/world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...)
set waitfor = FALSE
@@ -70,7 +70,7 @@
/datum/callback/proc/Invoke(...)
if(!usr)
var/weakref/W = user
var/datum/weakref/W = user
if(W)
var/mob/M = W.resolve()
if(M)
@@ -94,7 +94,7 @@
set waitfor = FALSE
if(!usr)
var/weakref/W = user
var/datum/weakref/W = user
if(W)
var/mob/M = W.resolve()
if(M)
+7 -7
View File
@@ -34,7 +34,7 @@ var/list/runechat_image_cache = list()
var/image/emote_image = image('icons/UI_Icons/chat/chat_icons.dmi', icon_state = "emote")
runechat_image_cache["emote"] = emote_image
return TRUE
/datum/chatmessage
@@ -99,10 +99,10 @@ var/list/runechat_image_cache = list()
if(!target || !owner)
qdel(src)
return
// Register client who owns this message
owned_by = owner.client
RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, .proc/qdel_self)
RegisterSignal(owned_by, COMSIG_PARENT_QDELETING, PROC_REF(qdel_self))
var/extra_length = owned_by.is_preference_enabled(/datum/client_preference/runechat_long_messages)
var/maxlen = extra_length ? CHAT_MESSAGE_EXT_LENGTH : CHAT_MESSAGE_LENGTH
@@ -147,10 +147,10 @@ var/list/runechat_image_cache = list()
// Icon on both ends?
//var/image/I = runechat_image_cache["emote"]
//text = "\icon[I][text]\icon[I]"
// Icon on one end?
//LAZYADD(prefixes, "\icon[runechat_image_cache["emote"]]")
// Asterisks instead?
text = "*&nbsp;[text]&nbsp;*"
@@ -168,7 +168,7 @@ var/list/runechat_image_cache = list()
// Translate any existing messages upwards, apply exponential decay factors to timers
message_loc = target.runechat_holder(src)
RegisterSignal(message_loc, COMSIG_PARENT_QDELETING, .proc/qdel_self)
RegisterSignal(message_loc, COMSIG_PARENT_QDELETING, PROC_REF(qdel_self))
if(owned_by.seen_messages)
var/idx = 1
var/combined_height = approx_lines
@@ -255,7 +255,7 @@ var/list/runechat_image_cache = list()
if(!message)
return
*/
var/list/extra_classes = list()
extra_classes += existing_extra_classes
+16 -16
View File
@@ -1,6 +1,6 @@
/datum/component/personal_crafting/Initialize()
if(ismob(parent))
RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button)
RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, PROC_REF(create_mob_button))
/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL)
// SIGNAL_HANDLER
@@ -12,7 +12,7 @@
C.alpha = H.ui_alpha
LAZYADD(H.other_important, C)
CL.screen += C
RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact)
RegisterSignal(C, COMSIG_CLICK, PROC_REF(component_ui_interact))
/datum/component/personal_crafting
var/busy
@@ -279,28 +279,28 @@
if(amt <= 0)//since machinery can have 0 aka CRAFTING_MACHINERY_USE - i.e. use it, don't consume it!
continue
// If the path is in R.parts, we want to grab those to stuff into the product
// If the path is in R.parts, we want to grab those to stuff into the product
var/amt_to_transfer = 0
if(is_path_in_list(path_key, R.parts))
amt_to_transfer = R.parts[path_key]
// Reagent: gotta go sniffing in all the beakers
if(ispath(path_key, /datum/reagent))
var/datum/reagent/reagent = path_key
var/id = initial(reagent.id)
for(var/obj/item/weapon/reagent_containers/RC in surroundings)
for(var/obj/item/weapon/reagent_containers/RC in surroundings)
// Found everything we need
if(amt <= 0 && amt_to_transfer <= 0)
break
break
// If we need to keep any to put in the new object, pull it out
if(amt_to_transfer > 0)
var/A = RC.reagents.trans_id_to(parts["reagents"], id, amt_to_transfer)
amt_to_transfer -= A
amt -= A
// If we need to consume some amount of it
if(amt > 0)
var/datum/reagent/RG = RC.reagents.get_reagent(id)
@@ -322,27 +322,27 @@
parts["items"] += split
amt_to_transfer -= split.get_amount()
amt -= split.get_amount()
if(amt > 0)
var/A = min(amt, S.get_amount())
if(S.use(A))
amt -= A
else // Just a regular item. Find them all and delete them
for(var/atom/movable/I in surroundings)
if(amt <= 0 && amt_to_transfer <= 0)
break
if(!istype(I, path_key))
continue
// Special case: the reagents may be needed for other recipes
if(istype(I, /obj/item/weapon/reagent_containers))
var/obj/item/weapon/reagent_containers/RC = I
if(RC.reagents.total_volume > 0)
continue
// We're using it for something
amt--
@@ -351,7 +351,7 @@
parts["items"] += I
amt_to_transfer--
continue
// Snowflake handling of reagent containers and storage atoms.
// If we consumed them in our crafting, we should dump their contents out before qdeling them.
if(istype(I, /obj/item/weapon/reagent_containers))
@@ -369,7 +369,7 @@
// SIGNAL_HANDLER
if(user == parent)
INVOKE_ASYNC(src, .proc/tgui_interact, user)
INVOKE_ASYNC(src, PROC_REF(tgui_interact), user)
/datum/component/personal_crafting/tgui_state(mob/user)
return GLOB.tgui_not_incapacitated_turf_state
@@ -499,7 +499,7 @@
//Also these are typepaths so sadly we can't just do "[a]"
L += "[req[req_atom]] [initial(req_atom.name)]"
req_text += L.Join(" OR ")
for(var/obj/machinery/content as anything in R.machinery)
req_text += "[R.reqs[content]] [initial(content.name)]"
if(R.additional_req_text)
@@ -530,4 +530,4 @@
name = "crafting menu"
icon = 'icons/mob/screen/midnight.dmi'
icon_state = "craft"
screen_loc = ui_smallquad
screen_loc = ui_smallquad
+4 -4
View File
@@ -76,9 +76,9 @@
. = ..()
if(!(mat_container_flags & MATCONTAINER_NO_INSERT))
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/on_attackby)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(on_attackby))
if(mat_container_flags & MATCONTAINER_EXAMINE)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
/datum/component/material_container/vv_edit_var(var_name, var_value)
@@ -86,12 +86,12 @@
. = ..()
if(var_name == NAMEOF(src, mat_container_flags) && parent)
if(!(old_flags & MATCONTAINER_EXAMINE) && mat_container_flags & MATCONTAINER_EXAMINE)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
else if(old_flags & MATCONTAINER_EXAMINE && !(mat_container_flags & MATCONTAINER_EXAMINE))
UnregisterSignal(parent, COMSIG_PARENT_EXAMINE)
if(old_flags & MATCONTAINER_NO_INSERT && !(mat_container_flags & MATCONTAINER_NO_INSERT))
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/on_attackby)
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, PROC_REF(on_attackby))
else if(!(old_flags & MATCONTAINER_NO_INSERT) && mat_container_flags & MATCONTAINER_NO_INSERT)
UnregisterSignal(parent, COMSIG_PARENT_ATTACKBY)
+31 -31
View File
@@ -111,15 +111,15 @@
/datum/component/overlay_lighting/RegisterWithParent()
. = ..()
if(directional)
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/on_parent_dir_change)
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_parent_moved)
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_RANGE, .proc/set_range)
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_POWER, .proc/set_power)
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_COLOR, .proc/set_color)
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_ON, .proc/on_toggle)
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_FLAGS, .proc/on_light_flags_change)
RegisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT, .proc/on_parent_crafted)
RegisterSignal(parent, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater)
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_parent_dir_change))
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_parent_moved))
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_RANGE, PROC_REF(set_range))
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_POWER, PROC_REF(set_power))
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_COLOR, PROC_REF(set_color))
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_ON, PROC_REF(on_toggle))
RegisterSignal(parent, COMSIG_ATOM_UPDATE_LIGHT_FLAGS, PROC_REF(on_light_flags_change))
RegisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT, PROC_REF(on_parent_crafted))
RegisterSignal(parent, COMSIG_LIGHT_EATER_QUEUE, PROC_REF(on_light_eater))
var/atom/movable/movable_parent = parent
if(movable_parent.light_flags & LIGHT_ATTACHED)
overlay_lighting_flags |= LIGHTING_ATTACHED
@@ -155,17 +155,17 @@
set_parent_attached_to(null)
set_holder(null)
clean_old_turfs()
qdel(visible_mask, TRUE)
visible_mask = null
if(directional)
qdel(directional_atom, TRUE)
directional_atom = null
qdel(cone, TRUE)
cone = null
return ..()
@@ -229,15 +229,15 @@
var/atom/movable/old_parent_attached_to = .
UnregisterSignal(old_parent_attached_to, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_LIGHT_EATER_QUEUE))
if(old_parent_attached_to == current_holder)
RegisterSignal(old_parent_attached_to, COMSIG_PARENT_QDELETING, .proc/on_holder_qdel)
RegisterSignal(old_parent_attached_to, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved)
RegisterSignal(old_parent_attached_to, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater)
RegisterSignal(old_parent_attached_to, COMSIG_PARENT_QDELETING, PROC_REF(on_holder_qdel))
RegisterSignal(old_parent_attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
RegisterSignal(old_parent_attached_to, COMSIG_LIGHT_EATER_QUEUE, PROC_REF(on_light_eater))
if(parent_attached_to)
if(parent_attached_to == current_holder)
UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED, COMSIG_LIGHT_EATER_QUEUE))
RegisterSignal(parent_attached_to, COMSIG_PARENT_QDELETING, .proc/on_parent_attached_to_qdel)
RegisterSignal(parent_attached_to, COMSIG_MOVABLE_MOVED, .proc/on_parent_attached_to_moved)
RegisterSignal(parent_attached_to, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater)
RegisterSignal(parent_attached_to, COMSIG_PARENT_QDELETING, PROC_REF(on_parent_attached_to_qdel))
RegisterSignal(parent_attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(on_parent_attached_to_moved))
RegisterSignal(parent_attached_to, COMSIG_LIGHT_EATER_QUEUE, PROC_REF(on_light_eater))
check_holder()
@@ -257,11 +257,11 @@
clean_old_turfs()
return
if(new_holder != parent && new_holder != parent_attached_to)
RegisterSignal(new_holder, COMSIG_PARENT_QDELETING, .proc/on_holder_qdel)
RegisterSignal(new_holder, COMSIG_MOVABLE_MOVED, .proc/on_holder_moved)
RegisterSignal(new_holder, COMSIG_LIGHT_EATER_QUEUE, .proc/on_light_eater)
RegisterSignal(new_holder, COMSIG_PARENT_QDELETING, PROC_REF(on_holder_qdel))
RegisterSignal(new_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved))
RegisterSignal(new_holder, COMSIG_LIGHT_EATER_QUEUE, PROC_REF(on_light_eater))
if(directional)
RegisterSignal(new_holder, COMSIG_ATOM_DIR_CHANGE, .proc/on_holder_dir_change)
RegisterSignal(new_holder, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_holder_dir_change))
if(overlay_lighting_flags & LIGHTING_ON)
make_luminosity_update()
add_dynamic_lumi()
@@ -444,7 +444,7 @@
if(final_distance > SHORT_CAST && !(ALL_CARDINALS & current_direction))
final_distance -= 1
var/turf/scanning = get_turf(current_holder)
. = 0
for(var/i in 1 to final_distance)
var/turf/next_turf = get_step(scanning, current_direction)
@@ -464,7 +464,7 @@
if(final_distance > SHORT_CAST && !(ALL_CARDINALS & get_dir(GET_PARENT, target)))
final_distance -= 1
var/turf/scanning = get_turf(GET_PARENT)
. = 0
for(var/i in 1 to final_distance)
var/next_dir = get_dir(scanning, target)
@@ -477,9 +477,9 @@
directional_atom.forceMove(scanning)
var/turf/Ts = get_turf(GET_PARENT)
var/turf/To = get_turf(GET_LIGHT_SOURCE)
var/angle = Get_Angle(Ts, To)
directional_atom.face_light(GET_PARENT, angle, .)
set_cone_direction(NORTH, angle)
@@ -510,7 +510,7 @@
return
current_direction = newdir
set_cone_direction(newdir)
if(newdir & NORTH)
cone.pixel_y = 16
else if(newdir & SOUTH)
@@ -522,7 +522,7 @@
else
cone.pixel_y = 0
directional_atom.pixel_y = 0
if(newdir & EAST)
cone.pixel_x = 16
else if(newdir & WEST)
@@ -538,7 +538,7 @@
else
cone.pixel_x = 0
directional_atom.pixel_x = 0
if(!skip_update && (overlay_lighting_flags & LIGHTING_ON))
make_luminosity_update()
@@ -549,7 +549,7 @@
return
UnregisterSignal(parent, COMSIG_ATOM_USED_IN_CRAFT)
RegisterSignal(new_craft, COMSIG_ATOM_USED_IN_CRAFT, .proc/on_parent_crafted)
RegisterSignal(new_craft, COMSIG_ATOM_USED_IN_CRAFT, PROC_REF(on_parent_crafted))
set_parent_attached_to(new_craft)
/// Handles putting the source for overlay lights into the light eater queue since we aren't tracked by [/atom/var/light_sources]
+2 -2
View File
@@ -6,7 +6,7 @@
/datum/component/resize_guard/RegisterWithParent()
// When our parent mob enters any atom, we check resize
RegisterSignal(parent, COMSIG_ATOM_ENTERING, .proc/check_resize)
RegisterSignal(parent, COMSIG_ATOM_ENTERING, PROC_REF(check_resize))
/datum/component/resize_guard/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_ATOM_ENTERING)
@@ -16,4 +16,4 @@
if(A?.limit_mob_size)
var/mob/living/L = parent
L.resize(L.size_multiplier)
qdel(src)
qdel(src)
+38 -10
View File
@@ -1,18 +1,46 @@
//
// datum defines!
// Note: Adding vars to /datum adds a var to EVERYTHING! Don't go overboard.
//
/**
* The absolute base class for everything
*
* A datum instantiated has no physical world prescence, use an atom if you want something
* that actually lives in the world
*
* Be very mindful about adding variables to this class, they are inherited by every single
* thing in the entire game, and so you can easily cause memory usage to rise a lot with careless
* use of variables at this level
*/
/datum
var/gc_destroyed //Time when this object was destroyed.
var/list/active_timers //for SStimer
var/list/datum_components //for /datum/components
/**
* Tick count time when this object was destroyed.
*
* If this is non zero then the object has been garbage collected and is awaiting either
* a hard del by the GC subsystme, or to be autocollected (if it has no references)
*/
var/gc_destroyed
/// Active timers with this datum as the target
var/list/active_timers
/**
* Components attached to this datum
*
* Lazy associated list in the structure of `type:component/list of components`
*/
var/list/datum_components
/**
* Any datum registered to receive signals from this datum is in this list
*
* Lazy associated list in the structure of `signal:registree/list of registrees`
*/
var/list/comp_lookup
var/list/list/signal_procs // List of lists
var/signal_enabled = FALSE
var/weakref/weakref // Holder of weakref instance pointing to this datum
/// Datum level flags
var/datum_flags = NONE
/// A weak reference to another datum
var/datum/weakref/weak_reference
#ifdef REFERENCE_TRACKING
var/tmp/running_find_references
var/tmp/last_find_references = 0
@@ -35,7 +63,7 @@
continue
qdel(timer)
weakref = null // Clear this reference to ensure it's kept for as brief duration as possible.
weak_reference = null // Clear this reference to ensure it's kept for as brief duration as possible.
//BEGIN: ECS SHIT
signal_enabled = FALSE
+2 -2
View File
@@ -63,11 +63,11 @@
if(!check_rights(NONE))
return
var/list/names = list()
var/list/componentsubtypes = sortTim(subtypesof(/datum/component), /proc/cmp_typepaths_asc)
var/list/componentsubtypes = sortTim(subtypesof(/datum/component), GLOBAL_PROC_REF(cmp_typepaths_asc))
names += "---Components---"
names += componentsubtypes
names += "---Elements---"
names += sortTim(subtypesof(/datum/element), /proc/cmp_typepaths_asc)
names += sortTim(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc))
var/result = tgui_input_list(usr, "Choose a component/element to add:", "Add Component/Element", names)
if(!usr || !result || result == "---Components---" || result == "---Elements---")
return
+1 -1
View File
@@ -23,7 +23,7 @@
return ELEMENT_INCOMPATIBLE
SEND_SIGNAL(target, COMSIG_ELEMENT_ATTACH, src)
if(element_flags & ELEMENT_DETACH)
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/OnTargetDelete, override = TRUE)
RegisterSignal(target, COMSIG_PARENT_QDELETING, PROC_REF(OnTargetDelete), override = TRUE)
/datum/element/proc/OnTargetDelete(datum/source, force)
SIGNAL_HANDLER
+2 -2
View File
@@ -18,7 +18,7 @@
CRASH("Invalid ID in conflict checking element.")
if(isnull(src.id))
src.id = id
RegisterSignal(target, COMSIG_CONFLICT_ELEMENT_CHECK, .proc/check)
RegisterSignal(target, COMSIG_CONFLICT_ELEMENT_CHECK, PROC_REF(check))
/datum/element/conflict_checking/proc/check(datum/source, id_to_check)
if(id == id_to_check)
@@ -32,4 +32,4 @@
for(var/i in GetAllContents())
var/atom/movable/AM = i
if(SEND_SIGNAL(AM, COMSIG_CONFLICT_ELEMENT_CHECK, id) & ELEMENT_CONFLICT_FOUND)
++.
++.
+1 -1
View File
@@ -9,7 +9,7 @@
. = ..()
if(!ismovable(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/on_target_move)
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_target_move))
var/atom/movable/movable_target = target
if(isturf(movable_target.loc))
var/turf/turf_loc = movable_target.loc
+6 -6
View File
@@ -14,8 +14,8 @@
our_turf.plane = OPENSPACE_PLANE
our_turf.layer = OPENSPACE_LAYER
RegisterSignal(target, COMSIG_TURF_MULTIZ_DEL, .proc/on_multiz_turf_del, override = TRUE)
RegisterSignal(target, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_turf_new, override = TRUE)
RegisterSignal(target, COMSIG_TURF_MULTIZ_DEL, PROC_REF(on_multiz_turf_del), override = TRUE)
RegisterSignal(target, COMSIG_TURF_MULTIZ_NEW, PROC_REF(on_multiz_turf_new), override = TRUE)
update_multiz(our_turf, TRUE, TRUE)
@@ -75,12 +75,12 @@
if(!ispath(path))
warning("Z-level [our_turf] has invalid baseturf '[get_base_turf_by_area(our_turf)]' in area '[get_area(our_turf)]'")
path = /turf/space
var/do_plane = ispath(path, /turf/space) ? SPACE_PLANE : null
var/do_state = ispath(path, /turf/space) ? "white" : initial(path.icon_state)
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), do_state, layer = TURF_LAYER-0.02, plane = do_plane)
underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR
our_turf.underlays += underlay_appearance
return TRUE
return TRUE
+3 -2
View File
@@ -63,7 +63,7 @@
if(query_sound)
SEND_SOUND(C, sound(query_sound))
tgui_alert_async(D, question, "[role_name] request", list("Yes", "No", "Never for this round"), CALLBACK(src, .proc/get_reply), wait_time SECONDS)
tgui_alert_async(D, question, "[role_name] request", list("Yes", "No", "Never for this round"), CALLBACK(src, PROC_REF(get_reply)), wait_time SECONDS)
/// Process an async alert response
/datum/ghost_query/proc/get_reply(response)
@@ -87,7 +87,7 @@
else if(finished) // Already finished candidate list
to_chat(D, "<span class='warning'>Unfortunately, you were not fast enough, and there are no more available roles. Sorry.</span>")
else // Prompt a second time
tgui_alert_async(D, "Are you sure you want to play as a [role_name]?", "[role_name] request", list("I'm Sure", "Nevermind"), CALLBACK(src, .proc/get_reply), wait_time SECONDS)
tgui_alert_async(D, "Are you sure you want to play as a [role_name]?", "[role_name] request", list("I'm Sure", "Nevermind"), CALLBACK(src, PROC_REF(get_reply)), wait_time SECONDS)
if("I'm Sure")
if(!evaluate_candidate(D)) // Failed revalidation
@@ -214,4 +214,5 @@
and they are attempting to open the cryopod.\n \
Would you like to play as the occupant? \n \
You MUST NOT use your station character!!!"
be_special_flag = BE_SURVIVOR
cutoff_number = 1
+2 -2
View File
@@ -87,7 +87,7 @@
if(!chance || prob(chance))
play(get_sound(starttime))
if(!timerid)
timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_STOPPABLE | TIMER_LOOP)
timerid = addtimer(CALLBACK(src, PROC_REF(sound_loop), world.time), mid_length, TIMER_STOPPABLE | TIMER_LOOP)
/datum/looping_sound/proc/play(soundfile)
var/list/atoms_cache = output_atoms
@@ -119,7 +119,7 @@
if(start_sound)
play(start_sound)
start_wait = start_length
addtimer(CALLBACK(src, .proc/sound_loop), start_wait)
addtimer(CALLBACK(src, PROC_REF(sound_loop)), start_wait)
/datum/looping_sound/proc/on_stop()
if(end_sound)
+2 -2
View File
@@ -54,7 +54,7 @@
/datum/looping_sound/sequence/sound_loop(starttime)
iterate_on_sequence()
timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), next_iteration_delay, TIMER_STOPPABLE)
timerid = addtimer(CALLBACK(src, PROC_REF(sound_loop), world.time), next_iteration_delay, TIMER_STOPPABLE)
#define MORSE_DOT "*" // Yes this is an asterisk but its easier to see on a computer compared to a period.
#define MORSE_DASH "-"
@@ -172,4 +172,4 @@
return spaces_between_letters
#undef MORSE_DOT
#undef MORSE_DASH
#undef MORSE_DASH
+1 -1
View File
@@ -112,7 +112,7 @@
to_chat(user, "<span class='warning'>You'll need [key_name] in one of your hands to move \the [ridden].</span>")
/datum/riding/proc/Unbuckle(atom/movable/M)
// addtimer(CALLBACK(ridden, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE)
// addtimer(CALLBACK(ridden, TYPE_PROC_REF(/atom/movable, unbuckle_mob), M), 0, TIMER_UNIQUE)
spawn(0)
// On /tg/ this uses the fancy CALLBACK system. Not entirely sure why they needed to do so with a duration of 0,
// so if there is a reason, this should replicate it close enough. Hopefully.
-26
View File
@@ -1,26 +0,0 @@
//obtain a weak reference to a datum
/proc/weakref(datum/D)
if(!istype(D))
return
if(QDELETED(D))
return
if(!D.weakref)
D.weakref = new/weakref(D)
return D.weakref
/weakref
var/ref
/weakref/New(datum/D)
ref = "\ref[D]"
/weakref/Destroy()
// A weakref datum should not be manually destroyed as it is a shared resource,
// rather it should be automatically collected by the BYOND GC when all references are gone.
return QDEL_HINT_LETMELIVE
/weakref/proc/resolve()
var/datum/D = locate(ref)
if(D && D.weakref == src)
return D
return null
+108
View File
@@ -0,0 +1,108 @@
/// Creates a weakref to the given input.
/// See /datum/weakref's documentation for more information.
/proc/WEAKREF(datum/input)
if(istype(input) && !QDELETED(input))
if(isweakref(input))
return input
if(!input.weak_reference)
input.weak_reference = new /datum/weakref(input)
return input.weak_reference
/datum/proc/create_weakref() //Forced creation for admin proccalls
return WEAKREF(src)
/**
* A weakref holds a non-owning reference to a datum.
* The datum can be referenced again using `resolve()`.
*
* To figure out why this is important, you must understand how deletion in
* BYOND works.
*
* Imagine a datum as a TV in a living room. When one person enters to watch
* TV, they turn it on. Others can come into the room and watch the TV.
* When the last person leaves the room, they turn off the TV because it's
* no longer being used.
*
* A datum being deleted tells everyone who's watching the TV to stop.
* If everyone leaves properly (AKA cleaning up their references), then the
* last person will turn off the TV, and everything is well.
* However, if someone is resistant (holds a hard reference after deletion),
* then someone has to walk in, drag them away, and turn off the TV forecefully.
* This process is very slow, and it's known as hard deletion.
*
* This is where weak references come in. Weak references don't count as someone
* watching the TV. Thus, when what it's referencing is destroyed, it will
* hopefully clean up properly, and limit hard deletions.
*
* A common use case for weak references is holding onto what created itself.
* For example, if a machine wanted to know what its last user was, it might
* create a `var/mob/living/last_user`. However, this is a strong reference to
* the mob, and thus will force a hard deletion when that mob is deleted.
* It is often better in this case to instead create a weakref to the user,
* meaning this type definition becomes `var/datum/weakref/last_user`.
*
* A good rule of thumb is that you should hold strong references to things
* that you *own*. For example, a dog holding a chew toy would be the owner
* of that chew toy, and thus a `var/obj/item/chew_toy` reference is fine
* (as long as it is cleaned up properly).
* However, a chew toy does not own its dog, so a `var/mob/living/dog/owner`
* might be inferior to a weakref.
* This is also a good rule of thumb to avoid circular references, such as the
* chew toy example. A circular reference that doesn't clean itself up properly
* will always hard delete.
*/
/datum/weakref
var/reference
/datum/weakref/New(datum/thing)
reference = REF(thing)
/datum/weakref/Destroy(force)
var/datum/target = resolve()
qdel(target)
if(!force)
return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore.
target?.weak_reference = null
return ..()
/**
* Retrieves the datum that this weakref is referencing.
*
* This will return `null` if the datum was deleted. This MUST be respected.
*/
/datum/weakref/proc/resolve()
var/datum/D = locate(reference)
return (!QDELETED(D) && D.weak_reference == src) ? D : null
/**
* SERIOUSLY READ THE AUTODOC COMMENT FOR THIS PROC BEFORE EVEN THINKING ABOUT USING IT
*
* Like resolve, but doesn't care if the datum is being qdeleted but hasn't been deleted yet.
*
* The return value of this proc leaves hanging references if the datum is being qdeleted but hasn't been deleted yet.
*
* Do not do anything that would create a lasting reference to the return value, such as giving it a tag, putting it on the map,
* adding it to an atom's contents or vis_contents, giving it a key (if it's a mob), attaching it to an atom (if it's an image),
* or assigning it to a datum or list referenced somewhere other than a temporary value.
*
* Unless you're resolving a weakref to a datum in a COMSIG_PARENT_QDELETING signal handler registered on that very same datum,
* just use resolve instead.
*/
/datum/weakref/proc/hard_resolve()
var/datum/D = locate(reference)
return (D?.weak_reference == src) ? D : null
/datum/weakref/vv_get_dropdown()
. = ..()
VV_DROPDOWN_OPTION(VV_HK_WEAKREF_RESOLVE, "Go to reference")
/datum/weakref/vv_do_topic(list/href_list)
. = ..()
if(href_list[VV_HK_WEAKREF_RESOLVE])
if(!check_rights(NONE))
return
var/datum/R = resolve()
if(R)
usr.client.debug_variables(R)
+1 -1
View File
@@ -698,7 +698,7 @@
if(length(speech_bubble_hearers))
var/image/I = generate_speech_bubble(src, "[bubble_icon][say_test(message)]", FLY_LAYER)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30)
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(flick_overlay), I, speech_bubble_hearers, 30)
/atom/proc/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list())
return
+2 -2
View File
@@ -741,7 +741,7 @@
// Cooldown
injector_ready = FALSE
addtimer(CALLBACK(src, .proc/injector_cooldown_finish), 30 SECONDS)
addtimer(CALLBACK(src, PROC_REF(injector_cooldown_finish)), 30 SECONDS)
// Create it
var/datum/dna2/record/buf = buffers[buffer_id]
@@ -798,4 +798,4 @@
#undef PAGE_BUFFER
#undef PAGE_REJUVENATORS
/////////////////////////// DNA MACHINES
/////////////////////////// DNA MACHINES
+1 -1
View File
@@ -154,7 +154,7 @@
return
/obj/effect/gateway/active/Initialize()
addtimer(CALLBACK(src, .proc/spawn_and_qdel), rand(30, 60) SECONDS)
addtimer(CALLBACK(src, PROC_REF(spawn_and_qdel)), rand(30, 60) SECONDS)
/obj/effect/gateway/active/proc/spawn_and_qdel()
if(LAZYLEN(spawnable))
@@ -9,12 +9,12 @@
category = UTILITY_SPELLS
//VOREStation Add - Multiple technomancer support
/datum/technomancer_marker
var/weakref/U
var/datum/weakref/U
var/image/I
var/turf/T
/datum/technomancer_marker/New(var/mob/user)
U = weakref(user)
U = WEAKREF(user)
T = get_turf(user)
I = image('icons/goonstation/featherzone.dmi', T, "spawn-wall")
I.plane = TURF_PLANE
@@ -46,7 +46,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
return 0
if(pay_energy(1000))
//VOREStation Add - Multiple technomancer support
var/datum/technomancer_marker/marker = GLOB.mark_spells[weakref(user)]
var/datum/technomancer_marker/marker = GLOB.mark_spells[WEAKREF(user)]
//They have one in the list
if(istype(marker))
qdel(marker)
@@ -54,7 +54,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
//They don't have one yet
else
to_chat(user, "<span class='notice'>You mark \the [get_turf(user)] under you.</span>")
GLOB.mark_spells[weakref(user)] = new /datum/technomancer_marker(user)
GLOB.mark_spells[WEAKREF(user)] = new /datum/technomancer_marker(user)
//VOREStation Add End
adjust_instability(5)
return 1
@@ -83,7 +83,7 @@ GLOBAL_LIST_INIT(mark_spells, list())
/obj/item/weapon/spell/recall/on_use_cast(var/mob/living/user)
if(pay_energy(3000))
var/datum/technomancer_marker/marker = GLOB.mark_spells[weakref(user)] //VOREStation Add - Multiple technomancer support
var/datum/technomancer_marker/marker = GLOB.mark_spells[WEAKREF(user)] //VOREStation Add - Multiple technomancer support
if(!istype(marker))
to_chat(user, "<span class='danger'>There's no Mark!</span>")
return 0
@@ -128,4 +128,3 @@ GLOBAL_LIST_INIT(mark_spells, list())
else
to_chat(user, "<span class='warning'>You can't afford the energy cost!</span>")
return 0
+2 -2
View File
@@ -34,7 +34,7 @@
if(!B || !I)
return
INVOKE_ASYNC(src, .proc/religion_prompts, H, B, I)
INVOKE_ASYNC(src, PROC_REF(religion_prompts), H, B, I)
/datum/job/chaplain/proc/religion_prompts(mob/living/carbon/human/H, obj/item/weapon/storage/bible/B, obj/item/weapon/card/id/I)
var/religion_name = "Unitarianism"
@@ -121,4 +121,4 @@
bible_name = bn
bible_icon_state = bis
bible_item_state = bits
title = t
title = t
+1 -1
View File
@@ -26,7 +26,7 @@ var/global/datum/controller/occupations/job_master
if(!job) continue
if(job.faction != faction) continue
occupations += job
sortTim(occupations, /proc/cmp_job_datums)
sortTim(occupations, GLOBAL_PROC_REF(cmp_job_datums))
return 1
+8 -7
View File
@@ -74,6 +74,7 @@
/// Keys are things like temperature and certain gasses. Values are lists, which contain, in order:
/// red warning minimum value, yellow warning minimum value, yellow warning maximum value, red warning maximum value
/// Use code\defines\gases.dm as reference for id/name. Please keep it consistent
var/list/TLV = list()
var/list/trace_gas = list("nitrous_oxide", "volatile_fuel") //list of other gases that this air alarm is able to detect
@@ -108,7 +109,7 @@
. = ..()
req_access = list(access_rd, access_atmospherics, access_engine_equip)
TLV["oxygen"] = list(-1.0, -1.0,-1.0,-1.0) // Partial pressure, kpa
TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
TLV["carbon_dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
TLV["phoron"] = list(-1.0, -1.0, 0, 0.5) // Partial pressure, kpa
TLV["other"] = list(-1.0, -1.0, 0.5, 1.0) // Partial pressure, kpa
TLV["pressure"] = list(0,ONE_ATMOSPHERE*0.10,ONE_ATMOSPHERE*1.40,ONE_ATMOSPHERE*1.60) /* kpa */
@@ -146,7 +147,7 @@
// breathable air according to human/Life()
TLV["oxygen"] = list(16, 19, 135, 140) // Partial pressure, kpa
TLV["nitrogen"] = list(0, 0, 135, 140) // Partial pressure, kpa
TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
TLV["carbon_dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
TLV["phoron"] = list(-1.0, -1.0, 0, 0.5) // Partial pressure, kpa
TLV["other"] = list(-1.0, -1.0, 0.5, 1.0) // Partial pressure, kpa
TLV["pressure"] = list(ONE_ATMOSPHERE * 0.80, ONE_ATMOSPHERE * 0.90, ONE_ATMOSPHERE * 1.10, ONE_ATMOSPHERE * 1.20) /* kpa */
@@ -273,7 +274,7 @@
pressure_dangerlevel = TEST_TLV_VALUES // not local because it's used in process()
LOAD_TLV_VALUES(TLV["oxygen"], environment.gas["oxygen"]*partial_pressure)
var/oxygen_dangerlevel = TEST_TLV_VALUES
LOAD_TLV_VALUES(TLV["carbon dioxide"], environment.gas["carbon_dioxide"]*partial_pressure)
LOAD_TLV_VALUES(TLV["carbon_dioxide"], environment.gas["carbon_dioxide"]*partial_pressure)
var/co2_dangerlevel = TEST_TLV_VALUES
LOAD_TLV_VALUES(TLV["phoron"], environment.gas["phoron"]*partial_pressure)
var/phoron_dangerlevel = TEST_TLV_VALUES
@@ -620,9 +621,9 @@
list("name" = "Oxygen", "command" = "o2_scrub", "val" = info["filter_o2"]),
list("name" = "Nitrogen", "command" = "n2_scrub", "val" = info["filter_n2"]),
list("name" = "Carbon Dioxide", "command" = "co2_scrub","val" = info["filter_co2"]),
list("name" = "Toxin" , "command" = "tox_scrub","val" = info["filter_phoron"]),
list("name" = "Phoron" , "command" = "tox_scrub","val" = info["filter_phoron"]),
list("name" = "Nitrous Oxide", "command" = "n2o_scrub","val" = info["filter_n2o"]),
list("name" = "Fuel", "command" = "fuel_scrub","val" = info["filter_fuel"])
list("name" = "Volatile Fuel", "command" = "fuel_scrub","val" = info["filter_fuel"])
)
))
data["scrubbers"] = scrubbers
@@ -641,7 +642,7 @@
var/list/selected
var/list/thresholds = list()
var/list/gas_names = list("oxygen", "carbon dioxide", "phoron", "other")
var/list/gas_names = list("oxygen", "carbon_dioxide", "phoron", "other") //Gas ids made to match code\defines\gases.dm
for(var/g in gas_names)
thresholds[++thresholds.len] = list("name" = g, "settings" = list())
selected = TLV[g]
@@ -844,4 +845,4 @@
// VOREStation Edit End
#undef LOAD_TLV_VALUES
#undef TEST_TLV_VALUES
#undef DECLARE_TLV_VALUES
#undef DECLARE_TLV_VALUES
@@ -48,13 +48,13 @@
"load" = scrubber.last_power_draw,
"area" = get_area(scrubber),
)))
return list("scrubbers" = working)
/obj/machinery/computer/area_atmos/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("toggle")
var/scrub_id = params["id"]
@@ -66,10 +66,10 @@
S.update_icon()
. = TRUE
if("allon")
INVOKE_ASYNC(src, .proc/toggle_all, TRUE)
INVOKE_ASYNC(src, PROC_REF(toggle_all), TRUE)
. = TRUE
if("alloff")
INVOKE_ASYNC(src, .proc/toggle_all, FALSE)
INVOKE_ASYNC(src, PROC_REF(toggle_all), FALSE)
. = TRUE
if("scan")
scanscrubbers()
@@ -78,7 +78,7 @@
add_fingerprint(usr)
/obj/machinery/computer/area_atmos/proc/toggle_all(on)
for(var/id in connectedscrubbers)
for(var/id in connectedscrubbers)
var/obj/machinery/portable_atmospherics/powered/scrubber/huge/S = connectedscrubbers["[id]"]
if(!validscrubber(S))
connectedscrubbers -= S
+1 -1
View File
@@ -33,7 +33,7 @@
var/filtertext
/obj/machinery/autolathe/Initialize()
AddComponent(/datum/component/material_container, subtypesof(/datum/material), 0, MATCONTAINER_EXAMINE, _after_insert = CALLBACK(src, .proc/AfterMaterialInsert))
AddComponent(/datum/component/material_container, subtypesof(/datum/material), 0, MATCONTAINER_EXAMINE, _after_insert = CALLBACK(src, PROC_REF(AfterMaterialInsert)))
. = ..()
if(!autolathe_recipes)
autolathe_recipes = new()
+1 -1
View File
@@ -142,7 +142,7 @@
. = TRUE
switch(action)
if("activate")
INVOKE_ASYNC(src, .proc/activate)
INVOKE_ASYNC(src, PROC_REF(activate))
return TRUE
if("detach")
if(beaker)
+10 -4
View File
@@ -16,15 +16,14 @@
/obj/machinery/cell_charger/Initialize()
. = ..()
default_apply_parts()
add_overlay("ccharger1")
/obj/machinery/cell_charger/update_icon()
icon_state = "ccharger[charging ? 1 : 0]"
if(!anchored)
cut_overlays()
icon_state = "ccharger2"
if(charging && !(stat & (BROKEN|NOPOWER)))
var/newlevel = round(charging.percent() * 4.0 / 99)
//to_world("nl: [newlevel]")
@@ -34,8 +33,14 @@
add_overlay("ccharger-o[newlevel]")
chargelevel = newlevel
else
add_overlay(image(charging.icon, charging.icon_state))
add_overlay("ccharger-[charging.connector_type]-on")
else if(anchored)
cut_overlays()
icon_state = "ccharger0"
add_overlay("ccharger1")
/obj/machinery/cell_charger/examine(mob/user)
. = ..()
@@ -77,6 +82,7 @@
anchored = !anchored
to_chat(user, "You [anchored ? "attach" : "detach"] [src] [anchored ? "to" : "from"] the ground")
playsound(src, W.usesound, 75, 1)
update_icon()
else if(default_deconstruction_screwdriver(user, W))
return
else if(default_deconstruction_crowbar(user, W))
+5 -5
View File
@@ -80,10 +80,10 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
network = list(NETWORK_THUNDER)
circuit = /obj/item/weapon/circuitboard/security/telescreen/entertainment
camera_datum_type = /datum/tgui_module/camera/bigscreen
var/obj/item/device/radio/radio = null
var/obj/effect/overlay/vis/pinboard
var/weakref/showing
var/datum/weakref/showing
var/enabled = TRUE // on or off
@@ -93,7 +93,7 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
var/static/icon/mask = icon('icons/obj/entertainment_monitor.dmi', "mask")
add_overlay("glass")
pinboard = new()
pinboard.icon = icon
pinboard.icon_state = "pinboard"
@@ -147,7 +147,7 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
stop_showing()
if(stat & NOPOWER)
return
showing = weakref(thing)
showing = WEAKREF(thing)
pinboard.vis_contents = list(thing)
/obj/machinery/computer/security/telescreen/entertainment/proc/stop_showing()
@@ -155,7 +155,7 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
pinboard.vis_contents = null
showing = null
/obj/machinery/computer/security/telescreen/entertainment/proc/maybe_stop_showing(weakref/thingref)
/obj/machinery/computer/security/telescreen/entertainment/proc/maybe_stop_showing(datum/weakref/thingref)
if(showing == thingref)
stop_showing()
+1 -1
View File
@@ -348,7 +348,7 @@
printing = TRUE
// playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE)
SStgui.update_uis(src)
addtimer(CALLBACK(src, .proc/print_finish), 5 SECONDS)
addtimer(CALLBACK(src, PROC_REF(print_finish)), 5 SECONDS)
else
return FALSE
+1 -1
View File
@@ -336,7 +336,7 @@
printing = TRUE
// playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE)
SStgui.update_uis(src)
addtimer(CALLBACK(src, .proc/print_finish), 5 SECONDS)
addtimer(CALLBACK(src, PROC_REF(print_finish)), 5 SECONDS)
if("photo_front")
var/icon/photo = get_photo(usr)
if(photo && active1)
+1 -1
View File
@@ -251,7 +251,7 @@
printing = TRUE
// playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE)
SStgui.update_uis(src)
addtimer(CALLBACK(src, .proc/print_finish), 5 SECONDS)
addtimer(CALLBACK(src, PROC_REF(print_finish)), 5 SECONDS)
else
return FALSE
+2 -2
View File
@@ -273,7 +273,7 @@
force_open()
if(autoclose && src.operating && !(stat & BROKEN || stat & NOPOWER))
addtimer(CALLBACK(src, .proc/close, 15 SECONDS))
addtimer(CALLBACK(src, PROC_REF(close), 15 SECONDS))
return 1
// Proc: close()
@@ -473,4 +473,4 @@
#undef BLAST_DOOR_CRUSH_DAMAGE
#undef SHUTTER_CRUSH_DAMAGE
#undef SHUTTER_CRUSH_DAMAGE
+294 -294
View File
@@ -1,294 +1,294 @@
#define CHARS_PER_LINE 5
#define FONT_SIZE "5pt"
#define FONT_COLOR "#09f"
#define FONT_STYLE "Small Fonts"
#define MAX_TIMER 36000
#define PRESET_SHORT 1 MINUTES
#define PRESET_MEDIUM 5 MINUTES
#define PRESET_LONG 10 MINUTES
///////////////////////////////////////////////////////////////////////////////////////////////
// Brig Door control displays.
// Description: This is a controls the timer for the brig doors, displays the timer on itself and
// has a popup window when used, allowing to set the timer.
// Code Notes: Combination of old brigdoor.dm code from rev4407 and the status_display.dm code
// Date: 01/September/2010
// Programmer: Veryinky
/////////////////////////////////////////////////////////////////////////////////////////////////
/obj/machinery/door_timer
name = "Door Timer"
icon = 'icons/obj/status_display.dmi'
icon_state = "frame"
layer = ABOVE_WINDOW_LAYER
desc = "A remote control for a door."
req_access = list(access_brig)
anchored = TRUE // can't pick it up
density = FALSE // can walk through it.
var/id = null // id of door it controls.
var/activation_time = 0
var/timer_duration = 0
var/timing = FALSE // boolean, true/1 timer is on, false/0 means it's not timing
var/list/obj/machinery/targets = list()
maptext_height = 26
maptext_width = 32
/obj/machinery/door_timer/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/door_timer/LateInitialize()
. = ..()
for(var/obj/machinery/door/window/brigdoor/M in machines)
if(M.id == id)
LAZYADD(targets,M)
for(var/obj/machinery/flasher/F in machines)
if(F.id == id)
LAZYADD(targets,F)
for(var/obj/structure/closet/secure_closet/brig/C in GLOB.all_brig_closets)
if(C.id == id)
LAZYADD(targets,C)
if(!LAZYLEN(targets))
stat |= BROKEN
update_icon()
/obj/machinery/door_timer/Destroy()
LAZYCLEARLIST(targets)
return ..()
//Main door timer loop, if it's timing and time is >0 reduce time by 1.
// if it's less than 0, open door, reset timer
// update the door_timer window and the icon
/obj/machinery/door_timer/process()
if(stat & (NOPOWER|BROKEN))
return
if(timing)
if(world.time - activation_time >= timer_duration)
timer_end() // open doors, reset timer, clear status screen
update_icon()
// has the door power situation changed, if so update icon.
/obj/machinery/door_timer/power_change()
..()
update_icon()
// open/closedoor checks if door_timer has power, if so it checks if the
// linked door is open/closed (by density) then opens it/closes it.
// Closes and locks doors, power check
/obj/machinery/door_timer/proc/timer_start()
if(stat & (NOPOWER|BROKEN))
return 0
activation_time = world.time
timing = TRUE
for(var/obj/machinery/door/window/brigdoor/door in targets)
if(door.density)
continue
INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/close)
for(var/obj/structure/closet/secure_closet/brig/C in targets)
if(C.broken)
continue
if(C.opened && !C.close())
continue
C.locked = TRUE
C.icon_state = "closed_locked"
return 1
/// Opens and unlocks doors, power check
/obj/machinery/door_timer/proc/timer_end(forced = FALSE)
if(stat & (NOPOWER|BROKEN))
return 0
timing = FALSE
activation_time = null
set_timer(0)
update_icon()
for(var/obj/machinery/door/window/brigdoor/door in targets)
if(!door.density)
continue
INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/open)
for(var/obj/structure/closet/secure_closet/brig/C in targets)
if(C.broken)
continue
if(C.opened)
continue
C.locked = FALSE
C.icon_state = "closed_unlocked"
return 1
/obj/machinery/door_timer/proc/time_left(seconds = FALSE)
. = max(0, timer_duration - (activation_time ? (world.time - activation_time) : 0))
if(seconds)
. /= 10
/obj/machinery/door_timer/proc/set_timer(value)
var/new_time = clamp(value, 0, MAX_TIMER)
. = new_time == timer_duration //return 1 on no change
timer_duration = new_time
if(timer_duration && activation_time && timing) // Setting it while active will reset the activation time
activation_time = world.time
/obj/machinery/door_timer/attack_ai(mob/user)
return src.attack_hand(user)
/obj/machinery/door_timer/attack_hand(mob/user)
if(..())
return TRUE
tgui_interact(user)
/obj/machinery/door_timer/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "BrigTimer", name)
ui.open()
/obj/machinery/door_timer/tgui_data()
var/list/data = list()
data["time_left"] = time_left()
data["max_time_left"] = MAX_TIMER
data["timing"] = timing
data["flash_found"] = FALSE
data["flash_charging"] = FALSE
data["preset_short"] = PRESET_SHORT
data["preset_medium"] = PRESET_MEDIUM
data["preset_long"] = PRESET_LONG
for(var/obj/machinery/flasher/F in targets)
data["flash_found"] = TRUE
if(F.last_flash && (F.last_flash + 150) > world.time)
data["flash_charging"] = TRUE
break
return data
/obj/machinery/door_timer/tgui_act(action, params)
if(..())
return
. = TRUE
if(!allowed(usr))
to_chat(usr, "<span class='warning'>Access denied.</span>")
return FALSE
switch(action)
if("time")
var/real_new_time = 0
var/new_time = params["time"]
var/list/L = splittext(new_time, ":")
if(LAZYLEN(L))
for(var/i in 1 to LAZYLEN(L))
real_new_time += text2num(L[i]) * (60 ** (LAZYLEN(L) - i))
else
real_new_time = text2num(new_time)
if(real_new_time)
set_timer(real_new_time * 10)
if("start")
timer_start()
if("stop")
timer_end(forced = TRUE)
if("flash")
for(var/obj/machinery/flasher/F in targets)
F.flash()
if("preset")
var/preset = params["preset"]
var/preset_time = time_left()
switch(preset)
if("short")
preset_time = PRESET_SHORT
if("medium")
preset_time = PRESET_MEDIUM
if("long")
preset_time = PRESET_LONG
set_timer(timer_duration + preset_time)
if(timing)
activation_time = world.time
else
. = FALSE
//icon update function
// if NOPOWER, display blank
// if BROKEN, display blue screen of death icon AI uses
// if timing=true, run update display function
/obj/machinery/door_timer/update_icon()
if(stat & (NOPOWER))
icon_state = "frame"
return
if(stat & (BROKEN))
set_picture("ai_bsod")
return
if(timing)
var/disp1 = id
var/timeleft = time_left(seconds = TRUE)
var/disp2 = "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, "0")]"
if(length(disp2) > CHARS_PER_LINE)
disp2 = "Error"
update_display(disp1, disp2)
else
if(maptext)
maptext = ""
return
// Adds an icon in case the screen is broken/off, stolen from status_display.dm
/obj/machinery/door_timer/proc/set_picture(state)
if(maptext)
maptext = ""
cut_overlays()
add_overlay(mutable_appearance('icons/obj/status_display.dmi', state))
//Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display
// Stolen from status_display
/obj/machinery/door_timer/proc/update_display(line1, line2)
line1 = uppertext(line1)
line2 = uppertext(line2)
var/new_text = {"<div style="font-size:[FONT_SIZE];color:[FONT_COLOR];font:'[FONT_STYLE]';text-align:center;" valign="top">[line1]<br>[line2]</div>"}
if(maptext != new_text)
maptext = new_text
/obj/machinery/door_timer/cell_1
name = "Cell 1"
id = "Cell 1"
/obj/machinery/door_timer/cell_2
name = "Cell 2"
id = "Cell 2"
/obj/machinery/door_timer/cell_3
name = "Cell 3"
id = "Cell 3"
/obj/machinery/door_timer/cell_4
name = "Cell 4"
id = "Cell 4"
/obj/machinery/door_timer/cell_5
name = "Cell 5"
id = "Cell 5"
/obj/machinery/door_timer/cell_6
name = "Cell 6"
id = "Cell 6"
/obj/machinery/door_timer/tactical_pet_storage //Vorestation Addition
name = "Tactical Pet Storage"
id = "tactical_pet_storage"
desc = "Opens and Closes on a timer. This one seals away a tactical boost in morale."
#undef FONT_SIZE
#undef FONT_COLOR
#undef FONT_STYLE
#undef CHARS_PER_LINE
#define CHARS_PER_LINE 5
#define FONT_SIZE "5pt"
#define FONT_COLOR "#09f"
#define FONT_STYLE "Small Fonts"
#define MAX_TIMER 36000
#define PRESET_SHORT 1 MINUTES
#define PRESET_MEDIUM 5 MINUTES
#define PRESET_LONG 10 MINUTES
///////////////////////////////////////////////////////////////////////////////////////////////
// Brig Door control displays.
// Description: This is a controls the timer for the brig doors, displays the timer on itself and
// has a popup window when used, allowing to set the timer.
// Code Notes: Combination of old brigdoor.dm code from rev4407 and the status_display.dm code
// Date: 01/September/2010
// Programmer: Veryinky
/////////////////////////////////////////////////////////////////////////////////////////////////
/obj/machinery/door_timer
name = "Door Timer"
icon = 'icons/obj/status_display.dmi'
icon_state = "frame"
layer = ABOVE_WINDOW_LAYER
desc = "A remote control for a door."
req_access = list(access_brig)
anchored = TRUE // can't pick it up
density = FALSE // can walk through it.
var/id = null // id of door it controls.
var/activation_time = 0
var/timer_duration = 0
var/timing = FALSE // boolean, true/1 timer is on, false/0 means it's not timing
var/list/obj/machinery/targets = list()
maptext_height = 26
maptext_width = 32
/obj/machinery/door_timer/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/door_timer/LateInitialize()
. = ..()
for(var/obj/machinery/door/window/brigdoor/M in machines)
if(M.id == id)
LAZYADD(targets,M)
for(var/obj/machinery/flasher/F in machines)
if(F.id == id)
LAZYADD(targets,F)
for(var/obj/structure/closet/secure_closet/brig/C in GLOB.all_brig_closets)
if(C.id == id)
LAZYADD(targets,C)
if(!LAZYLEN(targets))
stat |= BROKEN
update_icon()
/obj/machinery/door_timer/Destroy()
LAZYCLEARLIST(targets)
return ..()
//Main door timer loop, if it's timing and time is >0 reduce time by 1.
// if it's less than 0, open door, reset timer
// update the door_timer window and the icon
/obj/machinery/door_timer/process()
if(stat & (NOPOWER|BROKEN))
return
if(timing)
if(world.time - activation_time >= timer_duration)
timer_end() // open doors, reset timer, clear status screen
update_icon()
// has the door power situation changed, if so update icon.
/obj/machinery/door_timer/power_change()
..()
update_icon()
// open/closedoor checks if door_timer has power, if so it checks if the
// linked door is open/closed (by density) then opens it/closes it.
// Closes and locks doors, power check
/obj/machinery/door_timer/proc/timer_start()
if(stat & (NOPOWER|BROKEN))
return 0
activation_time = world.time
timing = TRUE
for(var/obj/machinery/door/window/brigdoor/door in targets)
if(door.density)
continue
INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/machinery/door/window/brigdoor, close))
for(var/obj/structure/closet/secure_closet/brig/C in targets)
if(C.broken)
continue
if(C.opened && !C.close())
continue
C.locked = TRUE
C.icon_state = "closed_locked"
return 1
/// Opens and unlocks doors, power check
/obj/machinery/door_timer/proc/timer_end(forced = FALSE)
if(stat & (NOPOWER|BROKEN))
return 0
timing = FALSE
activation_time = null
set_timer(0)
update_icon()
for(var/obj/machinery/door/window/brigdoor/door in targets)
if(!door.density)
continue
INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/machinery/door/window/brigdoor, open))
for(var/obj/structure/closet/secure_closet/brig/C in targets)
if(C.broken)
continue
if(C.opened)
continue
C.locked = FALSE
C.icon_state = "closed_unlocked"
return 1
/obj/machinery/door_timer/proc/time_left(seconds = FALSE)
. = max(0, timer_duration - (activation_time ? (world.time - activation_time) : 0))
if(seconds)
. /= 10
/obj/machinery/door_timer/proc/set_timer(value)
var/new_time = clamp(value, 0, MAX_TIMER)
. = new_time == timer_duration //return 1 on no change
timer_duration = new_time
if(timer_duration && activation_time && timing) // Setting it while active will reset the activation time
activation_time = world.time
/obj/machinery/door_timer/attack_ai(mob/user)
return src.attack_hand(user)
/obj/machinery/door_timer/attack_hand(mob/user)
if(..())
return TRUE
tgui_interact(user)
/obj/machinery/door_timer/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "BrigTimer", name)
ui.open()
/obj/machinery/door_timer/tgui_data()
var/list/data = list()
data["time_left"] = time_left()
data["max_time_left"] = MAX_TIMER
data["timing"] = timing
data["flash_found"] = FALSE
data["flash_charging"] = FALSE
data["preset_short"] = PRESET_SHORT
data["preset_medium"] = PRESET_MEDIUM
data["preset_long"] = PRESET_LONG
for(var/obj/machinery/flasher/F in targets)
data["flash_found"] = TRUE
if(F.last_flash && (F.last_flash + 150) > world.time)
data["flash_charging"] = TRUE
break
return data
/obj/machinery/door_timer/tgui_act(action, params)
if(..())
return
. = TRUE
if(!allowed(usr))
to_chat(usr, "<span class='warning'>Access denied.</span>")
return FALSE
switch(action)
if("time")
var/real_new_time = 0
var/new_time = params["time"]
var/list/L = splittext(new_time, ":")
if(LAZYLEN(L))
for(var/i in 1 to LAZYLEN(L))
real_new_time += text2num(L[i]) * (60 ** (LAZYLEN(L) - i))
else
real_new_time = text2num(new_time)
if(real_new_time)
set_timer(real_new_time * 10)
if("start")
timer_start()
if("stop")
timer_end(forced = TRUE)
if("flash")
for(var/obj/machinery/flasher/F in targets)
F.flash()
if("preset")
var/preset = params["preset"]
var/preset_time = time_left()
switch(preset)
if("short")
preset_time = PRESET_SHORT
if("medium")
preset_time = PRESET_MEDIUM
if("long")
preset_time = PRESET_LONG
set_timer(timer_duration + preset_time)
if(timing)
activation_time = world.time
else
. = FALSE
//icon update function
// if NOPOWER, display blank
// if BROKEN, display blue screen of death icon AI uses
// if timing=true, run update display function
/obj/machinery/door_timer/update_icon()
if(stat & (NOPOWER))
icon_state = "frame"
return
if(stat & (BROKEN))
set_picture("ai_bsod")
return
if(timing)
var/disp1 = id
var/timeleft = time_left(seconds = TRUE)
var/disp2 = "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, "0")]"
if(length(disp2) > CHARS_PER_LINE)
disp2 = "Error"
update_display(disp1, disp2)
else
if(maptext)
maptext = ""
return
// Adds an icon in case the screen is broken/off, stolen from status_display.dm
/obj/machinery/door_timer/proc/set_picture(state)
if(maptext)
maptext = ""
cut_overlays()
add_overlay(mutable_appearance('icons/obj/status_display.dmi', state))
//Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display
// Stolen from status_display
/obj/machinery/door_timer/proc/update_display(line1, line2)
line1 = uppertext(line1)
line2 = uppertext(line2)
var/new_text = {"<div style="font-size:[FONT_SIZE];color:[FONT_COLOR];font:'[FONT_STYLE]';text-align:center;" valign="top">[line1]<br>[line2]</div>"}
if(maptext != new_text)
maptext = new_text
/obj/machinery/door_timer/cell_1
name = "Cell 1"
id = "Cell 1"
/obj/machinery/door_timer/cell_2
name = "Cell 2"
id = "Cell 2"
/obj/machinery/door_timer/cell_3
name = "Cell 3"
id = "Cell 3"
/obj/machinery/door_timer/cell_4
name = "Cell 4"
id = "Cell 4"
/obj/machinery/door_timer/cell_5
name = "Cell 5"
id = "Cell 5"
/obj/machinery/door_timer/cell_6
name = "Cell 6"
id = "Cell 6"
/obj/machinery/door_timer/tactical_pet_storage //Vorestation Addition
name = "Tactical Pet Storage"
id = "tactical_pet_storage"
desc = "Opens and Closes on a timer. This one seals away a tactical boost in morale."
#undef FONT_SIZE
#undef FONT_COLOR
#undef FONT_STYLE
#undef CHARS_PER_LINE
+1 -1
View File
@@ -10,7 +10,7 @@
/obj/machinery/door/airlock/multi_tile/Initialize(mapload)
. = ..()
SetBounds()
RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/SetBounds)
RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(SetBounds))
apply_opacity_to_my_turfs(opacity)
/obj/machinery/door/airlock/multi_tile/set_opacity()
+3 -3
View File
@@ -67,13 +67,13 @@
if(istype(bot))
if(density && src.check_access(bot.botcard))
open()
addtimer(CALLBACK(src, .proc/close), 50)
addtimer(CALLBACK(src, PROC_REF(close)), 50)
else if(istype(AM, /obj/mecha))
var/obj/mecha/mecha = AM
if(density)
if(mecha.occupant && src.allowed(mecha.occupant))
open()
addtimer(CALLBACK(src, .proc/close), 50)
addtimer(CALLBACK(src, PROC_REF(close)), 50)
return
if (!( ticker ))
return
@@ -81,7 +81,7 @@
return
if (density && allowed(AM))
open()
addtimer(CALLBACK(src, .proc/close), check_access(null)? 50 : 20)
addtimer(CALLBACK(src, PROC_REF(close)), check_access(null)? 50 : 20)
/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
+2 -3
View File
@@ -29,7 +29,7 @@ GLOBAL_LIST_EMPTY(holoposters)
. = ..()
set_rand_sprite()
GLOB.holoposters += src
mytimer = addtimer(CALLBACK(src, .proc/set_rand_sprite), 30 MINUTES + rand(0, 5 MINUTES), TIMER_STOPPABLE | TIMER_LOOP)
mytimer = addtimer(CALLBACK(src, PROC_REF(set_rand_sprite)), 30 MINUTES + rand(0, 5 MINUTES), TIMER_STOPPABLE | TIMER_LOOP)
/obj/machinery/holoposter/Destroy()
GLOB.holoposters -= src
@@ -92,7 +92,7 @@ GLOBAL_LIST_EMPTY(holoposters)
stat &= ~BROKEN
icon_forced = FALSE
if(!mytimer)
mytimer = addtimer(CALLBACK(src, .proc/set_rand_sprite), 30 MINUTES + rand(0, 5 MINUTES), TIMER_STOPPABLE | TIMER_LOOP)
mytimer = addtimer(CALLBACK(src, PROC_REF(set_rand_sprite)), 30 MINUTES + rand(0, 5 MINUTES), TIMER_STOPPABLE | TIMER_LOOP)
set_rand_sprite()
return
icon_forced = TRUE
@@ -114,4 +114,3 @@ GLOBAL_LIST_EMPTY(holoposters)
/obj/machinery/holoposter/emp_act()
stat |= BROKEN
update_icon()
+3 -3
View File
@@ -80,7 +80,7 @@
// Or in Destroy at all, but especially after the ..().
/obj/machinery/Destroy()
if(ismovable(loc))
GLOB.moved_event.unregister(loc, src, .proc/update_power_on_move) // Unregister just in case
GLOB.moved_event.unregister(loc, src, PROC_REF(update_power_on_move)) // Unregister just in case
var/power = POWER_CONSUMPTION
REPORT_POWER_CONSUMPTION_CHANGE(power, 0)
. = ..()
@@ -91,9 +91,9 @@
. = ..()
update_power_on_move(src, old_loc, loc)
if(ismovable(loc)) // Register for recursive movement (if the thing we're inside moves)
GLOB.moved_event.register(loc, src, .proc/update_power_on_move)
GLOB.moved_event.register(loc, src, PROC_REF(update_power_on_move))
if(ismovable(old_loc)) // Unregister recursive movement.
GLOB.moved_event.unregister(old_loc, src, .proc/update_power_on_move)
GLOB.moved_event.unregister(old_loc, src, PROC_REF(update_power_on_move))
/obj/machinery/proc/update_power_on_move(atom/movable/mover, atom/old_loc, atom/new_loc)
var/area/old_area = get_area(old_loc)
+7 -7
View File
@@ -134,7 +134,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
var/last_shot = 0
var/kill_range = 18
var/rotation_speed = 0.25 SECONDS //How quickly we turn to face threats
var/weakref/engaging = null // The meteor we're shooting at
var/datum/weakref/engaging = null // The meteor we're shooting at
var/id_tag = null
/obj/machinery/power/pointdefense/Initialize()
@@ -235,7 +235,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
return FALSE
return TRUE
/obj/machinery/power/pointdefense/proc/Shoot(var/weakref/target)
/obj/machinery/power/pointdefense/proc/Shoot(var/datum/weakref/target)
var/obj/effect/meteor/M = target.resolve()
if(!istype(M))
engaging = null
@@ -244,12 +244,12 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
var/Angle = round(Get_Angle(src,M))
var/matrix/rot_matrix = matrix()
rot_matrix.Turn(Angle)
addtimer(CALLBACK(src, .proc/finish_shot, target), rotation_speed)
addtimer(CALLBACK(src, PROC_REF(finish_shot), target), rotation_speed)
animate(src, transform = rot_matrix, rotation_speed, easing = SINE_EASING)
set_dir(ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH)
/obj/machinery/power/pointdefense/proc/finish_shot(var/weakref/target)
/obj/machinery/power/pointdefense/proc/finish_shot(var/datum/weakref/target)
var/obj/machinery/pointdefense_control/PC = get_controller()
engaging = null
@@ -300,7 +300,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
// Compile list of known targets
var/list/existing_targets = list()
for(var/weakref/WR in PC.targets)
for(var/datum/weakref/WR in PC.targets)
var/obj/effect/meteor/M = WR.resolve()
existing_targets += M
@@ -308,7 +308,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
var/list/potential_targets = GLOB.meteor_list.Copy() - existing_targets
for(var/obj/effect/meteor/M in potential_targets)
if(targeting_check(M))
var/weakref/target = weakref(M)
var/datum/weakref/target = WEAKREF(M)
PC.targets += target
engaging = target
Shoot(target)
@@ -317,7 +317,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
// Then, focus fire on existing targets
for(var/obj/effect/meteor/M in existing_targets)
if(targeting_check(M))
var/weakref/target = weakref(M)
var/datum/weakref/target = WEAKREF(M)
engaging = target
Shoot(target)
return
@@ -0,0 +1,547 @@
GLOBAL_LIST_EMPTY(suit_cycler_typecache)
/obj/machinery/suit_cycler
name = "suit cycler"
desc = "An industrial machine for painting and refitting voidsuits."
anchored = TRUE
density = TRUE
icon = 'icons/obj/suit_cycler.dmi'
icon_state = "suit_cycler"
req_access = list(access_captain,access_heads)
var/active = 0 // PLEASE HOLD.
var/safeties = 1 // The cycler won't start with a living thing inside it unless safeties are off.
var/irradiating = 0 // If this is > 0, the cycler is decontaminating whatever is inside it.
var/radiation_level = 2 // 1 is removing germs, 2 is removing blood, 3 is removing phoron.
var/model_text = "" // Some flavour text for the topic box.
var/locked = 1 // If locked, nothing can be taken from or added to the cycler.
var/can_repair // If set, the cycler can repair voidsuits.
var/electrified = 0
/// Departments that the cycler can paint suits to look like. Null assumes all except specially excluded ones.
/// No idea why these particular suits are the default cycler's options.
var/list/limit_departments = list(
/datum/suit_cycler_choice/department/eng/standard,
/datum/suit_cycler_choice/department/crg/mining,
/datum/suit_cycler_choice/department/med/standard,
/datum/suit_cycler_choice/department/sec/standard,
/datum/suit_cycler_choice/department/eng/atmospherics,
/datum/suit_cycler_choice/department/eng/hazmat,
/datum/suit_cycler_choice/department/eng/construction,
/datum/suit_cycler_choice/department/med/biohazard,
/datum/suit_cycler_choice/department/med/emt,
/datum/suit_cycler_choice/department/sec/riot,
/datum/suit_cycler_choice/department/sec/eva
)
/// Species that the cycler can refit suits for. Null assumes all except specially excluded ones.
var/list/limit_species
var/list/departments
var/list/species
var/list/emagged_departments
var/datum/suit_cycler_choice/department/target_department
var/datum/suit_cycler_choice/species/target_species
var/mob/living/carbon/human/occupant = null
var/obj/item/clothing/suit/space/void/suit = null
var/obj/item/clothing/head/helmet/space/helmet = null
var/datum/wires/suit_storage_unit/wires = null
/obj/machinery/suit_cycler/Initialize()
. = ..()
departments = load_departments()
species = load_species()
emagged_departments = load_emagged()
limit_departments = null // just for mem
target_department = departments["No Change"]
target_species = species["No Change"]
if(!target_department || !target_species)
stat |= BROKEN
wires = new(src)
/obj/machinery/suit_cycler/Destroy()
qdel(wires)
wires = null
return ..()
/obj/machinery/suit_cycler/proc/load_departments()
var/list/typecache = GLOB.suit_cycler_typecache[type]
// First of our type
if(!typecache)
typecache = list()
GLOB.suit_cycler_typecache[type] = typecache
var/list/loaded = typecache["departments"]
// No departments loaded
if(!loaded)
loaded = list()
typecache["departments"] = loaded
for(var/datum/suit_cycler_choice/department/thing as anything in GLOB.suit_cycler_departments)
if(istype(thing, /datum/suit_cycler_choice/department/noop))
loaded[thing.name] = thing
continue
if(limit_departments && !is_type_in_list(thing, limit_departments))
continue
loaded[thing.name] = thing
return loaded
/obj/machinery/suit_cycler/proc/load_species()
var/list/typecache = GLOB.suit_cycler_typecache[type]
// First of our type
if(!typecache)
typecache = list()
GLOB.suit_cycler_typecache[type] = typecache
var/list/loaded = typecache["species"]
// No species loaded
if(!loaded)
loaded = list()
typecache["species"] = loaded
for(var/datum/suit_cycler_choice/species/thing as anything in GLOB.suit_cycler_species)
if(istype(thing, /datum/suit_cycler_choice/species/noop))
loaded[thing.name] = thing
continue
if(limit_species && !is_type_in_list(thing, limit_species))
continue
loaded[thing.name] = thing
return loaded
/obj/machinery/suit_cycler/proc/load_emagged()
var/list/typecache = GLOB.suit_cycler_typecache[type]
// First of our type
if(!typecache)
typecache = list()
GLOB.suit_cycler_typecache[type] = typecache
var/list/loaded = typecache["emagged"]
// No emagged loaded
if(!loaded)
loaded = list()
typecache["emagged"] = loaded
for(var/datum/suit_cycler_choice/department/thing as anything in GLOB.suit_cycler_emagged)
loaded[thing.name] = thing
return loaded
/obj/machinery/suit_cycler/attack_ai(mob/user as mob)
return attack_hand(user)
/obj/machinery/suit_cycler/attackby(obj/item/I as obj, mob/user as mob)
if(electrified != 0)
if(shock(user, 100))
return
//Hacking init.
if(istype(I, /obj/item/device/multitool) || I.is_wirecutter())
if(panel_open)
attack_hand(user)
return
//Other interface stuff.
if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
if(!(ismob(G.affecting)))
return
if(locked)
to_chat(user, "<span class='danger'>The suit cycler is locked.</span>")
return
if(contents.len > 0)
to_chat(user, "<span class='danger'>There is no room inside the cycler for [G.affecting.name].</span>")
return
visible_message("<span class='notice'>[user] starts putting [G.affecting.name] into the suit cycler.</span>", 3)
if(do_after(user, 20))
if(!G || !G.affecting) return
var/mob/M = G.affecting
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
M.loc = src
occupant = M
add_fingerprint(user)
qdel(G)
updateUsrDialog()
return
else if(I.is_screwdriver())
panel_open = !panel_open
playsound(src, I.usesound, 50, 1)
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
updateUsrDialog()
return
else if(istype(I,/obj/item/clothing/head/helmet/space/void) && !istype(I, /obj/item/clothing/head/helmet/space/rig))
var/obj/item/clothing/head/helmet/space/void/IH = I
if(locked)
to_chat(user, "<span class='danger'>The suit cycler is locked.</span>")
return
if(helmet)
to_chat(user, "<span class='danger'>The cycler already contains a helmet.</span>")
return
if(IH.no_cycle)
to_chat(user, "<span class='danger'>That item is not compatible with the cycler's protocols.</span>")
return
if(I.icon_override == CUSTOM_ITEM_MOB)
to_chat(user, "You cannot refit a customised voidsuit.")
return
//VOREStation Edit BEGINS
//Make it so autolok suits can't be refitted in a cycler
if(istype(I,/obj/item/clothing/head/helmet/space/void/autolok))
to_chat(user, "You cannot refit an autolok helmet. In fact you shouldn't even be able to remove it in the first place. Inform an admin!")
return
//Ditto the Mk7
if(istype(I,/obj/item/clothing/head/helmet/space/void/responseteam))
to_chat(user, "The cycler indicates that the Mark VII Emergency Response Helmet is not compatible with the refitting system. How did you manage to detach it anyway? Inform an admin!")
return
//VOREStation Edit ENDS
to_chat(user, "You fit \the [I] into the suit cycler.")
user.drop_item()
I.loc = src
helmet = I
update_icon()
updateUsrDialog()
return
else if(istype(I,/obj/item/clothing/suit/space/void))
var/obj/item/clothing/suit/space/void/IS = I
if(locked)
to_chat(user, "<span class='danger'>The suit cycler is locked.</span>")
return
if(suit)
to_chat(user, "<span class='danger'>The cycler already contains a voidsuit.</span>")
return
if(IS.no_cycle)
to_chat(user, "<span class='danger'>That item is not compatible with the cycler's protocols.</span>")
return
if(I.icon_override == CUSTOM_ITEM_MOB)
to_chat(user, "You cannot refit a customised voidsuit.")
return
//VOREStation Edit BEGINS
//Make it so autolok suits can't be refitted in a cycler
if(istype(I,/obj/item/clothing/suit/space/void/autolok))
to_chat(user, "You cannot refit an autolok suit.")
return
//Ditto the Mk7
if(istype(I,/obj/item/clothing/suit/space/void/responseteam))
to_chat(user, "The cycler indicates that the Mark VII Emergency Response Suit is not compatible with the refitting system.")
return
//VOREStation Edit ENDS
to_chat(user, "You fit \the [I] into the suit cycler.")
user.drop_item()
I.loc = src
suit = I
update_icon()
updateUsrDialog()
return
..()
/obj/machinery/suit_cycler/emag_act(var/remaining_charges, var/mob/user)
if(emagged)
to_chat(user, "<span class='danger'>The cycler has already been subverted.</span>")
return
//Clear the access reqs, disable the safeties, and open up all paintjobs.
to_chat(user, "<span class='danger'>You run the sequencer across the interface, corrupting the operating protocols.</span>")
emagged = 1
safeties = 0
req_access = list()
updateUsrDialog()
return 1
/obj/machinery/suit_cycler/attack_hand(mob/user as mob)
add_fingerprint(user)
if(..() || stat & (BROKEN|NOPOWER))
return
if(!user.IsAdvancedToolUser())
return 0
if(electrified != 0)
if(shock(user, 100))
return
tgui_interact(user)
/obj/machinery/suit_cycler/tgui_state(mob/user)
return GLOB.tgui_notcontained_state
/obj/machinery/suit_cycler/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SuitCycler", name)
ui.open()
/obj/machinery/suit_cycler/tgui_data(mob/user)
var/list/data = list()
data["model_text"] = model_text
data["can_repair"] = can_repair
data["userHasAccess"] = allowed(user)
data["locked"] = locked
data["active"] = active
data["safeties"] = safeties
data["uv_active"] = (active && irradiating > 0)
data["uv_level"] = radiation_level
data["max_uv_level"] = emagged ? 5 : 3
if(helmet)
data["helmet"] = helmet.name
else
data["helmet"] = null
if(suit)
data["suit"] = suit.name
if(istype(suit) && can_repair)
data["damage"] = suit.damage
else
data["suit"] = null
data["damage"] = null
if(occupant)
data["occupied"] = TRUE
else
data["occupied"] = FALSE
return data
/obj/machinery/suit_cycler/tgui_static_data(mob/user)
var/list/data = list()
// tgui gets angy if you pass values too
var/list/department_keys = list()
for(var/key in departments)
department_keys += key
// emagged at the bottom
if(emagged)
for(var/key in emagged_departments)
department_keys += key
var/list/species_keys = list()
for(var/key in species)
species_keys += key
data["departments"] = department_keys
data["species"] = species_keys
return data
/obj/machinery/suit_cycler/tgui_act(action, params)
if(..())
return TRUE
switch(action)
if("dispense")
switch(params["item"])
if("helmet")
helmet.forceMove(get_turf(src))
helmet = null
if("suit")
suit.forceMove(get_turf(src))
suit = null
. = TRUE
if("department")
var/choice = params["department"]
if(choice in departments)
target_department = departments[choice]
else if(emagged && (choice in emagged_departments))
target_department = emagged_departments[choice]
. = TRUE
if("species")
var/choice = params["species"]
if(choice in species)
target_species = species[choice]
. = TRUE
if("radlevel")
radiation_level = clamp(params["radlevel"], 1, emagged ? 5 : 3)
. = TRUE
if("repair_suit")
if(!suit || !can_repair)
return
active = 1
spawn(100)
repair_suit()
finished_job()
. = TRUE
if("apply_paintjob")
if(!suit && !helmet)
return
active = 1
spawn(100)
apply_paintjob()
finished_job()
. = TRUE
if("lock")
if(allowed(usr))
locked = !locked
to_chat(usr, "You [locked ? "" : "un"]lock \the [src].")
else
to_chat(usr, "<span class='danger'>Access denied.</span>")
. = TRUE
if("eject_guy")
eject_occupant(usr)
. = TRUE
if("uv")
if(safeties && occupant)
to_chat(usr, "<span class='danger'>The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.</span>")
return
active = 1
irradiating = 10
sleep(10)
if(helmet)
if(radiation_level > 2)
helmet.decontaminate()
if(radiation_level > 1)
helmet.clean_blood()
if(suit)
if(radiation_level > 2)
suit.decontaminate()
if(radiation_level > 1)
suit.clean_blood()
. = TRUE
/obj/machinery/suit_cycler/process()
if(electrified > 0)
electrified--
if(!active)
return
if(active && stat & (BROKEN|NOPOWER))
active = 0
irradiating = 0
electrified = 0
return
if(irradiating == 1)
add_overlay("decon")
finished_job()
irradiating = 0
cut_overlays()
return
irradiating--
if(occupant)
if(prob(radiation_level*2)) occupant.emote("scream")
if(radiation_level > 2)
occupant.take_organ_damage(0,radiation_level*2 + rand(1,3))
if(radiation_level > 1)
occupant.take_organ_damage(0,radiation_level + rand(1,3))
occupant.apply_effect(radiation_level*10, IRRADIATE)
/obj/machinery/suit_cycler/proc/finished_job()
var/turf/T = get_turf(src)
T.visible_message("\icon[src][bicon(src)]<span class='notice'>The [src] beeps several times.</span>")
icon_state = initial(icon_state)
active = 0
playsound(src, 'sound/machines/boobeebeep.ogg', 50)
updateUsrDialog()
/obj/machinery/suit_cycler/proc/repair_suit()
if(!suit || !suit.damage || !suit.can_breach)
return
suit.breaches = list()
suit.calc_breach_damage()
return
/obj/machinery/suit_cycler/verb/leave()
set name = "Eject Cycler"
set category = "Object"
set src in oview(1)
if(usr.stat != 0)
return
eject_occupant(usr)
/obj/machinery/suit_cycler/proc/eject_occupant(mob/user as mob)
if(locked || active)
to_chat(user, "<span class='warning'>The cycler is locked.</span>")
return
if(!occupant)
return
if(occupant.client)
occupant.client.eye = occupant.client.mob
occupant.client.perspective = MOB_PERSPECTIVE
occupant.loc = get_turf(occupant)
occupant = null
add_fingerprint(user)
updateUsrDialog()
update_icon()
return
// "Streamlined" before? Ok. -Aro
/obj/machinery/suit_cycler/proc/apply_paintjob()
if(!target_species || !target_department)
return
// Helmet to new paint
if(target_department.can_refit_helmet(helmet))
target_department.do_refit_helmet(helmet)
// Suit to new paint
if(target_department.can_refit_suit(suit))
target_department.do_refit_suit(suit)
// Attached voidsuit helmet to new paint
if(target_department.can_refit_helmet(suit?.helmet))
target_department.do_refit_helmet(suit.helmet)
// Species fitting for all 3 potential changes
if(target_species.can_refit_to(helmet, suit, suit?.helmet))
target_species.do_refit_to(helmet, suit, suit?.helmet)
else
visible_message("\icon[src][bicon(src)]<span class='warning'>Unable to apply specified cosmetics with specified species. Please try again with a different species or cosmetic option selected.</span>")
return
@@ -0,0 +1,112 @@
/obj/machinery/suit_cycler/refit_only
name = "Suit cycler"
desc = "A dedicated industrial machine that can refit voidsuits for \
different species, but not change the suit's overall appearance or \
departmental scheme."
model_text = "General Access"
req_access = null
limit_departments = list()
/obj/machinery/suit_cycler/engineering
name = "Engineering suit cycler"
model_text = "Engineering"
icon_state = "engi_cycler"
req_access = list(access_construction)
limit_departments = list(
/datum/suit_cycler_choice/department/eng
)
/obj/machinery/suit_cycler/mining
name = "Mining suit cycler"
model_text = "Mining"
icon_state = "industrial_cycler"
req_access = list(access_mining)
limit_departments = list(
/datum/suit_cycler_choice/department/crg
)
/obj/machinery/suit_cycler/security
name = "Security suit cycler"
model_text = "Security"
icon_state = "sec_cycler"
req_access = list(access_security)
limit_departments = list(
/datum/suit_cycler_choice/department/sec
)
/obj/machinery/suit_cycler/medical
name = "Medical suit cycler"
model_text = "Medical"
icon_state = "med_cycler"
req_access = list(access_medical)
limit_departments = list(
/datum/suit_cycler_choice/department/med
)
/obj/machinery/suit_cycler/syndicate
name = "Nonstandard suit cycler"
model_text = "Nonstandard"
icon_state = "red_cycler"
req_access = list(access_syndicate)
limit_departments = list(
/datum/suit_cycler_choice/department/emag
)
can_repair = 1
/obj/machinery/suit_cycler/exploration
name = "Explorer suit cycler"
model_text = "Exploration"
icon_state = "explo_cycler"
limit_departments = list(
/datum/suit_cycler_choice/department/exp
)
/obj/machinery/suit_cycler/pilot
name = "Pilot suit cycler"
model_text = "Pilot"
icon_state = "pilot_cycler"
limit_departments = list(
/datum/suit_cycler_choice/department/pil
)
/obj/machinery/suit_cycler/vintage
name = "Vintage Crew suit cycler"
model_text = "Vintage"
icon_state = "industrial_cycler"
limit_departments = list(
/datum/suit_cycler_choice/department/vintage/crew
)
req_access = null
/obj/machinery/suit_cycler/vintage/pilot
name = "Vintage Pilot suit cycler"
model_text = "Vintage Pilot"
limit_departments = list(
/datum/suit_cycler_choice/department/vintage/pilot
)
/obj/machinery/suit_cycler/vintage/medsci
name = "Vintage MedSci suit cycler"
model_text = "Vintage MedSci"
limit_departments = list(
/datum/suit_cycler_choice/department/vintage/research,
/datum/suit_cycler_choice/department/vintage/med
)
/obj/machinery/suit_cycler/vintage/rugged
name = "Vintage Ruggedized suit cycler"
model_text = "Vintage Ruggedized"
limit_departments = list(
/datum/suit_cycler_choice/department/vintage/eng,
/datum/suit_cycler_choice/department/vintage/marine,
/datum/suit_cycler_choice/department/vintage/officer,
/datum/suit_cycler_choice/department/vintage/merc
)
/obj/machinery/suit_cycler/vintage/omni
name = "Vintage Master suit cycler"
model_text = "Vintage Master"
limit_departments = list(
/datum/suit_cycler_choice/department/vintage
)
@@ -10,53 +10,62 @@
/obj/machinery/suit_cycler/captain
name = "Manager suit cycler"
model_text = "Manager"
icon_state = "cap_cycler"
req_access = list(access_captain)
departments = list(/datum/suit_cycler_choice/department/captain)
/obj/machinery/suit_cycler/prototype
name = "Prototype suit cycler"
model_text = "Prototype"
icon_state = "industrial_cycler"
req_access = list(access_hos)
departments = list(/datum/suit_cycler_choice/department/prototype)
/obj/machinery/suit_cycler/vintage/tcrew
name = "Talon crew suit cycler"
model_text = "Talon crew"
icon_state = "dark_cycler"
req_access = list(access_talon)
departments = list(/datum/suit_cycler_choice/department/talon/crew)
/obj/machinery/suit_cycler/vintage/tpilot
name = "Talon pilot suit cycler"
model_text = "Talon pilot"
icon_state = "dark_cycler"
req_access = list(access_talon)
departments = list(/datum/suit_cycler_choice/department/talon/pilot)
/obj/machinery/suit_cycler/vintage/tengi
name = "Talon engineer suit cycler"
model_text = "Talon engineer"
icon_state = "dark_cycler"
req_access = list(access_talon)
departments = list(/datum/suit_cycler_choice/department/talon/eng)
/obj/machinery/suit_cycler/vintage/tguard
name = "Talon guard suit cycler"
model_text = "Talon guard"
icon_state = "dark_cycler"
req_access = list(access_talon)
departments = list(/datum/suit_cycler_choice/department/talon/marine)
/obj/machinery/suit_cycler/vintage/tmedic
name = "Talon doctor suit cycler"
model_text = "Talon doctor"
icon_state = "dark_cycler"
req_access = list(access_talon)
departments = list(/datum/suit_cycler_choice/department/talon/med)
/obj/machinery/suit_cycler/vintage/tcaptain
name = "Talon captain suit cycler"
model_text = "Talon captain"
icon_state = "dark_cycler"
req_access = list(access_talon)
departments = list(/datum/suit_cycler_choice/department/talon/officer)
/obj/machinery/suit_cycler/vintage/tminer
name = "Talon miner suit cycler"
model_text = "Talon miner"
icon_state = "dark_cycler"
req_access = list(access_talon)
departments = list(/datum/suit_cycler_choice/department/talon/miner)
@@ -0,0 +1,476 @@
//////////////////////////////////////
// SUIT STORAGE UNIT /////////////////
//////////////////////////////////////
/obj/machinery/suit_storage_unit
name = "Suit Storage Unit"
desc = "An industrial U-Stor-It Storage unit designed to accomodate all kinds of space suits. Its on-board equipment also allows the user to decontaminate the contents through a UV-ray purging cycle. There's a warning label dangling from the control pad, reading \"STRICTLY NO BIOLOGICALS IN THE CONFINES OF THE UNIT\"."
icon = 'icons/obj/suit_storage.dmi'
icon_state = "suitstorage000000100" //order is: [has helmet][has suit][has human][is open][is locked][is UV cycling][is powered][is dirty/broken] [is superUVcycling]
anchored = TRUE
density = TRUE
var/mob/living/carbon/human/OCCUPANT = null
var/obj/item/clothing/suit/space/SUIT = null
var/suit_type = null
var/obj/item/clothing/head/helmet/space/HELMET = null
var/helmet_type = null
var/obj/item/clothing/mask/MASK = null //All the stuff that's gonna be stored insiiiiiiiiiiiiiiiiiiide, nyoro~n
var/mask_type = null //Erro's idea on standarising SSUs whle keeping creation of other SSU types easy: Make a child SSU, name it something then set the TYPE vars to your desired suit output. New() should take it from there by itself.
var/isopen = 0
var/islocked = 0
var/isUV = 0
var/ispowered = 1 //starts powered
var/isbroken = 0
var/issuperUV = 0
var/panelopen = 0
var/safetieson = 1
var/cycletime_left = 0
/obj/machinery/suit_storage_unit/Initialize()
. = ..()
if(suit_type)
SUIT = new suit_type(src)
if(helmet_type)
HELMET = new helmet_type(src)
if(mask_type)
MASK = new mask_type(src)
update_icon()
/obj/machinery/suit_storage_unit/update_icon()
var/hashelmet = 0
var/hassuit = 0
var/hashuman = 0
if(HELMET)
hashelmet = 1
if(SUIT)
hassuit = 1
if(OCCUPANT)
hashuman = 1
icon_state = text("suitstorage[][][][][][][][][]", hashelmet, hassuit, hashuman, isopen, islocked, isUV, ispowered, isbroken, issuperUV)
/obj/machinery/suit_storage_unit/power_change()
..()
if(!(stat & NOPOWER))
ispowered = 1
update_icon()
else
spawn(rand(0, 15))
ispowered = 0
islocked = 0
isopen = 1
dump_everything()
update_icon()
/obj/machinery/suit_storage_unit/ex_act(severity)
switch(severity)
if(1.0)
if(prob(50))
dump_everything() //So suits dont survive all the time
qdel(src)
if(2.0)
if(prob(50))
dump_everything()
qdel(src)
/obj/machinery/suit_storage_unit/attack_hand(mob/user)
if(..())
return
if(stat & NOPOWER)
return
if(!user.IsAdvancedToolUser())
return 0
tgui_interact(user)
/obj/machinery/suit_storage_unit/tgui_state(mob/user)
return GLOB.tgui_notcontained_state
/obj/machinery/suit_storage_unit/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SuitStorageUnit", name)
ui.open()
/obj/machinery/suit_storage_unit/tgui_data()
var/list/data = list()
data["broken"] = isbroken
data["panelopen"] = panelopen
data["locked"] = islocked
data["open"] = isopen
data["safeties"] = safetieson
data["uv_active"] = isUV
data["uv_super"] = issuperUV
if(HELMET)
data["helmet"] = HELMET.name
else
data["helmet"] = null
if(SUIT)
data["suit"] = SUIT.name
else
data["suit"] = null
if(MASK)
data["mask"] = MASK.name
else
data["mask"] = null
data["storage"] = null
if(OCCUPANT)
data["occupied"] = TRUE
else
data["occupied"] = FALSE
return data
/obj/machinery/suit_storage_unit/tgui_act(action, params) //I fucking HATE this proc
if(..() || isUV || isbroken)
return TRUE
switch(action)
if("door")
toggle_open(usr)
. = TRUE
if("dispense")
switch(params["item"])
if("helmet")
dispense_helmet(usr)
if("mask")
dispense_mask(usr)
if("suit")
dispense_suit(usr)
. = TRUE
if("uv")
start_UV(usr)
. = TRUE
if("lock")
toggle_lock(usr)
. = TRUE
if("eject_guy")
eject_occupant(usr)
. = TRUE
// Panel Open stuff
if(!. && panelopen)
switch(action)
if("toggleUV")
toggleUV(usr)
. = TRUE
if("togglesafeties")
togglesafeties(usr)
. = TRUE
update_icon()
add_fingerprint(usr)
/obj/machinery/suit_storage_unit/proc/toggleUV(mob/user as mob)
if(!panelopen)
return
else //welp, the guy is protected, we can continue
if(issuperUV)
to_chat(user, "You slide the dial back towards \"185nm\".")
issuperUV = 0
else
to_chat(user, "You crank the dial all the way up to \"15nm\".")
issuperUV = 1
return
/obj/machinery/suit_storage_unit/proc/togglesafeties(mob/user as mob)
if(!panelopen) //Needed check due to bugs
return
else
to_chat(user, "You push the button. The coloured LED next to it changes.")
safetieson = !safetieson
/obj/machinery/suit_storage_unit/proc/dispense_helmet(mob/user as mob)
if(!HELMET)
return //Do I even need this sanity check? Nyoro~n
else
HELMET.loc = src.loc
HELMET = null
return
/obj/machinery/suit_storage_unit/proc/dispense_suit(mob/user as mob)
if(!SUIT)
return
else
SUIT.loc = src.loc
SUIT = null
return
/obj/machinery/suit_storage_unit/proc/dispense_mask(mob/user as mob)
if(!MASK)
return
else
MASK.loc = src.loc
MASK = null
return
/obj/machinery/suit_storage_unit/proc/dump_everything()
islocked = 0 //locks go free
if(SUIT)
SUIT.loc = src.loc
SUIT = null
if(HELMET)
HELMET.loc = src.loc
HELMET = null
if(MASK)
MASK.loc = src.loc
MASK = null
if(OCCUPANT)
eject_occupant(OCCUPANT)
return
/obj/machinery/suit_storage_unit/proc/toggle_open(mob/user as mob)
if(islocked || isUV)
to_chat(user, "<font color='red'>Unable to open unit.</font>")
return
if(OCCUPANT)
eject_occupant(user)
return // eject_occupant opens the door, so we need to return
isopen = !isopen
return
/obj/machinery/suit_storage_unit/proc/toggle_lock(mob/user as mob)
if(OCCUPANT && safetieson)
to_chat(user, "<font color='red'>The Unit's safety protocols disallow locking when a biological form is detected inside its compartments.</font>")
return
if(isopen)
return
islocked = !islocked
return
/obj/machinery/suit_storage_unit/proc/start_UV(mob/user as mob)
if(isUV || isopen) //I'm bored of all these sanity checks
return
if(OCCUPANT && safetieson)
to_chat(user, "<font color='red'><B>WARNING:</B> Biological entity detected in the confines of the Unit's storage. Cannot initiate cycle.</font>")
return
if(!HELMET && !MASK && !SUIT && !OCCUPANT) //shit's empty yo
to_chat(user, "<font color='red'>Unit storage bays empty. Nothing to disinfect -- Aborting.</font>")
return
to_chat(user, "You start the Unit's cauterisation cycle.")
cycletime_left = 20
isUV = 1
if(OCCUPANT && !islocked)
islocked = 1 //Let's lock it for good measure
update_icon()
updateUsrDialog()
var/i //our counter
for(i=0,i<4,i++)
sleep(50)
if(OCCUPANT)
OCCUPANT.apply_effect(50, IRRADIATE)
var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in OCCUPANT.internal_organs
if(!rad_organ)
if(OCCUPANT.can_feel_pain())
OCCUPANT.emote("scream")
if(issuperUV)
var/burndamage = rand(28,35)
OCCUPANT.take_organ_damage(0,burndamage)
else
var/burndamage = rand(6,10)
OCCUPANT.take_organ_damage(0,burndamage)
if(i==3) //End of the cycle
if(!issuperUV)
if(HELMET)
HELMET.clean_blood()
if(SUIT)
SUIT.clean_blood()
if(MASK)
MASK.clean_blood()
else //It was supercycling, destroy everything
if(HELMET)
HELMET = null
if(SUIT)
SUIT = null
if(MASK)
MASK = null
visible_message("<font color='red'>With a loud whining noise, the Suit Storage Unit's door grinds open. Puffs of ashen smoke come out of its chamber.</font>", 3)
isbroken = 1
isopen = 1
islocked = 0
eject_occupant(OCCUPANT) //Mixing up these two lines causes bug. DO NOT DO IT.
isUV = 0 //Cycle ends
update_icon()
updateUsrDialog()
return
/obj/machinery/suit_storage_unit/proc/cycletimeleft()
if(cycletime_left >= 1)
cycletime_left--
return cycletime_left
/obj/machinery/suit_storage_unit/proc/eject_occupant(mob/user as mob)
if(islocked)
return
if(!OCCUPANT)
return
if(OCCUPANT.client)
if(user != OCCUPANT)
to_chat(OCCUPANT, "<font color='blue'>The machine kicks you out!</font>")
if(user.loc != src.loc)
to_chat(OCCUPANT, "<font color='blue'>You leave the not-so-cozy confines of the SSU.</font>")
OCCUPANT.client.eye = OCCUPANT.client.mob
OCCUPANT.client.perspective = MOB_PERSPECTIVE
OCCUPANT.loc = src.loc
OCCUPANT = null
if(!isopen)
isopen = 1
update_icon()
return
/obj/machinery/suit_storage_unit/verb/get_out()
set name = "Eject Suit Storage Unit"
set category = "Object"
set src in oview(1)
if(usr.stat != 0)
return
eject_occupant(usr)
add_fingerprint(usr)
updateUsrDialog()
update_icon()
return
/obj/machinery/suit_storage_unit/verb/move_inside()
set name = "Hide in Suit Storage Unit"
set category = "Object"
set src in oview(1)
if(usr.stat != 0)
return
if(!isopen)
to_chat(usr, "<font color='red'>The unit's doors are shut.</font>")
return
if(!ispowered || isbroken)
to_chat(usr, "<font color='red'>The unit is not operational.</font>")
return
if((OCCUPANT) || (HELMET) || (SUIT))
to_chat(usr, "<font color='red'>It's too cluttered inside for you to fit in!</font>")
return
visible_message("[usr] starts squeezing into the suit storage unit!", 3)
if(do_after(usr, 10))
usr.stop_pulling()
usr.client.perspective = EYE_PERSPECTIVE
usr.client.eye = src
usr.loc = src
OCCUPANT = usr
isopen = 0 //Close the thing after the guy gets inside
update_icon()
add_fingerprint(usr)
updateUsrDialog()
return
else
OCCUPANT = null //Testing this as a backup sanity test
return
/obj/machinery/suit_storage_unit/attackby(obj/item/I as obj, mob/user as mob)
if(!ispowered)
return
if(I.is_screwdriver())
panelopen = !panelopen
playsound(src, I.usesound, 100, 1)
to_chat(user, "<font color='blue'>You [panelopen ? "open up" : "close"] the unit's maintenance panel.</font>")
updateUsrDialog()
return
if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
if(!(ismob(G.affecting)))
return
if(!isopen)
to_chat(user, "<font color='red'>The unit's doors are shut.</font>")
return
if(!ispowered || isbroken)
to_chat(user, "<font color='red'>The unit is not operational.</font>")
return
if((OCCUPANT) || (HELMET) || (SUIT)) //Unit needs to be absolutely empty
to_chat(user, "<font color='red'>The unit's storage area is too cluttered.</font>")
return
visible_message("[user] starts putting [G.affecting.name] into the Suit Storage Unit.", 3)
if(do_after(user, 20))
if(!G || !G.affecting) return //derpcheck
var/mob/M = G.affecting
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
M.loc = src
OCCUPANT = M
isopen = 0 //close ittt
add_fingerprint(user)
qdel(G)
updateUsrDialog()
update_icon()
return
return
if(istype(I,/obj/item/clothing/suit/space))
if(!isopen)
return
var/obj/item/clothing/suit/space/S = I
if(SUIT)
to_chat(user, "<font color='blue'>The unit already contains a suit.</font>")
return
to_chat(user, "You load the [S.name] into the storage compartment.")
user.drop_item()
S.loc = src
SUIT = S
update_icon()
updateUsrDialog()
return
if(istype(I,/obj/item/clothing/head/helmet))
if(!isopen)
return
var/obj/item/clothing/head/helmet/H = I
if(HELMET)
to_chat(user, "<font color='blue'>The unit already contains a helmet.</font>")
return
to_chat(user, "You load the [H.name] into the storage compartment.")
user.drop_item()
H.loc = src
HELMET = H
update_icon()
updateUsrDialog()
return
if(istype(I,/obj/item/clothing/mask))
if(!isopen)
return
var/obj/item/clothing/mask/M = I
if(MASK)
to_chat(user, "<font color='blue'>The unit already contains a mask.</font>")
return
to_chat(user, "You load the [M.name] into the storage compartment.")
user.drop_item()
M.loc = src
MASK = M
update_icon()
updateUsrDialog()
return
update_icon()
updateUsrDialog()
return
/obj/machinery/suit_storage_unit/attack_ai(mob/user as mob)
return attack_hand(user)
//////////////////////////////REMINDER: Make it lock once you place some fucker inside.
//God this entire file is fucking awful //Yes
@@ -0,0 +1,54 @@
//Standard
/obj/machinery/suit_storage_unit/empty
suit_type = null
helmet_type = null
mask_type = null
/obj/machinery/suit_storage_unit/standard_unit
suit_type = /obj/item/clothing/suit/space
helmet_type = /obj/item/clothing/head/helmet/space
mask_type = /obj/item/clothing/mask/breath
//Engineering
/obj/machinery/suit_storage_unit/engineering
suit_type = /obj/item/clothing/head/helmet/space/void/engineering
helmet_type = /obj/item/clothing/suit/space/void/engineering
mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/hazmat
suit_type = /obj/item/clothing/head/helmet/space/void/engineering/hazmat
helmet_type = /obj/item/clothing/suit/space/void/engineering/hazmat
mask_type = /obj/item/clothing/mask/breath
//Mining
/obj/machinery/suit_storage_unit/mining
suit_type = /obj/item/clothing/head/helmet/space/void/mining
helmet_type = /obj/item/clothing/suit/space/void/mining
mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/mining_alt
suit_type = /obj/item/clothing/head/helmet/space/void/mining/alt
helmet_type = /obj/item/clothing/suit/space/void/mining/alt
mask_type = /obj/item/clothing/mask/breath
//Medical
/obj/machinery/suit_storage_unit/medical
suit_type = /obj/item/clothing/head/helmet/space/void/medical
helmet_type = /obj/item/clothing/suit/space/void/medical
mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/emt
suit_type = /obj/item/clothing/head/helmet/space/void/medical/emt
helmet_type = /obj/item/clothing/suit/space/void/medical/emt
mask_type = /obj/item/clothing/mask/breath
//Security
/obj/machinery/suit_storage_unit/security
suit_type = /obj/item/clothing/head/helmet/space/void/security
helmet_type = /obj/item/clothing/suit/space/void/security
mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/riot
suit_type = /obj/item/clothing/head/helmet/space/void/security/riot
helmet_type = /obj/item/clothing/suit/space/void/security/riot
mask_type = /obj/item/clothing/mask/breath
File diff suppressed because it is too large Load Diff
+5 -6
View File
@@ -37,7 +37,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/obj/machinery/telecomms/broadcaster/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
linked_radios_weakrefs |= WEAKREF(R)
/obj/machinery/telecomms/broadcaster/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
// Don't broadcast rejected signals
@@ -66,7 +66,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["level"] |= using_map.get_map_levels(listening_level, TRUE, overmap_range)
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -149,7 +149,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/obj/machinery/telecomms/allinone/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
linked_radios_weakrefs |= WEAKREF(R)
/obj/machinery/telecomms/allinone/receive_signal(datum/signal/signal)
@@ -197,7 +197,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -255,7 +255,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -761,4 +761,3 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
//to_world_log("Level: [signal.data["level"]] - Done: [signal.data["done"]]")
return signal
@@ -31,7 +31,7 @@
var/datum/radio_frequency/connection = signal.data["connection"]
var/list/forced_radios
for(var/weakref/wr in linked_radios_weakrefs)
for(var/datum/weakref/wr in linked_radios_weakrefs)
var/obj/item/device/radio/R = wr.resolve()
if(istype(R))
LAZYDISTINCTADD(forced_radios, R)
@@ -272,7 +272,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/receiver/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R))
return
linked_radios_weakrefs |= weakref(R)
linked_radios_weakrefs |= WEAKREF(R)
/obj/machinery/telecomms/receiver/receive_signal(datum/signal/signal)
if(!on) // has to be on to receive messages
@@ -299,7 +299,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
var/obj/item/device/radio/R = signal.data["radio"]
//Who're you?
if(!(weakref(R) in linked_radios_weakrefs))
if(!(WEAKREF(R) in linked_radios_weakrefs))
signal.data["reject"] = 1
return 0
+6 -8
View File
@@ -1,8 +1,8 @@
/obj/machinery/mecha_part_fabricator
icon = 'icons/obj/robotics_vr.dmi' //VOREStation Edit - New icon
icon_state = "mechfab-idle"
icon_state = "mechfab"
name = "Exosuit Fabricator"
desc = "A machine used for construction of mechas."
desc = "A machine used for the construction of mechas."
density = TRUE
anchored = TRUE
use_power = USE_POWER_IDLE
@@ -213,7 +213,7 @@
* Adds the overlay to show the fab working and sets active power usage settings.
*/
/obj/machinery/mecha_part_fabricator/proc/on_start_printing()
add_overlay("fab-active")
add_overlay("[icon_state]-active")
use_power = USE_POWER_ACTIVE
/**
@@ -222,7 +222,7 @@
* Removes the overlay to show the fab working and sets idle power usage settings. Additionally resets the description and turns off queue processing.
*/
/obj/machinery/mecha_part_fabricator/proc/on_finish_printing()
cut_overlay("fab-active")
cut_overlay("[icon_state]-active")
use_power = USE_POWER_IDLE
desc = initial(desc)
process_queue = FALSE
@@ -632,11 +632,9 @@
if(S && S.get_amount() >= 1)
var/count = 0
flick("[loading_icon_state]", src)
// yess hacky but whatever
// yess hacky but whatever //even more hacky now, but at least it works
if(loading_icon_state == "mechfab-idle")
add_overlay("mechfab-load-metal")
spawn(10)
cut_overlays("mechfab-load-metal")
flick("mechfab-load-metal", src)
while(materials[S.material.name] + amnt <= res_max_amount && S.get_amount() >= 1)
materials[S.material.name] += amnt
S.use(1)
+3 -3
View File
@@ -1,8 +1,8 @@
/obj/machinery/mecha_part_fabricator/pros
icon = 'icons/obj/robotics.dmi'
icon = 'icons/obj/robotics_vr.dmi' //VOREStation Edit - New icon
icon_state = "prosfab"
name = "Prosthetics Fabricator"
desc = "A machine used for construction of prosthetics."
desc = "A machine used for the construction of prosthetics."
density = TRUE
anchored = TRUE
unacidable = TRUE
@@ -17,7 +17,7 @@
var/species_types = list("Human")
var/species = "Human"
loading_icon_state = "prosfab_loading"
loading_icon_state = null
materials = list(
MAT_STEEL = 0,
+1 -1
View File
@@ -566,7 +566,7 @@
"View Stats" = radial_image_statpanel
)
var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_occupant_radial, user), require_near = TRUE, tooltips = TRUE)
var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, PROC_REF(check_occupant_radial), user), require_near = TRUE, tooltips = TRUE)
if(!check_occupant_radial(user))
return
if(!choice)
+3 -3
View File
@@ -23,9 +23,9 @@
metal = ismetal
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
if(dries) //VOREStation Add
addtimer(CALLBACK(src, .proc/post_spread), 3 + metal * 3)
addtimer(CALLBACK(src, .proc/pre_harden), 12 SECONDS)
addtimer(CALLBACK(src, .proc/harden), 15 SECONDS)
addtimer(CALLBACK(src, PROC_REF(post_spread)), 3 + metal * 3)
addtimer(CALLBACK(src, PROC_REF(pre_harden)), 12 SECONDS)
addtimer(CALLBACK(src, PROC_REF(harden)), 15 SECONDS)
/obj/effect/effect/foam/proc/post_spread()
process()
@@ -49,7 +49,7 @@ var/global/list/image/splatter_cache=list()
if (B.blood_DNA)
blood_DNA |= B.blood_DNA.Copy()
qdel(B)
addtimer(CALLBACK(src, .proc/dry), DRYING_TIME * (amount+1))
addtimer(CALLBACK(src, PROC_REF(dry)), DRYING_TIME * (amount+1))
/obj/effect/decal/cleanable/blood/update_icon()
if(basecolor == "rainbow") basecolor = get_random_colour(1)
@@ -36,7 +36,7 @@ GLOBAL_LIST_EMPTY(all_beam_points)
if(make_beams_on_init)
create_beams()
if(use_timer)
addtimer(CALLBACK(src, .proc/handle_beam_timer), initial_delay)
addtimer(CALLBACK(src, PROC_REF(handle_beam_timer)), initial_delay)
return ..()
/obj/effect/map_effect/beam_point/Destroy()
+2 -2
View File
@@ -4,7 +4,7 @@
density = FALSE
anchored = TRUE
icon = 'icons/obj/weapons.dmi'
icon_state = "uglymine"
icon_state = "landmine"
var/triggered = 0
var/smoke_strength = 3
var/obj/item/weapon/mine/mineitemtype = /obj/item/weapon/mine
@@ -16,7 +16,7 @@
var/obj/item/trap = null
/obj/effect/mine/Initialize()
icon_state = "uglyminearmed"
icon_state = "landmine_armed"
wires = new(src)
. = ..()
if(ispath(trap))
+3 -3
View File
@@ -728,7 +728,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
H.toggle_zoom_hud() // If the user has already limited their HUD this avoids them having a HUD when they zoom in
H.set_viewsize(viewsize)
zoom = 1
GLOB.moved_event.register(H, src, .proc/zoom)
GLOB.moved_event.register(H, src, PROC_REF(zoom))
var/tilesize = 32
var/viewoffset = tilesize * tileoffset
@@ -757,7 +757,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
if(!H.hud_used.hud_shown)
H.toggle_zoom_hud()
zoom = 0
GLOB.moved_event.unregister(H, src, .proc/zoom)
GLOB.moved_event.unregister(H, src, PROC_REF(zoom))
H.client.pixel_x = 0
H.client.pixel_y = 0
@@ -938,7 +938,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
. = ..()
if(usr.is_preference_enabled(/datum/client_preference/inv_tooltips) && ((src in usr) || isstorage(loc))) // If in inventory or in storage we're looking at
var/user = usr
tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, user), 5, TIMER_STOPPABLE)
tip_timer = addtimer(CALLBACK(src, PROC_REF(openTip), location, control, params, user), 5, TIMER_STOPPABLE)
/obj/item/MouseExited()
. = ..()
-12
View File
@@ -92,18 +92,6 @@
to_chat(user, "You unwrap the package.")
qdel(src)
/obj/item/weapon/storage/fancy/cigar/havana // Putting this here 'cuz fuck it. -Spades
name = "\improper Havana cigar case"
desc = "Save these for the fancy-pantses at the next CentCom black tie reception. You can't blow the smoke from such majestic stogies in just anyone's face."
icon_state = "cigarcase"
icon = 'icons/obj/cigarettes.dmi'
w_class = ITEMSIZE_TINY
throwforce = 2
slot_flags = SLOT_BELT
storage_slots = 7
can_hold = list(/obj/item/clothing/mask/smokable/cigarette/cigar/havana)
icon_type = "cigar"
/obj/item/weapon/miscdisc
name = "strange artefact"
desc = "A large disc-shaped item, with a red, opaque crystal embedded in the center. It is some what heavy. There are indentations along the ring of the disc. Alien scripture lines the disc."
+3 -3
View File
@@ -71,7 +71,7 @@
if("wipe")
msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].")
add_attack_logs(user,carded_ai,"Purged from AI Card")
INVOKE_ASYNC(src, .proc/wipe_ai)
INVOKE_ASYNC(src, PROC_REF(wipe_ai))
if("radio")
carded_ai.aiRadio.disabledAi = !carded_ai.aiRadio.disabledAi
to_chat(carded_ai, "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
@@ -83,7 +83,7 @@
if(carded_ai.control_disabled && carded_ai.deployed_shell)
carded_ai.disconnect_shell("Disconnecting from remote shell due to [src] wireless access interface being disabled.")
update_icon()
return TRUE
/obj/item/device/aicard/update_icon()
@@ -182,4 +182,4 @@
AI.adjustOxyLoss(2)
AI.updatehealth()
sleep(10)
flush = FALSE
flush = FALSE
@@ -106,7 +106,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
setup_tgui_camera()
//This is a pretty terrible way of doing this.
addtimer(CALLBACK(src, .proc/register_to_holder), 5 SECONDS)
addtimer(CALLBACK(src, PROC_REF(register_to_holder)), 5 SECONDS)
// Proc: register_to_holder()
// Parameters: None
@@ -376,4 +376,3 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
return
icon_state = initial(icon_state)
@@ -349,14 +349,14 @@
video_source = comm.camera
comm.visible_message("<span class='danger'>\icon[src][bicon(src)] New video connection from [comm].</span>")
update_active_camera_screen()
GLOB.moved_event.register(video_source, src, .proc/update_active_camera_screen)
GLOB.moved_event.register(video_source, src, PROC_REF(update_active_camera_screen))
update_icon()
// Proc: end_video()
// Parameters: reason - the text reason to print for why it ended
// Description: Ends the video call by clearing video_source
/obj/item/device/communicator/proc/end_video(var/reason)
GLOB.moved_event.unregister(video_source, src, .proc/update_active_camera_screen)
GLOB.moved_event.unregister(video_source, src, PROC_REF(update_active_camera_screen))
show_static()
video_source = null
@@ -364,4 +364,3 @@
visible_message(.)
update_icon()
@@ -49,7 +49,7 @@
if(!evaluate_ghost_join(user))
return ..()
tgui_alert_async(usr, "Would you like to become [src]? It is bound to [revivedby].", "Become Mob", list("Yes","No"), CALLBACK(src, .proc/reply_ghost_join), 20 SECONDS)
tgui_alert_async(usr, "Would you like to become [src]? It is bound to [revivedby].", "Become Mob", list("Yes","No"), CALLBACK(src, PROC_REF(reply_ghost_join)), 20 SECONDS)
/// A reply to an async alert request was received
/mob/living/simple_mob/proc/reply_ghost_join(response)
@@ -64,7 +64,7 @@
/mob/living/simple_mob/proc/ghost_join(mob/observer/dead/D)
log_and_message_admins("[key_name_admin(D)] joined [src] as a ghost [ADMIN_FLW(src)]")
active_ghost_pods -= src
// Move the ghost in
if(D.mind)
D.mind.active = TRUE
@@ -72,7 +72,7 @@
else
src.ckey = D.ckey
qdel(D)
// Clean up the simplemob
ghostjoin = FALSE
ghostjoin_icon()
@@ -91,14 +91,14 @@
return FALSE
// At this point we can at least send them messages as to why they can't join, since they are a mob with a client
if(!ghostjoin)
if(!ghostjoin)
to_chat(D, "<span class='notice'>Sorry, [src] is no longer ghost-joinable.</span>")
return FALSE
if(ckey)
to_chat(D, "<span class='notice'>Sorry, someone else has already inhabited [src].</span>")
return FALSE
if(capture_caught && !D.client.prefs.capture_crystal)
to_chat(D, "<span class='notice'>Sorry, [src] is participating in capture mechanics, and your preferences do not allow for that.</span>")
return FALSE
@@ -128,7 +128,7 @@
else
. += "<span class='notice'>The screen indicates that this device can be used again in [cooldowntime] seconds, and that it has enough energy for [charges] uses.</span>"
/obj/item/device/denecrotizer/proc/check_target(mob/living/simple_mob/target, mob/living/user)
/obj/item/device/denecrotizer/proc/check_target(mob/living/simple_mob/target, mob/living/user)
if(!target.Adjacent(user))
return FALSE
if(user.a_intent != I_HELP) //be gentle
@@ -150,10 +150,10 @@
if(!advanced)
to_chat(user, "<span class='notice'>[src] doesn't seem to work on that.</span>")
return FALSE
if(target.ai_holder.retaliate || target.ai_holder.hostile) // You can be friends with still living mobs if they are passive I GUESS
if(target.ai_holder.retaliate || target.ai_holder.hostile) // You can be friends with still living mobs if they are passive I GUESS
to_chat(user, "<span class='notice'>[src] doesn't seem to work on that.</span>")
return FALSE
if(!target.mind)
if(!target.mind)
user.visible_message("[user] gently presses [src] to [target]...", runemessage = "presses [src] to [target]")
if(do_after(user, revive_time, exclusive = TASK_USER_EXCLUSIVE, target = target))
target.faction = user.faction
@@ -197,7 +197,7 @@
icon_state = "[initial(icon_state)]-o"
update_icon()
return
/obj/item/device/denecrotizer/proc/basic_rez(mob/living/simple_mob/target, mob/living/user) //so medical can have a way to bring back people's pets or whatever, does not change any settings about the mob or offer it to ghosts.
user.visible_message("[user] presses [src] to [target]...", runemessage = "presses [src] to [target]")
if(do_after(user, revive_time, exclusive = TASK_ALL_EXCLUSIVE, target = target))
@@ -235,9 +235,9 @@
I.invisibility = INVISIBILITY_OBSERVER
I.plane = PLANE_GHOSTS
I.appearance_flags = KEEP_APART|RESET_TRANSFORM
cut_overlay(I)
if(ghostjoin)
add_overlay(I)
@@ -247,4 +247,4 @@
icon_state = "m-denecrotizer"
advanced = 0 //This one isn't as fancy
cooldown = 5 MINUTES //not as long
charges = 20 //in case spiders merc Ian
charges = 20 //in case spiders merc Ian
+2 -2
View File
@@ -45,8 +45,8 @@ var/list/GPS_list = list()
if(istype(loc, /mob))
holder = loc
GLOB.moved_event.register(holder, src, .proc/update_compass)
GLOB.dir_set_event.register(holder, src, .proc/update_compass)
GLOB.moved_event.register(holder, src, PROC_REF(update_compass))
GLOB.dir_set_event.register(holder, src, PROC_REF(update_compass))
if(holder && tracking)
if(!is_in_processing_list)
@@ -56,7 +56,7 @@ var/global/list/default_medbay_channels = list(
// Bluespace radios talk directly to telecomms equipment
var/bluespace_radio = FALSE
var/weakref/bs_tx_weakref //Maybe misleading, this is the device to TRANSMIT TO
var/datum/weakref/bs_tx_weakref //Maybe misleading, this is the device to TRANSMIT TO
// For mappers or subtypes, to start them prelinked to these devices
var/bs_tx_preload_id
var/bs_rx_preload_id
@@ -104,14 +104,14 @@ var/global/list/default_medbay_channels = list(
//Try to find a receiver
for(var/obj/machinery/telecomms/receiver/RX in telecomms_list)
if(RX.id == bs_tx_preload_id) //Again, bs_tx is the thing to TRANSMIT TO, so a receiver.
bs_tx_weakref = weakref(RX)
bs_tx_weakref = WEAKREF(RX)
RX.link_radio(src)
break
//Hmm, howabout an AIO machine
if(!bs_tx_weakref)
for(var/obj/machinery/telecomms/allinone/AIO in telecomms_list)
if(AIO.id == bs_tx_preload_id)
bs_tx_weakref = weakref(AIO)
bs_tx_weakref = WEAKREF(AIO)
AIO.link_radio(src)
break
if(!bs_tx_weakref)
@@ -2,8 +2,9 @@
name = "portable suit cooling unit"
desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling."
w_class = ITEMSIZE_LARGE
icon = 'icons/obj/device.dmi'
icon = 'icons/obj/suit_cooler.dmi'
icon_state = "suitcooler0"
item_state = "coolingpack"
slot_flags = SLOT_BACK
//copied from tank.dm
@@ -171,13 +172,32 @@
return ..()
/obj/item/device/suit_cooling_unit/proc/updateicon()
if (cover_open)
if (cell)
cut_overlays()
if(cover_open)
if(cell)
icon_state = "suitcooler1"
else
icon_state = "suitcooler2"
else
icon_state = "suitcooler0"
return
icon_state = "suitcooler0"
if(!cell || !on)
return
switch(round(cell.percent()))
if(86 to INFINITY)
add_overlay("battery-0")
if(69 to 85)
add_overlay("battery-1")
if(52 to 68)
add_overlay("battery-2")
if(35 to 51)
add_overlay("battery-3")
if(18 to 34)
add_overlay("battery-4")
if(-INFINITY to 17)
add_overlay("battery-5")
/obj/item/device/suit_cooling_unit/examine(mob/user)
. = ..()
@@ -218,7 +238,7 @@
/obj/item/device/suit_cooling_unit/emergency/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (W.is_screwdriver())
to_chat(user, "<span class='warning'>This model has the cell permanently installed!</span>")
to_chat(user, "<span class='warning'>This cooler's cell is permanently installed!</span>")
return
return ..()
@@ -88,8 +88,9 @@
/obj/item/device/taperecorder/hear_talk(mob/M, list/message_pieces, verb)
var/msg = multilingual_to_message(message_pieces, requires_machine_understands = TRUE, with_capitalization = TRUE)
var/voice = M.GetVoice() //Defined on living, returns name for normal mobs/
if(mytape && recording)
mytape.record_speech("[M.name] [verb], \"[msg]\"")
mytape.record_speech("[voice] [verb], \"[msg]\"")
/obj/item/device/taperecorder/see_emote(mob/M as mob, text, var/emote_type)
@@ -432,4 +433,4 @@
//Random colour tapes
/obj/item/device/tape/random/New()
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
@@ -125,7 +125,7 @@ This device can be easily used to break ERP preferences due to the nature of tel
Make sure you carefully examine someone's OOC prefs before teleporting them if you are going to use this device for ERP purposes.
This device records all warnings given and teleport events for admin review in case of pref-breaking, so just don't do it.
"},"OOC Warning")
var/choice = show_radial_menu(user, radial_menu_anchor, radial_images, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
var/choice = show_radial_menu(user, radial_menu_anchor, radial_images, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE)
if(!choice)
return
+2 -3
View File
@@ -8,7 +8,7 @@
var/channel = "NCS Northern Star News Feed"
var/obj/machinery/camera/network/thunder/camera
var/obj/item/device/radio/radio
var/weakref/showing
var/datum/weakref/showing
var/showing_name
/obj/item/device/tvcamera/New()
@@ -95,7 +95,7 @@
if(showing)
hide_tvs(showing)
showing = weakref(thing)
showing = WEAKREF(thing)
showing_name = "[thing]"
for(var/obj/machinery/computer/security/telescreen/entertainment/ES as anything in GLOB.entertainment_screens)
ES.show_thing(thing)
@@ -221,4 +221,3 @@
return
..()
+2 -2
View File
@@ -25,7 +25,7 @@
/obj/item/device/uplink/Initialize(var/mapload)
. = ..()
addtimer(CALLBACK(src, .proc/next_offer), offer_time) //It seems like only the /hidden type actually makes use of this...
addtimer(CALLBACK(src, PROC_REF(next_offer)), offer_time) //It seems like only the /hidden type actually makes use of this...
/obj/item/device/uplink/get_item_cost(var/item_type, var/item_cost)
return (discount_item && (item_type == discount_item)) ? max(1, round(item_cost*discount_amount)) : item_cost
@@ -63,7 +63,7 @@
discount_amount = pick(90;0.9, 80;0.8, 70;0.7, 60;0.6, 50;0.5, 40;0.4, 30;0.3, 20;0.2, 10;0.1)
next_offer_time = world.time + offer_time
SStgui.update_uis(src)
addtimer(CALLBACK(src, .proc/next_offer), offer_time)
addtimer(CALLBACK(src, PROC_REF(next_offer)), offer_time)
// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated.
/obj/item/device/uplink/hidden/proc/toggle()
+2 -2
View File
@@ -170,7 +170,7 @@
to_chat(user, "<span class='notice'>You offer battle to [target.name]!</span>")
to_chat(target, "<span class='notice'><b>[user.name] wants to battle with [T.His] [name]!</b> <i>Attack them with a toy mech to initiate combat.</i></span>")
wants_to_battle = TRUE
addtimer(CALLBACK(src, .proc/withdraw_offer, user), 6 SECONDS)
addtimer(CALLBACK(src, PROC_REF(withdraw_offer), user), 6 SECONDS)
return
..()
@@ -602,4 +602,4 @@
#undef SPECIAL_ATTACK_DAMAGE
#undef SPECIAL_ATTACK_UTILITY
#undef SPECIAL_ATTACK_OTHER
#undef MAX_BATTLE_LENGTH
#undef MAX_BATTLE_LENGTH

Some files were not shown because too many files have changed in this diff Show More