yog_cli/design/content/
choices.rs1use std::borrow::Cow;
5use std::path::Path;
6use yog_data::Value;
7use yog_ids::Format;
8
9use crate::design::assets::Resources;
10use crate::design::project::mod_root;
11
12#[derive(yog_data::Schema)]
13pub struct TextureChoice {
14 pub value: String,
16 pub group: Cow<'static, str>,
18}
19
20pub fn strings(file: &Path) -> Vec<String> {
22 let mut out = Vec::new();
23 let Some(root) = mod_root(file) else {
24 return out;
25 };
26 for p in crate::files::of(&root.join(yog_ids::project::RESOURCES), Format::Res) {
27 let Some(set) = p.file_stem().and_then(|s| s.to_str()) else {
28 continue;
29 };
30 if set.contains('.') {
31 continue; }
33 let Ok(text) = crate::files::read_source(&p) else {
34 continue;
35 };
36 let Some(doc) = crate::design::data::read_object(&text) else {
37 continue;
38 };
39 for (name, e) in doc.as_map().into_iter().flatten() {
40 let ty = e.get("type").and_then(Value::as_str);
41 if e.as_str().is_some() || ty.is_none_or(|t| t == "string") {
42 out.push(format!("@{set}.{name}"));
43 }
44 }
45 }
46 out.sort();
47 out
48}
49
50fn definitions(
53 file: &Path,
54 kind: &str,
55 built_ins: impl IntoIterator<Item = String>,
56) -> Vec<String> {
57 let mut out: Vec<String> = built_ins
58 .into_iter()
59 .map(|id| {
60 id.trim_start_matches(&format!(
61 "{}{}",
62 yog_ids::ns::MINECRAFT,
63 yog_ids::sep::NAMESPACE
64 ))
65 .to_string()
66 })
67 .collect();
68 let Some(root) = mod_root(file) else {
69 return out;
70 };
71 let ns = crate::design::project::mod_id(&root).unwrap_or_else(|| yog_ids::ns::MINECRAFT.into());
72 let mut own = Vec::new();
73 for p in crate::files::of(&root.join(yog_ids::project::CONTENT), Format::Def) {
74 let Some(doc) = crate::files::read_source(&p)
75 .ok()
76 .and_then(|t| crate::design::data::read_object(&t))
77 else {
78 continue;
79 };
80 if doc
81 .get(yog_ids::content_field::KIND)
82 .and_then(Value::as_str)
83 != Some(kind)
84 {
85 continue;
86 }
87 if let Some(id) = doc.get(yog_ids::content_field::ID).and_then(Value::as_str) {
88 own.push(format!(
89 "{}{kind}{}{}",
90 yog_ids::sep::TYPED,
91 yog_ids::sep::NAMESPACE,
92 yog_ids::qualify_in(&ns, id)
93 ));
94 }
95 }
96 own.sort();
97 out.extend(own);
98 out
99}
100
101pub fn sound_groups(file: &Path) -> Vec<String> {
103 definitions(
104 file,
105 "sound_group",
106 yog_formats::def::SoundGroup::built_ins()
107 .iter()
108 .map(|g| g.id.clone()),
109 )
110}
111
112pub fn tool_materials(file: &Path) -> Vec<String> {
114 definitions(
115 file,
116 "tool_material",
117 yog_formats::def::ToolMaterial::built_ins()
118 .iter()
119 .map(|m| m.id.clone()),
120 )
121}
122
123pub fn armor_materials(file: &Path) -> Vec<String> {
125 definitions(
126 file,
127 "armor_material",
128 yog_formats::def::ArmorMaterial::built_ins()
129 .iter()
130 .map(|m| m.id.clone()),
131 )
132}
133
134pub fn tags(file: &Path, registry: &str) -> Vec<String> {
138 let mut out = Vec::new();
139 if let Some(root) = mod_root(file) {
140 let ns = crate::design::project::mod_id(&root).unwrap_or_default();
141 let listed = crate::content::read_tags(&root)
142 .remove(registry)
143 .unwrap_or_default();
144 out.extend(
145 listed
146 .into_keys()
147 .filter_map(|t| t.strip_prefix(&format!("{ns}:")).map(str::to_string)),
148 );
149 }
150 out.extend(
151 yog_formats::tags::yog_tags(registry)
152 .into_iter()
153 .map(|(p, _)| format!("yog:{p}")),
154 );
155 out
156}
157
158pub fn textures(file: &Path) -> Vec<TextureChoice> {
160 let mut out = Vec::new();
161 let root = mod_root(file);
162 if let Some(root) = &root {
163 out.extend(
164 crate::media::textures(root)
165 .into_iter()
166 .map(|t| TextureChoice {
167 value: format!("{}{}", yog_ids::reference::TEXTURE, t.id),
168 group: Cow::Borrowed("Mod textures"),
169 }),
170 );
171 }
172 if let Some(v) = Resources::for_mod(root.as_deref()).vanilla {
173 let (items, blocks) = v.texture_names();
174 out.extend(blocks.into_iter().map(|b| TextureChoice {
175 value: format!(
176 "{}{}",
177 yog_ids::reference::TEXTURE,
178 yog_ids::join(
179 yog_ids::ns::MINECRAFT,
180 &format!("{}{b}", yog_ids::res::BLOCK_DIR)
181 )
182 ),
183 group: Cow::Borrowed("Minecraft blocks"),
184 }));
185 out.extend(items.into_iter().map(|i| TextureChoice {
186 value: format!(
187 "{}{}",
188 yog_ids::reference::TEXTURE,
189 yog_ids::join(
190 yog_ids::ns::MINECRAFT,
191 &format!("{}{i}", yog_ids::res::ITEM_DIR)
192 )
193 ),
194 group: Cow::Borrowed("Minecraft items"),
195 }));
196 }
197 out
198}