diff options
Diffstat (limited to 'server/src/entity')
| -rw-r--r-- | server/src/entity/pedestrians.rs | 3 | ||||
| -rw-r--r-- | server/src/entity/tutorial.rs | 120 |
2 files changed, 103 insertions, 20 deletions
diff --git a/server/src/entity/pedestrians.rs b/server/src/entity/pedestrians.rs index 4fe91464..40ec721d 100644 --- a/server/src/entity/pedestrians.rs +++ b/server/src/entity/pedestrians.rs @@ -1,5 +1,3 @@ -use crate::random_gauss; - /* Hurry Curry! - a game about cooking Copyright (C) 2025 Hurry Curry! Contributors @@ -18,6 +16,7 @@ use crate::random_gauss; */ use super::{Entity, EntityContext}; +use crate::random_gauss; use anyhow::Result; use hurrycurry_locale::TrError; use hurrycurry_protocol::{Character, PacketS, PlayerClass, PlayerID, glam::Vec2}; diff --git a/server/src/entity/tutorial.rs b/server/src/entity/tutorial.rs index 87896a09..47ec2aff 100644 --- a/server/src/entity/tutorial.rs +++ b/server/src/entity/tutorial.rs @@ -19,34 +19,60 @@ use super::{Entity, EntityContext}; use anyhow::Result; use hurrycurry_locale::{TrError, trm}; use hurrycurry_protocol::{ - ItemIndex, Message, PacketC, PlayerID, Recipe, RecipeIndex, TileIndex, glam::IVec2, + ItemIndex, ItemLocation, Message, PacketC, PlayerID, Recipe, RecipeIndex, TileIndex, + glam::IVec2, }; use log::{debug, warn}; pub struct Tutorial { pub player: PlayerID, - target: ItemIndex, - + state: TutorialState, next_update_due: f32, - had_aquired_target: bool, - current_hint: Option<(Option<IVec2>, Message)>, delete_timer: f32, pub ended: bool, } +pub enum TutorialState { + Item { + item: ItemIndex, + had_aquired_target: bool, + }, + Button { + tile: TileIndex, + pressed: bool, + }, +} + impl Tutorial { - pub fn new(player: PlayerID, item: ItemIndex) -> Self { + fn new(player: PlayerID, target: TutorialState) -> Self { Self { ended: false, player, next_update_due: 0., - target: item, + state: target, current_hint: None, delete_timer: 1.5, - had_aquired_target: false, } } + pub fn new_item(player: PlayerID, item: ItemIndex) -> Self { + Self::new( + player, + TutorialState::Item { + item, + had_aquired_target: false, + }, + ) + } + pub fn new_button(player: PlayerID, tile: TileIndex) -> Self { + Self::new( + player, + TutorialState::Button { + tile, + pressed: false, + }, + ) + } } impl Entity for Tutorial { @@ -63,10 +89,34 @@ impl Entity for Tutorial { } c.packet_out.push_back(PacketC::TutorialEnded { player: self.player, - item: self.target, + item: match &self.state { + TutorialState::Item { item, .. } => *item, + _ => ItemIndex(0), // TODO + }, success: false, }); } + fn interact( + &mut self, + c: EntityContext<'_>, + target: Option<ItemLocation>, + player: PlayerID, + ) -> Result<bool, TrError> { + if player == self.player { + match (&mut self.state, target) { + (TutorialState::Button { tile, pressed }, Some(ItemLocation::Tile(pos))) => { + if let Some(t) = c.game.tiles.get(&pos) { + if t.parts.contains(tile) { + *pressed = true; + } + } + } + _ => (), + }; + } + Ok(false) + } + fn tick(&mut self, c: EntityContext<'_>) -> Result<(), TrError> { if self.ended { return Ok(()); @@ -78,21 +128,30 @@ impl Entity for Tutorial { } self.next_update_due += TARGET_DT; - let mut hint = StepContext { - ent: &c, - had_aquired_target: &mut self.had_aquired_target, - player: self.player, - recursion_abort: 0, - } - .fulfil_demand(self.target) - .err(); + let mut hint = match &mut self.state { + TutorialState::Item { + item, + had_aquired_target, + } => StepContext { + ent: &c, + had_aquired_target, + player: self.player, + recursion_abort: 0, + } + .fulfil_demand(*item) + .err(), + TutorialState::Button { tile, pressed } => find_button(&c, *tile, *pressed), + }; if hint.is_none() { self.delete_timer -= TARGET_DT; if self.delete_timer <= 0. { self.ended = true; hint = None; c.packet_out.push_back(PacketC::TutorialEnded { - item: self.target, + item: match &self.state { + TutorialState::Item { item, .. } => *item, + _ => ItemIndex(0), + }, player: self.player, success: true, }); @@ -123,6 +182,31 @@ impl Entity for Tutorial { } } +fn find_button( + ent: &EntityContext, + tile: TileIndex, + pressed: bool, +) -> Option<(Option<IVec2>, Message)> { + if pressed { + return None; + } + ent.game + .tile_index + .get(&tile) + .map(|pos| pos.iter().next()) + .flatten() + .map(|p| { + ( + Some(*p), + match ent.game.data.tile_name(tile) { + "book" => trm!("s.tutorial.button.book"), + "map-selector" => trm!("s.tutorial.button.map_selector"), + _ => trm!("s.tutorial.interact"), + }, + ) + }) +} + struct StepContext<'a> { ent: &'a EntityContext<'a>, had_aquired_target: &'a mut bool, |