diff options
Diffstat (limited to 'server/tools/src/recipe_diagram.rs')
-rw-r--r-- | server/tools/src/recipe_diagram.rs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/server/tools/src/recipe_diagram.rs b/server/tools/src/recipe_diagram.rs new file mode 100644 index 00000000..25f8040c --- /dev/null +++ b/server/tools/src/recipe_diagram.rs @@ -0,0 +1,112 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + 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 anyhow::Result; +use hurrycurry_protocol::book::{Diagram, DiagramEdge, DiagramNode}; +use hurrycurry_protocol::glam::Vec2; +use hurrycurry_protocol::{ItemIndex, Message, RecipeIndex}; +use hurrycurry_server::data::DataIndex; +use std::collections::{BTreeMap, BTreeSet, HashSet}; + +pub(crate) fn recipe_diagram(target_items: &[String]) -> Result<Diagram> { + let mut index = DataIndex::default(); + index.reload()?; + + let (data, serverdata, _) = index.generate("5star")?; + + let ambient_items = serverdata + .initial_map + .iter() + .flat_map(|(_, (_, item))| item) + .copied() + .collect::<HashSet<_>>(); + + let mut need = BTreeSet::from_iter( + target_items + .iter() + .map(|name| data.get_item_by_name(name).unwrap()), + ); + let mut have = BTreeSet::<ItemIndex>::new(); + let mut recipes = BTreeSet::new(); + + #[derive(PartialEq, PartialOrd, Eq, Ord)] + struct GraphRecipe { + index: RecipeIndex, + inputs: Vec<ItemIndex>, + outputs: Vec<ItemIndex>, + } + + while let Some(item) = need.pop_last() { + for (ri, r) in data.recipes() { + if r.outputs().contains(&item) { + let gr = GraphRecipe { + inputs: r + .inputs() + .iter() + .filter(|i| !ambient_items.contains(i)) + .copied() + .collect(), + outputs: r + .outputs() + .iter() + .filter(|i| !ambient_items.contains(i)) + .copied() + .collect(), + index: ri, + }; + need.extend(&gr.inputs); + have.extend(&gr.outputs); + recipes.insert(gr); + } + } + } + + let mut diag = Diagram::default(); + let mut item_index = BTreeMap::new(); + for i in have { + item_index.insert(i, diag.nodes.len()); + diag.nodes.push(DiagramNode { + label: Message::Item(i), + position: Vec2::ZERO, + }); + } + for r in recipes { + let index = diag.nodes.len(); + diag.nodes.push(DiagramNode { + position: Vec2::ZERO, + label: Message::Text("blub".to_string()), + }); + + for i in r.inputs { + diag.edges.push(DiagramEdge { + src: item_index[&i], + dst: index, + label: None, + }); + } + for o in r.outputs { + diag.edges.push(DiagramEdge { + src: index, + dst: item_index[&o], + label: None, + }); + } + } + + Ok(diag) +} |