diff --git a/citadel.dme b/citadel.dme index 5ebc2fc7c5ac..afc15ac13484 100644 --- a/citadel.dme +++ b/citadel.dme @@ -611,28 +611,27 @@ #include "code\controllers\subsystem\job\joining.dm" #include "code\controllers\subsystem\job\roundstart.dm" #include "code\controllers\subsystem\job\spawnpoints.dm" -#include "code\controllers\subsystem\mapping\_mapping.dm" -#include "code\controllers\subsystem\mapping\allocation.dm" -#include "code\controllers\subsystem\mapping\boot.dm" -#include "code\controllers\subsystem\mapping\levels.dm" -#include "code\controllers\subsystem\mapping\maps.dm" -#include "code\controllers\subsystem\mapping\misc.dm" -#include "code\controllers\subsystem\mapping\obfuscation.dm" -#include "code\controllers\subsystem\mapping\reservations.dm" -#include "code\controllers\subsystem\mapping\level_helpers\air.dm" -#include "code\controllers\subsystem\mapping\level_helpers\attributes.dm" -#include "code\controllers\subsystem\mapping\level_helpers\baseturf.dm" -#include "code\controllers\subsystem\mapping\level_helpers\linkage.dm" -#include "code\controllers\subsystem\mapping\level_helpers\lookup.dm" -#include "code\controllers\subsystem\mapping\level_helpers\structs.dm" -#include "code\controllers\subsystem\mapping\level_helpers\traits.dm" -#include "code\controllers\subsystem\mapping\level_helpers\virtualization.dm" -#include "code\controllers\subsystem\mapping\spatial_helpers\angle.dm" -#include "code\controllers\subsystem\mapping\spatial_helpers\dir.dm" -#include "code\controllers\subsystem\mapping\spatial_helpers\distance.dm" -#include "code\controllers\subsystem\mapping\spatial_helpers\loc.dm" -#include "code\controllers\subsystem\mapping\spatial_helpers\stack.dm" -#include "code\controllers\subsystem\mapping\spatial_helpers\step.dm" +#include "code\controllers\subsystem\mapping\mapping-allocation.dm" +#include "code\controllers\subsystem\mapping\mapping-boot.dm" +#include "code\controllers\subsystem\mapping\mapping-levels.dm" +#include "code\controllers\subsystem\mapping\mapping-maps.dm" +#include "code\controllers\subsystem\mapping\mapping-misc.dm" +#include "code\controllers\subsystem\mapping\mapping-obfuscation.dm" +#include "code\controllers\subsystem\mapping\mapping-reservations.dm" +#include "code\controllers\subsystem\mapping\mapping.dm" +#include "code\controllers\subsystem\mapping\level\mapping-level-air.dm" +#include "code\controllers\subsystem\mapping\level\mapping-level-attributes.dm" +#include "code\controllers\subsystem\mapping\level\mapping-level-baseturf.dm" +#include "code\controllers\subsystem\mapping\level\mapping-level-lookup.dm" +#include "code\controllers\subsystem\mapping\level\mapping-level-structs.dm" +#include "code\controllers\subsystem\mapping\level\mapping-level-traits.dm" +#include "code\controllers\subsystem\mapping\level\mapping-level-virtualization.dm" +#include "code\controllers\subsystem\mapping\spatial\mapping-spatial-stack.dm" +#include "code\controllers\subsystem\mapping\virtual\mapping-virtual-angle.dm" +#include "code\controllers\subsystem\mapping\virtual\mapping-virtual-coords.dm" +#include "code\controllers\subsystem\mapping\virtual\mapping-virtual-dir.dm" +#include "code\controllers\subsystem\mapping\virtual\mapping-virtual-step.dm" +#include "code\controllers\subsystem\mapping\virtual\mapping-vritual-dist.dm" #include "code\controllers\subsystem\networks\_networks.dm" #include "code\controllers\subsystem\networks\simple.dm" #include "code\controllers\subsystem\persistence\bunker.dm" @@ -2118,6 +2117,7 @@ #include "code\modules\admin\callproc\callproc.dm" #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\functions\modify_traits.dm" +#include "code\modules\admin\modals\upload_map_sector.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" #include "code\modules\admin\secrets\admin_secrets\admin_logs.dm" #include "code\modules\admin\secrets\admin_secrets\alter_narsie.dm" diff --git a/code/controllers/subsystem/mapping/_mapping.dm b/code/controllers/subsystem/mapping/_mapping.dm deleted file mode 100644 index eabccb9b489d..000000000000 --- a/code/controllers/subsystem/mapping/_mapping.dm +++ /dev/null @@ -1,78 +0,0 @@ -#define INIT_ANNOUNCE(X) to_chat(world, "[X]"); log_world(X) - -GLOBAL_VAR_INIT(used_engine, "None") -// Handles map-related tasks, mostly here to ensure it does so after the MC initializes. -SUBSYSTEM_DEF(mapping) - name = "Mapping" - init_order = INIT_ORDER_MAPPING - subsystem_flags = SS_NO_FIRE - - /// global mutex for ensuring two map/level load ops don't go at once - /// a separate mutex is used at the actual maploader level - /// this ensures we aren't shoving maps in during map init, as that can be both laggy and/or bad to legacy code that - /// expect zlevel adjacency. - var/load_mutex = FALSE - - // todo: this is going to need a lot more documentation - // the idea of a single zlevel for areas is sorta flawed - // this is an acceptable lazy lookup but we need to standardize what this means / look at how this is generated. - var/list/areas_in_z = list() - -/datum/controller/subsystem/mapping/Initialize(timeofday) - // load data - // todo: refactor - load_map_templates() - // todo: refactor - preloadShelterTemplates() - - // init obfuscation - init_obfuscation_data() - // init maps - init_maps() - // load the map to use - read_next_map() - - // load world - this also initializes our first reserved level, which is compiled in. - load_station() - - // todo: refactor - Set up antagonists. - populate_antag_type_list() - // todo: refactor - Set up spawn points. - populate_spawn_points() - - // finalize - // todo: refactor - repopulate_sorted_areas() - - return ..() - -// -// Mapping subsystem handles initialization of random map elements at server start -// For us that means loading our random roundstart engine! -// -/datum/controller/subsystem/mapping - var/list/map_templates = list() - var/list/shelter_templates = list() - -/datum/controller/subsystem/mapping/Recover() - subsystem_flags |= SS_NO_INIT // Make extra sure we don't initialize twice. - shelter_templates = SSmapping.shelter_templates - -/datum/controller/subsystem/mapping/proc/load_map_templates() - for(var/T in subtypesof(/datum/map_template)) - var/datum/map_template/template = T - template = new T - if(!template.map_path) - qdel(template) - continue - map_templates[template.name] = template - return TRUE - -/datum/controller/subsystem/mapping/proc/preloadShelterTemplates() - for(var/item in subtypesof(/datum/map_template/shelter)) - var/datum/map_template/shelter/shelter_type = item - if(!(initial(shelter_type.map_path))) - continue - var/datum/map_template/shelter/S = new shelter_type() - - shelter_templates[S.shelter_id] = S diff --git a/code/controllers/subsystem/mapping/level_helpers/air.dm b/code/controllers/subsystem/mapping/level/mapping-level-air.dm similarity index 100% rename from code/controllers/subsystem/mapping/level_helpers/air.dm rename to code/controllers/subsystem/mapping/level/mapping-level-air.dm diff --git a/code/controllers/subsystem/mapping/level_helpers/attributes.dm b/code/controllers/subsystem/mapping/level/mapping-level-attributes.dm similarity index 100% rename from code/controllers/subsystem/mapping/level_helpers/attributes.dm rename to code/controllers/subsystem/mapping/level/mapping-level-attributes.dm diff --git a/code/controllers/subsystem/mapping/level_helpers/baseturf.dm b/code/controllers/subsystem/mapping/level/mapping-level-baseturf.dm similarity index 100% rename from code/controllers/subsystem/mapping/level_helpers/baseturf.dm rename to code/controllers/subsystem/mapping/level/mapping-level-baseturf.dm diff --git a/code/controllers/subsystem/mapping/level_helpers/lookup.dm b/code/controllers/subsystem/mapping/level/mapping-level-lookup.dm similarity index 100% rename from code/controllers/subsystem/mapping/level_helpers/lookup.dm rename to code/controllers/subsystem/mapping/level/mapping-level-lookup.dm diff --git a/code/controllers/subsystem/mapping/level_helpers/structs.dm b/code/controllers/subsystem/mapping/level/mapping-level-structs.dm similarity index 100% rename from code/controllers/subsystem/mapping/level_helpers/structs.dm rename to code/controllers/subsystem/mapping/level/mapping-level-structs.dm diff --git a/code/controllers/subsystem/mapping/level_helpers/traits.dm b/code/controllers/subsystem/mapping/level/mapping-level-traits.dm similarity index 100% rename from code/controllers/subsystem/mapping/level_helpers/traits.dm rename to code/controllers/subsystem/mapping/level/mapping-level-traits.dm diff --git a/code/controllers/subsystem/mapping/level_helpers/virtualization.dm b/code/controllers/subsystem/mapping/level/mapping-level-virtualization.dm similarity index 100% rename from code/controllers/subsystem/mapping/level_helpers/virtualization.dm rename to code/controllers/subsystem/mapping/level/mapping-level-virtualization.dm diff --git a/code/controllers/subsystem/mapping/level_helpers/linkage.dm b/code/controllers/subsystem/mapping/level_helpers/linkage.dm deleted file mode 100644 index 79b8d97723db..000000000000 --- a/code/controllers/subsystem/mapping/level_helpers/linkage.dm +++ /dev/null @@ -1,14 +0,0 @@ -//* This file is explicitly licensed under the MIT license. *// -//* Copyright (c) 2023 Citadel Station developers. *// - -/** - * Returns all crosslinked z indices - */ -/datum/controller/subsystem/mapping/proc/crosslinked_levels() - RETURN_TYPE(/list) - return list() - // todo: crosslink support - // . = list() - // for(var/datum/map_level/L as anything in ordered_levels) - // if(L.linkage == Z_LINKAGE_CROSSLINKED) - // . += L.z_index diff --git a/code/controllers/subsystem/mapping/allocation.dm b/code/controllers/subsystem/mapping/mapping-allocation.dm similarity index 78% rename from code/controllers/subsystem/mapping/allocation.dm rename to code/controllers/subsystem/mapping/mapping-allocation.dm index af4adad50094..499a910b1af9 100644 --- a/code/controllers/subsystem/mapping/allocation.dm +++ b/code/controllers/subsystem/mapping/mapping-allocation.dm @@ -15,18 +15,10 @@ * I do not recommend anyone use this unless they absolutely know what they're doing. * (if you think you need this, you probably don't, to be blunt.) */ -/datum/controller/subsystem/mapping - // list of levels ready for reuse - var/static/list/reusable_levels = list() -// todo: recover() +// todo: add this module to recover() // todo: zclear system will be in this later, for now, this is just a wrapper -/datum/controller/subsystem/mapping/on_max_z_changed(old_z_count, new_z_count) - . = ..() - // just to make sure order of ops / assumptions are right - ASSERT(length(ordered_levels) == world.maxz) - /** * gets an reusable level, or increments world.maxz * WARNING: AFTER THIS, YOU NEED TO USE THE LEVEL, OR READD TO REUSABLE, OR THIS IS A MEMORY LEAK! diff --git a/code/controllers/subsystem/mapping/boot.dm b/code/controllers/subsystem/mapping/mapping-boot.dm similarity index 100% rename from code/controllers/subsystem/mapping/boot.dm rename to code/controllers/subsystem/mapping/mapping-boot.dm diff --git a/code/controllers/subsystem/mapping/levels.dm b/code/controllers/subsystem/mapping/mapping-levels.dm similarity index 87% rename from code/controllers/subsystem/mapping/levels.dm rename to code/controllers/subsystem/mapping/mapping-levels.dm index 7bc62959a813..4642aa155513 100644 --- a/code/controllers/subsystem/mapping/levels.dm +++ b/code/controllers/subsystem/mapping/mapping-levels.dm @@ -6,49 +6,6 @@ * * All adds/removes should go through this. Directly modifying zlevel amount/whatever is forbidden. */ -/datum/controller/subsystem/mapping - //* level lookups - /// indexed level datums - var/static/list/datum/map_level/ordered_levels = list() - /// k-v id to level datum lookup - var/static/list/datum/map_level/keyed_levels = list() - /// typepath to level datum lookup - /// we do that because we automatically generate level ids - /// so we can't use initial(id) - var/static/list/datum/map_level/typed_levels = list() - - //* level fluff lookups - /// literally just a random hexadecimal store to prevent collision - var/static/list/random_fluff_level_hashes = list() - - //* multiz core - /// Ordered lookup list for multiz up - var/list/cached_level_up - /// Ordered lookup list for multiz down - var/list/cached_level_down - /// Ordered lookup list for east transition - var/list/cached_level_east - /// Ordered lookup list for west transition - var/list/cached_level_west - /// Ordered lookup list for north transition - var/list/cached_level_north - /// Ordered lookup list for south transition - var/list/cached_level_south - /// Z access lookup - z = list() of zlevels it can directly access vertically - /// * For performance, this is currently only including bidirectional links - /// * For performance, this does not support looping. - /// * This is a direct stack lookup. This does not take map_struct's into account. - /// * You should only be using this for technical use cases like z-rendering and whatnot, - /// for fluff this is not sufficient to determine if something is actually above/below if it's not actually connected. - var/list/z_stack_lookup - /// does z stack lookup need a rebuild? - var/z_stack_dirty = TRUE - - //* struct system - /// Active world_structs - var/static/list/datum/map_struct/structs = list() - /// World struct lookup by level - var/static/list/datum/map_struct/struct_by_z = list() //* Rebuilds / Caching @@ -69,7 +26,6 @@ SYNC(cached_level_north) SYNC(cached_level_south) SYNC(z_stack_lookup) - SYNC(struct_by_z) z_stack_dirty = FALSE if(.) z_stack_dirty = TRUE @@ -446,12 +402,6 @@ z_stack_lookup.len = world.maxz var/list/left = list() for(var/z in 1 to world.maxz) - // todo: stacks - // if(struct_by_z[z]) - // var/datum/world_struct/struct = struct_by_z[z] - // z_stack_lookup[z] = struct.stack_lookup[struct.real_indices.Find(z)] - // else - // left += z left += z var/list/datum/map_level/bottoms = list() // let's sing the bottom song @@ -500,9 +450,5 @@ var/datum/map_level/level = ordered_levels[z] level.link_above = null level.link_below = null - // if(struct_by_z[z]) - // var/datum/world_struct/struct = struct_by_z[z] - // struct.Deconstruct() - // qdel(struct) stack_trace("WARNING: Up/Down loops found in zlevels [english_list(loops)]. This is not allowed and will cause both falling and zcopy to infinitely loop. All zlevels involved have been disconnected, and any structs involved have been destroyed.") rebuild_verticality() diff --git a/code/controllers/subsystem/mapping/maps.dm b/code/controllers/subsystem/mapping/mapping-maps.dm similarity index 95% rename from code/controllers/subsystem/mapping/maps.dm rename to code/controllers/subsystem/mapping/mapping-maps.dm index 4f069765e0e4..b6a7b93f378f 100644 --- a/code/controllers/subsystem/mapping/maps.dm +++ b/code/controllers/subsystem/mapping/mapping-maps.dm @@ -6,21 +6,6 @@ * * Allows dynamic loading of clusters of zlevels (maps) and the initialization of the server with a single station map. */ -/datum/controller/subsystem/mapping - /// station is loaded - var/world_is_loaded = FALSE - /// loaded station map - var/static/datum/map/station/loaded_station - /// next station map - var/datum/map/station/next_station - /// loaded maps - var/static/list/datum/map/loaded_maps = list() - /// available maps - k-v lookup by id - var/list/datum/map/keyed_maps - -/datum/controller/subsystem/mapping/Shutdown() - . = ..() - write_next_map() /** * initializes the key-value store of map datums. diff --git a/code/controllers/subsystem/mapping/misc.dm b/code/controllers/subsystem/mapping/mapping-misc.dm similarity index 100% rename from code/controllers/subsystem/mapping/misc.dm rename to code/controllers/subsystem/mapping/mapping-misc.dm diff --git a/code/controllers/subsystem/mapping/obfuscation.dm b/code/controllers/subsystem/mapping/mapping-obfuscation.dm similarity index 92% rename from code/controllers/subsystem/mapping/obfuscation.dm rename to code/controllers/subsystem/mapping/mapping-obfuscation.dm index 192d67ada016..ca1025c340a8 100644 --- a/code/controllers/subsystem/mapping/obfuscation.dm +++ b/code/controllers/subsystem/mapping/mapping-obfuscation.dm @@ -14,18 +14,6 @@ * * It is usually already too late by the time Initialize() fires. * * By default, /datum/map (not /datum/map_level), /datum/map_template, /datum/shuttle_template are the three things that form new mangling boundaries/contexts. */ -/datum/controller/subsystem/mapping - /// used to ensure global-ness - // todo: should this be here? this is used literally everywhere - var/static/round_global_descriptor - /// round-local hash storage for specific map ids - var/static/round_local_mangling_cache = list() - /// round-local hash storage for specific map ids, reverse lookup - var/static/round_local_mangling_reverse_cache = list() - /// round-local hash storage for obfuscated ids - var/static/round_local_obfuscation_cache = list() - /// round-local hash storage for obfuscated ids, reverse lookup - var/static/round_local_obfuscation_reverse_cache = list() /** * Called at init first thing to setup mangling data diff --git a/code/controllers/subsystem/mapping/reservations.dm b/code/controllers/subsystem/mapping/mapping-reservations.dm similarity index 68% rename from code/controllers/subsystem/mapping/reservations.dm rename to code/controllers/subsystem/mapping/mapping-reservations.dm index cd329e039ca7..dab44afaa6bd 100644 --- a/code/controllers/subsystem/mapping/reservations.dm +++ b/code/controllers/subsystem/mapping/mapping-reservations.dm @@ -4,39 +4,6 @@ /** * turf reservation system */ -/datum/controller/subsystem/mapping - /// reserved levels allocated - var/static/reserved_level_count = 0 - /// reserved turfs allowed - we can over-allocate this if we're only going to be slightly over and can always allocate atleast one level. - var/static/reserved_turfs_max = 192 * 192 * 3 - /// allocated space reservations - var/static/list/datum/turf_reservation/reservations = list() - /// list of reserved z-indices for fast access - var/static/list/reserve_levels = list() - /// doing some blocking op on reservation system - var/static/reservation_blocking_op = FALSE - /// singleton area holding all free reservation turfs - var/static/area/reservation_unused/reservation_unallocated_area = new - /// spatial grid of turf reservations. the owner of a chunk is the bottom left tile's owner. - /// - /// this is a list with length of world.maxz, with the actual spatial grid list being at the index of the z - /// e.g. to grab a reserved level's lookup, do `reservation_spatia_lookups[z_index]` - /// - /// * null means that a level isn't a reservation level - /// * this also means that we can't zclear / 'free' reserved levels; they're effectively immovable due to this datastructure - /// * if it is a reserved level, it returns the spatial grid - /// * to get a chunk, do `spatial_lookup[ceil(where.x / TURF_CHUNK_RESOLUTION) + (ceil(where.y / TURF_CHUNK_RESOLUTION) - 1) * ceil(world.maxx / TURF_CHUNK_RESOLUTION)]` - /// * being in border counts as being in the reservation. you won't be soon, though. - var/static/list/reservation_spatial_lookups = list() - -/datum/controller/subsystem/mapping/on_max_z_changed(old_z_count, new_z_count) - . = ..() - if(length(reservation_spatial_lookups) < new_z_count) - reservation_spatial_lookups.len = new_z_count - -/datum/controller/subsystem/mapping/Recover() - . = ..() - reservation_blocking_op = FALSE /** * allocate a new reservation level diff --git a/code/controllers/subsystem/mapping/mapping.dm b/code/controllers/subsystem/mapping/mapping.dm new file mode 100644 index 000000000000..ac1f688455e2 --- /dev/null +++ b/code/controllers/subsystem/mapping/mapping.dm @@ -0,0 +1,190 @@ +#define INIT_ANNOUNCE(X) to_chat(world, "[X]"); log_world(X) + +GLOBAL_VAR_INIT(used_engine, "None") +// Handles map-related tasks, mostly here to ensure it does so after the MC initializes. +SUBSYSTEM_DEF(mapping) + name = "Mapping" + init_order = INIT_ORDER_MAPPING + subsystem_flags = SS_NO_FIRE + + //* Allocation *// + // list of levels ready for reuse + var/static/list/reusable_levels = list() + + //* Levels *// + /// indexed level datums + var/static/list/datum/map_level/ordered_levels = list() + /// k-v id to level datum lookup + var/static/list/datum/map_level/keyed_levels = list() + /// typepath to level datum lookup + /// we do that because we automatically generate level ids + /// so we can't use initial(id) + var/static/list/datum/map_level/typed_levels = list() + + //* Levels - Fluff *// + /// literally just a random hexadecimal store to prevent collision + var/static/list/random_fluff_level_hashes = list() + + //* Levels - Multiz *// + /// Ordered lookup list for multiz up + var/list/cached_level_up + /// Ordered lookup list for multiz down + var/list/cached_level_down + /// Ordered lookup list for east transition + var/list/cached_level_east + /// Ordered lookup list for west transition + var/list/cached_level_west + /// Ordered lookup list for north transition + var/list/cached_level_north + /// Ordered lookup list for south transition + var/list/cached_level_south + /// Z access lookup - z = list() of zlevels it can directly access vertically + /// * For performance, this is currently only including bidirectional links + /// * For performance, this does not support looping. + /// * This is a direct stack lookup. This does not take map_struct's into account. + /// * You should only be using this for technical use cases like z-rendering and whatnot, + /// for fluff this is not sufficient to determine if something is actually above/below if it's not actually connected. + var/list/z_stack_lookup + /// does z stack lookup need a rebuild? + var/z_stack_dirty = TRUE + + //* Maps *// + /// station is loaded + var/world_is_loaded = FALSE + /// loaded station map + var/static/datum/map/station/loaded_station + /// next station map + var/datum/map/station/next_station + /// loaded maps + var/static/list/datum/map/loaded_maps = list() + /// available maps - k-v lookup by id + var/list/datum/map/keyed_maps + + //* Obfuscation *// + /// used to ensure global-ness + // todo: should this be here? this is used literally everywhere + var/static/round_global_descriptor + /// round-local hash storage for specific map ids + var/static/round_local_mangling_cache = list() + /// round-local hash storage for specific map ids, reverse lookup + var/static/round_local_mangling_reverse_cache = list() + /// round-local hash storage for obfuscated ids + var/static/round_local_obfuscation_cache = list() + /// round-local hash storage for obfuscated ids, reverse lookup + var/static/round_local_obfuscation_reverse_cache = list() + + //* Reservations *// + /// reserved levels allocated + var/static/reserved_level_count = 0 + /// reserved turfs allowed - we can over-allocate this if we're only going to be slightly over and can always allocate atleast one level. + var/static/reserved_turfs_max = 192 * 192 * 3 + /// allocated space reservations + var/static/list/datum/turf_reservation/reservations = list() + /// list of reserved z-indices for fast access + var/static/list/reserve_levels = list() + /// doing some blocking op on reservation system + var/static/reservation_blocking_op = FALSE + /// singleton area holding all free reservation turfs + var/static/area/reservation_unused/reservation_unallocated_area = new + /// spatial grid of turf reservations. the owner of a chunk is the bottom left tile's owner. + /// + /// this is a list with length of world.maxz, with the actual spatial grid list being at the index of the z + /// e.g. to grab a reserved level's lookup, do `reservation_spatia_lookups[z_index]` + /// + /// * null means that a level isn't a reservation level + /// * this also means that we can't zclear / 'free' reserved levels; they're effectively immovable due to this datastructure + /// * if it is a reserved level, it returns the spatial grid + /// * to get a chunk, do `spatial_lookup[ceil(where.x / TURF_CHUNK_RESOLUTION) + (ceil(where.y / TURF_CHUNK_RESOLUTION) - 1) * ceil(world.maxx / TURF_CHUNK_RESOLUTION)]` + /// * being in border counts as being in the reservation. you won't be soon, though. + var/static/list/reservation_spatial_lookups = list() + + //* System *// + /// global mutex for ensuring two map/level load ops don't go at once + /// a separate mutex is used at the actual maploader level + /// this ensures we aren't shoving maps in during map init, as that can be both laggy and/or bad to legacy code that + /// expect zlevel adjacency. + var/load_mutex = FALSE + + //! Legacy !// + + // todo: this is going to need a lot more documentation + // the idea of a single zlevel for areas is sorta flawed + // this is an acceptable lazy lookup but we need to standardize what this means / look at how this is generated. + var/list/areas_in_z = list() + +/datum/controller/subsystem/mapping/Initialize(timeofday) + // load data + // todo: refactor + load_map_templates() + // todo: refactor + preloadShelterTemplates() + + // init obfuscation + init_obfuscation_data() + // init maps + init_maps() + // load the map to use + read_next_map() + + // load world - this also initializes our first reserved level, which is compiled in. + load_station() + + // todo: refactor - Set up antagonists. + populate_antag_type_list() + // todo: refactor - Set up spawn points. + populate_spawn_points() + + // finalize + // todo: refactor + repopulate_sorted_areas() + + return ..() + +/datum/controller/subsystem/mapping/Recover() + . = ..() + reservation_blocking_op = FALSE + +/datum/controller/subsystem/mapping/Shutdown() + . = ..() + write_next_map() + +/datum/controller/subsystem/mapping/on_max_z_changed(old_z_count, new_z_count) + . = ..() + if(length(reservation_spatial_lookups) < new_z_count) + reservation_spatial_lookups.len = new_z_count + // just to make sure order of ops / assumptions are right + ASSERT(length(ordered_levels) == world.maxz) + +//! Legacy Below !// + +// +// Mapping subsystem handles initialization of random map elements at server start +// For us that means loading our random roundstart engine! +// +/datum/controller/subsystem/mapping + var/list/map_templates = list() + var/list/shelter_templates = list() + +/datum/controller/subsystem/mapping/Recover() + . = ..() + subsystem_flags |= SS_NO_INIT // Make extra sure we don't initialize twice. + shelter_templates = SSmapping.shelter_templates + +/datum/controller/subsystem/mapping/proc/load_map_templates() + for(var/T in subtypesof(/datum/map_template)) + var/datum/map_template/template = T + template = new T + if(!template.map_path) + qdel(template) + continue + map_templates[template.name] = template + return TRUE + +/datum/controller/subsystem/mapping/proc/preloadShelterTemplates() + for(var/item in subtypesof(/datum/map_template/shelter)) + var/datum/map_template/shelter/shelter_type = item + if(!(initial(shelter_type.map_path))) + continue + var/datum/map_template/shelter/S = new shelter_type() + + shelter_templates[S.shelter_id] = S diff --git a/code/controllers/subsystem/mapping/spatial_helpers/stack.dm b/code/controllers/subsystem/mapping/spatial/mapping-spatial-stack.dm similarity index 100% rename from code/controllers/subsystem/mapping/spatial_helpers/stack.dm rename to code/controllers/subsystem/mapping/spatial/mapping-spatial-stack.dm diff --git a/code/controllers/subsystem/mapping/spatial_helpers/angle.dm b/code/controllers/subsystem/mapping/virtual/mapping-virtual-angle.dm similarity index 100% rename from code/controllers/subsystem/mapping/spatial_helpers/angle.dm rename to code/controllers/subsystem/mapping/virtual/mapping-virtual-angle.dm diff --git a/code/controllers/subsystem/mapping/spatial_helpers/loc.dm b/code/controllers/subsystem/mapping/virtual/mapping-virtual-coords.dm similarity index 100% rename from code/controllers/subsystem/mapping/spatial_helpers/loc.dm rename to code/controllers/subsystem/mapping/virtual/mapping-virtual-coords.dm diff --git a/code/controllers/subsystem/mapping/spatial_helpers/dir.dm b/code/controllers/subsystem/mapping/virtual/mapping-virtual-dir.dm similarity index 100% rename from code/controllers/subsystem/mapping/spatial_helpers/dir.dm rename to code/controllers/subsystem/mapping/virtual/mapping-virtual-dir.dm diff --git a/code/controllers/subsystem/mapping/spatial_helpers/step.dm b/code/controllers/subsystem/mapping/virtual/mapping-virtual-step.dm similarity index 100% rename from code/controllers/subsystem/mapping/spatial_helpers/step.dm rename to code/controllers/subsystem/mapping/virtual/mapping-virtual-step.dm diff --git a/code/controllers/subsystem/mapping/spatial_helpers/distance.dm b/code/controllers/subsystem/mapping/virtual/mapping-vritual-dist.dm similarity index 100% rename from code/controllers/subsystem/mapping/spatial_helpers/distance.dm rename to code/controllers/subsystem/mapping/virtual/mapping-vritual-dist.dm diff --git a/code/game/landmarks/landmarks.dm b/code/game/landmarks/landmarks.dm index 196b835db416..3397bf26def5 100644 --- a/code/game/landmarks/landmarks.dm +++ b/code/game/landmarks/landmarks.dm @@ -77,10 +77,6 @@ INITIALIZE_IMMEDIATE(/obj/landmark) tdomeadmin += loc if("tdomeobserve") tdomeobserve += loc - if("prisonsecuritywarp") - prisonsecuritywarp += loc - delete_on_roundstart = 1 - return if("blobstart") blobstart += loc delete_on_roundstart = 1 diff --git a/code/modules/admin/admin_modal.dm b/code/modules/admin/admin_modal.dm index ac6584d6760d..3f0f80bdf3fc 100644 --- a/code/modules/admin/admin_modal.dm +++ b/code/modules/admin/admin_modal.dm @@ -5,3 +5,6 @@ * Base type of admin modals, which tend to be standalone panels. */ /datum/admin_modal + /// TGUI ID + var/tgui_interface +#warn impl diff --git a/code/modules/admin/modals/upload_map_sector.dm b/code/modules/admin/modals/upload_map_sector.dm new file mode 100644 index 000000000000..99ad9f582db2 --- /dev/null +++ b/code/modules/admin/modals/upload_map_sector.dm @@ -0,0 +1,36 @@ +//* This file is explicitly licensed under the MIT license. *// +//* Copyright (c) 2024 Citadel Station Developers *// + +/** + * Modal supporting arbitrary map uploads. + * + * * Does not support shuttles. You must upload shuttles separately! + */ +/datum/admin_modal/upload_map_sector + #warn write modal + tgui_interface = "AdminModalUploadMapSector" + + //* constraints *// + + /// in bytes + var/max_upload_size = 1024 * 1024 * 10 + /// in levels + var/max_upload_levels = 9 + + //* buffer *// + + /// in bytes + var/current_upload_size = 0 + /// in levels + var/current_upload_levels = 0 + + /// current max size + var/current_max_x = 0 + /// current max size + var/current_max_y = 0 + + /// map level's + var/list/datum/map_level/level_buffers + +#warn impl + diff --git a/code/modules/mapping/map.dm b/code/modules/mapping/map.dm index b0a72057a60d..b88cc8136e70 100644 --- a/code/modules/mapping/map.dm +++ b/code/modules/mapping/map.dm @@ -373,11 +373,6 @@ /datum/map/station/proc/get_network_access(var/network) return 0 -// By default transition randomly to another zlevel -/datum/map/station/proc/get_transit_zlevel(current_z_level) - . = SSmapping.crosslinked_levels() - current_z_level - return SAFEPICK(.) - /datum/map/station/proc/get_empty_zlevel() if(empty_levels == null) var/datum/map_level/level = SSmapping.allocate_level() @@ -400,12 +395,14 @@ // Just the sector we're in if(!long_range || (om_range < 0)) - return O.map_z.Copy() + return O.location?.get_z_indices() || list() // Otherwise every sector we're on top of var/list/connections = list() for(var/obj/overmap/entity/visitable/V in bounds(O, om_range)) - connections |= V.map_z // Adding list to list adds contents + var/list/levels = V.location?.get_z_indices() + if(levels) + connections |= levels return connections // Traditional behavior diff --git a/code/modules/mapping/map_level.dm b/code/modules/mapping/map_level.dm index f3022142efc3..db7c012ba5e3 100644 --- a/code/modules/mapping/map_level.dm +++ b/code/modules/mapping/map_level.dm @@ -141,6 +141,7 @@ /// * the indices are zlevel, with the 'center ground floor' being list(0, 0, 0) /// * all levels on a map must have this specified if the map is going to build a struct. var/struct_create_pos + #warn hook //* Virtual Coordinates *// /// the coordinate of the lower-left / southwest corner border of the map diff --git a/code/modules/mapping/map_struct.dm b/code/modules/mapping/map_struct.dm index 4300d19e22e1..95605c4ca064 100644 --- a/code/modules/mapping/map_struct.dm +++ b/code/modules/mapping/map_struct.dm @@ -80,28 +80,28 @@ var/had_vertical = FALSE var/had_horizontal = FALSE - other = z_grid["[level.x+1],[level.y],[level.z]"] + other = z_grid["[level.struct_x+1],[level.struct_y],[level.struct_z]"] if(other) level.link_east = other had_horizontal = TRUE - other = z_grid["[level.x-1],[level.y],[level.z]"] + other = z_grid["[level.struct_x-1],[level.struct_y],[level.struct_z]"] if(other) level.link_west = other had_horizontal = TRUE - other = z_grid["[level.x],[level.y+1],[level.z]"] + other = z_grid["[level.struct_x],[level.struct_y+1],[level.struct_z]"] if(other) level.link_north = other had_horizontal = TRUE - other = z_grid["[level.x],[level.y-1],[level.z]"] + other = z_grid["[level.struct_x],[level.struct_y-1],[level.struct_z]"] if(other) level.link_south = other had_horizontal = TRUE - other = z_grid["[level.x],[level.y],[level.z+1]"] + other = z_grid["[level.struct_x],[level.struct_y],[level.struct_z+1]"] if(other) level.link_above = other had_vertical = TRUE - other = z_grid["[level.x],[level.y],[level.z-1]"] + other = z_grid["[level.struct_x],[level.struct_y],[level.struct_z-1]"] if(other) level.link_below = other had_vertical = TRUE @@ -182,6 +182,8 @@ CRASH("FATAL: duplicate level") if(!resolved.loaded) CRASH("FATAL: attempted to include an unloaded level in a struct. structs do not currently support lazy-loading.") + if(resolved.struct) + CRASH("FATAL: level already had struct") // add to levels list levels += resolved @@ -264,75 +266,6 @@ constructed = FALSE -#warn below - -#warn parse this file - -/datum/map_struct/proc/Register(rebuild = TRUE) - SSmapping.structs += src - SSmapping.z_stack_dirty = TRUE - if(rebuild) - SSmapping.rebuild_struct_lookup() - SSmapping.rebuild_verticality() - SSmapping.rebuild_transitions() - SSmapping.RebuildCrosslinking() - -/datum/map_struct/proc/Unregister(rebuild = TRUE) - SSmapping.structs -= src - SSmapping.z_stack_dirty = TRUE - if(rebuild) - SSmapping.rebuild_struct_lookup() - SSmapping.rebuild_verticality() - SSmapping.rebuild_transitions() - SSmapping.RebuildCrosslinking() - -/** - * Ensures all level IDs exist as currently instantiated levels, - * and also ensures there's no dupe keys/IDs - */ -/datum/map_struct/proc/Verify() - . = TRUE - var/list/keymap = list() - var/list/idmap = list() - for(var/key in z_grid) - if(keymap[key]) - stack_trace("Duplicate key [key].") - . = FALSE - keymap[key] = TRUE - grid_parser.Find(key) - if(key != "[grid_parser.group[1]],[grid_parser.group[2]],[grid_parser.group[3]]") - stack_trace("Invalid key [key].") - . = FALSE - var/id = z_grid[key] - if(!SSmapping.keyed_levels[id]) - stack_trace("Couldn't locate level id [id] in SSmapping keyed_levels list.") - . = FALSE - if(SSmapping.keyed_levels[id].struct) - stack_trace("Level id [id] was already in a struct.") - . = FALSE - if(idmap[id]) - stack_trace("Duplicate level ID [id]") - . = FALSE - idmap[id] = TRUE - -#warn above - -//* Z-Access *// - -/** - * returns mutable copy of real_indices - */ -/datum/map_struct/proc/mutable_z_list() - return z_indices.Copy() - -/** - * directly fetches real indices - * - * * Do not modify returned list. - */ -/datum/map_struct/proc/immutable_z_list() - return z_indices - //* Helpers *// /proc/cmp_map_level_struct_z(datum/map_level/A, datum/map_level/B) diff --git a/code/modules/overmap/entity/entity-location.dm b/code/modules/overmap/entity/entity-location.dm index a0d99d783d8c..e9f6b7024db3 100644 --- a/code/modules/overmap/entity/entity-location.dm +++ b/code/modules/overmap/entity/entity-location.dm @@ -2,22 +2,23 @@ //* Copyright (c) 2024 Citadel Station Developers *// /** - * get z-level indices in this entity + * get our z-level indices * * * entities that are on z's like shuttles instead of owning them use the z level they're on * - * @return null if there are none / this is not semantically an entity on a z + * @return null if there are none / this is not semantically an entity on a z, and list() if we're not in a level right now. */ /obj/overmap/entity/proc/get_z_indices() RETURN_TYPE(/list) return location?.get_z_indices() /** - * get a random z-level in this entity + * get our owned z-level indices * - * * entities that are on z's like shuttles instead of owning them use the z level they're on + * * shuttles and similar entities don't own their indices. * - * @return null if there are none / this is not semantically an entity on a z + * @return null if this is not semantically an entity on a z, and list() if none are owned, otherwise */ -/obj/overmap/entity/proc/get_random_z_index() - return location?.get_random_z_index() +/obj/overmap/entity/proc/get_owned_z_indices() + RETURN_TYPE(/list) + return location?.get_owned_z_indices() diff --git a/code/modules/overmap/entity/entity-physics.dm b/code/modules/overmap/entity/entity-physics.dm index bbea3c084f0b..509cfdfba155 100644 --- a/code/modules/overmap/entity/entity-physics.dm +++ b/code/modules/overmap/entity/entity-physics.dm @@ -51,8 +51,8 @@ vel_y += vy var/interpolate_limiter - if((interpolate_limiter = OVERMAP_DIST_TO_PIXEL(sqrt(vel_x ** 2 + vel_y ** 2))) > SSovermaps_physics.global_interpolate_limit) - interpolate_limiter = SSovermaps_physics.global_interpolate_limit / interpolate_limiter + if((interpolate_limiter = OVERMAP_DIST_TO_PIXEL(sqrt(vel_x ** 2 + vel_y ** 2))) > SSovermap_physics.global_interpolate_limit) + interpolate_limiter = SSovermap_physics.global_interpolate_limit / interpolate_limiter vel_x *= interpolate_limiter vel_y *= interpolate_limiter diff --git a/code/modules/overmap/entity/overmap_location.dm b/code/modules/overmap/entity/overmap_location.dm index 002458381c51..a83029ba4ffc 100644 --- a/code/modules/overmap/entity/overmap_location.dm +++ b/code/modules/overmap/entity/overmap_location.dm @@ -9,6 +9,8 @@ * Descriptive, I know. */ /datum/overmap_location + /// owning entity, if any + var/obj/overmap/entity/entity /** * get our z-level indices @@ -25,9 +27,9 @@ * * * shuttles and similar entities don't own their indices. * - * @return null if this is not semantically an entity on a z, and list() if none are owned, otherwise + * @return null if this is not semantically an entity on a z, and list() if none are owned, otherwise */ -/datum/overmap_location/proc/get_z_indices() +/datum/overmap_location/proc/get_owned_z_indices() RETURN_TYPE(/list) #warn impl diff --git a/maps/stations/rift/sectors/lythios_43c.dm b/maps/stations/rift/sectors/lythios_43c.dm index b8faffaeedda..5a6adb9ee8be 100644 --- a/maps/stations/rift/sectors/lythios_43c.dm +++ b/maps/stations/rift/sectors/lythios_43c.dm @@ -28,14 +28,7 @@ "NDV Quicksilver" = list("rift_specops_dock"), "Pirate Skiff" = list("rift_pirate_dock"), ) - - extra_z_levels = list( - /datum/map_level/rift/plains, - /datum/map_level/rift/caves, - /datum/map_level/rift/deep, - /datum/map_level/rift/base, - ) - + /obj/overmap/entity/visitable/sector/lythios43c/Crossed(var/atom/movable/AM) . = ..() announce_atc(AM,going = FALSE) diff --git a/maps/tether/sectors.dm b/maps/tether/sectors.dm index 08cafb27a5bc..278de42f4ef6 100644 --- a/maps/tether/sectors.dm +++ b/maps/tether/sectors.dm @@ -34,11 +34,6 @@ ) /obj/overmap/entity/visitable/sector/virgo3b - extra_z_levels = list( - /datum/map_level/tether/mine, - /datum/map_level/tether/plains, - /datum/map_level/tether/underdark, - ) in_space = FALSE var/list/snowflake_space_levels = list(