mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 00:29:02 +01:00
[MIRROR] Multi-Z Support for Lazy Templates | Cleans up some turf flag misuse [MDB IGNORE] (#23794)
* Multi-Z Support for Lazy Templates | Cleans up some turf flag misuse * Update hilbertshotel.dm * Modular proc ref --------- Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
co-authored by
Zephyr
Bloop
parent
4fa7c51670
commit
d9624bdf97
@@ -1,4 +1,10 @@
|
||||
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
|
||||
"aa" = (
|
||||
/turf/open/water,
|
||||
/area/awaymission/beach)
|
||||
"ab" = (
|
||||
/turf/open/lava,
|
||||
/area/awaymission/caves)
|
||||
"bX" = (
|
||||
/turf/closed/indestructible/abductor{
|
||||
icon_state = "alien11"
|
||||
@@ -592,3 +598,515 @@ bX
|
||||
Zf
|
||||
Xy
|
||||
"}
|
||||
|
||||
(1,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(2,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(3,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(4,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(5,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(6,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(7,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(8,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(9,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(10,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(11,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(12,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(13,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(14,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
(15,1,2) = {"
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
aa
|
||||
"}
|
||||
|
||||
(1,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(2,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(3,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(4,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(5,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(6,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(7,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(8,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(9,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(10,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(11,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(12,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(13,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(14,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
(15,1,3) = {"
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
"}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/// Fired on the lazy template datum when the template is finished loading. (list/loaded_atoms)
|
||||
#define COMSIG_LAZY_TEMPLATE_LOADED "lazy_template_loaded"
|
||||
@@ -88,7 +88,10 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
//TURF FLAGS
|
||||
/// If a turf cant be jaunted through.
|
||||
#define NOJAUNT (1<<0)
|
||||
/// If a turf is an usused reservation turf awaiting assignment
|
||||
#define UNUSED_RESERVATION_TURF (1<<1)
|
||||
/// If a turf is a reserved turf
|
||||
#define RESERVATION_TURF (1<<2)
|
||||
/// Blocks lava rivers being generated on the turf.
|
||||
#define NO_LAVA_GEN (1<<3)
|
||||
/// Blocks ruins spawning on the turf.
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
/// Attempt to get the turf below the provided one according to Z traits
|
||||
#define GET_TURF_BELOW(turf) ((!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_DOWN]) ? null : get_step((turf), DOWN))
|
||||
#define GET_TURF_BELOW(turf) ( \
|
||||
(turf.turf_flags & RESERVATION_TURF) ? SSmapping.get_reservation_from_turf(turf)?.get_turf_below(turf) : \
|
||||
(!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_DOWN]) ? null : get_step((turf), DOWN))
|
||||
/// Attempt to get the turf above the provided one according to Z traits
|
||||
#define GET_TURF_ABOVE(turf) ((!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_UP]) ? null : get_step((turf), UP))
|
||||
#define GET_TURF_ABOVE(turf) ( \
|
||||
(turf.turf_flags & RESERVATION_TURF) ? SSmapping.get_reservation_from_turf(turf)?.get_turf_above(turf) : \
|
||||
(!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_UP]) ? null : get_step((turf), UP))
|
||||
|
||||
@@ -75,6 +75,7 @@ DEFINE_BITFIELD(turf_flags, list(
|
||||
"NOJAUNT" = NOJAUNT,
|
||||
"IS_SOLID" = IS_SOLID,
|
||||
"UNUSED_RESERVATION_TURF" = UNUSED_RESERVATION_TURF,
|
||||
"RESERVATION_TURF" = RESERVATION_TURF,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(car_traits, list(
|
||||
|
||||
@@ -127,6 +127,9 @@ GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
|
||||
GLOBAL_LIST_EMPTY(ruin_landmarks)
|
||||
GLOBAL_LIST_EMPTY(bar_areas)
|
||||
|
||||
/// List of all the maps that have been cached for /proc/load_map
|
||||
GLOBAL_LIST_EMPTY(cached_maps)
|
||||
|
||||
/// Away missions
|
||||
GLOBAL_LIST_EMPTY(vr_spawnpoints)
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
unused_turfs["[T.z]"] |= T
|
||||
var/area/old_area = T.loc
|
||||
old_area.turfs_to_uncontain += T
|
||||
T.flags_1 |= UNUSED_RESERVATION_TURF
|
||||
T.turf_flags = UNUSED_RESERVATION_TURF
|
||||
world_contents += T
|
||||
world_turf_contents += T
|
||||
packet.len--
|
||||
@@ -309,6 +309,10 @@ SUBSYSTEM_DEF(mapping)
|
||||
returning += M
|
||||
qdel(T, TRUE)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/get_reservation_from_turf(turf/T)
|
||||
RETURN_TYPE(/datum/turf_reservation)
|
||||
return used_turfs[T]
|
||||
|
||||
/* Nuke threats, for making the blue tiles on the station go RED
|
||||
Used by the AI doomsday and the self-destruct nuke.
|
||||
*/
|
||||
@@ -695,26 +699,34 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
num_of_res_levels++
|
||||
return add_new_zlevel("Transit/Reserved #[num_of_res_levels]", list(ZTRAIT_RESERVED = TRUE))
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/RequestBlockReservation(width, height, z, type = /datum/turf_reservation, turf_type_override)
|
||||
UNTIL((!z || reservation_ready["[z]"]) && !clearing_reserved_turfs)
|
||||
var/datum/turf_reservation/reserve = new type
|
||||
if(turf_type_override)
|
||||
/// Requests a /datum/turf_reservation based on the given width, height, and z_size. You can specify a z_reservation to use a specific z level, or leave it null to use any z level.
|
||||
/datum/controller/subsystem/mapping/proc/request_turf_block_reservation(
|
||||
width,
|
||||
height,
|
||||
z_size = 1,
|
||||
z_reservation = null,
|
||||
reservation_type = /datum/turf_reservation,
|
||||
turf_type_override = null,
|
||||
)
|
||||
UNTIL((!z_reservation || reservation_ready["[z_reservation]"]) && !clearing_reserved_turfs)
|
||||
var/datum/turf_reservation/reserve = new reservation_type
|
||||
if(!isnull(turf_type_override))
|
||||
reserve.turf_type = turf_type_override
|
||||
if(!z)
|
||||
if(!z_reservation)
|
||||
for(var/i in levels_by_trait(ZTRAIT_RESERVED))
|
||||
if(reserve.Reserve(width, height, i))
|
||||
if(reserve.reserve(width, height, z_size, i))
|
||||
return reserve
|
||||
//If we didn't return at this point, theres a good chance we ran out of room on the exisiting reserved z levels, so lets try a new one
|
||||
var/datum/space_level/newReserved = add_reservation_zlevel()
|
||||
initialize_reserved_level(newReserved.z_value)
|
||||
if(reserve.Reserve(width, height, newReserved.z_value))
|
||||
if(reserve.reserve(width, height, z_size, newReserved.z_value))
|
||||
return reserve
|
||||
else
|
||||
if(!level_trait(z, ZTRAIT_RESERVED))
|
||||
if(!level_trait(z_reservation, ZTRAIT_RESERVED))
|
||||
qdel(reserve)
|
||||
return
|
||||
else
|
||||
if(reserve.Reserve(width, height, z))
|
||||
if(reserve.reserve(width, height, z_size, z_reservation))
|
||||
return reserve
|
||||
QDEL_NULL(reserve)
|
||||
|
||||
@@ -732,7 +744,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
var/block = block(A, B)
|
||||
for(var/turf/T as anything in block)
|
||||
// No need to empty() these, because they just got created and are already /turf/open/space/basic.
|
||||
T.flags_1 |= UNUSED_RESERVATION_TURF
|
||||
T.turf_flags = UNUSED_RESERVATION_TURF
|
||||
CHECK_TICK
|
||||
|
||||
// Gotta create these suckers if we've not done so already
|
||||
|
||||
@@ -617,12 +617,18 @@ SUBSYSTEM_DEF(shuttle)
|
||||
if(WEST)
|
||||
transit_path = /turf/open/space/transit/west
|
||||
|
||||
var/datum/turf_reservation/proposal = SSmapping.RequestBlockReservation(transit_width, transit_height, null, /datum/turf_reservation/transit, transit_path)
|
||||
var/datum/turf_reservation/proposal = SSmapping.request_turf_block_reservation(
|
||||
transit_width,
|
||||
transit_height,
|
||||
1,
|
||||
reservation_type = /datum/turf_reservation/transit,
|
||||
turf_type_override = transit_path,
|
||||
)
|
||||
|
||||
if(!istype(proposal))
|
||||
return FALSE
|
||||
|
||||
var/turf/bottomleft = locate(proposal.bottom_left_coords[1], proposal.bottom_left_coords[2], proposal.bottom_left_coords[3])
|
||||
var/turf/bottomleft = proposal.bottom_left_turfs[1]
|
||||
// Then create a transit docking port in the middle
|
||||
var/coords = M.return_coords(0, 0, dock_dir)
|
||||
/* 0------2
|
||||
@@ -893,10 +899,15 @@ SUBSYSTEM_DEF(shuttle)
|
||||
/datum/controller/subsystem/shuttle/proc/load_template(datum/map_template/shuttle/loading_template)
|
||||
. = FALSE
|
||||
// Load shuttle template to a fresh block reservation.
|
||||
preview_reservation = SSmapping.RequestBlockReservation(loading_template.width, loading_template.height, type = /datum/turf_reservation/transit)
|
||||
preview_reservation = SSmapping.request_turf_block_reservation(
|
||||
loading_template.width,
|
||||
loading_template.height,
|
||||
1,
|
||||
reservation_type = /datum/turf_reservation/transit,
|
||||
)
|
||||
if(!preview_reservation)
|
||||
CRASH("failed to reserve an area for shuttle template loading")
|
||||
var/turf/bottom_left = TURF_FROM_COORDS_LIST(preview_reservation.bottom_left_coords)
|
||||
var/turf/bottom_left = preview_reservation.bottom_left_turfs[1]
|
||||
loading_template.load(bottom_left, centered = FALSE, register = FALSE)
|
||||
|
||||
var/affected = loading_template.get_affected_turfs(bottom_left, centered=FALSE)
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
/datum/symptom/heal/starlight/proc/CanTileHealDirectional(turf/turf_to_check, direction)
|
||||
if(direction == UP)
|
||||
turf_to_check = turf_to_check.above()
|
||||
turf_to_check = GET_TURF_ABOVE(turf_to_check)
|
||||
if(!turf_to_check)
|
||||
return STARLIGHT_CANNOT_HEAL
|
||||
var/area/area_to_check = get_area(turf_to_check)
|
||||
@@ -98,9 +98,9 @@
|
||||
if(istransparentturf(turf_to_check) || istype(turf_to_check, /turf/open/openspace))
|
||||
// Check above or below us
|
||||
if(direction == UP)
|
||||
turf_to_check = turf_to_check.above()
|
||||
turf_to_check = GET_TURF_ABOVE(turf_to_check)
|
||||
else
|
||||
turf_to_check = turf_to_check.below()
|
||||
turf_to_check = GET_TURF_BELOW(turf_to_check)
|
||||
|
||||
// If we found a turf above or below us,
|
||||
// then we can rerun the loop on the newly found turf / area
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
return
|
||||
var/turf/checked_turf = get_turf(target)
|
||||
while(!isnull(checked_turf))
|
||||
checked_turf = checked_turf.above()
|
||||
checked_turf = GET_TURF_ABOVE(checked_turf)
|
||||
if(checked_turf?.z == user.z)
|
||||
INVOKE_ASYNC(source, TYPE_PROC_REF(/obj/item, handle_openspace_click), checked_turf, user, user.CanReach(checked_turf, source), click_parameters)
|
||||
break
|
||||
|
||||
@@ -103,7 +103,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
|
||||
if(!holding)
|
||||
return
|
||||
|
||||
var/turf/visual_target = to_display.above()
|
||||
var/turf/visual_target = GET_TURF_ABOVE(to_display)
|
||||
/// Basically, if we used to be under a non transparent turf, but are no longer in that position
|
||||
/// Then we add to the transparent turf we're now under, and nuke the old object
|
||||
if(!istransparentturf(visual_target))
|
||||
@@ -120,7 +120,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
|
||||
turf_sources[to_display] = sources
|
||||
sources |= source
|
||||
|
||||
var/turf/visual_target = to_display.above()
|
||||
var/turf/visual_target = GET_TURF_ABOVE(to_display)
|
||||
if(istransparentturf(visual_target) || isopenspaceturf(visual_target))
|
||||
visual_target.vis_contents += to_display
|
||||
else
|
||||
@@ -142,7 +142,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
|
||||
if(holding)
|
||||
qdel(holding)
|
||||
else
|
||||
var/turf/visual_target = to_hide.above()
|
||||
var/turf/visual_target = GET_TURF_ABOVE(to_hide)
|
||||
visual_target.vis_contents -= to_hide
|
||||
|
||||
if(!length(turf_sources) && !QDELETED(src))
|
||||
@@ -201,7 +201,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
|
||||
|
||||
///Updates the viscontents or underlays below this tile.
|
||||
/datum/element/turf_z_transparency/proc/update_multi_z(turf/our_turf)
|
||||
var/turf/below_turf = our_turf.below()
|
||||
var/turf/below_turf = GET_TURF_BELOW(our_turf)
|
||||
if(below_turf) // If we actually have something below us, display it.
|
||||
for(var/turf/partner in range(1, below_turf))
|
||||
// We use our z here to ensure the pillar is actually on our level
|
||||
@@ -228,7 +228,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z)
|
||||
return TRUE
|
||||
|
||||
/datum/element/turf_z_transparency/proc/clear_multiz(turf/our_turf)
|
||||
var/turf/below_turf = our_turf.below()
|
||||
var/turf/below_turf = GET_TURF_BELOW(our_turf)
|
||||
if(below_turf) // If we actually have something below us, we need to clear ourselves from it
|
||||
for(var/turf/partner in range(1, below_turf))
|
||||
// We use our z here to ensure the pillar is actually on our level
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
var/key
|
||||
var/map_dir = "_maps/templates/lazy_templates"
|
||||
var/map_name
|
||||
var/map_width
|
||||
var/map_height
|
||||
|
||||
/datum/lazy_template/New()
|
||||
reservations = list()
|
||||
@@ -46,25 +44,64 @@
|
||||
if(!load_path || !fexists(load_path))
|
||||
CRASH("lazy template [type] has an invalid load_path: '[load_path]', check directory and map name!")
|
||||
|
||||
var/datum/map_template/loading = new(path = load_path, cache = TRUE)
|
||||
if(!loading.cached_map)
|
||||
var/datum/parsed_map/parsed_template = load_map(
|
||||
file(load_path),
|
||||
measure_only = TRUE,
|
||||
)
|
||||
if(isnull(parsed_template.parsed_bounds))
|
||||
CRASH("Failed to cache lazy template for loading: '[key]'")
|
||||
|
||||
var/datum/turf_reservation/reservation = SSmapping.RequestBlockReservation(loading.width, loading.height)
|
||||
var/width = parsed_template.parsed_bounds[MAP_MAXX] - parsed_template.parsed_bounds[MAP_MINX] + 1
|
||||
var/height = parsed_template.parsed_bounds[MAP_MAXY] - parsed_template.parsed_bounds[MAP_MINY] + 1
|
||||
var/datum/turf_reservation/reservation = SSmapping.request_turf_block_reservation(
|
||||
width,
|
||||
height,
|
||||
parsed_template.parsed_bounds[MAP_MAXZ],
|
||||
)
|
||||
if(!reservation)
|
||||
CRASH("Failed to reserve a block for lazy template: '[key]'")
|
||||
|
||||
if(!loading.load(coords2turf(reservation.bottom_left_coords)))
|
||||
CRASH("Failed to load lazy template: '[key]'")
|
||||
reservations += reservation
|
||||
var/list/my_loaded_atoms = list()
|
||||
for(var/z_idx in parsed_template.parsed_bounds[MAP_MAXZ] to 1 step -1)
|
||||
var/turf/bottom_left = reservation.bottom_left_turfs[z_idx]
|
||||
var/turf/top_right = reservation.top_right_turfs[z_idx]
|
||||
load_map(
|
||||
file(load_path),
|
||||
bottom_left.x,
|
||||
bottom_left.y,
|
||||
bottom_left.z,
|
||||
z_upper = z_idx,
|
||||
z_lower = z_idx,
|
||||
)
|
||||
var/list/to_init = list()
|
||||
|
||||
// turfs can never be duplicated so keep them out of the below list to optimize O(n)
|
||||
var/list/turfs = list()
|
||||
// areas can be duplicated but lets keep them seperate for efficiency
|
||||
var/list/areas = list()
|
||||
// everything else that can be duplicated, such as areas or large objects
|
||||
var/list/not_turfs = list()
|
||||
for(var/turf/turf as anything in block(bottom_left, top_right))
|
||||
turfs += turf
|
||||
areas |= get_area(turf)
|
||||
for(var/thing in turf.get_all_contents())
|
||||
// atoms can actually be in the contents of two or more turfs based on its icon/bound size
|
||||
// see https://www.byond.com/docs/ref/index.html#/atom/var/contents
|
||||
not_turfs |= thing
|
||||
|
||||
SSatoms.InitializeAtoms(to_init)
|
||||
// we don't need to check for duplicates here
|
||||
my_loaded_atoms += not_turfs
|
||||
my_loaded_atoms += turfs
|
||||
my_loaded_atoms += areas
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_LAZY_TEMPLATE_LOADED, my_loaded_atoms)
|
||||
reservations += reservation
|
||||
return reservation
|
||||
|
||||
/datum/lazy_template/nukie_base
|
||||
key = LAZY_TEMPLATE_KEY_NUKIEBASE
|
||||
map_name = "nukie_base"
|
||||
map_width = 89
|
||||
map_height = 100
|
||||
|
||||
/datum/lazy_template/wizard_dem
|
||||
key = LAZY_TEMPLATE_KEY_WIZARDDEN
|
||||
|
||||
@@ -40,8 +40,9 @@
|
||||
return
|
||||
if(mapload)
|
||||
for (var/i in 1 to range)
|
||||
if(!isgroundlessturf(loc) || GET_TURF_BELOW(loc))
|
||||
new /obj/effect/decal/cleanable/xenoblood/xsplatter(loc)
|
||||
var/turf/my_turf = get_turf(src)
|
||||
if(!isgroundlessturf(my_turf) || GET_TURF_BELOW(my_turf))
|
||||
new /obj/effect/decal/cleanable/xenoblood/xsplatter(my_turf)
|
||||
if (!step_to(src, get_step(src, direction), 0))
|
||||
break
|
||||
return
|
||||
|
||||
@@ -159,8 +159,9 @@
|
||||
return
|
||||
if(mapload)
|
||||
for (var/i in 1 to range)
|
||||
if(!isgroundlessturf(loc) || GET_TURF_BELOW(loc))
|
||||
new /obj/effect/decal/cleanable/blood/splatter(loc)
|
||||
var/turf/my_turf = get_turf(src)
|
||||
if(!isgroundlessturf(my_turf) || GET_TURF_BELOW(my_turf))
|
||||
new /obj/effect/decal/cleanable/blood/splatter(my_turf)
|
||||
if (!step_to(src, get_step(src, direction), 0))
|
||||
break
|
||||
return
|
||||
|
||||
@@ -25,8 +25,9 @@
|
||||
return
|
||||
if(mapload)
|
||||
for (var/i in 1 to range)
|
||||
if(prob(40) && (!isgroundlessturf(loc) || GET_TURF_BELOW(loc)))
|
||||
new /obj/effect/decal/cleanable/oil/streak(loc)
|
||||
var/turf/my_turf = get_turf(src)
|
||||
if(prob(40) && (!isgroundlessturf(my_turf) || GET_TURF_BELOW(my_turf)))
|
||||
new /obj/effect/decal/cleanable/oil/streak(my_turf)
|
||||
if (!step_to(src, get_step(src, direction), 0))
|
||||
break
|
||||
return
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
return
|
||||
var/area/destination_area = newloc.loc
|
||||
movedelay = world.time + movespeed
|
||||
if(newloc.flags_1 & NOJAUNT)
|
||||
if(newloc.turf_flags & NOJAUNT)
|
||||
to_chat(user, span_warning("Some strange aura is blocking the way."))
|
||||
return
|
||||
if(destination_area.area_flags & NOTELEPORT || SSmapping.level_trait(newloc.z, ZTRAIT_NOPHASE))
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
return
|
||||
if(target.is_blocked_turf(exclude_mobs = TRUE))
|
||||
return
|
||||
var/turf/above = GET_TURF_ABOVE(user)
|
||||
var/turf/user_turf = get_turf(user)
|
||||
var/turf/above = GET_TURF_ABOVE(user_turf)
|
||||
if(!isopenspaceturf(above) || !above.Adjacent(target)) //are we below a hole, is the target blocked, is the target adjacent to our hole
|
||||
balloon_alert(user, "blocked!")
|
||||
return
|
||||
var/turf/user_turf = get_turf(user)
|
||||
var/away_dir = get_dir(above, target)
|
||||
user.visible_message(span_notice("[user] begins climbing upwards with [src]."), span_notice("You get to work on properly hooking [src] and going upwards."))
|
||||
playsound(target, 'sound/effects/picaxe1.ogg', 50) //plays twice so people above and below can hear
|
||||
@@ -47,11 +47,11 @@
|
||||
if(do_after(user, climb_time, target))
|
||||
user.Move(target)
|
||||
uses--
|
||||
|
||||
|
||||
if(uses <= 0)
|
||||
user.visible_message(span_warning("[src] snaps and tears apart!"))
|
||||
qdel(src)
|
||||
|
||||
|
||||
QDEL_LIST(effects)
|
||||
|
||||
/obj/item/climbing_hook/emergency
|
||||
|
||||
@@ -105,7 +105,9 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
|
||||
//We do this here so anything that doesn't want to persist can clear itself
|
||||
var/list/old_listen_lookup = _listen_lookup?.Copy()
|
||||
var/list/old_signal_procs = _signal_procs?.Copy()
|
||||
var/carryover_turf_flags = (RESERVATION_TURF | UNUSED_RESERVATION_TURF) & turf_flags
|
||||
var/turf/new_turf = new path(src)
|
||||
new_turf.turf_flags |= carryover_turf_flags
|
||||
|
||||
// WARNING WARNING
|
||||
// Turfs DO NOT lose their signals when they get replaced, REMEMBER THIS
|
||||
|
||||
@@ -235,7 +235,8 @@ GLOBAL_LIST_EMPTY(dug_up_basalt)
|
||||
turf_flags = CAN_BE_DIRTY_1 | IS_SOLID | NO_RUST | NO_RUINS
|
||||
|
||||
/turf/open/misc/asteroid/snow/icemoon/do_not_scrape
|
||||
turf_flags = CAN_BE_DIRTY_1 | IS_SOLID | NO_RUST | NO_CLEARING
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
turf_flags = IS_SOLID | NO_RUST | NO_CLEARING
|
||||
|
||||
/turf/open/lava/plasma/ice_moon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
|
||||
/turf/open/openspace/icemoon/Initialize(mapload)
|
||||
. = ..()
|
||||
var/turf/T = below()
|
||||
var/turf/T = GET_TURF_BELOW(src)
|
||||
//I wonder if I should error here
|
||||
if(!T)
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon_state = "black"
|
||||
dir = SOUTH
|
||||
baseturfs = /turf/open/space/transit
|
||||
flags_1 = NOJAUNT //This line goes out to every wizard that ever managed to escape the den. I'm sorry.
|
||||
turf_flags = NOJAUNT //This line goes out to every wizard that ever managed to escape the den. I'm sorry.
|
||||
explosive_resistance = INFINITY
|
||||
|
||||
/turf/open/space/transit/Initialize(mapload)
|
||||
|
||||
+11
-7
@@ -399,31 +399,35 @@ GLOBAL_VAR(restart_counter)
|
||||
else
|
||||
hub_password = "SORRYNOPASSWORD"
|
||||
|
||||
// If this is called as a part of maploading you cannot call it on the newly loaded map zs, because those get handled later on in the pipeline
|
||||
/world/proc/increaseMaxX(new_maxx, max_zs_to_load = maxz)
|
||||
/**
|
||||
* Handles incresing the world's maxx var and intializing the new turfs and assigning them to the global area.
|
||||
* If map_load_z_cutoff is passed in, it will only load turfs up to that z level, inclusive.
|
||||
* This is because maploading will handle the turfs it loads itself.
|
||||
*/
|
||||
/world/proc/increase_max_x(new_maxx, map_load_z_cutoff = maxz)
|
||||
if(new_maxx <= maxx)
|
||||
return
|
||||
var/old_max = world.maxx
|
||||
maxx = new_maxx
|
||||
if(!max_zs_to_load)
|
||||
if(!map_load_z_cutoff)
|
||||
return
|
||||
var/area/global_area = GLOB.areas_by_type[world.area] // We're guaranteed to be touching the global area, so we'll just do this
|
||||
var/list/to_add = block(
|
||||
locate(old_max + 1, 1, 1),
|
||||
locate(maxx, maxy, max_zs_to_load))
|
||||
locate(maxx, maxy, map_load_z_cutoff))
|
||||
global_area.contained_turfs += to_add
|
||||
|
||||
/world/proc/increaseMaxY(new_maxy, max_zs_to_load = maxz)
|
||||
/world/proc/increase_max_y(new_maxy, map_load_z_cutoff = maxz)
|
||||
if(new_maxy <= maxy)
|
||||
return
|
||||
var/old_maxy = maxy
|
||||
maxy = new_maxy
|
||||
if(!max_zs_to_load)
|
||||
if(!map_load_z_cutoff)
|
||||
return
|
||||
var/area/global_area = GLOB.areas_by_type[world.area] // We're guarenteed to be touching the global area, so we'll just do this
|
||||
var/list/to_add = block(
|
||||
locate(1, old_maxy + 1, 1),
|
||||
locate(maxx, maxy, max_zs_to_load))
|
||||
locate(maxx, maxy, map_load_z_cutoff))
|
||||
global_area.contained_turfs += to_add
|
||||
|
||||
/world/proc/incrementMaxZ()
|
||||
|
||||
@@ -1059,7 +1059,7 @@ GLOBAL_PROTECT(admin_verbs_poll)
|
||||
|
||||
if(!isobserver(usr))
|
||||
admin_ghost()
|
||||
usr.forceMove(coords2turf(reservation.bottom_left_coords))
|
||||
usr.forceMove(reservation.bottom_left_turfs[1])
|
||||
|
||||
message_admins("[key_name_admin(usr)] has loaded lazy template '[choice]'")
|
||||
to_chat(usr, span_boldnicegreen("Template loaded, you have been moved to the bottom left of the reservation."))
|
||||
|
||||
@@ -112,9 +112,10 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
|
||||
if(!storageTurf) //Blame subsystems for not allowing this to be in Initialize
|
||||
if(!GLOB.hhStorageTurf)
|
||||
var/datum/map_template/hilbertshotelstorage/storageTemp = new()
|
||||
var/datum/turf_reservation/storageReservation = SSmapping.RequestBlockReservation(3, 3)
|
||||
storageTemp.load(locate(storageReservation.bottom_left_coords[1], storageReservation.bottom_left_coords[2], storageReservation.bottom_left_coords[3]))
|
||||
GLOB.hhStorageTurf = locate(storageReservation.bottom_left_coords[1]+1, storageReservation.bottom_left_coords[2]+1, storageReservation.bottom_left_coords[3])
|
||||
var/datum/turf_reservation/storageReservation = SSmapping.request_turf_block_reservation(1, 1, 1)
|
||||
var/turf/storage_turf = storageReservation.bottom_left_turfs[1]
|
||||
storageTemp.load(storage_turf)
|
||||
GLOB.hhStorageTurf = storage_turf
|
||||
else
|
||||
storageTurf = GLOB.hhStorageTurf
|
||||
if(tryActiveRoom(chosenRoomNumber, target))
|
||||
@@ -127,20 +128,30 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
|
||||
if(activeRooms["[roomNumber]"])
|
||||
var/datum/turf_reservation/roomReservation = activeRooms["[roomNumber]"]
|
||||
do_sparks(3, FALSE, get_turf(user))
|
||||
user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
|
||||
var/turf/room_bottom_left = roomReservation.bottom_left_turfs[1]
|
||||
user.forceMove(locate(
|
||||
room_bottom_left.x + hotelRoomTemp.landingZoneRelativeX,
|
||||
room_bottom_left.y + hotelRoomTemp.landingZoneRelativeY,
|
||||
room_bottom_left.z,
|
||||
))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/hilbertshotel/proc/tryStoredRoom(roomNumber, mob/user)
|
||||
if(storedRooms["[roomNumber]"])
|
||||
var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
|
||||
hotelRoomTempEmpty.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
|
||||
var/datum/turf_reservation/roomReservation = SSmapping.request_turf_block_reservation(hotelRoomTemp.width, hotelRoomTemp.height, 1)
|
||||
var/turf/room_turf = roomReservation.bottom_left_turfs[1]
|
||||
hotelRoomTempEmpty.load(room_turf)
|
||||
var/turfNumber = 1
|
||||
for(var/x in 0 to hotelRoomTemp.width-1)
|
||||
for(var/y in 0 to hotelRoomTemp.height-1)
|
||||
for(var/atom/movable/A in storedRooms["[roomNumber]"][turfNumber])
|
||||
if(istype(A.loc, /obj/item/abstracthotelstorage))//Don't want to recall something thats been moved
|
||||
A.forceMove(locate(roomReservation.bottom_left_coords[1] + x, roomReservation.bottom_left_coords[2] + y, roomReservation.bottom_left_coords[3]))
|
||||
A.forceMove(locate(
|
||||
room_turf.x + x,
|
||||
room_turf.y + y,
|
||||
room_turf.z,
|
||||
))
|
||||
turfNumber++
|
||||
for(var/obj/item/abstracthotelstorage/S in storageTurf)
|
||||
if((S.roomNumber == roomNumber) && (S.parentSphere == src))
|
||||
@@ -149,29 +160,39 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
|
||||
activeRooms["[roomNumber]"] = roomReservation
|
||||
linkTurfs(roomReservation, roomNumber)
|
||||
do_sparks(3, FALSE, get_turf(user))
|
||||
user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
|
||||
user.forceMove(locate(
|
||||
room_turf.x + hotelRoomTemp.landingZoneRelativeX,
|
||||
room_turf.y + hotelRoomTemp.landingZoneRelativeY,
|
||||
room_turf.z,
|
||||
))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/hilbertshotel/proc/sendToNewRoom(roomNumber, mob/user, chosen_room) //SKYRAT EDIT ADDITION - GHOST HOTEL UPDATE. Was sendToNewRoom(chosenRoomNumber, target)
|
||||
var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
|
||||
/obj/item/hilbertshotel/proc/sendToNewRoom(roomNumber, mob/user, chosen_room) //SKYRAT EDIT ADDITION - GHOST HOTEL UPDATE. Was sendToNewRoom(roomNumber, mob/user)
|
||||
var/datum/turf_reservation/roomReservation = SSmapping.request_turf_block_reservation(hotelRoomTemp.width, hotelRoomTemp.height, 1)
|
||||
var/turf/bottom_left = roomReservation.bottom_left_turfs[1]
|
||||
var/datum/map_template/load_from = hotelRoomTemp
|
||||
|
||||
if(ruinSpawned && roomNumber == GLOB.hhMysteryRoomNumber)
|
||||
hotelRoomTempLore.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
|
||||
else
|
||||
//SKYRAT EDIT ADDITION - GHOST HOTEL UPDATE
|
||||
switch(chosen_room)
|
||||
if("Apartment")
|
||||
ghost_cafe_rooms_apartment.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
|
||||
else
|
||||
//SKYRAT EDIT END
|
||||
hotelRoomTemp.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
|
||||
load_from = hotelRoomTempLore
|
||||
//SKYRAT EDIT ADDITION START - GHOST HOTEL UPDATE
|
||||
else if(chosen_room == "Apartment")
|
||||
load_from = ghost_cafe_rooms_apartment
|
||||
//SKYRAT EDIT ADDITION END
|
||||
|
||||
load_from.load(bottom_left)
|
||||
activeRooms["[roomNumber]"] = roomReservation
|
||||
linkTurfs(roomReservation, roomNumber)
|
||||
do_sparks(3, FALSE, get_turf(user))
|
||||
user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
|
||||
user.forceMove(locate(
|
||||
bottom_left.x + hotelRoomTemp.landingZoneRelativeX,
|
||||
bottom_left.y + hotelRoomTemp.landingZoneRelativeY,
|
||||
bottom_left.z,
|
||||
))
|
||||
|
||||
/obj/item/hilbertshotel/proc/linkTurfs(datum/turf_reservation/currentReservation, currentRoomnumber)
|
||||
var/area/misc/hilbertshotel/currentArea = get_area(locate(currentReservation.bottom_left_coords[1], currentReservation.bottom_left_coords[2], currentReservation.bottom_left_coords[3]))
|
||||
var/turf/room_bottom_left = currentReservation.bottom_left_turfs[1]
|
||||
var/area/misc/hilbertshotel/currentArea = get_area(room_bottom_left)
|
||||
currentArea.name = "Hilbert's Hotel Room [currentRoomnumber]"
|
||||
currentArea.parentSphere = src
|
||||
currentArea.storageTurf = storageTurf
|
||||
@@ -187,9 +208,10 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
|
||||
if(activeRooms.len)
|
||||
for(var/x in activeRooms)
|
||||
var/datum/turf_reservation/room = activeRooms[x]
|
||||
var/turf/room_bottom_left = room.bottom_left_turfs[1]
|
||||
for(var/i in 0 to hotelRoomTemp.width-1)
|
||||
for(var/j in 0 to hotelRoomTemp.height-1)
|
||||
for(var/atom/movable/A in locate(room.bottom_left_coords[1] + i, room.bottom_left_coords[2] + j, room.bottom_left_coords[3]))
|
||||
for(var/atom/movable/A in locate(room_bottom_left.x + i, room_bottom_left.y + j, room_bottom_left.z))
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(M.mind)
|
||||
@@ -271,7 +293,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
|
||||
icon_state = "bluespace"
|
||||
base_icon_state = "bluespace"
|
||||
baseturfs = /turf/open/space/bluespace
|
||||
flags_1 = NOJAUNT
|
||||
turf_flags = NOJAUNT
|
||||
explosive_resistance = INFINITY
|
||||
var/obj/item/hilbertshotel/parentSphere
|
||||
|
||||
@@ -437,7 +459,11 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
|
||||
storeRoom()
|
||||
|
||||
/area/misc/hilbertshotel/proc/storeRoom()
|
||||
var/roomSize = (reservation.top_right_coords[1]-reservation.bottom_left_coords[1]+1)*(reservation.top_right_coords[2]-reservation.bottom_left_coords[2]+1)
|
||||
var/turf/room_bottom_left = reservation.bottom_left_turfs[1]
|
||||
var/turf/room_top_right = reservation.top_right_turfs[1]
|
||||
var/roomSize = \
|
||||
((room_top_right.x - room_bottom_left.x) + 1) * \
|
||||
((room_top_right.y - room_bottom_left.y) + 1)
|
||||
var/storage[roomSize]
|
||||
var/turfNumber = 1
|
||||
var/obj/item/abstracthotelstorage/storageObj = new(storageTurf)
|
||||
@@ -447,7 +473,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999))
|
||||
for(var/x in 0 to parentSphere.hotelRoomTemp.width-1)
|
||||
for(var/y in 0 to parentSphere.hotelRoomTemp.height-1)
|
||||
var/list/turfContents = list()
|
||||
for(var/atom/movable/A in locate(reservation.bottom_left_coords[1] + x, reservation.bottom_left_coords[2] + y, reservation.bottom_left_coords[3]))
|
||||
for(var/atom/movable/A in locate(room_bottom_left.x + x, room_bottom_left.y + y, room_bottom_left.z))
|
||||
if(ismob(A) && !isliving(A))
|
||||
continue //Don't want to store ghosts
|
||||
turfContents += A
|
||||
|
||||
@@ -133,7 +133,15 @@
|
||||
var/y = round((world.maxy - height) * 0.5) + 1
|
||||
|
||||
var/datum/space_level/level = SSmapping.add_new_zlevel(name, secret ? ZTRAITS_AWAY_SECRET : ZTRAITS_AWAY, contain_turfs = FALSE)
|
||||
var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=should_place_on_top, new_z = TRUE)
|
||||
var/datum/parsed_map/parsed = load_map(
|
||||
file(mappath),
|
||||
x,
|
||||
y,
|
||||
level.z_value,
|
||||
no_changeturf = (SSatoms.initialized == INITIALIZATION_INSSATOMS),
|
||||
place_on_top = should_place_on_top,
|
||||
new_z = TRUE,
|
||||
)
|
||||
var/list/bounds = parsed.bounds
|
||||
if(!bounds)
|
||||
return FALSE
|
||||
@@ -177,7 +185,14 @@
|
||||
|
||||
UNSETEMPTY(turf_blacklist)
|
||||
parsed.turf_blacklist = turf_blacklist
|
||||
if(!parsed.load(T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=should_place_on_top))
|
||||
if(!parsed.load(
|
||||
T.x,
|
||||
T.y,
|
||||
T.z,
|
||||
crop_map = TRUE,
|
||||
no_changeturf = (SSatoms.initialized == INITIALIZATION_INSSATOMS),
|
||||
place_on_top = should_place_on_top,
|
||||
))
|
||||
return
|
||||
|
||||
var/list/bounds = parsed.bounds
|
||||
|
||||
+159
-54
@@ -114,26 +114,72 @@
|
||||
var/turfsSkipped = 0
|
||||
#endif
|
||||
|
||||
/datum/parsed_map/proc/copy()
|
||||
// Avoids duped work just in case
|
||||
build_cache()
|
||||
var/datum/parsed_map/newfriend = new()
|
||||
newfriend.original_path = original_path
|
||||
newfriend.map_format = map_format
|
||||
newfriend.key_len = key_len
|
||||
newfriend.line_len = line_len
|
||||
newfriend.grid_models = grid_models.Copy()
|
||||
newfriend.gridSets = gridSets.Copy()
|
||||
newfriend.modelCache = modelCache.Copy()
|
||||
newfriend.parsed_bounds = parsed_bounds.Copy()
|
||||
// Copy parsed bounds to reset to initial values
|
||||
newfriend.bounds = parsed_bounds.Copy()
|
||||
newfriend.turf_blacklist = turf_blacklist?.Copy()
|
||||
return newfriend
|
||||
|
||||
//text trimming (both directions) helper macro
|
||||
#define TRIM_TEXT(text) (trim_reduced(text))
|
||||
|
||||
/// Shortcut function to parse a map and apply it to the world.
|
||||
///
|
||||
/// - `dmm_file`: A .dmm file to load (Required).
|
||||
/// - `x_offset`, `y_offset`, `z_offset`: Positions representign where to load 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/proc/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/proc/PlaceOnTop] rather than [/turf/proc/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, new_z)
|
||||
var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_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, new_z = new_z)
|
||||
return parsed
|
||||
/**
|
||||
* Helper and recommened way to load a map file
|
||||
* - dmm_file: The path to the map file
|
||||
* - x_offset: The x offset to load the map at
|
||||
* - y_offset: The y offset to load the map at
|
||||
* - z_offset: The z offset to load the map at
|
||||
* - crop_map: If true, the map will be cropped to the world bounds
|
||||
* - measure_only: If true, the map will not be loaded, but the bounds will be calculated
|
||||
* - no_changeturf: If true, the map will not call /turf/AfterChange
|
||||
* - x_lower: The minimum x coordinate to load
|
||||
* - x_upper: The maximum x coordinate to load
|
||||
* - y_lower: The minimum y coordinate to load
|
||||
* - y_upper: The maximum y coordinate to load
|
||||
* - z_lower: The minimum z coordinate to load
|
||||
* - z_upper: The maximum z coordinate to load
|
||||
* - place_on_top: Whether to use /turf/proc/PlaceOnTop rather than /turf/proc/ChangeTurf
|
||||
* - new_z: If true, a new z level will be created for the map
|
||||
*/
|
||||
/proc/load_map(
|
||||
dmm_file,
|
||||
x_offset = 0,
|
||||
y_offset = 0,
|
||||
z_offset = 0,
|
||||
crop_map = FALSE,
|
||||
measure_only = FALSE,
|
||||
no_changeturf = FALSE,
|
||||
x_lower = -INFINITY,
|
||||
x_upper = INFINITY,
|
||||
y_lower = -INFINITY,
|
||||
y_upper = INFINITY,
|
||||
z_lower = -INFINITY,
|
||||
z_upper = INFINITY,
|
||||
place_on_top = FALSE,
|
||||
new_z = FALSE,
|
||||
)
|
||||
if(!(dmm_file in GLOB.cached_maps))
|
||||
GLOB.cached_maps[dmm_file] = new /datum/parsed_map(dmm_file)
|
||||
|
||||
var/datum/parsed_map/parsed_map = GLOB.cached_maps[dmm_file]
|
||||
parsed_map = parsed_map.copy()
|
||||
if(!measure_only && !isnull(parsed_map.bounds))
|
||||
parsed_map.load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
|
||||
return parsed_map
|
||||
|
||||
/// 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)
|
||||
/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)
|
||||
// This proc sleeps for like 6 seconds. why?
|
||||
// Is it file accesses? if so, can those be done ahead of time, async to save on time here? I wonder.
|
||||
// Love ya :)
|
||||
@@ -184,20 +230,26 @@
|
||||
CRASH("Coords before model definition in DMM")
|
||||
|
||||
var/curr_x = text2num(regexOutput[3])
|
||||
|
||||
if(curr_x < x_lower || curr_x > x_upper)
|
||||
continue
|
||||
|
||||
var/curr_y = text2num(regexOutput[4])
|
||||
if(curr_y < y_lower || curr_y > y_upper)
|
||||
continue
|
||||
|
||||
var/curr_z = text2num(regexOutput[5])
|
||||
if(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(regexOutput[4])
|
||||
gridSet.zcrd = text2num(regexOutput[5])
|
||||
gridSet.ycrd = curr_y
|
||||
gridSet.zcrd = curr_z
|
||||
|
||||
bounds[MAP_MINX] = min(bounds[MAP_MINX], curr_x)
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], gridSet.zcrd)
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], gridSet.zcrd)
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], curr_y)
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], curr_z)
|
||||
|
||||
var/list/gridLines = splittext(regexOutput[6], "\n")
|
||||
gridSet.gridLines = gridLines
|
||||
@@ -238,16 +290,29 @@
|
||||
bounds[MAP_MAXX] = clamp(bounds[MAP_MAXX], x_lower, x_upper)
|
||||
bounds[MAP_MINY] = clamp(bounds[MAP_MINY], y_lower, y_upper)
|
||||
bounds[MAP_MAXY] = clamp(bounds[MAP_MAXY], y_lower, y_upper)
|
||||
bounds[MAP_MINZ] = clamp(bounds[MAP_MINZ], z_lower, z_upper)
|
||||
bounds[MAP_MAXZ] = clamp(bounds[MAP_MAXZ], z_lower, z_upper)
|
||||
|
||||
parsed_bounds = src.bounds
|
||||
src.key_len = key_len
|
||||
src.line_len = line_len
|
||||
|
||||
/// 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, whitelist = FALSE, new_z)
|
||||
/// Iterates over all grid sets and returns ones with z values within the given bounds. Inclusive
|
||||
/datum/parsed_map/proc/filter_grid_sets_based_on_z_bounds(lower_z, upper_z)
|
||||
var/list/filtered_sets = list()
|
||||
for(var/datum/grid_set/grid_set as anything in gridSets)
|
||||
if(grid_set.zcrd < lower_z)
|
||||
continue
|
||||
if(grid_set.zcrd > upper_z)
|
||||
continue
|
||||
filtered_sets += grid_set
|
||||
return filtered_sets
|
||||
|
||||
/// Load the parsed map into the world. You probably want [/proc/load_map]. Keep the signature the same.
|
||||
/datum/parsed_map/proc/load(x_offset = 0, y_offset = 0, z_offset = 0, crop_map = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, z_lower = -INFINITY, z_upper = INFINITY, place_on_top = FALSE, new_z = FALSE)
|
||||
//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, new_z)
|
||||
. = _load_impl(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
|
||||
Master.StopLoadingMap()
|
||||
|
||||
#define MAPLOADING_CHECK_TICK \
|
||||
@@ -262,7 +327,7 @@
|
||||
}
|
||||
|
||||
// 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, new_z = FALSE)
|
||||
/datum/parsed_map/proc/_load_impl(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
|
||||
PRIVATE_PROC(TRUE)
|
||||
// Tell ss atoms that we're doing maploading
|
||||
// We'll have to account for this in the following tick_checks so it doesn't overflow
|
||||
@@ -275,9 +340,9 @@
|
||||
var/sucessful = FALSE
|
||||
switch(map_format)
|
||||
if(MAP_TGM)
|
||||
sucessful = _tgm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
|
||||
sucessful = _tgm_load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
|
||||
else
|
||||
sucessful = _dmm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
|
||||
sucessful = _dmm_load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
|
||||
|
||||
// And we are done lads, call it off
|
||||
SSatoms.map_loader_stop(REF(src))
|
||||
@@ -309,7 +374,7 @@
|
||||
// In the tgm format, each gridset contains 255 lines, each line representing one tile, with 255 total gridsets
|
||||
// In the dmm format, each gridset contains 255 lines, each line representing one row of tiles, containing 255 * line length characters, with one gridset per z
|
||||
// You can think of dmm as storing maps in rows, whereas tgm stores them in columns
|
||||
/datum/parsed_map/proc/_tgm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
|
||||
/datum/parsed_map/proc/_tgm_load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
|
||||
// setup
|
||||
var/list/modelCache = build_cache(no_changeturf)
|
||||
var/space_key = modelCache[SPACE_KEY]
|
||||
@@ -330,12 +395,12 @@
|
||||
var/relative_y = first_column.ycrd
|
||||
var/highest_y = relative_y + y_relative_to_absolute
|
||||
|
||||
if(!cropMap && highest_y > world.maxy)
|
||||
if(!crop_map && highest_y > world.maxy)
|
||||
if(new_z)
|
||||
// Need to avoid improperly loaded area/turf_contents
|
||||
world.increaseMaxY(highest_y, max_zs_to_load = z_offset - 1)
|
||||
world.increase_max_y(highest_y, map_load_z_cutoff = z_offset - 1)
|
||||
else
|
||||
world.increaseMaxY(highest_y)
|
||||
world.increase_max_y(highest_y)
|
||||
expanded_y = TRUE
|
||||
|
||||
// Skip Y coords that are above the smallest of the three params
|
||||
@@ -345,7 +410,6 @@
|
||||
var/y_starting_skip = relative_y - y_skip_above
|
||||
highest_y -= y_starting_skip
|
||||
|
||||
|
||||
// Y is the LOWEST it will ever be here, so we can easily set a threshold for how low to go
|
||||
var/line_count = length(first_column.gridLines)
|
||||
var/lowest_y = relative_y - (line_count - 1) // -1 because we decrement at the end of the loop, not the start
|
||||
@@ -353,7 +417,7 @@
|
||||
|
||||
// X setup
|
||||
var/x_delta_with = x_upper
|
||||
if(cropMap)
|
||||
if(crop_map)
|
||||
// Take our smaller crop threshold yes?
|
||||
x_delta_with = min(x_delta_with, world.maxx)
|
||||
|
||||
@@ -367,33 +431,51 @@
|
||||
// If our relative x is greater then X upper, well then we've gotta limit our expansion
|
||||
var/delta = max(final_x - x_delta_with, 0)
|
||||
final_x -= delta
|
||||
if(final_x > world.maxx && !cropMap)
|
||||
if(final_x > world.maxx && !crop_map)
|
||||
if(new_z)
|
||||
// Need to avoid improperly loaded area/turf_contents
|
||||
world.increaseMaxX(final_x, max_zs_to_load = z_offset - 1)
|
||||
world.increase_max_x(final_x, map_load_z_cutoff = z_offset - 1)
|
||||
else
|
||||
world.increaseMaxX(final_x)
|
||||
world.increase_max_x(final_x)
|
||||
expanded_x = TRUE
|
||||
|
||||
var/lowest_x = max(x_lower, 1 - x_relative_to_absolute)
|
||||
|
||||
// Amount we offset the grid zcrd to get the true zcrd
|
||||
var/grid_z_offset = z_offset - 1
|
||||
var/z_upper_set = z_upper < INFINITY
|
||||
var/z_lower_set = z_lower > -INFINITY
|
||||
|
||||
// We make the assumption that the last block of turfs will have the highest embedded z in it
|
||||
var/highest_z = last_column.zcrd + z_offset - 1 // Lets not just make a new z level each time we increment maxz
|
||||
// true max zcrd
|
||||
var/map_bounds_z_max = last_column.zcrd
|
||||
var/z_upper_parsed = map_bounds_z_max + z_offset - 1
|
||||
if(z_upper_set)
|
||||
z_upper_parsed -= map_bounds_z_max - z_upper
|
||||
if(z_lower_set)
|
||||
var/offset_amount = z_lower - 1
|
||||
z_upper_parsed -= offset_amount
|
||||
grid_z_offset -= offset_amount
|
||||
|
||||
var/list/target_grid_sets = gridSets
|
||||
if(z_lower_set || z_upper_set) // bounds are set, filter out gridsets for z levels we don't want
|
||||
target_grid_sets = filter_grid_sets_based_on_z_bounds(z_lower, z_upper)
|
||||
|
||||
var/z_threshold = world.maxz
|
||||
if(highest_z > z_threshold && cropMap)
|
||||
for(var/i in z_threshold + 1 to highest_z) //create a new z_level if needed
|
||||
if(z_upper_parsed > z_threshold && crop_map)
|
||||
for(var/i in z_threshold + 1 to z_upper_parsed) //create a new z_level if needed
|
||||
world.incrementMaxZ()
|
||||
if(!no_changeturf)
|
||||
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called")
|
||||
|
||||
for(var/datum/grid_set/gset as anything in gridSets)
|
||||
for(var/datum/grid_set/gset as anything in target_grid_sets)
|
||||
var/true_xcrd = gset.xcrd + x_relative_to_absolute
|
||||
|
||||
// any cutoff of x means we just shouldn't iterate this gridset
|
||||
if(final_x < true_xcrd || lowest_x > gset.xcrd)
|
||||
continue
|
||||
|
||||
var/zcrd = gset.zcrd + z_offset - 1
|
||||
var/zcrd = gset.zcrd + grid_z_offset
|
||||
// If we're using changeturf, we disable it if we load into a z level we JUST created
|
||||
var/no_afterchange = no_changeturf || zcrd > z_threshold
|
||||
|
||||
@@ -420,7 +502,7 @@
|
||||
if(!cache)
|
||||
SSatoms.map_loader_stop(REF(src))
|
||||
CRASH("Undefined model key in DMM: [gset.gridLines[i]]")
|
||||
build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z)
|
||||
build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, place_on_top, new_z)
|
||||
|
||||
// only bother with bounds that actually exist
|
||||
if(!first_found)
|
||||
@@ -444,7 +526,7 @@
|
||||
/// Stanrdard loading, not used in production
|
||||
/// Doesn't take advantage of any tgm optimizations, which makes it slower but also more general
|
||||
/// Use this if for some reason your map format is messy
|
||||
/datum/parsed_map/proc/_dmm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
|
||||
/datum/parsed_map/proc/_dmm_load(x_offset, y_offset, z_offset, crop_map, no_changeturf, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, place_on_top, new_z)
|
||||
// setup
|
||||
var/list/modelCache = build_cache(no_changeturf)
|
||||
var/space_key = modelCache[SPACE_KEY]
|
||||
@@ -455,23 +537,46 @@
|
||||
var/y_relative_to_absolute = y_offset - 1
|
||||
var/x_relative_to_absolute = x_offset - 1
|
||||
var/line_len = src.line_len
|
||||
for(var/datum/grid_set/gset as anything in gridSets)
|
||||
|
||||
// Amount we offset the grid zcrd to get the true zcrd
|
||||
var/grid_z_offset = z_offset - 1
|
||||
var/z_upper_set = z_upper < INFINITY
|
||||
var/z_lower_set = z_lower > -INFINITY
|
||||
|
||||
// we now need to find the maximum z, fun!
|
||||
var/map_bounds_z_max = 1
|
||||
for(var/datum/grid_set/grid_set as anything in gridSets)
|
||||
map_bounds_z_max = max(map_bounds_z_max, grid_set.zcrd)
|
||||
|
||||
var/z_upper_parsed = map_bounds_z_max + z_offset - 1
|
||||
if(z_upper_set)
|
||||
z_upper_parsed -= map_bounds_z_max - z_upper
|
||||
if(z_lower_set)
|
||||
var/offset_amount = z_lower - 1
|
||||
z_upper_parsed -= offset_amount
|
||||
grid_z_offset -= offset_amount
|
||||
|
||||
var/list/target_grid_sets = gridSets
|
||||
if(z_lower_set || z_upper_set) // bounds are set, filter out gridsets for z levels we don't want
|
||||
target_grid_sets = filter_grid_sets_based_on_z_bounds(z_lower, z_upper)
|
||||
|
||||
for(var/datum/grid_set/gset as anything in target_grid_sets)
|
||||
var/relative_x = gset.xcrd
|
||||
var/relative_y = gset.ycrd
|
||||
var/true_xcrd = relative_x + x_relative_to_absolute
|
||||
var/ycrd = relative_y + y_relative_to_absolute
|
||||
var/zcrd = gset.zcrd + z_offset - 1
|
||||
if(!cropMap && ycrd > world.maxy)
|
||||
var/zcrd = gset.zcrd + grid_z_offset
|
||||
if(!crop_map && ycrd > world.maxy)
|
||||
if(new_z)
|
||||
// Need to avoid improperly loaded area/turf_contents
|
||||
world.increaseMaxY(ycrd, max_zs_to_load = z_offset - 1)
|
||||
world.increase_max_y(ycrd, map_load_z_cutoff = z_offset - 1)
|
||||
else
|
||||
world.increaseMaxY(ycrd)
|
||||
world.increase_max_y(ycrd)
|
||||
expanded_y = TRUE
|
||||
var/zexpansion = zcrd > world.maxz
|
||||
var/no_afterchange = no_changeturf
|
||||
if(zexpansion)
|
||||
if(cropMap)
|
||||
if(crop_map)
|
||||
continue
|
||||
else
|
||||
while (zcrd > world.maxz) //create a new z_level if needed
|
||||
@@ -508,7 +613,7 @@
|
||||
var/x_step_count = ROUND_UP(x_target / key_len)
|
||||
var/final_x = relative_x + (x_step_count - 1)
|
||||
var/x_delta_with = x_upper
|
||||
if(cropMap)
|
||||
if(crop_map)
|
||||
// Take our smaller crop threshold yes?
|
||||
x_delta_with = min(x_delta_with, world.maxx)
|
||||
if(final_x > x_delta_with)
|
||||
@@ -517,12 +622,12 @@
|
||||
x_step_count -= delta
|
||||
final_x -= delta
|
||||
x_target = x_step_count * key_len
|
||||
if(final_x > world.maxx && !cropMap)
|
||||
if(final_x > world.maxx && !crop_map)
|
||||
if(new_z)
|
||||
// Need to avoid improperly loaded area/turf_contents
|
||||
world.increaseMaxX(final_x, max_zs_to_load = z_offset - 1)
|
||||
world.increase_max_x(final_x, map_load_z_cutoff = z_offset - 1)
|
||||
else
|
||||
world.increaseMaxX(final_x)
|
||||
world.increase_max_x(final_x)
|
||||
expanded_x = TRUE
|
||||
|
||||
// We're gonna track the first and last pairs of coords we find
|
||||
@@ -553,7 +658,7 @@
|
||||
if(!cache)
|
||||
SSatoms.map_loader_stop(REF(src))
|
||||
CRASH("Undefined model key in DMM: [model_key]")
|
||||
build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z)
|
||||
build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, place_on_top, new_z)
|
||||
|
||||
// only bother with bounds that actually exist
|
||||
if(!first_found)
|
||||
|
||||
@@ -51,10 +51,10 @@
|
||||
return central_turf
|
||||
|
||||
/datum/map_template/ruin/proc/place_on_isolated_level(z)
|
||||
var/datum/turf_reservation/reservation = SSmapping.RequestBlockReservation(width, height, z) //Make the new level creation work with different traits.
|
||||
var/datum/turf_reservation/reservation = SSmapping.request_turf_block_reservation(width, height, 1, z) //Make the new level creation work with different traits.
|
||||
if(!reservation)
|
||||
return
|
||||
var/turf/placement = locate(reservation.bottom_left_coords[1],reservation.bottom_left_coords[2],reservation.bottom_left_coords[3])
|
||||
var/turf/placement = reservation.bottom_left_turfs[1]
|
||||
load(placement)
|
||||
loaded++
|
||||
for(var/turf/T in get_affected_turfs(placement))
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/proc/get_step_multiz(ref, dir)
|
||||
var/turf/us = get_turf(ref)
|
||||
if(dir & UP)
|
||||
dir &= ~UP
|
||||
return get_step(GET_TURF_ABOVE(get_turf(ref)), dir)
|
||||
return get_step(GET_TURF_ABOVE(us), dir)
|
||||
if(dir & DOWN)
|
||||
dir &= ~DOWN
|
||||
return get_step(GET_TURF_BELOW(get_turf(ref)), dir)
|
||||
return get_step(GET_TURF_BELOW(us), dir)
|
||||
return get_step(ref, dir)
|
||||
|
||||
/proc/get_dir_multiz(turf/us, turf/them)
|
||||
@@ -15,27 +16,21 @@
|
||||
if(us.z == them.z)
|
||||
return get_dir(us, them)
|
||||
else
|
||||
var/turf/T = us.above()
|
||||
var/turf/T = GET_TURF_ABOVE(us)
|
||||
var/dir = NONE
|
||||
if(T && (T.z == them.z))
|
||||
dir = UP
|
||||
else
|
||||
T = us.below()
|
||||
T = GET_TURF_BELOW(us)
|
||||
if(T && (T.z == them.z))
|
||||
dir = DOWN
|
||||
else
|
||||
return get_dir(us, them)
|
||||
return (dir | get_dir(us, them))
|
||||
|
||||
/turf/proc/above()
|
||||
return GET_TURF_ABOVE(src)
|
||||
|
||||
/turf/proc/below()
|
||||
return GET_TURF_BELOW(src)
|
||||
|
||||
/proc/get_lowest_turf(atom/ref)
|
||||
var/turf/us = get_turf(ref)
|
||||
var/next = GET_TURF_BELOW(us)
|
||||
var/turf/next = GET_TURF_BELOW(us)
|
||||
while(next)
|
||||
us = next
|
||||
next = GET_TURF_BELOW(us)
|
||||
@@ -44,7 +39,7 @@
|
||||
// I wish this was lisp
|
||||
/proc/get_highest_turf(atom/ref)
|
||||
var/turf/us = get_turf(ref)
|
||||
var/next = GET_TURF_ABOVE(us)
|
||||
var/turf/next = GET_TURF_ABOVE(us)
|
||||
while(next)
|
||||
us = next
|
||||
next = GET_TURF_ABOVE(us)
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
//Yes, they can only be rectangular.
|
||||
//Yes, I'm sorry.
|
||||
/datum/turf_reservation
|
||||
/// All turfs that we've reserved
|
||||
var/list/reserved_turfs = list()
|
||||
///Turfs around the reservation for cordoning
|
||||
|
||||
/// Turfs around the reservation for cordoning
|
||||
var/list/cordon_turfs = list()
|
||||
///Area of turfs next to the cordon to fill with pre_cordon_area's
|
||||
|
||||
/// Area of turfs next to the cordon to fill with pre_cordon_area's
|
||||
var/list/pre_cordon_turfs = list()
|
||||
|
||||
/// The width of the reservation
|
||||
var/width = 0
|
||||
|
||||
/// The height of the reservation
|
||||
var/height = 0
|
||||
var/bottom_left_coords[3]
|
||||
var/top_right_coords[3]
|
||||
|
||||
/// The z stack size of the reservation. Note that reservations are ALWAYS reserved from the bottom up
|
||||
var/z_size = 0
|
||||
|
||||
/// List of the bottom left turfs. Indexed by what their z index for this reservation is
|
||||
var/list/bottom_left_turfs = list()
|
||||
|
||||
/// List of the top right turfs. Indexed by what their z index for this reservation is
|
||||
var/list/top_right_turfs = list()
|
||||
|
||||
/// The turf type the reservation is initially made with
|
||||
var/turf_type = /turf/open/space
|
||||
|
||||
///Distance away from the cordon where we can put a "sort-cordon" and run some extra code (see make_repel). 0 makes nothing happen
|
||||
var/pre_cordon_distance = 0
|
||||
|
||||
@@ -19,6 +36,9 @@
|
||||
pre_cordon_distance = 7
|
||||
|
||||
/datum/turf_reservation/proc/Release()
|
||||
bottom_left_turfs.Cut()
|
||||
top_right_turfs.Cut()
|
||||
|
||||
var/list/reserved_copy = reserved_turfs.Copy()
|
||||
SSmapping.used_turfs -= reserved_turfs
|
||||
reserved_turfs = list()
|
||||
@@ -36,20 +56,20 @@
|
||||
INVOKE_ASYNC(SSmapping, TYPE_PROC_REF(/datum/controller/subsystem/mapping, reserve_turfs), release_turfs)
|
||||
|
||||
/// Attempts to calaculate and store a list of turfs around the reservation for cordoning. Returns whether a valid cordon was calculated
|
||||
/datum/turf_reservation/proc/calculate_cordon_turfs(turf/BL, turf/TR)
|
||||
if(BL.x < 2 || BL.y < 2 || TR.x > (world.maxx - 2) || TR.y > (world.maxy - 2))
|
||||
/datum/turf_reservation/proc/calculate_cordon_turfs(turf/bottom_left, turf/top_right)
|
||||
if(bottom_left.x < 2 || bottom_left.y < 2 || top_right.x > (world.maxx - 2) || top_right.y > (world.maxy - 2))
|
||||
return FALSE // no space for a cordon here
|
||||
|
||||
var/list/possible_turfs = CORNER_OUTLINE(BL, width, height)
|
||||
var/list/possible_turfs = CORNER_OUTLINE(bottom_left, width, height)
|
||||
// if they're our cordon turfs, accept them
|
||||
possible_turfs -= cordon_turfs
|
||||
for(var/turf/cordon_turf as anything in possible_turfs)
|
||||
if(!(cordon_turf.flags_1 & UNUSED_RESERVATION_TURF))
|
||||
if(!(cordon_turf.turf_flags & UNUSED_RESERVATION_TURF))
|
||||
return FALSE
|
||||
cordon_turfs = possible_turfs
|
||||
|
||||
pre_cordon_turfs.Cut()
|
||||
cordon_turfs |= possible_turfs
|
||||
|
||||
if(pre_cordon_distance)
|
||||
var/turf/offset_turf = locate(BL.x + pre_cordon_distance, BL.y + pre_cordon_distance, BL.z)
|
||||
var/turf/offset_turf = locate(bottom_left.x + pre_cordon_distance, bottom_left.y + pre_cordon_distance, bottom_left.z)
|
||||
var/list/to_add = CORNER_OUTLINE(offset_turf, width - pre_cordon_distance * 2, height - pre_cordon_distance * 2) //we step-by-stop move inwards from the outer cordon
|
||||
for(var/turf/turf_being_added as anything in to_add)
|
||||
pre_cordon_turfs |= turf_being_added //add one by one so we can filter out duplicates
|
||||
@@ -64,10 +84,11 @@
|
||||
old_area.turfs_to_uncontain += cordon_turf
|
||||
cordon_area.contained_turfs += cordon_turf
|
||||
cordon_area.contents += cordon_turf
|
||||
// Its no longer unused, but its also not "used"
|
||||
cordon_turf.turf_flags &= ~UNUSED_RESERVATION_TURF
|
||||
cordon_turf.ChangeTurf(/turf/cordon, /turf/cordon)
|
||||
|
||||
cordon_turf.flags_1 &= ~UNUSED_RESERVATION_TURF
|
||||
SSmapping.unused_turfs["[cordon_turf.z]"] -= cordon_turf
|
||||
// still gets linked to us though
|
||||
SSmapping.used_turfs[cordon_turf] = src
|
||||
|
||||
//swap the area with the pre-cordoning area
|
||||
@@ -113,7 +134,8 @@
|
||||
if(!HAS_TRAIT(enterer, TRAIT_FREE_HYPERSPACE_SOFTCORDON_MOVEMENT))
|
||||
space_dump(source, enterer)
|
||||
|
||||
/datum/turf_reservation/proc/Reserve(width, height, zlevel)
|
||||
/// Internal proc which handles reserving the area for the reservation.
|
||||
/datum/turf_reservation/proc/_reserve_area(width, height, zlevel)
|
||||
src.width = width
|
||||
src.height = height
|
||||
if(width > world.maxx || height > world.maxy || width < 1 || height < 1)
|
||||
@@ -126,12 +148,12 @@
|
||||
for(var/i in avail)
|
||||
CHECK_TICK
|
||||
BL = i
|
||||
if(!(BL.flags_1 & UNUSED_RESERVATION_TURF))
|
||||
if(!(BL.turf_flags & UNUSED_RESERVATION_TURF))
|
||||
continue
|
||||
if(BL.x + width > world.maxx || BL.y + height > world.maxy)
|
||||
continue
|
||||
TR = locate(BL.x + width - 1, BL.y + height - 1, BL.z)
|
||||
if(!(TR.flags_1 & UNUSED_RESERVATION_TURF))
|
||||
if(!(TR.turf_flags & UNUSED_RESERVATION_TURF))
|
||||
continue
|
||||
final = block(BL, TR)
|
||||
if(!final)
|
||||
@@ -139,7 +161,7 @@
|
||||
passing = TRUE
|
||||
for(var/I in final)
|
||||
var/turf/checking = I
|
||||
if(!(checking.flags_1 & UNUSED_RESERVATION_TURF))
|
||||
if(!(checking.turf_flags & UNUSED_RESERVATION_TURF))
|
||||
passing = FALSE
|
||||
break
|
||||
if(passing) // found a potentially valid area, now try to calculate its cordon
|
||||
@@ -149,18 +171,94 @@
|
||||
break
|
||||
if(!passing || !istype(BL) || !istype(TR))
|
||||
return FALSE
|
||||
bottom_left_coords = list(BL.x, BL.y, BL.z)
|
||||
top_right_coords = list(TR.x, TR.y, TR.z)
|
||||
for(var/i in final)
|
||||
var/turf/T = i
|
||||
reserved_turfs |= T
|
||||
T.flags_1 &= ~UNUSED_RESERVATION_TURF
|
||||
SSmapping.unused_turfs["[T.z]"] -= T
|
||||
SSmapping.used_turfs[T] = src
|
||||
T.turf_flags = (T.turf_flags | RESERVATION_TURF) & ~UNUSED_RESERVATION_TURF
|
||||
T.ChangeTurf(turf_type, turf_type)
|
||||
|
||||
bottom_left_turfs += BL
|
||||
top_right_turfs += TR
|
||||
return TRUE
|
||||
|
||||
/datum/turf_reservation/proc/reserve(width, height, z_size, z_reservation)
|
||||
src.z_size = z_size
|
||||
var/failed_reservation = FALSE
|
||||
for(var/_ in 1 to z_size)
|
||||
if(!_reserve_area(width, height, z_reservation))
|
||||
failed_reservation = TRUE
|
||||
break
|
||||
|
||||
if(failed_reservation)
|
||||
Release()
|
||||
return FALSE
|
||||
|
||||
generate_cordon()
|
||||
return TRUE
|
||||
|
||||
/// Calculates the effective bounds information for the given turf. Returns a list of the information, or null if not applicable.
|
||||
/datum/turf_reservation/proc/calculate_turf_bounds_information(turf/target)
|
||||
for(var/z_idx in 1 to z_size)
|
||||
var/turf/bottom_left = bottom_left_turfs[z_idx]
|
||||
var/turf/top_right = top_right_turfs[z_idx]
|
||||
var/bl_x = bottom_left.x
|
||||
var/bl_y = bottom_left.y
|
||||
var/tr_x = top_right.x
|
||||
var/tr_y = top_right.y
|
||||
|
||||
if(target.x < bl_x)
|
||||
continue
|
||||
|
||||
if(target.y < bl_y)
|
||||
continue
|
||||
|
||||
if(target.x > tr_x)
|
||||
continue
|
||||
|
||||
if(target.y > tr_y)
|
||||
continue
|
||||
|
||||
var/list/return_information = list()
|
||||
return_information["z_idx"] = z_idx
|
||||
return_information["offset_x"] = target.x - bl_x
|
||||
return_information["offset_y"] = target.y - bl_y
|
||||
return return_information
|
||||
return null
|
||||
|
||||
/// Gets the turf below the given target. Returns null if there is no turf below the target
|
||||
/datum/turf_reservation/proc/get_turf_below(turf/target)
|
||||
var/list/bounds_info = calculate_turf_bounds_information(target)
|
||||
if(isnull(bounds_info))
|
||||
return null
|
||||
|
||||
var/z_idx = bounds_info["z_idx"]
|
||||
// check what z level, if its the max, then there is no turf below
|
||||
if(z_idx == z_size)
|
||||
return null
|
||||
|
||||
var/offset_x = bounds_info["offset_x"]
|
||||
var/offset_y = bounds_info["offset_y"]
|
||||
var/turf/bottom_left = bottom_left_turfs[z_idx + 1]
|
||||
return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z)
|
||||
|
||||
/// Gets the turf above the given target. Returns null if there is no turf above the target
|
||||
/datum/turf_reservation/proc/get_turf_above(turf/target)
|
||||
var/list/bounds_info = calculate_turf_bounds_information(target)
|
||||
if(isnull(bounds_info))
|
||||
return null
|
||||
|
||||
var/z_idx = bounds_info["z_idx"]
|
||||
// check what z level, if its the min, then there is no turf above
|
||||
if(z_idx == 1)
|
||||
return null
|
||||
|
||||
var/offset_x = bounds_info["offset_x"]
|
||||
var/offset_y = bounds_info["offset_y"]
|
||||
var/turf/bottom_left = bottom_left_turfs[z_idx - 1]
|
||||
return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z)
|
||||
|
||||
/datum/turf_reservation/New()
|
||||
LAZYADD(SSmapping.turf_reservations, src)
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
name = ""
|
||||
icon = 'icons/misc/pic_in_pic.dmi'
|
||||
icon_state = "room_background"
|
||||
flags_1 = NOJAUNT
|
||||
turf_flags = NOJAUNT
|
||||
|
||||
/turf/open/ai_visible/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
var/list/turfs = list()
|
||||
var/list/mobs = list()
|
||||
var/blueprints = FALSE
|
||||
var/clone_area = SSmapping.RequestBlockReservation(size_x * 2 + 1, size_y * 2 + 1)
|
||||
var/clone_area = SSmapping.request_turf_block_reservation(size_x * 2 + 1, size_y * 2 + 1, 1)
|
||||
|
||||
var/width = size_x * 2 + 1
|
||||
var/height = size_y * 2 + 1
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
var/wipe_atoms = FALSE
|
||||
|
||||
if(istype(clone_area) && total_x == clone_area.width && total_y == clone_area.height && size_x >= 0 && size_y > 0)
|
||||
var/cloned_center_x = round(clone_area.bottom_left_coords[1] + ((total_x - 1) / 2))
|
||||
var/cloned_center_y = round(clone_area.bottom_left_coords[2] + ((total_y - 1) / 2))
|
||||
var/turf/bottom_left = clone_area.bottom_left_turfs[1]
|
||||
var/cloned_center_x = round(bottom_left.x + ((total_x - 1) / 2))
|
||||
var/cloned_center_y = round(bottom_left.y + ((total_y - 1) / 2))
|
||||
for(var/t in turfs)
|
||||
var/turf/T = t
|
||||
var/offset_x = T.x - center.x
|
||||
var/offset_y = T.y - center.y
|
||||
var/turf/newT = locate(cloned_center_x + offset_x, cloned_center_y + offset_y, clone_area.bottom_left_coords[3])
|
||||
var/turf/newT = locate(cloned_center_x + offset_x, cloned_center_y + offset_y, bottom_left.z)
|
||||
if(!(newT in clone_area.reserved_turfs)) //sanity check so we don't overwrite other areas somehow
|
||||
continue
|
||||
atoms += new /obj/effect/appearance_clone(newT, T)
|
||||
@@ -34,7 +35,7 @@
|
||||
atoms += new /obj/effect/appearance_clone(newT, A)
|
||||
skip_normal = TRUE
|
||||
wipe_atoms = TRUE
|
||||
center = locate(cloned_center_x, cloned_center_y, clone_area.bottom_left_coords[3])
|
||||
center = locate(cloned_center_x, cloned_center_y, bottom_left.z)
|
||||
|
||||
if(!skip_normal)
|
||||
for(var/i in turfs)
|
||||
|
||||
@@ -28,7 +28,18 @@
|
||||
var/z_offset = SSmapping.station_start
|
||||
var/list/bounds
|
||||
for (var/path in SSmapping.config.GetFullMapPaths())
|
||||
var/datum/parsed_map/parsed = load_map(file(path), 1, 1, z_offset, measureOnly = FALSE, no_changeturf = FALSE, cropMap=TRUE, x_lower = mother1.x_low, y_lower = mother1.y_low, x_upper = mother1.x_high, y_upper = mother1.y_high)
|
||||
var/datum/parsed_map/parsed = load_map(
|
||||
file(path),
|
||||
1,
|
||||
1,
|
||||
z_offset,
|
||||
no_changeturf = FALSE,
|
||||
crop_map = TRUE,
|
||||
x_lower = mother1.x_low,
|
||||
y_lower = mother1.y_low,
|
||||
x_upper = mother1.x_high,
|
||||
y_upper = mother1.y_high,
|
||||
)
|
||||
bounds = parsed?.bounds
|
||||
z_offset += bounds[MAP_MAXZ] - bounds[MAP_MINZ] + 1
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
return ..()
|
||||
|
||||
//Are we a trunk that goes up? Or down?
|
||||
var/turf/target = null
|
||||
var/turf/target = get_turf(src)
|
||||
if(multiz_dir == MULTIZ_PIPE_UP)
|
||||
target = GET_TURF_ABOVE(get_turf(src))
|
||||
target = GET_TURF_ABOVE(target)
|
||||
if(multiz_dir == MULTIZ_PIPE_DOWN)
|
||||
target = GET_TURF_BELOW(get_turf(src))
|
||||
target = GET_TURF_BELOW(target)
|
||||
if(!target) //Nothing located.
|
||||
return
|
||||
|
||||
|
||||
@@ -382,8 +382,17 @@
|
||||
/// This should be a unit test, but too much of our other code breaks during shuttle movement, so not yet, not yet.
|
||||
/proc/test_whiteship_sizes()
|
||||
var/obj/docking_port/stationary/port_type = /obj/docking_port/stationary/picked/whiteship
|
||||
var/datum/turf_reservation/docking_yard = SSmapping.RequestBlockReservation(initial(port_type.width), initial(port_type.height))
|
||||
var/turf/spawnpoint = locate(docking_yard.bottom_left_coords[1] + initial(port_type.dwidth), docking_yard.bottom_left_coords[2] + initial(port_type.dheight), docking_yard.bottom_left_coords[3])
|
||||
var/datum/turf_reservation/docking_yard = SSmapping.request_turf_block_reservation(
|
||||
initial(port_type.width),
|
||||
initial(port_type.height),
|
||||
1,
|
||||
)
|
||||
var/turf/bottom_left = docking_yard.bottom_left_turfs[1]
|
||||
var/turf/spawnpoint = locate(
|
||||
bottom_left.x + initial(port_type.dwidth),
|
||||
bottom_left.y + initial(port_type.dheight),
|
||||
bottom_left.z,
|
||||
)
|
||||
|
||||
var/obj/docking_port/stationary/picked/whiteship/port = new(spawnpoint)
|
||||
var/list/ids = port.shuttlekeys
|
||||
|
||||
@@ -11,15 +11,16 @@
|
||||
..()
|
||||
|
||||
//reserve a tile that is always empty for our z destination
|
||||
reserved = SSmapping.RequestBlockReservation(5,5)
|
||||
reserved = SSmapping.request_turf_block_reservation(5, 5, 1)
|
||||
|
||||
// Create a space tile that goes to another z-level
|
||||
claimed_tile = run_loc_floor_bottom_left.type
|
||||
|
||||
space_tile = run_loc_floor_bottom_left.ChangeTurf(/turf/open/space)
|
||||
space_tile.destination_x = round(reserved.bottom_left_coords[1] + (reserved.width-1) / 2)
|
||||
space_tile.destination_y = round(reserved.bottom_left_coords[2] + (reserved.height-1) / 2)
|
||||
space_tile.destination_z = reserved.bottom_left_coords[3]
|
||||
var/turf/bottom_left = reserved.bottom_left_turfs[1]
|
||||
space_tile.destination_x = round(bottom_left.x + (reserved.width-1) / 2)
|
||||
space_tile.destination_y = round(bottom_left.y + (reserved.height-1) / 2)
|
||||
space_tile.destination_z = bottom_left.z
|
||||
|
||||
// Create our list of humans, all adjacent to one another
|
||||
alice = new(locate(run_loc_floor_bottom_left.x + 2, run_loc_floor_bottom_left.y, run_loc_floor_bottom_left.z))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
for(var/obj/structure/flora/plant in contents)
|
||||
qdel(plant)
|
||||
var/turf/T = below()
|
||||
var/turf/T = GET_TURF_BELOW(src)
|
||||
if(T)
|
||||
if(T.turf_flags & NO_RUINS)
|
||||
ChangeTurf(replacement_turf, null, CHANGETURF_IGNORE_AIR)
|
||||
|
||||
@@ -300,6 +300,7 @@
|
||||
#include "code\__DEFINES\dcs\signals\signals_janitor.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_key.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_ladder.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_lazy_templates.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_leash.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_lift.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_light_eater.dm"
|
||||
|
||||
Reference in New Issue
Block a user