Use Visible component with opacity to indicate that something should appear visually.

This commit is contained in:
Nolan Darilek 2021-09-22 08:23:01 -05:00
parent e90a85641b
commit a59f8a22a1
4 changed files with 54 additions and 52 deletions

View File

@ -266,13 +266,9 @@ fn exploration_focus<S, A: 'static>(
config.action_explore_left.clone(),
config.action_explore_right.clone(),
) {
println!("Here1");
for map in map.iter() {
println!("Here2");
if let Ok((entity, coordinates, exploring)) = explorers.single() {
println!("Here");
let coordinates = coordinates.i32();
let coordinates = (coordinates.x() + 0.5, coordinates.y() + 0.5);
let coordinates = **coordinates;
let mut exploring = if let Some(exploring) = exploring {
**exploring
} else {
@ -346,7 +342,7 @@ fn exploration_changed_announcement(
for (map, revealed_tiles, visible_tiles) in map.iter() {
let point = **exploring;
let idx = point.to_index(map.width);
let shape = Cuboid::new(Vec2::new(0.5, 0.5).into());
let shape = Cuboid::new(Vec2::new(0.49, 0.49).into());
let known = revealed_tiles[idx];
let visible = visible_tiles[idx];
let fog_of_war = known && !visible;

View File

@ -13,7 +13,7 @@ use crate::{
exploration::{ExplorationType, Mappable},
log::Log,
utils::target_and_other,
visibility::BlocksVisibility,
visibility::Visible,
};
impl From<mapgen::geometry::Point> for Coordinates {
@ -232,7 +232,7 @@ fn spawn_colliders(
.insert(MapObstruction)
.id();
if tile.blocks_visibility() {
commands.entity(id).insert(BlocksVisibility::default());
commands.entity(id).insert(Visible::default());
}
commands.entity(map_entity).push_children(&[id]);
}
@ -327,7 +327,7 @@ fn spawn_colliders(
.insert(MapObstruction)
.id();
if map.at(x as usize, y as usize).blocks_visibility() {
commands.entity(id).insert(BlocksVisibility::default());
commands.entity(id).insert(Visible::default());
}
commands.entity(map_entity).push_children(&[id]);
bottom_left = None;

View File

@ -28,7 +28,7 @@ impl Default for Footstep {
Self {
sound: "".into(),
step_length: 0.8,
gain: 0.05,
gain: 1.,
reference_distance: 1.,
max_distance: f32::MAX,
rolloff_factor: 1.,

View File

@ -14,16 +14,6 @@ use crate::{
utils::target_and_other,
};
#[derive(Clone, Copy, Debug, Deref, DerefMut, Reflect)]
#[reflect(Component)]
pub struct BlocksVisibility(pub u8);
impl Default for BlocksVisibility {
fn default() -> Self {
Self(u8::MAX)
}
}
#[derive(Clone, Copy, Debug, Default, Reflect)]
#[reflect(Component)]
pub struct DontLogWhenVisible;
@ -56,6 +46,25 @@ impl Viewshed {
#[derive(Clone, Copy, Debug, Default, Reflect)]
struct VisibilityCollider;
#[derive(Clone, Copy, Debug, Deref, DerefMut, Reflect)]
#[reflect(Component)]
pub struct Visible(pub u8);
impl Default for Visible {
fn default() -> Self {
Self::opaque()
}
}
impl Visible {
pub fn transparent() -> Self {
Self(0)
}
fn opaque() -> Self {
Self(u8::MAX)
}
}
#[derive(Clone, Debug, Default, Deref, DerefMut)]
pub struct VisibleEntities(HashSet<Entity>);
@ -156,7 +165,6 @@ fn viewshed_changed(
if let Ok((collider_shape, collider_position)) = collider_data.get_mut(*collider_entity)
{
if viewshed.visible_points.len() < 2 {
println!("Too few points, removing");
commands.entity(*collider_entity).remove::<ColliderShape>();
} else {
let translation = position.position.translation;
@ -217,7 +225,7 @@ fn update_viewshed(
query_pipeline: &QueryPipeline,
collider_query: &QueryPipelineColliderComponentsQuery,
map: &Map,
blocks_visibility: &Query<&BlocksVisibility>,
visible: &Query<&Visible>,
) {
let mut context: Context<u8> = Context::default();
let vision_distance = vision_distance::Circle::new(viewshed.range);
@ -236,11 +244,10 @@ fn update_viewshed(
&shape_pos.into(),
&shape,
InteractionGroups::all(),
Some(&|v| v.entity() != *viewer_entity && blocks_visibility.get(v.entity()).is_ok()),
Some(&|v| v.entity() != *viewer_entity && visible.get(v.entity()).is_ok()),
|handle| {
if let Ok(blocks_visibility) = blocks_visibility.get(handle.entity()) {
opacity = **blocks_visibility;
} else {
if let Ok(visible) = visible.get(handle.entity()) {
opacity = **visible;
}
true
},
@ -264,12 +271,12 @@ fn update_viewshed(
}
fn update_viewshed_for_coordinates(
visible: Query<(Entity, &Coordinates), (Changed<Coordinates>, With<BlocksVisibility>)>,
visible: Query<(Entity, &Coordinates), (Changed<Coordinates>, With<Visible>)>,
mut viewers: Query<(Entity, &mut Viewshed, &Coordinates)>,
map: Query<&Map>,
query_pipeline: Res<QueryPipeline>,
collider_query: QueryPipelineColliderComponentsQuery,
blocks_visibility: Query<&BlocksVisibility>,
visible_query: Query<&Visible>,
) {
for (visible_entity, coordinates) in visible.iter() {
for (viewer_entity, mut viewshed, start) in viewers.iter_mut() {
@ -286,7 +293,7 @@ fn update_viewshed_for_coordinates(
&*query_pipeline,
&collider_query,
map,
&blocks_visibility,
&visible_query,
);
}
}
@ -298,7 +305,7 @@ fn update_viewshed_for_start(
map: Query<&Map>,
query_pipeline: Res<QueryPipeline>,
collider_query: QueryPipelineColliderComponentsQuery,
blocks_visibility: Query<&BlocksVisibility>,
visible: Query<&Visible>,
) {
for (viewer_entity, mut viewshed, start) in viewers.iter_mut() {
if let Ok(map) = map.single() {
@ -309,19 +316,19 @@ fn update_viewshed_for_start(
&*query_pipeline,
&collider_query,
map,
&blocks_visibility,
&visible,
);
}
}
}
fn remove_blocks_visibility(
removed: RemovedComponents<BlocksVisibility>,
fn remove_visible(
removed: RemovedComponents<Visible>,
mut viewers: Query<(Entity, &mut Viewshed, &mut VisibleEntities, &Coordinates)>,
map: Query<&Map>,
query_pipeline: Res<QueryPipeline>,
collider_query: QueryPipelineColliderComponentsQuery,
blocks_visibility: Query<&BlocksVisibility>,
visible: Query<&Visible>,
) {
for removed in removed.iter() {
for (viewer_entity, mut viewshed, mut visible_entities, start) in viewers.iter_mut() {
@ -337,7 +344,7 @@ fn remove_blocks_visibility(
&*query_pipeline,
&collider_query,
map,
&blocks_visibility,
&visible,
);
}
}
@ -370,6 +377,7 @@ fn intersection(
collider_to_viewshed: Res<VisibilityColliderToViewshed>,
colliders: Query<Entity, With<VisibilityCollider>>,
mut viewers: Query<&mut VisibleEntities>,
visible: Query<Entity, With<Visible>>,
mut visibility_changed: EventWriter<VisibilityChanged>,
) {
for event in events.iter() {
@ -378,23 +386,21 @@ fn intersection(
colliders.get(v).is_ok()
})
{
if let Some(viewshed_entity) = collider_to_viewshed.get(&visibility_collider) {
if let Ok(mut visible_entities) = viewers.get_mut(*viewshed_entity) {
if event.intersecting {
visibility_changed.send(VisibilityChanged::Gained {
viewer: *viewshed_entity,
viewed: other,
});
visible_entities.insert(other);
} else {
visibility_changed.send(VisibilityChanged::Lost {
viewer: *viewshed_entity,
viewed: other,
});
if visible_entities.contains(&other) {
visible_entities.remove(&other);
if visible.get(other).is_ok() {
if let Some(viewshed_entity) = collider_to_viewshed.get(&visibility_collider) {
if let Ok(mut visible_entities) = viewers.get_mut(*viewshed_entity) {
if event.intersecting {
visibility_changed.send(VisibilityChanged::Gained {
viewer: *viewshed_entity,
viewed: other,
});
visible_entities.insert(other);
} else {
println!("Making invisible something that was never visible");
visibility_changed.send(VisibilityChanged::Lost {
viewer: *viewshed_entity,
viewed: other,
});
visible_entities.remove(&other);
}
}
}
@ -461,7 +467,7 @@ impl Plugin for VisibilityPlugin {
.add_system_to_stage(CoreStage::PostUpdate, viewshed_removed.system())
.add_system(update_viewshed_for_coordinates.system())
.add_system(update_viewshed_for_start.system())
.add_system_to_stage(CoreStage::PostUpdate, remove_blocks_visibility.system())
.add_system_to_stage(CoreStage::PostUpdate, remove_visible.system())
.add_system_to_stage(
CoreStage::PostUpdate,
update_visible_and_revealed_tiles.system(),