mod consts;
use consts as equipment;
use serde_json::json;
use std::path::Path;
use yog_ids::res;
use crate::consts::item_def;
use crate::content::ctx::caveat;
use crate::content::{Compiled, pretty};
use crate::diagnostics::Diagnostic;
const OPAQUE: u32 = 0xFF00_0000;
fn own(root: &Path, out: &Compiled, path: &str) -> bool {
root.join(path).is_file() || out.outputs.iter().any(|(p, _)| p == path)
}
pub(super) fn spawn_egg(
root: &Path,
out: &mut Compiled,
ns: &str,
p: &str,
[base, spots]: [u32; 2],
) {
let item = format!("{p}{}", res::SPAWN_EGG_SUFFIX);
let model = format!("{}{item}", res::ITEM_DIR);
let model_path = yog_ids::asset_file(ns, &yog_ids::model_file(&model));
if !own(root, out, &model_path) {
out.outputs.push((
model_path,
pretty(&json!({ (yog_ids::model::PARENT): yog_ids::yog::SPAWN_EGG_MODEL })),
));
}
let def_path =
yog_ids::asset_file(ns, &format!("{}{item}{}", res::ITEM_DEFINITIONS, res::JSON));
if own(root, out, &def_path) {
return;
}
let tint = |rgb: u32| json!({ (item_def::TYPE): item_def::CONSTANT, (item_def::VALUE): (OPAQUE | rgb) as i32 });
let def = json!({ (item_def::MODEL): {
(item_def::TYPE): item_def::PLAIN,
(item_def::MODEL): yog_ids::join(ns, &model),
(item_def::TINTS): [tint(base), tint(spots)],
} });
out.outputs.push((def_path, pretty(&def)));
}
pub(super) fn equipment(
root: &Path,
out: &mut Compiled,
texture: &str,
warnings: &mut Vec<Diagnostic>,
) {
let (ns, path) = yog_ids::split(texture);
let layer = json!([{ (equipment::TEXTURE): texture }]);
let asset_path = yog_ids::asset_file(ns, &format!("{}{path}{}", res::EQUIPMENT, res::JSON));
if !own(root, out, &asset_path) {
let def = json!({ (equipment::LAYERS): {
(equipment::HUMANOID): layer.clone(),
(equipment::HUMANOID_LEGGINGS): layer,
} });
out.outputs.push((asset_path, pretty(&def)));
}
for (n, worn) in [(1, equipment::HUMANOID), (2, equipment::HUMANOID_LEGGINGS)] {
let old = yog_ids::asset_file(
ns,
&yog_ids::texture_file(&format!(
"{}{path}{}{n}",
res::ARMOR_TEXTURES,
res::ARMOR_LAYER
)),
);
let new = yog_ids::asset_file(
ns,
&yog_ids::texture_file(&format!(
"{}{worn}{}{path}",
res::EQUIPMENT_TEXTURES,
yog_ids::sep::PATH
)),
);
if own(root, out, &new) {
continue;
}
let picture = out
.outputs
.iter()
.find(|(p, _)| *p == old)
.map(|(_, b)| b.clone())
.or_else(|| std::fs::read(root.join(&old)).ok());
match picture {
Some(bytes) => out.outputs.push((new, bytes)),
None => warnings.push(caveat(format!(
"armor texture {texture}: no {old}, worn armor shows nothing"
))),
}
}
}