From 828c1ddf2cb0743c97459db5bd8594e5d450d1f9 Mon Sep 17 00:00:00 2001 From: Menshin Date: Sat, 16 Jan 2016 15:27:31 +0100 Subject: [PATCH] * Generalized AStar check for objects preventing passability * Fixed AStar not detecting plastic flaps as impassable for mobs that can't pass them (fixes #14616) --- code/datums/diseases/_disease.dm | 2 +- .../gamemodes/changeling/powers/tiny_prick.dm | 2 +- code/game/machinery/doors/door.dm | 4 -- code/game/objects/objs.dm | 3 ++ code/game/objects/structures/plasticflaps.dm | 11 +++++ code/game/objects/structures/window.dm | 8 ++++ .../mob/living/simple_animal/bot/bot.dm | 6 +-- .../mob/living/simple_animal/bot/cleanbot.dm | 2 +- .../mob/living/simple_animal/bot/floorbot.dm | 4 +- .../mob/living/simple_animal/bot/medbot.dm | 4 +- .../mob/living/simple_animal/bot/mulebot.dm | 2 +- .../mob/living/simple_animal/parrot.dm | 2 +- code/orphaned procs/AStar.dm | 48 +++++++------------ 13 files changed, 52 insertions(+), 46 deletions(-) diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 6ba2dd648b4..1f52a78a89d 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -122,7 +122,7 @@ var/list/diseases = subtypesof(/datum/disease) if(isturf(source.loc)) for(var/mob/living/carbon/C in oview(spread_range, source)) if(isturf(C.loc)) - if(AStar(source.loc, C.loc, null, /turf/proc/Distance, spread_range, adjacent = (spread_flags & AIRBORNE) ? /turf/proc/reachableAdjacentAtmosTurfs : /turf/proc/reachableAdjacentTurfs)) + if(AStar(source, C.loc,/turf/proc/Distance, spread_range, adjacent = (spread_flags & AIRBORNE) ? /turf/proc/reachableAdjacentAtmosTurfs : /turf/proc/reachableAdjacentTurfs)) C.ContractDisease(src) diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm index d5e3c54277c..48acd03a592 100644 --- a/code/game/gamemodes/changeling/powers/tiny_prick.dm +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -38,7 +38,7 @@ return if(!isturf(user.loc)) return - if(!AStar(user.loc, target.loc, null, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0)) + if(!AStar(user, target.loc, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0)) return if(target.mind && target.mind.changeling) sting_feedback(user,target) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 3a67b933959..8a8989a0bc5 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -75,10 +75,6 @@ /obj/machinery/door/CanAtmosPass() return !density -//used in the AStar algorithm to determinate if the turf the door is on is passable -/obj/machinery/door/proc/CanAStarPass(var/obj/item/weapon/card/id/ID) - return !density - /obj/machinery/door/proc/CheckForMobs() if(locate(/mob/living) in get_turf(src)) sleep(1) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 2cd7a772f8c..aab2bb1c402 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -199,3 +199,6 @@ tesla_zap(src, 3, power_bounced) spawn(10) being_shocked = 0 + +/obj/proc/CanAStarPass() + . = !density \ No newline at end of file diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index eb15ba1d4c3..82bb58e9e08 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -7,6 +7,17 @@ anchored = 1 layer = 4 +/obj/structure/plasticflaps/CanAStarPass(ID, to_dir, caller) + if(istype(caller, /mob/living)) + if(istype(caller,/mob/living/simple_animal/bot/mulebot)) + return 1 + + var/mob/living/M = caller + if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY) + return 0 + + return 1 //diseases, stings, etc can pass + /obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T) if(istype(A) && A.checkpass(PASSGLASS)) return prob(60) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 63a85afa005..3c0a54f43b1 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -439,6 +439,14 @@ /obj/structure/window/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user) return 0 +/obj/structure/window/CanAStarPass(ID, to_dir) + if(!density) + return 1 + if((dir == SOUTHWEST) || (dir == to_dir)) + return 0 + + return 1 + /obj/structure/window/reinforced name = "reinforced window" icon_state = "rwindow" diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 8e18387a10a..eeda5d6e6f7 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -407,7 +407,7 @@ Pass a positive integer as an argument to override a bot's default speed. var/datum/job/captain/All = new/datum/job/captain all_access.access = All.get_access() - path = get_path_to(src, waypoint, src, /turf/proc/Distance_cardinal, 0, 200, id=all_access) + path = get_path_to(src, waypoint, /turf/proc/Distance_cardinal, 0, 200, id=all_access) calling_ai = caller //Link the AI to the bot! ai_waypoint = waypoint @@ -630,12 +630,12 @@ Pass a positive integer as an argument to override a bot's default speed. // given an optional turf to avoid /mob/living/simple_animal/bot/proc/calc_path(turf/avoid) check_bot_access() - path = get_path_to(loc, patrol_target, src, /turf/proc/Distance_cardinal, 0, 120, id=access_card, exclude=avoid) + path = get_path_to(src, patrol_target, /turf/proc/Distance_cardinal, 0, 120, id=access_card, exclude=avoid) /mob/living/simple_animal/bot/proc/calc_summon_path(turf/avoid) check_bot_access() spawn() - path = get_path_to(loc, summon_target, src, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid) + path = get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid) if(!path.len || tries >= 5) //Cannot reach target. Give up and announce the issue. speak("Summon command failed, destination unreachable.",radio_channel) bot_reset() diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 97a5c7174a3..f2ad2462ab5 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -118,7 +118,7 @@ if(target) if(!path || path.len == 0) //No path, need a new one //Try to produce a path to the target, and ignore airlocks to which it has access. - path = get_path_to(loc, target.loc, src, /turf/proc/Distance_cardinal, 0, 30, id=access_card) + path = get_path_to(src, target.loc, /turf/proc/Distance_cardinal, 0, 30, id=access_card) if (!bot_move(target)) add_to_ignore(target) target = null diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index a8c3c93aaa5..0b64ad5ad13 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -217,9 +217,9 @@ if(path.len == 0) if(!istype(target, /turf/)) var/turf/TL = get_turf(target) - path = get_path_to(loc, TL, src, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0) + path = get_path_to(src, TL, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0) else - path = get_path_to(loc, target, src, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0) + path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0) if(!bot_move(target)) add_to_ignore(target) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index bf77108174d..7bd16d4f6a4 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -302,10 +302,10 @@ return if(patient && path.len == 0 && (get_dist(src,patient) > 1)) - path = get_path_to(loc, get_turf(patient), src, /turf/proc/Distance_cardinal, 0, 30,id=access_card) + path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,id=access_card) mode = BOT_MOVING if(!path.len) //try to get closer if you can't reach the patient directly - path = get_path_to(loc, get_turf(patient), src, /turf/proc/Distance_cardinal, 0, 30,1,id=access_card) + path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,1,id=access_card) if(!path.len) //Do not chase a patient we cannot reach. soft_reset() diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 46d8832ddd8..8bda6918e34 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -604,7 +604,7 @@ mob/living/simple_animal/bot/mulebot/bot_reset() // calculates a path to the current destination // given an optional turf to avoid /mob/living/simple_animal/bot/mulebot/calc_path(turf/avoid = null) - path = get_path_to(loc, target, src, /turf/proc/Distance_cardinal, 0, 250, id=access_card, exclude=avoid) + path = get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 250, id=access_card, exclude=avoid) // sets the current destination // signals all beacons matching the delivery code diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index eb62324b13f..1891322dc3b 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -623,7 +623,7 @@ if((C.l_hand && C.l_hand.w_class <= 2) || (C.r_hand && C.r_hand.w_class <= 2)) item = C if(item) - if(!AStar(loc, get_turf(item), src, /turf/proc/Distance_cardinal)) + if(!AStar(src, get_turf(item), /turf/proc/Distance_cardinal)) item = null continue return item diff --git a/code/orphaned procs/AStar.dm b/code/orphaned procs/AStar.dm index fdcd3f531f1..64648dbea73 100644 --- a/code/orphaned procs/AStar.dm +++ b/code/orphaned procs/AStar.dm @@ -62,14 +62,19 @@ Actual Adjacent procs : return b.f - a.f //wrapper that returns an empty list if A* failed to find a path -/proc/get_path_to(start, end, atom, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1) - var/list/path = AStar(start, end, atom, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only) +/proc/get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1) + var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only) if(!path) path = list() return path //the actual algorithm -/proc/AStar(start, end, atom, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1) +/proc/AStar(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableAdjacentTurfs, id=null, turf/exclude=null, simulated_only = 1) + + //sanitation + var/start = get_turf(caller) + if(!start) + return 0 if(maxnodes) //if start turf is farther than maxnodes from end turf, no need to do anything @@ -82,11 +87,6 @@ Actual Adjacent procs : var/list/path = null //the returned path, if any var/PathNode/cur //current processed turf - //sanitation - start = get_turf(start) - if(!start) - return 0 - //initialization open.Insert(new /PathNode(start,null,0,call(start,dist)(end),0)) @@ -118,7 +118,7 @@ Actual Adjacent procs : break //get adjacents turfs using the adjacent proc, checking for access with id - var/list/L = call(cur.source,adjacent)(atom,id, simulated_only) + var/list/L = call(cur.source,adjacent)(caller,id, simulated_only) for(var/turf/T in L) if(T == exclude || (T in closed)) continue @@ -151,7 +151,7 @@ Actual Adjacent procs : //Returns adjacent turfs in cardinal directions that are reachable //simulated_only controls whether only simulated turfs are considered or not -/turf/proc/reachableAdjacentTurfs(atom, ID, simulated_only) +/turf/proc/reachableAdjacentTurfs(caller, ID, simulated_only) var/list/L = new() var/turf/simulated/T @@ -159,7 +159,7 @@ Actual Adjacent procs : T = get_step(src,dir) if(simulated_only && !istype(T)) continue - if(!T.density && !LinkBlockedWithAccess(T, ID)) + if(!T.density && !LinkBlockedWithAccess(T,ID, caller)) L.Add(T) return L @@ -177,27 +177,15 @@ Actual Adjacent procs : L.Add(T) return L -/turf/proc/LinkBlockedWithAccess(turf/T, obj/item/weapon/card/id/ID) +/turf/proc/LinkBlockedWithAccess(turf/T, ID, caller) var/adir = get_dir(src, T) var/rdir = get_dir(T, src) - if(DirBlockedWithAccess(src, adir, ID)) - return 1 - if(DirBlockedWithAccess(T, rdir, ID)) - return 1 - for(var/obj/O in T) - if(O.density && !istype(O, /obj/machinery/door) && !(O.flags & ON_BORDER)) - return 1 - return 0 -/proc/DirBlockedWithAccess(turf/T, dir, ID) - for(var/obj/structure/window/D in T) - if(!D.density) - continue - if(D.dir == SOUTHWEST) + for(var/obj/structure/window/W in src) + if(!W.CanAStarPass(ID, adir)) return 1 - if(D.dir == dir) + for(var/obj/O in T) + if(!O.CanAStarPass(ID, rdir, caller)) return 1 - for(var/obj/machinery/door/D in T) - if(!D.CanAStarPass(ID, dir)) - return 1 - return 0 + + return 0 \ No newline at end of file