var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away_mission_config.txt") // Call this before you remove the last dirt on a z level - that way, all objects // will have proper atmos and other important enviro things /proc/late_setup_level(turfs, smoothTurfs) var/total_timer = start_watch() var/subtimer = start_watch() if(!smoothTurfs) smoothTurfs = turfs log_debug("Setting up atmos") if(SSair) SSair.setup_allturfs(turfs) log_debug("\tTook [stop_watch(subtimer)]s") subtimer = start_watch() log_debug("Smoothing tiles") for(var/turf/T in smoothTurfs) if(T.smooth) queue_smooth(T) for(var/R in T) var/atom/A = R if(A.smooth) queue_smooth(A) log_debug("\tTook [stop_watch(subtimer)]s") log_debug("Late setup finished - took [stop_watch(total_timer)]s") /proc/empty_rect(low_x,low_y, hi_x,hi_y, z) var/timer = start_watch() log_debug("Emptying region: ([low_x], [low_y]) to ([hi_x], [hi_y]) on z '[z]'") empty_region(block(locate(low_x, low_y, z), locate(hi_x, hi_y, z))) log_debug("Took [stop_watch(timer)]s") /proc/empty_region(list/turfs) for(var/thing in turfs) var/turf/T = thing for(var/otherthing in T) qdel(otherthing) T.ChangeTurf(T.baseturf) /proc/createRandomZlevel() if(awaydestinations.len) //crude, but it saves another var! return if(potentialRandomZlevels && potentialRandomZlevels.len) var/watch = start_watch() log_startup_progress("Loading away mission...") var/map = pick(potentialRandomZlevels) var/file = file(map) if(isfile(file)) var/zlev = space_manager.add_new_zlevel(AWAY_MISSION, linkage = UNAFFECTED, traits = list(AWAY_LEVEL,BLOCK_TELEPORT)) space_manager.add_dirt(zlev) maploader.load_map(file, z_offset = zlev) late_setup_level(block(locate(1, 1, zlev), locate(world.maxx, world.maxy, zlev))) space_manager.remove_dirt(zlev) log_world(" Away mission loaded: [map]") for(var/obj/effect/landmark/L in GLOB.landmarks_list) if(L.name != "awaystart") continue awaydestinations.Add(L) log_startup_progress(" Away mission loaded in [stop_watch(watch)]s.") else log_startup_progress(" No away missions found.") return /proc/createALLZlevels() if(awaydestinations.len) //crude, but it saves another var! return if(potentialRandomZlevels && potentialRandomZlevels.len) var/watch = start_watch() log_startup_progress("Loading away missions...") for(var/map in potentialRandomZlevels) var/file = file(map) if(isfile(file)) log_startup_progress("Loading away mission: [map]") var/zlev = space_manager.add_new_zlevel() space_manager.add_dirt(zlev) maploader.load_map(file, z_offset = zlev) late_setup_level(block(locate(1, 1, zlev), locate(world.maxx, world.maxy, zlev))) space_manager.remove_dirt(zlev) log_world(" Away mission loaded: [map]") //map_transition_config.Add(AWAY_MISSION_LIST) for(var/obj/effect/landmark/L in GLOB.landmarks_list) if(L.name != "awaystart") continue awaydestinations.Add(L) log_startup_progress(" Away mission loaded in [stop_watch(watch)]s.") watch = start_watch() else log_startup_progress(" No away missions found.") return /proc/generateMapList(filename) var/list/potentialMaps = list() var/list/Lines = file2list(filename) if(!Lines.len) return for(var/t in Lines) if(!t) continue t = trim(t) if(length(t) == 0) continue else if(copytext(t, 1, 2) == "#") continue var/pos = findtext(t, " ") var/name = null if(pos) name = lowertext(copytext(t, 1, pos)) else name = lowertext(t) if(!name) continue potentialMaps.Add(t) return potentialMaps /datum/map_template/ruin/proc/try_to_place(z,allowed_areas) var/sanity = PLACEMENT_TRIES while(sanity > 0) sanity-- var/width_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(width / 2) var/height_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(height / 2) var/turf/central_turf = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z) var/valid = TRUE for(var/turf/check in get_affected_turfs(central_turf,1)) var/area/new_area = get_area(check) if(!(istype(new_area, allowed_areas)) || check.flags & NO_RUINS) valid = FALSE break if(!valid) continue log_world("Ruin \"[name]\" placed at ([central_turf.x], [central_turf.y], [central_turf.z])") for(var/i in get_affected_turfs(central_turf, 1)) var/turf/T = i for(var/mob/living/simple_animal/monster in T) qdel(monster) for(var/obj/structure/flora/ash/plant in T) qdel(plant) load(central_turf,centered = TRUE) loaded++ for(var/turf/T in get_affected_turfs(central_turf, 1)) T.flags |= NO_RUINS new /obj/effect/landmark/ruin(central_turf, src) return TRUE return FALSE /proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins) if(!z_levels || !z_levels.len) WARNING("No Z levels provided - Not generating ruins") return for(var/zl in z_levels) var/turf/T = locate(1, 1, zl) if(!T) WARNING("Z level [zl] does not exist - Not generating ruins") return var/list/ruins = potentialRuins.Copy() var/list/forced_ruins = list() //These go first on the z level associated (same random one by default) var/list/ruins_availible = list() //we can try these in the current pass var/forced_z //If set we won't pick z level and use this one instead. //Set up the starting ruin list for(var/key in ruins) var/datum/map_template/ruin/R = ruins[key] if(R.cost > budget) //Why would you do that continue if(R.always_place) forced_ruins[R] = -1 if(R.unpickable) continue ruins_availible[R] = R.placement_weight while(budget > 0 && (ruins_availible.len || forced_ruins.len)) var/datum/map_template/ruin/current_pick var/forced = FALSE if(forced_ruins.len) //We have something we need to load right now, so just pick it for(var/ruin in forced_ruins) current_pick = ruin if(forced_ruins[ruin] > 0) //Load into designated z forced_z = forced_ruins[ruin] forced = TRUE break else //Otherwise just pick random one current_pick = pickweight(ruins_availible) var/placement_tries = PLACEMENT_TRIES var/failed_to_place = TRUE var/z_placed = 0 while(placement_tries > 0) placement_tries-- z_placed = pick(z_levels) if(!current_pick.try_to_place(forced_z ? forced_z : z_placed,whitelist)) continue else failed_to_place = FALSE break //That's done remove from priority even if it failed if(forced) //TODO : handle forced ruins with multiple variants forced_ruins -= current_pick forced = FALSE if(failed_to_place) for(var/datum/map_template/ruin/R in ruins_availible) if(R.id == current_pick.id) ruins_availible -= R log_world("Failed to place [current_pick.name] ruin.") else budget -= current_pick.cost if(!current_pick.allow_duplicates) for(var/datum/map_template/ruin/R in ruins_availible) if(R.id == current_pick.id) ruins_availible -= R if(current_pick.never_spawn_with) for(var/blacklisted_type in current_pick.never_spawn_with) for(var/possible_exclusion in ruins_availible) if(istype(possible_exclusion,blacklisted_type)) ruins_availible -= possible_exclusion forced_z = 0 //Update the availible list for(var/datum/map_template/ruin/R in ruins_availible) if(R.cost > budget) ruins_availible -= R log_world("Ruin loader finished with [budget] left to spend.")