diff --git a/src/colorize.rs b/src/colorize.rs index 4c107e6..0df3a7c 100644 --- a/src/colorize.rs +++ b/src/colorize.rs @@ -40,6 +40,8 @@ pub fn run( out_dir: &Path, lang: &str, damage_colors: DamageColors, + with_non_damage: bool, + with_class_names: bool, ) { let colors = color_map(dbs); @@ -63,7 +65,7 @@ pub fn run( continue; } let text = String::from_utf8_lossy(&record.data); - let (rewritten, colored) = recolor_file(&text, &colors, damage_colors); + let (rewritten, colored) = recolor_file(&text, &colors, damage_colors, with_non_damage, with_class_names); if colored == 0 { continue; } @@ -101,9 +103,12 @@ fn recolor_file( text: &str, colors: &HashMap, damage_colors: DamageColors, + with_non_damage: bool, + with_class_names: bool, ) -> (String, usize) { let mut out = String::with_capacity(text.len()); let mut colored = 0usize; + let mut class_values: Vec<(String, String)> = Vec::new(); for segment in text.split_inclusive('\n') { let (line, eol) = split_eol(segment); if let Some((tag, value)) = line.split_once('=') { @@ -128,6 +133,42 @@ fn recolor_file( out.push_str(eol); continue; } + if with_non_damage { + if let Some(color) = property::color_other_for(tag) + { + let new_value = apply_color(value, color); + if new_value != value { + colored += 1; + } + out.push_str(tag); + out.push('='); + out.push_str(&new_value); + out.push_str(eol); + continue; + } + } + if with_class_names { + if let Some((name, class_value)) = property::text_class(tag, value) { + // Save translated class name + class_values.push((name, class_value)); + out.push_str(tag); + out.push('='); + out.push_str(&value); + out.push_str(eol); + continue; + } + if let Some(suffix) = property::text_for(tag, &class_values) { + let new_value = format!("{value} {suffix}"); + if new_value != value { + colored += 1; + } + out.push_str(tag); + out.push('='); + out.push_str(&new_value); + out.push_str(eol); + continue; + } + } } out.push_str(segment); } diff --git a/src/palette.rs b/src/palette.rs index d7ce01a..22bca0b 100644 --- a/src/palette.rs +++ b/src/palette.rs @@ -19,6 +19,7 @@ pub const WHITE: char = 'w'; pub const YELLOW: char = 'y'; /// `10EB5D` pub const GREEN: char = 'g'; +pub const DARK_GREEN: char = 'x'; /// `F1E78C` pub const KHAKI: char = 'k'; /// `FF69B5` diff --git a/src/property.rs b/src/property.rs index 99d158e..69a562c 100644 --- a/src/property.rs +++ b/src/property.rs @@ -12,7 +12,7 @@ //! no element token and so are left untouched. use crate::palette::{ - AQUA, COBALT, CYAN, FUSHIA, KHAKI, MAROON, OLIVE, ORANGE, PURPLE, RED, YELLOW, + AQUA, COBALT, CYAN, FUSHIA, KHAKI, MAROON, OLIVE, ORANGE, PURPLE, RED, YELLOW, WHITE, DARK_GREEN, }; /// Structural prefixes that mark a damage / resistance / retaliation / @@ -104,3 +104,78 @@ pub fn color_for(tag: &str, damage_colors: DamageColors) -> Option { } Some(color) } + +const PREFIXES_OTHER: [&str; 4] = [ + "tagChar", + "tagDamageModifier", + "ItemMasteryIncrement", + "ItemAllSkillIncrement", +]; + +const TOKENS_OTHER: [(&str, char); 13] = [ + ("tagCharAttribute0", WHITE), + ("ItemMasteryIncrement", DARK_GREEN), + ("ItemAllSkillIncrement", DARK_GREEN), + ("tagCharRunSpeed", DARK_GREEN), + ("tagCharSpellCastSpeed", DARK_GREEN), + ("tagCharAttackSpeed", DARK_GREEN), + ("tagCharTotalSpeedModifier", DARK_GREEN), + ("tagCharRunSpeedModifier", DARK_GREEN), + ("tagCharOffensiveAbility", DARK_GREEN), + ("tagCharDefensiveAbility", DARK_GREEN), + ("tagDamageModifierCritDamage", DARK_GREEN), + ("tagDamageModifierDamageMult", DARK_GREEN), + ("tagDamageModifierTotalDamage", DARK_GREEN), +]; + +pub fn color_other_for(tag: &str) -> Option { + if !PREFIXES_OTHER.iter().any(|p| tag.starts_with(p)) { + return None; + } + let color = TOKENS_OTHER + .iter() + .find(|(tok, _)| tag.contains(tok)) + .map(|(_, color)| *color)?; + Some(color) +} + +const CLASSES: [&str; 4] = [ + "tagClass", + "tagGDX1Class", + "tagGDX2Class", + "tagGDX3Class", +]; + +pub fn text_class(tag: &str, value: &str) -> Option<(String, String)> { + match tag { + "tagSkillClassName01" => Some(("Class01Skill".to_string(), value.to_string())), + "tagSkillClassName02" => Some(("Class02Skill".to_string(), value.to_string())), + "tagSkillClassName03" => Some(("Class03Skill".to_string(), value.to_string())), + "tagSkillClassName04" => Some(("Class04Skill".to_string(), value.to_string())), + "tagSkillClassName05" => Some(("Class05Skill".to_string(), value.to_string())), + "tagSkillClassName06" => Some(("Class06Skill".to_string(), value.to_string())), + "tagSkillClassName07" => Some(("Class07Skill".to_string(), value.to_string())), + "tagSkillClassName08" => Some(("Class08Skill".to_string(), value.to_string())), + "tagSkillClassName09" => Some(("Class09Skill".to_string(), value.to_string())), + "tagSkillClassName10" => Some(("Class10Skill".to_string(), value.to_string())), + _ => None, + } +} + +pub fn text_for(tag: &str, class_values: &[(String, String)]) -> Option { + if !CLASSES.iter().any(|p| tag.starts_with(p)) { + return None; + } + if !tag.contains("Name") { + return None; + } + // This contains the class name, not a skill + if tag.contains("SkillName00A") { + return None; + } + let class = class_values + .iter() + .find(|(tok, _)| tag.contains(tok)) + .map(|(_, class)| class)?; + Some(format!("({class})")) +}