Replace hardcoded z-level numbers with a trait system

This commit is contained in:
Tad Hardesty
2018-01-11 12:05:49 -08:00
committed by CitadelStationBot
parent b2021912d7
commit 72319a9794
23 changed files with 518 additions and 125 deletions

View File

@@ -21,7 +21,7 @@ Last space-z level = empty
#define CITY_OF_COGS "City of Cogs" #define CITY_OF_COGS "City of Cogs"
#define EMPTY_AREA_1 "Empty Area 1" #define EMPTY_AREA_1 "Empty Area 1"
#define EMPTY_AREA_2 "Empty Area 2" #define EMPTY_AREA_2 "Empty Area 2"
#define MINING "Mining Asteroid" #define MINING_ASTEROID "Mining Asteroid"
#define EMPTY_AREA_3 "Empty Area 3" #define EMPTY_AREA_3 "Empty Area 3"
#define EMPTY_AREA_4 "Empty Area 4" #define EMPTY_AREA_4 "Empty Area 4"
#define EMPTY_AREA_5 "Empty Area 5" #define EMPTY_AREA_5 "Empty Area 5"
@@ -36,11 +36,8 @@ Last space-z level = empty
#define MAP_REMOVE_JOB(jobpath) /datum/job/##jobpath/map_check() { return (SSmapping.config.map_name != JOB_MODIFICATION_MAP_NAME) && ..() } #define MAP_REMOVE_JOB(jobpath) /datum/job/##jobpath/map_check() { return (SSmapping.config.map_name != JOB_MODIFICATION_MAP_NAME) && ..() }
//zlevel defines, can be overridden for different maps in the appropriate _maps file. //zlevel defines, can be overridden for different maps in the appropriate _maps file.
#define ZLEVEL_CENTCOM 1
#define ZLEVEL_STATION_PRIMARY 2 #define ZLEVEL_STATION_PRIMARY 2
#define ZLEVEL_MINING 5
#define ZLEVEL_LAVALAND 5 #define ZLEVEL_LAVALAND 5
#define ZLEVEL_CITYOFCOGS 6
#define ZLEVEL_EMPTY_SPACE 12 #define ZLEVEL_EMPTY_SPACE 12
//Unless you modify it in map config should be equal to ZLEVEL_SPACEMAX //Unless you modify it in map config should be equal to ZLEVEL_SPACEMAX
#define ZLEVEL_TRANSIT 13 #define ZLEVEL_TRANSIT 13
@@ -49,3 +46,31 @@ Last space-z level = empty
#define ZLEVEL_SPACEMAX 13 #define ZLEVEL_SPACEMAX 13
#define SPACERUIN_MAP_EDGE_PAD 15 #define SPACERUIN_MAP_EDGE_PAD 15
#define ZLEVEL_SPACE_RUIN_COUNT 5
// traits
#define ZTRAIT_CENTCOM "CentCom"
#define ZTRAIT_STATION "Station"
#define ZTRAIT_MINING "Mining"
#define ZTRAIT_REEBE "Reebe"
#define ZTRAIT_TRANSIT "Transit"
#define ZTRAIT_AWAY "Away Mission"
#define ZTRAIT_SPACE_RUINS "Space Ruins"
#define ZTRAIT_LAVA_RUINS "Lava Ruins"
#define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier"
// trait definitions
#define DL_NAME "name"
#define DL_LINKAGE "linkage"
#define DL_TRAITS "traits"
#define DECLARE_LEVEL(NAME, LINKAGE, TRAITS) list(DL_NAME = NAME, DL_LINKAGE = LINKAGE, DL_TRAITS = TRAITS)
// corresponds to basemap.dm
#define DEFAULT_MAP_TRAITS list(\
DECLARE_LEVEL("CentCom", SELFLOOPING, list(ZTRAIT_CENTCOM = TRUE)),\
DECLARE_LEVEL("Main Station", CROSSLINKED, list(ZTRAIT_STATION = TRUE)),\
DECLARE_LEVEL("Empty Area 1", CROSSLINKED, list(ZTRAIT_SPACE_RUINS = TRUE)),\
DECLARE_LEVEL("Empty Area 2", CROSSLINKED, list(ZTRAIT_SPACE_RUINS = TRUE)),\
DECLARE_LEVEL("Lavaland", UNAFFECTED, list(ZTRAIT_MINING = TRUE, ZTRAIT_LAVA_RUINS = TRUE, ZTRAIT_BOMBCAP_MULTIPLIER = 3)),\
DECLARE_LEVEL("Reebe", UNAFFECTED, list(ZTRAIT_REEBE = TRUE, ZTRAIT_BOMBCAP_MULTIPLIER = 0.5)),\
)

View File

@@ -1,17 +1,17 @@
// Helpers for checking whether a z-level conforms to a specific requirement // Helpers for checking whether a z-level conforms to a specific requirement
// Basic levels // Basic levels
#define is_centcom_level(z) ((z) == ZLEVEL_CENTCOM) #define is_centcom_level(z) SSmapping.level_trait(z, ZTRAIT_CENTCOM)
#define is_station_level(z) ((z) in GLOB.station_z_levels) #define is_station_level(z) SSmapping.level_trait(z, ZTRAIT_STATION)
#define is_mining_level(z) ((z) == ZLEVEL_MINING) #define is_mining_level(z) SSmapping.level_trait(z, ZTRAIT_MINING)
#define is_reebe(z) ((z) == ZLEVEL_CITYOFCOGS) #define is_reebe(z) SSmapping.level_trait(z, ZTRAIT_REEBE)
#define is_transit_level(z) ((z) == ZLEVEL_TRANSIT) #define is_transit_level(z) SSmapping.level_trait(z, ZTRAIT_TRANSIT)
#define is_away_level(z) ((z) > ZLEVEL_SPACEMAX) #define is_away_level(z) SSmapping.level_trait(z, ZTRAIT_AWAY)
// If true, the singularity cannot strip away asteroid turf on this Z // If true, the singularity cannot strip away asteroid turf on this Z
#define is_planet_level(z) (GLOB.z_is_planet["z"]) #define is_planet_level(z) (GLOB.z_is_planet["z"])

View File

@@ -1,14 +1,7 @@
#define Z_NORTH 1
#define Z_EAST 2
#define Z_SOUTH 3
#define Z_WEST 4
GLOBAL_LIST_INIT(cardinals, list(NORTH, SOUTH, EAST, WEST)) GLOBAL_LIST_INIT(cardinals, list(NORTH, SOUTH, EAST, WEST))
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(station_z_levels, list(ZLEVEL_STATION_PRIMARY))
GLOBAL_LIST(global_map) GLOBAL_LIST(global_map)
//list/global_map = list(list(1,5),list(4,3))//an array of map Z levels. //list/global_map = list(list(1,5),list(4,3))//an array of map Z levels.
//Resulting sector map looks like //Resulting sector map looks like

View File

@@ -22,6 +22,9 @@ SUBSYSTEM_DEF(mapping)
var/loading_ruins = FALSE var/loading_ruins = FALSE
// Z-manager stuff
var/list/z_list
/datum/controller/subsystem/mapping/PreInit() /datum/controller/subsystem/mapping/PreInit()
if(!config) if(!config)
#ifdef FORCE_MAP #ifdef FORCE_MAP
@@ -39,28 +42,34 @@ SUBSYSTEM_DEF(mapping)
repopulate_sorted_areas() repopulate_sorted_areas()
process_teleport_locs() //Sets up the wizard teleport locations process_teleport_locs() //Sets up the wizard teleport locations
preloadTemplates() preloadTemplates()
// Create space levels
for(var/I in 1 to ZLEVEL_SPACE_RUIN_COUNT)
add_new_zlevel("Empty Area [2 + I]", CROSSLINKED, list(ZTRAIT_SPACE_RUINS = TRUE))
add_new_zlevel("Empty Area [3 + ZLEVEL_SPACE_RUIN_COUNT]", CROSSLINKED, list()) // no ruins
add_new_zlevel("Transit", UNAFFECTED, list(ZTRAIT_TRANSIT = TRUE))
// Pick a random away mission. // Pick a random away mission.
createRandomZlevel() createRandomZlevel()
// Generate mining. if (z_list.len < world.maxz)
add_new_zlevel("Away Mission", UNAFFECTED, list(ZTRAIT_AWAY = TRUE))
// Generate mining ruins
loading_ruins = TRUE loading_ruins = TRUE
var/mining_type = config.minetype var/list/lava_ruins = levels_by_trait(ZTRAIT_LAVA_RUINS)
if (mining_type == "lavaland") if (lava_ruins.len)
seedRuins(list(ZLEVEL_LAVALAND), CONFIG_GET(number/lavaland_budget), /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates) seedRuins(lava_ruins, CONFIG_GET(number/lavaland_budget), /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates)
spawn_rivers() for (var/lava_z in lava_ruins)
spawn_rivers(lava_z)
// deep space ruins // Generate deep space ruins
var/space_zlevels = list() var/list/space_ruins = levels_by_trait(ZTRAIT_SPACE_RUINS)
for(var/i in ZLEVEL_SPACEMIN to ZLEVEL_SPACEMAX) if (space_ruins.len)
switch(i) seedRuins(space_ruins, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
if(ZLEVEL_MINING, ZLEVEL_LAVALAND, ZLEVEL_EMPTY_SPACE, ZLEVEL_TRANSIT, ZLEVEL_CITYOFCOGS)
continue
else
space_zlevels += i
seedRuins(space_zlevels, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
loading_ruins = FALSE loading_ruins = FALSE
repopulate_sorted_areas() repopulate_sorted_areas()
// Set up Z-level transistions. // Set up Z-level transitions.
setup_map_transitions() setup_map_transitions()
generate_station_area_list() generate_station_area_list()
..() ..()
@@ -98,6 +107,8 @@ SUBSYSTEM_DEF(mapping)
config = SSmapping.config config = SSmapping.config
next_map_config = SSmapping.next_map_config next_map_config = SSmapping.next_map_config
z_list = SSmapping.z_list
/datum/controller/subsystem/mapping/proc/TryLoadZ(filename, errorList, forceLevel, last) /datum/controller/subsystem/mapping/proc/TryLoadZ(filename, errorList, forceLevel, last)
var/static/dmm_suite/loader var/static/dmm_suite/loader
if(!loader) if(!loader)
@@ -107,11 +118,6 @@ SUBSYSTEM_DEF(mapping)
if(last) if(last)
QDEL_NULL(loader) QDEL_NULL(loader)
/datum/controller/subsystem/mapping/proc/CreateSpace(MaxZLevel)
while(world.maxz < MaxZLevel)
++world.maxz
CHECK_TICK
#define INIT_ANNOUNCE(X) to_chat(world, "<span class='boldannounce'>[X]</span>"); log_world(X) #define INIT_ANNOUNCE(X) to_chat(world, "<span class='boldannounce'>[X]</span>"); log_world(X)
/datum/controller/subsystem/mapping/proc/loadWorld() /datum/controller/subsystem/mapping/proc/loadWorld()
//if any of these fail, something has gone horribly, HORRIBLY, wrong //if any of these fail, something has gone horribly, HORRIBLY, wrong
@@ -121,6 +127,7 @@ SUBSYSTEM_DEF(mapping)
INIT_ANNOUNCE("Loading [config.map_name]...") INIT_ANNOUNCE("Loading [config.map_name]...")
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION_PRIMARY) TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION_PRIMARY)
InitializeDefaultZLevels()
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!") INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
if(SSdbcore.Connect()) if(SSdbcore.Connect())
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]") var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
@@ -129,8 +136,6 @@ SUBSYSTEM_DEF(mapping)
if(config.minetype != "lavaland") if(config.minetype != "lavaland")
INIT_ANNOUNCE("WARNING: A map without lavaland set as its minetype was loaded! This is being ignored! Update the maploader code!") INIT_ANNOUNCE("WARNING: A map without lavaland set as its minetype was loaded! This is being ignored! Update the maploader code!")
CreateSpace(ZLEVEL_SPACEMAX)
if(LAZYLEN(FailedZs)) //but seriously, unless the server's filesystem is messed up this will never happen if(LAZYLEN(FailedZs)) //but seriously, unless the server's filesystem is messed up this will never happen
var/msg = "RED ALERT! The following map files failed to load: [FailedZs[1]]" var/msg = "RED ALERT! The following map files failed to load: [FailedZs[1]]"
if(FailedZs.len > 1) if(FailedZs.len > 1)

View File

@@ -5,9 +5,10 @@ SUBSYSTEM_DEF(minimap)
var/const/MINIMAP_SIZE = 2048 var/const/MINIMAP_SIZE = 2048
var/const/TILE_SIZE = 8 var/const/TILE_SIZE = 8
var/list/z_levels = list(ZLEVEL_STATION_PRIMARY) var/list/z_levels
/datum/controller/subsystem/minimap/Initialize(timeofday) /datum/controller/subsystem/minimap/Initialize(timeofday)
z_levels = SSmapping.levels_by_trait(ZTRAIT_STATION)
var/hash = md5(SSmapping.config.GetFullMapPath()) var/hash = md5(SSmapping.config.GetFullMapPath())
if(CONFIG_GET(flag/generate_minimaps)) if(CONFIG_GET(flag/generate_minimaps))
if(hash == trim(file2text(hash_path()))) if(hash == trim(file2text(hash_path())))

View File

@@ -34,7 +34,7 @@ SUBSYSTEM_DEF(squeak)
/datum/controller/subsystem/squeak/proc/find_exposed_wires() /datum/controller/subsystem/squeak/proc/find_exposed_wires()
exposed_wires.Cut() exposed_wires.Cut()
var/list/all_turfs var/list/all_turfs
for (var/z in GLOB.station_z_levels) for (var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
all_turfs += block(locate(1,1,z), locate(world.maxx,world.maxy,z)) all_turfs += block(locate(1,1,z), locate(world.maxx,world.maxy,z))
for(var/turf/open/floor/plating/T in all_turfs) for(var/turf/open/floor/plating/T in all_turfs)
if(is_blocked_turf(T)) if(is_blocked_turf(T))

View File

@@ -1,6 +1,4 @@
#define EXPLOSION_THROW_SPEED 4 #define EXPLOSION_THROW_SPEED 4
#define CITYOFCOGS_CAP_MULTIPLIER 0.5
#define MINING_CAP_MULTIPLIER 3
GLOBAL_LIST_EMPTY(explosions) GLOBAL_LIST_EMPTY(explosions)
//Against my better judgement, I will return the explosion datum //Against my better judgement, I will return the explosion datum
@@ -54,17 +52,14 @@ GLOBAL_LIST_EMPTY(explosions)
var/orig_dev_range = devastation_range var/orig_dev_range = devastation_range
var/orig_heavy_range = heavy_impact_range var/orig_heavy_range = heavy_impact_range
var/orig_light_range = light_impact_range var/orig_light_range = light_impact_range
var/orig_max_distance = max(devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range) var/orig_max_distance = max(devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range)
//Zlevel specific bomb cap multiplier //Zlevel specific bomb cap multiplier
var/cap_multiplier = 1 var/cap_multiplier = SSmapping.level_trait(epicenter.z, ZTRAIT_BOMBCAP_MULTIPLIER)
switch(epicenter.z) if (isnull(cap_multiplier))
if(ZLEVEL_CITYOFCOGS) cap_multiplier = 1
cap_multiplier = CITYOFCOGS_CAP_MULTIPLIER
if(ZLEVEL_MINING)
cap_multiplier = MINING_CAP_MULTIPLIER
if(!ignorecap) if(!ignorecap)
devastation_range = min(GLOB.MAX_EX_DEVESTATION_RANGE * cap_multiplier, devastation_range) devastation_range = min(GLOB.MAX_EX_DEVESTATION_RANGE * cap_multiplier, devastation_range)
heavy_impact_range = min(GLOB.MAX_EX_HEAVY_RANGE * cap_multiplier, heavy_impact_range) heavy_impact_range = min(GLOB.MAX_EX_HEAVY_RANGE * cap_multiplier, heavy_impact_range)
@@ -91,11 +86,11 @@ GLOBAL_LIST_EMPTY(explosions)
if(adminlog) if(adminlog)
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [epi_area] [ADMIN_COORDJMP(epicenter)]") message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [epi_area] [ADMIN_COORDJMP(epicenter)]")
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])") log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
var/x0 = epicenter.x var/x0 = epicenter.x
var/y0 = epicenter.y var/y0 = epicenter.y
var/z0 = epicenter.z var/z0 = epicenter.z
SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flash" = flash_range, "flame" = flame_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = epi_area.type)) SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flash" = flash_range, "flame" = flame_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = epi_area.type))
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. // Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
@@ -199,7 +194,7 @@ GLOBAL_LIST_EMPTY(explosions)
//------- EX_ACT AND TURF FIRES ------- //------- EX_ACT AND TURF FIRES -------
if(T == epicenter) // Ensures explosives detonating from bags trigger other explosives in that bag if(T == epicenter) // Ensures explosives detonating from bags trigger other explosives in that bag
var/list/items = list() var/list/items = list()
for(var/I in T) for(var/I in T)
var/atom/A = I var/atom/A = I
items += A.GetAllContents() items += A.GetAllContents()
@@ -418,6 +413,3 @@ GLOBAL_LIST_EMPTY(explosions)
// 10 explosion power is a (1, 3, 6) explosion. // 10 explosion power is a (1, 3, 6) explosion.
// 5 explosion power is a (0, 1, 3) explosion. // 5 explosion power is a (0, 1, 3) explosion.
// 1 explosion power is a (0, 0, 1) explosion. // 1 explosion power is a (0, 0, 1) explosion.
#undef CITYOFCOGS_CAP_MULTIPLIER
#undef MINING_CAP_MULTIPLIER

View File

@@ -166,9 +166,12 @@
// Safe location finder // Safe location finder
/proc/find_safe_turf(zlevel = ZLEVEL_STATION_PRIMARY, list/zlevels, extended_safety_checks = FALSE) /proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE)
if(!zlevels) if(!zlevels)
zlevels = list(zlevel) if (zlevel)
zlevels = list(zlevel)
else
zlevels = SSmapping.levels_by_trait(ZTRAIT_STATION)
var/cycles = 1000 var/cycles = 1000
for(var/cycle in 1 to cycles) for(var/cycle in 1 to cycles)
// DRUNK DIALLING WOOOOOOOOO // DRUNK DIALLING WOOOOOOOOO

View File

@@ -1,3 +1,4 @@
<<<<<<< HEAD
//Designed for things that need precision trajectories like projectiles. //Designed for things that need precision trajectories like projectiles.
//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels. //Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels.
@@ -237,3 +238,244 @@
last_process = world.time last_process = world.time
last_move = world.time last_move = world.time
increment(needed_time) increment(needed_time)
=======
//Designed for things that need precision trajectories like projectiles.
//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels.
#define RETURN_PRECISE_POSITION(A) new /datum/position(A)
#define RETURN_PRECISE_POINT(A) new /datum/point(A)
/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess.
var/x = 0
var/y = 0
var/z = 0
var/pixel_x = 0
var/pixel_y = 0
/datum/position/proc/valid()
return x && y && z && !isnull(pixel_x) && !isnull(pixel_y)
/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point.
if(istype(_x, /datum/point))
var/datum/point/P = _x
var/turf/T = P.return_turf()
_x = T.x
_y = T.y
_z = T.z
_pixel_x = P.return_px()
_pixel_y = P.return_py()
else if(isatom(_x))
var/atom/A = _x
_x = A.x
_y = A.y
_z = A.z
_pixel_x = A.pixel_x
_pixel_y = A.pixel_y
x = _x
y = _y
z = _z
pixel_x = _pixel_x
pixel_y = _pixel_y
/datum/position/proc/return_turf()
return locate(x, y, z)
/datum/position/proc/return_px()
return pixel_x
/datum/position/proc/return_py()
return pixel_y
/datum/position/proc/return_point()
return new /datum/point(src)
/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below.
var/datum/point/P = new
P.x = round(a.x + (b.x - a.x) / 2, 1)
P.y = round(a.y + (b.y - a.y) / 2, 1)
P.z = a.z
return P
/proc/pixel_length_between_points(datum/point/a, datum/point/b)
return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2))
/proc/angle_between_points(datum/point/a, datum/point/b)
return ATAN2((b.y - a.y), (b.x - a.x))
/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP!
var/x = 0
var/y = 0
var/z = 0
/datum/point/proc/valid()
return x && y && z
/datum/point/proc/copy_to(datum/point/p = new)
p.x = x
p.y = y
p.z = z
return p
/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom.
if(istype(_x, /datum/position))
var/datum/position/P = _x
_x = P.x
_y = P.y
_z = P.z
_pixel_x = P.pixel_x
_pixel_y = P.pixel_y
else if(istype(_x, /atom))
var/atom/A = _x
_x = A.x
_y = A.y
_z = A.z
_pixel_x = A.pixel_x
_pixel_y = A.pixel_y
initialize_location(_x, _y, _z, _pixel_x, _pixel_y)
/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
if(!isnull(tile_x))
x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x
if(!isnull(tile_y))
y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2+ p_y
if(!isnull(tile_z))
z = tile_z
/datum/point/proc/return_turf()
return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
/datum/point/proc/return_coordinates() //[turf_x, turf_y, z]
return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
/datum/point/proc/return_position()
return new /datum/position(src)
/datum/point/proc/return_px()
return MODULUS(x, world.icon_size) - 16
/datum/point/proc/return_py()
return MODULUS(y, world.icon_size) - 16
/datum/point/proc/mapcheck()
. = FALSE
var/maxx = world.icon_size * world.maxx
var/maxy = world.icon_size * world.maxy
var/move_zx = 0
var/move_zy = 0
if(x < 0)
x += maxx
move_zx -= 1
if(y < 0)
y += maxy
move_zy -= 1
if(x > maxx)
x -= maxx
move_zx += 1
if(y > maxy)
y -= maxy
move_zy += 1
var/datum/space_level/S = SSmapping.get_level(z)
if(move_zx != 0)
var/datum/space_level/L = S.neigbours["[move_zx < 0? WEST : EAST]"]
z = L.z_value
. = TRUE
if(move_zy != 0)
var/datum/space_level/L = S.neigbours["[move_zy < 0? SOUTH : NORTH]"]
z = L.z_value
. = TRUE
/datum/point/vector
var/speed = 32 //pixels per iteration
var/iteration = 0
var/angle = 0
var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step.
var/mpy = 0
var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location().
var/starting_y = 0
var/starting_z = 0
/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed)
..()
initialize_trajectory(_speed, _angle)
/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
. = ..()
starting_x = x
starting_y = y
starting_z = z
/datum/point/vector/copy_to(datum/point/vector/v = new)
..(v)
v.speed = speed
v.iteration = iteration
v.angle = angle
v.mpx = mpx
v.mpy = mpy
v.starting_x = starting_x
v.starting_y = starting_y
v.starting_z = starting_z
return v
/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle)
if(!isnull(pixel_speed))
speed = pixel_speed
set_angle(new_angle)
/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270.
if(isnull(angle))
return
angle = new_angle
update_offsets()
/datum/point/vector/proc/update_offsets()
mpx = sin(angle) * speed
mpy = cos(angle) * speed
/datum/point/vector/proc/set_speed(new_speed)
if(isnull(new_speed) || speed == new_speed)
return
speed = new_speed
update_offsets()
/datum/point/vector/proc/increment(multiplier = 1)
iteration++
x += mpx * 1
y += mpy * 1
if(mapcheck())
on_z_change()
/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE)
var/datum/point/vector/v = copy_to()
if(force_simulate)
for(var/i in 1 to amount)
v.increment(multiplier)
else
v.increment(multiplier * amount)
return v
/datum/point/vector/proc/on_z_change()
return
/datum/point/vector/processed //pixel_speed is per decisecond.
var/last_process = 0
var/last_move = 0
var/paused = FALSE
/datum/point/vector/processed/Destroy()
STOP_PROCESSING(SSprojectiles, src)
/datum/point/vector/processed/proc/start()
last_process = world.time
last_move = world.time
START_PROCESSING(SSprojectiles, src)
/datum/point/vector/processed/process()
if(paused)
last_move += world.time - last_process
last_process = world.time
return
var/needed_time = world.time - last_move
last_process = world.time
last_move = world.time
increment(needed_time)
>>>>>>> 827c4b3... Replace hardcoded z-level numbers with a trait system (#34090)

View File

@@ -8,7 +8,7 @@
var/mach = 0 var/mach = 0
/datum/station_state/proc/count() /datum/station_state/proc/count()
for(var/Z in GLOB.station_z_levels) for(var/Z in SSmapping.levels_by_trait(ZTRAIT_STATION))
for(var/turf/T in block(locate(1,1,Z), locate(world.maxx,world.maxy,Z))) for(var/turf/T in block(locate(1,1,Z), locate(world.maxx,world.maxy,Z)))
// don't count shuttles since they may have just left // don't count shuttles since they may have just left
if(istype(T.loc, /area/shuttle)) if(istype(T.loc, /area/shuttle))

View File

@@ -31,7 +31,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/max_i = 10//number of tries to spawn meteor. var/max_i = 10//number of tries to spawn meteor.
while(!isspaceturf(pickedstart)) while(!isspaceturf(pickedstart))
var/startSide = pick(GLOB.cardinals) var/startSide = pick(GLOB.cardinals)
var/startZ = pick(GLOB.station_z_levels) var/startZ = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
pickedstart = spaceDebrisStartLoc(startSide, startZ) pickedstart = spaceDebrisStartLoc(startSide, startZ)
pickedgoal = spaceDebrisFinishLoc(startSide, startZ) pickedgoal = spaceDebrisFinishLoc(startSide, startZ)
max_i-- max_i--
@@ -40,7 +40,6 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
var/Me = pickweight(meteortypes) var/Me = pickweight(meteortypes)
var/obj/effect/meteor/M = new Me(pickedstart, pickedgoal) var/obj/effect/meteor/M = new Me(pickedstart, pickedgoal)
M.dest = pickedgoal M.dest = pickedgoal
M.z_original = M.z
/proc/spaceDebrisStartLoc(startSide, Z) /proc/spaceDebrisStartLoc(startSide, Z)
var/starty var/starty
@@ -95,7 +94,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
pass_flags = PASSTABLE pass_flags = PASSTABLE
var/heavy = 0 var/heavy = 0
var/meteorsound = 'sound/effects/meteorimpact.ogg' var/meteorsound = 'sound/effects/meteorimpact.ogg'
var/z_original = ZLEVEL_STATION_PRIMARY var/z_original
var/threat = 0 // used for determining which meteors are most interesting var/threat = 0 // used for determining which meteors are most interesting
var/lifetime = DEFAULT_METEOR_LIFETIME var/lifetime = DEFAULT_METEOR_LIFETIME
var/timerid = null var/timerid = null
@@ -126,6 +125,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
/obj/effect/meteor/Initialize(mapload, target) /obj/effect/meteor/Initialize(mapload, target)
. = ..() . = ..()
z_original = z
GLOB.meteor_list += src GLOB.meteor_list += src
SSaugury.register_doom(src, threat) SSaugury.register_doom(src, threat)
SpinAnimation() SpinAnimation()

View File

@@ -17,7 +17,7 @@
/obj/machinery/computer/camera_advanced/Initialize() /obj/machinery/computer/camera_advanced/Initialize()
. = ..() . = ..()
if(station_lock_override) if(station_lock_override)
z_lock = GLOB.station_z_levels.Copy() z_lock = SSmapping.levels_by_trait(ZTRAIT_STATION)
/obj/machinery/computer/camera_advanced/syndie /obj/machinery/computer/camera_advanced/syndie
icon_keyboard = "syndie_key" icon_keyboard = "syndie_key"

View File

@@ -4,7 +4,7 @@
#define RANDOM_LOWER_X 50 #define RANDOM_LOWER_X 50
#define RANDOM_LOWER_Y 50 #define RANDOM_LOWER_Y 50
/proc/spawn_rivers(target_z = ZLEVEL_LAVALAND, nodes = 4, turf_type = /turf/open/lava/smooth/lava_land_surface, whitelist_area = /area/lavaland/surface/outdoors, min_x = RANDOM_LOWER_X, min_y = RANDOM_LOWER_Y, max_x = RANDOM_UPPER_X, max_y = RANDOM_UPPER_Y) /proc/spawn_rivers(target_z, nodes = 4, turf_type = /turf/open/lava/smooth/lava_land_surface, whitelist_area = /area/lavaland/surface/outdoors, min_x = RANDOM_LOWER_X, min_y = RANDOM_LOWER_Y, max_x = RANDOM_UPPER_X, max_y = RANDOM_UPPER_Y)
var/list/river_nodes = list() var/list/river_nodes = list()
var/num_spawned = 0 var/num_spawned = 0
while(num_spawned < nodes) while(num_spawned < nodes)

View File

@@ -45,7 +45,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
/client/proc/start_line_profiling, /client/proc/start_line_profiling,
/client/proc/stop_line_profiling, /client/proc/stop_line_profiling,
/client/proc/show_line_profiling, /client/proc/show_line_profiling,
/client/proc/create_mapping_job_icons /client/proc/create_mapping_job_icons,
/client/proc/debug_z_levels,
)) ))
/obj/effect/debugging/mapfix_marker /obj/effect/debugging/mapfix_marker
@@ -292,4 +293,64 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
//Also add the x //Also add the x
for(var/x_number in 1 to 4) for(var/x_number in 1 to 4)
final.Insert(icon('icons/mob/screen_gen.dmi', "x[x_number == 1 ? "" : x_number]"), "x[x_number == 1 ? "" : x_number]") final.Insert(icon('icons/mob/screen_gen.dmi', "x[x_number == 1 ? "" : x_number]"), "x[x_number == 1 ? "" : x_number]")
fcopy(final, "icons/mob/landmarks.dmi") fcopy(final, "icons/mob/landmarks.dmi")
/client/proc/debug_z_levels()
set name = "Debug Z-Levels"
set category = "Mapping"
var/list/z_list = SSmapping.z_list
var/list/messages = list()
messages += "<b>World</b>: [world.maxx] x [world.maxy] x [world.maxz]<br>"
var/list/linked_levels = list()
var/min_x = INFINITY
var/min_y = INFINITY
var/max_x = -INFINITY
var/max_y = -INFINITY
for(var/z in 1 to max(world.maxz, z_list.len))
if (z > z_list.len)
messages += "<b>[z]</b>: Unmanaged (out of bounds)<br>"
continue
var/datum/space_level/S = z_list[z]
if (!S)
messages += "<b>[z]</b>: Unmanaged (null)<br>"
continue
var/linkage
switch (S.linkage)
if (UNAFFECTED)
linkage = "no linkage"
if (SELFLOOPING)
linkage = "self-looping"
if (CROSSLINKED)
linkage = "linked at ([S.xi], [S.yi])"
linked_levels += S
min_x = min(min_x, S.xi)
min_y = min(min_y, S.yi)
max_x = max(max_x, S.xi)
max_y = max(max_y, S.yi)
else
linkage = "unknown linkage '[S.linkage]'"
messages += "<b>[z]</b>: [S.name], [linkage], traits: [json_encode(S.traits)]<br>"
if (S.z_value != z)
messages += "-- z_value is [S.z_value], should be [z]<br>"
if (S.name == initial(S.name))
messages += "-- name not set<br>"
if (z > world.maxz)
messages += "-- exceeds max z"
var/grid[max_x - min_x + 1][max_y - min_y + 1]
for(var/datum/space_level/S in linked_levels)
grid[S.xi - min_x + 1][S.yi - min_y + 1] = S.z_value
messages += "<table border='1'>"
for(var/y in max_y to min_y step -1)
var/list/part = list()
for(var/x in min_x to max_x)
part += "[grid[x - min_x + 1][y - min_y + 1]]"
messages += "<tr><td>[part.Join("</td><td>")]</td></tr>"
messages += "</table>"
to_chat(src, messages.Join(""))

View File

@@ -5,12 +5,12 @@
anchored = TRUE anchored = TRUE
density = TRUE density = TRUE
var/question = "Travel back?" var/question = "Travel back?"
var/list/zlevels = list() var/list/zlevels
/obj/structure/signpost/New() /obj/structure/signpost/New()
. = ..() . = ..()
set_light(2) set_light(2)
zlevels = GLOB.station_z_levels zlevels = SSmapping.levels_by_trait(ZTRAIT_STATION)
/obj/structure/signpost/attackby(obj/item/W, mob/user, params) /obj/structure/signpost/attackby(obj/item/W, mob/user, params)
return attack_hand(user) return attack_hand(user)
@@ -44,6 +44,6 @@
zlevels = list() zlevels = list()
for(var/i in 1 to world.maxz) for(var/i in 1 to world.maxz)
zlevels += i zlevels += i
zlevels -= ZLEVEL_CENTCOM // no easy victory, even with meme signposts zlevels -= SSmapping.levels_by_trait(ZTRAIT_CENTCOM) // no easy victory, even with meme signposts
// also, could you think of the horror if they ended up in a holodeck // also, could you think of the horror if they ended up in a holodeck
// template or something // template or something

View File

@@ -32,8 +32,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
/datum/round_event/immovable_rod/start() /datum/round_event/immovable_rod/start()
var/datum/round_event_control/immovable_rod/C = control var/datum/round_event_control/immovable_rod/C = control
var/startside = pick(GLOB.cardinals) var/startside = pick(GLOB.cardinals)
var/turf/startT = spaceDebrisStartLoc(startside, ZLEVEL_STATION_PRIMARY) var/z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
var/turf/endT = spaceDebrisFinishLoc(startside, ZLEVEL_STATION_PRIMARY) var/turf/startT = spaceDebrisStartLoc(startside, z)
var/turf/endT = spaceDebrisFinishLoc(startside, z)
new /obj/effect/immovablerod(startT, endT, C.special_target) new /obj/effect/immovablerod(startT, endT, C.special_target)
/obj/effect/immovablerod /obj/effect/immovablerod
@@ -60,7 +61,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>", enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>",
source=src, action=NOTIFY_ORBIT) source=src, action=NOTIFY_ORBIT)
GLOB.poi_list += src GLOB.poi_list += src
var/special_target_valid = FALSE var/special_target_valid = FALSE
if(special_target) if(special_target)
var/turf/T = get_turf(special_target) var/turf/T = get_turf(special_target)

View File

@@ -0,0 +1,14 @@
/datum/space_level
var/name = "Your config settings failed, you need to fix this for the datum space levels to work"
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, new_linkage = SELFLOOPING, list/new_traits = list())
z_value = new_z
name = new_name
traits = new_traits
set_linkage(new_linkage)

View File

@@ -1,18 +1,6 @@
//This is a simple 3 by 3 grid working off the corpse of the space torus. The donut is dead, cube has been avenged! /datum/space_level/proc/set_linkage(new_linkage)
linkage = new_linkage
GLOBAL_LIST_EMPTY(z_levels_list) if(linkage == SELFLOOPING)
/datum/space_level
var/name = "Your config settings failed, you need to fix this for the datum space levels to work"
var/list/neigbours = list()
var/z_value = 1 //actual z placement
var/linked = SELFLOOPING
var/xi
var/yi //imaginary placements on the grid
/datum/space_level/New(transition_type)
linked = transition_type
if(linked == SELFLOOPING)
neigbours = list() neigbours = list()
var/list/L = list(TEXT_NORTH,TEXT_SOUTH,TEXT_EAST,TEXT_WEST) var/list/L = list(TEXT_NORTH,TEXT_SOUTH,TEXT_EAST,TEXT_WEST)
for(var/A in L) for(var/A in L)
@@ -69,21 +57,15 @@ GLOBAL_LIST_EMPTY(z_levels_list)
if(y-1 >= 1) if(y-1 >= 1)
neigbours |= grid[x][y-1] neigbours |= grid[x][y-1]
/proc/setup_map_transitions() //listamania /datum/controller/subsystem/mapping/proc/setup_map_transitions() //listamania
var/list/SLS = list() var/list/SLS = list()
var/datum/space_level/D var/list/cached_z_list = z_list
var/list/cached_transitions = SSmapping.config.transition_config var/conf_set_len = 0
var/conf_set_len = cached_transitions.len for(var/A in cached_z_list)
var/k = 1 var/datum/space_level/D = A
for(var/A in cached_transitions) if (D.linkage == CROSSLINKED)
D = new(cached_transitions[A])
D.name = A
D.z_value = k
if(D.linked != CROSSLINKED)
GLOB.z_levels_list["[D.z_value]"] = D
else
SLS.Add(D) SLS.Add(D)
k++ conf_set_len++
var/list/point_grid[conf_set_len*2+1][conf_set_len*2+1] var/list/point_grid[conf_set_len*2+1][conf_set_len*2+1]
var/list/grid = list() var/list/grid = list()
var/datum/space_transition_point/P var/datum/space_transition_point/P
@@ -99,7 +81,7 @@ GLOBAL_LIST_EMPTY(z_levels_list)
var/list/used_points = list() var/list/used_points = list()
grid.Cut() grid.Cut()
while(SLS.len) while(SLS.len)
D = pick_n_take(SLS) var/datum/space_level/D = pick_n_take(SLS)
D.xi = P.x D.xi = P.x
D.yi = P.y D.yi = P.y
P.spl = D P.spl = D
@@ -108,10 +90,7 @@ GLOBAL_LIST_EMPTY(z_levels_list)
possible_points.Remove(used_points) possible_points.Remove(used_points)
D.set_neigbours(used_points) D.set_neigbours(used_points)
P = pick(possible_points) P = pick(possible_points)
grid["[D.z_value]"] = D CHECK_TICK
for(var/A in GLOB.z_levels_list)
grid[A] = GLOB.z_levels_list[A]
//Lists below are pre-calculated values arranged in the list in such a way to be easily accessable in the loop by the counter //Lists below are pre-calculated values arranged in the list in such a way to be easily accessable in the loop by the counter
//Its either this or madness with lotsa math //Its either this or madness with lotsa math
@@ -123,13 +102,12 @@ GLOBAL_LIST_EMPTY(z_levels_list)
var/list/x_pos_transition = list(1, 1, TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2) //values of x for the transition from respective blocks on the side of zlevel, 1 is being translated into turfs respective x value later in the code var/list/x_pos_transition = list(1, 1, TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2) //values of x for the transition from respective blocks on the side of zlevel, 1 is being translated into turfs respective x value later in the code
var/list/y_pos_transition = list(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2, 1, 1) //values of y for the transition from respective blocks on the side of zlevel, 1 is being translated into turfs respective y value later in the code var/list/y_pos_transition = list(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2, 1, 1) //values of y for the transition from respective blocks on the side of zlevel, 1 is being translated into turfs respective y value later in the code
for(var/zlevelnumber = 1, zlevelnumber<=grid.len, zlevelnumber++) for(var/I in cached_z_list)
D = grid["[zlevelnumber]"] var/datum/space_level/D = I
if(!D) if(!D.neigbours.len)
CRASH("[zlevelnumber] position has no space level datum.")
if(!(D.neigbours.len))
continue continue
for(var/side = 1, side<5, side++) var/zlevelnumber = D.z_value
for(var/side in 1 to 4)
var/turf/beginning = locate(x_pos_beginning[side], y_pos_beginning[side], zlevelnumber) var/turf/beginning = locate(x_pos_beginning[side], y_pos_beginning[side], zlevelnumber)
var/turf/ending = locate(x_pos_ending[side], y_pos_ending[side], zlevelnumber) var/turf/ending = locate(x_pos_ending[side], y_pos_ending[side], zlevelnumber)
var/list/turfblock = block(beginning, ending) var/list/turfblock = block(beginning, ending)
@@ -143,12 +121,8 @@ GLOBAL_LIST_EMPTY(z_levels_list)
while(D.neigbours["[dirside]"] && D.neigbours["[dirside]"] != D) while(D.neigbours["[dirside]"] && D.neigbours["[dirside]"] != D)
D = D.neigbours["[dirside]"] D = D.neigbours["[dirside]"]
zdestination = D.z_value zdestination = D.z_value
D = grid["[zlevelnumber]"] D = I
for(var/turf/open/space/S in turfblock) for(var/turf/open/space/S in turfblock)
S.destination_x = x_pos_transition[side] == 1 ? S.x : x_pos_transition[side] S.destination_x = x_pos_transition[side] == 1 ? S.x : x_pos_transition[side]
S.destination_y = y_pos_transition[side] == 1 ? S.y : y_pos_transition[side] S.destination_y = y_pos_transition[side] == 1 ? S.y : y_pos_transition[side]
S.destination_z = zdestination S.destination_z = zdestination
//S.maptext = "[zdestination]" // for debugging
for(var/A in grid)
GLOB.z_levels_list[A] = grid[A]

View File

@@ -0,0 +1,46 @@
// Look up levels[z].traits[trait]
/datum/controller/subsystem/mapping/proc/level_trait(z, trait)
if (!z)
return null
var/list/trait_list
if (z_list)
var/datum/space_level/S = get_level(z)
trait_list = S.traits
else
var/list/default_map_traits = DEFAULT_MAP_TRAITS
trait_list = default_map_traits[z][DL_TRAITS]
return trait_list[trait]
// Check if levels[z] has any of the specified traits
/datum/controller/subsystem/mapping/proc/level_has_any_trait(z, list/traits)
for (var/I in traits)
if (level_trait(z, I))
return TRUE
return FALSE
// Check if levels[z] has all of the specified traits
/datum/controller/subsystem/mapping/proc/level_has_all_traits(z, list/traits)
for (var/I in traits)
if (!level_trait(z, I))
return FALSE
return TRUE
// Get a list of all z which have the specified trait
/datum/controller/subsystem/mapping/proc/levels_by_trait(trait)
. = list()
var/list/_z_list = z_list
for(var/A in _z_list)
var/datum/space_level/S = A
if (S.traits[trait])
. += S.z_value
// Get a list of all z which have any of the specified traits
/datum/controller/subsystem/mapping/proc/levels_by_any_trait(list/traits)
. = list()
var/list/_z_list = z_list
for(var/A in _z_list)
var/datum/space_level/S = A
for (var/trait in traits)
if (S.traits[trait])
. += S.z_value
break

View File

@@ -0,0 +1,32 @@
// Populate the space level list and prepare space transitions
/datum/controller/subsystem/mapping/proc/InitializeDefaultZLevels()
if (z_list) // subsystem/Recover or badminnery, no need
return
z_list = list()
var/list/default_map_traits = DEFAULT_MAP_TRAITS
if (default_map_traits.len != world.maxz)
WARNING("More or less map attributes pre-defined ([default_map_traits.len]) than existent z-levels ([world.maxz]). Ignoring the larger.")
if (default_map_traits.len > world.maxz)
default_map_traits.Cut(world.maxz + 1)
for (var/I in 1 to default_map_traits.len)
var/list/features = default_map_traits[I]
var/datum/space_level/S = new(I, features[DL_NAME], features[DL_LINKAGE], features[DL_TRAITS])
z_list += S
/datum/controller/subsystem/mapping/proc/add_new_zlevel(name, linkage = SELFLOOPING, traits = list(), z_type = /datum/space_level)
var/new_z = z_list.len + 1
if (world.maxz < new_z)
++world.maxz
CHECK_TICK
// TODO: sleep here if the Z level needs to be cleared
var/datum/space_level/S = new z_type(new_z, name, linkage, traits)
z_list += S
return new_z
/datum/controller/subsystem/mapping/proc/get_level(z)
. = z_list[z]
if (!.)
CRASH("Unmanaged z-level: '[z]'")

View File

@@ -102,7 +102,10 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
if(href_list["random"] && !possible_destinations) if(href_list["random"] && !possible_destinations)
usr.changeNext_move(CLICK_CD_RAPID) //Anti-spam usr.changeNext_move(CLICK_CD_RAPID) //Anti-spam
var/turf/LZ = safepick(Z_TURFS(ZLEVEL_MINING)) //Pick a random mining Z-level turf var/list/all_mining_turfs = list()
for (var/z_level in SSmapping.levels_by_trait(ZTRAIT_MINING))
all_mining_turfs += Z_TURFS(z_level)
var/turf/LZ = safepick(all_mining_turfs) //Pick a random mining Z-level turf
if(!ismineralturf(LZ) && !istype(LZ, /turf/open/floor/plating/asteroid)) if(!ismineralturf(LZ) && !istype(LZ, /turf/open/floor/plating/asteroid))
//Find a suitable mining turf. Reduces chance of landing in a bad area //Find a suitable mining turf. Reduces chance of landing in a bad area
to_chat(usr, "<span class='warning'>Landing zone scan failed. Please try again.</span>") to_chat(usr, "<span class='warning'>Landing zone scan failed. Please try again.</span>")

View File

@@ -1,6 +1,6 @@
/datum/mapGenerator/lavaland /datum/mapGenerator/lavaland
var/start_z = ZLEVEL_LAVALAND var/start_z
var/min_x = 0 var/min_x = 0
var/min_y = 0 var/min_y = 0
var/max_x = 0 var/max_x = 0
@@ -19,11 +19,9 @@
/datum/mapGeneratorModule/river /datum/mapGeneratorModule/river
var/river_type = /turf/open/lava/smooth var/river_type = /turf/open/lava/smooth
var/river_nodes = 4 var/river_nodes = 4
var/start_z = ZLEVEL_LAVALAND
/datum/mapGeneratorModule/river/generate() /datum/mapGeneratorModule/river/generate()
var/datum/mapGenerator/lavaland/L = mother var/datum/mapGenerator/lavaland/L = mother
if(!istype(L)) if(!istype(L))
return return
start_z = L.start_z spawn_rivers(L.start_z, river_nodes, river_type, min_x = L.min_x, min_y = L.min_y, max_x = L.max_x, max_y = L.max_y)
spawn_rivers(start_z, river_nodes, river_type, min_x = L.min_x, min_y = L.min_y, max_x = L.max_x, max_y = L.max_y)

View File

@@ -1685,6 +1685,10 @@
#include "code\modules\mapping\mapping_helpers.dm" #include "code\modules\mapping\mapping_helpers.dm"
#include "code\modules\mapping\reader.dm" #include "code\modules\mapping\reader.dm"
#include "code\modules\mapping\ruins.dm" #include "code\modules\mapping\ruins.dm"
#include "code\modules\mapping\space_management\space_level.dm"
#include "code\modules\mapping\space_management\space_transition.dm"
#include "code\modules\mapping\space_management\traits.dm"
#include "code\modules\mapping\space_management\zlevel_manager.dm"
#include "code\modules\mining\abandoned_crates.dm" #include "code\modules\mining\abandoned_crates.dm"
#include "code\modules\mining\aux_base.dm" #include "code\modules\mining\aux_base.dm"
#include "code\modules\mining\aux_base_camera.dm" #include "code\modules\mining\aux_base_camera.dm"
@@ -2332,7 +2336,6 @@
#include "code\modules\shuttle\supply.dm" #include "code\modules\shuttle\supply.dm"
#include "code\modules\shuttle\syndicate.dm" #include "code\modules\shuttle\syndicate.dm"
#include "code\modules\shuttle\white_ship.dm" #include "code\modules\shuttle\white_ship.dm"
#include "code\modules\space_transition\space_transition.dm"
#include "code\modules\spells\spell.dm" #include "code\modules\spells\spell.dm"
#include "code\modules\spells\spell_types\aimed.dm" #include "code\modules\spells\spell_types\aimed.dm"
#include "code\modules\spells\spell_types\area_teleport.dm" #include "code\modules\spells\spell_types\area_teleport.dm"