diff --git a/assets/voxygen/i18n/de_DE.ron b/assets/voxygen/i18n/de_DE.ron index d50d454d33..c01de37556 100644 --- a/assets/voxygen/i18n/de_DE.ron +++ b/assets/voxygen/i18n/de_DE.ron @@ -160,7 +160,7 @@ https://account.veloren.net. // Chat outputs "hud.chat.online_msg": "[{name}] ist jetzt online.", - "hud.chat.offline_msg": "{name} ist jetzt offline.", + "hud.chat.offline_msg": "[{name}] ist jetzt offline.", "hud.chat.loot_msg": "Ihr erhaltet [{item}]", "hud.chat.loot_fail": "Euer Inventar ist voll!", "hud.chat.goodbye": "Verbindung getrennt.", diff --git a/assets/voxygen/i18n/en.ron b/assets/voxygen/i18n/en.ron index eaf7366f07..cee8bdb3d9 100644 --- a/assets/voxygen/i18n/en.ron +++ b/assets/voxygen/i18n/en.ron @@ -159,8 +159,22 @@ https://account.veloren.net."#, "hud.press_key_to_toggle_debug_info_fmt": "Press {key} to toggle debug info", // Chat outputs - "hud.chat.online_msg": "[{name}] joined.", - "hud.chat.offline_msg": "{name} went offline.", + "hud.chat.online_msg": "[{name}] came online", + "hud.chat.offline_msg": "[{name}] went offline", + + "hud.chat.default_death_msg": "[{name}] died", + "hud.chat.environmental_kill_msg": "[{name}] died in {environment}", + "hud.chat.fall_kill_msg": "[{name}] died from fall damage", + "hud.chat.suicide_msg": "[{name}] died from self-inflicted wounds", + + "hud.chat.pvp_melee_kill_msg": "[{attacker}] killed [{victim}]", + "hud.chat.pvp_ranged_kill_msg": "[{attacker}] shot [{victim}]", + "hud.chat.pvp_explosion_kill_msg": "[{attacker}] blew up [{victim}]", + + "hud.chat.npc_melee_kill_msg": "{attacker} killed [{victim}]", + "hud.chat.npc_ranged_kill_msg": "{attacker} shot [{victim}]", + "hud.chat.npc_explosion_kill_msg": "{attacker} blew up [{victim}]", + "hud.chat.loot_msg": "You picked up [{item}]", "hud.chat.loot_fail": "Your Inventory is full!", "hud.chat.goodbye": "Goodbye!", diff --git a/assets/voxygen/i18n/es_la.ron b/assets/voxygen/i18n/es_la.ron index 8bb8f04c9b..fe42e6c20b 100644 --- a/assets/voxygen/i18n/es_la.ron +++ b/assets/voxygen/i18n/es_la.ron @@ -156,7 +156,7 @@ https://account.veloren.net."#, // Chat outputs "hud.chat.online_msg": "[{name}] se ha conectado.", - "hud.chat.offline_msg": "{name} se ha desconectado.", + "hud.chat.offline_msg": "[{name}] se ha desconectado.", "hud.chat.loot_msg": "Recogiste [{item}]", "hud.chat.loot_fail": "Tu inventario está lleno!", "hud.chat.goodbye": "Adiós!", diff --git a/assets/voxygen/i18n/fr_FR.ron b/assets/voxygen/i18n/fr_FR.ron index 0a0ea98d9d..93e1747c81 100644 --- a/assets/voxygen/i18n/fr_FR.ron +++ b/assets/voxygen/i18n/fr_FR.ron @@ -140,7 +140,7 @@ https://account.veloren.net."#, // Sorties Tchat "hud.chat.online_msg": "[{name}] est maintenant en ligne.", - "hud.chat.offline_msg": "{name} s'est déconnecté.", + "hud.chat.offline_msg": "[{name}] s'est déconnecté.", "hud.chat.loot_msg": "Vous avez ramassé [{item}]", "hud.chat.loot_fail": "Votre inventaire est plein!", "hud.chat.goodbye": "Au revoir!", diff --git a/assets/voxygen/i18n/it_IT.ron b/assets/voxygen/i18n/it_IT.ron index bcefb59a0e..eda74021df 100644 --- a/assets/voxygen/i18n/it_IT.ron +++ b/assets/voxygen/i18n/it_IT.ron @@ -207,7 +207,7 @@ https://account.veloren.net."#, // Chat outputs "hud.chat.online_msg": "[{name}] è ora online.", - "hud.chat.offline_msg": "{name} è andato offline.", + "hud.chat.offline_msg": "[{name}] è andato offline.", "hud.chat.loot_msg": "Hai raccolto [{item}]", "hud.chat.loot_fail": "Il tuo inventario è pieno!", "hud.chat.goodbye": "Addio!", diff --git a/assets/voxygen/i18n/pt_BR.ron b/assets/voxygen/i18n/pt_BR.ron index 453916c477..c6e17458c6 100644 --- a/assets/voxygen/i18n/pt_BR.ron +++ b/assets/voxygen/i18n/pt_BR.ron @@ -142,7 +142,7 @@ https://account.veloren.net."#, // Chat outputs "hud.chat.online_msg": "[{name}] está online.", - "hud.chat.offline_msg": "{name} está offline.", + "hud.chat.offline_msg": "[{name}] está offline.", "hud.chat.loot_msg": "Você pegou [{item}]", "hud.chat.loot_fail": "Seu Inventário está cheio!", "hud.chat.goodbye": "Tchau!", diff --git a/assets/voxygen/i18n/ru_RU.ron b/assets/voxygen/i18n/ru_RU.ron index 9531cecd5a..33155586b7 100644 --- a/assets/voxygen/i18n/ru_RU.ron +++ b/assets/voxygen/i18n/ru_RU.ron @@ -144,7 +144,7 @@ https://account.veloren.net."#, // Chat outputs "hud.chat.online_msg": "[{name}] сейчас онлайн.", - "hud.chat.offline_msg": "{name} сейчас оффлайн.", + "hud.chat.offline_msg": "[{name}] сейчас оффлайн.", "hud.chat.loot_msg": "Вы подобрали [{item}]", "hud.chat.loot_fail": "Ваш инвентарь полон!", "hud.chat.goodbye": "До встречи!", diff --git a/assets/voxygen/i18n/tr_TR.ron b/assets/voxygen/i18n/tr_TR.ron index a0e3a6ab0c..5e8f59cf3d 100644 --- a/assets/voxygen/i18n/tr_TR.ron +++ b/assets/voxygen/i18n/tr_TR.ron @@ -162,7 +162,7 @@ bir hesap oluşturabilirsin."#, // Chat outputs "hud.chat.online_msg": "[{name}] çevrimiçi oldu.", - "hud.chat.offline_msg": "{name} çevrimdışı oldu.", + "hud.chat.offline_msg": "[{name}] çevrimdışı oldu.", "hud.chat.loot_msg": "[{item}] topladın.", "hud.chat.loot_fail": "Envanterin dolu!", "hud.chat.goodbye": "Hoşçakal!", diff --git a/assets/voxygen/i18n/zh_CN.ron b/assets/voxygen/i18n/zh_CN.ron index a38c6470b1..cff7e2e9e9 100644 --- a/assets/voxygen/i18n/zh_CN.ron +++ b/assets/voxygen/i18n/zh_CN.ron @@ -159,7 +159,7 @@ https://account.veloren.net."#, // Chat outputs "hud.chat.online_msg": "[{name}] 正在线上.", - "hud.chat.offline_msg": "{name} 下线了.", + "hud.chat.offline_msg": "[{name}] 下线了.", "hud.chat.loot_msg": "你捡起了 [{item}]", "hud.chat.loot_fail": "你的背包已满!", "hud.chat.goodbye": "再见!", diff --git a/client/src/lib.rs b/client/src/lib.rs index 874515ec3a..3583b8650e 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1605,43 +1605,42 @@ impl Client { } }; match chat_type { - comp::ChatType::Online(uid) => format!("{} joined", alias_of_uid(uid)), - comp::ChatType::Offline(uid) => format!("{} left", alias_of_uid(uid)), + // For ChatType::{Online, Offline, Kill} these message strings are localized + // in voxygen/src/hud/chat.rs before being formatted here. + // Kill messages are generated in server/src/events/entity_manipulation.rs + // fn handle_destroy + comp::ChatType::Online(uid) => message.replace("{name}", &alias_of_uid(uid)), + comp::ChatType::Offline(uid) => message.replace("{name}", &alias_of_uid(uid)), comp::ChatType::CommandError => message.to_string(), comp::ChatType::CommandInfo => message.to_string(), comp::ChatType::Loot => message.to_string(), comp::ChatType::FactionMeta(_) => message.to_string(), comp::ChatType::GroupMeta(_) => message.to_string(), - comp::ChatType::Kill(kill_source, victim) => { - // TODO: Localize - match kill_source { - KillSource::Player(attacker_uid, KillType::Melee) => format!( - "{} killed {}", - alias_of_uid(attacker_uid), - alias_of_uid(victim) - ), - KillSource::Player(attacker_uid, KillType::Projectile) => format!( - "{} shot {}", - alias_of_uid(attacker_uid), - alias_of_uid(victim) - ), - KillSource::NonPlayer(attacker_name, KillType::Melee) => { - format!("[{}] killed {}", attacker_name, alias_of_uid(victim)) - }, - KillSource::NonPlayer(attacker_name, KillType::Projectile) => { - format!("[{}] shot {}", attacker_name, alias_of_uid(victim)) - }, - KillSource::Environment(environment) => { - format!("{} died in [{}]", alias_of_uid(victim), environment) - }, - KillSource::FallDamage => { - format!("{} died from fall damage", alias_of_uid(victim)) - }, - KillSource::Suicide => { - format!("{} died from self-inflicted wounds", alias_of_uid(victim)) - }, - KillSource::Other => format!("{} died", alias_of_uid(victim)), - } + comp::ChatType::Kill(kill_source, victim) => match kill_source { + KillSource::Player(attacker_uid, KillType::Melee) => message + .replace("{attacker}", &alias_of_uid(attacker_uid)) + .replace("{victim}", &alias_of_uid(victim)), + KillSource::Player(attacker_uid, KillType::Projectile) => message + .replace("{attacker}", &alias_of_uid(attacker_uid)) + .replace("{victim}", &alias_of_uid(victim)), + KillSource::Player(attacker_uid, KillType::Explosion) => message + .replace("{attacker}", &alias_of_uid(attacker_uid)) + .replace("{victim}", &alias_of_uid(victim)), + KillSource::NonPlayer(attacker_name, KillType::Melee) => message + .replace("{attacker}", attacker_name) + .replace("{victim}", &alias_of_uid(victim)), + KillSource::NonPlayer(attacker_name, KillType::Projectile) => message + .replace("{attacker}", attacker_name) + .replace("{victim}", &alias_of_uid(victim)), + KillSource::NonPlayer(attacker_name, KillType::Explosion) => message + .replace("{attacker}", attacker_name) + .replace("{victim}", &alias_of_uid(victim)), + KillSource::Environment(environment) => message + .replace("{name}", &alias_of_uid(victim)) + .replace("{environment}", environment), + KillSource::FallDamage => message.replace("{name}", &alias_of_uid(victim)), + KillSource::Suicide => message.replace("{name}", &alias_of_uid(victim)), + KillSource::Other => message.replace("{name}", &alias_of_uid(victim)), }, comp::ChatType::Tell(from, to) => { let from_alias = alias_of_uid(from); diff --git a/common/src/comp/chat.rs b/common/src/comp/chat.rs index 067b5caa54..613f9f38e2 100644 --- a/common/src/comp/chat.rs +++ b/common/src/comp/chat.rs @@ -49,6 +49,7 @@ impl Default for ChatMode { pub enum KillType { Melee, Projectile, + Explosion, // Projectile(String), TODO: add projectile name when available } diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs index 0f9dd9f470..2c8faf0e4b 100644 --- a/common/src/comp/stats.rs +++ b/common/src/comp/stats.rs @@ -18,6 +18,7 @@ pub struct HealthChange { pub enum HealthSource { Attack { by: Uid }, // TODO: Implement weapon Projectile { owner: Option }, + Explosion { owner: Option }, Suicide, World, Revive, diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 105df321fa..18245f77bb 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -76,10 +76,10 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc { KillSource::NonPlayer(stats.name.clone(), KillType::Melee) } else { - KillSource::NonPlayer("Unknown".to_string(), KillType::Melee) + KillSource::NonPlayer("".to_string(), KillType::Melee) } } else { - KillSource::NonPlayer("Unknown".to_string(), KillType::Melee) + KillSource::NonPlayer("".to_string(), KillType::Melee) } }, HealthSource::Projectile { owner: Some(by) } => { @@ -99,15 +99,38 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc { KillSource::NonPlayer(stats.name.clone(), KillType::Projectile) } else { - KillSource::NonPlayer("Unknown".to_string(), KillType::Projectile) + KillSource::NonPlayer("".to_string(), KillType::Projectile) } } else { - KillSource::NonPlayer("Unknown".to_string(), KillType::Projectile) + KillSource::NonPlayer("".to_string(), KillType::Projectile) + } + }, + HealthSource::Explosion { owner: Some(by) } => { + // Get explosion owner entity + if let Some(char_entity) = state.ecs().entity_from_uid(by.into()) { + // Check if attacker is another player or entity with stats (npc) + if state + .ecs() + .read_storage::() + .get(char_entity) + .is_some() + { + KillSource::Player(by, KillType::Explosion) + } else if let Some(stats) = + state.ecs().read_storage::().get(char_entity) + { + KillSource::NonPlayer(stats.name.clone(), KillType::Explosion) + } else { + KillSource::NonPlayer("".to_string(), KillType::Explosion) + } + } else { + KillSource::NonPlayer("".to_string(), KillType::Explosion) } }, HealthSource::World => KillSource::FallDamage, HealthSource::Suicide => KillSource::Suicide, HealthSource::Projectile { owner: None } + | HealthSource::Explosion { owner: None } | HealthSource::Revive | HealthSource::Command | HealthSource::LevelUp @@ -472,7 +495,7 @@ pub fn handle_explosion( stats_b.health.change_by(HealthChange { amount: damage.healthchange as i32, - cause: HealthSource::Projectile { owner }, + cause: HealthSource::Explosion { owner }, }); } } diff --git a/voxygen/src/hud/chat.rs b/voxygen/src/hud/chat.rs index c2074056e6..20baed4b9f 100644 --- a/voxygen/src/hud/chat.rs +++ b/voxygen/src/hud/chat.rs @@ -2,10 +2,13 @@ use super::{ img_ids::Imgs, ERROR_COLOR, FACTION_COLOR, GROUP_COLOR, INFO_COLOR, KILL_COLOR, LOOT_COLOR, OFFLINE_COLOR, ONLINE_COLOR, REGION_COLOR, SAY_COLOR, TELL_COLOR, TEXT_COLOR, WORLD_COLOR, }; -use crate::{ui::fonts::ConrodVoxygenFonts, GlobalState}; +use crate::{i18n::VoxygenLocalization, ui::fonts::ConrodVoxygenFonts, GlobalState}; use client::{cmd, Client}; use common::{ - comp::{ChatMsg, ChatType}, + comp::{ + chat::{KillSource, KillType}, + ChatMsg, ChatType, + }, msg::validate_chat_msg, }; use conrod_core::{ @@ -56,6 +59,8 @@ pub struct Chat<'a> { // TODO: add an option to adjust this history_max: usize, + + localized_strings: &'a std::sync::Arc, } impl<'a> Chat<'a> { @@ -65,6 +70,7 @@ impl<'a> Chat<'a> { global_state: &'a GlobalState, imgs: &'a Imgs, fonts: &'a ConrodVoxygenFonts, + localized_strings: &'a std::sync::Arc, ) -> Self { Self { new_messages, @@ -77,6 +83,7 @@ impl<'a> Chat<'a> { global_state, common: widget::CommonBuilder::default(), history_max: 32, + localized_strings, } } @@ -333,9 +340,67 @@ impl<'a> Widget for Chat<'a> { while let Some(item) = items.next(ui) { // This would be easier if conrod used the v-metrics from rusttype. if item.i < state.messages.len() { - let message = &state.messages[item.i]; + let mut message = state.messages[item.i].clone(); let (color, icon) = render_chat_line(&message.chat_type, &self.imgs); - let msg = self.client.format_message(message, show_char_name); + let ChatMsg { chat_type, .. } = &message; + // For each ChatType needing localization get/set matching pre-formatted + // localized string. This string will be formatted with the data + // provided in ChatType in the client/src/lib.rs + // fn format_message called below + message.message = match chat_type { + ChatType::Online(_) => self + .localized_strings + .get("hud.chat.online_msg") + .to_string(), + ChatType::Offline(_) => self + .localized_strings + .get("hud.chat.offline_msg") + .to_string(), + ChatType::Kill(kill_source, _) => match kill_source { + KillSource::Player(_, KillType::Melee) => self + .localized_strings + .get("hud.chat.pvp_melee_kill_msg") + .to_string(), + KillSource::Player(_, KillType::Projectile) => self + .localized_strings + .get("hud.chat.pvp_ranged_kill_msg") + .to_string(), + KillSource::Player(_, KillType::Explosion) => self + .localized_strings + .get("hud.chat.pvp_explosion_kill_msg") + .to_string(), + KillSource::NonPlayer(_, KillType::Melee) => self + .localized_strings + .get("hud.chat.npc_melee_kill_msg") + .to_string(), + KillSource::NonPlayer(_, KillType::Projectile) => self + .localized_strings + .get("hud.chat.npc_ranged_kill_msg") + .to_string(), + KillSource::NonPlayer(_, KillType::Explosion) => self + .localized_strings + .get("hud.chat.npc_explosion_kill_msg") + .to_string(), + KillSource::Environment(_) => self + .localized_strings + .get("hud.chat.environmental_kill_msg") + .to_string(), + KillSource::FallDamage => self + .localized_strings + .get("hud.chat.fall_kill_msg") + .to_string(), + KillSource::Suicide => self + .localized_strings + .get("hud.chat.suicide_msg") + .to_string(), + KillSource::Other => self + .localized_strings + .get("hud.chat.default_death_msg") + .to_string(), + }, + _ => message.message, + }; + let msg = self.client.format_message(&message, show_char_name); let text = Text::new(&msg) .font_size(self.fonts.opensans.scale(15)) .font_id(self.fonts.opensans.conrod_id) diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 64324936e0..f705dcb116 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -1826,6 +1826,7 @@ impl Hud { global_state, &self.imgs, &self.fonts, + &self.voxygen_i18n, ) .and_then(self.force_chat_input.take(), |c, input| c.input(input)) .and_then(self.tab_complete.take(), |c, input| {