mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
* TGUI Preferences Menu + total rewrite of the preferences backend (#17368) * It compiles * It opens * Sync 1 * Add asset caching * Sync 2 * It opens without dev now * Update a few packages * Sync 3 * Sync 4 keybind fix * start of dehardcoded species * Small fixes * Add more individual preferences * ASS sync * Automatic changelog generation #17368 [ci skip] * AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH * e * Fix some TS stuff * Sort quirks starting from good * Fix skin tone selector * Jamie Fixes * Update moth.dm * Fix latejoin menu + tweaks * Some fixes * Finally fix job selection * e * Ling * MORE * config * Convert pref: ooccolor * Convert pref: asay color * Convert pref: tooltips * Convert pref: ui style * Convert pref: buttons locked * Convert pref: hotkeys * Convert pref: tgui stuff * Convert pref: windowflashing * Convert pref: ghost stuff * Convert pref: map & antag * Convert pref: PDA stuff * Convert pref: credits & glasses 1 * Convert pref: name * Convert pref: appearances 1 * Convert pref: appearances 2 * Convert pref: jobless role * Convert pref: runechat * Convert pref: yogtoggles + tail wagging 1 * Convert pref: client fps * Convert pref: graphic settings * Convert pref: pda uplink & menuoptions * Convert pref: map & flare * Convert pref: Bar choice * Fix setup character button * Convert pref: alt announcer * Fix * Add cycle background button * Convert pref: disable balloon alert * fix * Clean savefile * Fix backpack pref * Fix underwear selection * Fixes some shit * Updates * Fix computer runtime * Fix pref names * Convert pref: donor item & hat * More computer fixes * Convert pref: borg hat * Convert pref: donor pda (broken) * Convert pref: purrbation * Convert pref: afreeze * Convert pref: accent * Various savefile improvements * Convert pref: persistent scars 1 * A few pref fixes * Some more fixes * Various SSoverlays improvements * Add IPC appearances * Add polysmorph appearances * No icons for ipc and polysmorph * Podpeople deserve death * Add plasmaman appearance * h * fix * fix2 * asdf * fsdf * aaaaa * FUCK MOTHS * Preternis color * e * e * Update human.dmi * icon fix * un snowflake * fix underwear icon * remove color from here * donor ree * aa * maybe * Restore a bunch of TGUI files * More TGUI fixes * test * Fix more errors * a * test * e? * a;lso this * maybe * Fix * Revert "maybe" This reverts commit14d044a7e3. * fuck off m8 * e * fak off m8 * e2? * AHHH * AHA * AHHH * fix linter 2 * debug * fix runtime * Update dynamic.json * Revert "debug" This reverts commit18681432bd. * 2 * who sleeps in an async? * Hack * e * Fix a few blocking calls * Oh bother * Stay dead * fuck * Update jobs.dm * move debugging * Update jobs.dm * Test * YEET * Revert "YEET" This reverts commit4082e3b133. * Update jobs.dm * Update jobs.dm * e * Fix sechailer runtime * Fix human hair color * d * Ports part of that job refactor * Convert latejoin to new departments * Fix ghost form * Quirk validation * Hopefully pod color fix * oops * Prayge job fix * test * Better unit test asset loading * Remove print * Add error just in case * Remove brief outfit and bypass centcom deadmin * Remove broadcast login/logout * Remove darkened flash * Remove fov darkness * Remove ghost lighting * Remove some tgui prefs * Typo fix * Small fixes * IPC name fix * IPC and pod colors * Jobless fix * Donor item fix * Oopsie * Quirk bandaid * Misc * Move new prefs to Preferences tab for now * Add skillcape * FUCK THIS SHIT * Remove /tg/ gamer cloak * Restrict some job related preferences to clean up UI * Remove useless client var * e * Small tweaks * Dont allow selecting mood quirks if mood is disabled * AHHH * Filter ckey-locked donor items * stupid jamie * AI core display fix * Move donor stuff back to the top * Remove TODOs * Clean up perks * Linter fixes * e * WORKS * LORE * Fix skillcape list * Backpack why * Fixes * Fix cargo console * Remove these * Add horns, frills and mark * Fix not applying all features * Add some missing mutant bodyparts * Update numberinput * Makes animatednumber cooler * Oops * Add default ghost orbit * Default to normal backpack * Fixes skillcapes not being filtered * Donor fix prayge * yep * Adds fallback latejoin menu * Rework donor stuff a bit * Fix donor tgui logic * Delete unused proc * Update FA * Un-yogify quirks * Better checking of quirks * Update tgfont * Fix quirk icons * Fix backup name * Fix donor stuff * A few runtime fixes * Fix another runtime * Give fallback latejoin verb upon connecting * Update AirAlarm interface * maybe this works * Test * Sentient * Remove AI core display preview icons * Fix resetting plasmaman helmet style * Equip plasman in preview * Fix plasmaman preview icon * fuck keybind fix * Extra keybind sanity --------- Co-authored-by: Yogbot-13 <admin@yogstation.net> Co-authored-by: Jamie D <993128+JamieD1@users.noreply.github.com> Co-authored-by: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com> Co-authored-by: adamsong <adamsong@users.noreply.github.com>
630 lines
23 KiB
Plaintext
630 lines
23 KiB
Plaintext
SUBSYSTEM_DEF(mapping)
|
|
name = "Mapping"
|
|
init_order = INIT_ORDER_MAPPING
|
|
runlevels = ALL
|
|
|
|
loading_points = 11 SECONDS // Yogs -- loading times
|
|
|
|
var/list/nuke_tiles = list()
|
|
var/list/nuke_threats = list()
|
|
|
|
var/datum/map_config/config
|
|
var/datum/map_config/next_map_config
|
|
|
|
var/map_voted = FALSE
|
|
|
|
var/list/map_templates = list()
|
|
|
|
var/list/ruins_templates = list()
|
|
var/list/space_ruins_templates = list()
|
|
var/list/lava_ruins_templates = list()
|
|
var/list/ice_ruins_templates = list()
|
|
var/list/ice_ruins_underground_templates = list()
|
|
|
|
var/list/shuttle_templates = list()
|
|
var/list/shelter_templates = list()
|
|
|
|
var/list/station_minimaps = list()
|
|
|
|
var/list/areas_in_z = list()
|
|
|
|
var/loading_ruins = FALSE
|
|
var/list/turf/unused_turfs = list() //Not actually unused turfs they're unused but reserved for use for whatever requests them. "[zlevel_of_turf]" = list(turfs)
|
|
var/list/datum/turf_reservations //list of turf reservations
|
|
var/list/used_turfs = list() //list of turf = datum/turf_reservation
|
|
/// List of lists of turfs to reserve
|
|
var/list/lists_to_reserve = list()
|
|
|
|
var/clearing_reserved_turfs = FALSE
|
|
|
|
// Z-manager stuff
|
|
var/station_start // should only be used for maploading-related tasks
|
|
var/space_levels_so_far = 0
|
|
var/list/z_list
|
|
var/datum/space_level/transit
|
|
var/datum/space_level/empty_space
|
|
var/num_of_res_levels = 1
|
|
|
|
//dlete dis once #39770 is resolved
|
|
/datum/controller/subsystem/mapping/proc/HACK_LoadMapConfig()
|
|
if(!config)
|
|
#ifdef FORCE_MAP
|
|
config = load_map_config(FORCE_MAP)
|
|
#else
|
|
config = load_map_config(error_if_missing = FALSE)
|
|
#endif
|
|
|
|
/datum/controller/subsystem/mapping/Initialize(timeofday)
|
|
HACK_LoadMapConfig()
|
|
if(initialized)
|
|
return
|
|
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 Box Station"))
|
|
config = old_config
|
|
loadWorld()
|
|
require_area_resort()
|
|
process_teleport_locs() //Sets up the wizard teleport locations
|
|
preloadTemplates()
|
|
run_map_generation()
|
|
#ifndef LOWMEMORYMODE
|
|
// Create space ruin levels
|
|
while (space_levels_so_far < config.space_ruin_levels)
|
|
++space_levels_so_far
|
|
add_new_zlevel("Empty Area [space_levels_so_far]", ZTRAITS_SPACE)
|
|
// and one level with no ruins
|
|
for (var/i in 1 to config.space_empty_levels)
|
|
++space_levels_so_far
|
|
empty_space = add_new_zlevel("Empty Area [space_levels_so_far]", list(ZTRAIT_LINKAGE = CROSSLINKED))
|
|
|
|
// Pick a random away mission.
|
|
if(CONFIG_GET(flag/roundstart_away))
|
|
createRandomZlevel(prob(CONFIG_GET(number/config_gateway_chance)))
|
|
|
|
// Load the virtual reality hub
|
|
if(CONFIG_GET(flag/virtual_reality))
|
|
to_chat(world, span_boldannounce("Loading virtual reality..."))
|
|
load_new_z_level("_maps/RandomZLevels/VR/vrhub.dmm", "Virtual Reality Hub")
|
|
to_chat(world, span_boldannounce("Virtual reality loaded."))
|
|
|
|
// Generate mining ruins
|
|
loading_ruins = TRUE
|
|
var/list/lava_ruins = levels_by_trait(ZTRAIT_LAVA_RUINS)
|
|
if (lava_ruins.len)
|
|
seedRuins(lava_ruins, CONFIG_GET(number/lavaland_budget), list(/area/lavaland/surface/outdoors/unexplored), lava_ruins_templates, clear_below = TRUE)
|
|
for (var/lava_z in lava_ruins)
|
|
spawn_rivers(lava_z)
|
|
|
|
var/list/ice_ruins = levels_by_trait(ZTRAIT_ICE_RUINS)
|
|
if (ice_ruins.len)
|
|
// needs to be whitelisted for underground too so place_below ruins work
|
|
seedRuins(ice_ruins, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/surface/outdoors/unexplored, /area/icemoon/underground/unexplored), ice_ruins_templates, clear_below = TRUE)
|
|
for(var/ice_z in ice_ruins)
|
|
spawn_rivers(ice_z, 4, /turf/open/openspace/icemoon, /area/icemoon/surface/outdoors/unexplored)
|
|
|
|
var/list/ice_ruins_underground = levels_by_trait(ZTRAIT_ICE_RUINS_UNDERGROUND)
|
|
if (ice_ruins_underground.len)
|
|
seedRuins(ice_ruins_underground, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/underground/unexplored), ice_ruins_underground_templates, clear_below = TRUE)
|
|
for(var/ice_z in ice_ruins_underground)
|
|
spawn_rivers(ice_z, 4, /turf/open/lava/plasma/ice_moon, /area/icemoon/underground/unexplored)
|
|
|
|
// Generate deep space ruins
|
|
var/list/space_ruins = levels_by_trait(ZTRAIT_SPACE_RUINS)
|
|
if (space_ruins.len)
|
|
seedRuins(space_ruins, CONFIG_GET(number/space_budget), list(/area/space), space_ruins_templates)
|
|
seedStation()
|
|
loading_ruins = FALSE
|
|
#endif
|
|
|
|
//Load Reebe
|
|
var/list/errorList = list()
|
|
var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE)
|
|
if(errorList.len) // reebe failed to load
|
|
message_admins("Reebe failed to load!")
|
|
log_game("Reebe failed to load!")
|
|
for(var/datum/parsed_map/PM in reebes)
|
|
PM.initTemplateBounds()
|
|
//Load an Arena
|
|
errorList = list()
|
|
var/list/arenas = SSmapping.LoadGroup(errorList, "Arena", "templates", "arena.dmm", silent = TRUE)
|
|
if(errorList.len) // arena failed to load
|
|
message_admins("A shuttle arena failed to load!")
|
|
log_game("A shuttle arena failed to load!")
|
|
for(var/datum/parsed_map/PM in arenas)
|
|
PM.initTemplateBounds()
|
|
// Add the transit level
|
|
transit = add_new_zlevel("Transit/Reserved", list(ZTRAIT_RESERVED = TRUE))
|
|
require_area_resort()
|
|
// Set up Z-level transitions.
|
|
setup_map_transitions()
|
|
generate_station_area_list()
|
|
initialize_reserved_level()
|
|
// Build minimaps
|
|
build_minimaps()
|
|
return SS_INIT_SUCCESS
|
|
|
|
/datum/controller/subsystem/mapping/fire(resumed)
|
|
// Cache for sonic speed
|
|
var/list/unused_turfs = src.unused_turfs
|
|
var/list/world_contents = GLOB.areas_by_type[world.area].contents
|
|
var/list/world_turf_contents = GLOB.areas_by_type[world.area].contained_turfs
|
|
var/list/lists_to_reserve = src.lists_to_reserve
|
|
var/index = 0
|
|
while(index < length(lists_to_reserve))
|
|
var/list/packet = lists_to_reserve[index + 1]
|
|
var/packetlen = length(packet)
|
|
while(packetlen)
|
|
if(MC_TICK_CHECK)
|
|
lists_to_reserve.Cut(1, index)
|
|
return
|
|
var/turf/T = packet[packetlen]
|
|
T.empty(RESERVED_TURF_TYPE, RESERVED_TURF_TYPE, null, TRUE)
|
|
LAZYINITLIST(unused_turfs["[T.z]"])
|
|
unused_turfs["[T.z]"] |= T
|
|
var/area/old_area = T.loc
|
|
old_area.turfs_to_uncontain += T
|
|
T.flags_1 |= UNUSED_RESERVATION_TURF_1
|
|
world_contents += T
|
|
world_turf_contents += T
|
|
packet.len--
|
|
packetlen = length(packet)
|
|
|
|
index++
|
|
lists_to_reserve.Cut(1, index)
|
|
|
|
/datum/controller/subsystem/mapping/proc/wipe_reservations(wipe_safety_delay = 100)
|
|
if(clearing_reserved_turfs || !initialized) //in either case this is just not needed.
|
|
return
|
|
clearing_reserved_turfs = TRUE
|
|
SSshuttle.transit_requesters.Cut()
|
|
message_admins("Clearing dynamic reservation space.")
|
|
var/list/obj/docking_port/mobile/in_transit = list()
|
|
for(var/i in SSshuttle.transit)
|
|
var/obj/docking_port/stationary/transit/T = i
|
|
if(!istype(T))
|
|
continue
|
|
in_transit[T] = T.get_docked()
|
|
var/go_ahead = world.time + wipe_safety_delay
|
|
if(in_transit.len)
|
|
message_admins("Shuttles in transit detected. Attempting to fast travel. Timeout is [wipe_safety_delay/10] seconds.")
|
|
var/list/cleared = list()
|
|
for(var/i in in_transit)
|
|
INVOKE_ASYNC(src, .proc/safety_clear_transit_dock, i, in_transit[i], cleared)
|
|
UNTIL((go_ahead < world.time) || (cleared.len == in_transit.len))
|
|
do_wipe_turf_reservations()
|
|
clearing_reserved_turfs = FALSE
|
|
|
|
/datum/controller/subsystem/mapping/proc/safety_clear_transit_dock(obj/docking_port/stationary/transit/T, obj/docking_port/mobile/M, list/returning)
|
|
M.setTimer(0)
|
|
var/error = M.initiate_docking(M.destination, M.preferred_direction)
|
|
if(!error)
|
|
returning += M
|
|
qdel(T, TRUE)
|
|
|
|
/* Nuke threats, for making the blue tiles on the station go RED
|
|
Used by the AI doomsday and the self destruct nuke.
|
|
*/
|
|
|
|
/datum/controller/subsystem/mapping/proc/add_nuke_threat(datum/nuke)
|
|
nuke_threats[nuke] = TRUE
|
|
check_nuke_threats()
|
|
|
|
/datum/controller/subsystem/mapping/proc/remove_nuke_threat(datum/nuke)
|
|
nuke_threats -= nuke
|
|
check_nuke_threats()
|
|
|
|
/datum/controller/subsystem/mapping/proc/check_nuke_threats()
|
|
for(var/datum/d in nuke_threats)
|
|
if(!istype(d) || QDELETED(d))
|
|
nuke_threats -= d
|
|
|
|
for(var/N in nuke_tiles)
|
|
var/turf/open/floor/circuit/C = N
|
|
C.update_icon()
|
|
|
|
/datum/controller/subsystem/mapping/Recover()
|
|
flags |= SS_NO_INIT
|
|
initialized = SSmapping.initialized
|
|
map_templates = SSmapping.map_templates
|
|
ruins_templates = SSmapping.ruins_templates
|
|
space_ruins_templates = SSmapping.space_ruins_templates
|
|
lava_ruins_templates = SSmapping.lava_ruins_templates
|
|
ice_ruins_templates = SSmapping.ice_ruins_templates
|
|
ice_ruins_underground_templates = SSmapping.ice_ruins_underground_templates
|
|
shuttle_templates = SSmapping.shuttle_templates
|
|
shelter_templates = SSmapping.shelter_templates
|
|
unused_turfs = SSmapping.unused_turfs
|
|
turf_reservations = SSmapping.turf_reservations
|
|
used_turfs = SSmapping.used_turfs
|
|
|
|
config = SSmapping.config
|
|
next_map_config = SSmapping.next_map_config
|
|
|
|
clearing_reserved_turfs = SSmapping.clearing_reserved_turfs
|
|
|
|
z_list = SSmapping.z_list
|
|
|
|
#define INIT_ANNOUNCE(X) to_chat(world, span_boldannounce("[X]")); log_world(X)
|
|
/datum/controller/subsystem/mapping/proc/LoadGroup(list/errorList, name, path, files, list/traits, list/default_traits, silent = FALSE)
|
|
. = list()
|
|
var/start_time = REALTIMEOFDAY
|
|
|
|
if (!islist(files)) // handle single-level maps
|
|
files = list(files)
|
|
|
|
// check that the total z count of all maps matches the list of traits
|
|
var/total_z = 0
|
|
var/list/parsed_maps = list()
|
|
for (var/file in files)
|
|
var/full_path = "_maps/[path]/[file]"
|
|
var/datum/parsed_map/pm = new(file(full_path))
|
|
var/bounds = pm?.bounds
|
|
if (!bounds)
|
|
errorList |= full_path
|
|
continue
|
|
parsed_maps[pm] = total_z // save the start Z of this file
|
|
total_z += bounds[MAP_MAXZ] - bounds[MAP_MINZ] + 1
|
|
|
|
if (!length(traits)) // null or empty - default
|
|
for (var/i in 1 to total_z)
|
|
traits += list(default_traits)
|
|
else if (total_z != traits.len) // mismatch
|
|
INIT_ANNOUNCE("WARNING: [traits.len] trait sets specified for [total_z] z-levels in [path]!")
|
|
if (total_z < traits.len) // ignore extra traits
|
|
traits.Cut(total_z + 1)
|
|
while (total_z > traits.len) // fall back to defaults on extra levels
|
|
traits += list(default_traits)
|
|
|
|
// preload the relevant space_level datums
|
|
var/start_z = world.maxz + 1
|
|
var/i = 0
|
|
for (var/level in traits)
|
|
add_new_zlevel("[name][i ? " [i + 1]" : ""]", level, contain_turfs = FALSE)
|
|
++i
|
|
|
|
// load the maps
|
|
for (var/P in parsed_maps)
|
|
var/datum/parsed_map/pm = P
|
|
if (!pm.load(1, 1, start_z + parsed_maps[P], no_changeturf = TRUE, new_z = TRUE))
|
|
errorList |= pm.original_path
|
|
if(!silent)
|
|
INIT_ANNOUNCE("Loaded [name] in [(REALTIMEOFDAY - start_time)/10]s!")
|
|
return parsed_maps
|
|
|
|
/datum/controller/subsystem/mapping/proc/loadWorld()
|
|
//if any of these fail, something has gone horribly, HORRIBLY, wrong
|
|
var/list/FailedZs = list()
|
|
|
|
// ensure we have space_level datums for compiled-in maps
|
|
InitializeDefaultZLevels()
|
|
|
|
// 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)
|
|
|
|
if(SSdbcore.Connect())
|
|
var/datum/DBQuery/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))
|
|
query_round_map_name.Execute()
|
|
qdel(query_round_map_name)
|
|
|
|
#ifndef LOWMEMORYMODE
|
|
// TODO: remove this when the DB is prepared for the z-levels getting reordered
|
|
while (world.maxz < (5 - 1) && space_levels_so_far < config.space_ruin_levels)
|
|
++space_levels_so_far
|
|
add_new_zlevel("Empty Area [space_levels_so_far]", ZTRAITS_SPACE)
|
|
|
|
// load mining
|
|
if(config.minetype == "lavaland")
|
|
LoadGroup(FailedZs, "Lavaland", "map_files/mining", "Lavaland.dmm", default_traits = ZTRAITS_LAVALAND) //Yogs, yoglavaland
|
|
else if(config.minetype == "icemoon")
|
|
LoadGroup(FailedZs, "Ice moon", "map_files/mining", "Icemoon.dmm", default_traits = ZTRAITS_ICEMOON)
|
|
LoadGroup(FailedZs, "Ice moon Underground", "map_files/mining", "IcemoonUnderground.dmm", default_traits = ZTRAITS_ICEMOON_UNDERGROUND)
|
|
else if (!isnull(config.minetype))
|
|
INIT_ANNOUNCE("WARNING: An unknown minetype '[config.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
|
|
var/msg = "RED ALERT! The following map files failed to load: [FailedZs[1]]"
|
|
if(FailedZs.len > 1)
|
|
for(var/I in 2 to FailedZs.len)
|
|
msg += ", [FailedZs[I]]"
|
|
msg += ". Yell at your server host!"
|
|
INIT_ANNOUNCE(msg)
|
|
#undef INIT_ANNOUNCE
|
|
|
|
GLOBAL_LIST_EMPTY(the_station_areas)
|
|
|
|
/datum/controller/subsystem/mapping/proc/generate_station_area_list()
|
|
var/list/station_areas_blacklist = typecacheof(list(/area/space, /area/mine, /area/ruin, /area/asteroid/nearstation))
|
|
for(var/area/A in GLOB.areas)
|
|
if (is_type_in_typecache(A, station_areas_blacklist))
|
|
continue
|
|
if (!A.contents.len || !A.unique)
|
|
continue
|
|
var/turf/picked = A.contents[1]
|
|
if (is_station_level(picked.z))
|
|
GLOB.the_station_areas += A.type
|
|
|
|
if(!GLOB.the_station_areas.len)
|
|
log_world("ERROR: Station areas list failed to generate!")
|
|
|
|
/datum/controller/subsystem/mapping/proc/run_map_generation()
|
|
for(var/area/A as anything in GLOB.areas)
|
|
A.RunGeneration()
|
|
|
|
/datum/controller/subsystem/mapping/proc/maprotate()
|
|
if(map_voted)
|
|
map_voted = FALSE
|
|
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)
|
|
if (!(map in global.config.maplist))
|
|
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 = pickweight(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/changemap(var/datum/map_config/VM)
|
|
if(!VM.MakeNextMap())
|
|
next_map_config = load_map_config(default_to_box = TRUE)
|
|
message_admins("Failed to set new map with next_map.json for [VM.map_name]! Using default as backup!")
|
|
return
|
|
|
|
next_map_config = VM
|
|
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)
|
|
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
|
|
map_templates[T.name] = T
|
|
|
|
preloadRuinTemplates()
|
|
preloadShuttleTemplates()
|
|
preloadShelterTemplates()
|
|
|
|
/datum/controller/subsystem/mapping/proc/preloadRuinTemplates()
|
|
// Still supporting bans by filename
|
|
var/list/banned = generateMapList("[global.config.directory]/lavaruinblacklist.txt")
|
|
banned += generateMapList("[global.config.directory]/spaceruinblacklist.txt")
|
|
banned += generateMapList("[global.config.directory]/iceruinblacklist.txt")
|
|
|
|
for(var/item in sortList(subtypesof(/datum/map_template/ruin), /proc/cmp_ruincost_priority))
|
|
var/datum/map_template/ruin/ruin_type = item
|
|
// screen out the abstract subtypes
|
|
if(!initial(ruin_type.id))
|
|
continue
|
|
var/datum/map_template/ruin/R = new ruin_type()
|
|
|
|
if(banned.Find(R.mappath))
|
|
continue
|
|
|
|
map_templates[R.name] = R
|
|
ruins_templates[R.name] = R
|
|
|
|
if(istype(R, /datum/map_template/ruin/lavaland))
|
|
lava_ruins_templates[R.name] = R
|
|
else if(istype(R, /datum/map_template/ruin/icemoon/underground))
|
|
ice_ruins_underground_templates[R.name] = R
|
|
else if(istype(R, /datum/map_template/ruin/icemoon))
|
|
ice_ruins_templates[R.name] = R
|
|
else if(istype(R, /datum/map_template/ruin/space))
|
|
space_ruins_templates[R.name] = R
|
|
else if(istype(R, /datum/map_template/ruin/station)) //yogs
|
|
station_room_templates[R.name] = R //yogs
|
|
|
|
/datum/controller/subsystem/mapping/proc/preloadShuttleTemplates()
|
|
var/list/unbuyable = generateMapList("[global.config.directory]/unbuyableshuttles.txt")
|
|
|
|
for(var/item in subtypesof(/datum/map_template/shuttle))
|
|
var/datum/map_template/shuttle/shuttle_type = item
|
|
if(!(initial(shuttle_type.suffix)))
|
|
continue
|
|
|
|
var/datum/map_template/shuttle/S = new shuttle_type()
|
|
if(unbuyable.Find(S.mappath))
|
|
S.credit_cost = INFINITY
|
|
|
|
shuttle_templates[S.shuttle_id] = S
|
|
map_templates[S.shuttle_id] = S
|
|
|
|
/datum/controller/subsystem/mapping/proc/preloadShelterTemplates()
|
|
for(var/item in subtypesof(/datum/map_template/shelter))
|
|
var/datum/map_template/shelter/shelter_type = item
|
|
if(!(initial(shelter_type.mappath)))
|
|
continue
|
|
var/datum/map_template/shelter/S = new shelter_type()
|
|
|
|
shelter_templates[S.shelter_id] = S
|
|
map_templates[S.shelter_id] = S
|
|
|
|
//Manual loading of away missions.
|
|
/client/proc/admin_away()
|
|
set name = "Load Away Mission"
|
|
set category = "Misc.Server Debug"
|
|
|
|
if(!holder ||!check_rights(R_FUN))
|
|
return
|
|
|
|
|
|
if(!GLOB.the_gateway)
|
|
if(tgui_alert(usr, "There's no home gateway on the station. You sure you want to continue ?", "Uh oh", list("Yes", "No")) != "Yes")
|
|
return
|
|
|
|
var/list/possible_options = GLOB.potentialRandomZlevels + "Custom"
|
|
var/away_name
|
|
var/datum/space_level/away_level
|
|
var/secret = FALSE
|
|
if(tgui_alert(usr, "Do you want your mission secret? (This will prevent ghosts from looking at your map in any way other than through a living player's eyes.)", "Are you $$$ekret?", list("Yes", "No")) != "No")
|
|
secret = TRUE
|
|
var/answer = input("What kind?","Away") as null|anything in possible_options
|
|
switch(answer)
|
|
if("Custom")
|
|
var/mapfile = input("Pick file:", "File") as null|file
|
|
if(!mapfile)
|
|
return
|
|
away_name = "[mapfile] custom"
|
|
to_chat(usr,span_notice("Loading [away_name]..."))
|
|
var/datum/map_template/template = new(mapfile, "Away Mission")
|
|
away_level = template.load_new_z(secret)
|
|
else
|
|
if(answer in GLOB.potentialRandomZlevels)
|
|
away_name = answer
|
|
to_chat(usr,span_notice("Loading [away_name]..."))
|
|
var/datum/map_template/template = new(away_name, "Away Mission")
|
|
away_level = template.load_new_z(secret)
|
|
else
|
|
return
|
|
|
|
message_admins("Admin [key_name_admin(usr)] has loaded [away_name] away mission.")
|
|
log_admin("Admin [key_name(usr)] has loaded [away_name] away mission.")
|
|
if(!away_level)
|
|
message_admins("Loading [away_name] failed!")
|
|
return
|
|
|
|
|
|
if(GLOB.the_gateway)
|
|
//Link any found away gate with station gate
|
|
var/obj/machinery/gateway/centeraway/new_gate
|
|
for(var/obj/machinery/gateway/centeraway/G in GLOB.machines)
|
|
if(G.z == away_level.z_value) //I'll have to refactor gateway shitcode before multi-away support.
|
|
new_gate = G
|
|
break
|
|
//Link station gate with away gate and remove wait time.
|
|
GLOB.the_gateway.awaygate = new_gate
|
|
GLOB.the_gateway.wait = world.time
|
|
|
|
/datum/controller/subsystem/mapping/proc/RequestBlockReservation(width, height, z, type = /datum/turf_reservation, turf_type_override)
|
|
UNTIL(initialized && !clearing_reserved_turfs)
|
|
var/datum/turf_reservation/reserve = new type
|
|
if(turf_type_override)
|
|
reserve.turf_type = turf_type_override
|
|
if(!z)
|
|
for(var/i in levels_by_trait(ZTRAIT_RESERVED))
|
|
if(reserve.Reserve(width, height, i))
|
|
return reserve
|
|
//If we didn't return at this point, theres a good chance we ran out of room on the exisiting reserved z levels, so lets try a new one
|
|
num_of_res_levels += 1
|
|
var/datum/space_level/newReserved = add_new_zlevel("Transit/Reserved [num_of_res_levels]", list(ZTRAIT_RESERVED = TRUE))
|
|
initialize_reserved_level(newReserved.z_value)
|
|
if(reserve.Reserve(width, height, newReserved.z_value))
|
|
return reserve
|
|
else
|
|
if(!level_trait(z, ZTRAIT_RESERVED))
|
|
qdel(reserve)
|
|
return
|
|
else
|
|
if(reserve.Reserve(width, height, z))
|
|
return reserve
|
|
QDEL_NULL(reserve)
|
|
|
|
//This is not for wiping reserved levels, use wipe_reservations() for that.
|
|
/datum/controller/subsystem/mapping/proc/initialize_reserved_level()
|
|
UNTIL(!clearing_reserved_turfs) //regardless, lets add a check just in case.
|
|
clearing_reserved_turfs = TRUE //This operation will likely clear any existing reservations, so lets make sure nothing tries to make one while we're doing it.
|
|
for(var/i in levels_by_trait(ZTRAIT_RESERVED))
|
|
var/turf/A = get_turf(locate(SHUTTLE_TRANSIT_BORDER,SHUTTLE_TRANSIT_BORDER,i))
|
|
var/turf/B = get_turf(locate(world.maxx - SHUTTLE_TRANSIT_BORDER,world.maxy - SHUTTLE_TRANSIT_BORDER,i))
|
|
var/block = block(A, B)
|
|
for(var/t in block)
|
|
// No need to empty() these, because it's world init and they're
|
|
// already /turf/open/space/basic.
|
|
var/turf/T = t
|
|
T.flags_1 |= UNUSED_RESERVATION_TURF_1
|
|
unused_turfs["[i]"] = block
|
|
clearing_reserved_turfs = FALSE
|
|
|
|
/// Schedules a group of turfs to be handed back to the reservation system's control
|
|
/// If await is true, will sleep until the turfs are finished work
|
|
/datum/controller/subsystem/mapping/proc/reserve_turfs(list/turfs, await = FALSE)
|
|
lists_to_reserve += list(turfs)
|
|
if(await)
|
|
UNTIL(!length(turfs))
|
|
|
|
//DO NOT CALL THIS PROC DIRECTLY, CALL wipe_reservations().
|
|
/datum/controller/subsystem/mapping/proc/do_wipe_turf_reservations()
|
|
PRIVATE_PROC(TRUE)
|
|
UNTIL(initialized) //This proc is for AFTER init, before init turf reservations won't even exist and using this will likely break things.
|
|
for(var/i in turf_reservations)
|
|
var/datum/turf_reservation/TR = i
|
|
if(!QDELETED(TR))
|
|
qdel(TR, TRUE)
|
|
UNSETEMPTY(turf_reservations)
|
|
var/list/clearing = list()
|
|
for(var/l in unused_turfs) //unused_turfs is a assoc list by z = list(turfs)
|
|
if(islist(unused_turfs[l]))
|
|
clearing |= unused_turfs[l]
|
|
clearing |= used_turfs //used turfs is an associative list, BUT, reserve_turfs() can still handle it. If the code above works properly, this won't even be needed as the turfs would be freed already.
|
|
unused_turfs.Cut()
|
|
used_turfs.Cut()
|
|
reserve_turfs(clearing, await = TRUE)
|
|
|
|
/datum/controller/subsystem/mapping/proc/build_minimaps()
|
|
to_chat(world, span_boldannounce("Building minimaps..."))
|
|
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
|
station_minimaps += new /datum/minimap(z)
|
|
|
|
/datum/controller/subsystem/mapping/proc/reg_in_areas_in_z(list/areas)
|
|
for(var/B in areas)
|
|
var/area/A = B
|
|
A.reg_in_areas_in_z()
|
|
|
|
/datum/controller/subsystem/mapping/proc/build_area_turfs(z_level, space_guaranteed)
|
|
// If we know this is filled with default tiles, we can use the default area
|
|
// Faster
|
|
if(space_guaranteed)
|
|
var/area/global_area = GLOB.areas_by_type[world.area]
|
|
global_area.contained_turfs += Z_TURFS(z_level)
|
|
return
|
|
|
|
for(var/turf/to_contain as anything in Z_TURFS(z_level))
|
|
var/area/our_area = to_contain.loc
|
|
our_area.contained_turfs += to_contain
|