Merge branch 'juliancoffee/add_ability_i18n' into 'master'

Add i18n keys to abilities and smol fix

Closes #1253

See merge request veloren/veloren!3446
This commit is contained in:
Imbris 2022-06-26 19:50:04 +00:00
commit 10bbea89e2
10 changed files with 131 additions and 83 deletions

View File

@ -0,0 +1,35 @@
/// WARNING: Localization files shall be saved in UTF-8 format without BOM
/// Localization for "global" English
(
string_map: {
// Debug stick
"common.abilities.debug.possess.name": "Possessing Arrow",
"common.abilities.debug.possess.desc": "Shoots a poisonous arrow. Lets you control your target.",
// Sword
"common.abilities.sword.spin.name": "Whirlwind",
"common.abilities.sword.spin.desc": "Move forward while spinning with your sword.",
// Axe
"common.abilities.axe.leap.name": "Axe Jump",
"common.abilities.axe.leap.desc": "A jump with the slashing leap to position of cursor.",
// Hammer
"common.abilities.hammer.leap.name": "Smash of Doom",
"common.abilities.hammer.leap.desc": "An AOE attack with knockback. Leaps to position of cursor.",
// Bow
"common.abilities.bow.shotgun.name": "Burst",
"common.abilities.bow.shotgun.desc": "Launches a burst of arrows",
// Staff
"common.abilities.staff.fireshockwave.name": "Ring of Fire",
"common.abilities.staff.fireshockwave.desc": "Ignites the ground with fiery shockwave.",
// Sceptre
"common.abilities.sceptre.wardingaura.name": "Warding Aura",
"common.abilities.sceptre.wardingaura.desc": "Wards your allies against enemy attacks.",
// Unknown
"common.abilities.unknown.name": "Ability has no title",
"common.abilities.unknown.desc": "Ability has no description",
},
vector_map: {
}
)

View File

@ -0,0 +1,35 @@
/// WARNING: Localization files shall be saved in UTF-8 format without BOM
/// Localization for Ukrainian language
(
string_map: {
// Debug stick
"common.abilities.debug.possess.name": "Заклинаюча Стріла",
"common.abilities.debug.possess.desc": "Стріляє отруйною стрілою. Дає тобі контроль над ціллю.",
// Sword
"common.abilities.sword.spin.name": "Буревій",
"common.abilities.sword.spin.desc": "Рушай вперед кружляючи з мечем.",
// Axe
"common.abilities.axe.leap.name": "Стрибок Сокири",
"common.abilities.axe.leap.desc": "Стрибок з рубаним ударом, слідує за курсором.",
// Hammer
"common.abilities.hammer.leap.name": "Погром",
"common.abilities.hammer.leap.desc": "Атака по області. Стрибок спрямований за курсором.",
// Bow
"common.abilities.bow.shotgun.name": "Стріловик",
"common.abilities.bow.shotgun.desc": "Постріл купою стріл за раз.",
// Staff
"common.abilities.staff.fireshockwave.name": "Кільце Вогню",
"common.abilities.staff.fireshockwave.desc": "Підпалює землю вогненною ударною хвилєю.",
// Sceptre
"common.abilities.sceptre.wardingaura.name": "Захисна Аура",
"common.abilities.sceptre.wardingaura.desc": "Укріплює тебе і твоїх спільників силами природи на деякий час.",
// Unknown
"common.abilities.unknown.name": "Неназвана Здатність",
"common.abilities.unknown.desc": "Здатність без опису",
},
vector_map: {
}
)

View File

@ -80,17 +80,12 @@ struct Language {
impl Language { impl Language {
/// Get a localized text from the given key /// Get a localized text from the given key
pub fn get<'a>(&'a self, key: &'a str) -> Option<&str> { pub fn get(&self, key: &str) -> Option<&str> { self.string_map.get(key).map(String::as_str) }
self.string_map.get(key).map(String::as_str)
}
/// Get a variation of localized text from the given key /// Get a variation of localized text from the given key
/// ///
/// `index` should be a random number from `0` to `u16::max()` /// `index` should be a random number from `0` to `u16::max()`
/// pub fn get_variation(&self, key: &str, index: u16) -> Option<&str> {
/// If the key is not present in the localization object
/// then the key is returned.
pub fn get_variation<'a>(&'a self, key: &'a str, index: u16) -> Option<&str> {
self.vector_map.get(key).and_then(|v| { self.vector_map.get(key).and_then(|v| {
if v.is_empty() { if v.is_empty() {
None None
@ -163,19 +158,30 @@ pub struct LocalizationGuard {
pub type Localization = LocalizationGuard; pub type Localization = LocalizationGuard;
impl LocalizationGuard { impl LocalizationGuard {
/// Get a localized text from the given key
///
/// First lookup is done in the active language, second in
/// the fallback (if present).
pub fn get_opt<'a>(&'a self, key: &str) -> Option<&'a str> {
self.active
.get(key)
.or_else(|| self.fallback.as_ref().and_then(|f| f.get(key)))
}
/// Get a localized text from the given key /// Get a localized text from the given key
/// ///
/// First lookup is done in the active language, second in /// First lookup is done in the active language, second in
/// the fallback (if present). /// the fallback (if present).
/// If the key is not present in the localization object /// If the key is not present in the localization object
/// then the key is returned. /// then the key is returned.
pub fn get<'a>(&'a self, key: &'a str) -> &str { pub fn get<'a>(&'a self, key: &'a str) -> &str { self.get_opt(key).unwrap_or(key) }
self.active.get(key).unwrap_or_else(|| {
self.fallback /// Get a localized text from the given key
.as_ref() ///
.and_then(|f| f.get(key)) /// First lookup is done in the active language, second in
.unwrap_or(key) /// the fallback (if present).
}) pub fn get_or(&self, key: &str, fallback_key: &str) -> Option<&str> {
self.get_opt(key).or_else(|| self.get_opt(fallback_key))
} }
/// Get a variation of localized text from the given key /// Get a variation of localized text from the given key

View File

@ -425,9 +425,7 @@ impl<'a> Buttons<'a> {
text: widget::Id, text: widget::Id,
) { ) {
let key_layout = &self.global_state.window.key_layout; let key_layout = &self.global_state.window.key_layout;
let key_desc = key_mouse let key_desc = key_mouse.display_shortest(key_layout);
.display_shortened(key_layout)
.unwrap_or_else(|| key_mouse.display_string(key_layout));
//Create shadow //Create shadow
Text::new(&key_desc) Text::new(&key_desc)

View File

@ -835,7 +835,7 @@ impl<'a> Widget for Diary<'a> {
) )
.ability_id(Some(self.inventory)); .ability_id(Some(self.inventory));
let (ability_title, ability_desc) = if let Some(ability_id) = ability_id { let (ability_title, ability_desc) = if let Some(ability_id) = ability_id {
util::ability_description(ability_id) util::ability_description(ability_id, self.localized_strings)
} else { } else {
(Cow::Borrowed("Drag an ability here to use it."), "") (Cow::Borrowed("Drag an ability here to use it."), "")
}; };
@ -878,7 +878,7 @@ impl<'a> Widget for Diary<'a> {
] ]
.get(i) .get(i)
.and_then(|input| keys.get_binding(*input)) .and_then(|input| keys.get_binding(*input))
.map(|key| key.display_string(key_layout)) .map(|key| key.display_shortest(key_layout))
.unwrap_or_default(); .unwrap_or_default();
Text::new(&ability_key) Text::new(&ability_key)
@ -1033,7 +1033,7 @@ impl<'a> Widget for Diary<'a> {
.enumerate() .enumerate()
{ {
let (ability_title, ability_desc) = let (ability_title, ability_desc) =
util::ability_description(ability_id.unwrap_or("")); util::ability_description(ability_id.unwrap_or(""), self.localized_strings);
let (align_state, image_offsets) = if id_index < 6 { let (align_state, image_offsets) = if id_index < 6 {
(state.ids.sb_page_left_align, 120.0 * id_index as f64) (state.ids.sb_page_left_align, 120.0 * id_index as f64)

View File

@ -1425,11 +1425,7 @@ impl<'a> Widget for Map<'a> {
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.zoom_txt, ui); .set(state.ids.zoom_txt, ui);
Text::new( Text::new(&location_marker_binding.display_shortest(key_layout))
&location_marker_binding
.display_shortened(key_layout)
.unwrap_or_default(),
)
.right_from(state.ids.zoom_txt, 15.0) .right_from(state.ids.zoom_txt, 15.0)
.font_size(self.fonts.cyri.scale(14)) .font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)

View File

@ -134,7 +134,7 @@ impl<'a> Widget for Controls<'a> {
format!( format!(
"{} {}", "{} {}",
key.display_string(key_layout), key.display_string(key_layout),
key.display_shortened(key_layout) key.try_shortened(key_layout)
.map_or("".to_owned(), |short| format!("({})", short)) .map_or("".to_owned(), |short| format!("({})", short))
), ),
if controls.has_conflicting_bindings(key) { if controls.has_conflicting_bindings(key) {

View File

@ -612,7 +612,7 @@ impl<'a> Skillbar<'a> {
.get(i) .get(i)
.and_then(|a| Ability::from(*a).ability_id(Some(inventory))) .and_then(|a| Ability::from(*a).ability_id(Some(inventory)))
}) })
.map(util::ability_description), .map(|id| util::ability_description(id, self.localized_strings)),
}) })
}; };
@ -655,9 +655,7 @@ impl<'a> Skillbar<'a> {
let position_bg = entry.shortcut_position_bg; let position_bg = entry.shortcut_position_bg;
let (id, id_bg) = entry.shortcut_widget_ids; let (id, id_bg) = entry.shortcut_widget_ids;
let key_desc = key let key_desc = key.display_shortest(key_layout);
.display_shortened(key_layout)
.unwrap_or_else(|| key.display_string(key_layout));
// shortcut text // shortcut text
Text::new(&key_desc) Text::new(&key_desc)
.position(position) .position(position)

View File

@ -356,48 +356,20 @@ pub fn ability_image(imgs: &img_ids::Imgs, ability_id: &str) -> image::Id {
} }
} }
#[rustfmt::skip] pub fn ability_description<'a>(
pub fn ability_description(ability_id: &str) -> (Cow<str>, &str) { ability_id: &'a str,
let (name, desc) = match ability_id { loc: &'a i18n::Localization,
// Debug stick ) -> (Cow<'a, str>, &'a str) {
"common.abilities.debug.possess" => ( let (name, desc) = (
"Possessing Arrow", format!("{}.name", ability_id),
"Shoots a poisonous arrow. Lets you control your target.", format!("{}.desc", ability_id),
);
(
Cow::Borrowed(
loc.get_or(&name, "common.abilities.unknown.name")
.unwrap_or(ability_id),
), ),
// Sword loc.get_or(&desc, "common.abilities.unknown.desc")
"common.abilities.sword.spin" => ( .unwrap_or(ability_id),
"Whirlwind", )
"Move forward while spinning with your sword.",
),
// Axe
"common.abilities.axe.leap" => (
"Axe Jump",
"A jump with the slashing leap to position of cursor.",
),
// Hammer
"common.abilities.hammer.leap" => (
"Smash of Doom",
"An AOE attack with knockback. Leaps to position of cursor.",
),
// Bow
"common.abilities.bow.shotgun" => (
"Burst",
"Launches a burst of arrows",
),
// Staff
"common.abilities.staff.fireshockwave" => (
"Ring of Fire",
"Ignites the ground with fiery shockwave.",
),
// Sceptre
"common.abilities.sceptre.wardingaura" => (
"Thorn Bulwark",
"Protects you and your group with thorns for a short amount of time.",
),
_ => (
"Ability has no title",
"Ability has no description."
),
};
(Cow::Borrowed(name), desc)
} }

View File

@ -344,10 +344,9 @@ impl KeyMouse {
key_string.to_owned() key_string.to_owned()
} }
/// Returns shortened key name (e.g. Left Click -> LMB) /// If it exists, returns the shortened version of a key name
/// /// (e.g. Left Click -> M1)
/// Use it in case if space does really matter. pub fn try_shortened(&self, _key_layout: &Option<KeyLayout>) -> Option<String> {
pub fn display_shortened(&self, _key_layout: &Option<KeyLayout>) -> Option<String> {
use self::KeyMouse::*; use self::KeyMouse::*;
use winit::event::{MouseButton, VirtualKeyCode::*}; use winit::event::{MouseButton, VirtualKeyCode::*};
let key_string = match self { let key_string = match self {
@ -366,6 +365,15 @@ impl KeyMouse {
Some(key_string.to_owned()) Some(key_string.to_owned())
} }
/// Returns shortest name of key (e.g. Left Click - M1)
/// If key doesn't have shorter version, use regular one.
///
/// Use it in case if space does really matter.
pub fn display_shortest(&self, key_layout: &Option<KeyLayout>) -> String {
self.try_shortened(key_layout)
.unwrap_or_else(|| self.display_string(key_layout))
}
} }
pub struct Window { pub struct Window {