Separate viewshed updates based on coordinate and visibility_blocked.
This commit is contained in:
parent
3050235926
commit
3084d02f66
|
@ -23,7 +23,7 @@ pub struct DontLogWhenVisible;
|
|||
#[reflect(Component)]
|
||||
pub struct RevealedTiles(pub Vec<bool>);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Viewshed {
|
||||
pub visible: HashSet<(i32, i32)>,
|
||||
pub range: u32,
|
||||
|
@ -100,11 +100,11 @@ pub(crate) fn set_visibility_blocked(
|
|||
}
|
||||
|
||||
#[derive(Default, Deref, DerefMut)]
|
||||
struct PreviousIndex(HashMap<Entity, usize>);
|
||||
struct PrevIndex(HashMap<Entity, usize>);
|
||||
|
||||
fn map_visibility_indexing(
|
||||
mut map: Query<(&Map, &mut VisibilityBlocked)>,
|
||||
mut prev_index: ResMut<PreviousIndex>,
|
||||
mut prev_index: ResMut<PrevIndex>,
|
||||
query: Query<
|
||||
(Entity, &Coordinates),
|
||||
(
|
||||
|
@ -135,7 +135,7 @@ fn map_visibility_indexing(
|
|||
}
|
||||
|
||||
fn remove_blocks_visibility(
|
||||
mut prev_index: ResMut<PreviousIndex>,
|
||||
mut prev_index: ResMut<PrevIndex>,
|
||||
mut map: Query<(&Map, &mut VisibilityBlocked)>,
|
||||
removed: RemovedComponents<BlocksVisibility>,
|
||||
coordinates: Query<&Coordinates>,
|
||||
|
@ -184,33 +184,89 @@ impl InputGrid for VisibilityGrid {
|
|||
}
|
||||
|
||||
fn update_viewshed(
|
||||
mut viewers: Query<
|
||||
(&mut Viewshed, &Coordinates),
|
||||
Or<(Changed<VisibilityBlocked>, Changed<Coordinates>)>,
|
||||
>,
|
||||
viewshed: &mut Viewshed,
|
||||
start: &Coordinates,
|
||||
map: &Map,
|
||||
visibility_blocked: &VisibilityBlocked,
|
||||
) {
|
||||
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 visibility_grid = VisibilityGrid(map.clone(), visibility_blocked.clone());
|
||||
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(
|
||||
mut viewers: Query<(&mut Viewshed, &Coordinates), Changed<Coordinates>>,
|
||||
map: Query<(&Map, &VisibilityBlocked)>,
|
||||
) {
|
||||
for (mut viewshed, start) in viewers.iter_mut() {
|
||||
for (map, visibility_blocked) 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 visibility_grid = VisibilityGrid(map.clone(), visibility_blocked.clone());
|
||||
context.for_each_visible(
|
||||
coord,
|
||||
&visibility_grid,
|
||||
&visibility_grid,
|
||||
vision_distance,
|
||||
255,
|
||||
|coord, _directions, _visibility| {
|
||||
viewshed.visible.insert((coord.x, coord.y));
|
||||
},
|
||||
);
|
||||
update_viewshed(&mut viewshed, start, &map, &visibility_blocked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deref, DerefMut)]
|
||||
struct PrevVisibilityBlocked(Vec<bool>);
|
||||
|
||||
fn visibility_blocked_added(mut prev_visibility_blocked: ResMut<PrevVisibilityBlocked>, added: Query<&VisibilityBlocked, Added<VisibilityBlocked>>) {
|
||||
for visibility_blocked in added.iter() {
|
||||
**prev_visibility_blocked = visibility_blocked.to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
fn visibility_blocked_removed(mut prev_visibility_blocked: ResMut<PrevVisibilityBlocked>, removed: RemovedComponents<VisibilityBlocked>) {
|
||||
for _ in removed.iter() {
|
||||
prev_visibility_blocked.clear();
|
||||
}
|
||||
}
|
||||
|
||||
fn update_viewshed_for_visibility_blocked(
|
||||
mut prev_visibility_blocked: ResMut<PrevVisibilityBlocked>,
|
||||
map: Query<(&Map, &VisibilityBlocked), Changed<VisibilityBlocked>>,
|
||||
mut queryset: QuerySet<(
|
||||
Query<(Entity, &Viewshed)>,
|
||||
Query<(&mut Viewshed, &Coordinates)>,
|
||||
)>,
|
||||
) {
|
||||
for (map, visibility_blocked) in map.iter() {
|
||||
let mut to_check = vec![];
|
||||
for (index, new) in visibility_blocked.iter().enumerate() {
|
||||
let changed = if let Some(prev) = prev_visibility_blocked.get(index) {
|
||||
prev != new
|
||||
} else {
|
||||
true
|
||||
};
|
||||
if changed {
|
||||
let coords = (index % map.width(), index / map.width());
|
||||
for (entity, viewshed) in queryset.q0().iter() {
|
||||
if viewshed.is_visible(&coords) {
|
||||
to_check.push(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
to_check.dedup();
|
||||
for entity in to_check {
|
||||
if let Ok((mut viewshed, coordinates)) = queryset.q1_mut().get_mut(entity) {
|
||||
update_viewshed(&mut viewshed, coordinates, &map, &visibility_blocked);
|
||||
}
|
||||
}
|
||||
**prev_visibility_blocked = visibility_blocked.to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
fn update_visible_and_revealed_tiles(
|
||||
mut map: Query<
|
||||
(&Map, &mut RevealedTiles, &mut VisibleTiles),
|
||||
|
@ -301,7 +357,10 @@ impl Plugin for VisibilityPlugin {
|
|||
const UPDATE_VISIBILITY_INDEX: &str = "UPDATE_VISIBILITY_INDEX";
|
||||
const UPDATE_VIEWSHED: &str = "UPDATE_VIEWSHED";
|
||||
const MAP_VISIBILITY: &str = "MAP_VISIBILITY";
|
||||
app.insert_resource(PreviousIndex::default())
|
||||
app.init_resource::<PrevVisibilityBlocked>()
|
||||
.init_resource::<PrevIndex>()
|
||||
.add_system(visibility_blocked_added.system())
|
||||
.add_system_to_stage(CoreStage::PostUpdate, visibility_blocked_removed.system())
|
||||
.add_system(add_visibility_indices.system())
|
||||
.add_system_to_stage(
|
||||
CoreStage::PostUpdate,
|
||||
|
@ -324,7 +383,14 @@ impl Plugin for VisibilityPlugin {
|
|||
)
|
||||
.add_system_to_stage(
|
||||
CoreStage::PostUpdate,
|
||||
update_viewshed
|
||||
update_viewshed_for_coordinates
|
||||
.system()
|
||||
.label(UPDATE_VIEWSHED)
|
||||
.after(UPDATE_VISIBILITY_INDEX),
|
||||
)
|
||||
.add_system_to_stage(
|
||||
CoreStage::PostUpdate,
|
||||
update_viewshed_for_visibility_blocked
|
||||
.system()
|
||||
.label(UPDATE_VIEWSHED)
|
||||
.after(UPDATE_VISIBILITY_INDEX),
|
||||
|
|
Loading…
Reference in New Issue
Block a user