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);
|
self = self.with_name(name);
|
||||||
},
|
},
|
||||||
NameKind::Automatic => {
|
NameKind::Automatic => {
|
||||||
self = self.with_automatic_name();
|
self = self.with_automatic_name(None);
|
||||||
},
|
},
|
||||||
NameKind::Uninit => {},
|
NameKind::Uninit => {},
|
||||||
}
|
}
|
||||||
@ -408,7 +408,7 @@ impl EntityInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[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 npc_names = NPC_NAMES.read();
|
||||||
let name = match &self.body {
|
let name = match &self.body {
|
||||||
Body::Humanoid(body) => Some(get_npc_name(&npc_names.humanoid, body.species)),
|
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)),
|
Body::Arthropod(body) => Some(get_npc_name(&npc_names.arthropod, body.species)),
|
||||||
_ => None,
|
_ => 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
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,25 +287,6 @@ pub enum Profession {
|
|||||||
Captain,
|
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)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct WorldSettings {
|
pub struct WorldSettings {
|
||||||
pub start_time: f64,
|
pub start_time: f64,
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
use crate::ai::Action;
|
use crate::{ai::Action, gen::name};
|
||||||
pub use common::rtsim::{NpcId, Profession};
|
pub use common::rtsim::{NpcId, Profession};
|
||||||
use common::{
|
use common::{
|
||||||
comp,
|
comp,
|
||||||
grid::Grid,
|
grid::Grid,
|
||||||
rtsim::{
|
rtsim::{
|
||||||
Actor, ChunkResource, FactionId, NpcAction, NpcActivity, NpcMsg, Personality, SiteId,
|
Actor, ChunkResource, FactionId, NpcAction, NpcActivity, Personality, SiteId, VehicleId,
|
||||||
VehicleId,
|
|
||||||
},
|
},
|
||||||
store::Id,
|
store::Id,
|
||||||
terrain::TerrainChunkSize,
|
terrain::TerrainChunkSize,
|
||||||
@ -136,6 +135,9 @@ impl Clone for Npc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
pub fn new(seed: u32, wpos: Vec3<f32>, body: comp::Body) -> Self {
|
||||||
Self {
|
Self {
|
||||||
seed,
|
seed,
|
||||||
@ -191,6 +193,8 @@ impl Npc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn rng(&self, perm: u32) -> impl Rng { RandomPerm::new(self.seed.wrapping_add(perm)) }
|
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)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
@ -297,10 +301,11 @@ impl Npcs {
|
|||||||
pub fn nearby(
|
pub fn nearby(
|
||||||
&self,
|
&self,
|
||||||
this_npc: Option<NpcId>,
|
this_npc: Option<NpcId>,
|
||||||
wpos: Vec2<f32>,
|
wpos: Vec3<f32>,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
) -> impl Iterator<Item = Actor> + '_ {
|
) -> impl Iterator<Item = Actor> + '_ {
|
||||||
let chunk_pos = wpos
|
let chunk_pos = wpos
|
||||||
|
.xy()
|
||||||
.as_::<i32>()
|
.as_::<i32>()
|
||||||
.map2(TerrainChunkSize::RECT_SIZE.as_::<i32>(), |e, sz| {
|
.map2(TerrainChunkSize::RECT_SIZE.as_::<i32>(), |e, sz| {
|
||||||
e.div_euclid(sz)
|
e.div_euclid(sz)
|
||||||
@ -316,7 +321,7 @@ impl Npcs {
|
|||||||
.filter(move |npc| {
|
.filter(move |npc| {
|
||||||
self.npcs
|
self.npcs
|
||||||
.get(*npc)
|
.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
|
&& Some(*npc) != this_npc
|
||||||
})
|
})
|
||||||
.map(Actor::Npc)
|
.map(Actor::Npc)
|
||||||
@ -328,7 +333,7 @@ impl Npcs {
|
|||||||
.get(&chunk_pos)
|
.get(&chunk_pos)
|
||||||
.map(|characters| {
|
.map(|characters| {
|
||||||
characters.iter().filter_map(move |(character, c_wpos)| {
|
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))
|
Some(Actor::Character(*character))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
pub mod faction;
|
pub mod faction;
|
||||||
|
pub mod name;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
|
|
||||||
use crate::data::{
|
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
|
.state
|
||||||
.data()
|
.data()
|
||||||
.npcs
|
.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)
|
.choose(&mut ctx.rng)
|
||||||
{
|
{
|
||||||
just(move |ctx| ctx.controller.say(other, "npc-speech-villager_open")).boxed()
|
just(move |ctx| ctx.controller.say(other, "npc-speech-villager_open")).boxed()
|
||||||
@ -654,7 +654,7 @@ fn villager(visiting_site: SiteId) -> impl Action {
|
|||||||
.state
|
.state
|
||||||
.data()
|
.data()
|
||||||
.npcs
|
.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)
|
.choose(&mut ctx.rng)
|
||||||
{
|
{
|
||||||
(Some(other), &[
|
(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 {
|
fn get_npc_entity_info(npc: &Npc, sites: &Sites, index: IndexRef) -> EntityInfo {
|
||||||
let pos = comp::Pos(npc.wpos);
|
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 {
|
if let Some(ref profession) = npc.profession {
|
||||||
let economy = npc.home.and_then(|home| {
|
let economy = npc.home.and_then(|home| {
|
||||||
let site = sites.get(home)?.world_site?;
|
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_economy(economy.as_ref())
|
||||||
.with_lazy_loadout(profession_extra_loadout(npc.profession.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()))
|
.with_agent_mark(profession_agent_mark(npc.profession.as_ref()))
|
||||||
} else {
|
} else {
|
||||||
let config_asset = match npc.body {
|
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),
|
quadruped_small::Body::random_with(dynamic_rng, &species),
|
||||||
))
|
))
|
||||||
.with_alignment(comp::Alignment::Tame)
|
.with_alignment(comp::Alignment::Tame)
|
||||||
.with_automatic_name()
|
.with_automatic_name(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bird(pos: Vec3<f32>, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
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,
|
&species,
|
||||||
)))
|
)))
|
||||||
.with_alignment(comp::Alignment::Tame)
|
.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 {
|
fn humanoid(pos: Vec3<f32>, economy: &SiteInformation, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
||||||
|
Loading…
Reference in New Issue
Block a user