summaryrefslogtreecommitdiff
path: root/server/src/entity
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/entity')
-rw-r--r--server/src/entity/bot.rs1
-rw-r--r--server/src/entity/mod.rs22
-rw-r--r--server/src/entity/pedestrians.rs86
-rw-r--r--server/src/entity/tram.rs1
4 files changed, 109 insertions, 1 deletions
diff --git a/server/src/entity/bot.rs b/server/src/entity/bot.rs
index 6e6c9162..922cc55e 100644
--- a/server/src/entity/bot.rs
+++ b/server/src/entity/bot.rs
@@ -57,6 +57,7 @@ impl<T: BotAlgo + Any> Entity for BotDriver<T> {
character,
id: Some(self.id),
class,
+ position: None,
})
}
diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs
index ddafc2f7..75ea0e9b 100644
--- a/server/src/entity/mod.rs
+++ b/server/src/entity/mod.rs
@@ -22,12 +22,14 @@ pub mod conveyor;
pub mod customers;
pub mod environment_effect;
pub mod item_portal;
+pub mod pedestrians;
pub mod player_portal;
pub mod tram;
pub mod tutorial;
use crate::{
data::{ItemTileRegistry, Serverdata},
+ entity::pedestrians::Pedestrians,
message::TrError,
scoreboard::ScoreboardStore,
};
@@ -45,7 +47,10 @@ use hurrycurry_protocol::{
use item_portal::ItemPortal;
use player_portal::PlayerPortal;
use serde::{Deserialize, Serialize};
-use std::{any::Any, collections::VecDeque};
+use std::{
+ any::Any,
+ collections::{HashMap, VecDeque},
+};
use tram::Tram;
pub type DynEntity = Box<dyn Entity + Send + Sync + 'static>;
@@ -143,6 +148,11 @@ pub enum EntityDecl {
smoothing: f32,
},
Book,
+ Pedestrians {
+ spawn_delay: f32,
+ spawn_delay_stdev: f32,
+ points: Vec<Vec2>,
+ },
}
pub fn construct_entity(
@@ -222,5 +232,15 @@ pub fn construct_entity(
spacing,
smoothing,
}),
+ EntityDecl::Pedestrians {
+ spawn_delay,
+ spawn_delay_stdev,
+ points,
+ } => Box::new(Pedestrians {
+ players: HashMap::new(),
+ points,
+ spawn_delay_distr: rand_distr::Normal::new(spawn_delay, spawn_delay_stdev).unwrap(),
+ cooldown: 0.,
+ }),
})
}
diff --git a/server/src/entity/pedestrians.rs b/server/src/entity/pedestrians.rs
new file mode 100644
index 00000000..9b433ded
--- /dev/null
+++ b/server/src/entity/pedestrians.rs
@@ -0,0 +1,86 @@
+use std::collections::HashMap;
+
+/*
+ Hurry Curry! - a game about cooking
+ Copyright 2025 metamuffin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License only.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+*/
+use super::{Entity, EntityContext};
+use anyhow::Result;
+use hurrycurry_protocol::{glam::Vec2, PacketS, PlayerClass, PlayerID};
+use rand::{random, rng};
+use rand_distr::Distribution;
+
+pub struct Pedestrians {
+ pub players: HashMap<PlayerID, usize>,
+ pub points: Vec<Vec2>,
+ pub spawn_delay_distr: rand_distr::Normal<f32>,
+ pub cooldown: f32,
+}
+
+impl Entity for Pedestrians {
+ fn finished(&self) -> bool {
+ false
+ }
+ fn tick(&mut self, c: EntityContext<'_>) -> Result<()> {
+ self.cooldown -= c.dt;
+ if self.cooldown <= 0. && self.players.len() < 32 {
+ let id = PlayerID(random());
+ c.packet_in.push_back(PacketS::Join {
+ name: "Pedestrian".to_string(),
+ character: 0,
+ class: PlayerClass::Customer,
+ id: Some(id),
+ position: self.points.get(0).copied(),
+ });
+ self.players.insert(id, 0);
+ self.cooldown += self.spawn_delay_distr.sample(&mut rng()).max(0.1);
+ }
+
+ let mut remove = Vec::new();
+
+ for (id, index) in &mut self.players {
+ if let Some(player) = c.game.players.get(id) {
+ let diff = self.points[*index] - player.movement.position;
+ if diff.length() < 0.8 {
+ *index += 1;
+ if *index >= self.points.len() {
+ remove.push(*id)
+ }
+ } else {
+ c.packet_in.push_back(PacketS::Movement {
+ player: *id,
+ dir: diff,
+ boost: false,
+ pos: None,
+ });
+ }
+ }
+ }
+
+ for id in remove {
+ if self.players.remove(&id).is_some() {
+ c.packet_in.push_back(PacketS::Leave { player: id });
+ }
+ }
+
+ Ok(())
+ }
+ fn destructor(&mut self, c: EntityContext<'_>) {
+ for (id, _) in self.players.drain() {
+ c.packet_in.push_back(PacketS::Leave { player: id })
+ }
+ }
+}
diff --git a/server/src/entity/tram.rs b/server/src/entity/tram.rs
index 5b7fcaa8..26a191aa 100644
--- a/server/src/entity/tram.rs
+++ b/server/src/entity/tram.rs
@@ -43,6 +43,7 @@ impl Entity for Tram {
character: self.character,
class: PlayerClass::Bot,
id: Some(id),
+ position: None,
});
self.ids.push(id);
}