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 crate::prelude::*;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
@@ -40,4 +41,5 @@ impl MovingState {
|
|||||||
#[derive(Component, Default)]
|
#[derive(Component, Default)]
|
||||||
pub struct InteractionTarget {
|
pub struct InteractionTarget {
|
||||||
pub target: Option<(u32, u32)>,
|
pub target: Option<(u32, u32)>,
|
||||||
|
pub action: Option<InteractionAction>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::features::pom::actions::InteractionAction;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
@@ -15,6 +16,7 @@ pub struct InvalidMoveMessage {
|
|||||||
pub struct InteractStartMessage {
|
pub struct InteractStartMessage {
|
||||||
pub x: u32,
|
pub x: u32,
|
||||||
pub y: u32,
|
pub y: u32,
|
||||||
|
pub action: InteractionAction,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use std::collections::VecDeque;
|
|||||||
use utils::find_path;
|
use utils::find_path;
|
||||||
use utils::manhattan_distance;
|
use utils::manhattan_distance;
|
||||||
|
|
||||||
|
pub mod actions;
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
@@ -71,6 +72,7 @@ fn handle_move(
|
|||||||
for (grid_pos, mut path_queue, mut interaction_target) 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
|
// Clear any pending interaction when moving manually
|
||||||
interaction_target.target = None;
|
interaction_target.target = None;
|
||||||
|
interaction_target.action = 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);
|
||||||
@@ -108,6 +110,7 @@ fn handle_interact(
|
|||||||
if manhattan_distance(current_pos.0, current_pos.1, target_pos.0, target_pos.1) == 1 {
|
if manhattan_distance(current_pos.0, current_pos.1, target_pos.0, target_pos.1) == 1 {
|
||||||
path_queue.steps.clear();
|
path_queue.steps.clear();
|
||||||
interaction_target.target = Some(target_pos);
|
interaction_target.target = Some(target_pos);
|
||||||
|
interaction_target.action = Some(message.action.clone());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,10 +141,12 @@ fn handle_interact(
|
|||||||
if let Some(path) = best_path {
|
if let Some(path) = best_path {
|
||||||
path_queue.steps = path;
|
path_queue.steps = path;
|
||||||
interaction_target.target = Some(target_pos);
|
interaction_target.target = Some(target_pos);
|
||||||
|
interaction_target.action = Some(message.action.clone());
|
||||||
} else {
|
} else {
|
||||||
println!("Cannot reach interaction target at {:?}", target_pos);
|
println!("Cannot reach interaction target at {:?}", target_pos);
|
||||||
// Don't set target if unreachable
|
// Don't set target if unreachable
|
||||||
interaction_target.target = None;
|
interaction_target.target = None;
|
||||||
|
interaction_target.action = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,8 +154,11 @@ fn handle_interact(
|
|||||||
|
|
||||||
fn perform_interaction(
|
fn perform_interaction(
|
||||||
mut pom_query: Query<(&GridPosition, &mut InteractionTarget, &PathQueue)>,
|
mut pom_query: Query<(&GridPosition, &mut InteractionTarget, &PathQueue)>,
|
||||||
// grid: Res<Grid>,
|
grid: Res<Grid>,
|
||||||
// mut tile_query: Query<&mut TileState>,
|
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() {
|
for (pos, mut target_component, path_queue) in pom_query.iter_mut() {
|
||||||
if let Some(target) = target_component.target {
|
if let Some(target) = target_component.target {
|
||||||
@@ -165,10 +173,20 @@ fn perform_interaction(
|
|||||||
target.0, target.1
|
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.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