feat: Implement InteractionAction system for Pom

This commit is contained in:
demenik
2025-12-02 12:54:20 +01:00
parent c5c4b31d71
commit 1b169b00de
4 changed files with 120 additions and 4 deletions

View File

@@ -0,0 +1,95 @@
use crate::prelude::*;
#[derive(Clone, Debug, PartialEq)]
pub enum InteractionAction {
Plant(ItemType),
}
impl InteractionAction {
pub fn get_name(&self, game_config: &GameConfig) -> String {
match self {
InteractionAction::Plant(item) => format!("Pflanze {}", item.singular(game_config)),
}
}
pub fn get_sprite(
&self,
asset_server: &Res<AssetServer>,
game_config: &GameConfig,
) -> Option<AseSlice> {
match self {
InteractionAction::Plant(item) => Some(item.get_sprite(asset_server, game_config)),
}
}
pub fn list_options(
tile_state: &TileState,
inventory: &Inventory,
item_query: Query<&ItemStack>,
) -> Vec<InteractionAction> {
let mut options: Vec<InteractionAction> = vec![];
for &entity in &inventory.items {
let Ok(stack) = item_query.get(entity) else {
continue;
};
if stack.amount <= 0 {
continue;
}
println!("1");
match tile_state {
TileState::Empty => match &stack.item_type {
ItemType::BerrySeed { .. } => {
options.push(InteractionAction::Plant(stack.item_type.clone()));
}
_ => (),
},
_ => (),
}
}
options
}
pub fn execute(
&self,
pos: (u32, u32),
grid: &Grid,
tile_query: &mut Query<&mut TileState>,
inventory: &mut Inventory,
item_stack_query: &mut Query<&mut ItemStack>,
commands: &mut Commands,
) {
let Ok(tile_entity) = grid.get_tile(pos) else {
println!("Error during interaction: Couldn't get tile_entity");
return;
};
let Ok(mut tile_state) = tile_query.get_mut(tile_entity) else {
println!("Error during interaction: Couldn't get mut tile_state");
return;
};
match self {
InteractionAction::Plant(seed_type) => {
if let TileState::Empty = *tile_state {
if inventory.update_item_stack(
commands,
item_stack_query,
seed_type.clone(),
-1,
) {
println!("Planting {:?}", seed_type);
*tile_state = TileState::Occupied {
seed: seed_type.clone(),
};
} else {
println!("No {:?} in inventory!", seed_type);
}
} else {
println!("Tile is not empty, cannot plant.");
}
}
}
}
}

View File

@@ -1,3 +1,4 @@
use crate::features::pom::actions::InteractionAction;
use crate::prelude::*;
use std::collections::VecDeque;
@@ -40,4 +41,5 @@ impl MovingState {
#[derive(Component, Default)]
pub struct InteractionTarget {
pub target: Option<(u32, u32)>,
pub action: Option<InteractionAction>,
}

View File

@@ -1,3 +1,4 @@
use crate::features::pom::actions::InteractionAction;
use crate::prelude::*;
#[derive(Message)]
@@ -15,6 +16,7 @@ pub struct InvalidMoveMessage {
pub struct InteractStartMessage {
pub x: u32,
pub y: u32,
pub action: InteractionAction,
}
#[derive(Message)]

View File

@@ -5,6 +5,7 @@ use std::collections::VecDeque;
use utils::find_path;
use utils::manhattan_distance;
pub mod actions;
pub mod components;
pub mod messages;
pub mod ui;
@@ -71,6 +72,7 @@ fn handle_move(
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;
interaction_target.action = None;
let grid_start = (grid_pos.x, grid_pos.y);
let start = path_queue.steps.front().unwrap_or(&grid_start);
@@ -108,6 +110,7 @@ fn handle_interact(
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);
interaction_target.action = Some(message.action.clone());
continue;
}
@@ -138,10 +141,12 @@ fn handle_interact(
if let Some(path) = best_path {
path_queue.steps = path;
interaction_target.target = Some(target_pos);
interaction_target.action = Some(message.action.clone());
} else {
println!("Cannot reach interaction target at {:?}", target_pos);
// Don't set target if unreachable
interaction_target.target = None;
interaction_target.action = None;
}
}
}
@@ -149,8 +154,11 @@ fn handle_interact(
fn perform_interaction(
mut pom_query: Query<(&GridPosition, &mut InteractionTarget, &PathQueue)>,
// grid: Res<Grid>,
// mut tile_query: Query<&mut TileState>,
grid: Res<Grid>,
mut tile_query: Query<&mut TileState>,
mut inventory: ResMut<Inventory>,
mut item_stack_query: Query<&mut ItemStack>,
mut commands: Commands,
) {
for (pos, mut target_component, path_queue) in pom_query.iter_mut() {
if let Some(target) = target_component.target {
@@ -165,10 +173,20 @@ fn perform_interaction(
target.0, target.1
);
// TODO: Implement interaction logic
if let Some(action) = &target_component.action {
action.execute(
target,
&grid,
&mut tile_query,
&mut inventory,
&mut item_stack_query,
&mut commands,
);
}
}
target_component.target = None;
target_component.action = None;
}
}
}
@@ -248,4 +266,3 @@ fn update_pom(asset_server: Res<AssetServer>, mut query: Query<(&MovingState, &m
}
}
}