diff options
Diffstat (limited to 'server/src/entity')
-rw-r--r-- | server/src/entity/mod.rs | 12 | ||||
-rw-r--r-- | server/src/entity/tram.rs | 95 |
2 files changed, 107 insertions, 0 deletions
diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs index 044fccab..60f02d2a 100644 --- a/server/src/entity/mod.rs +++ b/server/src/entity/mod.rs @@ -23,6 +23,7 @@ pub mod customers; pub mod environment_effect; pub mod item_portal; pub mod player_portal; +pub mod tram; pub mod tutorial; use crate::{ @@ -45,6 +46,7 @@ use item_portal::ItemPortal; use player_portal::PlayerPortal; use serde::{Deserialize, Serialize}; use std::{any::Any, collections::VecDeque}; +use tram::Tram; pub type DynEntity = Box<dyn Entity + Send + Sync + 'static>; pub type Entities = Vec<DynEntity>; @@ -133,6 +135,11 @@ pub enum EntityDecl { location: Option<IVec2>, condition: GateCondition, }, + Tram { + length: usize, + character: Option<i32>, + points: Vec<Vec2>, + }, Book, } @@ -198,5 +205,10 @@ pub fn construct_entity( } EntityDecl::EnvironmentEffect(config) => Box::new(EnvironmentEffectController::new(config)), EntityDecl::Environment(names) => Box::new(EnvironmentController(names)), + EntityDecl::Tram { + length, + character, + points, + } => Box::new(Tram::new(character.unwrap_or(51), length, points)), }) } diff --git a/server/src/entity/tram.rs b/server/src/entity/tram.rs new file mode 100644 index 00000000..27c3bcbb --- /dev/null +++ b/server/src/entity/tram.rs @@ -0,0 +1,95 @@ +/* + 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; + +pub struct Tram { + length: usize, + character: i32, + ids: Vec<PlayerID>, + points: Vec<Vec2>, + index: usize, +} + +impl Tram { + pub fn new(character: i32, length: usize, points: Vec<Vec2>) -> Self { + Self { + character, + ids: Vec::new(), + length, + points, + index: 0, + } + } +} +impl Entity for Tram { + fn finished(&self) -> bool { + false + } + fn tick(&mut self, c: EntityContext<'_>) -> Result<()> { + if self.ids.is_empty() { + for i in 0..self.length { + let id = PlayerID(random()); + c.packet_in.push_back(PacketS::Join { + name: format!("Tram {i}"), + character: self.character, + class: PlayerClass::Bot, + id: Some(id), + }); + self.ids.push(id); + } + } + + let mut ppos = None; + for id in &self.ids { + if let Some(p) = c.game.players.get(id) { + let target = if let Some(pos) = ppos { + pos + } else { + let tar = self.points[self.index]; + if p.movement.position.distance(tar) < 2. { + self.index += 1; + self.index %= self.points.len(); + } + tar + }; + ppos = Some(p.movement.position); + let dir = if p.movement.position.distance(target) > 2. { + target - p.movement.position + } else { + Vec2::ZERO + }; + c.packet_in.push_back(PacketS::Movement { + player: *id, + dir, + boost: false, + pos: None, + }); + } + } + + Ok(()) + } + fn destructor(&mut self, c: EntityContext<'_>) { + for id in self.ids.drain(..) { + c.packet_in.push_back(PacketS::Leave { player: id }) + } + } +} |