feat: Implement interact click logic (#25)
This commit is contained in:
@@ -36,3 +36,8 @@ impl MovingState {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
pub struct InteractionTarget {
|
||||||
|
pub target: Option<(u32, u32)>,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use components::*;
|
use components::*;
|
||||||
use messages::InvalidMoveMessage;
|
use messages::{InteractStartMessage, InvalidMoveMessage};
|
||||||
|
use std::collections::VecDeque;
|
||||||
use utils::find_path;
|
use utils::find_path;
|
||||||
|
use utils::manhattan_distance;
|
||||||
|
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
@@ -16,7 +18,14 @@ impl Plugin for PomPlugin {
|
|||||||
|
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(handle_move, move_pom, update_pom).run_if(in_state(AppState::GameScreen)),
|
(
|
||||||
|
handle_move,
|
||||||
|
handle_interact,
|
||||||
|
move_pom,
|
||||||
|
update_pom,
|
||||||
|
perform_interaction,
|
||||||
|
)
|
||||||
|
.run_if(in_state(AppState::GameScreen)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,6 +36,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, config: Res<Gam
|
|||||||
GridPosition { x: 0, y: 0 },
|
GridPosition { x: 0, y: 0 },
|
||||||
PathQueue::default(),
|
PathQueue::default(),
|
||||||
MovingState::default(),
|
MovingState::default(),
|
||||||
|
InteractionTarget::default(),
|
||||||
AseAnimation {
|
AseAnimation {
|
||||||
aseprite: asset_server.load("pom/pom-sleep.aseprite"),
|
aseprite: asset_server.load("pom/pom-sleep.aseprite"),
|
||||||
animation: Animation::tag("sleep-sit-start").with_repeat(AnimationRepeat::Loop),
|
animation: Animation::tag("sleep-sit-start").with_repeat(AnimationRepeat::Loop),
|
||||||
@@ -53,10 +63,13 @@ fn handle_move(
|
|||||||
mut invalid_move_messages: MessageWriter<InvalidMoveMessage>,
|
mut invalid_move_messages: MessageWriter<InvalidMoveMessage>,
|
||||||
grid: Res<Grid>,
|
grid: Res<Grid>,
|
||||||
tile_query: Query<&TileState>,
|
tile_query: Query<&TileState>,
|
||||||
mut pom_query: Query<(&GridPosition, &mut PathQueue)>,
|
mut pom_query: Query<(&GridPosition, &mut PathQueue, &mut InteractionTarget)>,
|
||||||
) {
|
) {
|
||||||
for message in move_messages.read() {
|
for message in move_messages.read() {
|
||||||
for (grid_pos, mut path_queue) in pom_query.iter_mut() {
|
for (grid_pos, mut path_queue, mut interaction_target) in pom_query.iter_mut() {
|
||||||
|
// Clear any pending interaction when moving manually
|
||||||
|
interaction_target.target = None;
|
||||||
|
|
||||||
let grid_start = (grid_pos.x, grid_pos.y);
|
let grid_start = (grid_pos.x, grid_pos.y);
|
||||||
let start = path_queue.steps.front().unwrap_or(&grid_start);
|
let start = path_queue.steps.front().unwrap_or(&grid_start);
|
||||||
let end = (message.x, message.y);
|
let end = (message.x, message.y);
|
||||||
@@ -78,6 +91,86 @@ fn handle_move(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_interact(
|
||||||
|
mut interact_messages: MessageReader<InteractStartMessage>,
|
||||||
|
mut pom_query: Query<(&GridPosition, &mut PathQueue, &mut InteractionTarget)>,
|
||||||
|
grid: Res<Grid>,
|
||||||
|
tile_query: Query<&TileState>,
|
||||||
|
) {
|
||||||
|
for message in interact_messages.read() {
|
||||||
|
for (grid_pos, mut path_queue, mut interaction_target) in pom_query.iter_mut() {
|
||||||
|
let target_pos = (message.x, message.y);
|
||||||
|
let current_pos = (grid_pos.x, grid_pos.y);
|
||||||
|
|
||||||
|
// If we are already adjacent to the target, just set the target and clear path
|
||||||
|
if manhattan_distance(current_pos.0, current_pos.1, target_pos.0, target_pos.1) == 1 {
|
||||||
|
path_queue.steps.clear();
|
||||||
|
interaction_target.target = Some(target_pos);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a path to an adjacent tile
|
||||||
|
let neighbors = [
|
||||||
|
(target_pos.0 as i32 + 1, target_pos.1 as i32),
|
||||||
|
(target_pos.0 as i32 - 1, target_pos.1 as i32),
|
||||||
|
(target_pos.0 as i32, target_pos.1 as i32 + 1),
|
||||||
|
(target_pos.0 as i32, target_pos.1 as i32 - 1),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut best_path: Option<VecDeque<(u32, u32)>> = None;
|
||||||
|
|
||||||
|
for (nx, ny) in neighbors {
|
||||||
|
if nx < 0 || ny < 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let neighbor_pos = (nx as u32, ny as u32);
|
||||||
|
|
||||||
|
if let Some(path) = find_path(current_pos, neighbor_pos, &grid, &tile_query) {
|
||||||
|
// Pick the shortest path
|
||||||
|
if best_path.as_ref().map_or(true, |p| path.len() < p.len()) {
|
||||||
|
best_path = Some(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(path) = best_path {
|
||||||
|
path_queue.steps = path;
|
||||||
|
interaction_target.target = Some(target_pos);
|
||||||
|
} else {
|
||||||
|
println!("Cannot reach interaction target at {:?}", target_pos);
|
||||||
|
// Don't set target if unreachable
|
||||||
|
interaction_target.target = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn perform_interaction(
|
||||||
|
mut pom_query: Query<(&GridPosition, &mut InteractionTarget, &PathQueue)>,
|
||||||
|
// grid: Res<Grid>,
|
||||||
|
// mut tile_query: Query<&mut TileState>,
|
||||||
|
) {
|
||||||
|
for (pos, mut target_component, path_queue) in pom_query.iter_mut() {
|
||||||
|
if let Some(target) = target_component.target {
|
||||||
|
// Wait until movement stops
|
||||||
|
if !path_queue.steps.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if manhattan_distance(pos.x, pos.y, target.0, target.1) == 1 {
|
||||||
|
println!(
|
||||||
|
"Performing interaction on tile ({}, {})",
|
||||||
|
target.0, target.1
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: Implement interaction logic
|
||||||
|
}
|
||||||
|
|
||||||
|
target_component.target = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn move_pom(
|
fn move_pom(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
mut query: Query<(
|
mut query: Query<(
|
||||||
@@ -153,3 +246,4 @@ fn update_pom(asset_server: Res<AssetServer>, mut query: Query<(&MovingState, &m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user