Former-commit-id: b43b7192f7a2dd71da26182ca0c74449867381f3
This commit is contained in:
Joshua Barretto 2019-05-09 18:58:16 +01:00
parent 3b44bda43c
commit 54cc9e137a
17 changed files with 144 additions and 117 deletions

View File

@ -4,7 +4,10 @@ pub mod error;
pub mod input;
// Reexports
pub use crate::{error::Error, input::{Input, InputEvent}};
pub use crate::{
error::Error,
input::{Input, InputEvent},
};
pub use specs::join::Join;
pub use specs::Entity as EcsEntity;
@ -196,7 +199,11 @@ impl Client {
// Remove chunks that are too far from the player
let mut chunks_to_remove = Vec::new();
self.state.terrain().iter().for_each(|(key, _)| {
if (Vec2::from(chunk_pos) - Vec2::from(key)).map(|e: i32| e.abs()).reduce_max() > 6 {
if (Vec2::from(chunk_pos) - Vec2::from(key))
.map(|e: i32| e.abs())
.reduce_max()
> 6
{
chunks_to_remove.push(key);
}
});

View File

@ -203,11 +203,7 @@ impl<S: PostMsg, R: PostMsg> PostBox<S, R> {
*/
// Assemble into packet
let mut packet_bytes = msg_bytes
.len()
.to_le_bytes()
.as_ref()
.to_vec();
let mut packet_bytes = msg_bytes.len().to_le_bytes().as_ref().to_vec();
packet_bytes.push(msg_bytes.iter().fold(0, |a, x| a ^ *x));
packet_bytes.append(&mut msg_bytes);
@ -270,25 +266,32 @@ impl<S: PostMsg, R: PostMsg> PostBox<S, R> {
for _ in 0..100 {
match incoming_buf.get(0..9) {
Some(len_bytes) => {
let len = usize::from_le_bytes(<[u8; 8]>::try_from(&len_bytes[0..8]).unwrap()); // Can't fail
let len = usize::from_le_bytes(
<[u8; 8]>::try_from(&len_bytes[0..8]).unwrap(),
); // Can't fail
if len > MAX_MSG_SIZE {
recv_tx.send(Err(Error::InvalidMessage)).unwrap();
break 'work;
} else if incoming_buf.len() >= len + 9 {
let checksum_found = incoming_buf[9..len + 9].iter().fold(0, |a, x| a ^ *x);
let checksum_found =
incoming_buf[9..len + 9].iter().fold(0, |a, x| a ^ *x);
let checksum_expected = len_bytes[8];
assert_eq!(checksum_found, checksum_expected, "Message checksum failed!");
assert_eq!(
checksum_found, checksum_expected,
"Message checksum failed!"
);
let msg_bytes = lz4_compress::decompress(&incoming_buf[9..len + 9]).unwrap();
let msg_bytes =
lz4_compress::decompress(&incoming_buf[9..len + 9]).unwrap();
match bincode::deserialize(&msg_bytes) {
Ok(msg) => recv_tx.send(Ok(msg)).unwrap(),
Err(err) => {
println!("BINCODE ERROR: {:?}", err);
recv_tx.send(Err(err.into())).unwrap()
},
}
}
incoming_buf = incoming_buf.split_off(len + 9);

View File

@ -1,5 +1,5 @@
// Library
use specs::{Entities, Join, Read, ReadStorage, ReadExpect, System, WriteStorage};
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage};
use vek::*;
// Crate
@ -8,9 +8,9 @@ use crate::{
phys::{Dir, Pos, Vel},
Animation, AnimationHistory, Control,
},
state::DeltaTime,
terrain::TerrainMap,
vol::{ReadVol, Vox},
state::DeltaTime,
};
// Basic ECS AI agent system
@ -28,14 +28,18 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Control>,
);
fn run(&mut self, (terrain, dt, entities, pos, mut vels, mut dirs, mut anims, controls): Self::SystemData) {
fn run(
&mut self,
(terrain, dt, entities, pos, mut vels, mut dirs, mut anims, controls): Self::SystemData,
) {
for (entity, pos, mut vel, mut dir, control) in
(&entities, &pos, &mut vels, &mut dirs, &controls).join()
{
let on_ground = terrain
.get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32))
.map(|vox| !vox.is_empty())
.unwrap_or(false) && vel.0.z <= 0.0;
.unwrap_or(false)
&& vel.0.z <= 0.0;
if on_ground {
// TODO: Don't hard-code this
@ -64,8 +68,8 @@ impl<'a> System<'a> for Sys {
let last_history = anims.get_mut(entity).cloned();
let time = if let Some((true, time)) = last_history
.map(|last| (last.current == animation, last.time))
let time = if let Some((true, time)) =
last_history.map(|last| (last.current == animation, last.time))
{
time + dt.0 as f64
} else {

View File

@ -8,19 +8,10 @@ pub mod input;
// Reexports
pub use crate::{error::Error, input::Input};
use std::{
collections::HashSet,
net::SocketAddr,
sync::mpsc,
time::Duration,
i32,
use crate::{
client::{Client, Clients},
cmd::CHAT_COMMANDS,
};
use specs::{
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
Entity as EcsEntity,
};
use threadpool::ThreadPool;
use vek::*;
use common::{
comp,
comp::character::Animation,
@ -29,11 +20,14 @@ use common::{
state::{State, Uid},
terrain::TerrainChunk,
};
use world::World;
use crate::{
client::{Client, Clients},
cmd::CHAT_COMMANDS,
use specs::{
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
Entity as EcsEntity,
};
use std::{collections::HashSet, i32, net::SocketAddr, sync::mpsc, time::Duration};
use threadpool::ThreadPool;
use vek::*;
use world::World;
const CLIENT_TIMEOUT: f64 = 20.0; // Seconds
@ -204,7 +198,9 @@ impl Server {
.join()
{
let chunk_pos = self.state.terrain().pos_key(pos.0.map(|e| e as i32));
let dist = (Vec2::from(chunk_pos) - Vec2::from(key)).map(|e: i32| e.abs()).reduce_max();
let dist = (Vec2::from(chunk_pos) - Vec2::from(key))
.map(|e: i32| e.abs())
.reduce_max();
if dist < 5 {
self.clients.notify(

View File

@ -1,8 +1,5 @@
// Standard
use std::{
f32::consts::PI,
ops::Mul,
};
use std::{f32::consts::PI, ops::Mul};
// Library
use vek::*;
@ -16,7 +13,11 @@ impl Animation for IdleAnimation {
type Skeleton = CharacterSkeleton;
type Dependency = f64;
fn update_skeleton(skeleton: &Self::Skeleton, global_time: f64, anim_time: f64) -> Self::Skeleton {
fn update_skeleton(
skeleton: &Self::Skeleton,
global_time: f64,
anim_time: f64,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let wave = (anim_time as f32 * 12.0).sin();
@ -48,16 +49,16 @@ impl Animation for IdleAnimation {
next.shorts.scale = Vec3::one();
next.l_hand.offset = Vec3::new(
-7.5, -2.0 + waveultracos_slow * 0.3,
-7.5,
-2.0 + waveultracos_slow * 0.3,
12.0 + waveultra_slow * 1.1,
);
next.l_hand.ori = Quaternion::rotation_x(0.0 + waveultra_slow * 0.06);
next.l_hand.scale = Vec3::one();
next.r_hand.offset = Vec3::new(
7.5, -2.0 + waveultracos_slow * 0.3,
7.5,
-2.0 + waveultracos_slow * 0.3,
12.0 + waveultra_slow * 1.1,
);
next.r_hand.ori = Quaternion::rotation_x(0.0 + waveultra_slow * 0.06);

View File

@ -14,7 +14,11 @@ impl Animation for JumpAnimation {
type Skeleton = CharacterSkeleton;
type Dependency = f64;
fn update_skeleton(skeleton: &Self::Skeleton, global_time: f64, anim_time: f64) -> Self::Skeleton {
fn update_skeleton(
skeleton: &Self::Skeleton,
global_time: f64,
anim_time: f64,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let wave = (anim_time as f32 * 14.0).sin();
let arcwave = (1.0f32.ln_1p() - 1.0).abs();
@ -22,7 +26,7 @@ impl Animation for JumpAnimation {
let fuzzwave = (anim_time as f32 * 12.0).sin();
let wavecos = (anim_time as f32 * 14.0).cos();
let wave_slow = (anim_time as f32 * 5.0 + PI).min(PI / 2.0).sin();
let wave_slowtest = (anim_time as f32).min(PI/2.0).sin();
let wave_slowtest = (anim_time as f32).min(PI / 2.0).sin();
let wavecos_slow = (anim_time as f32 * 8.0 + PI).cos();
let wave_dip = (wave_slow.abs() - 0.5).abs();
let mult = wave_slow / (wave_slow.abs());

View File

@ -1,11 +1,11 @@
pub mod idle;
pub mod run;
pub mod jump;
pub mod run;
// Reexports
pub use self::idle::IdleAnimation;
pub use self::run::RunAnimation;
pub use self::jump::JumpAnimation;
pub use self::run::RunAnimation;
// Crate
use crate::render::FigureBoneData;

View File

@ -13,7 +13,11 @@ impl Animation for RunAnimation {
type Skeleton = CharacterSkeleton;
type Dependency = (f32, f64);
fn update_skeleton(skeleton: &Self::Skeleton, (velocity, global_time): Self::Dependency, anim_time: f64) -> Self::Skeleton {
fn update_skeleton(
skeleton: &Self::Skeleton,
(velocity, global_time): Self::Dependency,
anim_time: f64,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let wave = (anim_time as f32 * 14.0).sin();
@ -61,7 +65,7 @@ impl Animation for RunAnimation {
next.weapon.scale = Vec3::one();
next.torso.offset = Vec3::new(-0.5, -0.2, 0.2);
next.torso.ori = Quaternion::rotation_x( - velocity * 0.05 - wavecos * 0.1);
next.torso.ori = Quaternion::rotation_x(-velocity * 0.05 - wavecos * 0.1);
next.torso.scale = Vec3::one() / 11.0;
next.l_shoulder.offset = Vec3::new(3.0, 6.0, 18.0);

View File

@ -50,5 +50,9 @@ pub trait Animation {
type Dependency;
/// Returns a new skeleton that is generated by the animation
fn update_skeleton(skeleton: &Self::Skeleton, dependency: Self::Dependency, anim_time: f64) -> Self::Skeleton;
fn update_skeleton(
skeleton: &Self::Skeleton,
dependency: Self::Dependency,
anim_time: f64,
) -> Self::Skeleton;
}

View File

@ -1,9 +1,9 @@
use client::{error::Error as ClientError, Client};
use common::comp;
use std::{
net::ToSocketAddrs,
sync::mpsc::{channel, Receiver, TryRecvError},
thread::{self, JoinHandle},
net::ToSocketAddrs,
time::Duration,
};
@ -23,7 +23,11 @@ pub struct ClientInit {
rx: Receiver<Result<Client, Error>>,
}
impl ClientInit {
pub fn new(connection_args: (String, u16, bool), client_args: (comp::Player, u64), wait: bool) -> Self {
pub fn new(
connection_args: (String, u16, bool),
client_args: (comp::Player, u64),
wait: bool,
) -> Self {
let (server_address, default_port, prefer_ipv6) = connection_args;
let (player, view_distance) = client_args;

View File

@ -1,11 +1,11 @@
use std::net::SocketAddr;
use log::warn;
use common::comp;
use super::{client_init::ClientInit, DEFAULT_PORT};
use crate::{
menu::char_selection::CharSelectionState, singleplayer::Singleplayer, Direction, GlobalState,
PlayState, PlayStateResult,
};
use super::{client_init::ClientInit, DEFAULT_PORT};
use common::comp;
use log::warn;
use std::net::SocketAddr;
pub struct StartSingleplayerState {
singleplayer: Singleplayer,
@ -17,10 +17,7 @@ impl StartSingleplayerState {
pub fn new() -> Self {
let (singleplayer, sock) = Singleplayer::new();
Self {
singleplayer,
sock,
}
Self { singleplayer, sock }
}
}
@ -45,7 +42,7 @@ impl PlayState for StartSingleplayerState {
Some(Err(err)) => {
warn!("Failed to start singleplayer server: {:?}", err);
return PlayStateResult::Pop;
},
}
_ => {}
}
};

View File

@ -12,7 +12,7 @@ use gfx::{
// Local
use super::{
super::{Mesh, Pipeline, WinColorFmt, WinDepthFmt, Tri},
super::{Mesh, Pipeline, Tri, WinColorFmt, WinDepthFmt},
Globals,
};

View File

@ -1,4 +1,4 @@
use super::super::{Pipeline, Quad, WinColorFmt, WinDepthFmt, Tri};
use super::super::{Pipeline, Quad, Tri, WinColorFmt, WinDepthFmt};
use gfx::{
self,
// Macros

View File

@ -1,6 +1,6 @@
use crate::{
anim::{
character::{CharacterSkeleton, IdleAnimation, RunAnimation, JumpAnimation},
character::{CharacterSkeleton, IdleAnimation, JumpAnimation, RunAnimation},
Animation, Skeleton,
},
mesh::Meshable,
@ -207,15 +207,21 @@ impl FigureCache {
.or_insert_with(|| FigureState::new(renderer, CharacterSkeleton::new()));
let target_skeleton = match animation_history.current {
comp::character::Animation::Idle => {
IdleAnimation::update_skeleton(&mut state.skeleton, time, animation_history.time)
},
comp::character::Animation::Run => {
RunAnimation::update_skeleton(&mut state.skeleton, (vel.0.magnitude(), time), animation_history.time)
},
comp::character::Animation::Jump => {
JumpAnimation::update_skeleton(&mut state.skeleton, time, animation_history.time)
},
comp::character::Animation::Idle => IdleAnimation::update_skeleton(
&mut state.skeleton,
time,
animation_history.time,
),
comp::character::Animation::Run => RunAnimation::update_skeleton(
&mut state.skeleton,
(vel.0.magnitude(), time),
animation_history.time,
),
comp::character::Animation::Jump => JumpAnimation::update_skeleton(
&mut state.skeleton,
time,
animation_history.time,
),
};
state.skeleton.interpolate(&target_skeleton);
@ -266,7 +272,7 @@ impl<S: Skeleton> FigureState<S> {
fn update(&mut self, renderer: &mut Renderer, pos: Vec3<f32>, dir: Vec3<f32>) {
let mat = Mat4::<f32>::identity()
* Mat4::translation_3d(pos)
* Mat4::rotation_z(-dir.x.atan2(dir.y));// + f32::consts::PI / 2.0);
* Mat4::rotation_z(-dir.x.atan2(dir.y)); // + f32::consts::PI / 2.0);
let locals = FigureLocals::new(mat);
renderer.update_consts(&mut self.locals, &[locals]).unwrap();

View File

@ -1,17 +1,3 @@
use std::{
cell::RefCell,
rc::Rc,
time::Duration,
mem,
};
use vek::*;
use common::clock::Clock;
use client::{
self,
Client,
Input,
InputEvent,
};
use crate::{
hud::{Event as HudEvent, Hud},
key_state::KeyState,
@ -21,6 +7,10 @@ use crate::{
window::{Event, Key, Window},
Direction, Error, GlobalState, PlayState, PlayStateResult,
};
use client::{self, Client, Input, InputEvent};
use common::clock::Clock;
use std::{cell::RefCell, mem, rc::Rc, time::Duration};
use vek::*;
const FPS: u64 = 60;
@ -72,15 +62,14 @@ impl SessionState {
let mut input_events = Vec::new();
mem::swap(&mut self.input_events, &mut input_events);
for event in self
.client
.borrow_mut()
.tick(Input {
for event in self.client.borrow_mut().tick(
Input {
move_dir,
jumping: self.key_state.jump,
events: input_events,
}, dt)?
{
},
dt,
)? {
match event {
client::Event::Chat(msg) => {
self.hud.new_message(msg);
@ -155,7 +144,7 @@ impl PlayState for SessionState {
Event::KeyDown(Key::Jump) => {
self.input_events.push(InputEvent::Jump);
self.key_state.jump = true;
},
}
// Movement Key Released
Event::KeyUp(Key::MoveForward) => self.key_state.up = false,
Event::KeyUp(Key::MoveBack) => self.key_state.down = false,

View File

@ -1,13 +1,13 @@
use std::{
sync::mpsc::{channel, Receiver, Sender, TryRecvError},
time::Duration,
thread::{self, JoinHandle},
net::SocketAddr,
};
use common::clock::Clock;
use log::info;
use portpicker::pick_unused_port;
use common::clock::Clock;
use server::{Event, Input, Server};
use std::{
net::SocketAddr,
sync::mpsc::{channel, Receiver, Sender, TryRecvError},
thread::{self, JoinHandle},
time::Duration,
};
const TPS: u64 = 30;
@ -26,18 +26,23 @@ impl Singleplayer {
pub fn new() -> (Self, SocketAddr) {
let (sender, reciever) = channel();
let sock = SocketAddr::from(([127,0,0,1], pick_unused_port()
.expect("Failed to find unused port")));
let sock = SocketAddr::from((
[127, 0, 0, 1],
pick_unused_port().expect("Failed to find unused port"),
));
let sock2 = sock.clone();
let thread = thread::spawn(move || {
run_server(sock2, reciever);
});
(Singleplayer {
(
Singleplayer {
server_thread: thread,
sender,
}, sock)
},
sock,
)
}
}

View File

@ -32,12 +32,9 @@ impl World {
let dirt = Block::new(3, Rgb::new(128, 90, 0));
let sand = Block::new(4, Rgb::new(180, 150, 50));
let perlin_nz = Perlin::new()
.set_seed(1);
let temp_nz = Perlin::new()
.set_seed(2);
let chaos_nz = Perlin::new()
.set_seed(3);
let perlin_nz = Perlin::new().set_seed(1);
let temp_nz = Perlin::new().set_seed(2);
let chaos_nz = Perlin::new().set_seed(3);
for lpos in chunk.iter_positions() {
let wpos = lpos + chunk_pos * chunk.get_size().map(|e| e as i32);
@ -50,10 +47,16 @@ impl World {
let small_ampl = 6.0;
let offs = 32.0;
let chaos = chaos_nz.get(Vec2::from(wposf * chaos_freq).into_array()).max(0.0) + 0.5;
let chaos = chaos_nz
.get(Vec2::from(wposf * chaos_freq).into_array())
.max(0.0)
+ 0.5;
let height = perlin_nz.get(Vec2::from(wposf * freq).into_array()) * ampl * chaos
+ perlin_nz.get((wposf * small_freq).into_array()) * small_ampl * 2.0 * chaos.powf(2.0)
+ perlin_nz.get((wposf * small_freq).into_array())
* small_ampl
* 2.0
* chaos.powf(2.0)
+ offs;
let temp = (temp_nz.get(Vec2::from(wposf * (1.0 / 64.0)).into_array()) + 1.0) * 0.5;