vintage_schematics/convert/
material.rs

1//! Wood and stone material conversion logic.
2
3use tracing::{info, warn};
4
5/// Converts the given wood to its Vintage Story equivalent.
6/// For example, `spruce` becomes `walnut`, while `oak` remains unchanged.
7///
8/// If `log_missing` is `true`, a warning will be logged for unknown wood types.
9#[must_use]
10pub fn convert_wood(tree: &str, log_missing: bool) -> Option<&str> {
11	Some(match tree {
12		"spruce" => "walnut",
13		"dark_oak" => "ebony",
14		"mangrove" => "redwood",
15		"pale_oak" => "baldcypress",
16		"jungle" => "pine",
17
18		// bamboo
19		"bamboo" | "bamboo_mosaic" => "maple",
20
21		// crimson stem
22		"cherry" | "crimson" => "purpleheart",
23
24		// warped stem
25		// TODO: something better, idk
26		"warped" => "larch",
27
28		// (flowering) azalea leaves
29		"azalea" | "flowering_azalea" => "birch",
30
31		"oak" | "birch" | "acacia" => tree,
32
33		_ if log_missing => {
34			warn!("unknown tree: {tree}");
35			return None;
36		}
37		_ => return None,
38	})
39}
40
41/// Converts Minecraft stone materials to their Vintage Story equivalents.
42///
43/// The first element of the tuple is the stone type, the second is an optional variant.
44/// For example, `("cobblestone", Some("granite"))` means "cobblestone (granite)", and would be used as (for example)
45/// `cobblestonestairs-granite`, whereas `("quartz", None)` would be used as `quartzstairs`.
46///
47/// If `log_missing` is `true`, a warning will be logged for unknown stone types.
48#[must_use]
49pub fn convert_stone(material: &str, log_missing: bool) -> Option<(&str, Option<&str>)> {
50	Some(match material {
51		"cobblestone" | "tuff" | "polished_tuff" | "tuff_brick" | "tuff_bricks" => ("cobblestone", Some("granite")),
52		"mossy_cobblestone" | "prismarine" | "prismarine_brick" | "prismarine_bricks" | "infested_cobblestone" => {
53			("cobblestone", Some("peridotite"))
54		}
55		"stone" | "stone_brick" | "stone_bricks" | "andesite" | "polished_andesite" | "infested_stone" => {
56			("stonebrick", Some("granite"))
57		}
58		"smooth_stone" => ("rockpolished", Some("chalk")),
59		"mossy_stone_brick" | "mossy_stone_bricks" | "infested_mossy_stone_bricks" => ("stonebrick", Some("peridotite")),
60		"cobbled_deepslate" => ("cobblestone", Some("shale")),
61		"deepslate" | "polished_deepslate" | "deepslate_brick" | "deepslate_bricks" | "deepslate_tile"
62		| "infested_deepslate" => ("stonebrick", Some("shale")),
63		"diorite" | "polished_diorite" => ("cobblestone", Some("whitemarble")),
64		"granite" | "polished_granite" | "red_sandstone" | "smooth_red_sandstone" => ("cobblestone", Some("bauxite")),
65		"cut_red_sandstone" => ("rockpolished", Some("bauxite")),
66		"chiseled_red_sandstone" => ("cobbleskull", Some("bauxite")),
67		"sandstone" | "cut_sandstone" => ("cobblestone", Some("sandstone")),
68		"smooth_sandstone" => ("rockpolished", Some("sandstone")),
69		"chiseled_sandstone" => ("cobbleskull", Some("sandstone")),
70		"dark_prismarine" => ("cobblestone", Some("kimberlite")),
71		"quartz" | "quartz_bricks" | "smooth_quartz" | "end_stone_brick" | "end_stone_bricks" => {
72			("stonebrick", Some("chalk"))
73		}
74		"blackstone" => ("cobblestone", Some("basalt")),
75		"polished_blackstone" | "polished_blackstone_brick" | "polished_blackstone_bricks" => {
76			("stonebrick", Some("basalt"))
77		}
78		"cracked_polished_blackstone_brick" | "cracked_polished_blackstone_bricks" => {
79			("crackedstonebricks", Some("basalt"))
80		}
81		"brick" | "bricks" => ("brick", Some("four-red")),
82		"mud_brick" | "mud_bricks" => ("brick", Some("four-brown")),
83		"resin_brick" | "resin_bricks" => ("brick", Some("four-orange")),
84		"purpur" => ("plank", Some("purpleheart")),
85		"nether_brick" | "nether_bricks" => ("clayshingle", Some("orange")),
86		"red_nether_brick" | "red_nether_bricks" => ("clayshingle", Some("red")),
87		"basalt" | "polished_basalt" => ("debarkedlog-veryaged-ud", None),
88		"smooth_basalt" => ("polishedrockold-full", Some("slate")),
89		_ if log_missing => {
90			info!("unknown stone material: {material}");
91			return None;
92		}
93		_ => return None,
94	})
95}
96
97/// Runs `convert_wood` followed by `convert_stone`.
98#[must_use]
99pub fn convert_wood_or_stone(material: &str) -> Option<(&str, Option<&str>)> {
100	convert_stone(material, false)
101		.or_else(|| convert_wood(material, false).map(|tree| ("plank", Some(tree))))
102		.or_else(|| {
103			info!("unknown wood or stone material: {material}");
104			None
105		})
106}
107
108/// Returns `true` if the given material is a known wood type.
109#[must_use]
110pub fn is_tree(material: &str) -> bool { convert_wood(material, false).is_some() }
111
112/// Returns `true` if the given material is a known stone type.
113#[must_use]
114pub fn is_stone(material: &str) -> bool { convert_wood_or_stone(material).is_some() && !is_tree(material) }