[TM] Port TG Jump Point Search and SSpathfinder (#18984)

* move along move along

* Update bot.dm

* Diagonals are now more expensive

* Update path.dm

* Update parrot.dm

* Update path.dm

* Tweaks

* Fix cleanbot, add path safety

* Tweaked, added a safety, removed the previous one

* Update medbot.dm

* path.len isn't very safe as a whole, floorbots also had order of operations wrong

* Update medbot.dm

* clings not even once

* Back to the drawing board

* Update path.dm

* Make mules actually clear the drawn path.

* Make bots use step_towards unconditionally instead of flipping between step_to and Move

* Making extra sure the path is cleared. Somehow path was left over.

* Check for length as get_path_to is always true

* This and that
This commit is contained in:
Vi3trice
2022-10-30 15:54:51 +00:00
committed by GitHub
parent d253e13c35
commit 05d93f665a
28 changed files with 630 additions and 286 deletions
@@ -41,7 +41,7 @@
user.hud_used.lingstingdisplay.invisibility = 101
/datum/action/changeling/sting/can_sting(mob/user, mob/target)
if(!..() || !iscarbon(target) || !isturf(user.loc) || !AStar(user, target.loc, /turf/proc/Distance, cling.sting_range, simulated_only = 0))
if(!..() || !iscarbon(target) || !isturf(user.loc) || !length(get_path_to(user, target, max_distance = cling.sting_range, simulated_only = FALSE)))
return FALSE
if(!cling.chosen_sting)
to_chat(user, "We haven't prepared our sting yet!")
@@ -193,6 +193,7 @@
data_hud.remove_hud_from(src)
GLOB.bots_list -= src
QDEL_NULL(path)
QDEL_NULL(Radio)
QDEL_NULL(access_card)
@@ -489,12 +490,12 @@ Movement proc for stepping a bot through a path generated through A-star.
Pass a positive integer as an argument to override a bot's default speed.
*/
/mob/living/simple_animal/bot/proc/bot_move(dest, move_speed)
if(!dest || !path || path.len == 0) //A-star failed or a path/destination was not set.
if(!dest || !path || !length(path)) //A-star failed or a path/destination was not set.
set_path(null)
return FALSE
dest = get_turf(dest) //We must always compare turfs, so get the turf of the dest var if dest was originally something else.
var/turf/last_node = get_turf(path[path.len]) //This is the turf at the end of the path, it should be equal to dest.
var/turf/last_node = get_turf(path[length(path)]) //This is the turf at the end of the path, it should be equal to dest.
if(get_turf(src) == dest) //We have arrived, no need to move again.
return TRUE
@@ -517,21 +518,12 @@ Pass a positive integer as an argument to override a bot's default speed.
if(!length(path))
return FALSE
// Only one destination
if(length(path) == 1)
step_to(src, path[1])
set_path(null)
else
// Move us slowly
Move(path[1], get_dir(src, path[1]), BOT_STEP_DELAY)
if(get_turf(src) == path[1]) //Successful move
increment_path()
tries = 0
else
tries++
return FALSE
if(!step_towards(src, path[1]))
tries++
return FALSE
increment_path()
tries = 0
return TRUE
@@ -546,18 +538,18 @@ Pass a positive integer as an argument to override a bot's default speed.
var/datum/job/captain/All = new/datum/job/captain
access_card.access = All.get_access() // Give the bot temporary all access
set_path(get_path_to(src, waypoint, /turf/proc/Distance_cardinal, 0, 200, id = access_card))
set_path(get_path_to(src, waypoint, 200, id = access_card))
calling_ai = caller //Link the AI to the bot!
ai_waypoint = waypoint
if(path && path.len) //Ensures that a valid path is calculated!
if(path && length(path)) //Ensures that a valid path is calculated!
if(!on)
turn_on() //Saves the AI the hassle of having to activate a bot manually.
if(client)
reset_access_timer_id = addtimer(CALLBACK (src, .proc/bot_reset), 600, TIMER_OVERRIDE|TIMER_STOPPABLE) //if the bot is player controlled, they get the extra access for a limited time
to_chat(src, "<span class='notice'><span class='big'>Priority waypoint set by [calling_ai] <b>[caller]</b>. Proceed to <b>[end_area.name]</b>.</span><br>[path.len-1] meters to destination. You have been granted additional door access for 60 seconds.</span>")
to_chat(src, "<span class='notice'><span class='big'>Priority waypoint set by [calling_ai] <b>[caller]</b>. Proceed to <b>[end_area.name]</b>.</span><br>[length(path)-1] meters to destination. You have been granted additional door access for 60 seconds.</span>")
if(message)
to_chat(calling_ai, "<span class='notice'>[bicon(src)] [name] called to [end_area.name]. [path.len-1] meters to destination.</span>")
to_chat(calling_ai, "<span class='notice'>[bicon(src)] [name] called to [end_area.name]. [length(path)-1] meters to destination.</span>")
pathset = TRUE
mode = BOT_RESPONDING
tries = 0
@@ -640,27 +632,26 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/patrol_step()
if(client) // In use by player, don't actually move.
if(client) // In use by player, don't actually move.
return
if(loc == patrol_target) // reached target
if(loc == patrol_target) // reached target
//Find the next beacon matching the target.
if(!get_next_patrol_target())
find_patrol_target() //If it fails, look for the nearest one instead.
return
else if(path.len > 0 && patrol_target) // valid path
var/turf/next = path[1]
if(next == loc)
else if(length(path) && patrol_target) // valid path
if(path[1] == loc)
increment_path()
return
var/moved = bot_move(patrol_target)//step_towards(src, next) // attempt to move
var/moved = bot_move(patrol_target)//step_towards(src, next) // attempt to move
if(!moved) //Couldn't proceed the next step of the path BOT_STEP_MAX_RETRIES times
addtimer(CALLBACK(src, .proc/patrol_step_not_moved), 2)
else // no path, so calculate new one
else // no path, so calculate new one
mode = BOT_START_PATROL
/mob/living/simple_animal/bot/proc/patrol_step_not_moved()
@@ -766,13 +757,13 @@ 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()
set_path(get_path_to(src, patrol_target, /turf/proc/Distance_cardinal, 0, 120, id=access_card, exclude=avoid))
set_path(get_path_to(src, patrol_target, 120, id=access_card, exclude=avoid))
/mob/living/simple_animal/bot/proc/calc_summon_path(turf/avoid)
set waitfor = FALSE
check_bot_access()
set_path(get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid))
if(!path.len) //Cannot reach target. Give up and announce the issue.
set_path(get_path_to(src, summon_target, 150, id=access_card, exclude=avoid))
if(!length(path)) //Cannot reach target. Give up and announce the issue.
speak("Summon command failed, destination unreachable.",radio_channel)
bot_reset()
@@ -785,7 +776,7 @@ Pass a positive integer as an argument to override a bot's default speed.
bot_reset()
return
else if(path.len > 0 && summon_target) //Proper path acquired!
else if(length(path) && summon_target) //Proper path acquired!
var/turf/next = path[1]
if(next == loc)
increment_path()
@@ -1090,7 +1081,7 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/increment_path()
if(!path || !path.len)
if(!path || !length(path))
return
var/image/I = path[path[1]]
if(I)
@@ -115,10 +115,15 @@
if(mode == BOT_PATROL)
bot_patrol()
if(target && loc == get_turf(target))
start_clean(target)
path = list()
target = null
if(target)
if(!path || path.len == 0) //No path, need a new one
if(!path || !length(path)) //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(src, target.loc, /turf/proc/Distance_cardinal, 0, 30, id=access_card)
path = get_path_to(src, target, 30, id=access_card)
if(!bot_move(target))
add_to_ignore(target)
target = null
@@ -130,11 +135,6 @@
mode = BOT_IDLE
return
if(target && loc == target.loc)
start_clean(target)
path = list()
target = null
oldloc = loc
/mob/living/simple_animal/bot/cleanbot/proc/get_targets()
@@ -214,23 +214,6 @@
bot_patrol()
if(target)
if(path.len == 0)
if(!isturf(target))
var/turf/TL = get_turf(target)
path = get_path_to(src, TL, /turf/proc/Distance_cardinal, 0, 30, id=access_card,simulated_only = 0)
else
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)
target = null
mode = BOT_IDLE
return
else if( !bot_move(target) )
target = null
mode = BOT_IDLE
return
if(loc == target || loc == target.loc)
if(istype(target, /obj/item/stack/tile/plasteel))
start_eattile(target)
@@ -251,6 +234,22 @@
path = list()
return
if(!length(path))
if(!isturf(target))
var/turf/TL = get_turf(target)
path = get_path_to(src, TL, 30, id=access_card,simulated_only = 0)
else
path = get_path_to(src, target, 30, id=access_card,simulated_only = 0)
if(!bot_move(target))
add_to_ignore(target)
target = null
mode = BOT_IDLE
return
else if(!bot_move(target))
target = null
mode = BOT_IDLE
return
oldloc = loc
@@ -322,7 +322,7 @@
return
//Patient has moved away from us!
else if(patient && path.len && (get_dist(patient,path[path.len]) > 2))
else if(patient && length(path) && (get_dist(patient,path[length(path)]) > 2))
path = list()
mode = BOT_IDLE
last_found = world.time
@@ -331,21 +331,21 @@
soft_reset()
return
if(patient && path.len == 0 && (get_dist(src,patient) > 1))
path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,id=access_card)
if(patient && !length(path) && (get_dist(src,patient) > 1))
path = get_path_to(src, patient, 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(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.
if(!length(path)) //try to get closer if you can't reach the patient directly
path = get_path_to(src, patient, 30,1,id=access_card)
if(!length(path)) //Do not chase a patient we cannot reach.
soft_reset()
if(path.len > 0 && patient)
if(!bot_move(path[path.len]))
if(length(path) && patient)
if(!bot_move(path[length(path)]))
oldpatient = patient
soft_reset()
return
if(path.len > 8 && patient)
if(length(path) > 8 && patient)
frustration++
if(auto_patrol && !stationary_mode && !patient)
@@ -80,6 +80,9 @@
QDEL_NULL(cell)
return ..()
/mob/living/simple_animal/bot/mulebot/CanPathfindPass(obj/item/card/id/ID, to_dir, atom/movable/caller, no_id)
return FALSE
/mob/living/simple_animal/bot/mulebot/can_buckle()
return FALSE //no ma'am, you cannot buckle mulebots to chairs
@@ -465,7 +468,7 @@
/mob/living/simple_animal/bot/mulebot/call_bot()
..()
var/area/dest_area
if(path && path.len)
if(path && length(path))
target = ai_waypoint //Target is the end point of the path, the waypoint set by the AI.
dest_area = get_area(target)
destination = format_text(dest_area.name)
@@ -514,6 +517,7 @@
var/turf/next = path[1]
reached_target = FALSE
if(next == loc)
increment_path()
path -= next
return
if(isturf(next))
@@ -521,6 +525,7 @@
var/moved = step_towards(src, next) // attempt to move
if(moved && oldloc!=loc) // successful move
blockcount = 0
increment_path()
path -= loc
if(destination == home_destination)
mode = BOT_GO_HOME
@@ -577,7 +582,7 @@
// given an optional turf to avoid
/mob/living/simple_animal/bot/mulebot/calc_path(turf/avoid = null)
check_bot_access()
set_path(get_path_to(src, target, /turf/proc/Distance_cardinal, 0, 250, id=access_card, exclude=avoid))
set_path(get_path_to(src, target, 250, id=access_card, exclude=avoid))
// sets the current destination
// signals all beacons matching the delivery code
@@ -414,7 +414,7 @@
parrot_state = PARROT_SWOOP|PARROT_RETURN
return
var/list/path_to_take = get_path_to(src, get_turf(parrot_interest), /turf/proc/Distance_cardinal)
var/list/path_to_take = get_path_to(src, parrot_interest)
if(length(path_to_take) <= 1) // The target is below us
parrot_interest = null
parrot_state = PARROT_SWOOP|PARROT_RETURN
@@ -439,7 +439,7 @@
icon_state = "parrot_sit"
return
var/list/path_to_take = get_path_to(src, get_turf(parrot_perch), /turf/proc/Distance_cardinal)
var/list/path_to_take = get_path_to(src, parrot_perch)
if(length(path_to_take) <= 1) // The target is below us
parrot_perch = null
parrot_state = PARROT_WANDER
@@ -544,7 +544,7 @@
var/turf/T = get_turf(O)
if(my_turf != T)
var/cache_id = "[my_turf.UID()]_[T.UID()]"
computed_paths[cache_id] = computed_paths[cache_id] || get_path_to(src, T, /turf/proc/Distance_cardinal)
computed_paths[cache_id] = computed_paths[cache_id] || get_path_to(src, T)
if(!length(computed_paths[cache_id]))
continue
@@ -760,5 +760,5 @@
animate(held_item_icon, transform = m180)
underlays += held_item_icon
/mob/living/simple_animal/parrot/CanAStarPassTo(ID, dir, obj/destination)
/mob/living/simple_animal/parrot/CanPathfindPassTo(ID, dir, obj/destination)
return is_type_in_typecache(destination, desired_perches)
+2 -2
View File
@@ -474,12 +474,12 @@
var/germs = 0
for(var/mob/living/carbon/human/H in view(2, E.loc))//germs from people
if(AStar(E.loc, H.loc, /turf/proc/Distance, 2, simulated_only = 0))
if(length(get_path_to(E.loc, H.loc, max_distance = 2, simulated_only = FALSE)))
if(!HAS_TRAIT(H, TRAIT_NOBREATH) && !H.wear_mask) //wearing a mask helps preventing people from breathing cooties into open incisions
germs += H.germ_level * 0.25
for(var/obj/effect/decal/cleanable/M in view(2, E.loc))//germs from messes
if(AStar(E.loc, M.loc, /turf/proc/Distance, 2, simulated_only = 0))
if(length(get_path_to(E.loc, M.loc, 2, simulated_only = FALSE)))
germs++
if(tool && tool.blood_DNA && length(tool.blood_DNA)) //germs from blood-stained tools