diff options
-rw-r--r-- | data/maps/debug.yaml | 4 | ||||
-rw-r--r-- | data/maps/debug2.yaml | 112 | ||||
-rw-r--r-- | server/src/entity/mod.rs | 12 | ||||
-rw-r--r-- | server/src/entity/tram.rs | 95 |
4 files changed, 223 insertions, 0 deletions
diff --git a/data/maps/debug.yaml b/data/maps/debug.yaml index 90cd3480..2e902315 100644 --- a/data/maps/debug.yaml +++ b/data/maps/debug.yaml @@ -102,6 +102,10 @@ entities: - !environment_effect { name: rain, on: 60, off: 40 } - !environment_effect { name: wind, on: 60, off: 40 } - !environment [night] + - !tram + length: 3 + character: 51 + points: [[1, 2], [15, 2], [15, 8], [1, 8]] tile_entities: "}": !conveyor { dir: [1, 0], filter: dough-foodprocessor } diff --git a/data/maps/debug2.yaml b/data/maps/debug2.yaml new file mode 100644 index 00000000..1968c8ca --- /dev/null +++ b/data/maps/debug2.yaml @@ -0,0 +1,112 @@ +# Hurry Curry! - a game about cooking +# Copyright 2024 metamuffin +# Copyright 2024 nokoe +# +# 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/>. +# +score_baseline: 100000 +map: + - "........................" + - "...~...................." + - "........................" + - "........................" + - "........................" + - "........................" + - "........................" + - "........................" + - "........................" + - ".............'''''''''''" + - ".............''''''''.''" + - ".............''l''''''''" + - ".............'''''''''''" + - ".............''l''''''''" + - ".............'''''''''''" + - ".............''l''''''''" + - ".............'''''''''''" + - ".............'''''''''''" + +tiles: + "⌷": counter + "f": counter + "p": counter + "t": table + "w": counter-window + "s": sink + "o": oven + "z": freezer + "S": stove + "b": book + "C": cuttingboard + "0": rice-crate + "1": steak-crate + "2": tomato-crate + "3": leek-crate + "4": coconut-crate + "5": strawberry-crate + "6": flour-crate + "7": fish-crate + "8": cheese-crate + "9": lettuce-crate + "X": trash + + "¹": black-hole-counter + "²": white-hole-counter + "³": black-hole + "⁴": white-hole + "l": lamp + "c": chair + "~": floor + ".": floor + "'": grass + "*": tree + "!": path + "_": path + "d": door + "▒": wall-window + "█": wall + +items: + "S": pot + "w": plate + "p": plate + "f": foodprocessor + "}": foodprocessor + "]": foodprocessor + "ö": pot + +entities: + - !environment_effect { name: rain, on: 60, off: 40 } + - !environment_effect { name: wind, on: 60, off: 40 } + - !tram + length: 3 + character: 51 + points: [[1, 2], [15, 2], [15, 8], [1, 8]] + +chef_spawn: "~" +customer_spawn: "!" + +walkable: + - door + - floor + - chair + - grass + - path + - black-hole + - chandelier + +collider: + - wall + - wall-window + - tree + - lamp + - white-hole 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 }) + } + } +} |