From b0cec39d840d66a4d51e90258a07f5ab4506d7a5 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sun, 14 Jul 2024 20:20:27 -0400
Subject: [PATCH] overmaps 1 - generation & spatial (#6550)
here we go gamers
---
citadel.dme | 7 +-
.../controllers/subsystem/mapping/_mapping.dm | 4 -
.../subsystem/mapping/obfuscation.dm | 3 +
code/controllers/subsystem/overmap.dm | 122 ++++++++++++-
code/controllers/subsystem/spatial_grids.dm | 5 +-
.../components/turfs/reservation_border.dm | 1 +
code/game/atoms/movable/movable.dm | 46 -----
code/game/gamemodes/events/dust.dm | 3 -
code/game/machinery/nuclear_bomb.dm | 3 -
code/game/mecha/combat/fighter.dm | 71 --------
code/game/turfs/space/space.dm | 21 ---
code/modules/admin/admin_verbs.dm | 1 +
code/modules/mapping/map.dm | 1 -
code/modules/mapping/turf_reservation.dm | 64 +++++--
code/modules/media/mediamanager.dm | 3 +-
code/modules/overmap/entity/entity.dm | 30 +++-
code/modules/overmap/entity/physics.dm | 52 +++++-
code/modules/overmap/events/event_handler.dm | 60 -------
code/modules/overmap/legacy/sectors.dm | 79 ++++-----
.../overmap/legacy/ships/computers/helm.dm | 18 +-
code/modules/overmap/legacy/spacetravel.dm | 157 -----------------
code/modules/overmap/map/area.dm | 34 +++-
code/modules/overmap/map/overmap.dm | 94 ++++++++++
code/modules/overmap/map/overmap_template.dm | 67 +++++++
.../overmap/map/overmap_template_layer.dm | 17 ++
.../map/template_layers/legacy_events.dm | 78 +++++++++
code/modules/overmap/map/turf.dm | 165 +++++++++++-------
code/modules/overmap/{map => }/object.dm | 0
code/modules/power/supermatter/supermatter.dm | 10 --
code/modules/tgui/modules/overmap.dm | 16 +-
.../{numbers.dmi => numbers_unused.dmi} | Bin
icons/modules/overmap/area.dmi | Bin 0 -> 229 bytes
icons/modules/overmap/turf.dmi | Bin 0 -> 1199 bytes
33 files changed, 707 insertions(+), 525 deletions(-)
delete mode 100644 code/modules/overmap/legacy/spacetravel.dm
create mode 100644 code/modules/overmap/map/overmap.dm
create mode 100644 code/modules/overmap/map/overmap_template.dm
create mode 100644 code/modules/overmap/map/overmap_template_layer.dm
create mode 100644 code/modules/overmap/map/template_layers/legacy_events.dm
rename code/modules/overmap/{map => }/object.dm (100%)
rename icons/effects/{numbers.dmi => numbers_unused.dmi} (100%)
create mode 100644 icons/modules/overmap/area.dmi
create mode 100644 icons/modules/overmap/turf.dmi
diff --git a/citadel.dme b/citadel.dme
index 6add89d2cc5..6ad6d866c6f 100644
--- a/citadel.dme
+++ b/citadel.dme
@@ -4172,6 +4172,7 @@
#include "code\modules\organs\subtypes\nano.dm"
#include "code\modules\organs\subtypes\unbreakable.dm"
#include "code\modules\organs\subtypes\unseverable.dm"
+#include "code\modules\overmap\object.dm"
#include "code\modules\overmap\public.dm"
#include "code\modules\overmap\entity\entity.dm"
#include "code\modules\overmap\entity\physics.dm"
@@ -4186,7 +4187,6 @@
#include "code\modules\overmap\legacy\overmap_planet.dm"
#include "code\modules\overmap\legacy\overmap_shuttle.dm"
#include "code\modules\overmap\legacy\sectors.dm"
-#include "code\modules\overmap\legacy\spacetravel.dm"
#include "code\modules\overmap\legacy\disperser\disperser.dm"
#include "code\modules\overmap\legacy\disperser\disperser_charge.dm"
#include "code\modules\overmap\legacy\disperser\disperser_circuit.dm"
@@ -4206,8 +4206,11 @@
#include "code\modules\overmap\legacy\ships\engines\gas_thruster_vr.dm"
#include "code\modules\overmap\legacy\ships\engines\ion_thruster.dm"
#include "code\modules\overmap\map\area.dm"
-#include "code\modules\overmap\map\object.dm"
+#include "code\modules\overmap\map\overmap.dm"
+#include "code\modules\overmap\map\overmap_template.dm"
+#include "code\modules\overmap\map\overmap_template_layer.dm"
#include "code\modules\overmap\map\turf.dm"
+#include "code\modules\overmap\map\template_layers\legacy_events.dm"
#include "code\modules\overmap\tiled\tiled.dm"
#include "code\modules\paperwork\adminpaper.dm"
#include "code\modules\paperwork\carbonpaper.dm"
diff --git a/code/controllers/subsystem/mapping/_mapping.dm b/code/controllers/subsystem/mapping/_mapping.dm
index c6cbd9b305f..eabccb9b489 100644
--- a/code/controllers/subsystem/mapping/_mapping.dm
+++ b/code/controllers/subsystem/mapping/_mapping.dm
@@ -35,10 +35,6 @@ SUBSYSTEM_DEF(mapping)
// load world - this also initializes our first reserved level, which is compiled in.
load_station()
- // perform snowflake legacy init stuff
- // todo: refactor
- if(!(LEGACY_MAP_DATUM).overmap_z)
- build_overmap()
// todo: refactor - Set up antagonists.
populate_antag_type_list()
// todo: refactor - Set up spawn points.
diff --git a/code/controllers/subsystem/mapping/obfuscation.dm b/code/controllers/subsystem/mapping/obfuscation.dm
index 84117b1bc8b..192d67ada01 100644
--- a/code/controllers/subsystem/mapping/obfuscation.dm
+++ b/code/controllers/subsystem/mapping/obfuscation.dm
@@ -4,6 +4,8 @@
/**
* Obfuscation module
*
+ * todo: should this be mapping? this is a lot more important than just mapping
+ *
* * Generates **mangled** IDs; these are either persistently-unique or round-local IDs that are separate per map / map template.
* * Generates **obfuscated** IDs; these are mangled and obfuscated IDs that are safe to reveal to players.
*
@@ -14,6 +16,7 @@
*/
/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()
diff --git a/code/controllers/subsystem/overmap.dm b/code/controllers/subsystem/overmap.dm
index 63ef976132b..6a49061cc46 100644
--- a/code/controllers/subsystem/overmap.dm
+++ b/code/controllers/subsystem/overmap.dm
@@ -3,12 +3,21 @@ SUBSYSTEM_DEF(overmaps)
subsystem_flags = SS_NO_FIRE
init_order = INIT_ORDER_OVERMAPS
+ /// overmap by id
+ // todo: recover
+ var/static/list/datum/overmap/overmap_by_id = list()
+
+ /// im so sorry bros dont hurt me please--
+ /// (eventually we'll have proper bindings but for now, uh, this is how it is!)
+ var/const/default_overmap_id = "main"
+
/datum/controller/subsystem/overmaps/Initialize()
- if((LEGACY_MAP_DATUM).use_overmap)
- GLOB.overmap_event_handler.create_events((LEGACY_MAP_DATUM).overmap_z, (LEGACY_MAP_DATUM).overmap_size, (LEGACY_MAP_DATUM).overmap_event_areas)
+ make_default_overmap()
rebuild_helm_computers()
return ..()
+//! legacy code below
+
/datum/controller/subsystem/overmaps/proc/rebuild_helm_computers()
for(var/obj/machinery/computer/ship/helm/H in GLOB.machines)
H.get_known_sectors()
@@ -17,3 +26,112 @@ SUBSYSTEM_DEF(overmaps)
if(!initialized)
return
addtimer(CALLBACK(src, PROC_REF(rebuild_helm_computers)), 0, TIMER_UNIQUE)
+
+/*
+/client/proc/overmap_upload()
+ set name = "Instantiate Overmap"
+ set category = "Debug"
+
+ var/are_you_sure = alert(
+ src,
+ "Instantiating overmaps is an advanced feature. \
+ The uploaded file is placed and instantiated as an overmap; only overmap tiles, overmap entities, and overmap tile entities \
+ should exist in the file, or you may have funny things happen and the server explode. \
+ Are you sure you know what you are doing?",
+ "Upload Overmap",
+ "No",
+ "Yes",
+ )
+ if(are_you_sure != "Yes")
+ return
+
+ var/map = input(src, "Select overmap .dmm", "Instantiate Overmap") as file|null
+ if(!map)
+ return
+
+ var/datum/dmm_parsed/parsed_map = parse_map(map)
+
+ if(!parsed_map.parsed)
+ alert(src, "Failed to parse map.", "Parse Error")
+ return
+
+ var/max_x = world.maxx - TURF_CHUNK_RESOLUTION * 2
+ var/max_y = world.maxy - TURF_CHUNK_RESOLUTION * 2
+
+ if(parsed_map.width >= max_x || parsed_map.height >= max_y)
+ alert(src, "Your map is too big for the current world size. Maximum: [max_x]x[max_y]", "Improper Dimensions")
+ return
+
+ // welcome to hell
+ // allocate turf reservation and load at offset
+ // from this point on, if we crash, we don't warn the user, because it shouldn't be possible to crash
+ var/datum/overmap_template/template = new
+ template.width = parsed_map.width
+ template.height = parsed_map.height
+ var/datum/overmap/creating = new("loaded-[rand(1, 1000000)]", template)
+ creating.initialize()
+ // loaded, load the map template in there
+ var/datum/dmm_context/loaded_context = parsed_map.load(
+ creating.reservation.bottom_left_coords[1],
+ creating.reservation.bottom_left_coords[2],
+ creating.reservation.bottom_left_coords[3],
+ )
+ // initialize
+ SSatoms.init_map_bounds(loaded_context)
+ var/llx = loaded_context.loaded_bounds[MAP_MINX]
+ var/lly = loaded_context.loaded_bounds[MAP_MINY]
+ var/llz = loaded_context.loaded_bounds[MAP_MINZ]
+ // announce
+ log_and_message_admins("overmap [creating.id] with dimensions [creating.width]x[creating.height] loaded at LL-bounds [llx], [lly], [llz]")
+*/
+
+//! end
+
+//* Overmap Management *//
+
+/**
+ * i don't know what to put here
+ * this isn't a good long-term proc but for now it's fine
+ */
+/datum/controller/subsystem/overmaps/proc/get_or_load_default_overmap()
+ if(overmap_by_id[default_overmap_id])
+ return overmap_by_id[default_overmap_id]
+ make_default_overmap()
+ return overmap_by_id[default_overmap_id]
+
+
+/datum/controller/subsystem/overmaps/proc/make_default_overmap()
+ if(overmap_by_id[default_overmap_id])
+ return
+ var/datum/map/station/map_datum = SSmapping.loaded_station
+ if(!map_datum.use_overmap)
+ return
+ var/datum/overmap_template/legacy_default/using_default_template = new(map_datum.overmap_size, map_datum.overmap_size, event_clouds = map_datum.overmap_event_areas)
+ create_overmap_from_template(using_default_template, default_overmap_id)
+
+/datum/controller/subsystem/overmaps/proc/create_overmap_from_template(datum/overmap_template/templatelike, use_id)
+ if(ispath(templatelike))
+ templatelike = new templatelike
+ // make sure template is valid
+ ASSERT(istype(templatelike))
+ // get template into another var
+ var/datum/overmap_template/template = templatelike
+ // get id or generate
+ var/id = use_id || generate_overmap_id()
+ ASSERT(!overmap_by_id[id])
+ // make overmap
+ var/datum/overmap/creating = new(id, template)
+ // instantiation
+ creating.initialize()
+ // done
+ return creating
+
+/datum/controller/subsystem/overmaps/proc/generate_overmap_id()
+ var/potential
+ var/safety = 1000
+ do
+ if(safety-- <= 0)
+ CRASH("failed to generate overmap id - too many loops")
+ potential = "[SSmapping.round_global_descriptor && "[SSmapping.round_global_descriptor]-"][copytext(md5("[rand(1, 1000000)]"), 1, 5)]"
+ while(overmap_by_id[potential])
+ return potential
diff --git a/code/controllers/subsystem/spatial_grids.dm b/code/controllers/subsystem/spatial_grids.dm
index 89793acb3e4..660724af43e 100644
--- a/code/controllers/subsystem/spatial_grids.dm
+++ b/code/controllers/subsystem/spatial_grids.dm
@@ -12,13 +12,16 @@ SUBSYSTEM_DEF(spatial_grids)
/// /living mobs. they don't have to be alive, just a subtype of /living.
var/datum/spatial_grid/living
+ /// /obj/overmap/entity's
+ var/datum/spatial_grid/overmap_entities
/datum/controller/subsystem/spatial_grids/Initialize()
make_grids()
return ..()
/datum/controller/subsystem/spatial_grids/proc/make_grids()
- living = new /datum/spatial_grid(/mob/living, 16)
+ living = new /datum/spatial_grid(/mob/living)
+ overmap_entities = new /datum/spatial_grid(/obj/overmap/entity)
/datum/controller/subsystem/spatial_grids/on_max_z_changed(old_z_count, new_z_count)
. = ..()
diff --git a/code/datums/components/turfs/reservation_border.dm b/code/datums/components/turfs/reservation_border.dm
index 5132dc924c5..e0c45e377b1 100644
--- a/code/datums/components/turfs/reservation_border.dm
+++ b/code/datums/components/turfs/reservation_border.dm
@@ -8,6 +8,7 @@
* todo: allow simulation of specific atmos instead of just RESERVED_TURF_TYPe
*/
/datum/component/reservation_border
+ can_transfer = TRUE
var/atom/movable/mirage_border/holder1
var/atom/movable/mirage_border/holder2
var/atom/movable/mirage_border/holder3
diff --git a/code/game/atoms/movable/movable.dm b/code/game/atoms/movable/movable.dm
index ef9da3be942..8efb1632f1e 100644
--- a/code/game/atoms/movable/movable.dm
+++ b/code/game/atoms/movable/movable.dm
@@ -231,52 +231,6 @@
if(mover.loc in locs)
. = TRUE
-/atom/movable/proc/touch_map_edge()
- if(z in (LEGACY_MAP_DATUM).sealed_levels)
- return
-
- if((LEGACY_MAP_DATUM).use_overmap)
- overmap_spacetravel(get_turf(src), src)
- return
-
- var/move_to_z = src.get_transit_zlevel()
- if(move_to_z)
- var/new_z = move_to_z
- var/new_x
- var/new_y
-
- if(x <= TRANSITIONEDGE)
- new_x = world.maxx - TRANSITIONEDGE - 2
- new_y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
-
- else if (x >= (world.maxx - TRANSITIONEDGE + 1))
- new_x = TRANSITIONEDGE + 1
- new_y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
-
- else if (y <= TRANSITIONEDGE)
- new_y = world.maxy - TRANSITIONEDGE -2
- new_x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
-
- else if (y >= (world.maxy - TRANSITIONEDGE + 1))
- new_y = TRANSITIONEDGE + 1
- new_x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
-
- if(SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) // Only really care if the game mode is nuclear
- var/datum/game_mode/nuclear/G = SSticker.mode
- G.check_nuke_disks()
-
- var/turf/T = locate(new_x, new_y, new_z)
- if(istype(T))
- forceMove(T)
-
-//by default, transition randomly to another zlevel
-/atom/movable/proc/get_transit_zlevel()
- var/list/candidates = SSmapping.crosslinked_levels()
- candidates -= z
- if(!length(candidates))
- return
- return pick(candidates)
-
// Returns the current scaling of the sprite.
// Note this DOES NOT measure the height or width of the icon, but returns what number is being multiplied with to scale the icons, if any.
/atom/movable/proc/get_icon_scale_x()
diff --git a/code/game/gamemodes/events/dust.dm b/code/game/gamemodes/events/dust.dm
index 4cc3660bdef..0b6aa3cb0e1 100644
--- a/code/game/gamemodes/events/dust.dm
+++ b/code/game/gamemodes/events/dust.dm
@@ -84,9 +84,6 @@ The "dust" will damage the hull of the station causin minor hull breaches.
walk(src, 0) // Because we might have called walk_towards, we must stop the walk loop or BYOND keeps an internal reference to us forever.
return ..()
-/obj/effect/space_dust/touch_map_edge()
- qdel(src)
-
/obj/effect/space_dust/Bump(atom/A)
. = ..()
hit(A)
diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm
index 2cd56489cbd..d7f7a571d1d 100644
--- a/code/game/machinery/nuclear_bomb.dm
+++ b/code/game/machinery/nuclear_bomb.dm
@@ -423,6 +423,3 @@ var/bomb_set
log_game("[src], the last authentication disk, has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).")
nuke_disks -= src
return ..()
-
-/obj/item/disk/nuclear/touch_map_edge()
- qdel(src)
diff --git a/code/game/mecha/combat/fighter.dm b/code/game/mecha/combat/fighter.dm
index 8080722b351..dcfe0d5392d 100644
--- a/code/game/mecha/combat/fighter.dm
+++ b/code/game/mecha/combat/fighter.dm
@@ -61,77 +61,6 @@
. = ..()
consider_gravity()
-//We don't get lost quite as easy.
-/obj/mecha/combat/fighter/touch_map_edge()
- //No overmap enabled or no driver to choose
- if(!(LEGACY_MAP_DATUM).use_overmap || !occupant || !can_ztravel())
- return ..()
-
- var/obj/overmap/entity/visitable/our_ship = get_overmap_sector(z)
-
- //We're not on the overmap
- if(!our_ship)
- return ..()
-
- //Stored for safety checking after user input
- var/this_x = x
- var/this_y = y
- var/this_z = z
- var/this_occupant = occupant
-
- var/what_edge
-
- var/new_x
- var/new_y
- var/new_z
-
- if(x <= TRANSITIONEDGE)
- what_edge = WEST
- new_x = world.maxx - TRANSITIONEDGE - 2
- new_y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
-
- else if (x >= (world.maxx - TRANSITIONEDGE + 1))
- what_edge = EAST
- new_x = TRANSITIONEDGE + 1
- new_y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
-
- else if (y <= TRANSITIONEDGE)
- what_edge = SOUTH
- new_y = world.maxy - TRANSITIONEDGE -2
- new_x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
-
- else if (y >= (world.maxy - TRANSITIONEDGE + 1))
- what_edge = NORTH
- new_y = TRANSITIONEDGE + 1
- new_x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
-
- var/list/choices = list()
- for(var/obj/overmap/entity/visitable/V in range(1, our_ship))
- choices[V.name] = V
-
- var/choice = input("Choose an overmap destination:", "Destination", null) as null|anything in choices
- if(!choice)
- var/backwards = turn(what_edge, 180)
- forceMove(get_step(src,backwards)) //Move them back a step, then.
- setDir(backwards)
- return
- else
- var/obj/overmap/entity/visitable/V = choices[choice]
- if(occupant != this_occupant || this_x != x || this_y != y || this_z != z || get_dist(V,our_ship) > 1) //Sanity after user input
- to_chat(occupant, "You or they appear to have moved!")
- return
- var/list/levels = V.get_space_zlevels()
- if(!levels.len)
- to_chat(occupant, "You don't appear to be able to get there from here!")
- return
- new_z = pick(levels)
- var/turf/destination = locate(new_x, new_y, new_z)
- if(!destination || destination.density)
- to_chat(occupant, "You don't appear to be able to get there from here! Is it blocked?")
- return
- else
- forceMove(destination)
-
//Modified phazon code
/obj/mecha/combat/fighter/Topic(href, href_list)
..()
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index 88fa14d618b..1b2459a30cb 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -36,17 +36,6 @@
// we have parallax and don't need this anymore
// icon_state = SPACE_ICON_STATE(x, y, z)
- // We might be an edge
- if(y == world.maxy || forced_dirs & NORTH)
- edge |= NORTH
- else if(y == 1 || forced_dirs & SOUTH)
- edge |= SOUTH
-
- if(x == 1 || forced_dirs & WEST)
- edge |= WEST
- else if(x == world.maxx || forced_dirs & EAST)
- edge |= EAST
-
if (CONFIG_GET(flag/starlight))
update_starlight()
@@ -163,16 +152,6 @@
// If that's changed, then you'll want to swipe the rest of the roofing code from code/game/turfs/simulated/floor_attackby.dm
return
-/turf/space/Entered(var/atom/movable/A)
- . = ..()
-
- if(edge)
- addtimer(CALLBACK(src, PROC_REF(on_atom_edge_touch), A), 0)
-
-/turf/space/proc/on_atom_edge_touch(atom/movable/AM)
- if(!QDELETED(AM) && (AM.loc == src))
- AM.touch_map_edge()
-
//// Special variants used in various maps ////
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index cb878a2e71b..363d9c100b0 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -155,6 +155,7 @@ var/list/admin_verbs_spawn = list(
/client/proc/virus2_editor,
/client/proc/map_template_load,
/client/proc/map_template_upload,
+ // /client/proc/overmap_upload,
/client/proc/map_template_load_on_new_z
)
diff --git a/code/modules/mapping/map.dm b/code/modules/mapping/map.dm
index 256ef2e647e..4d0afdb101a 100644
--- a/code/modules/mapping/map.dm
+++ b/code/modules/mapping/map.dm
@@ -252,7 +252,6 @@
var/use_overmap = 0 // If overmap should be used (including overmap space travel override)
var/overmap_size = 20 // Dimensions of overmap zlevel if overmap is used.
- var/overmap_z = 0 // If 0 will generate overmap zlevel on init. Otherwise will populate the zlevel provided.
var/overmap_event_areas = 0 // How many event "clouds" will be generated
/// list of title cutscreens by path to display. for legacy support, tuples of list(icon, state) work too. associate to % chance, defaulting to 1.
diff --git a/code/modules/mapping/turf_reservation.dm b/code/modules/mapping/turf_reservation.dm
index cf626310bad..5404480cfd0 100644
--- a/code/modules/mapping/turf_reservation.dm
+++ b/code/modules/mapping/turf_reservation.dm
@@ -10,9 +10,12 @@
/datum/turf_reservation
/// are we allocated?
var/tmp/allocated = FALSE
- /// reserved turfs - set when allocated
- var/list/turf/reserved_turfs
/// border turfs - just the first layer / the immediate border
+ ///
+ /// todo: this shouldn't be a var, make it a proc
+ ///
+ /// * does not include the rest of the border
+ /// * you shouldn't need to initialize more than one layer of turfs.
var/list/turf/border_turfs
/// width
@@ -33,6 +36,7 @@
/// callback to use when something crosses border
///
+ /// * called with (turf/border)
/// * only used if border is custom-initalized, otherwise we use selflooping transition borders
/// * specifying this makes us put a reservation border component on the turfs as needed.
var/datum/callback/border_handler
@@ -40,6 +44,7 @@
var/border_mirage_anyways = FALSE
/// border initializer to call with every turf on the border to init them
///
+ /// * called with (turf/border, datum/turf_reservation/reservation)
/// * if border is specified but initializer isn't, we just make them transition borders.
var/datum/callback/border_initializer
@@ -50,6 +55,8 @@
/// our border area instance if needed
var/area/reservation_border/border_area
+ /// our area instance
+ var/area/reservation_area
//* spatial lookup *//
var/spatial_bl_x
@@ -81,7 +88,6 @@
), locate(
top_right_coords[1], top_right_coords[2], top_right_coords[3])
))
- reserved_turfs = null
allocated = FALSE
if(border_area)
QDEL_NULL(border_area)
@@ -100,6 +106,10 @@
spatial_bl_x = spatial_tr_x = spatial_bl_y = spatial_tr_y = spatial_z = null
+ if(!reservation_area.unique)
+ qdel(reservation_area)
+ reservation_area = null
+
return TRUE
/datum/turf_reservation/proc/reserve(width, height, border, z_override)
@@ -170,7 +180,7 @@
// calculate non-bordered
BL = locate(1 + TURF_CHUNK_RESOLUTION * (outer_x - 1) + border, 1 + TURF_CHUNK_RESOLUTION * (outer_y - 1) + border, level_index)
- TR = locate(BL.x + real_width - 1 - border, BL.y + real_height - 1 - border, BL.z)
+ TR = locate(BL.x + width - 1, BL.y + height - 1, level_index)
final = block(BL, TR)
// calculate border
@@ -261,7 +271,7 @@
locate(bottom_left_coords[1] - 1, top_right_coords[2], bottom_left_coords[3]),
)
for(var/turf/T as anything in immediate_left)
- border_initializer?.Invoke(T)
+ border_initializer?.Invoke(T, src)
if(needs_component)
T.AddComponent(/datum/component/reservation_border, mirage_range, WEST, should_mirage, locate(top_right_coords[1], T.y, T.z), border_handler)
// right
@@ -270,7 +280,7 @@
locate(top_right_coords[1] + 1, top_right_coords[2], bottom_left_coords[3]),
)
for(var/turf/T as anything in immediate_right)
- border_initializer?.Invoke(T)
+ border_initializer?.Invoke(T, src)
if(needs_component)
T.AddComponent(/datum/component/reservation_border, mirage_range, EAST, should_mirage, locate(bottom_left_coords[1], T.y, T.z), border_handler)
// up
@@ -279,7 +289,7 @@
locate(top_right_coords[1], top_right_coords[2] + 1, bottom_left_coords[3]),
)
for(var/turf/T as anything in immediate_up)
- border_initializer?.Invoke(T)
+ border_initializer?.Invoke(T, src)
if(needs_component)
T.AddComponent(/datum/component/reservation_border, mirage_range, NORTH, should_mirage, locate(T.x, bottom_left_coords[2], T.z), border_handler)
// down
@@ -288,7 +298,7 @@
locate(top_right_coords[1], bottom_left_coords[2] - 1, bottom_left_coords[3]),
)
for(var/turf/T as anything in immediate_down)
- border_initializer?.Invoke(T)
+ border_initializer?.Invoke(T, src)
if(needs_component)
T.AddComponent(/datum/component/reservation_border, mirage_range, SOUTH, should_mirage, locate(T.x, top_right_coords[2], T.z), border_handler)
@@ -296,25 +306,25 @@
var/turf/corner
// top left
corner = locate(bottom_left_coords[1] - 1, top_right_coords[2] + 1, bottom_left_coords[3])
- border_initializer?.Invoke(corner)
+ border_initializer?.Invoke(corner, src)
if(needs_component)
corner.AddComponent(/datum/component/reservation_border, mirage_range, NORTHWEST, should_mirage, locate(top_right_coords[1], bottom_left_coords[2], bottom_left_coords[3]), border_handler)
immediate_corners += corner
// top right
corner = locate(top_right_coords[1] + 1, top_right_coords[2] + 1, bottom_left_coords[3])
- border_initializer?.Invoke(corner)
+ border_initializer?.Invoke(corner, src)
if(needs_component)
corner.AddComponent(/datum/component/reservation_border, mirage_range, NORTHEAST, should_mirage, locate(bottom_left_coords[1], bottom_left_coords[2], bottom_left_coords[3]), border_handler)
immediate_corners += corner
// bottom left
corner = locate(bottom_left_coords[1] - 1, bottom_left_coords[2] - 1, bottom_left_coords[3])
- border_initializer?.Invoke(corner)
+ border_initializer?.Invoke(corner, src)
if(needs_component)
corner.AddComponent(/datum/component/reservation_border, mirage_range, SOUTHWEST, should_mirage, locate(top_right_coords[1], top_right_coords[2], bottom_left_coords[3]), border_handler)
immediate_corners += corner
// bottom right
corner = locate(top_right_coords[1] + 1, bottom_left_coords[2] - 1, bottom_left_coords[3])
- border_initializer?.Invoke(corner)
+ border_initializer?.Invoke(corner, src)
if(needs_component)
corner.AddComponent(/datum/component/reservation_border, mirage_range, SOUTHEAST, should_mirage, locate(bottom_left_coords[1], top_right_coords[2], bottom_left_coords[3]), border_handler)
immediate_corners += corner
@@ -329,7 +339,7 @@
// todo: area.assimilate_turfs?
area_instance.contents.Add(final)
- src.reserved_turfs = final.Copy()
+ src.reservation_area = area_instance
src.width = width
src.height = height
src.border = border
@@ -356,6 +366,34 @@
return TRUE
+/**
+ * gets an unordered list of all inner (non-border) turfs
+ */
+/datum/turf_reservation/proc/unordered_inner_turfs()
+ return block(
+ locate(bottom_left_coords[1], bottom_left_coords[2], bottom_left_coords[3]),
+ locate(top_right_coords[1], top_right_coords[2], top_right_coords[3]),
+ )
+
+/**
+ * gets an unordered list of all outer (border) turfs
+ */
+/datum/turf_reservation/proc/unordered_border_turfs()
+ if(!border)
+ return list()
+ return border_turfs.Copy()
+
+/**
+ * gets an unordered list of all immediate (1-outside) turfs
+ */
+/datum/turf_reservation/proc/unordered_immediate_border_turfs()
+ if(!border)
+ return list()
+ // todo: implement this
+ CRASH("unimplemented")
+
+//* Reservation Border Area *//
+
/area/reservation_border
name = "Reservation Border Area"
unique = FALSE
diff --git a/code/modules/media/mediamanager.dm b/code/modules/media/mediamanager.dm
index edc2ed313d1..2d16ae5348c 100644
--- a/code/modules/media/mediamanager.dm
+++ b/code/modules/media/mediamanager.dm
@@ -35,7 +35,8 @@
// Update when moving between areas.
// TODO - While this direct override might technically be faster, probably better code to use observer or hooks ~Leshana
-/area/Entered(var/mob/living/M)
+/area/Entered(atom/movable/AM, atom/oldLoc)
+ var/mob/M = AM
// Note, we cannot call ..() first, because it would update lastarea.
if(!istype(M))
return ..()
diff --git a/code/modules/overmap/entity/entity.dm b/code/modules/overmap/entity/entity.dm
index 6e34bc6ec61..77b8fa97fec 100644
--- a/code/modules/overmap/entity/entity.dm
+++ b/code/modules/overmap/entity/entity.dm
@@ -4,13 +4,17 @@
* overmap objects capable of motion
*/
/obj/overmap/entity
- //* identity
+ //* identity *//
/// id
var/id
/// next id
var/static/id_next = 0
- //* physics
+ //* overmap *//
+ /// if we're currently in an overmap; if so, which?
+ var/datum/overmap/overmap
+
+ //* physics *//
/// velocity x in overmap units per second
var/vel_x
/// velocity y in overmap units per second
@@ -23,6 +27,10 @@
var/max_speed = OVERMAP_DISTANCE_TILE
/// is moving
var/tmp/is_moving = FALSE
+ /// is forced moving
+ ///
+ /// todo: reevaluate if this is the right way to perform forced movements like wrapping.
+ var/tmp/is_forced_moving = FALSE
/obj/overmap/entity/New()
// assign id immediately
@@ -31,16 +39,20 @@
/obj/overmap/entity/Initialize(mapload)
. = ..()
+ // init physics
initialize_physics()
update_velocity_ticking()
+ // add to spatial grid
+ AddComponent(/datum/component/spatial_grid, SSspatial_grids.overmap_entities)
/obj/overmap/entity/Destroy()
+ // stop physics
deactivate_physics()
return ..()
/obj/overmap/entity/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
. = ..()
- if(!isturf(old_loc) || forced)
+ if(!isturf(old_loc) || (forced && !is_forced_moving))
initialize_physics()
/obj/overmap/entity/vv_edit_var(var_name, var_value, mass_edit, raw_edit)
@@ -52,3 +64,15 @@
set_velocity(vy = var_value)
return TRUE
return ..()
+
+/**
+ * called when we join an overmap
+ */
+/obj/overmap/entity/proc/on_overmap_join(datum/overmap/map)
+ src.overmap = map
+
+/**
+ * called when we leave an overmap
+ */
+/obj/overmap/entity/proc/on_overmap_leave(datum/overmap/map)
+ src.overmap = map
diff --git a/code/modules/overmap/entity/physics.dm b/code/modules/overmap/entity/physics.dm
index 208d0160b28..adbd1e2b429 100644
--- a/code/modules/overmap/entity/physics.dm
+++ b/code/modules/overmap/entity/physics.dm
@@ -1,5 +1,7 @@
/**
* (re)initialize physics
+ *
+ * always sets us back to a non-ticking state
*/
/obj/overmap/entity/proc/initialize_physics()
deactivate_physics()
@@ -16,6 +18,8 @@
physics_tick(delta_time)
/obj/overmap/entity/proc/physics_tick(dt)
+ if(!overmap)
+ return // what are we doing
// todo: proper overmaps physics, take diff from overmap south/west
var/new_position_x = pos_x + vel_x * dt
var/new_position_y = pos_y + vel_y * dt
@@ -37,9 +41,25 @@
if(new_loc != loc)
var/turf/old_loc = loc
- if(!Move(new_loc, NORTH, dt * 10))
- initialize_physics() // for athena's event
- return
+ var/jumping = FALSE
+ if(istype(new_loc, /turf/overmap/edge))
+ var/turf/overmap/edge/edge = new_loc
+ new_loc = edge.get_wrap_counterpart()
+ jumping = TRUE
+ pos_x += edge.wrap_sign_x * OVERMAP_DISTANCE_TILE * overmap.width
+ pos_y += edge.wrap_sign_y * OVERMAP_DISTANCE_TILE * overmap.height
+ if(jumping)
+ is_forced_moving = TRUE
+ forceMove(new_loc)
+ is_forced_moving = FALSE
+ else if(get_dist(loc, new_loc) == 1)
+ if(!Move(new_loc, NORTH, dt * 10))
+ initialize_physics()
+ return
+ else
+ message_admins(SPAN_DANGER("overmap entity attempted to perform an illegal move ([src]); please check logs. halting movement of affected entity."))
+ initialize_physics()
+ CRASH("attempted to move not one tile but also while not jumping")
if(get_dist(old_loc, loc) > 1)
pixel_x = new_pixel_x
pixel_y = new_pixel_y
@@ -59,7 +79,7 @@
/obj/overmap/entity/proc/set_velocity(vx, vy)
if(!isnull(vx))
vel_x = vx
- if(isnull(vy))
+ if(!isnull(vy))
vel_y = vy
if(!is_moving && (QUANTIZE_OVERMAP_DISTANCE(vel_x) || QUANTIZE_OVERMAP_DISTANCE(vel_y)))
@@ -92,8 +112,30 @@
/obj/overmap/entity/proc/is_moving()
return QUANTIZE_OVERMAP_DISTANCE(vel_x) || QUANTIZE_OVERMAP_DISTANCE(vel_y)
+//* Getters *//
+
+/**
+ * gets our tile X on overmap
+ *
+ * @return 0 if not on overmap
+ */
+/obj/overmap/entity/proc/get_tile_x()
+ if(!overmap)
+ return 0
+ return x - overmap.lower_left_x + 1
+
+/**
+ * gets our tile Y on overmap
+ *
+ * @return 0 if not on overmap
+ */
+/obj/overmap/entity/proc/get_tile_y()
+ if(!overmap)
+ return 0
+ return y - overmap.lower_left_y + 1
+
/**
- * gets our movement (non-angular) speed
+ * gets our movement (non-angular) speed in overmaps units per second
*/
/obj/overmap/entity/proc/get_speed()
return sqrt(vel_x ** 2 + vel_y ** 2)
diff --git a/code/modules/overmap/events/event_handler.dm b/code/modules/overmap/events/event_handler.dm
index d629abe683e..d153de1d413 100644
--- a/code/modules/overmap/events/event_handler.dm
+++ b/code/modules/overmap/events/event_handler.dm
@@ -9,66 +9,6 @@ GLOBAL_DATUM_INIT(overmap_event_handler, /singleton/overmap_event_handler, new)
hazard_by_turf = list()
ship_events = list()
-// Populates overmap with random events! Should be called once at startup at some point.
-/singleton/overmap_event_handler/proc/create_events(var/z_level, var/overmap_size, var/number_of_events)
- // Acquire the list of not-yet utilized overmap turfs on this Z-level
- var/list/overmap_turfs = block(locate(OVERMAP_EDGE, OVERMAP_EDGE, z_level), locate(overmap_size - OVERMAP_EDGE, overmap_size - OVERMAP_EDGE, z_level))
- var/list/candidate_turfs = list()
- for(var/Trf in overmap_turfs)
- var/turf/T = Trf
- if(!(locate(/obj/overmap/entity/visitable) in T))
- candidate_turfs += T
-
- for(var/i = 1 to number_of_events)
- if(!candidate_turfs.len)
- break
- var/overmap_event_type = pick(subtypesof(/datum/overmap_event))
- var/datum/overmap_event/datum_spawn = new overmap_event_type
- log_debug(SPAN_DEBUGINFO("Generating cloud of [datum_spawn.count] [datum_spawn] overmap event hazards"))
-
- var/list/event_turfs = acquire_event_turfs(datum_spawn.count, datum_spawn.radius, candidate_turfs, datum_spawn.continuous)
- candidate_turfs -= event_turfs
-
- for(var/event_turf in event_turfs)
- var/type = pick(datum_spawn.hazards)
- new type(event_turf)
-
- qdel(datum_spawn) // IDK help how do I do this better?
-
-/singleton/overmap_event_handler/proc/acquire_event_turfs(var/number_of_turfs, var/distance_from_origin, var/list/candidate_turfs, var/continuous = TRUE)
- number_of_turfs = min(number_of_turfs, candidate_turfs.len)
- candidate_turfs = candidate_turfs.Copy() // Not this proc's responsibility to adjust the given lists
-
- var/origin_turf = pick(candidate_turfs)
- var/list/selected_turfs = list(origin_turf)
- var/list/selection_turfs = list(origin_turf)
- candidate_turfs -= origin_turf
-
- while(selection_turfs.len && selected_turfs.len < number_of_turfs)
- var/selection_turf = pick(selection_turfs)
- var/random_neighbour = get_random_neighbour(selection_turf, candidate_turfs, continuous, distance_from_origin)
-
- if(random_neighbour)
- candidate_turfs -= random_neighbour
- selected_turfs += random_neighbour
- if(get_dist(origin_turf, random_neighbour) < distance_from_origin)
- selection_turfs += random_neighbour
- else
- selection_turfs -= selection_turf
-
- return selected_turfs
-
-/singleton/overmap_event_handler/proc/get_random_neighbour(var/turf/origin_turf, var/list/candidate_turfs, var/continuous = TRUE, var/range)
- var/fitting_turfs
- if(continuous)
- fitting_turfs = origin_turf.CardinalTurfs(FALSE)
- else
- fitting_turfs = trange(range, origin_turf)
- fitting_turfs = shuffle(fitting_turfs)
- for(var/turf/T in fitting_turfs)
- if(T in candidate_turfs)
- return T
-
/singleton/overmap_event_handler/proc/start_hazard(var/obj/overmap/entity/visitable/ship/ship, var/obj/overmap/tiled/hazard/hazard) // Make these accept both hazards or events
if(!(ship in ship_events))
ship_events += ship
diff --git a/code/modules/overmap/legacy/sectors.dm b/code/modules/overmap/legacy/sectors.dm
index 608619913ac..a963b4d77b4 100644
--- a/code/modules/overmap/legacy/sectors.dm
+++ b/code/modules/overmap/legacy/sectors.dm
@@ -44,32 +44,32 @@
find_z_levels() // This populates map_z and assigns z levels to the ship.
register_z_levels() // This makes external calls to update global z level information.
- ASSERT((LEGACY_MAP_DATUM).overmap_z)
-
- start_x = start_x || rand(OVERMAP_EDGE, (LEGACY_MAP_DATUM).overmap_size - OVERMAP_EDGE)
- start_y = start_y || rand(OVERMAP_EDGE, (LEGACY_MAP_DATUM).overmap_size - OVERMAP_EDGE)
-
- forceMove(locate(start_x, start_y, (LEGACY_MAP_DATUM).overmap_z))
-
docking_codes = "[ascii2text(rand(65,90))][ascii2text(rand(65,90))][ascii2text(rand(65,90))][ascii2text(rand(65,90))]"
- testing("Located sector \"[name]\" at [start_x],[start_y], containing Z [english_list(map_z)]")
+ // todo: This is shitcode but sue me tbh we gotta refactor this shit anyways to be overmap_initializer's
+ spawn(-1)
+ var/datum/overmap/legacy_bind_overmap = SSovermaps.get_or_load_default_overmap()
+ var/turf/where_to_go = free_overmap_space(legacy_bind_overmap)
+ start_x = where_to_go.x
+ start_y = where_to_go.y
- LAZYADD(SSshuttle.sectors_to_initialize, src) //Queued for further init. Will populate the waypoint lists; waypoints not spawned yet will be added in as they spawn.
- SSshuttle.process_init_queues()
+ forceMove(where_to_go)
+ testing("Located sector \"[name]\" at [start_x],[start_y], containing Z [english_list(map_z)]")
- if(known)
- plane = ABOVE_LIGHTING_PLANE
- for(var/obj/machinery/computer/ship/helm/H in GLOB.machines)
- H.get_known_sectors()
- else
- real_appearance = image(icon, src, icon_state)
- real_appearance.override = TRUE
- name = unknown_name
- icon_state = unknown_state
- color = null
- desc = "Scan this to find out more information."
+ if(known)
+ plane = ABOVE_LIGHTING_PLANE
+ for(var/obj/machinery/computer/ship/helm/H in GLOB.machines)
+ H.get_known_sectors()
+ else
+ real_appearance = image(icon, src, icon_state)
+ real_appearance.override = TRUE
+ name = unknown_name
+ icon_state = unknown_state
+ color = null
+ desc = "Scan this to find out more information."
+ LAZYADD(SSshuttle.sectors_to_initialize, src) //Queued for further init. Will populate the waypoint lists; waypoints not spawned yet will be added in as they spawn.
+ SSshuttle.process_init_queues()
// You generally shouldn't destroy these.
/obj/overmap/entity/visitable/Destroy()
@@ -222,25 +222,18 @@
priority_announcement.Announce(message, new_title = "Automated Distress Signal", new_sound = 'sound/AI/sos.ogg', zlevel = -1)
-/proc/build_overmap()
- if(!(LEGACY_MAP_DATUM).use_overmap)
- return 1
-
- ASSERT(!(LEGACY_MAP_DATUM).overmap_z)
- testing("Building overmap...")
- (LEGACY_MAP_DATUM).overmap_z = SSmapping.allocate_level().z_index
-
- testing("Putting overmap on [(LEGACY_MAP_DATUM).overmap_z]")
- var/area/overmap/A = new
- for (var/square in block(locate(1,1,(LEGACY_MAP_DATUM).overmap_z), locate((LEGACY_MAP_DATUM).overmap_size,(LEGACY_MAP_DATUM).overmap_size,(LEGACY_MAP_DATUM).overmap_z)))
- var/turf/T = square
- if(T.x == 1 || T.y == 1 || T.x == (LEGACY_MAP_DATUM).overmap_size || T.y == (LEGACY_MAP_DATUM).overmap_size)
- T = T.ChangeTurf(/turf/overmap/edge)
- else
- T = T.ChangeTurf(/turf/overmap)
- ChangeArea(T, A)
-
- (LEGACY_MAP_DATUM).sealed_levels |= (LEGACY_MAP_DATUM).overmap_z
-
- testing("Overmap build complete.")
- return 1
+/obj/overmap/entity/visitable/proc/free_overmap_space(datum/overmap/map)
+ var/list/turf/potential_turfs = map.reservation.unordered_inner_turfs()
+ var/safety = 1000
+ var/turf/potential
+ while((potential = pick_n_take(potential_turfs)))
+ if(length(potential.contents))
+ // something already here
+ continue
+ if(safety-- < 0)
+ stack_trace("safety ran out, that shouldn't really happen but okay")
+ break
+ break
+ if(!potential)
+ potential = locate(map.lower_left_x, map.lower_left_y, map.reservation.bottom_left_coords[3])
+ return potential
diff --git a/code/modules/overmap/legacy/ships/computers/helm.dm b/code/modules/overmap/legacy/ships/computers/helm.dm
index cbd8d4cfaa1..c7ccf8a01be 100644
--- a/code/modules/overmap/legacy/ships/computers/helm.dm
+++ b/code/modules/overmap/legacy/ships/computers/helm.dm
@@ -54,14 +54,14 @@ GLOBAL_LIST_EMPTY(all_waypoints)
if (S.known)
var/datum/computer_file/data/waypoint/R = new()
R.fields["name"] = S.name
- R.fields["x"] = S.x
- R.fields["y"] = S.y
+ R.fields["x"] = S.get_tile_x()
+ R.fields["y"] = S.get_tile_y()
known_sectors[S.name] = R
/obj/machinery/computer/ship/helm/process(delta_time)
..()
if(autopilot && dx && dy && !autopilot_disabled)
- var/turf/T = locate(dx,dy,(LEGACY_MAP_DATUM).overmap_z)
+ var/turf/T = locate(dx, dy, linked.z)
if(linked.loc == T)
if(!linked.is_moving())
autopilot = 0
@@ -104,8 +104,8 @@ GLOBAL_LIST_EMPTY(all_waypoints)
data["sector"] = current_sector ? current_sector.name : "Deep Space"
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
data["landed"] = linked.get_landed_info()
- data["s_x"] = linked.x
- data["s_y"] = linked.y
+ data["s_x"] = linked.get_tile_x()
+ data["s_y"] = linked.get_tile_y()
data["dest"] = dy && dx
data["d_x"] = dx
data["d_y"] = dy
@@ -166,13 +166,13 @@ GLOBAL_LIST_EMPTY(all_waypoints)
return TRUE
switch(params["add"])
if("current")
- R.fields["x"] = linked.x
- R.fields["y"] = linked.y
+ R.fields["x"] = linked.get_tile_x()
+ R.fields["y"] = linked.get_tile_y()
if("new")
- var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num
+ var/newx = input("Input new entry x coordinate", "Coordinate input", linked.get_tile_x()) as num
if(ui_status(usr, ui.state) != UI_INTERACTIVE)
return TRUE
- var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num
+ var/newy = input("Input new entry y coordinate", "Coordinate input", linked.get_tile_y()) as num
if(ui_status(usr, ui.state) != UI_INTERACTIVE)
return FALSE
R.fields["x"] = clamp(newx, 1, world.maxx)
diff --git a/code/modules/overmap/legacy/spacetravel.dm b/code/modules/overmap/legacy/spacetravel.dm
deleted file mode 100644
index e28e4a88668..00000000000
--- a/code/modules/overmap/legacy/spacetravel.dm
+++ /dev/null
@@ -1,157 +0,0 @@
-// List used to cache empty zlevels to avoid nedless map bloat
-var/list/cached_space = list()
-
-// Space stragglers go here
-
-/obj/overmap/entity/visitable/sector/temporary
- name = "Deep Space"
- invisibility = 101
- known = 0
-
-/obj/overmap/entity/visitable/sector/temporary/New(var/nx, var/ny, var/nz)
- loc = locate(nx, ny, (LEGACY_MAP_DATUM).overmap_z)
- x = nx
- y = ny
- map_z += nz
- map_sectors["[nz]"] = src
- testing("Temporary sector at [x],[y] was created, corresponding zlevel is [nz].")
-
-/obj/overmap/entity/visitable/sector/temporary/Destroy()
- map_sectors["[map_z]"] = null
- testing("Temporary sector at [x],[y] was deleted.")
- return ..()
-
-/obj/overmap/entity/visitable/sector/temporary/proc/can_die(var/mob/observer)
- testing("Checking if sector at [map_z[1]] can die.")
- for(var/mob/M in global.GLOB.player_list)
- if(M != observer && (M.z in map_z))
- testing("There are people on it.")
- return 0
- return 1
-
-/proc/get_deepspace(x, y)
- var/turf/overmap/overmap_turf = locate(x,y,(LEGACY_MAP_DATUM).overmap_z)
- if(!istype(overmap_turf))
- CRASH("Attempt to get deepspace at ([x],[y]) which is not on overmap: [overmap_turf]")
- var/obj/overmap/entity/visitable/sector/temporary/res = locate() in overmap_turf
- if(istype(res))
- return res
- else if(cached_space.len)
- res = cached_space[cached_space.len]
- cached_space -= res
- res.forceMove(overmap_turf)
- return res
- else
- return new /obj/overmap/entity/visitable/sector/temporary(x, y, (LEGACY_MAP_DATUM).get_empty_zlevel())
-
-/atom/movable/proc/lost_in_space()
- for(var/atom/movable/AM in contents)
- if(!AM.lost_in_space())
- return FALSE
- if(has_buckled_mobs())
- for(var/mob/M in buckled_mobs)
- if(!M.lost_in_space())
- return FALSE
-
- return TRUE
-
-/*
-/obj/item/uav/lost_in_space()
- if(state == 1)
- return FALSE
- return ..()
-*/
-
-/obj/machinery/power/supermatter/lost_in_space()
- return FALSE
-
-/obj/singularity/lost_in_space()
- return FALSE
-
-/obj/vehicle_old/lost_in_space()
- if(load && !load.lost_in_space())
- return FALSE
- return ..()
-
-/mob/lost_in_space()
- return isnull(client)
-
-/mob/observer/lost_in_space() // heeyyyyyy buddy can we not :)
- return FALSE
-
-/mob/living/carbon/human/lost_in_space()
- return FALSE
- // return isnull(client) && !key && stat == DEAD // Allows bodies that players have ghosted from to be deleted - Ater
-
-/proc/overmap_spacetravel(turf/space/T, atom/movable/A)
- if (!T || !A)
- return
-
- var/obj/overmap/entity/visitable/M = get_overmap_sector(T.z)
- if (!M)
- return
-
- // Is the landmark still on the map.
- if(!isturf(M.loc))
- return
-
- // Don't let AI eyes yeet themselves off the map
- if(istype(A, /mob/observer/eye))
- return
-
- if(A.lost_in_space())
- if(!QDELETED(A))
- qdel(A)
- return
-
- var/nx = 1
- var/ny = 1
- var/nz = 1
-
- if(T.x <= TRANSITIONEDGE)
- nx = world.maxx - TRANSITIONEDGE - 2
- ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
-
- else if (A.x >= (world.maxx - TRANSITIONEDGE - 1))
- nx = TRANSITIONEDGE + 2
- ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
-
- else if (T.y <= TRANSITIONEDGE)
- ny = world.maxy - TRANSITIONEDGE -2
- nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
-
- else if (A.y >= (world.maxy - TRANSITIONEDGE - 1))
- ny = TRANSITIONEDGE + 2
- nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
-
- nz = SAFEPICK(M.map_z)
- if(!isnull(nz))
- A.forceMove(locate(nx, ny, nz))
- return
-
- testing("[A] spacemoving from [M] ([M.x], [M.y]).")
-
- var/turf/map = locate(M.x,M.y,(LEGACY_MAP_DATUM).overmap_z)
- var/obj/overmap/entity/visitable/TM
- for(var/obj/overmap/entity/visitable/O in map)
- if(O != M && O.in_space && prob(50))
- TM = O
- break
- if(!TM)
- TM = get_deepspace(M.x,M.y)
- nz = pick(TM.get_space_zlevels())
-
- var/turf/dest = locate(nx,ny,nz)
- if(istype(dest))
- A.forceMove(dest)
- if(ismob(A))
- var/mob/D = A
- if(D.pulling)
- D.pulling.forceMove(dest)
-
- if(istype(M, /obj/overmap/entity/visitable/sector/temporary))
- var/obj/overmap/entity/visitable/sector/temporary/source = M
- if (source.can_die())
- testing("Caching [M] for future use")
- source.moveToNullspace()
- cached_space += source
diff --git a/code/modules/overmap/map/area.dm b/code/modules/overmap/map/area.dm
index a69cf68a0ee..1861976dd8d 100644
--- a/code/modules/overmap/map/area.dm
+++ b/code/modules/overmap/map/area.dm
@@ -1,5 +1,35 @@
+//* This file is explicitly licensed under the MIT license. *//
+//* Copyright (c) 2024 silicons *//
+
+/**
+ * this is only on the turfs inside the overmap,
+ * not the turfs outside of it
+ */
/area/overmap
- name = "System Map"
+ name = "Overmap Zone"
+ icon = 'icons/modules/overmap/area.dmi'
+ icon_state = "map"
icon_state = "start"
- requires_power = FALSE
+ // todo: sensor update
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
+
+ /// our overmap
+ var/datum/overmap/overmap
+
+/area/overmap/Destroy()
+ overmap = null
+ return ..()
+
+/area/overmap/Entered(atom/movable/AM, atom/oldLoc)
+ . = ..()
+ if(!istype(AM, /obj/overmap/entity))
+ return
+ var/obj/overmap/entity/entity = AM
+ entity.on_overmap_join(overmap)
+
+/area/overmap/Exited(atom/movable/AM, atom/oldLoc)
+ . = ..()
+ if(!istype(AM, /obj/overmap/entity))
+ return
+ var/obj/overmap/entity/entity = AM
+ entity.on_overmap_leave(overmap)
diff --git a/code/modules/overmap/map/overmap.dm b/code/modules/overmap/map/overmap.dm
new file mode 100644
index 00000000000..86012125629
--- /dev/null
+++ b/code/modules/overmap/map/overmap.dm
@@ -0,0 +1,94 @@
+//* This file is explicitly licensed under the MIT license. *//
+//* Copyright (c) 2024 silicons *//
+
+/datum/overmap
+ /// friendly name, if any; generated if not
+ var/name
+ /// unique id
+ var/id
+ /// width in tiles
+ var/width
+ /// height in tiles
+ var/height
+ /// cached for speed
+ var/lower_left_x
+ /// cached for speed
+ var/lower_left_y
+ /// cached for speed
+ var/upper_right_x
+ /// cached for speed
+ var/upper_right_y
+ /// our turf reservation
+ var/datum/turf_reservation/reservation
+ /// our template
+ var/datum/overmap_template/template
+
+/datum/overmap/New(id, datum/overmap_template/template)
+ src.id = id
+ src.template = template
+
+/**
+ * initializes an overmap from a template
+ */
+/datum/overmap/proc/initialize(datum/overmap_template/template = src.template)
+ ASSERT(!SSovermaps.overmap_by_id[id])
+
+ if(!template.initialized)
+ template.initialize()
+
+ construct(template)
+
+ allocate()
+ template.on_allocation(src)
+
+ build(template)
+ template.on_allocation_initialized(src)
+
+ SSovermaps.overmap_by_id[id] = src
+ return TRUE
+
+/**
+ * allocates our reservation block
+ */
+/datum/overmap/proc/allocate()
+ if(reservation)
+ CRASH("has reservation already")
+ // alloc a 1 tile border
+ reservation = SSmapping.request_block_reservation(
+ width,
+ height,
+ area_override = /area/overmap,
+ border = 1,
+ border_initializer = CALLBACK(src, PROC_REF(reservation_border_initializer)),
+ )
+ lower_left_x = reservation.bottom_left_coords[1]
+ lower_left_y = reservation.bottom_left_coords[2]
+ upper_right_x = reservation.top_right_coords[1]
+ upper_right_y = reservation.top_right_coords[2]
+ var/area/overmap/created_area = reservation.reservation_area
+ created_area.overmap = src
+ return reservation
+
+/**
+ * constructs our parameters from template
+ */
+/datum/overmap/proc/construct(datum/overmap_template/template)
+ src.width = template.width
+ src.height = template.height
+
+/**
+ * builds and initializes our map, which is usually blank unless a template put stuff in.
+ */
+/datum/overmap/proc/build()
+ var/list/turf/map_turfs = reservation.unordered_inner_turfs()
+ for(var/turf/turf as anything in map_turfs)
+ var/turf/overmap/map/map_tile = turf.ChangeTurf(/turf/overmap/map)
+ map_tile.initialize_overmap(src)
+
+
+/**
+ * makes a border turf
+ */
+/datum/overmap/proc/reservation_border_initializer(turf/border, datum/turf_reservation/reservation)
+ var/turf/overmap/edge/edge = border.ChangeTurf(/turf/overmap/edge)
+ edge.initialize_border(src, reservation)
diff --git a/code/modules/overmap/map/overmap_template.dm b/code/modules/overmap/map/overmap_template.dm
new file mode 100644
index 00000000000..62fe8789c6c
--- /dev/null
+++ b/code/modules/overmap/map/overmap_template.dm
@@ -0,0 +1,67 @@
+//* This file is explicitly licensed under the MIT license. *//
+//* Copyright (c) 2024 silicons *//
+
+/**
+ * a template used to construct an overmap
+ */
+/datum/overmap_template
+ /// are we initialized?
+ var/initialized = FALSE
+ /// our width
+ var/width
+ /// our height
+ var/height
+ /// our layers
+ /// typepath to init
+ /// applied in order
+ var/list/layers = list()
+
+/datum/overmap_template/New(width, height, list/additional_layers)
+ src.width = width
+ src.height = height
+ if(additional_layers)
+ src.layers += additional_layers
+
+/**
+ * should be idempotent!
+ */
+/datum/overmap_template/proc/initialize()
+ for(var/index in 1 to length(layers))
+ var/datum/overmap_template_layer/maybe_layer = layers[index]
+ if(istype(maybe_layer))
+ continue
+ maybe_layer = new maybe_layer
+ layers[index] = maybe_layer
+
+ initialized = TRUE
+
+/**
+ * called right after the turf reservation is allocated and initialized
+ */
+/datum/overmap_template/proc/on_allocation_initialized(datum/overmap/map)
+ for(var/datum/overmap_template_layer/layer as anything in layers)
+ layer.apply_to(map)
+
+/**
+ * called right after the turf reservation is allocated, but not initialized
+ */
+/datum/overmap_template/proc/on_allocation(datum/overmap/map)
+ return
+
+/**
+ * default
+ */
+/datum/overmap_template/legacy_default
+ width = 20
+ height = 20
+
+ /// event clouds to spawn
+ var/event_clouds = 2
+
+/datum/overmap_template/legacy_default/New(width, height, list/additional_layers, event_clouds)
+ ..()
+ src.event_clouds = event_clouds
+
+/datum/overmap_template/legacy_default/initialize()
+ layers += new /datum/overmap_template_layer/legacy_events(event_clouds)
+ return ..()
diff --git a/code/modules/overmap/map/overmap_template_layer.dm b/code/modules/overmap/map/overmap_template_layer.dm
new file mode 100644
index 00000000000..17ed788b15b
--- /dev/null
+++ b/code/modules/overmap/map/overmap_template_layer.dm
@@ -0,0 +1,17 @@
+//* This file is explicitly licensed under the MIT license. *//
+//* Copyright (c) 2024 silicons *//
+
+/**
+ * generation layers
+ */
+/datum/overmap_template_layer
+
+/**
+ * apply to overmap
+ *
+ * * this doesn't have to be idempotent as of right now
+ * * this is called after the overmap is instanced, so this can't be previewed properly
+ * * this is called before anything is put on the overmap / build_map() is done
+ */
+/datum/overmap_template_layer/proc/apply_to(datum/overmap/map)
+ return TRUE
diff --git a/code/modules/overmap/map/template_layers/legacy_events.dm b/code/modules/overmap/map/template_layers/legacy_events.dm
new file mode 100644
index 00000000000..b113ccadf03
--- /dev/null
+++ b/code/modules/overmap/map/template_layers/legacy_events.dm
@@ -0,0 +1,78 @@
+//* This file is explicitly licensed under the MIT license. *//
+//* Copyright (c) 2024 silicons *//
+
+/**
+ * legacy seeded events
+ */
+/datum/overmap_template_layer/legacy_events
+ /// number of clouds
+ var/number_of_clouds = 2
+
+/datum/overmap_template_layer/legacy_events/New(number_of_clouds)
+ if(!isnull(number_of_clouds))
+ src.number_of_clouds = number_of_clouds
+ return ..()
+
+/datum/overmap_template_layer/legacy_events/apply_to(datum/overmap/map)
+ . = ..()
+ if(!.)
+ return
+
+ var/list/turf/overmap_turfs = map.reservation.unordered_inner_turfs()
+ var/list/turf/candidate_turfs = list()
+
+ for(var/turf/candidate as anything in overmap_turfs)
+ if(length(candidate.contents))
+ continue
+ candidate_turfs += candidate
+
+ for(var/i in 1 to number_of_clouds)
+ if(!length(candidate_turfs))
+ break
+ var/event_type = pick(subtypesof(/datum/overmap_event))
+ var/datum/overmap_event/datum_spawn = new event_type
+
+ var/list/turf/event_turfs = get_cloud_turfs(datum_spawn.count, datum_spawn.radius, candidate_turfs, datum_spawn.continuous)
+ candidate_turfs -= event_turfs
+
+ for(var/turf/event_turf as anything in event_turfs)
+ var/event_spawn_type = pick(datum_spawn.hazards)
+ new event_spawn_type(event_turf)
+
+ qdel(datum_spawn)
+
+/datum/overmap_template_layer/legacy_events/proc/get_cloud_turfs(amount, radius, list/turf/candidates, continuous)
+ // don't modify original list
+ candidates = candidates.Copy()
+ // clamp
+ amount = min(amount, length(candidates))
+
+ var/turf/origin = pick(candidates)
+ var/list/turf/selected = list(origin)
+ var/list/turf/expanding = list(origin)
+
+ candidates -= origin
+
+ while(length(expanding) && length(selected) < amount)
+ var/turf/checking = pick(expanding)
+ var/turf/neighbor = get_random_neighbor(checking, candidates, continuous, radius)
+
+ if(neighbor)
+ candidates -= neighbor
+ selected += neighbor
+ if(get_dist(origin, neighbor) < radius)
+ expanding += neighbor
+ else
+ expanding -= expanding
+
+ return selected
+
+/datum/overmap_template_layer/legacy_events/proc/get_random_neighbor(turf/origin, list/turf/candidates, continuous, range)
+ var/list/turf/potential
+ if(continuous)
+ potential = origin.CardinalTurfs(FALSE)
+ else
+ potential = trange(range, origin)
+ for(var/turf/checking in potential)
+ if(checking in candidates)
+ return checking
diff --git a/code/modules/overmap/map/turf.dm b/code/modules/overmap/map/turf.dm
index f9666f923a0..37e32b95e62 100644
--- a/code/modules/overmap/map/turf.dm
+++ b/code/modules/overmap/map/turf.dm
@@ -1,74 +1,117 @@
/turf/overmap
- icon = 'icons/turf/space.dmi'
+ name = "--init--"
+ desc = "If you see this, it means coders didn't update the description but did allow perspective-relayed examine. Yell at them."
+ icon = 'icons/modules/overmap/turf.dmi'
icon_state = "map"
permit_ao = FALSE
-// initialized = FALSE // TODO - Fix unsimulated turf initialization so this override is not necessary!
+
+ maptext_height = 32
+ maptext_width = 32
+ maptext_x = 0
+ maptext_y = 12
+
+/turf/overmap/proc/initialize_overmap(datum/overmap/map)
+ return TRUE
+
+/turf/overmap/map
+ opacity = FALSE
+ density = FALSE
+
+/turf/overmap/map/initialize_overmap(datum/overmap/map)
+ var/calculated_x = x - map.lower_left_x
+ var/calculated_y = y - map.lower_left_y
+ name = "[calculated_x]-[calculated_y]"
+ return ..()
/turf/overmap/edge
opacity = TRUE
density = TRUE
- var/map_is_to_my
- var/turf/overmap/edge/wrap_buddy
-/turf/overmap/edge/Initialize(mapload)
- ..()
- return INITIALIZE_HINT_LATELOAD
-
-/turf/overmap/edge/LateInitialize()
- //This could be done by using the (LEGACY_MAP_DATUM).overmap_size much faster, HOWEVER, doing it programatically to 'find'
- // the edges this way allows for 'sub overmaps' elsewhere and whatnot.
- for(var/side in GLOB.alldirs) //The order of this list is relevant: It should definitely break on finding a cardinal FIRST.
- var/turf/T = get_step(src, side)
- if(T?.type == /turf/overmap) //Not a wall, not something else, EXACTLY a flat map turf.
- map_is_to_my = side
- break
-
- if(map_is_to_my)
- var/turf/T = get_step(src, map_is_to_my) // Should be a normal map turf
- while(istype(T, /turf/overmap))
- T = get_step(T, map_is_to_my) // Could be a wall if the map is only 1 turf big
- if(istype(T, /turf/overmap/edge))
- wrap_buddy = T
- break
-
-/turf/overmap/edge/Destroy()
- wrap_buddy = null
+ /// stores a reference to our overmap for wrap purposes
+ ///
+ /// todo: is this a good method? it works for now but i hate storing turf vars...
+ var/datum/overmap/overmap
+ /// sign of wrap, x
+ var/wrap_sign_x
+ /// sign of wrap, y
+ var/wrap_sign_y
+
+/turf/overmap/edge/initialize_overmap(datum/overmap/map)
+ name = "border (warp-enabled)"
+ overmap = map
return ..()
-/turf/overmap/edge/Bumped(var/atom/movable/AM)
- if(wrap_buddy?.map_is_to_my)
- AM.forceMove(get_step(wrap_buddy, wrap_buddy.map_is_to_my))
- else
- . = ..()
-
-/turf/overmap/Initialize(mapload)
- . = ..()
- name = "[x]-[y]"
- var/list/numbers = list()
-
- if(x == 1 || x == (LEGACY_MAP_DATUM).overmap_size)
- numbers += list("[round(y/10)]","[round(y%10)]")
- if(y == 1 || y == (LEGACY_MAP_DATUM).overmap_size)
- numbers += "-"
- if(y == 1 || y == (LEGACY_MAP_DATUM).overmap_size)
- numbers += list("[round(x/10)]","[round(x%10)]")
-
- for(var/i = 1 to numbers.len)
- var/image/I = image('icons/effects/numbers.dmi',numbers[i])
- I.pixel_x = 5*i - 2
- I.pixel_y = world.icon_size/2 - 3
- if(y == 1)
- I.pixel_y = 3
- I.pixel_x = 5*i + 4
- if(y == (LEGACY_MAP_DATUM).overmap_size)
- I.pixel_y = world.icon_size - 9
- I.pixel_x = 5*i + 4
- if(x == 1)
- I.pixel_x = 5*i - 2
- if(x == (LEGACY_MAP_DATUM).overmap_size)
- I.pixel_x = 5*i + 2
- add_overlay(I)
+/**
+ * initializes our locality
+ *
+ * remember: at this point, overmap hasn't been set, because we're currently being called from a /datum/turf_reservation!
+ */
+/turf/overmap/edge/proc/initialize_border(datum/overmap/map, datum/turf_reservation/reservation)
+ var/lower_left_x = reservation.bottom_left_coords[1]
+ var/lower_left_y = reservation.bottom_left_coords[2]
+ var/upper_right_x = reservation.top_right_coords[1]
+ var/upper_right_y = reservation.top_right_coords[2]
+
+ var/number
+ if((x == lower_left_x - 1) || (x == upper_right_x + 1))
+ // left or right borders
+ if((y == lower_left_y - 1) || (y == upper_right_y + 1))
+ else
+ number = y - lower_left_y + 1
+ else if((y == lower_left_y - 1) || (y == upper_right_y + 1))
+ // top or bottom borders
+ if((x == lower_left_x - 1) || (x == upper_right_x + 1))
+ else
+ number = x - lower_left_x + 1
+
+ wrap_sign_x = 0
+ wrap_sign_y = 0
+
+ if(x == lower_left_x - 1)
+ if(y == lower_left_y - 1)
+ wrap_sign_y = 1
+ wrap_sign_x = 1
+ else if(x == upper_right_x + 1)
+ if(y == upper_right_y + 1)
+ wrap_sign_y = -1
+ wrap_sign_x = -1
+ if(y == lower_left_y - 1)
+ if(x == upper_right_x + 1)
+ wrap_sign_x = -1
+ wrap_sign_y = 1
+ else if(y == upper_right_y + 1)
+ if(x == lower_left_x - 1)
+ wrap_sign_x = 1
+ wrap_sign_y = -1
+
+ if(number)
+ maptext = MAPTEXT_CENTER("[number]")
+
+/**
+ * get where a ship wraps to when it touches us
+ *
+ * supports diagonals.
+ */
+/turf/overmap/edge/proc/get_wrap_counterpart()
+ if(x == overmap.lower_left_x - 1)
+ if(y == overmap.lower_left_y - 1)
+ return locate(overmap.upper_right_x, overmap.upper_right_y, z)
+ return locate(overmap.upper_right_x, y, z)
+ else if(x == overmap.upper_right_x + 1)
+ if(y == overmap.upper_right_y + 1)
+ return locate(overmap.lower_left_x, overmap.lower_left_y, z)
+ return locate(overmap.lower_left_x, y, z)
+ if(y == overmap.lower_left_y - 1)
+ if(x == overmap.upper_right_x + 1)
+ return locate(overmap.lower_left_x, overmap.upper_right_y, z)
+ return locate(x, overmap.upper_right_y, z)
+ else if(y == overmap.upper_right_y + 1)
+ if(x == overmap.lower_left_x - 1)
+ return locate(overmap.upper_right_x, overmap.lower_left_y, z)
+ return locate(x, overmap.lower_left_y, z)
+
+//! LEGACY BELOW
/turf/overmap/Entered(var/atom/movable/O, var/atom/oldloc)
..()
@@ -79,3 +122,5 @@
..()
if(istype(O, /obj/overmap/entity/visitable/ship))
GLOB.overmap_event_handler.on_turf_exited(src, O, newloc)
+
+//! END
diff --git a/code/modules/overmap/map/object.dm b/code/modules/overmap/object.dm
similarity index 100%
rename from code/modules/overmap/map/object.dm
rename to code/modules/overmap/object.dm
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 7c6186aaf15..599a8ed31d9 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -240,16 +240,6 @@
GLOB.global_announcer.autosay(alert_msg, "Supermatter Monitor")
public_alert = 0
-
-/obj/machinery/power/supermatter/get_transit_zlevel()
- //don't send it back to the station -- most of the time
- if(prob(99))
- var/list/candidates = SSmapping.crosslinked_levels() - (LEGACY_MAP_DATUM).station_levels
- . = SAFEPICK(candidates)
- if(.)
- return
- return ..()
-
/obj/machinery/power/supermatter/process(delta_time)
var/turf/L = loc
diff --git a/code/modules/tgui/modules/overmap.dm b/code/modules/tgui/modules/overmap.dm
index 89b71e86644..4a6149f409a 100644
--- a/code/modules/tgui/modules/overmap.dm
+++ b/code/modules/tgui/modules/overmap.dm
@@ -110,8 +110,8 @@
data["sector"] = current_sector ? current_sector.name : "Deep Space"
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
- data["s_x"] = linked.x
- data["s_y"] = linked.y
+ data["s_x"] = linked.get_tile_x()
+ data["s_y"] = linked.get_tile_y()
data["speed"] = round(linked.get_speed_legacy()*1000, 0.01)
data["accel"] = round(linked.get_acceleration_legacy()*1000, 0.01)
data["heading"] = linked.get_heading()
@@ -188,8 +188,8 @@
data["sector"] = current_sector ? current_sector.name : "Deep Space"
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
data["landed"] = linked.get_landed_info()
- data["s_x"] = linked.x
- data["s_y"] = linked.y
+ data["s_x"] = linked.get_tile_x()
+ data["s_y"] = linked.get_tile_y()
data["dest"] = dy && dx
data["d_x"] = dx
data["d_y"] = dy
@@ -311,11 +311,11 @@
return TRUE
switch(params["add"])
if("current")
- R.fields["x"] = linked.x
- R.fields["y"] = linked.y
+ R.fields["x"] = linked.get_tile_x()
+ R.fields["y"] = linked.get_tile_y()
if("new")
- var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num
- var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num
+ var/newx = input("Input new entry x coordinate", "Coordinate input", linked.get_tile_x()) as num
+ var/newy = input("Input new entry y coordinate", "Coordinate input", linked.get_tile_y()) as num
R.fields["x"] = clamp(newx, 1, world.maxx)
R.fields["y"] = clamp(newy, 1, world.maxy)
known_sectors[sec_name] = R
diff --git a/icons/effects/numbers.dmi b/icons/effects/numbers_unused.dmi
similarity index 100%
rename from icons/effects/numbers.dmi
rename to icons/effects/numbers_unused.dmi
diff --git a/icons/modules/overmap/area.dmi b/icons/modules/overmap/area.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..c107bcc6475ae68c3194f1cef117fdecdf808ea4
GIT binary patch
literal 229
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ?5dE65|`BCklFziD-R$&XJM9faA!9WTWM2S_a0&Cmu|e%6RpyKJrb@IYyv5Brqw3f%OYhwmJP
zK}keTk6WHeqyrm$-k5(SDe^Ibwu5Xn=#4!Z>Gqb%e$*TzPALyDVCD
zVtBADU2$7`n`?ZzVRfx7UU6Q1m@ZXuDpPDLS7adVEXCsAluZ=rOMuxW^Sad{X
zb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1gNKs6#&p*Aw@yiHuwMl0~|?2K~z|Uwbofv>Oc^N;RFbaBKs25APE6M
zk$nk@ApieQou26o#i^pdTv+xMGtb3)LrurBY%><>Ncb}EfM<6tlJuv;9EoddGdw`nSsx~HktTCLVI5B;ju)FoLu
zlgSiIrHUTUqm$?Hp;Ri;$;oC54{90>*L~q}-9|&-6|xja^VI9@>#5h{`?TZa^W}0?
z&11LgI8K)j)pFTUlgr)dX*N4gJe^Lb*;H4(UM`ok5BvaoKg2#5ChP-0z}^qBUj=Ue
zU;S6?{So%@Tf#ngf5ko-VgE1z!EFwI3Ri)kbSr&Tg>2V|#jQ{VUBX_m|FcKgjkzm`jN
zNfz|`{mFDX*K<75>3HPBbUL9^I2epS)U4N0^urTH>$Scc4=4}>uWDAS-R_fTN3&Yd
zU7#imN2A$nq2}v!3d8WkhsA6bsu>R7^lUc!1J8cH-)z*?`8*sR{sG;#XjP9t*Qx*j
N002ovPDHLkV1kVNFY^EZ
literal 0
HcmV?d00001