From 6b73d6a8ed7932fa279a787942df250089b921ec Mon Sep 17 00:00:00 2001 From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com> Date: Thu, 27 Jun 2024 00:01:36 -0400 Subject: [PATCH] Fixes Pathfinder module AGAIN, General JPS Tweak (#84348) ## About The Pull Request 1. Fixes the modsuit pathfinder module's pathfinding for the second time. This time AI idling broke it, we just make it not idle. 2. Changes the heuristic used by JPS nodes from Chebyshev distance to Euclidean distance. I have no real logical explanation, it just appeared to produce a more optimal path. CC @LemonInTheDark 3. Renames `get_dist_euclidian()` to `get_dist_euclidean()`. Red line: Euclidean dist JPS path (roughly) Green line: Chebyshev dist JPS path (roughly) ![image](https://github.com/tgstation/tgstation/assets/75460809/57d75ff3-ee6d-4f73-82da-0e66e026d790) ## Changelog :cl: fix: MODsuit pathfinder module works. Again. code: AI pathfinding should produce slightly better paths. /:cl: --- code/__HELPERS/paths/jps.dm | 4 ++-- code/__HELPERS/spatial_info.dm | 2 +- code/controllers/subsystem/radiation.dm | 2 +- code/datums/ai/objects/mod.dm | 1 + code/datums/status_effects/agent_pinpointer.dm | 2 +- code/game/machinery/syndicatebomb.dm | 2 +- code/game/objects/items/pinpointer.dm | 2 +- .../antagonists/changeling/powers/pheromone_receptors.dm | 2 +- code/modules/mob/living/navigation.dm | 4 ++-- .../modules/modular_computers/file_system/programs/radar.dm | 6 +++--- 10 files changed, 14 insertions(+), 13 deletions(-) diff --git a/code/__HELPERS/paths/jps.dm b/code/__HELPERS/paths/jps.dm index 2dc46dea1b7..fbdccdef12c 100644 --- a/code/__HELPERS/paths/jps.dm +++ b/code/__HELPERS/paths/jps.dm @@ -34,7 +34,7 @@ previous_node = incoming_previous_node number_tiles = previous_node.number_tiles + jumps node_goal = previous_node.node_goal - heuristic = get_dist(tile, node_goal) + heuristic = get_dist_euclidean(tile, node_goal) f_value = number_tiles + heuristic // otherwise, no parent node means this is from a subscan lateral scan, so we just need the tile for now until we call [datum/jps/proc/update_parent] on it @@ -47,7 +47,7 @@ node_goal = previous_node.node_goal jumps = get_dist(tile, previous_node.tile) number_tiles = previous_node.number_tiles + jumps - heuristic = get_dist(tile, node_goal) + heuristic = get_dist_euclidean(tile, node_goal) f_value = number_tiles + heuristic /proc/HeapPathWeightCompare(datum/jps_node/a, datum/jps_node/b) diff --git a/code/__HELPERS/spatial_info.dm b/code/__HELPERS/spatial_info.dm index c23e3a408a5..529532f50cf 100644 --- a/code/__HELPERS/spatial_info.dm +++ b/code/__HELPERS/spatial_info.dm @@ -283,7 +283,7 @@ return atoms ///Returns the distance between two atoms -/proc/get_dist_euclidian(atom/first_location as turf|mob|obj, atom/second_location as turf|mob|obj) +/proc/get_dist_euclidean(atom/first_location, atom/second_location) var/dx = first_location.x - second_location.x var/dy = first_location.y - second_location.y diff --git a/code/controllers/subsystem/radiation.dm b/code/controllers/subsystem/radiation.dm index d52fe83856a..6a9cc631cf5 100644 --- a/code/controllers/subsystem/radiation.dm +++ b/code/controllers/subsystem/radiation.dm @@ -74,7 +74,7 @@ SUBSYSTEM_DEF(radiation) if(pulse_information.chance < 100) // Prevents log(0) runtime if chance is 100% intensity = -log(1 - pulse_information.chance / 100) * (1 + pulse_information.max_range / 2) ** 2 - perceived_intensity = intensity * INVERSE((1 + get_dist_euclidian(source, target)) ** 2) // Diminishes over range. + perceived_intensity = intensity * INVERSE((1 + get_dist_euclidean(source, target)) ** 2) // Diminishes over range. perceived_intensity *= (current_insulation - pulse_information.threshold) * INVERSE(1 - pulse_information.threshold) // Perceived intensity decreases as objects that absorb radiation block its trajectory. perceived_chance = 100 * (1 - NUM_E ** -perceived_intensity) else diff --git a/code/datums/ai/objects/mod.dm b/code/datums/ai/objects/mod.dm index edad77aa4c4..2b4c1f7e2b0 100644 --- a/code/datums/ai/objects/mod.dm +++ b/code/datums/ai/objects/mod.dm @@ -4,6 +4,7 @@ BB_MOD_TARGET, BB_MOD_IMPLANT, ) + can_idle = FALSE max_target_distance = MOD_AI_RANGE //a little spicy but its one specific item that summons it, and it doesn't run otherwise ai_movement = /datum/ai_movement/jps/modsuit ///ID card generated from the suit's required access. Used for pathing. diff --git a/code/datums/status_effects/agent_pinpointer.dm b/code/datums/status_effects/agent_pinpointer.dm index 29dfbd43387..c22242be400 100644 --- a/code/datums/status_effects/agent_pinpointer.dm +++ b/code/datums/status_effects/agent_pinpointer.dm @@ -43,7 +43,7 @@ if(here.z != there.z) linked_alert.icon_state = "pinonnull" return - if(get_dist_euclidian(here,there) <= minimum_range + rand(0, range_fuzz_factor)) + if(get_dist_euclidean(here,there) <= minimum_range + rand(0, range_fuzz_factor)) linked_alert.icon_state = "pinondirect" return linked_alert.setDir(get_dir(here, there)) diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 693668e9e89..e4f7b0a8338 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -642,7 +642,7 @@ var/skip_sound = TRUE if(num_affected % 5) //makes it play the sound more sparingly skip_sound = FALSE - var/time_mult = round(get_dist_euclidian(get_turf(src), affected)) + 1 + var/time_mult = round(get_dist_euclidean(get_turf(src), affected)) + 1 addtimer(CALLBACK(theme_to_use, TYPE_PROC_REF(/datum/dimension_theme, apply_theme), affected, skip_sound, TRUE), 0.1 SECONDS * time_mult) qdel(src) diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm index 3a020ec5393..5d7fc1957f4 100644 --- a/code/game/objects/items/pinpointer.dm +++ b/code/game/objects/items/pinpointer.dm @@ -78,7 +78,7 @@ ///Called by update_icon after sanity. There is a target /obj/item/pinpointer/proc/get_direction_icon(here, there) - if(get_dist_euclidian(here,there) <= minimum_range) + if(get_dist_euclidean(here,there) <= minimum_range) return "pinon[alert ? "alert" : ""]direct[icon_suffix]" else setDir(get_dir(here, there)) diff --git a/code/modules/antagonists/changeling/powers/pheromone_receptors.dm b/code/modules/antagonists/changeling/powers/pheromone_receptors.dm index 0e468159a3c..7b9eee1bfe9 100644 --- a/code/modules/antagonists/changeling/powers/pheromone_receptors.dm +++ b/code/modules/antagonists/changeling/powers/pheromone_receptors.dm @@ -55,7 +55,7 @@ var/datum/antagonist/changeling/antag_datum = IS_CHANGELING(C) if(istype(antag_datum)) var/their_loc = get_turf(C) - var/distance = get_dist_euclidian(my_loc, their_loc) + var/distance = get_dist_euclidean(my_loc, their_loc) if (distance < CHANGELING_PHEROMONE_MAX_DISTANCE) changelings[C] = (CHANGELING_PHEROMONE_MAX_DISTANCE ** 2) - (distance ** 2) diff --git a/code/modules/mob/living/navigation.dm b/code/modules/mob/living/navigation.dm index 98f1080c791..3096efb3a7c 100644 --- a/code/modules/mob/living/navigation.dm +++ b/code/modules/mob/living/navigation.dm @@ -132,7 +132,7 @@ if(!target) target = lad continue - if(get_dist_euclidian(lad, src) > get_dist_euclidian(target, src)) + if(get_dist_euclidean(lad, src) > get_dist_euclidean(target, src)) continue target = lad @@ -144,7 +144,7 @@ if(!target) target = stairs_bro.z == z ? stairs_bro : get_step_multiz(stairs_bro, UP) //if the stairs aren't on our z level, get the turf above them (on our zlevel) to path to instead continue - if(get_dist_euclidian(stairs_bro, src) > get_dist_euclidian(target, src)) + if(get_dist_euclidean(stairs_bro, src) > get_dist_euclidean(target, src)) continue target = stairs_bro.z == z ? stairs_bro : get_step_multiz(stairs_bro, UP) diff --git a/code/modules/modular_computers/file_system/programs/radar.dm b/code/modules/modular_computers/file_system/programs/radar.dm index 34771cde63b..33dcd95e86b 100644 --- a/code/modules/modular_computers/file_system/programs/radar.dm +++ b/code/modules/modular_computers/file_system/programs/radar.dm @@ -114,7 +114,7 @@ var/locx = (target_turf.x - here_turf.x) + 24 var/locy = (here_turf.y - target_turf.y) + 24 - if(get_dist_euclidian(here_turf, target_turf) > 24) + if(get_dist_euclidean(here_turf, target_turf) > 24) userot = TRUE rot = round(get_angle(here_turf, target_turf)) else @@ -208,7 +208,7 @@ var/here_turf = get_turf(computer) var/target_turf = get_turf(signal) - var/trackdistance = get_dist_euclidian(here_turf, target_turf) + var/trackdistance = get_dist_euclidean(here_turf, target_turf) switch(trackdistance) if(0) program_open_overlay = "[initial(program_open_overlay)]direct" @@ -471,7 +471,7 @@ */ /obj/item/circuit_component/mod_program/radar/proc/can_track(datum/source, atom/signal, signal_turf, computer_turf) SIGNAL_HANDLER - if(target.value && get_dist_euclidian(computer_turf, signal_turf) > MAX_RADAR_CIRCUIT_DISTANCE) + if(target.value && get_dist_euclidean(computer_turf, signal_turf) > MAX_RADAR_CIRCUIT_DISTANCE) return COMPONENT_RADAR_DONT_TRACK return COMPONENT_RADAR_TRACK_ANYWAY