Skip to content

Commit

Permalink
Localization semi finished
Browse files Browse the repository at this point in the history
  • Loading branch information
TCA166 committed May 16, 2024
1 parent 69ddb04 commit b196c86
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 73 deletions.
108 changes: 61 additions & 47 deletions src/localizer.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -30,59 +30,73 @@ impl Localizer{
let mut data: HashMap<String, GameString> = 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<PathBuf> = Vec::new();
stack.push(PathBuf::from(path));
// a vector to keep track of all the files
let mut all_files: Vec<PathBuf> = 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{
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod game_object;
mod save_file;
use save_file::SaveFile;

/// A submodule handling game localization.
mod localizer;
use localizer::Localizer;

Expand Down
29 changes: 26 additions & 3 deletions src/structures/character.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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()
}
Expand Down Expand Up @@ -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();
Expand Down
11 changes: 10 additions & 1 deletion src/structures/culture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
58 changes: 44 additions & 14 deletions src/structures/dynasty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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));
}
}
Expand Down Expand Up @@ -134,20 +150,24 @@ fn get_parent(base:&GameObject, game_state:&mut GameState) -> Option<Shared<Dyna
}
}

fn get_name(base:&GameObject, parent:Option<Shared<Dynasty>>) -> GameString{
fn get_name(base:&GameObject, parent:Option<Shared<Dynasty>>) -> Option<GameString>{
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<GameString>{
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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);
}
Expand All @@ -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()
}
}
Expand Down Expand Up @@ -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();
Expand Down
15 changes: 9 additions & 6 deletions src/structures/faith.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions src/structures/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion src/structures/title.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion templates/homeTemplate.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ <h5 class="card-title">{{node.character.name}} {{node.character.nick if node.cha
{% if node.lifestyle != none %}
<li class="list-group-item">Reached a score of: {{node.score}}</li>
<li class="list-group-item">Had a keen interest in {{node.lifestyle}}</li>
<li class="list-group-item">{% if node.perks|length != 0%}Was a: {%for perk in node.perks%}{{perk}}, {%endfor%} {%else%}Didn't master a specific field{%endif%}</li>
<li class="list-group-item">{% if node.perks|length != 0%}Was a: {%for perk in node.perks%}{{perk}} {%endfor%}{%else%}Didn't master a specific field{%endif%}</li>
{% else %}
<li class="list-group-item">This character has yet to prove himself.</li>
{% endif %}
Expand Down

0 comments on commit b196c86

Please sign in to comment.