mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-24 21:40:55 +01:00
Merge pull request #24 from Aurorastation/prepare_stuff_for_second_week
Prepare stuff for second week
This commit is contained in:
+37
-25
@@ -14,30 +14,42 @@
|
||||
// Shims for some list procs in lists.dm.
|
||||
#define isemptylist(L) (!LAZYLEN(L))
|
||||
|
||||
// binary search sorted insert
|
||||
// IN: Object to be inserted
|
||||
// LIST: List to insert object into
|
||||
// TYPECONT: The typepath of the contents of the list
|
||||
// COMPARE: The variable on the objects to compare
|
||||
#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \
|
||||
var/__BIN_CTTL = length(LIST);\
|
||||
if(!__BIN_CTTL) {\
|
||||
LIST += IN;\
|
||||
} else {\
|
||||
var/__BIN_LEFT = 1;\
|
||||
var/__BIN_RIGHT = __BIN_CTTL;\
|
||||
var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
var/##TYPECONT/__BIN_ITEM;\
|
||||
while(__BIN_LEFT < __BIN_RIGHT) {\
|
||||
__BIN_ITEM = LIST[__BIN_MID];\
|
||||
if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\
|
||||
__BIN_LEFT = __BIN_MID + 1;\
|
||||
} else {\
|
||||
__BIN_RIGHT = __BIN_MID;\
|
||||
/// Passed into BINARY_INSERT to compare keys
|
||||
#define COMPARE_KEY __BIN_LIST[__BIN_MID]
|
||||
/// Passed into BINARY_INSERT to compare values
|
||||
#define COMPARE_VALUE __BIN_LIST[__BIN_LIST[__BIN_MID]]
|
||||
|
||||
/**
|
||||
* Binary search sorted insert from TG
|
||||
* INPUT: Object to be inserted
|
||||
* LIST: List to insert object into
|
||||
* TYPECONT: The typepath of the contents of the list
|
||||
* COMPARE: The object to compare against, usualy the same as INPUT
|
||||
* COMPARISON: The variable on the objects to compare
|
||||
* COMPTYPE: How should the values be compared? Either COMPARE_KEY or COMPARE_VALUE.
|
||||
*/
|
||||
#define BINARY_INSERT(INPUT, LIST, TYPECONT, COMPARE, COMPARISON, COMPTYPE) \
|
||||
do {\
|
||||
var/list/__BIN_LIST = LIST;\
|
||||
var/__BIN_CTTL = length(__BIN_LIST);\
|
||||
if(!__BIN_CTTL) {\
|
||||
__BIN_LIST += INPUT;\
|
||||
} else {\
|
||||
var/__BIN_LEFT = 1;\
|
||||
var/__BIN_RIGHT = __BIN_CTTL;\
|
||||
var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
var ##TYPECONT/__BIN_ITEM;\
|
||||
while(__BIN_LEFT < __BIN_RIGHT) {\
|
||||
__BIN_ITEM = COMPTYPE;\
|
||||
if(__BIN_ITEM.##COMPARISON <= COMPARE.##COMPARISON) {\
|
||||
__BIN_LEFT = __BIN_MID + 1;\
|
||||
} else {\
|
||||
__BIN_RIGHT = __BIN_MID;\
|
||||
};\
|
||||
__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
};\
|
||||
__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
__BIN_ITEM = COMPTYPE;\
|
||||
__BIN_MID = __BIN_ITEM.##COMPARISON > COMPARE.##COMPARISON ? __BIN_MID : __BIN_MID + 1;\
|
||||
__BIN_LIST.Insert(__BIN_MID, INPUT);\
|
||||
};\
|
||||
__BIN_ITEM = LIST[__BIN_MID];\
|
||||
__BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\
|
||||
LIST.Insert(__BIN_MID, IN);\
|
||||
}
|
||||
} while(FALSE)
|
||||
|
||||
@@ -95,4 +95,10 @@
|
||||
#define BODYTYPE_MONKEY "Monkey"
|
||||
|
||||
#define BODYTYPE_SKELETON "Skeleton"
|
||||
#define BODYTYPE_CULTGHOST "Apparition"
|
||||
#define BODYTYPE_CULTGHOST "Apparition"
|
||||
|
||||
#define ALL_SPECIES list(SPECIES_HUMAN, SPECIES_HUMAN_OFFWORLD, SPECIES_IPC, SPECIES_IPC_BISHOP, SPECIES_IPC_G1, \
|
||||
SPECIES_IPC_G2, SPECIES_IPC_SHELL, SPECIES_IPC_UNBRANDED, SPECIES_IPC_XION, SPECIES_IPC_ZENGHU, \
|
||||
SPECIES_DIONA, SPECIES_DIONA_COEUS, SPECIES_SKRELL, SPECIES_SKRELL_AXIORI, SPECIES_TAJARA, \
|
||||
SPECIES_TAJARA_MSAI, SPECIES_TAJARA_ZHAN, SPECIES_UNATHI, SPECIES_VAURCA_WORKER, \
|
||||
SPECIES_VAURCA_WARRIOR, SPECIES_VAURCA_BULWARK, SPECIES_VAURCA_BREEDER)
|
||||
@@ -167,4 +167,7 @@
|
||||
|
||||
// Will filter out extra rotations and negative rotations
|
||||
// E.g: 540 becomes 180. -180 becomes 180.
|
||||
#define SIMPLIFY_DEGREES(degrees) (MODULUS_FLOAT((degrees), 360))
|
||||
#define SIMPLIFY_DEGREES(degrees) (MODULUS_FLOAT((degrees), 360))
|
||||
|
||||
/// Value or the next multiple of divisor in a positive direction. Ceilm(-1.5, 0.3) = -1.5 , Ceilm(-1.5, 0.4) = -1.2
|
||||
#define Ceilm(value, divisor) ( -round(-(value) / (divisor)) * (divisor) )
|
||||
|
||||
@@ -144,13 +144,13 @@
|
||||
return O
|
||||
return
|
||||
|
||||
/mob/Login()
|
||||
..()
|
||||
/mob/living/LateLogin()
|
||||
. = ..()
|
||||
if(ability_master)
|
||||
ability_master.toggle_open(1)
|
||||
client.screen -= ability_master
|
||||
|
||||
/mob/Initialize()
|
||||
/mob/living/Initialize()
|
||||
. = ..()
|
||||
ability_master = new /obj/screen/movable/ability_master(FALSE, src)
|
||||
|
||||
|
||||
@@ -294,6 +294,7 @@ var/list/gamemode_cache = list()
|
||||
// Configurable hostname / port for the NTSL Daemon.
|
||||
var/ntsl_hostname = "localhost"
|
||||
var/ntsl_port = "1945"
|
||||
var/ntsl_disabled = TRUE
|
||||
|
||||
// Is external Auth enabled
|
||||
var/external_auth = FALSE
|
||||
@@ -938,6 +939,8 @@ var/list/gamemode_cache = list()
|
||||
ntsl_hostname = value
|
||||
if ("ntsl_port")
|
||||
ntsl_port = value
|
||||
if ("ntsl_disabled")
|
||||
ntsl_disabled = text2num(value)
|
||||
|
||||
if ("external_auth")
|
||||
external_auth = TRUE
|
||||
|
||||
@@ -489,7 +489,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
queue_node.times_fired++
|
||||
|
||||
if (queue_node_flags & SS_TICKER)
|
||||
queue_node.next_fire = world.time + (world.tick_lag * (queue_node.wait + (queue_node.tick_overrun/100)))
|
||||
queue_node.next_fire = world.time + (world.tick_lag * queue_node.wait)
|
||||
else if (queue_node_flags & SS_POST_FIRE_TIMING)
|
||||
queue_node.next_fire = world.time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100))
|
||||
else if (queue_node_flags & SS_KEEP_TIMING)
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
else
|
||||
if (SS_flags & SS_BACKGROUND)
|
||||
continue
|
||||
if (SS_flags & SS_TICKER)
|
||||
if (SS_flags & (SS_TICKER|SS_BACKGROUND) == SS_TICKER)
|
||||
break
|
||||
if (queue_node_priority < SS_priority)
|
||||
break
|
||||
|
||||
@@ -137,10 +137,11 @@ var/datum/controller/subsystem/docs/SSdocs
|
||||
//Loads the document data from JSON
|
||||
/datum/controller/subsystem/docs/proc/load_from_json()
|
||||
var/list/docsconfig = list()
|
||||
try
|
||||
|
||||
if(isfile("config/docs.json"))
|
||||
docsconfig = json_decode(return_file_text("config/docs.json"))
|
||||
catch(var/exception/ej)
|
||||
log_debug("SSdocs: Warning: Could not load config, as docs.json is missing - [ej]")
|
||||
else
|
||||
log_debug("SSdocs: Warning: Could not load config, as docs.json is missing")
|
||||
return 0
|
||||
|
||||
//Reset the currently loaded data
|
||||
|
||||
@@ -34,7 +34,7 @@ NTSL2 deamon management subsystem, responsible for handling events from deamon a
|
||||
if(RUSTG_HTTP_METHOD_POST)
|
||||
if(arguments)
|
||||
body = json_encode(arguments)
|
||||
|
||||
|
||||
return http_create_request(method, url, body)
|
||||
return FALSE
|
||||
|
||||
@@ -107,7 +107,7 @@ NTSL2 deamon management subsystem, responsible for handling events from deamon a
|
||||
if(istype(cb))
|
||||
cb.InvokeAsync(response)
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/controller/subsystem/processing/ntsl2/proc/is_complete(var/task_id)
|
||||
if(!task_id)
|
||||
@@ -115,9 +115,12 @@ NTSL2 deamon management subsystem, responsible for handling events from deamon a
|
||||
if(tasks[task_id])
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/datum/controller/subsystem/processing/ntsl2/proc/attempt_connect()
|
||||
if(config.ntsl_disabled)
|
||||
log_debug("NTSL2++ Daemon disabled via config")
|
||||
return FALSE
|
||||
var/res = sync_send("clear")
|
||||
if(!res)
|
||||
log_debug("NTSL2++ Daemon could not be connected to. Functionality will not be enabled.")
|
||||
@@ -150,4 +153,4 @@ NTSL2 deamon management subsystem, responsible for handling events from deamon a
|
||||
handle_task_completion(result, task)
|
||||
tasks -= task_id
|
||||
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
var/datum/controller/subsystem/shuttle/SSshuttle
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle
|
||||
/datum/controller/subsystem/shuttle
|
||||
name = "Shuttle"
|
||||
wait = 2 SECONDS
|
||||
flags = 0
|
||||
priority = SS_PRIORITY_SHUTTLE
|
||||
init_order = SS_INIT_MISC //Should be initialized after all maploading is over and atoms are initialized, to ensure that landmarks have been initialized.
|
||||
|
||||
@@ -27,10 +26,10 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
|
||||
var/tmp/list/working_shuttles
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/New()
|
||||
/datum/controller/subsystem/shuttle/New()
|
||||
NEW_SS_GLOBAL(SSshuttle)
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/Initialize()
|
||||
/datum/controller/subsystem/shuttle/Initialize()
|
||||
last_landmark_registration_time = world.time
|
||||
for(var/shuttle_type in subtypesof(/datum/shuttle)) // This accounts for most shuttles, though away maps can queue up more.
|
||||
var/datum/shuttle/shuttle = shuttle_type
|
||||
@@ -42,26 +41,26 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
clear_init_queue()
|
||||
. = ..()
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/fire(resumed = FALSE)
|
||||
/datum/controller/subsystem/shuttle/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
working_shuttles = process_shuttles.Copy()
|
||||
|
||||
while(working_shuttles.len)
|
||||
var/datum/shuttle/shuttle = working_shuttles[working_shuttles.len]
|
||||
working_shuttles.len--
|
||||
if(shuttle.process_state && (shuttle.process(wait, times_fired, src) == PROCESS_KILL))
|
||||
if(shuttle.process_state && (shuttle.process() == PROCESS_KILL))
|
||||
process_shuttles -= shuttle
|
||||
|
||||
if(TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/clear_init_queue()
|
||||
/datum/controller/subsystem/shuttle/proc/clear_init_queue()
|
||||
if(block_queue)
|
||||
return
|
||||
initialize_shuttles()
|
||||
initialize_sectors()
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/initialize_shuttles()
|
||||
/datum/controller/subsystem/shuttle/proc/initialize_shuttles()
|
||||
var/list/shuttles_made = list()
|
||||
for(var/shuttle_type in shuttles_to_initialize)
|
||||
var/shuttle = initialize_shuttle(shuttle_type)
|
||||
@@ -70,12 +69,12 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
hook_up_motherships(shuttles_made)
|
||||
shuttles_to_initialize = null
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/initialize_sectors()
|
||||
/datum/controller/subsystem/shuttle/proc/initialize_sectors()
|
||||
for(var/sector in sectors_to_initialize)
|
||||
initialize_sector(sector)
|
||||
sectors_to_initialize = null
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/register_landmark(shuttle_landmark_tag, obj/effect/shuttle_landmark/shuttle_landmark)
|
||||
/datum/controller/subsystem/shuttle/proc/register_landmark(shuttle_landmark_tag, obj/effect/shuttle_landmark/shuttle_landmark)
|
||||
if (registered_shuttle_landmarks[shuttle_landmark_tag])
|
||||
CRASH("Attempted to register shuttle landmark with tag [shuttle_landmark_tag], but it is already registered!")
|
||||
if (istype(shuttle_landmark))
|
||||
@@ -93,12 +92,12 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
else
|
||||
landmarks_awaiting_sector += shuttle_landmark
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/get_landmark(var/shuttle_landmark_tag)
|
||||
/datum/controller/subsystem/shuttle/proc/get_landmark(var/shuttle_landmark_tag)
|
||||
return registered_shuttle_landmarks[shuttle_landmark_tag]
|
||||
|
||||
//Checks if the given sector's landmarks have initialized; if so, registers them with the sector, if not, marks them for assignment after they come in.
|
||||
//Also adds automatic landmarks that were waiting on their sector to spawn.
|
||||
/datum/controller/subsystem/processing/shuttle/proc/initialize_sector(obj/effect/overmap/visitable/given_sector)
|
||||
/datum/controller/subsystem/shuttle/proc/initialize_sector(obj/effect/overmap/visitable/given_sector)
|
||||
given_sector.populate_sector_objects() // This is a late init operation that sets up the sector's map_z and does non-overmap-related init tasks.
|
||||
|
||||
for(var/landmark_tag in given_sector.initial_generic_waypoints)
|
||||
@@ -119,7 +118,7 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
|
||||
initialized_sectors |= given_sector
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/try_add_landmark_tag(landmark_tag, obj/effect/overmap/visitable/given_sector)
|
||||
/datum/controller/subsystem/shuttle/proc/try_add_landmark_tag(landmark_tag, obj/effect/overmap/visitable/given_sector)
|
||||
var/obj/effect/shuttle_landmark/landmark = get_landmark(landmark_tag)
|
||||
if(!landmark)
|
||||
return FALSE
|
||||
@@ -132,14 +131,14 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
given_sector.add_landmark(landmark, shuttle_name)
|
||||
. = TRUE
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/initialize_shuttle(var/shuttle_type)
|
||||
/datum/controller/subsystem/shuttle/proc/initialize_shuttle(var/shuttle_type)
|
||||
var/datum/shuttle/shuttle = shuttle_type
|
||||
if(initial(shuttle.category) != shuttle_type)
|
||||
shuttle = new shuttle()
|
||||
shuttle_areas |= shuttle.shuttle_area
|
||||
return shuttle
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/hook_up_motherships(shuttles_list)
|
||||
/datum/controller/subsystem/shuttle/proc/hook_up_motherships(shuttles_list)
|
||||
for(var/datum/shuttle/S in shuttles_list)
|
||||
if(S.mothershuttle && !S.motherdock)
|
||||
var/datum/shuttle/mothership = shuttles[S.mothershuttle]
|
||||
@@ -149,7 +148,7 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
else
|
||||
error("Shuttle [S] was unable to find mothership [mothership]!")
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/toggle_overmap(new_setting)
|
||||
/datum/controller/subsystem/shuttle/proc/toggle_overmap(new_setting)
|
||||
if(overmap_halted == new_setting)
|
||||
return
|
||||
overmap_halted = !overmap_halted
|
||||
@@ -157,5 +156,5 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
var/obj/effect/overmap/visitable/ship/ship_effect = ship
|
||||
overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/stat_entry()
|
||||
/datum/controller/subsystem/shuttle/stat_entry()
|
||||
..("Shuttles:[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]")
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
#define BUCKET_LEN (round(10*(60/world.tick_lag), 1)) //how many ticks should we keep in the bucket. (1 minutes worth)
|
||||
/// Controls how many buckets should be kept, each representing a tick. (1 minutes worth)
|
||||
#define BUCKET_LEN (world.fps*1*60)
|
||||
/// Helper for getting the correct bucket for a given timer
|
||||
#define BUCKET_POS(timer) (((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag)+1) % BUCKET_LEN)||BUCKET_LEN)
|
||||
#define TIMER_ID_MAX (2**24) //max float with integer precision
|
||||
/// Gets the maximum time at which timers will be invoked from buckets, used for deferring to secondary queue
|
||||
#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1)))
|
||||
/// Max float with integer precision
|
||||
#define TIMER_ID_MAX (2**24)
|
||||
|
||||
/**
|
||||
* # Timer Subsystem
|
||||
*
|
||||
* Handles creation, callbacks, and destruction of timed events.
|
||||
*
|
||||
* It is important to understand the buckets used in the timer subsystem are just a series of circular doubly-linked
|
||||
* lists. The object at a given index in bucket_list is a /datum/timedevent, the head of a circular list, which has prev
|
||||
* and next references for the respective elements in that bucket's circular list.
|
||||
*/
|
||||
var/datum/controller/subsystem/timer/SStimer
|
||||
|
||||
/datum/controller/subsystem/timer
|
||||
@@ -10,72 +23,96 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
wait = 1 //SS_TICKER subsystem, so wait is in ticks
|
||||
priority = SS_PRIORITY_TIMER
|
||||
|
||||
flags = SS_FIRE_IN_LOBBY|SS_TICKER|SS_NO_INIT
|
||||
flags = SS_TICKER|SS_NO_INIT|SS_FIRE_IN_LOBBY
|
||||
|
||||
var/list/datum/timedevent/second_queue = list() //awe, yes, you've had first queue, but what about second queue?
|
||||
/// Queue used for storing timers that do not fit into the current buckets
|
||||
var/list/datum/timedevent/second_queue = list()
|
||||
/// A hashlist dictionary used for storing unique timers
|
||||
var/list/hashes = list()
|
||||
|
||||
var/head_offset = 0 //world.time of the first entry in the the bucket.
|
||||
var/practical_offset = 0 //index of the first non-empty item in the bucket.
|
||||
var/bucket_resolution = 0 //world.tick_lag the bucket was designed for
|
||||
var/bucket_count = 0 //how many timers are in the buckets
|
||||
|
||||
var/list/bucket_list = list() //list of buckets, each bucket holds every timer that has to run that byond tick.
|
||||
|
||||
var/list/timer_id_dict = list() //list of all active timers assoicated to their timer id (for easy lookup)
|
||||
|
||||
var/list/clienttime_timers = list() //special snowflake timers that run on fancy pansy "client time"
|
||||
|
||||
/// world.time of the first entry in the bucket list, effectively the 'start time' of the current buckets
|
||||
var/head_offset = 0
|
||||
/// Index of the wrap around pivot for buckets. buckets before this are later running buckets wrapped around from the end of the bucket list.
|
||||
var/practical_offset = 1
|
||||
/// world.tick_lag the bucket was designed for
|
||||
var/bucket_resolution = 0
|
||||
/// How many timers are in the buckets
|
||||
var/bucket_count = 0
|
||||
/// List of buckets, each bucket holds every timer that has to run that byond tick
|
||||
var/list/bucket_list = list()
|
||||
/// List of all active timers associated to their timer ID (for easy lookup)
|
||||
var/list/timer_id_dict = list()
|
||||
/// Special timers that run in real-time, not BYOND time; these are more expensive to run and maintain
|
||||
var/list/clienttime_timers = list()
|
||||
/// Contains the last time that a timer's callback was invoked, or the last tick the SS fired if no timers are being processed
|
||||
var/last_invoke_tick = 0
|
||||
/// Keeps track of the next index to work on for client timers
|
||||
var/next_clienttime_timer_index = 0
|
||||
/// Contains the last time that a warning was issued for not invoking callbacks
|
||||
var/static/last_invoke_warning = 0
|
||||
/// Boolean operator controlling if the timer SS will automatically reset buckets if it fails to invoke callbacks for an extended period of time
|
||||
var/static/bucket_auto_reset = TRUE
|
||||
/// How many times bucket was reset
|
||||
var/bucket_reset_count = 0
|
||||
|
||||
/datum/controller/subsystem/timer/New()
|
||||
NEW_SS_GLOBAL(SStimer)
|
||||
bucket_list.len = BUCKET_LEN
|
||||
head_offset = world.time
|
||||
bucket_resolution = world.tick_lag
|
||||
|
||||
/datum/controller/subsystem/timer/stat_entry(msg)
|
||||
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)]")
|
||||
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)] RST:[bucket_reset_count]")
|
||||
|
||||
/datum/controller/subsystem/timer/fire(resumed = FALSE)
|
||||
var/lit = last_invoke_tick
|
||||
var/last_check = world.time - TICKS2DS(BUCKET_LEN*1.5)
|
||||
var/list/bucket_list = src.bucket_list
|
||||
|
||||
if(!bucket_count)
|
||||
last_invoke_tick = world.time
|
||||
|
||||
if(lit && lit < last_check && head_offset < last_check && last_invoke_warning < last_check)
|
||||
last_invoke_warning = world.time
|
||||
var/msg = "No regular timers processed in the last [BUCKET_LEN*1.5] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!"
|
||||
message_admins(msg)
|
||||
WARNING(msg)
|
||||
if(bucket_auto_reset)
|
||||
bucket_resolution = 0
|
||||
|
||||
log_ss(name, "Timer bucket reset. world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
/datum/controller/subsystem/timer/proc/dump_timer_buckets(full = TRUE)
|
||||
var/list/to_log = list("Timer bucket reset. world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
if (full)
|
||||
for (var/i in 1 to length(bucket_list))
|
||||
var/datum/timedevent/bucket_head = bucket_list[i]
|
||||
if (!bucket_head)
|
||||
continue
|
||||
|
||||
log_ss(name, "Active timers at index [i]:")
|
||||
|
||||
to_log += "Active timers at index [i]:"
|
||||
var/datum/timedevent/bucket_node = bucket_head
|
||||
var/anti_loop_check = 1000
|
||||
var/anti_loop_check = 1
|
||||
do
|
||||
log_ss(name, get_timer_debug_string(bucket_node))
|
||||
to_log += get_timer_debug_string(bucket_node)
|
||||
bucket_node = bucket_node.next
|
||||
anti_loop_check--
|
||||
while(bucket_node && bucket_node != bucket_head && anti_loop_check)
|
||||
log_ss(name, "Active timers in the second_queue queue:")
|
||||
|
||||
to_log += "Active timers in the second_queue queue:"
|
||||
for(var/I in second_queue)
|
||||
log_ss(name, get_timer_debug_string(I))
|
||||
to_log += get_timer_debug_string(I)
|
||||
|
||||
var/next_clienttime_timer_index = 0
|
||||
var/len = length(clienttime_timers)
|
||||
// Dump all the logged data to the world log
|
||||
log_ss("timers", to_log.Join("\n"))
|
||||
|
||||
for (next_clienttime_timer_index in 1 to len)
|
||||
/datum/controller/subsystem/timer/fire(resumed = FALSE)
|
||||
// Store local references to datum vars as it is faster to access them
|
||||
var/lit = last_invoke_tick
|
||||
var/list/bucket_list = src.bucket_list
|
||||
var/last_check = world.time - TICKS2DS(BUCKET_LEN * 1.5)
|
||||
|
||||
// If there are no timers being tracked, then consider now to be the last invoked time
|
||||
if(!bucket_count)
|
||||
last_invoke_tick = world.time
|
||||
|
||||
// Check that we have invoked a callback in the last 1.5 minutes of BYOND time,
|
||||
// and throw a warning and reset buckets if this is true
|
||||
if(lit && lit < last_check && head_offset < last_check && last_invoke_warning < last_check)
|
||||
last_invoke_warning = world.time
|
||||
var/msg = "No regular timers processed in the last [BUCKET_LEN * 1.5] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!"
|
||||
message_admins(msg)
|
||||
WARNING(msg)
|
||||
if(bucket_auto_reset)
|
||||
bucket_resolution = 0
|
||||
dump_timer_buckets()
|
||||
|
||||
// Process client-time timers
|
||||
if (next_clienttime_timer_index)
|
||||
clienttime_timers.Cut(1, next_clienttime_timer_index+1)
|
||||
next_clienttime_timer_index = 0
|
||||
for (next_clienttime_timer_index in 1 to length(clienttime_timers))
|
||||
if (MC_TICK_CHECK)
|
||||
next_clienttime_timer_index--
|
||||
break
|
||||
@@ -86,8 +123,8 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
|
||||
var/datum/callback/callBack = ctime_timer.callBack
|
||||
if (!callBack)
|
||||
clienttime_timers.Cut(next_clienttime_timer_index,next_clienttime_timer_index+1)
|
||||
CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]")
|
||||
CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], \
|
||||
head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]")
|
||||
|
||||
ctime_timer.spent = REALTIMEOFDAY
|
||||
callBack.InvokeAsync()
|
||||
@@ -95,148 +132,115 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
if(ctime_timer.flags & TIMER_LOOP)
|
||||
ctime_timer.spent = 0
|
||||
ctime_timer.timeToRun = REALTIMEOFDAY + ctime_timer.wait
|
||||
BINARY_INSERT(ctime_timer, clienttime_timers, datum/timedevent, timeToRun)
|
||||
BINARY_INSERT(ctime_timer, clienttime_timers, /datum/timedevent, ctime_timer, timeToRun, COMPARE_KEY)
|
||||
else
|
||||
qdel(ctime_timer)
|
||||
|
||||
|
||||
// Remove invoked client-time timers
|
||||
if (next_clienttime_timer_index)
|
||||
clienttime_timers.Cut(1, next_clienttime_timer_index+1)
|
||||
next_clienttime_timer_index = 0
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
var/static/list/spent = list()
|
||||
var/static/datum/timedevent/timer
|
||||
// Check for when we need to loop the buckets, this occurs when
|
||||
// the head_offset is approaching BUCKET_LEN ticks in the past
|
||||
if (practical_offset > BUCKET_LEN)
|
||||
head_offset += TICKS2DS(BUCKET_LEN)
|
||||
practical_offset = 1
|
||||
resumed = FALSE
|
||||
|
||||
// Check for when we have to reset buckets, typically from auto-reset
|
||||
if ((length(bucket_list) != BUCKET_LEN) || (world.tick_lag != bucket_resolution))
|
||||
reset_buckets()
|
||||
bucket_list = src.bucket_list
|
||||
resumed = FALSE
|
||||
|
||||
|
||||
if (!resumed)
|
||||
timer = null
|
||||
|
||||
while (practical_offset <= BUCKET_LEN && head_offset + ((practical_offset-1)*world.tick_lag) <= world.time)
|
||||
var/datum/timedevent/head = bucket_list[practical_offset]
|
||||
if (!timer || !head || timer == head)
|
||||
head = bucket_list[practical_offset]
|
||||
timer = head
|
||||
while (timer)
|
||||
// Iterate through each bucket starting from the practical offset
|
||||
while (practical_offset <= BUCKET_LEN && head_offset + ((practical_offset - 1) * world.tick_lag) <= world.time)
|
||||
var/datum/timedevent/timer
|
||||
while ((timer = bucket_list[practical_offset]))
|
||||
var/datum/callback/callBack = timer.callBack
|
||||
if (!callBack)
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
crash_with("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], \
|
||||
head_offset: [head_offset], practical_offset: [practical_offset], bucket_joined: [timer.bucket_joined]")
|
||||
if (!timer.spent)
|
||||
bucket_resolution = null // force bucket recreation
|
||||
return
|
||||
|
||||
timer.bucketEject() //pop the timer off of the bucket list.
|
||||
|
||||
// Invoke callback if possible
|
||||
if (!timer.spent)
|
||||
spent += timer
|
||||
timer.spent = world.time
|
||||
callBack.InvokeAsync()
|
||||
last_invoke_tick = world.time
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
timer = timer.next
|
||||
if (timer == head)
|
||||
break
|
||||
|
||||
|
||||
bucket_list[practical_offset++] = null
|
||||
|
||||
//we freed up a bucket, lets see if anything in second_queue needs to be shifted to that bucket.
|
||||
var/i = 0
|
||||
var/L = length(second_queue)
|
||||
for (i in 1 to L)
|
||||
timer = second_queue[i]
|
||||
if (timer.timeToRun >= TIMER_MAX)
|
||||
i--
|
||||
break
|
||||
|
||||
if (timer.timeToRun < head_offset)
|
||||
bucket_resolution = null //force bucket recreation
|
||||
crash_with("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
|
||||
if (timer.callBack && !timer.spent)
|
||||
timer.callBack.InvokeAsync()
|
||||
spent += timer
|
||||
bucket_count++
|
||||
else if(!QDELETED(timer))
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
if (timer.timeToRun < head_offset + TICKS2DS(practical_offset-1))
|
||||
bucket_resolution = null //force bucket recreation
|
||||
crash_with("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
if (timer.callBack && !timer.spent)
|
||||
timer.callBack.InvokeAsync()
|
||||
spent += timer
|
||||
bucket_count++
|
||||
else if(!QDELETED(timer))
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
bucket_count++
|
||||
var/bucket_pos = max(1, BUCKET_POS(timer))
|
||||
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
if (!bucket_head)
|
||||
bucket_list[bucket_pos] = timer
|
||||
timer.next = null
|
||||
timer.prev = null
|
||||
continue
|
||||
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
timer.next = bucket_head
|
||||
timer.prev = bucket_head.prev
|
||||
timer.next.prev = timer
|
||||
timer.prev.next = timer
|
||||
if (i)
|
||||
second_queue.Cut(1, i+1)
|
||||
|
||||
timer = null
|
||||
|
||||
bucket_count -= length(spent)
|
||||
|
||||
for (var/i in spent)
|
||||
var/datum/timedevent/qtimer = i
|
||||
if(QDELETED(qtimer))
|
||||
bucket_count++
|
||||
continue
|
||||
if(!(qtimer.flags & TIMER_LOOP))
|
||||
qdel(qtimer)
|
||||
else
|
||||
bucket_count++
|
||||
qtimer.spent = 0
|
||||
qtimer.bucketEject()
|
||||
if(qtimer.flags & TIMER_CLIENT_TIME)
|
||||
qtimer.timeToRun = REALTIMEOFDAY + qtimer.wait
|
||||
if (timer.flags & TIMER_LOOP) // Prepare looping timers to re-enter the queue
|
||||
timer.spent = 0
|
||||
timer.timeToRun = world.time + timer.wait
|
||||
timer.bucketJoin()
|
||||
else
|
||||
qtimer.timeToRun = world.time + qtimer.wait
|
||||
qtimer.bucketJoin()
|
||||
qdel(timer)
|
||||
|
||||
spent.len = 0
|
||||
if (MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
if (!bucket_list[practical_offset])
|
||||
// Empty the bucket, check if anything in the secondary queue should be shifted to this bucket
|
||||
bucket_list[practical_offset] = null // Just in case
|
||||
practical_offset++
|
||||
var/i = 0
|
||||
for (i in 1 to length(second_queue))
|
||||
timer = second_queue[i]
|
||||
if (timer.timeToRun >= TIMER_MAX)
|
||||
i--
|
||||
break
|
||||
|
||||
// Check for timers that are scheduled to run in the past
|
||||
if (timer.timeToRun < head_offset)
|
||||
bucket_resolution = null // force bucket recreation
|
||||
crash_with("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. \
|
||||
[get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
break
|
||||
|
||||
// Check for timers that are not capable of being scheduled to run without rebuilding buckets
|
||||
if (timer.timeToRun < head_offset + TICKS2DS(practical_offset - 1))
|
||||
bucket_resolution = null // force bucket recreation
|
||||
crash_with("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to \
|
||||
short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
break
|
||||
|
||||
timer.bucketJoin()
|
||||
if (i)
|
||||
second_queue.Cut(1, i+1)
|
||||
if (MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
/**
|
||||
* Generates a string with details about the timed event for debugging purposes
|
||||
*/
|
||||
/datum/controller/subsystem/timer/proc/get_timer_debug_string(datum/timedevent/TE)
|
||||
. = "Timer: [TE]"
|
||||
. += "Prev: [TE.prev ? TE.prev : "NULL"], Next: [TE.next ? TE.next : "NULL"]"
|
||||
if(TE.spent)
|
||||
. += ", SPENT"
|
||||
. += ", SPENT([TE.spent])"
|
||||
if(QDELETED(TE))
|
||||
. += ", QDELETED"
|
||||
if(!TE.callBack)
|
||||
. += ", NO CALLBACK"
|
||||
|
||||
/**
|
||||
* Destroys the existing buckets and creates new buckets from the existing timed events
|
||||
*/
|
||||
/datum/controller/subsystem/timer/proc/reset_buckets()
|
||||
var/list/bucket_list = src.bucket_list
|
||||
log_debug("Timer buckets have been reset, this may cause timers to lag")
|
||||
bucket_reset_count++
|
||||
|
||||
var/list/bucket_list = src.bucket_list // Store local reference to datum var, this is faster
|
||||
var/list/alltimers = list()
|
||||
//collect the timers currently in the bucket
|
||||
|
||||
// Get all timers currently in the buckets
|
||||
for (var/bucket_head in bucket_list)
|
||||
if (!bucket_head)
|
||||
if (!bucket_head) // if bucket is empty for this tick
|
||||
continue
|
||||
var/datum/timedevent/bucket_node = bucket_head
|
||||
do
|
||||
@@ -244,25 +248,38 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
bucket_node = bucket_node.next
|
||||
while(bucket_node && bucket_node != bucket_head)
|
||||
|
||||
// Empty the list by zeroing and re-assigning the length
|
||||
bucket_list.len = 0
|
||||
bucket_list.len = BUCKET_LEN
|
||||
|
||||
// Reset values for the subsystem to their initial values
|
||||
practical_offset = 1
|
||||
bucket_count = 0
|
||||
head_offset = world.time
|
||||
bucket_resolution = world.tick_lag
|
||||
|
||||
// Add all timed events from the secondary queue as well
|
||||
alltimers += second_queue
|
||||
|
||||
// If there are no timers being tracked by the subsystem,
|
||||
// there is no need to do any further rebuilding
|
||||
if (!length(alltimers))
|
||||
return
|
||||
|
||||
sortTim(alltimers, /proc/cmp_timer)
|
||||
// Sort all timers by time to run
|
||||
sortTim(alltimers, .proc/cmp_timer)
|
||||
|
||||
// Get the earliest timer, and if the TTR is earlier than the current world.time,
|
||||
// then set the head offset appropriately to be the earliest time tracked by the
|
||||
// current set of buckets
|
||||
var/datum/timedevent/head = alltimers[1]
|
||||
|
||||
if (head.timeToRun < head_offset)
|
||||
head_offset = head.timeToRun
|
||||
|
||||
// Iterate through each timed event and insert it into an appropriate bucket,
|
||||
// up unto the point that we can no longer insert into buckets as the TTR
|
||||
// is outside the range we are tracking, then insert the remainder into the
|
||||
// secondary queue
|
||||
var/new_bucket_count
|
||||
var/i = 1
|
||||
for (i in 1 to length(alltimers))
|
||||
@@ -270,19 +287,24 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
if (!timer)
|
||||
continue
|
||||
|
||||
var/bucket_pos = BUCKET_POS(timer)
|
||||
// Check that the TTR is within the range covered by buckets, when exceeded we've finished
|
||||
if (timer.timeToRun >= TIMER_MAX)
|
||||
i--
|
||||
break
|
||||
|
||||
|
||||
// Check that timer has a valid callback and hasn't been invoked
|
||||
if (!timer.callBack || timer.spent)
|
||||
WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], \
|
||||
head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
if (timer.callBack)
|
||||
qdel(timer)
|
||||
continue
|
||||
|
||||
// Insert the timer into the bucket, and perform necessary circular doubly-linked list operations
|
||||
new_bucket_count++
|
||||
var/bucket_pos = BUCKET_POS(timer)
|
||||
timer.bucket_pos = bucket_pos
|
||||
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
if (!bucket_head)
|
||||
bucket_list[bucket_pos] = timer
|
||||
@@ -290,14 +312,14 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
timer.prev = null
|
||||
continue
|
||||
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
bucket_head.prev = timer
|
||||
timer.next = bucket_head
|
||||
timer.prev = bucket_head.prev
|
||||
timer.next.prev = timer
|
||||
timer.prev.next = timer
|
||||
timer.prev = null
|
||||
bucket_list[bucket_pos] = timer
|
||||
|
||||
// Cut the timers that are tracked by the buckets from the secondary queue
|
||||
if (i)
|
||||
alltimers.Cut(1, i+1)
|
||||
alltimers.Cut(1, i + 1)
|
||||
second_queue = alltimers
|
||||
bucket_count = new_bucket_count
|
||||
|
||||
@@ -308,46 +330,68 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
timer_id_dict |= SStimer.timer_id_dict
|
||||
bucket_list |= SStimer.bucket_list
|
||||
|
||||
/**
|
||||
* # Timed Event
|
||||
*
|
||||
* This is the actual timer, it contains the callback and necessary data to maintain
|
||||
* the timer.
|
||||
*
|
||||
* See the documentation for the timer subsystem for an explanation of the buckets referenced
|
||||
* below in next and prev
|
||||
*/
|
||||
/datum/timedevent
|
||||
/// ID used for timers when the TIMER_STOPPABLE flag is present
|
||||
var/id
|
||||
/// The callback to invoke after the timer completes
|
||||
var/datum/callback/callBack
|
||||
/// The time at which the callback should be invoked at
|
||||
var/timeToRun
|
||||
/// The length of the timer
|
||||
var/wait
|
||||
/// Unique hash generated when TIMER_UNIQUE flag is present
|
||||
var/hash
|
||||
/// The source of the timedevent, whatever called addtimer
|
||||
var/source
|
||||
/// Flags associated with the timer, see _DEFINES/subsystems.dm
|
||||
var/list/flags
|
||||
var/spent = FALSE //set to true right before running.
|
||||
var/name //for easy debugging.
|
||||
|
||||
//cicular doublely linked list
|
||||
/// Time at which the timer was invoked or destroyed
|
||||
var/spent = 0
|
||||
/// An informative name generated for the timer as its representation in strings, useful for debugging
|
||||
var/name
|
||||
/// Next timed event in the bucket
|
||||
var/datum/timedevent/next
|
||||
/// Previous timed event in the bucket
|
||||
var/datum/timedevent/prev
|
||||
/// Boolean indicating if timer joined into bucket
|
||||
var/bucket_joined = FALSE
|
||||
/// Initial bucket position
|
||||
var/bucket_pos = -1
|
||||
|
||||
/datum/timedevent/New(datum/callback/callBack, wait, flags, hash, source)
|
||||
var/static/nextid = 1
|
||||
|
||||
/datum/timedevent/New(datum/callback/callBack, wait, flags, hash)
|
||||
id = TIMER_ID_NULL
|
||||
src.callBack = callBack
|
||||
src.wait = wait
|
||||
src.flags = flags
|
||||
src.hash = hash
|
||||
src.source = source
|
||||
|
||||
if (flags & TIMER_CLIENT_TIME)
|
||||
timeToRun = REALTIMEOFDAY + wait
|
||||
else
|
||||
timeToRun = world.time + wait
|
||||
// Determine time at which the timer's callback should be invoked
|
||||
timeToRun = (flags & TIMER_CLIENT_TIME ? REALTIMEOFDAY : world.time) + wait
|
||||
|
||||
// Include the timer in the hash table if the timer is unique
|
||||
if (flags & TIMER_UNIQUE)
|
||||
SStimer.hashes[hash] = src
|
||||
|
||||
// Generate ID for the timer if the timer is stoppable, include in the timer id dictionary
|
||||
if (flags & TIMER_STOPPABLE)
|
||||
id = num2text(nextid, 100)
|
||||
if (nextid >= TIMER_ID_MAX)
|
||||
nextid += min(1, 2**round(nextid/TIMER_ID_MAX))
|
||||
nextid += min(1, 2 ** round(nextid / TIMER_ID_MAX))
|
||||
else
|
||||
nextid++
|
||||
SStimer.timer_id_dict[id] = src
|
||||
|
||||
name = "Timer: " + num2text(id, 8) + ", TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT", "TIMER_LOOP")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
|
||||
|
||||
if ((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME))
|
||||
CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]")
|
||||
|
||||
@@ -388,64 +432,104 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
prev = null
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
/**
|
||||
* Removes this timed event from any relevant buckets, or the secondary queue
|
||||
*/
|
||||
/datum/timedevent/proc/bucketEject()
|
||||
var/bucketpos = BUCKET_POS(src)
|
||||
// Store local references for the bucket list and secondary queue
|
||||
// This is faster than referencing them from the datum itself
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
var/list/second_queue = SStimer.second_queue
|
||||
|
||||
// Attempt to get the head of the bucket
|
||||
var/datum/timedevent/buckethead
|
||||
if(bucketpos > 0)
|
||||
buckethead = bucket_list[bucketpos]
|
||||
if(bucket_pos > 0)
|
||||
buckethead = bucket_list[bucket_pos]
|
||||
|
||||
// Decrement the number of timers in buckets if the timed event is
|
||||
// the head of the bucket, or has a TTR less than TIMER_MAX implying it fits
|
||||
// into an existing bucket, or is otherwise not present in the secondary queue
|
||||
if(buckethead == src)
|
||||
bucket_list[bucketpos] = next
|
||||
bucket_list[bucket_pos] = next
|
||||
SStimer.bucket_count--
|
||||
else if(timeToRun < TIMER_MAX || next || prev)
|
||||
else if(timeToRun < TIMER_MAX)
|
||||
SStimer.bucket_count--
|
||||
else
|
||||
var/l = length(second_queue)
|
||||
second_queue -= src
|
||||
if(l == length(second_queue))
|
||||
SStimer.bucket_count--
|
||||
if(prev != next)
|
||||
|
||||
// Remove the timed event from the bucket, ensuring to maintain
|
||||
// the integrity of the bucket's list if relevant
|
||||
if (prev && prev.next == src)
|
||||
prev.next = next
|
||||
if (next && next.prev == src)
|
||||
next.prev = prev
|
||||
else
|
||||
prev?.next = null
|
||||
next?.prev = null
|
||||
prev = next = null
|
||||
bucket_pos = -1
|
||||
bucket_joined = FALSE
|
||||
|
||||
/**
|
||||
* Attempts to add this timed event to a bucket, will enter the secondary queue
|
||||
* if there are no appropriate buckets at this time.
|
||||
*
|
||||
* Secondary queueing of timed events will occur when the timespan covered by the existing
|
||||
* buckets is exceeded by the time at which this timed event is scheduled to be invoked.
|
||||
* If the timed event is tracking client time, it will be added to a special bucket.
|
||||
*/
|
||||
/datum/timedevent/proc/bucketJoin()
|
||||
var/list/L
|
||||
// Generate debug-friendly name for timer
|
||||
var/static/list/bitfield_flags = list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT", "TIMER_LOOP")
|
||||
name = "Timer: [id] (\ref[src]), TTR: [timeToRun], wait:[wait] Flags: [jointext(bitfield2list(flags, bitfield_flags), ", ")], \
|
||||
callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), \
|
||||
callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""]), source: [source]"
|
||||
|
||||
if (bucket_joined)
|
||||
crash_with("Bucket already joined! [name]")
|
||||
|
||||
// Check if this timed event should be diverted to the client time bucket, or the secondary queue
|
||||
var/list/L
|
||||
if (flags & TIMER_CLIENT_TIME)
|
||||
L = SStimer.clienttime_timers
|
||||
else if (timeToRun >= TIMER_MAX)
|
||||
L = SStimer.second_queue
|
||||
|
||||
if(L)
|
||||
BINARY_INSERT(src, L, datum/timedevent, timeToRun)
|
||||
BINARY_INSERT(src, L, /datum/timedevent, src, timeToRun, COMPARE_KEY)
|
||||
return
|
||||
|
||||
//get the list of buckets
|
||||
// Get a local reference to the bucket list, this is faster than referencing the datum
|
||||
var/list/bucket_list = SStimer.bucket_list
|
||||
|
||||
//calculate our place in the bucket list
|
||||
var/bucket_pos = BUCKET_POS(src)
|
||||
// Find the correct bucket for this timed event
|
||||
bucket_pos = BUCKET_POS(src)
|
||||
|
||||
if (bucket_pos < SStimer.practical_offset && timeToRun < (SStimer.head_offset + TICKS2DS(BUCKET_LEN)))
|
||||
WARNING("Bucket pos in past: bucket_pos = [bucket_pos] < practical_offset = [SStimer.practical_offset] \
|
||||
&& timeToRun = [timeToRun] < [SStimer.head_offset + TICKS2DS(BUCKET_LEN)], Timer: [name]")
|
||||
bucket_pos = SStimer.practical_offset // Recover bucket_pos to avoid timer blocking queue
|
||||
|
||||
//get the bucket for our tick
|
||||
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
|
||||
SStimer.bucket_count++
|
||||
//empty bucket, we will just add ourselves
|
||||
|
||||
// If there is no timed event at this position, then the bucket is 'empty'
|
||||
// and we can just set this event to that position
|
||||
if (!bucket_head)
|
||||
bucket_joined = TRUE
|
||||
bucket_list[bucket_pos] = src
|
||||
return
|
||||
//other wise, lets do a simplified linked list add.
|
||||
if (!bucket_head.prev)
|
||||
bucket_head.prev = bucket_head
|
||||
next = bucket_head
|
||||
prev = bucket_head.prev
|
||||
next.prev = src
|
||||
prev.next = src
|
||||
|
||||
// Otherwise, we merely add this timed event into the bucket, which is a
|
||||
// doubly-linked list
|
||||
bucket_joined = TRUE
|
||||
bucket_head.prev = src
|
||||
next = bucket_head
|
||||
prev = null
|
||||
bucket_list[bucket_pos] = src
|
||||
|
||||
/**
|
||||
* Returns a string of the type of the callback for this timer
|
||||
*/
|
||||
/datum/timedevent/proc/getcallingtype()
|
||||
. = "ERROR"
|
||||
if (callBack.object == GLOBAL_PROC)
|
||||
@@ -453,39 +537,47 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
else
|
||||
. = "[callBack.object.type]"
|
||||
|
||||
/**
|
||||
* Create a new timer and insert it in the queue.
|
||||
* You should not call this directly, and should instead use the addtimer macro, which includes source information.
|
||||
*
|
||||
* Arguments:
|
||||
* * callback the callback to call on timer finish
|
||||
* * wait deciseconds to run the timer for
|
||||
* * flags flags for this timer, see: code\__DEFINES\subsystems.dm
|
||||
*/
|
||||
/proc/addtimer(datum/callback/callback, wait, flags)
|
||||
if (!callback)
|
||||
CRASH("addtimer called without a callback")
|
||||
|
||||
if (wait < 0)
|
||||
crash_with("addtimer called with a negative wait. Converting to 0")
|
||||
CRASH("addtimer called with a negative wait. Converting to [world.tick_lag]")
|
||||
|
||||
if (callback.object != GLOBAL_PROC && QDELETED(callback.object) && !QDESTROYING(callback.object))
|
||||
crash_with("addtimer called with a callback assigned to a qdeleted object. In the future such timers will not be supported and may refuse to run or run with a 0 wait")
|
||||
CRASH("addtimer called with a callback assigned to a qdeleted object. In the future such timers will not \
|
||||
be supported and may refuse to run or run with a 0 wait")
|
||||
|
||||
wait = max(wait, 0)
|
||||
wait = max(Ceilm(wait, world.tick_lag), world.tick_lag)
|
||||
|
||||
if(wait >= INFINITY)
|
||||
CRASH("Attempted to create timer with INFINITY delay")
|
||||
|
||||
// Generate hash if relevant for timed events with the TIMER_UNIQUE flag
|
||||
var/hash
|
||||
|
||||
if (flags & TIMER_UNIQUE)
|
||||
var/list/hashlist
|
||||
if(flags & TIMER_NO_HASH_WAIT)
|
||||
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
else
|
||||
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
|
||||
var/list/hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, flags & TIMER_CLIENT_TIME)
|
||||
if(!(flags & TIMER_NO_HASH_WAIT))
|
||||
hashlist += wait
|
||||
hashlist += callback.arguments
|
||||
hash = hashlist.Join("|||||||")
|
||||
|
||||
var/datum/timedevent/hash_timer = SStimer.hashes[hash]
|
||||
if(hash_timer)
|
||||
if (hash_timer.spent) //it's pending deletion, pretend it doesn't exist.
|
||||
hash_timer.hash = null
|
||||
SStimer.hashes -= hash
|
||||
if (hash_timer.spent) // it's pending deletion, pretend it doesn't exist.
|
||||
hash_timer.hash = null // but keep it from accidentally deleting us
|
||||
else
|
||||
if (flags & TIMER_OVERRIDE)
|
||||
hash_timer.hash = null // no need having it delete it's hash if we are going to replace it
|
||||
qdel(hash_timer)
|
||||
else
|
||||
if (hash_timer.flags & TIMER_STOPPABLE)
|
||||
@@ -497,18 +589,22 @@ var/datum/controller/subsystem/timer/SStimer
|
||||
var/datum/timedevent/timer = new(callback, wait, flags, hash)
|
||||
return timer.id
|
||||
|
||||
|
||||
/**
|
||||
* Delete a timer
|
||||
*
|
||||
* Arguments:
|
||||
* * id a timerid or a /datum/timedevent
|
||||
*/
|
||||
/proc/deltimer(id)
|
||||
if (!id)
|
||||
return FALSE
|
||||
|
||||
if (id == TIMER_ID_NULL)
|
||||
CRASH("Tried to delete a null timerid. Use the TIMER_STOPPABLE flag.")
|
||||
|
||||
if (!istext(id))
|
||||
if (istype(id, /datum/timedevent))
|
||||
qdel(id)
|
||||
return TRUE
|
||||
|
||||
CRASH("Tried to delete a null timerid. Use TIMER_STOPPABLE flag")
|
||||
if (istype(id, /datum/timedevent))
|
||||
qdel(id)
|
||||
return TRUE
|
||||
//id is string
|
||||
var/datum/timedevent/timer = SStimer.timer_id_dict[id]
|
||||
if (timer && !timer.spent)
|
||||
qdel(timer)
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
if(!chance || prob(chance))
|
||||
play(get_sound(starttime))
|
||||
if(!timerid)
|
||||
timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_CLIENT_TIME | TIMER_STOPPABLE | TIMER_LOOP)
|
||||
timerid = addtimer(CALLBACK(src, .proc/sound_loop, world.time), mid_length, TIMER_STOPPABLE | TIMER_LOOP)
|
||||
|
||||
/datum/looping_sound/proc/play(soundfile)
|
||||
var/list/atoms_cache = output_atoms
|
||||
@@ -93,7 +93,7 @@
|
||||
if(start_sound)
|
||||
play(start_sound)
|
||||
start_wait = start_length
|
||||
addtimer(CALLBACK(src, .proc/sound_loop), start_wait, TIMER_CLIENT_TIME)
|
||||
addtimer(CALLBACK(src, .proc/sound_loop), start_wait)
|
||||
|
||||
/datum/looping_sound/proc/on_stop()
|
||||
if(end_sound)
|
||||
|
||||
@@ -201,7 +201,6 @@
|
||||
|
||||
var/last_color_level = 5
|
||||
var/health_timer = 10 MINUTES // you need to reduce the health by standing near it with a neutralizer
|
||||
var/datum/looping_sound/revenant_rift/soundloop
|
||||
|
||||
/obj/effect/portal/revenant/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -210,8 +209,6 @@
|
||||
var/turf/T = get_turf(src)
|
||||
log_and_message_admins("Revenant Bluespace Rift spawned at \the [get_area(T)]", null, T)
|
||||
revenants.revenant_rift = src
|
||||
soundloop = new(list(src), FALSE)
|
||||
soundloop.start()
|
||||
|
||||
/obj/effect/portal/revenant/Destroy()
|
||||
revenants.destroyed_rift()
|
||||
@@ -224,7 +221,6 @@
|
||||
O.throw_at_random(FALSE, 3, THROWNOBJ_KNOCKBACK_SPEED)
|
||||
var/area/A = get_area(src)
|
||||
message_all_revenants(FONT_LARGE(SPAN_WARNING("The rift keeping us here has been destroyed in [A.name]!")))
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/revenant/attackby(obj/item/I, mob/user)
|
||||
|
||||
@@ -6,14 +6,11 @@
|
||||
w_class = ITEMSIZE_HUGE
|
||||
force = 12
|
||||
var/time_multiplier = 1
|
||||
var/datum/looping_sound/thermal_drill/soundloop
|
||||
|
||||
/obj/item/thermal_drill/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(src), FALSE)
|
||||
|
||||
/obj/item/thermal_drill/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
/obj/item/thermal_drill/diamond_drill
|
||||
|
||||
@@ -54,7 +54,6 @@ FLOOR SAFES
|
||||
|
||||
/obj/structure/safe/Destroy()
|
||||
if(drill)
|
||||
drill.soundloop.stop()
|
||||
drill.forceMove(loc)
|
||||
drill = null
|
||||
return ..()
|
||||
@@ -119,7 +118,6 @@ FLOOR SAFES
|
||||
if(broken)
|
||||
return
|
||||
last_drill_time = world.time
|
||||
drill.soundloop.start()
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
update_icon()
|
||||
if("Turn Off")
|
||||
@@ -128,7 +126,6 @@ FLOOR SAFES
|
||||
if(do_after(user, 2 SECONDS))
|
||||
if(!drill || !isprocessing)
|
||||
return
|
||||
drill.soundloop.stop()
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
update_icon()
|
||||
if("Remove Drill")
|
||||
@@ -251,12 +248,10 @@ FLOOR SAFES
|
||||
|
||||
/obj/structure/safe/proc/drill_open()
|
||||
broken = TRUE
|
||||
if(drill)
|
||||
drill.soundloop.stop()
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
update_icon()
|
||||
|
||||
obj/structure/safe/ex_act(severity)
|
||||
/obj/structure/safe/ex_act(severity)
|
||||
return
|
||||
|
||||
//FLOOR SAFES
|
||||
|
||||
@@ -142,15 +142,12 @@
|
||||
var/mobpresent = 0 //true if there is a mob on the shower's loc, this is to ease process()
|
||||
var/is_washing = 0
|
||||
var/list/temperature_settings = list("normal" = 310, "boiling" = T0C+100, "freezing" = T0C)
|
||||
var/datum/looping_sound/showering/soundloop
|
||||
|
||||
/obj/machinery/shower/Initialize()
|
||||
. = ..()
|
||||
create_reagents(2)
|
||||
soundloop = new(list(src), FALSE)
|
||||
|
||||
/obj/machinery/shower/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
//add heat controls? when emagged, you can freeze to death in it?
|
||||
@@ -191,7 +188,6 @@
|
||||
qdel(mymist)
|
||||
|
||||
if(on)
|
||||
soundloop.start(src)
|
||||
add_overlay(image('icons/obj/watercloset.dmi', src, "water", MOB_LAYER + 1, dir))
|
||||
if(temperature_settings[watertemp] < T20C)
|
||||
return //no mist for cold water
|
||||
@@ -204,7 +200,6 @@
|
||||
ismist = 1
|
||||
mymist = new /obj/effect/mist(loc)
|
||||
else
|
||||
soundloop.stop(src)
|
||||
if(ismist)
|
||||
ismist = 1
|
||||
mymist = new /obj/effect/mist(loc)
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
/turf/simulated/wall/cult/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_CULT)
|
||||
desc = "Hideous images dance beneath the surface."
|
||||
canSmoothWith = list(/turf/simulated/wall/cult, /turf/simulated/wall/cult_reinforced)
|
||||
|
||||
/turf/simulated/wall/cult_reinforced/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_CULT, MATERIAL_CULT_REINFORCED)
|
||||
desc = "Hideous images dance beneath the surface."
|
||||
canSmoothWith = list(/turf/simulated/wall/cult, /turf/simulated/wall/cult_reinforced)
|
||||
|
||||
/turf/unsimulated/wall/cult
|
||||
name = "cult wall"
|
||||
@@ -29,49 +31,65 @@
|
||||
|
||||
/turf/simulated/wall/vaurca/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_VAURCA)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/iron/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_IRON)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/uranium/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_URANIUM)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/diamond/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_DIAMOND)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/gold/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_GOLD)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/silver/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_SILVER)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/phoron/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_PHORON)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/sandstone/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_SANDSTONE)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/ironphoron/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_IRON, MATERIAL_PHORON)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/golddiamond/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_GOLD, MATERIAL_DIAMOND)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/silvergold/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_SILVER, MATERIAL_GOLD)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/sandstonediamond/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_SANDSTONE, MATERIAL_DIAMOND)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/titanium/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_TITANIUM)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/titanium_reinforced/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_TITANIUM, MATERIAL_TITANIUM)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/wood/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_WOOD)
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/turf/simulated/wall/rusty/Initialize(mapload)
|
||||
. = ..(mapload, MATERIAL_RUST)
|
||||
desc = "Rust stains this ancient wall."
|
||||
desc = "Rust stains this ancient wall."
|
||||
canSmoothWith = list(src.type)
|
||||
@@ -10,6 +10,7 @@
|
||||
blocks_air = TRUE
|
||||
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
|
||||
heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall
|
||||
canSmoothWith = list(/turf/simulated/wall, /turf/simulated/wall/r_wall, /obj/structure/window/full, /obj/structure/window/full/phoron)
|
||||
|
||||
var/damage = 0
|
||||
var/damage_overlay = 0
|
||||
@@ -40,12 +41,6 @@
|
||||
O.hide(1)
|
||||
|
||||
/turf/simulated/wall/Initialize(mapload, var/materialtype, var/rmaterialtype)
|
||||
if(!canSmoothWith && ((smooth & SMOOTH_TRUE) || (smooth & SMOOTH_MORE)))
|
||||
canSmoothWith = list(
|
||||
src.type,
|
||||
/obj/structure/window/full,
|
||||
/obj/structure/window/full/phoron
|
||||
)
|
||||
. = ..()
|
||||
if(!use_set_icon_state)
|
||||
icon_state = "blank"
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
|
||||
src.custom_emote(VISIBLE_MESSAGE,"presses a button on their suit, followed by a polite bow.")
|
||||
spark(src, 5, alldirs)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, src), 10, TIMER_CLIENT_TIME)
|
||||
QDEL_IN(src, 10)
|
||||
animate(src, alpha = 0, time = 9, easing = QUAD_EASING)
|
||||
if(key)
|
||||
if(client.holder && client.holder.original_mob)
|
||||
|
||||
@@ -116,30 +116,7 @@
|
||||
workplace of various contractors on board NSS Aurora."
|
||||
|
||||
job_species_blacklist = list(
|
||||
"Consular Officer" = list(
|
||||
SPECIES_HUMAN,
|
||||
SPECIES_HUMAN_OFFWORLD,
|
||||
SPECIES_IPC,
|
||||
SPECIES_IPC_BISHOP,
|
||||
SPECIES_IPC_G1,
|
||||
SPECIES_IPC_G2,
|
||||
SPECIES_IPC_SHELL,
|
||||
SPECIES_IPC_UNBRANDED,
|
||||
SPECIES_IPC_XION,
|
||||
SPECIES_IPC_ZENGHU,
|
||||
SPECIES_DIONA,
|
||||
SPECIES_DIONA_COEUS,
|
||||
SPECIES_SKRELL,
|
||||
SPECIES_SKRELL_AXIORI,
|
||||
SPECIES_TAJARA,
|
||||
SPECIES_TAJARA_MSAI,
|
||||
SPECIES_TAJARA_ZHAN,
|
||||
SPECIES_UNATHI,
|
||||
SPECIES_VAURCA_WORKER,
|
||||
SPECIES_VAURCA_WARRIOR,
|
||||
SPECIES_VAURCA_BULWARK,
|
||||
SPECIES_VAURCA_BREEDER
|
||||
)
|
||||
"Consular Officer" = ALL_SPECIES
|
||||
)
|
||||
|
||||
/datum/citizenship/coalition
|
||||
|
||||
@@ -55,3 +55,15 @@
|
||||
name = "Jargon Consular Officer"
|
||||
|
||||
uniform = /obj/item/clothing/under/skrell
|
||||
|
||||
/datum/citizenship/epsilon
|
||||
name = CITIZENSHIP_EUM
|
||||
description = "An independent nation on the edge of Skrell space, the Co-Operative Territories of Epsilon Ursae Minoris, \
|
||||
also known as the CT-EUM, is a nation primarily comprised of Dionae with a minority of skrell mostly situated \
|
||||
in the city of Nral'Daaq. The CT-EUM is compromised of a myriad of smaller nations and city-states that make up \
|
||||
the whole of the nation. While the nation is independent it does have heavy ties to the Jargon Federation, \
|
||||
being instrumental in the nations' founding and contact with the rest of the galaxy. "
|
||||
|
||||
job_species_blacklist = list(
|
||||
"Consular Officer" = ALL_SPECIES
|
||||
)
|
||||
@@ -9,6 +9,7 @@
|
||||
#define CITIZENSHIP_IZWESKI "Izweski Hegemony"
|
||||
|
||||
#define CITIZENSHIP_JARGON "Jargon Federation"
|
||||
#define CITIZENSHIP_EUM "Co-Operative Territories of EUM"
|
||||
|
||||
#define CITIZENSHIP_PRA "People's Republic of Adhomai"
|
||||
#define CITIZENSHIP_DPRA "Democratic People's Republic of Adhomai"
|
||||
|
||||
@@ -127,7 +127,6 @@
|
||||
/datum/gear/eyes/blindfolds/New()
|
||||
..()
|
||||
var/list/blindfold = list()
|
||||
blindfold["blindfold, black"] = /obj/item/clothing/glasses/sunglasses/blindfold
|
||||
blindfold["blindfold, white"] = /obj/item/clothing/glasses/sunglasses/blindfold/white
|
||||
blindfold["blindfold, transparent white"] = /obj/item/clothing/glasses/sunglasses/blindfold/white/seethrough
|
||||
blindfold["blindfold"] = /obj/item/clothing/glasses/sunglasses/blindfold/white
|
||||
blindfold["blindfold, transparent"] = /obj/item/clothing/glasses/sunglasses/blindfold/white/seethrough
|
||||
gear_tweaks += new /datum/gear_tweak/path(blindfold)
|
||||
|
||||
@@ -216,6 +216,12 @@
|
||||
slot = slot_gloves
|
||||
faction = "Zeng-Hu Pharmaceuticals"
|
||||
|
||||
/datum/gear/faction/zenghu_cloak
|
||||
display_name = "Zeng-Hu Jargon Division cloak"
|
||||
path = /obj/item/clothing/accessory/poncho/shouldercape/qeblak/zeng
|
||||
slot = slot_wear_suit
|
||||
faction = "Zeng-Hu Pharmaceuticals"
|
||||
|
||||
/datum/gear/faction/zavodskoi_patch
|
||||
display_name = "zavodskoi sleeve patch"
|
||||
path = /obj/item/clothing/accessory/sleevepatch/zavodskoi
|
||||
|
||||
@@ -603,15 +603,12 @@ BLIND // can't see anything
|
||||
pickup_sound = 'sound/items/pickup/gloves.ogg'
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/blindfold/white
|
||||
name = "white blindfold"
|
||||
desc = "A white blindfold that covers the eyes, preventing sight."
|
||||
icon_state = "blindfoldwhite"
|
||||
item_state = "blindfoldwhite"
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/blindfold/white/seethrough
|
||||
desc = "A white blindfold that covers the eyes, this one seems to be made of thinner material."
|
||||
tint = TINT_MODERATE
|
||||
flash_protection = FLASH_PROTECTION_MODERATE
|
||||
desc = "A blindfold that covers the eyes, this one seems to be made of thinner material."
|
||||
tint = TINT_NONE // It's practically a fluff thing anyway, so.
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/blinders
|
||||
name = "vaurcae blinders"
|
||||
|
||||
@@ -573,6 +573,19 @@
|
||||
item_state = "qeblak_cape"
|
||||
flippable = FALSE
|
||||
|
||||
/obj/item/clothing/accessory/poncho/shouldercape/qeblak/zeng
|
||||
name = "Jargon Division Zeng-Hu cloak"
|
||||
desc = "This cloak is given to Zeng-Hu employees who have assisted or worked in collaboration with the Jargon Federation."
|
||||
desc_fluff = "A cloak given to senior level doctors and researchers for Zeng-Hu who has \
|
||||
in the past been given the privilege of working within or in collaboration with the Jargon Federation\
|
||||
as a show of goodwill between the corporation and federation."
|
||||
icon = 'icons/obj/contained_items/accessories/ZH_cape.dmi'
|
||||
icon_override = 'icons/obj/contained_items/accessories/ZH_cape.dmi'
|
||||
icon_state = "ZH_cape"
|
||||
item_state = "ZH_cape"
|
||||
flippable = FALSE
|
||||
contained_sprite = TRUE
|
||||
|
||||
/obj/item/clothing/accessory/poncho/trinary
|
||||
name = "trinary perfection cape"
|
||||
desc = "A brilliant red and brown cape, commonly worn by those who serve the Trinary Perfection."
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
var/datum/reagents/oil
|
||||
var/optimal_oil = 9000//90 litres of cooking oil
|
||||
var/datum/looping_sound/deep_fryer/fry_loop
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/examine(var/mob/user)
|
||||
. = ..()
|
||||
@@ -41,7 +40,6 @@
|
||||
//Sometimes the fryer will start with much less than full oil, significantly impacting efficiency until filled
|
||||
variance = rand()*0.5
|
||||
oil.add_reagent(/decl/reagent/nutriment/triglyceride/oil/corn, optimal_oil*(1 - variance))
|
||||
fry_loop = new(list(src), FALSE)
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/heat_up()
|
||||
if (..())
|
||||
@@ -74,10 +72,8 @@
|
||||
/obj/machinery/appliance/cooker/fryer/update_icon()
|
||||
if (cooking)
|
||||
icon_state = on_icon
|
||||
fry_loop.start()
|
||||
else
|
||||
icon_state = off_icon
|
||||
fry_loop.stop(src)
|
||||
..()
|
||||
|
||||
//Fryer gradually infuses any cooked food with oil. Moar calories
|
||||
|
||||
@@ -2380,3 +2380,11 @@ All custom items with worn sprites must follow the contained sprite system: http
|
||||
if(has_suit)
|
||||
has_suit.verbs -= /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/verb/change_cloak
|
||||
..()
|
||||
|
||||
/obj/item/clothing/accessory/poncho/shouldercape/qeblak/zeng/fluff/eden_cloak // Zeng-Hu Jargon division cloak - Eden Li - Huntime
|
||||
name = "Zeng-Hu cloak: Jargon Division"
|
||||
desc = "A cloak worn by Zeng-Hu personnel who worked with or in the Jargon Federation."
|
||||
icon = 'icons/obj/custom_items/eden_cloak.dmi'
|
||||
icon_override = 'icons/obj/custom_items/eden_cloak.dmi'
|
||||
icon_state = "ZH_cape_custom"
|
||||
item_state = "ZH_cape_custom"
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
|
||||
using = new /obj/screen/new_player/title(src)
|
||||
using.name = "Title"
|
||||
using.hud = src
|
||||
adding += using
|
||||
|
||||
using = new /obj/screen/new_player/selection/join_game(src)
|
||||
using.name = "Join Game"
|
||||
using.hud = src
|
||||
adding += using
|
||||
|
||||
using = new /obj/screen/new_player/selection/settings(src)
|
||||
@@ -83,6 +85,8 @@
|
||||
. = ..()
|
||||
|
||||
/obj/screen/new_player/title/proc/Update()
|
||||
if(!istype(hud) || !isnewplayer(hud.mymob))
|
||||
return
|
||||
lobby_index += 1
|
||||
if (lobby_index > length(current_map.lobby_screens))
|
||||
lobby_index = 1
|
||||
|
||||
@@ -380,7 +380,7 @@ INITIALIZE_IMMEDIATE(/mob/abstract/new_player)
|
||||
SSrecords.open_manifest_vueui(src)
|
||||
|
||||
/mob/abstract/new_player/Move()
|
||||
return 0
|
||||
return TRUE
|
||||
|
||||
/mob/abstract/new_player/proc/close_spawn_windows()
|
||||
src << browse(null, "window=playersetup") //closes the player setup window
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
max_hydration_factor = -1
|
||||
|
||||
allowed_citizenships = list(CITIZENSHIP_BIESEL, CITIZENSHIP_JARGON, CITIZENSHIP_SOL, CITIZENSHIP_COALITION, CITIZENSHIP_DOMINIA, CITIZENSHIP_IZWESKI, CITIZENSHIP_NONE)
|
||||
allowed_citizenships = list(CITIZENSHIP_BIESEL, CITIZENSHIP_JARGON, CITIZENSHIP_SOL, CITIZENSHIP_COALITION, CITIZENSHIP_DOMINIA, CITIZENSHIP_IZWESKI, CITIZENSHIP_EUM, CITIZENSHIP_NONE)
|
||||
allowed_religions = list(RELIGION_QEBLAK, RELIGION_WEISHII, RELIGION_MOROZ, RELIGION_THAKH, RELIGION_SKAKH, RELIGION_ETERNAL, RELIGION_NONE, RELIGION_OTHER)
|
||||
|
||||
allowed_accents = list(ACCENT_ROOTSONG, ACCENT_VOIDSONG)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
name_language = "Encoded Audio Language"
|
||||
num_alternate_languages = 2
|
||||
secondary_langs = list("Encoded Audio Language", "Sol Common")
|
||||
secondary_langs = list("Encoded Audio Language", "Sol Common", "Elyran Standard")
|
||||
ethanol_resistance = -1//Can't get drunk
|
||||
radiation_mod = 0 // not affected by radiation
|
||||
remains_type = /obj/effect/decal/remains/robot
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
default_h_style = "Skrell Short Tentacles"
|
||||
|
||||
allowed_citizenships = list(CITIZENSHIP_JARGON, CITIZENSHIP_BIESEL, CITIZENSHIP_SOL, CITIZENSHIP_COALITION, CITIZENSHIP_ERIDANI)
|
||||
allowed_citizenships = list(CITIZENSHIP_JARGON, CITIZENSHIP_BIESEL, CITIZENSHIP_SOL, CITIZENSHIP_COALITION, CITIZENSHIP_ERIDANI, CITIZENSHIP_EUM)
|
||||
allowed_religions = list(RELIGION_QEBLAK, RELIGION_WEISHII, RELIGION_SUURKA, RELIGION_KIRGUL, RELIGION_NONE, RELIGION_OTHER)
|
||||
default_citizenship = CITIZENSHIP_JARGON
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
src.custom_emote(VISIBLE_MESSAGE, "politely beeps as its lights start to flash.")
|
||||
spark(src, 5, alldirs)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, src), 10, TIMER_CLIENT_TIME)
|
||||
QDEL_IN(src, 10)
|
||||
animate(src, alpha = 0, time = 9, easing = QUAD_EASING)
|
||||
|
||||
if(key)
|
||||
|
||||
@@ -13,11 +13,9 @@
|
||||
var/open = FALSE
|
||||
var/power_output = 1
|
||||
has_special_power_checks = TRUE
|
||||
var/datum/looping_sound/generator/soundloop
|
||||
|
||||
/obj/machinery/power/port_gen/Initialize()
|
||||
. = ..()
|
||||
soundloop = new(list(src), active)
|
||||
|
||||
/obj/machinery/power/port_gen/proc/IsBroken()
|
||||
return (stat & (BROKEN|EMPED))
|
||||
@@ -51,11 +49,9 @@
|
||||
/obj/machinery/power/port_gen/attack_hand(mob/user)
|
||||
if(..())
|
||||
update_icon()
|
||||
soundloop.stop()
|
||||
return
|
||||
if(!anchored)
|
||||
update_icon()
|
||||
soundloop.start()
|
||||
return
|
||||
|
||||
/obj/machinery/power/port_gen/update_icon()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/turf/simulated/wall/diona/Initialize(mapload)
|
||||
. = ..(mapload, "biomass")
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
/obj/structure/diona
|
||||
icon = 'icons/obj/diona.dmi'
|
||||
|
||||
@@ -108,16 +108,12 @@
|
||||
var/debug = 0
|
||||
var/last_message_time = -100 //for message
|
||||
|
||||
var/datum/looping_sound/supermatter/soundloop
|
||||
|
||||
/obj/machinery/power/supermatter/Initialize()
|
||||
. = ..()
|
||||
radio = new /obj/item/device/radio{channels=list("Engineering")}(src)
|
||||
soundloop = new(list(src), TRUE)
|
||||
|
||||
/obj/machinery/power/supermatter/Destroy()
|
||||
QDEL_NULL(radio)
|
||||
QDEL_NULL(soundloop)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/power/supermatter/proc/explode()
|
||||
@@ -209,11 +205,6 @@
|
||||
if(!istype(L)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now.
|
||||
return //Yeah just stop.
|
||||
|
||||
if(power)
|
||||
soundloop.volume = min(100, (round(power/7)+1))
|
||||
else
|
||||
soundloop.volume = 0
|
||||
|
||||
if(damage > explosion_point)
|
||||
if(!exploded)
|
||||
if(!istype(L, /turf/space))
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
/turf/simulated/wall/elevator/Initialize(mapload)
|
||||
. = ..(mapload, "elevatorium")
|
||||
canSmoothWith = list(src.type)
|
||||
|
||||
@@ -56,6 +56,7 @@ var/global/datum/global_init/init = new ()
|
||||
cache_lifespan = 0 //stops player uploaded stuff from being kept in the rsc past the current session
|
||||
maxx = WORLD_MIN_SIZE // So that we don't get map-window-popin at boot. DMMS will expand this.
|
||||
maxy = WORLD_MIN_SIZE
|
||||
fps = 20
|
||||
|
||||
#define RECOMMENDED_VERSION 510
|
||||
/world/New()
|
||||
|
||||
@@ -551,6 +551,7 @@ CURRENT_SPACE_SECTOR Romanovich Cloud
|
||||
# NTSL2+ Connection Info
|
||||
NTSL_HOSTNAME localhost
|
||||
NTSL_PORT 1945
|
||||
NTSL_DISABLED 1
|
||||
|
||||
# Limit to how many hacked drones can AI have at the same time.
|
||||
# HACKED_DRONES_LIMIT 5
|
||||
|
||||
@@ -35,6 +35,20 @@
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
|
||||
<h2 class="date">19 January 2022</h2>
|
||||
<h3 class="author">MattAtlas updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Fixed exoplanet generation.</li>
|
||||
</ul>
|
||||
<h3 class="author">Omicega updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Fixed IPCs not actually getting access to Elyran Standard. Oops!</li>
|
||||
</ul>
|
||||
<h3 class="author">TheGreyWolf updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Skrell and diona now have a new possible citizenship, the Co-Operative Territories of Epsilon Ursae Minoris.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">18 January 2022</h2>
|
||||
<h3 class="author">MattAtlas updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
|
||||
@@ -22423,3 +22423,11 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
|
||||
- rscadd: Animals can now have natural armor.
|
||||
Wowzewow:
|
||||
- bugfix: Fixes sprite issues with cell chargers and APCs.
|
||||
2022-01-19:
|
||||
MattAtlas:
|
||||
- bugfix: Fixed exoplanet generation.
|
||||
Omicega:
|
||||
- bugfix: Fixed IPCs not actually getting access to Elyran Standard. Oops!
|
||||
TheGreyWolf:
|
||||
- rscadd: Skrell and diona now have a new possible citizenship, the Co-Operative
|
||||
Territories of Epsilon Ursae Minoris.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
author: TheGreyWolf
|
||||
|
||||
delete-after: True
|
||||
|
||||
changes:
|
||||
- rscadd: "Added the zeng-hu jargon division cloak to the loadout under factions."
|
||||
@@ -0,0 +1,6 @@
|
||||
author: Geevesy
|
||||
|
||||
delete-after: True
|
||||
|
||||
changes:
|
||||
- backend: "Fixed a couple of roundstart runtimes, added an option in the config to disable NTSL."
|
||||
@@ -0,0 +1,41 @@
|
||||
################################
|
||||
# Example Changelog File
|
||||
#
|
||||
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||
#
|
||||
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||
# When it is, any changes listed below will disappear.
|
||||
#
|
||||
# Valid Prefixes:
|
||||
# bugfix
|
||||
# wip (For works in progress)
|
||||
# tweak
|
||||
# soundadd
|
||||
# sounddel
|
||||
# rscadd (general adding of nice things)
|
||||
# rscdel (general deleting of nice things)
|
||||
# imageadd
|
||||
# imagedel
|
||||
# maptweak
|
||||
# spellcheck (typo fixes)
|
||||
# experiment
|
||||
# balance
|
||||
# admin
|
||||
# backend
|
||||
# security
|
||||
# refactor
|
||||
#################################
|
||||
|
||||
# Your name.
|
||||
author: MattAtlas
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
|
||||
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- bugfix: "The main menu no longer spams client time timers."
|
||||
+1
-1
@@ -38,4 +38,4 @@ delete-after: True
|
||||
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
|
||||
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- bugfix: "Fixed exoplanet generation."
|
||||
- bugfix: "Fixed a lobby spawn issue."
|
||||
@@ -0,0 +1,6 @@
|
||||
author: Sparky_hotdog
|
||||
|
||||
delete-after: True
|
||||
|
||||
changes:
|
||||
- maptweak: "Added a hand labeler to the desk in the First Responder bay."
|
||||
@@ -0,0 +1,6 @@
|
||||
author: Sparky_hotdog
|
||||
|
||||
delete-after: True
|
||||
|
||||
changes:
|
||||
- bugfix: "Fixed a few walls not smoothing properly."
|
||||
@@ -0,0 +1,14 @@
|
||||
################################
|
||||
# Example Changelog File
|
||||
#
|
||||
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||
#
|
||||
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||
# When it is, any changes listed below will disappear.
|
||||
#
|
||||
author: Sparky_hotdog
|
||||
|
||||
delete-after: True
|
||||
|
||||
changes:
|
||||
- bugfix: "Fixed regular and reinforced walls not smoothing properly."
|
||||
@@ -0,0 +1,43 @@
|
||||
################################
|
||||
# Example Changelog File
|
||||
#
|
||||
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||
#
|
||||
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||
# When it is, any changes listed below will disappear.
|
||||
#
|
||||
# Valid Prefixes:
|
||||
# bugfix
|
||||
# wip (For works in progress)
|
||||
# tweak
|
||||
# soundadd
|
||||
# sounddel
|
||||
# rscadd (general adding of nice things)
|
||||
# rscdel (general deleting of nice things)
|
||||
# imageadd
|
||||
# imagedel
|
||||
# maptweak
|
||||
# spellcheck (typo fixes)
|
||||
# experiment
|
||||
# balance
|
||||
# admin
|
||||
# backend
|
||||
# security
|
||||
# refactor
|
||||
#################################
|
||||
|
||||
# Your name.
|
||||
author: Wowzewow (Wezzy)
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
|
||||
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- bugfix: "Seethrough blindfolds are actually see-through again."
|
||||
- bugfix: "Recolored blindfolds no longer are called white. Check your loadouts."
|
||||
- balance: "Seethrough blindfolds no longer provide flash protection."
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 487 B |
Binary file not shown.
|
After Width: | Height: | Size: 494 B |
@@ -50,5 +50,8 @@
|
||||
icon_state = "tcomsatwest"
|
||||
|
||||
/area/tcommsat/mainlvl_tcomms__relay
|
||||
name = "Sublevel - Telecommunications Relay"
|
||||
name = "First Deck Telecommunications Relay"
|
||||
icon_state = "tcomsatcham"
|
||||
|
||||
/area/tcommsat/mainlvl_tcomms__relay/second
|
||||
name = "Second Deck Telecommunications Relay"
|
||||
|
||||
@@ -44531,6 +44531,7 @@
|
||||
/obj/machinery/vending/wallmed1{
|
||||
pixel_y = -30
|
||||
},
|
||||
/obj/item/device/hand_labeler,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/medical/first_responder)
|
||||
"bBH" = (
|
||||
|
||||
@@ -464,16 +464,21 @@
|
||||
/obj/machinery/door/firedoor,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/security/prison)
|
||||
"and" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
"anb" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate/damaged,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"and" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/machinery/light/small/emergency{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/starboard)
|
||||
"ann" = (
|
||||
@@ -6106,13 +6111,6 @@
|
||||
"dSU" = (
|
||||
/turf/simulated/wall/shuttle/scc_space_ship/cardinal,
|
||||
/area/maintenance/substation/engineering)
|
||||
"dTa" = (
|
||||
/obj/structure/railing/mapped,
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"dTc" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/structure/bed/stool/padded/red,
|
||||
@@ -7533,6 +7531,13 @@
|
||||
},
|
||||
/turf/simulated/floor/tiled/dark,
|
||||
/area/turret_protected/ai_upload)
|
||||
"eUX" = (
|
||||
/obj/machinery/door/airlock/maintenance,
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/tiled/dark,
|
||||
/area/maintenance/wing/port/far)
|
||||
"eUY" = (
|
||||
/obj/structure/table/standard,
|
||||
/obj/item/stack/packageWrap,
|
||||
@@ -9103,6 +9108,16 @@
|
||||
},
|
||||
/turf/simulated/floor/reinforced,
|
||||
/area/template_noop)
|
||||
"fRN" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/obj/machinery/alarm{
|
||||
pixel_y = 28
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/tcommsat/mainlvl_tcomms__relay/second)
|
||||
"fSg" = (
|
||||
/obj/effect/floor_decal/corner/white,
|
||||
/obj/effect/floor_decal/spline/plain/corner,
|
||||
@@ -9278,6 +9293,13 @@
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/engineering/smes/tesla)
|
||||
"fWG" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"fWI" = (
|
||||
/turf/simulated/floor/tiled/dark,
|
||||
/area/chapel/main)
|
||||
@@ -10807,6 +10829,13 @@
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/hydroponics)
|
||||
"gRU" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"gRY" = (
|
||||
/obj/effect/floor_decal/corner/mauve/diagonal,
|
||||
/obj/machinery/light{
|
||||
@@ -11013,15 +11042,6 @@
|
||||
"gZt" = (
|
||||
/turf/simulated/floor/wood,
|
||||
/area/hydroponics/garden)
|
||||
"gZV" = (
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"hal" = (
|
||||
/obj/effect/floor_decal/corner_wide/yellow/full,
|
||||
/obj/machinery/button/remote/blast_door{
|
||||
@@ -13299,8 +13319,6 @@
|
||||
"iBT" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
@@ -13976,6 +13994,15 @@
|
||||
/obj/structure/bed/stool/chair/office/dark,
|
||||
/turf/simulated/floor/carpet/rubber,
|
||||
/area/crew_quarters/heads/hor)
|
||||
"iTh" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/telecomms/relay/preset/station,
|
||||
/obj/machinery/camera/network/telecom{
|
||||
c_tag = "Telecomms - Second Deck Relay";
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/tcommsat/mainlvl_tcomms__relay/second)
|
||||
"iUg" = (
|
||||
/obj/structure/table/standard,
|
||||
/obj/item/stamp/rd{
|
||||
@@ -14283,6 +14310,16 @@
|
||||
/obj/machinery/firealarm/east,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/security/armory)
|
||||
"jeo" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/machinery/light/small/emergency{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"jes" = (
|
||||
/obj/effect/floor_decal/spline/fancy/wood{
|
||||
dir = 8
|
||||
@@ -15642,6 +15679,13 @@
|
||||
/obj/machinery/disposal,
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/storage/primary)
|
||||
"jVc" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"jVn" = (
|
||||
/obj/effect/floor_decal/corner_wide/yellow{
|
||||
dir = 5
|
||||
@@ -16843,6 +16887,13 @@
|
||||
},
|
||||
/turf/simulated/floor/tiled/dark,
|
||||
/area/maintenance/wing/port/far)
|
||||
"kPu" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/light/small{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/tcommsat/mainlvl_tcomms__relay/second)
|
||||
"kPz" = (
|
||||
/obj/effect/floor_decal/corner/grey/diagonal,
|
||||
/obj/machinery/appliance/cooker/oven,
|
||||
@@ -23127,6 +23178,9 @@
|
||||
dir = 6
|
||||
},
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"oKR" = (
|
||||
@@ -23186,6 +23240,13 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/turf/simulated/floor/tiled/dark,
|
||||
/area/rnd/xenobiology)
|
||||
"oNE" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/structure/cable{
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"oNS" = (
|
||||
/obj/machinery/vending/battlemonsters,
|
||||
/obj/machinery/alarm{
|
||||
@@ -23415,13 +23476,6 @@
|
||||
/obj/machinery/door/firedoor,
|
||||
/turf/simulated/floor/lino/grey,
|
||||
/area/crew_quarters/bar)
|
||||
"oUW" = (
|
||||
/obj/structure/railing/mapped,
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"oVe" = (
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 8
|
||||
@@ -31278,8 +31332,6 @@
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/tiled/ramp{
|
||||
@@ -33035,17 +33087,15 @@
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/security/checkpoint2)
|
||||
"uNq" = (
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 4
|
||||
/obj/machinery/door/airlock/highsecurity{
|
||||
name = "Second Deck Telecommunications Relay";
|
||||
req_access = list(61)
|
||||
},
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 1
|
||||
/obj/structure/cable{
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
/area/tcommsat/mainlvl_tcomms__relay/second)
|
||||
"uNs" = (
|
||||
/obj/effect/floor_decal/corner/grey/diagonal,
|
||||
/obj/structure/table/stone/marble,
|
||||
@@ -33443,6 +33493,15 @@
|
||||
},
|
||||
/turf/simulated/open/airless,
|
||||
/area/template_noop)
|
||||
"vbe" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/structure/cable,
|
||||
/obj/machinery/power/apc{
|
||||
name = "south bump";
|
||||
pixel_y = -24
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/tcommsat/mainlvl_tcomms__relay/second)
|
||||
"vbk" = (
|
||||
/obj/structure/railing/mapped{
|
||||
dir = 4
|
||||
@@ -36043,11 +36102,6 @@
|
||||
},
|
||||
/turf/simulated/floor/tiled/dark,
|
||||
/area/rnd/xenobiology/xenoflora)
|
||||
"wzU" = (
|
||||
/turf/simulated/floor/tiled/ramp{
|
||||
dir = 4
|
||||
},
|
||||
/area/maintenance/wing/port/far)
|
||||
"wAa" = (
|
||||
/obj/item/reagent_containers/glass/beaker/cryoxadone{
|
||||
pixel_x = 6;
|
||||
@@ -36106,11 +36160,8 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/hydroponics/garden)
|
||||
"wBF" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/tiled/ramp{
|
||||
dir = 8
|
||||
},
|
||||
/area/maintenance/wing/port/far)
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/tcommsat/mainlvl_tcomms__relay/second)
|
||||
"wCm" = (
|
||||
/obj/structure/cable/green{
|
||||
icon_state = "2-4"
|
||||
@@ -39005,6 +39056,13 @@
|
||||
/obj/item/storage/box/syringes,
|
||||
/turf/simulated/floor/tiled/dark,
|
||||
/area/rnd/xenobiology/xenoflora)
|
||||
"yjg" = (
|
||||
/obj/structure/lattice/catwalk/indoor/grate,
|
||||
/obj/structure/cable{
|
||||
icon_state = "2-4"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/maintenance/wing/port/far)
|
||||
"yjZ" = (
|
||||
/obj/effect/floor_decal/corner/mauve/diagonal,
|
||||
/obj/structure/table/standard,
|
||||
@@ -71697,10 +71755,10 @@ lBd
|
||||
lBd
|
||||
sEu
|
||||
vqk
|
||||
lBd
|
||||
lBd
|
||||
lBd
|
||||
lBd
|
||||
yjg
|
||||
oNE
|
||||
oNE
|
||||
gRU
|
||||
lBd
|
||||
lBd
|
||||
lBd
|
||||
@@ -71900,9 +71958,9 @@ lBd
|
||||
fuu
|
||||
wBF
|
||||
uNq
|
||||
gZV
|
||||
dTa
|
||||
qQs
|
||||
wBF
|
||||
wBF
|
||||
anb
|
||||
lBd
|
||||
dXB
|
||||
lZQ
|
||||
@@ -72100,11 +72158,11 @@ fuu
|
||||
fuu
|
||||
lBd
|
||||
dXB
|
||||
ueH
|
||||
jIj
|
||||
jIj
|
||||
oUW
|
||||
lBd
|
||||
wBF
|
||||
fRN
|
||||
vbe
|
||||
wBF
|
||||
jVc
|
||||
lBd
|
||||
wox
|
||||
ulr
|
||||
@@ -72302,11 +72360,11 @@ aIx
|
||||
rLg
|
||||
lBd
|
||||
dXB
|
||||
jIj
|
||||
jIj
|
||||
jIj
|
||||
oUW
|
||||
lBd
|
||||
wBF
|
||||
iTh
|
||||
kPu
|
||||
wBF
|
||||
jVc
|
||||
lBd
|
||||
lGm
|
||||
ulr
|
||||
@@ -72504,11 +72562,11 @@ uuL
|
||||
hIV
|
||||
sEu
|
||||
fuu
|
||||
wzU
|
||||
uNq
|
||||
gZV
|
||||
xdA
|
||||
lBd
|
||||
wBF
|
||||
wBF
|
||||
wBF
|
||||
wBF
|
||||
jVc
|
||||
qQs
|
||||
xpX
|
||||
jIj
|
||||
@@ -72705,12 +72763,12 @@ lBd
|
||||
lBd
|
||||
lBd
|
||||
lBd
|
||||
lBd
|
||||
mLH
|
||||
lBd
|
||||
lBd
|
||||
lBd
|
||||
lBd
|
||||
yjg
|
||||
jeo
|
||||
oNE
|
||||
oNE
|
||||
oNE
|
||||
fWG
|
||||
lBd
|
||||
kPj
|
||||
jpc
|
||||
@@ -72907,7 +72965,7 @@ xPm
|
||||
xPm
|
||||
xPm
|
||||
xPm
|
||||
qOt
|
||||
eUX
|
||||
fuu
|
||||
fuu
|
||||
fuu
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pygit2==1.4.0
|
||||
bidict==0.21.2
|
||||
Pillow==8.3.2
|
||||
Pillow==9.0.0
|
||||
PyYAML==5.4.1
|
||||
beautifulsoup4==4.10.0
|
||||
|
||||
Generated
+7
-15
@@ -5752,7 +5752,7 @@
|
||||
"dependencies": {
|
||||
"globby": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
|
||||
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -5765,7 +5765,7 @@
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -6934,9 +6934,9 @@
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
|
||||
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==",
|
||||
"version": "1.14.7",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
|
||||
"dev": true
|
||||
},
|
||||
"for-in": {
|
||||
@@ -12676,7 +12676,6 @@
|
||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
|
||||
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"hash-sum": "^2.0.0",
|
||||
@@ -12688,7 +12687,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
@@ -12698,7 +12696,6 @@
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
@@ -12709,7 +12706,6 @@
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
@@ -12718,22 +12714,19 @@
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
|
||||
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
@@ -12745,7 +12738,6 @@
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user