mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 16:07:40 +00:00
Introducing noitatsxoB (#12073)
* okay * ok * ok * ok * ok * why am i doing this * WHY DID I DO THIS * mirror doesn't work * compile * shuttles should work * fix engine * fix engine * off by 1 * ok * adds proccall to write next map * haha post processing funny * fixes * Update code/modules/mapping/map_template.dm Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> * Update code/modules/mapping/map_template.dm Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> * Update code/modules/mapping/map_template.dm Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> * Update code/modules/mapping/map_template.dm Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
3
code/__DEFINES/mapping/maploader.dm
Normal file
3
code/__DEFINES/mapping/maploader.dm
Normal file
@@ -0,0 +1,3 @@
|
||||
//map template annihilate_bounds
|
||||
#define MAP_TEMPLATE_ANNIHILATE_PRELOAD 1 //annihilate bounds before starting loading
|
||||
#define MAP_TEMPLATE_ANNIHILATE_LOADING 2 //"sweeping" delete during loading
|
||||
@@ -196,7 +196,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
z_list = SSmapping.z_list
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/LoadGroup(list/errorList, name, path, files, list/traits, list/default_traits, silent = FALSE)
|
||||
/datum/controller/subsystem/mapping/proc/LoadGroup(list/errorList, name, path, files, list/traits, list/default_traits, silent = FALSE, orientation = SOUTH)
|
||||
. = list()
|
||||
var/start_time = REALTIMEOFDAY
|
||||
|
||||
@@ -236,7 +236,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
// load the maps
|
||||
for (var/P in parsed_maps)
|
||||
var/datum/parsed_map/pm = P
|
||||
if (!pm.load(1, 1, start_z + parsed_maps[P], no_changeturf = TRUE))
|
||||
if (!pm.load(1, 1, start_z + parsed_maps[P], no_changeturf = TRUE, orientation = orientation))
|
||||
errorList |= pm.original_path
|
||||
if(!silent)
|
||||
INIT_ANNOUNCE("Loaded [name] in [(REALTIMEOFDAY - start_time)/10]s!")
|
||||
@@ -252,7 +252,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
// load the station
|
||||
station_start = world.maxz + 1
|
||||
INIT_ANNOUNCE("Loading [config.map_name]...")
|
||||
LoadGroup(FailedZs, "Station", config.map_path, config.map_file, config.traits, ZTRAITS_STATION)
|
||||
LoadGroup(FailedZs, "Station", config.map_path, config.map_file, config.traits, ZTRAITS_STATION, FALSE, config.orientation)
|
||||
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
mappath = "[prefix][shuttle_id].dmm"
|
||||
. = ..()
|
||||
|
||||
/datum/map_template/shuttle/preload_size(path, cache)
|
||||
/datum/map_template/shuttle/preload_size(path = mappath, force_cache = FALSE)
|
||||
. = ..(path, TRUE) // Done this way because we still want to know if someone actualy wanted to cache the map
|
||||
if(!cached_map)
|
||||
return
|
||||
|
||||
discover_port_offset()
|
||||
|
||||
if(!cache)
|
||||
if(!cached_map)
|
||||
cached_map = null
|
||||
|
||||
/datum/map_template/shuttle/proc/discover_port_offset()
|
||||
@@ -53,12 +53,11 @@
|
||||
++xcrd
|
||||
--ycrd
|
||||
|
||||
/datum/map_template/shuttle/load(turf/T, centered, register=TRUE)
|
||||
/datum/map_template/shuttle/load(turf/T, centered = FALSE, orientation = SOUTH, annihilate = default_annihilate, force_cache = FALSE, rotate_placement_to_orientation = FALSE, register = TRUE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/list/turfs = block( locate(.[MAP_MINX], .[MAP_MINY], .[MAP_MINZ]),
|
||||
locate(.[MAP_MAXX], .[MAP_MAXY], .[MAP_MAXZ]))
|
||||
var/list/turfs = get_last_loaded_turf_block()
|
||||
for(var/i in 1 to turfs.len)
|
||||
var/turf/place = turfs[i]
|
||||
if(istype(place, /turf/open/space)) // This assumes all shuttles are loaded in a single spot then moved to their real destination.
|
||||
|
||||
@@ -492,7 +492,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
if(!template)
|
||||
return FALSE
|
||||
testing("Room \"[template_name]\" placed at ([T.x], [T.y], [T.z])")
|
||||
template.load(T, centered = FALSE)
|
||||
template.load(T, centered = FALSE, orientation = dir, rotate_placement_to_orientation = TRUE)
|
||||
template.loaded++
|
||||
GLOB.stationroom_landmarks -= src
|
||||
qdel(src)
|
||||
@@ -504,7 +504,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
templates = list("Engine SM" = 3, "Engine Singulo" = 3, "Engine Tesla" = 3)
|
||||
icon = 'icons/rooms/box/engine.dmi'
|
||||
|
||||
|
||||
/obj/effect/landmark/stationroom/box/engine/New()
|
||||
. = ..()
|
||||
templates = CONFIG_GET(keyed_list/box_random_engine)
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
var/image/item = image('icons/turf/overlays.dmi',S,"greenOverlay")
|
||||
item.plane = ABOVE_LIGHTING_PLANE
|
||||
preview += item
|
||||
var/list/orientations = list("South" = SOUTH, "North" = NORTH, "East" = EAST, "West" = WEST)
|
||||
var/choice = input(src, "Which orientation? Maps are normally facing SOUTH.", "Template Orientation", "South") as null|anything in orientations
|
||||
var/orientation = orientations[choice]
|
||||
images += preview
|
||||
if(alert(src,"Confirm location.","Template Confirm","Yes","No") == "Yes")
|
||||
if(template.load(T, centered = TRUE))
|
||||
if(template.load(T, centered = TRUE, orientation = orientation))
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(src)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]</span>")
|
||||
else
|
||||
to_chat(src, "Failed to place map")
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
dmm_suite{
|
||||
/*
|
||||
|
||||
dmm_suite version 1.0
|
||||
Released January 30th, 2011.
|
||||
|
||||
NOTE: Map saving functionality removed
|
||||
|
||||
defines the object /dmm_suite
|
||||
- Provides the proc load_map()
|
||||
- Loads the specified map file onto the specified z-level.
|
||||
- provides the proc write_map()
|
||||
- Returns a text string of the map in dmm format
|
||||
ready for output to a file.
|
||||
- provides the proc save_map()
|
||||
- Returns a .dmm file if map is saved
|
||||
- Returns FALSE if map fails to save
|
||||
|
||||
The dmm_suite provides saving and loading of map files in BYOND's native DMM map
|
||||
format. It approximates the map saving and loading processes of the Dream Maker
|
||||
and Dream Seeker programs so as to allow editing, saving, and loading of maps at
|
||||
runtime.
|
||||
|
||||
------------------------
|
||||
|
||||
To save a map at runtime, create an instance of /dmm_suite, and then call
|
||||
write_map(), which accepts three arguments:
|
||||
- A turf representing one corner of a three dimensional grid (Required).
|
||||
- Another turf representing the other corner of the same grid (Required).
|
||||
- Any, or a combination, of several bit flags (Optional, see documentation).
|
||||
|
||||
The order in which the turfs are supplied does not matter, the /dmm_writer will
|
||||
determine the grid containing both, in much the same way as DM's block() function.
|
||||
write_map() will then return a string representing the saved map in dmm format;
|
||||
this string can then be saved to a file, or used for any other purose.
|
||||
|
||||
------------------------
|
||||
|
||||
To load a map at runtime, create an instance of /dmm_suite, and then call load_map(),
|
||||
which accepts two arguments:
|
||||
- A .dmm file to load (Required).
|
||||
- A number representing the z-level on which to start loading the map (Optional).
|
||||
|
||||
The /dmm_suite will load the map file starting on the specified z-level. If no
|
||||
z-level was specified, world.maxz will be increased so as to fit the map. Note
|
||||
that if you wish to load a map onto a z-level that already has objects on it,
|
||||
you will have to handle the removal of those objects. Otherwise the new map will
|
||||
simply load the new objects on top of the old ones.
|
||||
|
||||
Also note that all type paths specified in the .dmm file must exist in the world's
|
||||
code, and that the /dmm_reader trusts that files to be loaded are in fact valid
|
||||
.dmm files. Errors in the .dmm format will cause runtime errors.
|
||||
|
||||
*/
|
||||
|
||||
verb/load_map(var/dmm_file as file, var/x_offset as num, var/y_offset as num, var/z_offset as num, var/cropMap as num, var/measureOnly as num, no_changeturf as num){
|
||||
// dmm_file: A .dmm file to load (Required).
|
||||
// z_offset: A number representing the z-level on which to start loading the map (Optional).
|
||||
// cropMap: When true, the map will be cropped to fit the existing world dimensions (Optional).
|
||||
// measureOnly: When true, no changes will be made to the world (Optional).
|
||||
// no_changeturf: When true, turf/AfterChange won't be called on loaded turfs
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,10 @@
|
||||
|
||||
var/year_offset = 540 //The offset of ingame year from the actual IRL year. You know you want to make a map that takes place in the 90's. Don't lie.
|
||||
|
||||
// "fun things"
|
||||
/// Orientation to load in by default.
|
||||
var/orientation = SOUTH //byond defaults to placing everyting SOUTH.
|
||||
|
||||
/proc/load_map_config(filename = "data/next_map.json", default_to_box, delete_after, error_if_missing = TRUE)
|
||||
var/datum/map_config/config = new
|
||||
if (default_to_box)
|
||||
@@ -139,13 +143,18 @@
|
||||
|
||||
if ("minetype" in json)
|
||||
minetype = json["minetype"]
|
||||
|
||||
|
||||
if ("maptype" in json)
|
||||
maptype = json["maptype"]
|
||||
|
||||
if ("announcertype" in json)
|
||||
announcertype = json["announcertype"]
|
||||
|
||||
if ("orientation" in json)
|
||||
orientation = json["orientation"]
|
||||
if(!(orientation in GLOB.cardinals))
|
||||
orientation = SOUTH
|
||||
|
||||
allow_custom_shuttles = json["allow_custom_shuttles"] != FALSE
|
||||
|
||||
defaulted = FALSE
|
||||
@@ -161,3 +170,23 @@
|
||||
|
||||
/datum/map_config/proc/MakeNextMap()
|
||||
return config_filename == "data/next_map.json" || fcopy(config_filename, "data/next_map.json")
|
||||
|
||||
/// badmin moments. Keep up to date with LoadConfig()!
|
||||
/datum/map_config/proc/WriteNextMap()
|
||||
var/list/jsonlist = list()
|
||||
jsonlist["map_name"] = map_name
|
||||
jsonlist["map_path"] = map_path
|
||||
jsonlist["map_file"] = map_file
|
||||
jsonlist["shuttles"] = shuttles
|
||||
jsonlist["traits"] = traits
|
||||
jsonlist["space_ruin_levels"] = space_ruin_levels
|
||||
jsonlist["year_offset"] = year_offset
|
||||
jsonlist["minetype"] = minetype
|
||||
jsonlist["maptype"] = maptype
|
||||
jsonlist["announcertype"] = announcertype
|
||||
jsonlist["orientation"] = orientation
|
||||
jsonlist["allow_custom_shuttles"] = allow_custom_shuttles
|
||||
if(fexists("data/next_map.json"))
|
||||
fdel("data/next_map.json")
|
||||
var/F = file("data/next_map.json")
|
||||
WRITE_FILE(F, json_encode(jsonlist))
|
||||
46
code/modules/mapping/map_orientation_pattern.dm
Normal file
46
code/modules/mapping/map_orientation_pattern.dm
Normal file
@@ -0,0 +1,46 @@
|
||||
GLOBAL_LIST_INIT(map_orientation_patterns, list(
|
||||
TEXT_NORTH = new /datum/map_orientation_pattern/north,
|
||||
TEXT_SOUTH = new /datum/map_orientation_pattern/south,
|
||||
TEXT_EAST = new /datum/map_orientation_pattern/east,
|
||||
TEXT_WEST = new /datum/map_orientation_pattern/west
|
||||
))
|
||||
|
||||
/datum/map_orientation_pattern
|
||||
var/invert_x
|
||||
var/invert_y
|
||||
var/swap_xy
|
||||
var/xi
|
||||
var/yi
|
||||
var/turn_angle
|
||||
|
||||
/datum/map_orientation_pattern/north
|
||||
invert_y = TRUE
|
||||
invert_x = TRUE
|
||||
swap_xy = FALSE
|
||||
xi = -1
|
||||
yi = 1
|
||||
turn_angle = 180
|
||||
|
||||
/datum/map_orientation_pattern/south
|
||||
invert_y = FALSE
|
||||
invert_x = FALSE
|
||||
swap_xy = FALSE
|
||||
xi = 1
|
||||
yi = -1
|
||||
turn_angle = 0
|
||||
|
||||
/datum/map_orientation_pattern/east
|
||||
invert_y = TRUE
|
||||
invert_x = FALSE
|
||||
swap_xy = TRUE
|
||||
xi = 1
|
||||
yi = 1
|
||||
turn_angle = 90
|
||||
|
||||
/datum/map_orientation_pattern/west
|
||||
invert_y = FALSE
|
||||
invert_x = TRUE
|
||||
swap_xy = TRUE
|
||||
xi = -1
|
||||
yi = -1
|
||||
turn_angle = 270
|
||||
@@ -1,11 +1,14 @@
|
||||
/datum/map_template
|
||||
var/name = "Default Template Name"
|
||||
var/width = 0
|
||||
var/width = 0 //all these are for SOUTH!
|
||||
var/height = 0
|
||||
var/mappath = null
|
||||
var/zdepth = 1
|
||||
var/mappath
|
||||
var/loaded = 0 // Times loaded this round
|
||||
var/datum/parsed_map/cached_map
|
||||
var/keep_cached_map = FALSE
|
||||
var/default_annihilate = FALSE
|
||||
var/list/ztraits //zlevel traits for load_new_z
|
||||
|
||||
/datum/map_template/New(path = null, rename = null, cache = FALSE)
|
||||
if(path)
|
||||
@@ -15,16 +18,45 @@
|
||||
if(rename)
|
||||
name = rename
|
||||
|
||||
/datum/map_template/proc/preload_size(path, cache = FALSE)
|
||||
/datum/map_template/Destroy()
|
||||
QDEL_NULL(cached_map)
|
||||
return ..()
|
||||
|
||||
/datum/map_template/proc/preload_size(path = mappath, force_cache = FALSE)
|
||||
if(cached_map)
|
||||
return cached_map.parsed_bounds
|
||||
var/datum/parsed_map/parsed = new(file(path))
|
||||
var/bounds = parsed?.bounds
|
||||
var/bounds = parsed?.parsed_bounds
|
||||
if(bounds)
|
||||
width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1
|
||||
height = bounds[MAP_MAXY]
|
||||
if(cache)
|
||||
width = bounds[MAP_MAXX] - bounds[MAP_MINX] + 1
|
||||
height = bounds[MAP_MAXY] - bounds[MAP_MINY] + 1
|
||||
zdepth = bounds[MAP_MAXZ] - bounds[MAP_MINZ] + 1
|
||||
if(force_cache || keep_cached_map)
|
||||
cached_map = parsed
|
||||
return bounds
|
||||
|
||||
/datum/map_template/proc/get_parsed_bounds()
|
||||
return preload_size(mappath)
|
||||
|
||||
/datum/map_template/proc/get_last_loaded_bounds()
|
||||
if(cached_map)
|
||||
return cached_map.bounds
|
||||
return get_parsed_bounds()
|
||||
|
||||
/datum/map_template/proc/get_last_loaded_turf_block()
|
||||
if(!cached_map)
|
||||
CRASH("Improper use of get_last_loaded_turf_block, no cached_map.")
|
||||
var/list/B = cached_map.bounds
|
||||
return block(locate(B[MAP_MINX], B[MAP_MINY], B[MAP_MINZ]), locate(B[MAP_MAXX], B[MAP_MAXY], B[MAP_MAXZ]))
|
||||
|
||||
/datum/map_template/proc/get_size(orientation = SOUTH)
|
||||
if(!width || !height || !zdepth)
|
||||
preload_size(mappath)
|
||||
var/rotate = (orientation & (NORTH|SOUTH)) != NONE
|
||||
if(rotate)
|
||||
return list(height, width, zdepth)
|
||||
return list(width, height, zdepth)
|
||||
|
||||
/datum/parsed_map/proc/initTemplateBounds()
|
||||
var/list/obj/machinery/atmospherics/atmos_machines = list()
|
||||
var/list/obj/structure/cable/cables = list()
|
||||
@@ -55,12 +87,12 @@
|
||||
SSmachines.setup_template_powernets(cables)
|
||||
SSair.setup_template_machinery(atmos_machines)
|
||||
|
||||
/datum/map_template/proc/load_new_z(list/traits = list(ZTRAIT_AWAY = TRUE))
|
||||
var/x = round((world.maxx - width)/2)
|
||||
var/y = round((world.maxy - height)/2)
|
||||
/datum/map_template/proc/load_new_z(orientation = SOUTH, list/ztraits = src.ztraits || list(ZTRAIT_AWAY = TRUE), centered = TRUE)
|
||||
var/x = centered? max(round((world.maxx - width) / 2), 1) : 1
|
||||
var/y = centered? max(round((world.maxy - height) / 2), 1) : 1
|
||||
|
||||
var/datum/space_level/level = SSmapping.add_new_zlevel(name, traits)
|
||||
var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE)
|
||||
var/datum/space_level/level = SSmapping.add_new_zlevel(name, ztraits)
|
||||
var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop = TRUE, orientation = orientation)
|
||||
var/list/bounds = parsed.bounds
|
||||
if(!bounds)
|
||||
return FALSE
|
||||
@@ -71,31 +103,67 @@
|
||||
parsed.initTemplateBounds()
|
||||
smooth_zlevel(world.maxz)
|
||||
log_game("Z-level [name] loaded at [x],[y],[world.maxz]")
|
||||
on_map_loaded(world.maxz, parsed.bounds)
|
||||
|
||||
return level
|
||||
|
||||
/datum/map_template/proc/load(turf/T, centered = FALSE)
|
||||
//Override for custom behavior
|
||||
/datum/map_template/proc/on_map_loaded(z, list/bounds)
|
||||
loaded++
|
||||
|
||||
/**
|
||||
* Proc to trigger a load at a specific area. Calls on_map_loaded(T.z, loaded_bounds) afterwards.
|
||||
*
|
||||
* @params
|
||||
* * turf/T - Turf to load at
|
||||
* * centered - Center at T or load with the bottomright corner being at T
|
||||
* * orientation - SOUTH is default, anything else rotates the map to face it with the point of reference being the map itself is facing south by default. Cardinals only, don't be a 4head and put in multiple flags. It won't work or be pretty if you try.
|
||||
* * annihilate - Should we destroy stuff in our bounds while loading
|
||||
* * force_cache - Should we force the parsed shuttle to cache instead of being GC'd post loading if it wasn't going to be cached by default
|
||||
* * rotate_placement_to_orientation - Has no effect if centered. Should we rotate where we load it around the turf we're loading at? Used for stuff like engine submaps when the station is rotated.
|
||||
*
|
||||
*/
|
||||
/datum/map_template/proc/load(turf/T, centered = FALSE, orientation = SOUTH, annihilate = default_annihilate, force_cache = FALSE, rotate_placement_to_orientation = FALSE)
|
||||
var/old_T = T
|
||||
if(centered)
|
||||
T = locate(T.x - round(width/2) , T.y - round(height/2) , T.z)
|
||||
T = locate(T.x - round(((orientation & (NORTH|SOUTH))? width : height) / 2) , T.y - round(((orientation & (NORTH|SOUTH)) ? height : width) / 2) , T.z) // %180 catches East/West (90,270) rotations on true, North/South (0,180) rotations on false
|
||||
else if(rotate_placement_to_orientation && (orientation != SOUTH))
|
||||
var/newx = T.x
|
||||
var/newy = T.y
|
||||
if(orientation == NORTH)
|
||||
newx -= width
|
||||
newy -= height - 1
|
||||
else if(orientation == WEST)
|
||||
newy -= width
|
||||
else if(orientation == EAST)
|
||||
newx -= height - 1
|
||||
// eh let's not silently fail.
|
||||
if(!ISINRANGE(newx, 1, world.maxx) || !ISINRANGE(newy, 1, world.maxy))
|
||||
stack_trace("Warning: Rotation placed a map template load spot ([COORD(T)]) out of bounds of the game world. Clamping to world borders, this might cause issues.")
|
||||
T = locate(clamp(newx, 1, world.maxx), clamp(newy, 1, world.maxy), T.z)
|
||||
if(!T)
|
||||
return
|
||||
if(T.x+width > world.maxx)
|
||||
if(T.x+width-1 > world.maxx)
|
||||
return
|
||||
if(T.y+height > world.maxy)
|
||||
if(T.y+height-1 > world.maxy)
|
||||
return
|
||||
|
||||
var/list/border = block(locate(max(T.x-1, 1), max(T.y-1, 1), T.z),
|
||||
locate(min(T.x+width+1, world.maxx), min(T.y+height+1, world.maxy), T.z))
|
||||
for(var/L in border)
|
||||
var/turf/turf_to_disable = L
|
||||
var/list/border = block(locate(max(T.x - 1, 1), max(T.y - 1, 1), T.z),
|
||||
locate(min(T.x + width + 1, world.maxx), min(T.y + height + 1, world.maxy), T.z))
|
||||
for(var/i in border)
|
||||
var/turf/turf_to_disable = i
|
||||
SSair.remove_from_active(turf_to_disable) //stop processing turfs along the border to prevent runtimes, we return it in initTemplateBounds()
|
||||
turf_to_disable.atmos_adjacent_turfs?.Cut()
|
||||
|
||||
if(annihilate == MAP_TEMPLATE_ANNIHILATE_PRELOAD)
|
||||
annihilate_bounds(old_T, centered, orientation)
|
||||
|
||||
// Accept cached maps, but don't save them automatically - we don't want
|
||||
// ruins clogging up memory for the whole round.
|
||||
var/datum/parsed_map/parsed = cached_map || new(file(mappath))
|
||||
cached_map = keep_cached_map ? parsed : null
|
||||
if(!parsed.load(T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE))
|
||||
var/is_cached = cached_map
|
||||
var/datum/parsed_map/parsed = is_cached || new(file(mappath))
|
||||
cached_map = (force_cache || keep_cached_map) ? parsed : is_cached
|
||||
if(!parsed.load(T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE, orientation = orientation, annihilate_tiles = (annihilate == MAP_TEMPLATE_ANNIHILATE_LOADING)))
|
||||
return
|
||||
var/list/bounds = parsed.bounds
|
||||
if(!bounds)
|
||||
@@ -108,19 +176,36 @@
|
||||
parsed.initTemplateBounds()
|
||||
|
||||
log_game("[name] loaded at [T.x],[T.y],[T.z]")
|
||||
on_map_loaded(T.z, parsed.bounds)
|
||||
|
||||
return bounds
|
||||
|
||||
/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE)
|
||||
var/turf/placement = T
|
||||
if(centered)
|
||||
var/turf/corner = locate(placement.x - round(width/2), placement.y - round(height/2), placement.z)
|
||||
if(corner)
|
||||
placement = corner
|
||||
return block(placement, locate(placement.x+width-1, placement.y+height-1, placement.z))
|
||||
|
||||
//This, get_affected_turfs, and load() calculations for bounds/center can probably be optimized. Later.
|
||||
/datum/map_template/proc/annihilate_bounds(turf/origin, centered = FALSE, orientation = SOUTH)
|
||||
var/deleted_atoms = 0
|
||||
log_world("Annihilating objects in map loading location.")
|
||||
var/list/turfs_to_clean = get_affected_turfs(origin, centered, orientation)
|
||||
if(turfs_to_clean.len)
|
||||
var/list/kill_these = list()
|
||||
for(var/i in turfs_to_clean)
|
||||
var/turf/T = i
|
||||
kill_these += T.contents
|
||||
for(var/i in kill_these)
|
||||
qdel(i)
|
||||
CHECK_TICK
|
||||
deleted_atoms++
|
||||
log_world("Annihilated [deleted_atoms] objects.")
|
||||
|
||||
//for your ever biggening badminnery kevinz000
|
||||
//❤ - Cyberboss
|
||||
/proc/load_new_z_level(file, name, list/traits)
|
||||
/proc/load_new_z_level(file, name, orientation, list/ztraits)
|
||||
var/datum/map_template/template = new(file, name)
|
||||
return template.load_new_z(traits)
|
||||
return template.load_new_z(orientation, ztraits)
|
||||
|
||||
/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE, orientation = SOUTH)
|
||||
var/turf/placement = T
|
||||
if(centered)
|
||||
var/turf/corner = locate(placement.x - round(((orientation & (NORTH|SOUTH))? width : height) / 2), placement.y - round(((orientation & (NORTH|SOUTH))? height : width) / 2), placement.z) // %180 catches East/West (90,270) rotations on true, North/South (0,180) rotations on false
|
||||
if(corner)
|
||||
placement = corner
|
||||
return block(placement, locate(placement.x + ((orientation & (NORTH|SOUTH)) ? width : height) - 1, placement.y + ((orientation & (NORTH|SOUTH))? height : width) - 1, placement.z))
|
||||
|
||||
@@ -7,13 +7,21 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
parent_type = /datum
|
||||
var/list/attributes
|
||||
var/target_path
|
||||
var/turn_angle
|
||||
var/swap_x
|
||||
var/swap_y
|
||||
var/swap_xy
|
||||
|
||||
/world/proc/preloader_setup(list/the_attributes, path)
|
||||
if(the_attributes.len)
|
||||
/world/proc/preloader_setup(list/the_attributes, path, turn_angle, swap_x, swap_y, swap_xy)
|
||||
if(length(the_attributes) || turn_angle)
|
||||
GLOB.use_preloader = TRUE
|
||||
var/datum/map_preloader/preloader_local = GLOB._preloader
|
||||
preloader_local.attributes = the_attributes
|
||||
preloader_local.target_path = path
|
||||
preloader_local.turn_angle = turn_angle
|
||||
preloader_local.swap_x = swap_x
|
||||
preloader_local.swap_y = swap_y
|
||||
preloader_local.swap_xy = swap_xy
|
||||
|
||||
/world/proc/preloader_load(atom/what)
|
||||
GLOB.use_preloader = FALSE
|
||||
@@ -29,6 +37,21 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
GLOB.dirty_vars += message
|
||||
#endif
|
||||
what.vars[attribute] = value
|
||||
// handle post processing, so things like directions on subtypes don't break.
|
||||
if(preloader_local.turn_angle) //safe way to check for if this is necessary
|
||||
what.dir = turn(what.dir, preloader_local.turn_angle)
|
||||
var/px = what.pixel_x
|
||||
var/py = what.pixel_y
|
||||
if(preloader_local.swap_y) //same order of operations as the load rotation, mirror and then x/y swapping.
|
||||
py = -py
|
||||
if(preloader_local.swap_x)
|
||||
px = -px
|
||||
if(preloader_local.swap_xy)
|
||||
var/opx = px
|
||||
px = py
|
||||
py = opx
|
||||
what.pixel_x = px
|
||||
what.pixel_y = py
|
||||
|
||||
/area/template_noop
|
||||
name = "Area Passthrough"
|
||||
|
||||
@@ -19,9 +19,13 @@
|
||||
|
||||
/// Unoffset bounds. Null on parse failure.
|
||||
var/list/parsed_bounds
|
||||
var/width
|
||||
var/height
|
||||
/// Offset bounds. Same as parsed_bounds until load().
|
||||
var/list/bounds
|
||||
|
||||
var/datum/map_template/template_host
|
||||
|
||||
// raw strings used to represent regexes more accurately
|
||||
// '' used to avoid confusing syntax highlighting
|
||||
var/static/regex/dmmRegex = new(@'"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}', "g")
|
||||
@@ -41,14 +45,33 @@
|
||||
/// - `no_changeturf`: When true, [turf/AfterChange] won't be called on loaded turfs
|
||||
/// - `x_lower`, `x_upper`, `y_lower`, `y_upper`: Coordinates (relative to the map) to crop to (Optional).
|
||||
/// - `placeOnTop`: Whether to use [turf/PlaceOnTop] rather than [turf/ChangeTurf] (Optional).
|
||||
/proc/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num, no_changeturf as num, x_lower = -INFINITY as num, x_upper = INFINITY as num, y_lower = -INFINITY as num, y_upper = INFINITY as num, placeOnTop = FALSE as num)
|
||||
var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_upper, measureOnly)
|
||||
/proc/load_map(
|
||||
dmm_file as file,
|
||||
x_offset as num,
|
||||
y_offset as num,
|
||||
z_offset as num,
|
||||
cropMap as num,
|
||||
measureOnly as num,
|
||||
no_changeturf as num,
|
||||
x_lower = -INFINITY as num,
|
||||
x_upper = INFINITY as num,
|
||||
y_lower = -INFINITY as num,
|
||||
y_upper = INFINITY as num,
|
||||
placeOnTop = FALSE as num,
|
||||
orientation = SOUTH as num,
|
||||
annihilate_tiles = FALSE,
|
||||
z_lower = -INFINITY as num,
|
||||
z_upper = INFINITY as num
|
||||
)
|
||||
var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, measureOnly)
|
||||
if(parsed.bounds && !measureOnly)
|
||||
parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop)
|
||||
parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, orientation, annihilate_tiles)
|
||||
return parsed
|
||||
|
||||
/// Parse a map, possibly cropping it.
|
||||
/datum/parsed_map/New(tfile, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper=INFINITY, measureOnly=FALSE)
|
||||
//WHY THE HECK DO WE EVEN SUPPORT NEGATIVE COORDINATES, ALL IT IS IS A WASTE OF TIME AND CPU!!!???
|
||||
//DO NOT USE THIS TO TRIM MAPS UNLESS STRICTLY NEEDED! IT IS EXTREMELY EXPENSIVE TO DO SO!
|
||||
/datum/parsed_map/New(tfile, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, z_lower = -INFINITY, z_upper = INFINITY, measureOnly = FALSE)
|
||||
if(isfile(tfile))
|
||||
original_path = "[tfile]"
|
||||
tfile = file2text(tfile)
|
||||
@@ -57,6 +80,9 @@
|
||||
return
|
||||
|
||||
bounds = parsed_bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
|
||||
ASSERT(x_upper >= x_lower)
|
||||
ASSERT(y_upper >= y_lower)
|
||||
ASSERT(z_upper >= z_lower)
|
||||
var/stored_index = 1
|
||||
|
||||
//multiz lool
|
||||
@@ -82,20 +108,23 @@
|
||||
CRASH("Coords before model definition in DMM")
|
||||
|
||||
var/curr_x = text2num(dmmRegex.group[3])
|
||||
var/curr_y = text2num(dmmRegex.group[4])
|
||||
var/curr_z = text2num(dmmRegex.group[5])
|
||||
|
||||
if(curr_x < x_lower || curr_x > x_upper)
|
||||
if(curr_x < x_lower || curr_y < y_lower || curr_z < z_lower || curr_z > z_upper)
|
||||
continue
|
||||
|
||||
var/datum/grid_set/gridSet = new
|
||||
|
||||
gridSet.xcrd = curr_x
|
||||
//position of the currently processed square
|
||||
gridSet.ycrd = text2num(dmmRegex.group[4])
|
||||
gridSet.zcrd = text2num(dmmRegex.group[5])
|
||||
gridSet.ycrd = curr_y
|
||||
gridSet.zcrd = curr_z
|
||||
|
||||
bounds[MAP_MINX] = min(bounds[MAP_MINX], clamp(gridSet.xcrd, x_lower, x_upper))
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], gridSet.zcrd)
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], gridSet.zcrd)
|
||||
bounds[MAP_MINX] = min(bounds[MAP_MINX], curr_x) //since down is up for y/gridlines, we now know the lower left corner.
|
||||
bounds[MAP_MINY] = min(bounds[MAP_MINY], curr_y)
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], curr_z)
|
||||
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], curr_z) //we know max z now
|
||||
|
||||
var/list/gridLines = splittext(dmmRegex.group[6], "\n")
|
||||
gridSet.gridLines = gridLines
|
||||
@@ -105,102 +134,132 @@
|
||||
if(leadingBlanks > 1)
|
||||
gridLines.Cut(1, leadingBlanks) // Remove all leading blank lines.
|
||||
|
||||
if(!gridLines.len) // Skip it if only blank lines exist.
|
||||
continue
|
||||
|
||||
gridSets += gridSet
|
||||
|
||||
if(gridLines.len && gridLines[gridLines.len] == "")
|
||||
gridLines.Cut(gridLines.len) // Remove only one blank line at the end.
|
||||
var/lines = length(gridLines)
|
||||
if(lines)
|
||||
if(gridLines[gridLines.len] == "")
|
||||
gridLines.Cut(gridLines.len) // Remove only one blank line at the end.
|
||||
var/right_length = y_upper - curr_y + 1
|
||||
if(lines > right_length)
|
||||
gridLines.len = right_length //this can't be negative due to our ASSERTions above, hopefully.
|
||||
|
||||
bounds[MAP_MINY] = min(bounds[MAP_MINY], clamp(gridSet.ycrd, y_lower, y_upper))
|
||||
if(!gridLines.len) // Skip it if there's no content.
|
||||
continue
|
||||
|
||||
//do not use curr_y after this point, ycrd has changed. use it before because local var.
|
||||
gridSet.ycrd += gridLines.len - 1 // Start at the top and work down
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], clamp(gridSet.ycrd, y_lower, y_upper))
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], gridSet.ycrd) //we know max y now
|
||||
|
||||
var/maxx = gridSet.xcrd
|
||||
if(gridLines.len) //Not an empty map
|
||||
maxx = max(maxx, gridSet.xcrd + length(gridLines[1]) / key_len - 1)
|
||||
var/linelength = length(gridLines[1]) //yes it only samples the first line, this is why you use TGM instead of DMM!
|
||||
var/xlength = linelength / key_len
|
||||
|
||||
bounds[MAP_MAXX] = clamp(max(bounds[MAP_MAXX], maxx), x_lower, x_upper)
|
||||
var/maxx = gridSet.xcrd + xlength - 1
|
||||
if(maxx > x_upper)
|
||||
for(var/i in 1 to length(gridLines))
|
||||
gridLines[i] = copytext(gridLines[i], 1, key_len * (x_upper - curr_x + 1))
|
||||
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], maxx)
|
||||
CHECK_TICK
|
||||
|
||||
// Indicate failure to parse any coordinates by nulling bounds
|
||||
if(bounds[1] == 1.#INF)
|
||||
bounds = null
|
||||
else
|
||||
width = bounds[MAP_MAXX] - bounds[MAP_MINX] + 1
|
||||
height = bounds[MAP_MAXY] - bounds[MAP_MINY] + 1
|
||||
parsed_bounds = bounds
|
||||
|
||||
/datum/parsed_map/Destroy()
|
||||
if(template_host && template_host.cached_map == src)
|
||||
template_host.cached_map = null
|
||||
return ..()
|
||||
|
||||
/// Load the parsed map into the world. See [/proc/load_map] for arguments.
|
||||
/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop)
|
||||
/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, orientation, annihilate_tiles, datum/map_orientation_pattern/forced_pattern)
|
||||
//How I wish for RAII
|
||||
Master.StartLoadingMap()
|
||||
. = _load_impl(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop)
|
||||
. = _load_impl(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, orientation, annihilate_tiles, forced_pattern)
|
||||
Master.StopLoadingMap()
|
||||
|
||||
// Do not call except via load() above.
|
||||
/datum/parsed_map/proc/_load_impl(x_offset = 1, y_offset = 1, z_offset = world.maxz + 1, cropMap = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, placeOnTop = FALSE)
|
||||
// Lower/upper here refers to the actual map template's parsed coordinates, NOT ACTUAL COORDINATES! Figure it out yourself my head hurts too much to implement that too.
|
||||
/datum/parsed_map/proc/_load_impl(x_offset = 1, y_offset = 1, z_offset = world.maxz + 1, cropMap = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, placeOnTop = FALSE, orientation = SOUTH, annihilate_tiles = FALSE, datum/map_orientation_pattern/forced_pattern)
|
||||
var/list/areaCache = list()
|
||||
var/list/modelCache = build_cache(no_changeturf)
|
||||
var/space_key = modelCache[SPACE_KEY]
|
||||
var/list/bounds
|
||||
src.bounds = bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
|
||||
var/datum/map_orientation_pattern/mode = forced_pattern || GLOB.map_orientation_patterns["[orientation]"] || GLOB.map_orientation_patterns["[SOUTH]"]
|
||||
var/invert_y = mode.invert_y
|
||||
var/invert_x = mode.invert_x
|
||||
var/swap_xy = mode.swap_xy
|
||||
var/xi = mode.xi
|
||||
var/yi = mode.yi
|
||||
var/turn_angle = round(SIMPLIFY_DEGREES(mode.turn_angle), 90)
|
||||
var/delta_swap = x_offset - y_offset
|
||||
|
||||
for(var/I in gridSets)
|
||||
var/datum/grid_set/gset = I
|
||||
var/ycrd = gset.ycrd + y_offset - 1
|
||||
var/zcrd = gset.zcrd + z_offset - 1
|
||||
if(!cropMap && ycrd > world.maxy)
|
||||
world.maxy = ycrd // Expand Y here. X is expanded in the loop below
|
||||
var/zexpansion = zcrd > world.maxz
|
||||
for(var/__I in gridSets)
|
||||
var/datum/grid_set/gridset = __I
|
||||
var/parsed_z = gridset.zcrd + z_offset - 1
|
||||
var/zexpansion = parsed_z > world.maxz
|
||||
if(zexpansion)
|
||||
if(cropMap)
|
||||
continue
|
||||
else
|
||||
while (zcrd > world.maxz) //create a new z_level if needed
|
||||
while(parsed_z > world.maxz)
|
||||
world.incrementMaxZ()
|
||||
if(!no_changeturf)
|
||||
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called")
|
||||
//these values are the same until a new gridset is reached.
|
||||
var/edge_dist_x = gridset.xcrd - 1 //from left side, 0 is right on the x_offset
|
||||
var/edge_dist_y = gridset.ycrd - length(gridset.gridLines) //from bottom, 0 is right on the y_offset
|
||||
var/actual_x_starting = invert_x? (x_offset + width - edge_dist_x - 1) : (x_offset + edge_dist_x) //this value is not changed, cache.
|
||||
//this value is changed
|
||||
var/actual_y = invert_y? (y_offset + edge_dist_y) : (y_offset + gridset.ycrd - 1)
|
||||
for(var/line in gridset.gridLines)
|
||||
var/actual_x = actual_x_starting
|
||||
for(var/pos = 1 to (length(line) - key_len + 1) step key_len)
|
||||
var/placement_x = swap_xy? (actual_y + delta_swap) : actual_x
|
||||
var/placement_y = swap_xy? (actual_x - delta_swap) : actual_y
|
||||
if(placement_x > world.maxx)
|
||||
if(cropMap)
|
||||
actual_x += xi
|
||||
continue
|
||||
else
|
||||
world.maxx = placement_x
|
||||
if(placement_y > world.maxy)
|
||||
if(cropMap)
|
||||
break
|
||||
else
|
||||
world.maxy = placement_y
|
||||
if(placement_x < 1)
|
||||
actual_x += xi
|
||||
continue
|
||||
if(placement_y < 1)
|
||||
break
|
||||
var/model_key = copytext(line, pos, pos + key_len)
|
||||
var/no_afterchange = no_changeturf || zexpansion
|
||||
if(!no_afterchange || (model_key != space_key))
|
||||
var/list/cache = modelCache[model_key]
|
||||
if(!cache)
|
||||
CRASH("Undefined model key in DMM: [model_key]")
|
||||
build_coordinate(areaCache, cache, locate(placement_x, placement_y, parsed_z), no_afterchange, placeOnTop, turn_angle, annihilate_tiles, swap_xy, invert_y, invert_x)
|
||||
|
||||
for(var/line in gset.gridLines)
|
||||
if((ycrd - y_offset + 1) < y_lower || (ycrd - y_offset + 1) > y_upper) //Reverse operation and check if it is out of bounds of cropping.
|
||||
--ycrd
|
||||
continue
|
||||
if(ycrd <= world.maxy && ycrd >= 1)
|
||||
var/xcrd = gset.xcrd + x_offset - 1
|
||||
for(var/tpos = 1 to length(line) - key_len + 1 step key_len)
|
||||
if((xcrd - x_offset + 1) < x_lower || (xcrd - x_offset + 1) > x_upper) //Same as above.
|
||||
++xcrd
|
||||
continue //X cropping.
|
||||
if(xcrd > world.maxx)
|
||||
if(cropMap)
|
||||
break
|
||||
else
|
||||
world.maxx = xcrd
|
||||
|
||||
if(xcrd >= 1)
|
||||
var/model_key = copytext(line, tpos, tpos + key_len)
|
||||
var/no_afterchange = no_changeturf || zexpansion
|
||||
if(!no_afterchange || (model_key != space_key))
|
||||
var/list/cache = modelCache[model_key]
|
||||
if(!cache)
|
||||
CRASH("Undefined model key in DMM: [model_key]")
|
||||
build_coordinate(areaCache, cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop)
|
||||
|
||||
// only bother with bounds that actually exist
|
||||
bounds[MAP_MINX] = min(bounds[MAP_MINX], xcrd)
|
||||
bounds[MAP_MINY] = min(bounds[MAP_MINY], ycrd)
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd)
|
||||
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], xcrd)
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], ycrd)
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd)
|
||||
#ifdef TESTING
|
||||
else
|
||||
++turfsSkipped
|
||||
#endif
|
||||
CHECK_TICK
|
||||
++xcrd
|
||||
--ycrd
|
||||
|
||||
CHECK_TICK
|
||||
// only bother with bounds that actually exist
|
||||
bounds[MAP_MINX] = min(bounds[MAP_MINX], placement_x)
|
||||
bounds[MAP_MINY] = min(bounds[MAP_MINY], placement_y)
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], parsed_z)
|
||||
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], placement_x)
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], placement_y)
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], parsed_z)
|
||||
#ifdef TESTING
|
||||
else
|
||||
++turfsSkipped
|
||||
#endif
|
||||
actual_x += xi
|
||||
CHECK_TICK
|
||||
actual_y += yi
|
||||
CHECK_TICK
|
||||
|
||||
if(!no_changeturf)
|
||||
for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
@@ -294,7 +353,7 @@
|
||||
|
||||
.[model_key] = list(members, members_attributes)
|
||||
|
||||
/datum/parsed_map/proc/build_coordinate(list/areaCache, list/model, turf/crds, no_changeturf as num, placeOnTop as num)
|
||||
/datum/parsed_map/proc/build_coordinate(list/areaCache, list/model, turf/crds, no_changeturf as num, placeOnTop as num, turn_angle as num, annihilate_tiles = FALSE, swap_xy, invert_y, invert_x)
|
||||
var/index
|
||||
var/list/members = model[1]
|
||||
var/list/members_attributes = model[2]
|
||||
@@ -306,6 +365,8 @@
|
||||
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
|
||||
//first instance the /area and remove it from the members list
|
||||
index = members.len
|
||||
if(annihilate_tiles && crds)
|
||||
crds.empty(null)
|
||||
if(members[index] != /area/template_noop)
|
||||
var/atype = members[index]
|
||||
world.preloader_setup(members_attributes[index], atype)//preloader for assigning set variables on atom creation
|
||||
@@ -332,20 +393,20 @@
|
||||
//instanciate the first /turf
|
||||
var/turf/T
|
||||
if(members[first_turf_index] != /turf/template_noop)
|
||||
T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],crds,no_changeturf,placeOnTop)
|
||||
T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],crds,no_changeturf,placeOnTop,turn_angle, swap_xy, invert_y, invert_x)
|
||||
|
||||
if(T)
|
||||
//if others /turf are presents, simulates the underlays piling effect
|
||||
index = first_turf_index + 1
|
||||
while(index <= members.len - 1) // Last item is an /area
|
||||
var/underlay = T.appearance
|
||||
T = instance_atom(members[index],members_attributes[index],crds,no_changeturf,placeOnTop)//instance new turf
|
||||
T = instance_atom(members[index],members_attributes[index],crds,no_changeturf,placeOnTop,turn_angle, swap_xy, invert_y, invert_x)//instance new turf
|
||||
T.underlays += underlay
|
||||
index++
|
||||
|
||||
//finally instance all remainings objects/mobs
|
||||
for(index in 1 to first_turf_index-1)
|
||||
instance_atom(members[index],members_attributes[index],crds,no_changeturf,placeOnTop)
|
||||
instance_atom(members[index],members_attributes[index],crds,no_changeturf,placeOnTop,turn_angle, swap_xy, invert_y, invert_x)
|
||||
//Restore initialization to the previous value
|
||||
SSatoms.map_loader_stop()
|
||||
|
||||
@@ -354,8 +415,8 @@
|
||||
////////////////
|
||||
|
||||
//Instance an atom at (x,y,z) and gives it the variables in attributes
|
||||
/datum/parsed_map/proc/instance_atom(path,list/attributes, turf/crds, no_changeturf, placeOnTop)
|
||||
world.preloader_setup(attributes, path)
|
||||
/datum/parsed_map/proc/instance_atom(path,list/attributes, turf/crds, no_changeturf, placeOnTop, turn_angle = 0, swap_xy, invert_y, invert_x)
|
||||
world.preloader_setup(attributes, path, turn_angle, invert_x, invert_y, swap_xy)
|
||||
|
||||
if(crds)
|
||||
if(ispath(path, /turf))
|
||||
|
||||
@@ -196,12 +196,16 @@
|
||||
|
||||
switch(tdir)
|
||||
if(NORTH)
|
||||
pixel_x = 0
|
||||
pixel_y = 23
|
||||
if(SOUTH)
|
||||
pixel_x = 0
|
||||
pixel_y = -23
|
||||
if(EAST)
|
||||
pixel_y = 0
|
||||
pixel_x = 24
|
||||
if(WEST)
|
||||
pixel_y = 0
|
||||
pixel_x = -25
|
||||
|
||||
/obj/machinery/power/apc/Destroy()
|
||||
|
||||
@@ -91,6 +91,21 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
d1 = _d1
|
||||
d2 = _d2
|
||||
|
||||
if(dir != SOUTH)
|
||||
var/angle_to_turn = dir2angle(dir)
|
||||
if(angle_to_turn == 0 || angle_to_turn == 180)
|
||||
angle_to_turn += 180
|
||||
// direct dir set instead of setDir intentional
|
||||
dir = SOUTH
|
||||
if(d1)
|
||||
d1 = turn(d1, angle_to_turn)
|
||||
if(d2)
|
||||
d2 = turn(d2, angle_to_turn)
|
||||
if(d1 > d2)
|
||||
var/temp = d2
|
||||
d2 = d1
|
||||
d1 = temp
|
||||
|
||||
var/turf/T = get_turf(src) // hide if turf is not intact
|
||||
if(level==1)
|
||||
hide(T.intact)
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
var/turf/landmark_turf = get_turf(locate(/obj/effect/landmark/shuttle_import) in GLOB.landmarks_list)
|
||||
S.load(landmark_turf, centered = TRUE, register = FALSE)
|
||||
|
||||
var/affected = S.get_affected_turfs(landmark_turf, centered=TRUE)
|
||||
var/affected = S.get_affected_turfs(landmark_turf, centered = TRUE)
|
||||
|
||||
var/found = 0
|
||||
// Search the turfs for docking ports
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
#include "code\__DEFINES\dcs\helpers.dm"
|
||||
#include "code\__DEFINES\dcs\signals.dm"
|
||||
#include "code\__DEFINES\flags\shields.dm"
|
||||
#include "code\__DEFINES\mapping\maploader.dm"
|
||||
#include "code\__DEFINES\misc\return_values.dm"
|
||||
#include "code\__DEFINES\skills\skills.dm"
|
||||
#include "code\__HELPERS\_cit_helpers.dm"
|
||||
@@ -348,7 +349,6 @@
|
||||
#include "code\datums\forced_movement.dm"
|
||||
#include "code\datums\holocall.dm"
|
||||
#include "code\datums\hud.dm"
|
||||
#include "code\datums\map_config.dm"
|
||||
#include "code\datums\mind.dm"
|
||||
#include "code\datums\mutable_appearance.dm"
|
||||
#include "code\datums\numbered_display.dm"
|
||||
@@ -2148,7 +2148,8 @@
|
||||
#include "code\modules\lighting\lighting_setup.dm"
|
||||
#include "code\modules\lighting\lighting_source.dm"
|
||||
#include "code\modules\lighting\lighting_turf.dm"
|
||||
#include "code\modules\mapping\dmm_suite.dm"
|
||||
#include "code\modules\mapping\map_config.dm"
|
||||
#include "code\modules\mapping\map_orientation_pattern.dm"
|
||||
#include "code\modules\mapping\map_template.dm"
|
||||
#include "code\modules\mapping\minimaps.dm"
|
||||
#include "code\modules\mapping\preloader.dm"
|
||||
|
||||
Reference in New Issue
Block a user