Merge remote-tracking branch 'citadel/master' into typing_indicators
This commit is contained in:
@@ -103,7 +103,7 @@
|
||||
return FALSE
|
||||
var/temp = text2num(trim(str_val))
|
||||
if(!isnull(temp))
|
||||
config_entry_value = CLAMP(integer ? round(temp) : temp, min_val, max_val)
|
||||
config_entry_value = clamp(integer ? round(temp) : temp, min_val, max_val)
|
||||
if(config_entry_value != temp && !(datum_flags & DF_VAR_EDITED))
|
||||
log_config("Changing [name] from [temp] to [config_entry_value]!")
|
||||
return TRUE
|
||||
|
||||
@@ -368,12 +368,16 @@
|
||||
var/list/datum/dynamic_storyteller/runnable_storytellers = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight)
|
||||
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
|
||||
var/list/min_player_counts = Get(/datum/config_entry/keyed_list/storyteller_min_players)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/config_tag = initial(S.config_tag)
|
||||
var/probability = (config_tag in probabilities) ? probabilities[config_tag] : initial(S.weight)
|
||||
var/min_players = (config_tag in min_player_counts) ? min_player_counts[config_tag] : initial(S.min_players)
|
||||
if(probability <= 0)
|
||||
continue
|
||||
if(length(GLOB.player_list) < min_players)
|
||||
continue
|
||||
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
|
||||
var/name = initial(S.name)
|
||||
var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3)
|
||||
|
||||
@@ -92,3 +92,7 @@
|
||||
/datum/config_entry/keyed_list/storyteller_weight
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_NUM
|
||||
|
||||
/datum/config_entry/keyed_list/storyteller_min_players
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_NUM
|
||||
|
||||
@@ -396,6 +396,14 @@
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_NUM
|
||||
|
||||
/datum/config_entry/keyed_list/job_threat
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_NUM
|
||||
|
||||
/datum/config_entry/keyed_list/antag_threat
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_NUM
|
||||
|
||||
/datum/config_entry/number/monkeycap
|
||||
config_entry_value = 64
|
||||
min_val = 0
|
||||
@@ -436,3 +444,39 @@
|
||||
/datum/config_entry/number/penis_max_inches_prefs
|
||||
config_entry_value = 20
|
||||
min_val = 0
|
||||
|
||||
/datum/config_entry/keyed_list/safe_visibility_toggles
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_FLAG
|
||||
config_entry_value = list(GEN_VISIBLE_NO_CLOTHES, GEN_VISIBLE_NO_UNDIES, GEN_VISIBLE_NEVER) //refer to cit_helpers for all toggles.
|
||||
|
||||
//Body size configs, the feature will be disabled if both min and max have the same value.
|
||||
/datum/config_entry/number/body_size_min
|
||||
config_entry_value = RESIZE_DEFAULT_SIZE
|
||||
min_val = 0.1 //to avoid issues with zeros and negative values.
|
||||
max_val = RESIZE_DEFAULT_SIZE
|
||||
integer = FALSE
|
||||
|
||||
/datum/config_entry/number/body_size_max
|
||||
config_entry_value = RESIZE_DEFAULT_SIZE
|
||||
min_val = RESIZE_DEFAULT_SIZE
|
||||
integer = FALSE
|
||||
|
||||
//Pun-Pun movement slowdown given to characters with a body size smaller than this value,
|
||||
//to compensate for their smaller hitbox.
|
||||
//To disable, just make sure the value is lower than 'body_size_min'
|
||||
/datum/config_entry/number/threshold_body_size_slowdown
|
||||
config_entry_value = RESIZE_DEFAULT_SIZE * 0.85
|
||||
min_val = 0
|
||||
max_val = RESIZE_DEFAULT_SIZE
|
||||
integer = FALSE
|
||||
|
||||
//multiplicative slowdown multiplier. See 'dna.update_body_size' for the operation.
|
||||
//doesn't apply to floating or crawling mobs
|
||||
/datum/config_entry/number/body_size_slowdown_multiplier
|
||||
config_entry_value = 0.25
|
||||
min_val = 0.1 //To encourage folks to disable the slowdown through the above config instead.
|
||||
integer = FALSE
|
||||
|
||||
//Allows players to set a hexadecimal color of their choice as skin tone, on top of the standard ones.
|
||||
/datum/config_entry/flag/allow_custom_skintones
|
||||
|
||||
@@ -27,13 +27,11 @@
|
||||
var/hook_path = text2path("/hook/[hook]")
|
||||
if(!hook_path)
|
||||
CRASH("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)))
|
||||
CRASH("Hook '[P]' failed or runtimed.")
|
||||
status = 0
|
||||
|
||||
return status
|
||||
|
||||
@@ -38,11 +38,17 @@ PROCESSING_SUBSYSTEM_DEF(dcs)
|
||||
if(istext(key))
|
||||
value = arguments[key]
|
||||
if(!(istext(key) || isnum(key)))
|
||||
key = REF(key)
|
||||
if(islist(key)) // CITADEL EDIT
|
||||
key = deep_list2params(key)
|
||||
else
|
||||
key = REF(key)
|
||||
key = "[key]" // Key is stringified so numbers dont break things
|
||||
if(!isnull(value))
|
||||
if(!(istext(value) || isnum(value)))
|
||||
value = REF(value)
|
||||
if(islist(value)) // CITADEL EDIT
|
||||
value = deep_list2params(value)
|
||||
else
|
||||
value = REF(value)
|
||||
named_arguments["[key]"] = value
|
||||
else
|
||||
fullid += "[key]"
|
||||
|
||||
@@ -21,9 +21,6 @@ SUBSYSTEM_DEF(fail2topic)
|
||||
|
||||
DropFirewallRule() // Clear the old bans if any still remain
|
||||
|
||||
if (world.system_type == UNIX && enabled)
|
||||
enabled = FALSE
|
||||
subsystem_log("DISABLED - UNIX systems are not supported.")
|
||||
if(!enabled)
|
||||
flags |= SS_NO_FIRE
|
||||
can_fire = FALSE
|
||||
@@ -90,7 +87,10 @@ SUBSYSTEM_DEF(fail2topic)
|
||||
fail_counts -= ip
|
||||
rate_limiting -= ip
|
||||
|
||||
. = shell("netsh advfirewall firewall add rule name=\"[rule_name]\" dir=in interface=any action=block remoteip=[ip]")
|
||||
if (world.system_type == UNIX)
|
||||
. = shell("iptables -A [rule_name] -s [ip] -j DROP")
|
||||
else
|
||||
. = shell("netsh advfirewall firewall add rule name=\"[rule_name]\" dir=in interface=any action=block remoteip=[ip]")
|
||||
|
||||
if (.)
|
||||
subsystem_log("Failed to ban [ip]. Exit code: [.].")
|
||||
@@ -105,7 +105,10 @@ SUBSYSTEM_DEF(fail2topic)
|
||||
|
||||
active_bans = list()
|
||||
|
||||
. = shell("netsh advfirewall firewall delete rule name=\"[rule_name]\"")
|
||||
if (world.system_type == UNIX)
|
||||
. = shell("iptables -F [rule_name]") //Let's just assume that folks running linux are smart enough to have a dedicated chain configured for this.
|
||||
else
|
||||
. = shell("netsh advfirewall firewall delete rule name=\"[rule_name]\"")
|
||||
|
||||
if (.)
|
||||
subsystem_log("Failed to drop firewall rule. Exit code: [.].")
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
SUBSYSTEM_DEF(holodeck)
|
||||
name = "Holodeck"
|
||||
init_order = INIT_ORDER_HOLODECK
|
||||
flags = SS_NO_FIRE
|
||||
var/list/program_cache = list() //list of safe holodeck programs.
|
||||
var/list/emag_program_cache = list() //like above, but dangerous.
|
||||
var/list/offline_programs = list() //default when offline.
|
||||
var/list/target_holodeck_area = list()
|
||||
var/list/rejected_areas = list()
|
||||
|
||||
/datum/controller/subsystem/holodeck/Initialize()
|
||||
. = ..()
|
||||
//generates the list of available holodeck programs.
|
||||
for(var/path in subtypesof(/datum/holodeck_cache))
|
||||
new path
|
||||
for(var/path in typesof(/obj/machinery/computer/holodeck)) //The istances will be handled by SSatoms.
|
||||
var/obj/machinery/computer/holodeck/H = path
|
||||
offline_programs[path] = pop(get_areas(initial(H.offline_program)), FALSE)
|
||||
target_holodeck_area[path] = pop(get_areas(initial(H.holodeck_type)), FALSE)
|
||||
|
||||
|
||||
/*
|
||||
* The sole scope of this datum is to generate lists of holodeck programs caches per holodeck computer type.
|
||||
*/
|
||||
|
||||
/datum/holodeck_cache
|
||||
var/area/holodeck/master_type //the /area/holodeck typepath we'll be using for typesof loop.
|
||||
var/skip_types //Areas that won't be added to the global list category.
|
||||
var/list/compatible_holodeck_comps //list of typepaths of holodeck computers that can access this category.
|
||||
|
||||
/datum/holodeck_cache/New()
|
||||
if(!master_type || !compatible_holodeck_comps)
|
||||
return
|
||||
var/list/to_add = typesof(master_type) - skip_types
|
||||
var/list/programs
|
||||
var/list/emag_programs
|
||||
for(var/typekey in to_add)
|
||||
var/area/holodeck/A = GLOB.areas_by_type[typekey]
|
||||
if(!A || !A.contents.len)
|
||||
LAZYOR(SSholodeck.rejected_areas[typekey], compatible_holodeck_comps)
|
||||
continue
|
||||
var/list/info_this = list("name" = A.name, "type" = A.type)
|
||||
if(A.restricted)
|
||||
LAZYADD(emag_programs, list(info_this))
|
||||
else
|
||||
LAZYADD(programs, list(info_this))
|
||||
for(var/comp in compatible_holodeck_comps)
|
||||
if(programs)
|
||||
LAZYADD(SSholodeck.program_cache[comp], programs)
|
||||
if(emag_programs)
|
||||
LAZYADD(SSholodeck.emag_program_cache[comp], emag_programs)
|
||||
|
||||
/datum/holodeck_cache/standard
|
||||
master_type = /area/holodeck/rec_center
|
||||
skip_types = /area/holodeck/rec_center
|
||||
compatible_holodeck_comps = list(/obj/machinery/computer/holodeck)
|
||||
@@ -66,6 +66,7 @@ SUBSYSTEM_DEF(job)
|
||||
|
||||
|
||||
/datum/controller/subsystem/job/proc/GetJob(rank)
|
||||
RETURN_TYPE(/datum/job)
|
||||
if(!occupations.len)
|
||||
SetupOccupations()
|
||||
return name_occupations[rank]
|
||||
@@ -427,6 +428,8 @@ SUBSYSTEM_DEF(job)
|
||||
if(!joined_late)
|
||||
var/obj/S = null
|
||||
for(var/obj/effect/landmark/start/sloc in GLOB.start_landmarks_list)
|
||||
if(!sloc.job_spawnpoint)
|
||||
continue
|
||||
if(sloc.name != rank)
|
||||
S = sloc //so we can revert to spawning them on top of eachother if something goes wrong
|
||||
continue
|
||||
@@ -738,4 +741,4 @@ SUBSYSTEM_DEF(job)
|
||||
. |= player.mind
|
||||
|
||||
/datum/controller/subsystem/job/proc/JobDebug(message)
|
||||
log_job_debug(message)
|
||||
log_job_debug(message)
|
||||
|
||||
@@ -14,6 +14,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
var/list/saved_modes = list(1,2,3)
|
||||
var/list/saved_dynamic_rules = list(list(),list(),list())
|
||||
var/list/saved_storytellers = list("foo","bar","baz")
|
||||
var/list/average_dynamic_threat = 50
|
||||
var/list/saved_maps
|
||||
var/list/saved_trophies = list()
|
||||
var/list/spawned_objects = list()
|
||||
@@ -191,6 +192,8 @@ SUBSYSTEM_DEF(persistence)
|
||||
if(!json)
|
||||
return
|
||||
saved_storytellers = json["data"]
|
||||
if(saved_storytellers.len > 3)
|
||||
average_dynamic_threat = saved_storytellers[4]
|
||||
saved_storytellers.len = 3
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
|
||||
@@ -434,9 +437,10 @@ SUBSYSTEM_DEF(persistence)
|
||||
saved_storytellers[3] = saved_storytellers[2]
|
||||
saved_storytellers[2] = saved_storytellers[1]
|
||||
saved_storytellers[1] = mode.storyteller.name
|
||||
average_dynamic_threat = (mode.threat_average + average_dynamic_threat) / 2
|
||||
var/json_file = file("data/RecentStorytellers.json")
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_storytellers
|
||||
file_data["data"] = saved_storytellers + average_dynamic_threat
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(chemistry)
|
||||
wait = 5
|
||||
flags = SS_KEEP_TIMING
|
||||
|
||||
|
||||
name = "Chemistry"
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(instruments)
|
||||
name = "Instruments"
|
||||
wait = 0.5
|
||||
init_order = INIT_ORDER_INSTRUMENTS
|
||||
flags = SS_KEEP_TIMING
|
||||
priority = FIRE_PRIORITY_INSTRUMENTS
|
||||
var/static/list/datum/instrument/instrument_data = list() //id = datum
|
||||
var/static/list/datum/song/songs = list()
|
||||
var/static/musician_maxlines = 600
|
||||
var/static/musician_maxlinechars = 300
|
||||
var/static/musician_hearcheck_mindelay = 5
|
||||
var/static/max_instrument_channels = MAX_INSTRUMENT_CHANNELS
|
||||
var/static/current_instrument_channels = 0
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/Initialize()
|
||||
initialize_instrument_data()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/proc/on_song_new(datum/song/S)
|
||||
songs += S
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/proc/on_song_del(datum/song/S)
|
||||
songs -= S
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/proc/initialize_instrument_data()
|
||||
for(var/path in subtypesof(/datum/instrument))
|
||||
var/datum/instrument/I = path
|
||||
if(initial(I.abstract_type) == path)
|
||||
continue
|
||||
I = new path
|
||||
I.Initialize()
|
||||
instrument_data[I.id || "[I.type]"] = I
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/proc/get_instrument(id_or_path)
|
||||
return instrument_data["[id_or_path]"]
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/proc/reserve_instrument_channel(datum/instrument/I)
|
||||
if(current_instrument_channels > max_instrument_channels)
|
||||
return
|
||||
. = SSsounds.reserve_sound_channel(I)
|
||||
if(!isnull(.))
|
||||
current_instrument_channels++
|
||||
@@ -37,11 +37,11 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
|
||||
if(job?.blacklisted_quirks)
|
||||
cut = filter_quirks(my_quirks, job.blacklisted_quirks)
|
||||
for(var/V in my_quirks)
|
||||
var/datum/quirk/Q = quirks[V]
|
||||
if(Q)
|
||||
if(V in quirks)
|
||||
var/datum/quirk/Q = quirks[V]
|
||||
user.add_quirk(Q, spawn_effects)
|
||||
else
|
||||
stack_trace("Invalid quirk \"[V]\" in client [cli.ckey] preferences")
|
||||
log_admin("Invalid quirk \"[V]\" in client [cli.ckey] preferences")
|
||||
cli.prefs.all_quirks -= V
|
||||
badquirk = TRUE
|
||||
if(badquirk)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(status_effects)
|
||||
wait = 1
|
||||
flags = SS_TICKER
|
||||
name = "Status Effects"
|
||||
|
||||
@@ -47,7 +47,6 @@ PROCESSING_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 = SSmapping.levels_by_trait(initial(weather_datum_type.target_trait))
|
||||
@@ -55,7 +54,6 @@ PROCESSING_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()
|
||||
|
||||
@@ -5,7 +5,7 @@ SUBSYSTEM_DEF(profiler)
|
||||
init_order = INIT_ORDER_PROFILER
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
wait = 3000
|
||||
flags = SS_NO_TICK_CHECK
|
||||
flags = SS_NO_TICK_CHECK
|
||||
var/fetch_cost = 0
|
||||
var/write_cost = 0
|
||||
|
||||
@@ -31,23 +31,12 @@ SUBSYSTEM_DEF(profiler)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/StartProfiling()
|
||||
#if DM_BUILD < 1506 || DM_VERSION < 513
|
||||
stack_trace("Auto profiling unsupported on this byond version")
|
||||
CONFIG_SET(flag/auto_profile, FALSE)
|
||||
#else
|
||||
world.Profile(PROFILE_START)
|
||||
#endif
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/StopProfiling()
|
||||
#if DM_BUILD >= 1506 && DM_VERSION >= 513
|
||||
world.Profile(PROFILE_STOP)
|
||||
#endif
|
||||
|
||||
/datum/controller/subsystem/profiler/proc/DumpFile()
|
||||
#if DM_BUILD < 1506 || DM_VERSION < 513
|
||||
stack_trace("Auto profiling unsupported on this byond version")
|
||||
CONFIG_SET(flag/auto_profile, FALSE)
|
||||
#else
|
||||
var/timer = TICK_USAGE_REAL
|
||||
var/current_profile_data = world.Profile(PROFILE_REFRESH,format="json")
|
||||
fetch_cost = MC_AVERAGE(fetch_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
@@ -60,4 +49,3 @@ SUBSYSTEM_DEF(profiler)
|
||||
timer = TICK_USAGE_REAL
|
||||
WRITE_FILE(json_file, current_profile_data)
|
||||
write_cost = MC_AVERAGE(write_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#define DATUMLESS "NO_DATUM"
|
||||
|
||||
SUBSYSTEM_DEF(sounds)
|
||||
name = "Sounds"
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_SOUNDS
|
||||
var/static/using_channels_max = CHANNEL_HIGHEST_AVAILABLE //BYOND max channels
|
||||
|
||||
// Hey uh these two needs to be initialized fast because the whole "things get deleted before init" thing.
|
||||
/// Assoc list, "[channel]" = either the datum using it or TRUE for an unsafe-reserved (datumless reservation) channel
|
||||
var/list/using_channels = list()
|
||||
/// Assoc list datum = list(channel1, channel2, ...) for what channels something reserved.
|
||||
var/list/using_channels_by_datum = list()
|
||||
/// List of all available channels with associations set to TRUE for fast lookups/allocation.
|
||||
var/list/available_channels
|
||||
|
||||
/datum/controller/subsystem/sounds/Initialize()
|
||||
setup_available_channels()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/sounds/proc/setup_available_channels()
|
||||
available_channels = list()
|
||||
for(var/i in 1 to using_channels_max)
|
||||
available_channels[num2text(i)] = TRUE
|
||||
|
||||
/// Removes a channel from using list.
|
||||
/datum/controller/subsystem/sounds/proc/free_sound_channel(channel)
|
||||
channel = num2text(channel)
|
||||
var/using = using_channels[channel]
|
||||
using_channels -= channel
|
||||
if(using)
|
||||
using_channels_by_datum[using] -= channel
|
||||
if(!length(using_channels_by_datum[using]))
|
||||
using_channels_by_datum -= using
|
||||
available_channels[channel] = TRUE
|
||||
|
||||
/// Frees all the channels a datum is using.
|
||||
/datum/controller/subsystem/sounds/proc/free_datum_channels(datum/D)
|
||||
var/list/L = using_channels_by_datum[D]
|
||||
if(!L)
|
||||
return
|
||||
for(var/channel in L)
|
||||
using_channels -= channel
|
||||
available_channels[channel] = TRUE
|
||||
using_channels_by_datum -= D
|
||||
|
||||
/// Frees all datumless channels
|
||||
/datum/controller/subsystem/sounds/proc/free_datumless_channels()
|
||||
free_datum_channels(DATUMLESS)
|
||||
|
||||
/// NO AUTOMATIC CLEANUP - If you use this, you better manually free it later! Returns an integer for channel.
|
||||
/datum/controller/subsystem/sounds/proc/reserve_sound_channel_datumless()
|
||||
var/channel = random_available_channel_text()
|
||||
if(!channel) //oh no..
|
||||
return FALSE
|
||||
available_channels -= channel
|
||||
using_channels[channel] = DATUMLESS
|
||||
LAZYINITLIST(using_channels_by_datum[DATUMLESS])
|
||||
using_channels_by_datum[DATUMLESS] += channel
|
||||
return text2num(channel)
|
||||
|
||||
/// Reserves a channel for a datum. Automatic cleanup only when the datum is deleted. Returns an integer for channel.
|
||||
/datum/controller/subsystem/sounds/proc/reserve_sound_channel(datum/D)
|
||||
if(!D) //i don't like typechecks but someone will fuck it up
|
||||
CRASH("Attempted to reserve sound channel without datum using the managed proc.")
|
||||
var/channel = random_available_channel_text()
|
||||
if(!channel)
|
||||
return FALSE
|
||||
available_channels -= channel
|
||||
using_channels[channel] = D
|
||||
LAZYINITLIST(using_channels_by_datum[D])
|
||||
using_channels_by_datum[D] += channel
|
||||
return text2num(channel)
|
||||
|
||||
/// Random available channel, returns text.
|
||||
/datum/controller/subsystem/sounds/proc/random_available_channel_text()
|
||||
return pick(available_channels)
|
||||
|
||||
/// Random available channel, returns number
|
||||
/datum/controller/subsystem/sounds/proc/random_available_channel()
|
||||
return text2num(pick(available_channels))
|
||||
|
||||
/// If a channel is available
|
||||
/datum/controller/subsystem/sounds/proc/is_channel_available(channel)
|
||||
return available_channels[num2text(channel)]
|
||||
|
||||
/// How many channels we have left.
|
||||
/datum/controller/subsystem/sounds/proc/available_channels_left()
|
||||
return length(available_channels)
|
||||
|
||||
#undef DATUMLESS
|
||||
@@ -479,15 +479,15 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/vote_type = CONFIG_GET(string/map_vote_type)
|
||||
switch(vote_type)
|
||||
if("PLURALITY")
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE)
|
||||
SSvote.initiate_vote("map","server", display = SHOW_RESULTS)
|
||||
if("APPROVAL")
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = APPROVAL_VOTING)
|
||||
SSvote.initiate_vote("map","server", display = SHOW_RESULTS, votesystem = APPROVAL_VOTING)
|
||||
if("IRV")
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = INSTANT_RUNOFF_VOTING)
|
||||
SSvote.initiate_vote("map","server", display = SHOW_RESULTS, votesystem = INSTANT_RUNOFF_VOTING)
|
||||
if("SCORE")
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING)
|
||||
SSvote.initiate_vote("map","server", display = SHOW_RESULTS, votesystem = MAJORITY_JUDGEMENT_VOTING)
|
||||
else
|
||||
SSvote.initiate_vote("map","server",hideresults=TRUE)
|
||||
SSvote.initiate_vote("map","server", display = SHOW_RESULTS)
|
||||
// fallback
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
|
||||
@@ -503,9 +503,9 @@ SUBSYSTEM_DEF(ticker)
|
||||
SSticker.modevoted = TRUE
|
||||
var/dynamic = CONFIG_GET(flag/dynamic_voting)
|
||||
if(dynamic)
|
||||
SSvote.initiate_vote("dynamic","server",hideresults=TRUE,votesystem=SCORE_VOTING,forced=TRUE,vote_time = 20 MINUTES)
|
||||
SSvote.initiate_vote("dynamic", "server", display = NONE, votesystem = SCORE_VOTING, forced = TRUE,vote_time = 20 MINUTES)
|
||||
else
|
||||
SSvote.initiate_vote("roundtype","server",hideresults=TRUE,votesystem=PLURALITY_VOTING,forced=TRUE, \
|
||||
SSvote.initiate_vote("roundtype", "server", display = NONE, votesystem = PLURALITY_VOTING, forced=TRUE, \
|
||||
vote_time = (CONFIG_GET(flag/modetier_voting) ? 1 MINUTES : 20 MINUTES))
|
||||
|
||||
/datum/controller/subsystem/ticker/Recover()
|
||||
|
||||
@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(time_track)
|
||||
var/time_dilation_text
|
||||
|
||||
/datum/controller/subsystem/time_track/fire()
|
||||
stat_time_text = "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]\n\nRound Time: [WORLDTIME2TEXT("hh:mm:ss")]\n\nStation Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]\n\n[time_dilation_text]"
|
||||
stat_time_text = "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]\n\nRound Time: [DisplayTimeText(world.time - SSticker.round_start_time, 1)] \n\nStation Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]\n\n[time_dilation_text]"
|
||||
|
||||
if(++last_measurement == measurement_delay)
|
||||
last_measurement = 0
|
||||
|
||||
@@ -172,7 +172,7 @@ SUBSYSTEM_DEF(traumas)
|
||||
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/mecha/combat/gygax/dark, /obj/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate,
|
||||
/obj/item/cartridge/virus/frame, /obj/item/chameleon, /obj/item/storage/box/syndie_kit/cutouts, /obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/card/emag, /obj/item/storage/toolbox/syndicate, /obj/item/storage/book/bible/syndicate, /obj/item/encryptionkey/binary, /obj/item/encryptionkey/syndicate, /obj/item/aiModule/syndicate,
|
||||
/obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited,
|
||||
/obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate,
|
||||
/obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/fingerless/pugilist/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate,
|
||||
/obj/machinery/computer/pod/old/syndicate, /obj/machinery/vending/medical/syndicate_access, /obj/item/mmi/syndie, /obj/item/target/syndicate, /obj/machinery/vending/cigarette/syndicate, /obj/item/robot_module/syndicate, /obj/item/clothing/mask/gas/syndicate, /obj/machinery/power/singularity_beacon/syndicate, /obj/item/clothing/head/syndicatefake,
|
||||
/obj/item/radio/headset/syndicate, /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate, /obj/item/pda/syndicate, /obj/item/clothing/suit/armor/vest/capcarapace/syndicate, /obj/item/gun/ballistic/automatic/flechette, /obj/item/ammo_box/magazine/flechette, /obj/item/clothing/suit/toggle/lawyer/black/syndie, /obj/item/melee/transforming/energy/sword/cx/traitor,
|
||||
/obj/structure/sign/poster/contraband/syndicate_pistol, /obj/structure/sign/poster/contraband/syndicate_recruitment, /obj/item/bedsheet/syndie, /obj/item/borg/upgrade/syndicate, /obj/item/tank/jetpack/oxygen/harness, /obj/item/firing_pin/implant/pindicate, /obj/item/reagent_containers/glass/bottle/traitor, /obj/item/storage/belt/military,
|
||||
|
||||
@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(vote)
|
||||
var/list/generated_actions = list()
|
||||
var/next_pop = 0
|
||||
|
||||
var/obfuscated = FALSE//CIT CHANGE - adds obfuscated/admin-only votes
|
||||
var/display_votes = SHOW_RESULTS|SHOW_VOTES|SHOW_WINNER|SHOW_ABSTENTION //CIT CHANGE - adds obfuscated/admin-only votes
|
||||
|
||||
var/list/stored_gamemode_votes = list() //Basically the last voted gamemode is stored here for end-of-round use.
|
||||
|
||||
@@ -59,7 +59,7 @@ SUBSYSTEM_DEF(vote)
|
||||
voted.Cut()
|
||||
voting.Cut()
|
||||
scores.Cut()
|
||||
obfuscated = FALSE //CIT CHANGE - obfuscated votes
|
||||
display_votes = initial(display_votes) //CIT CHANGE - obfuscated votes
|
||||
remove_action_buttons()
|
||||
|
||||
/datum/controller/subsystem/vote/proc/get_result()
|
||||
@@ -250,7 +250,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if(winners.len > 0)
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes = list()
|
||||
if(!obfuscated)
|
||||
if(display_votes & SHOW_RESULTS)
|
||||
if(vote_system == SCHULZE_VOTING)
|
||||
text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
|
||||
if(vote_system == MAJORITY_JUDGEMENT_VOTING)
|
||||
@@ -261,15 +261,15 @@ SUBSYSTEM_DEF(vote)
|
||||
votes = 0
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes[choices[i]] = votes
|
||||
text += "\n<b>[choices[i]]:</b> [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
|
||||
text += "\n<b>[choices[i]]:</b> [display_votes & SHOW_RESULTS ? votes : "???"]" //CIT CHANGE - adds obfuscated votes
|
||||
if(mode != "custom")
|
||||
if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes
|
||||
if(winners.len > 1 && display_votes & SHOW_WINNER) //CIT CHANGE - adds obfuscated votes
|
||||
text = "\n<b>Vote Tied Between:</b>"
|
||||
for(var/option in winners)
|
||||
text += "\n\t[option]"
|
||||
. = pick(winners)
|
||||
text += "\n<b>Vote Result: [obfuscated ? "???" : .]</b>" //CIT CHANGE - adds obfuscated votes
|
||||
else
|
||||
text += "\n<b>Vote Result: [display_votes & SHOW_WINNER ? . : "???"]</b>" //CIT CHANGE - adds obfuscated votes
|
||||
if(display_votes & SHOW_ABSTENTION)
|
||||
text += "\n<b>Did not vote:</b> [GLOB.clients.len-voted.len]"
|
||||
else if(vote_system == SCORE_VOTING)
|
||||
for(var/score_name in scores)
|
||||
@@ -278,7 +278,7 @@ SUBSYSTEM_DEF(vote)
|
||||
score = 0
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes[score_name] = score
|
||||
text = "\n<b>[score_name]:</b> [obfuscated ? "???" : score]"
|
||||
text = "\n<b>[score_name]:</b> [display_votes & SHOW_RESULTS ? score : "???"]"
|
||||
. = 1
|
||||
else
|
||||
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
|
||||
@@ -295,7 +295,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if(islist(myvote))
|
||||
for(var/j=1,j<=myvote.len,j++)
|
||||
SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]]))
|
||||
if(obfuscated) //CIT CHANGE - adds obfuscated votes. this messages admins with the vote's true results
|
||||
if(!(display_votes & SHOW_RESULTS)) //CIT CHANGE - adds obfuscated votes. this messages admins with the vote's true results
|
||||
var/admintext = "Obfuscated results"
|
||||
if(vote_system != SCORE_VOTING)
|
||||
if(vote_system == SCHULZE_VOTING)
|
||||
@@ -327,7 +327,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if(CONFIG_GET(flag/modetier_voting))
|
||||
reset()
|
||||
started_time = 0
|
||||
initiate_vote("mode tiers","server",hideresults=FALSE,votesystem=SCORE_VOTING,forced=TRUE, vote_time = 30 MINUTES)
|
||||
initiate_vote("mode tiers","server", votesystem=SCORE_VOTING, forced=TRUE, vote_time = 30 MINUTES)
|
||||
to_chat(world,"<b>The vote will end right as the round starts.</b>")
|
||||
return .
|
||||
if("restart")
|
||||
@@ -354,11 +354,15 @@ SUBSYSTEM_DEF(vote)
|
||||
return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.")
|
||||
GLOB.master_mode = "dynamic"
|
||||
var/list/runnable_storytellers = config.get_runnable_storytellers()
|
||||
var/datum/dynamic_storyteller/picked
|
||||
for(var/T in runnable_storytellers)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
if(stored_gamemode_votes[initial(S.name)] == 1 && CHECK_BITFIELD(initial(S.flags), FORCE_IF_WON))
|
||||
picked = S
|
||||
runnable_storytellers[S] *= round(stored_gamemode_votes[initial(S.name)]*100000,1)
|
||||
var/datum/dynamic_storyteller/S = pickweightAllowZero(runnable_storytellers)
|
||||
GLOB.dynamic_storyteller_type = S
|
||||
if(!picked)
|
||||
picked = pickweightAllowZero(runnable_storytellers)
|
||||
GLOB.dynamic_storyteller_type = picked
|
||||
if("map")
|
||||
var/datum/map_config/VM = config.maplist[.]
|
||||
message_admins("The map has been voted for and will change to: [VM.map_name]")
|
||||
@@ -432,7 +436,7 @@ SUBSYSTEM_DEF(vote)
|
||||
saved -= usr.ckey
|
||||
return 0
|
||||
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, hideresults, votesystem = PLURALITY_VOTING, forced = FALSE,vote_time = -1)//CIT CHANGE - adds hideresults argument to votes to allow for obfuscated votes
|
||||
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, display = display_votes, votesystem = PLURALITY_VOTING, forced = FALSE,vote_time = -1)//CIT CHANGE - adds display argument to votes to allow for obfuscated votes
|
||||
vote_system = votesystem
|
||||
if(!mode)
|
||||
if(started_time)
|
||||
@@ -452,7 +456,7 @@ SUBSYSTEM_DEF(vote)
|
||||
|
||||
SEND_SOUND(world, sound('sound/misc/notice2.ogg'))
|
||||
reset()
|
||||
obfuscated = hideresults //CIT CHANGE - adds obfuscated votes
|
||||
display_votes = display //CIT CHANGE - adds obfuscated votes
|
||||
switch(vote_type)
|
||||
if("restart")
|
||||
choices.Add("Restart Round","Continue Playing")
|
||||
@@ -503,6 +507,21 @@ SUBSYSTEM_DEF(vote)
|
||||
if(!option || mode || !usr.client)
|
||||
break
|
||||
choices.Add(option)
|
||||
var/keep_going = TRUE
|
||||
var/toggles = SHOW_RESULTS|SHOW_VOTES|SHOW_WINNER
|
||||
while(keep_going)
|
||||
var/list/choices = list()
|
||||
for(var/A in GLOB.display_vote_settings)
|
||||
var/toggletext
|
||||
var/bitflag = GLOB.display_vote_settings[A]
|
||||
toggletext = "[toggles & bitflag ? "Show" : "Hide"] [A]"
|
||||
choices[toggletext] = bitflag
|
||||
var/chosen = input(usr, "Toggle vote display settings. Cancel to finalize.", toggles) as null|anything in choices
|
||||
if(!chosen)
|
||||
keep_going = FALSE
|
||||
else
|
||||
toggles ^= choices[chosen]
|
||||
display_votes = toggles
|
||||
else
|
||||
return 0
|
||||
mode = vote_type
|
||||
@@ -573,7 +592,7 @@ SUBSYSTEM_DEF(vote)
|
||||
ivotedforthis = ((C.ckey in voted) && (i in voted[C.ckey]))
|
||||
if(!votes)
|
||||
votes = 0
|
||||
. += "<li>[ivotedforthis ? "<b>" : ""]<a href='?src=[REF(src)];vote=[i]'>[choices[i]]</a> ([obfuscated ? (admin ? "??? ([votes])" : "???") : votes] votes)[ivotedforthis ? "</b>" : ""]</li>" // CIT CHANGE - adds obfuscated votes
|
||||
. += "<li>[ivotedforthis ? "<b>" : ""]<a href='?src=[REF(src)];vote=[i]'>[choices[i]]</a> ([display_votes & SHOW_VOTES ? votes : (admin ? "??? ([votes])" : "???")] votes)[ivotedforthis ? "</b>" : ""]</li>" // CIT CHANGE - adds obfuscated votes
|
||||
if(choice_descs.len >= i)
|
||||
. += "<li>[choice_descs[i]]</li>"
|
||||
. += "</ul><hr>"
|
||||
@@ -744,7 +763,7 @@ SUBSYSTEM_DEF(vote)
|
||||
remove_from_client()
|
||||
Remove(owner)
|
||||
|
||||
/datum/action/vote/IsAvailable()
|
||||
/datum/action/vote/IsAvailable(silent = FALSE)
|
||||
return 1
|
||||
|
||||
/datum/action/vote/proc/remove_from_client()
|
||||
|
||||
Reference in New Issue
Block a user