Made waypoints work, added waypoint spawning

This commit is contained in:
Joshua Barretto 2020-01-25 12:27:36 +00:00
parent 11193a692a
commit d04a595b3f
7 changed files with 65 additions and 12 deletions

View File

@ -24,6 +24,12 @@ impl Component for Waypoint {
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct WaypointArea(f32);
impl WaypointArea {
pub fn radius(&self) -> f32 {
self.0
}
}
impl Component for WaypointArea {
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
}

View File

@ -1,11 +1,8 @@
use crate::terrain::TerrainGrid;
use crate::{
comp::{
self, Agent, Alignment, CharacterState, Controller, MountState, MovementState::Glide, Pos,
Stats,
},
comp::{self, Agent, Alignment, CharacterState, Controller, MountState, Pos, Stats},
state::Time,
sync::{Uid, UidAllocator},
sync::UidAllocator,
};
use rand::{seq::SliceRandom, thread_rng, Rng};
use specs::{

View File

@ -4,6 +4,7 @@ pub mod sentinel;
pub mod subscription;
pub mod terrain;
pub mod terrain_sync;
pub mod waypoint;
use specs::DispatcherBuilder;
use std::{marker::PhantomData, time::Instant};
@ -21,6 +22,7 @@ const SENTINEL_SYS: &str = "sentinel_sys";
const SUBSCRIPTION_SYS: &str = "server_subscription_sys";
const TERRAIN_SYNC_SYS: &str = "server_terrain_sync_sys";
const TERRAIN_SYS: &str = "server_terrain_sys";
const WAYPOINT_SYS: &str = "waypoint_sys";
pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
// TODO: makes some of these dependent on systems in common like the phys system
@ -37,6 +39,7 @@ pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
);
dispatch_builder.add(terrain_sync::Sys, TERRAIN_SYS, &[]);
dispatch_builder.add(terrain::Sys, TERRAIN_SYNC_SYS, &[TERRAIN_SYS]);
dispatch_builder.add(waypoint::Sys, WAYPOINT_SYS, &[]);
}
/// Used to keep track of how much time each system takes

View File

@ -0,0 +1,32 @@
use common::comp::{Player, Pos, Waypoint, WaypointArea};
use specs::{Entities, Join, Read, ReadStorage, System, Write, WriteStorage};
/// This system will handle loading generated chunks and unloading uneeded chunks.
/// 1. Inserts newly generated chunks into the TerrainGrid
/// 2. Sends new chunks to neaby clients
/// 3. Handles the chunk's supplement (e.g. npcs)
/// 4. Removes chunks outside the range of players
pub struct Sys;
impl<'a> System<'a> for Sys {
type SystemData = (
Entities<'a>,
ReadStorage<'a, Pos>,
ReadStorage<'a, Player>,
ReadStorage<'a, WaypointArea>,
WriteStorage<'a, Waypoint>,
);
fn run(
&mut self,
(entities, positions, players, waypoint_areas, mut waypoints): Self::SystemData,
) {
for (entity, player_pos, _) in (&entities, &positions, &players).join() {
for (waypoint_pos, waypoint_area) in (&positions, &waypoint_areas).join() {
if player_pos.0.distance_squared(waypoint_pos.0) < waypoint_area.radius().powf(2.0)
{
let _ = waypoints.insert(entity, Waypoint::new(player_pos.0));
}
}
}
}
}

View File

@ -30,6 +30,15 @@ impl World {
]);
let height = rng.gen::<i32>() % 8;
let mut supplement = ChunkSupplement::default();
if chunk_pos.map(|e| e % 3 == 0).reduce_and() {
supplement = supplement.with_entity(EntityInfo {
pos: Vec3::<f32>::from(chunk_pos.map(|e| e as f32 * 32.0)) + Vec3::unit_z() * 256.0,
kind: EntityKind::Waypoint,
});
}
Ok((
TerrainChunk::new(
256 + if rng.gen::<u8>() < 64 { height } else { 0 },
@ -37,10 +46,7 @@ impl World {
Block::empty(),
TerrainChunkMeta::void(),
),
ChunkSupplement::default().with_entity(EntityInfo {
pos: Vec3::<f32>::from(chunk_pos.map(|e| e as f32 * 32.0)) + Vec3::unit_z() * 256.0,
kind: EntityKind::Waypoint,
}),
supplement,
))
}
}

View File

@ -112,7 +112,7 @@ impl FigureMgr {
for (entity, pos, ori, scale, body, character, last_character, stats) in (
&ecs.entities(),
&ecs.read_storage::<Pos>(),
&ecs.read_storage::<Ori>(),
ecs.read_storage::<Ori>().maybe(),
ecs.read_storage::<Scale>().maybe(),
&ecs.read_storage::<Body>(),
ecs.read_storage::<CharacterState>().maybe(),
@ -121,6 +121,8 @@ impl FigureMgr {
)
.join()
{
let ori = ori.copied().unwrap_or(Ori(Vec3::unit_y()));
// Don't process figures outside the vd
let vd_frac = Vec2::from(pos.0 - player_pos)
.map2(TerrainChunk::RECT_SIZE, |d: f32, sz| {
@ -1225,7 +1227,7 @@ impl FigureMgr {
for (entity, _, _, body, stats, _) in (
&ecs.entities(),
&ecs.read_storage::<Pos>(),
&ecs.read_storage::<Ori>(),
ecs.read_storage::<Ori>().maybe(),
&ecs.read_storage::<Body>(),
ecs.read_storage::<Stats>().maybe(),
ecs.read_storage::<Scale>().maybe(),

View File

@ -149,7 +149,7 @@ impl World {
const SPAWN_RATE: f32 = 0.1;
const BOSS_RATE: f32 = 0.03;
let supplement = ChunkSupplement {
let mut supplement = ChunkSupplement {
entities: if rand::thread_rng().gen::<f32>() < SPAWN_RATE
&& sim_chunk.chaos < 0.5
&& !sim_chunk.is_underwater
@ -167,6 +167,13 @@ impl World {
},
};
if chunk_pos.map(|e| e % 8 == 0).reduce_and() {
supplement = supplement.with_entity(EntityInfo {
pos: gen_entity_pos(),
kind: EntityKind::Waypoint,
});
}
Ok((chunk, supplement))
}
}