From 036262043347ede8a6e752265b49d2f7d44d1cd2 Mon Sep 17 00:00:00 2001 From: demenik Date: Wed, 10 Dec 2025 14:00:47 +0100 Subject: [PATCH 1/8] feat: Add `berries_per_focus_minute` option in `GameConfig` (#63) --- assets/config.json | 3 ++- src/features/config/components.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/config.json b/assets/config.json index 4798184..0e6ba58 100644 --- a/assets/config.json +++ b/assets/config.json @@ -27,5 +27,6 @@ "growth_stages": 6 } ], - "wonder_event_url": "wss://pomomon.farm/ws" + "wonder_event_url": "wss://pomomon.farm/ws", + "berries_per_focus_minute": 1 } diff --git a/src/features/config/components.rs b/src/features/config/components.rs index d9b3b14..1f3ccb8 100644 --- a/src/features/config/components.rs +++ b/src/features/config/components.rs @@ -11,6 +11,7 @@ pub struct GameConfig { pub shovel_rate: f32, pub berry_seeds: Vec, pub wonder_event_url: String, + pub berries_per_focus_minute: u32, } #[derive(Deserialize, Debug, Clone)] @@ -54,6 +55,7 @@ impl Default for GameConfig { }, ], wonder_event_url: "wss://pomomon.farm/ws".into(), + berries_per_focus_minute: 1, } } } From a20807ce09e2aee63930c217af576402cd545c5f Mon Sep 17 00:00:00 2001 From: demenik Date: Wed, 10 Dec 2025 14:11:02 +0100 Subject: [PATCH 2/8] feat: Add focus minute berry reward (#63) --- src/features/phase/mod.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/features/phase/mod.rs b/src/features/phase/mod.rs index 77cbf6d..31b067a 100644 --- a/src/features/phase/mod.rs +++ b/src/features/phase/mod.rs @@ -70,13 +70,35 @@ fn tick_timer( mut phase_res: ResMut, mut finish_writer: MessageWriter, mut savegame_messages: MessageWriter, + config: Res, + mut inventory: ResMut, + mut commands: Commands, + mut items_query: Query<&mut ItemStack>, + mut session_tracker: ResMut, ) { let delta = time.delta_secs(); let phase = &mut phase_res.0; match phase { Phase::Focus { duration } | Phase::Break { duration } => { + let old_minutes = (*duration / 60.0).floor() as i32; *duration -= delta; + let new_minutes = (*duration / 60.0).floor() as i32; + + if new_minutes < old_minutes { + println!( + "A minute of focus has been completed. Granting {} berries as a reward.", + config.berries_per_focus_minute + ); + + inventory.update_item_stack( + &mut commands, + &mut items_query, + ItemType::Berry, + config.berries_per_focus_minute as i32, + ); + session_tracker.total_berries_earned += config.berries_per_focus_minute; + } if *duration <= 0.0 { finish_writer.write(PhaseTimerFinishedMessage { From 3a8e16d0855fec09e4e5c94ae0a4cc2aa3079803 Mon Sep 17 00:00:00 2001 From: demenik Date: Wed, 10 Dec 2025 15:01:29 +0100 Subject: [PATCH 3/8] feat: Add notification feature and display notification for berry reward (#63) --- src/features/mod.rs | 2 + src/features/notification/components.rs | 74 +++++++++++++++++++++++++ src/features/notification/mod.rs | 58 +++++++++++++++++++ src/features/notification/ui.rs | 60 ++++++++++++++++++++ src/features/phase/mod.rs | 14 +++++ src/main.rs | 1 + src/prelude.rs | 1 + 7 files changed, 210 insertions(+) create mode 100644 src/features/notification/components.rs create mode 100644 src/features/notification/mod.rs create mode 100644 src/features/notification/ui.rs diff --git a/src/features/mod.rs b/src/features/mod.rs index 609a10c..6b6c2b8 100644 --- a/src/features/mod.rs +++ b/src/features/mod.rs @@ -5,6 +5,7 @@ pub mod grid; pub mod hud; pub mod input; pub mod inventory; +pub mod notification; pub mod phase; pub mod pom; pub mod savegame; @@ -19,6 +20,7 @@ pub use grid::GridPlugin; pub use hud::HudPlugin; pub use input::InputPlugin; pub use inventory::InventoryPlugin; +pub use notification::NotificationPlugin; pub use phase::PhasePlugin; pub use pom::PomPlugin; pub use savegame::SavegamePlugin; diff --git a/src/features/notification/components.rs b/src/features/notification/components.rs new file mode 100644 index 0000000..3f1f2b0 --- /dev/null +++ b/src/features/notification/components.rs @@ -0,0 +1,74 @@ +use crate::prelude::*; + +#[derive(Resource)] +pub struct Notifications { + items: Vec<(Notification, NotificationLevel)>, +} + +impl Default for Notifications { + fn default() -> Self { + Self { items: Vec::new() } + } +} + +impl Notifications { + fn new( + &mut self, + level: NotificationLevel, + title: Option>, + message: impl Into, + ) { + self.items.push(( + Notification { + title: title.map(|s| s.into()), + message: message.into(), + }, + level, + )); + } + + pub fn drain(&mut self) -> std::vec::Drain<'_, (Notification, NotificationLevel)> { + self.items.drain(..) + } + + pub fn info(&mut self, title: Option>, message: impl Into) { + self.new(NotificationLevel::Info, title, message); + } + + pub fn warn(&mut self, title: Option>, message: impl Into) { + self.new(NotificationLevel::Warning, title, message); + } + + pub fn error(&mut self, title: Option>, message: impl Into) { + self.new(NotificationLevel::Error, title, message); + } +} + +#[derive(Component)] +pub struct NotificationContainer; + +#[derive(Component)] +pub struct NotificationLifetime(pub Timer); + +#[derive(Component)] +pub struct Notification { + pub title: Option, + pub message: String, +} + +#[derive(Component)] +pub enum NotificationLevel { + Info, + Warning, + Error, +} + +impl NotificationLevel { + pub fn bg_color(&self) -> Color { + match self { + NotificationLevel::Info => Color::srgba(0.0, 0.0, 0.0, 0.7), + NotificationLevel::Warning => Color::srgba(1.0, 1.0, 0.0, 0.7), + NotificationLevel::Error => Color::srgba(1.0, 0.0, 0.0, 0.7), + } + } +} diff --git a/src/features/notification/mod.rs b/src/features/notification/mod.rs new file mode 100644 index 0000000..a639706 --- /dev/null +++ b/src/features/notification/mod.rs @@ -0,0 +1,58 @@ +use crate::{ + features::notification::ui::{notification_container, spawn_notification}, + prelude::*, +}; +use components::{NotificationContainer, NotificationLifetime, Notifications}; + +pub mod components; +pub mod ui; + +pub struct NotificationPlugin; + +impl Plugin for NotificationPlugin { + fn build(&self, app: &mut App) { + app.init_resource::() + .add_systems(Startup, setup) + .add_systems(Update, handle_notification); + } +} + +// Spawns the notification container up +fn setup(mut commands: Commands) { + commands.spawn(notification_container()); +} + +// Spawns/Despawns UI elements for each item in the `Notifications` Resource +fn handle_notification( + mut commands: Commands, + mut notifications: ResMut, + container_q: Query>, + mut notification_entities: Query<(Entity, &mut NotificationLifetime)>, + time: Res