Moved knockback to a server event so that it would actually be applied to the player.

This commit is contained in:
Sam 2020-08-23 16:10:58 -04:00
parent 819fb8ee77
commit 6327dd18b6
8 changed files with 36 additions and 6 deletions

View File

@ -22,6 +22,7 @@ use common::{
group, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip,
InventoryManip, InventoryUpdateEvent,
},
event::{EventBus, LocalEvent},
msg::{
validate_chat_msg, ChatMsgValidationError, ClientMsg, ClientState, DisconnectReason,
InviteAnswer, Notification, PlayerInfo, PlayerListUpdate, RegisterError, RequestStateError,
@ -1426,6 +1427,15 @@ impl Client {
ServerMsg::Outcomes(outcomes) => {
frontend_events.extend(outcomes.into_iter().map(Event::Outcome))
},
ServerMsg::Knockback(force) => {
self.state
.ecs()
.read_resource::<EventBus<LocalEvent>>()
.emit_now(LocalEvent::ApplyForce {
entity: self.entity,
force,
});
},
}
}
}

View File

@ -56,6 +56,10 @@ pub enum ServerEvent {
pos: Pos,
ori: Ori,
},
Knockback {
entity: EcsEntity,
force: Vec3<f32>,
},
LandOnGround {
entity: EcsEntity,
vel: Vec3<f32>,

View File

@ -254,6 +254,7 @@ pub enum ServerMsg {
Notification(Notification),
SetViewDistance(u32),
Outcomes(Vec<Outcome>),
Knockback(Vec3<f32>),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]

View File

@ -154,7 +154,7 @@ impl<'a> System<'a> for Sys {
}
if attack.knockback != 0.0 {
local_emitter.emit(LocalEvent::ApplyForce {
server_emitter.emit(ServerEvent::Knockback {
entity: b,
force: attack.knockback
* *Dir::slerp(ori.0, Dir::new(Vec3::new(0.0, 0.0, 1.0)), 0.5),

View File

@ -63,7 +63,7 @@ impl<'a> System<'a> for Sys {
): Self::SystemData,
) {
let mut server_emitter = server_bus.emitter();
let mut local_emitter = local_bus.emitter();
let _local_emitter = local_bus.emitter();
let time = time.0;
let dt = dt.0;
@ -211,13 +211,13 @@ impl<'a> System<'a> for Sys {
}
if shockwave.knockback != 0.0 {
if shockwave.knockback < 0.0 {
local_emitter.emit(LocalEvent::ApplyForce {
server_emitter.emit(ServerEvent::Knockback {
entity: b,
force: shockwave.knockback
* *Dir::slerp(ori.0, Dir::new(Vec3::new(0.0, 0.0, -1.0)), 0.85),
});
} else {
local_emitter.emit(LocalEvent::ApplyForce {
server_emitter.emit(ServerEvent::Knockback {
entity: b,
force: shockwave.knockback
* *Dir::slerp(ori.0, Dir::new(Vec3::new(0.0, 0.0, 1.0)), 0.5),

View File

@ -32,6 +32,19 @@ pub fn handle_damage(server: &Server, uid: Uid, change: HealthChange) {
}
}
pub fn handle_knockback(server: &Server, entity: EcsEntity, force: Vec3<f32>) {
let state = &server.state;
let ecs = state.ecs();
let mut velocities = ecs.write_storage::<comp::Vel>();
if let Some(vel) = velocities.get_mut(entity) {
vel.0 = force;
}
let mut clients = state.ecs().write_storage::<Client>();
if let Some(client) = clients.get_mut(entity) {
client.notify(ServerMsg::Knockback(force));
}
}
/// Handle an entity dying. If it is a player, it will send a message to all
/// other players. If the entity that killed it had stats, then give it exp for
/// the kill. Experience given is equal to the level of the entity that was

View File

@ -8,8 +8,8 @@ use entity_creation::{
handle_loaded_character_data, handle_shockwave, handle_shoot,
};
use entity_manipulation::{
handle_damage, handle_destroy, handle_explosion, handle_land_on_ground, handle_level_up,
handle_respawn,
handle_damage, handle_destroy, handle_explosion, handle_knockback, handle_land_on_ground,
handle_level_up, handle_respawn,
};
use group_manip::handle_group;
use interaction::{handle_lantern, handle_mount, handle_possess, handle_unmount};
@ -75,6 +75,7 @@ impl Server {
pos,
ori,
} => handle_shockwave(self, properties, pos, ori),
ServerEvent::Knockback { entity, force } => handle_knockback(&self, entity, force),
ServerEvent::Damage { uid, change } => handle_damage(&self, uid, change),
ServerEvent::Destroy { entity, cause } => handle_destroy(self, entity, cause),
ServerEvent::InventoryManip(entity, manip) => handle_inventory(self, entity, manip),

View File

@ -420,6 +420,7 @@ impl ParticleMgr {
}
}
}
fn maintain_shockwave_particles(&mut self, scene_data: &SceneData) {
let state = scene_data.state;
let ecs = state.ecs();