diff options
Diffstat (limited to 'server')
| -rw-r--r-- | server/data/src/filter_demands.rs | 8 | ||||
| -rw-r--r-- | server/data/src/index.rs | 6 | ||||
| -rw-r--r-- | server/data/src/lib.rs | 148 |
3 files changed, 97 insertions, 65 deletions
diff --git a/server/data/src/filter_demands.rs b/server/data/src/filter_demands.rs index ab175d98..99246252 100644 --- a/server/data/src/filter_demands.rs +++ b/server/data/src/filter_demands.rs @@ -25,6 +25,12 @@ pub fn filter_demands_and_recipes( demands: &mut Vec<Demand>, recipes: &mut Vec<Recipe>, ) { + debug!( + "running demand filter with {} recipes and {} demands", + recipes.len(), + demands.len() + ); + // Remove tile-bound recipes that cant be performed recipes.retain(|r| r.tile().map_or(true, |t| map_tiles.contains(&t))); @@ -89,7 +95,7 @@ pub fn filter_demands_and_recipes( } }); debug!( - "{} recipes and {} demands left", + "{} applicable recipes and {} demands selected", recipes.len(), demands.len() ) diff --git a/server/data/src/index.rs b/server/data/src/index.rs index 9a44d202..a74b283c 100644 --- a/server/data/src/index.rs +++ b/server/data/src/index.rs @@ -18,6 +18,7 @@ use anyhow::{Context, Result, anyhow, bail}; use hurrycurry_protocol::{Gamedata, MapMetadata}; +use log::debug; use serde::Deserialize; use std::{ collections::{HashMap, HashSet}, @@ -70,6 +71,7 @@ impl DataIndex { Ok(read_to_string(path)?) } pub fn generate(&self, map: &str) -> Result<(Gamedata, Serverdata)> { + debug!("Loading map {map}..."); let map_in: MapDecl = serde_yml::from_str( &self .read_map(map) @@ -83,7 +85,9 @@ impl DataIndex { ) .context("Failed to parse recipe file")?; - build_data(&self.maps, map.to_string(), map_in, recipes_in) + let data = build_data(&self.maps, map.to_string(), map_in, recipes_in)?; + debug!("Done."); + Ok(data) } pub fn generate_with_book(&self, map: &str) -> Result<(Gamedata, Serverdata)> { let (gd, mut sd) = self.generate(map)?; diff --git a/server/data/src/lib.rs b/server/data/src/lib.rs index 86dec209..d316d0b7 100644 --- a/server/data/src/lib.rs +++ b/server/data/src/lib.rs @@ -29,6 +29,7 @@ use hurrycurry_protocol::{ book::Book, glam::{IVec2, Vec2}, }; +use log::debug; use serde::{Deserialize, Serialize}; use std::{ collections::{BTreeMap, BTreeSet, HashMap, HashSet}, @@ -132,71 +133,10 @@ fn build_data( map_in: MapDecl, recipes_in: Vec<RecipeDecl>, ) -> Result<(Gamedata, Serverdata)> { + debug!("Preparing gamedata for {map_name}"); let reg = ItemTileRegistry::default(); - let mut recipes = Vec::new(); - let mut demands = Vec::new(); - let mut entities = Vec::new(); - let mut recipe_groups = BTreeMap::<String, BTreeSet<ItemIndex>>::new(); - for mut r in recipes_in { - #[cfg(feature = "fast_recipes")] - match r.action { - RecipeDeclAction::Passive | RecipeDeclAction::Active => { - if !r.warn { - r.duration = Some(0.5) - } - } - _ => (), - } - - let r2 = r.clone(); - let mut inputs = r.inputs.into_iter().map(|i| reg.register_item(i)); - let mut outputs = r.outputs.into_iter().map(|o| reg.register_item(o)); - let tile = r.tile.map(|t| reg.register_tile(t)); - if let Some(g) = r.group { - if !r.group_hidden { - recipe_groups.entry(g).or_default().extend(inputs.clone()); - } - } - match r.action { - RecipeDeclAction::Never => {} - RecipeDeclAction::Passive => recipes.push(Recipe::Passive { - speed: 1. / r.duration.ok_or(anyhow!("duration for passive missing"))?, - warn: r.warn, - tile, - revert_speed: r.revert_duration.map(|d| 1. / d), - input: inputs - .next() - .ok_or(anyhow!("passive recipe without input"))?, - output: outputs.next(), - }), - RecipeDeclAction::Active => recipes.push(Recipe::Active { - speed: 1. / r.duration.ok_or(anyhow!("duration for active missing"))?, - tile, - input: inputs - .next() - .ok_or(anyhow!("active recipe without input"))?, - outputs: [outputs.next(), outputs.next()], - }), - RecipeDeclAction::Instant => { - recipes.push(Recipe::Instant { - points: r.points.take().unwrap_or(0), - tile, - inputs: [inputs.next(), inputs.next()], - outputs: [outputs.next(), outputs.next()], - }); - } - RecipeDeclAction::Demand => demands.push(Demand { - input: inputs.next().ok_or(anyhow!("demand needs inputs"))?, - output: outputs.next(), - duration: r.duration.unwrap_or(10.), - points: 0, // assigned later when filtering - }), - } - assert_eq!(inputs.next(), None, "{r2:?} inputs left over"); - assert_eq!(outputs.next(), None, "{r2:?} outputs left over"); - assert_eq!(r.points, None, "points specified where not possible") - } + let (mut recipes, mut demands, recipe_groups) = load_recipes(recipes_in, ®)?; let mut tile_specs = BTreeMap::new(); for (char, tile_spec_raw) in map_in.tiles { @@ -205,6 +145,7 @@ fn build_data( tile_specs.insert(char, TileArgs::try_parse_from(toks)?); } + let mut entities = Vec::new(); let mut chef_spawn = None; let mut customer_spawn = None; let mut initial_map = HashMap::new(); @@ -270,6 +211,7 @@ fn build_data( for e in &entities { e.run_register(®); } + debug!("{} entites created", entities.len()); filter_demands_and_recipes(&tiles_used, &items_used, &mut demands, &mut recipes); @@ -301,6 +243,11 @@ fn build_data( let item_names = reg.items.into_inner().unwrap(); let tile_names = reg.tiles.into_inner().unwrap(); + debug!( + "{} items and {} tiles registered", + item_names.len(), + tile_names.len() + ); let default_timer = if map_name.ends_with("lobby") { None @@ -341,6 +288,81 @@ fn build_data( )) } +fn load_recipes( + recipes_in: Vec<RecipeDecl>, + reg: &ItemTileRegistry, +) -> Result<( + Vec<Recipe>, + Vec<Demand>, + BTreeMap<String, BTreeSet<ItemIndex>>, +)> { + let mut recipes = Vec::new(); + let mut demands = Vec::new(); + let mut recipe_groups = BTreeMap::<String, BTreeSet<ItemIndex>>::new(); + + for mut r in recipes_in { + #[cfg(feature = "fast_recipes")] + match r.action { + RecipeDeclAction::Passive | RecipeDeclAction::Active => { + if !r.warn { + r.duration = Some(0.5) + } + } + _ => (), + } + + let r2 = r.clone(); + let mut inputs = r.inputs.into_iter().map(|i| reg.register_item(i)); + let mut outputs = r.outputs.into_iter().map(|o| reg.register_item(o)); + let tile = r.tile.map(|t| reg.register_tile(t)); + if let Some(g) = r.group { + if !r.group_hidden { + recipe_groups.entry(g).or_default().extend(inputs.clone()); + } + } + match r.action { + RecipeDeclAction::Never => {} + RecipeDeclAction::Passive => recipes.push(Recipe::Passive { + speed: 1. / r.duration.ok_or(anyhow!("duration for passive missing"))?, + warn: r.warn, + tile, + revert_speed: r.revert_duration.map(|d| 1. / d), + input: inputs + .next() + .ok_or(anyhow!("passive recipe without input"))?, + output: outputs.next(), + }), + RecipeDeclAction::Active => recipes.push(Recipe::Active { + speed: 1. / r.duration.ok_or(anyhow!("duration for active missing"))?, + tile, + input: inputs + .next() + .ok_or(anyhow!("active recipe without input"))?, + outputs: [outputs.next(), outputs.next()], + }), + RecipeDeclAction::Instant => { + recipes.push(Recipe::Instant { + points: r.points.take().unwrap_or(0), + tile, + inputs: [inputs.next(), inputs.next()], + outputs: [outputs.next(), outputs.next()], + }); + } + RecipeDeclAction::Demand => demands.push(Demand { + input: inputs.next().ok_or(anyhow!("demand needs inputs"))?, + output: outputs.next(), + duration: r.duration.unwrap_or(10.), + points: 0, // assigned later when filtering + }), + } + assert_eq!(inputs.next(), None, "{r2:?} inputs left over"); + assert_eq!(outputs.next(), None, "{r2:?} outputs left over"); + assert_eq!(r.points, None, "points specified where not possible") + } + + Ok((recipes, demands, recipe_groups)) +} + #[derive(Default)] pub(crate) struct ItemTileRegistry { tiles: RwLock<Vec<String>>, |