Skip to content
This repository has been archived by the owner on Nov 22, 2023. It is now read-only.

Commit

Permalink
Fix signals following voxel migration (#976)
Browse files Browse the repository at this point in the history
* Fix off-by-one in signal visualization

* Diplay signal info on terrain selection correctly

* Make walkable neighbors asymettric to let units and signals escape

* Modiffy validation to account for new logic
  • Loading branch information
alice-i-cecile authored Jun 23, 2023
1 parent 35aedb2 commit ff0c161
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
36 changes: 25 additions & 11 deletions emergence_lib/src/geometry/indexing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ impl MapGeometry {

for (voxel_pos, voxel_data) in self.voxel_index.iter() {
if voxel_data.object_kind.can_walk_on_roof() {
let can_walk_through = match self.get_voxel(voxel_pos.above()) {
let can_walk_through: bool = match self.get_voxel(voxel_pos.above()) {
Some(voxel_data) => voxel_data.object_kind.can_walk_through(),
None => true,
};
Expand All @@ -774,6 +774,19 @@ impl MapGeometry {
walkable_voxels
}

/// The set of voxels that units and signals can originate from.
fn origin_voxels(&self) -> HashSet<VoxelPos> {
let mut origin_voxels = HashSet::new();

for (voxel_pos, voxel_data) in self.voxel_index.iter() {
if voxel_data.object_kind.can_walk_on_roof() {
origin_voxels.insert(voxel_pos.above());
}
}

origin_voxels
}

/// Recomputes the set of passable neighbors for the provided `voxel_pos`.
///
/// This will update the entire map at once.
Expand All @@ -782,14 +795,16 @@ impl MapGeometry {
let walkable_voxels = self.walkable_voxels();
self.walkable_neighbors.clear();

for walkable_voxel in &walkable_voxels {
// We need to compute paths *from* (but not *to*) any place where signals or units could possibly originate
// This includes solid structures, in addition to empty or walkable voxels
for origin_voxel in &self.origin_voxels() {
let mut local_neighbors = Neighbors::NONE;

for (i, &direction) in hexx::Direction::ALL_DIRECTIONS.iter().enumerate() {
let neighbor_hex = walkable_voxel.hex.neighbor(direction);
let neighbor_hex = origin_voxel.hex.neighbor(direction);
let neighbor_flat = VoxelPos {
hex: neighbor_hex,
height: walkable_voxel.height,
height: origin_voxel.height,
};
let neighbor_above = neighbor_flat.above();
let neighbor_below = neighbor_flat.below();
Expand All @@ -808,7 +823,7 @@ impl MapGeometry {
}

self.walkable_neighbors
.insert(*walkable_voxel, local_neighbors);
.insert(*origin_voxel, local_neighbors);
}

#[cfg(test)]
Expand Down Expand Up @@ -876,13 +891,12 @@ impl MapGeometry {
.copied()
.collect::<HashSet<_>>();

let a_minus_b = walkable_voxels.difference(&walkable_neighbors_keys);
let b_minus_a = walkable_neighbors_keys.difference(&walkable_voxels);

assert!(
walkable_voxels == walkable_neighbors_keys,
"Walkable voxels and walkable neighbors keys do not match. Found {:?} in walkable voxels but not in walkable neighbors keys. Found {:?} in walkable neighbors keys but not in walkable voxels.",
a_minus_b, b_minus_a
// The set of keys should be larger, because it accounts for all possible origins
// Units and signals must be able to *leave* any voxel
walkable_voxels.difference(&walkable_neighbors_keys).into_iter().count() == 0,
"Walkable voxels and walkable neighbors keys have desynced. Found {:?} in walkable voxels but not in walkable neighbors keys.",
walkable_voxels.difference(&walkable_neighbors_keys)
);

for neighbors in self.walkable_neighbors.values() {
Expand Down
6 changes: 4 additions & 2 deletions emergence_lib/src/graphics/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,12 +490,14 @@ fn set_overlay_material(
let maybe_material = match tile_overlay.overlay_type {
OverlayType::None => None,
OverlayType::Single(signal_type) => {
let signal_strength = signals.get(signal_type, voxel_pos);
// We must look at the voxel above the terrain to get the signal strength, as those are the voxels that units can walk in
let signal_strength = signals.get(signal_type, voxel_pos.above());
let signal_kind = signal_type.into();
tile_overlay.get_signal_material(signal_kind, signal_strength)
}
OverlayType::StrongestSignal => signals
.strongest_goal_signal_at_position(voxel_pos)
// We must look at the voxel above the terrain to get the signal strength, as those are the voxels that units can walk in
.strongest_goal_signal_at_position(voxel_pos.above())
.and_then(|(signal_type, signal_strength)| {
let signal_kind = signal_type.into();
tile_overlay.get_signal_material(signal_kind, signal_strength)
Expand Down
4 changes: 3 additions & 1 deletion emergence_lib/src/ui/selection_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,9 @@ fn get_details(
depth_to_water_table: *terrain_query_item.water_depth,
shade: terrain_query_item.shade.clone(),
recieved_light: terrain_query_item.recieved_light.clone(),
signals: signals.all_signals_at_position(*terrain_query_item.voxel_pos),
// We must display the signals at the position above the terrain, because
// the terrain itself is opaque to signals.
signals: signals.all_signals_at_position(terrain_query_item.voxel_pos.above()),
zoning: terrain_query_item.zoning.clone(),
maybe_terraforming_details: terrain_query_item.maybe_terraforming_details.map(
|q| terrain_details::TerraformingDetails {
Expand Down

0 comments on commit ff0c161

Please sign in to comment.