mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Rtsim now uses entity configs.
This commit is contained in:
parent
70c2e9bebe
commit
27823ce8fa
@ -1,6 +1,5 @@
|
||||
use super::*;
|
||||
use common::{
|
||||
comp::inventory::loadout_builder::LoadoutBuilder,
|
||||
resources::Time,
|
||||
rtsim::{Memory, MemoryItem},
|
||||
store::Id,
|
||||
@ -39,6 +38,8 @@ const PERM_GENUS: u32 = 4;
|
||||
impl Entity {
|
||||
pub fn rng(&self, perm: u32) -> impl Rng { RandomPerm::new(self.seed + perm) }
|
||||
|
||||
pub fn loadout_rng(&self) -> impl Rng { self.rng(PERM_LOADOUT) }
|
||||
|
||||
pub fn get_body(&self) -> comp::Body {
|
||||
match self.kind {
|
||||
RtSimEntityKind::Random => {
|
||||
@ -81,47 +82,30 @@ impl Entity {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> String {
|
||||
match self.kind {
|
||||
RtSimEntityKind::Random => {
|
||||
use common::{generation::get_npc_name, npc::NPC_NAMES};
|
||||
let npc_names = NPC_NAMES.read();
|
||||
match self.get_body() {
|
||||
comp::Body::BirdMedium(b) => {
|
||||
get_npc_name(&npc_names.bird_medium, b.species).to_string()
|
||||
},
|
||||
comp::Body::BirdLarge(b) => {
|
||||
get_npc_name(&npc_names.bird_large, b.species).to_string()
|
||||
},
|
||||
comp::Body::Dragon(b) => get_npc_name(&npc_names.dragon, b.species).to_string(),
|
||||
comp::Body::Humanoid(b) => {
|
||||
get_npc_name(&npc_names.humanoid, b.species).to_string()
|
||||
},
|
||||
comp::Body::Ship(_) => "Veloren Air".to_string(),
|
||||
//TODO: finish match as necessary
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
pub fn get_entity_config(&self) -> &str {
|
||||
match self.get_body() {
|
||||
comp::Body::Humanoid(_) => match self.kind {
|
||||
RtSimEntityKind::Cultist => "",
|
||||
RtSimEntityKind::Random => "",
|
||||
},
|
||||
RtSimEntityKind::Cultist => "Cultist Raider".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_loadout(&self) -> comp::inventory::loadout::Loadout {
|
||||
let mut rng = self.rng(PERM_LOADOUT);
|
||||
match self.kind {
|
||||
RtSimEntityKind::Random => {
|
||||
LoadoutBuilder::from_asset_expect("common.loadout.world.traveler", Some(&mut rng))
|
||||
.bag(
|
||||
comp::inventory::slot::ArmorSlot::Bag1,
|
||||
Some(comp::inventory::loadout_builder::make_potion_bag(100)),
|
||||
)
|
||||
.build()
|
||||
comp::Body::BirdMedium(b) => match b.species {
|
||||
comp::bird_medium::Species::Duck => "",
|
||||
comp::bird_medium::Species::Chicken => "",
|
||||
comp::bird_medium::Species::Goose => "",
|
||||
comp::bird_medium::Species::Peacock => "",
|
||||
comp::bird_medium::Species::Eagle => "",
|
||||
comp::bird_medium::Species::Owl => "",
|
||||
comp::bird_medium::Species::Parrot => "",
|
||||
},
|
||||
RtSimEntityKind::Cultist => LoadoutBuilder::from_asset_expect(
|
||||
"common.loadout.dungeon.tier-5.cultist",
|
||||
Some(&mut rng),
|
||||
)
|
||||
.build(),
|
||||
comp::Body::BirdLarge(b) => match b.species {
|
||||
comp::bird_large::Species::Phoenix => "",
|
||||
comp::bird_large::Species::Cockatrice => "",
|
||||
comp::bird_large::Species::Roc => "",
|
||||
// Wildcard match used here as there is an array above which limits what species are
|
||||
// used
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
#![allow(dead_code)] // TODO: Remove this when rtsim is fleshed out
|
||||
|
||||
use super::*;
|
||||
use crate::sys::terrain::NpcData;
|
||||
use common::{
|
||||
comp::{self, inventory::loadout_builder::LoadoutBuilder, Behavior, BehaviorCapability},
|
||||
comp,
|
||||
event::{EventBus, ServerEvent},
|
||||
generation::EntityInfo,
|
||||
resources::{DeltaTime, Time},
|
||||
terrain::TerrainGrid,
|
||||
};
|
||||
@ -106,75 +108,62 @@ impl<'a> System<'a> for Sys {
|
||||
for id in to_reify {
|
||||
rtsim.reify_entity(id);
|
||||
let entity = &rtsim.entities[id];
|
||||
let entity_config = entity.get_entity_config();
|
||||
let rtsim_entity = Some(RtSimEntity(id));
|
||||
let body = entity.get_body();
|
||||
let alignment = match body {
|
||||
comp::Body::Humanoid(_) => match entity.kind {
|
||||
RtSimEntityKind::Random => comp::Alignment::Npc,
|
||||
RtSimEntityKind::Cultist => comp::Alignment::Enemy,
|
||||
},
|
||||
comp::Body::BirdLarge(bird_large) => match bird_large.species {
|
||||
comp::bird_large::Species::Roc => comp::Alignment::Enemy,
|
||||
comp::bird_large::Species::Cockatrice => comp::Alignment::Enemy,
|
||||
_ => comp::Alignment::Wild,
|
||||
},
|
||||
_ => comp::Alignment::Wild,
|
||||
};
|
||||
let spawn_pos = terrain
|
||||
.find_space(entity.pos.map(|e| e.floor() as i32))
|
||||
.map(|e| e as f32)
|
||||
+ Vec3::new(0.5, 0.5, body.flying_height());
|
||||
let pos = comp::Pos(spawn_pos);
|
||||
let mut agent = Some(comp::Agent::from_body(&body).with_behavior(
|
||||
if matches!(body, comp::Body::Humanoid(_)) {
|
||||
Behavior::from(BehaviorCapability::SPEAK)
|
||||
} else {
|
||||
Behavior::default()
|
||||
},
|
||||
));
|
||||
|
||||
if matches!(alignment, comp::Alignment::Enemy) {
|
||||
agent = agent.map(|a| a.with_aggro_no_warn());
|
||||
}
|
||||
|
||||
let rtsim_entity = Some(RtSimEntity(id));
|
||||
|
||||
// TODO: this should be a bit more intelligent
|
||||
let loadout = match body {
|
||||
comp::Body::Humanoid(_) => entity.get_loadout(),
|
||||
_ => LoadoutBuilder::empty().with_default_maintool(&body).build(),
|
||||
};
|
||||
|
||||
let event = match body {
|
||||
comp::Body::Ship(ship) => ServerEvent::CreateShip {
|
||||
pos,
|
||||
ship,
|
||||
mountable: false,
|
||||
agent,
|
||||
rtsim_entity,
|
||||
},
|
||||
_ => ServerEvent::CreateNpc {
|
||||
pos: comp::Pos(spawn_pos),
|
||||
stats: comp::Stats::new(entity.get_name()),
|
||||
skill_set: comp::SkillSet::default(),
|
||||
health: Some(comp::Health::new(body, 10)),
|
||||
loadout,
|
||||
poise: comp::Poise::new(body),
|
||||
body,
|
||||
agent,
|
||||
alignment,
|
||||
scale: match body {
|
||||
comp::Body::Ship(_) => comp::Scale(comp::ship::AIRSHIP_SCALE),
|
||||
_ => comp::Scale(1.0),
|
||||
let mut loadout_rng = entity.loadout_rng();
|
||||
let entity_info = NpcData::from_entity_info(
|
||||
EntityInfo::at(pos.0).with_asset_expect(entity_config),
|
||||
&mut loadout_rng,
|
||||
);
|
||||
if let NpcData::Data {
|
||||
pos,
|
||||
stats,
|
||||
skill_set,
|
||||
health,
|
||||
poise,
|
||||
loadout,
|
||||
agent,
|
||||
// Body discarded here so that species and body type are consistent between
|
||||
// reifications
|
||||
body: _,
|
||||
alignment,
|
||||
scale,
|
||||
drop_item,
|
||||
} = entity_info
|
||||
{
|
||||
let event = match body {
|
||||
comp::Body::Ship(ship) => ServerEvent::CreateShip {
|
||||
pos,
|
||||
ship,
|
||||
mountable: false,
|
||||
agent,
|
||||
rtsim_entity,
|
||||
},
|
||||
// FIXME;
|
||||
// Drop loot
|
||||
drop_item: None,
|
||||
anchor: None,
|
||||
rtsim_entity,
|
||||
projectile: None,
|
||||
},
|
||||
};
|
||||
server_emitter.emit(event);
|
||||
_ => ServerEvent::CreateNpc {
|
||||
pos,
|
||||
stats,
|
||||
skill_set,
|
||||
health,
|
||||
poise,
|
||||
loadout,
|
||||
agent,
|
||||
body,
|
||||
alignment,
|
||||
scale,
|
||||
anchor: None,
|
||||
drop_item,
|
||||
rtsim_entity,
|
||||
projectile: None,
|
||||
},
|
||||
};
|
||||
server_emitter.emit(event);
|
||||
}
|
||||
}
|
||||
|
||||
// Update rtsim with real entity data
|
||||
|
@ -364,7 +364,7 @@ pub enum NpcData {
|
||||
}
|
||||
|
||||
impl NpcData {
|
||||
pub fn from_entity_info(entity: EntityInfo, rng: &mut impl Rng) -> Self {
|
||||
pub fn from_entity_info(entity: EntityInfo, loadout_rng: &mut impl Rng) -> Self {
|
||||
let EntityInfo {
|
||||
// flags
|
||||
is_waypoint,
|
||||
@ -423,7 +423,7 @@ impl NpcData {
|
||||
// If there is config, apply it.
|
||||
// If not, use default equipement for this body.
|
||||
if let Some(asset) = loadout_asset {
|
||||
loadout_builder = loadout_builder.with_asset_expect(&asset, rng);
|
||||
loadout_builder = loadout_builder.with_asset_expect(&asset, loadout_rng);
|
||||
} else {
|
||||
loadout_builder = loadout_builder.with_default_equipment(&body);
|
||||
}
|
||||
@ -465,6 +465,14 @@ impl NpcData {
|
||||
.with_no_flee(!matches!(agent_mark, Some(agent::Mark::Guard)))
|
||||
});
|
||||
|
||||
let agent = if matches!(alignment, comp::Alignment::Enemy)
|
||||
&& matches!(body, comp::Body::Humanoid(_))
|
||||
{
|
||||
agent.map(|a| a.with_aggro_no_warn())
|
||||
} else {
|
||||
agent
|
||||
};
|
||||
|
||||
NpcData::Data {
|
||||
pos: Pos(pos),
|
||||
stats,
|
||||
|
Loading…
Reference in New Issue
Block a user