Merge pull request #4764 from Citadel-Station-13/upstream-merge-34090
[MIRROR] Replace hardcoded z-level numbers with a trait system
This commit is contained in:
@@ -45,7 +45,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
|
||||
/client/proc/start_line_profiling,
|
||||
/client/proc/stop_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
|
||||
@@ -292,4 +293,64 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
|
||||
//Also add the x
|
||||
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]")
|
||||
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(""))
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
var/question = "Travel back?"
|
||||
var/list/zlevels = list()
|
||||
var/list/zlevels
|
||||
|
||||
/obj/structure/signpost/New()
|
||||
. = ..()
|
||||
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)
|
||||
return attack_hand(user)
|
||||
@@ -44,6 +44,6 @@
|
||||
zlevels = list()
|
||||
for(var/i in 1 to world.maxz)
|
||||
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
|
||||
// template or something
|
||||
|
||||
@@ -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()
|
||||
var/datum/round_event_control/immovable_rod/C = control
|
||||
var/startside = pick(GLOB.cardinals)
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, ZLEVEL_STATION_PRIMARY)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, ZLEVEL_STATION_PRIMARY)
|
||||
var/z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, z)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, z)
|
||||
new /obj/effect/immovablerod(startT, endT, C.special_target)
|
||||
|
||||
/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>",
|
||||
source=src, action=NOTIFY_ORBIT)
|
||||
GLOB.poi_list += src
|
||||
|
||||
|
||||
var/special_target_valid = FALSE
|
||||
if(special_target)
|
||||
var/turf/T = get_turf(special_target)
|
||||
|
||||
@@ -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)
|
||||
+18
-44
@@ -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!
|
||||
|
||||
GLOBAL_LIST_EMPTY(z_levels_list)
|
||||
|
||||
/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)
|
||||
/datum/space_level/proc/set_linkage(new_linkage)
|
||||
linkage = new_linkage
|
||||
if(linkage == SELFLOOPING)
|
||||
neigbours = list()
|
||||
var/list/L = list(TEXT_NORTH,TEXT_SOUTH,TEXT_EAST,TEXT_WEST)
|
||||
for(var/A in L)
|
||||
@@ -69,21 +57,15 @@ GLOBAL_LIST_EMPTY(z_levels_list)
|
||||
if(y-1 >= 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/datum/space_level/D
|
||||
var/list/cached_transitions = SSmapping.config.transition_config
|
||||
var/conf_set_len = cached_transitions.len
|
||||
var/k = 1
|
||||
for(var/A in cached_transitions)
|
||||
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
|
||||
var/list/cached_z_list = z_list
|
||||
var/conf_set_len = 0
|
||||
for(var/A in cached_z_list)
|
||||
var/datum/space_level/D = A
|
||||
if (D.linkage == CROSSLINKED)
|
||||
SLS.Add(D)
|
||||
k++
|
||||
conf_set_len++
|
||||
var/list/point_grid[conf_set_len*2+1][conf_set_len*2+1]
|
||||
var/list/grid = list()
|
||||
var/datum/space_transition_point/P
|
||||
@@ -99,7 +81,7 @@ GLOBAL_LIST_EMPTY(z_levels_list)
|
||||
var/list/used_points = list()
|
||||
grid.Cut()
|
||||
while(SLS.len)
|
||||
D = pick_n_take(SLS)
|
||||
var/datum/space_level/D = pick_n_take(SLS)
|
||||
D.xi = P.x
|
||||
D.yi = P.y
|
||||
P.spl = D
|
||||
@@ -108,10 +90,7 @@ GLOBAL_LIST_EMPTY(z_levels_list)
|
||||
possible_points.Remove(used_points)
|
||||
D.set_neigbours(used_points)
|
||||
P = pick(possible_points)
|
||||
grid["[D.z_value]"] = D
|
||||
|
||||
for(var/A in GLOB.z_levels_list)
|
||||
grid[A] = GLOB.z_levels_list[A]
|
||||
CHECK_TICK
|
||||
|
||||
//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
|
||||
@@ -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/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++)
|
||||
D = grid["[zlevelnumber]"]
|
||||
if(!D)
|
||||
CRASH("[zlevelnumber] position has no space level datum.")
|
||||
if(!(D.neigbours.len))
|
||||
for(var/I in cached_z_list)
|
||||
var/datum/space_level/D = I
|
||||
if(!D.neigbours.len)
|
||||
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/ending = locate(x_pos_ending[side], y_pos_ending[side], zlevelnumber)
|
||||
var/list/turfblock = block(beginning, ending)
|
||||
@@ -143,12 +121,8 @@ GLOBAL_LIST_EMPTY(z_levels_list)
|
||||
while(D.neigbours["[dirside]"] && D.neigbours["[dirside]"] != D)
|
||||
D = D.neigbours["[dirside]"]
|
||||
zdestination = D.z_value
|
||||
D = grid["[zlevelnumber]"]
|
||||
D = I
|
||||
for(var/turf/open/space/S in turfblock)
|
||||
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_z = zdestination
|
||||
//S.maptext = "[zdestination]" // for debugging
|
||||
|
||||
for(var/A in grid)
|
||||
GLOB.z_levels_list[A] = grid[A]
|
||||
@@ -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
|
||||
@@ -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]'")
|
||||
@@ -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)
|
||||
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))
|
||||
//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>")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
/datum/mapGenerator/lavaland
|
||||
var/start_z = ZLEVEL_LAVALAND
|
||||
var/start_z
|
||||
var/min_x = 0
|
||||
var/min_y = 0
|
||||
var/max_x = 0
|
||||
@@ -19,11 +19,9 @@
|
||||
/datum/mapGeneratorModule/river
|
||||
var/river_type = /turf/open/lava/smooth
|
||||
var/river_nodes = 4
|
||||
var/start_z = ZLEVEL_LAVALAND
|
||||
|
||||
/datum/mapGeneratorModule/river/generate()
|
||||
var/datum/mapGenerator/lavaland/L = mother
|
||||
if(!istype(L))
|
||||
return
|
||||
start_z = L.start_z
|
||||
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)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user