mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
NPCs now call for help when you hit them. Redraw speech bubble dark mode.
This commit is contained in:
parent
3c07d02218
commit
3cea76b82f
BIN
assets/voxygen/element/frames/bubble_dark/bottom.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/bottom.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/bottom_left.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/bottom_left.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/bottom_right.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/bottom_right.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/left.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/left.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/mid.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/mid.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/right.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/right.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/tail.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/tail.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/top.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/top.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/top_left.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/top_left.png
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/frames/bubble_dark/top_right.png
(Stored with Git LFS)
BIN
assets/voxygen/element/frames/bubble_dark/top_right.png
(Stored with Git LFS)
Binary file not shown.
@ -383,5 +383,8 @@ Willenskraft
|
|||||||
"esc_menu.logout": "Ausloggen",
|
"esc_menu.logout": "Ausloggen",
|
||||||
"esc_menu.quit_game": "Desktop",
|
"esc_menu.quit_game": "Desktop",
|
||||||
/// End Escape Menu Section
|
/// End Escape Menu Section
|
||||||
|
},
|
||||||
|
|
||||||
|
vector_map: {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -376,14 +376,52 @@ Fitness
|
|||||||
|
|
||||||
Willpower
|
Willpower
|
||||||
"#,
|
"#,
|
||||||
|
/// End character window section
|
||||||
|
|
||||||
/// Start character window section
|
|
||||||
|
|
||||||
|
|
||||||
/// Start Escape Menu Section
|
/// Start Escape Menu Section
|
||||||
"esc_menu.logout": "Logout",
|
"esc_menu.logout": "Logout",
|
||||||
"esc_menu.quit_game": "Quit Game",
|
"esc_menu.quit_game": "Quit Game",
|
||||||
/// End Escape Menu Section
|
/// End Escape Menu Section
|
||||||
|
},
|
||||||
|
|
||||||
|
vector_map: {
|
||||||
|
"npc.speech.villager_under_attack": [
|
||||||
|
"Help, I'm under attack!",
|
||||||
|
"Help! I'm under attack!",
|
||||||
|
"Ouch! I'm under attack!",
|
||||||
|
"Ouch! I'm under attack! Help!",
|
||||||
|
"Help me! I'm under attack!",
|
||||||
|
"I'm under attack! Help!",
|
||||||
|
"I'm under attack! Help me!",
|
||||||
|
"Help!",
|
||||||
|
"Help! Help!",
|
||||||
|
"Help! Help! Help!",
|
||||||
|
"I'm under attack!",
|
||||||
|
"AAAHHH! I'm under attack!",
|
||||||
|
"AAAHHH! I'm under attack! Help!",
|
||||||
|
"Help! We're under attack!",
|
||||||
|
"Help! Murderer!",
|
||||||
|
"Help! There's a murder on the loose!",
|
||||||
|
"Help! They're trying to kill me!",
|
||||||
|
"Guards, I'm under attack!",
|
||||||
|
"Guards! I'm under attack!",
|
||||||
|
"I'm under attack! Guards!",
|
||||||
|
"Help! Guards! I'm under attack!",
|
||||||
|
"Guards! Come quick!",
|
||||||
|
"Guards! Guards!",
|
||||||
|
"Guards! There's a villain attacking me!",
|
||||||
|
"Guards, slay this foul villain!",
|
||||||
|
"Guards! There's a murderer!",
|
||||||
|
"Guards! Help me!",
|
||||||
|
"You won't get away with this! Guards!",
|
||||||
|
"You fiend!",
|
||||||
|
"Help me!",
|
||||||
|
"Help! Please!",
|
||||||
|
"Ouch! Guards! Help!",
|
||||||
|
"They're coming for me!",
|
||||||
|
"Help! Help! I'm being repressed",
|
||||||
|
"Ah, now we see the violence inherent in the system.",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -323,5 +323,8 @@ Force
|
|||||||
Dexterité
|
Dexterité
|
||||||
|
|
||||||
Intelligence"#,
|
Intelligence"#,
|
||||||
|
},
|
||||||
|
|
||||||
|
vector_map: {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -524,5 +524,8 @@ Volontà
|
|||||||
"esc_menu.logout": "Disconnettiti",
|
"esc_menu.logout": "Disconnettiti",
|
||||||
"esc_menu.quit_game": "Esci dal Gioco",
|
"esc_menu.quit_game": "Esci dal Gioco",
|
||||||
/// End Escape Menu Section
|
/// End Escape Menu Section
|
||||||
}
|
},
|
||||||
|
|
||||||
|
vector_map: {
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
@ -368,5 +368,8 @@ Força de vontade
|
|||||||
"esc_menu.logout": "Desconectar",
|
"esc_menu.logout": "Desconectar",
|
||||||
"esc_menu.quit_game": "Sair do jogo",
|
"esc_menu.quit_game": "Sair do jogo",
|
||||||
/// End Escape Menu Section
|
/// End Escape Menu Section
|
||||||
|
},
|
||||||
|
|
||||||
|
vector_map: {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -365,5 +365,8 @@ https://account.veloren.net."#,
|
|||||||
"esc_menu.logout": "Выйти в меню",
|
"esc_menu.logout": "Выйти в меню",
|
||||||
"esc_menu.quit_game": "Выйти из игры",
|
"esc_menu.quit_game": "Выйти из игры",
|
||||||
/// End Escape Menu Section
|
/// End Escape Menu Section
|
||||||
|
},
|
||||||
|
|
||||||
|
vector_map: {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -397,5 +397,8 @@ Hareket gücü
|
|||||||
"esc_menu.logout": "Çıkış yap",
|
"esc_menu.logout": "Çıkış yap",
|
||||||
"esc_menu.quit_game": "Oyundan çık",
|
"esc_menu.quit_game": "Oyundan çık",
|
||||||
/// End Escape Menu Section
|
/// End Escape Menu Section
|
||||||
|
},
|
||||||
|
|
||||||
|
vector_map: {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -89,13 +89,46 @@ impl Default for Activity {
|
|||||||
/// Default duration in seconds of speech bubbles
|
/// Default duration in seconds of speech bubbles
|
||||||
pub const SPEECH_BUBBLE_DURATION: f64 = 5.0;
|
pub const SPEECH_BUBBLE_DURATION: f64 = 5.0;
|
||||||
|
|
||||||
|
/// The contents of a speech bubble
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub enum SpeechBubbleMessage {
|
||||||
|
/// This message was said by a player and needs no translation
|
||||||
|
Plain(String),
|
||||||
|
/// This message was said by an NPC. The fields are a i18n key and a random
|
||||||
|
/// u16 index
|
||||||
|
Localized(String, u16),
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds a speech bubble to the entity
|
/// Adds a speech bubble to the entity
|
||||||
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct SpeechBubble {
|
pub struct SpeechBubble {
|
||||||
pub message: String,
|
pub message: SpeechBubbleMessage,
|
||||||
pub timeout: Option<Time>,
|
pub timeout: Option<Time>,
|
||||||
// TODO add icon enum for player chat type / npc quest+trade
|
// TODO add icon enum for player chat type / npc quest+trade
|
||||||
}
|
}
|
||||||
impl Component for SpeechBubble {
|
impl Component for SpeechBubble {
|
||||||
type Storage = FlaggedStorage<Self, HashMapStorage<Self>>;
|
type Storage = FlaggedStorage<Self, HashMapStorage<Self>>;
|
||||||
}
|
}
|
||||||
|
impl SpeechBubble {
|
||||||
|
pub fn npc_new(i18n_key: String, now: Time) -> Self {
|
||||||
|
let message = SpeechBubbleMessage::Localized(i18n_key, rand::random());
|
||||||
|
let timeout = Some(Time(now.0 + SPEECH_BUBBLE_DURATION));
|
||||||
|
Self { message, timeout }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn player_new(message: String, now: Time) -> Self {
|
||||||
|
let message = SpeechBubbleMessage::Plain(message);
|
||||||
|
let timeout = Some(Time(now.0 + SPEECH_BUBBLE_DURATION));
|
||||||
|
Self { message, timeout }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn message<F>(&self, i18n_variation: F) -> String
|
||||||
|
where
|
||||||
|
F: Fn(String, u16) -> String,
|
||||||
|
{
|
||||||
|
match &self.message {
|
||||||
|
SpeechBubbleMessage::Plain(m) => m.to_string(),
|
||||||
|
SpeechBubbleMessage::Localized(k, i) => i18n_variation(k.to_string(), *i).to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
agent::Activity,
|
agent::Activity,
|
||||||
item::{tool::ToolKind, ItemKind},
|
item::{tool::ToolKind, ItemKind},
|
||||||
Agent, Alignment, CharacterState, ControlAction, Controller, Loadout, MountState, Ori, Pos,
|
Agent, Alignment, CharacterState, ControlAction, Controller, Loadout, MountState, Ori, Pos,
|
||||||
Scale, Stats,
|
Scale, SpeechBubble, Stats,
|
||||||
},
|
},
|
||||||
path::Chaser,
|
path::Chaser,
|
||||||
state::{DeltaTime, Time},
|
state::{DeltaTime, Time},
|
||||||
@ -38,6 +38,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
ReadStorage<'a, Alignment>,
|
ReadStorage<'a, Alignment>,
|
||||||
WriteStorage<'a, Agent>,
|
WriteStorage<'a, Agent>,
|
||||||
WriteStorage<'a, Controller>,
|
WriteStorage<'a, Controller>,
|
||||||
|
WriteStorage<'a, SpeechBubble>,
|
||||||
ReadStorage<'a, MountState>,
|
ReadStorage<'a, MountState>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
alignments,
|
alignments,
|
||||||
mut agents,
|
mut agents,
|
||||||
mut controllers,
|
mut controllers,
|
||||||
|
mut speech_bubbles,
|
||||||
mount_states,
|
mount_states,
|
||||||
): Self::SystemData,
|
): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
@ -386,6 +388,10 @@ impl<'a> System<'a> for Sys {
|
|||||||
if !agent.activity.is_attack() {
|
if !agent.activity.is_attack() {
|
||||||
if let Some(attacker) = uid_allocator.retrieve_entity_internal(by.id())
|
if let Some(attacker) = uid_allocator.retrieve_entity_internal(by.id())
|
||||||
{
|
{
|
||||||
|
let message = "npc.speech.villager_under_attack".to_string();
|
||||||
|
let bubble = SpeechBubble::npc_new(message, *time);
|
||||||
|
let _ = speech_bubbles.insert(entity, bubble);
|
||||||
|
|
||||||
agent.activity = Activity::Attack {
|
agent.activity = Activity::Attack {
|
||||||
target: attacker,
|
target: attacker,
|
||||||
chaser: Chaser::default(),
|
chaser: Chaser::default(),
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
Admin, CanBuild, ControlEvent, Controller, ForceUpdate, Ori, Player, Pos, SpeechBubble,
|
Admin, CanBuild, ControlEvent, Controller, ForceUpdate, Ori, Player, Pos, SpeechBubble,
|
||||||
Stats, Vel, SPEECH_BUBBLE_DURATION,
|
Stats, Vel,
|
||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
msg::{
|
msg::{
|
||||||
@ -76,8 +76,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
) {
|
) {
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
let time = time.0;
|
|
||||||
|
|
||||||
let persistence_db_dir = &persistence_db_dir.0;
|
let persistence_db_dir = &persistence_db_dir.0;
|
||||||
|
|
||||||
let mut server_emitter = server_event_bus.emitter();
|
let mut server_emitter = server_event_bus.emitter();
|
||||||
@ -97,13 +95,13 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
// Update client ping.
|
// Update client ping.
|
||||||
if new_msgs.len() > 0 {
|
if new_msgs.len() > 0 {
|
||||||
client.last_ping = time
|
client.last_ping = time.0
|
||||||
} else if time - client.last_ping > CLIENT_TIMEOUT // Timeout
|
} else if time.0 - client.last_ping > CLIENT_TIMEOUT // Timeout
|
||||||
|| client.postbox.error().is_some()
|
|| client.postbox.error().is_some()
|
||||||
// Postbox error
|
// Postbox error
|
||||||
{
|
{
|
||||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||||
} else if time - client.last_ping > CLIENT_TIMEOUT * 0.5 {
|
} else if time.0 - client.last_ping > CLIENT_TIMEOUT * 0.5 {
|
||||||
// Try pinging the client if the timeout is nearing.
|
// Try pinging the client if the timeout is nearing.
|
||||||
client.postbox.send_message(ServerMsg::Ping);
|
client.postbox.send_message(ServerMsg::Ping);
|
||||||
}
|
}
|
||||||
@ -406,11 +404,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
server_emitter.emit(ServerEvent::ChatCmd(entity, argv));
|
server_emitter.emit(ServerEvent::ChatCmd(entity, argv));
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
let timeout = Some(Time(time + SPEECH_BUBBLE_DURATION));
|
let bubble = SpeechBubble::player_new(message.clone(), *time);
|
||||||
let bubble = SpeechBubble {
|
|
||||||
message: message.clone(),
|
|
||||||
timeout,
|
|
||||||
};
|
|
||||||
let _ = speech_bubbles.insert(entity, bubble);
|
let _ = speech_bubbles.insert(entity, bubble);
|
||||||
match players.get(entity) {
|
match players.get(entity) {
|
||||||
Some(player) => {
|
Some(player) => {
|
||||||
|
@ -21,7 +21,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
.map(|(ent, _)| ent)
|
.map(|(ent, _)| ent)
|
||||||
.collect();
|
.collect();
|
||||||
for ent in expired_ents {
|
for ent in expired_ents {
|
||||||
println!("Remoaving bobble");
|
|
||||||
speech_bubbles.remove(ent);
|
speech_bubbles.remove(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,6 +954,7 @@ impl Hud {
|
|||||||
own_level,
|
own_level,
|
||||||
&global_state.settings.gameplay,
|
&global_state.settings.gameplay,
|
||||||
self.pulse,
|
self.pulse,
|
||||||
|
&self.voxygen_i18n,
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
&self.fonts,
|
&self.fonts,
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::{img_ids::Imgs, HP_COLOR, LOW_HP_COLOR, MANA_COLOR};
|
use super::{img_ids::Imgs, HP_COLOR, LOW_HP_COLOR, MANA_COLOR};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
i18n::VoxygenLocalization,
|
||||||
settings::GameplaySettings,
|
settings::GameplaySettings,
|
||||||
ui::{fonts::ConrodVoxygenFonts, Ingameable},
|
ui::{fonts::ConrodVoxygenFonts, Ingameable},
|
||||||
};
|
};
|
||||||
@ -51,6 +52,7 @@ pub struct Overhead<'a> {
|
|||||||
own_level: u32,
|
own_level: u32,
|
||||||
settings: &'a GameplaySettings,
|
settings: &'a GameplaySettings,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
|
voxygen_i18n: &'a std::sync::Arc<VoxygenLocalization>,
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
fonts: &'a ConrodVoxygenFonts,
|
fonts: &'a ConrodVoxygenFonts,
|
||||||
#[conrod(common_builder)]
|
#[conrod(common_builder)]
|
||||||
@ -66,6 +68,7 @@ impl<'a> Overhead<'a> {
|
|||||||
own_level: u32,
|
own_level: u32,
|
||||||
settings: &'a GameplaySettings,
|
settings: &'a GameplaySettings,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
|
voxygen_i18n: &'a std::sync::Arc<VoxygenLocalization>,
|
||||||
imgs: &'a Imgs,
|
imgs: &'a Imgs,
|
||||||
fonts: &'a ConrodVoxygenFonts,
|
fonts: &'a ConrodVoxygenFonts,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -77,6 +80,7 @@ impl<'a> Overhead<'a> {
|
|||||||
own_level,
|
own_level,
|
||||||
settings,
|
settings,
|
||||||
pulse,
|
pulse,
|
||||||
|
voxygen_i18n,
|
||||||
imgs,
|
imgs,
|
||||||
fonts,
|
fonts,
|
||||||
common: widget::CommonBuilder::default(),
|
common: widget::CommonBuilder::default(),
|
||||||
@ -139,7 +143,11 @@ impl<'a> Widget for Overhead<'a> {
|
|||||||
// Speech bubble
|
// Speech bubble
|
||||||
if let Some(bubble) = self.bubble {
|
if let Some(bubble) = self.bubble {
|
||||||
let dark_mode = self.settings.speech_bubble_dark_mode;
|
let dark_mode = self.settings.speech_bubble_dark_mode;
|
||||||
let mut text = Text::new(&bubble.message)
|
let localizer =
|
||||||
|
|s: String, i| -> String { self.voxygen_i18n.get_variation(&s, i).to_string() };
|
||||||
|
let bubble_contents: String = bubble.message(localizer);
|
||||||
|
|
||||||
|
let mut text = Text::new(&bubble_contents)
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.font_size(18)
|
.font_size(18)
|
||||||
.up_from(state.ids.name, 10.0)
|
.up_from(state.ids.name, 10.0)
|
||||||
|
@ -53,10 +53,15 @@ pub type VoxygenFonts = HashMap<String, Font>;
|
|||||||
pub struct VoxygenLocalization {
|
pub struct VoxygenLocalization {
|
||||||
/// A map storing the localized texts
|
/// A map storing the localized texts
|
||||||
///
|
///
|
||||||
/// Localized content can be access using a String key
|
/// Localized content can be accessed using a String key.
|
||||||
pub string_map: HashMap<String, String>,
|
pub string_map: HashMap<String, String>,
|
||||||
|
|
||||||
/// Either to convert the input text encoded in UTF-8
|
/// A map for storing variations of localized texts, for example multiple
|
||||||
|
/// ways of saying "Help, I'm under attack". Used primarily for npc
|
||||||
|
/// dialogue.
|
||||||
|
pub vector_map: HashMap<String, Vec<String>>,
|
||||||
|
|
||||||
|
/// Whether to convert the input text encoded in UTF-8
|
||||||
/// into a ASCII version by using the `deunicode` crate.
|
/// into a ASCII version by using the `deunicode` crate.
|
||||||
pub convert_utf8_to_ascii: bool,
|
pub convert_utf8_to_ascii: bool,
|
||||||
|
|
||||||
@ -78,23 +83,56 @@ impl VoxygenLocalization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the missing keys compared to the reference language and return
|
/// Get a variation of localized text from the given key
|
||||||
/// them
|
///
|
||||||
pub fn list_missing_entries(&self) -> HashSet<String> {
|
/// `index` should be a random number from `0` to `u16::max()`
|
||||||
|
///
|
||||||
|
/// 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) -> &str {
|
||||||
|
match self.vector_map.get(key) {
|
||||||
|
Some(v) if !v.is_empty() => &v[index as usize % v.len()],
|
||||||
|
_ => key,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the missing keys compared to the reference language
|
||||||
|
pub fn list_missing_entries(&self) -> (HashSet<String>, HashSet<String>) {
|
||||||
let reference_localization =
|
let reference_localization =
|
||||||
load_expect::<VoxygenLocalization>(i18n_asset_key(REFERENCE_LANG).as_ref());
|
load_expect::<VoxygenLocalization>(i18n_asset_key(REFERENCE_LANG).as_ref());
|
||||||
let reference_keys: HashSet<_> =
|
|
||||||
reference_localization.string_map.keys().cloned().collect();
|
|
||||||
let current_keys: HashSet<_> = self.string_map.keys().cloned().collect();
|
|
||||||
|
|
||||||
reference_keys.difference(¤t_keys).cloned().collect()
|
let reference_string_keys: HashSet<_> =
|
||||||
|
reference_localization.string_map.keys().cloned().collect();
|
||||||
|
let string_keys: HashSet<_> = self.string_map.keys().cloned().collect();
|
||||||
|
let strings = reference_string_keys
|
||||||
|
.difference(&string_keys)
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let reference_vector_keys: HashSet<_> =
|
||||||
|
reference_localization.vector_map.keys().cloned().collect();
|
||||||
|
let vector_keys: HashSet<_> = self.vector_map.keys().cloned().collect();
|
||||||
|
let vectors = reference_vector_keys
|
||||||
|
.difference(&vector_keys)
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
(strings, vectors)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Log missing entries (compared to the reference language) as warnings
|
/// Log missing entries (compared to the reference language) as warnings
|
||||||
pub fn log_missing_entries(&self) {
|
pub fn log_missing_entries(&self) {
|
||||||
for missing_key in self.list_missing_entries() {
|
let (missing_strings, missing_vectors) = self.list_missing_entries();
|
||||||
|
for missing_key in missing_strings {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"[{:?}] Missing key {:?}",
|
"[{:?}] Missing string key {:?}",
|
||||||
|
self.metadata.language_identifier,
|
||||||
|
missing_key
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for missing_key in missing_vectors {
|
||||||
|
log::warn!(
|
||||||
|
"[{:?}] Missing vector key {:?}",
|
||||||
self.metadata.language_identifier,
|
self.metadata.language_identifier,
|
||||||
missing_key
|
missing_key
|
||||||
);
|
);
|
||||||
@ -116,6 +154,10 @@ impl Asset for VoxygenLocalization {
|
|||||||
for value in asked_localization.string_map.values_mut() {
|
for value in asked_localization.string_map.values_mut() {
|
||||||
*value = deunicode(value);
|
*value = deunicode(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for value in asked_localization.vector_map.values_mut() {
|
||||||
|
*value = value.into_iter().map(|s| deunicode(s)).collect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
asked_localization.metadata.language_name =
|
asked_localization.metadata.language_name =
|
||||||
deunicode(&asked_localization.metadata.language_name);
|
deunicode(&asked_localization.metadata.language_name);
|
||||||
|
Loading…
Reference in New Issue
Block a user