mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Implement hit time delay
Former-commit-id: 6c1990645fd07e23de5eb97b6fc22f34ce09a6b7
This commit is contained in:
parent
ad3b8dffa1
commit
0344f3eba8
@ -1,4 +1,4 @@
|
||||
use client::{Client, Event, Input};
|
||||
use client::{Client, Event};
|
||||
use common::{clock::Clock, comp};
|
||||
use log::info;
|
||||
use std::time::Duration;
|
||||
@ -23,7 +23,7 @@ fn main() {
|
||||
client.send_chat("Hello!".to_string());
|
||||
|
||||
loop {
|
||||
let events = match client.tick(Input::default(), clock.get_last_delta()) {
|
||||
let events = match client.tick(comp::Inputs::default(), clock.get_last_delta()) {
|
||||
Ok(events) => events,
|
||||
Err(err) => {
|
||||
println!("Error: {:?}", err);
|
||||
|
@ -1,24 +0,0 @@
|
||||
use vek::*;
|
||||
|
||||
pub enum InputEvent {
|
||||
Jump,
|
||||
AttackStarted,
|
||||
}
|
||||
|
||||
pub struct Input {
|
||||
pub move_dir: Vec2<f32>,
|
||||
pub jumping: bool,
|
||||
pub gliding: bool,
|
||||
pub events: Vec<InputEvent>,
|
||||
}
|
||||
|
||||
impl Default for Input {
|
||||
fn default() -> Self {
|
||||
Input {
|
||||
move_dir: Vec2::zero(),
|
||||
jumping: false,
|
||||
gliding: false,
|
||||
events: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,9 @@
|
||||
#![feature(label_break_value, duration_float)]
|
||||
|
||||
pub mod error;
|
||||
pub mod input;
|
||||
|
||||
// Reexports
|
||||
pub use crate::{
|
||||
error::Error,
|
||||
input::{Input, InputEvent},
|
||||
};
|
||||
pub use crate::error::Error;
|
||||
pub use specs::join::Join;
|
||||
pub use specs::Entity as EcsEntity;
|
||||
|
||||
@ -75,8 +71,8 @@ impl Client {
|
||||
_ => return Err(Error::ServerWentMad),
|
||||
};
|
||||
|
||||
// Initialize ecs components the client has control over
|
||||
state.write_component(entity, comp::Actions::new());
|
||||
// Initialize ecs components the client has actions over
|
||||
state.write_component(entity, comp::Inputs::default());
|
||||
|
||||
Ok(Self {
|
||||
client_state,
|
||||
@ -180,7 +176,7 @@ impl Client {
|
||||
|
||||
/// Execute a single client tick, handle input and update the game state by the given duration.
|
||||
#[allow(dead_code)]
|
||||
pub fn tick(&mut self, input: Input, dt: Duration) -> Result<Vec<Event>, Error> {
|
||||
pub fn tick(&mut self, input: comp::Inputs, dt: Duration) -> Result<Vec<Event>, Error> {
|
||||
// This tick function is the centre of the Veloren universe. Most client-side things are
|
||||
// managed from here, and as such it's important that it stays organised. Please consult
|
||||
// the core developers before making significant changes to this code. Here is the
|
||||
@ -193,45 +189,16 @@ impl Client {
|
||||
// 4) Perform a single LocalState tick (i.e: update the world and entities in the world)
|
||||
// 5) Go through the terrain update queue and apply all changes to the terrain
|
||||
// 6) Sync information to the server
|
||||
// 7) Finish the tick, passing control of the main thread back to the frontend
|
||||
// 7) Finish the tick, passing actions of the main thread back to the frontend
|
||||
|
||||
// 1) Handle input from frontend.
|
||||
for event in input.events {
|
||||
match event {
|
||||
InputEvent::AttackStarted => {
|
||||
self.state
|
||||
.ecs_mut()
|
||||
.write_storage::<comp::Actions>()
|
||||
.get_mut(self.entity)
|
||||
.unwrap() // We initialized it in the constructor
|
||||
.0
|
||||
.push(comp::Action::Attack);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// Pass character actions from frontend input to the player's entity.
|
||||
// TODO: Only do this if the entity already has a Inputs component!
|
||||
self.state.write_component(self.entity, input.clone());
|
||||
|
||||
// Tell the server about the actions.
|
||||
if let Some(actions) = self
|
||||
.state
|
||||
.ecs()
|
||||
.read_storage::<comp::Actions>()
|
||||
.get(self.entity)
|
||||
{
|
||||
self.postbox
|
||||
.send_message(ClientMsg::PlayerActions(actions.clone()));
|
||||
}
|
||||
|
||||
// Pass character control from frontend input to the player's entity.
|
||||
// TODO: Only do this if the entity already has a Control component!
|
||||
self.state.write_component(
|
||||
self.entity,
|
||||
comp::Control {
|
||||
move_dir: input.move_dir,
|
||||
jumping: input.jumping,
|
||||
gliding: input.gliding,
|
||||
},
|
||||
);
|
||||
// Tell the server about the inputs.
|
||||
self.postbox
|
||||
.send_message(ClientMsg::PlayerInputs(input.clone()));
|
||||
|
||||
// 2) Build up a list of events for this frame, to be passed to the frontend.
|
||||
let mut frontend_events = Vec::new();
|
||||
|
@ -1,20 +0,0 @@
|
||||
use specs::{Component, FlaggedStorage, VecStorage};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Action {
|
||||
Attack,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Actions(pub Vec<Action>);
|
||||
|
||||
impl Actions {
|
||||
pub fn new() -> Self {
|
||||
Self(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Actions {
|
||||
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
|
||||
}
|
@ -13,24 +13,3 @@ pub enum Agent {
|
||||
impl Component for Agent {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Control {
|
||||
pub move_dir: Vec2<f32>,
|
||||
pub jumping: bool,
|
||||
pub gliding: bool,
|
||||
}
|
||||
|
||||
impl Default for Control {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
move_dir: Vec2::zero(),
|
||||
jumping: false,
|
||||
gliding: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Control {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
32
common/src/comp/inputs.rs
Normal file
32
common/src/comp/inputs.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use specs::{Component, FlaggedStorage, VecStorage};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum InputEvent {
|
||||
Jump,
|
||||
Attack,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Inputs {
|
||||
// Held down
|
||||
pub move_dir: Vec2<f32>,
|
||||
pub jumping: bool,
|
||||
pub gliding: bool,
|
||||
|
||||
// Event based
|
||||
pub events: Vec<InputEvent>,
|
||||
}
|
||||
|
||||
impl Component for Inputs {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Actions {
|
||||
pub attack_time: Option<f32>,
|
||||
}
|
||||
|
||||
impl Component for Actions {
|
||||
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
|
||||
}
|
@ -1,21 +1,22 @@
|
||||
pub mod action;
|
||||
pub mod actor;
|
||||
pub mod agent;
|
||||
pub mod animation;
|
||||
pub mod inputs;
|
||||
pub mod phys;
|
||||
pub mod player;
|
||||
pub mod stats;
|
||||
|
||||
// Reexports
|
||||
pub use action::Action;
|
||||
pub use action::Actions;
|
||||
pub use actor::Actor;
|
||||
pub use actor::Body;
|
||||
pub use actor::HumanoidBody;
|
||||
pub use actor::QuadrupedBody;
|
||||
pub use agent::{Agent, Control};
|
||||
pub use agent::Agent;
|
||||
pub use animation::Animation;
|
||||
pub use animation::AnimationInfo;
|
||||
pub use inputs::Actions;
|
||||
pub use inputs::InputEvent;
|
||||
pub use inputs::Inputs;
|
||||
pub use player::Player;
|
||||
pub use stats::Dying;
|
||||
pub use stats::Stats;
|
||||
|
@ -16,7 +16,7 @@ pub enum ClientMsg {
|
||||
Ping,
|
||||
Pong,
|
||||
Chat(String),
|
||||
PlayerActions(comp::Actions),
|
||||
PlayerInputs(comp::Inputs),
|
||||
PlayerAnimation(comp::AnimationInfo),
|
||||
PlayerPhysics {
|
||||
pos: comp::phys::Pos,
|
||||
|
@ -23,6 +23,7 @@ sphynx::sum_type! {
|
||||
Actor(comp::Actor),
|
||||
Player(comp::Player),
|
||||
Stats(comp::Stats),
|
||||
Actions(comp::Actions),
|
||||
}
|
||||
}
|
||||
// Automatically derive From<T> for EcsCompPhantom
|
||||
@ -36,6 +37,7 @@ sphynx::sum_type! {
|
||||
Actor(PhantomData<comp::Actor>),
|
||||
Player(PhantomData<comp::Player>),
|
||||
Stats(PhantomData<comp::Stats>),
|
||||
Actions(PhantomData<comp::Actions>),
|
||||
}
|
||||
}
|
||||
impl sphynx::CompPacket for EcsCompPacket {
|
||||
|
@ -110,10 +110,10 @@ impl State {
|
||||
ecs.register::<comp::phys::Vel>();
|
||||
ecs.register::<comp::phys::Dir>();
|
||||
ecs.register::<comp::AnimationInfo>();
|
||||
ecs.register::<comp::Inputs>();
|
||||
ecs.register::<comp::Actions>();
|
||||
ecs.register::<comp::Dying>();
|
||||
ecs.register::<comp::Agent>();
|
||||
ecs.register::<comp::Control>();
|
||||
ecs.register::<inventory::Inventory>();
|
||||
|
||||
// Register synced resources used by the ECS.
|
||||
|
@ -1,71 +0,0 @@
|
||||
// Library
|
||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||
use vek::*;
|
||||
|
||||
// Crate
|
||||
use crate::{
|
||||
comp::{
|
||||
phys::{Dir, ForceUpdate, Pos, Vel},
|
||||
Action, Actions, Control, Stats,
|
||||
},
|
||||
state::{DeltaTime, Time},
|
||||
};
|
||||
|
||||
// Basic ECS AI agent system
|
||||
pub struct Sys;
|
||||
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
Read<'a, Time>,
|
||||
Read<'a, DeltaTime>,
|
||||
WriteStorage<'a, Actions>,
|
||||
ReadStorage<'a, Pos>,
|
||||
WriteStorage<'a, Vel>,
|
||||
ReadStorage<'a, Dir>,
|
||||
WriteStorage<'a, Stats>,
|
||||
WriteStorage<'a, ForceUpdate>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
&mut self,
|
||||
(
|
||||
entities,
|
||||
time,
|
||||
dt,
|
||||
mut actions,
|
||||
positions,
|
||||
mut velocities,
|
||||
directions,
|
||||
mut stats,
|
||||
mut force_updates,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
for (a, actions_a, pos_a, dir_a) in
|
||||
(&entities, &mut actions, &positions, &directions).join()
|
||||
{
|
||||
for event in actions_a.0.drain(..) {
|
||||
match event {
|
||||
Action::Attack => {
|
||||
for (b, pos_b, stat_b, vel_b) in
|
||||
(&entities, &positions, &mut stats, &mut velocities).join()
|
||||
{
|
||||
if a == b {
|
||||
continue;
|
||||
}
|
||||
if a != b
|
||||
&& pos_a.0.distance_squared(pos_b.0) < 50.0
|
||||
&& dir_a.0.angle_between_degrees(pos_b.0 - pos_a.0) < 70.0
|
||||
{
|
||||
stat_b.hp.change_by(-10); // TODO: variable damage
|
||||
vel_b.0 += (pos_b.0 - pos_a.0).normalized() * 20.0;
|
||||
vel_b.0.z = 20.0;
|
||||
force_updates.insert(b, ForceUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
34
common/src/sys/actions.rs
Normal file
34
common/src/sys/actions.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// Library
|
||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage};
|
||||
use vek::*;
|
||||
|
||||
// Crate
|
||||
use crate::{
|
||||
comp::{
|
||||
phys::{Dir, Pos, Vel},
|
||||
Actions, Animation, AnimationInfo,
|
||||
},
|
||||
state::DeltaTime,
|
||||
terrain::TerrainMap,
|
||||
vol::{ReadVol, Vox},
|
||||
};
|
||||
|
||||
// Basic ECS AI agent system
|
||||
pub struct Sys;
|
||||
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (Entities<'a>, Read<'a, DeltaTime>, WriteStorage<'a, Actions>);
|
||||
|
||||
fn run(&mut self, (entities, dt, mut actions): Self::SystemData) {
|
||||
for (entity, mut action) in (&entities, &mut actions).join() {
|
||||
let should_end = action.attack_time.as_mut().map_or(false, |mut time| {
|
||||
*time += dt.0;
|
||||
*time > 0.5 // TODO: constant
|
||||
});
|
||||
|
||||
if should_end {
|
||||
action.attack_time = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ use specs::{Join, Read, ReadStorage, System, WriteStorage};
|
||||
use vek::*;
|
||||
|
||||
// Crate
|
||||
use crate::comp::{phys::Pos, Agent, Control};
|
||||
use crate::comp::{phys::Pos, Agent, Inputs};
|
||||
|
||||
// Basic ECS AI agent system
|
||||
pub struct Sys;
|
||||
@ -12,11 +12,11 @@ impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
WriteStorage<'a, Agent>,
|
||||
ReadStorage<'a, Pos>,
|
||||
WriteStorage<'a, Control>,
|
||||
WriteStorage<'a, Inputs>,
|
||||
);
|
||||
|
||||
fn run(&mut self, (mut agents, positions, mut controls): Self::SystemData) {
|
||||
for (mut agent, pos, mut control) in (&mut agents, &positions, &mut controls).join() {
|
||||
fn run(&mut self, (mut agents, positions, mut inputs): Self::SystemData) {
|
||||
for (mut agent, pos, mut input) in (&mut agents, &positions, &mut inputs).join() {
|
||||
match agent {
|
||||
Agent::Wanderer(bearing) => {
|
||||
*bearing += Vec2::new(rand::random::<f32>() - 0.5, rand::random::<f32>() - 0.5)
|
||||
@ -25,7 +25,7 @@ impl<'a> System<'a> for Sys {
|
||||
- pos.0 * 0.0002;
|
||||
|
||||
if bearing.magnitude_squared() != 0.0 {
|
||||
control.move_dir = bearing.normalized();
|
||||
input.move_dir = bearing.normalized();
|
||||
}
|
||||
}
|
||||
Agent::Pet { target, offset } => {
|
||||
@ -35,11 +35,11 @@ impl<'a> System<'a> for Sys {
|
||||
let tgt_pos = tgt_pos.0 + *offset;
|
||||
|
||||
// Jump with target.
|
||||
control.jumping = tgt_pos.z > pos.0.z + 1.0;
|
||||
input.jumping = tgt_pos.z > pos.0.z + 1.0;
|
||||
|
||||
// Move towards the target.
|
||||
let dist = tgt_pos.distance(pos.0);
|
||||
control.move_dir = if dist > 5.0 {
|
||||
input.move_dir = if dist > 5.0 {
|
||||
Vec2::from(tgt_pos - pos.0).normalized()
|
||||
} else if dist < 1.5 && dist > 0.0 {
|
||||
Vec2::from(pos.0 - tgt_pos).normalized()
|
||||
@ -47,7 +47,7 @@ impl<'a> System<'a> for Sys {
|
||||
Vec2::zero()
|
||||
};
|
||||
}
|
||||
_ => control.move_dir = Vec2::zero(),
|
||||
_ => input.move_dir = Vec2::zero(),
|
||||
}
|
||||
|
||||
// Change offset occasionally.
|
||||
|
@ -4,7 +4,7 @@ use vek::*;
|
||||
|
||||
// Crate
|
||||
use crate::{
|
||||
comp::{phys::Pos, Animation, AnimationInfo, Control, Stats},
|
||||
comp::{phys::Pos, Animation, AnimationInfo, Stats},
|
||||
state::DeltaTime,
|
||||
};
|
||||
|
||||
|
@ -5,10 +5,10 @@ use vek::*;
|
||||
// Crate
|
||||
use crate::{
|
||||
comp::{
|
||||
phys::{Dir, Pos, Vel},
|
||||
Animation, AnimationInfo, Control,
|
||||
phys::{Dir, ForceUpdate, Pos, Vel},
|
||||
Actions, Animation, AnimationInfo, InputEvent, Inputs, Stats,
|
||||
},
|
||||
state::DeltaTime,
|
||||
state::{DeltaTime, Time},
|
||||
terrain::TerrainMap,
|
||||
vol::{ReadVol, Vox},
|
||||
};
|
||||
@ -18,23 +18,47 @@ pub struct Sys;
|
||||
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
ReadExpect<'a, TerrainMap>,
|
||||
Read<'a, DeltaTime>,
|
||||
Entities<'a>,
|
||||
Read<'a, Time>,
|
||||
Read<'a, DeltaTime>,
|
||||
ReadExpect<'a, TerrainMap>,
|
||||
WriteStorage<'a, Inputs>,
|
||||
WriteStorage<'a, Actions>,
|
||||
ReadStorage<'a, Pos>,
|
||||
WriteStorage<'a, Vel>,
|
||||
WriteStorage<'a, Dir>,
|
||||
WriteStorage<'a, AnimationInfo>,
|
||||
ReadStorage<'a, Control>,
|
||||
WriteStorage<'a, Stats>,
|
||||
WriteStorage<'a, ForceUpdate>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
&mut self,
|
||||
(terrain, dt, entities, pos, mut vels, mut dirs, mut animation_infos, controls): Self::SystemData,
|
||||
(
|
||||
entities,
|
||||
time,
|
||||
dt,
|
||||
terrain,
|
||||
mut inputs,
|
||||
mut actions,
|
||||
positions,
|
||||
mut velocities,
|
||||
mut directions,
|
||||
mut animation_infos,
|
||||
mut stats,
|
||||
mut force_updates,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
for (entity, pos, mut vel, mut dir, control) in
|
||||
(&entities, &pos, &mut vels, &mut dirs, &controls).join()
|
||||
for (entity, inputs, pos, mut dir, mut vel) in (
|
||||
&entities,
|
||||
&mut inputs,
|
||||
&positions,
|
||||
&mut directions,
|
||||
&mut velocities,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
// Handle held-down inputs
|
||||
let on_ground = terrain
|
||||
.get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32))
|
||||
.map(|vox| !vox.is_empty())
|
||||
@ -44,9 +68,9 @@ impl<'a> System<'a> for Sys {
|
||||
let (gliding, friction) = if on_ground {
|
||||
// TODO: Don't hard-code this.
|
||||
// Apply physics to the player: acceleration and non-linear deceleration.
|
||||
vel.0 += Vec2::broadcast(dt.0) * control.move_dir * 200.0;
|
||||
vel.0 += Vec2::broadcast(dt.0) * inputs.move_dir * 200.0;
|
||||
|
||||
if control.jumping {
|
||||
if inputs.jumping {
|
||||
vel.0.z += 16.0;
|
||||
}
|
||||
|
||||
@ -54,9 +78,9 @@ impl<'a> System<'a> for Sys {
|
||||
} else {
|
||||
// TODO: Don't hard-code this.
|
||||
// Apply physics to the player: acceleration and non-linear deceleration.
|
||||
vel.0 += Vec2::broadcast(dt.0) * control.move_dir * 10.0;
|
||||
vel.0 += Vec2::broadcast(dt.0) * inputs.move_dir * 10.0;
|
||||
|
||||
if control.gliding && vel.0.z < 0.0 {
|
||||
if inputs.gliding && vel.0.z < 0.0 {
|
||||
// TODO: Don't hard-code this.
|
||||
let anti_grav = 9.81 * 3.95 + vel.0.z.powf(2.0) * 0.2;
|
||||
vel.0.z +=
|
||||
@ -83,7 +107,7 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
|
||||
let animation = if on_ground {
|
||||
if control.move_dir.magnitude() > 0.01 {
|
||||
if inputs.move_dir.magnitude() > 0.01 {
|
||||
Animation::Run
|
||||
} else {
|
||||
Animation::Idle
|
||||
@ -109,5 +133,41 @@ impl<'a> System<'a> for Sys {
|
||||
},
|
||||
);
|
||||
}
|
||||
for (entity, inputs, mut action, pos, dir) in (
|
||||
&entities,
|
||||
&mut inputs,
|
||||
&mut actions,
|
||||
&positions,
|
||||
&mut directions,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
// Handle event-based inputs
|
||||
for event in inputs.events.drain(..) {
|
||||
match event {
|
||||
InputEvent::Attack => {
|
||||
// Attack delay
|
||||
if action.attack_time.is_some() {
|
||||
continue;
|
||||
}
|
||||
for (b, pos_b, mut stat_b, mut vel_b) in
|
||||
(&entities, &positions, &mut stats, &mut velocities).join()
|
||||
{
|
||||
if entity != b
|
||||
&& pos.0.distance_squared(pos_b.0) < 50.0
|
||||
&& dir.0.angle_between(pos_b.0 - pos.0).to_degrees() < 70.0
|
||||
{
|
||||
action.attack_time = Some(0.0);
|
||||
stat_b.hp.change_by(-10); // TODO: variable damage
|
||||
vel_b.0 += (pos_b.0 - pos.0).normalized() * 20.0;
|
||||
vel_b.0.z = 20.0;
|
||||
force_updates.insert(b, ForceUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
InputEvent::Jump => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
pub mod action;
|
||||
pub mod actions;
|
||||
pub mod agent;
|
||||
pub mod animation;
|
||||
pub mod control;
|
||||
pub mod inputs;
|
||||
pub mod phys;
|
||||
mod stats;
|
||||
|
||||
@ -10,21 +10,18 @@ use specs::DispatcherBuilder;
|
||||
|
||||
// System names
|
||||
const AGENT_SYS: &str = "agent_sys";
|
||||
const CONTROL_SYS: &str = "control_sys";
|
||||
const INPUTS_SYS: &str = "inputs_sys";
|
||||
const ACTIONS_SYS: &str = "actions_sys";
|
||||
const PHYS_SYS: &str = "phys_sys";
|
||||
const ANIM_SYS: &str = "anim_sys";
|
||||
const MOVEMENT_SYS: &str = "movement_sys";
|
||||
const ACTION_SYS: &str = "action_sys";
|
||||
const ANIMATION_SYS: &str = "animation_sys";
|
||||
const STATS_SYS: &str = "stats_sys";
|
||||
|
||||
pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||
dispatch_builder.add(agent::Sys, AGENT_SYS, &[]);
|
||||
dispatch_builder.add(phys::Sys, PHYS_SYS, &[]);
|
||||
dispatch_builder.add(control::Sys, CONTROL_SYS, &[PHYS_SYS]);
|
||||
dispatch_builder.add(anim::Sys, ANIM_SYS, &[]);
|
||||
dispatch_builder.add(agent::Sys, AGENT_SYS, &[]);
|
||||
dispatch_builder.add(action::Sys, ACTION_SYS, &[]);
|
||||
dispatch_builder.add(inputs::Sys, INPUTS_SYS, &[]);
|
||||
dispatch_builder.add(actions::Sys, ACTIONS_SYS, &[]);
|
||||
dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[]);
|
||||
dispatch_builder.add(stats::Sys, STATS_SYS, &[ACTION_SYS]);
|
||||
dispatch_builder.add(stats::Sys, STATS_SYS, &[INPUTS_SYS]);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use vek::*;
|
||||
|
||||
// Crate
|
||||
use crate::{
|
||||
comp::{Control, Dying, Stats},
|
||||
comp::{Dying, Stats},
|
||||
state::DeltaTime,
|
||||
};
|
||||
|
||||
|
@ -214,7 +214,6 @@ fn handle_pet(server: &mut Server, entity: EcsEntity, args: String, action: &Cha
|
||||
"Bungo".to_owned(),
|
||||
comp::Body::Quadruped(comp::QuadrupedBody::random()),
|
||||
)
|
||||
.with(comp::Control::default())
|
||||
.with(comp::Agent::Pet {
|
||||
target: entity,
|
||||
offset: Vec2::zero(),
|
||||
|
@ -98,7 +98,7 @@ impl Server {
|
||||
"Tobermory".to_owned(),
|
||||
comp::Body::Humanoid(comp::HumanoidBody::random()),
|
||||
)
|
||||
.with(comp::Control::default())
|
||||
.with(comp::Actions::default())
|
||||
.with(comp::Agent::Wanderer(Vec2::zero()))
|
||||
.build();
|
||||
}
|
||||
@ -133,7 +133,8 @@ impl Server {
|
||||
.with(comp::phys::Pos(Vec3::new(0.0, 0.0, 64.0)))
|
||||
.with(comp::phys::Vel(Vec3::zero()))
|
||||
.with(comp::phys::Dir(Vec3::unit_y()))
|
||||
.with(comp::Actions::new())
|
||||
.with(comp::Inputs::default())
|
||||
.with(comp::Actions::default())
|
||||
.with(comp::Actor::Character { name, body })
|
||||
.with(comp::Stats::default())
|
||||
}
|
||||
@ -149,18 +150,15 @@ impl Server {
|
||||
|
||||
state.write_component(entity, comp::Actor::Character { name, body });
|
||||
state.write_component(entity, comp::Stats::default());
|
||||
state.write_component(entity, comp::Inputs::default());
|
||||
state.write_component(entity, comp::Actions::default());
|
||||
state.write_component(entity, comp::AnimationInfo::new());
|
||||
state.write_component(entity, comp::phys::Pos(spawn_point));
|
||||
state.write_component(entity, comp::phys::Vel(Vec3::zero()));
|
||||
state.write_component(entity, comp::phys::Dir(Vec3::unit_y()));
|
||||
// Make sure everything is accepted.
|
||||
// Make sure physics are accepted.
|
||||
state.write_component(entity, comp::phys::ForceUpdate);
|
||||
|
||||
// Set initial animation.
|
||||
state.write_component(entity, comp::AnimationInfo::new());
|
||||
|
||||
// Set initial actions (none).
|
||||
state.write_component(entity, comp::Actions::new());
|
||||
|
||||
// Tell the client its request was successful.
|
||||
client.allow_state(ClientState::Character);
|
||||
}
|
||||
@ -391,13 +389,13 @@ impl Server {
|
||||
| ClientState::Spectator
|
||||
| ClientState::Character => new_chat_msgs.push((entity, msg)),
|
||||
},
|
||||
ClientMsg::PlayerActions(mut actions) => {
|
||||
ClientMsg::PlayerInputs(mut inputs) => {
|
||||
state
|
||||
.ecs_mut()
|
||||
.write_storage::<comp::Actions>()
|
||||
.write_storage::<comp::Inputs>()
|
||||
.get_mut(entity)
|
||||
.map(|s| {
|
||||
s.0.append(&mut actions.0);
|
||||
s.events.append(&mut inputs.events);
|
||||
});
|
||||
}
|
||||
ClientMsg::PlayerAnimation(animation_info) => {
|
||||
@ -613,7 +611,7 @@ impl Server {
|
||||
.remove(entity);
|
||||
self.state
|
||||
.ecs_mut()
|
||||
.write_storage::<comp::Actions>()
|
||||
.write_storage::<comp::Inputs>()
|
||||
.remove(entity);
|
||||
if let Some(client) = self.clients.get_mut(&entity) {
|
||||
client.force_state(ClientState::Registered);
|
||||
|
@ -111,7 +111,7 @@ impl PlayState for CharSelectionState {
|
||||
// Tick the client (currently only to keep the connection alive).
|
||||
self.client
|
||||
.borrow_mut()
|
||||
.tick(client::Input::default(), clock.get_last_delta())
|
||||
.tick(comp::Inputs::default(), clock.get_last_delta())
|
||||
.expect("Failed to tick the client");
|
||||
self.client.borrow_mut().cleanup();
|
||||
|
||||
|
@ -7,8 +7,8 @@ use crate::{
|
||||
window::{Event, Key, Window},
|
||||
Direction, Error, GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
use client::{self, Client, Input, InputEvent};
|
||||
use common::{clock::Clock, msg::ClientState};
|
||||
use client::{self, Client};
|
||||
use common::{comp, clock::Clock, msg::ClientState};
|
||||
use glutin::MouseButton;
|
||||
use std::{cell::RefCell, mem, rc::Rc, time::Duration};
|
||||
use vek::*;
|
||||
@ -19,7 +19,7 @@ pub struct SessionState {
|
||||
scene: Scene,
|
||||
client: Rc<RefCell<Client>>,
|
||||
key_state: KeyState,
|
||||
input_events: Vec<InputEvent>,
|
||||
input_events: Vec<comp::InputEvent>,
|
||||
hud: Hud,
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ impl SessionState {
|
||||
mem::swap(&mut self.input_events, &mut input_events);
|
||||
|
||||
for event in self.client.borrow_mut().tick(
|
||||
Input {
|
||||
comp::Inputs {
|
||||
move_dir,
|
||||
jumping: self.key_state.jump,
|
||||
gliding: self.key_state.glide,
|
||||
@ -144,7 +144,7 @@ impl PlayState for SessionState {
|
||||
}
|
||||
// Attack key pressed
|
||||
Event::Click(MouseButton::Left, state) => {
|
||||
self.input_events.push(InputEvent::AttackStarted)
|
||||
self.input_events.push(comp::InputEvent::Attack)
|
||||
}
|
||||
// Movement key pressed
|
||||
Event::KeyDown(Key::MoveForward) => self.key_state.up = true,
|
||||
@ -152,7 +152,7 @@ impl PlayState for SessionState {
|
||||
Event::KeyDown(Key::MoveLeft) => self.key_state.left = true,
|
||||
Event::KeyDown(Key::MoveRight) => self.key_state.right = true,
|
||||
Event::KeyDown(Key::Jump) => {
|
||||
self.input_events.push(InputEvent::Jump);
|
||||
self.input_events.push(comp::InputEvent::Jump);
|
||||
self.key_state.jump = true;
|
||||
}
|
||||
Event::KeyDown(Key::Glide) => self.key_state.glide = true,
|
||||
|
Loading…
Reference in New Issue
Block a user