From af396aa8dd25c441904897f2092cbd2527fe7bc3 Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Fri, 19 Jan 2024 22:33:50 +0200 Subject: [PATCH] Add Gender marker for body - Add gender() method on body, which is derived from body_type - Expose it in ChatContext so that chat i18n can use it. --- client/src/lib.rs | 89 ++++++++++++++++++++++-------------- common/net/src/msg/server.rs | 5 +- common/src/comp/body.rs | 74 ++++++++++++++++++++++++++++++ common/src/comp/mod.rs | 2 +- 4 files changed, 132 insertions(+), 38 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 97ece6c5bb..4cd6377833 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -2870,10 +2870,13 @@ impl Client { } /// Change player alias to "You" if client belongs to matching player + // TODO: move this to voxygen or i18n-helpers and properly localize there + // or what's better, just remove completely, it won't properly work with + // localization anyway. pub fn personalize_alias(&self, uid: Uid, alias: String) -> String { let client_uid = self.uid().expect("Client doesn't have a Uid!!!"); if client_uid == uid { - "You".to_string() // TODO: Localize + "You".to_string() } else { alias } @@ -2886,7 +2889,9 @@ impl Client { you: self.uid().expect("Client doesn't have a Uid!!!"), player_alias: HashMap::new(), entity_name: HashMap::new(), + gender: HashMap::new(), }; + let name_of_uid = |uid| { let ecs = self.state.ecs(); ( @@ -2897,53 +2902,67 @@ impl Client { .find(|(_, u)| u == &uid) .map(|(c, _)| c.name.clone()) }; - let mut alias_of_uid = |uid| match self.player_list.get(uid) { - Some(player_info) => { - result.player_alias.insert(*uid, player_info.clone()); - }, - None => { - result - .entity_name - .insert(*uid, name_of_uid(uid).unwrap_or_else(|| "".to_string())); - }, + + let gender_of_uid = |uid| { + let ecs = self.state.ecs(); + ( + &ecs.read_storage::(), + &ecs.read_storage::(), + ) + .join() + .find(|(_, u)| u == &uid) + .map(|(c, _)| c.original_body.gender()) }; + + let mut add_data_of = |uid| { + match self.player_list.get(uid) { + Some(player_info) => { + result.player_alias.insert(*uid, player_info.clone()); + }, + None => { + result + .entity_name + .insert(*uid, name_of_uid(uid).unwrap_or_else(|| "".to_string())); + }, + }; + result + .gender + .insert(*uid, gender_of_uid(uid).unwrap_or(comp::Gender::Masculine)); + }; + match &msg.chat_type { - comp::ChatType::Online(uid) | comp::ChatType::Offline(uid) => { - alias_of_uid(uid); - }, - comp::ChatType::CommandError => (), - comp::ChatType::CommandInfo => (), - comp::ChatType::FactionMeta(_) => (), - comp::ChatType::GroupMeta(_) => (), + comp::ChatType::Online(uid) | comp::ChatType::Offline(uid) => add_data_of(uid), comp::ChatType::Kill(kill_source, victim) => { - alias_of_uid(victim); + add_data_of(victim); + match kill_source { KillSource::Player(attacker_uid, _) => { - alias_of_uid(attacker_uid); + add_data_of(attacker_uid); }, - KillSource::NonPlayer(_, _) => (), - KillSource::Environment(_) => (), - KillSource::FallDamage => (), - KillSource::Suicide => (), - KillSource::NonExistent(_) => (), - KillSource::Other => (), + KillSource::NonPlayer(_, _) + | KillSource::Environment(_) + | KillSource::FallDamage + | KillSource::Suicide + | KillSource::NonExistent(_) + | KillSource::Other => (), }; }, comp::ChatType::Tell(from, to) | comp::ChatType::NpcTell(from, to) => { - alias_of_uid(from); - alias_of_uid(to); + add_data_of(from); + add_data_of(to); }, comp::ChatType::Say(uid) | comp::ChatType::Region(uid) | comp::ChatType::World(uid) - | comp::ChatType::NpcSay(uid) => { - alias_of_uid(uid); - }, - comp::ChatType::Group(uid, _) | comp::ChatType::Faction(uid, _) => { - alias_of_uid(uid); - }, - comp::ChatType::Npc(uid) => alias_of_uid(uid), - comp::ChatType::Meta => (), + | comp::ChatType::NpcSay(uid) + | comp::ChatType::Group(uid, _) + | comp::ChatType::Faction(uid, _) + | comp::ChatType::Npc(uid) => add_data_of(uid), + comp::ChatType::CommandError + | comp::ChatType::CommandInfo + | comp::ChatType::FactionMeta(_) + | comp::ChatType::GroupMeta(_) + | comp::ChatType::Meta => (), }; result } diff --git a/common/net/src/msg/server.rs b/common/net/src/msg/server.rs index 2f7ecf8ad9..194792d31b 100644 --- a/common/net/src/msg/server.rs +++ b/common/net/src/msg/server.rs @@ -6,7 +6,7 @@ use crate::sync; use common::{ calendar::Calendar, character::{self, CharacterItem}, - comp::{self, invite::InviteKind, item::MaterialStatManifest, Content}, + comp::{self, body::Gender, invite::InviteKind, item::MaterialStatManifest, Content}, event::UpdateCharacterMetadata, lod, outcome::Outcome, @@ -35,7 +35,7 @@ pub enum ServerMsg { Init(Box), /// Result to `ClientMsg::Register`. send ONCE RegisterAnswer(ServerRegisterAnswer), - ///Msg that can be send ALWAYS as soon as client is registered, e.g. `Chat` + /// Msg that can be send ALWAYS as soon as client is registered, e.g. `Chat` General(ServerGeneral), Ping(PingMsg), } @@ -259,6 +259,7 @@ pub struct ChatTypeContext { pub you: Uid, pub player_alias: HashMap, pub entity_name: HashMap, + pub gender: HashMap, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 61bbb137a0..7b011bb7be 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -198,6 +198,12 @@ impl< const EXTENSION: &'static str = "ron"; } +// Grammatical gender +pub enum Gender { + Masculine, + Feminine, +} + impl Body { pub fn is_same_species_as(&self, other: &Body) -> bool { match self { @@ -1352,6 +1358,74 @@ impl Body { _ => Content::localized("body-generic"), } } + + pub fn gender(&self) -> Gender { + match self { + Body::Humanoid(b) => match b.body_type { + humanoid::BodyType::Male => Gender::Masculine, + humanoid::BodyType::Female => Gender::Feminine, + }, + Body::QuadrupedSmall(b) => match b.body_type { + quadruped_small::BodyType::Male => Gender::Masculine, + quadruped_small::BodyType::Female => Gender::Feminine, + }, + Body::QuadrupedMedium(b) => match b.body_type { + quadruped_medium::BodyType::Male => Gender::Masculine, + quadruped_medium::BodyType::Female => Gender::Feminine, + }, + Body::BirdMedium(b) => match b.body_type { + bird_medium::BodyType::Male => Gender::Masculine, + bird_medium::BodyType::Female => Gender::Feminine, + }, + Body::FishMedium(b) => match b.body_type { + fish_medium::BodyType::Male => Gender::Masculine, + fish_medium::BodyType::Female => Gender::Feminine, + }, + Body::Dragon(b) => match b.body_type { + dragon::BodyType::Male => Gender::Masculine, + dragon::BodyType::Female => Gender::Feminine, + }, + Body::BirdLarge(b) => match b.body_type { + bird_large::BodyType::Male => Gender::Masculine, + bird_large::BodyType::Female => Gender::Feminine, + }, + Body::FishSmall(b) => match b.body_type { + fish_small::BodyType::Male => Gender::Masculine, + fish_small::BodyType::Female => Gender::Feminine, + }, + Body::BipedLarge(b) => match b.body_type { + biped_large::BodyType::Male => Gender::Masculine, + biped_large::BodyType::Female => Gender::Feminine, + }, + Body::BipedSmall(b) => match b.body_type { + biped_small::BodyType::Male => Gender::Masculine, + biped_small::BodyType::Female => Gender::Feminine, + }, + Body::Golem(b) => match b.body_type { + golem::BodyType::Male => Gender::Masculine, + golem::BodyType::Female => Gender::Feminine, + }, + Body::Theropod(b) => match b.body_type { + theropod::BodyType::Male => Gender::Masculine, + theropod::BodyType::Female => Gender::Feminine, + }, + Body::QuadrupedLow(b) => match b.body_type { + quadruped_low::BodyType::Male => Gender::Masculine, + quadruped_low::BodyType::Female => Gender::Feminine, + }, + Body::Arthropod(b) => match b.body_type { + arthropod::BodyType::Male => Gender::Masculine, + arthropod::BodyType::Female => Gender::Feminine, + }, + Body::Crustacean(b) => match b.body_type { + crustacean::BodyType::Male => Gender::Masculine, + crustacean::BodyType::Female => Gender::Feminine, + }, + Body::ItemDrop(_) | Body::Object(_) | Body::Ship(_) => { + panic!("we don't care about item gender") + }, + } + } } impl Component for Body { diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index dedd41e83d..10a03646fc 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -54,7 +54,7 @@ pub use self::{ body::{ arthropod, biped_large, biped_small, bird_large, bird_medium, crustacean, dragon, fish_medium, fish_small, golem, humanoid, item_drop, object, quadruped_low, - quadruped_medium, quadruped_small, ship, theropod, AllBodies, Body, BodyData, + quadruped_medium, quadruped_small, ship, theropod, AllBodies, Body, BodyData, Gender, }, buff::{ Buff, BuffCategory, BuffChange, BuffData, BuffEffect, BuffKey, BuffKind, BuffSource, Buffs,