From 5aa88ac2235324cf924f6354aaa3ca77e1cb7cec Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Sat, 3 Feb 2024 18:32:49 +0200 Subject: [PATCH] Store the gender in CharacterInfo --- client/src/lib.rs | 20 +++----------------- common/net/src/msg/server.rs | 4 ++-- common/src/comp/body.rs | 7 ++++--- server/src/events/player.rs | 2 ++ server/src/state_ext.rs | 2 ++ server/src/sys/msg/register.rs | 2 ++ voxygen/i18n-helpers/src/lib.rs | 23 +++++++++++++++++------ voxygen/src/hud/chat.rs | 2 +- 8 files changed, 33 insertions(+), 29 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 63854dea95..17ca930b22 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -2250,6 +2250,7 @@ impl Client { player_info.character = match &player_info.character { Some(character) => Some(msg::CharacterInfo { name: character.name.to_string(), + gender: character.gender, }), None => { warn!( @@ -2887,9 +2888,8 @@ impl Client { pub fn lookup_msg_context(&self, msg: &comp::ChatMsg) -> ChatTypeContext { let mut result = ChatTypeContext { you: self.uid().expect("Client doesn't have a Uid!!!"), - player_alias: HashMap::new(), + player_info: HashMap::new(), entity_name: HashMap::new(), - gender: HashMap::new(), }; let name_of_uid = |uid| { @@ -2903,24 +2903,10 @@ impl Client { .map(|(c, _)| c.name.clone()) }; - let gender_of_uid = |uid| { - let ecs = self.state.ecs(); - ( - &ecs.read_storage::(), - &ecs.read_storage::(), - ) - .join() - .find(|(_, u)| u == &uid) - .and_then(|(c, _)| c.original_body.humanoid_gender()) - }; - let mut add_data_of = |uid| { match self.player_list.get(uid) { Some(player_info) => { - result.player_alias.insert(*uid, player_info.clone()); - result - .gender - .insert(*uid, gender_of_uid(uid).unwrap_or(comp::Gender::Masculine)); + result.player_info.insert(*uid, player_info.clone()); }, None => { result diff --git a/common/net/src/msg/server.rs b/common/net/src/msg/server.rs index 194792d31b..3e1a5cb990 100644 --- a/common/net/src/msg/server.rs +++ b/common/net/src/msg/server.rs @@ -257,14 +257,14 @@ pub struct PlayerInfo { /// used for localisation, filled by client and used by i18n code pub struct ChatTypeContext { pub you: Uid, - pub player_alias: HashMap, + pub player_info: HashMap, pub entity_name: HashMap, - pub gender: HashMap, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CharacterInfo { pub name: String, + pub gender: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 4a7b024342..5dd5eaf83f 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -203,9 +203,10 @@ impl< /// Should be used for localization with extreme care. /// For basically everything except *maybe* humanoids, it's simply wrong to /// assume that this may be used as grammatical gender. -// -// TODO: remove this and instead add GUI for players to choose preferred gender. -// Read a comment for `gender_str` in voxygen/i18n-helpers/src/lib.rs. +/// +/// TODO: remove this and instead add GUI for players to choose preferred +/// gender. Read a comment for `gender_str` in voxygen/i18n-helpers/src/lib.rs. +#[derive(Copy, Clone, Debug, Deserialize, Serialize)] pub enum Gender { Masculine, Feminine, diff --git a/server/src/events/player.rs b/server/src/events/player.rs index 91f10f54d3..b31ff69177 100644 --- a/server/src/events/player.rs +++ b/server/src/events/player.rs @@ -522,6 +522,8 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possessee_uid: Ui character: ecs.read_storage::().get(possessee).map(|s| { msg::CharacterInfo { name: s.name.clone(), + // NOTE: hack, read docs for humanoid_gender() for more + gender: s.original_body.humanoid_gender(), } }), uuid: player.uuid(), diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index e6b2c35035..2d242c7903 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -724,6 +724,8 @@ impl StateExt for State { self.notify_players(ServerGeneral::PlayerListUpdate( PlayerListUpdate::SelectedCharacter(player_uid, CharacterInfo { name: String::from(&stats.name), + // NOTE: hack, read docs for humanoid_gender() for more + gender: stats.original_body.humanoid_gender(), }), )); diff --git a/server/src/sys/msg/register.rs b/server/src/sys/msg/register.rs index a29e80381e..c4bf118e42 100644 --- a/server/src/sys/msg/register.rs +++ b/server/src/sys/msg/register.rs @@ -99,6 +99,8 @@ impl<'a> System<'a> for Sys { player_alias: player.alias.clone(), character: stats.map(|stats| CharacterInfo { name: stats.name.clone(), + // NOTE: hack, read docs for humanoid_gender() + gender: stats.original_body.humanoid_gender(), }), uuid: player.uuid(), }), diff --git a/voxygen/i18n-helpers/src/lib.rs b/voxygen/i18n-helpers/src/lib.rs index bf3e2bc6b6..810520f55e 100644 --- a/voxygen/i18n-helpers/src/lib.rs +++ b/voxygen/i18n-helpers/src/lib.rs @@ -20,7 +20,7 @@ pub fn localize_chat_message( ) -> (ChatType, String) { let info = lookup_fn(&msg); - let name_format_or_complex = |complex, uid: &Uid| match info.player_alias.get(uid).cloned() { + let name_format_or_complex = |complex, uid: &Uid| match info.player_info.get(uid).cloned() { Some(pi) => { if complex { insert_alias(info.you == *uid, pi, localization) @@ -75,10 +75,21 @@ pub fn localize_chat_message( // If the language can represent Female, Male and Neuter, we can pass these. // // Exact design of such a complex system is honestly up to discussion. - let gender_str = |uid: &Uid| match info.gender.get(uid) { - Some(Gender::Feminine) => "she".to_owned(), - Some(Gender::Masculine) => "he".to_owned(), - None => "??".to_owned(), + let gender_str = |uid: &Uid| match info.player_info.get(uid) { + Some(pi) => match pi.character.as_ref().and_then(|c| c.gender) { + Some(Gender::Feminine) => "she".to_owned(), + Some(Gender::Masculine) => "he".to_owned(), + None => { + tracing::error!("We tried to get the gender, but failed"); + + "??".to_owned() + } + }, + None => { + tracing::error!("We tried to get the gender of the player we can't find"); + + "??".to_owned() + }, }; // This is where the most fun begings. @@ -128,7 +139,7 @@ pub fn localize_chat_message( let message_format = |from: &Uid, content: &Content, group: Option<&String>| { let alias = name_format_or_complex(true, from); - let name = if let Some(pi) = info.player_alias.get(from).cloned() && show_char_name { + let name = if let Some(pi) = info.player_info.get(from).cloned() && show_char_name { pi.character.map(|c| c.name) } else { None diff --git a/voxygen/src/hud/chat.rs b/voxygen/src/hud/chat.rs index 85c482f7f3..794a5d0e81 100644 --- a/voxygen/src/hud/chat.rs +++ b/voxygen/src/hud/chat.rs @@ -481,7 +481,7 @@ impl<'a> Widget for Chat<'a> { .and_then(|uid| { self.client .lookup_msg_context(m) - .player_alias + .player_info .get(&uid) .map(|i| i.is_moderator) })