aboutsummaryrefslogtreecommitdiff
path: root/server/tools/src/recipe_diagram.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/tools/src/recipe_diagram.rs')
-rw-r--r--server/tools/src/recipe_diagram.rs112
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)
+}