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,
|
||||
pool: Res<AsyncComputeTaskPool>,
|
||||
mut calculating: Local<HashMap<Entity, Receiver<Path>>>,
|
||||
query: Query<(Entity, &Destination, &Coordinates), Changed<Destination>>,
|
||||
query: Query<(Entity, &Destination, &Coordinates), Without<Path>>,
|
||||
destinations: Query<&Destination>,
|
||||
map: Query<&Map>,
|
||||
) {
|
||||
|
@ -55,6 +55,8 @@ fn calculate_path(
|
|||
if let Ok(path) = rx.try_recv() {
|
||||
commands.entity(*entity).insert(path);
|
||||
calculating.remove(&entity);
|
||||
} else {
|
||||
commands.entity(*entity).remove::<Destination>();
|
||||
}
|
||||
} else {
|
||||
calculating.remove(&entity);
|
||||
|
@ -104,7 +106,13 @@ fn negotiate_path(
|
|||
if let Some(upcoming) = iter.next() {
|
||||
new_path = vec![start_i32];
|
||||
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;
|
||||
if path.len() >= 2 {
|
||||
|
@ -113,7 +121,7 @@ fn negotiate_path(
|
|||
position.position.translation.y,
|
||||
);
|
||||
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() {
|
||||
let v = next - start;
|
||||
let angle = v.y.atan2(v.x);
|
||||
|
@ -121,12 +129,12 @@ fn negotiate_path(
|
|||
}
|
||||
let mut direction = next - start;
|
||||
direction = direction.normalize();
|
||||
direction *= speed.0;
|
||||
direction *= **speed;
|
||||
velocity.linvel = direction.into();
|
||||
} else {
|
||||
commands.entity(entity).remove::<Path>();
|
||||
commands.entity(entity).remove::<Destination>();
|
||||
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>>,
|
||||
map: Query<&Map>,
|
||||
query_pipeline: Res<QueryPipeline>,
|
||||
|
@ -102,49 +177,45 @@ fn update_viewshed<'a>(
|
|||
blocks_visibility: Query<&BlocksVisibility>,
|
||||
) {
|
||||
for (viewer_entity, mut viewshed, start) in viewers.iter_mut() {
|
||||
for map in map.iter() {
|
||||
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 collider_set = QueryPipelineColliderComponentsSet(&collider_query);
|
||||
let shape = Cuboid::new(Vec2::new(0.49, 0.49).into());
|
||||
let range = viewshed.range as f32;
|
||||
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));
|
||||
},
|
||||
if let Ok(map) = map.single() {
|
||||
update_viewshed(
|
||||
&viewer_entity,
|
||||
&mut viewshed,
|
||||
start,
|
||||
&*query_pipeline,
|
||||
&collider_query,
|
||||
map,
|
||||
&blocks_visibility,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
mut map: Query<(&Map, &mut RevealedTiles, &mut VisibleTiles)>,
|
||||
viewers: Query<&Viewshed, With<Player>>,
|
||||
|
@ -241,7 +312,12 @@ pub struct VisibilityPlugin;
|
|||
impl Plugin for VisibilityPlugin {
|
||||
fn build(&self, app: &mut AppBuilder) {
|
||||
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(
|
||||
CoreStage::PostUpdate,
|
||||
update_visible_and_revealed_tiles.system(),
|
||||
|
|
Loading…
Reference in New Issue
Block a user