diff options
author | metamuffin <metamuffin@disroot.org> | 2025-10-06 23:03:32 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-10-06 23:03:40 +0200 |
commit | 176e6bc6c4c29bea3be2aceca99743b997c76c97 (patch) | |
tree | 1161e7a966843324756340da4b6452492902fa07 /server/src/entity | |
parent | ea86b11b682500160f37b35ea8f06b081cd05036 (diff) | |
download | hurrycurry-176e6bc6c4c29bea3be2aceca99743b997c76c97.tar hurrycurry-176e6bc6c4c29bea3be2aceca99743b997c76c97.tar.bz2 hurrycurry-176e6bc6c4c29bea3be2aceca99743b997c76c97.tar.zst |
Move data code to own crate + general data refactor
Diffstat (limited to 'server/src/entity')
-rw-r--r-- | server/src/entity/campaign.rs | 28 | ||||
-rw-r--r-- | server/src/entity/conveyor.rs | 23 | ||||
-rw-r--r-- | server/src/entity/customers.rs | 6 | ||||
-rw-r--r-- | server/src/entity/environment_effect.rs | 14 | ||||
-rw-r--r-- | server/src/entity/mod.rs | 157 |
5 files changed, 40 insertions, 188 deletions
diff --git a/server/src/entity/campaign.rs b/server/src/entity/campaign.rs index 53ea6582..fdc169d1 100644 --- a/server/src/entity/campaign.rs +++ b/server/src/entity/campaign.rs @@ -18,16 +18,16 @@ use super::{Entity, EntityContext}; use crate::{scoreboard::ScoreboardStore, server::GameServerExt}; use anyhow::Result; +use hurrycurry_data::entities::GateCondition; use hurrycurry_locale::{trm, TrError}; use hurrycurry_protocol::{ glam::{IVec2, Vec2}, Message, PacketC, PlayerID, TileIndex, }; -use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Clone)] pub struct Map { - pub location: Vec2, + pub pos: Vec2, pub name: String, } @@ -36,7 +36,7 @@ impl Entity for Map { let mut activate = false; c.game .players_spatial_index - .query(self.location, 0.5, |_, _| activate = true); + .query(self.pos, 0.5, |_, _| activate = true); if activate { *c.load_map = Some(self.name.clone()); @@ -46,19 +46,11 @@ impl Entity for Map { } } -#[derive(Debug, Clone, Deserialize, Serialize)] -#[serde(rename_all = "kebab-case")] -pub enum GateCondition { - All(Vec<GateCondition>), - Any(Vec<GateCondition>), - Stars(String, u8), -} - #[derive(Debug, Clone)] pub struct Gate { pub active: bool, pub unlocked: bool, - pub location: IVec2, + pub pos: IVec2, pub blocker_tile: TileIndex, pub condition: GateCondition, } @@ -69,7 +61,7 @@ impl Entity for Gate { self.unlocked = self.condition.check(c.scoreboard); if !self.unlocked { c.game - .set_tile(self.location, Some(self.blocker_tile), c.packet_out); + .set_tile(self.pos, Some(self.blocker_tile), c.packet_out); c.packet_out.push_back(PacketC::FlushMap); // TODO dont send too often } } @@ -81,7 +73,7 @@ impl Entity for Gate { pos: Option<IVec2>, _player: PlayerID, ) -> Result<bool, TrError> { - if !self.unlocked && pos == Some(self.location) { + if !self.unlocked && pos == Some(self.pos) { c.packet_out.push_back(PacketC::ServerMessage { message: trm!( "s.campaign.unlock_condition", @@ -95,7 +87,11 @@ impl Entity for Gate { } } -impl GateCondition { +trait GateConditionExt { + fn check(&self, scoreboard: &ScoreboardStore) -> bool; + fn show(&self, scoreboard: &ScoreboardStore) -> Message; +} +impl GateConditionExt for GateCondition { fn check(&self, scoreboard: &ScoreboardStore) -> bool { match self { GateCondition::All(cs) => cs.iter().all(|c| c.check(scoreboard)), @@ -105,7 +101,7 @@ impl GateCondition { .is_some_and(|s| s.best.first().is_some_and(|b| b.score.stars >= *thres)), } } - pub fn show(&self, scoreboard: &ScoreboardStore) -> Message { + fn show(&self, scoreboard: &ScoreboardStore) -> Message { match self { GateCondition::All(cs) => cs .iter() diff --git a/server/src/entity/conveyor.rs b/server/src/entity/conveyor.rs index 9c7f5e4d..e31410e3 100644 --- a/server/src/entity/conveyor.rs +++ b/server/src/entity/conveyor.rs @@ -18,14 +18,12 @@ use super::{Entity, EntityContext}; use crate::interaction::interact; use anyhow::{anyhow, bail, Result}; -use hurrycurry_protocol::{glam::IVec2, ItemIndex, ItemLocation}; +use hurrycurry_protocol::{glam::IVec2, ItemLocation}; #[derive(Debug, Clone)] pub struct Conveyor { pub(super) from: IVec2, pub(super) to: IVec2, - pub(super) filter_tile: Option<IVec2>, - pub(super) filter_item: Option<ItemIndex>, pub(super) cooldown: f32, pub(super) max_cooldown: f32, } @@ -38,24 +36,7 @@ impl Entity for Conveyor { .get(&self.from) .ok_or(anyhow!("conveyor from missing"))?; - if let Some(from_item) = from.item.as_ref() { - let filter = if let Some(t) = &self.filter_tile { - let filter_tile = c - .game - .tiles - .get(t) - .ok_or(anyhow!("conveyor filter missing"))?; - filter_tile.item.as_ref().map(|e| e.kind) - } else { - self.filter_item.as_ref().map(|i| *i) - }; - - if let Some(filter) = filter { - if from_item.kind != filter { - return Ok(()); - } - } - + if from.item.is_some() { self.cooldown += c.dt; if self.cooldown < self.max_cooldown { return Ok(()); diff --git a/server/src/entity/customers.rs b/server/src/entity/customers.rs index e3a23830..22522e4e 100644 --- a/server/src/entity/customers.rs +++ b/server/src/entity/customers.rs @@ -29,13 +29,13 @@ pub struct Customers { } impl Customers { - pub fn new(scaling_factor: f32) -> Result<Self> { - Ok(Self { + pub fn new(scaling_factor: f32) -> Self { + Self { customers: Default::default(), spawn_cooldown: 0., chair_count: None, scaling_factor, - }) + } } } diff --git a/server/src/entity/environment_effect.rs b/server/src/entity/environment_effect.rs index 95040954..ba2c395e 100644 --- a/server/src/entity/environment_effect.rs +++ b/server/src/entity/environment_effect.rs @@ -16,23 +16,11 @@ */ use super::{Entity, EntityContext}; +use hurrycurry_data::entities::EnvironmentEffect; use hurrycurry_protocol::PacketC; use rand::random; -use serde::{Deserialize, Serialize}; use std::time::{Duration, Instant}; -#[derive(Clone, Debug, Deserialize, Serialize, Default)] -pub struct EnvironmentEffect { - name: String, - #[serde(default = "default_onoff")] - on: f32, - #[serde(default = "default_onoff")] - off: f32, -} -fn default_onoff() -> f32 { - 40. -} - #[derive(Clone, Debug)] pub struct EnvironmentEffectController { config: EnvironmentEffect, diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs index 928910bc..47d37f3d 100644 --- a/server/src/entity/mod.rs +++ b/server/src/entity/mod.rs @@ -27,26 +27,19 @@ pub mod player_portal; pub mod tram; pub mod tutorial; -use crate::{ - data::{ItemTileRegistry, Serverdata}, - entity::pedestrians::Pedestrians, - scoreboard::ScoreboardStore, -}; -use anyhow::{anyhow, Result}; +use crate::{entity::pedestrians::Pedestrians, scoreboard::ScoreboardStore}; +use anyhow::Result; use book::Book; -use campaign::{Gate, GateCondition, Map}; +use campaign::{Gate, Map}; use conveyor::Conveyor; use customers::Customers; -use environment_effect::{EnvironmentController, EnvironmentEffect, EnvironmentEffectController}; +use environment_effect::{EnvironmentController, EnvironmentEffectController}; use hurrycurry_client_lib::Game; +use hurrycurry_data::{entities::EntityDecl, Serverdata}; use hurrycurry_locale::TrError; -use hurrycurry_protocol::{ - glam::{IVec2, Vec2}, - Character, PacketC, PacketS, PlayerID, -}; +use hurrycurry_protocol::{glam::IVec2, Character, Gamedata, PacketC, PacketS, PlayerID}; use item_portal::ItemPortal; use player_portal::PlayerPortal; -use serde::{Deserialize, Serialize}; use std::{ any::Any, collections::{HashMap, VecDeque}, @@ -87,135 +80,29 @@ pub trait Entity: Any { } } -// macro_rules! entities { -// ($($e:ident),*) => { -// pub enum DynEntity { $($e($e)),* } -// impl Entity for DynEntity { -// fn tick(&mut self, c: EntityContext<'_>) -> Result<()> { -// match self { $(DynEntity::$e(x) => x.tick(c)),*, } -// } -// fn destructor(&mut self, c: EntityContext<'_>) { -// match self { $(DynEntity::$e(x) => x.destructor(c)),*, } -// } -// } -// }; -// } -// entities!( -// Conveyor, -// ItemPortal, -// PlayerPortal, -// Customers, -// EnvironmentEffectController, -// EnvironmentController -// ); - -#[derive(Debug, Clone, Deserialize, Serialize)] -#[serde(rename_all = "snake_case")] -pub enum EntityDecl { - Conveyor { - from: Option<IVec2>, - to: Option<IVec2>, - filter_dir: Option<IVec2>, - filter: Option<String>, - dir: Option<IVec2>, - speed: Option<f32>, - }, - ItemPortal { - from: Option<IVec2>, - to: IVec2, - }, - PlayerPortal { - from: Option<Vec2>, - to: Vec2, - }, - Customers { - scaling_factor: Option<f32>, - }, - Map { - name: String, - location: Option<Vec2>, - }, - EnvironmentEffect(EnvironmentEffect), - Environment(Vec<String>), - Gate { - location: Option<IVec2>, - condition: GateCondition, - }, - Tram { - length: usize, - color: Option<i32>, - points: Vec<Vec2>, - spacing: f32, - smoothing: f32, - }, - Book, - Pedestrians { - spawn_delay: f32, - spawn_delay_stdev: Option<f32>, - speed: Option<f32>, - points: Vec<Vec2>, - }, -} - -pub fn construct_entity( - pos: Option<IVec2>, - decl: &EntityDecl, - reg: &ItemTileRegistry, -) -> Result<DynEntity> { - Ok(match decl.to_owned() { - EntityDecl::Book => Box::new(Book(pos.ok_or(anyhow!("book is tile entity"))?)), - EntityDecl::ItemPortal { from, to } => Box::new(ItemPortal { - from: from - .or(pos) - .ok_or(anyhow!("Item portal start without start"))?, - to, - }), - EntityDecl::PlayerPortal { from, to } => Box::new(PlayerPortal { - from: from - .or(pos.map(|v| v.as_vec2())) - .ok_or(anyhow!("Player portal without start"))?, - to, - }), - EntityDecl::Conveyor { +pub fn construct_entity(decl: &EntityDecl, data: &Gamedata) -> DynEntity { + match decl.to_owned() { + EntityDecl::Book { pos } => Box::new(Book(pos)), + EntityDecl::ItemPortal { from, to } => Box::new(ItemPortal { from, to }), + EntityDecl::PlayerPortal { from, to } => Box::new(PlayerPortal { from, to }), + EntityDecl::Conveyor { from, to, speed } => Box::new(Conveyor { from, to, - speed, - dir, - filter, - filter_dir, - } => { - let from = from.or(pos).ok_or(anyhow!("Conveyor has no start"))?; - let to = to - .or(dir.map(|s| s + from)) - .ok_or(anyhow!("Conveyor has no destination"))?; - Box::new(Conveyor { - from, - to, - max_cooldown: 1. / speed.unwrap_or(2.), - filter_tile: filter_dir.map(|o| to + o), - filter_item: filter.map(|name| reg.register_item(name)), - cooldown: 0., - }) - } - EntityDecl::Map { name, location } => Box::new(Map { - location: location - .or(pos.map(|p| p.as_vec2() + 0.5)) - .ok_or(anyhow!("no location"))?, - name, + max_cooldown: 1. / speed.unwrap_or(2.), + cooldown: 0., }), - EntityDecl::Gate { - condition, - location, - } => Box::new(Gate { + EntityDecl::Map { name, pos } => Box::new(Map { pos, name }), + EntityDecl::Gate { condition, pos } => Box::new(Gate { condition, unlocked: false, - location: location.or(pos).ok_or(anyhow!("no location"))?, - blocker_tile: reg.register_tile("fence".to_string()), + pos, + blocker_tile: data + .get_tile_by_name("fence") + .expect("asserted earlier (tm)"), active: true, }), EntityDecl::Customers { scaling_factor } => { - reg.register_item("unknown-order".to_owned()); - Box::new(Customers::new(scaling_factor.unwrap_or(0.5))?) + Box::new(Customers::new(scaling_factor.unwrap_or(0.5))) } EntityDecl::EnvironmentEffect(config) => Box::new(EnvironmentEffectController::new(config)), EntityDecl::Environment(names) => Box::new(EnvironmentController(names)), @@ -254,5 +141,5 @@ pub fn construct_entity( cooldown: 0., speed: speed.unwrap_or(0.6), }), - }) + } } |