diff options
Diffstat (limited to 'server')
| -rw-r--r-- | server/src/commands.rs | 14 | ||||
| -rw-r--r-- | server/src/entity/tutorial.rs | 8 | ||||
| -rw-r--r-- | server/src/server.rs | 17 | 
3 files changed, 37 insertions, 2 deletions
| diff --git a/server/src/commands.rs b/server/src/commands.rs index dab0e540..c03c8bcd 100644 --- a/server/src/commands.rs +++ b/server/src/commands.rs @@ -81,9 +81,11 @@ enum Command {      Reload,      /// Shows the recipe book      Book, +    #[clap(alias = "tutorial")]      StartTutorial {          item: String,      }, +    EndTutorial,      #[clap(alias = "tr")]      TranslateMessage {          message_id: String, @@ -270,6 +272,18 @@ impl Server {                  }                  self.entities.push(Box::new(Tutorial::new(player, item)));              } +            Command::EndTutorial => { +                #[cfg(not(test))] // TODO rust-analyser does not undestand trait upcasting +                if let Some(tutorial) = self +                    .entities +                    .iter_mut() +                    .find_map(|e| <dyn std::any::Any>::downcast_mut::<Tutorial>(e.as_mut())) +                { +                    tutorial.ended = true; +                } else { +                    bail!("No tutorial running") +                } +            }              Command::TranslateMessage {                  message_id,                  arguments, diff --git a/server/src/entity/tutorial.rs b/server/src/entity/tutorial.rs index a49c5993..d33f14ea 100644 --- a/server/src/entity/tutorial.rs +++ b/server/src/entity/tutorial.rs @@ -15,11 +15,13 @@ pub struct Tutorial {      current_hint: Option<(Option<IVec2>, Message)>,      delete_timer: f32, +    pub ended: bool,  }  impl Tutorial {      pub fn new(player: PlayerID, item: ItemIndex) -> Self {          Self { +            ended: false,              player,              next_update_due: 0.,              target: item, @@ -32,7 +34,7 @@ impl Tutorial {  impl Entity for Tutorial {      fn finished(&self) -> bool { -        self.delete_timer <= 0. +        self.ended      }      fn destructor(&mut self, c: EntityContext<'_>) {          if let Some((position, _)) = self.current_hint { @@ -49,6 +51,9 @@ impl Entity for Tutorial {          });      }      fn tick(&mut self, c: EntityContext<'_>) -> Result<()> { +        if self.ended { +            return Ok(()); +        }          const TARGET_DT: f32 = 0.2;          self.next_update_due -= c.dt;          if self.next_update_due > 0. { @@ -67,6 +72,7 @@ impl Entity for Tutorial {          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, diff --git a/server/src/server.rs b/server/src/server.rs index 6350d635..06b6e5fd 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -674,7 +674,22 @@ impl Server {                  warn!("Entity tick failed: {e}")              }          } -        self.entities.retain(|e| !e.finished()); +        self.entities.retain_mut(|e| { +            if e.finished() { +                e.destructor(EntityContext { +                    game: &mut self.game, +                    load_map: &mut load_map, +                    packet_out: &mut self.packet_out, +                    score_changed: &mut self.score_changed, +                    packet_in: &mut self.packet_loopback, +                    scoreboard: &self.scoreboard, +                    dt: 0., +                }); +                false +            } else { +                true +            } +        });          if let Some(map) = load_map {              return Some((map, Some(Duration::from_secs(300)))); | 
