diff options
| -rw-r--r-- | data/index.yaml | 2 | ||||
| -rw-r--r-- | data/makefile | 2 | ||||
| -rw-r--r-- | data/maps/campaign/01.yaml | 70 | ||||
| -rw-r--r-- | data/maps/campaign/lobby.yaml | 59 | ||||
| -rw-r--r-- | server/src/bin/graph.rs | 9 | ||||
| -rw-r--r-- | server/src/bin/graph_summary.rs | 8 | ||||
| -rw-r--r-- | server/src/data/mod.rs | 38 | ||||
| -rw-r--r-- | server/src/server.rs | 2 | ||||
| -rw-r--r-- | server/src/state.rs | 18 | 
9 files changed, 160 insertions, 48 deletions
| diff --git a/data/index.yaml b/data/index.yaml index 2073fd5d..199ed423 100644 --- a/data/index.yaml +++ b/data/index.yaml @@ -29,7 +29,6 @@ demands:  # 5 Unplayable  maps: -    lobby: { name: "Lobby", players: 0, difficulty: 1 }      sophomore: { name: "Sophomore", players: 1, difficulty: 1 }      junior: { name: "Junior", players: 3, difficulty: 1 }      senior: { name: "Senior", players: 4, difficulty: 1 } @@ -51,7 +50,6 @@ maps:      5star: { name: "5 Star", players: 4, difficulty: 3 }      auto_sushi: { name: "AutoSushi", players: 2, difficulty: 2 }      factory: { name: "Factory", players: 3, difficulty: 4 } -    debug: { name: "DEBUG", players: 0, difficulty: 5 }  recipes:      - none diff --git a/data/makefile b/data/makefile index 95dc953a..23956869 100644 --- a/data/makefile +++ b/data/makefile @@ -14,7 +14,7 @@  # along with this program.  If not, see <https://www.gnu.org/licenses/>.  #  all: $(patsubst %.ts,%.yaml,$(wildcard recipes/*.ts)) -graphs: $(patsubst %.ts,%.svg,$(wildcard recipes/*.ts)) +graphs: recipes/default.svg  recipes/%.yaml: recipes/%.ts  	DENO_NO_UPDATE_CHECK=1 deno run $< > $@ diff --git a/data/maps/campaign/01.yaml b/data/maps/campaign/01.yaml new file mode 100644 index 00000000..8fe64c5b --- /dev/null +++ b/data/maps/campaign/01.yaml @@ -0,0 +1,70 @@ +# Hurry Curry! - a game about cooking +# Copyright 2024 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/>. +# +score_baseline: 100 +map: +    - "*''''*'''*'''''*'''" +    - "'''*''''*'*'*'''*'*" +    - "''████▒█████▒███'*" +    - "*'█tc....█..~.s█''" +    - "''▒c.ctc.d....⌷█'*" +    - "'*█tc.c..█....C█'*" +    - "''█c.....█XTppp█''" +    - "*'████dd████████''" +    - "'*''''__'''''''''''" +    - "'''*''____________!" +    - "'*'''''''''''''''''" + +tiles: +    "⌷": counter +    "p": counter +    "t": table +    "w": counter-window +    "s": sink +    "C": cuttingboard +    "T": tomato-crate +    "X": trash + +    "c": chair +    "~": floor +    ".": floor +    "'": grass +    "*": tree +    "!": path +    "_": path +    "d": door +    "▒": wall-window +    "█": wall + +items: +    "p": plate + +entities: +    - !customers + +chef_spawn: "~" +customer_spawn: "!" + +walkable: +    - door +    - floor +    - chair +    - grass +    - path + +collider: +    - wall +    - wall-window +    - tree diff --git a/data/maps/campaign/lobby.yaml b/data/maps/campaign/lobby.yaml new file mode 100644 index 00000000..6090d96a --- /dev/null +++ b/data/maps/campaign/lobby.yaml @@ -0,0 +1,59 @@ +# Hurry Curry! - a game about cooking +# Copyright 2024 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/>. +# +score_baseline: 0 +map: +    - "'*''''''''''''*'" +    - "*'''''*'''*'''''" +    - "'*''*''''*'*'*'*" +    - "*''''''''''''*''" +    - "*''''''''''''**'" +    - "''''''''''''''''" +    - "''*''''''''''*'*" +    - "'*'''''~''''''''" +    - "''''''''''''''*'" +    - "'*'''''''''''*''" +    - "''*'''''''''''*'" +    - "'''''''''''''*''" +    - "'*'''''''''''*''" +    - "''*'''*'''*''*''" +    - "'*''*''**'''**''" +    - "*'''''''''*''''*" + +tiles: +    "t": table +    "T": table +    "s": sink +    "c": chair +    "~": floor +    ".": floor +    "b": book +    "'": grass +    "*": tree +    "█": wall + +items: +    "t": tomato-soup-plate +    "T": bread-slice-plate + +chef_spawn: "~" +customer_spawn: "!" + +walkable: +    - floor +    - chair +    - grass +collider: +    - wall diff --git a/server/src/bin/graph.rs b/server/src/bin/graph.rs index 7019de9c..0bc3702f 100644 --- a/server/src/bin/graph.rs +++ b/server/src/bin/graph.rs @@ -15,7 +15,7 @@      along with this program.  If not, see <https://www.gnu.org/licenses/>.  */ -use anyhow::{anyhow, Result}; +use anyhow::Result;  use hurrycurry_protocol::{Demand, ItemIndex, Recipe, RecipeIndex};  use hurrycurry_server::data::DataIndex; @@ -26,12 +26,7 @@ async fn main() -> Result<()> {      println!("digraph {{"); -    let rn = std::env::args() -        .nth(1) -        .ok_or(anyhow!("first arg should be recipe set name"))?; - -    let (data, _, _) = index.generate(format!("5star-{rn}")).await?; - +    let (data, _, _) = index.generate("5star").await?;      for i in 0..data.item_names.len() {          println!("i{i} [label=\"{}\"]", data.item_name(ItemIndex(i)))      } diff --git a/server/src/bin/graph_summary.rs b/server/src/bin/graph_summary.rs index 12df0b1a..2c97799a 100644 --- a/server/src/bin/graph_summary.rs +++ b/server/src/bin/graph_summary.rs @@ -15,7 +15,7 @@      along with this program.  If not, see <https://www.gnu.org/licenses/>.  */ -use anyhow::{anyhow, Result}; +use anyhow::Result;  use hurrycurry_protocol::{ItemIndex, Recipe, TileIndex};  use hurrycurry_server::data::DataIndex;  use std::collections::HashSet; @@ -27,11 +27,7 @@ async fn main() -> Result<()> {      println!("digraph {{"); -    let rn = std::env::args() -        .nth(1) -        .ok_or(anyhow!("first arg should be recipe set name"))?; - -    let (data, sdata, _) = index.generate(format!("5star-{rn}")).await?; +    let (data, sdata, _) = index.generate("5star").await?;      struct Node {          inputs: Vec<ItemIndex>, diff --git a/server/src/data/mod.rs b/server/src/data/mod.rs index dd916a93..7ec0707d 100644 --- a/server/src/data/mod.rs +++ b/server/src/data/mod.rs @@ -69,6 +69,8 @@ pub struct RecipeDecl {  #[derive(Debug, Clone, Deserialize)]  pub struct MapDecl { +    #[serde(default)] +    recipes: Option<String>,      map: Vec<String>,      tiles: HashMap<char, String>,      #[serde(default)] @@ -96,7 +98,6 @@ pub struct DemandDecl {  #[derive(Debug,Clone, Default)]  #[rustfmt::skip]  pub struct Serverdata { -    pub spec: String,      pub initial_map: HashMap<IVec2, (TileIndex, Option<ItemIndex>)>,      pub chef_spawn: Vec2,      pub customer_spawn: Vec2, @@ -125,8 +126,9 @@ impl DataIndex {      }      pub async fn read_map(&self, name: &str) -> Result<String> { -        if !self.maps.contains_key(name) { -            bail!("unknown map: {name:?}"); +        // Scary! +        if name.contains("..") || name.starts_with("/") || name.contains("//") { +            bail!("illegal map path");          }          let path = data_dir().join(format!("maps/{name}.yaml"));          Ok(read_to_string(path).await?) @@ -138,26 +140,25 @@ impl DataIndex {          let path = data_dir().join(format!("recipes/{name}.yaml"));          Ok(read_to_string(path).await?)      } - -    pub async fn generate(&self, spec: String) -> Result<(Gamedata, Serverdata, Entities)> { -        let (map, recipes) = spec.split_once("-").unwrap_or((spec.as_str(), "default")); - -        let map_in = serde_yml::from_str(&self.read_map(map).await?)?; -        let recipes_in = serde_yml::from_str(&self.read_recipes(recipes).await?)?; - -        Ok(build_data( -            &self.maps, -            spec.clone(), -            map.to_string(), -            map_in, -            recipes_in, -        )?) +    pub async fn generate(&self, map: &str) -> Result<(Gamedata, Serverdata, Entities)> { +        let map_in: MapDecl = serde_yml::from_str(&self.read_map(map).await?)?; +        let recipes_in = serde_yml::from_str( +            &self +                .read_recipes( +                    map_in +                        .recipes +                        .as_ref() +                        .map(|a| a.as_str()) +                        .unwrap_or("default"), +                ) +                .await?, +        )?; +        Ok(build_data(&self.maps, map.to_string(), map_in, recipes_in)?)      }  }  pub fn build_data(      maps: &HashMap<String, MapMetadata>, -    spec: String,      map_name: String,      map_in: MapDecl,      recipes_in: Vec<RecipeDecl>, @@ -301,7 +302,6 @@ pub fn build_data(              tile_names,          },          Serverdata { -            spec,              initial_map,              chef_spawn,              customer_spawn, diff --git a/server/src/server.rs b/server/src/server.rs index 75ecede1..cce99266 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -252,7 +252,6 @@ impl Server<'_> {          packet_out: &mut VecDeque<PacketC>,      ) {          self.game.load(gamedata, &serverdata, timer, packet_out); -        self.state.data = serverdata.into();          for mut e in self.state.entities.drain(..) {              e.destructor(EntityContext {                  game: self.game, @@ -262,6 +261,7 @@ impl Server<'_> {                  dt: 0.,              });          } +        self.state.data = serverdata.into();          self.state.entities = entities;      } diff --git a/server/src/state.rs b/server/src/state.rs index 20a57b9d..4be0fb5a 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -99,11 +99,7 @@ impl State {                  game: &mut game,                  state: &mut server,              } -            .load( -                index.generate("lobby-none".to_string()).await?, -                None, -                &mut packet_out, -            ); +            .load(index.generate("lobby").await?, None, &mut packet_out);          }          Ok(Self { @@ -123,7 +119,7 @@ impl State {          };          if server.tick(dt, &mut self.packet_out) {              server.load( -                self.index.generate("lobby-none".to_string()).await?, +                self.index.generate("lobby").await?,                  None,                  &mut self.packet_out,              ); @@ -192,7 +188,7 @@ impl State {                  })                  .ok();              server.load( -                self.index.generate("lobby-none".to_string()).await?, +                self.index.generate("lobby").await?,                  None,                  &mut self.packet_out,              ); @@ -231,7 +227,7 @@ impl State {          };          match command {              Command::Start { spec, timer } => { -                let data = self.index.generate(spec).await?; +                let data = self.index.generate(&spec).await?;                  server.load(data, Some(Duration::from_secs(timer)), &mut self.packet_out);              }              Command::End => { @@ -249,7 +245,7 @@ impl State {                      })                      .ok();                  server.load( -                    self.index.generate("lobby-none".to_string()).await?, +                    self.index.generate("lobby").await?,                      None,                      &mut self.packet_out,                  ); @@ -259,9 +255,7 @@ impl State {                      bail!("must be at most one player to reload");                  }                  server.load( -                    self.index -                        .generate(server.state.data.spec.to_string()) -                        .await?, +                    self.index.generate(&server.game.data.current_map).await?,                      None,                      &mut self.packet_out,                  ); | 
