diff --git a/assets/common/entity/dungeon/tier-5/cultist.ron b/assets/common/entity/dungeon/tier-5/cultist.ron index 283fd9f054..53ccc29b63 100644 --- a/assets/common/entity/dungeon/tier-5/cultist.ron +++ b/assets/common/entity/dungeon/tier-5/cultist.ron @@ -8,6 +8,7 @@ EntityConfig ( hands: TwoHanded(Choice([ (2.0, Some(Item("common.items.weapons.axe_1h.orichalcum-0"))), (4.0, Some(Item("common.items.weapons.sword.cultist"))), + (2.0, Some(Item("common.items.weapons.staff.cultist_staff"))), (2.0, Some(Item("common.items.weapons.hammer.cultist_purp_2h-0"))), (2.0, Some(Item("common.items.weapons.hammer_1h.orichalcum-0"))), (2.0, Some(Item("common.items.weapons.bow.velorite"))), diff --git a/assets/common/loadout/dungeon/tier-5/cultist.ron b/assets/common/loadout/dungeon/tier-5/cultist.ron index 426a32c963..ecfbae5e64 100644 --- a/assets/common/loadout/dungeon/tier-5/cultist.ron +++ b/assets/common/loadout/dungeon/tier-5/cultist.ron @@ -14,4 +14,14 @@ ]), Glider: Item("common.items.glider.glider_purp"), + + ActiveMainhand: Choice([ + (2.0, Some(Item("common.items.weapons.axe_1h.orichalcum-0"))), + (4.0, Some(Item("common.items.weapons.sword.cultist"))), + (2.0, Some(Item("common.items.weapons.staff.cultist_staff"))), + (2.0, Some(Item("common.items.weapons.hammer.cultist_purp_2h-0"))), + (2.0, Some(Item("common.items.weapons.hammer_1h.orichalcum-0"))), + (2.0, Some(Item("common.items.weapons.bow.velorite"))), + (1.0, Some(Item("common.items.weapons.sceptre.sceptre_velorite_0"))), + ]), }) diff --git a/server/src/rtsim/entity.rs b/server/src/rtsim/entity.rs index c154497c0f..97498fdcb4 100644 --- a/server/src/rtsim/entity.rs +++ b/server/src/rtsim/entity.rs @@ -21,10 +21,15 @@ pub struct Entity { pub seed: u32, pub last_time_ticked: f64, pub controller: RtSimController, - + pub kind: RtSimEntityKind, pub brain: Brain, } +pub enum RtSimEntityKind { + Random, + Cultist, +} + const PERM_SPECIES: u32 = 0; const PERM_BODY: u32 = 1; const PERM_LOADOUT: u32 = 2; @@ -35,22 +40,34 @@ impl Entity { pub fn rng(&self, perm: u32) -> impl Rng { RandomPerm::new(self.seed + perm) } pub fn get_body(&self) -> comp::Body { - match self.rng(PERM_GENUS).gen::() { - // we want 5% airships, 45% birds, 50% humans - x if x < 0.05 => comp::ship::Body::random_with(&mut self.rng(PERM_BODY)).into(), - x if x < 0.45 => { - let species = *(&comp::bird_medium::ALL_SPECIES) - .choose(&mut self.rng(PERM_SPECIES)) - .unwrap(); - comp::bird_medium::Body::random_with(&mut self.rng(PERM_BODY), &species).into() + match self.kind { + RtSimEntityKind::Random => { + match self.rng(PERM_GENUS).gen::() { + // we want 5% airships, 45% birds, 50% humans + x if x < 0.05 => comp::ship::Body::random_with(&mut self.rng(PERM_BODY)).into(), + x if x < 0.45 => { + let species = *(&comp::bird_medium::ALL_SPECIES) + .choose(&mut self.rng(PERM_SPECIES)) + .unwrap(); + comp::bird_medium::Body::random_with(&mut self.rng(PERM_BODY), &species) + .into() + }, + x if x < 0.50 => { + let species = *(&comp::bird_large::ALL_SPECIES) + .choose(&mut self.rng(PERM_SPECIES)) + .unwrap(); + comp::bird_large::Body::random_with(&mut self.rng(PERM_BODY), &species) + .into() + }, + _ => { + let species = *(&comp::humanoid::ALL_SPECIES) + .choose(&mut self.rng(PERM_SPECIES)) + .unwrap(); + comp::humanoid::Body::random_with(&mut self.rng(PERM_BODY), &species).into() + }, + } }, - x if x < 0.50 => { - let species = *(&comp::bird_large::ALL_SPECIES) - .choose(&mut self.rng(PERM_SPECIES)) - .unwrap(); - comp::bird_large::Body::random_with(&mut self.rng(PERM_BODY), &species).into() - }, - _ => { + RtSimEntityKind::Cultist => { let species = *(&comp::humanoid::ALL_SPECIES) .choose(&mut self.rng(PERM_SPECIES)) .unwrap(); @@ -60,30 +77,47 @@ impl Entity { } pub fn get_name(&self) -> String { - 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() + 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!(), + } }, - 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!(), + RtSimEntityKind::Cultist => "Cultist Raider".to_string(), } } pub fn get_loadout(&self) -> comp::inventory::loadout::Loadout { let mut rng = self.rng(PERM_LOADOUT); - - 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)), + 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() + }, + RtSimEntityKind::Cultist => LoadoutBuilder::from_asset_expect( + "common.loadout.dungeon.tier-5.cultist", + Some(&mut rng), ) - .build() + .build(), + } } pub fn tick(&mut self, time: &Time, terrain: &TerrainGrid, world: &World, index: &IndexRef) { diff --git a/server/src/rtsim/mod.rs b/server/src/rtsim/mod.rs index 13816809d3..239150376b 100644 --- a/server/src/rtsim/mod.rs +++ b/server/src/rtsim/mod.rs @@ -20,7 +20,7 @@ use slab::Slab; use specs::{DispatcherBuilder, WorldExt}; use vek::*; -pub use self::entity::{Entity, Brain}; +pub use self::entity::{Brain, Entity, RtSimEntityKind}; pub struct RtSim { tick: u64, @@ -104,7 +104,11 @@ pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) { ]); } -pub fn init(state: &mut State, #[cfg(feature = "worldgen")] world: &world::World, #[cfg(feature = "worldgen")] index: world::IndexRef) { +pub fn init( + state: &mut State, + #[cfg(feature = "worldgen")] world: &world::World, + #[cfg(feature = "worldgen")] index: world::IndexRef, +) { #[cfg(feature = "worldgen")] let mut rtsim = RtSim::new(world.sim().get_size()); #[cfg(not(feature = "worldgen"))] @@ -128,30 +132,35 @@ pub fn init(state: &mut State, #[cfg(feature = "worldgen")] world: &world::World seed: thread_rng().gen(), controller: RtSimController::default(), last_time_ticked: 0.0, + kind: RtSimEntityKind::Random, brain: Default::default(), }); } - for site in world.civs().sites.iter().filter_map(|(_, site)| site.site_tmp.map(|id| &index.sites[id])) { + for site in world + .civs() + .sites + .iter() + .filter_map(|(_, site)| site.site_tmp.map(|id| &index.sites[id])) + { use world::site::SiteKind; match &site.kind { - SiteKind::Dungeon(dungeon) => { - match dungeon.dungeon_difficulty() { - Some(5) => { - let pos = site.get_origin(); + SiteKind::Dungeon(dungeon) => match dungeon.dungeon_difficulty() { + Some(5) => { + let pos = site.get_origin(); - for _ in 0..25 { - rtsim.entities.insert(Entity { - is_loaded: false, - pos: Vec3::from(pos.map(|e| e as f32)), - seed: thread_rng().gen(), - controller: RtSimController::default(), - last_time_ticked: 0.0, - brain: Brain::idle(), - }); - } - }, - _ => {}, - } + for _ in 0..25 { + rtsim.entities.insert(Entity { + is_loaded: false, + pos: Vec3::from(pos.map(|e| e as f32)), + seed: thread_rng().gen(), + controller: RtSimController::default(), + last_time_ticked: 0.0, + kind: RtSimEntityKind::Cultist, + brain: Brain::idle(), + }); + } + }, + _ => {}, }, _ => {}, } diff --git a/server/src/rtsim/tick.rs b/server/src/rtsim/tick.rs index b813461e7c..4cb01ca297 100644 --- a/server/src/rtsim/tick.rs +++ b/server/src/rtsim/tick.rs @@ -146,7 +146,10 @@ impl<'a> System<'a> for Sys { body, agent, alignment: match body { - comp::Body::Humanoid(_) => comp::Alignment::Npc, + 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,