Fixing selecting multiple pieces woot woot!

main
Elijah C. Voigt 2 years ago
parent 06fa416447
commit 1b70e0707e

@ -43,7 +43,7 @@ Neothic Font by Daymarius: https://www.dafont.com/neothic.font
# Colors are in hex (RED GREEN BLUE ALPHA)
rgba_hidden = "#00000000"
rgba_visible = "#FFFFFFFF"
rgba_background = "#000000FF"
rgba_background = "#000000AA"
# Higher rate is slower typing speed. Integers only!
delay = 0.1
text = [
@ -69,7 +69,7 @@ Will you be a part of the universal rhyme, and if so, which side are you on?
# Hex colors for in/visible text (only visible used for now)
rgba_hidden = "#00000000"
rgba_visible = "#FFFFFFFF"
rgba_background = "#000000FF"
rgba_background = "#000000AA"
intro = [
"""

@ -47,7 +47,7 @@ fn init_credits_ui(
padding: UiRect::all(Val::Px(25.0)),
..default()
},
background_color: Color::BLACK.into(),
background_color: Color::BLACK.with_a(0.9).into(),
..default()
},
))

@ -558,49 +558,72 @@ fn select(
mut selections: EventWriter<game::Selection>,
state: Res<State<game::TurnState>>,
) {
// For every mouse click event
events
.read()
// Only read button presses
.filter(|ev| ev.state == ButtonState::Pressed)
.for_each(|_| {
// For each window (there should be only one)
windows.iter().for_each(|window| {
// Get the cursor position
if let Some(pos) = window.cursor_position() {
// iterate over every camera
cameras.iter().for_each(|(camera, gt)| {
// Get a ray from the camera through the cursor into the world
if let Some(ray) = camera.viewport_to_world(gt, pos) {
// Iterate over every entity with a 3d scene
query
.iter()
// Transform the scene handle into mesh data
.filter_map(|(entity, handle, gt)| {
meshes.get(handle).map(|mesh| (entity, mesh, gt))
})
.for_each(|(entity, mesh, gt)| {
if let Some(_hit) = hit::intersects3d(&ray, mesh, gt) {
selectable
.iter()
.find_map(|(e, &board_index, &side)| {
// Check the side of the selection if no piece is selected
// Otherwise this is fine, select away
let side_check =
!selected.is_empty() || state.get().0 == side;
let hit_check = {
// This entity was hit (tile hitboxes)
let primary = entity == e;
// A child was hit (pieces)
let secondary = children
.iter_descendants(e)
.any(|child| child == entity);
primary || secondary
};
(side_check && hit_check).then_some(board_index)
})
.iter()
.for_each(|&board_index| {
info!("Board index selected: {:?}", board_index);
selections.send(game::Selection(board_index));
});
}
// Iterate over every mesh + global transform
.filter_map(|(entity, mesh, gt)| {
// If the camera -> cursor -> * ray intersects with the mesh
hit3d::intersects3d(&ray, mesh, gt).map(|hit| (entity, hit))
})
.filter_map(|(entity, hit)| {
// Find this entity in the set of selectable entities
selectable
.iter()
.find_map(|(e, &board_index, &side)| {
// Check the side of the selection if no piece is selected
// Otherwise this is fine, select away
let side_check =
!selected.is_empty() || state.get().0 == side;
let hit_check = {
// This entity was hit (tile hitboxes)
let primary = entity == e;
// A child was hit (pieces)
let secondary = children
.iter_descendants(e)
.any(|child| child == entity);
primary || secondary
};
// Return the board index of this piece
(side_check && hit_check).then_some(board_index)
})
.map(|board_index| {
// Include the hit from the camera
(hit, board_index)
})
})
// Compare the distance of all hits, choosing the closest one
.min_by(|(hit_a, _), (hit_b, _)| {
hit_a.distance.partial_cmp(&hit_b.distance).unwrap()
})
// Iterate over the 0 or 1 outcomes of the above
.iter()
// Send an event that this board index was selected
.for_each(|(_, board_index)| {
info!("Board index selected: {:?}", board_index);
selections.send(game::Selection(*board_index));
});
}
});

@ -3,7 +3,7 @@ use crate::prelude::*;
/// Hit data for 3d objects in Global (not Local) space and the distance from the Camera
#[derive(Debug)]
pub(crate) struct Hit3d {
distance: f32,
pub distance: f32,
_point: Vec3,
}

@ -8,7 +8,7 @@ mod credits;
mod debug;
mod display3d;
mod game;
mod hit;
mod hit3d;
mod intro;
mod loading;
mod menu;

Loading…
Cancel
Save