diff --git a/client/src/lib.rs b/client/src/lib.rs index 5a90e14ff8..09305ff7a8 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -7,10 +7,7 @@ use vek::*; use threadpool; // Project -use common::{ - state::State, - terrain::TerrainChunk, -}; +use common::{comp::phys::Vel, state::State, terrain::TerrainChunk}; use world::World; #[derive(Debug)] @@ -21,6 +18,7 @@ pub enum Error { pub struct Input { // TODO: Use this type to manage client input + pub move_vec: Vec2, } pub struct Client { @@ -61,6 +59,7 @@ impl Client { // TODO: Get rid of this pub fn with_test_state(mut self) -> Self { self.chunk = Some(self.world.generate_chunk(Vec3::zero())); + self.player = Some(self.state.new_test_player()); self } @@ -76,6 +75,11 @@ impl Client { /// Get a mutable reference to the client's game state. pub fn state_mut(&mut self) -> &mut State { &mut self.state } + /// Get the player entity + pub fn player(&self) -> Option { + self.player + } + /// Get the current tick number. pub fn get_tick(&self) -> u64 { self.tick @@ -95,6 +99,27 @@ impl Client { // 4) Go through the terrain update queue and apply all changes to the terrain // 5) Finish the tick, passing control of the main thread back to the frontend + // (step 1) + if let Some(p) = self.player { + let vel = input.move_vec; + + const MIN_LOOKING: f32 = 0.5; + const LEANING_FAC: f32 = 0.05; + + let dir = Vec3::from([ + // Rotation + match vel.magnitude() > MIN_LOOKING { + true => vel[0].atan2(vel[1]), + _ => 0.0, + }, + // Lean + Vec2::new(vel[0], vel[1]).magnitude() * LEANING_FAC, + ]); + + // TODO: Set acceleration instead and adjust dir calculations accordingly + self.state.write_component(p, Vel(Vec3::from(vel))); + } + // Tick the client's LocalState (step 3) self.state.tick(dt); diff --git a/common/src/lib.rs b/common/src/lib.rs index 4d33fd7988..7105e390f7 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -4,6 +4,7 @@ pub mod clock; pub mod comp; pub mod figure; pub mod state; +pub mod sys; pub mod terrain; pub mod util; pub mod volumes; diff --git a/common/src/state.rs b/common/src/state.rs index a4d974ee57..df82b00dd1 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -2,15 +2,12 @@ use std::time::Duration; // Library -use specs::World as EcsWorld; use shred::{Fetch, FetchMut}; +use specs::{Builder, Component, DispatcherBuilder, Entity as EcsEntity, World as EcsWorld}; use vek::*; // Crate -use crate::{ - comp, - terrain::TerrainMap, -}; +use crate::{comp, sys, terrain::TerrainMap}; /// How much faster should an in-game day be compared to a real day? // TODO: Don't hard-code this @@ -22,6 +19,10 @@ struct TimeOfDay(f64); /// A resource to store the tick (i.e: physics) time struct Time(f64); +/// A resource used to store the time since the last tick +#[derive(Default)] +pub struct DeltaTime(pub f64); + pub struct Changes { pub new_chunks: Vec>, pub changed_chunks: Vec>, @@ -59,6 +60,7 @@ impl State { // Register resources used by the ECS ecs_world.add_resource(TimeOfDay(0.0)); ecs_world.add_resource(Time(0.0)); + ecs_world.add_resource(DeltaTime(0.0)); ecs_world.add_resource(TerrainMap::new()); // Register common components with the state @@ -70,15 +72,36 @@ impl State { } } + // TODO: Get rid of this + pub fn new_test_player(&mut self) -> EcsEntity { + self.ecs_world + .create_entity() + .with(comp::phys::Pos(Vec3::default())) + .with(comp::phys::Vel(Vec3::default())) + .with(comp::phys::Dir(Vec3::default())) + .build() + } + + /// Write a component + pub fn write_component(&mut self, e: EcsEntity, c: C) { + let _ = self.ecs_world.write_storage().insert(e, c); + } + /// Get a reference to the internal ECS world - pub fn ecs_world(&self) -> &EcsWorld { &self.ecs_world } + pub fn ecs_world(&self) -> &EcsWorld { + &self.ecs_world + } /// Get a reference to the `Changes` structure of the state. This contains /// information about state that has changed since the last game tick. - pub fn changes(&self) -> &Changes { &self.changes } + pub fn changes(&self) -> &Changes { + &self.changes + } // TODO: Get rid of this since it shouldn't be needed - pub fn changes_mut(&mut self) -> &mut Changes { &mut self.changes } + pub fn changes_mut(&mut self) -> &mut Changes { + &mut self.changes + } /// Get the current in-game time of day. /// @@ -95,12 +118,12 @@ impl State { } /// Get a reference to this state's terrain. - pub fn terrain<'a>(&'a self) -> Fetch<'a, TerrainMap> { + pub fn terrain(&self) -> Fetch { self.ecs_world.read_resource::() } // TODO: Get rid of this since it shouldn't be needed - pub fn terrain_mut<'a>(&'a mut self) -> FetchMut<'a, TerrainMap> { + pub fn terrain_mut(&mut self) -> FetchMut { self.ecs_world.write_resource::() } @@ -109,6 +132,17 @@ impl State { // Change the time accordingly self.ecs_world.write_resource::().0 += dt.as_float_secs() * DAY_CYCLE_FACTOR; self.ecs_world.write_resource::