From 9b00f12ba0a7d85b4baa613dd7746e151e2141cd Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 4 Sep 2017 01:36:00 -0500 Subject: [PATCH] Makes the shuttle code a little bit more robust by removing a snowflake loop (#2559) --- code/__DEFINES/shuttles.dm | 7 +- code/modules/shuttle/on_move.dm | 64 +++++++----- code/modules/shuttle/shuttle.dm | 175 ++++++++++++++++++++------------ 3 files changed, 152 insertions(+), 94 deletions(-) diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index bee6508609..f25dddcaf6 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -58,4 +58,9 @@ #define DOCKING_COMPLETE 1 #define DOCKING_BLOCKED 2 #define DOCKING_IMMOBILIZED 4 -#define DOCKING_AREA_EMPTY 8 \ No newline at end of file +#define DOCKING_AREA_EMPTY 8 + +//Docking turf movements +#define MOVE_TURF 1 +#define MOVE_AREA 2 +#define MOVE_CONTENTS 4 \ No newline at end of file diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index b09c38d714..59a0a46ae8 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -4,15 +4,17 @@ All ShuttleMove procs go here /************************************Base procs************************************/ -// Called on every turf in the shuttle region, return false if it doesn't want to move -/turf/proc/fromShuttleMove(turf/newT, turf_type, baseturf_type) - if(type == turf_type && baseturf == baseturf_type) - return FALSE - return TRUE +// Called on every turf in the shuttle region, returns a bitflag for allowed movements of that turf +// returns the new move_mode (based on the old) +/turf/proc/fromShuttleMove(turf/newT, turf_type, list/baseturf_cache, move_mode) + if(!(move_mode & MOVE_AREA) || (istype(src, turf_type) && baseturf_cache[baseturf])) + return move_mode + return move_mode | MOVE_TURF | MOVE_CONTENTS // Called from the new turf before anything has been moved // Only gets called if fromShuttleMove returns true first -/turf/proc/toShuttleMove(turf/oldT, shuttle_dir) +// returns the new move_mode (based on the old) +/turf/proc/toShuttleMove(turf/oldT, shuttle_dir, move_mode) for(var/i in contents) var/atom/movable/thing = i if(ismob(thing)) @@ -38,7 +40,7 @@ All ShuttleMove procs go here else qdel(thing) - return TRUE + return move_mode // Called on the old turf to move the turf data /turf/proc/onShuttleMove(turf/newT, turf_type, baseturf_type, rotation, list/movement_force, move_dir) @@ -73,9 +75,9 @@ All ShuttleMove procs go here ///////////////////////////////////////////////////////////////////////////////////// // Called on every atom in shuttle turf contents before anything has been moved -// Return true if it should be moved regardless of turf being moved -/atom/movable/proc/beforeShuttleMove(turf/newT, rotation) - return FALSE +// returns the new move_mode (based on the old) +/atom/movable/proc/beforeShuttleMove(turf/newT, rotation, move_mode) + return move_mode // Called on atoms to move the atom to the new location /atom/movable/proc/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) @@ -102,13 +104,16 @@ All ShuttleMove procs go here ///////////////////////////////////////////////////////////////////////////////////// // Called on areas before anything has been moved -/area/proc/beforeShuttleMove() - return TRUE +// returns the new move_mode (based on the old) +/area/proc/beforeShuttleMove(list/shuttle_areas) + if(!shuttle_areas[src]) + return NONE + return MOVE_AREA // Called on areas to move their turf between areas /area/proc/onShuttleMove(turf/oldT, turf/newT, area/underlying_old_area) if(newT == oldT) // In case of in place shuttle rotation shenanigans. - return + return TRUE contents -= oldT underlying_old_area.contents += oldT @@ -117,7 +122,7 @@ All ShuttleMove procs go here var/area/old_dest_area = newT.loc parallax_movedir = old_dest_area.parallax_movedir - + old_dest_area.contents -= newT contents += newT newT.change_area(old_dest_area, src) @@ -160,9 +165,11 @@ All ShuttleMove procs go here SSair.add_to_active(src, TRUE) SSair.add_to_active(oldT, TRUE) +/************************************Area move procs************************************/ + /************************************Machinery move procs************************************/ -/obj/machinery/door/airlock/beforeShuttleMove(turf/newT, rotation) +/obj/machinery/door/airlock/beforeShuttleMove(turf/newT, rotation, move_mode) . = ..() shuttledocked = 0 for(var/obj/machinery/door/airlock/A in range(1, src)) @@ -176,11 +183,11 @@ All ShuttleMove procs go here for(var/obj/machinery/door/airlock/A in range(1, src)) A.shuttledocked = 1 -/obj/machinery/camera/beforeShuttleMove(turf/newT, rotation) +/obj/machinery/camera/beforeShuttleMove(turf/newT, rotation, move_mode) . = ..() GLOB.cameranet.removeCamera(src) GLOB.cameranet.updateChunk() - return TRUE + . |= MOVE_CONTENTS /obj/machinery/camera/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) . = ..() @@ -207,7 +214,7 @@ All ShuttleMove procs go here if(z == ZLEVEL_MINING) //Avoids double logging and landing on other Z-levels due to badminnery SSblackbox.add_details("colonies_dropped", "[x]|[y]|[z]") //Number of times a base has been dropped! -/obj/machinery/gravity_generator/main/beforeShuttleMove(turf/newT, rotation) +/obj/machinery/gravity_generator/main/beforeShuttleMove(turf/newT, rotation, move_mode) . = ..() on = FALSE update_list() @@ -218,9 +225,9 @@ All ShuttleMove procs go here on = TRUE update_list() -/obj/machinery/thruster/beforeShuttleMove(turf/newT, rotation) +/obj/machinery/thruster/beforeShuttleMove(turf/newT, rotation, move_mode) . = ..() - . = TRUE + . |= MOVE_CONTENTS //Properly updates pipes on shuttle movement /obj/machinery/atmospherics/shuttleRotate(rotation) @@ -271,7 +278,7 @@ All ShuttleMove procs go here var/turf/T = loc hide(T.intact) -/obj/machinery/navbeacon/beforeShuttleMove(turf/newT, rotation) +/obj/machinery/navbeacon/beforeShuttleMove(turf/newT, rotation, move_mode) . = ..() GLOB.navbeacons["[z]"] -= src GLOB.deliverybeacons -= src @@ -333,13 +340,13 @@ All ShuttleMove procs go here /************************************Structure move procs************************************/ -/obj/structure/grille/beforeShuttleMove(turf/newT, rotation) +/obj/structure/grille/beforeShuttleMove(turf/newT, rotation, move_mode) . = ..() - . = TRUE + . |= MOVE_CONTENTS -/obj/structure/lattice/beforeShuttleMove(turf/newT, rotation) +/obj/structure/lattice/beforeShuttleMove(turf/newT, rotation, move_mode) . = ..() - . = TRUE + . |= MOVE_CONTENTS /obj/structure/disposalpipe/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) . = ..() @@ -350,6 +357,11 @@ All ShuttleMove procs go here var/turf/T = loc if(level==1) hide(T.intact) + +/obj/structure/shuttle/beforeShuttleMove(turf/newT, rotation, move_mode) + . = ..() + . |= MOVE_CONTENTS + /************************************Misc move procs************************************/ @@ -371,4 +383,4 @@ All ShuttleMove procs go here /obj/effect/abstract/proximity_checker/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) //timer so it only happens once - addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE) + addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE) \ No newline at end of file diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index d0d5952a0c..6ae0d98dfe 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -21,6 +21,10 @@ var/dwidth = 0 //position relative to covered area, perpendicular to dir var/dheight = 0 //position relative to covered area, parallel to dir + var/area_type + var/turf_type + var/baseturf_type + //these objects are indestructible /obj/docking_port/Destroy(force) // unless you assert that you know what you're doing. Horrible things @@ -119,6 +123,39 @@ else . += T +/obj/docking_port/proc/return_ordered_assoc_turfs(_x, _y, _z, _dir) + if(!_dir) + _dir = dir + if(!_x) + _x = x + if(!_y) + _y = y + if(!_z) + _z = z + var/cos = 1 + var/sin = 0 + switch(_dir) + if(WEST) + cos = 0 + sin = 1 + if(SOUTH) + cos = -1 + sin = 0 + if(EAST) + cos = 0 + sin = -1 + + . = list() + + var/xi + var/yi + for(var/dx=0, dx