Simplify costmaps and add bounds checks to prevent overflows.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Nolan Darilek 2023-02-02 10:45:52 -06:00
parent c2b2694866
commit b113ab891f

View File

@ -2,6 +2,7 @@ use bevy::{
ecs::entity::Entities, ecs::entity::Entities,
prelude::*, prelude::*,
tasks::{prelude::*, Task}, tasks::{prelude::*, Task},
utils::HashMap,
}; };
use bevy_rapier2d::{ use bevy_rapier2d::{
na::{Isometry2, Vector2}, na::{Isometry2, Vector2},
@ -58,32 +59,9 @@ pub struct NoPath;
#[reflect(Component)] #[reflect(Component)]
pub struct Path(pub Vec<(i32, i32)>); pub struct Path(pub Vec<(i32, i32)>);
#[derive(Component, Clone, Debug, Default, Reflect)] #[derive(Component, Clone, Debug, Default, Reflect, Deref, DerefMut)]
#[reflect(Component)] #[reflect(Component)]
pub struct CostMap { pub struct CostMap(pub HashMap<(i32, i32), f32>);
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: i32, y: i32) -> 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 * self.width + x;
self.costs[idx] = cost;
}
}
pub fn find_path<D: 'static + Clone + Default + Send + Sync>( pub fn find_path<D: 'static + Clone + Default + Send + Sync>(
start: &dyn PointLike, start: &dyn PointLike,
@ -95,17 +73,20 @@ pub fn find_path<D: 'static + Clone + Default + Send + Sync>(
&start.into(), &start.into(),
|p| { |p| {
let mut successors: Vec<((i32, i32), u32)> = vec![]; let mut successors: Vec<((i32, i32), u32)> = vec![];
if let Some(tile) = map.at(p.0 as usize, p.1 as usize) { if p.0 >= 0 && p.1 >= 0 {
if tile.is_walkable() { if let Some(tile) = map.at(p.0 as usize, p.1 as usize) {
for tile in map.get_available_exits(p.0 as usize, p.1 as usize) { if tile.is_walkable() {
let mut cost = tile.2 * 100.; for tile in map.get_available_exits(p.0 as usize, p.1 as usize) {
if let Some(cost_map) = cost_map { let mut cost = tile.2 * 100.;
if let Some(modifier) = cost_map.modifier(tile.0 as i32, tile.1 as i32) if let Some(cost_map) = cost_map {
{ if let Some(modifier) =
cost *= modifier; cost_map.get(&(tile.0 as i32, tile.1 as i32))
{
cost *= modifier;
}
} }
successors.push(((tile.0 as i32, tile.1 as i32), cost as u32));
} }
successors.push(((tile.0 as i32, tile.1 as i32), cost as u32));
} }
} }
} }
@ -161,7 +142,7 @@ fn find_path_for_shape(
if should_push { if should_push {
let mut cost = exit.1 * 100.; let mut cost = exit.1 * 100.;
if let Some(cost_map) = cost_map { if let Some(cost_map) = cost_map {
if let Some(modifier) = cost_map.modifier(exit.0 .0, exit.0 .1) { if let Some(modifier) = cost_map.get(&(exit.0 .0, exit.0 .1)) {
cost *= modifier; cost *= modifier;
} }
} }