More tweaks to pathfinding and visibility.
This commit is contained in:
parent
2e805b3b8b
commit
98bca77f66
|
@ -45,7 +45,7 @@ fn calculate_path(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
pool: Res<AsyncComputeTaskPool>,
|
pool: Res<AsyncComputeTaskPool>,
|
||||||
mut calculating: Local<HashMap<Entity, Receiver<Path>>>,
|
mut calculating: Local<HashMap<Entity, Receiver<Path>>>,
|
||||||
query: Query<(Entity, &Destination, &Coordinates), Changed<Destination>>,
|
query: Query<(Entity, &Destination, &Coordinates), Without<Path>>,
|
||||||
destinations: Query<&Destination>,
|
destinations: Query<&Destination>,
|
||||||
map: Query<&Map>,
|
map: Query<&Map>,
|
||||||
) {
|
) {
|
||||||
|
@ -55,6 +55,8 @@ fn calculate_path(
|
||||||
if let Ok(path) = rx.try_recv() {
|
if let Ok(path) = rx.try_recv() {
|
||||||
commands.entity(*entity).insert(path);
|
commands.entity(*entity).insert(path);
|
||||||
calculating.remove(&entity);
|
calculating.remove(&entity);
|
||||||
|
} else {
|
||||||
|
commands.entity(*entity).remove::<Destination>();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
calculating.remove(&entity);
|
calculating.remove(&entity);
|
||||||
|
@ -104,7 +106,13 @@ fn negotiate_path(
|
||||||
if let Some(upcoming) = iter.next() {
|
if let Some(upcoming) = iter.next() {
|
||||||
new_path = vec![start_i32];
|
new_path = vec![start_i32];
|
||||||
new_path.append(&mut upcoming.to_vec());
|
new_path.append(&mut upcoming.to_vec());
|
||||||
|
} else {
|
||||||
|
commands.entity(entity).remove::<Path>();
|
||||||
|
velocity.linvel = Vec2::ZERO.into();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
commands.entity(entity).remove::<Path>();
|
||||||
|
velocity.linvel = Vec2::ZERO.into();
|
||||||
}
|
}
|
||||||
**path = new_path;
|
**path = new_path;
|
||||||
if path.len() >= 2 {
|
if path.len() >= 2 {
|
||||||
|
@ -113,7 +121,7 @@ fn negotiate_path(
|
||||||
position.position.translation.y,
|
position.position.translation.y,
|
||||||
);
|
);
|
||||||
let next = path[1];
|
let next = path[1];
|
||||||
let next = Vec2::new(next.0 as f32, next.1 as f32);
|
let next = Vec2::new(next.0 as f32 + 0.5, next.1 as f32 + 0.5);
|
||||||
if rotation_speed.is_some() {
|
if rotation_speed.is_some() {
|
||||||
let v = next - start;
|
let v = next - start;
|
||||||
let angle = v.y.atan2(v.x);
|
let angle = v.y.atan2(v.x);
|
||||||
|
@ -121,12 +129,12 @@ fn negotiate_path(
|
||||||
}
|
}
|
||||||
let mut direction = next - start;
|
let mut direction = next - start;
|
||||||
direction = direction.normalize();
|
direction = direction.normalize();
|
||||||
direction *= speed.0;
|
direction *= **speed;
|
||||||
velocity.linvel = direction.into();
|
velocity.linvel = direction.into();
|
||||||
} else {
|
} else {
|
||||||
commands.entity(entity).remove::<Path>();
|
commands.entity(entity).remove::<Path>();
|
||||||
commands.entity(entity).remove::<Destination>();
|
|
||||||
velocity.linvel = Vec2::ZERO.into();
|
velocity.linvel = Vec2::ZERO.into();
|
||||||
|
commands.entity(entity).remove::<Destination>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,82 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_viewshed<'a>(
|
fn update_viewshed(
|
||||||
|
viewer_entity: &Entity,
|
||||||
|
viewshed: &mut Viewshed,
|
||||||
|
start: &dyn PointLike,
|
||||||
|
query_pipeline: &QueryPipeline,
|
||||||
|
collider_query: &QueryPipelineColliderComponentsQuery,
|
||||||
|
map: &Map,
|
||||||
|
blocks_visibility: &Query<&BlocksVisibility>,
|
||||||
|
) {
|
||||||
|
let mut context: Context<u8> = Context::default();
|
||||||
|
let vision_distance = vision_distance::Circle::new(viewshed.range);
|
||||||
|
let coord = Coord::new(start.x_i32(), start.y_i32());
|
||||||
|
viewshed.visible.clear();
|
||||||
|
let shape = Cuboid::new(Vec2::new(0.49, 0.49).into());
|
||||||
|
let range = viewshed.range as f32;
|
||||||
|
let collider_set = QueryPipelineColliderComponentsSet(&collider_query);
|
||||||
|
let visibility_grid = VisibilityGrid(map, |coord: Coord| {
|
||||||
|
if coord.distance(start) > range {
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
let shape_pos = (Vec2::new(coord.x as f32 + 0.5, coord.y as f32 + 0.5), 0.);
|
||||||
|
let mut opacity = 0;
|
||||||
|
query_pipeline.intersections_with_shape(
|
||||||
|
&collider_set,
|
||||||
|
&shape_pos.into(),
|
||||||
|
&shape,
|
||||||
|
InteractionGroups::all(),
|
||||||
|
Some(&|v| v.entity() != *viewer_entity && blocks_visibility.get(v.entity()).is_ok()),
|
||||||
|
|_| {
|
||||||
|
opacity = 255;
|
||||||
|
false
|
||||||
|
},
|
||||||
|
);
|
||||||
|
opacity
|
||||||
|
});
|
||||||
|
context.for_each_visible(
|
||||||
|
coord,
|
||||||
|
&visibility_grid,
|
||||||
|
&visibility_grid,
|
||||||
|
vision_distance,
|
||||||
|
255,
|
||||||
|
|coord, _directions, _visibility| {
|
||||||
|
viewshed.visible.insert((coord.x, coord.y));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_viewshed_for_coordinates<'a>(
|
||||||
|
visible: Query<(&Coordinates, &BlocksVisibility), Changed<Coordinates>>,
|
||||||
|
mut viewers: Query<(Entity, &mut Viewshed, &Coordinates)>,
|
||||||
|
map: Query<&Map>,
|
||||||
|
query_pipeline: Res<QueryPipeline>,
|
||||||
|
collider_query: QueryPipelineColliderComponentsQuery,
|
||||||
|
blocks_visibility: Query<&BlocksVisibility>,
|
||||||
|
) {
|
||||||
|
for (coordinates, _) in visible.iter() {
|
||||||
|
for (viewer_entity, mut viewshed, start) in viewers.iter_mut() {
|
||||||
|
if coordinates.distance(start) > viewshed.range as f32 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Ok(map) = map.single() {
|
||||||
|
update_viewshed(
|
||||||
|
&viewer_entity,
|
||||||
|
&mut viewshed,
|
||||||
|
start,
|
||||||
|
&*query_pipeline,
|
||||||
|
&collider_query,
|
||||||
|
map,
|
||||||
|
&blocks_visibility,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_viewshed_for_start<'a>(
|
||||||
mut viewers: Query<(Entity, &mut Viewshed, &Coordinates), Changed<Coordinates>>,
|
mut viewers: Query<(Entity, &mut Viewshed, &Coordinates), Changed<Coordinates>>,
|
||||||
map: Query<&Map>,
|
map: Query<&Map>,
|
||||||
query_pipeline: Res<QueryPipeline>,
|
query_pipeline: Res<QueryPipeline>,
|
||||||
|
@ -102,49 +177,45 @@ fn update_viewshed<'a>(
|
||||||
blocks_visibility: Query<&BlocksVisibility>,
|
blocks_visibility: Query<&BlocksVisibility>,
|
||||||
) {
|
) {
|
||||||
for (viewer_entity, mut viewshed, start) in viewers.iter_mut() {
|
for (viewer_entity, mut viewshed, start) in viewers.iter_mut() {
|
||||||
for map in map.iter() {
|
if let Ok(map) = map.single() {
|
||||||
let mut context: Context<u8> = Context::default();
|
update_viewshed(
|
||||||
let vision_distance = vision_distance::Circle::new(viewshed.range);
|
&viewer_entity,
|
||||||
let coord = Coord::new(start.x_i32(), start.y_i32());
|
&mut viewshed,
|
||||||
viewshed.visible.clear();
|
start,
|
||||||
let collider_set = QueryPipelineColliderComponentsSet(&collider_query);
|
&*query_pipeline,
|
||||||
let shape = Cuboid::new(Vec2::new(0.49, 0.49).into());
|
&collider_query,
|
||||||
let range = viewshed.range as f32;
|
map,
|
||||||
let visibility_grid = VisibilityGrid(map, |coord: Coord| {
|
&blocks_visibility,
|
||||||
if coord.distance(start) > range {
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
let shape_pos = (Vec2::new(coord.x as f32 + 0.5, coord.y as f32 + 0.5), 0.);
|
|
||||||
let mut opacity = 0;
|
|
||||||
query_pipeline.intersections_with_shape(
|
|
||||||
&collider_set,
|
|
||||||
&shape_pos.into(),
|
|
||||||
&shape,
|
|
||||||
InteractionGroups::all(),
|
|
||||||
Some(&|v| {
|
|
||||||
v.entity() != viewer_entity && blocks_visibility.get(v.entity()).is_ok()
|
|
||||||
}),
|
|
||||||
|_| {
|
|
||||||
opacity = 255;
|
|
||||||
false
|
|
||||||
},
|
|
||||||
);
|
|
||||||
opacity
|
|
||||||
});
|
|
||||||
context.for_each_visible(
|
|
||||||
coord,
|
|
||||||
&visibility_grid,
|
|
||||||
&visibility_grid,
|
|
||||||
vision_distance,
|
|
||||||
255,
|
|
||||||
|coord, _directions, _visibility| {
|
|
||||||
viewshed.visible.insert((coord.x, coord.y));
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_blocks_visibility<'a>(
|
||||||
|
removed: RemovedComponents<BlocksVisibility>,
|
||||||
|
mut viewers: Query<(Entity, &mut Viewshed, &Coordinates)>,
|
||||||
|
map: Query<&Map>,
|
||||||
|
query_pipeline: Res<QueryPipeline>,
|
||||||
|
collider_query: QueryPipelineColliderComponentsQuery,
|
||||||
|
blocks_visibility: Query<&BlocksVisibility>,
|
||||||
|
) {
|
||||||
|
for _ in removed.iter() {
|
||||||
|
for (viewer_entity, mut viewshed, start) in viewers.iter_mut() {
|
||||||
|
if let Ok(map) = map.single() {
|
||||||
|
update_viewshed(
|
||||||
|
&viewer_entity,
|
||||||
|
&mut viewshed,
|
||||||
|
start,
|
||||||
|
&*query_pipeline,
|
||||||
|
&collider_query,
|
||||||
|
map,
|
||||||
|
&blocks_visibility,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_visible_and_revealed_tiles(
|
fn update_visible_and_revealed_tiles(
|
||||||
mut map: Query<(&Map, &mut RevealedTiles, &mut VisibleTiles)>,
|
mut map: Query<(&Map, &mut RevealedTiles, &mut VisibleTiles)>,
|
||||||
viewers: Query<&Viewshed, With<Player>>,
|
viewers: Query<&Viewshed, With<Player>>,
|
||||||
|
@ -241,7 +312,12 @@ pub struct VisibilityPlugin;
|
||||||
impl Plugin for VisibilityPlugin {
|
impl Plugin for VisibilityPlugin {
|
||||||
fn build(&self, app: &mut AppBuilder) {
|
fn build(&self, app: &mut AppBuilder) {
|
||||||
app.add_system(add_visibility_indices.system())
|
app.add_system(add_visibility_indices.system())
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, update_viewshed.system())
|
.add_system_to_stage(
|
||||||
|
CoreStage::PostUpdate,
|
||||||
|
update_viewshed_for_coordinates.system(),
|
||||||
|
)
|
||||||
|
.add_system_to_stage(CoreStage::PostUpdate, update_viewshed_for_start.system())
|
||||||
|
.add_system_to_stage(CoreStage::PostUpdate, remove_blocks_visibility.system())
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
update_visible_and_revealed_tiles.system(),
|
update_visible_and_revealed_tiles.system(),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user