added path finding
This commit is contained in:
@@ -56,7 +56,7 @@ pub fn tile_to_world_distance(dist: u32) -> f32 {
|
|||||||
return dist as f32 * (2. * INNER_RADIUS);
|
return dist as f32 * (2. * INNER_RADIUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tile_count(radius: usize) -> usize {
|
pub fn get_tile_count_in_range(radius: usize) -> usize {
|
||||||
return 1 + 3 * (radius + 1) * radius;
|
return 1 + 3 * (radius + 1) * radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ impl HexCoord {
|
|||||||
|
|
||||||
pub fn hex_select(&self, radius: usize, include_center: bool) -> Vec<HexCoord> {
|
pub fn hex_select(&self, radius: usize, include_center: bool) -> Vec<HexCoord> {
|
||||||
assert!(radius != 0, "Radius cannot be zero");
|
assert!(radius != 0, "Radius cannot be zero");
|
||||||
let mut result = Vec::with_capacity(get_tile_count(radius));
|
let mut result = Vec::with_capacity(get_tile_count_in_range(radius));
|
||||||
|
|
||||||
if include_center {
|
if include_center {
|
||||||
result.push(*self);
|
result.push(*self);
|
||||||
@@ -267,7 +267,7 @@ impl HexCoord {
|
|||||||
width: usize,
|
width: usize,
|
||||||
) -> Vec<HexCoord> {
|
) -> Vec<HexCoord> {
|
||||||
assert!(radius != 0, "Radius cannot be zero");
|
assert!(radius != 0, "Radius cannot be zero");
|
||||||
let mut result = Vec::with_capacity(get_tile_count(radius));
|
let mut result = Vec::with_capacity(get_tile_count_in_range(radius));
|
||||||
|
|
||||||
if include_center {
|
if include_center {
|
||||||
if self.is_in_bounds(height, width) {
|
if self.is_in_bounds(height, width) {
|
||||||
@@ -296,10 +296,10 @@ impl HexCoord {
|
|||||||
|
|
||||||
let mut p = self.scale(4, radius);
|
let mut p = self.scale(4, radius);
|
||||||
|
|
||||||
if radius == 1 {
|
// if radius == 1 {
|
||||||
result.push(*self);
|
// result.push(*self);
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
|
||||||
for i in 0..6 {
|
for i in 0..6 {
|
||||||
for _j in 0..radius {
|
for _j in 0..radius {
|
||||||
|
|||||||
@@ -180,9 +180,9 @@ impl Map {
|
|||||||
assert!(radius != 0, "Radius cannot be zero");
|
assert!(radius != 0, "Radius cannot be zero");
|
||||||
|
|
||||||
let mut result = if include_center {
|
let mut result = if include_center {
|
||||||
Vec::with_capacity(get_tile_count(radius) + 1)
|
Vec::with_capacity(get_tile_count_in_range(radius) + 1)
|
||||||
} else {
|
} else {
|
||||||
Vec::with_capacity(get_tile_count(radius))
|
Vec::with_capacity(get_tile_count_in_range(radius))
|
||||||
};
|
};
|
||||||
if include_center {
|
if include_center {
|
||||||
let h = self.sample_height(¢er);
|
let h = self.sample_height(¢er);
|
||||||
@@ -218,9 +218,9 @@ impl Map {
|
|||||||
assert!(radius != 0, "Radius cannot be zero");
|
assert!(radius != 0, "Radius cannot be zero");
|
||||||
|
|
||||||
let mut result = if include_center {
|
let mut result = if include_center {
|
||||||
Vec::with_capacity(get_tile_count(radius) + 1)
|
Vec::with_capacity(get_tile_count_in_range(radius) + 1)
|
||||||
} else {
|
} else {
|
||||||
Vec::with_capacity(get_tile_count(radius))
|
Vec::with_capacity(get_tile_count_in_range(radius))
|
||||||
};
|
};
|
||||||
if include_center {
|
if include_center {
|
||||||
let h = self.sample_height_mut(¢er);
|
let h = self.sample_height_mut(¢er);
|
||||||
|
|||||||
@@ -34,11 +34,10 @@ use crate::{
|
|||||||
},
|
},
|
||||||
utlis::{
|
utlis::{
|
||||||
chunk_utils::{paint_map, prepare_chunk_mesh_with_collider},
|
chunk_utils::{paint_map, prepare_chunk_mesh_with_collider},
|
||||||
render_distance_system::RenderDistanceVisibility,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{chunk_rebuild::ChunkRebuildPlugin, terraforming_test::TerraFormingTestPlugin};
|
use super::{chunk_rebuild::ChunkRebuildPlugin, render_distance_system::RenderDistanceVisibility, terraforming_test::TerraFormingTestPlugin};
|
||||||
|
|
||||||
pub struct MapInitPlugin;
|
pub struct MapInitPlugin;
|
||||||
|
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ pub mod chunk_rebuild;
|
|||||||
pub mod map_init;
|
pub mod map_init;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
pub mod terraforming_test;
|
pub mod terraforming_test;
|
||||||
|
pub mod render_distance_system;
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ impl Plugin for RenderDistancePlugin {
|
|||||||
app.register_type::<RenderDistanceSettings>();
|
app.register_type::<RenderDistanceSettings>();
|
||||||
app.add_systems(PostUpdate, render_distance_system)
|
app.add_systems(PostUpdate, render_distance_system)
|
||||||
.insert_resource(RenderDistanceSettings::default());
|
.insert_resource(RenderDistanceSettings::default());
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
app.insert_resource(RenderDistanceSettings::new(f32::MAX));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::camera_system::components::PhosCamera;
|
use crate::camera_system::components::PhosCamera;
|
||||||
use crate::map_rendering::map_init::MapInitPlugin;
|
use crate::map_rendering::map_init::MapInitPlugin;
|
||||||
|
use crate::map_rendering::render_distance_system::RenderDistancePlugin;
|
||||||
use crate::utlis::editor_plugin::EditorPlugin;
|
use crate::utlis::editor_plugin::EditorPlugin;
|
||||||
use crate::utlis::render_distance_system::RenderDistancePlugin;
|
|
||||||
use crate::utlis::tile_selection_plugin::TileSelectionPlugin;
|
use crate::utlis::tile_selection_plugin::TileSelectionPlugin;
|
||||||
use crate::{camera_system::camera_plugin::PhosCameraPlugin, utlis::debug_plugin::DebugPlugin};
|
use crate::{camera_system::camera_plugin::PhosCameraPlugin, utlis::debug_plugin::DebugPlugin};
|
||||||
use bevy::{
|
use bevy::{
|
||||||
|
|||||||
@@ -1,16 +1,7 @@
|
|||||||
use bevy::{prelude::*, window::PrimaryWindow};
|
use bevy::prelude::*;
|
||||||
use bevy_inspector_egui::bevy_egui::{systems::InputEvents, EguiContexts};
|
|
||||||
use bevy_inspector_egui::egui;
|
|
||||||
use bevy_rapier3d::prelude::*;
|
|
||||||
use shared::resources::TileUnderCursor;
|
use shared::resources::TileUnderCursor;
|
||||||
use shared::states::GameplayState;
|
use shared::states::GameplayState;
|
||||||
use shared::tags::MainCamera;
|
use world_generation::{consts::HEX_CORNERS, prelude::Map, states::GeneratorState};
|
||||||
use world_generation::{
|
|
||||||
consts::HEX_CORNERS,
|
|
||||||
hex_utils::{HexCoord, INNER_RADIUS},
|
|
||||||
prelude::Map,
|
|
||||||
states::GeneratorState,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct DebugPlugin;
|
pub struct DebugPlugin;
|
||||||
|
|
||||||
@@ -76,24 +67,10 @@ fn show_tile_heights(map: Res<Map>, mut gizmos: Gizmos, shape: Res<Shape>, tile_
|
|||||||
Quat::IDENTITY,
|
Quat::IDENTITY,
|
||||||
Color::WHITE,
|
Color::WHITE,
|
||||||
);
|
);
|
||||||
let nbors = map.get_neighbors(&contact.tile);
|
|
||||||
let contact_tile_pos = contact.tile.to_world(map.sample_height(&contact.tile));
|
|
||||||
|
|
||||||
// for i in 0..6 {
|
|
||||||
// if let Some(s) = nbors[i] {
|
|
||||||
// let coord = contact.tile.get_neighbor(i);
|
|
||||||
// let p = coord.to_world(s);
|
|
||||||
// gizmos.arrow(p, p + Vec3::Y * (i as f32 + 1.0), Color::WHITE);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let p = HEX_CORNERS[i] + contact_tile_pos;
|
|
||||||
// gizmos.arrow(p, p + Vec3::Y * (i as f32 + 1.0), LinearRgba::rgb(1.0, 0.0, 0.5));
|
|
||||||
// }
|
|
||||||
|
|
||||||
gizmos.line(contact.point, contact.point + Vec3::X, LinearRgba::RED);
|
gizmos.line(contact.point, contact.point + Vec3::X, LinearRgba::RED);
|
||||||
gizmos.line(contact.point, contact.point + Vec3::Y, LinearRgba::GREEN);
|
gizmos.line(contact.point, contact.point + Vec3::Y, LinearRgba::GREEN);
|
||||||
gizmos.line(contact.point, contact.point + Vec3::Z, LinearRgba::BLUE);
|
gizmos.line(contact.point, contact.point + Vec3::Z, LinearRgba::BLUE);
|
||||||
//gizmos.sphere(contact_point, Quat::IDENTITY, 0.1, LinearRgba::rgb(1., 0., 0.5));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
pub mod chunk_utils;
|
pub mod chunk_utils;
|
||||||
pub mod render_distance_system;
|
|
||||||
pub mod debug_plugin;
|
pub mod debug_plugin;
|
||||||
pub mod editor_plugin;
|
pub mod editor_plugin;
|
||||||
pub mod tile_selection_plugin;
|
pub mod tile_selection_plugin;
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ pub struct Target(pub HexCoord);
|
|||||||
pub struct Path(pub Vec<Vec3>, pub usize);
|
pub struct Path(pub Vec<Vec3>, pub usize);
|
||||||
|
|
||||||
#[derive(Component, Debug)]
|
#[derive(Component, Debug)]
|
||||||
pub struct PathTask(pub Task<CommandQueue>);
|
pub struct PathTask(pub Task<Option<CommandQueue>>);
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
|
use bevy::prelude::Resource;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use world_generation::{
|
use world_generation::{hex_utils::HexCoord, prelude::Map};
|
||||||
hex_utils::HexCoord,
|
|
||||||
prelude::{Chunk, Map},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Resource)]
|
||||||
pub struct NavData {
|
pub struct NavData {
|
||||||
pub tiles: Vec<NavTile>,
|
pub tiles: Vec<NavTile>,
|
||||||
pub map_height: usize,
|
pub map_height: usize,
|
||||||
@@ -14,12 +12,14 @@ pub struct NavData {
|
|||||||
impl NavData {
|
impl NavData {
|
||||||
pub fn get_neighbors(&self, coord: &HexCoord) -> Vec<(HexCoord, OrderedFloat<f32>)> {
|
pub fn get_neighbors(&self, coord: &HexCoord) -> Vec<(HexCoord, OrderedFloat<f32>)> {
|
||||||
let mut neighbors = Vec::with_capacity(6);
|
let mut neighbors = Vec::with_capacity(6);
|
||||||
|
let cur_height = self.get_height(coord);
|
||||||
for i in 0..6 {
|
for i in 0..6 {
|
||||||
let n = coord.get_neighbor(i);
|
let n = coord.get_neighbor(i);
|
||||||
if !self.is_in_bounds(&n) {
|
if !self.is_in_bounds(&n) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
neighbors.push((n, OrderedFloat(1.0)));
|
let n_height = self.get_height(&n);
|
||||||
|
neighbors.push((n, OrderedFloat((cur_height - n_height).abs().powi(2))));
|
||||||
}
|
}
|
||||||
return neighbors;
|
return neighbors;
|
||||||
}
|
}
|
||||||
@@ -27,11 +27,17 @@ impl NavData {
|
|||||||
return &self.tiles[coord.to_index(self.map_width)];
|
return &self.tiles[coord.to_index(self.map_width)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_height(&self, coord: &HexCoord) -> f32 {
|
||||||
|
return self.tiles[coord.to_index(self.map_width)].height;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_in_bounds(&self, pos: &HexCoord) -> bool {
|
pub fn is_in_bounds(&self, pos: &HexCoord) -> bool {
|
||||||
return pos.is_in_bounds(self.map_height, self.map_width);
|
return pos.is_in_bounds(self.map_height, self.map_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(map: &Map) -> NavData {
|
pub fn build(map: &Map) -> NavData {
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
let _path_span = info_span!("Build Nav Data").entered();
|
||||||
let mut tiles = Vec::with_capacity(map.get_tile_count());
|
let mut tiles = Vec::with_capacity(map.get_tile_count());
|
||||||
let h = map.get_tile_height();
|
let h = map.get_tile_height();
|
||||||
let w = map.get_tile_width();
|
let w = map.get_tile_width();
|
||||||
@@ -54,6 +60,25 @@ impl NavData {
|
|||||||
map_height: h,
|
map_height: h,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, map: &Map) {
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
let _path_span = info_span!("Update Nav Data").entered();
|
||||||
|
let h = map.get_tile_height();
|
||||||
|
let w = map.get_tile_width();
|
||||||
|
for y in 0..h {
|
||||||
|
for x in 0..w {
|
||||||
|
let coord = HexCoord::from_grid_pos(x, y);
|
||||||
|
let height = map.sample_height(&coord);
|
||||||
|
let tile = NavTile {
|
||||||
|
coord,
|
||||||
|
height,
|
||||||
|
move_cost: 1.0,
|
||||||
|
};
|
||||||
|
self.tiles[y * w + x] = tile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -65,6 +90,6 @@ pub struct NavTile {
|
|||||||
|
|
||||||
impl NavTile {
|
impl NavTile {
|
||||||
pub fn calculate_heuristic(&self, to: &HexCoord) -> OrderedFloat<f32> {
|
pub fn calculate_heuristic(&self, to: &HexCoord) -> OrderedFloat<f32> {
|
||||||
todo!();
|
return (self.coord.distance(to) as f32).into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
use std::f32::consts::E;
|
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use shared::{resources::TileUnderCursor, sets::GameplaySet, states::AssetLoadState};
|
use shared::{resources::TileUnderCursor, sets::GameplaySet, states::AssetLoadState};
|
||||||
use world_generation::{heightmap, prelude::Map};
|
|
||||||
|
|
||||||
use crate::components::{LandUnit, Target, Unit};
|
use crate::components::{LandUnit, Path, Target, Unit};
|
||||||
|
|
||||||
pub struct UnitsDebugPlugin;
|
pub struct UnitsDebugPlugin;
|
||||||
|
|
||||||
@@ -13,6 +10,7 @@ impl Plugin for UnitsDebugPlugin {
|
|||||||
app.add_systems(Update, init.run_if(in_state(AssetLoadState::Loading)));
|
app.add_systems(Update, init.run_if(in_state(AssetLoadState::Loading)));
|
||||||
|
|
||||||
app.add_systems(Update, (spawn_test_unit, set_unit_target).in_set(GameplaySet));
|
app.add_systems(Update, (spawn_test_unit, set_unit_target).in_set(GameplaySet));
|
||||||
|
app.add_systems(FixedUpdate, (visualize_paths).in_set(GameplaySet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,3 +62,21 @@ fn set_unit_target(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visualize_paths(units: Query<&Path, With<Unit>>, mut gizmos: Gizmos) {
|
||||||
|
for path in units.iter() {
|
||||||
|
if path.1 > path.0.len() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for node in 1..path.0.len() {
|
||||||
|
let from = path.0[node];
|
||||||
|
let to = path.0[node - 1];
|
||||||
|
let color = if node > path.1 {
|
||||||
|
LinearRgba::rgb(1.0, 0.5, 0.0)
|
||||||
|
} else {
|
||||||
|
LinearRgba::rgb(1.0, 0.5, 1.5)
|
||||||
|
};
|
||||||
|
gizmos.line(from + Vec3::Y * 0.1, to + Vec3::Y * 0.1, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use world_generation::{hex_utils::HexCoord, prelude::Map};
|
|||||||
use crate::{
|
use crate::{
|
||||||
assets::unit_asset::UnitAssetPlugin,
|
assets::unit_asset::UnitAssetPlugin,
|
||||||
components::{Path, PathTask, Target, Unit},
|
components::{Path, PathTask, Target, Unit},
|
||||||
nav_data::{self, NavData},
|
nav_data::NavData,
|
||||||
units_debug_plugin::UnitsDebugPlugin,
|
units_debug_plugin::UnitsDebugPlugin,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,12 +65,15 @@ fn dispatch_path_requests(
|
|||||||
map: Res<Map>,
|
map: Res<Map>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
|
if units.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let mut groups: HashMap<HexCoord, Vec<PathRequest>> = HashMap::new();
|
let mut groups: HashMap<HexCoord, Vec<PathRequest>> = HashMap::new();
|
||||||
|
|
||||||
for (transform, target, entity) in units.iter() {
|
for (transform, target, entity) in units.iter() {
|
||||||
let req = PathRequest {
|
let req = PathRequest {
|
||||||
entity,
|
entity,
|
||||||
to: HexCoord::from_world_pos(transform.translation),
|
from: HexCoord::from_world_pos(transform.translation),
|
||||||
};
|
};
|
||||||
if let Some(group) = groups.get_mut(&target.0) {
|
if let Some(group) = groups.get_mut(&target.0) {
|
||||||
group.push(req);
|
group.push(req);
|
||||||
@@ -79,45 +82,94 @@ fn dispatch_path_requests(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo: only generate when map is changed
|
||||||
let nav_data = NavData::build(&map);
|
let nav_data = NavData::build(&map);
|
||||||
|
|
||||||
let pool = AsyncComputeTaskPool::get();
|
let pool = AsyncComputeTaskPool::get();
|
||||||
for (from, units) in groups {
|
for (target, units) in groups {
|
||||||
|
let destinations = get_end_points(&target, units.len(), &map);
|
||||||
|
let mut i = 0;
|
||||||
for req in units {
|
for req in units {
|
||||||
let d = nav_data.clone();
|
let d = nav_data.clone();
|
||||||
|
let dst = destinations[i];
|
||||||
|
i += 1;
|
||||||
let task = pool.spawn(async move {
|
let task = pool.spawn(async move {
|
||||||
let path = calculate_path(&from, &req.to, d);
|
#[cfg(feature = "tracing")]
|
||||||
let mut queue = CommandQueue::default();
|
let _path_span = info_span!("Path Finding").entered();
|
||||||
queue.push(move |world: &mut World| {
|
if let Some(path) = calculate_path(&req.from, &dst, d) {
|
||||||
world.entity_mut(req.entity).insert(path);
|
let mut queue = CommandQueue::default();
|
||||||
});
|
queue.push(move |world: &mut World| {
|
||||||
return queue;
|
world.entity_mut(req.entity).insert(path);
|
||||||
|
});
|
||||||
|
return Some(queue);
|
||||||
|
}
|
||||||
|
return None;
|
||||||
});
|
});
|
||||||
commands.entity(req.entity).insert(PathTask(task)).remove::<Target>();
|
commands
|
||||||
|
.entity(req.entity)
|
||||||
|
.insert(PathTask(task))
|
||||||
|
.remove::<Target>()
|
||||||
|
.remove::<Path>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_end_points(coord: &HexCoord, count: usize, map: &Map) -> Vec<HexCoord> {
|
||||||
|
let mut result = Vec::with_capacity(count);
|
||||||
|
if count == 1 {
|
||||||
|
return vec![*coord];
|
||||||
|
}
|
||||||
|
result.push(*coord);
|
||||||
|
let mut r = 1;
|
||||||
|
while result.len() < count {
|
||||||
|
let tiles = HexCoord::select_ring(coord, r);
|
||||||
|
let needed = count - result.len();
|
||||||
|
if needed >= tiles.len() {
|
||||||
|
for t in tiles {
|
||||||
|
if map.is_in_bounds(&t) {
|
||||||
|
result.push(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i in 0..needed {
|
||||||
|
let t = tiles[i];
|
||||||
|
if map.is_in_bounds(&t) {
|
||||||
|
result.push(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_path_task(mut tasks: Query<(&mut PathTask, Entity), With<Unit>>, mut commands: Commands) {
|
fn resolve_path_task(mut tasks: Query<(&mut PathTask, Entity), With<Unit>>, mut commands: Commands) {
|
||||||
for (mut task, entity) in tasks.iter_mut() {
|
for (mut task, entity) in tasks.iter_mut() {
|
||||||
if let Some(mut c) = futures::check_ready(&mut task.0) {
|
if let Some(c) = futures::check_ready(&mut task.0) {
|
||||||
commands.append(&mut c);
|
if let Some(mut queue) = c {
|
||||||
|
commands.append(&mut queue);
|
||||||
|
}
|
||||||
commands.entity(entity).remove::<PathTask>();
|
commands.entity(entity).remove::<PathTask>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_path(from: &HexCoord, to: &HexCoord, nav: NavData) -> Path {
|
fn calculate_path(from: &HexCoord, to: &HexCoord, nav: NavData) -> Option<Path> {
|
||||||
let path = astar(
|
let path = astar(
|
||||||
from,
|
from,
|
||||||
|n| nav.get_neighbors(n),
|
|n| nav.get_neighbors(n),
|
||||||
|n| nav.get(n).calculate_heuristic(to),
|
|n| nav.get(n).calculate_heuristic(to),
|
||||||
|n| n == to,
|
|n| n == to,
|
||||||
);
|
);
|
||||||
todo!("Convert path");
|
if let Some((nodes, _cost)) = path {
|
||||||
|
let result: Vec<_> = nodes.iter().map(|f| f.to_world(nav.get_height(f))).collect();
|
||||||
|
return Some(Path(result, 1));
|
||||||
|
}
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PathRequest {
|
struct PathRequest {
|
||||||
pub entity: Entity,
|
pub entity: Entity,
|
||||||
pub to: HexCoord,
|
pub from: HexCoord,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user