Move map-based pathfinding code to Map.

This commit is contained in:
Nolan Darilek 2025-01-07 16:24:58 -05:00
parent 8db8b72824
commit 1fa48f89ab
3 changed files with 45 additions and 34 deletions

View File

@ -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

View File

@ -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<D: 'static + Clone + Default + Send + Sync>(pub MapgenMap<D>);
impl<D: 'static + Clone + Default + Send + Sync> Map<D> {
pub fn find_path(
&self,
start: &UVec2,
destination: &UVec2,
cost_map: &Option<CostMap>,
) -> Option<(Vec<UVec2>, 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<D: Clone + Default + Send + Sync> From<MapgenMap<D>> for Map<D> {
fn from(v: MapgenMap<D>) -> Self {
Self(v)

View File

@ -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<D: 'static + Clone + Default + Send + Sync>(
start: IVec2,
destination: IVec2,
map: &Map<D>,
cost_map: &Option<CostMap>,
) -> Option<(Vec<IVec2>, 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,