Merge pull request #15536 from SandPoot/JPS

Implements JPS (Jump Point Search) Pathfinding
This commit is contained in:
silicons
2022-03-10 16:51:07 -07:00
committed by GitHub
24 changed files with 477 additions and 296 deletions
+3 -3
View File
@@ -102,7 +102,7 @@
rad_insulation = RAD_MEDIUM_INSULATION
var/static/list/airlock_overlays = list()
/// sigh
var/unelectrify_timerid
@@ -1278,8 +1278,8 @@
assemblytype = /obj/structure/door_assembly/door_assembly_extmai
update_icon()
/obj/machinery/door/airlock/CanAStarPass(obj/item/card/id/ID)
//Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off)
/obj/machinery/door/airlock/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
//Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off)
return !density || (check_access(ID) && !locked && hasPower())
/obj/machinery/door/airlock/emag_act(mob/user)
+12 -1
View File
@@ -238,7 +238,18 @@
/obj/get_dumping_location(datum/component/storage/source,mob/user)
return get_turf(src)
/obj/proc/CanAStarPass()
/**
* This proc is used for telling whether something can pass by this object in a given direction, for use by the pathfinding system.
*
* Trying to generate one long path across the station will call this proc on every single object on every single tile that we're seeing if we can move through, likely
* multiple times per tile since we're likely checking if we can access said tile from multiple directions, so keep these as lightweight as possible.
*
* Arguments:
* * ID- An ID card representing what access we have (and thus if we can open things like airlocks or windows to pass through them). The ID card's physical location does not matter, just the reference
* * to_dir- What direction we're trying to move in, relevant for things like directional windows that only block movement in certain directions
* * caller- The movable we're checking pass flags for, if we're making any such checks
**/
/obj/proc/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
. = !density
/obj/proc/check_uplink_validity()
+3 -4
View File
@@ -305,11 +305,10 @@
else
return 0
/obj/structure/girder/CanAStarPass(ID, dir, caller)
/obj/structure/girder/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
. = !density
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || (mover.pass_flags & PASSGRILLE)
if(istype(caller))
. = . || (caller.pass_flags & PASSGRILLE)
/obj/structure/girder/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
+3 -4
View File
@@ -133,11 +133,10 @@
else
return !density
/obj/structure/grille/CanAStarPass(ID, dir, caller)
/obj/structure/grille/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
. = !density
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || (mover.pass_flags & PASSGRILLE)
if(istype(caller))
. = . || (caller.pass_flags & PASSGRILLE)
/obj/structure/grille/attackby(obj/item/W, mob/user, params)
user.DelayNextAction(CLICK_CD_MELEE)
+3 -4
View File
@@ -371,8 +371,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
else
return 0
/obj/structure/tray/m_tray/CanAStarPass(ID, dir, caller)
/obj/structure/tray/m_tray/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
. = !density
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || (mover.pass_flags & PASSTABLE)
if(istype(caller))
. = . || (caller.pass_flags & PASSTABLE)
+9 -9
View File
@@ -56,18 +56,18 @@
return FALSE
return TRUE
/obj/structure/plasticflaps/CanAStarPass(ID, to_dir, caller)
/obj/structure/plasticflaps/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
if(isliving(caller))
if(isbot(caller))
return 1
return TRUE
var/mob/living/M = caller
if(!(SEND_SIGNAL(M, COMSIG_CHECK_VENTCRAWL)) && M.mob_size != MOB_SIZE_TINY)
return 0
var/atom/movable/M = caller
if(M && M.pulling)
return CanAStarPass(ID, to_dir, M.pulling)
return 1 //diseases, stings, etc can pass
var/mob/living/living_caller = caller
if(!(SEND_SIGNAL(living_caller, COMSIG_CHECK_VENTCRAWL)) && living_caller.mob_size != MOB_SIZE_TINY)
return FALSE
if(caller?.pulling)
return CanAStarPass(ID, to_dir, caller.pulling)
return TRUE //diseases, stings, etc can pass
/obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T)
if(istype(A) && (A.pass_flags & PASSGLASS))
+6 -8
View File
@@ -109,11 +109,10 @@
else
return !density
/obj/structure/table/CanAStarPass(ID, dir, caller)
/obj/structure/table/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
. = !density
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || (mover.pass_flags & PASSTABLE)
if(istype(caller))
. = . || (caller.pass_flags & PASSTABLE)
/obj/structure/table/proc/tableplace(mob/living/user, mob/living/pushed_mob)
pushed_mob.forceMove(src.loc)
@@ -702,11 +701,10 @@
else
return 0
/obj/structure/rack/CanAStarPass(ID, dir, caller)
/obj/structure/rack/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
. = !density
if(ismovable(caller))
var/atom/movable/mover = caller
. = . || (mover.pass_flags & PASSTABLE)
if(istype(caller))
. = . || (caller.pass_flags & PASSTABLE)
/obj/structure/rack/MouseDrop_T(obj/O, mob/user)
. = ..()
+6 -6
View File
@@ -90,13 +90,13 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
. = ..()
if(direct)
setDir(direct)
if(extra_reinforced && anchored)
state = PRWINDOW_SECURE
else if(reinf && anchored)
state = WINDOW_SCREWED_TO_FRAME
if(mapload && electrochromatic_id && electrochromatic_id[1] == "!")
electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id)
@@ -571,13 +571,13 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
/obj/structure/window/get_dumping_location(obj/item/storage/source,mob/user)
return null
/obj/structure/window/CanAStarPass(ID, to_dir)
/obj/structure/window/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
if(!density)
return 1
return TRUE
if((dir == FULLTILE_WINDOW_DIR) || (dir == to_dir))
return 0
return FALSE
return 1
return TRUE
/obj/structure/window/GetExplosionBlock()
return reinf && fulltile ? real_explosion_block : 0
+20
View File
@@ -638,3 +638,23 @@ GLOBAL_LIST_EMPTY(station_turfs)
var/obj/machinery/door/D = locate() in src
if(D?.density)
. += D.opacity? 29 : 19 // glass doors are slightly more resistant to screaming
/**
* Returns adjacent turfs to this turf that are reachable, in all cardinal directions
*
* Arguments:
* * caller: The movable, if one exists, being used for mobility checks to see what tiles it can reach
* * ID: An ID card that decides if we can gain access to doors that would otherwise block a turf
* * simulated_only: Do we only worry about turfs with simulated atmos, most notably things that aren't space?
*/
/turf/proc/reachableAdjacentTurfs(caller, ID, simulated_only)
var/static/space_type_cache = typecacheof(/turf/open/space)
. = list()
for(var/iter_dir in GLOB.cardinals)
var/turf/turf_to_check = get_step(src,iter_dir)
if(!turf_to_check || (simulated_only && space_type_cache[turf_to_check.type]))
continue
if(turf_to_check.density || LinkBlockedWithAccess(turf_to_check, caller, ID))
continue
. += turf_to_check