Files
S.P.L.U.R.T-Station-13/code/controllers/subsystem/mapping.dm
2017-11-09 11:04:50 -06:00

258 lines
7.9 KiB
Plaintext

SUBSYSTEM_DEF(mapping)
name = "Mapping"
init_order = INIT_ORDER_MAPPING
flags = SS_NO_FIRE
var/list/nuke_tiles = list()
var/list/nuke_threats = list()
var/datum/map_config/config
var/datum/map_config/next_map_config
var/list/map_templates = list()
var/list/ruins_templates = list()
var/list/space_ruins_templates = list()
var/list/lava_ruins_templates = list()
var/list/shuttle_templates = list()
var/list/shelter_templates = list()
var/list/areas_in_z = list()
var/loading_ruins = FALSE
/datum/controller/subsystem/mapping/PreInit()
if(!config)
#ifdef FORCE_MAP
config = new(FORCE_MAP)
#else
config = new
#endif
return ..()
/datum/controller/subsystem/mapping/Initialize(timeofday)
if(config.defaulted)
to_chat(world, "<span class='boldannounce'>Unable to load next map config, defaulting to Box Station</span>")
loadWorld()
repopulate_sorted_areas()
process_teleport_locs() //Sets up the wizard teleport locations
preloadTemplates()
// Pick a random away mission.
createRandomZlevel()
// Generate mining.
loading_ruins = TRUE
var/mining_type = config.minetype
if (mining_type == "lavaland")
seedRuins(list(ZLEVEL_LAVALAND), CONFIG_GET(number/lavaland_budget), /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates)
spawn_rivers()
// deep space ruins
var/space_zlevels = list()
for(var/i in ZLEVEL_SPACEMIN to ZLEVEL_SPACEMAX)
switch(i)
if(ZLEVEL_MINING, ZLEVEL_LAVALAND, ZLEVEL_EMPTY_SPACE, ZLEVEL_TRANSIT, ZLEVEL_CITYOFCOGS)
continue
else
space_zlevels += i
seedRuins(space_zlevels, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
loading_ruins = FALSE
repopulate_sorted_areas()
// Set up Z-level transistions.
setup_map_transitions()
..()
/* 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
map_templates = SSmapping.map_templates
ruins_templates = SSmapping.ruins_templates
space_ruins_templates = SSmapping.space_ruins_templates
lava_ruins_templates = SSmapping.lava_ruins_templates
shuttle_templates = SSmapping.shuttle_templates
shelter_templates = SSmapping.shelter_templates
config = SSmapping.config
next_map_config = SSmapping.next_map_config
/datum/controller/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/controller/subsystem/mapping/proc/CreateSpace(MaxZLevel)
while(world.maxz < MaxZLevel)
++world.maxz
CHECK_TICK
#define INIT_ANNOUNCE(X) to_chat(world, "<span class='boldannounce'>[X]</span>"); log_world(X)
/datum/controller/subsystem/mapping/proc/loadWorld()
//if any of these fail, something has gone horribly, HORRIBLY, wrong
var/list/FailedZs = list()
var/start_time = REALTIMEOFDAY
INIT_ANNOUNCE("Loading [config.map_name]...")
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION_PRIMARY)
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
if(SSdbcore.Connect())
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
query_round_map_name.Execute()
if(config.minetype != "lavaland")
INIT_ANNOUNCE("WARNING: A map without lavaland set as its minetype was loaded! This is being ignored! Update the maploader code!")
CreateSpace(ZLEVEL_SPACEMAX)
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
/datum/controller/subsystem/mapping/proc/maprotate()
var/players = GLOB.clients.len
var/list/mapvotes = list()
//count votes
var/amv = CONFIG_GET(flag/allow_map_voting)
if(amv)
for (var/client/c in GLOB.clients)
var/vote = c.prefs.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(amv)
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 class='boldannounce'>Map rotation has chosen [VM.map_name] for next round!</span>")
/datum/controller/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/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("config/lavaruinblacklist.txt")
banned += generateMapList("config/spaceruinblacklist.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/space))
space_ruins_templates[R.name] = R
/datum/controller/subsystem/mapping/proc/preloadShuttleTemplates()
var/list/unbuyable = generateMapList("config/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.can_be_bought = FALSE
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