diff --git a/src/features/pom/actions.rs b/src/features/pom/actions.rs new file mode 100644 index 0000000..4849fa4 --- /dev/null +++ b/src/features/pom/actions.rs @@ -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, + game_config: &GameConfig, + ) -> Option { + 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 { + let mut options: Vec = 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."); + } + } + } + } +} diff --git a/src/features/pom/components.rs b/src/features/pom/components.rs index 089438a..43dfa25 100644 --- a/src/features/pom/components.rs +++ b/src/features/pom/components.rs @@ -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, } diff --git a/src/features/pom/messages.rs b/src/features/pom/messages.rs index 60aa82c..58b2355 100644 --- a/src/features/pom/messages.rs +++ b/src/features/pom/messages.rs @@ -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)] diff --git a/src/features/pom/mod.rs b/src/features/pom/mod.rs index 447278c..9f08aa8 100644 --- a/src/features/pom/mod.rs +++ b/src/features/pom/mod.rs @@ -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, - // mut tile_query: Query<&mut TileState>, + grid: Res, + mut tile_query: Query<&mut TileState>, + mut inventory: ResMut, + 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, mut query: Query<(&MovingState, &m } } } -