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) # Colors are in hex (RED GREEN BLUE ALPHA)
rgba_hidden = "#00000000" rgba_hidden = "#00000000"
rgba_visible = "#FFFFFFFF" rgba_visible = "#FFFFFFFF"
rgba_background = "#000000FF" rgba_background = "#000000AA"
# Higher rate is slower typing speed. Integers only! # Higher rate is slower typing speed. Integers only!
delay = 0.1 delay = 0.1
text = [ 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) # Hex colors for in/visible text (only visible used for now)
rgba_hidden = "#00000000" rgba_hidden = "#00000000"
rgba_visible = "#FFFFFFFF" rgba_visible = "#FFFFFFFF"
rgba_background = "#000000FF" rgba_background = "#000000AA"
intro = [ intro = [
""" """

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

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

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

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

Loading…
Cancel
Save