aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/commands.rs13
-rw-r--r--server/src/entity/bot.rs3
-rw-r--r--server/src/entity/campaign.rs6
-rw-r--r--server/src/entity/mod.rs4
-rw-r--r--server/src/entity/tutorial.rs10
-rw-r--r--server/src/lib.rs9
6 files changed, 39 insertions, 6 deletions
diff --git a/server/src/commands.rs b/server/src/commands.rs
index 8e6f32c7..f5792a22 100644
--- a/server/src/commands.rs
+++ b/server/src/commands.rs
@@ -239,7 +239,18 @@ impl Server {
.data
.get_item_by_name(&item)
.ok_or(anyhow!("unknown item"))?;
- // TODO prevent too many (> 1) tutorials for this player
+ #[cfg(not(test))] // TODO rust-analyser does not undestand trait upcasting
+ if self
+ .entities
+ .iter()
+ .find(|e| {
+ <dyn std::any::Any>::downcast_ref::<Tutorial>(e.as_ref())
+ .map_or(false, |t| t.player == player)
+ })
+ .is_some()
+ {
+ bail!("Tutorial already running")
+ }
self.entities.push(Box::new(Tutorial::new(player, item)));
}
Command::TranslateMessage {
diff --git a/server/src/entity/bot.rs b/server/src/entity/bot.rs
index 6f39fab2..cd505c4f 100644
--- a/server/src/entity/bot.rs
+++ b/server/src/entity/bot.rs
@@ -21,6 +21,7 @@ use hurrycurry_bot::{BotAlgo, DynBotAlgo};
use hurrycurry_protocol::{PacketS, PlayerID};
use log::info;
use rand::random;
+use std::any::Any;
pub type DynBotDriver = BotDriver<DynBotAlgo>;
@@ -43,7 +44,7 @@ impl<T: BotAlgo> BotDriver<T> {
}
}
}
-impl<T: BotAlgo> Entity for BotDriver<T> {
+impl<T: BotAlgo + Any> Entity for BotDriver<T> {
fn finished(&self) -> bool {
self.left
}
diff --git a/server/src/entity/campaign.rs b/server/src/entity/campaign.rs
index 5d669a4d..2e45e650 100644
--- a/server/src/entity/campaign.rs
+++ b/server/src/entity/campaign.rs
@@ -123,6 +123,12 @@ impl GateCondition {
o
}
GateCondition::Stars(map, thres) => {
+ // TODO what if the language wants map first?
+ // trm!(
+ // "s.campaign.condition.stars",
+ // s = thres.to_string(),
+ // s = map.to_string()
+ // )
format!("Reach at least {thres} stars in {map}")
}
}
diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs
index 532031d5..aa565c83 100644
--- a/server/src/entity/mod.rs
+++ b/server/src/entity/mod.rs
@@ -40,7 +40,7 @@ use hurrycurry_protocol::{
use item_portal::ItemPortal;
use player_portal::PlayerPortal;
use serde::{Deserialize, Serialize};
-use std::collections::VecDeque;
+use std::{any::Any, collections::VecDeque};
pub type DynEntity = Box<dyn Entity + Send + Sync + 'static>;
pub type Entities = Vec<DynEntity>;
@@ -55,7 +55,7 @@ pub struct EntityContext<'a> {
pub dt: f32,
}
-pub trait Entity {
+pub trait Entity: Any {
fn tick(&mut self, _c: EntityContext<'_>) -> Result<()> {
Ok(())
}
diff --git a/server/src/entity/tutorial.rs b/server/src/entity/tutorial.rs
index 9b2146d2..0d3d512d 100644
--- a/server/src/entity/tutorial.rs
+++ b/server/src/entity/tutorial.rs
@@ -8,7 +8,7 @@ use hurrycurry_protocol::{
use log::{debug, warn};
pub struct Tutorial {
- player: PlayerID,
+ pub player: PlayerID,
target: ItemIndex,
current_hint: Option<(Option<IVec2>, Message)>,
@@ -30,6 +30,14 @@ impl Entity for Tutorial {
fn finished(&self) -> bool {
self.delete_timer <= 0.
}
+ fn destructor(&mut self, c: EntityContext<'_>) {
+ if let Some((position, _)) = self.current_hint {
+ c.packet_out.push_back(PacketC::ServerHint {
+ position,
+ message: None,
+ });
+ }
+ }
fn tick(&mut self, c: EntityContext<'_>) -> Result<()> {
let mut hint = StepContext {
ent: &c,
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 306ebd40..112f28ea 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -15,7 +15,14 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#![feature(if_let_guard, map_many_mut, let_chains, iterator_try_collect, isqrt)]
+#![feature(
+ if_let_guard,
+ map_many_mut,
+ let_chains,
+ iterator_try_collect,
+ isqrt,
+ trait_upcasting
+)]
pub mod commands;
pub mod data;
pub mod entity;