use crate::*;
use ayaka_bindings_types::VarMap;
use fallback::Fallback;
use serde::Deserialize;
use std::collections::HashMap;
#[derive(Debug, Deserialize)]
pub struct Paragraph {
pub tag: String,
pub title: Option<String>,
pub texts: Vec<Line>,
pub next: Option<Text>,
}
#[derive(Debug, Default, Deserialize)]
pub struct GameConfig {
pub title: String,
#[serde(default)]
pub author: String,
pub paras: String,
pub start: String,
#[serde(default)]
pub plugins: PluginConfig,
#[serde(default)]
pub props: HashMap<String, String>,
pub res: Option<String>,
pub base_lang: Locale,
}
#[derive(Debug, Default, Deserialize)]
pub struct PluginConfig {
pub dir: String,
#[serde(default)]
pub modules: Vec<String>,
}
pub struct Game {
pub config: GameConfig,
pub paras: HashMap<Locale, HashMap<String, Vec<Paragraph>>>,
pub res: HashMap<Locale, VarMap>,
}
impl Game {
pub fn start_context(&self) -> RawContext {
RawContext {
cur_base_para: self.config.start.clone(),
cur_para: self.config.start.clone(),
..Default::default()
}
}
fn choose_from_keys<'a, V>(&'a self, loc: &Locale, map: &'a HashMap<Locale, V>) -> &'a Locale {
loc.choose_from(map.keys())
.unwrap_or(&self.config.base_lang)
}
pub fn find_para(&self, loc: &Locale, base_tag: &str, tag: &str) -> Option<&Paragraph> {
if let Some(paras) = self.paras.get(loc) {
if let Some(paras) = paras.get(base_tag) {
for p in paras.iter() {
if p.tag == tag {
return Some(p);
}
}
}
}
None
}
pub fn find_para_fallback(
&self,
loc: &Locale,
base_tag: &str,
tag: &str,
) -> Fallback<&Paragraph> {
let key = self.choose_from_keys(loc, &self.paras);
let base_key = self.choose_from_keys(&self.config.base_lang, &self.paras);
Fallback::new(
if key == base_key {
None
} else {
self.find_para(key, base_tag, tag)
},
self.find_para(base_key, base_tag, tag),
)
}
fn find_res(&self, loc: &Locale) -> Option<&VarMap> {
self.res.get(loc)
}
pub fn find_res_fallback(&self, loc: &Locale) -> Fallback<&VarMap> {
let key = self.choose_from_keys(loc, &self.res);
let base_key = self.choose_from_keys(&self.config.base_lang, &self.res);
Fallback::new(
if key == base_key {
None
} else {
self.find_res(key)
},
self.find_res(base_key),
)
}
}