From b196c86e7baa70179d770503e67837a692ee2310 Mon Sep 17 00:00:00 2001 From: TCA166 Date: Thu, 16 May 2024 23:20:58 +0200 Subject: [PATCH] Localization semi finished --- src/localizer.rs | 108 ++++++++++++++++++++---------------- src/main.rs | 1 + src/structures/character.rs | 29 +++++++++- src/structures/culture.rs | 11 +++- src/structures/dynasty.rs | 58 ++++++++++++++----- src/structures/faith.rs | 15 +++-- src/structures/memory.rs | 1 + src/structures/title.rs | 4 +- templates/homeTemplate.html | 2 +- 9 files changed, 156 insertions(+), 73 deletions(-) diff --git a/src/localizer.rs b/src/localizer.rs index 3e143a7..623338c 100644 --- a/src/localizer.rs +++ b/src/localizer.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use std::{fs, mem}; -use std::path::Path; +use std::path::{Path, PathBuf}; use crate::game_object::GameString; use crate::types::Wrapper; @@ -30,59 +30,73 @@ impl Localizer{ let mut data: HashMap = HashMap::new(); let path = Path::new(&path); if path.is_dir() { - if let Ok(entries) = fs::read_dir(path) { - for entry in entries { - if let Ok(entry) = entry { - //TODO check if the file has localization data we care about - if let Ok(file_type) = entry.file_type() { - if file_type.is_file() && entry.file_name().to_str().unwrap().ends_with(".yml"){ - // read the file to string - let contents = fs::read_to_string(entry.path()).unwrap(); - //The thing here is that these 'yaml' files are... peculiar. rust_yaml doesn't seem to be able to parse them correctly - //so we doing the thing ourselves :) + // a stack to keep track of the directories + let mut stack: Vec = Vec::new(); + stack.push(PathBuf::from(path)); + // a vector to keep track of all the files + let mut all_files: Vec = Vec::new(); + while !stack.is_empty() { + let entry = stack.pop().unwrap(); + if let Ok(entries) = fs::read_dir(entry) { + for entry in entries { + if let Ok(entry) = entry { + if let Ok(file_type) = entry.file_type() { + if file_type.is_dir() { + stack.push(entry.path()); + } else if entry.file_name().to_str().unwrap().ends_with(".yml"){ + all_files.push(entry.path()); + } + } + } + } + } + } + // having gone through all the directories, we can now read the files + for entry in all_files { + // read the file to string + let contents = fs::read_to_string(entry).unwrap(); + //The thing here is that these 'yaml' files are... peculiar. rust_yaml doesn't seem to be able to parse them correctly + //so we doing the thing ourselves :) - //parse the 'yaml' file - let mut key = String::new(); - let mut value = String::new(); - let mut past = false; - let mut quotes = false; - for char in contents.chars(){ - match char{ - ' ' | '\t' => { - if quotes { - value.push(char); - } - }, - '\n' => { - if past && !quotes && !value.is_empty(){ - data.insert(mem::take(&mut key), GameString::wrap(mem::take(&mut value))); - } - past = false; - quotes = false; - } - ':' => { - past = true; - } - '"' => { - quotes = !quotes; - } - _ => { - if past { - if quotes { - value.push(char); - } - } else { - key.push(char); - } - } - } + //parse the 'yaml' file + let mut key = String::new(); + let mut value = String::new(); + let mut past = false; + let mut quotes = false; + for char in contents.chars(){ + match char{ + ' ' | '\t' => { + if quotes { + value.push(char); + } + }, + '\n' => { + if past && !quotes && !value.is_empty(){ + data.insert(mem::take(&mut key), GameString::wrap(mem::take(&mut value))); + } + past = false; + quotes = false; + } + ':' => { + past = true; + } + '"' => { + quotes = !quotes; + } + _ => { + if past { + if quotes { + value.push(char); } + } else { + key.push(char); } } } } - hmap = Some(data); } + //TODO resolve the localization functions + hmap = Some(data); } } Localizer{ diff --git a/src/main.rs b/src/main.rs index 3d7515a..6311436 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod game_object; mod save_file; use save_file::SaveFile; +/// A submodule handling game localization. mod localizer; use localizer::Localizer; diff --git a/src/structures/character.rs b/src/structures/character.rs index 16e63dd..2f4ff71 100644 --- a/src/structures/character.rs +++ b/src/structures/character.rs @@ -41,6 +41,8 @@ pub struct Character { depth: usize } +//TODO some characters are stored within history files. Will need to parse those too godamit + // So both faith and culture can be stored for a character in the latest leader of their house. // The problem with reading that now is that while Houses are already likely loaded, // the characters that the houses hold reference to are likely still dummy, so we can't read the faith and culture from the house leader. @@ -410,8 +412,7 @@ impl GameObjectDerived for Character { fn get_name(&self) -> GameString { if self.name.is_none(){ - //FIXME wtf? - return GameString::wrap("".to_string()) + return GameString::wrap("Unknown".to_string()) } self.name.as_ref().unwrap().clone() } @@ -544,10 +545,32 @@ impl Renderable for Character { impl Cullable for Character { fn set_depth(&mut self, depth:usize, localization:&Localizer) { + { // localization + if self.name.is_none() { + self.name = Some(GameString::wrap("Unknown".to_string())); + } + else{ + self.name = Some(localization.localize(self.name.as_ref().unwrap().as_str())); + } + if self.nick.is_some(){ + self.nick = Some(localization.localize(self.nick.as_ref().unwrap().as_str())); + } + if self.reason.is_some(){ + self.reason = Some(localization.localize(self.reason.as_ref().unwrap().as_str())); + } + for t in self.traits.iter_mut(){ + *t = localization.localize(t.as_str()); + } + for t in self.recessive.iter_mut(){ + *t = localization.localize(t.as_str()); + } + for t in self.languages.iter_mut(){ + *t = localization.localize(t.as_str()); + } + } if depth <= self.depth || depth == 0 { return; } - //TODO localize self.depth = depth; for s in self.spouses.iter(){ let o = s.try_get_internal_mut(); diff --git a/src/structures/culture.rs b/src/structures/culture.rs index c1266a3..145f0ec 100644 --- a/src/structures/culture.rs +++ b/src/structures/culture.rs @@ -154,10 +154,19 @@ impl Cullable for Culture { } fn set_depth(&mut self, depth:usize, localization:&Localizer) { + { //localization + self.name = localization.localize(self.name.as_str()); + self.ethos = localization.localize(self.ethos.as_str()); + self.heritage = localization.localize(self.heritage.as_str()); + self.martial = localization.localize(self.martial.as_str()); + self.language = localization.localize(self.language.as_str()); + for t in &mut self.traditions{ + *t = localization.localize(t.as_str()); + } + } if depth <= self.depth || depth == 0{ return; } - //TODO localize self.depth = depth; for p in &self.parents{ p.get_internal_mut().set_depth(depth-1, localization); diff --git a/src/structures/dynasty.rs b/src/structures/dynasty.rs index ef86e9a..9fec3f8 100644 --- a/src/structures/dynasty.rs +++ b/src/structures/dynasty.rs @@ -23,6 +23,8 @@ pub struct Dynasty{ depth: usize } +//TODO it's possible that dynasties sometimes are stored within history files like characters + impl Dynasty { /// Gets the faith of the dynasty. /// Really this is just the faith of the current house leader. @@ -72,6 +74,20 @@ fn get_perks(perks:&mut Vec<(GameString, u8)>, base:&GameObject){ if key.is_none(){ continue; } + let mut added = false; + for perk in perks.iter_mut(){ + if perk.0.as_str() == key.unwrap(){ + if perk.1 < val{ + perk.1 = val; + } + added = true; + break; + } + } + if added{ + continue; + } + //if the perk is not found, add it perks.push((GameString::wrap(key.unwrap().to_owned()), val)); } } @@ -134,20 +150,24 @@ fn get_parent(base:&GameObject, game_state:&mut GameState) -> Option>) -> GameString{ +fn get_name(base:&GameObject, parent:Option>) -> Option{ let mut n = base.get("name"); if n.is_none(){ n = base.get("localized_name"); if n.is_none(){ if parent.is_none(){ - //TODO this happens for dynasties that exist at game start. WTF? - return GameString::wrap("".to_owned().into()); + //println!("{:?}", base); + return None; + } + let p = parent.as_ref().unwrap().get_internal(); + if p.name.is_none(){ + return None; } //this may happen for dynasties with a house with the same name - return parent.unwrap().get_internal().name.as_ref().unwrap().clone(); + return Some(p.name.as_ref().unwrap().clone()); } } - n.unwrap().as_string() + Some(n.unwrap().as_string()) } fn get_date(base:&GameObject) -> Option{ @@ -169,7 +189,7 @@ impl GameObjectDerived for Dynasty { let res = get_prestige(&base); let p = get_parent(&base, game_state); Dynasty{ - name: Some(get_name(&base, p.clone())), + name: get_name(&base, p.clone()), parent: p, members: 0, houses: 0, @@ -185,7 +205,7 @@ impl GameObjectDerived for Dynasty { fn dummy(id:GameId) -> Self { Dynasty{ - name: Some(GameString::wrap("".to_owned())), + name: None, parent: None, members: 0, houses: 0, @@ -209,8 +229,8 @@ impl GameObjectDerived for Dynasty { } self.parent = get_parent(&base, game_state); let name = get_name(&base, self.parent.clone()); - if !name.is_empty() || self.name.is_none(){ - self.name = Some(name); + if self.name.is_none() { + self.name = name; } self.found_date = get_date(&base); } @@ -220,6 +240,9 @@ impl GameObjectDerived for Dynasty { } fn get_name(&self) -> GameString { + if self.name.is_none(){ + return GameString::wrap("Unknown".to_owned()); + } self.name.as_ref().unwrap().clone() } } @@ -273,14 +296,21 @@ impl Renderable for Dynasty { impl Cullable for Dynasty { fn set_depth(&mut self, depth:usize, localization:&Localizer) { + //TODO deal with weird name chicanery + { //localization + for perk in self.perks.iter_mut(){ + perk.0 = localization.localize(perk.0.as_str()); + } + if self.name.is_some() { + self.name = Some(localization.localize(self.name.as_ref().unwrap().as_str())); + } + else{ + self.name = Some(GameString::wrap("Unknown".to_owned())); + } + } if depth <= self.depth || depth == 0 { return; } - //localize the keys - for perk in self.perks.iter_mut(){ - perk.0 = localization.localize(perk.0.as_str()); - } - self.name = Some(localization.localize(self.name.as_ref().unwrap().as_str())); self.depth = depth; for leader in self.leaders.iter(){ let o = leader.try_get_internal_mut(); diff --git a/src/structures/faith.rs b/src/structures/faith.rs index ad8898c..178797b 100644 --- a/src/structures/faith.rs +++ b/src/structures/faith.rs @@ -155,15 +155,18 @@ impl Cullable for Faith { } fn set_depth(&mut self, depth: usize, localization:&Localizer) { + { //localization + self.name = Some(localization.localize(self.name.as_ref().unwrap().as_str())); + for tenet in self.tenets.iter_mut(){ + *tenet = localization.localize(tenet.as_str()); + } + for doctrine in self.doctrines.iter_mut(){ + *doctrine = localization.localize(doctrine.as_str()); + } + } if depth <= self.depth || depth == 0{ return; } - for tenet in self.tenets.iter_mut(){ - *tenet = localization.localize(tenet.as_str()); - } - for doctrine in self.doctrines.iter_mut(){ - *doctrine = localization.localize(doctrine.as_str()); - } self.depth = depth; if self.head.is_some(){ let o = self.head.as_ref().unwrap().try_get_internal_mut(); diff --git a/src/structures/memory.rs b/src/structures/memory.rs index 3469644..2f179c5 100644 --- a/src/structures/memory.rs +++ b/src/structures/memory.rs @@ -89,6 +89,7 @@ impl Cullable for Memory { self.r#type = Some(localization.localize(&self.r#type.as_ref().unwrap())); self.depth = depth; for part in self.participants.iter_mut(){ + part.0 = localization.localize(&part.0).to_string(); let o = part.1.try_get_internal_mut(); if o.is_ok(){ o.unwrap().set_depth(depth - 1, localization); diff --git a/src/structures/title.rs b/src/structures/title.rs index 7923b1c..4114768 100644 --- a/src/structures/title.rs +++ b/src/structures/title.rs @@ -274,10 +274,12 @@ impl Renderable for Title { impl Cullable for Title { fn set_depth(&mut self, depth:usize, localization:&Localizer) { + { //localization + self.name = Some(localization.localize(self.key.as_ref().unwrap().as_str())); + } if depth <= self.depth || depth == 0{ return; } - self.name = Some(localization.localize(self.key.as_ref().unwrap().as_str())); self.depth = depth; if self.de_jure.is_some(){ let c = self.de_jure.as_ref().unwrap().try_get_internal_mut(); diff --git a/templates/homeTemplate.html b/templates/homeTemplate.html index fb8ed6d..a1980c3 100644 --- a/templates/homeTemplate.html +++ b/templates/homeTemplate.html @@ -28,7 +28,7 @@
{{node.character.name}} {{node.character.nick if node.cha {% if node.lifestyle != none %}
  • Reached a score of: {{node.score}}
  • Had a keen interest in {{node.lifestyle}}
  • -
  • {% if node.perks|length != 0%}Was a: {%for perk in node.perks%}{{perk}}, {%endfor%} {%else%}Didn't master a specific field{%endif%}
  • +
  • {% if node.perks|length != 0%}Was a: {%for perk in node.perks%}{{perk}} {%endfor%}{%else%}Didn't master a specific field{%endif%}
  • {% else %}
  • This character has yet to prove himself.
  • {% endif %}