Move map-based pathfinding code to Map
.
This commit is contained in:
parent
8db8b72824
commit
1fa48f89ab
10
src/core.rs
10
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) {
|
impl PointLike for (i32, i32) {
|
||||||
fn x(&self) -> f32 {
|
fn x(&self) -> f32 {
|
||||||
self.0 as f32
|
self.0 as f32
|
||||||
|
|
35
src/map.rs
35
src/map.rs
|
@ -5,11 +5,13 @@ use bevy::prelude::*;
|
||||||
pub use here_be_dragons::Map as MapgenMap;
|
pub use here_be_dragons::Map as MapgenMap;
|
||||||
use here_be_dragons::{geometry::Rect as MRect, MapFilter, Tile};
|
use here_be_dragons::{geometry::Rect as MRect, MapFilter, Tile};
|
||||||
use maze_generator::{prelude::*, recursive_backtracking::RbGenerator};
|
use maze_generator::{prelude::*, recursive_backtracking::RbGenerator};
|
||||||
|
use pathfinding::prelude::*;
|
||||||
use rand::prelude::StdRng;
|
use rand::prelude::StdRng;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{Obstacle, PointLike, Zone},
|
core::{Obstacle, PointLike, Zone},
|
||||||
exploration::Mappable,
|
exploration::Mappable,
|
||||||
|
pathfinding::CostMap,
|
||||||
visibility::Visible,
|
visibility::Visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,6 +19,39 @@ use crate::{
|
||||||
#[require(Transform, SpawnColliders, SpawnPortals)]
|
#[require(Transform, SpawnColliders, SpawnPortals)]
|
||||||
pub struct Map<D: 'static + Clone + Default + Send + Sync>(pub MapgenMap<D>);
|
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> {
|
impl<D: Clone + Default + Send + Sync> From<MapgenMap<D>> for Map<D> {
|
||||||
fn from(v: MapgenMap<D>) -> Self {
|
fn from(v: MapgenMap<D>) -> Self {
|
||||||
Self(v)
|
Self(v)
|
||||||
|
|
|
@ -5,7 +5,6 @@ use pathfinding::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{GlobalTransformExt, Obstacle},
|
core::{GlobalTransformExt, Obstacle},
|
||||||
map::Map,
|
|
||||||
navigation::{NavigationAction, RotationSpeed, Speed},
|
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(
|
fn calculate_path(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
spatial_query: SpatialQuery,
|
spatial_query: SpatialQuery,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user