From 1fa48f89abeedbd7e01e541289b0a645520f56dd Mon Sep 17 00:00:00 2001 From: Nolan Darilek Date: Tue, 7 Jan 2025 16:24:58 -0500 Subject: [PATCH] Move map-based pathfinding code to `Map`. --- src/core.rs | 10 ++++++++++ src/map.rs | 35 +++++++++++++++++++++++++++++++++++ src/pathfinding.rs | 34 ---------------------------------- 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/core.rs b/src/core.rs index d688143..3ab0326 100644 --- a/src/core.rs +++ b/src/core.rs @@ -353,6 +353,16 @@ impl PointLike for IVec2 { } } +impl PointLike for UVec2 { + fn x(&self) -> f32 { + self.x as f32 + } + + fn y(&self) -> f32 { + self.y as f32 + } +} + impl PointLike for (i32, i32) { fn x(&self) -> f32 { self.0 as f32 diff --git a/src/map.rs b/src/map.rs index cc74c77..0e3990e 100644 --- a/src/map.rs +++ b/src/map.rs @@ -5,11 +5,13 @@ use bevy::prelude::*; pub use here_be_dragons::Map as MapgenMap; use here_be_dragons::{geometry::Rect as MRect, MapFilter, Tile}; use maze_generator::{prelude::*, recursive_backtracking::RbGenerator}; +use pathfinding::prelude::*; use rand::prelude::StdRng; use crate::{ core::{Obstacle, PointLike, Zone}, exploration::Mappable, + pathfinding::CostMap, visibility::Visible, }; @@ -17,6 +19,39 @@ use crate::{ #[require(Transform, SpawnColliders, SpawnPortals)] pub struct Map(pub MapgenMap); +impl Map { + pub fn find_path( + &self, + start: &UVec2, + destination: &UVec2, + cost_map: &Option, + ) -> Option<(Vec, u32)> { + astar( + &start, + |p| { + let mut successors: Vec<(UVec2, u32)> = vec![]; + if let Some(tile) = self.at(p.x as usize, p.y as usize) { + if tile.is_walkable() { + for tile in self.get_available_exits(p.x as usize, p.y as usize) { + let mut cost = tile.2 * 100.; + if let Some(cost_map) = cost_map { + if let Some(modifier) = cost_map.get(&p.as_ivec2()) { + cost *= modifier; + } + } + successors + .push((UVec2::new(tile.0 as u32, tile.1 as u32), cost as u32)); + } + } + } + successors + }, + |p| (p.distance_squared(destination) * 100.) as u32, + |p| *p == *destination, + ) + } +} + impl From> for Map { fn from(v: MapgenMap) -> Self { Self(v) diff --git a/src/pathfinding.rs b/src/pathfinding.rs index e6e8a08..ef7d270 100644 --- a/src/pathfinding.rs +++ b/src/pathfinding.rs @@ -5,7 +5,6 @@ use pathfinding::prelude::*; use crate::{ core::{GlobalTransformExt, Obstacle}, - map::Map, navigation::{NavigationAction, RotationSpeed, Speed}, }; @@ -45,39 +44,6 @@ impl Default for PathfindingControlsBundle { } } -pub fn find_path( - start: IVec2, - destination: IVec2, - map: &Map, - cost_map: &Option, -) -> Option<(Vec, u32)> { - astar( - &start, - |p| { - let mut successors: Vec<(IVec2, u32)> = vec![]; - if p.x >= 0 && p.y >= 0 { - if let Some(tile) = map.at(p.x as usize, p.y as usize) { - if tile.is_walkable() { - for tile in map.get_available_exits(p.x as usize, p.y as usize) { - let mut cost = tile.2 * 100.; - if let Some(cost_map) = cost_map { - if let Some(modifier) = cost_map.get(p) { - cost *= modifier; - } - } - successors - .push((IVec2::new(tile.0 as i32, tile.1 as i32), cost as u32)); - } - } - } - } - successors - }, - |p| (p.distance_squared(destination) * 100) as u32, - |p| *p == destination, - ) -} - fn calculate_path( mut commands: Commands, spatial_query: SpatialQuery,