mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix #21 by checking animation history
Former-commit-id: 5272d1d7aee73fc07edeb31d9f29238d19b7d229
This commit is contained in:
parent
1e4d02a5d8
commit
b9607ef405
@ -168,8 +168,12 @@ impl Client {
|
||||
}
|
||||
|
||||
// Update the server about the player's currently playing animation
|
||||
if let Some(animation) = self.state.read_storage().get(self.player).cloned() {
|
||||
self.postbox.send_message(ClientMsg::PlayerAnimation(animation));
|
||||
if let Some(animationHistory) = self.state.read_storage::<comp::AnimationHistory>().get(self.player).cloned() {
|
||||
if let Some(last) = animationHistory.last {
|
||||
if animationHistory.current != last {
|
||||
self.postbox.send_message(ClientMsg::PlayerAnimation(animationHistory));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Request chunks from the server
|
||||
@ -228,9 +232,9 @@ impl Client {
|
||||
},
|
||||
None => {},
|
||||
},
|
||||
ServerMsg::EntityAnimation { entity, animation } => match self.state.ecs().entity_from_uid(entity) {
|
||||
ServerMsg::EntityAnimation { entity, animationHistory } => match self.state.ecs().entity_from_uid(entity) {
|
||||
Some(entity) => {
|
||||
self.state.write_component(entity, animation);
|
||||
self.state.write_component(entity, animationHistory);
|
||||
},
|
||||
None => {},
|
||||
},
|
||||
|
@ -19,6 +19,12 @@ pub enum Gender {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AnimationHistory {
|
||||
pub last: Option<Animation>,
|
||||
pub current: Animation,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Animation {
|
||||
Idle,
|
||||
Run,
|
||||
@ -55,6 +61,6 @@ impl Component for Character {
|
||||
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
|
||||
}
|
||||
|
||||
impl Component for Animation {
|
||||
impl Component for AnimationHistory {
|
||||
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
|
||||
}
|
||||
|
@ -7,4 +7,5 @@ pub mod phys;
|
||||
pub use agent::{Agent, Control};
|
||||
pub use character::Character;
|
||||
pub use player::Player;
|
||||
pub use character::AnimationHistory;
|
||||
pub use character::Animation;
|
||||
|
@ -11,7 +11,7 @@ pub enum ClientMsg {
|
||||
Ping,
|
||||
Pong,
|
||||
Chat(String),
|
||||
PlayerAnimation(comp::character::Animation),
|
||||
PlayerAnimation(comp::character::AnimationHistory),
|
||||
PlayerPhysics {
|
||||
pos: comp::phys::Pos,
|
||||
vel: comp::phys::Vel,
|
||||
|
@ -25,7 +25,7 @@ pub enum ServerMsg {
|
||||
},
|
||||
EntityAnimation {
|
||||
entity: u64,
|
||||
animation: comp::Animation,
|
||||
animationHistory: comp::AnimationHistory,
|
||||
},
|
||||
TerrainChunkUpdate {
|
||||
key: Vec3<i32>,
|
||||
|
@ -100,7 +100,7 @@ impl State {
|
||||
ecs.internal_mut().register::<comp::phys::Pos>();
|
||||
ecs.internal_mut().register::<comp::phys::Vel>();
|
||||
ecs.internal_mut().register::<comp::phys::Dir>();
|
||||
ecs.internal_mut().register::<comp::Animation>();
|
||||
ecs.internal_mut().register::<comp::AnimationHistory>();
|
||||
ecs.internal_mut().register::<comp::Agent>();
|
||||
ecs.internal_mut().register::<comp::Control>();
|
||||
|
||||
|
@ -3,7 +3,7 @@ use specs::{Join, Read, ReadStorage, System, WriteStorage, Entities};
|
||||
use vek::*;
|
||||
|
||||
// Crate
|
||||
use crate::comp::{Control, Animation, phys::{Pos, Vel, Dir}};
|
||||
use crate::comp::{Control, Animation, AnimationHistory, phys::{Pos, Vel, Dir}};
|
||||
|
||||
// Basic ECS AI agent system
|
||||
pub struct Sys;
|
||||
@ -13,7 +13,7 @@ impl<'a> System<'a> for Sys {
|
||||
Entities<'a>,
|
||||
WriteStorage<'a, Vel>,
|
||||
WriteStorage<'a, Dir>,
|
||||
WriteStorage<'a, Animation>,
|
||||
WriteStorage<'a, AnimationHistory>,
|
||||
ReadStorage<'a, Control>,
|
||||
);
|
||||
|
||||
@ -23,12 +23,20 @@ impl<'a> System<'a> for Sys {
|
||||
// Apply physics to the player: acceleration and non-linear decceleration
|
||||
vel.0 += control.move_dir * 2.0 - vel.0.map(|e| e * e.abs() + e) * 0.03;
|
||||
|
||||
let animation =
|
||||
if control.move_dir.magnitude() > 0.01 {
|
||||
dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0);
|
||||
anims.insert(entity, Animation::Run);
|
||||
Animation::Run
|
||||
} else {
|
||||
anims.insert(entity, Animation::Idle);
|
||||
}
|
||||
Animation::Idle
|
||||
};
|
||||
|
||||
let lastAnimation = anims.get_mut(entity).map(|h| h.current);
|
||||
|
||||
anims.insert(entity, AnimationHistory {
|
||||
last: lastAnimation,
|
||||
current: animation,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ impl Server {
|
||||
ClientMsg::Ping => client.postbox.send_message(ServerMsg::Pong),
|
||||
ClientMsg::Pong => {}
|
||||
ClientMsg::Chat(msg) => new_chat_msgs.push((entity, msg)),
|
||||
ClientMsg::PlayerAnimation(animation) => state.write_component(entity, animation),
|
||||
ClientMsg::PlayerAnimation(animationHistory) => state.write_component(entity, animationHistory),
|
||||
ClientMsg::PlayerPhysics { pos, vel, dir } => {
|
||||
state.write_component(entity, pos);
|
||||
state.write_component(entity, vel);
|
||||
@ -369,16 +369,32 @@ impl Server {
|
||||
}
|
||||
|
||||
// Sync animation states
|
||||
for (entity, &uid, &animation) in (
|
||||
for (entity, &uid, &animationHistory) in (
|
||||
&self.state.ecs().internal().entities(),
|
||||
&self.state.ecs().internal().read_storage::<Uid>(),
|
||||
&self.state.ecs().internal().read_storage::<comp::Animation>(),
|
||||
&self.state.ecs().internal().read_storage::<comp::AnimationHistory>(),
|
||||
).join() {
|
||||
if let Some(last) = animationHistory.last {
|
||||
if animationHistory.current == last {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.clients.notify_connected_except(entity, ServerMsg::EntityAnimation {
|
||||
entity: uid.into(),
|
||||
animation,
|
||||
animationHistory,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Update animation last/current state
|
||||
for (entity, mut animationHistory) in (
|
||||
&self.state.ecs().internal().entities(),
|
||||
&mut self.state.ecs().internal().write_storage::<comp::AnimationHistory>()
|
||||
).join() {
|
||||
animationHistory.last = None;
|
||||
let mut new = animationHistory.clone();
|
||||
new.last = Some(new.current);
|
||||
}
|
||||
|
||||
// Remove all force flags
|
||||
self.state.ecs_mut().internal_mut().write_storage::<comp::phys::ForceUpdate>().clear();
|
||||
|
@ -83,18 +83,18 @@ impl Figures {
|
||||
pub fn maintain(&mut self, renderer: &mut Renderer, client: &mut Client) {
|
||||
let time = client.state().get_time();
|
||||
let ecs = client.state_mut().ecs_mut().internal_mut();
|
||||
for (entity, pos, dir, character, animation) in (
|
||||
for (entity, pos, dir, character, animationHistory) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<comp::phys::Pos>(),
|
||||
&ecs.read_storage::<comp::phys::Dir>(),
|
||||
&ecs.read_storage::<comp::Character>(),
|
||||
&ecs.read_storage::<comp::Animation>(),
|
||||
&ecs.read_storage::<comp::AnimationHistory>(),
|
||||
).join() {
|
||||
let state = self.states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| FigureState::new(renderer, CharacterSkeleton::new()));
|
||||
|
||||
let target_skeleton = match animation {
|
||||
let target_skeleton = match animationHistory.current {
|
||||
comp::character::Animation::Idle => IdleAnimation::update_skeleton(&mut state.skeleton, time),
|
||||
comp::character::Animation::Run => RunAnimation::update_skeleton(&mut state.skeleton, time),
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user