Add ability to store path cost modifiers as a component.
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
c980854663
commit
0f78ed421d
|
@ -39,10 +39,38 @@ pub struct NoPath;
|
|||
#[reflect(Component)]
|
||||
pub struct Path(pub Vec<(i32, i32)>);
|
||||
|
||||
#[derive(Component, Clone, Debug, Default, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct CostMap {
|
||||
width: usize,
|
||||
costs: Vec<f32>,
|
||||
}
|
||||
|
||||
impl CostMap {
|
||||
pub fn new(width: usize, height: usize) -> Self {
|
||||
let count = width * height;
|
||||
Self {
|
||||
width,
|
||||
costs: vec![1.; count],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modifier(&self, x: usize, y: usize) -> Option<&f32> {
|
||||
let idx = (y as usize) * self.width + (x as usize);
|
||||
self.costs.get(idx)
|
||||
}
|
||||
|
||||
pub fn set_modifier(&mut self, x: usize, y: usize, cost: f32) {
|
||||
let idx = (y as usize) * self.width + (x as usize);
|
||||
self.costs[idx] = cost;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_path<D: 'static + Clone + Default + Send + Sync>(
|
||||
start: &dyn PointLike,
|
||||
destination: &dyn PointLike,
|
||||
map: &Map<D>,
|
||||
cost_map: &Option<CostMap>,
|
||||
) -> Option<(Vec<(i32, i32)>, u32)> {
|
||||
astar(
|
||||
&start.into(),
|
||||
|
@ -51,7 +79,13 @@ pub fn find_path<D: 'static + Clone + Default + Send + Sync>(
|
|||
if let Some(tile) = map.at(p.0 as usize, p.1 as usize) {
|
||||
if tile.is_walkable() {
|
||||
for tile in map.get_available_exits(p.0 as usize, p.1 as usize) {
|
||||
successors.push(((tile.0 as i32, tile.1 as i32), (tile.2 * 100.) as u32));
|
||||
let mut cost = tile.2 * 100.;
|
||||
if let Some(cost_map) = cost_map {
|
||||
if let Some(modifier) = cost_map.modifier(tile.0, tile.1) {
|
||||
cost *= modifier;
|
||||
}
|
||||
}
|
||||
successors.push(((tile.0 as i32, tile.1 as i32), cost as u32));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +101,7 @@ fn find_path_for_shape<D: 'static + Clone + Default + Send + Sync>(
|
|||
start: Transform,
|
||||
destination: Destination,
|
||||
map: Map<D>,
|
||||
cost_map: &Option<CostMap>,
|
||||
query_pipeline: QueryPipeline,
|
||||
collider_set: ColliderSet,
|
||||
rigid_body_set: RigidBodySet,
|
||||
|
@ -97,8 +132,14 @@ fn find_path_for_shape<D: 'static + Clone + Default + Send + Sync>(
|
|||
},
|
||||
);
|
||||
if should_push {
|
||||
let mut cost = tile.2 * 100.;
|
||||
if let Some(cost_map) = cost_map {
|
||||
if let Some(modifier) = cost_map.modifier(tile.0, tile.1) {
|
||||
cost *= modifier;
|
||||
}
|
||||
}
|
||||
successors
|
||||
.push(((tile.0 as i32, tile.1 as i32), (tile.2 * 100.) as u32));
|
||||
.push(((tile.0 as i32, tile.1 as i32), cost as u32));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,12 +167,13 @@ fn calculate_path<D: 'static + Clone + Default + Send + Sync>(
|
|||
&Destination,
|
||||
&Transform,
|
||||
&Collider,
|
||||
Option<&CostMap>,
|
||||
),
|
||||
Changed<Destination>,
|
||||
>,
|
||||
map: Query<&Map<D>>,
|
||||
) {
|
||||
for (entity, handle, destination, coordinates, shape) in query.iter() {
|
||||
for (entity, handle, destination, coordinates, shape, cost_map) in &query {
|
||||
if coordinates.i32() == **destination {
|
||||
commands
|
||||
.entity(entity)
|
||||
|
@ -147,6 +189,7 @@ fn calculate_path<D: 'static + Clone + Default + Send + Sync>(
|
|||
let destination_clone = *destination;
|
||||
let query_pipeline = rapier_context.query_pipeline.clone();
|
||||
let map_clone = map.clone();
|
||||
let cost_map_clone = cost_map.cloned();
|
||||
let handle_clone = *handle;
|
||||
let mut collider_set = rapier_context.colliders.clone();
|
||||
let mut to_remove = vec![];
|
||||
|
@ -170,6 +213,7 @@ fn calculate_path<D: 'static + Clone + Default + Send + Sync>(
|
|||
coordinates_clone,
|
||||
destination_clone,
|
||||
map_clone,
|
||||
&cost_map_clone,
|
||||
query_pipeline,
|
||||
collider_set,
|
||||
bodies,
|
||||
|
|
Loading…
Reference in New Issue
Block a user