use std::{
collections::HashMap,
fs::File,
io::prelude::*,
path::Path
};
use lazy_static::lazy_static;
use crate::{
config::{Config, ModeSettings},
model::game::TitleId
};
pub const REGION_TITLE_INDICES_KEY: &str = "region_title_indices";
const YAML_INDENT: &str = " ";
const EXPECT_REGION_TITLE_INDICES: &str = "region title indices must be provided in title-based regions mode";
lazy_static! {
static ref PROGRAM_NAME_AND_VERSION: String = format!("{} v{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
}
pub fn write_metadata(
metadata_yaml_path: &Path,
config: &Config,
region_title_indices: Option<&HashMap<TitleId, u32>>,
max_region_index: u32
) -> std::io::Result<()> {
let mut metadata_yaml_file = File::create(metadata_yaml_path)?;
let regions_map_relative_path = config.mod_paths.regions_map.strip_prefix(&config.mod_paths.mod_root)
.expect("regions map path must have mod root as prefix");
match config.mode_settings {
ModeSettings::TitleBasedRegions { region_title_tier: _ } => {
write_region_title_indices_comment(&mut metadata_yaml_file, regions_map_relative_path)?;
writeln!(&mut metadata_yaml_file, "{}:", REGION_TITLE_INDICES_KEY)?;
let mut sorted_region_title_indices: Vec<_> = region_title_indices
.expect(EXPECT_REGION_TITLE_INDICES)
.into_iter()
.collect();
assert_eq!(sorted_region_title_indices.len(), max_region_index as usize);
sorted_region_title_indices.sort_by(|(_, idx_0), (_, idx_1)| idx_0.cmp(idx_1));
for (title_id, region_title_index) in sorted_region_title_indices {
writeln!(&mut metadata_yaml_file, "{}{}: {}", YAML_INDENT, title_id, region_title_index)?;
}
},
ModeSettings::PredefinedRegions {..} => {},
};
Ok(())
}
fn _write_header_comment(yaml_file: &mut File, mod_prefix: &str) -> std::io::Result<()> {
writeln!(
yaml_file,
"# This file was generated for {} using {}.\n# Please avoid making manual changes here.\n",
mod_prefix,
*PROGRAM_NAME_AND_VERSION,
)
}
fn _write_regions_count_comment(yaml_file: &mut File, regions_map_relative_path: &Path) -> std::io::Result<()> {
write!(
yaml_file,
r#"# Number of separately controllable dynamic terrain regions.
# Corresponds to the number of distinct 16bit pixel RG values in {},
# starting from R channel for the least significant 8 bits.
"#,
regions_map_relative_path.display(),
)
}
fn write_region_title_indices_comment(yaml_file: &mut File, regions_map_relative_path: &Path) -> std::io::Result<()> {
write!(
yaml_file,
r#"# The following region title indices were generated along with {}
# and correspond to the 16 bits of pixel RG values in that texture file,
# starting from R channel for the least significant 8 bits.
"#,
regions_map_relative_path.display(),
)
}