|
|
|
@ -21,7 +21,6 @@ fn main() {
|
|
|
|
Update,
|
|
|
|
Update,
|
|
|
|
(
|
|
|
|
(
|
|
|
|
kb_input.run_if(on_event::<KeyboardInput>),
|
|
|
|
kb_input.run_if(on_event::<KeyboardInput>),
|
|
|
|
update_position,
|
|
|
|
|
|
|
|
falling
|
|
|
|
falling
|
|
|
|
.run_if(in_state(Falling::On))
|
|
|
|
.run_if(in_state(Falling::On))
|
|
|
|
.run_if(clock_cycle(1.0)),
|
|
|
|
.run_if(clock_cycle(1.0)),
|
|
|
|
@ -31,19 +30,16 @@ fn main() {
|
|
|
|
.or(any_component_added::<Orientation>)
|
|
|
|
.or(any_component_added::<Orientation>)
|
|
|
|
.or(any_component_changed::<Orientation>),
|
|
|
|
.or(any_component_changed::<Orientation>),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
shape_block_movement.run_if(
|
|
|
|
update_relative_position,
|
|
|
|
any_component_added::<RelativePosition>
|
|
|
|
update_position.after(update_relative_position),
|
|
|
|
.or(any_component_changed::<RelativePosition>)
|
|
|
|
|
|
|
|
.or(any_component_changed::<GridPosition>),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
sync_singleton_to_ui::<Shape>.run_if(any_component_changed::<Shape>),
|
|
|
|
sync_singleton_to_ui::<Shape>.run_if(any_component_changed::<Shape>),
|
|
|
|
sync_singleton_to_ui::<Orientation>.run_if(any_component_changed::<Orientation>),
|
|
|
|
sync_singleton_to_ui::<Orientation>.run_if(any_component_changed::<Orientation>),
|
|
|
|
check_collision.run_if(any_component_changed::<GridPosition>),
|
|
|
|
|
|
|
|
add_piece.run_if(not(any_with_component::<Shape>)),
|
|
|
|
add_piece.run_if(not(any_with_component::<Shape>)),
|
|
|
|
clear_line.run_if(any_component_changed::<LineBlocks>),
|
|
|
|
clear_line.run_if(any_component_changed::<LineBlocks>),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.add_systems(Update, draw_grid)
|
|
|
|
.add_systems(Update, draw_grid)
|
|
|
|
|
|
|
|
.add_observer(deactive_shape)
|
|
|
|
.run();
|
|
|
|
.run();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -115,7 +111,7 @@ struct Line(u8);
|
|
|
|
#[derive(Component, Debug)]
|
|
|
|
#[derive(Component, Debug)]
|
|
|
|
struct Block;
|
|
|
|
struct Block;
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Component, Event, Debug)]
|
|
|
|
#[derive(Component, Event, Debug, Clone, Copy)]
|
|
|
|
#[require(GridPosition)]
|
|
|
|
#[require(GridPosition)]
|
|
|
|
struct RelativePosition {
|
|
|
|
struct RelativePosition {
|
|
|
|
x: i8,
|
|
|
|
x: i8,
|
|
|
|
@ -124,31 +120,19 @@ struct RelativePosition {
|
|
|
|
|
|
|
|
|
|
|
|
impl RelativePosition {
|
|
|
|
impl RelativePosition {
|
|
|
|
fn up() -> Self {
|
|
|
|
fn up() -> Self {
|
|
|
|
RelativePosition {
|
|
|
|
RelativePosition { x: 0, y: 1 }
|
|
|
|
x: 0,
|
|
|
|
|
|
|
|
y: 1,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn down() -> Self {
|
|
|
|
fn down() -> Self {
|
|
|
|
RelativePosition {
|
|
|
|
RelativePosition { x: 0, y: -1 }
|
|
|
|
x: 0,
|
|
|
|
|
|
|
|
y: -1,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn left() -> Self {
|
|
|
|
fn left() -> Self {
|
|
|
|
RelativePosition {
|
|
|
|
RelativePosition { x: -1, y: 0 }
|
|
|
|
x: -1,
|
|
|
|
|
|
|
|
y: 0,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn right() -> Self {
|
|
|
|
fn right() -> Self {
|
|
|
|
RelativePosition {
|
|
|
|
RelativePosition { x: 1, y: 0 }
|
|
|
|
x: 1,
|
|
|
|
|
|
|
|
y: 0,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -206,12 +190,23 @@ impl GridPosition {
|
|
|
|
self.x == other.x && self.y.saturating_sub(1) == other.y
|
|
|
|
self.x == other.x && self.y.saturating_sub(1) == other.y
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn add_offset(&self, RelativePosition { x: x1, y: y1 }: &RelativePosition) -> Result<Self, GameError> {
|
|
|
|
fn add_relative(
|
|
|
|
let x = self.x.checked_add_signed(*x1 as i32).ok_or(GameError::OutOfBoundsLeft)?;
|
|
|
|
&self,
|
|
|
|
let y = self.y.checked_add_signed(*y1 as i32).ok_or(GameError::OutOfBoundsDown)?;
|
|
|
|
RelativePosition { x: x1, y: y1 }: &RelativePosition,
|
|
|
|
if x >= X_MAX { // TODO: y > Y_MAX?
|
|
|
|
) -> Result<Self, GameError> {
|
|
|
|
|
|
|
|
let x = self
|
|
|
|
|
|
|
|
.x
|
|
|
|
|
|
|
|
.checked_add_signed(*x1 as i32)
|
|
|
|
|
|
|
|
.ok_or(GameError::OutOfBoundsLeft)?;
|
|
|
|
|
|
|
|
let y = self
|
|
|
|
|
|
|
|
.y
|
|
|
|
|
|
|
|
.checked_add_signed(*y1 as i32)
|
|
|
|
|
|
|
|
.ok_or(GameError::OutOfBoundsDown)?;
|
|
|
|
|
|
|
|
if x >= X_MAX {
|
|
|
|
|
|
|
|
// TODO: y > Y_MAX?
|
|
|
|
Err(GameError::OutOfBoundsRight)
|
|
|
|
Err(GameError::OutOfBoundsRight)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
debug!("Moving to {x},{y}");
|
|
|
|
Ok(GridPosition { x, y })
|
|
|
|
Ok(GridPosition { x, y })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -514,7 +509,7 @@ fn set_piece(
|
|
|
|
visuals: Res<Visuals>,
|
|
|
|
visuals: Res<Visuals>,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
query.iter().for_each(|(e, s, o)| {
|
|
|
|
query.iter().for_each(|(e, s, o)| {
|
|
|
|
debug!("{e:?} {s:?} {o:?}");
|
|
|
|
debug!("Setting piece: {e:?} {s:?} {o:?}");
|
|
|
|
|
|
|
|
|
|
|
|
let mesh = visuals.mesh.clone();
|
|
|
|
let mesh = visuals.mesh.clone();
|
|
|
|
let mat = visuals.material.clone();
|
|
|
|
let mat = visuals.material.clone();
|
|
|
|
@ -525,7 +520,9 @@ fn set_piece(
|
|
|
|
.entity(e)
|
|
|
|
.entity(e)
|
|
|
|
.with_related_entities::<ShapeBlock>(|parent| {
|
|
|
|
.with_related_entities::<ShapeBlock>(|parent| {
|
|
|
|
positions.into_iter().for_each(|rp| {
|
|
|
|
positions.into_iter().for_each(|rp| {
|
|
|
|
parent.spawn((Mesh2d(mesh.clone()), MeshMaterial2d(mat.clone()), rp, Block));
|
|
|
|
parent
|
|
|
|
|
|
|
|
.spawn((Mesh2d(mesh.clone()), MeshMaterial2d(mat.clone()), rp, Block))
|
|
|
|
|
|
|
|
.observe(movement);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@ -537,11 +534,42 @@ fn set_piece(
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn update_position(mut query: Query<(&GridPosition, &mut Transform), Changed<GridPosition>>) {
|
|
|
|
fn update_position(
|
|
|
|
query.iter_mut().for_each(|(gp, mut t)| {
|
|
|
|
mut changed: Query<
|
|
|
|
|
|
|
|
(Entity, &GridPosition, &mut Transform),
|
|
|
|
|
|
|
|
Or<(Added<GridPosition>, Changed<GridPosition>)>,
|
|
|
|
|
|
|
|
>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
changed.iter_mut().for_each(|(e, gp, mut t)| {
|
|
|
|
|
|
|
|
let v3: Vec3 = gp.into();
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
|
|
|
|
"Updating {e} with grid position {:?} to coordinates {:?}",
|
|
|
|
|
|
|
|
gp, v3
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
debug_assert!(gp.x < X_MAX, "block x > x_max");
|
|
|
|
debug_assert!(gp.x < X_MAX, "block x > x_max");
|
|
|
|
t.translation = gp.into();
|
|
|
|
t.translation = gp.into();
|
|
|
|
debug!("Updating position {:?}", t.translation);
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn update_relative_position(
|
|
|
|
|
|
|
|
shape: Single<&GridPosition, With<ShapeBlocks>>,
|
|
|
|
|
|
|
|
mut query: Query<
|
|
|
|
|
|
|
|
(Entity, &mut GridPosition, &RelativePosition),
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
Without<ShapeBlocks>,
|
|
|
|
|
|
|
|
Or<(Added<RelativePosition>, Changed<RelativePosition>)>,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
query.iter_mut().for_each(|(e, mut gp, rp)| {
|
|
|
|
|
|
|
|
debug!(
|
|
|
|
|
|
|
|
"Updating {e} grid position to {:?} + {:?} = {:?}",
|
|
|
|
|
|
|
|
gp,
|
|
|
|
|
|
|
|
rp,
|
|
|
|
|
|
|
|
gp.add_relative(rp).unwrap()
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
*gp = (*shape).add_relative(rp).unwrap();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -568,13 +596,13 @@ fn kb_input(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeyCode::ArrowDown => {
|
|
|
|
KeyCode::ArrowDown => {
|
|
|
|
commands.entity(e).trigger(RelativePosition::down());
|
|
|
|
commands.entity(e).trigger(RelativePosition::down());
|
|
|
|
},
|
|
|
|
}
|
|
|
|
KeyCode::ArrowLeft => {
|
|
|
|
KeyCode::ArrowLeft => {
|
|
|
|
commands.entity(e).trigger(RelativePosition::left());
|
|
|
|
commands.entity(e).trigger(RelativePosition::left());
|
|
|
|
},
|
|
|
|
}
|
|
|
|
KeyCode::ArrowRight => {
|
|
|
|
KeyCode::ArrowRight => {
|
|
|
|
commands.entity(e).trigger(RelativePosition::right());
|
|
|
|
commands.entity(e).trigger(RelativePosition::right());
|
|
|
|
},
|
|
|
|
}
|
|
|
|
KeyCode::Space => next.set(match curr.get() {
|
|
|
|
KeyCode::Space => next.set(match curr.get() {
|
|
|
|
Falling::On => Falling::Off,
|
|
|
|
Falling::On => Falling::Off,
|
|
|
|
Falling::Off => Falling::On,
|
|
|
|
Falling::Off => Falling::On,
|
|
|
|
@ -607,28 +635,11 @@ fn draw_grid(mut gizmos: Gizmos) {
|
|
|
|
|
|
|
|
|
|
|
|
fn falling(mut shape: Query<Entity, With<Shape>>, mut commands: Commands) {
|
|
|
|
fn falling(mut shape: Query<Entity, With<Shape>>, mut commands: Commands) {
|
|
|
|
shape.iter_mut().for_each(|e| {
|
|
|
|
shape.iter_mut().for_each(|e| {
|
|
|
|
|
|
|
|
info!("Making {:?} fall", e);
|
|
|
|
commands.entity(e).trigger(RelativePosition::down());
|
|
|
|
commands.entity(e).trigger(RelativePosition::down());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Re-implement parenting for movement, but on the grid structure
|
|
|
|
|
|
|
|
fn shape_block_movement(
|
|
|
|
|
|
|
|
shape: Query<
|
|
|
|
|
|
|
|
&GridPosition,
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
With<ShapeBlocks>,
|
|
|
|
|
|
|
|
Without<RelativePosition>,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
>,
|
|
|
|
|
|
|
|
mut blocks: Query<(&mut GridPosition, &RelativePosition), With<ShapeBlock>>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
shape.iter().for_each(|shape_gp| {
|
|
|
|
|
|
|
|
blocks.iter_mut().for_each(|(mut block_gp, block_rp)| {
|
|
|
|
|
|
|
|
*block_gp = shape_gp.add_offset(block_rp).expect("Cannot move there...");
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run condition that returns `true` every `n` seconds
|
|
|
|
// Run condition that returns `true` every `n` seconds
|
|
|
|
// TODO: Update a resource with the current tick
|
|
|
|
// TODO: Update a resource with the current tick
|
|
|
|
fn clock_cycle(n: f32) -> impl FnMut(Res<Time>, Local<f32>) -> bool {
|
|
|
|
fn clock_cycle(n: f32) -> impl FnMut(Res<Time>, Local<f32>) -> bool {
|
|
|
|
@ -643,58 +654,12 @@ fn clock_cycle(n: f32) -> impl FnMut(Res<Time>, Local<f32>) -> bool {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Check if the active piece is about to collide with the ground
|
|
|
|
|
|
|
|
fn check_collision(
|
|
|
|
|
|
|
|
active: Query<(&GridPosition, Entity), (With<Block>, With<RelativePosition>)>,
|
|
|
|
|
|
|
|
shape: Single<(&GridPosition, Entity), With<ShapeBlocks>>,
|
|
|
|
|
|
|
|
inactive: Query<&GridPosition, (With<Block>, Without<RelativePosition>)>,
|
|
|
|
|
|
|
|
lines: Query<(&Line, Entity)>,
|
|
|
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
// TODO: Easy optimizations
|
|
|
|
|
|
|
|
let hit = active.iter().any(|(a, _e)| {
|
|
|
|
|
|
|
|
debug!("Checking: {:?}", a);
|
|
|
|
|
|
|
|
// Check if active shape is at floor
|
|
|
|
|
|
|
|
let hit_floor = a.y == 0;
|
|
|
|
|
|
|
|
// Check if active peice is near other blocks
|
|
|
|
|
|
|
|
let hit_block = inactive.iter().any(|b| {
|
|
|
|
|
|
|
|
debug!("Checking against: {:?}", b);
|
|
|
|
|
|
|
|
a.is_colliding_with(b)
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hit_floor || hit_block
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if hit {
|
|
|
|
|
|
|
|
info!("hit detected!");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let blocks: Vec<Entity> = active
|
|
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.map(|(gp, e)| commands.entity(e).remove::<RelativePosition>().id())
|
|
|
|
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
debug_assert_eq!(blocks.len(), 4, "Shapes should have 4 blocks");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
info!("De-relating blocks {:?} and shape {:?}", blocks, *shape);
|
|
|
|
|
|
|
|
let (_shape_pos, shape_e) = *shape;
|
|
|
|
|
|
|
|
commands
|
|
|
|
|
|
|
|
.entity(shape_e)
|
|
|
|
|
|
|
|
.remove_related::<ShapeBlock>(blocks.as_slice())
|
|
|
|
|
|
|
|
.despawn();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
active.iter().for_each(|(GridPosition { y, .. }, block_e)| {
|
|
|
|
|
|
|
|
lines.iter().for_each(|(Line(i), line_e)| {
|
|
|
|
|
|
|
|
if *y == *i as u32 {
|
|
|
|
|
|
|
|
commands.entity(line_e).add_one_related::<LineBlock>(block_e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn add_piece(mut commands: Commands) {
|
|
|
|
fn add_piece(mut commands: Commands) {
|
|
|
|
// TODO: Choose a different piece
|
|
|
|
// TODO: Choose a different piece
|
|
|
|
commands.spawn((Orientation::default(), GridPosition::default(), Shape::T)).observe(movement).observe(rotation);
|
|
|
|
commands
|
|
|
|
|
|
|
|
.spawn((Orientation::default(), GridPosition::default(), Shape::T))
|
|
|
|
|
|
|
|
.observe(movement)
|
|
|
|
|
|
|
|
.observe(rotation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// When a line reaches 10 blocks, clear it
|
|
|
|
/// When a line reaches 10 blocks, clear it
|
|
|
|
@ -713,51 +678,77 @@ fn clear_line(
|
|
|
|
|
|
|
|
|
|
|
|
fn movement(
|
|
|
|
fn movement(
|
|
|
|
trigger: Trigger<RelativePosition>,
|
|
|
|
trigger: Trigger<RelativePosition>,
|
|
|
|
mut shapes: Query<&mut GridPosition, With<Shape>>,
|
|
|
|
mut grid_positions: Query<&mut GridPosition, Or<(With<RelativePosition>, With<Shape>)>>,
|
|
|
|
mut active: Query<&mut GridPosition, (With<RelativePosition>, Without<Shape>)>,
|
|
|
|
parent: Query<&ShapeBlocks>,
|
|
|
|
inactive: Query<&GridPosition, (Without<RelativePosition>, Without<Shape>)>,
|
|
|
|
inactive: Query<
|
|
|
|
blocks: Query<&ShapeBlocks>,
|
|
|
|
&GridPosition,
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
Without<RelativePosition>,
|
|
|
|
|
|
|
|
Without<Shape>,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
>,
|
|
|
|
mut commands: Commands,
|
|
|
|
mut commands: Commands,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
// Find any errors
|
|
|
|
// Do a bunch of checks if this move is valid
|
|
|
|
for block in blocks.iter_descendants(trigger.target()) {
|
|
|
|
for block in parent.iter_descendants(trigger.target()) {
|
|
|
|
// Get the child's grid position
|
|
|
|
let block_gp = grid_positions.get(block).unwrap();
|
|
|
|
let gp = active.get(block).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match gp.add_offset(trigger.event()) {
|
|
|
|
match block_gp.add_relative(trigger.event()) {
|
|
|
|
// If this would go out of bounds to the left or right, prevent this move
|
|
|
|
|
|
|
|
Err(GameError::OutOfBoundsLeft) | Err(GameError::OutOfBoundsRight) => {
|
|
|
|
Err(GameError::OutOfBoundsLeft) | Err(GameError::OutOfBoundsRight) => {
|
|
|
|
return
|
|
|
|
// Hit the left/right wall, just ignore this move
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// If this would go out of bounds down, or cause a collision, remove the active
|
|
|
|
Err(GameError::OutOfBoundsDown) => {
|
|
|
|
// component from the piece
|
|
|
|
|
|
|
|
Err(GameError::OutOfBoundsDown) | Err(GameError::Collision) => {
|
|
|
|
|
|
|
|
// remove active component
|
|
|
|
|
|
|
|
commands.entity(trigger.target()).remove::<Shape>();
|
|
|
|
commands.entity(trigger.target()).remove::<Shape>();
|
|
|
|
return
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Err(GameError::Collision) => {
|
|
|
|
|
|
|
|
// Do nothing. add_relative does not return this variant
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(new_gp) => {
|
|
|
|
Ok(new_block_gp) => {
|
|
|
|
// If any children collide with the new position, remove the active component
|
|
|
|
let collision = inactive
|
|
|
|
if inactive.iter().any(|other_gp| new_gp == *other_gp) {
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.any(|inactive_block_gp| new_block_gp == *inactive_block_gp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if collision {
|
|
|
|
commands.entity(trigger.target()).remove::<Shape>();
|
|
|
|
commands.entity(trigger.target()).remove::<Shape>();
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If the above checks went ok, we can move
|
|
|
|
// Move shape itself
|
|
|
|
let mut gp = shapes.get_mut(trigger.target()).unwrap();
|
|
|
|
if let Ok(mut shape_gp) = grid_positions.get_mut(trigger.target()) {
|
|
|
|
*gp = gp.add_offset(trigger.event()).unwrap();
|
|
|
|
*shape_gp = shape_gp.add_relative(trigger.event()).unwrap();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Move the blocks of this shape
|
|
|
|
|
|
|
|
parent.iter_descendants(trigger.target()).for_each(|block| {
|
|
|
|
|
|
|
|
info!("Propogating movement {:?} to child {:?}", trigger.event(), block);
|
|
|
|
|
|
|
|
commands.entity(block).trigger(*trigger.event());
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn rotation(
|
|
|
|
fn rotation(trigger: Trigger<Orientation>, mut q: Query<&mut Orientation>) {
|
|
|
|
trigger: Trigger<Orientation>,
|
|
|
|
let mut o = q.get_mut(trigger.target()).unwrap();
|
|
|
|
mut q: Query<(&mut Orientation, &mut GridPosition)>,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
let (mut o, mut _gp) = q.get_mut(trigger.target()).unwrap();
|
|
|
|
|
|
|
|
// If children would go out of bounds to the left
|
|
|
|
// If children would go out of bounds to the left
|
|
|
|
// If children would not go out of bounds to the right
|
|
|
|
// If children would not go out of bounds to the right
|
|
|
|
// If children would not go out of bounds to the down
|
|
|
|
// If children would not go out of bounds to the down
|
|
|
|
*o = trigger.event().clone();
|
|
|
|
*o = trigger.event().clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Just despawn?
|
|
|
|
|
|
|
|
fn deactive_shape(
|
|
|
|
|
|
|
|
trigger: Trigger<OnRemove, Shape>,
|
|
|
|
|
|
|
|
parent: Query<&ShapeBlocks>,
|
|
|
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
let v: Vec<Entity> = parent.iter_descendants(trigger.target()).collect();
|
|
|
|
|
|
|
|
parent.iter_descendants(trigger.target()).for_each(|block| {
|
|
|
|
|
|
|
|
commands.entity(block).remove::<RelativePosition>();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
commands
|
|
|
|
|
|
|
|
.entity(trigger.target())
|
|
|
|
|
|
|
|
.remove_related::<ShapeBlock>(v.as_slice())
|
|
|
|
|
|
|
|
.despawn();
|
|
|
|
|
|
|
|
}
|
|
|
|
|