[MIRROR] Space/Changeturf fixes and optimizations [MDB IGNORE] (#19201)

Space/Changeturf fixes and optimizations

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: GoldenAlpharex <jerego1234@hotmail.com>
Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-02-28 21:23:35 +01:00
committed by GitHub
parent f558095a40
commit db33d75a5e
20 changed files with 231 additions and 120 deletions

View File

@@ -148,13 +148,13 @@ SUBSYSTEM_DEF(mapping)
#endif
// Run map generation after ruin generation to prevent issues
run_map_generation()
// Add the transit level
transit = add_new_zlevel("Transit/Reserved", list(ZTRAIT_RESERVED = TRUE))
// Add the first transit level
var/datum/space_level/base_transit = add_reservation_zlevel()
require_area_resort()
// Set up Z-level transitions.
setup_map_transitions()
generate_station_area_list()
initialize_reserved_level(transit.z_value)
initialize_reserved_level(base_transit.z_value)
calculate_default_z_level_gravities()
return SS_INIT_SUCCESS
@@ -171,7 +171,8 @@ SUBSYSTEM_DEF(mapping)
var/packetlen = length(packet)
while(packetlen)
if(MC_TICK_CHECK)
lists_to_reserve.Cut(1, index)
if(index)
lists_to_reserve.Cut(1, index)
return
var/turf/T = packet[packetlen]
T.empty(RESERVED_TURF_TYPE, RESERVED_TURF_TYPE, null, TRUE)
@@ -328,7 +329,6 @@ Used by the AI doomsday and the self-destruct nuke.
turf_reservations = SSmapping.turf_reservations
used_turfs = SSmapping.used_turfs
holodeck_templates = SSmapping.holodeck_templates
transit = SSmapping.transit
areas_in_z = SSmapping.areas_in_z
config = SSmapping.config
@@ -663,6 +663,12 @@ GLOBAL_LIST_EMPTY(the_station_areas)
message_admins("Loading [away_name] failed!")
return
/// Adds a new reservation z level. A bit of space that can be handed out on request
/// Of note, reservations default to transit turfs, to make their most common use, shuttles, faster
/datum/controller/subsystem/mapping/proc/add_reservation_zlevel(for_shuttles)
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
@@ -673,8 +679,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
if(reserve.Reserve(width, height, 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
num_of_res_levels += 1
var/datum/space_level/newReserved = add_new_zlevel("Transit/Reserved [num_of_res_levels]", list(ZTRAIT_RESERVED = TRUE))
var/datum/space_level/newReserved = add_reservation_zlevel()
initialize_reserved_level(newReserved.z_value)
if(reserve.Reserve(width, height, newReserved.z_value))
return reserve
@@ -687,7 +692,9 @@ GLOBAL_LIST_EMPTY(the_station_areas)
return reserve
QDEL_NULL(reserve)
//This is not for wiping reserved levels, use wipe_reservations() for that.
///Sets up a z level as reserved
///This is not for wiping reserved levels, use wipe_reservations() for that.
///If this is called after SSatom init, it will call Initialize on all turfs on the passed z, as its name promises
/datum/controller/subsystem/mapping/proc/initialize_reserved_level(z)
UNTIL(!clearing_reserved_turfs) //regardless, lets add a check just in case.
clearing_reserved_turfs = TRUE //This operation will likely clear any existing reservations, so lets make sure nothing tries to make one while we're doing it.
@@ -697,11 +704,15 @@ GLOBAL_LIST_EMPTY(the_station_areas)
var/turf/A = get_turf(locate(SHUTTLE_TRANSIT_BORDER,SHUTTLE_TRANSIT_BORDER,z))
var/turf/B = get_turf(locate(world.maxx - SHUTTLE_TRANSIT_BORDER,world.maxy - SHUTTLE_TRANSIT_BORDER,z))
var/block = block(A, B)
for(var/t in block)
// No need to empty() these, because it's world init and they're
// already /turf/open/space/basic.
var/turf/T = t
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
CHECK_TICK
// Gotta create these suckers if we've not done so already
if(SSatoms.initialized)
SSatoms.InitializeAtoms(Z_TURFS(z))
unused_turfs["[z]"] = block
reservation_ready["[z]"] = TRUE
clearing_reserved_turfs = FALSE

View File

@@ -1,4 +1,10 @@
#define MAX_TRANSIT_REQUEST_RETRIES 10
/// How many turfs to allow before we stop blocking transit requests
#define MAX_TRANSIT_TILE_COUNT (150 ** 2)
/// How many turfs to allow before we start freeing up existing "soft reserved" transit docks
/// If we're under load we want to allow for cycling, but if not we want to preserve already generated docks for use
#define SOFT_TRANSIT_RESERVATION_THRESHOLD (100 ** 2)
SUBSYSTEM_DEF(shuttle)
name = "Shuttle"
@@ -25,6 +31,8 @@ SUBSYSTEM_DEF(shuttle)
var/list/transit_requesters = list()
/// An associative list of the mobile docking ports that have failed a transit request, with the amount of times they've actually failed that transit request, up to MAX_TRANSIT_REQUEST_RETRIES
var/list/transit_request_failures = list()
/// How many turfs our shuttles are currently utilizing in reservation space
var/transit_utilized = 0
/**
* Emergency shuttle stuff
@@ -192,6 +200,11 @@ SUBSYSTEM_DEF(shuttle)
// This next one removes transit docks/zones that aren't
// immediately being used. This will mean that the zone creation
// code will be running a lot.
// If we're below the soft reservation threshold, don't clear the old space
// We're better off holding onto it for now
if(transit_utilized < SOFT_TRANSIT_RESERVATION_THRESHOLD)
continue
var/obj/docking_port/mobile/owner = T.owner
if(owner)
var/idle = owner.mode == SHUTTLE_IDLE
@@ -204,7 +217,10 @@ SUBSYSTEM_DEF(shuttle)
if(!SSmapping.clearing_reserved_turfs)
while(transit_requesters.len)
var/requester = popleft(transit_requesters)
var/success = generate_transit_dock(requester)
var/success = null
// Do not try and generate any transit if we're using more then our max already
if(transit_utilized < MAX_TRANSIT_TILE_COUNT)
success = generate_transit_dock(requester)
if(!success) // BACK OF THE QUEUE
transit_request_failures[requester]++
if(transit_request_failures[requester] < MAX_TRANSIT_REQUEST_RETRIES)
@@ -619,6 +635,7 @@ SUBSYSTEM_DEF(shuttle)
var/turf/midpoint = locate(transit_x, transit_y, bottomleft.z)
if(!midpoint)
qdel(proposal)
return FALSE
var/area/old_area = midpoint.loc
old_area.turfs_to_uncontain += proposal.reserved_turfs
@@ -635,9 +652,18 @@ SUBSYSTEM_DEF(shuttle)
// Add 180, because ports point inwards, rather than outwards
new_transit_dock.setDir(angle2dir(dock_angle))
// Proposals use 2 extra hidden tiles of space, from the cordons that surround them
transit_utilized += (proposal.width + 2) * (proposal.height + 2)
M.assigned_transit = new_transit_dock
RegisterSignal(proposal, COMSIG_PARENT_QDELETING, PROC_REF(transit_space_clearing))
return new_transit_dock
/// Gotta manage our space brother
/datum/controller/subsystem/shuttle/proc/transit_space_clearing(datum/turf_reservation/source)
SIGNAL_HANDLER
transit_utilized -= (source.width + 2) * (source.height + 2)
/datum/controller/subsystem/shuttle/Recover()
initialized = SSshuttle.initialized
if (istype(SSshuttle.mobile_docking_ports))
@@ -856,7 +882,7 @@ 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, SSmapping.transit.z_value, /datum/turf_reservation/transit)
preview_reservation = SSmapping.RequestBlockReservation(loading_template.width, loading_template.height, 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)