mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 03:27:05 +01:00
Merge branch 'master' into convert-tickets
This commit is contained in:
@@ -36,7 +36,7 @@
|
||||
var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi)
|
||||
var/vote_no_dead = 0 // dead people can't vote (tbi)
|
||||
// var/enable_authentication = 0 // goon authentication
|
||||
var/del_new_on_log = 1 // del's new players if they log before they spawn in
|
||||
var/del_new_on_log = 1 // qdel's new players if they log before they spawn in
|
||||
var/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard
|
||||
var/traitor_scaling = 0 //if amount of traitors scales based on amount of players
|
||||
var/protect_roles_from_antagonist = 0// If security and such can be tratior/cult/other
|
||||
@@ -200,8 +200,8 @@
|
||||
var/disable_away_missions = 0 // disable away missions
|
||||
var/disable_space_ruins = 0 //disable space ruins
|
||||
|
||||
var/extra_space_ruin_levels_min = 2
|
||||
var/extra_space_ruin_levels_max = 4
|
||||
var/extra_space_ruin_levels_min = 4
|
||||
var/extra_space_ruin_levels_max = 8
|
||||
|
||||
var/ooc_allowed = 1
|
||||
var/looc_allowed = 1
|
||||
@@ -265,6 +265,11 @@
|
||||
src.votable_modes += "secret"
|
||||
|
||||
/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist
|
||||
if(IsAdminAdvancedProcCall())
|
||||
to_chat(usr, "<span class='boldannounce'>Config reload blocked: Advanced ProcCall detected.</span>")
|
||||
message_admins("[key_name(usr)] attempted to reload configuration via advanced proc-call")
|
||||
log_admin("[key_name(usr)] attempted to reload configuration via advanced proc-call")
|
||||
return
|
||||
var/list/Lines = file2list(filename)
|
||||
|
||||
for(var/t in Lines)
|
||||
@@ -641,31 +646,31 @@
|
||||
config.max_maint_drones = text2num(value)
|
||||
|
||||
if("expected_round_length")
|
||||
config.expected_round_length = MinutesToTicks(text2num(value))
|
||||
config.expected_round_length = text2num(value) MINUTES
|
||||
|
||||
if("event_custom_start_mundane")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2]))
|
||||
config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
|
||||
|
||||
if("event_custom_start_moderate")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2]))
|
||||
config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
|
||||
|
||||
if("event_custom_start_major")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2]))
|
||||
config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
|
||||
|
||||
if("event_delay_lower")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_delay_lower[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1])
|
||||
config.event_delay_lower[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2])
|
||||
config.event_delay_lower[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3])
|
||||
config.event_delay_lower[EVENT_LEVEL_MUNDANE] = values[1] MINUTES
|
||||
config.event_delay_lower[EVENT_LEVEL_MODERATE] = values[2] MINUTES
|
||||
config.event_delay_lower[EVENT_LEVEL_MAJOR] = values[3] MINUTES
|
||||
|
||||
if("event_delay_upper")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_delay_upper[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1])
|
||||
config.event_delay_upper[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2])
|
||||
config.event_delay_upper[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3])
|
||||
config.event_delay_upper[EVENT_LEVEL_MUNDANE] = values[1] MINUTES
|
||||
config.event_delay_upper[EVENT_LEVEL_MODERATE] = values[2] MINUTES
|
||||
config.event_delay_upper[EVENT_LEVEL_MAJOR] = values[3] MINUTES
|
||||
|
||||
if("starlight")
|
||||
config.starlight = 1
|
||||
@@ -701,7 +706,7 @@
|
||||
config.max_loadout_points = text2num(value)
|
||||
|
||||
if("round_abandon_penalty_period")
|
||||
config.round_abandon_penalty_period = MinutesToTicks(text2num(value))
|
||||
config.round_abandon_penalty_period = text2num(value) MINUTES
|
||||
|
||||
if("medal_hub_address")
|
||||
config.medal_hub_address = value
|
||||
@@ -808,8 +813,12 @@
|
||||
log_config("Unknown setting in configuration: '[name]'")
|
||||
|
||||
/datum/configuration/proc/loadsql(filename) // -- TLE
|
||||
if(IsAdminAdvancedProcCall())
|
||||
to_chat(usr, "<span class='boldannounce'>SQL configuration reload blocked: Advanced ProcCall detected.</span>")
|
||||
message_admins("[key_name(usr)] attempted to reload SQL configuration via advanced proc-call")
|
||||
log_admin("[key_name(usr)] attempted to reload SQL configuration via advanced proc-call")
|
||||
return
|
||||
var/list/Lines = file2list(filename)
|
||||
var/db_version = 0
|
||||
for(var/t in Lines)
|
||||
if(!t) continue
|
||||
|
||||
@@ -848,10 +857,13 @@
|
||||
if("feedback_tableprefix")
|
||||
sqlfdbktableprefix = value
|
||||
if("db_version")
|
||||
db_version = text2num(value)
|
||||
sql_version = text2num(value)
|
||||
else
|
||||
log_config("Unknown setting in configuration: '[name]'")
|
||||
if(config.sql_enabled && db_version != SQL_VERSION)
|
||||
|
||||
// The unit tests have their own version of this check, which wont hold the server up infinitely, so this is disabled if we are running unit tests
|
||||
#ifndef UNIT_TESTS
|
||||
if(config.sql_enabled && sql_version != SQL_VERSION)
|
||||
config.sql_enabled = 0
|
||||
log_config("WARNING: DB_CONFIG DEFINITION MISMATCH!")
|
||||
spawn(60)
|
||||
@@ -859,6 +871,7 @@
|
||||
SSticker.ticker_going = FALSE
|
||||
spawn(600)
|
||||
to_chat(world, "<span class='alert'>DB_CONFIG MISMATCH, ROUND START DELAYED. <BR>Please check database version for recent upstream changes!</span>")
|
||||
#endif
|
||||
|
||||
/datum/configuration/proc/loadoverflowwhitelist(filename)
|
||||
var/list/Lines = file2list(filename)
|
||||
|
||||
@@ -14,7 +14,7 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
|
||||
var/datum/controller/exclude_these = new
|
||||
gvars_datum_in_built_vars = exclude_these.vars + list("gvars_datum_protected_varlist", "gvars_datum_in_built_vars", "gvars_datum_init_order")
|
||||
qdel(exclude_these)
|
||||
QDEL_IN(exclude_these, 0) //signal logging isn't ready
|
||||
|
||||
Initialize()
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Startup hook.
|
||||
* Called in world.dm when the server starts.
|
||||
*/
|
||||
/hook/startup
|
||||
|
||||
/**
|
||||
* Roundstart hook.
|
||||
* Called in gameticker.dm when a round starts.
|
||||
*/
|
||||
/hook/roundstart
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* @file hooks.dm
|
||||
* Implements hooks, a simple way to run code on pre-defined events.
|
||||
*/
|
||||
|
||||
/** @page hooks Code hooks
|
||||
* @section hooks Hooks
|
||||
* A hook is defined under /hook in the type tree.
|
||||
*
|
||||
* To add some code to be called by the hook, define a proc under the type, as so:
|
||||
* @code
|
||||
/hook/foo/proc/bar()
|
||||
if(1)
|
||||
return 1 //Sucessful
|
||||
else
|
||||
return 0 //Error, or runtime.
|
||||
* @endcode
|
||||
* All hooks must return nonzero on success, as runtimes will force return null.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calls a hook, executing every piece of code that's attached to it.
|
||||
* @param hook Identifier of the hook to call.
|
||||
* @returns 1 if all hooked code runs successfully, 0 otherwise.
|
||||
*/
|
||||
/proc/callHook(hook, list/args=null)
|
||||
var/hook_path = text2path("/hook/[hook]")
|
||||
if(!hook_path)
|
||||
error("Invalid hook '/hook/[hook]' called.")
|
||||
return 0
|
||||
|
||||
var/caller = new hook_path
|
||||
var/status = 1
|
||||
for(var/P in typesof("[hook_path]/proc"))
|
||||
if(!call(caller, P)(arglist(args)))
|
||||
error("Hook '[P]' failed or runtimed.")
|
||||
status = 0
|
||||
|
||||
return status
|
||||
@@ -451,14 +451,15 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
// in those cases, so we just let them run)
|
||||
if(queue_node_flags & SS_NO_TICK_CHECK)
|
||||
if(queue_node.tick_usage > TICK_LIMIT_RUNNING - TICK_USAGE && ran_non_ticker)
|
||||
queue_node.queued_priority += queue_priority_count * 0.1
|
||||
queue_priority_count -= queue_node_priority
|
||||
queue_priority_count += queue_node.queued_priority
|
||||
current_tick_budget -= queue_node_priority
|
||||
queue_node = queue_node.queue_next
|
||||
if(!(queue_node_flags & SS_BACKGROUND))
|
||||
queue_node.queued_priority += queue_priority_count * 0.1
|
||||
queue_priority_count -= queue_node_priority
|
||||
queue_priority_count += queue_node.queued_priority
|
||||
current_tick_budget -= queue_node_priority
|
||||
queue_node = queue_node.queue_next
|
||||
continue
|
||||
|
||||
if((queue_node_flags & SS_BACKGROUND) && !bg_calc)
|
||||
if(!bg_calc && (queue_node_flags & SS_BACKGROUND))
|
||||
current_tick_budget = queue_priority_count_bg
|
||||
bg_calc = TRUE
|
||||
|
||||
@@ -511,7 +512,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
queue_node.paused_ticks = 0
|
||||
queue_node.paused_tick_usage = 0
|
||||
|
||||
if(queue_node_flags & SS_BACKGROUND) //update our running total
|
||||
if(bg_calc) //update our running total
|
||||
queue_priority_count_bg -= queue_node_priority
|
||||
else
|
||||
queue_priority_count -= queue_node_priority
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
/datum/controller/subsystem
|
||||
// Metadata; you should define these.
|
||||
name = "fire coderbus" //name of the subsystem
|
||||
name = "fire codertrain" //name of the subsystem
|
||||
var/init_order = INIT_ORDER_DEFAULT //order of initialization. Higher numbers are initialized first, lower numbers later. Use defines in __DEFINES/subsystems.dm for easy understanding of order.
|
||||
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
|
||||
var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
|
||||
@@ -89,7 +89,7 @@
|
||||
queue_node_flags = queue_node.flags
|
||||
|
||||
if(queue_node_flags & SS_TICKER)
|
||||
if(!(SS_flags & SS_TICKER))
|
||||
if((SS_flags & (SS_TICKER|SS_BACKGROUND)) != SS_TICKER)
|
||||
continue
|
||||
if(queue_node_priority < SS_priority)
|
||||
break
|
||||
|
||||
@@ -49,7 +49,7 @@ SUBSYSTEM_DEF(afk)
|
||||
if(mins_afk >= config.auto_cryo_afk && A.can_get_auto_cryod)
|
||||
if(A.fast_despawn)
|
||||
toRemove += H.ckey
|
||||
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.</span>")
|
||||
warn(H, "<span class='danger'>You have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.</span>")
|
||||
log_afk_action(H, mins_afk, T, "despawned", "AFK in a fast despawn area")
|
||||
force_cryo_human(H)
|
||||
else
|
||||
@@ -67,7 +67,7 @@ SUBSYSTEM_DEF(afk)
|
||||
|
||||
else if(afk_players[H.ckey] != AFK_ADMINS_WARNED && mins_afk >= config.auto_despawn_afk)
|
||||
log_afk_action(H, mins_afk, T, "despawned")
|
||||
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes.</span>")
|
||||
warn(H, "<span class='danger'>You have been despawned after being AFK for [mins_afk] minutes.</span>")
|
||||
toRemove += H.ckey
|
||||
force_cryo_human(H)
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(dcs)
|
||||
name = "Datum Component System"
|
||||
flags = SS_NO_INIT
|
||||
|
||||
var/list/elements_by_type = list()
|
||||
|
||||
/datum/controller/subsystem/processing/dcs/Recover()
|
||||
comp_lookup = SSdcs.comp_lookup
|
||||
|
||||
/datum/controller/subsystem/processing/dcs/proc/GetElement(list/arguments)
|
||||
var/datum/element/eletype = arguments[1]
|
||||
var/element_id = eletype
|
||||
|
||||
if(!ispath(eletype, /datum/element))
|
||||
CRASH("Attempted to instantiate [eletype] as a /datum/element")
|
||||
|
||||
if(initial(eletype.element_flags) & ELEMENT_BESPOKE)
|
||||
element_id = GetIdFromArguments(arguments)
|
||||
|
||||
. = elements_by_type[element_id]
|
||||
if(.)
|
||||
return
|
||||
. = elements_by_type[element_id] = new eletype
|
||||
|
||||
/****
|
||||
* Generates an id for bespoke elements when given the argument list
|
||||
* Generating the id here is a bit complex because we need to support named arguments
|
||||
* Named arguments can appear in any order and we need them to appear after ordered arguments
|
||||
* We assume that no one will pass in a named argument with a value of null
|
||||
**/
|
||||
/datum/controller/subsystem/processing/dcs/proc/GetIdFromArguments(list/arguments)
|
||||
var/datum/element/eletype = arguments[1]
|
||||
var/list/fullid = list("[eletype]")
|
||||
var/list/named_arguments = list()
|
||||
for(var/i in initial(eletype.id_arg_index) to length(arguments))
|
||||
var/key = arguments[i]
|
||||
var/value
|
||||
if(istext(key))
|
||||
value = arguments[key]
|
||||
if(!(istext(key) || isnum(key)))
|
||||
key = "\ref[key]"
|
||||
key = "[key]" // Key is stringified so numbers dont break things
|
||||
if(!isnull(value))
|
||||
if(!(istext(value) || isnum(value)))
|
||||
value = "\ref[value]"
|
||||
named_arguments["[key]"] = value
|
||||
else
|
||||
fullid += "[key]"
|
||||
|
||||
if(length(named_arguments))
|
||||
named_arguments = sortList(named_arguments)
|
||||
fullid += named_arguments
|
||||
return list2params(fullid)
|
||||
@@ -90,7 +90,7 @@ SUBSYSTEM_DEF(events)
|
||||
if(E.isRunning)
|
||||
message += "and is still running."
|
||||
else
|
||||
if(E.endedAt - E.startedAt > MinutesToTicks(5)) // Only mention end time if the entire duration was more than 5 minutes
|
||||
if(E.endedAt - E.startedAt > 5 MINUTES) // Only mention end time if the entire duration was more than 5 minutes
|
||||
message += "and ended at [station_time_timestamp("hh:mm:ss", E.endedAt)]."
|
||||
else
|
||||
message += "and ran to completion."
|
||||
|
||||
@@ -7,7 +7,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
init_order = INIT_ORDER_GARBAGE
|
||||
offline_implications = "Garbage collection is no longer functional, and objects will not be qdel'd. Immediate server restart recommended."
|
||||
|
||||
var/list/collection_timeout = list(0, 2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
var/list/collection_timeout = list(2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
|
||||
//Stat tracking
|
||||
var/delslasttick = 0 // number of del()'s we've done this tick
|
||||
|
||||
@@ -19,8 +19,18 @@ SUBSYSTEM_DEF(icon_smooth)
|
||||
can_fire = 0
|
||||
|
||||
/datum/controller/subsystem/icon_smooth/Initialize()
|
||||
smooth_zlevel(1,TRUE)
|
||||
smooth_zlevel(2,TRUE)
|
||||
log_startup_progress("Smoothing atoms...")
|
||||
// Smooth EVERYTHING in the world
|
||||
for(var/turf/T in world)
|
||||
if(T.smooth)
|
||||
smooth_icon(T)
|
||||
for(var/A in T)
|
||||
var/atom/AA = A
|
||||
if(AA.smooth)
|
||||
smooth_icon(AA)
|
||||
CHECK_TICK
|
||||
|
||||
// Incase any new atoms were added to the smoothing queue for whatever reason
|
||||
var/queue = smooth_queue
|
||||
smooth_queue = list()
|
||||
for(var/V in queue)
|
||||
|
||||
@@ -121,3 +121,8 @@ SUBSYSTEM_DEF(input)
|
||||
for(var/i in 1 to clients.len)
|
||||
var/client/C = clients[i]
|
||||
C.keyLoop()
|
||||
|
||||
/datum/controller/subsystem/input/Recover()
|
||||
macro_sets = SSinput.macro_sets
|
||||
movement_keys = SSinput.movement_keys
|
||||
alt_movement_keys = SSinput.alt_movement_keys
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
GLOBAL_LIST_EMPTY(lighting_update_lights) // List of lighting sources queued for update.
|
||||
GLOBAL_LIST_EMPTY(lighting_update_corners) // List of lighting corners queued for update.
|
||||
GLOBAL_LIST_EMPTY(lighting_update_objects) // List of lighting objects queued for update.
|
||||
|
||||
SUBSYSTEM_DEF(lighting)
|
||||
name = "Lighting"
|
||||
wait = 2
|
||||
init_order = INIT_ORDER_LIGHTING
|
||||
flags = SS_TICKER
|
||||
offline_implications = "Lighting will no longer update. Shuttle call recommended."
|
||||
var/static/list/sources_queue = list() // List of lighting sources queued for update.
|
||||
var/static/list/corners_queue = list() // List of lighting corners queued for update.
|
||||
var/static/list/objects_queue = list() // List of lighting objects queued for update.
|
||||
|
||||
/datum/controller/subsystem/lighting/stat_entry()
|
||||
..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]")
|
||||
..("L:[length(sources_queue)]|C:[length(corners_queue)]|O:[length(objects_queue)]")
|
||||
|
||||
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
||||
if(!initialized)
|
||||
@@ -31,9 +30,10 @@ SUBSYSTEM_DEF(lighting)
|
||||
MC_SPLIT_TICK_INIT(3)
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
var/list/queue = sources_queue
|
||||
var/i = 0
|
||||
for(i in 1 to GLOB.lighting_update_lights.len)
|
||||
var/datum/light_source/L = GLOB.lighting_update_lights[i]
|
||||
for(i in 1 to length(queue))
|
||||
var/datum/light_source/L = queue[i]
|
||||
|
||||
L.update_corners()
|
||||
|
||||
@@ -44,14 +44,15 @@ SUBSYSTEM_DEF(lighting)
|
||||
else if(MC_TICK_CHECK)
|
||||
break
|
||||
if(i)
|
||||
GLOB.lighting_update_lights.Cut(1, i+1)
|
||||
queue.Cut(1, i + 1)
|
||||
i = 0
|
||||
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
for (i in 1 to GLOB.lighting_update_corners.len)
|
||||
var/datum/lighting_corner/C = GLOB.lighting_update_corners[i]
|
||||
queue = corners_queue
|
||||
for(i in 1 to length(queue))
|
||||
var/datum/lighting_corner/C = queue[i]
|
||||
|
||||
C.update_objects()
|
||||
C.needs_update = FALSE
|
||||
@@ -60,15 +61,16 @@ SUBSYSTEM_DEF(lighting)
|
||||
else if(MC_TICK_CHECK)
|
||||
break
|
||||
if(i)
|
||||
GLOB.lighting_update_corners.Cut(1, i+1)
|
||||
queue.Cut(1, i + 1)
|
||||
i = 0
|
||||
|
||||
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
for (i in 1 to GLOB.lighting_update_objects.len)
|
||||
var/atom/movable/lighting_object/O = GLOB.lighting_update_objects[i]
|
||||
queue = objects_queue
|
||||
for(i in 1 to length(queue))
|
||||
var/atom/movable/lighting_object/O = queue[i]
|
||||
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
@@ -80,7 +82,7 @@ SUBSYSTEM_DEF(lighting)
|
||||
else if(MC_TICK_CHECK)
|
||||
break
|
||||
if(i)
|
||||
GLOB.lighting_update_objects.Cut(1, i+1)
|
||||
queue.Cut(1, i + 1)
|
||||
|
||||
|
||||
/datum/controller/subsystem/lighting/Recover()
|
||||
|
||||
@@ -42,7 +42,7 @@ SUBSYSTEM_DEF(machines)
|
||||
while(currentrun.len)
|
||||
var/obj/O = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(O)
|
||||
if(O && !QDELETED(O))
|
||||
var/datum/powernet/newPN = new() // create a new powernet...
|
||||
propagate_network(O, newPN)//... and propagate it to the other side of the cable
|
||||
|
||||
|
||||
@@ -11,24 +11,57 @@ SUBSYSTEM_DEF(mapping)
|
||||
createRandomZlevel()
|
||||
// Seed space ruins
|
||||
if(!config.disable_space_ruins)
|
||||
var/timer = start_watch()
|
||||
log_startup_progress("Creating random space levels...")
|
||||
seedRuins(list(level_name_to_num(EMPTY_AREA)), rand(0, 3), /area/space, GLOB.space_ruins_templates)
|
||||
log_startup_progress("Loaded random space levels in [stop_watch(timer)]s.")
|
||||
|
||||
// load in extra levels of space ruins
|
||||
|
||||
var/load_zlevels_timer = start_watch()
|
||||
log_startup_progress("Creating random space levels...")
|
||||
var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max)
|
||||
for(var/i = 1, i <= num_extra_space, i++)
|
||||
var/zlev = GLOB.space_manager.add_new_zlevel("[EMPTY_AREA] #[i]", linkage = CROSSLINKED, traits = list(REACHABLE))
|
||||
seedRuins(list(zlev), rand(0, 3), /area/space, GLOB.space_ruins_templates)
|
||||
GLOB.space_manager.add_new_zlevel("Ruin Area #[i]", linkage = CROSSLINKED, traits = list(REACHABLE, SPAWN_RUINS))
|
||||
log_startup_progress("Loaded random space levels in [stop_watch(load_zlevels_timer)]s.")
|
||||
|
||||
// Now spawn ruins, random budget between 20 and 30 for all zlevels combined.
|
||||
// While this may seem like a high number, the amount of ruin Z levels can be anywhere between 3 and 7.
|
||||
// Note that this budget is not split evenly accross all zlevels
|
||||
log_startup_progress("Seeding ruins...")
|
||||
var/seed_ruins_timer = start_watch()
|
||||
seedRuins(levels_by_trait(SPAWN_RUINS), rand(20, 30), /area/space, GLOB.space_ruins_templates)
|
||||
log_startup_progress("Successfully seeded ruins in [stop_watch(seed_ruins_timer)]s.")
|
||||
|
||||
// Makes a blank space level for the sake of randomness
|
||||
GLOB.space_manager.add_new_zlevel("Empty Area", linkage = CROSSLINKED, traits = list(REACHABLE))
|
||||
|
||||
|
||||
// Setup the Z-level linkage
|
||||
GLOB.space_manager.do_transition_setup()
|
||||
|
||||
// Spawn Lavaland ruins and rivers.
|
||||
log_startup_progress("Populating lavaland...")
|
||||
var/lavaland_setup_timer = start_watch()
|
||||
seedRuins(list(level_name_to_num(MINING)), config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, GLOB.lava_ruins_templates)
|
||||
spawn_rivers(list(level_name_to_num(MINING)))
|
||||
log_startup_progress("Successfully populated lavaland in [stop_watch(lavaland_setup_timer)]s.")
|
||||
|
||||
// Now we make a list of areas for teleport locs
|
||||
// TOOD: Make these locs into lists on the SS itself, not globs
|
||||
for(var/area/AR in world)
|
||||
if(AR.no_teleportlocs)
|
||||
continue
|
||||
if(GLOB.teleportlocs[AR.name])
|
||||
continue
|
||||
var/turf/picked = safepick(get_area_turfs(AR.type))
|
||||
if(picked && is_station_level(picked.z))
|
||||
GLOB.teleportlocs[AR.name] = AR
|
||||
|
||||
GLOB.teleportlocs = sortAssoc(GLOB.teleportlocs)
|
||||
|
||||
for(var/area/AR in world)
|
||||
if(GLOB.ghostteleportlocs[AR.name])
|
||||
continue
|
||||
var/list/turfs = get_area_turfs(AR.type)
|
||||
if(turfs.len)
|
||||
GLOB.ghostteleportlocs[AR.name] = AR
|
||||
|
||||
GLOB.ghostteleportlocs = sortAssoc(GLOB.ghostteleportlocs)
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -103,12 +103,12 @@ SUBSYSTEM_DEF(mob_hunt)
|
||||
return
|
||||
if(red_terminal && red_terminal.ready && blue_terminal && blue_terminal.ready)
|
||||
battle_turn = pick("Red", "Blue")
|
||||
red_terminal.audible_message("Battle starting!", null, 5)
|
||||
blue_terminal.audible_message("Battle starting!", null, 5)
|
||||
red_terminal.atom_say("Battle starting!")
|
||||
blue_terminal.atom_say("Battle starting!")
|
||||
if(battle_turn == "Red")
|
||||
red_terminal.audible_message("Red Player's Turn!", null, 5)
|
||||
red_terminal.atom_say("Red Player's Turn!")
|
||||
else if(battle_turn == "Blue")
|
||||
blue_terminal.audible_message("Blue Player's Turn!", null, 5)
|
||||
blue_terminal.atom_say("Blue Player's Turn!")
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/launch_attack(team, raw_damage, datum/mob_type/attack_type)
|
||||
if(!team || !raw_damage)
|
||||
@@ -135,11 +135,11 @@ SUBSYSTEM_DEF(mob_hunt)
|
||||
winner_terminal.ready = 0
|
||||
loser_terminal.ready = 0
|
||||
if(surrender) //surrender doesn't give exp, to avoid people just farming exp without actually doing a battle
|
||||
winner_terminal.audible_message("Your rival surrendered!", null, 2)
|
||||
winner_terminal.atom_say("Your rival surrendered!")
|
||||
else
|
||||
var/progress_message = winner_terminal.mob_info.gain_exp()
|
||||
winner_terminal.audible_message("[winner_terminal.team] Player wins!", null, 5)
|
||||
winner_terminal.audible_message(progress_message, null, 2)
|
||||
winner_terminal.atom_say("[winner_terminal.team] Player wins!")
|
||||
winner_terminal.atom_say(progress_message)
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/end_turn()
|
||||
red_terminal.updateUsrDialog()
|
||||
@@ -148,7 +148,7 @@ SUBSYSTEM_DEF(mob_hunt)
|
||||
return
|
||||
if(battle_turn == "Red")
|
||||
battle_turn = "Blue"
|
||||
blue_terminal.audible_message("Blue's turn.", null, 5)
|
||||
blue_terminal.atom_say("Blue's turn.")
|
||||
else if(battle_turn == "Blue")
|
||||
battle_turn = "Red"
|
||||
blue_terminal.audible_message("Red's turn.", null, 5)
|
||||
blue_terminal.atom_say("Red's turn.")
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
* tgui subsystem
|
||||
*
|
||||
* Contains all tgui state and subsystem code.
|
||||
**/
|
||||
|
||||
|
||||
SUBSYSTEM_DEF(tgui)
|
||||
name = "TGUI"
|
||||
wait = 9
|
||||
flags = SS_NO_INIT
|
||||
priority = FIRE_PRIORITY_NANOUI // Yes I am aware that this is TGUI and I used the nanoUI fire priority. Dont @ me.
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
offline_implications = "All TGUIs will no longer process. Shuttle call recommended."
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/open_uis = list() // A list of open UIs, grouped by src_object and ui_key.
|
||||
var/list/processing_uis = list() // A list of processing UIs, ungrouped.
|
||||
var/basehtml // The HTML base used for all UIs.
|
||||
|
||||
/datum/controller/subsystem/tgui/PreInit()
|
||||
basehtml = file2text('tgui/packages/tgui/public/tgui.html')
|
||||
|
||||
/datum/controller/subsystem/tgui/Shutdown()
|
||||
close_all_uis()
|
||||
|
||||
/datum/controller/subsystem/tgui/stat_entry()
|
||||
..("P:[processing_uis.len]")
|
||||
|
||||
/datum/controller/subsystem/tgui/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = processing_uis.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(currentrun.len)
|
||||
var/datum/tgui/ui = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(ui && ui.user && ui.src_object)
|
||||
ui.process()
|
||||
else
|
||||
processing_uis.Remove(ui)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Get a open UI given a user, src_object, and ui_key and try to update it with data.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object datum The object/datum which owns the UI.
|
||||
* required ui_key string The ui_key of the UI.
|
||||
* optional ui datum/tgui The UI to be updated, if it exists.
|
||||
* optional force_open bool If the UI should be re-opened instead of updated.
|
||||
*
|
||||
* return datum/tgui The found UI.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/try_update_ui(mob/user, datum/src_object, ui_key, datum/tgui/ui, force_open = FALSE)
|
||||
if(isnull(ui)) // No UI was passed, so look for one.
|
||||
ui = get_open_ui(user, src_object, ui_key)
|
||||
|
||||
if(!isnull(ui))
|
||||
var/data = src_object.tgui_data(user) // Get data from the src_object.
|
||||
if(!force_open) // UI is already open; update it.
|
||||
ui.push_data(data)
|
||||
else // Re-open it anyways.
|
||||
ui.reinitialize(null, data)
|
||||
return ui // We found the UI, return it.
|
||||
else
|
||||
return null // We couldn't find a UI.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Get a open UI given a user, src_object, and ui_key.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object datum The object/datum which owns the UI.
|
||||
* required ui_key string The ui_key of the UI.
|
||||
*
|
||||
* return datum/tgui The found UI.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/get_open_ui(mob/user, datum/src_object, ui_key)
|
||||
var/src_object_key = "[src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return null // No UIs open.
|
||||
else if(isnull(open_uis[src_object_key][ui_key]) || !istype(open_uis[src_object_key][ui_key], /list))
|
||||
return null // No UIs open for this object.
|
||||
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key]) // Find UIs for this object.
|
||||
if(ui.user == user) // Make sure we have the right user
|
||||
return ui
|
||||
|
||||
return null // Couldn't find a UI!
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update all UIs attached to src_object.
|
||||
*
|
||||
* required src_object datum The object/datum which owns the UIs.
|
||||
*
|
||||
* return int The number of UIs updated.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/update_uis(datum/src_object)
|
||||
var/src_object_key = "[src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // Couldn't find any UIs for this object.
|
||||
|
||||
var/update_count = 0
|
||||
for(var/ui_key in open_uis[src_object_key])
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid.
|
||||
ui.process(force = 1) // Update the UI.
|
||||
update_count++ // Count each UI we update.
|
||||
return update_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Close all UIs attached to src_object.
|
||||
*
|
||||
* required src_object datum The object/datum which owns the UIs.
|
||||
*
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/close_uis(datum/src_object)
|
||||
var/src_object_key = "[src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // Couldn't find any UIs for this object.
|
||||
|
||||
var/close_count = 0
|
||||
for(var/ui_key in open_uis[src_object_key])
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid.
|
||||
ui.close() // Close the UI.
|
||||
close_count++ // Count each UI we close.
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Close *ALL* UIs
|
||||
*
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/close_all_uis()
|
||||
var/close_count = 0
|
||||
for(var/src_object_key in open_uis)
|
||||
for(var/ui_key in open_uis[src_object_key])
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid.
|
||||
ui.close() // Close the UI.
|
||||
close_count++ // Count each UI we close.
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update all UIs belonging to a user.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional src_object datum If provided, only update UIs belonging this src_object.
|
||||
* optional ui_key string If provided, only update UIs with this UI key.
|
||||
*
|
||||
* return int The number of UIs updated.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/update_user_uis(mob/user, datum/src_object = null, ui_key = null)
|
||||
if(isnull(user.open_tguis) || !istype(user.open_tguis, /list) || open_uis.len == 0)
|
||||
return 0 // Couldn't find any UIs for this user.
|
||||
|
||||
var/update_count = 0
|
||||
for(var/datum/tgui/ui in user.open_tguis)
|
||||
if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.process(force = 1) // Update the UI.
|
||||
update_count++ // Count each UI we upadte.
|
||||
return update_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Close all UIs belonging to a user.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional src_object datum If provided, only close UIs belonging this src_object.
|
||||
* optional ui_key string If provided, only close UIs with this UI key.
|
||||
*
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/close_user_uis(mob/user, datum/src_object = null, ui_key = null)
|
||||
if(isnull(user.open_tguis) || !istype(user.open_tguis, /list) || open_uis.len == 0)
|
||||
return 0 // Couldn't find any UIs for this user.
|
||||
|
||||
var/close_count = 0
|
||||
for(var/datum/tgui/ui in user.open_tguis)
|
||||
if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.close() // Close the UI.
|
||||
close_count++ // Count each UI we close.
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Add a UI to the list of open UIs.
|
||||
*
|
||||
* required ui datum/tgui The UI to be added.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/on_open(datum/tgui/ui)
|
||||
var/src_object_key = "[ui.src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
open_uis[src_object_key] = list(ui.ui_key = list()) // Make a list for the ui_key and src_object.
|
||||
else if(isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
|
||||
open_uis[src_object_key][ui.ui_key] = list() // Make a list for the ui_key.
|
||||
|
||||
// Append the UI to all the lists.
|
||||
ui.user.open_tguis |= ui
|
||||
var/list/uis = open_uis[src_object_key][ui.ui_key]
|
||||
uis |= ui
|
||||
processing_uis |= ui
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Remove a UI from the list of open UIs.
|
||||
*
|
||||
* required ui datum/tgui The UI to be removed.
|
||||
*
|
||||
* return bool If the UI was removed or not.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/on_close(datum/tgui/ui)
|
||||
var/src_object_key = "[ui.src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return FALSE // It wasn't open.
|
||||
else if(isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
|
||||
return FALSE // It wasn't open.
|
||||
|
||||
processing_uis.Remove(ui) // Remove it from the list of processing UIs.
|
||||
if(ui.user) // If the user exists, remove it from them too.
|
||||
ui.user.open_tguis.Remove(ui)
|
||||
var/Ukey = ui.ui_key
|
||||
var/list/uis = open_uis[src_object_key][Ukey] // Remove it from the list of open UIs.
|
||||
uis.Remove(ui)
|
||||
if(!uis.len)
|
||||
var/list/uiobj = open_uis[src_object_key]
|
||||
uiobj.Remove(Ukey)
|
||||
if(!uiobj.len)
|
||||
open_uis.Remove(src_object_key)
|
||||
|
||||
return TRUE // Let the caller know we did it.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle client logout, by closing all their UIs.
|
||||
*
|
||||
* required user mob The mob which logged out.
|
||||
*
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/on_logout(mob/user)
|
||||
return close_user_uis(user)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle clients switching mobs, by transferring their UIs.
|
||||
*
|
||||
* required user source The client's original mob.
|
||||
* required user target The client's new mob.
|
||||
*
|
||||
* return bool If the UIs were transferred.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/on_transfer(mob/source, mob/target)
|
||||
if(!source || isnull(source.open_tguis) || !istype(source.open_tguis, /list) || open_uis.len == 0)
|
||||
return FALSE // The old mob had no open UIs.
|
||||
|
||||
if(isnull(target.open_tguis) || !istype(target.open_tguis, /list))
|
||||
target.open_tguis = list() // Create a list for the new mob if needed.
|
||||
|
||||
for(var/datum/tgui/ui in source.open_tguis)
|
||||
ui.user = target // Inform the UIs of their new owner.
|
||||
target.open_tguis.Add(ui) // Transfer all the UIs.
|
||||
|
||||
source.open_tguis.Cut() // Clear the old list.
|
||||
return TRUE // Let the caller know we did it.
|
||||
@@ -180,7 +180,14 @@ SUBSYSTEM_DEF(ticker)
|
||||
current_state = GAME_STATE_PLAYING
|
||||
Master.SetRunLevel(RUNLEVEL_GAME)
|
||||
|
||||
callHook("roundstart")
|
||||
// Generate the list of playable AI cores in the world
|
||||
for(var/obj/effect/landmark/start/S in GLOB.landmarks_list)
|
||||
if(S.name != "AI")
|
||||
continue
|
||||
if(locate(/mob/living) in S.loc)
|
||||
continue
|
||||
GLOB.empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(get_turf(S))
|
||||
|
||||
|
||||
//here to initialize the random events nicely at round start
|
||||
setup_economy()
|
||||
@@ -280,7 +287,21 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(N.client)
|
||||
N.new_player_panel_proc()
|
||||
|
||||
return 1
|
||||
// Now that every other piece of the round has initialized, lets setup player job scaling
|
||||
var/playercount = length(GLOB.clients)
|
||||
var/highpop_trigger = 80
|
||||
|
||||
if(playercount >= highpop_trigger)
|
||||
log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - loading highpop job config")
|
||||
SSjobs.LoadJobs("config/jobs_highpop.txt")
|
||||
else
|
||||
log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - keeping standard job config")
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
RunUnitTests()
|
||||
#endif
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/station_explosion_cinematic(station_missed = 0, override = null)
|
||||
if(cinematic)
|
||||
@@ -405,7 +426,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
EquipCustomItems(player)
|
||||
if(captainless)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!istype(M,/mob/new_player))
|
||||
if(!isnewplayer(M))
|
||||
to_chat(M, "Captainship not forced on anyone.")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets)
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets/New()
|
||||
NEW_SS_GLOBAL(SSmentor_tickets);
|
||||
PreInit();
|
||||
NEW_SS_GLOBAL(SSmentor_tickets)
|
||||
PreInit()
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets
|
||||
name = "Mentor Tickets"
|
||||
|
||||
@@ -24,7 +24,6 @@ SUBSYSTEM_DEF(tickets)
|
||||
var/rights_needed = R_ADMIN | R_MOD
|
||||
var/other_ticket_name = "Mentor"
|
||||
var/list/close_messages
|
||||
|
||||
var/list/allTickets = list() //make it here because someone might ahelp before the system has initialized
|
||||
|
||||
var/ticketCounter = 1
|
||||
@@ -151,7 +150,7 @@ SUBSYSTEM_DEF(tickets)
|
||||
"Already Resolved" = "The problem has been resolved already.",
|
||||
"Mentorhelp" = "Please redirect your question to Mentorhelp, as they are better experienced with these types of questions.",
|
||||
"Happens Again" = "Thanks, let us know if it continues to happen.",
|
||||
"Clear Cache" = "To fix a blank screen, please leave the game and clear your Byond Cache. To clear your Byond Cache, there is a Settings icon in the top right of the launcher. After you click that, go into the Games tab and hit the Clear Cache button. If the issue persists a few minutes after rejoining and doing this, please adminhelp again and state you cleared your cache." ,
|
||||
"Clear Cache" = "To fix a blank screen, go to the 'Special Verbs' tab and press 'Reload UI Resources'. If that fails, clear your BYOND cache (instructions provided with 'Reload UI Resources'). If that still fails, please adminhelp again, stating you have already done the following." ,
|
||||
"IC Issue" = "This is an In Character (IC) issue and will not be handled by admins. You could speak to Security, Internal Affairs, a Departmental Head, Nanotrasen Representetive, or any other relevant authority currently on station.",
|
||||
"Reject" = "Reject",
|
||||
"Man Up" = "Man Up",
|
||||
|
||||
@@ -160,7 +160,7 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
if(timer.timeToRun < head_offset)
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("[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]")
|
||||
stack_trace("[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()
|
||||
@@ -172,7 +172,7 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
if(timer.timeToRun < head_offset + TICKS2DS(practical_offset-1))
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("[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]")
|
||||
stack_trace("[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
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
SUBSYSTEM_DEF(title)
|
||||
name = "Title Screen"
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_TITLE
|
||||
|
||||
/datum/controller/subsystem/title/Initialize()
|
||||
var/list/provisional_title_screens = flist("config/title_screens/images/")
|
||||
var/list/title_screens = list()
|
||||
var/use_rare_screens = prob(1)
|
||||
|
||||
for(var/S in provisional_title_screens)
|
||||
var/list/L = splittext(S,"+")
|
||||
if(L.len == 1 && L[1] != "blank.png")
|
||||
title_screens += S
|
||||
|
||||
else if(L.len > 1)
|
||||
if(use_rare_screens && lowertext(L[1]) == "rare")
|
||||
title_screens += S
|
||||
else if(GLOB.using_map && (lowertext(L[1]) == lowertext(GLOB.using_map.name)))
|
||||
title_screens += S
|
||||
|
||||
if(!isemptylist(title_screens))
|
||||
if(length(title_screens) > 1)
|
||||
for(var/S in title_screens)
|
||||
var/list/L = splittext(S,".")
|
||||
if(L.len != 2 || L[1] != "default")
|
||||
continue
|
||||
title_screens -= S
|
||||
break
|
||||
|
||||
var/file_path = "config/title_screens/images/[pick(title_screens)]"
|
||||
|
||||
var/icon/icon = new(fcopy_rsc(file_path))
|
||||
|
||||
for(var/turf/unsimulated/wall/splashscreen/splash in world)
|
||||
splash.icon = icon
|
||||
|
||||
return ..()
|
||||
@@ -57,7 +57,6 @@ SUBSYSTEM_DEF(weather)
|
||||
break
|
||||
if(!ispath(weather_datum_type, /datum/weather))
|
||||
CRASH("run_weather called with invalid weather_datum_type: [weather_datum_type || "null"]")
|
||||
return
|
||||
|
||||
if(isnull(z_levels))
|
||||
z_levels = levels_by_trait(initial(weather_datum_type.target_trait))
|
||||
@@ -65,7 +64,6 @@ SUBSYSTEM_DEF(weather)
|
||||
z_levels = list(z_levels)
|
||||
else if(!islist(z_levels))
|
||||
CRASH("run_weather called with invalid z_levels: [z_levels || "null"]")
|
||||
return
|
||||
|
||||
var/datum/weather/W = new weather_datum_type(z_levels)
|
||||
W.telegraph()
|
||||
|
||||
Reference in New Issue
Block a user