diff --git a/assets/common/npc_names.ron b/assets/common/npc_names.ron index f0754fe52b..1d068ea772 100644 --- a/assets/common/npc_names.ron +++ b/assets/common/npc_names.ron @@ -2,7 +2,7 @@ humanoid: ( body: ( keyword: "humanoid", - names: [ + names_0: [ "Adon", "Agro", "Arlo", @@ -104,7 +104,98 @@ "Zaden", "Zagaroth", "Zenner" - ] + ], + names_1: Some([ + "Acele", + "Autumn", + "Acholate", + "Ada", + "Adorra", + "Ahanna", + "Brana", + "Bathelie", + "Calene", + "Calina", + "Celestine", + "Caela", + "Cassia", + "Celoa", + "Dalavesta", + "Dylena", + "Desini", + "Diva", + "Ebatryne", + "Efari", + "Enona", + "Enaldie", + "Ember", + "Esdel", + "Eune", + "Fayne", + "Frida", + "Ferra", + "Flora", + "Fintis", + "Gatlen", + "Gatline", + "Gronalyn", + "Helenia", + "Halete", + "Hyza", + "Helena", + "Halin", + "Hera", + "Hilda", + "Hydra", + "Ismeria", + "Iris", + "Joss", + "Kadra", + "Kagra", + "Kyra", + "Konta", + "Krinn", + "Lydia", + "Laelia", + "Leda", + "Leta", + "Lisbeth", + "Lyra", + "Luna", + "Medora", + "Mazarine", + "Merlyn", + "Marina", + "Nephele", + "Odessa", + "Orla", + "Perl", + "Rhodeia", + "Rosella", + "Raven", + "Rachel", + "Ryven", + "Solenne", + "Seren", + "Summer", + "Solstice", + "Stella", + "Sarah", + "Syrin", + "Tessa", + "Thea", + "Tez", + "Vivien", + "Varda", + "Veridia", + "Victoria", + "Vale", + "Vega", + "Yorja", + "Xaviera", + "Zorina", + "Zephyra" + ]) ), /*keyword: "humanoid_f", names: [ @@ -229,7 +320,7 @@ quadruped_medium: ( body: ( keyword: "quadruped_medium", - names: [ + names_0: [ "Achak", "Adalwolf", "Akela", @@ -421,7 +512,7 @@ quadruped_small: ( body: ( keyword: "quadruped_small", - names: [ + names_0: [ "Acorn", "Adeline", "Ajna", @@ -632,7 +723,7 @@ bird_medium: ( body: ( keyword: "bird_medium", - names: [ + names_0: [ "Donald" ] ), @@ -674,7 +765,7 @@ biped_large: ( body: ( keyword: "biped_large", - names: [ + names_0: [ "Tobermory" ] ), @@ -724,7 +815,7 @@ golem: ( body: ( keyword: "golem", - names: [ + names_0: [ "phil" ] ), @@ -742,7 +833,7 @@ theropod: ( body: ( keyword: "theropod", - names: [ + names_0: [ "Remy" ] ), @@ -772,7 +863,7 @@ dragon: ( body: ( keyword: "dragon", - names: [ + names_0: [ "Smaug" ] ), @@ -786,14 +877,14 @@ object: ( body: ( keyword: "object", - names: [] + names_0: [] ), species: () ), fish_small: ( body: ( keyword: "fish_small", - names: [ + names_0: [ "Dagon" ] ), @@ -807,7 +898,7 @@ fish_medium: ( body: ( keyword: "fish_medium", - names: [ + names_0: [ "Njord" ] ), @@ -821,14 +912,14 @@ bird_small: ( body: ( keyword: "bird_small", - names: [] + names_0: [] ), species: () ), quadruped_low: ( body: ( keyword: "quadruped_low", - names: [ + names_0: [ "Sobek" ] ), diff --git a/common/src/lottery.rs b/common/src/lottery.rs index 4aaa7db851..1e9759219f 100644 --- a/common/src/lottery.rs +++ b/common/src/lottery.rs @@ -1,3 +1,31 @@ +// Example for calculating a drop rate: +// +// On every roll an f32 between 0 and 1 is created. +// For every loot table a total range is created by the sum of the individual +// ranges per item. +// +// This range is the sum of all single ranges defined per item in a table. +// // Individual Range +// (3, "common.items.food.cheese"), // 0.0..3.0 +// (3, "common.items.food.apple"), // 3.0..6.0 +// (3, "common.items.food.mushroom"), // 6.0..9.0 +// (1, "common.items.food.coconut"), // 9.0..10.0 +// (0.05, "common.items.food.apple_mushroom_curry"), // 10.0..10.05 +// (0.10, "common.items.food.apple_stick"), // 10.05..10.15 +// (0.10, "common.items.food.mushroom_stick"), // 10.15..10.25 +// +// The f32 is multiplied by the max. value needed to drop an item in this +// particular table. X = max. value needed = 10.15 +// +// Example roll +// [Random Value 0..1] * X = Number inside the table's total range +// 0.45777 * X = 4.65 +// 4.65 is in the range of 3.0..6.0 => Apple drops +// +// Example drop chance calculation +// Cheese drop rate = 3/X = 29.6% +// Coconut drop rate = 1/X = 9.85% + use crate::assets; use rand::prelude::*; use serde::{de::DeserializeOwned, Deserialize}; diff --git a/common/src/npc.rs b/common/src/npc.rs index 87f4e72fc7..8d68c507e9 100644 --- a/common/src/npc.rs +++ b/common/src/npc.rs @@ -1,6 +1,6 @@ use crate::{ assets::{AssetExt, AssetHandle}, - comp::{self, AllBodies, Body}, + comp::{self, body, AllBodies, Body}, }; use lazy_static::lazy_static; use rand::seq::SliceRandom; @@ -47,7 +47,8 @@ pub struct BodyNames { /// A list of canonical names for NPCs with this body types (currently used /// when spawning this kind of NPC from the console). Going forward, /// these names will likely be split up by species. - pub names: Vec, + pub names_0: Vec, + pub names_1: Option>, } /// Species-specific NPC name metadata. @@ -83,15 +84,33 @@ impl FromStr for NpcKind { } } -pub fn get_npc_name(npc_type: NpcKind) -> String { +pub fn get_npc_name(npc_type: NpcKind, body_type: Option) -> String { let npc_names = NPC_NAMES.read(); - let BodyNames { keyword, names } = &npc_names[npc_type]; + let BodyNames { + keyword, + names_0, + names_1, + } = &npc_names[npc_type]; // If no pretty name is found, fall back to the keyword. - names - .choose(&mut rand::thread_rng()) - .unwrap_or(keyword) - .clone() + match body_type { + Some(BodyType::Male) => names_0 + .choose(&mut rand::thread_rng()) + .unwrap_or(keyword) + .clone(), + Some(BodyType::Female) if names_1.is_some() => { + names_1 + .as_ref() + .unwrap() // Unwrap safe since is_some is true + .choose(&mut rand::thread_rng()) + .unwrap_or(keyword) + .clone() + }, + _ => names_0 + .choose(&mut rand::thread_rng()) + .unwrap_or(keyword) + .clone(), + } } /// Randomly generates a body associated with this NPC kind. @@ -265,3 +284,20 @@ impl NpcBody { .ok_or(()) } } + +pub enum BodyType { + Male, + Female, +} + +impl BodyType { + pub fn from_body(body: Body) -> Option { + match body { + Body::Humanoid(humanoid) => match humanoid.body_type { + body::humanoid::BodyType::Male => Some(BodyType::Male), + body::humanoid::BodyType::Female => Some(BodyType::Female), + }, + _ => None, + } + } +} diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 52825a05e9..c4c32b96ed 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -820,7 +820,10 @@ fn handle_spawn( .state .create_npc( pos, - comp::Stats::new(get_npc_name(id), body), + comp::Stats::new( + get_npc_name(id, npc::BodyType::from_body(body)), + body, + ), comp::Health::new(body, 1), inventory, body, diff --git a/voxygen/src/hud/group.rs b/voxygen/src/hud/group.rs index 98b1d9bea9..64777a1f41 100644 --- a/voxygen/src/hud/group.rs +++ b/voxygen/src/hud/group.rs @@ -437,7 +437,7 @@ impl<'a> Widget for Group<'a> { let indicator_col = cr_color(combat_rating); Image::new(self.imgs.combat_rating_ico_shadow) .w_h(18.0, 18.0) - .top_left_with_margins_on(state.ids.member_panels_frame[i], 20.0, 2.0) + .top_left_with_margins_on(state.ids.member_panels_frame[i], -20.0, 2.0) .color(Some(indicator_col)) .set(state.ids.combat_rating_indicators[i], ui); // Panel Text diff --git a/voxygen/src/hud/social.rs b/voxygen/src/hud/social.rs index 432b54d470..8df73d199d 100644 --- a/voxygen/src/hud/social.rs +++ b/voxygen/src/hud/social.rs @@ -391,19 +391,14 @@ impl<'a> Widget for Social<'a> { }; let name_text = match &player_info.character { Some(character) => { - if Some(uid) == my_uid { - format!( - "{} ({})", - &self.localized_strings.get("hud.common.you"), - &character.name - ) - } else if hide_username { - format!("{} [{}]", &character.name, zone_name) + if hide_username { + character.name.to_string() } else { - format!("[{}] {} [{}]", alias, &character.name, zone_name) + format!("[{}] {}", alias, &character.name) } }, - None => alias.clone(), // character select or spectating + None => format!("{} [{}]", alias.clone(), zone_name), /* character select or + * spectating */ }; // Player name widgets let button = Button::image(if !selected { diff --git a/voxygen/src/menu/char_selection/ui/mod.rs b/voxygen/src/menu/char_selection/ui/mod.rs index ae83da0f75..29b90c534f 100644 --- a/voxygen/src/menu/char_selection/ui/mod.rs +++ b/voxygen/src/menu/char_selection/ui/mod.rs @@ -1279,7 +1279,10 @@ impl Controls { body.skin = rng.gen_range(0, species.num_skin_colors()); body.eye_color = rng.gen_range(0, species.num_eye_colors()); body.eyes = rng.gen_range(0, species.num_eyes(body_type)); - *name = npc::get_npc_name(npc::NpcKind::Humanoid); + *name = npc::get_npc_name( + npc::NpcKind::Humanoid, + npc::BodyType::from_body(comp::Body::Humanoid(*body)), + ); } }, Message::ConfirmDeletion => {