Added the z-level manager system from TG (#19532)

Added the z-level manager system from TG, mostly
This commit is contained in:
Fluffy
2024-07-22 15:00:38 +02:00
committed by GitHub
parent 0a9176841c
commit 1345beac4b
90 changed files with 614 additions and 245 deletions
+63
View File
@@ -0,0 +1,63 @@
/*
dmm_suite version 1.0
Released January 30th, 2011.
NOTE: Map saving functionality removed
defines the object /dmm_suite
- Provides the proc load_map()
- Loads the specified map file onto the specified z-level.
- provides the proc write_map()
- Returns a text string of the map in dmm format
ready for output to a file.
- provides the proc save_map()
- Returns a .dmm file if map is saved
- Returns FALSE if map fails to save
The dmm_suite provides saving and loading of map files in BYOND's native DMM map
format. It approximates the map saving and loading processes of the Dream Maker
and Dream Seeker programs so as to allow editing, saving, and loading of maps at
runtime.
------------------------
To save a map at runtime, create an instance of /dmm_suite, and then call
write_map(), which accepts three arguments:
- A turf representing one corner of a three dimensional grid (Required).
- Another turf representing the other corner of the same grid (Required).
- Any, or a combination, of several bit flags (Optional, see documentation).
The order in which the turfs are supplied does not matter, the /dmm_writer will
determine the grid containing both, in much the same way as DM's block() function.
write_map() will then return a string representing the saved map in dmm format;
this string can then be saved to a file, or used for any other purose.
------------------------
To load a map at runtime, create an instance of /dmm_suite, and then call load_map(),
which accepts two arguments:
- A .dmm file to load (Required).
- A number representing the z-level on which to start loading the map (Optional).
The /dmm_suite will load the map file starting on the specified z-level. If no
z-level was specified, world.maxz will be increased so as to fit the map. Note
that if you wish to load a map onto a z-level that already has objects on it,
you will have to handle the removal of those objects. Otherwise the new map will
simply load the new objects on top of the old ones.
Also note that all type paths specified in the .dmm file must exist in the world's
code, and that the /dmm_reader trusts that files to be loaded are in fact valid
.dmm files. Errors in the .dmm format will cause runtime errors.
*/
/dmm_suite
/**
* 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
*/
/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, no_changeturf as num)
CAN_BE_REDEFINED(TRUE)
+41
View File
@@ -0,0 +1,41 @@
/obj/effect/landmark/map_load_mark
name = "map loader landmark"
var/list/templates //list of template types to pick from
//Clears walls
/obj/effect/landmark/clear
name = "clear turf"
icon = 'icons/effects/landmarks.dmi'
icon_state = "clear"
/obj/effect/landmark/clear/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/effect/landmark/clear/LateInitialize()
var/turf/simulated/wall/W = get_turf(src)
if(istype(W))
W.dismantle_wall(TRUE, TRUE)
var/turf/simulated/mineral/M = W
if(istype(M))
M.GetDrilled()
qdel(src) //Our job here is done
//Applies fire act to the turf
/obj/effect/landmark/scorcher
name = "fire"
icon = 'icons/effects/landmarks.dmi'
icon_state = "fire"
var/temp = T0C + 3000
/obj/effect/landmark/scorcher/Initialize()
..()
return INITIALIZE_HINT_LATELOAD //This assures that everything under the marker has loaded before burning it
/obj/effect/landmark/scorcher/LateInitialize()
var/turf/simulated/T = get_turf(src)
if(istype(T))
T.fire_act(temp)
qdel(src) //Our job here is done
+248
View File
@@ -0,0 +1,248 @@
/datum/map_template
var/name = "Default Template Name"
var/id = null // All maps that should be loadable during runtime need an id
var/width = 0
var/height = 0
var/list/mappaths = null
var/loaded = 0 // Times loaded this round
var/static/dmm_suite/maploader = new
var/list/shuttles_to_initialise = list()
var/list/subtemplates_to_spawn
var/base_turf_for_zs = null
var/accessibility_weight = 0
var/template_flags = TEMPLATE_FLAG_ALLOW_DUPLICATES
///A list of groups, as strings, that this template belongs to. When adding new map templates, try to keep this balanced on the CI execution time, or consider adding a new one
///ONLY IF IT'S THE LONGEST RUNNING CI POD AND THEY ARE ALREADY BALANCED
var/list/unit_test_groups = list()
/datum/map_template/New(var/list/paths = null, rename = null)
if(paths && !islist(paths))
crash_with("Non-list paths passed into map template constructor.")
if(paths)
mappaths = paths
if(mappaths)
preload_size(mappaths)
if(rename)
name = rename
..()
/datum/map_template/proc/preload_size(paths)
var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
var/z_offset = 1 // needed to calculate z-bounds correctly
for(var/mappath in mappaths)
var/datum/map_load_metadata/M = maploader.load_map(file(mappath), 1, 1, z_offset, cropMap=FALSE, measureOnly=TRUE)
if(M)
bounds = extend_bounds_if_needed(bounds, M.bounds)
z_offset++
else
return FALSE
width = bounds[MAP_MAXX] - bounds[MAP_MINX] + 1
height = bounds[MAP_MAXY] - bounds[MAP_MINX] + 1
return bounds
/datum/map_template/proc/load_new_z(var/no_changeturf = TRUE)
RETURN_TYPE(/turf)
var/x = round((world.maxx - width)/2)
var/y = round((world.maxy - height)/2)
var/initial_z = world.maxz + 1
if (x < 1) x = 1
if (y < 1) y = 1
var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
var/list/atoms_to_initialise = list()
var/shuttle_state = pre_init_shuttles()
//Since SSicon_smooth.add_to_queue() manually wakes the subsystem, we have to use enable/disable.
SSicon_smooth.can_fire = FALSE
var/is_first = TRUE
for(var/i in 1 to length(mappaths))
var/mappath = mappaths[i]
var/list/trait = ZTRAITS_AWAY
//Second or subsequent map file
if(!is_first)
//Last map file in a multi level map, can only go down
if(i == length(mappaths))
trait += list(ZTRAIT_UP = FALSE, ZTRAIT_DOWN = TRUE)
//Intermediate map file, can go up and down
else
trait += list(ZTRAIT_UP = TRUE, ZTRAIT_DOWN = TRUE)
//First map file
else
//Multi-level map
if(length(mappaths) >= 2)
trait += list(ZTRAIT_UP = TRUE, ZTRAIT_DOWN = FALSE)
//Single-level map
else
trait += list(ZTRAIT_UP = FALSE, ZTRAIT_DOWN = FALSE)
var/datum/space_level/level = SSmapping.add_new_zlevel(name, trait, contain_turfs = FALSE)
var/datum/map_load_metadata/M = maploader.load_map(file(mappath), x, y, level.z_value, no_changeturf = no_changeturf)
if (M)
bounds = extend_bounds_if_needed(bounds, M.bounds)
atoms_to_initialise += M.atoms_to_initialise
else
SSicon_smooth.can_fire = TRUE
return FALSE
is_first = FALSE
for (var/z_index = bounds[MAP_MINZ]; z_index <= bounds[MAP_MAXZ]; z_index++)
if (accessibility_weight)
SSatlas.current_map.accessible_z_levels[num2text(z_index)] = accessibility_weight
if (base_turf_for_zs)
SSatlas.current_map.base_turf_by_z[num2text(z_index)] = base_turf_for_zs
SSatlas.current_map.player_levels |= z_index
smooth_zlevel(world.maxz)
resort_all_areas()
//initialize things that are normally initialized after map load
init_atoms(atoms_to_initialise)
init_shuttles(shuttle_state)
after_load(initial_z)
for(var/light_z = initial_z to world.maxz)
create_lighting_overlays_zlevel(light_z)
log_game("Z-level [name] loaded at [x], [y], [world.maxz]")
message_admins("Z-level [name] loaded at [x], [y], [world.maxz]")
SSicon_smooth.can_fire = TRUE
loaded++
return bounds
/datum/map_template/proc/pre_init_shuttles()
. = SSshuttle.block_queue
SSshuttle.block_queue = TRUE
/datum/map_template/proc/init_shuttles(var/pre_init_state)
for (var/shuttle_type in shuttles_to_initialise)
LAZYADD(SSshuttle.shuttles_to_initialize, shuttle_type) // queue up for init.
SSshuttle.block_queue = pre_init_state
SSshuttle.clear_init_queue() // We will flush the queue unless there were other blockers, in which case they will do it.
/datum/map_template/proc/init_atoms(var/list/atoms)
if (SSatoms.initialized == INITIALIZATION_INSSATOMS)
return // let proper initialisation handle it later
var/list/turf/turfs = list()
var/list/obj/machinery/atmospherics/atmos_machines = list()
var/list/obj/machinery/machines = list()
var/list/obj/structure/cable/cables = list()
var/list/obj/machinery/power/apc/apcs = list()
for(var/atom/A as anything in atoms)
if(isnull(A) || (A.flags_1 & INITIALIZED_1))
atoms -= A
continue
if(istype(A, /turf))
turfs += A
continue
if(istype(A, /obj/structure/cable))
cables += A
continue
if(istype(A,/obj/effect/landmark/map_load_mark))
LAZYADD(subtemplates_to_spawn, A)
continue
//Not mutually exclusive anymore section, no continue here, keep checking
if(istype(A, /obj/machinery/atmospherics))
atmos_machines += A
if(istype(A, /obj/machinery))
machines += A
if(istype(A, /obj/machinery/power/apc))
apcs += A
var/notsuspended
if(!SSmachinery.can_fire)
SSmachinery.can_fire = FALSE
notsuspended = TRUE
SSatoms.InitializeAtoms(atoms) // The atoms should have been getting queued there. This flushes the queue.
SSmachinery.setup_powernets_for_cables(cables)
SSmachinery.setup_atmos_machinery(atmos_machines)
if(notsuspended)
SSmachinery.can_fire = TRUE
for (var/i in apcs)
var/obj/machinery/power/apc/apc = i
apc.update() // map-loading areas and APCs is weird, okay
for (var/i in machines)
var/obj/machinery/machine = i
machine.power_change()
for (var/i in turfs)
var/turf/T = i
T.post_change(FALSE)
if(template_flags & TEMPLATE_FLAG_NO_RUINS)
T.turf_flags |= TURF_NORUINS
if(istype(T,/turf/simulated))
var/turf/simulated/sim = T
sim.update_air_properties()
/datum/map_template/proc/load(turf/T, centered = FALSE)
if(centered)
T = locate(T.x - round(width / 2) , T.y - round(height / 2) , T.z)
if(!T)
return
if(T.x + width > world.maxx)
return
if(T.y + height > world.maxy)
return
var/list/atoms_to_initialise = list()
var/shuttle_state = pre_init_shuttles()
//Since SSicon_smooth.add_to_queue() manually wakes the subsystem, we have to use enable/disable.
SSicon_smooth.can_fire = FALSE
for (var/mappath in mappaths)
var/datum/map_load_metadata/M = maploader.load_map(file(mappath), T.x, T.y, T.z, cropMap=TRUE)
if (M)
atoms_to_initialise += M.atoms_to_initialise
else
SSicon_smooth.can_fire = TRUE
return FALSE
//initialize things that are normally initialized after map load
init_atoms(atoms_to_initialise)
init_shuttles(shuttle_state)
SSicon_smooth.can_fire = TRUE
message_admins("[name] loaded at [T.x], [T.y], [T.z]")
log_game("[name] loaded at [T.x], [T.y], [T.z]")
return TRUE
/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE)
var/turf/placement = T
if(centered)
var/turf/corner = locate(placement.x - round(width / 2), placement.y - round(height / 2), placement.z)
if(corner)
placement = corner
return block(placement, locate(placement.x + width-1, placement.y + height-1, placement.z))
/datum/map_template/proc/extend_bounds_if_needed(var/list/existing_bounds, var/list/new_bounds)
var/list/bounds_to_combine = existing_bounds.Copy()
for (var/min_bound in list(MAP_MINX, MAP_MINY, MAP_MINZ))
bounds_to_combine[min_bound] = min(existing_bounds[min_bound], new_bounds[min_bound])
for (var/max_bound in list(MAP_MAXX, MAP_MAXY, MAP_MAXZ))
bounds_to_combine[max_bound] = max(existing_bounds[max_bound], new_bounds[max_bound])
return bounds_to_combine
/datum/map_template/proc/after_load(z)
for(var/obj/effect/landmark/map_load_mark/mark in subtemplates_to_spawn)
subtemplates_to_spawn -= mark
if(LAZYLEN(mark.templates))
var/template = pick(mark.templates)
var/datum/map_template/M = new template()
M.load(get_turf(mark), TRUE)
qdel(mark)
LAZYCLEARLIST(subtemplates_to_spawn)
@@ -0,0 +1,48 @@
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid
name = "mineral asteroid"
desc = "A large, resource rich asteroid."
massvolume = "~0.02"
surfacegravity = "0.04~"
surface_color = COLOR_GRAY
scanimage = "asteroid.png"
possible_themes = list(/datum/exoplanet_theme/barren/asteroid)
rock_colors = list(COLOR_ASTEROID_ROCK)
planetary_area = /area/exoplanet/barren/asteroid
ruin_planet_type = PLANET_ASTEROID
ruin_allowed_tags = RUIN_AIRLESS|RUIN_LOWPOP|RUIN_MINING|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
place_near_main = list(1, 1)
unit_test_groups = list(2)
soil_data = list("Rich aluminium oxide layer", "Rich iron oxide layer", "Rich silver dust layer", "Rich gold dust layer", "Low density silicon dioxide layer", "Large rock particle layer")
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/update_icon()
icon_state = "asteroid[rand(1,3)]"
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/generate_planet_image()
skybox_image = image('icons/skybox/skybox_rock_128.dmi', "bigrock")
skybox_image.color = pick(rock_colors)
skybox_image.pixel_x = rand(0,64)
skybox_image.pixel_y = rand(128,256)
skybox_image.appearance_flags = DEFAULT_APPEARANCE_FLAGS | RESET_COLOR
skybox_image.blend_mode = BLEND_OVERLAY
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/generate_atmosphere()
atmosphere = null
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/romanovich
name = "romanovich cloud asteroid"
desc = "A phoron rich asteroid."
possible_themes = list(/datum/exoplanet_theme/barren/asteroid/phoron)
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ice
name = "ice asteroid"
desc = "A large, mineral-rich asteroid covered in frozen water deposits."
surface_color = COLOR_BLUE_GRAY
scanimage = "asteroid.png"
possible_themes = list(/datum/exoplanet_theme/barren/asteroid/ice)
rock_colors = list(COLOR_ASH)
planetary_area = /area/exoplanet/barren/asteroid
ruin_planet_type = PLANET_ASTEROID
ruin_allowed_tags = RUIN_AIRLESS|RUIN_LOWPOP|RUIN_MINING|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
@@ -0,0 +1,74 @@
/obj/effect/overmap/visitable/sector/exoplanet/barren
name = "barren exoplanet"
desc = "An exoplanet that couldn't hold its atmosphere."
color = "#ad9c9c"
scanimage = "barren.png"
planetary_area = /area/exoplanet/barren
rock_colors = list(COLOR_BEIGE, COLOR_GRAY80, COLOR_BROWN)
possible_themes = list(/datum/exoplanet_theme/barren)
features_budget = 6
surface_color = "#807d7a"
water_color = null
ruin_planet_type = PLANET_BARREN
ruin_allowed_tags = RUIN_AIRLESS|RUIN_LOWPOP|RUIN_MINING|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
unit_test_groups = list(1)
soil_data = list("Rich iron oxide layer", "Low density silicon dioxide layer", "Large rock particle layer", "Trace organic particle layer", "Trace ice crytal layer")
/obj/effect/overmap/visitable/sector/exoplanet/barren/generate_habitability()
return HABITABILITY_BAD
/obj/effect/overmap/visitable/sector/exoplanet/barren/generate_atmosphere()
..()
atmosphere = null
/obj/effect/overmap/visitable/sector/exoplanet/barren/get_surface_color()
return "#6C6251"
/obj/effect/overmap/visitable/sector/exoplanet/barren/generate_ground_survey_result()
..()
if(prob(50))
ground_survey_result += "<br>Evidence of lava tubes being present in the subsurface"
if(prob(50))
ground_survey_result += "<br>Water ice pockets detected deep underground"
if(prob(50))
ground_survey_result += "<br>No geothermal activity observed in the planetary core"
if(prob(50))
ground_survey_result += "<br>Micro-textural analysis indicates availability of fissile material"
if(prob(50))
ground_survey_result += "<br>Surface soil may provide adequate radiation shielding"
if(prob(50))
ground_survey_result += "<br>Silicon carbides found deep in the crust"
if(prob(50))
ground_survey_result += "<br>Oxygen found in locally stable metal oxides"
if(prob(40))
ground_survey_result += "<br>Regolith rich in heavy silicate alloys"
if(prob(30))
ground_survey_result += "<br>Relatively high abundance of fusile material, accumulated on the surface by the solar wind"
if(prob(10))
ground_survey_result += "<br>Traces of fusile material"
if(prob(10))
ground_survey_result += "<br>Carbon nanotubes naturally found in the regolith"
/obj/effect/overmap/visitable/sector/exoplanet/barren/generate_magnet_survey_result()
..()
magnet_strength = "[rand(1, 10)] uT/Gauss"
magnet_difference = "[rand(0,2000)] kilometers"
magnet_particles = ""
var/list/particle_types = PARTICLE_TYPES
var/particles = rand(2,8)
for(var/i in 1 to particles)
var/p = pick(particle_types)
if(i == particles) //Last item, no comma
magnet_particles += p
else
magnet_particles += "[p], "
particle_types -= p
day_length = "~[rand(1,200)/100] BCY (Biesel Cycles)"
if(prob(40))
magnet_survey_result += "<br>Pockets of zero magnetism detected"
if(prob(40))
magnet_survey_result += "<br>Minimal solar protection present"
if(prob(10))
magnet_survey_result += "<br>Rich ferromagnetic core found"
@@ -0,0 +1,68 @@
/obj/effect/overmap/visitable/sector/exoplanet/crystal
name = "crystalline exoplanet"
desc = "A near-airless world whose surface is encrusted with various crystalline minerals."
color = "#6ba7f7"
scanimage = "barren.png"
geology = "Exceptional silica content compared to baseline; minimal tectonic activity present"
planetary_area = /area/exoplanet/crystal
rock_colors = list(COLOR_BLUE_GRAY, COLOR_PALE_BLUE_GRAY)
possible_themes = list(/datum/exoplanet_theme/crystal)
features_budget = 6
surface_color = null
water_color = null
ruin_planet_type = PLANET_CRYSTAL
ruin_allowed_tags = RUIN_AIRLESS|RUIN_LOWPOP|RUIN_MINING|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
unit_test_groups = list(3)
soil_data = list("Porous crystal layer", "High density silicon carbide layer", "Layer of fused refractive crystals", "Degrading volatile layer", "Silica aerogel layer", "Crystal mush layer")
/obj/effect/overmap/visitable/sector/exoplanet/crystal/generate_habitability()
return HABITABILITY_BAD
/obj/effect/overmap/visitable/sector/exoplanet/crystal/generate_atmosphere()
..()
atmosphere.remove_ratio(0.9)
/obj/effect/overmap/visitable/sector/exoplanet/crystal/get_surface_color()
return "#6ba7f7"
/obj/effect/overmap/visitable/sector/exoplanet/crystal/generate_ground_survey_result()
..()
if(prob(50))
ground_survey_result += "<br>Crystal mush detected in deep crust"
if(prob(50))
ground_survey_result += "<br>Natural silica aerogels predicted to be found in subterranean pockets"
if(prob(50))
ground_survey_result += "<br>Planetary core contains volatiles, maintaining stability due to high pressure"
if(prob(50))
ground_survey_result += "<br>Micro-textural analysis indicates porous crystals in shallow crust"
if(prob(50))
ground_survey_result += "<br>Superconductors in crystalline form present in the crust"
if(prob(50))
ground_survey_result += "<br>Silicon carbides found deep in the crust"
if(prob(50))
ground_survey_result += "<br>High content of refractory materials"
if(prob(10))
ground_survey_result += "<br>Traces of fusile material"
/obj/effect/overmap/visitable/sector/exoplanet/crystal/generate_magnet_survey_result()
..()
magnet_strength = "[rand(60, 300)] uT/Gauss"
magnet_difference = "[rand(0,1000)] kilometers"
magnet_particles = ""
var/list/particle_types = PARTICLE_TYPES
var/particles = rand(2,5)
for(var/i in 1 to particles)
var/p = pick(particle_types)
if(i == particles) //Last item, no comma
magnet_particles += p
else
magnet_particles += "[p], "
particle_types -= p
day_length = "~[rand(1,200)/10] BCY (Biesel Cycles)"
if(prob(40))
magnet_survey_result += "<br>Magnetic resonance with crystaline surface catalogued"
if(prob(40))
magnet_survey_result += "<br>Major energy flux detected in magnetosphere"
if(prob(10))
magnet_survey_result += "<br>Magnetic tail producing strong dust storms in solar shadow"
+186
View File
@@ -0,0 +1,186 @@
/obj/effect/overmap/visitable/sector/exoplanet/desert
name = "desert exoplanet"
desc = "An arid exoplanet with sparse biological resources but rich mineral deposits underground."
color = "#a08444"
scanimage = "desert.png"
geology = "Non-existent tectonic activity, minimal geothermal signature"
weather = "Global full-atmosphere geothermal weather system. Barely-habitable ambient high temperatures. Slow-moving, stagnant meteorological activity prone to unpredictable upset in wind condition"
planetary_area = /area/exoplanet/desert
initial_weather_state = /singleton/state/weather/calm/desert_planet
rock_colors = list(COLOR_BEIGE, COLOR_PALE_YELLOW, COLOR_GRAY80, COLOR_BROWN)
plant_colors = list("#efdd6f","#7b4a12","#e49135","#ba6222","#5c755e","#420d22")
possible_themes = list(/datum/exoplanet_theme/desert)
flora_diversity = 4
has_trees = FALSE
surface_color = "#d6cca4"
water_color = null
ruin_planet_type = PLANET_DESERT
ruin_allowed_tags = RUIN_LOWPOP|RUIN_MINING|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
soil_data = list("Low density silicon dioxide layer", "Trace gold dust layer", "Trace silver dust layer", "Large rock particle layer", "Trace organic particle layer")
water_data = list("Sodium ions present", "Calcium ions present", "Sulfate ions present", "Magnesium ions present", "Copper ions present")
unit_test_groups = list(1)
/obj/effect/overmap/visitable/sector/exoplanet/desert/generate_map()
lightlevel = rand(5,10)/10 //deserts are usually :lit:
..()
/obj/effect/overmap/visitable/sector/exoplanet/desert/generate_atmosphere()
..()
if(atmosphere)
var/limit = 1000
if(habitability_class <= HABITABILITY_OKAY)
var/datum/species/human/H = /datum/species/human
limit = initial(H.heat_level_1) - rand(1,10)
atmosphere.temperature = min(T20C + rand(20, 100), limit)
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/desert/generate_ground_survey_result()
..()
if(prob(40))
ground_survey_result += "<br>High quality natural fertilizer found in subterranean pockets"
if(prob(40))
ground_survey_result += "<br>High nitrogen and phosphorus contents of the soil"
if(prob(40))
ground_survey_result += "<br>Chemical extraction indicates soil is rich in major and secondary nutrients for agriculture"
if(prob(40))
ground_survey_result += "<br>Analysis indicates low contaminants of the soil"
if(prob(40))
ground_survey_result += "<br>Soft clays detected, composed of quartz and calcites"
if(prob(40))
ground_survey_result += "<br>Muddy dirt rich in organic material"
if(prob(40))
ground_survey_result += "<br>Stratigraphy indicates low risk of tectonic activity in this region"
if(prob(40))
ground_survey_result += "<br>Fossilized organic material found settled in sedimentary rock"
if(prob(10))
ground_survey_result += "<br>Traces of fissile material"
/obj/effect/overmap/visitable/sector/exoplanet/desert/generate_magnet_survey_result()
..()
magnet_strength = "[rand(10, 100)] uT/Gauss"
magnet_difference = "[rand(0,1500)] kilometers"
magnet_particles = ""
var/list/particle_types = PARTICLE_TYPES
var/particles = rand(1,5)
for(var/i in 1 to particles)
var/p = pick(particle_types)
if(i == particles) //Last item, no comma
magnet_particles += p
else
magnet_particles += "[p], "
particle_types -= p
day_length = "~[rand(1,200)/10] BCY (Biesel Cycles)"
if(prob(40))
magnet_survey_result += "<br>Highly variable magnetic flux detected"
if(prob(40))
magnet_survey_result += "<br>Strong solar winds present"
if(prob(10))
magnet_survey_result += "<br>High levels of plasma present in magnetosphere"
/obj/effect/overmap/visitable/sector/exoplanet/desert/adapt_seed(var/datum/seed/S)
..()
if(prob(90))
S.set_trait(TRAIT_REQUIRES_WATER,0)
else
S.set_trait(TRAIT_REQUIRES_WATER,1)
S.set_trait(TRAIT_WATER_CONSUMPTION,1)
if(prob(75))
S.set_trait(TRAIT_STINGS,1)
if(prob(75))
S.set_trait(TRAIT_CARNIVOROUS,2)
S.set_trait(TRAIT_SPREAD,0)
/obj/structure/quicksand
name = "sand"
icon = 'icons/obj/quicksand.dmi'
icon_state = "intact0"
density = 0
anchored = 1
can_buckle = 1
buckle_dir = SOUTH
var/exposed = 0
var/busy
/obj/structure/quicksand/New()
icon_state = "intact[rand(0,2)]"
..()
/obj/structure/quicksand/user_unbuckle(mob/user)
if(buckled && !user.stat && !user.restrained())
if(busy)
to_chat(user, "<span class='wanoticerning'>[buckled] is already getting out, be patient.</span>")
return
var/delay = 60
if(user == buckled)
delay *=2
user.visible_message(
SPAN_NOTICE("\The [user] tries to climb out of \the [src]."),
SPAN_NOTICE("You begin to pull yourself out of \the [src]."),
SPAN_NOTICE("You hear water sloushing.")
)
else
user.visible_message(
SPAN_NOTICE("\The [user] begins pulling \the [buckled] out of \the [src]."),
SPAN_NOTICE("You begin to pull \the [buckled] out of \the [src]."),
SPAN_NOTICE("You hear water sloushing.")
)
busy = 1
if(do_after(user, delay, src))
busy = 0
if(user == buckled)
if(prob(80))
to_chat(user, SPAN_WARNING("You slip and fail to get out!"))
return
user.visible_message(SPAN_NOTICE("\The [buckled] pulls himself out of \the [src]."))
else
user.visible_message(SPAN_NOTICE("\The [buckled] has been freed from \the [src] by \the [user]."))
unbuckle()
else
busy = 0
to_chat(user, SPAN_WARNING("You slip and fail to get out!"))
return
/obj/structure/quicksand/unbuckle()
..()
update_icon()
/obj/structure/quicksand/buckle(var/mob/L)
..()
update_icon()
/obj/structure/quicksand/update_icon()
if(!exposed)
return
icon_state = "open"
overlays.Cut()
if(buckled)
overlays += buckled
var/image/I = image(icon,icon_state="overlay")
I.layer = ABOVE_HUMAN_LAYER
overlays += I
/obj/structure/quicksand/proc/expose()
if(exposed)
return
visible_message(SPAN_WARNING("The upper crust breaks, exposing treacherous quicksands underneath!"))
name = "quicksand"
desc = "There is no candy at the bottom."
exposed = 1
update_icon()
/obj/structure/quicksand/attackby(obj/item/attacking_item, mob/user)
if(!exposed && attacking_item.force)
expose()
else
..()
/obj/structure/quicksand/Crossed(var/atom/movable/AM)
if(isliving(AM))
var/mob/living/L = AM
if(L.throwing)
return
buckle(L)
if(!exposed)
expose()
to_chat(L, SPAN_DANGER("You fall into \the [src]!"))
+101
View File
@@ -0,0 +1,101 @@
/obj/effect/overmap/visitable/sector/exoplanet/grass
name = "lush exoplanet"
desc = "An exoplanet with abundant flora and fauna."
color = "#407c40"
scanimage = "jungle.png"
geology = "High-energy geothermal signature, tectonic activity non-obstructive to surface environment"
weather = "Global full-atmosphere hydrological weather system. Dangerous meteorological activity not present"
surfacewater = "63% surface water, majority readings not visibly potable. Expected mineral toxicity or salt presence in water bodies"
planetary_area = /area/exoplanet/grass
flora_diversity = 7
has_trees = TRUE
rock_colors = list(COLOR_ASTEROID_ROCK, COLOR_GRAY80, COLOR_BROWN)
plant_colors = list("#3c772e","#27614b","#3f8d35","#185f18","#799628", "RANDOM")
possible_themes = list(/datum/exoplanet_theme/grass)
ruin_planet_type = PLANET_GRASS
ruin_allowed_tags = RUIN_LOWPOP|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
soil_data = list("Low density organic matter layer", "Rich microbiome layer", "Moderate water layer", "Large rock particle layer", "Iron oxide layer")
water_data = list("Sodium ions present", "Calcium ions present", "Sulfate ions present", "Magnesium ions present", "Copper ions present", "Nitrate ions present", "Potassium ions present", "Phorsporous ions present")
unit_test_groups = list(2)
/obj/effect/overmap/visitable/sector/exoplanet/grass/generate_map()
if(prob(40))
lightlevel = rand(1,7)/10 //give a chance of twilight jungle
..()
/obj/effect/overmap/visitable/sector/exoplanet/grass/generate_atmosphere()
..()
if(atmosphere)
atmosphere.temperature = T20C + rand(10, 30)
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/grass/get_surface_color()
return grass_color
/obj/effect/overmap/visitable/sector/exoplanet/grass/generate_ground_survey_result()
..()
if(prob(40))
ground_survey_result += "<br>High quality natural fertilizer found in subterranean pockets"
if(prob(40))
ground_survey_result += "<br>High nitrogen and phosphorus contents of the soil"
if(prob(40))
ground_survey_result += "<br>Chemical extraction indicates soil is rich in major and secondary nutrients for agriculture"
if(prob(40))
ground_survey_result += "<br>Analysis indicates low contaminants of the soil"
if(prob(40))
ground_survey_result += "<br>Soft clays detected, composed of quartz and calcites"
if(prob(40))
ground_survey_result += "<br>Muddy dirt rich in organic material"
if(prob(40))
ground_survey_result += "<br>Stratigraphy indicates low risk of tectonic activity in this region"
if(prob(40))
ground_survey_result += "<br>Fossilized organic material found settled in sedimentary rock"
if(prob(10))
ground_survey_result += "<br>Traces of fissile material"
/obj/effect/overmap/visitable/sector/exoplanet/grass/generate_magnet_survey_result()
..()
magnet_strength = "[rand(10, 100)] uT/Gauss"
magnet_difference = "[rand(0,1500)] kilometers"
magnet_particles = ""
var/list/particle_types = PARTICLE_TYPES
var/particles = rand(1,5)
for(var/i in 1 to particles)
var/p = pick(particle_types)
if(i == particles) //Last item, no comma
magnet_particles += p
else
magnet_particles += "[p], "
particle_types -= p
day_length = "~[rand(1,200)/10] BCY (Biesel Cycles)"
if(prob(40))
magnet_survey_result += "<br>Highly variable magnetic flux detected"
if(prob(40))
magnet_survey_result += "<br>Strong solar winds present"
if(prob(10))
magnet_survey_result += "<br>High levels of plasma present in magnetosphere"
/obj/effect/overmap/visitable/sector/exoplanet/grass/adapt_seed(var/datum/seed/S)
..()
var/carnivore_prob = rand(100)
if(carnivore_prob < 30)
S.set_trait(TRAIT_CARNIVOROUS,2)
if(prob(75))
S.get_trait(TRAIT_STINGS, 1)
else if(carnivore_prob < 60)
S.set_trait(TRAIT_CARNIVOROUS,1)
if(prob(50))
S.get_trait(TRAIT_STINGS)
if(prob(15) || (S.get_trait(TRAIT_CARNIVOROUS) && prob(40)))
S.set_trait(TRAIT_BIOLUM,1)
S.set_trait(TRAIT_BIOLUM_COLOUR,get_random_colour(0,75,190))
if(prob(30))
S.set_trait(TRAIT_PARASITE,1)
/obj/effect/overmap/visitable/sector/exoplanet/grass/marsh
name = "marsh exoplanet"
desc = "A swampy planet, home to exotic creatures and flora."
possible_themes = list(/datum/exoplanet_theme/grass/marsh)
ruin_planet_type = PLANET_MARSH
@@ -0,0 +1,20 @@
/obj/effect/overmap/visitable/sector/exoplanet/grass/grove
name = "grove exoplanet"
desc = "A temperate planet with abundant, peaceful flora and fauna."
color = "#346934"
scanimage = "grove.png"
planetary_area = /area/exoplanet/grass/grove
rock_colors = list(COLOR_BEIGE, COLOR_PALE_YELLOW, COLOR_GRAY80, COLOR_BROWN)
grass_color = null
plant_colors = null
flora_diversity = 7
has_trees = TRUE
possible_themes = list(/datum/exoplanet_theme/jungle)
initial_weather_state = /singleton/state/weather/rain/storm/jungle_planet
ruin_planet_type = PLANET_GROVE
ruin_allowed_tags = RUIN_LOWPOP|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
unit_test_groups = list(3)
/obj/effect/overmap/visitable/sector/exoplanet/grass/grove/get_surface_color()
return "#5C7F34"
+74
View File
@@ -0,0 +1,74 @@
/obj/effect/overmap/visitable/sector/exoplanet/lava
name = "lava exoplanet"
desc = "An exoplanet with an excess of volcanic activity."
color = "#575d5e"
scanimage = "lava.png"
geology = "Extreme, surface-apparent tectonic activity. Unreadable high-energy geothermal readings. Surface traversal demands caution"
weather = "Global sub-atmospheric volcanic ambient weather system. Exercise extreme caution with unpredictable volcanic eruption"
surfacewater = "Majority superheated methane, silicon and metallic substances, 7% liquid surface area."
planetary_area = /area/exoplanet/lava
initial_weather_state = /singleton/state/weather/calm/lava_planet
rock_colors = list(COLOR_DARK_GRAY)
possible_themes = list(/datum/exoplanet_theme/volcanic)
features_budget = 4
surface_color = "#cf1020"
water_color = null
ruin_planet_type = PLANET_LAVA
ruin_allowed_tags = RUIN_AIRLESS|RUIN_LOWPOP|RUIN_MINING|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
soil_data = list("Low density silicon dioxide layer", "Iron pyroxene layer", "Magnesium olivine layer", "Large rock particle layer", "Aluminium biotite layer")
unit_test_groups = list(1)
/obj/effect/overmap/visitable/sector/exoplanet/lava/generate_habitability()
return HABITABILITY_BAD
/obj/effect/overmap/visitable/sector/exoplanet/lava/generate_atmosphere()
..()
atmosphere.temperature = T20C + rand(220, 800)
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/lava/get_surface_color()
return "#575d5e"
/obj/effect/overmap/visitable/sector/exoplanet/lava/generate_ground_survey_result()
..()
if(prob(50))
ground_survey_result += "<br>High sulfide content of the shallow rock bed"
if(prob(50))
ground_survey_result += "<br>Pockets of saturated hydrocarbons in deep crust"
if(prob(50))
ground_survey_result += "<br>Planetary core contains volatiles, maintaining stability due to high pressure"
if(prob(50))
ground_survey_result += "<br>Silica alloy superconductors found in stability in the lava"
if(prob(50))
ground_survey_result += "<br>Analysis indicates heavy metals of low impurity, high possibility of easy extraction"
if(prob(50))
ground_survey_result += "<br>Traces of precious metals scattered in the crust"
if(prob(20))
ground_survey_result += "<br>High entropy alloys detected in deep crust"
if(prob(30))
ground_survey_result += "<br>Traces of fusile material"
if(prob(40))
ground_survey_result += "<br>High content of fissile material in the rock"
/obj/effect/overmap/visitable/sector/exoplanet/lava/generate_magnet_survey_result()
..()
magnet_strength = "[rand(20, 120)] uT/Gauss"
magnet_difference = "[rand(0,2500)] kilometers"
magnet_particles = ""
var/list/particle_types = PARTICLE_TYPES
var/particles = rand(1,5)
for(var/i in 1 to particles)
var/p = pick(particle_types)
if(i == particles) //Last item, no comma
magnet_particles += p
else
magnet_particles += "[p], "
particle_types -= p
day_length = "~[rand(1,200)/10] BCY (Biesel Cycles)"
if(prob(40))
magnet_survey_result += "<br>Molten surface interfering with magnetosphere"
if(prob(40))
magnet_survey_result += "<br>Strong solar winds present"
if(prob(10))
magnet_survey_result += "<br>High levels of plasma present in magnetosphere"
@@ -0,0 +1,69 @@
// --------------------------------- Burzsia I
/obj/effect/overmap/visitable/sector/exoplanet/burzsia
name = "Burzsia I"
desc = "An important Hephaestus Industries mining planet. Burzsia is inhospitable, toxic and dangerous to life."
icon_state = "globe1"
color = "#b7410e"
planetary_area = /area/exoplanet/barren/burzsia
scanimage = "adhomai.png"
massvolume = "4.24/2.33"
surfacegravity = "4.14"
charted = "Charted 2199CE, Solarian Alliance"
geology = "Extreme volcanic activity with surface minerals in abundance"
weather = "Tidally locked day/night split, extreme weather conditions with a toxic atmosphere and lightning storms"
surfacewater = "No presence of water. Large bodies of liquid ammonia and molten metal"
rock_colors = list(COLOR_DARK_BROWN)
plant_colors = null
possible_themes = list(/datum/exoplanet_theme/barren)
features_budget = 1
surface_color = "#b7410e"
generated_name = FALSE
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/burzsia_mining, /datum/map_template/ruin/exoplanet/burzsia_dead_ipc)
place_near_main = list(2, 2)
var/bright_side = TRUE
/obj/effect/overmap/visitable/sector/exoplanet/burzsia/pre_ruin_preparation()
if(prob(50))
bright_side = FALSE
/obj/effect/overmap/visitable/sector/exoplanet/burzsia/generate_habitability()
return HABITABILITY_BAD
/obj/effect/overmap/visitable/sector/exoplanet/burzsia/get_surface_color()
return "#b7410e"
/obj/effect/overmap/visitable/sector/exoplanet/burzsia/generate_atmosphere()
..()
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_CO2, MOLES_N2STANDARD)
atmosphere.adjust_gas(GAS_NO2, MOLES_O2STANDARD)
if(bright_side)
atmosphere.temperature = T0C + 546
else
atmosphere.temperature = T0C - 113
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/burzsia/generate_map()
if(bright_side)
lightlevel = 10
else
lightlevel = 0
..()
/obj/effect/overmap/visitable/sector/exoplanet/burzsia/generate_planet_image()
skybox_image = image('icons/skybox/lore_planets.dmi', "burzsia")
skybox_image.pixel_x = rand(0,64)
skybox_image.pixel_y = rand(128,256)
/obj/effect/overmap/visitable/sector/exoplanet/burzsia/generate_ground_survey_result()
ground_survey_result = "" // so it does not get randomly generated survey results
// --------------------------------- Burzsia II
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/burzsia
name = "Burzsia II"
generated_name = FALSE
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/burzsia/generate_ground_survey_result()
ground_survey_result = "" // so it does not get randomly generated survey results
@@ -0,0 +1,184 @@
// --------------------------------- Konyang
/obj/effect/overmap/visitable/sector/exoplanet/konyang
name = "Konyang"
desc = "A Coalition world which was recently Solarian territory, now resting on the fringes of the northern Frontier. It possesses very humid weather and highly developed infrastructure, boasting a population in some billions."
icon_state = "globe2"
color = "#68e968"
planetary_area = /area/exoplanet/grass/konyang
initial_weather_state = /singleton/state/weather/rain/storm/jungle_planet
scanimage = "konyang.png"
massvolume = "0.89/0.99"
surfacegravity = "0.93"
charted = "Charted 2305, Sol Alliance Department of Colonization."
geology = "Low-energy tectonic heat signature, minimal surface disruption"
weather = "Global full-atmosphere hydrological weather system. Substantial meteorological activity, violent storms unpredictable"
surfacewater = "Majority potable, 88% surface water. Significant tidal forces from natural satellite"
features_budget = 8
surface_color = null//pre colored
water_color = null//pre colored
rock_colors = null//pre colored
plant_colors = null//pre colored
generated_name = FALSE
flora_diversity = 0
has_trees = FALSE
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list(
/datum/map_template/ruin/exoplanet/konyang_landing_zone,
/datum/map_template/ruin/exoplanet/konyang_jeweler_nest,
/datum/map_template/ruin/exoplanet/konyang_village,
/datum/map_template/ruin/exoplanet/konyang_telecomms_outpost,
/datum/map_template/ruin/exoplanet/pirate_outpost,
/datum/map_template/ruin/exoplanet/pirate_moonshine,
/datum/map_template/ruin/exoplanet/hivebot_burrows_1,
/datum/map_template/ruin/exoplanet/hivebot_burrows_2,
/datum/map_template/ruin/exoplanet/konyang_fireoutpost,
/datum/map_template/ruin/exoplanet/konyang_homestead,
/datum/map_template/ruin/exoplanet/konyang_tribute,
/datum/map_template/ruin/exoplanet/konyang_swamp_1,
/datum/map_template/ruin/exoplanet/konyang_swamp_2,
/datum/map_template/ruin/exoplanet/konyang_swamp_3,
/datum/map_template/ruin/exoplanet/konyang_swamp_4,
/datum/map_template/ruin/exoplanet/konyang_abandoned_outpost,
/datum/map_template/ruin/exoplanet/konyang_abandoned_village,
/datum/map_template/ruin/exoplanet/konyang_lostcop,
/datum/map_template/ruin/exoplanet/rural_clinic
)
possible_themes = list(/datum/exoplanet_theme/konyang)
place_near_main = list(1,0)
var/landing_area
/obj/effect/overmap/visitable/sector/exoplanet/konyang/Initialize()
. = ..()
var/area/overmap/map = global.map_overmap
for(var/obj/effect/overmap/visitable/sector/point_verdant/P in map)
P.x = x
P.y = y
/obj/effect/overmap/visitable/sector/exoplanet/konyang/generate_habitability()
return HABITABILITY_IDEAL
/obj/effect/overmap/visitable/sector/exoplanet/konyang/generate_map()
lightlevel = 50
..()
/obj/effect/overmap/visitable/sector/exoplanet/konyang/generate_planet_image()
skybox_image = image('icons/skybox/lore_planets.dmi', "konyang")
skybox_image.pixel_x = rand(0,64)
skybox_image.pixel_y = rand(128,256)
/obj/effect/overmap/visitable/sector/exoplanet/konyang/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/konyang/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_OXYGEN, MOLES_O2STANDARD, 1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_N2STANDARD, 1)
atmosphere.temperature = T20C
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/konyang/generate_ground_survey_result()
ground_survey_result = "" // so it does not get randomly generated survey results
/obj/effect/overmap/visitable/sector/exoplanet/konyang/pre_ruin_preparation()
landing_area = pick("overgrown wilderness within the Yakusoku Jungle.", "abandoned infrastructure in Han'ei Industrial Park, discontinued.")
switch(landing_area)
if("overgrown wilderness within the Yakusoku Jungle.")
possible_themes = list(/datum/exoplanet_theme/konyang)
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/konyang_landing_zone, /datum/map_template/ruin/exoplanet/konyang_jeweler_nest, /datum/map_template/ruin/exoplanet/konyang_village, /datum/map_template/ruin/exoplanet/konyang_telecomms_outpost, /datum/map_template/ruin/exoplanet/pirate_outpost, /datum/map_template/ruin/exoplanet/pirate_moonshine, /datum/map_template/ruin/exoplanet/hivebot_burrows_1, /datum/map_template/ruin/exoplanet/hivebot_burrows_2, /datum/map_template/ruin/exoplanet/konyang_fireoutpost, /datum/map_template/ruin/exoplanet/konyang_homestead, /datum/map_template/ruin/exoplanet/konyang_tribute, /datum/map_template/ruin/exoplanet/konyang_swamp_1, /datum/map_template/ruin/exoplanet/konyang_swamp_2, /datum/map_template/ruin/exoplanet/konyang_swamp_3, /datum/map_template/ruin/exoplanet/konyang_swamp_4, /datum/map_template/ruin/exoplanet/konyang_abandoned_outpost, /datum/map_template/ruin/exoplanet/konyang_abandoned_village)
if("abandoned infrastructure in Han'ei Industrial Park, discontinued.")
possible_themes = list(/datum/exoplanet_theme/konyang/abandoned)
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/konyang_abandoned_landing_zone, /datum/map_template/ruin/exoplanet/konyang_office, /datum/map_template/ruin/exoplanet/konyang_house_small, /datum/map_template/ruin/exoplanet/konyang_factory_robotics, /datum/map_template/ruin/exoplanet/konyang_factory_refinery, /datum/map_template/ruin/exoplanet/konyang_factory_arms, /datum/map_template/ruin/exoplanet/konyang_garage)
desc += " Landing beacon details of [landing_area]"
// --------------------------------- Qixi
/obj/effect/overmap/visitable/sector/exoplanet/barren/qixi
name = "Qixi"
desc = "The small, lifeless, and largely insignificant moon of Konyang."
icon_state = "globe1"
color = "#a2b3ad"
rock_colors = list("#807f7f")
massvolume = "0.27/0.39"
surfacegravity = "0.19"
geology = "No tectonic activity detected."
charted = "Natural satellite of Konyang. Charted 2305, Sol Alliance Department of Colonization."
features_budget = 1
surface_color = "#807f7f"
generated_name = FALSE
ring_chance = 0
ruin_planet_type = PLANET_LORE
place_near_main = list(1, 1)
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/haneunim_mystery, /datum/map_template/ruin/exoplanet/haneunim_flag, /datum/map_template/ruin/exoplanet/haneunim_mining, /datum/map_template/ruin/exoplanet/haneunim_crash)
/obj/effect/overmap/visitable/sector/exoplanet/barren/qixi/get_surface_color()
return "#807f7f"
/obj/effect/overmap/visitable/sector/exoplanet/barren/qixi/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/barren/qixi/generate_ground_survey_result()
ground_survey_result = "" // so it does not get randomly generated survey results
// --------------------------------- ice asteroid
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ice/haneunim
desc = "An ice-covered rock from the outlying asteroid belt of Haneunim. Largely unexplored and uninhabited."
ruin_planet_type = PLANET_LORE
place_near_main = null
generated_name = FALSE
features_budget = 1
ring_chance = 0
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/haneunim_crash, /datum/map_template/ruin/exoplanet/haneunim_refugees, /datum/map_template/ruin/exoplanet/haneunim_mystery, /datum/map_template/ruin/exoplanet/haneunim_mining)
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ice/haneunim/generate_ground_survey_result()
ground_survey_result = "" // so it does not get randomly generated survey results
// --------------------------------- Huozhu
/obj/effect/overmap/visitable/sector/exoplanet/lava/huozhu
name = "Huozhu"
desc = "A scorching dwarf planet close to Haneunim's star. Largely unexplored."
icon_state = "globe1"
massvolume = "0.39/0.56"
surfacegravity = "0.32"
charted = "Charted 2305, Sol Alliance Department of Colonization."
ruin_planet_type = PLANET_LORE
generated_name = FALSE
features_budget = 1
ring_chance = 0
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/haneunim_crash, /datum/map_template/ruin/exoplanet/haneunim_mystery)
/obj/effect/overmap/visitable/sector/exoplanet/lava/huozhu/generate_atmosphere()
..()
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_SULFUR, MOLES_N2STANDARD)
atmosphere.temperature = T20C + rand(600, 1000)
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/lava/huozhu/generate_ground_survey_result()
ground_survey_result = "" // so it does not get randomly generated survey results
// --------------------------------- Hwanung
/obj/effect/overmap/visitable/sector/exoplanet/barren/hwanung
name = "Hwanung"
generated_name = FALSE
desc = "A dwarf planet in the Haneunim system, largely considered insignificant."
icon_state = "globe1"
massvolume = "0.31/0.42"
surfacegravity = "0.18"
charted = "Charted 2305, Sol Alliance Department of Colonization."
features_budget = 1
ring_chance = 0
ruin_planet_type = PLANET_LORE
rock_colors = list(COLOR_GRAY80)
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/haneunim_crash, /datum/map_template/ruin/exoplanet/haneunim_refugees, /datum/map_template/ruin/exoplanet/haneunim_mystery, /datum/map_template/ruin/exoplanet/haneunim_flag, /datum/map_template/ruin/exoplanet/haneunim_mining)
/obj/effect/overmap/visitable/sector/exoplanet/barren/hwanung/generate_ground_survey_result()
ground_survey_result = "" // so it does not get randomly generated survey results
@@ -0,0 +1,241 @@
// --------------------------------- Ae'themir
/obj/effect/overmap/visitable/sector/exoplanet/barren/aethemir
name = "Ae'themir"
desc = "A planet comprised mainly of solid common minerals and silicate."
color = "#bf7c39"
icon_state = "globe1"
charted = "Tajaran core world, charted 2418CE, NanoTrasen Corporation"
rock_colors = list(COLOR_GRAY80)
features_budget = 1
surface_color = "#B1A69B"
generated_name = FALSE
ring_chance = 0
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/pra_exploration_drone)
/obj/effect/overmap/visitable/sector/exoplanet/barren/aethemir/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_O2STANDARD)
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/barren/aethemir/get_surface_color()
return "#B1A69B"
/obj/effect/overmap/visitable/sector/exoplanet/barren/aethemir/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/barren/aethemir/generate_ground_survey_result()
ground_survey_result = "<br>High concentrations of silicate detected"
// --------------------------------- Az'Mar
/obj/effect/overmap/visitable/sector/exoplanet/barren/azmar
name = "Az'Mar"
desc = "A small planet with a caustic shale crust. The surface is extremely hot and dense."
charted = "Tajaran core world, charted 2418CE, NanoTrasen Corporation"
color = "#8f4754"
icon_state = "globe2"
plant_colors = null
rock_colors = list("#4a3f41")
features_budget = 1
surface_color = "#4a3f41"
generated_name = FALSE
ring_chance = 0
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/pra_exploration_drone)
/obj/effect/overmap/visitable/sector/exoplanet/barren/azmar/get_surface_color()
return "#4a3f41"
/obj/effect/overmap/visitable/sector/exoplanet/barren/azmar/get_atmosphere_color()
return "#D8E2E9"
/obj/effect/overmap/visitable/sector/exoplanet/barren/azmar/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_CHLORINE, MOLES_O2STANDARD)
atmosphere.temperature = T0C + 500
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/barren/azmar/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/barren/azmar/generate_ground_survey_result()
ground_survey_result = "<br>No notable concentration of valuable minerals detected in the mantle"
// --------------------------------- Sahul
/obj/effect/overmap/visitable/sector/exoplanet/lava/sahul
name = "Sahul"
desc = "Az'mar's moon is a celestial body composed primarily of molten metals."
charted = "Natural satellite of Az'mar, Tajaran core world, charted 2418CE, NanoTrasen Corporation"
icon_state = "globe1"
color = "#cf1020"
generated_name = FALSE
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/pra_exploration_drone)
ring_chance = 0
/obj/effect/overmap/visitable/sector/exoplanet/lava/sahul/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/lava/sahul/generate_ground_survey_result()
ground_survey_result = "<br>Molten metals detected in the crust"
// --------------------------------- Raskara
/obj/effect/overmap/visitable/sector/exoplanet/barren/raskara
name = "Raskara"
desc = "A barren moon orbiting Adhomai."
icon_state = "globe1"
color = "#ab46d4"
rock_colors = list("#373737")
planetary_area = /area/exoplanet/barren/raskara
scanimage = "raskara.png"
massvolume = "0.27/0.39"
surfacegravity = "0.25"
charted = "Natural satellite of Tajaran homeworld, charted 2418CE, NanoTrasen Corporation"
geology = "Zero tectonic heat, completely dormant geothermal signature. Presumed dead core"
possible_themes = list(/datum/exoplanet_theme/barren/raskara)
features_budget = 1
surface_color = "#373737"
generated_name = FALSE
ring_chance = 0
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/raskara_ritual, /datum/map_template/ruin/exoplanet/raskara_okon, /datum/map_template/ruin/exoplanet/raskara_wreck, /datum/map_template/ruin/exoplanet/pra_exploration_drone)
place_near_main = list(3, 3)
/obj/effect/overmap/visitable/sector/exoplanet/barren/raskara/get_surface_color()
return "#373737"
/obj/effect/overmap/visitable/sector/exoplanet/barren/raskara/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/barren/raskara/generate_planet_image()
skybox_image = image('icons/skybox/lore_planets.dmi', "raskara")
skybox_image.pixel_x = rand(0,64)
skybox_image.pixel_y = rand(128,256)
/obj/effect/overmap/visitable/sector/exoplanet/barren/raskara/generate_ground_survey_result()
if(prob(1))
ground_survey_result = "<br>Unidentified anomalous readings detected in the inner core"
else
ground_survey_result = "<br>High concretation of dense metal in the mantle"
// --------------------------------- Adhomai
// NOTE: To trigger Adhomai 'event' (eclipses). Use the set holiday verb to the eclipse name BEFORE this planet is initialized, or have holiday added to holidays.dm
// "Shi-rrata" : Messa Eclipse. Lighting changes.
// "Shi-rra ArrKahata" : Raskara Eclipse. This makes planet covered in darkness and increases hostile animal spawns (Adhomai Hell)
/obj/effect/overmap/visitable/sector/exoplanet/adhomai
name = "Adhomai"
desc = "The Tajaran homeworld. Adhomai is a cold and icy world, suffering from almost perpetual snowfall and extremely low temperatures."
icon_state = "globe2"
color = "#b5dfeb"
planetary_area = /area/exoplanet/adhomai
initial_weather_state = /singleton/state/weather/calm/snow_planet
scanimage = "adhomai.png"
massvolume = "0.86/0.98"
surfacegravity = "0.80"
charted = "Tajaran homeworld, charted 2418CE, NanoTrasen Corporation"
geology = "Minimal tectonic heat, miniscule geothermal signature overall"
weather = "Global full-atmosphere hydrological weather system. Substantial meteorological activity, violent storms unpredictable"
surfacewater = "Majority frozen, 78% surface water. Significant tidal forces from natural satellite"
rock_colors = list("#6fb1b5")
plant_colors = null
flora_diversity = 0
has_trees = FALSE
possible_themes = list(/datum/exoplanet_theme/snow/adhomai)
features_budget = 8
surface_color = "#e8faff"
water_color = "#b5dfeb"
generated_name = FALSE
ruin_planet_type = PLANET_LORE
small_flora_types = list(/datum/seed/shand, /datum/seed/mtear, /datum/seed/earthenroot, /datum/seed/nifberries, /datum/seed/mushroom/nfrihi, /datum/seed/nmshaan)
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/adhomai_hunting, /datum/map_template/ruin/exoplanet/adhomai_minefield, /datum/map_template/ruin/exoplanet/adhomai_village,
/datum/map_template/ruin/exoplanet/adhomai_abandoned_village, /datum/map_template/ruin/exoplanet/adhomai_battlefield, /datum/map_template/ruin/exoplanet/adhomai_cavern, /datum/map_template/ruin/exoplanet/adhomai_bar,
/datum/map_template/ruin/exoplanet/adhomai_war_memorial, /datum/map_template/ruin/exoplanet/adhomai_raskara_ritual, /datum/map_template/ruin/exoplanet/adhomai_raskariim_hideout, /datum/map_template/ruin/exoplanet/adhomai_cavern_geist,
/datum/map_template/ruin/exoplanet/adhomai_tunneler_nest, /datum/map_template/ruin/exoplanet/adhomai_rafama_herd)
place_near_main = list(2, 2)
var/landing_faction
/obj/effect/overmap/visitable/sector/exoplanet/adhomai/pre_ruin_preparation()
if(prob(15))
landing_faction = "North Pole"
else
landing_faction = pick("People's Republic of Adhomai", "Democratic People's Republic of Adhomai", "New Kingdom of Adhomai")
switch(landing_faction)
if("People's Republic of Adhomai")
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/adhomai_hunting, /datum/map_template/ruin/exoplanet/adhomai_minefield, /datum/map_template/ruin/exoplanet/adhomai_village,
/datum/map_template/ruin/exoplanet/adhomai_abandoned_village, /datum/map_template/ruin/exoplanet/adhomai_battlefield, /datum/map_template/ruin/exoplanet/adhomai_cavern, /datum/map_template/ruin/exoplanet/adhomai_raskara_ritual,
/datum/map_template/ruin/exoplanet/adhomai_bar, /datum/map_template/ruin/exoplanet/adhomai_war_memorial, /datum/map_template/ruin/exoplanet/adhomai_raskariim_hideout, /datum/map_template/ruin/exoplanet/adhomai_cavern_geist,
/datum/map_template/ruin/exoplanet/adhomai_tunneler_nest, /datum/map_template/ruin/exoplanet/adhomai_rafama_herd, /datum/map_template/ruin/exoplanet/adhomai_abandoned_labor_camp,
/datum/map_template/ruin/exoplanet/psis_outpost, /datum/map_template/ruin/exoplanet/pra_base, /datum/map_template/ruin/exoplanet/adhomai_president_hadii_statue, /datum/map_template/ruin/exoplanet/pra_mining_camp, /datum/map_template/ruin/exoplanet/adhomai_nuclear_waste,
/datum/map_template/ruin/exoplanet/adhomai_fallout_bunker, /datum/map_template/ruin/exoplanet/adhomai_schlorrgo_cage, /datum/map_template/ruin/exoplanet/adhomai_silo)
if("Democratic People's Republic of Adhomai")
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/adhomai_hunting, /datum/map_template/ruin/exoplanet/adhomai_minefield, /datum/map_template/ruin/exoplanet/adhomai_village,
/datum/map_template/ruin/exoplanet/adhomai_abandoned_village, /datum/map_template/ruin/exoplanet/adhomai_battlefield, /datum/map_template/ruin/exoplanet/adhomai_cavern, /datum/map_template/ruin/exoplanet/adhomai_raskara_ritual,
/datum/map_template/ruin/exoplanet/adhomai_bar, /datum/map_template/ruin/exoplanet/adhomai_war_memorial, /datum/map_template/ruin/exoplanet/adhomai_raskariim_hideout, /datum/map_template/ruin/exoplanet/adhomai_cavern_geist,
/datum/map_template/ruin/exoplanet/adhomai_tunneler_nest, /datum/map_template/ruin/exoplanet/adhomai_rafama_herd, /datum/map_template/ruin/exoplanet/adhomai_amohdan,
/datum/map_template/ruin/exoplanet/ala_cell, /datum/map_template/ruin/exoplanet/adhomai_chemical_testing, /datum/map_template/ruin/exoplanet/adhomai_president_hadii_statue_toppled, /datum/map_template/ruin/exoplanet/ala_base,
/datum/map_template/ruin/exoplanet/adhomai_deserter, /datum/map_template/ruin/exoplanet/adhomai_nuclear_waste_makeshift, /datum/map_template/ruin/exoplanet/adhomai_rredouane_shrine, /datum/map_template/ruin/exoplanet/adhomai_sole_rock_nomad)
if("New Kingdom of Adhomai")
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/adhomai_hunting, /datum/map_template/ruin/exoplanet/adhomai_minefield, /datum/map_template/ruin/exoplanet/adhomai_village,
/datum/map_template/ruin/exoplanet/adhomai_abandoned_village, /datum/map_template/ruin/exoplanet/adhomai_battlefield, /datum/map_template/ruin/exoplanet/adhomai_cavern, /datum/map_template/ruin/exoplanet/adhomai_raskara_ritual,
/datum/map_template/ruin/exoplanet/adhomai_bar, /datum/map_template/ruin/exoplanet/adhomai_war_memorial, /datum/map_template/ruin/exoplanet/adhomai_raskariim_hideout,/datum/map_template/ruin/exoplanet/adhomai_cavern_geist,
/datum/map_template/ruin/exoplanet/adhomai_tunneler_nest, /datum/map_template/ruin/exoplanet/adhomai_rafama_herd, /datum/map_template/ruin/exoplanet/adhomai_amohdan, /datum/map_template/ruin/exoplanet/adhomai_archeology,
/datum/map_template/ruin/exoplanet/nka_base, /datum/map_template/ruin/exoplanet/adhomai_president_hadii_statue_toppled, /datum/map_template/ruin/exoplanet/adhomai_rredouane_shrine, /datum/map_template/ruin/exoplanet/adhomai_sole_rock_nomad)
if("North Pole")
features_budget = 1
possible_themes = list(/datum/exoplanet_theme/snow/tundra/adhomai)
ruin_type_whitelist = list (/datum/map_template/ruin/exoplanet/north_pole_monolith, /datum/map_template/ruin/exoplanet/north_pole_nka_expedition, /datum/map_template/ruin/exoplanet/north_pole_worm)
initial_weather_state = /singleton/state/weather/calm/arctic_planet
if(Holiday == "Shi-rra ArrKahata") // Messa weeps.
if(landing_faction != "North Pole")
possible_themes = list(/datum/exoplanet_theme/snow/adhomai/darkest_eclipse)
else
possible_themes = list(/datum/exoplanet_theme/snow/tundra/adhomai/darkest_eclipse)
desc += " The landing sites are located at the [landing_faction]'s territory."
/obj/effect/overmap/visitable/sector/exoplanet/adhomai/generate_habitability()
return HABITABILITY_IDEAL
/obj/effect/overmap/visitable/sector/exoplanet/adhomai/generate_map()
if(prob(75))
lightlevel = rand(3,10)/10
switch(Holiday) // Handle eclipses
if("Shi-rrata") // Messa Eclipse
lightlevel = 9/10
lightcolor = COLOR_CYAN
if("Shi-rra ArrKahata") //Raskara Eclipse. Board your windows.
lightlevel = 0
..()
/obj/effect/overmap/visitable/sector/exoplanet/adhomai/generate_planet_image()
skybox_image = image('icons/skybox/lore_planets.dmi', "adhomai")
skybox_image.pixel_x = rand(0,64)
skybox_image.pixel_y = rand(128,256)
/obj/effect/overmap/visitable/sector/exoplanet/adhomai/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_OXYGEN, MOLES_O2STANDARD, 1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_N2STANDARD, 1)
if(landing_faction == "North Pole")
atmosphere.temperature = T0C - 40
else
atmosphere.temperature = T0C - 5
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/adhomai/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/adhomai/generate_ground_survey_result()
ground_survey_result = "<br>High quality minerals detected in the crust and mantle"
@@ -0,0 +1,201 @@
// --------------------------------- Caprice
/obj/effect/overmap/visitable/sector/exoplanet/lava/caprice
name = "Caprice"
desc = "A scorching-hot volcanic planet close to Tau Ceti."
charted = "Charted 2147CE, Sol Alliance Department of Colonization."
icon_state = "globe1"
color = "#cf1020"
generated_name = FALSE
ring_chance = 0
/obj/effect/overmap/visitable/sector/exoplanet/lava/caprice/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/lava/caprice/generate_ground_survey_result()
ground_survey_result = "<br>Natural caverns and artificial tunnels"
/obj/effect/overmap/visitable/sector/exoplanet/lava/caprice/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_O2STANDARD)
atmosphere.temperature = T0C + 400
atmosphere.update_values()
// --------------------------------- Luthien
/obj/effect/overmap/visitable/sector/exoplanet/desert/luthien
name = "Luthien"
desc = "A desert planet with a thin, unbreathable atmosphere of primarily nitrogen."
charted = "Charted 2147CE, Sol Alliance Department of Colonization."
icon_state = "globe1"
rock_colors = list("#e49135")
color = "#e49135"
generated_name = FALSE
ring_chance = 0
/obj/effect/overmap/visitable/sector/exoplanet/lava/luthien/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/desert/luthien/generate_habitability()
return HABITABILITY_BAD
/obj/effect/overmap/visitable/sector/exoplanet/desert/luthien/generate_ground_survey_result()
ground_survey_result = "<br>Sandy soil with organic fungal contamination"
/obj/effect/overmap/visitable/sector/exoplanet/desert/luthien/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_O2STANDARD)
atmosphere.update_values()
// --------------------------------- Valkyrie
/obj/effect/overmap/visitable/sector/exoplanet/barren/valkyrie
name = "Valkyrie"
desc = "The moon of Tau Ceti, the third planet to be settled in the system."
charted = "Natural satellite of Tau Ceti, charted 2147CE, Sol Alliance Department of Colonization."
icon_state = "globe1"
rock_colors = list("#4a3f41")
color = "#4a3f41"
generated_name = FALSE
ring_chance = 0
/obj/effect/overmap/visitable/sector/exoplanet/barren/valkyrie/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/barren/valkyrie/generate_ground_survey_result()
ground_survey_result = "<br>Soil with presence of nitrogen deposits"
// --------------------------------- New Gibson
/obj/effect/overmap/visitable/sector/exoplanet/snow/new_gibson
name = "New Gibson"
desc = "An ice world just outside the outer edge of the habitable zone."
charted = "Charted 2147CE, Sol Alliance Department of Colonization."
icon_state = "globe1"
features_budget = 1
possible_themes = list(/datum/exoplanet_theme/snow/tundra)
rock_colors = list(COLOR_GUNMETAL)
generated_name = FALSE
ring_chance = 0
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/gibson_mining, /datum/map_template/ruin/exoplanet/gibson_resupply)
/obj/effect/overmap/visitable/sector/exoplanet/snow/new_gibson/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/snow/new_gibson/generate_habitability()
return HABITABILITY_BAD
/obj/effect/overmap/visitable/sector/exoplanet/snow/new_gibson/generate_ground_survey_result()
ground_survey_result = "<br>Mineral-rich soil with presence of artificial structures"
/obj/effect/overmap/visitable/sector/exoplanet/snow/new_gibson/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_O2STANDARD)
atmosphere.temperature = T0C - 200
atmosphere.update_values()
// --------------------------------- Chandras
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ice/chandras
name = "Chandras"
desc = "An an icy body in a distant orbit of Tau Ceti."
charted = "Charted 2147CE, Sol Alliance Department of Colonization."
icon_state = "globe1"
color = "#b2abbf"
rock_colors = list("#b2abbf")
generated_name = FALSE
ring_chance = 0
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ice/chandras/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ice/chandras/generate_habitability()
return HABITABILITY_BAD
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ice/chandras/generate_ground_survey_result()
ground_survey_result = "<br>Soil with presence of nitrogen and ice deposits"
// --------------------------------- Dumas
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/dumas
name = "Dumas"
desc = "An extremely small rocky body that orbits within the far reaches of Tau Ceti."
charted = "Charted 2147CE, Sol Alliance Department of Colonization."
icon_state = "asteroid"
generated_name = FALSE
ring_chance = 0
place_near_main = null
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/dumas/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/dumas/generate_ground_survey_result()
ground_survey_result = "<br>No notable deposits underground"
// --------------------------------- Biesel
/obj/effect/overmap/visitable/sector/exoplanet/biesel
name = "Biesel"
desc = "The third closest planet to Tau Ceti's star, Biesel is an Earth-like planet that benefits from a temperate climate and breathable atmosphere. It is the capital planet of the Republic of Biesel."
icon_state = "globe2"
color = "#5B8958"
planetary_area = /area/exoplanet/grass
scanimage = "biesel.png"
massvolume = "0.95~/1.1"
surfacegravity = "0.99"
charted = "Charted 2147CE, Sol Alliance Department of Colonization."
geology = "Low-energy tectonic heat signature, minimal surface disruption"
weather = "Global full-atmosphere hydrological weather system."
surfacewater = "Majority potable, 75% surface water. Significant tidal forces from natural satellite"
rock_colors = list(COLOR_BROWN)
flora_diversity = 0
possible_themes = list(/datum/exoplanet_theme/grass/biesel)
features_budget = 8
surface_color = null//pre colored
water_color = null//pre colored
plant_colors = null//pre colored
generated_name = FALSE
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list(
/datum/map_template/ruin/exoplanet/abandoned_warehouse_1,
/datum/map_template/ruin/exoplanet/abandoned_warehouse_2,
/datum/map_template/ruin/exoplanet/biesel_camp_site,
/datum/map_template/ruin/exoplanet/cargo_ruins_1,
/datum/map_template/ruin/exoplanet/cargo_ruins_2,
/datum/map_template/ruin/exoplanet/cargo_ruins_3,
/datum/map_template/ruin/exoplanet/pra_camp_site)
place_near_main = list(2, 2)
/obj/effect/overmap/visitable/sector/exoplanet/biesel/generate_habitability()
return HABITABILITY_IDEAL
/obj/effect/overmap/visitable/sector/exoplanet/biesel/generate_map()
if(prob(75))
lightlevel = rand(5,10)/10
..()
/obj/effect/overmap/visitable/sector/exoplanet/biesel/generate_planet_image()
skybox_image = image('icons/skybox/lore_planets.dmi', "biesel")
skybox_image.pixel_x = rand(0,64)
skybox_image.pixel_y = rand(128,256)
/obj/effect/overmap/visitable/sector/exoplanet/biesel/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_OXYGEN, MOLES_O2STANDARD, 1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_N2STANDARD, 1)
atmosphere.temperature = T20C
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/biesel/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/biesel/generate_ground_survey_result()
ground_survey_result = "Notable mineral deposits located underground"
@@ -0,0 +1,325 @@
//Omzoli
/obj/effect/overmap/visitable/sector/exoplanet/barren/omzoli
name = "Omzoli"
desc = "A small and barren planet, bereft of anything other than scientific value and some small mineral deposits"
color = "#a39f9e"
icon_state = "globe"
rock_colors = list(COLOR_GRAY80)
possible_themes = list(/datum/exoplanet_theme/barren)
features_budget = 1
surface_color = "#6b6464"
generated_name = FALSE
charted = "Unathi core world. Charted 2403CE, Sol Alliance Department of Colonization"
geology = "Low mineral levels. No active geothermal signatures detected. "
ring_chance = 0
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/izweski_probe, /datum/map_template/ruin/exoplanet/heph_survey_post, /datum/map_template/ruin/exoplanet/kazhkz_crash)
/obj/effect/overmap/visitable/sector/exoplanet/barren/omzoli/get_surface_color()
return "#6b6464"
/obj/effect/overmap/visitable/sector/exoplanet/barren/omzoli/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/barren/omzoli/generate_ground_survey_result()
..()
ground_survey_result += "<br>Trace mineral deposits detected in regolith"
ground_survey_result += "<br>Planetary rotation counter to spin of local star and other planets in system"
ground_survey_result += "<br>Carbon-dating indicates planetary age of at least 6.32 billion years"
ground_survey_result += "<br>Lack of atmosphere and unusual rotation can cause extremely wild temperature fluctuations"
ground_survey_result += "<br>High chance of meteor impact indicated through analysis of local surface craters"
//Pid
/obj/effect/overmap/visitable/sector/exoplanet/barren/pid
name = "Pid"
desc = "Tret's moon, now home to a majority of K'laxan k'ois farming efforts."
icon_state = "asteroid"
color = "#ddff61"
rock_colors = list("#93948f")
features_budget = 1
surface_color = "#83857f"
charted = "Natural satellite of Tret, Unathi core world. Charted 2403CE, Sol Alliance Department of Colonization"
generated_name = FALSE
small_flora_types = list(/datum/seed/koisspore)
possible_themes = list(/datum/exoplanet_theme/barren/pid)
ring_chance = 0
ruin_planet_type = PLANET_LORE
planetary_area = /area/exoplanet/barren/pid
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/pid_crashed_shuttle, /datum/map_template/ruin/exoplanet/pid_kois_farm, /datum/map_template/ruin/exoplanet/izweski_probe, /datum/map_template/ruin/exoplanet/heph_survey_post, /datum/map_template/ruin/exoplanet/kazhkz_crash)
/obj/effect/overmap/visitable/sector/exoplanet/barren/pid/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_N2STANDARD)
atmosphere.temperature = T0C + 20
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/barren/pid/generate_ground_survey_result()
..()
ground_survey_result += "<br>Trace elements of phoron and biological matter detected in local atmosphere"
ground_survey_result += "<br>Small mineral deposits detected, largely untapped"
ground_survey_result += "<br>Evidence of lava tubes being present in the subsurface"
ground_survey_result += "<br>K'ois spores detected in local soil. Sample destruction recommended"
ground_survey_result += "<br>Surface soil may provide adequate radiation shielding"
//Ytizi Belt Asteroid. This exists solely for unique away site spawns, and is otherwise indistinguishable from a regular asteroid
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ytizi
name = "Ytizi Belt asteroid"
desc = "One of the many mineral-rich asteroids found in the Uueoa-Esa system's asteroid belt"
icon_state = "asteroid2"
possible_themes = list(/datum/exoplanet_theme/barren/asteroid, /datum/exoplanet_theme/barren/asteroid/ice)
ruin_planet_type = PLANET_LORE
features_budget = 3
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/heph_mining_station, /datum/map_template/ruin/exoplanet/miners_guild_outpost, /datum/map_template/ruin/exoplanet/sol_listening_post, /datum/map_template/ruin/exoplanet/crashed_sol_shuttle_01, /datum/map_template/ruin/exoplanet/crashed_skrell_shuttle_01, /datum/map_template/ruin/exoplanet/digsite, /datum/map_template/ruin/exoplanet/abandoned_outpost, /datum/map_template/ruin/exoplanet/izweski_probe, /datum/map_template/ruin/exoplanet/heph_survey_post, /datum/map_template/ruin/exoplanet/kazhkz_crash)
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/ytizi/pre_ruin_preparation()
if(istype(theme, /datum/exoplanet_theme/barren/asteroid/ice))
surface_color = COLOR_BLUE_GRAY
else
surface_color = COLOR_GRAY
//Chanterel
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/chanterel
name = "Chanterel"
desc = "Moghes' only moon. Rich in minerals, it is home to several mining operations."
icon_state = "asteroid"
color = "#dddedc"
possible_themes = list(/datum/exoplanet_theme/barren/asteroid/chanterel)
rock_colors = list("#c9c9c7")
features_budget = 3
surface_color = "#a3a3a3"
charted = "Natural satellite of Moghes, Unathi homeworld. Charted 2403CE, Sol Alliance Department of Colonization"
geology = "Large mineral deposits. No sign of geothermal activity."
generated_name = FALSE
ring_chance = 0
ruin_planet_type = PLANET_LORE
place_near_main = list(2,2)
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/heph_mining_station, /datum/map_template/ruin/exoplanet/miners_guild_outpost, /datum/map_template/ruin/exoplanet/digsite, /datum/map_template/ruin/exoplanet/abandoned_outpost, /datum/map_template/ruin/exoplanet/crashed_sol_shuttle_01, /datum/map_template/ruin/exoplanet/crashed_skrell_shuttle_01, /datum/map_template/ruin/exoplanet/izweski_probe, /datum/map_template/ruin/exoplanet/heph_survey_post, /datum/map_template/ruin/exoplanet/kazhkz_crash)
scanimage = "chanterel.png"
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/chanterel/generate_planet_image()
skybox_image = image('icons/skybox/lore_planets.dmi', "chanterel")
skybox_image.pixel_x = rand(0,64)
skybox_image.pixel_y = rand(128,256)
/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid/chanterel/generate_ground_survey_result()
..()
ground_survey_result += "<br>No geothermal activity observed in the planetary core"
ground_survey_result += "<br>Silicon carbides found deep in the crust"
ground_survey_result += "<br>Oxygen found in locally stable metal oxides"
ground_survey_result += "<br>Regolith rich in heavy silicate alloys"
ground_survey_result += "<br>Traces of fusile material"
//Moghes
/obj/effect/overmap/visitable/sector/exoplanet/moghes
name = "Moghes"
desc = "The hot and arid homeworld of the Unathi race, and capital world of the Izweski Hegemony. Moghes is currently suffering from an ongoing ecological collapse due to recent nuclear war."
icon_state = "globe2"
color = "#dfe08d"
planetary_area = /area/exoplanet/moghes
massvolume = "0.97/1.03"
surfacegravity = "0.93"
charted = "Unathi homeworld. Charted 2403CE, Sol Alliance Department of Colonization"
geology = "High tectonic heat. Significant geothermal activity detected."
weather = "Global full-atmosphere hydrological weather system. Substantial meteorological activity, violent storms unpredictable. Heavy radioactive contamination detected in atmosphere."
surfacewater = "34% surface water. Weak tidal forces from natural satellite."
scanimage = "moghes.png"
ring_chance = 0
rock_colors = list(COLOR_BEIGE, COLOR_PALE_YELLOW, COLOR_GRAY80, COLOR_BROWN)
plant_colors = null
possible_themes = list(/datum/exoplanet_theme/grass/moghes) //default to untouched lands in case pre_ruin_preparation fucks up
features_budget = 8
flora_diversity = 0
has_trees = FALSE
initial_weather_state = /singleton/state/weather/calm/jungle_planet
small_flora_types = list(/datum/seed/xuizi, /datum/seed/gukhe, /datum/seed/sarezhi, /datum/seed/flower/serkiflower, /datum/seed/sthberry)
surface_color = "#e8faff"
generated_name = FALSE
ruin_planet_type = PLANET_LORE
ruin_type_whitelist = list(/datum/map_template/ruin/exoplanet/moghes_village) //defaults to village bc for some reason nothing spawns if this is empty
place_near_main = list(2,2)
actors = list("reptilian humanoid", "three-faced reptilian humanoid", "a statue", "a sword", "an unidentifiable object", "an Unathi skull", "a staff", "a fishing spear", "reptilian humanoids", "unusual devices", "a pyramid")
var/landing_region
/obj/effect/overmap/visitable/sector/exoplanet/moghes/pre_ruin_preparation()
if(prob(30))
landing_region = "Untouched Lands"
else
landing_region = "Wasteland"
switch(landing_region)
if("Untouched Lands")
possible_themes = list(/datum/exoplanet_theme/grass/moghes) //non-nuked theme
surface_color = "#164a14"
//Untouched Lands ruins
ruin_type_whitelist = list(
/datum/map_template/ruin/exoplanet/moghes_village,
/datum/map_template/ruin/exoplanet/moghes_heph_mining,
/datum/map_template/ruin/exoplanet/moghes_bar,
/datum/map_template/ruin/exoplanet/moghes_hegemony_base,
/datum/map_template/ruin/exoplanet/moghes_skakh,
/datum/map_template/ruin/exoplanet/moghes_thakh,
/datum/map_template/ruin/exoplanet/moghes_kung_fu,
/datum/map_template/ruin/exoplanet/moghes_fishing_spot,
/datum/map_template/ruin/exoplanet/moghes_memorial,
/datum/map_template/ruin/exoplanet/moghes_guild_mining,
/datum/map_template/ruin/exoplanet/moghes_threshbeast_herd,
/datum/map_template/ruin/exoplanet/moghes_diona_traders,
/datum/map_template/ruin/exoplanet/moghes_untouched_tyrant
)
if("Wasteland")
possible_themes = list(/datum/exoplanet_theme/desert/wasteland) //nuked theme
surface_color = "#faeac5"
set_weather(/singleton/state/weather/calm/desert_planet)
//Wasteland ruins
ruin_type_whitelist = list(
/datum/map_template/ruin/exoplanet/moghes_guwandi,
/datum/map_template/ruin/exoplanet/moghes_gawgaryn_bikers,
/datum/map_template/ruin/exoplanet/moghes_kataphract_wasteland,
/datum/map_template/ruin/exoplanet/moghes_wasteland_dorviza,
/datum/map_template/ruin/exoplanet/moghes_wasteland_ozeuoi,
/datum/map_template/ruin/exoplanet/moghes_wasteland_vihnmes,
/datum/map_template/ruin/exoplanet/moghes_wasteland_village,
/datum/map_template/ruin/exoplanet/moghes_wasteland_izweski,
/datum/map_template/ruin/exoplanet/moghes_siakh,
/datum/map_template/ruin/exoplanet/moghes_queendom,
/datum/map_template/ruin/exoplanet/moghes_wasteland_klax,
/datum/map_template/ruin/exoplanet/moghes_wasteland_reclaimer,
/datum/map_template/ruin/exoplanet/moghes_wasteland_mikuetz,
/datum/map_template/ruin/exoplanet/moghes_wasteland_crater,
/datum/map_template/ruin/exoplanet/moghes_wasteland_oasis,
/datum/map_template/ruin/exoplanet/moghes_wasteland_battlefield,
/datum/map_template/ruin/exoplanet/moghes_ruined_base,
/datum/map_template/ruin/exoplanet/moghes_wasteland_tomb,
/datum/map_template/ruin/exoplanet/moghes_wasteland_bomb,
/datum/map_template/ruin/exoplanet/moghes_wasteland_crash,
/datum/map_template/ruin/exoplanet/moghes_wasteland_priests,
/datum/map_template/ruin/exoplanet/moghes_dead_guwandi,
/datum/map_template/ruin/exoplanet/moghes_gawgaryn_riders,
/datum/map_template/ruin/exoplanet/moghes_wasteland_tyrant
)
desc += " The landing sites are located in the [landing_region]."
/obj/effect/overmap/visitable/sector/exoplanet/moghes/generate_habitability()
return HABITABILITY_IDEAL
/obj/effect/overmap/visitable/sector/exoplanet/moghes/generate_map()
if(prob(75))
lightlevel = rand(5,10)/10
..()
/obj/effect/overmap/visitable/sector/exoplanet/moghes/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_OXYGEN, MOLES_O2STANDARD, 1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_N2STANDARD, 1)
if(landing_region == "Wasteland")
atmosphere.temperature = T0C + rand(40, 50)
else
atmosphere.temperature = T0C + rand(30, 40)
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/moghes/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/moghes/generate_planet_image()
skybox_image = image('icons/skybox/lore_planets.dmi', "moghes")
skybox_image.pixel_x = rand(0,64)
skybox_image.pixel_y = rand(128,256)
/obj/effect/overmap/visitable/sector/exoplanet/moghes/generate_ground_survey_result()
..()
switch(landing_region)
if("Untouched Lands")
ground_survey_result += "<br>Low levels of radioactive material detected in the soil"
ground_survey_result += "<br>Signs indicate soil is undergoing signs of early nutrient depletion"
ground_survey_result += "<br>Stratigraphy indicates low risk of tectonic activity in this region"
ground_survey_result += "<br>Fossilized organic material found settled in sedimentary rock"
ground_survey_result += "<br>Soft clays detected, composed of quartz and calcites"
ground_survey_result += "<br>Trace signs of radioactive contamination present in local surface water deposits"
if("Wasteland")
ground_survey_result += "<br>Extremely high levels of radioactive material detected in the soil"
ground_survey_result += "<br>Soil near-completely depleted of nutrients."
ground_survey_result += "<br>High concentration of decayed organic matter detected in soil samples"
ground_survey_result += "<br>Fragmented concrete detected within local soil. High levels of radiation indicated"
ground_survey_result += "<br>Geological analysis suggests there were once large bodies of water in this region"
ground_survey_result += "<br>Fossilized organic material found settled in sedimentary rock"
if(prob(10))
ground_survey_result += "<br>Signs of a large subterranean aquifer in this region"
//Ouerea
/obj/effect/overmap/visitable/sector/exoplanet/ouerea
name = "Ouerea"
desc = "The fourth planet from the Uueoa-Esa star, Ouerea was the first planet colonized by the Unathi. It is now home to most of the Hegemony's food production, as ecological collapse devastated Moghes"
icon_state = "globe1"
color = "#0b9e68"
planetary_area = /area/exoplanet/ouerea
massvolume = "0.94/1.0"
surfacegravity = "0.98"
charted = "Unathi core world. Charted 2403CE, Sol Alliance Department of Colonization"
geology = "High-energy geothermal signature, tectonic activity non-obstructive to surface environment"
weather = "Global full-atmosphere hydrological weather system. Dangerous meteorological activity not present"
surfacewater = "67% surface water. Four major surface seas detected."
rock_colors = null
plant_colors = null
possible_themes = list(/datum/exoplanet_theme/grass/ouerea)
features_budget = 6
ring_chance = 0
flora_diversity = 0
has_trees = FALSE
small_flora_types = list(/datum/seed/xuizi, /datum/seed/gukhe, /datum/seed/aghrassh)
generated_name = FALSE
ruin_planet_type = PLANET_LORE
initial_weather_state = /singleton/state/weather/calm/jungle_planet
ruin_type_whitelist = list(
/datum/map_template/ruin/exoplanet/ouerea_heph_mining,
/datum/map_template/ruin/exoplanet/ouerea_village,
/datum/map_template/ruin/exoplanet/ouerea_bar, /datum/map_template/ruin/exoplanet/ouerea_autakh,
/datum/map_template/ruin/exoplanet/ouerea_hegemony_base,
/datum/map_template/ruin/exoplanet/ouerea_farm,
/datum/map_template/ruin/exoplanet/ouerea_fishing_spot,
/datum/map_template/ruin/exoplanet/ouerea_sol_base,
/datum/map_template/ruin/exoplanet/ouerea_skrell_base,
/datum/map_template/ruin/exoplanet/ouerea_guild_mining,
/datum/map_template/ruin/exoplanet/ouerea_nt_ruin,
/datum/map_template/ruin/exoplanet/ouerea_freewater,
/datum/map_template/ruin/exoplanet/ouerea_battlefield,
/datum/map_template/ruin/exoplanet/ouerea_threshbeast_herd
)
place_near_main = list(2,2)
/obj/effect/overmap/visitable/sector/exoplanet/ouerea/generate_habitability()
return HABITABILITY_IDEAL
/obj/effect/overmap/visitable/sector/exoplanet/ouerea/generate_map()
if(prob(75))
lightlevel = rand(5,10)/10
..()
/obj/effect/overmap/visitable/sector/exoplanet/ouerea/generate_atmosphere()
..()
if(atmosphere)
atmosphere.remove_ratio(1)
atmosphere.adjust_gas(GAS_OXYGEN, MOLES_O2STANDARD, 1)
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_N2STANDARD, 1)
atmosphere.temperature = T0C + rand(25, 30)
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/ouerea/update_icon()
return
/obj/effect/overmap/visitable/sector/exoplanet/ouerea/generate_ground_survey_result()
..()
ground_survey_result += "<br>High quality natural fertilizer found in subterranean pockets"
ground_survey_result += "<br>Chemical extraction indicates soil is rich in major and secondary nutrients for agriculture"
ground_survey_result += "<br>Extensive subterranean water deposits detected"
ground_survey_result += "<br>Stratigraphy indicates moderate risk of tectonic activity in this region"
ground_survey_result += "<br>Muddy dirt rich in organic material"
ground_survey_result += "<br>Fossilized organic material found settled in sedimentary rock"
ground_survey_result += "<br>High nitrogen and phosphorus contents of the soil"
+80
View File
@@ -0,0 +1,80 @@
/obj/effect/overmap/visitable/sector/exoplanet/snow
name = "snow exoplanet"
desc = "A frigid exoplanet with limited plant life."
color = "#dcdcdc"
scanimage = "snow.png"
geology = "Non-existent tectonic activity, minimal geothermal signature"
weather = "Global full-atmosphere hydrological weather system. Barely-habitable ambient low temperatures. Frequently dangerous, unpredictable meteorological upsets"
surfacewater = "Majority frozen, 70% surface water"
initial_weather_state = /singleton/state/weather/calm/snow_planet
planetary_area = /area/exoplanet/snow
flora_diversity = 4
has_trees = TRUE
rock_colors = list(COLOR_DARK_BLUE_GRAY, COLOR_GUNMETAL, COLOR_GRAY80, COLOR_DARK_GRAY)
plant_colors = list("#d0fef5","#93e1d8","#93e1d8", "#b2abbf", "#3590f3", "#4b4e6d")
possible_themes = list(/datum/exoplanet_theme/snow)
surface_color = "#e8faff"
water_color = "#b5dfeb"
ruin_planet_type = PLANET_SNOW
ruin_allowed_tags = RUIN_LOWPOP|RUIN_MINING|RUIN_SCIENCE|RUIN_HOSTILE|RUIN_WRECK|RUIN_NATURAL
soil_data = list("Low density silicon dioxide layer", "Trace iron oxide layer", "Trace aluminium oxide layer", "Large rock particle layer", "Ice crystal layer", "Snow partcile layer")
water_data = list("Sodium ions present", "Calcium ions present", "Nitrate ions present", "Magnesium ions present", "Copper ions present")
unit_test_groups = list(2)
/obj/effect/overmap/visitable/sector/exoplanet/snow/generate_atmosphere()
..()
if(atmosphere)
var/limit = 0
if(habitability_class <= HABITABILITY_OKAY)
var/datum/species/human/H = /datum/species/human
limit = initial(H.cold_level_1) + rand(1,10)
atmosphere.temperature = max(T0C - rand(10, 100), limit)
atmosphere.update_values()
/obj/effect/overmap/visitable/sector/exoplanet/snow/generate_ground_survey_result()
..()
if(prob(40))
ground_survey_result += "<br>High quality natural fertilizer found in subterranean pockets"
if(prob(40))
ground_survey_result += "<br>High nitrogen and phosphorus contents of the soil"
if(prob(40))
ground_survey_result += "<br>Chemical extraction indicates soil is rich in major and secondary nutrients for agriculture"
if(prob(40))
ground_survey_result += "<br>Analysis indicates low contaminants of the soil"
if(prob(40))
ground_survey_result += "<br>Soft clays detected, composed of quartz and calcites"
if(prob(40))
ground_survey_result += "<br>Muddy dirt rich in organic material"
if(prob(40))
ground_survey_result += "<br>Stratigraphy indicates low risk of tectonic activity in this region"
if(prob(40))
ground_survey_result += "<br>Fossilized organic material found settled in sedimentary rock"
if(prob(10))
ground_survey_result += "<br>Traces of fissile material"
if(prob(50))
ground_survey_result += "<br>Atmosphere micro-analysis detects high contents of aerogens stable in low temperature"
/obj/effect/overmap/visitable/sector/exoplanet/snow/generate_magnet_survey_result()
..()
magnet_strength = "[rand(20, 120)] uT/Gauss"
magnet_difference = "[rand(0,1250)] kilometers"
magnet_particles = ""
var/list/particle_types = PARTICLE_TYPES
var/particles = rand(1,5)
for(var/i in 1 to particles)
var/p = pick(particle_types)
if(i == particles) //Last item, no comma
magnet_particles += p
else
magnet_particles += "[p], "
particle_types -= p
day_length = "~[rand(1,200)/10] BCY (Biesel Cycles)"
if(prob(40))
magnet_survey_result += "<br>Highly variable magnetic flux detected"
if(prob(40))
magnet_survey_result += "<br>Strong solar winds present"
if(prob(40))
magnet_survey_result += "<br>Strong magnetotail indicitive of likely polar aurora occurance"
if(prob(10))
magnet_survey_result += "<br>High levels of plasma present in magnetosphere"
+523
View File
@@ -0,0 +1,523 @@
///////////////////////////////////////////////////////////////
//SS13 Optimized Map loader
//////////////////////////////////////////////////////////////
//global datum that will preload variables on atoms instanciation
GLOBAL_VAR_INIT(use_preloader, FALSE)
GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new)
/datum/map_load_metadata
var/bounds
var/list/atoms_to_initialise
/dmm_suite
// /"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}/g
var/static/regex/dmmRegex = new/regex({""(\[a-zA-Z]+)" = \\(((?:.|\n)*?)\\)\n(?!\t)|\\((\\d+),(\\d+),(\\d+)\\) = \\{"(\[a-zA-Z\n]*)"\\}"}, "g")
// /^[\s\n]+"?|"?[\s\n]+$|^"|"$/g
var/static/regex/trimQuotesRegex = new/regex({"^\[\\s\n]+"?|"?\[\\s\n]+$|^"|"$"}, "g")
// /^[\s\n]+|[\s\n]+$/
var/static/regex/trimRegex = new/regex("^\[\\s\n]+|\[\\s\n]+$", "g")
var/static/list/modelCache = list()
var/static/space_key
#ifdef TESTING
var/static/turfsSkipped
#endif
/**
* Construct the model map and control the loading process
*
* WORKING :
*
* 1) Makes an associative mapping of model_keys with model
* e.g aa = /turf/unsimulated/wall{icon_state = "rock"}
* 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, no_changeturf as num, lower_crop_x as num, lower_crop_y as num, upper_crop_x as num, upper_crop_y as num)
//How I wish for RAII
Master.StartLoadingMap()
space_key = null
#ifdef TESTING
turfsSkipped = 0
#endif
. = load_map_impl(dmm_file, x_offset, y_offset, z_offset, cropMap, measureOnly, no_changeturf, lower_crop_x, upper_crop_x, lower_crop_y, upper_crop_y)
#ifdef TESTING
if(turfsSkipped)
testing("Skipped loading [turfsSkipped] default turfs")
#endif
Master.StopLoadingMap()
/dmm_suite/proc/load_map_impl(dmm_file, x_offset, y_offset, z_offset, cropMap, measureOnly, no_changeturf, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY)
var/tfile = dmm_file//the map file we're creating
if(isfile(tfile))
// name/path of dmm file, new var so as to not rename the `tfile` var
// to maybe maintain compatibility with other codebases
var/tfilepath = "[tfile]"
// use bapi to read, parse, process, mapmanip etc
// this will "crash"/stacktrace on fail
tfile = bapi_read_dmm_file(tfilepath)
// if bapi for whatever reason fails and returns null
// try to load it the old dm way instead
if(!tfile)
tfile = file2text(tfilepath)
if(!x_offset)
x_offset = 1
if(!y_offset)
y_offset = 1
if(!z_offset)
z_offset = world.maxz + 1
var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
var/list/grid_models = list()
var/key_len = 0
var/stored_index = 1
var/list/atoms_to_initialise = list()
var/has_expanded_world_maxx = FALSE
var/has_expanded_world_maxy = FALSE
while(dmmRegex.Find(tfile, stored_index))
stored_index = dmmRegex.next
// "aa" = (/type{vars=blah})
if(dmmRegex.group[1]) // Model
var/key = dmmRegex.group[1]
if(grid_models[key]) // Duplicate model keys are ignored in DMMs
continue
if(key_len != length(key))
if(!key_len)
key_len = length(key)
else
throw EXCEPTION("Inconsistant key length in DMM")
if(!measureOnly)
grid_models[key] = dmmRegex.group[2]
// (1,1,1) = {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
else if(dmmRegex.group[3]) // Coords
if(!key_len)
throw EXCEPTION("Coords before model definition in DMM")
var/curr_x = text2num(dmmRegex.group[3])
if(curr_x < x_lower || curr_x > x_upper)
continue
var/xcrdStart = curr_x + x_offset - 1
//position of the currently processed square
var/xcrd
var/ycrd = text2num(dmmRegex.group[4]) + y_offset - 1
var/zcrd = text2num(dmmRegex.group[5]) + z_offset - 1
var/zexpansion = zcrd > world.maxz
if(zexpansion && !measureOnly) // don't actually expand the world if we're only measuring bounds
if(cropMap)
continue
else
world.maxz = zcrd //create a new z_level if needed
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_Z, world.maxz)
if(!no_changeturf)
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/post_change is called.")
bounds[MAP_MINX] = min(bounds[MAP_MINX], Clamp(xcrdStart, x_lower, x_upper))
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd)
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd)
var/list/gridLines = splittext(dmmRegex.group[6], "\n")
var/leadingBlanks = 0
while(leadingBlanks < gridLines.len && gridLines[++leadingBlanks] == "")
if(leadingBlanks > 1)
gridLines.Cut(1, leadingBlanks) // Remove all leading blank lines.
if(!gridLines.len) // Skip it if only blank lines exist.
continue
if(gridLines.len && gridLines[gridLines.len] == "")
gridLines.Cut(gridLines.len) // Remove only one blank line at the end.
bounds[MAP_MINY] = min(bounds[MAP_MINY], Clamp(ycrd, y_lower, y_upper))
ycrd += gridLines.len - 1 // Start at the top and work down
if(!cropMap && ycrd > world.maxy)
if(!measureOnly)
world.maxy = ycrd // Expand Y here. X is expanded in the loop below
has_expanded_world_maxy = TRUE
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], Clamp(ycrd, y_lower, y_upper))
else
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], Clamp(min(ycrd, world.maxy), y_lower, y_upper))
var/maxx = xcrdStart
if(measureOnly)
for(var/line in gridLines)
maxx = max(maxx, xcrdStart + length(line) / key_len - 1)
else
for(var/line in gridLines)
if((ycrd - y_offset + 1) < y_lower || (ycrd - y_offset + 1) > y_upper) //Reverse operation and check if it is out of bounds of cropping.
--ycrd
continue
if(ycrd <= world.maxy && ycrd >= 1)
xcrd = xcrdStart
for(var/tpos = 1 to length(line) - key_len + 1 step key_len)
if((xcrd - x_offset + 1) < x_lower || (xcrd - x_offset + 1) > x_upper) //Same as above.
++xcrd
continue //X cropping.
if(xcrd > world.maxx)
if(cropMap)
break
else
world.maxx = xcrd
has_expanded_world_maxx = TRUE
if(xcrd >= 1)
var/model_key = copytext(line, tpos, tpos + key_len)
var/no_afterchange = no_changeturf || zexpansion
if(!no_afterchange || (model_key != space_key))
if(!grid_models[model_key])
throw EXCEPTION("Undefined model key in DMM.")
var/datum/grid_load_metadata/M = parse_grid(grid_models[model_key], model_key, xcrd, ycrd, zcrd, no_changeturf || zexpansion)
if (M)
atoms_to_initialise += M.atoms_to_initialise
#ifdef TESTING
else
++turfsSkipped
#endif
CHECK_TICK
maxx = max(maxx, xcrd)
++xcrd
--ycrd
bounds[MAP_MAXX] = Clamp(max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx), x_lower, x_upper)
CHECK_TICK
if(bounds[1] == 1.#INF) // Shouldn't need to check every item
return null
else
if(!measureOnly)
if(!no_changeturf)
for(var/turf/T as anything in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
T.post_change(FALSE)
if(has_expanded_world_maxx || has_expanded_world_maxy)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_EXPANDED_WORLD_BOUNDS, has_expanded_world_maxx, has_expanded_world_maxy)
var/datum/map_load_metadata/M = new
M.bounds = bounds
M.atoms_to_initialise = atoms_to_initialise
return M
/datum/grid_load_metadata
var/list/atoms_to_initialise
var/list/atoms_to_delete
/**
* Fill a given tile with its area/turf/objects/mobs
* Variable model is one full map line (e.g /turf/unsimulated/wall{icon_state = "rock"}, /area/mine/explored)
*
* WORKING :
*
* 1) Read the model string, member by member (delimiter is ',')
*
* 2) Get the path of the atom and store it into a list
*
* 3) a) Check if the member has variables (text within '{' and '}')
*
* 3) b) Construct an associative list with found variables, if any (the atom index in members is the same as its variables in members_attributes)
*
* 4) Instanciates the atom with its variables
*
*/
/dmm_suite/proc/parse_grid(model as text, model_key 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.
*/
var/list/members //will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
var/list/members_attributes //will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
var/list/cached = modelCache[model]
var/index
if(cached)
members = cached[1]
members_attributes = cached[2]
else
/////////////////////////////////////////////////////////
//Constructing members and corresponding variables lists
////////////////////////////////////////////////////////
members = list()
members_attributes = list()
index = 1
var/old_position = 1
var/dpos
do
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
dpos = find_next_delimiter_position(model, old_position, ",", "{", "}") //find next delimiter (comma here) that's not within {...}
var/full_def = trim_text(copytext(model, old_position, dpos)) //full definition, e.g : /obj/foo/bar{variables=derp}
var/variables_start = findtext(full_def, "{")
var/path_str = trim_text(copytext(full_def, 1, variables_start))
var/atom_def = text2path(path_str) //path definition, e.g /obj/foo/bar
old_position = dpos + 1
if(!atom_def) // Skip the item if the path does not exist. Fix your crap, mappers!
crash_with("Invalid type in map. [path_str]")
continue
members += atom_def
//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
var/list/fields
if(variables_start)//if there's any variable
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
fields = readlist(full_def, ";")
if(fields.len)
if(!trim(fields[fields.len]))
--fields.len
for(var/I in fields)
var/value = fields[I]
if(istext(value))
fields[I] = apply_text_macros(value)
//then fill the members_attributes list with the corresponding variables
members_attributes.len++
members_attributes[index++] = fields
CHECK_TICK
while(dpos != 0)
//check and see if we can just skip this turf
//So you don't have to understand this horrid statement, we can do this if
// 1. no_changeturf is set
// 2. the space_key isn't set yet
// 3. there are exactly 2 members
// 4. with no attributes
// 5. and the members are world.turf and world.area
// Basically, if we find an entry like this: "XXX" = (/turf/default, /area/default)
// We can skip calling this proc every time we see XXX
if(no_changeturf && !space_key && members.len == 2 && members_attributes.len == 2 && length(members_attributes[1]) == 0 && length(members_attributes[2]) == 0 && (world.area in members) && (world.turf in members))
space_key = model_key
return
modelCache[model] = list(members, members_attributes)
////////////////
//Instanciation
////////////////
//since we've switched off autoinitialisation, record atoms to initialise later
var/list/atoms_to_initialise = list()
//turn off base new Initialization until the whole thing is loaded
SSatoms.map_loader_begin(text_ref(src))
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
var/turf/crds = locate(xcrd,ycrd,zcrd)
//first instance the /area and remove it from the members list
index = members.len
if(members[index] != /area/template_noop)
var/atype = members[index]
var/atom/instance = GLOB.areas_by_type[atype]
var/list/attr = members_attributes[index]
if (LAZYLEN(attr))
GLOB._preloader.setup(attr)//preloader for assigning set variables on atom creation
if(!instance)
instance = new atype(null)
atoms_to_initialise += instance
if(crds)
instance.contents += crds
if(GLOB.use_preloader && instance)
GLOB._preloader.load(instance)
//then instance the /turf
var/first_turf_index = 1
while(!ispath(members[first_turf_index], /turf)) //find first /turf object in members
first_turf_index++
//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],crds,no_changeturf)
atoms_to_initialise += T
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],crds,no_changeturf)//instance new turf
T.underlays += underlay
index++
atoms_to_initialise += T
//finally instance all remainings objects/mobs
for(index in 1 to first_turf_index-1)
atoms_to_initialise += instance_atom(members[index],members_attributes[index],crds,no_changeturf)
//Restore initialization to the previous value
SSatoms.map_loader_stop(text_ref(src))
var/datum/grid_load_metadata/M = new
M.atoms_to_initialise = atoms_to_initialise
return M
////////////////
//Helpers procs
////////////////
//Instance an atom at (x,y,z) and gives it the variables in attributes
/dmm_suite/proc/instance_atom(path,list/attributes, turf/crds, no_changeturf)
if (LAZYLEN(attributes))
GLOB._preloader.setup(attributes, path)
if(crds)
if(!no_changeturf && ispath(path, /turf))
. = crds.ChangeTurf(path, FALSE, TRUE, TRUE)
else
. = create_atom(path, crds)//first preloader pass
if(GLOB.use_preloader && .)//second preloader pass, for those atoms that don't ..() in New()
GLOB._preloader.load(.)
//custom CHECK_TICK here because we don't want things created while we're sleeping to not initialize
if(TICK_CHECK)
SSatoms.map_loader_stop(text_ref(src))
stoplag()
SSatoms.map_loader_begin(text_ref(src))
/dmm_suite/proc/create_atom(path, crds)
// Doing this async is impossible, as we must return the ref.
return new path (crds)
//text trimming (both directions) helper proc
//optionally removes quotes before and after the text (for variable name)
/dmm_suite/proc/trim_text(what as text,trim_quotes=0)
if(trim_quotes)
return trimQuotesRegex.Replace(what, "")
else
return trimRegex.Replace(what, "")
//find the position of the next delimiter,skipping whatever is comprised between opening_escape and closing_escape
//returns 0 if reached the last delimiter
/dmm_suite/proc/find_next_delimiter_position(text as text,initial_position as num, delimiter=",",opening_escape="\"",closing_escape="\"")
var/position = initial_position
var/next_delimiter = findtext(text,delimiter,position,0)
var/next_opening = findtext(text,opening_escape,position,0)
while((next_opening != 0) && (next_opening < next_delimiter))
position = findtext(text,closing_escape,next_opening + 1,0)+1
next_delimiter = findtext(text,delimiter,position,0)
next_opening = findtext(text,opening_escape,position,0)
return next_delimiter
/dmm_suite/proc/readlistitem(text as text, is_key = FALSE)
//Check for string
if(findtext(text,"\"",1,2))
. = copytext(text,2,findtext(text,"\"",3,0))
//Check for number
// Keys cannot safely be numbers. This implementation will return null if
// an assoc key is a number.
else if(!is_key && isnum(text2num(text)))
. = text2num(text)
//Check for null
else if(text == "null")
. = null
//Check for list
else if(copytext(text,1,6) == "list(")
. = readlist(copytext(text,6,length(text)))
//Check for file
else if(copytext(text,1,2) == "'")
. = file(copytext(text,2,length(text)))
//Check for path
else if(ispath(text2path(text)))
. = text2path(text)
// Associative keys are fed in without quotation marks.
// So if none of the other cases apply, return simply the string that was given.
// This case is also triggered for item values. So I guess we're also looking for text.
else if(is_key || istext(text))
. = text
//build a list from variables in text form (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
//return the filled list
/dmm_suite/proc/readlist(text as text, delimiter=",")
var/list/to_return = list()
var/position
var/old_position = 1
var/list_index = 1
do
//find next delimiter that is not within "..."
position = find_next_delimiter_position(text,old_position,delimiter)
//check if this is a simple variable (as in list(var1, var2)) or an associative one (as in list(var1="foo",var2=7))
var/equal_position = findtext(text,"=",old_position, position)
var/trim_left = trim_text(copytext(text,old_position,(equal_position ? equal_position : position)),1)//the name of the variable, must trim quotes to build a BYOND compliant associatives list
old_position = position + 1
if(equal_position) //associative var, so do the association
var/trim_right = trim_text(copytext(text,equal_position+1,position))//the content of the variable
trim_left = readlistitem(trim_left, TRUE) // Assoc vars can be anything that isn't a num!
to_return[trim_left] = readlistitem(trim_right)
list_index++
else if (length(trim_left)) //simple var
to_return.len++
to_return[list_index++] = readlistitem(trim_left)
while(position != 0)
return to_return
/dmm_suite/Destroy()
..()
return QDEL_HINT_HARDDEL_NOW
//////////////////
//Preloader datum
//////////////////
GLOBAL_LIST_INIT(_preloader_path, null)
/dmm_suite/preloader
parent_type = /datum
var/list/attributes
/dmm_suite/preloader/proc/setup(list/the_attributes, path)
if(LAZYLEN(the_attributes))
GLOB.use_preloader = TRUE
attributes = the_attributes
GLOB._preloader_path = path
/dmm_suite/preloader/proc/load(atom/what)
for(var/attribute in attributes)
var/value = attributes[attribute]
if(islist(value))
value = deepCopyList(value)
what.vars[attribute] = value
GLOB.use_preloader = FALSE
/area/template_noop
name = "Area Passthrough"
icon_state = "noop"
/turf/template_noop
name = "Turf Passthrough"
icon_state = "noop"
+169
View File
@@ -0,0 +1,169 @@
GLOBAL_LIST_EMPTY(banned_ruin_ids)
/proc/seedRuins(list/zlevels, budget, list/potentialRuins, allowed_area = /area/space, var/maxx = world.maxx, var/maxy = world.maxy, ignore_sector = FALSE)
if (!length(zlevels))
UNLINT(log_module_ruins_warning("No Z levels provided - Not generating ruins"))
return
for (var/z in zlevels)
var/turf/check = locate(1, 1, z)
if (!check)
UNLINT(log_module_ruins_warning("Z level [z] does not exist - Not generating ruins"))
return
var/remaining = budget
var/list/available = list()
var/list/selected = list()
var/list/force_spawn = list()
/// List of ruin paths we've already processed as potential ruins, so we don't get stuck in an infinite loop if there's a cross-reference
var/list/handled_ruin_paths = list()
while(length(potentialRuins) > 0)
var/datum/map_template/ruin/ruin = pick(potentialRuins)
if((ruin.id in GLOB.banned_ruin_ids) || (ruin.type in handled_ruin_paths))
potentialRuins -= ruin
handled_ruin_paths += ruin.type
continue
if((ruin.template_flags & TEMPLATE_FLAG_SPAWN_GUARANTEED) && (ruin.spawns_in_current_sector()))
force_spawn |= ruin
for(var/ruin_path in ruin.force_ruins)
var/datum/map_template/ruin/force_ruin = new ruin_path
force_spawn |= force_ruin
potentialRuins -= ruin
handled_ruin_paths += ruin.type
continue
if(!(ruin.spawns_in_current_sector()) && !ignore_sector)
potentialRuins -= ruin
handled_ruin_paths += ruin.type
continue
if((ruin.template_flags & TEMPLATE_FLAG_PORT_SPAWN))
if(SSatlas.is_port_call_day())
force_spawn |= ruin
for(var/ruin_path in ruin.force_ruins)
var/datum/map_template/ruin/force_ruin = new ruin_path
force_spawn |= force_ruin
// No matter if it spawns or not, we want it removed from further consideration, it either spawns here or not at all
potentialRuins -= ruin
handled_ruin_paths += ruin.type
continue
available[ruin] = ruin.spawn_weight
for(var/ruin_path in ruin.allow_ruins)
var/datum/map_template/ruin/force_ruin = new ruin_path
potentialRuins += force_ruin
potentialRuins -= ruin
handled_ruin_paths += ruin.type
if(!length(available) && !length(force_spawn))
UNLINT(log_module_ruins_warning("No ruins available - Not generating ruins"))
while (remaining > 0 && length(available))
var/datum/map_template/ruin/ruin = pickweight(available)
if(ruin.id in GLOB.banned_ruin_ids)
available -= ruin
continue
var/turf/choice = validate_ruin(ruin, zlevels, remaining, allowed_area, maxx, maxy)
if(!choice)
available -= ruin
continue
log_admin("Ruin \"[ruin.name]\" placed at ([choice.x], [choice.y], [choice.z])!")
load_ruin(choice, ruin)
selected += ruin
for(var/ruin_path in ruin.force_ruins)
var/datum/map_template/ruin/force_ruin = new ruin_path
if(force_ruin.spawns_in_current_sector())
force_spawn |= force_ruin
for(var/datum/map_template/ruin/ban_ruin as anything in ruin.ban_ruins)
var/ruin_id = initial(ban_ruin.id)
GLOB.banned_ruin_ids += ruin_id
if(ruin.spawn_cost > 0)
remaining -= ruin.spawn_cost
if(!(ruin.template_flags & TEMPLATE_FLAG_ALLOW_DUPLICATES))
GLOB.banned_ruin_ids += ruin.id
available -= ruin
for(var/datum/map_template/ruin/ruin in force_spawn)
if(ruin.id in GLOB.banned_ruin_ids)
continue
var/turf/choice = validate_ruin(ruin, zlevels, filter_area = allowed_area, max_x = maxx, max_y = maxy)
if(!choice)
log_admin("Ruin \"[ruin.name]\" failed to force-spawned at ([choice.x], [choice.y], [choice.z])!!!")
continue
log_admin("Ruin \"[ruin.name]\" force-spawned at ([choice.x], [choice.y], [choice.z])!")
load_ruin(choice, ruin)
selected += ruin
if(!(ruin.template_flags & TEMPLATE_FLAG_ALLOW_DUPLICATES))
GLOB.banned_ruin_ids += ruin.id
if (remaining)
log_admin("Ruin loader had no ruins to pick from with [budget] left to spend.")
if (length(selected))
log_module_ruins("Finished selecting planet ruins ([english_list(selected)]) for [budget - remaining] cost of [budget] budget.")
return selected
/proc/validate_ruin(datum/map_template/ruin/ruin, list/zlevels, budget = 0, filter_area = /area/exoplanet, max_x = world.maxx, max_y = world.maxy)
if(!istype(ruin) || !length(zlevels))
return
if(budget && (ruin.spawn_cost > budget))
return
var/width = TRANSITIONEDGE + RUIN_MAP_EDGE_PAD + round(ruin.width / 2)
var/height = TRANSITIONEDGE + RUIN_MAP_EDGE_PAD + round(ruin.height / 2)
if(width > max_x - width || height > max_y - height)
return
var/valid = TRUE
for(var/attempts = 20, attempts > 0, --attempts)
var/z = pick(zlevels)
var/turf/choice = locate(rand(width, max_x - width), rand(height, max_y - height), z)
valid = TRUE
for(var/turf/check_turf in ruin.get_affected_turfs(choice, TRUE))
var/area/check_area = get_area(check_turf)
if(!istype(check_area, filter_area) || check_turf.turf_flags & TURF_NORUINS)
valid = FALSE
break
if(valid)
return choice
/proc/load_ruin(turf/central_turf, datum/map_template/template)
if(!template)
return FALSE
for(var/i in template.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/S in T)
qdel(S)
for(var/obj/machinery/M in T)
qdel(M)
if(LAZYLEN(T.decals))
T.decals.Cut()
T.ClearOverlays()
template.load(central_turf, TRUE)
var/datum/map_template/ruin = template
if(istype(ruin))
new /obj/effect/landmark/ruin(central_turf, ruin)
return TRUE
@@ -0,0 +1,22 @@
/datum/space_level
var/name = "NAME MISSING"
var/list/neigbours = list()
var/list/traits
var/z_value = 1 //actual z placement
var/linkage = SELFLOOPING
var/xi
var/yi //imaginary placements on the grid
/datum/space_level/New(new_z, new_name, list/new_traits = list())
z_value = new_z
name = new_name
traits = new_traits
if (islist(new_traits))
for (var/trait in new_traits)
SSmapping.z_trait_levels[trait] += list(new_z)
else // in case a single trait is passed in
SSmapping.z_trait_levels[new_traits] += list(new_z)
set_linkage(new_traits[ZTRAIT_LINKAGE])
@@ -0,0 +1,95 @@
/* THIS IS ONLY A PLACEHOLDER AND DOESN'T WORK */
//Yes, they can only be rectangular.
//Yes, I'm sorry.
/datum/turf_reservation
/// All turfs that we've reserved
var/list/reserved_turfs = list()
/// Turfs around the reservation for cordoning
var/list/cordon_turfs = list()
/// Area of turfs next to the cordon to fill with pre_cordon_area's
var/list/pre_cordon_turfs = list()
/// The width of the reservation
var/width = 0
/// The height of the reservation
var/height = 0
/// The z stack size of the reservation. Note that reservations are ALWAYS reserved from the bottom up
var/z_size = 0
/// List of the bottom left turfs. Indexed by what their z index for this reservation is
var/list/bottom_left_turfs = list()
/// List of the top right turfs. Indexed by what their z index for this reservation is
var/list/top_right_turfs = list()
/// The turf type the reservation is initially made with
var/turf_type = /turf/space
///Distance away from the cordon where we can put a "sort-cordon" and run some extra code (see make_repel). 0 makes nothing happen
var/pre_cordon_distance = 0
/// Calculates the effective bounds information for the given turf. Returns a list of the information, or null if not applicable.
/datum/turf_reservation/proc/calculate_turf_bounds_information(turf/target)
for(var/z_idx in 1 to z_size)
var/turf/bottom_left = bottom_left_turfs[z_idx]
var/turf/top_right = top_right_turfs[z_idx]
var/bl_x = bottom_left.x
var/bl_y = bottom_left.y
var/tr_x = top_right.x
var/tr_y = top_right.y
if(target.x < bl_x)
continue
if(target.y < bl_y)
continue
if(target.x > tr_x)
continue
if(target.y > tr_y)
continue
var/list/return_information = list()
return_information["z_idx"] = z_idx
return_information["offset_x"] = target.x - bl_x
return_information["offset_y"] = target.y - bl_y
return return_information
return null
/// Gets the turf below the given target. Returns null if there is no turf below the target
/datum/turf_reservation/proc/get_turf_below(turf/target)
var/list/bounds_info = calculate_turf_bounds_information(target)
if(isnull(bounds_info))
return null
var/z_idx = bounds_info["z_idx"]
// check what z level, if its the max, then there is no turf below
if(z_idx == z_size)
return null
var/offset_x = bounds_info["offset_x"]
var/offset_y = bounds_info["offset_y"]
var/turf/bottom_left = bottom_left_turfs[z_idx + 1]
return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z)
/// Gets the turf above the given target. Returns null if there is no turf above the target
/datum/turf_reservation/proc/get_turf_above(turf/target)
var/list/bounds_info = calculate_turf_bounds_information(target)
if(isnull(bounds_info))
return null
var/z_idx = bounds_info["z_idx"]
// check what z level, if its the min, then there is no turf above
if(z_idx == 1)
return null
var/offset_x = bounds_info["offset_x"]
var/offset_y = bounds_info["offset_y"]
var/turf/bottom_left = bottom_left_turfs[z_idx - 1]
return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z)
@@ -0,0 +1,6 @@
/datum/space_level/proc/set_linkage(new_linkage)
linkage = new_linkage
if(linkage == SELFLOOPING)
neigbours = list(TEXT_NORTH,TEXT_SOUTH,TEXT_EAST,TEXT_WEST)
for(var/A in neigbours)
neigbours[A] = src
@@ -0,0 +1,16 @@
/// Look up levels[z].traits[trait]
/datum/controller/subsystem/mapping/proc/level_trait(z, trait)
if (!isnum(z) || z < 1)
return null
if (z_list)
if (z > z_list.len)
stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list.len]")
return list()
var/datum/space_level/S = z_list[z]
return S.traits[trait]
else
var/list/default = DEFAULT_MAP_TRAITS
if (z > default.len)
stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], default.len = [default.len]")
return list()
return default[z][DL_TRAITS][trait]
@@ -0,0 +1,21 @@
/// Generates a real, honest to god new z level. Will create the actual space, and also generate a datum that holds info about the new plot of land
/// Accepts the name, traits list, datum type, and if we should manage the turfs we create
/datum/controller/subsystem/mapping/proc/add_new_zlevel(name, traits = list(), z_type = /datum/space_level, contain_turfs = TRUE)
UNTIL(!adding_new_zlevel)
adding_new_zlevel = TRUE
var/new_z = z_list.len + 1
if (world.maxz < new_z)
world.incrementMaxZ()
CHECK_TICK
// TODO: sleep here if the Z level needs to be cleared
var/datum/space_level/S = new z_type(new_z, name, traits)
manage_z_level(S, filled_with_space = TRUE, contain_turfs = contain_turfs)
generate_linkages_for_z_level(new_z)
adding_new_zlevel = FALSE
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_Z, S)
return S
/datum/controller/subsystem/mapping/proc/get_level(z)
if (z_list && z >= 1 && z <= z_list.len)
return z_list[z]
CRASH("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list ? z_list.len : "null"]")
+599
View File
@@ -0,0 +1,599 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/*
SwapMaps library by Lummox JR
developed for digitalBYOND
http://www.digitalbyond.org
Version 2.1
The purpose of this library is to make it easy for authors to swap maps
in and out of their game using savefiles. Swapped-out maps can be
transferred between worlds for an MMORPG, sent to the client, etc.
This is facilitated by the use of a special datum and a global list.
Uses of swapmaps:
- Temporary battle arenas
- House interiors
- Individual custom player houses
- Virtually unlimited terrain
- Sharing maps between servers running different instances of the same game
- Loading and saving pieces of maps for reusable room templates
*/
/*
User Interface:
VARS:
swapmaps_iconcache
An associative list of icon files with names, like
'player.dmi' = "player"
swapmaps_mode
This must be set at runtime, like in world/New().
SWAPMAPS_SAV 0 (default)
Uses .sav files for raw /savefile output.
SWAPMAPS_TEXT 1
Uses .txt files via ExportText() and ImportText(). These maps
are easily editable and appear to take up less space in the
current version of BYOND.
PROCS:
SwapMaps_Find(id)
Find a map by its id
SwapMaps_Load(id)
Load a map by its id
SwapMaps_Save(id)
Save a map by its id (calls swapmap.Save())
SwapMaps_Unload(id)
Save and unload a map by its id (calls swapmap.Unload())
SwapMaps_Save_All()
Save all maps
SwapMaps_DeleteFile(id)
Delete a map file
SwapMaps_CreateFromTemplate(id)
Create a new map by loading another map to use as a template.
This map has id==src and will not be saved. To make it savable,
change id with swapmap.SetID(newid).
SwapMaps_LoadChunk(id,turf/locorner)
Load a swapmap as a "chunk", at a specific place. A new datum is
created but it's not added to the list of maps to save or unload.
The new datum can be safely deleted without affecting the turfs
it loaded. The purpose of this is to load a map file onto part of
another swapmap or an existing part of the world.
locorner is the corner turf with the lowest x,y,z values.
SwapMaps_SaveChunk(id,turf/corner1,turf/corner2)
Save a piece of the world as a "chunk". A new datum is created
for the chunk, but it can be deleted without destroying any turfs.
The chunk file can be reloaded as a swapmap all its own, or loaded
via SwapMaps_LoadChunk() to become part of another map.
SwapMaps_GetSize(id)
Return a list corresponding to the x,y,z sizes of a map file,
without loading the map.
Returns null if the map is not found.
SwapMaps_AddIconToCache(name,icon)
Cache an icon file by name for space-saving storage
swapmap.New(id,x,y,z)
Create a new map; specify id, width (x), height (y), and depth (z)
Default size is world.maxx,world.maxy,1
swapmap.New(id,turf1,turf2)
Create a new map; specify id and 2 corners
This becomes a /swapmap for one of the compiled-in maps, for easy saving.
swapmap.New()
Create a new map datum, but does not allocate space or assign an ID (used for loading).
swapmap.Del()
Deletes a map but does not save
swapmap.Save()
Saves to map_[id].sav
Maps with id==src are not saved.
swapmap.Unload()
Saves the map and then deletes it
Maps with id==src are not saved.
swapmap.SetID(id)
Change the map's id and make changes to the lookup list
swapmap.AllTurfs(z)
Returns a block of turfs encompassing the entire map, or on just one z-level
z is in world coordinates; it is optional
swapmap.Contains(turf/T)
Returns nonzero if T is inside the map's boundaries.
Also works for objs and mobs, but the proc is not area-safe.
swapmap.InUse()
Returns nonzero if a mob with a key is within the map's boundaries.
swapmap.LoCorner(z=z1)
Returns locate(x1,y1,z), where z=z1 if none is specified.
swapmap.HiCorner(z=z2)
Returns locate(x2,y2,z), where z=z2 if none is specified.
swapmap.BuildFilledRectangle(turf/corner1,turf/corner2,item)
Builds a filled rectangle of item from one corner turf to the other, on multiple z-levels if necessary. The corners may be specified in any order.
item is a type path like /turf/wall or /obj/barrel{full=1}.
swapmap.BuildRectangle(turf/corner1,turf/corner2,item)
Builds an unfilled rectangle of item from one corner turf to the other, on multiple z-levels if necessary.
swapmap.BuildInTurfs(list/turfs,item)
Builds item on all of the turfs listed. The list need not contain only turfs, or even only atoms.
*/
/swapmap
var/id // a string identifying this map uniquely
var/x1 // minimum x,y,z coords
var/y1
var/z1
var/x2 // maximum x,y,z coords (also used as width,height,depth until positioned)
var/y2
var/z2
var/tmp/locked // don't move anyone to this map; it's saving or loading
var/tmp/mode // save as text-mode
var/ischunk // tells the load routine to load to the specified location
/swapmap/New(_id,x,y,z)
if(isnull(_id)) return
id=_id
mode=swapmaps_mode
if(isturf(x) && isturf(y))
/*
Special format: Defines a map as an existing set of turfs;
this is useful for saving a compiled map in swapmap format.
Because this is a compiled-in map, its turfs are not deleted
when the datum is deleted.
*/
x1=min(x:x,y:x);x2=max(x:x,y:x)
y1=min(x:y,y:y);y2=max(x:y,y:y)
z1=min(x:z,y:z);z2=max(x:z,y:z)
InitializeSwapMaps()
if(z2>swapmaps_compiled_maxz ||\
y2>swapmaps_compiled_maxy ||\
x2>swapmaps_compiled_maxx)
qdel(src)
return
x2=x?(x):world.maxx
y2=y?(y):world.maxy
z2=z?(z):1
AllocateSwapMap()
/swapmap/Del()
// a temporary datum for a chunk can be deleted outright
// for others, some cleanup is necessary
if(!ischunk)
swapmaps_loaded-=src
swapmaps_byname-=id
if(z2>swapmaps_compiled_maxz ||\
y2>swapmaps_compiled_maxy ||\
x2>swapmaps_compiled_maxx)
var/list/areas=new
for(var/atom/A in block(locate(x1,y1,z1),locate(x2,y2,z2)))
for(var/obj/O in A) qdel(O)
for(var/mob/M in A)
if(!M.key) qdel(M)
else M.loc=null
areas[A.loc]=null
qdel(A)
// delete areas that belong only to this map
for(var/area/a in areas)
if(a && !a.contents.len) qdel(a)
if(x2>=world.maxx || y2>=world.maxy || z2>=world.maxz) CutXYZ()
qdel(areas)
..()
/swapmap/Read(savefile/S,_id,turf/locorner)
var/x
var/y
var/z
var/n
var/list/areas
var/area/defarea=locate(world.area)
id=_id
if(locorner)
ischunk=1
x1=locorner.x
y1=locorner.y
z1=locorner.z
if(!defarea) defarea=new world.area
if(!_id)
S["id"] >> id
else
var/dummy
S["id"] >> dummy
S["z"] >> z2 // these are depth,
S["y"] >> y2 // height,
S["x"] >> x2 // width
S["areas"] >> areas
locked=1
AllocateSwapMap() // adjust x1,y1,z1 - x2,y2,z2 coords
var/oldcd=S.cd
for(z=z1,z<=z2,++z)
S.cd="[z-z1+1]"
for(y=y1,y<=y2,++y)
S.cd="[y-y1+1]"
for(x=x1,x<=x2,++x)
S.cd="[x-x1+1]"
var/tp
S["type"]>>tp
var/turf/T=locate(x,y,z)
T.loc.contents-=T
T=new tp(locate(x,y,z))
if("AREA" in S.dir)
S["AREA"]>>n
var/area/A=areas[n]
A.contents+=T
else defarea.contents+=T
// clear the turf
for(var/obj/O in T) qdel(O)
for(var/mob/M in T)
if(!M.key) qdel(M)
else M.loc=null
// finish the read
T.Read(S)
S.cd=".."
S.cd=".."
sleep()
S.cd=oldcd
locked=0
qdel(areas)
/*
Find an empty block on the world map in which to load this map.
If no space is found, increase world.maxz as necessary. (If the
map is greater in x,y size than the current world, expand
world.maxx and world.maxy too.)
Ignore certain operations if loading a map as a chunk. Use the
x1,y1,z1 position for it, and *don't* count it as a loaded map.
*/
/swapmap/proc/AllocateSwapMap()
InitializeSwapMaps()
world.maxx=max(x2,world.maxx) // stretch x/y if necessary
world.maxy=max(y2,world.maxy)
if(!ischunk)
if(world.maxz<=swapmaps_compiled_maxz)
z1=swapmaps_compiled_maxz+1
x1=1;y1=1
else
var/list/l=ConsiderRegion(1,1,world.maxx,world.maxy,swapmaps_compiled_maxz+1)
x1=l[1]
y1=l[2]
z1=l[3]
qdel(l)
x2+=x1-1
y2+=y1-1
z2+=z1-1
if(z2 > world.maxz)
world.maxz = z2 // stretch z if necessary
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_Z, world.maxz)
if(!ischunk)
swapmaps_loaded[src]=null
swapmaps_byname[id]=src
/swapmap/proc/ConsiderRegion(X1,Y1,X2,Y2,Z1,Z2)
while(1)
var/nextz=0
var/swapmap/M
for(M in swapmaps_loaded)
if(M.z2<Z1 || (Z2 && M.z1>Z2) || M.z1>=Z1+z2 ||\
M.x1>X2 || M.x2<X1 || M.x1>=X1+x2 ||\
M.y1>Y2 || M.y2<Y1 || M.y1>=Y1+y2) continue
// look for sub-regions with a defined ceiling
var/nz2=Z2?(Z2):Z1+z2-1+M.z2-M.z1
if(M.x1>=X1+x2)
.=ConsiderRegion(X1,Y1,M.x1-1,Y2,Z1,nz2)
if(.) return
else if(M.x2<=X2-x2)
.=ConsiderRegion(M.x2+1,Y1,X2,Y2,Z1,nz2)
if(.) return
if(M.y1>=Y1+y2)
.=ConsiderRegion(X1,Y1,X2,M.y1-1,Z1,nz2)
if(.) return
else if(M.y2<=Y2-y2)
.=ConsiderRegion(X1,M.y2+1,X2,Y2,Z1,nz2)
if(.) return
nextz=nextz?min(nextz,M.z2+1):(M.z2+1)
if(!M)
/* If nextz is not 0, then at some point there was an overlap that
could not be resolved by using an area to the side */
if(nextz) Z1=nextz
if(!nextz || (Z2 && Z2-Z1+1<z2))
return (!Z2 || Z2-Z1+1>=z2)?list(X1,Y1,Z1):null
X1=1;X2=world.maxx
Y1=1;Y2=world.maxy
/swapmap/proc/CutXYZ()
var/mx=swapmaps_compiled_maxx
var/my=swapmaps_compiled_maxy
var/mz=swapmaps_compiled_maxz
for(var/swapmap/M in swapmaps_loaded) // may not include src
mx=max(mx,M.x2)
my=max(my,M.y2)
mz=max(mz,M.z2)
world.maxx=mx
world.maxy=my
world.maxz=mz
// save and delete
/swapmap/proc/Unload()
Save()
qdel(src)
/swapmap/proc/Save()
if(id==src) return 0
var/savefile/S=mode?(new):new("map_[id].sav")
to_chat(S, src)
while(locked) sleep(1)
if(mode)
fdel("map_[id].txt")
S.ExportText("/","map_[id].txt")
return 1
// this will not delete existing savefiles for this map
/swapmap/proc/SetID(newid)
swapmaps_byname-=id
id=newid
swapmaps_byname[id]=src
/swapmap/proc/AllTurfs(z)
if(isnum(z) && (z<z1 || z>z2)) return null
return block(LoCorner(z),HiCorner(z))
// this could be safely called for an obj or mob as well, but
// probably not an area
/swapmap/proc/Contains(turf/T)
return (T && T.x>=x1 && T.x<=x2\
&& T.y>=y1 && T.y<=y2\
&& T.z>=z1 && T.z<=z2)
/swapmap/proc/InUse()
for(var/turf/T in AllTurfs())
for(var/mob/M in T) if(M.key) return 1
/swapmap/proc/LoCorner(z=z1)
return locate(x1,y1,z)
/swapmap/proc/HiCorner(z=z2)
return locate(x2,y2,z)
// Build procs: Take 2 turfs as corners, plus an item type.
// An item may be like:
//
// /turf/wall
// /obj/fence{icon_state="iron"}
/swapmap/proc/BuildFilledRectangle(turf/T1,turf/T2,item)
if(!Contains(T1) || !Contains(T2)) return
var/turf/T=T1
// pick new corners in a block()-friendly form
T1=locate(min(T1.x,T2.x),min(T1.y,T2.y),min(T1.z,T2.z))
T2=locate(max(T.x,T2.x),max(T.y,T2.y),max(T.z,T2.z))
for(T in block(T1,T2)) new item(T)
/swapmap/proc/BuildRectangle(turf/T1,turf/T2,item)
if(!Contains(T1) || !Contains(T2)) return
var/turf/T=T1
// pick new corners in a block()-friendly form
T1=locate(min(T1.x,T2.x),min(T1.y,T2.y),min(T1.z,T2.z))
T2=locate(max(T.x,T2.x),max(T.y,T2.y),max(T.z,T2.z))
if(T2.x-T1.x<2 || T2.y-T1.y<2) BuildFilledRectangle(T1,T2,item)
else
//for(T in block(T1,T2)-block(locate(T1.x+1,T1.y+1,T1.z),locate(T2.x-1,T2.y-1,T2.z)))
for(T in block(T1,locate(T2.x,T1.y,T2.z))) new item(T)
for(T in block(locate(T1.x,T2.y,T1.z),T2)) new item(T)
for(T in block(locate(T1.x,T1.y+1,T1.z),locate(T1.x,T2.y-1,T2.z))) new item(T)
for(T in block(locate(T2.x,T1.y+1,T1.z),locate(T2.x,T2.y-1,T2.z))) new item(T)
/*
Supplementary build proc: Takes a list of turfs, plus an item
type. Actually the list doesn't have to be just turfs.
*/
/swapmap/proc/BuildInTurfs(list/turfs,item)
for(var/T in turfs) new item(T)
/atom/Read(savefile/S)
var/list/l
if(contents.len) l=contents
..()
// if the icon was a text string, it would not have loaded properly
// replace it from the cache list
if(!icon && ("icon" in S.dir))
var/ic
S["icon"]>>ic
if(istext(ic)) icon=swapmaps_iconcache[ic]
if(l && contents!=l)
contents+=l
qdel(l)
// set this up (at runtime) as follows:
// list(
// 'player.dmi'="player",
// 'monster.dmi'="monster",
// ...
// 'item.dmi'="item")
var/list/swapmaps_iconcache
// preferred mode; sav or text
var/const/SWAPMAPS_SAV=0
var/const/SWAPMAPS_TEXT=1
var/swapmaps_mode=SWAPMAPS_SAV
var/swapmaps_compiled_maxx
var/swapmaps_compiled_maxy
var/swapmaps_compiled_maxz
var/swapmaps_initialized
var/swapmaps_loaded
var/swapmaps_byname
/proc/InitializeSwapMaps()
if(swapmaps_initialized) return
swapmaps_initialized=1
swapmaps_compiled_maxx=world.maxx
swapmaps_compiled_maxy=world.maxy
swapmaps_compiled_maxz=world.maxz
swapmaps_loaded=list()
swapmaps_byname=list()
if(swapmaps_iconcache)
for(var/V in swapmaps_iconcache)
// reverse-associate everything
// so you can look up an icon file by name or vice-versa
swapmaps_iconcache[swapmaps_iconcache[V]]=V
/proc/SwapMaps_AddIconToCache(name,icon)
if(!swapmaps_iconcache) swapmaps_iconcache=list()
swapmaps_iconcache[name]=icon
swapmaps_iconcache[icon]=name
/proc/SwapMaps_Find(id)
InitializeSwapMaps()
return swapmaps_byname[id]
/proc/SwapMaps_Load(id)
InitializeSwapMaps()
var/swapmap/M=swapmaps_byname[id]
if(!M)
var/savefile/S
var/text=0
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[id].txt"))
text=1
else if(fexists("map_[id].sav"))
S=new("map_[id].sav")
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[id].txt"))
text=1
else return // no file found
if(text)
S=new
S.ImportText("/",file("map_[id].txt"))
S >> M
while(M.locked) sleep(1)
M.mode=text
return M
/proc/SwapMaps_Save(id)
InitializeSwapMaps()
var/swapmap/M=swapmaps_byname[id]
if(M) M.Save()
return M
/proc/SwapMaps_Save_All()
InitializeSwapMaps()
for(var/swapmap/M in swapmaps_loaded)
if(M) M.Save()
/proc/SwapMaps_Unload(id)
InitializeSwapMaps()
var/swapmap/M=swapmaps_byname[id]
if(!M) return // return silently from an error
M.Unload()
return 1
/proc/SwapMaps_DeleteFile(id)
fdel("map_[id].sav")
fdel("map_[id].txt")
/proc/SwapMaps_CreateFromTemplate(template_id)
var/swapmap/M=new
var/savefile/S
var/text=0
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[template_id].txt"))
text=1
else if(fexists("map_[template_id].sav"))
S=new("map_[template_id].sav")
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[template_id].txt"))
text=1
else
world.log << "SwapMaps error in SwapMaps_CreateFromTemplate(): map_[template_id] file not found."
return
if(text)
S=new
S.ImportText("/",file("map_[template_id].txt"))
/*
This hacky workaround is needed because S >> M will create a brand new
M to fill with data. There's no way to control the Read() process
properly otherwise. The //.0 path should always match the map, however.
*/
S.cd="//.0"
M.Read(S,M)
M.mode=text
while(M.locked) sleep(1)
return M
/proc/SwapMaps_LoadChunk(chunk_id,turf/locorner)
var/swapmap/M=new
var/savefile/S
var/text=0
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[chunk_id].txt"))
text=1
else if(fexists("map_[chunk_id].sav"))
S=new("map_[chunk_id].sav")
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[chunk_id].txt"))
text=1
else
world.log << "SwapMaps error in SwapMaps_LoadChunk(): map_[chunk_id] file not found."
return
if(text)
S=new
S.ImportText("/",file("map_[chunk_id].txt"))
/*
This hacky workaround is needed because S >> M will create a brand new
M to fill with data. There's no way to control the Read() process
properly otherwise. The //.0 path should always match the map, however.
*/
S.cd="//.0"
M.Read(S,M,locorner)
while(M.locked) sleep(1)
qdel(M)
return 1
/proc/SwapMaps_SaveChunk(chunk_id,turf/corner1,turf/corner2)
if(!corner1 || !corner2)
world.log << "SwapMaps error in SwapMaps_SaveChunk():"
if(!corner1) world.log << " corner1 turf is null"
if(!corner2) world.log << " corner2 turf is null"
return
var/swapmap/M=new
M.id=chunk_id
M.ischunk=1 // this is a chunk
M.x1=min(corner1.x,corner2.x)
M.y1=min(corner1.y,corner2.y)
M.z1=min(corner1.z,corner2.z)
M.x2=max(corner1.x,corner2.x)
M.y2=max(corner1.y,corner2.y)
M.z2=max(corner1.z,corner2.z)
M.mode=swapmaps_mode
M.Save()
while(M.locked) sleep(1)
qdel(M)
return 1
/proc/SwapMaps_GetSize(id)
var/savefile/S
var/text=0
if(swapmaps_mode==SWAPMAPS_TEXT && fexists("map_[id].txt"))
text=1
else if(fexists("map_[id].sav"))
S=new("map_[id].sav")
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[id].txt"))
text=1
else
world.log << "SwapMaps error in SwapMaps_GetSize(): map_[id] file not found."
return
if(text)
S=new
S.ImportText("/",file("map_[id].txt"))
/*
The //.0 path should always be the map. There's no other way to
read this data.
*/
S.cd="//.0"
var/x
var/y
var/z
S["x"] >> x
S["y"] >> y
S["z"] >> z
return list(x,y,z)