2020-11-23 15:39:03 +00:00
|
|
|
#![allow(dead_code)] // TODO: Remove this when rtsim is fleshed out
|
|
|
|
|
|
|
|
mod chunks;
|
|
|
|
mod entity;
|
2020-11-11 11:42:22 +00:00
|
|
|
mod load_chunks;
|
2020-11-11 23:59:09 +00:00
|
|
|
mod tick;
|
2020-11-23 15:39:03 +00:00
|
|
|
mod unload_chunks;
|
2020-11-10 15:27:52 +00:00
|
|
|
|
2020-11-23 15:39:03 +00:00
|
|
|
use self::{chunks::Chunks, entity::Entity};
|
2020-11-11 23:59:09 +00:00
|
|
|
use common::{
|
2020-11-23 15:39:03 +00:00
|
|
|
comp,
|
|
|
|
rtsim::{RtSimController, RtSimEntity, RtSimId},
|
2020-11-11 23:59:09 +00:00
|
|
|
terrain::TerrainChunk,
|
|
|
|
vol::RectRasterableVol,
|
|
|
|
};
|
2020-12-01 12:13:07 +00:00
|
|
|
use common_sys::state::State;
|
2020-11-11 23:59:09 +00:00
|
|
|
use rand::prelude::*;
|
2020-11-23 15:39:03 +00:00
|
|
|
use slab::Slab;
|
|
|
|
use specs::{DispatcherBuilder, WorldExt};
|
|
|
|
use vek::*;
|
2020-11-11 11:42:22 +00:00
|
|
|
|
|
|
|
pub struct RtSim {
|
2020-11-12 21:31:28 +00:00
|
|
|
tick: u64,
|
|
|
|
chunks: Chunks,
|
2020-11-11 23:59:09 +00:00
|
|
|
entities: Slab<Entity>,
|
2020-11-11 11:42:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl RtSim {
|
|
|
|
pub fn new(world_chunk_size: Vec2<u32>) -> Self {
|
|
|
|
Self {
|
2020-11-12 21:31:28 +00:00
|
|
|
tick: 0,
|
|
|
|
chunks: Chunks::new(world_chunk_size),
|
2020-11-11 23:59:09 +00:00
|
|
|
entities: Slab::new(),
|
2020-11-11 11:42:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn hook_load_chunk(&mut self, key: Vec2<i32>) {
|
2020-11-12 21:31:28 +00:00
|
|
|
if let Some(chunk) = self.chunks.chunk_mut(key) {
|
2020-11-11 11:42:22 +00:00
|
|
|
if !chunk.is_loaded {
|
|
|
|
chunk.is_loaded = true;
|
2020-11-12 21:31:28 +00:00
|
|
|
self.chunks.chunks_to_load.push(key);
|
2020-11-11 11:42:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn hook_unload_chunk(&mut self, key: Vec2<i32>) {
|
2020-11-12 21:31:28 +00:00
|
|
|
if let Some(chunk) = self.chunks.chunk_mut(key) {
|
2020-11-11 11:42:22 +00:00
|
|
|
if chunk.is_loaded {
|
|
|
|
chunk.is_loaded = false;
|
2020-11-12 21:31:28 +00:00
|
|
|
self.chunks.chunks_to_unload.push(key);
|
2020-11-11 11:42:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-11 23:59:09 +00:00
|
|
|
pub fn assimilate_entity(&mut self, entity: RtSimId) {
|
2020-11-14 01:12:47 +00:00
|
|
|
// tracing::info!("Assimilated rtsim entity {}", entity);
|
2020-11-11 23:59:09 +00:00
|
|
|
self.entities.get_mut(entity).map(|e| e.is_loaded = false);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn reify_entity(&mut self, entity: RtSimId) {
|
2020-11-14 01:12:47 +00:00
|
|
|
// tracing::info!("Reified rtsim entity {}", entity);
|
2020-11-11 23:59:09 +00:00
|
|
|
self.entities.get_mut(entity).map(|e| e.is_loaded = true);
|
2020-11-11 11:42:22 +00:00
|
|
|
}
|
|
|
|
|
2020-11-11 23:59:09 +00:00
|
|
|
pub fn update_entity(&mut self, entity: RtSimId, pos: Vec3<f32>) {
|
|
|
|
self.entities.get_mut(entity).map(|e| e.pos = pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn destroy_entity(&mut self, entity: RtSimId) {
|
2020-11-14 01:12:47 +00:00
|
|
|
// tracing::info!("Destroyed rtsim entity {}", entity);
|
2020-11-11 23:59:09 +00:00
|
|
|
self.entities.remove(entity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-11 11:42:22 +00:00
|
|
|
const LOAD_CHUNK_SYS: &str = "rtsim_load_chunk_sys";
|
|
|
|
const UNLOAD_CHUNK_SYS: &str = "rtsim_unload_chunk_sys";
|
2020-11-11 23:59:09 +00:00
|
|
|
const TICK_SYS: &str = "rtsim_tick_sys";
|
2020-11-11 11:42:22 +00:00
|
|
|
|
|
|
|
pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
|
|
|
|
dispatch_builder.add(unload_chunks::Sys, UNLOAD_CHUNK_SYS, &[]);
|
2020-11-11 23:59:09 +00:00
|
|
|
dispatch_builder.add(load_chunks::Sys, LOAD_CHUNK_SYS, &[UNLOAD_CHUNK_SYS]);
|
|
|
|
dispatch_builder.add(tick::Sys, TICK_SYS, &[LOAD_CHUNK_SYS, UNLOAD_CHUNK_SYS]);
|
2020-11-11 11:42:22 +00:00
|
|
|
}
|
|
|
|
|
2020-11-25 04:55:44 +00:00
|
|
|
pub fn init(state: &mut State, #[cfg(feature = "worldgen")] world: &world::World) {
|
|
|
|
#[cfg(feature = "worldgen")]
|
2020-11-11 23:59:09 +00:00
|
|
|
let mut rtsim = RtSim::new(world.sim().get_size());
|
2020-11-25 04:55:44 +00:00
|
|
|
#[cfg(not(feature = "worldgen"))]
|
|
|
|
let mut rtsim = RtSim::new(Vec2::new(40, 40));
|
2020-11-11 23:59:09 +00:00
|
|
|
|
2021-01-15 00:42:57 +00:00
|
|
|
for _ in 0..5000 {
|
2020-11-23 15:39:03 +00:00
|
|
|
let pos = rtsim
|
|
|
|
.chunks
|
|
|
|
.size()
|
|
|
|
.map2(TerrainChunk::RECT_SIZE, |sz, chunk_sz| {
|
2021-01-26 20:23:18 +00:00
|
|
|
thread_rng().gen_range(0..sz * chunk_sz) as i32
|
2020-11-23 15:39:03 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
rtsim.entities.insert(Entity {
|
2020-11-11 23:59:09 +00:00
|
|
|
is_loaded: false,
|
|
|
|
pos: Vec3::from(pos.map(|e| e as f32)),
|
|
|
|
seed: thread_rng().gen(),
|
2020-11-12 21:31:28 +00:00
|
|
|
controller: RtSimController::default(),
|
|
|
|
last_tick: 0,
|
|
|
|
brain: Default::default(),
|
2020-11-11 23:59:09 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
state.ecs_mut().insert(rtsim);
|
2020-11-11 11:42:22 +00:00
|
|
|
state.ecs_mut().register::<RtSimEntity>();
|
|
|
|
tracing::info!("Initiated real-time world simulation");
|
2020-11-10 15:27:52 +00:00
|
|
|
}
|