bug infestation. selecting/capturing/etc in 2d works worse than in 3d

bevy0.12
Elijah C. Voigt 2 years ago
parent 8e0254c7e8
commit 38b796ad31

@ -33,7 +33,7 @@ impl Plugin for Display2dPlugin {
}),
update_background.run_if(on_event::<WindowResized>()),
set_transform
.after(game::update_board::<Display2d>)
.after(game::update_board)
.run_if(any_component_changed::<BoardIndex>),
set_piece_sprite.run_if(any_component_changed::<Side>),
set_tile_sprite.run_if(any_component_added::<game::Tile>),

@ -11,8 +11,7 @@ impl Plugin for GamePlugin {
Update,
(
menu::exit_to_menu.run_if(in_state(GameState::Play)),
update_board::<display2d::Display2d>.run_if(on_event::<Move>()),
update_board::<display3d::Display3d>.run_if(on_event::<Move>()),
update_board.run_if(on_event::<Move>()),
set_side.run_if(on_event::<Move>()), // TODO: correct run_if?
cancel_place.run_if(|buttons: Res<Input<MouseButton>>| -> bool {
buttons.just_pressed(MouseButton::Right)
@ -20,10 +19,7 @@ impl Plugin for GamePlugin {
select_sync.run_if(any_component_added::<Selected>),
deselect_sync.run_if(any_component_removed::<Selected>()),
move_piece.run_if(any_component_added::<Selected>),
exclusive_select::<display2d::Display2d>
.run_if(any_component_added::<Selected>),
exclusive_select::<display2d::Display2d>
.run_if(any_component_added::<Selected>),
capture_piece.run_if(any_component_added::<Captured>),
),
)
.add_systems(
@ -62,6 +58,9 @@ pub(crate) fn tiles() -> impl Iterator<Item = (BoardIndex, Tile)> {
#[derive(Debug, Component)]
pub(crate) struct BoardComponent;
#[derive(Debug, Component)]
pub(crate) struct Captured;
// manually for the type.
impl std::fmt::Display for Piece {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
@ -76,7 +75,6 @@ impl std::fmt::Display for Piece {
#[derive(Debug)]
pub(crate) enum GameError {
NullMove,
InvalidMove,
InvalidIndex,
}
@ -150,12 +148,14 @@ impl Board {
) -> Result<Vec<Move>, GameError> {
if from == to {
Err(GameError::NullMove)
} else if self.at(to).is_none() {
} else {
self.at(from).map_or(Err(GameError::NullMove), |from_val| {
// The current epoch is the last epoch + 1
let epoch = self.moves.last().unwrap_or(&Move { ..default() }).epoch + 1;
// Local moves vec we can return
let mut moves = vec![];
// If the position we are moving to is occupied, capture the removal in the ledger
if self.inner[to.y][to.x].is_some() {
moves.push(Move {
@ -164,21 +164,21 @@ impl Board {
to: None,
});
}
// Capture the intened move in the moves ledger
moves.push(Move {
epoch,
from: from.clone(),
to: Some(to.clone()),
});
self.moves.extend(moves.clone());
// TODO: We can self.inner.swap(to, from) if board is single vec
// Update board to reflect move
self.inner[to.y][to.x] = Some(from_val);
self.inner[from.y][from.x] = None;
Ok(moves)
})
} else {
Err(GameError::InvalidMove)
}
}
@ -272,9 +272,10 @@ fn debug_board(board: Res<Board>, mut debug_info: ResMut<debug::DebugInfo>) {
/// Update this method to use a diff between the board and the state of the 2d/3d worlds
/// Only update the tiles without a corresponding board piece
pub(crate) fn update_board<T: Component>(
pub(crate) fn update_board(
mut events: EventReader<Move>,
mut pieces: Query<(Entity, &mut BoardIndex), (With<Piece>, With<T>)>,
mut pieces: Query<(Entity, &mut BoardIndex), (With<Piece>, Without<Tile>)>,
tiles: Query<(Entity, &BoardIndex), (With<Tile>, Without<Piece>)>,
mut commands: Commands,
) {
events.iter().for_each(|Move { from, to, .. }| {
@ -282,12 +283,25 @@ pub(crate) fn update_board<T: Component>(
.iter_mut()
.filter(|(_, index)| **index == *from)
.for_each(|(entity, mut index)| {
if let Some(idx) = to {
*index = idx.clone();
} else {
commands.entity(entity).remove::<BoardIndex>();
match to {
Some(to_idx) => {
*index = to_idx.clone();
}
None => {
commands
.entity(entity)
.remove::<BoardIndex>()
.insert(Captured);
}
}
})
commands.entity(entity).remove::<Selected>();
});
tiles
.iter()
.filter_map(|(entity, idx)| (Some(idx) == to.as_ref() || idx == from).then_some(entity))
.for_each(|entity| {
commands.entity(entity).remove::<Selected>();
});
})
}
@ -349,44 +363,32 @@ fn cancel_place(current: Query<Entity, (With<Selected>, With<Piece>)>, mut comma
/// When a tile is selected, move all selected pieces to that index
fn move_piece(
events: Query<(Entity, &BoardIndex), (With<Tile>, Added<Selected>)>,
selected_pieces: Query<(Entity, &BoardIndex), (With<Selected>, With<Piece>)>,
events: Query<(Entity, &BoardIndex), (With<BoardIndex>, Added<Selected>)>,
selected_pieces: Query<&BoardIndex, (With<Selected>, With<Piece>)>,
mut board: ResMut<Board>,
mut commands: Commands,
mut move_events: EventWriter<Move>,
) {
events.iter().for_each(|(tile, to)| {
selected_pieces.iter().for_each(|(piece, from)| {
selected_pieces.iter().for_each(|from| {
// Move piece
match board.move_piece(from, to) {
Ok(moves) => {
// De-select the piece
commands.entity(piece).remove::<Selected>();
info!("Applying moves {:?}", moves);
moves.iter().for_each(|m| move_events.send(m.clone()));
}
Err(GameError::NullMove) => warn!("Null move!"),
Err(GameError::InvalidMove) => warn!("Invalid move!"),
Err(GameError::InvalidIndex) => warn!("Invalid index!"),
}
});
// De-select the tile
commands.entity(tile).remove::<Selected>();
});
}
/// TEMPORARY: Exclusive selection; only select one piece at a time
fn exclusive_select<T: Component>(
events: Query<Entity, (Added<Selected>, With<Piece>, With<T>)>,
selected: Query<Entity, (With<Selected>, With<Piece>, With<T>)>,
mut commands: Commands,
) {
// Iterate over selected component markers on pieces
events.iter().for_each(|entity| {
// Selected > 2 (one for each display2d/3d)
selected.iter().filter(|&e| e != entity).for_each(|e| {
// Remove the previously added selected marker
commands.entity(e).remove::<Selected>();
});
/// When a piece's _BoardIndex_ is removed, we hide that entity from the viewer
fn capture_piece(mut events: Query<&mut Visibility, Added<Captured>>) {
events.iter_mut().for_each(|mut vis| {
info!("Hiding captured piece");
*vis = Visibility::Hidden
});
}

@ -143,7 +143,7 @@ fn toggle_display_mode(
fn activate<Marker: Component>(
mut cameras: Query<&mut Camera, With<Marker>>,
mut entities: Query<&mut Visibility, With<Marker>>,
mut entities: Query<&mut Visibility, (With<Marker>, Without<game::Captured>)>,
) {
cameras.iter_mut().for_each(|mut camera| {
camera.is_active = true;
@ -155,7 +155,7 @@ fn activate<Marker: Component>(
fn deactivate<Marker: Component>(
mut cameras: Query<&mut Camera, With<Marker>>,
mut entities: Query<&mut Visibility, With<Marker>>,
mut entities: Query<&mut Visibility, (With<Marker>, Without<game::Captured>)>,
) {
cameras.iter_mut().for_each(|mut camera| {
camera.is_active = false;

Loading…
Cancel
Save