From d2db146eb6430b6ae02486b17c9f70dbfd238348 Mon Sep 17 00:00:00 2001 From: demenik Date: Tue, 2 Dec 2025 19:05:11 +0100 Subject: [PATCH] feat: Implement crop withering mechanics (#28) --- src/features/grid/components.rs | 4 ++++ src/features/input/mod.rs | 2 ++ src/features/phase/mod.rs | 15 ++++++++++++++- src/features/pom/actions.rs | 12 +++++++++++- tests/growth.rs | 6 ++++++ tests/interaction.rs | 2 ++ tests/pathfinding.rs | 4 ++++ 7 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/features/grid/components.rs b/src/features/grid/components.rs index e2b20fa..571e63f 100644 --- a/src/features/grid/components.rs +++ b/src/features/grid/components.rs @@ -22,6 +22,10 @@ pub enum TileState { seed: ItemType, watered: bool, growth_stage: u32, + #[serde(default)] + withered: bool, + #[serde(default)] + dry_counter: u8, }, } diff --git a/src/features/input/mod.rs b/src/features/input/mod.rs index e002979..8ed6757 100644 --- a/src/features/input/mod.rs +++ b/src/features/input/mod.rs @@ -127,6 +127,8 @@ fn debug_click( }, watered: false, growth_stage: 0, + withered: false, + dry_counter: 0, }, TileState::Occupied { .. } => TileState::Unclaimed, }, diff --git a/src/features/phase/mod.rs b/src/features/phase/mod.rs index b4cb214..77cbf6d 100644 --- a/src/features/phase/mod.rs +++ b/src/features/phase/mod.rs @@ -176,21 +176,34 @@ pub fn handle_continue( seed, watered, growth_stage, + withered, + dry_counter, } = &*state { let mut new_stage = *growth_stage; + let mut new_withered = *withered; + let mut new_dry_counter = *dry_counter; + if *watered { + new_dry_counter = 0; if let Some(config) = seed.get_seed_config(&game_config) { - if new_stage < config.growth_stages { + if new_stage < config.growth_stages && !new_withered { new_stage += 1; } } + } else { + new_dry_counter += 1; + if new_dry_counter >= 2 { + new_withered = true; + } } *state = TileState::Occupied { seed: seed.clone(), watered: false, growth_stage: new_stage, + withered: new_withered, + dry_counter: new_dry_counter, }; } } diff --git a/src/features/pom/actions.rs b/src/features/pom/actions.rs index e63af7e..d88a62e 100644 --- a/src/features/pom/actions.rs +++ b/src/features/pom/actions.rs @@ -93,6 +93,8 @@ impl InteractionAction { seed: seed_type.clone(), watered: false, growth_stage: 0, + withered: false, + dry_counter: 0, }; } else { println!("No {:?} in inventory!", seed_type); @@ -102,12 +104,20 @@ impl InteractionAction { } } InteractionAction::Water => { - if let TileState::Occupied { seed, growth_stage, .. } = &*tile_state { + if let TileState::Occupied { + seed, + growth_stage, + withered, + .. + } = &*tile_state + { println!("Watering {:?}", seed); *tile_state = TileState::Occupied { seed: seed.clone(), watered: true, growth_stage: *growth_stage, + withered: *withered, + dry_counter: 0, }; } else { println!("Tile is not occupied, cannot water."); diff --git a/tests/growth.rs b/tests/growth.rs index 85ed8fb..00b6a9f 100644 --- a/tests/growth.rs +++ b/tests/growth.rs @@ -86,6 +86,8 @@ fn test_crop_growth_logic() { seed: seed_type.clone(), watered: true, growth_stage: 0, + withered: false, + dry_counter: 0, }, ), ( @@ -95,6 +97,8 @@ fn test_crop_growth_logic() { seed: seed_type.clone(), watered: false, growth_stage: 0, + withered: false, + dry_counter: 0, }, ), ( @@ -104,6 +108,8 @@ fn test_crop_growth_logic() { seed: seed_type.clone(), watered: true, growth_stage: 2, // Max + withered: false, + dry_counter: 0, }, ), ]; diff --git a/tests/interaction.rs b/tests/interaction.rs index b657ff2..7609fa8 100644 --- a/tests/interaction.rs +++ b/tests/interaction.rs @@ -180,6 +180,8 @@ fn test_water_crop() { seed: seed_type.clone(), watered: false, growth_stage: 0, + withered: false, + dry_counter: 0, }, )], vec![], diff --git a/tests/pathfinding.rs b/tests/pathfinding.rs index 99eba5a..4ddea09 100644 --- a/tests/pathfinding.rs +++ b/tests/pathfinding.rs @@ -95,6 +95,8 @@ fn test_find_path_around_obstacle() { }, watered: false, growth_stage: 0, + withered: false, + dry_counter: 0, }; let obstacles = vec![ (2, 2, obstacle.clone()), @@ -148,6 +150,8 @@ fn test_find_path_no_path() { }, watered: false, growth_stage: 0, + withered: false, + dry_counter: 0, }; let obstacles = vec![ (2, 0, obstacle.clone()),