mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 03:26:31 +01:00
Persistent Map Vote Tallies (#86788)
## About The Pull Request Changes map votes to be based on a persistent tally count. Tallies for maps are cached between rounds and are added to by map votes. When a map is chosen, and it wasn't the only valid one, the tallies for said chosen map will be reset. Refactors map vote handling and moves it from SSmapping to SSmap_vote. Rock the Vote has been removed as a result of this refactor. ## Why It's Good For The Game Makes it more likely that all maps will be played over the course of a server instead of always being truly random. Removes some clutter off of SSmapping. 🆑 refactor: Map Votes are now carried over between rounds. When a map vote is actually a contest, the winning map will have its votes reset. /🆑
This commit is contained in:
@@ -221,7 +221,7 @@ Always compile, always use that verb, and always make sure that it works for wha
|
||||
#define CLUSTER_CHECK_ALL 30 //!Don't let anything cluster, like, at all
|
||||
|
||||
/// Checks the job changes in the map config for the passed change key.
|
||||
#define CHECK_MAP_JOB_CHANGE(job, change) SSmapping.config.job_changes?[job]?[change]
|
||||
#define CHECK_MAP_JOB_CHANGE(job, change) SSmapping.current_map.job_changes?[job]?[change]
|
||||
|
||||
///Identifiers for away mission spawnpoints
|
||||
#define AWAYSTART_BEACH "AWAYSTART_BEACH"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///name of the file that has all the memory strings
|
||||
#define MEMORY_FILE "memories.json"
|
||||
///name of the file that has all the saved engravings
|
||||
#define ENGRAVING_SAVE_FILE "data/engravings/[SSmapping.config.map_name]_engravings.json"
|
||||
#define ENGRAVING_SAVE_FILE "data/engravings/[SSmapping.current_map.map_name]_engravings.json"
|
||||
///name of the file that has all the prisoner tattoos
|
||||
#define PRISONER_TATTOO_SAVE_FILE "data/engravings/prisoner_tattoos.json"
|
||||
///Current version of the engraving persistence json
|
||||
|
||||
@@ -738,3 +738,27 @@
|
||||
/datum/config_entry/number/upload_limit_admin
|
||||
default = 5242880
|
||||
min_val = 0
|
||||
|
||||
/// The minimum number of tallies a map vote entry can have.
|
||||
/datum/config_entry/number/map_vote_minimum_tallies
|
||||
default = 1
|
||||
min_val = 0
|
||||
max_val = 50
|
||||
|
||||
/// The flat amount all maps get by default
|
||||
/datum/config_entry/number/map_vote_flat_bonus
|
||||
default = 5
|
||||
min_val = 0
|
||||
max_val = INFINITY
|
||||
|
||||
/// The maximum number of tallies a map vote entry can have.
|
||||
/datum/config_entry/number/map_vote_maximum_tallies
|
||||
default = 200
|
||||
min_val = 0
|
||||
max_val = INFINITY
|
||||
|
||||
/// The number of tallies that are carried over between rounds.
|
||||
/datum/config_entry/number/map_vote_tally_carryover_percentage
|
||||
default = 100
|
||||
min_val = 0
|
||||
max_val = 100
|
||||
|
||||
@@ -357,7 +357,7 @@ Versioning
|
||||
"z_coord" = L.z,
|
||||
"last_words" = L.last_words,
|
||||
"suicide" = did_they_suicide,
|
||||
"map" = SSmapping.config.map_name,
|
||||
"map" = SSmapping.current_map.map_name,
|
||||
"internet_address" = world.internet_address || "0",
|
||||
"port" = "[world.port]",
|
||||
"round_id" = GLOB.round_id,
|
||||
|
||||
@@ -26,14 +26,14 @@ SUBSYSTEM_DEF(library)
|
||||
|
||||
/datum/controller/subsystem/library/proc/load_shelves()
|
||||
var/list/datum/callback/load_callbacks = list()
|
||||
|
||||
|
||||
for(var/obj/structure/bookcase/case_to_load as anything in shelves_to_load)
|
||||
if(!case_to_load)
|
||||
stack_trace("A null bookcase somehow ended up in SSlibrary's shelves_to_load list. Did something harddel?")
|
||||
continue
|
||||
load_callbacks += CALLBACK(case_to_load, TYPE_PROC_REF(/obj/structure/bookcase, load_shelf))
|
||||
shelves_to_load = null
|
||||
|
||||
|
||||
//Load all of the shelves asyncronously at the same time, blocking until the last one is finished.
|
||||
callback_select(load_callbacks, savereturns = FALSE)
|
||||
|
||||
@@ -59,6 +59,6 @@ SUBSYSTEM_DEF(library)
|
||||
|
||||
/datum/controller/subsystem/library/proc/prepare_library_areas()
|
||||
library_areas = typesof(/area/station/service/library) - /area/station/service/library/abandoned
|
||||
var/list/additional_areas = SSmapping.config.library_areas
|
||||
var/list/additional_areas = SSmapping.current_map.library_areas
|
||||
if(additional_areas)
|
||||
library_areas += additional_areas
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
#define MAP_VOTE_CACHE_LOCATION "data/map_vote_cache.json"
|
||||
|
||||
SUBSYSTEM_DEF(map_vote)
|
||||
name = "Map Vote"
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
/// Has an admin specifically set a map.
|
||||
var/admin_override = FALSE
|
||||
|
||||
/// Have we already done a vote.
|
||||
var/already_voted = FALSE
|
||||
|
||||
/// The map that has been chosen for next round.
|
||||
var/datum/map_config/next_map_config
|
||||
|
||||
/// Stores the current map vote cache, so that players can look at the current tally.
|
||||
var/list/map_vote_cache
|
||||
|
||||
/// Stores the previous map vote cache, used when a map vote is reverted.
|
||||
var/list/previous_cache
|
||||
|
||||
/// Stores a formatted html string of the tally counts
|
||||
var/tally_printout = span_red("Loading...")
|
||||
|
||||
/datum/controller/subsystem/map_vote/Initialize()
|
||||
if(rustg_file_exists(MAP_VOTE_CACHE_LOCATION))
|
||||
map_vote_cache = json_decode(file2text(MAP_VOTE_CACHE_LOCATION))
|
||||
var/carryover = CONFIG_GET(number/map_vote_tally_carryover_percentage)
|
||||
for(var/map_id in map_vote_cache)
|
||||
map_vote_cache[map_id] = round(map_vote_cache[map_id] * (carryover / 100))
|
||||
sanitize_cache()
|
||||
else
|
||||
map_vote_cache = list()
|
||||
update_tally_printout()
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/map_vote/proc/write_cache()
|
||||
rustg_file_write(json_encode(map_vote_cache), MAP_VOTE_CACHE_LOCATION)
|
||||
|
||||
/datum/controller/subsystem/map_vote/proc/sanitize_cache()
|
||||
var/max = CONFIG_GET(number/map_vote_maximum_tallies)
|
||||
for(var/map_id in map_vote_cache)
|
||||
if(!(map_id in config.maplist))
|
||||
map_vote_cache -= map_id
|
||||
var/count = map_vote_cache[map_id]
|
||||
if(count > max)
|
||||
map_vote_cache[map_id] = max
|
||||
|
||||
/datum/controller/subsystem/map_vote/proc/send_map_vote_notice(...)
|
||||
var/static/last_message_at
|
||||
if(last_message_at == world.time)
|
||||
message_admins("Call to send_map_vote_notice twice in one game tick. Yell at someone to condense messages.")
|
||||
last_message_at = world.time
|
||||
|
||||
var/list/messages = args.Copy()
|
||||
to_chat(world, span_purple(examine_block("Map Vote\n<hr>\n[messages.Join("\n")]")))
|
||||
|
||||
/datum/controller/subsystem/map_vote/proc/finalize_map_vote(datum/vote/map_vote/map_vote)
|
||||
if(already_voted)
|
||||
message_admins("Attempted to finalize a map vote after a map vote has already been finalized.")
|
||||
return
|
||||
already_voted = TRUE
|
||||
|
||||
var/flat = CONFIG_GET(number/map_vote_flat_bonus)
|
||||
previous_cache = map_vote_cache.Copy()
|
||||
for(var/map_id in map_vote.choices)
|
||||
var/datum/map_config/map = config.maplist[map_id]
|
||||
map_vote_cache[map_id] += (map_vote.choices[map_id] * map.voteweight) + flat
|
||||
sanitize_cache()
|
||||
write_cache()
|
||||
update_tally_printout()
|
||||
|
||||
if(admin_override)
|
||||
send_map_vote_notice("Admin Override is in effect. Map will not be changed.", "Tallies are recorded and saved.")
|
||||
return
|
||||
|
||||
var/list/valid_maps = filter_cache_to_valid_maps()
|
||||
if(!length(valid_maps))
|
||||
send_map_vote_notice("No valid maps.")
|
||||
return
|
||||
|
||||
var/winner = pick_weight(filter_cache_to_valid_maps())
|
||||
set_next_map(config.maplist[winner])
|
||||
send_map_vote_notice("Map Selected - [span_bold(next_map_config.map_name)]")
|
||||
|
||||
// do not reset tallies if only one map is even possible
|
||||
if(length(valid_maps) > 1)
|
||||
map_vote_cache[winner] = CONFIG_GET(number/map_vote_minimum_tallies)
|
||||
write_cache()
|
||||
update_tally_printout()
|
||||
|
||||
/// Returns a list of all map options that are invalid for the current population.
|
||||
/datum/controller/subsystem/map_vote/proc/get_valid_map_vote_choices()
|
||||
var/list/valid_maps = list()
|
||||
|
||||
// Fill in our default choices with all of the maps in our map config, if they are votable and not blocked.
|
||||
var/list/maps = shuffle(global.config.maplist)
|
||||
for(var/map in maps)
|
||||
var/datum/map_config/possible_config = config.maplist[map]
|
||||
if(!possible_config.votable || (possible_config.map_name in SSpersistence.blocked_maps))
|
||||
continue
|
||||
valid_maps += possible_config.map_name
|
||||
|
||||
var/filter_threshold = 0
|
||||
if(SSticker.HasRoundStarted())
|
||||
filter_threshold = get_active_player_count(alive_check = FALSE, afk_check = TRUE, human_check = FALSE)
|
||||
else
|
||||
filter_threshold = length(GLOB.clients)
|
||||
|
||||
for(var/map in valid_maps)
|
||||
var/datum/map_config/possible_config = config.maplist[map]
|
||||
if(possible_config.config_min_users > 0 && filter_threshold < possible_config.config_min_users)
|
||||
valid_maps -= map
|
||||
|
||||
else if(possible_config.config_max_users > 0 && filter_threshold > possible_config.config_max_users)
|
||||
valid_maps -= map
|
||||
|
||||
return valid_maps
|
||||
|
||||
/datum/controller/subsystem/map_vote/proc/filter_cache_to_valid_maps()
|
||||
var/connected_players = length(GLOB.player_list)
|
||||
var/list/valid_maps = list()
|
||||
for(var/map_id in map_vote_cache)
|
||||
var/datum/map_config/map = config.maplist[map_id]
|
||||
if(!map.votable)
|
||||
continue
|
||||
if(map.config_min_users > 0 && (connected_players < map.config_min_users))
|
||||
continue
|
||||
if(map.config_max_users > 0 && (connected_players > map.config_max_users))
|
||||
continue
|
||||
valid_maps[map_id] = map_vote_cache[map_id]
|
||||
return valid_maps
|
||||
|
||||
/datum/controller/subsystem/map_vote/proc/set_next_map(datum/map_config/change_to)
|
||||
if(!change_to.MakeNextMap())
|
||||
message_admins("Failed to set new map with next_map.json for [change_to.map_name]!")
|
||||
return FALSE
|
||||
|
||||
next_map_config = change_to
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/map_vote/proc/revert_next_map()
|
||||
if(!next_map_config)
|
||||
return
|
||||
if(previous_cache)
|
||||
map_vote_cache = previous_cache
|
||||
previous_cache = null
|
||||
|
||||
already_voted = FALSE
|
||||
admin_override = FALSE
|
||||
send_map_vote_notice("Next map reverted. Voting re-enabled.")
|
||||
|
||||
#undef MAP_VOTE_CACHE_LOCATION
|
||||
|
||||
/datum/controller/subsystem/map_vote/proc/update_tally_printout()
|
||||
var/list/data = list()
|
||||
for(var/map_id in map_vote_cache)
|
||||
var/datum/map_config/map = config.maplist[map_id]
|
||||
data += "[map.map_name] - [map_vote_cache[map_id]]"
|
||||
tally_printout = examine_block("Current Tallies\n<hr>\n[data.Join("\n")]")
|
||||
@@ -6,15 +6,8 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/list/nuke_tiles = list()
|
||||
var/list/nuke_threats = list()
|
||||
|
||||
var/datum/map_config/config
|
||||
var/datum/map_config/next_map_config
|
||||
|
||||
/// Has the map for the next round been voted for already?
|
||||
var/map_voted = FALSE
|
||||
/// Has the map for the next round been deliberately chosen by an admin?
|
||||
var/map_force_chosen = FALSE
|
||||
/// Has the map vote been rocked?
|
||||
var/map_vote_rocked = FALSE
|
||||
/// The current map config the server loaded at round start.
|
||||
var/datum/map_config/current_map
|
||||
|
||||
var/list/map_templates = list()
|
||||
|
||||
@@ -95,20 +88,20 @@ SUBSYSTEM_DEF(mapping)
|
||||
/datum/controller/subsystem/mapping/PreInit()
|
||||
..()
|
||||
#ifdef FORCE_MAP
|
||||
config = load_map_config(FORCE_MAP, FORCE_MAP_DIRECTORY)
|
||||
current_map = load_map_config(FORCE_MAP, FORCE_MAP_DIRECTORY)
|
||||
#else
|
||||
config = load_map_config(error_if_missing = FALSE)
|
||||
current_map = load_map_config(error_if_missing = FALSE)
|
||||
#endif
|
||||
|
||||
/datum/controller/subsystem/mapping/Initialize()
|
||||
if(initialized)
|
||||
return SS_INIT_SUCCESS
|
||||
if(config.defaulted)
|
||||
var/old_config = config
|
||||
config = global.config.defaultmap
|
||||
if(!config || config.defaulted)
|
||||
to_chat(world, span_boldannounce("Unable to load next or default map config, defaulting to MetaStation."))
|
||||
config = old_config
|
||||
if(current_map.defaulted)
|
||||
var/datum/map_config/old_config = current_map
|
||||
current_map = config.defaultmap
|
||||
if(!current_map || current_map.defaulted)
|
||||
to_chat(world, span_boldannounce("Unable to load next or default map config, defaulting to [old_config.map_name]."))
|
||||
current_map = old_config
|
||||
plane_offset_to_true = list()
|
||||
true_to_offset_planes = list()
|
||||
plane_to_offset = list()
|
||||
@@ -132,11 +125,11 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
#ifndef LOWMEMORYMODE
|
||||
// Create space ruin levels
|
||||
while (space_levels_so_far < config.space_ruin_levels)
|
||||
while (space_levels_so_far < current_map.space_ruin_levels)
|
||||
add_new_zlevel("Ruin Area [space_levels_so_far+1]", ZTRAITS_SPACE)
|
||||
++space_levels_so_far
|
||||
// Create empty space levels
|
||||
while (space_levels_so_far < config.space_empty_levels + config.space_ruin_levels)
|
||||
while (space_levels_so_far < current_map.space_empty_levels + current_map.space_ruin_levels)
|
||||
empty_space = add_new_zlevel("Empty Area [space_levels_so_far+1]", list(ZTRAIT_LINKAGE = CROSSLINKED))
|
||||
++space_levels_so_far
|
||||
|
||||
@@ -144,7 +137,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
if(CONFIG_GET(flag/roundstart_away))
|
||||
createRandomZlevel(prob(CONFIG_GET(number/config_gateway_chance)))
|
||||
|
||||
else if (SSmapping.config.load_all_away_missions) // we're likely in a local testing environment, so punch it.
|
||||
else if (SSmapping.current_map.load_all_away_missions) // we're likely in a local testing environment, so punch it.
|
||||
load_all_away_missions()
|
||||
|
||||
loading_ruins = TRUE
|
||||
@@ -363,9 +356,7 @@ Used by the AI doomsday and the self-destruct nuke.
|
||||
holodeck_templates = SSmapping.holodeck_templates
|
||||
areas_in_z = SSmapping.areas_in_z
|
||||
|
||||
config = SSmapping.config
|
||||
next_map_config = SSmapping.next_map_config
|
||||
|
||||
current_map = SSmapping.current_map
|
||||
clearing_reserved_turfs = SSmapping.clearing_reserved_turfs
|
||||
|
||||
z_list = SSmapping.z_list
|
||||
@@ -431,22 +422,22 @@ Used by the AI doomsday and the self-destruct nuke.
|
||||
|
||||
// load the station
|
||||
station_start = world.maxz + 1
|
||||
INIT_ANNOUNCE("Loading [config.map_name]...")
|
||||
LoadGroup(FailedZs, "Station", config.map_path, config.map_file, config.traits, ZTRAITS_STATION)
|
||||
INIT_ANNOUNCE("Loading [current_map.map_name]...")
|
||||
LoadGroup(FailedZs, "Station", current_map.map_path, current_map.map_file, current_map.traits, ZTRAITS_STATION)
|
||||
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/db_query/query_round_map_name = SSdbcore.NewQuery({"
|
||||
UPDATE [format_table_name("round")] SET map_name = :map_name WHERE id = :round_id
|
||||
"}, list("map_name" = config.map_name, "round_id" = GLOB.round_id))
|
||||
"}, list("map_name" = current_map.map_name, "round_id" = GLOB.round_id))
|
||||
query_round_map_name.Execute()
|
||||
qdel(query_round_map_name)
|
||||
|
||||
#ifndef LOWMEMORYMODE
|
||||
|
||||
if(config.minetype == "lavaland")
|
||||
if(current_map.minetype == "lavaland")
|
||||
LoadGroup(FailedZs, "Lavaland", "map_files/Mining", "Lavaland.dmm", default_traits = ZTRAITS_LAVALAND)
|
||||
else if (!isnull(config.minetype) && config.minetype != "none")
|
||||
INIT_ANNOUNCE("WARNING: An unknown minetype '[config.minetype]' was set! This is being ignored! Update the maploader code!")
|
||||
else if (!isnull(current_map.minetype) && current_map.minetype != "none")
|
||||
INIT_ANNOUNCE("WARNING: An unknown minetype '[current_map.minetype]' was set! This is being ignored! Update the maploader code!")
|
||||
#endif
|
||||
|
||||
if(LAZYLEN(FailedZs)) //but seriously, unless the server's filesystem is messed up this will never happen
|
||||
@@ -459,10 +450,8 @@ Used by the AI doomsday and the self-destruct nuke.
|
||||
#undef INIT_ANNOUNCE
|
||||
|
||||
// Custom maps are removed after station loading so the map files does not persist for no reason.
|
||||
if(config.map_path == CUSTOM_MAP_PATH)
|
||||
fdel("_maps/custom/[config.map_file]")
|
||||
// And as the file is now removed set the next map to default.
|
||||
next_map_config = load_default_map_config()
|
||||
if(current_map.map_path == CUSTOM_MAP_PATH)
|
||||
fdel("_maps/custom/[current_map.map_file]")
|
||||
|
||||
/**
|
||||
* Global list of AREA TYPES that are associated with the station.
|
||||
@@ -494,88 +483,6 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
for(var/area/A as anything in GLOB.areas)
|
||||
A.RunTerrainPopulation()
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/maprotate()
|
||||
if(map_voted || SSmapping.next_map_config) //If voted or set by other means.
|
||||
return
|
||||
|
||||
var/players = GLOB.clients.len
|
||||
var/list/mapvotes = list()
|
||||
//count votes
|
||||
var/pmv = CONFIG_GET(flag/preference_map_voting)
|
||||
if(pmv)
|
||||
for (var/client/c in GLOB.clients)
|
||||
var/vote = c.prefs.read_preference(/datum/preference/choiced/preferred_map)
|
||||
if (!vote)
|
||||
if (global.config.defaultmap)
|
||||
mapvotes[global.config.defaultmap.map_name] += 1
|
||||
continue
|
||||
mapvotes[vote] += 1
|
||||
else
|
||||
for(var/M in global.config.maplist)
|
||||
mapvotes[M] = 1
|
||||
|
||||
//filter votes
|
||||
for (var/map in mapvotes)
|
||||
if (!map)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (!(map in global.config.maplist))
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if(map in SSpersistence.blocked_maps)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
var/datum/map_config/VM = global.config.maplist[map]
|
||||
if (!VM)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.voteweight <= 0)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.config_min_users > 0 && players < VM.config_min_users)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.config_max_users > 0 && players > VM.config_max_users)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
|
||||
if(pmv)
|
||||
mapvotes[map] = mapvotes[map]*VM.voteweight
|
||||
|
||||
var/pickedmap = pick_weight(mapvotes)
|
||||
if (!pickedmap)
|
||||
return
|
||||
var/datum/map_config/VM = global.config.maplist[pickedmap]
|
||||
message_admins("Randomly rotating map to [VM.map_name]")
|
||||
. = changemap(VM)
|
||||
if (. && VM.map_name != config.map_name)
|
||||
to_chat(world, span_boldannounce("Map rotation has chosen [VM.map_name] for next round!"))
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/mapvote()
|
||||
if(map_voted || SSmapping.next_map_config) //If voted or set by other means.
|
||||
return
|
||||
if(SSvote.current_vote) //Theres already a vote running, default to rotation.
|
||||
maprotate()
|
||||
return
|
||||
SSvote.initiate_vote(/datum/vote/map_vote, "automatic map rotation", forced = TRUE)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/changemap(datum/map_config/change_to)
|
||||
if(!change_to.MakeNextMap())
|
||||
next_map_config = load_default_map_config()
|
||||
message_admins("Failed to set new map with next_map.json for [change_to.map_name]! Using default as backup!")
|
||||
return
|
||||
|
||||
var/filter_threshold = get_active_player_count(alive_check = FALSE, afk_check = TRUE, human_check = FALSE)
|
||||
if (change_to.config_min_users > 0 && filter_threshold != 0 && filter_threshold < change_to.config_min_users)
|
||||
message_admins("[change_to.map_name] was chosen for the next map, despite there being less current players than its set minimum population range!")
|
||||
log_game("[change_to.map_name] was chosen for the next map, despite there being less current players than its set minimum population range!")
|
||||
if (change_to.config_max_users > 0 && filter_threshold > change_to.config_max_users)
|
||||
message_admins("[change_to.map_name] was chosen for the next map, despite there being more current players than its set maximum population range!")
|
||||
log_game("[change_to.map_name] was chosen for the next map, despite there being more current players than its set maximum population range!")
|
||||
|
||||
next_map_config = change_to
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup
|
||||
var/list/filelist = flist(path)
|
||||
for(var/map in filelist)
|
||||
@@ -590,10 +497,10 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
/datum/controller/subsystem/mapping/proc/preloadRuinTemplates()
|
||||
// Still supporting bans by filename
|
||||
var/list/banned = generateMapList("spaceruinblacklist.txt")
|
||||
if(config.minetype == "lavaland")
|
||||
if(current_map.minetype == "lavaland")
|
||||
banned += generateMapList("lavaruinblacklist.txt")
|
||||
else if(config.blacklist_file)
|
||||
banned += generateMapList(config.blacklist_file)
|
||||
else if(current_map.blacklist_file)
|
||||
banned += generateMapList(current_map.blacklist_file)
|
||||
|
||||
for(var/item in sort_list(subtypesof(/datum/map_template/ruin), GLOBAL_PROC_REF(cmp_ruincost_priority)))
|
||||
var/datum/map_template/ruin/ruin_type = item
|
||||
@@ -953,7 +860,7 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away
|
||||
|
||||
/// Returns true if the map we're playing on is on a planet
|
||||
/datum/controller/subsystem/mapping/proc/is_planetary()
|
||||
return config.planetary
|
||||
return current_map.planetary
|
||||
|
||||
/// For debug purposes, will add every single away mission present in a given directory.
|
||||
/// You can optionally pass in a string directory to load from instead of the default.
|
||||
|
||||
@@ -111,7 +111,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
for(var/map in config.maplist)
|
||||
var/datum/map_config/VM = config.maplist[map]
|
||||
var/run = 0
|
||||
if(VM.map_name == SSmapping.config.map_name)
|
||||
if(VM.map_name == SSmapping.current_map.map_name)
|
||||
run++
|
||||
for(var/name in SSpersistence.saved_maps)
|
||||
if(VM.map_name == name)
|
||||
@@ -128,7 +128,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
saved_maps += mapstosave
|
||||
for(var/i = mapstosave; i > 1; i--)
|
||||
saved_maps[i] = saved_maps[i-1]
|
||||
saved_maps[1] = SSmapping.config.map_name
|
||||
saved_maps[1] = SSmapping.current_map.map_name
|
||||
var/json_file = file(FILE_RECENT_MAPS)
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = saved_maps
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
saved_engravings = json["entries"]
|
||||
|
||||
if(!saved_engravings.len)
|
||||
log_world("Failed to load engraved messages on map [SSmapping.config.map_name]")
|
||||
log_world("Failed to load engraved messages on map [SSmapping.current_map.map_name]")
|
||||
return
|
||||
|
||||
var/list/viable_turfs = get_area_turfs(/area/station/maintenance, subtypes = TRUE) + get_area_turfs(/area/station/security/prison, subtypes = TRUE)
|
||||
@@ -42,7 +42,7 @@
|
||||
successfully_loaded_engravings++
|
||||
turfs_to_pick_from -= engraved_wall
|
||||
|
||||
log_world("Loaded [successfully_loaded_engravings] engraved messages on map [SSmapping.config.map_name]")
|
||||
log_world("Loaded [successfully_loaded_engravings] engraved messages on map [SSmapping.current_map.map_name]")
|
||||
|
||||
///Saves all new engravings in the world.
|
||||
/datum/controller/subsystem/persistence/proc/save_wall_engravings()
|
||||
|
||||
@@ -22,9 +22,9 @@ SUBSYSTEM_DEF(statpanels)
|
||||
/datum/controller/subsystem/statpanels/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
num_fires++
|
||||
var/datum/map_config/cached = SSmapping.next_map_config
|
||||
var/datum/map_config/cached = SSmap_vote.next_map_config
|
||||
global_data = list(
|
||||
"Map: [SSmapping.config?.map_name || "Loading..."]",
|
||||
"Map: [SSmapping.current_map?.map_name || "Loading..."]",
|
||||
cached ? "Next Map: [cached.map_name]" : null,
|
||||
"Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]",
|
||||
"Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]",
|
||||
|
||||
@@ -93,12 +93,12 @@ SUBSYSTEM_DEF(ticker)
|
||||
switch(L.len)
|
||||
if(3) //rare+MAP+sound.ogg or MAP+rare.sound.ogg -- Rare Map-specific sounds
|
||||
if(use_rare_music)
|
||||
if(L[1] == "rare" && L[2] == SSmapping.config.map_name)
|
||||
if(L[1] == "rare" && L[2] == SSmapping.current_map.map_name)
|
||||
music += S
|
||||
else if(L[2] == "rare" && L[1] == SSmapping.config.map_name)
|
||||
else if(L[2] == "rare" && L[1] == SSmapping.current_map.map_name)
|
||||
music += S
|
||||
if(2) //rare+sound.ogg or MAP+sound.ogg -- Rare sounds or Map-specific sounds
|
||||
if((use_rare_music && L[1] == "rare") || (L[1] == SSmapping.config.map_name))
|
||||
if((use_rare_music && L[1] == "rare") || (L[1] == SSmapping.current_map.map_name))
|
||||
music += S
|
||||
if(1) //sound.ogg -- common sound
|
||||
if(L[1] == "exclude")
|
||||
@@ -157,7 +157,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
for(var/client/C in GLOB.clients)
|
||||
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
|
||||
to_chat(world, span_notice("<b>Welcome to [station_name()]!</b>"))
|
||||
send2chat(new /datum/tgs_message_content("New round starting on [SSmapping.config.map_name]!"), CONFIG_GET(string/channel_announce_new_game))
|
||||
send2chat(new /datum/tgs_message_content("New round starting on [SSmapping.current_map.map_name]!"), CONFIG_GET(string/channel_announce_new_game))
|
||||
current_state = GAME_STATE_PREGAME
|
||||
SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME)
|
||||
|
||||
@@ -211,7 +211,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
toggle_ooc(TRUE) // Turn it on
|
||||
toggle_dooc(TRUE)
|
||||
declare_completion(force_ending)
|
||||
check_maprotate()
|
||||
Master.SetRunLevel(RUNLEVEL_POSTGAME)
|
||||
|
||||
/// Checks if the round should be ending, called every ticker tick
|
||||
@@ -514,13 +513,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
queued_players -= next_in_line
|
||||
queue_delay = 0
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/check_maprotate()
|
||||
if(!CONFIG_GET(flag/maprotation))
|
||||
return
|
||||
if(world.time - SSticker.round_start_time < 10 MINUTES) //Not forcing map rotation for very short rounds.
|
||||
return
|
||||
INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping/, maprotate))
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
|
||||
return current_state >= GAME_STATE_PLAYING
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ SUBSYSTEM_DEF(time_track)
|
||||
)
|
||||
|
||||
/datum/controller/subsystem/time_track/Initialize()
|
||||
GLOB.perf_log = "[GLOB.log_directory]/perf-[GLOB.round_id ? GLOB.round_id : "NULL"]-[SSmapping.config?.map_name].csv"
|
||||
GLOB.perf_log = "[GLOB.log_directory]/perf-[GLOB.round_id ? GLOB.round_id : "NULL"]-[SSmapping.current_map.map_name].csv"
|
||||
world.Profile(PROFILE_RESTART, type = "sendmaps")
|
||||
//Need to do the sendmaps stuff in its own file, since it works different then everything else
|
||||
var/list/sendmaps_headers = list()
|
||||
|
||||
@@ -25,7 +25,7 @@ SUBSYSTEM_DEF(title)
|
||||
|
||||
for(var/S in provisional_title_screens)
|
||||
var/list/L = splittext(S,"+")
|
||||
if((L.len == 1 && (L[1] != "exclude" && L[1] != "blank.png")) || (L.len > 1 && ((use_rare_screens && LOWER_TEXT(L[1]) == "rare") || (LOWER_TEXT(L[1]) == LOWER_TEXT(SSmapping.config.map_name)))))
|
||||
if((L.len == 1 && (L[1] != "exclude" && L[1] != "blank.png")) || (L.len > 1 && ((use_rare_screens && LOWER_TEXT(L[1]) == "rare") || (LOWER_TEXT(L[1]) == LOWER_TEXT(SSmapping.current_map.map_name)))))
|
||||
title_screens += S
|
||||
|
||||
if(length(title_screens))
|
||||
|
||||
@@ -101,24 +101,28 @@ SUBSYSTEM_DEF(vote)
|
||||
|
||||
// stringify the winners to prevent potential unimplemented serialization errors.
|
||||
// Perhaps this can be removed in the future and we assert that vote choices must implement serialization.
|
||||
var/final_winner_string = final_winner && "[final_winner]"
|
||||
var/final_winner_string = (final_winner && "[final_winner]") || "NO WINNER"
|
||||
var/list/winners_string = list()
|
||||
for(var/winner in winners)
|
||||
winners_string += "[winner]"
|
||||
|
||||
if(length(winners))
|
||||
for(var/winner in winners)
|
||||
winners_string += "[winner]"
|
||||
else
|
||||
winners_string = list("NO WINNER")
|
||||
|
||||
var/list/vote_log_data = list(
|
||||
"type" = "[current_vote.type]",
|
||||
"choices" = vote_choice_data,
|
||||
"total" = total_votes,
|
||||
"winners" = winners_string,
|
||||
"final_winner" = final_winner_string,
|
||||
)
|
||||
var/log_string = replacetext(to_display, "\n", "\\n") // 'keep' the newlines, but dont actually print them as newlines
|
||||
log_vote(log_string, vote_log_data)
|
||||
to_chat(world, span_infoplain(vote_font("\n[to_display]")))
|
||||
log_vote("vote finalized", vote_log_data)
|
||||
if(to_display)
|
||||
to_chat(world, span_infoplain(vote_font("\n[to_display]")))
|
||||
|
||||
// Finally, doing any effects on vote completion
|
||||
if (final_winner) // if no one voted, or the vote cannot be won, final_winner will be null
|
||||
current_vote.finalize_vote(final_winner)
|
||||
current_vote.finalize_vote(final_winner)
|
||||
|
||||
/**
|
||||
* One selection per person, and the selection with the most votes wins.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
job = SSjob.get_job_type(job)
|
||||
|
||||
if(isnull(job_changes))
|
||||
job_changes = SSmapping.config.job_changes
|
||||
job_changes = SSmapping.current_map.job_changes
|
||||
|
||||
if(!length(job_changes))
|
||||
refresh_trim_access()
|
||||
|
||||
@@ -2,29 +2,18 @@
|
||||
name = "Map"
|
||||
default_message = "Vote for next round's map!"
|
||||
count_method = VOTE_COUNT_METHOD_SINGLE
|
||||
winner_method = VOTE_WINNER_METHOD_WEIGHTED_RANDOM
|
||||
winner_method = VOTE_WINNER_METHOD_NONE
|
||||
display_statistics = FALSE
|
||||
|
||||
/datum/vote/map_vote/New()
|
||||
. = ..()
|
||||
|
||||
default_choices = list()
|
||||
|
||||
// Fill in our default choices with all of the maps in our map config, if they are votable and not blocked.
|
||||
var/list/maps = shuffle(global.config.maplist)
|
||||
for(var/map in maps)
|
||||
var/datum/map_config/possible_config = config.maplist[map]
|
||||
if(!possible_config.votable || (possible_config.map_name in SSpersistence.blocked_maps))
|
||||
continue
|
||||
|
||||
default_choices += possible_config.map_name
|
||||
default_choices = SSmap_vote.get_valid_map_vote_choices()
|
||||
|
||||
/datum/vote/map_vote/create_vote()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
choices -= get_choices_invalid_for_population()
|
||||
if(length(choices) == 1) // Only one choice, no need to vote. Let's just auto-rotate it to the only remaining map because it would just happen anyways.
|
||||
var/datum/map_config/change_me_out = global.config.maplist[choices[1]]
|
||||
finalize_vote(choices[1])// voted by not voting, very sad.
|
||||
@@ -48,35 +37,16 @@
|
||||
. = ..()
|
||||
if(. != VOTE_AVAILABLE)
|
||||
return .
|
||||
if(forced)
|
||||
return VOTE_AVAILABLE
|
||||
var/num_choices = length(default_choices - get_choices_invalid_for_population())
|
||||
|
||||
var/num_choices = length(default_choices)
|
||||
if(num_choices <= 1)
|
||||
return "There [num_choices == 1 ? "is only one map" : "are no maps"] to choose from."
|
||||
if(SSmapping.map_vote_rocked)
|
||||
return VOTE_AVAILABLE
|
||||
if(SSmapping.map_voted)
|
||||
if(SSmap_vote.next_map_config)
|
||||
return "The next map has already been selected."
|
||||
return VOTE_AVAILABLE
|
||||
|
||||
/// Returns a list of all map options that are invalid for the current population.
|
||||
/datum/vote/map_vote/proc/get_choices_invalid_for_population()
|
||||
var/filter_threshold = 0
|
||||
if(SSticker.HasRoundStarted())
|
||||
filter_threshold = get_active_player_count(alive_check = FALSE, afk_check = TRUE, human_check = FALSE)
|
||||
else
|
||||
filter_threshold = GLOB.clients.len
|
||||
|
||||
var/list/invalid_choices = list()
|
||||
for(var/map in default_choices)
|
||||
var/datum/map_config/possible_config = config.maplist[map]
|
||||
if(possible_config.config_min_users > 0 && filter_threshold < possible_config.config_min_users)
|
||||
invalid_choices += map
|
||||
|
||||
else if(possible_config.config_max_users > 0 && filter_threshold > possible_config.config_max_users)
|
||||
invalid_choices += map
|
||||
|
||||
return invalid_choices
|
||||
/datum/vote/map_vote/get_result_text(list/all_winners, real_winner, list/non_voters)
|
||||
return null
|
||||
|
||||
/datum/vote/map_vote/get_vote_result(list/non_voters)
|
||||
// Even if we have default no vote off,
|
||||
@@ -97,20 +67,4 @@
|
||||
return ..()
|
||||
|
||||
/datum/vote/map_vote/finalize_vote(winning_option)
|
||||
var/datum/map_config/winning_map = global.config.maplist[winning_option]
|
||||
if(!istype(winning_map))
|
||||
CRASH("[type] wasn't passed a valid winning map choice. (Got: [winning_option || "null"] - [winning_map || "null"])")
|
||||
|
||||
SSmapping.changemap(winning_map)
|
||||
SSmapping.map_voted = TRUE
|
||||
if(SSmapping.map_vote_rocked)
|
||||
SSmapping.map_vote_rocked = FALSE
|
||||
|
||||
/proc/revert_map_vote()
|
||||
var/datum/map_config/override_map = SSmapping.config
|
||||
if(isnull(override_map))
|
||||
return
|
||||
|
||||
SSmapping.changemap(override_map)
|
||||
log_game("The next map has been reset to [override_map.map_name].")
|
||||
send_to_playing_players(span_boldannounce("The next map is: [override_map.map_name]."))
|
||||
SSmap_vote.finalize_map_vote(src)
|
||||
|
||||
@@ -57,10 +57,10 @@
|
||||
return
|
||||
|
||||
// If there was a previous map vote, we revert the change.
|
||||
if(!isnull(SSmapping.next_map_config))
|
||||
if(!isnull(SSmap_vote.next_map_config))
|
||||
log_game("The next map has been reset due to successful restart vote.")
|
||||
send_to_playing_players(span_boldannounce("The next map has been reset due to successful restart vote."))
|
||||
revert_map_vote()
|
||||
SSmap_vote.revert_next_map()
|
||||
|
||||
SSticker.force_ending = FORCE_END_ROUND
|
||||
log_game("End round forced by successful restart vote.")
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
#define CHOICE_TO_ROCK "Yes, re-do the map vote."
|
||||
#define CHOICE_NOT_TO_ROCK "No, keep the currently selected map."
|
||||
|
||||
/// If a map vote is called before the emergency shuttle leaves the station, the players can call another vote to re-run the vote on the shuttle leaving.
|
||||
/datum/vote/rock_the_vote
|
||||
name = "Rock the Vote"
|
||||
override_question = "Rock the Vote?"
|
||||
contains_vote_in_name = TRUE //lol
|
||||
default_choices = list(
|
||||
CHOICE_TO_ROCK,
|
||||
CHOICE_NOT_TO_ROCK,
|
||||
)
|
||||
default_message = "Override the current map vote."
|
||||
/// The number of times we have rocked the vote thus far.
|
||||
var/rocking_votes = 0
|
||||
|
||||
/datum/vote/rock_the_vote/toggle_votable()
|
||||
CONFIG_SET(flag/allow_rock_the_vote, !CONFIG_GET(flag/allow_rock_the_vote))
|
||||
|
||||
/datum/vote/rock_the_vote/is_config_enabled()
|
||||
return CONFIG_GET(flag/allow_rock_the_vote)
|
||||
|
||||
/datum/vote/rock_the_vote/can_be_initiated(forced)
|
||||
. = ..()
|
||||
if(. != VOTE_AVAILABLE)
|
||||
return .
|
||||
|
||||
if(SSticker.current_state == GAME_STATE_FINISHED)
|
||||
return "The game is finished, no map votes can be initiated."
|
||||
|
||||
if(rocking_votes >= CONFIG_GET(number/max_rocking_votes))
|
||||
return "The maximum number of times to rock the vote has been reached."
|
||||
|
||||
if(SSmapping.map_vote_rocked)
|
||||
return "The vote has already been rocked! Initiate a map vote!"
|
||||
|
||||
if(!SSmapping.map_voted)
|
||||
return "Rocking the vote is disabled because no map has been voted on yet!"
|
||||
|
||||
if(SSmapping.map_force_chosen)
|
||||
return "Rocking the vote is disabled because an admin has forcibly set the map!"
|
||||
|
||||
if(EMERGENCY_ESCAPED_OR_ENDGAMED && SSmapping.map_voted)
|
||||
return "The emergency shuttle has already left the station and the next map has already been chosen!"
|
||||
|
||||
return VOTE_AVAILABLE
|
||||
|
||||
/datum/vote/rock_the_vote/finalize_vote(winning_option)
|
||||
rocking_votes++
|
||||
if(winning_option == CHOICE_NOT_TO_ROCK)
|
||||
return
|
||||
|
||||
if(winning_option == CHOICE_TO_ROCK)
|
||||
to_chat(world, span_boldannounce("The vote has been rocked! Players are now able to re-run the map vote once more."))
|
||||
message_admins("The players have successfully rocked the vote.")
|
||||
SSmapping.map_vote_rocked = TRUE
|
||||
return
|
||||
|
||||
CRASH("[type] wasn't passed a valid winning choice. (Got: [winning_option || "null"])")
|
||||
|
||||
#undef CHOICE_TO_ROCK
|
||||
#undef CHOICE_NOT_TO_ROCK
|
||||
@@ -212,7 +212,7 @@
|
||||
.["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho
|
||||
.["gamestate"] = SSticker.current_state
|
||||
|
||||
.["map_name"] = SSmapping.config?.map_name || "Loading..."
|
||||
.["map_name"] = SSmapping.current_map.map_name || "Loading..."
|
||||
|
||||
if(key_valid)
|
||||
.["active_players"] = get_active_player_count()
|
||||
|
||||
@@ -672,7 +672,7 @@
|
||||
/// Returns TRUE if the user can buy shuttles.
|
||||
/// If they cannot, returns FALSE or a string detailing why.
|
||||
/obj/machinery/computer/communications/proc/can_buy_shuttles(mob/user)
|
||||
if (!SSmapping.config.allow_custom_shuttles)
|
||||
if (!SSmapping.current_map.allow_custom_shuttles)
|
||||
return FALSE
|
||||
if (HAS_SILICON_ACCESS(user))
|
||||
return FALSE
|
||||
|
||||
+4
-4
@@ -399,10 +399,10 @@ GLOBAL_VAR(tracy_log)
|
||||
new_status += " | Shuttle: <b>[SSshuttle.emergency.getModeStr()] [SSshuttle.emergency.getTimerStr()]</b>"
|
||||
else if(SSticker.current_state == GAME_STATE_FINISHED)
|
||||
new_status += "<br><b>RESTARTING</b>"
|
||||
if(SSmapping.config)
|
||||
new_status += "<br>Map: <b>[SSmapping.config.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmapping.config.map_name]</b>"
|
||||
if(SSmapping.next_map_config)
|
||||
new_status += "[SSmapping.config ? " | " : "<br>"]Next: <b>[SSmapping.next_map_config.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmapping.next_map_config.map_name]</b>"
|
||||
if(SSmapping.current_map)
|
||||
new_status += "<br>Map: <b>[SSmapping.current_map.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmapping.current_map.map_name]</b>"
|
||||
if(SSmap_vote.next_map_config)
|
||||
new_status += "[SSmapping.current_map ? " | " : "<br>"]Next: <b>[SSmap_vote.next_map_config.map_path == CUSTOM_MAP_PATH ? "Uncharted Territory" : SSmap_vote.next_map_config.map_name]</b>"
|
||||
|
||||
status = new_status
|
||||
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
|
||||
ADMIN_VERB(force_random_rotate, R_SERVER, "Trigger 'Random' Map Rotation", "Force a map vote.", ADMIN_CATEGORY_SERVER)
|
||||
var/rotate = tgui_alert(user,"Force a random map rotation to trigger?", "Rotate map?", list("Yes", "Cancel"))
|
||||
if (rotate != "Yes")
|
||||
return
|
||||
message_admins("[key_name_admin(user)] is forcing a random map rotation.")
|
||||
log_admin("[key_name(user)] is forcing a random map rotation.")
|
||||
SSmapping.maprotate()
|
||||
|
||||
ADMIN_VERB(admin_change_map, R_SERVER, "Change Map", "Set the next map.", ADMIN_CATEGORY_SERVER)
|
||||
var/list/maprotatechoices = list()
|
||||
for (var/map in config.maplist)
|
||||
@@ -119,14 +110,14 @@ ADMIN_VERB(admin_change_map, R_SERVER, "Change Map", "Set the next map.", ADMIN_
|
||||
fdel(PATH_TO_NEXT_MAP_JSON)
|
||||
text2file(json_encode(json_value), PATH_TO_NEXT_MAP_JSON)
|
||||
|
||||
if(SSmapping.changemap(virtual_map))
|
||||
if(SSmap_vote.set_next_map(virtual_map))
|
||||
message_admins("[key_name_admin(user)] has changed the map to [virtual_map.map_name]")
|
||||
SSmapping.map_force_chosen = TRUE
|
||||
SSmap_vote.admin_override = TRUE
|
||||
fdel("data/custom_map_json/[config_file]")
|
||||
else
|
||||
var/datum/map_config/virtual_map = maprotatechoices[chosenmap]
|
||||
message_admins("[key_name_admin(user)] is changing the map to [virtual_map.map_name]")
|
||||
log_admin("[key_name(user)] is changing the map to [virtual_map.map_name]")
|
||||
if (SSmapping.changemap(virtual_map))
|
||||
if (SSmap_vote.set_next_map(virtual_map))
|
||||
message_admins("[key_name_admin(user)] has changed the map to [virtual_map.map_name]")
|
||||
SSmapping.map_force_chosen = TRUE
|
||||
SSmap_vote.admin_override = TRUE
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
var/static/list/doom_options = list()
|
||||
if (!length(doom_options))
|
||||
doom_options = list(DOOM_SINGULARITY, DOOM_TESLA)
|
||||
if (!SSmapping.config.planetary)
|
||||
if (!SSmapping.is_planetary())
|
||||
doom_options += DOOM_METEORS
|
||||
|
||||
switch(pick(doom_options))
|
||||
|
||||
@@ -456,3 +456,9 @@ ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC
|
||||
ASSERT(prefs, "User attempted to export preferences while preferences were null!") // what the fuck
|
||||
|
||||
prefs.savefile.export_json_to_client(usr, ckey)
|
||||
|
||||
/client/verb/map_vote_tally_count()
|
||||
set name = "Show Map Vote Tallies"
|
||||
set desc = "View the current map vote tally counts."
|
||||
set category = "Server"
|
||||
to_chat(mob, SSmap_vote.tally_printout)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/datum/tgs_chat_command/tgscheck/Run(datum/tgs_chat_user/sender, params)
|
||||
var/server = CONFIG_GET(string/server)
|
||||
return new /datum/tgs_message_content("[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [server ? server : "[world.internet_address]:[world.port]"]")
|
||||
return new /datum/tgs_message_content("[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.current_map.map_name]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [server ? server : "[world.internet_address]:[world.port]"]")
|
||||
|
||||
/datum/tgs_chat_command/gameversion
|
||||
name = "gameversion"
|
||||
|
||||
@@ -35,7 +35,7 @@ GLOBAL_DATUM(escape_menu_details, /atom/movable/screen/escape_menu/details)
|
||||
<span style='text-align: right; line-height: 0.7'>
|
||||
Round ID: [GLOB.round_id || "Unset"]<br />
|
||||
Round Time: [ROUND_TIME()]<br />
|
||||
Map: [SSmapping.config?.map_name || "Loading..."]<br />
|
||||
Map: [SSmapping.current_map.map_name || "Loading..."]<br />
|
||||
Time Dilation: [round(SStime_track.time_dilation_current,1)]%<br />
|
||||
</span>
|
||||
"}
|
||||
|
||||
@@ -278,6 +278,6 @@
|
||||
|
||||
///Generates a persistence id unique to the current map. Every bar should feel a little bit different after all.
|
||||
/obj/structure/sign/picture_frame/portrait/bar/Initialize(mapload)
|
||||
if(SSmapping.config.map_path != CUSTOM_MAP_PATH) //skip adminloaded custom maps.
|
||||
persistence_id = "frame_bar_[SSmapping.config.map_name]"
|
||||
if(SSmapping.current_map.map_path != CUSTOM_MAP_PATH) //skip adminloaded custom maps.
|
||||
persistence_id = "frame_bar_[SSmapping.current_map.map_name]"
|
||||
return ..()
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
// changed to allow Z cropping and that's a mess
|
||||
var/z_offset = SSmapping.station_start
|
||||
var/list/bounds
|
||||
for (var/path in SSmapping.config.GetFullMapPaths())
|
||||
for (var/path in SSmapping.current_map.GetFullMapPaths())
|
||||
var/datum/parsed_map/parsed = load_map(
|
||||
file(path),
|
||||
1,
|
||||
|
||||
@@ -549,7 +549,7 @@
|
||||
color_override = "orange",
|
||||
)
|
||||
INVOKE_ASYNC(SSticker, TYPE_PROC_REF(/datum/controller/subsystem/ticker, poll_hearts))
|
||||
SSmapping.mapvote() //If no map vote has been run yet, start one.
|
||||
INVOKE_ASYNC(SSvote, TYPE_PROC_REF(/datum/controller/subsystem/vote, initiate_vote), /datum/vote/map_vote, initiator_name = "Map Rotation")
|
||||
|
||||
if(!is_reserved_level(z))
|
||||
CRASH("Emergency shuttle did not move to transit z-level!")
|
||||
|
||||
@@ -264,7 +264,7 @@
|
||||
|
||||
/obj/docking_port/stationary/proc/load_roundstart()
|
||||
if(json_key)
|
||||
var/sid = SSmapping.config.shuttles[json_key]
|
||||
var/sid = SSmapping.current_map.shuttles[json_key]
|
||||
roundstart_template = SSmapping.shuttle_templates[sid]
|
||||
if(!roundstart_template)
|
||||
CRASH("json_key:[json_key] value \[[sid]\] resulted in a null shuttle template for [src]")
|
||||
|
||||
@@ -158,7 +158,7 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
|
||||
|
||||
/// Logs a test message. Will use GitHub action syntax found at https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
|
||||
/datum/unit_test/proc/log_for_test(text, priority, file, line)
|
||||
var/map_name = SSmapping.config.map_name
|
||||
var/map_name = SSmapping.current_map.map_name
|
||||
|
||||
// Need to escape the text to properly support newlines.
|
||||
var/annotation_text = replacetext(text, "%", "%25")
|
||||
@@ -177,14 +177,14 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests())
|
||||
|
||||
GLOB.current_test = test
|
||||
var/duration = REALTIMEOFDAY
|
||||
var/skip_test = (test_path in SSmapping.config.skipped_tests)
|
||||
var/skip_test = (test_path in SSmapping.current_map.skipped_tests)
|
||||
var/test_output_desc = "[test_path]"
|
||||
var/message = ""
|
||||
|
||||
log_world("::group::[test_path]")
|
||||
|
||||
if(skip_test)
|
||||
log_world("[TEST_OUTPUT_YELLOW("SKIPPED")] Skipped run on map [SSmapping.config.map_name].")
|
||||
log_world("[TEST_OUTPUT_YELLOW("SKIPPED")] Skipped run on map [SSmapping.current_map.map_name].")
|
||||
|
||||
else
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
## A flat bonus to give to all maps after a map vote is concluded.
|
||||
MAP_VOTE_FLAT_BONUS 5
|
||||
|
||||
## The minimum number of tallies a map can have for purposes of map rotation.
|
||||
MAP_VOTE_MINIMUM_TALLIES 1
|
||||
|
||||
## The maximum number of tallies a map can have for purposes of keeping things sane.
|
||||
MAP_VOTE_MAXIMUM_TALLIES 200
|
||||
|
||||
## The percentage of tallies that are carried over between rounds.
|
||||
MAP_VOTE_TALLY_CARRYOVER_PERCENTAGE 100
|
||||
+1
-1
@@ -659,6 +659,7 @@
|
||||
#include "code\controllers\subsystem\lighting.dm"
|
||||
#include "code\controllers\subsystem\lua.dm"
|
||||
#include "code\controllers\subsystem\machines.dm"
|
||||
#include "code\controllers\subsystem\map_vote.dm"
|
||||
#include "code\controllers\subsystem\mapping.dm"
|
||||
#include "code\controllers\subsystem\market.dm"
|
||||
#include "code\controllers\subsystem\materials.dm"
|
||||
@@ -1924,7 +1925,6 @@
|
||||
#include "code\datums\votes\custom_vote.dm"
|
||||
#include "code\datums\votes\map_vote.dm"
|
||||
#include "code\datums\votes\restart_vote.dm"
|
||||
#include "code\datums\votes\rock_the_vote.dm"
|
||||
#include "code\datums\weather\weather.dm"
|
||||
#include "code\datums\weather\weather_types\ash_storm.dm"
|
||||
#include "code\datums\weather\weather_types\floor_is_lava.dm"
|
||||
|
||||
Reference in New Issue
Block a user