mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Gave NPCs names
This commit is contained in:
parent
74610833d0
commit
a7a08763f2
@ -256,7 +256,7 @@ impl EntityInfo {
|
||||
self = self.with_name(name);
|
||||
},
|
||||
NameKind::Automatic => {
|
||||
self = self.with_automatic_name();
|
||||
self = self.with_automatic_name(None);
|
||||
},
|
||||
NameKind::Uninit => {},
|
||||
}
|
||||
@ -408,7 +408,7 @@ impl EntityInfo {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_automatic_name(mut self) -> Self {
|
||||
pub fn with_automatic_name(mut self, alias: Option<String>) -> Self {
|
||||
let npc_names = NPC_NAMES.read();
|
||||
let name = match &self.body {
|
||||
Body::Humanoid(body) => Some(get_npc_name(&npc_names.humanoid, body.species)),
|
||||
@ -430,7 +430,23 @@ impl EntityInfo {
|
||||
Body::Arthropod(body) => Some(get_npc_name(&npc_names.arthropod, body.species)),
|
||||
_ => None,
|
||||
};
|
||||
self.name = name.map(str::to_owned);
|
||||
self.name = name.map(|name| {
|
||||
if let Some(alias) = alias {
|
||||
format!("{alias} ({name})")
|
||||
} else {
|
||||
name.to_string()
|
||||
}
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_alias(mut self, alias: String) -> Self {
|
||||
self.name = Some(if let Some(name) = self.name {
|
||||
format!("{alias} ({name})")
|
||||
} else {
|
||||
alias
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -287,25 +287,6 @@ pub enum Profession {
|
||||
Captain,
|
||||
}
|
||||
|
||||
impl Profession {
|
||||
pub fn to_name(&self) -> String {
|
||||
match self {
|
||||
Self::Farmer => "Farmer".to_string(),
|
||||
Self::Hunter => "Hunter".to_string(),
|
||||
Self::Merchant => "Merchant".to_string(),
|
||||
Self::Guard => "Guard".to_string(),
|
||||
Self::Adventurer(_) => "Adventurer".to_string(),
|
||||
Self::Blacksmith => "Blacksmith".to_string(),
|
||||
Self::Chef => "Chef".to_string(),
|
||||
Self::Alchemist => "Alchemist".to_string(),
|
||||
Self::Pirate => "Pirate".to_string(),
|
||||
Self::Cultist => "Cultist".to_string(),
|
||||
Self::Herbalist => "Herbalist".to_string(),
|
||||
Self::Captain => "Captain".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct WorldSettings {
|
||||
pub start_time: f64,
|
||||
|
@ -1,11 +1,10 @@
|
||||
use crate::ai::Action;
|
||||
use crate::{ai::Action, gen::name};
|
||||
pub use common::rtsim::{NpcId, Profession};
|
||||
use common::{
|
||||
comp,
|
||||
grid::Grid,
|
||||
rtsim::{
|
||||
Actor, ChunkResource, FactionId, NpcAction, NpcActivity, NpcMsg, Personality, SiteId,
|
||||
VehicleId,
|
||||
Actor, ChunkResource, FactionId, NpcAction, NpcActivity, Personality, SiteId, VehicleId,
|
||||
},
|
||||
store::Id,
|
||||
terrain::TerrainChunkSize,
|
||||
@ -136,6 +135,9 @@ impl Clone for Npc {
|
||||
}
|
||||
|
||||
impl Npc {
|
||||
pub const PERM_ENTITY_CONFIG: u32 = 1;
|
||||
const PERM_NAME: u32 = 0;
|
||||
|
||||
pub fn new(seed: u32, wpos: Vec3<f32>, body: comp::Body) -> Self {
|
||||
Self {
|
||||
seed,
|
||||
@ -191,6 +193,8 @@ impl Npc {
|
||||
}
|
||||
|
||||
pub fn rng(&self, perm: u32) -> impl Rng { RandomPerm::new(self.seed.wrapping_add(perm)) }
|
||||
|
||||
pub fn get_name(&self) -> String { name::generate(&mut self.rng(Self::PERM_NAME)) }
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
@ -297,10 +301,11 @@ impl Npcs {
|
||||
pub fn nearby(
|
||||
&self,
|
||||
this_npc: Option<NpcId>,
|
||||
wpos: Vec2<f32>,
|
||||
wpos: Vec3<f32>,
|
||||
radius: f32,
|
||||
) -> impl Iterator<Item = Actor> + '_ {
|
||||
let chunk_pos = wpos
|
||||
.xy()
|
||||
.as_::<i32>()
|
||||
.map2(TerrainChunkSize::RECT_SIZE.as_::<i32>(), |e, sz| {
|
||||
e.div_euclid(sz)
|
||||
@ -316,7 +321,7 @@ impl Npcs {
|
||||
.filter(move |npc| {
|
||||
self.npcs
|
||||
.get(*npc)
|
||||
.map_or(false, |npc| npc.wpos.xy().distance_squared(wpos) < r_sqr)
|
||||
.map_or(false, |npc| npc.wpos.distance_squared(wpos) < r_sqr)
|
||||
&& Some(*npc) != this_npc
|
||||
})
|
||||
.map(Actor::Npc)
|
||||
@ -328,7 +333,7 @@ impl Npcs {
|
||||
.get(&chunk_pos)
|
||||
.map(|characters| {
|
||||
characters.iter().filter_map(move |(character, c_wpos)| {
|
||||
if c_wpos.xy().distance_squared(wpos) < r_sqr {
|
||||
if c_wpos.distance_squared(wpos) < r_sqr {
|
||||
Some(Actor::Character(*character))
|
||||
} else {
|
||||
None
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod faction;
|
||||
pub mod name;
|
||||
pub mod site;
|
||||
|
||||
use crate::data::{
|
||||
|
22
rtsim/src/gen/name.rs
Normal file
22
rtsim/src/gen/name.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use rand::prelude::*;
|
||||
|
||||
pub fn generate(rng: &mut impl Rng) -> String {
|
||||
let starts = ["ad", "tr", "b", "l", "p", "d", "r", "w", "t", "fr", "s"];
|
||||
let vowels = ["o", "e", "a", "i"];
|
||||
let cons = ["m", "d", "st", "n", "y", "gh", "s"];
|
||||
|
||||
let mut name = String::new();
|
||||
|
||||
name += starts.choose(rng).unwrap();
|
||||
|
||||
for _ in 0..thread_rng().gen_range(1..=3) {
|
||||
name += vowels.choose(rng).unwrap();
|
||||
name += cons.choose(rng).unwrap();
|
||||
}
|
||||
|
||||
// Make the first letter uppercase (hacky)
|
||||
name.chars()
|
||||
.enumerate()
|
||||
.map(|(i, c)| if i == 0 { c.to_ascii_uppercase() } else { c })
|
||||
.collect()
|
||||
}
|
@ -464,7 +464,7 @@ fn socialize() -> impl Action {
|
||||
.state
|
||||
.data()
|
||||
.npcs
|
||||
.nearby(Some(ctx.npc_id), ctx.npc.wpos.xy(), 8.0)
|
||||
.nearby(Some(ctx.npc_id), ctx.npc.wpos, 8.0)
|
||||
.choose(&mut ctx.rng)
|
||||
{
|
||||
just(move |ctx| ctx.controller.say(other, "npc-speech-villager_open")).boxed()
|
||||
@ -654,7 +654,7 @@ fn villager(visiting_site: SiteId) -> impl Action {
|
||||
.state
|
||||
.data()
|
||||
.npcs
|
||||
.nearby(Some(ctx.npc_id), ctx.npc.wpos.xy(), 8.0)
|
||||
.nearby(Some(ctx.npc_id), ctx.npc.wpos, 8.0)
|
||||
.choose(&mut ctx.rng)
|
||||
{
|
||||
(Some(other), &[
|
||||
|
@ -130,7 +130,7 @@ fn profession_agent_mark(profession: Option<&Profession>) -> Option<comp::agent:
|
||||
fn get_npc_entity_info(npc: &Npc, sites: &Sites, index: IndexRef) -> EntityInfo {
|
||||
let pos = comp::Pos(npc.wpos);
|
||||
|
||||
let mut rng = npc.rng(3);
|
||||
let mut rng = npc.rng(Npc::PERM_ENTITY_CONFIG);
|
||||
if let Some(ref profession) = npc.profession {
|
||||
let economy = npc.home.and_then(|home| {
|
||||
let site = sites.get(home)?.world_site?;
|
||||
@ -150,6 +150,7 @@ fn get_npc_entity_info(npc: &Npc, sites: &Sites, index: IndexRef) -> EntityInfo
|
||||
})
|
||||
.with_economy(economy.as_ref())
|
||||
.with_lazy_loadout(profession_extra_loadout(npc.profession.as_ref()))
|
||||
.with_alias(npc.get_name())
|
||||
.with_agent_mark(profession_agent_mark(npc.profession.as_ref()))
|
||||
} else {
|
||||
let config_asset = match npc.body {
|
||||
|
@ -973,7 +973,7 @@ fn barnyard(pos: Vec3<f32>, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
||||
quadruped_small::Body::random_with(dynamic_rng, &species),
|
||||
))
|
||||
.with_alignment(comp::Alignment::Tame)
|
||||
.with_automatic_name()
|
||||
.with_automatic_name(None)
|
||||
}
|
||||
|
||||
fn bird(pos: Vec3<f32>, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
||||
@ -990,7 +990,7 @@ fn bird(pos: Vec3<f32>, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
||||
&species,
|
||||
)))
|
||||
.with_alignment(comp::Alignment::Tame)
|
||||
.with_automatic_name()
|
||||
.with_automatic_name(None)
|
||||
}
|
||||
|
||||
fn humanoid(pos: Vec3<f32>, economy: &SiteInformation, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user