Added initial impl of factions

This commit is contained in:
Joshua Barretto 2022-08-15 15:00:39 +01:00
parent ca02b5e97c
commit feaaaa9a25
9 changed files with 115 additions and 26 deletions

View File

@ -13,6 +13,8 @@ slotmap::new_key_type! { pub struct NpcId; }
slotmap::new_key_type! { pub struct SiteId; }
slotmap::new_key_type! { pub struct FactionId; }
#[derive(Copy, Clone, Debug)]
pub struct RtSimEntity(pub NpcId);

36
rtsim/src/data/faction.rs Normal file
View File

@ -0,0 +1,36 @@
use hashbrown::HashMap;
use serde::{Serialize, Deserialize};
use slotmap::HopSlotMap;
use vek::*;
use std::ops::{Deref, DerefMut};
use common::{
uid::Uid,
store::Id,
};
use super::Actor;
pub use common::rtsim::FactionId;
#[derive(Clone, Serialize, Deserialize)]
pub struct Faction {
pub leader: Option<Actor>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct Factions {
pub factions: HopSlotMap<FactionId, Faction>,
}
impl Factions {
pub fn create(&mut self, faction: Faction) -> FactionId {
self.factions.insert(faction)
}
}
impl Deref for Factions {
type Target = HopSlotMap<FactionId, Faction>;
fn deref(&self) -> &Self::Target { &self.factions }
}
impl DerefMut for Factions {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.factions }
}

View File

@ -1,3 +1,4 @@
pub mod faction;
pub mod npc;
pub mod site;
pub mod nature;
@ -5,6 +6,7 @@ pub mod nature;
pub use self::{
npc::{Npc, NpcId, Npcs},
site::{Site, SiteId, Sites},
faction::{Faction, FactionId, Factions},
nature::Nature,
};
@ -29,6 +31,7 @@ pub struct Data {
pub nature: Nature,
pub npcs: Npcs,
pub sites: Sites,
pub factions: Factions,
pub time_of_day: TimeOfDay,
}

View File

@ -7,7 +7,7 @@ use std::ops::{Deref, DerefMut};
use common::{
uid::Uid,
store::Id,
rtsim::{SiteId, RtSimController},
rtsim::{SiteId, FactionId, RtSimController},
comp,
};
use world::util::RandomPerm;
@ -32,6 +32,7 @@ pub struct Npc {
pub profession: Option<Profession>,
pub home: Option<SiteId>,
pub faction: Option<FactionId>,
// Unpersisted state
@ -55,18 +56,24 @@ impl Npc {
wpos,
profession: None,
home: None,
faction: None,
target: None,
mode: NpcMode::Simulated,
}
}
pub fn with_profession(mut self, profession: Profession) -> Self {
self.profession = Some(profession);
pub fn with_profession(mut self, profession: impl Into<Option<Profession>>) -> Self {
self.profession = profession.into();
self
}
pub fn with_home(mut self, home: SiteId) -> Self {
self.home = Some(home);
pub fn with_home(mut self, home: impl Into<Option<SiteId>>) -> Self {
self.home = home.into();
self
}
pub fn with_faction(mut self, faction: impl Into<Option<FactionId>>) -> Self {
self.faction = faction.into();
self
}

View File

@ -6,6 +6,7 @@ use std::ops::{Deref, DerefMut};
use common::{
uid::Uid,
store::Id,
rtsim::FactionId,
};
pub use common::rtsim::SiteId;
use world::site::Site as WorldSite;
@ -13,6 +14,7 @@ use world::site::Site as WorldSite;
#[derive(Clone, Serialize, Deserialize)]
pub struct Site {
pub wpos: Vec2<i32>,
pub faction: Option<FactionId>,
/// The site generated during initial worldgen that this site corresponds to.
///
@ -26,6 +28,13 @@ pub struct Site {
pub world_site: Option<Id<WorldSite>>,
}
impl Site {
pub fn with_faction(mut self, faction: impl Into<Option<FactionId>>) -> Self {
self.faction = faction.into();
self
}
}
#[derive(Clone, Serialize, Deserialize)]
pub struct Sites {
pub sites: HopSlotMap<SiteId, Site>,

13
rtsim/src/gen/faction.rs Normal file
View File

@ -0,0 +1,13 @@
use crate::data::Faction;
use vek::*;
use rand::prelude::*;
use world::{
World,
IndexRef,
};
impl Faction {
pub fn generate(world: &World, index: IndexRef, rng: &mut impl Rng) -> Self {
Self { leader: None }
}
}

View File

@ -1,17 +1,22 @@
pub mod site;
pub mod faction;
use crate::data::{
npc::{Npcs, Npc, Profession},
site::{Sites, Site},
faction::{Factions, Faction},
Data,
Nature,
};
use hashbrown::HashMap;
use rand::prelude::*;
use tracing::info;
use vek::*;
use common::{
rtsim::WorldSettings,
resources::TimeOfDay,
terrain::TerrainChunkSize,
vol::RectVolSize,
};
use world::{
site::SiteKind,
@ -29,16 +34,29 @@ impl Data {
nature: Nature::generate(world),
npcs: Npcs { npcs: Default::default() },
sites: Sites { sites: Default::default() },
factions: Factions { factions: Default::default() },
time_of_day: TimeOfDay(settings.start_time),
};
let initial_factions = (0..10)
.map(|_| {
let faction = Faction::generate(world, index, &mut rng);
let wpos = world
.sim()
.get_size()
.map2(TerrainChunkSize::RECT_SIZE, |e, sz| rng.gen_range(0..(e * sz) as i32));
(wpos, this.factions.create(faction))
})
.collect::<Vec<_>>();
info!("Generated {} rtsim factions.", this.factions.len());
// Register sites with rtsim
for (world_site_id, _) in index
.sites
.iter()
{
let site = Site::generate(world_site_id, world, index);
let site = Site::generate(world_site_id, world, index, &initial_factions);
this.sites.create(site);
}
info!("Registering {} rtsim sites from world sites.", this.sites.len());
@ -52,17 +70,20 @@ impl Data {
};
for _ in 0..20 {
this.npcs.create(Npc::new(rng.gen(), rand_wpos(&mut rng)).with_home(site_id).with_profession(match rng.gen_range(0..15) {
0 => Profession::Hunter,
1 => Profession::Blacksmith,
2 => Profession::Chef,
3 => Profession::Alchemist,
5..=10 => Profession::Farmer,
_ => Profession::Guard,
}));
this.npcs.create(Npc::new(rng.gen(), rand_wpos(&mut rng))
.with_faction(site.faction)
.with_home(site_id).with_profession(match rng.gen_range(0..15) {
0 => Profession::Hunter,
1 => Profession::Blacksmith,
2 => Profession::Chef,
3 => Profession::Alchemist,
5..=10 => Profession::Farmer,
_ => Profession::Guard,
}));
}
this.npcs.create(Npc::new(rng.gen(), rand_wpos(&mut rng)).with_home(site_id).with_profession(Profession::Merchant));
}
info!("Generated {} rtsim NPCs.", this.npcs.len());
this
}

View File

@ -1,5 +1,6 @@
use crate::data::Site;
use crate::data::{Site, FactionId};
use common::store::Id;
use vek::*;
use world::{
site::Site as WorldSite,
World,
@ -7,19 +8,16 @@ use world::{
};
impl Site {
pub fn generate(world_site: Id<WorldSite>, world: &World, index: IndexRef) -> Self {
// match &world_site.kind {
// SiteKind::Refactor(site2) => {
// let site = Site::generate(world_site_id, world, index);
// println!("Registering rtsim site at {:?}...", site.wpos);
// this.sites.create(site);
// }
// _ => {},
// }
pub fn generate(world_site: Id<WorldSite>, world: &World, index: IndexRef, nearby_factions: &[(Vec2<i32>, FactionId)]) -> Self {
let wpos = index.sites.get(world_site).get_origin();
Self {
wpos: index.sites.get(world_site).get_origin(),
wpos,
world_site: Some(world_site),
faction: nearby_factions
.iter()
.min_by_key(|(faction_wpos, _)| faction_wpos.distance_squared(wpos))
.map(|(_, faction)| *faction),
}
}
}

View File

@ -41,7 +41,7 @@ impl Rule for Setup {
warn!("{:?} is new and does not have a corresponding rtsim site. One will now be generated afresh.", world_site_id);
data
.sites
.create(Site::generate(world_site_id, ctx.world, ctx.index));
.create(Site::generate(world_site_id, ctx.world, ctx.index, &[]));
}
}