mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-28 07:38:05 +01:00
Runtime Dynamic Station Loading (#24171)
* Dynamic map loading prototype * Get the title screen working * Fixes the random pod bugs * map configs * Add back the asteroid * Ignore the rotate file * Fix some shit * More shit fixes * Babby's first json * Cyberboss confirmed shitcoder * Makes map rotation great again * Moves the map defines * Delete tgstation2.dm * Convert runtimestation * Convert PubbyStation * Convert OmegaStation * Convert Metastation * Convert Delta Station * Lol file extensions * Reee line endings * Take out the trash * Fix loadallmaps.dm * Deltaassssssstation? * Fix travis * Did I ASK you to change the line endings? * Remove votable maps * Cleanup * Previous config. Load configs in New. Fix splash * Fix this * More generic minetype * STOP TOUCHING THE LINE ENDINGS!!! * Add some flexibility to /obj/screen/splash * Fix the shit * Update gitignore * Smooth transition from last map * Better check * Missed this map rotate check * Remove these checks too * Prep for a future request by @kevinz000 * Fix z2 line endings * Solution for custom .dms * Rename some things, trim some fat * Fixes default map_config * Remove stale comment * Delete the previous config after loading * Don't try to open a non-existent file * Delete the old rotator script * And references to it * Line endings * More line endings * Del checks from when m-config may have not existed * LINE ENDINGS * Update the default map config * Map load error checking for what it's worth * Small cleanup * For case sensitive * File systems * Strip maprotate stuff from build script * Spruce up the _maps tree. Compile some empty space * Make travis simpler * LINEARU ENDARU!!! * tgstation TWO!!! * Lowercase mine type * Dummy dm's for testmerging * Fixes job ordering * If ghosts wanna watch the map load so be it * Let them know what's going on * Fixes z-transitions * Optimize z expansion further * Remove this old var * Fix wiznerd teleportation * Rmove butt * Does the thing * Moved temp configs to the data dir * Un-touch gitignore * Forgot templates.dm * Forgot to include the includer * Fair enough * SILENCE IMBECILE! * @Cyberboss still a fuckboi * Speed things up a bit * Fix a potential bug with the error message * Whatever
This commit is contained in:
@@ -350,9 +350,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
|
||||
//if find_references isn't working for some datum
|
||||
//update this list using tools/DMTreeToGlobalsList
|
||||
/datum/proc/find_references_in_globals()
|
||||
SearchVar(nextmap)
|
||||
SearchVar(mapchanging)
|
||||
SearchVar(rebootingpendingmapchange)
|
||||
SearchVar(clockwork_construction_value)
|
||||
SearchVar(clockwork_caches)
|
||||
SearchVar(clockwork_daemons)
|
||||
@@ -481,7 +478,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
|
||||
SearchVar(CELLRATE)
|
||||
SearchVar(CHARGELEVEL)
|
||||
SearchVar(powernets)
|
||||
SearchVar(map_name)
|
||||
SearchVar(hair_styles_list)
|
||||
SearchVar(hair_styles_male_list)
|
||||
SearchVar(hair_styles_female_list)
|
||||
|
||||
@@ -39,6 +39,9 @@ var/datum/subsystem/job/SSjob
|
||||
continue
|
||||
if(!job.config_check())
|
||||
continue
|
||||
if(!job.map_check()) //Even though we initialize before mapping, this is fine because the config is loaded at new
|
||||
testing("Removed [job.type] due to map config");
|
||||
continue
|
||||
occupations += job
|
||||
name_occupations[job.title] = job
|
||||
type_occupations[J] = job
|
||||
|
||||
@@ -8,6 +8,10 @@ var/datum/subsystem/mapping/SSmapping
|
||||
var/list/nuke_tiles = list()
|
||||
var/list/nuke_threats = list()
|
||||
|
||||
var/datum/map_config/previous_map_config
|
||||
var/datum/map_config/config
|
||||
var/datum/map_config/next_map_config
|
||||
|
||||
var/list/map_templates = list()
|
||||
|
||||
var/list/ruins_templates = list()
|
||||
@@ -19,18 +23,29 @@ var/datum/subsystem/mapping/SSmapping
|
||||
|
||||
/datum/subsystem/mapping/New()
|
||||
NEW_SS_GLOBAL(SSmapping)
|
||||
if(!previous_map_config)
|
||||
previous_map_config = new("data/previous_map.json", delete_after = TRUE)
|
||||
if(previous_map_config.defaulted)
|
||||
previous_map_config = null
|
||||
if(!config)
|
||||
config = new
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/subsystem/mapping/Initialize(timeofday)
|
||||
if(config.defaulted)
|
||||
world << "<span class='boldannounce'>Unable to load next map config, defaulting to Box Station</span>"
|
||||
loadWorld()
|
||||
SortAreas()
|
||||
process_teleport_locs() //Sets up the wizard teleport locations
|
||||
preloadTemplates()
|
||||
// Pick a random away mission.
|
||||
createRandomZlevel()
|
||||
// Generate mining.
|
||||
|
||||
var/mining_type = MINETYPE
|
||||
var/mining_type = config.minetype
|
||||
if (mining_type == "lavaland")
|
||||
seedRuins(list(5), config.lavaland_budget, /area/lavaland/surface/outdoors, lava_ruins_templates)
|
||||
seedRuins(list(5), global.config.lavaland_budget, /area/lavaland/surface/outdoors, lava_ruins_templates)
|
||||
spawn_rivers()
|
||||
|
||||
// deep space ruins
|
||||
@@ -42,7 +57,7 @@ var/datum/subsystem/mapping/SSmapping
|
||||
else
|
||||
space_zlevels += i
|
||||
|
||||
seedRuins(space_zlevels, config.space_budget, /area/space, space_ruins_templates)
|
||||
seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates)
|
||||
|
||||
// Set up Z-level transistions.
|
||||
setup_map_transitions()
|
||||
@@ -80,6 +95,108 @@ var/datum/subsystem/mapping/SSmapping
|
||||
shuttle_templates = SSmapping.shuttle_templates
|
||||
shelter_templates = SSmapping.shelter_templates
|
||||
|
||||
previous_map_config = SSmapping.previous_map_config
|
||||
config = SSmapping.config
|
||||
next_map_config = SSmapping.next_map_config
|
||||
|
||||
/datum/subsystem/mapping/proc/TryLoadZ(filename, errorList, forceLevel, last)
|
||||
var/static/dmm_suite/loader
|
||||
if(!loader)
|
||||
loader = new
|
||||
if(!loader.load_map(file(filename), 0, 0, forceLevel, no_changeturf = TRUE))
|
||||
errorList |= filename
|
||||
if(last)
|
||||
QDEL_NULL(loader)
|
||||
|
||||
/datum/subsystem/mapping/proc/CreateSpace()
|
||||
++world.maxz
|
||||
CHECK_TICK
|
||||
for(var/T in block(locate(1, 1, world.maxz), locate(world.maxx, world.maxy, world.maxz)))
|
||||
CHECK_TICK
|
||||
new /turf/open/space(T)
|
||||
|
||||
#define INIT_ANNOUNCE(X) world << "<span class='boldannounce'>[X]</span>"; log_world(X)
|
||||
/datum/subsystem/mapping/proc/loadWorld()
|
||||
//if any of these fail, something has gone horribly, HORRIBLY, wrong
|
||||
var/list/FailedZs = list()
|
||||
|
||||
INIT_ANNOUNCE("Loading [config.map_name]...")
|
||||
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
|
||||
INIT_ANNOUNCE("Loaded station!")
|
||||
|
||||
INIT_ANNOUNCE("Loading mining level...")
|
||||
TryLoadZ("_maps/map_files/generic/[config.minetype].dmm", FailedZs, ZLEVEL_MINING, TRUE)
|
||||
INIT_ANNOUNCE("Loaded mining level!")
|
||||
|
||||
for(var/I in (ZLEVEL_MINING + 1) to ZLEVEL_SPACEMAX)
|
||||
CreateSpace()
|
||||
|
||||
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 += ", [I]"
|
||||
msg += ". Yell at your server host!"
|
||||
INIT_ANNOUNCE(msg)
|
||||
#undef INIT_ANNOUNCE
|
||||
|
||||
/datum/subsystem/mapping/proc/maprotate()
|
||||
var/players = clients.len
|
||||
var/list/mapvotes = list()
|
||||
//count votes
|
||||
for (var/client/c in clients)
|
||||
var/vote = c.prefs.preferred_map
|
||||
if (!vote)
|
||||
if (global.config.defaultmap)
|
||||
mapvotes[global.config.defaultmap.map_name] += 1
|
||||
continue
|
||||
mapvotes[vote] += 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
|
||||
|
||||
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 (.)
|
||||
world << "<span class='boldannounce'>Map rotation has chosen [VM.map_name] for next round!</span>"
|
||||
|
||||
/datum/subsystem/mapping/proc/changemap(var/datum/map_config/VM)
|
||||
if(!VM.MakeNextMap())
|
||||
next_map_config = new(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/subsystem/mapping/Shutdown()
|
||||
if(config)
|
||||
config.MakePreviousMap()
|
||||
|
||||
/datum/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup
|
||||
var/list/filelist = flist(path)
|
||||
for(var/map in filelist)
|
||||
@@ -136,4 +253,4 @@ var/datum/subsystem/mapping/SSmapping
|
||||
var/datum/map_template/shelter/S = new shelter_type()
|
||||
|
||||
shelter_templates[S.shelter_id] = S
|
||||
map_templates[S.shelter_id] = S
|
||||
map_templates[S.shelter_id] = S
|
||||
|
||||
@@ -13,7 +13,7 @@ var/datum/subsystem/minimap/SSminimap
|
||||
NEW_SS_GLOBAL(SSminimap)
|
||||
|
||||
/datum/subsystem/minimap/Initialize(timeofday)
|
||||
var/hash = md5(file2text("_maps/[MAP_PATH]/[MAP_FILE]"))
|
||||
var/hash = md5(SSmapping.config.GetFullMapPath())
|
||||
if(config.generate_minimaps)
|
||||
if(hash == trim(file2text(hash_path())))
|
||||
for(var/z in z_levels) //We have these files cached, let's register them
|
||||
@@ -45,22 +45,22 @@ var/datum/subsystem/minimap/SSminimap
|
||||
for(var/z in z_levels)
|
||||
if(!fexists(file(map_path(z,backup)))) //Let's make sure we have a file for this map
|
||||
if(backup)
|
||||
log_world("Failed to find backup file for map [MAP_NAME] on zlevel [z].")
|
||||
log_world("Failed to find backup file for map [SSmapping.config.map_name] on zlevel [z].")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/subsystem/minimap/proc/hash_path(backup)
|
||||
if(backup)
|
||||
return "icons/minimaps/[MAP_NAME].md5"
|
||||
return "icons/minimaps/[SSmapping.config.map_name].md5"
|
||||
else
|
||||
return "data/minimaps/[MAP_NAME].md5"
|
||||
return "data/minimaps/[SSmapping.config.map_name].md5"
|
||||
|
||||
/datum/subsystem/minimap/proc/map_path(z,backup)
|
||||
if(backup)
|
||||
return "icons/minimaps/[MAP_NAME]_[z].png"
|
||||
return "icons/minimaps/[SSmapping.config.map_name]_[z].png"
|
||||
else
|
||||
return "data/minimaps/[MAP_NAME]_[z].png"
|
||||
return "data/minimaps/[SSmapping.config.map_name]_[z].png"
|
||||
|
||||
/datum/subsystem/minimap/proc/send(client/client)
|
||||
for(var/z in z_levels)
|
||||
|
||||
@@ -25,7 +25,7 @@ var/datum/subsystem/persistence/SSpersistence
|
||||
/datum/subsystem/persistence/proc/LoadSatchels()
|
||||
secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
|
||||
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/weapon/crowbar))
|
||||
secret_satchels[MAP_NAME] >> old_secret_satchels
|
||||
secret_satchels[SSmapping.config.map_name] >> old_secret_satchels
|
||||
|
||||
var/list/expanded_old_satchels = list()
|
||||
var/placed_satchels = 0
|
||||
@@ -51,7 +51,7 @@ var/datum/subsystem/persistence/SSpersistence
|
||||
satchel_string = pick_n_take(expanded_old_satchels)
|
||||
|
||||
old_secret_satchels = jointext(expanded_old_satchels,"#")
|
||||
secret_satchels[MAP_NAME] << old_secret_satchels
|
||||
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
|
||||
|
||||
var/list/chosen_satchel = splittext(satchel_string,"|")
|
||||
if(!chosen_satchel || isemptylist(chosen_satchel) || chosen_satchel.len != 3) //Malformed
|
||||
@@ -78,7 +78,7 @@ var/datum/subsystem/persistence/SSpersistence
|
||||
/datum/subsystem/persistence/proc/LoadChiselMessages()
|
||||
chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
var/saved_json
|
||||
chisel_messages_sav[MAP_NAME] >> saved_json
|
||||
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
|
||||
|
||||
if(!saved_json)
|
||||
return
|
||||
@@ -118,13 +118,13 @@ var/datum/subsystem/persistence/SSpersistence
|
||||
if(isemptylist(savable_obj))
|
||||
continue
|
||||
old_secret_satchels += "[F.x]|[F.y]|[pick(savable_obj)]#"
|
||||
secret_satchels[MAP_NAME] << old_secret_satchels
|
||||
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
|
||||
|
||||
/datum/subsystem/persistence/proc/CollectChiselMessages()
|
||||
for(var/obj/structure/chisel_message/M in chisel_messages)
|
||||
saved_messages += list(M.pack())
|
||||
|
||||
chisel_messages_sav[MAP_NAME] << json_encode(saved_messages)
|
||||
chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages)
|
||||
|
||||
/datum/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
|
||||
saved_messages += list(M.pack()) // dm eats one list.
|
||||
|
||||
@@ -613,7 +613,7 @@ var/datum/subsystem/ticker/ticker
|
||||
queue_delay = 0
|
||||
|
||||
/datum/subsystem/ticker/proc/check_maprotate()
|
||||
if (!config.maprotation || !SERVERTOOLS)
|
||||
if (!config.maprotation)
|
||||
return
|
||||
if (SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall())
|
||||
return
|
||||
@@ -625,7 +625,7 @@ var/datum/subsystem/ticker/ticker
|
||||
//map rotate chance defaults to 75% of the length of the round (in minutes)
|
||||
if (!prob((world.time/600)*config.maprotatechancedelta))
|
||||
return
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /.proc/maprotate)
|
||||
INVOKE_ASYNC(SSmapping, /datum/subsystem/mapping/.proc/maprotate)
|
||||
|
||||
|
||||
/world/proc/has_round_started()
|
||||
|
||||
@@ -2,11 +2,10 @@ var/datum/subsystem/title/SStitle
|
||||
|
||||
/datum/subsystem/title
|
||||
name = "Title Screen"
|
||||
init_order = INFINITY //It's the very first thing you see, don't make it wait!
|
||||
init_order = 15
|
||||
flags = SS_NO_FIRE
|
||||
var/turf/closed/indestructible/splashscreen/title_screen
|
||||
|
||||
|
||||
/datum/subsystem/title/New()
|
||||
NEW_SS_GLOBAL(SStitle)
|
||||
|
||||
@@ -15,27 +14,26 @@ var/datum/subsystem/title/SStitle
|
||||
var/list/title_screens = list()
|
||||
var/use_rare_screens = FALSE
|
||||
|
||||
if(!title_screen)
|
||||
return
|
||||
if(title_screen)
|
||||
if(prob(1))
|
||||
use_rare_screens = TRUE
|
||||
|
||||
if(prob(1))
|
||||
use_rare_screens = TRUE
|
||||
for(var/S in provisional_title_screens)
|
||||
var/list/L = splittext(S,"+")
|
||||
if((L.len == 1 && L[1] != "blank.png")|| (L.len > 1 && ((use_rare_screens && lowertext(L[1]) == "rare") || (lowertext(L[1]) == lowertext(SSmapping.config.map_name)))))
|
||||
title_screens += S
|
||||
|
||||
for(var/S in provisional_title_screens)
|
||||
var/list/L = splittext(S,"+")
|
||||
if((L.len == 1 && L[1] != "blank.png")|| (L.len > 1 && ((use_rare_screens && lowertext(L[1]) == "rare") || (lowertext(L[1]) == lowertext(MAP_NAME)))))
|
||||
title_screens += S
|
||||
if(!isemptylist(title_screens))
|
||||
if(length(title_screens) > 1)
|
||||
for(var/S in title_screens)
|
||||
var/list/L = splittext(S,".")
|
||||
if(L.len != 2 || L[1] != "default")
|
||||
continue
|
||||
title_screens -= S
|
||||
break
|
||||
|
||||
if(!isemptylist(title_screens))
|
||||
if(length(title_screens) > 1)
|
||||
for(var/S in title_screens)
|
||||
var/list/L = splittext(S,".")
|
||||
if(L.len != 2 || L[1] != "default")
|
||||
continue
|
||||
title_screens -= S
|
||||
break
|
||||
var/path_string = "config/title_screens/images/[pick(title_screens)]"
|
||||
var/icon/screen_to_use = new(path_string)
|
||||
|
||||
var/path_string = "config/title_screens/images/[pick(title_screens)]"
|
||||
var/icon/screen_to_use = new(path_string)
|
||||
|
||||
title_screen.icon = screen_to_use
|
||||
title_screen.icon = screen_to_use
|
||||
..()
|
||||
Reference in New Issue
Block a user