mod event_graph; mod templates; mod tsv_util; use std::{collections::HashMap, path::Path}; use anyhow::{bail, Result}; pub use event_graph::*; use paste::paste; pub use templates::*; use tokio::sync::OnceCell; macro_rules! template_collections { ($($template_type:ident;)*) => { $(paste! { static [<$template_type:snake:upper _COLLECTION>]: OnceCell]>> = OnceCell::const_new(); })* fn init_template_collections() -> Result<()> { $(paste! { let path = concat!("assets/TemplateCollections/", stringify!($template_type), "TemplateCollection.tsv"); let data = std::fs::read_to_string(path)?; [<$template_type:snake:upper _COLLECTION>].set(tsv_util::from_str(&data)?).unwrap(); })* Ok(()) } $(paste! { pub fn []() -> ::std::slice::Iter<'static, [<$template_type Template>]> { [<$template_type:snake:upper _COLLECTION>].get().unwrap().iter() } })* }; } template_collections! { AvatarConfig; UnlockConfig; MainCityObject; NPCTransform; } static EVENT_GRAPH_COLLECTION: OnceCell> = OnceCell::const_new(); fn init_binoutput() -> Result<()> { let _ = EVENT_GRAPH_COLLECTION.set(serde_json::from_str( std::fs::read_to_string("assets/BinOutput/EventGraphCollection.json")?.as_str(), )?); Ok(()) } pub fn init_assets() -> Result<()> { if !Path::new("assets/").exists() { bail!( "Assets directory not found! Make sure you have it in the same directory with executable." ) } init_template_collections()?; init_binoutput() } pub fn get_main_city_object(tag_id: i32, npc_id: i32) -> Option<&'static MainCityObjectTemplate> { iter_main_city_object_collection().find(|o| o.tag_id == tag_id && o.npc_id == npc_id) } pub fn is_transform_in_section(transform_id: &str, section_id: i32) -> bool { iter_n_p_c_transform_collection() .find(|t| t.id == transform_id) .map_or(false, |t| t.section == section_id) } pub fn get_event_graph(id: i32) -> Option<&'static ConfigEventGraph> { EVENT_GRAPH_COLLECTION.get().unwrap().get(&id) }