mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 20:20:33 +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:
@@ -116,10 +116,8 @@ var/list/admin_verbs_server = list(
|
||||
/client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/
|
||||
/client/proc/cmd_debug_del_all,
|
||||
/client/proc/toggle_random_events,
|
||||
#if SERVERTOOLS
|
||||
/client/proc/forcerandomrotate,
|
||||
/client/proc/adminchangemap,
|
||||
#endif
|
||||
/client/proc/panicbunker,
|
||||
/client/proc/toggle_hub
|
||||
|
||||
|
||||
@@ -7,27 +7,27 @@
|
||||
message_admins("[key_name_admin(usr)] is forcing a random map rotation.")
|
||||
log_admin("[key_name(usr)] is forcing a random map rotation.")
|
||||
ticker.maprotatechecked = 1
|
||||
maprotate()
|
||||
SSmapping.maprotate()
|
||||
|
||||
/client/proc/adminchangemap()
|
||||
set category = "Server"
|
||||
set name = "Change Map"
|
||||
var/list/maprotatechoices = list()
|
||||
for (var/map in config.maplist)
|
||||
var/datum/votablemap/VM = config.maplist[map]
|
||||
var/mapname = VM.friendlyname
|
||||
var/datum/map_config/VM = config.maplist[map]
|
||||
var/mapname = VM.map_name
|
||||
if (VM == config.defaultmap)
|
||||
mapname += " (Default)"
|
||||
|
||||
if (VM.minusers > 0 || VM.maxusers > 0)
|
||||
if (VM.config_min_users > 0 || VM.config_max_users > 0)
|
||||
mapname += " \["
|
||||
if (VM.minusers > 0)
|
||||
mapname += "[VM.minusers]"
|
||||
if (VM.config_min_users > 0)
|
||||
mapname += "[VM.config_min_users]"
|
||||
else
|
||||
mapname += "0"
|
||||
mapname += "-"
|
||||
if (VM.maxusers > 0)
|
||||
mapname += "[VM.maxusers]"
|
||||
if (VM.config_max_users > 0)
|
||||
mapname += "[VM.config_max_users]"
|
||||
else
|
||||
mapname += "inf"
|
||||
mapname += "\]"
|
||||
@@ -37,8 +37,8 @@
|
||||
if (!chosenmap)
|
||||
return
|
||||
ticker.maprotatechecked = 1
|
||||
var/datum/votablemap/VM = maprotatechoices[chosenmap]
|
||||
message_admins("[key_name_admin(usr)] is changing the map to [VM.name]([VM.friendlyname])")
|
||||
log_admin("[key_name(usr)] is changing the map to [VM.name]([VM.friendlyname])")
|
||||
if (changemap(VM) == 0)
|
||||
message_admins("[key_name_admin(usr)] has changed the map to [VM.name]([VM.friendlyname])")
|
||||
var/datum/map_config/VM = maprotatechoices[chosenmap]
|
||||
message_admins("[key_name_admin(usr)] is changing the map to [VM.map_name]")
|
||||
log_admin("[key_name(usr)] is changing the map to [VM.map_name]")
|
||||
if (SSmapping.changemap(VM) == 0)
|
||||
message_admins("[key_name_admin(usr)] has changed the map to [VM.map_name]")
|
||||
@@ -409,19 +409,19 @@ var/list/preferences_datums = list()
|
||||
|
||||
dat += "<b>Ghosts of Others:</b> <a href='?_src_=prefs;task=input;preference=ghostothers'>[button_name]</a><br>"
|
||||
|
||||
if (SERVERTOOLS && config.maprotation)
|
||||
if (config.maprotation)
|
||||
var/p_map = preferred_map
|
||||
if (!p_map)
|
||||
p_map = "Default"
|
||||
if (config.defaultmap)
|
||||
p_map += " ([config.defaultmap.friendlyname])"
|
||||
p_map += " ([config.defaultmap.map_name])"
|
||||
else
|
||||
if (p_map in config.maplist)
|
||||
var/datum/votablemap/VM = config.maplist[p_map]
|
||||
var/datum/map_config/VM = config.maplist[p_map]
|
||||
if (!VM)
|
||||
p_map += " (No longer exists)"
|
||||
else
|
||||
p_map = VM.friendlyname
|
||||
p_map = VM.map_name
|
||||
else
|
||||
p_map += " (No longer exists)"
|
||||
dat += "<b>Preferred Map:</b> <a href='?_src_=prefs;preference=preferred_map;task=input'>[p_map]</a><br>"
|
||||
@@ -1106,13 +1106,13 @@ var/list/preferences_datums = list()
|
||||
var/maplist = list()
|
||||
var/default = "Default"
|
||||
if (config.defaultmap)
|
||||
default += " ([config.defaultmap.friendlyname])"
|
||||
default += " ([config.defaultmap.map_name])"
|
||||
for (var/M in config.maplist)
|
||||
var/datum/votablemap/VM = config.maplist[M]
|
||||
var/friendlyname = "[VM.friendlyname] "
|
||||
var/datum/map_config/VM = config.maplist[M]
|
||||
var/friendlyname = "[VM.map_name] "
|
||||
if (VM.voteweight <= 0)
|
||||
friendlyname += " (disabled)"
|
||||
maplist[friendlyname] = VM.name
|
||||
maplist[friendlyname] = VM.map_name
|
||||
maplist[default] = null
|
||||
var/pickedmap = input(user, "Choose your preferred map. This will be used to help weight random map selection.", "Character Preference") as null|anything in maplist
|
||||
if (pickedmap)
|
||||
|
||||
@@ -110,6 +110,8 @@
|
||||
/datum/job/proc/config_check()
|
||||
return 1
|
||||
|
||||
/datum/job/proc/map_check()
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/outfit/job
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
//this needs to come after the job_types subfolder to keep the correct ordering
|
||||
|
||||
#include "..\..\..\..\_maps\map_files\OmegaStation\job_changes.dm"
|
||||
#undef JOB_MODIFICATION_MAP_NAME
|
||||
#include "..\..\..\..\_maps\map_files\PubbyStation\job_changes.dm"
|
||||
#undef JOB_MODIFICATION_MAP_NAME
|
||||
@@ -189,7 +189,7 @@
|
||||
creator_name = user.real_name
|
||||
creator_key = user.ckey
|
||||
realdate = world.timeofday
|
||||
map = MAP_NAME
|
||||
map = SSmapping.config.map_name
|
||||
update_icon()
|
||||
|
||||
/obj/structure/chisel_message/update_icon()
|
||||
@@ -204,7 +204,7 @@
|
||||
data["creator_name"] = creator_name
|
||||
data["creator_key"] = creator_key
|
||||
data["realdate"] = realdate
|
||||
data["map"] = MAP_NAME
|
||||
data["map"] = SSmapping.config.map_name
|
||||
var/turf/T = get_turf(src)
|
||||
data["x"] = T.x
|
||||
data["y"] = T.y
|
||||
|
||||
@@ -51,11 +51,12 @@ dmm_suite{
|
||||
|
||||
*/
|
||||
|
||||
verb/load_map(var/dmm_file as file, var/x_offset as num, var/y_offset as num, var/z_offset as num, var/cropMap as num, var/measureOnly as num){
|
||||
verb/load_map(var/dmm_file as file, var/x_offset as num, var/y_offset as num, var/z_offset as num, var/cropMap as num, var/measureOnly as num, no_changeturf as num){
|
||||
// dmm_file: A .dmm file to load (Required).
|
||||
// z_offset: A number representing the z-level on which to start loading the map (Optional).
|
||||
// cropMap: When true, the map will be cropped to fit the existing world dimensions (Optional).
|
||||
// measureOnly: When true, no changes will be made to the world (Optional).
|
||||
// no_changeturf: When true, turf/AfterChange won't be called on loaded turfs
|
||||
}
|
||||
verb/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
|
||||
// t1: A turf representing one corner of a three dimensional grid (Required).
|
||||
|
||||
@@ -25,13 +25,13 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
* 2) Read the map line by line, parsing the result (using parse_grid)
|
||||
*
|
||||
*/
|
||||
/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num)
|
||||
/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num, no_changeturf as num)
|
||||
//How I wish for RAII
|
||||
Master.StartLoadingMap()
|
||||
. = load_map_impl(dmm_file, x_offset, y_offset, z_offset, cropMap, measureOnly)
|
||||
. = load_map_impl(dmm_file, x_offset, y_offset, z_offset, cropMap, measureOnly, no_changeturf)
|
||||
Master.StopLoadingMap()
|
||||
|
||||
/dmm_suite/proc/load_map_impl(dmm_file, x_offset, y_offset, z_offset, cropMap, measureOnly)
|
||||
/dmm_suite/proc/load_map_impl(dmm_file, x_offset, y_offset, z_offset, cropMap, measureOnly, no_changeturf)
|
||||
var/tfile = dmm_file//the map file we're creating
|
||||
if(isfile(tfile))
|
||||
tfile = file2text(tfile)
|
||||
@@ -75,7 +75,8 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
var/ycrd = text2num(dmmRegex.group[4]) + y_offset - 1
|
||||
var/zcrd = text2num(dmmRegex.group[5]) + z_offset - 1
|
||||
|
||||
if(zcrd > world.maxz)
|
||||
var/zexpansion = zcrd > world.maxz
|
||||
if(zexpansion)
|
||||
if(cropMap)
|
||||
continue
|
||||
else
|
||||
@@ -127,7 +128,7 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
var/model_key = copytext(line, tpos, tpos + key_len)
|
||||
if(!grid_models[model_key])
|
||||
throw EXCEPTION("Undefined model key in DMM.")
|
||||
parse_grid(grid_models[model_key], xcrd, ycrd, zcrd)
|
||||
parse_grid(grid_models[model_key], xcrd, ycrd, zcrd, no_changeturf || zexpansion)
|
||||
CHECK_TICK
|
||||
|
||||
maxx = max(maxx, xcrd)
|
||||
@@ -142,10 +143,11 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
return null
|
||||
else
|
||||
if(!measureOnly)
|
||||
for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
var/turf/T = t
|
||||
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
|
||||
T.AfterChange(TRUE)
|
||||
if(!no_changeturf)
|
||||
for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
var/turf/T = t
|
||||
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
|
||||
T.AfterChange(TRUE)
|
||||
return bounds
|
||||
|
||||
/**
|
||||
@@ -165,7 +167,7 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
* 4) Instanciates the atom with its variables
|
||||
*
|
||||
*/
|
||||
/dmm_suite/proc/parse_grid(model as text,xcrd as num,ycrd as num,zcrd as num)
|
||||
/dmm_suite/proc/parse_grid(model as text,xcrd as num,ycrd as num,zcrd as num, no_changeturf as num)
|
||||
/*Method parse_grid()
|
||||
- Accepts a text string containing a comma separated list of type paths of the
|
||||
same construction as those contained in a .dmm file, and instantiates them.
|
||||
@@ -253,20 +255,20 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
//instanciate the first /turf
|
||||
var/turf/T
|
||||
if(members[first_turf_index] != /turf/template_noop)
|
||||
T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],xcrd,ycrd,zcrd)
|
||||
T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],xcrd,ycrd,zcrd,no_changeturf)
|
||||
|
||||
if(T)
|
||||
//if others /turf are presents, simulates the underlays piling effect
|
||||
index = first_turf_index + 1
|
||||
while(index <= members.len - 1) // Last item is an /area
|
||||
var/underlay = T.appearance
|
||||
T = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)//instance new turf
|
||||
T = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd,no_changeturf)//instance new turf
|
||||
T.underlays += underlay
|
||||
index++
|
||||
|
||||
//finally instance all remainings objects/mobs
|
||||
for(index in 1 to first_turf_index-1)
|
||||
instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)
|
||||
instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd,no_changeturf)
|
||||
|
||||
//custom CHECK_TICK here because we don't want things created while we're sleeping to not initialize
|
||||
if(world.tick_usage > CURRENT_TICKLIMIT)
|
||||
@@ -281,13 +283,13 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
////////////////
|
||||
|
||||
//Instance an atom at (x,y,z) and gives it the variables in attributes
|
||||
/dmm_suite/proc/instance_atom(path,list/attributes, x, y, z)
|
||||
/dmm_suite/proc/instance_atom(path,list/attributes, x, y, z, no_changeturf)
|
||||
var/atom/instance
|
||||
_preloader.setup(attributes, path)
|
||||
|
||||
var/turf/T = locate(x,y,z)
|
||||
if(T)
|
||||
if(ispath(path, /turf))
|
||||
if(!no_changeturf && ispath(path, /turf))
|
||||
T.ChangeTurf(path, TRUE)
|
||||
instance = T
|
||||
else
|
||||
|
||||
@@ -99,7 +99,7 @@ var/list/image/ghost_images_simple = list() //this is a list of all ghost images
|
||||
|
||||
update_icon()
|
||||
|
||||
if(!T)
|
||||
if(!T && latejoin.len)
|
||||
T = pick(latejoin) //Safety in case we cannot find the body's position
|
||||
loc = T
|
||||
|
||||
|
||||
@@ -555,9 +555,10 @@ var/next_mob_id = 0
|
||||
if(statpanel("Status"))
|
||||
if (client)
|
||||
stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)")
|
||||
stat(null, "Map: [MAP_NAME]")
|
||||
if(nextmap && istype(nextmap))
|
||||
stat(null, "Next Map: [nextmap.friendlyname]")
|
||||
stat(null, "Map: [SSmapping.config.map_name]")
|
||||
var/datum/map_config/cached = SSmapping.next_map_config
|
||||
if(cached)
|
||||
stat(null, "Next Map: [cached.map_name]")
|
||||
stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]")
|
||||
stat(null, "Station Time: [worldtime2text()]")
|
||||
stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)")
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
tag = "mob_[next_mob_id++]"
|
||||
mob_list += src
|
||||
|
||||
if(client && ticker.state == GAME_STATE_STARTUP)
|
||||
var/obj/screen/splash/S = new(client, TRUE, TRUE)
|
||||
S.Fade(TRUE)
|
||||
|
||||
if(length(newplayer_start))
|
||||
loc = pick(newplayer_start)
|
||||
else
|
||||
@@ -70,7 +74,7 @@
|
||||
|
||||
if(statpanel("Lobby"))
|
||||
stat("Game Mode:", (ticker.hide_mode) ? "Secret" : "[master_mode]")
|
||||
stat("Map:", MAP_NAME)
|
||||
stat("Map:", SSmapping.config.map_name)
|
||||
|
||||
if(ticker.current_state == GAME_STATE_PREGAME)
|
||||
var/time_remaining = ticker.GetTimeLeft()
|
||||
@@ -125,7 +129,7 @@
|
||||
if (O)
|
||||
observer.loc = O.loc
|
||||
else
|
||||
src << "<span class='notice'>Teleporting failed. You should be able to use ghost verbs to teleport somewhere useful</span>"
|
||||
src << "<span class='notice'>Teleporting failed. The map is probably still loading...</span>"
|
||||
observer.key = key
|
||||
observer.client = client
|
||||
observer.set_ghost_appearance()
|
||||
|
||||
@@ -78,10 +78,11 @@ var/list/z_levels_list = list()
|
||||
/proc/setup_map_transitions() //listamania
|
||||
var/list/SLS = list()
|
||||
var/datum/space_level/D
|
||||
var/conf_set_len = map_transition_config.len
|
||||
var/list/cached_transitions = SSmapping.config.transition_config
|
||||
var/conf_set_len = cached_transitions.len
|
||||
var/k = 1
|
||||
for(var/A in map_transition_config)
|
||||
D = new(map_transition_config[A])
|
||||
for(var/A in cached_transitions)
|
||||
D = new(cached_transitions[A])
|
||||
D.name = A
|
||||
D.z_value = k
|
||||
if(D.linked != CROSSLINKED)
|
||||
|
||||
Reference in New Issue
Block a user