feat: Implement InteractionAction system for Pom
This commit is contained in:
95
src/features/pom/actions.rs
Normal file
95
src/features/pom/actions.rs
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>,
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user