moves is making progress

bevy0.12
Elijah C. Voigt 2 years ago
parent cdf0b52ea6
commit 1eba3d962e

@ -47,22 +47,15 @@ impl Plugin for Display3dPlugin {
.add_systems( .add_systems(
Update, Update,
( (
move_camera move_camera.run_if(on_event::<MouseMotion>()),
.run_if(resource_exists::<debug::DebugEnabled>()) mouse_zoom.run_if(on_event::<MouseWheel>()),
.run_if(in_state(GameState::Play)) gizmo_system,
.run_if(in_state(DisplayState::Display3d)) selected_gizmo,
.run_if(on_event::<MouseMotion>()), moves_gizmo,
gizmo_system )
.run_if(resource_exists::<debug::DebugEnabled>()) .run_if(resource_exists::<debug::DebugEnabled>())
.run_if(in_state(GameState::Play)) .run_if(in_state(GameState::Play))
.run_if(in_state(DisplayState::Display3d)), .run_if(in_state(DisplayState::Display3d)),
mouse_zoom
.run_if(resource_exists::<debug::DebugEnabled>())
.run_if(in_state(GameState::Play))
.run_if(in_state(DisplayState::Display3d))
.run_if(on_event::<MouseWheel>()),
selected_gizmo.run_if(resource_exists::<debug::DebugEnabled>()),
),
) )
.add_systems( .add_systems(
OnEnter(DisplayState::Display3d), OnEnter(DisplayState::Display3d),
@ -516,14 +509,7 @@ fn select(
} }
fn selected_gizmo( fn selected_gizmo(
selected: Query< selected: Query<&Transform, (With<game::Selected>, With<Display3d>)>,
&Transform,
(
With<game::Selected>,
With<game::Selectable>,
With<Display3d>,
),
>,
mut gizmos: Gizmos, mut gizmos: Gizmos,
) { ) {
selected.iter().for_each(|transform| { selected.iter().for_each(|transform| {
@ -531,6 +517,20 @@ fn selected_gizmo(
}) })
} }
fn moves_gizmo(
selected: Query<&BoardIndex, (With<game::Piece>, With<game::Selected>, With<Display3d>)>,
board: Res<Board>,
mut gizmos: Gizmos,
) {
selected.iter().for_each(|idx| {
board
.possible_moves(*idx)
.iter()
.map(|i| Transform::from_translation(board_translation(i)))
.for_each(|t| gizmos.cuboid(t, Color::WHITE))
});
}
fn pick_up( fn pick_up(
mut events: Query< mut events: Query<
(Entity, &game::Piece), (Entity, &game::Piece),

@ -1,3 +1,5 @@
use bevy::utils::HashSet;
use crate::prelude::*; use crate::prelude::*;
pub(crate) struct GamePlugin; pub(crate) struct GamePlugin;
@ -20,6 +22,14 @@ impl Plugin for GamePlugin {
deselect_sync.run_if(any_component_removed::<Selected>()), deselect_sync.run_if(any_component_removed::<Selected>()),
move_piece.run_if(any_component_added::<Selected>), move_piece.run_if(any_component_added::<Selected>),
capture_piece.run_if(any_component_added::<Captured>), capture_piece.run_if(any_component_added::<Captured>),
null_selections.run_if(any_component_added::<Selected>),
),
)
.add_systems(
PostUpdate,
(
asserts::<display2d::Display2d>,
asserts::<display3d::Display3d>,
), ),
) )
.add_systems( .add_systems(
@ -110,7 +120,7 @@ pub(crate) struct Move {
pub to: Option<BoardIndex>, pub to: Option<BoardIndex>,
} }
#[derive(Debug, Component, PartialEq, Clone, Default, Copy)] #[derive(Debug, Component, PartialEq, Clone, Default, Copy, Eq, Hash)]
pub(crate) struct BoardIndex { pub(crate) struct BoardIndex {
pub x: usize, pub x: usize,
pub y: usize, pub y: usize,
@ -196,24 +206,46 @@ impl Board {
} }
/// Returns the possible moves the piece at this tile can make. /// Returns the possible moves the piece at this tile can make.
pub(crate) fn possible_moves(&self, BoardIndex { x, y }: BoardIndex) -> Vec<BoardIndex> { pub(crate) fn possible_moves(&self, BoardIndex { x, y }: BoardIndex) -> HashSet<BoardIndex> {
match self.at(BoardIndex { x, y }) { match self.at(BoardIndex { x, y }) {
// One space in any diagonal // One space in any diagonal
Some(Piece::Pawn) => { Some(Piece::Pawn) => (-1..=1)
self.at(BoardIndex { x: x + 1, y }); .flat_map(move |xi| {
vec![] (-1..=1).map(move |yi| BoardIndex {
} x: x.checked_add_signed(xi).map_or(0, |val| val).clamp(0, 7),
y: y.checked_add_signed(yi).map_or(0, |val| val).clamp(0, 3),
})
})
.collect(),
// One or two spaces in either horizontal // One or two spaces in either horizontal
Some(Piece::Drone) => { Some(Piece::Drone) => std::iter::empty()
todo!("Where can a drone move?"); .chain((-2..=2).map(|i| BoardIndex {
vec![] x: x.checked_add_signed(i).map_or(0, |val| val).clamp(0, 7),
} y,
}))
.chain((-2..=2).map(|i| BoardIndex {
x,
y: y.checked_add_signed(i).map_or(0, |val| val).clamp(0, 3),
}))
.collect(),
// Any distance in any straight line // Any distance in any straight line
Some(Piece::Queen) => { Some(Piece::Queen) => std::iter::empty()
todo!("Where can a queen move?"); .chain((-7..=7).map(|i| BoardIndex {
vec![] x: x.checked_add_signed(i).map_or(0, |val| val).clamp(0, 7),
} y,
None => Vec::new(), }))
.chain((-3..=3).map(|i| BoardIndex {
x,
y: y.checked_add_signed(i).map_or(0, |val| val).clamp(0, 3),
}))
.chain((-3..=3).flat_map(move |xi| {
(-3..=3).map(move |yi| BoardIndex {
x: x.checked_add_signed(xi).map_or(0, |val| val).clamp(0, 7),
y: y.checked_add_signed(yi).map_or(0, |val| val).clamp(0, 3),
})
}))
.collect(),
None => std::iter::empty().collect(),
} }
} }
} }
@ -301,15 +333,13 @@ fn debug_board(board: Res<Board>, mut debug_info: ResMut<debug::DebugInfo>) {
/// Only update the tiles without a corresponding board piece /// Only update the tiles without a corresponding board piece
pub(crate) fn update_board( pub(crate) fn update_board(
mut events: EventReader<Move>, mut events: EventReader<Move>,
mut pieces: Query<(Entity, &mut BoardIndex), (With<Piece>, Without<Tile>)>, mut pieces: Query<(Entity, &mut BoardIndex), With<Piece>>,
tiles: Query<(Entity, &BoardIndex), (With<Tile>, Without<Piece>)>, selected: Query<Entity, With<Selected>>,
mut commands: Commands, mut commands: Commands,
) { ) {
events.iter().for_each(|Move { from, to, .. }| { events.iter().for_each(|Move { from, to, .. }| {
pieces pieces.iter_mut().for_each(|(entity, mut index)| {
.iter_mut() if *index == *from {
.filter(|(_, index)| **index == *from)
.for_each(|(entity, mut index)| {
match to { match to {
Some(to_idx) => { Some(to_idx) => {
*index = to_idx.clone(); *index = to_idx.clone();
@ -321,12 +351,9 @@ pub(crate) fn update_board(
.insert(Captured); .insert(Captured);
} }
} }
commands.entity(entity).remove::<Selected>(); }
}); });
tiles selected.iter().for_each(|entity| {
.iter()
.filter_map(|(entity, idx)| (Some(idx) == to.as_ref() || idx == from).then_some(entity))
.for_each(|entity| {
commands.entity(entity).remove::<Selected>(); commands.entity(entity).remove::<Selected>();
}); });
}) })
@ -381,7 +408,7 @@ fn deselect_sync(
} }
/// Triggered when right-mouse-button clicked /// Triggered when right-mouse-button clicked
fn cancel_place(current: Query<Entity, (With<Selected>, With<Piece>)>, mut commands: Commands) { fn cancel_place(current: Query<Entity, With<Selected>>, mut commands: Commands) {
current.iter().for_each(|entity| { current.iter().for_each(|entity| {
info!("De-selecting {:?}", entity); info!("De-selecting {:?}", entity);
commands.entity(entity).remove::<Selected>(); commands.entity(entity).remove::<Selected>();
@ -390,13 +417,12 @@ fn cancel_place(current: Query<Entity, (With<Selected>, With<Piece>)>, mut comma
/// When a tile is selected, move all selected pieces to that index /// When a tile is selected, move all selected pieces to that index
fn move_piece( fn move_piece(
events: Query<(Entity, &BoardIndex), (With<BoardIndex>, Added<Selected>)>, events: Query<&BoardIndex, (With<BoardIndex>, Added<Selected>)>,
selected_pieces: Query<&BoardIndex, (With<Selected>, With<Piece>)>, selected_pieces: Query<&BoardIndex, (With<Selected>, With<Piece>)>,
mut board: ResMut<Board>, mut board: ResMut<Board>,
mut commands: Commands,
mut move_events: EventWriter<Move>, mut move_events: EventWriter<Move>,
) { ) {
events.iter().for_each(|(tile, to)| { events.iter().for_each(|to| {
selected_pieces.iter().for_each(|from| { selected_pieces.iter().for_each(|from| {
// Move piece // Move piece
match board.move_piece(*from, *to) { match board.move_piece(*from, *to) {
@ -412,6 +438,20 @@ fn move_piece(
}); });
} }
/// De-select anything that shouldn't be selected
/// Namely tiles when there are not selected pieces
fn null_selections(
events: Query<Entity, Added<Selected>>,
selected_pieces: Query<Entity, (With<Selected>, With<Piece>)>,
mut commands: Commands,
) {
events.iter().for_each(|entity| {
if selected_pieces.is_empty() {
commands.entity(entity).remove::<Selected>();
}
});
}
/// When a piece's _BoardIndex_ is removed, we hide that entity from the viewer /// When a piece's _BoardIndex_ is removed, we hide that entity from the viewer
fn capture_piece(mut events: Query<&mut Visibility, Added<Captured>>) { fn capture_piece(mut events: Query<&mut Visibility, Added<Captured>>) {
events.iter_mut().for_each(|mut vis| { events.iter_mut().for_each(|mut vis| {
@ -419,3 +459,19 @@ fn capture_piece(mut events: Query<&mut Visibility, Added<Captured>>) {
*vis = Visibility::Hidden *vis = Visibility::Hidden
}); });
} }
/// Panics if more than two pieces are selected at a time
fn asserts<T: Component>(
selected_pieces: Query<Entity, (With<Piece>, With<T>, With<Selected>)>,
selected_tiles: Query<Entity, (With<Tile>, With<T>, With<Selected>)>,
) {
if selected_pieces.iter().len() > 2 {
panic!("More than two piece is selected");
}
if selected_tiles.iter().len() > 1 {
panic!(
"More than one tile is selected {:?}",
selected_tiles.iter().len()
);
}
}

Loading…
Cancel
Save