Merge branch 'combat' of https://gitlab.com/veloren/veloren into combat

This commit is contained in:
jshipsey 2020-03-22 11:55:35 -04:00
commit 3baa0471ec
49 changed files with 268 additions and 138 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -2,7 +2,7 @@ Item(
name: "Blue Linen Skirt",
description: "WIP",
kind: Armor(
kind: Belt(ClothBlue0),
kind: Pants(ClothBlue0),
stats: 20,
),
)

View File

@ -2,7 +2,7 @@ Item(
name: "Green Linen Skirt",
description: "WIP",
kind: Armor(
kind: Belt(ClothGreen0),
kind: Pants(ClothGreen0),
stats: 20,
),
)

View File

@ -2,7 +2,7 @@ Item(
name: "Purple Linen Skirt",
description: "WIP",
kind: Armor(
kind: Belt(ClothPurple0),
kind: Pants(ClothPurple0),
stats: 20,
),
)

View File

@ -2,7 +2,7 @@ Item(
name: "Blue Linen Coat",
description: "WIP",
kind: Armor(
kind: Belt(ClothBlue0),
kind: Shoulder(ClothBlue0),
stats: 20,
),
)

View File

@ -2,7 +2,7 @@ Item(
name: "Green Linen Coat",
description: "WIP",
kind: Armor(
kind: Belt(ClothGreen0),
kind: Shoulder(ClothGreen0),
stats: 20,
),
)
)

View File

@ -2,7 +2,7 @@ Item(
name: "Purple Linen Coat",
description: "WIP",
kind: Armor(
kind: Belt(ClothPurple0),
kind: Shoulder(ClothPurple0),
stats: 20,
),
)
)

View File

@ -192,7 +192,7 @@ Enjoy your stay in the World of Veloren."#,
// Inventory
"hud.bag.inventory": "'s Inventory",
"hud.bag.inventory": "'s Inventory",
"hud.bag.stats": "'s Stats",
"hud.bag.exp": "Exp",
// Settings

View File

@ -74,11 +74,11 @@
(0.0, 0.0, 0.0), (-95.0, 140.0, 0.0), 1.1,
),
Armor(Hand(Assassin)): VoxTrans(
"voxel.armor.hand.assa_left",
"voxel.armor.hand.assa_right",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
),
Armor(Shoulder(Assassin)): VoxTrans(
"voxel.armor.shoulder.assa_left",
"voxel.armor.shoulder.assa_right",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
),
// Starting Armor - Plate
@ -99,15 +99,15 @@
(0.0, 0.0, 0.0), (-95.0, 140.0, 0.0), 1.1,
),
Armor(Hand(Plate0)): VoxTrans(
"voxel.armor.hand.plate_left-0",
"voxel.armor.hand.plate_right-0",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
),
Armor(Shoulder(Plate0)): VoxTrans(
"voxel.armor.shoulder.plate_left-0",
"voxel.armor.shoulder.plate_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
),
//Leather0 Armor
Armor(Chest(Leather0)): VoxTrans(
Armor(Chest(Leather0)): VoxTrans(
"voxel.armor.chest.leather-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
),
@ -124,15 +124,98 @@
(0.0, 0.0, 0.0), (-95.0, 140.0, 0.0), 1.1,
),
Armor(Hand(Leather0)): VoxTrans(
"voxel.armor.hand.leather_left-0",
"voxel.armor.hand.leather_right-0",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
),
Armor(Shoulder(Leather1)): VoxTrans(
"voxel.armor.shoulder.leather_left-1",
"voxel.armor.shoulder.leather_right-1",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
),
Armor(Shoulder(Leather0)): VoxTrans(
"voxel.armor.shoulder.leather_left-0",
"voxel.armor.shoulder.leather_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
),
//Linen Cloth
Armor(Chest(ClothBlue0)): VoxTrans(
"voxel.armor.chest.cloth_blue-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
),
Armor(Pants(ClothBlue0)): VoxTrans(
"voxel.armor.pants.cloth_blue-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
),
Armor(Belt(ClothBlue0)): VoxTrans(
"voxel.armor.belt.cloth_blue-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.8,
),
Armor(Foot(ClothBlue0)): VoxTrans(
"voxel.armor.foot.cloth_blue-0",
(0.0, 0.0, 0.0), (-95.0, 140.0, 0.0), 1.1,
),
Armor(Hand(ClothBlue0)): VoxTrans(
"voxel.armor.hand.cloth_blue_right-0",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
),
Armor(Shoulder(ClothBlue0)): VoxTrans(
"voxel.armor.shoulder.cloth_blue_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
),
//////////////
Armor(Chest(ClothGreen0)): VoxTrans(
"voxel.armor.chest.cloth_green-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
),
Armor(Pants(ClothGreen0)): VoxTrans(
"voxel.armor.pants.cloth_green-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
),
Armor(Belt(ClothGreen0)): VoxTrans(
"voxel.armor.belt.cloth_green-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.8,
),
Armor(Foot(ClothGreen0)): VoxTrans(
"voxel.armor.foot.cloth_green-0",
(0.0, 0.0, 0.0), (-95.0, 140.0, 0.0), 1.1,
),
Armor(Hand(ClothGreen0)): VoxTrans(
"voxel.armor.hand.cloth_green_right-0",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
),
Armor(Shoulder(Leather1)): VoxTrans(
"voxel.armor.shoulder.cloth_green_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
),
Armor(Shoulder(ClothGreen0)): VoxTrans(
"voxel.armor.shoulder.cloth_green_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
),
//////
Armor(Chest(ClothPurple0)): VoxTrans(
"voxel.armor.chest.cloth_purple-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
),
Armor(Pants(ClothPurple0)): VoxTrans(
"voxel.armor.pants.cloth_purple-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.2,
),
Armor(Belt(ClothPurple0)): VoxTrans(
"voxel.armor.belt.cloth_purple-0",
(0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.8,
),
Armor(Foot(ClothPurple0)): VoxTrans(
"voxel.armor.foot.cloth_purple-0",
(0.0, 0.0, 0.0), (-95.0, 140.0, 0.0), 1.1,
),
Armor(Hand(ClothPurple0)): VoxTrans(
"voxel.armor.hand.cloth_purple_right-0",
(0.0, -1.0, 0.0), (-90.0, 135.0, 0.0), 1.0,
),
Armor(Shoulder(ClothPurple0)): VoxTrans(
"voxel.armor.shoulder.cloth_purple_right-1",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
),
Armor(Shoulder(ClothPurple0)): VoxTrans(
"voxel.armor.shoulder.cloth_purple_right-0",
(0.0, 0.0, 0.0), (-90.0, 130.0, 0.0), 1.2,
),
// Consumables

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -36,16 +36,16 @@
color: None
),
ClothPurple0:(
vox_spec: ("armor.belt.cloth_purple_0", (-5.0, -3.5, 2.0)),
vox_spec: ("armor.belt.cloth_purple-0", (-5.0, -3.5, 2.0)),
color: None
),
ClothBlue0:(
vox_spec: ("armor.belt.cloth_blue_0", (-5.0, -3.5, 2.0)),
vox_spec: ("armor.belt.cloth_blue-0", (-5.0, -3.5, 2.0)),
color: None
),
ClothGreen0:(
vox_spec: ("armor.belt.cloth_purple_0", (-5.0, -3.5, 2.0)),
vox_spec: ("armor.belt.cloth_green-0", (-5.0, -3.5, 2.0)),
color: None
),
})

View File

@ -44,16 +44,16 @@
color: None
),
ClothPurple0:(
vox_spec: ("armor.chest.cloth_purple-0", (-7.0, -3.5, 2.0)),
vox_spec: ("armor.chest.cloth_purple-0", (-7.0, -3.5, 1.0)),
color: None
),
ClothBlue0:(
vox_spec: ("armor.chest.cloth_blue-0", (-7.0, -3.5, 2.0)),
vox_spec: ("armor.chest.cloth_blue-0", (-7.0, -3.5, 1.0)),
color: None
),
ClothGreen0:(
vox_spec: ("armor.chest.cloth_green-0", (-7.0, -3.5, 2.0)),
vox_spec: ("armor.chest.cloth_green-0", (-7.0, -3.5, 1.0)),
color: None
),
})

View File

@ -28,15 +28,15 @@
color: None
),
ClothPurple0:(
vox_spec: ("armor.foot.cloth_purple_0", (-2.5, -3.5, -9.0)),
vox_spec: ("armor.foot.cloth_purple-0", (-2.5, -3.5, -9.0)),
color: None
),
ClothBlue0:(
vox_spec: ("armor.foot.cloth_purple_0", (-2.5, -3.5, -9.0)),
vox_spec: ("armor.foot.cloth_blue-0", (-2.5, -3.5, -9.0)),
color: None
),
ClothGreen0:(
vox_spec: ("armor.foot.cloth_purple_0", (-2.5, -3.5, -9.0)),
vox_spec: ("armor.foot.cloth_green-0", (-2.5, -3.5, -9.0)),
color: None
),
})

View File

@ -51,7 +51,7 @@
),
ClothPurple0: (
left: (
vox_spec: ("armor.hand.cloth_purple_left-0", (-1.5, -1.5, -7.0)),
vox_spec: ("armor.hand.cloth_purple_right-0", (-1.5, -1.5, -7.0)),
color: None
),
right: (
@ -61,7 +61,7 @@
),
ClothBlue0: (
left: (
vox_spec: ("armor.hand.cloth_blue_left-0", (-1.5, -1.5, -7.0)),
vox_spec: ("armor.hand.cloth_blue_right-0", (-1.5, -1.5, -7.0)),
color: None
),
right: (
@ -71,7 +71,7 @@
),
ClothGreen0: (
left: (
vox_spec: ("armor.hand.cloth_green_left-0", (-1.5, -1.5, -7.0)),
vox_spec: ("armor.hand.cloth_green_right-0", (-1.5, -1.5, -7.0)),
color: None
),
right: (

View File

@ -40,15 +40,15 @@
color: None
),
ClothPurple0:(
vox_spec: ("armor.pants.cloth_purple_0", (-5.0, -3.5, 2.0)),
vox_spec: ("armor.pants.cloth_purple-0", (-5.0, -3.5, 0.0)),
color: None
),
ClothBlue0:(
vox_spec: ("armor.pants.cloth_blue_0", (-5.0, -3.5, 2.0)),
vox_spec: ("armor.pants.cloth_blue-0", (-5.0, -3.5, 0.0)),
color: None
),
ClothGreen0:(
vox_spec: ("armor.pants.cloth_purple_0", (-5.0, -3.5, 2.0)),
vox_spec: ("armor.pants.cloth_green-0", (-5.0, -3.5, 0.0)),
color: None
),
})

View File

@ -82,7 +82,7 @@
),
ClothPurple0: (
left: (
vox_spec: ("armor.shoulder.cloth_purple_left-0", (-3.2, -3.5, 1.0)),
vox_spec: ("armor.shoulder.cloth_purple_right-0", (-3.2, -3.5, 1.0)),
color: None
),
right: (

View File

@ -393,7 +393,7 @@ impl Client {
{
if last_character_states
.get(entity)
.map(|l| !client_character_state.equals(&l.0))
.map(|l| !client_character_state.same_variant(&l.0))
.unwrap_or(true)
{
let _ = last_character_states
@ -692,8 +692,7 @@ impl Client {
self.state
.ecs()
.read_resource::<EventBus<SfxEventItem>>()
.emitter()
.emit(SfxEventItem::at_player_position(SfxEvent::Inventory(event)));
.emit_now(SfxEventItem::at_player_position(SfxEvent::Inventory(event)));
},
ServerMsg::TerrainChunkUpdate { key, chunk } => {
if let Ok(chunk) = chunk {

View File

@ -3,7 +3,7 @@ use crate::{
states::*,
sys::character_behavior::JoinData,
};
use specs::{Component, FlaggedStorage, HashMapStorage};
use specs::{Component, FlaggedStorage};
use specs_idvs::IDVStorage;
use std::time::Duration;
@ -13,6 +13,8 @@ pub enum CharacterAbility {
buildup_duration: Duration,
recover_duration: Duration,
base_damage: u32,
range: f32,
max_angle: f32,
},
BasicRanged {
recover_duration: Duration,
@ -66,10 +68,6 @@ impl CharacterAbility {
}
}
impl Component for CharacterAbility {
type Storage = IDVStorage<Self>;
}
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct ItemConfig {
pub item: Item,
@ -99,11 +97,15 @@ impl From<&CharacterAbility> for CharacterState {
buildup_duration,
recover_duration,
base_damage,
range,
max_angle,
} => CharacterState::BasicMelee(basic_melee::Data {
exhausted: false,
buildup_duration: *buildup_duration,
recover_duration: *recover_duration,
base_damage: *base_damage,
range: *range,
max_angle: *max_angle,
}),
CharacterAbility::BasicRanged {
recover_duration,
@ -133,7 +135,7 @@ impl From<&CharacterAbility> for CharacterState {
}),
CharacterAbility::BasicBlock => CharacterState::BasicBlock,
CharacterAbility::Roll => CharacterState::Roll(roll::Data {
remaining_duration: Duration::from_millis(600),
remaining_duration: Duration::from_millis(300),
}),
CharacterAbility::TimedCombo {
buildup_duration,

View File

@ -111,7 +111,7 @@ impl CharacterState {
}
/// Compares for shallow equality (does not check internal struct equality)
pub fn equals(&self, other: &Self) -> bool {
pub fn same_variant(&self, other: &Self) -> bool {
// Check if state is the same without looking at the inner data
std::mem::discriminant(self) == std::mem::discriminant(other)
}

View File

@ -10,7 +10,7 @@ use crate::{
use rand::seq::SliceRandom;
use specs::{Component, FlaggedStorage};
use specs_idvs::IDVStorage;
use std::{fs::File, io::BufReader, time::Duration, vec::Vec};
use std::{fs::File, io::BufReader, time::Duration};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum SwordKind {
@ -68,28 +68,24 @@ impl ToolData {
use ToolKind::*;
match self.kind {
Sword(_) => vec![
// BasicMelee {
// buildup_duration: Duration::from_millis(100),
// recover_duration: Duration::from_millis(500),
// base_damage: 6,
// },
CharacterAbility::TripleStrike { base_damage: 7 },
DashMelee {
buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500),
base_damage: 20,
},
],
Sword(_) => vec![TripleStrike { base_damage: 7 }, DashMelee {
buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500),
base_damage: 20,
}],
Axe(_) => vec![BasicMelee {
buildup_duration: Duration::from_millis(700),
recover_duration: Duration::from_millis(100),
base_damage: 8,
range: 3.5,
max_angle: 30.0,
}],
Hammer(_) => vec![BasicMelee {
buildup_duration: Duration::from_millis(700),
recover_duration: Duration::from_millis(300),
base_damage: 10,
range: 3.5,
max_angle: 60.0,
}],
Bow(_) => vec![BasicRanged {
projectile: Projectile {
@ -113,12 +109,16 @@ impl ToolData {
buildup_duration: Duration::from_millis(100),
recover_duration: Duration::from_millis(400),
base_damage: 5,
range: 3.5,
max_angle: 60.0,
}],
Staff(_) => vec![
BasicMelee {
buildup_duration: Duration::from_millis(400),
buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(300),
base_damage: 7,
base_damage: 3,
range: 10.0,
max_angle: 45.0,
},
BasicRanged {
projectile: Projectile {
@ -321,8 +321,28 @@ impl Item {
"common.items.armor.shoulder.plate_0",
"common.items.armor.shoulder.leather_1",
"common.items.armor.shoulder.leather_0",
"common.items.armor.hand.leather_0",
"common.items.armor.hand.plate_0",
"common.items.weapons.wood_sword",
"common.items.weapons.short_sword_0",
"common.items.armor.belt.cloth_blue_0",
"common.items.armor.chest.cloth_blue_0",
"common.items.armor.foot.cloth_blue_0",
"common.items.armor.pants.cloth_blue_0",
"common.items.armor.shoulder.cloth_blue_0",
"common.items.armor.hand.cloth_blue_0",
"common.items.armor.belt.cloth_green_0",
"common.items.armor.chest.cloth_green_0",
"common.items.armor.foot.cloth_green_0",
"common.items.armor.pants.cloth_green_0",
"common.items.armor.shoulder.cloth_green_0",
"common.items.armor.hand.cloth_green_0",
"common.items.armor.belt.cloth_purple_0",
"common.items.armor.chest.cloth_purple_0",
"common.items.armor.foot.cloth_purple_0",
"common.items.armor.pants.cloth_purple_0",
"common.items.armor.shoulder.cloth_purple_0",
"common.items.armor.hand.cloth_purple_0",
]
.choose(&mut rand::thread_rng())
.unwrap(), // Can't fail

View File

@ -144,7 +144,7 @@ impl<E> EventBus<E> {
}
}
pub fn emit(&self, event: E) { self.queue.lock().push_front(event); }
pub fn emit_now(&self, event: E) { self.queue.lock().push_back(event); }
pub fn recv_all(&self) -> impl ExactSizeIterator<Item = E> {
std::mem::replace(self.queue.lock().deref_mut(), VecDeque::new()).into_iter()
@ -157,7 +157,7 @@ pub struct Emitter<'a, E> {
}
impl<'a, E> Emitter<'a, E> {
pub fn emit(&mut self, event: E) { self.events.push_front(event); }
pub fn emit(&mut self, event: E) { self.events.push_back(event); }
pub fn append(&mut self, other: &mut VecDeque<E>) { self.events.append(other) }
}

View File

@ -21,9 +21,7 @@ sum_type! {
Mass(comp::Mass),
Gravity(comp::Gravity),
Sticky(comp::Sticky),
CharacterAbility(comp::CharacterAbility),
Loadout(comp::Loadout),
Attacking(comp::Attacking),
CharacterState(comp::CharacterState),
Pos(comp::Pos),
Vel(comp::Vel),
@ -48,9 +46,7 @@ sum_type! {
Mass(PhantomData<comp::Mass>),
Gravity(PhantomData<comp::Gravity>),
Sticky(PhantomData<comp::Sticky>),
CharacterAbility(PhantomData<comp::CharacterAbility>),
Loadout(PhantomData<comp::Loadout>),
Attacking(PhantomData<comp::Attacking>),
CharacterState(PhantomData<comp::CharacterState>),
Pos(PhantomData<comp::Pos>),
Vel(PhantomData<comp::Vel>),
@ -75,9 +71,7 @@ impl sync::CompPacket for EcsCompPacket {
EcsCompPacket::Mass(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Gravity(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Sticky(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::CharacterAbility(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Loadout(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Attacking(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::CharacterState(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Pos(comp) => sync::handle_insert(comp, entity, world),
EcsCompPacket::Vel(comp) => sync::handle_insert(comp, entity, world),
@ -100,9 +94,7 @@ impl sync::CompPacket for EcsCompPacket {
EcsCompPacket::Mass(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Gravity(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Sticky(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::CharacterAbility(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Loadout(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Attacking(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::CharacterState(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Pos(comp) => sync::handle_modify(comp, entity, world),
EcsCompPacket::Vel(comp) => sync::handle_modify(comp, entity, world),
@ -127,11 +119,7 @@ impl sync::CompPacket for EcsCompPacket {
EcsCompPhantom::Mass(_) => sync::handle_remove::<comp::Mass>(entity, world),
EcsCompPhantom::Gravity(_) => sync::handle_remove::<comp::Gravity>(entity, world),
EcsCompPhantom::Sticky(_) => sync::handle_remove::<comp::Sticky>(entity, world),
EcsCompPhantom::CharacterAbility(_) => {
sync::handle_remove::<comp::CharacterAbility>(entity, world)
},
EcsCompPhantom::Loadout(_) => sync::handle_remove::<comp::Loadout>(entity, world),
EcsCompPhantom::Attacking(_) => sync::handle_remove::<comp::Attacking>(entity, world),
EcsCompPhantom::CharacterState(_) => {
sync::handle_remove::<comp::CharacterState>(entity, world)
},

View File

@ -107,7 +107,6 @@ impl State {
ecs.register_sync_marker();
// Register server -> all clients synced components.
ecs.register::<comp::Loadout>();
ecs.register::<comp::Projectile>();
ecs.register::<comp::Body>();
ecs.register::<comp::Player>();
ecs.register::<comp::Stats>();
@ -121,7 +120,6 @@ impl State {
ecs.register::<comp::Mass>();
ecs.register::<comp::Sticky>();
ecs.register::<comp::Gravity>();
ecs.register::<comp::Attacking>();
// Register components send from clients -> server
ecs.register::<comp::Controller>();
@ -150,6 +148,7 @@ impl State {
ecs.register::<comp::Admin>();
ecs.register::<comp::Waypoint>();
ecs.register::<comp::Projectile>();
ecs.register::<comp::Attacking>();
// Register synced resources used by the ECS.
ecs.insert(TimeOfDay(0.0));

View File

@ -5,7 +5,7 @@ use crate::{
};
use std::time::Duration;
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Data {
/// How long until state should deal damage
pub buildup_duration: Duration,
@ -13,6 +13,10 @@ pub struct Data {
pub recover_duration: Duration,
/// Base damage
pub base_damage: u32,
/// Max range
pub range: f32,
/// Max angle (45.0 will give you a 90.0 angle window)
pub max_angle: f32,
/// Whether the attack can deal more damage
pub exhausted: bool,
}
@ -32,13 +36,15 @@ impl CharacterBehavior for Data {
.unwrap_or_default(),
recover_duration: self.recover_duration,
base_damage: self.base_damage,
range: self.range,
max_angle: self.max_angle,
exhausted: false,
});
} else if !self.exhausted {
// Hit attempt
data.updater.insert(data.entity, Attacking {
base_damage: self.base_damage,
max_angle: 75_f32.to_radians(),
max_angle: self.max_angle.to_radians(),
applied: false,
hit_count: 0,
});
@ -47,6 +53,8 @@ impl CharacterBehavior for Data {
buildup_duration: self.buildup_duration,
recover_duration: self.recover_duration,
base_damage: self.base_damage,
range: self.range,
max_angle: self.max_angle,
exhausted: true,
});
} else if self.recover_duration != Duration::default() {
@ -58,6 +66,8 @@ impl CharacterBehavior for Data {
.checked_sub(Duration::from_secs_f32(data.dt.0))
.unwrap_or_default(),
base_damage: self.base_damage,
range: self.range,
max_angle: self.max_angle,
exhausted: true,
});
} else {

View File

@ -22,7 +22,7 @@ impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData) -> StateUpdate {
let mut update = StateUpdate::from(data);
if let Err(_) = update.energy.try_change_by(-5, EnergySource::Climb) {
if let Err(_) = update.energy.try_change_by(-8, EnergySource::Climb) {
update.character = CharacterState::Idle {};
}

View File

@ -27,6 +27,7 @@ impl CharacterBehavior for Data {
if self.initialize {
update.vel.0 = data.inputs.look_dir * 20.0;
update.ori.0 = data.vel.0.normalized();
}
if self.buildup_duration != Duration::default() && data.physics.touch_entity.is_none() {

View File

@ -129,6 +129,9 @@ impl<'a> System<'a> for Sys {
mountings,
): Self::SystemData,
) {
let mut server_emitter = server_bus.emitter();
let mut local_emitter = local_bus.emitter();
let mut join_iter = (
&entities,
&uids,
@ -191,8 +194,8 @@ impl<'a> System<'a> for Sys {
*tuple.5 = state_update.ori;
*tuple.6 = state_update.energy;
*tuple.7 = state_update.loadout;
local_bus.emitter().append(&mut state_update.local_events);
server_bus.emitter().append(&mut state_update.server_events);
local_emitter.append(&mut state_update.local_events);
server_emitter.append(&mut state_update.server_events);
}
}
}

View File

@ -1,7 +1,7 @@
use crate::{
comp::{
Attacking, Body, CharacterState, Controller, HealthChange, HealthSource, Ori, Pos, Scale,
Stats,
Agent, Attacking, Body, CharacterState, Controller, HealthChange, HealthSource, Ori, Pos,
Scale, Stats,
},
event::{EventBus, ServerEvent},
sync::Uid,
@ -25,6 +25,7 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Pos>,
ReadStorage<'a, Ori>,
ReadStorage<'a, Scale>,
ReadStorage<'a, Agent>,
ReadStorage<'a, Controller>,
ReadStorage<'a, Body>,
ReadStorage<'a, Stats>,
@ -41,6 +42,7 @@ impl<'a> System<'a> for Sys {
positions,
orientations,
scales,
agents,
controllers,
bodies,
stats,
@ -48,13 +50,15 @@ impl<'a> System<'a> for Sys {
character_states,
): Self::SystemData,
) {
let mut server_emitter = server_bus.emitter();
// Attacks
for (entity, uid, pos, ori, scale_maybe, _, _attacker_stats, attack) in (
for (entity, uid, pos, ori, scale_maybe, agent_maybe, _, _attacker_stats, attack) in (
&entities,
&uids,
&positions,
&orientations,
scales.maybe(),
agents.maybe(),
&controllers,
&stats,
&mut attacking_storage,
@ -81,7 +85,7 @@ impl<'a> System<'a> for Sys {
{
// 2D versions
let pos2 = Vec2::from(pos.0);
let pos_b2: Vec2<f32> = Vec2::from(pos_b.0);
let pos_b2 = Vec2::<f32>::from(pos_b.0);
let ori2 = Vec2::from(ori.0);
// Scales
@ -99,6 +103,15 @@ impl<'a> System<'a> for Sys {
// Weapon gives base damage
let mut dmg = attack.base_damage;
// NPCs do less damage:
if agent_maybe.is_some() {
dmg = (dmg / 2).max(1);
}
if rand::random() {
dmg += 1;
}
// Block
if character_b.is_block()
&& ori_b.0.angle_between(pos.0 - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0
@ -106,7 +119,7 @@ impl<'a> System<'a> for Sys {
dmg = (dmg as f32 * (1.0 - BLOCK_EFFICIENCY)) as u32
}
server_bus.emitter().emit(ServerEvent::Damage {
server_emitter.emit(ServerEvent::Damage {
uid: *uid_b,
change: HealthChange {
amount: -(dmg as i32),

View File

@ -836,7 +836,7 @@ fn handle_explosion(server: &mut Server, entity: EcsEntity, args: String, action
.state
.ecs()
.read_resource::<EventBus<ServerEvent>>()
.emit(ServerEvent::Explosion { pos: pos.0, radius }),
.emit_now(ServerEvent::Explosion { pos: pos.0, radius }),
None => server.notify_client(
entity,
ServerMsg::private(String::from("You have no position!")),

View File

@ -45,7 +45,7 @@ impl<'a> System<'a> for Sys {
&mut self,
(
entities,
server_emitter,
server_event_bus,
time,
terrain,
mut timer,
@ -68,6 +68,8 @@ impl<'a> System<'a> for Sys {
let time = time.0;
let mut server_emitter = server_event_bus.emitter();
let mut new_chat_msgs = Vec::new();
// Player list to send new players.

View File

@ -38,7 +38,7 @@ impl<'a> System<'a> for Sys {
fn run(
&mut self,
(
server_emitter,
server_event_bus,
tick,
mut timer,
mut chunk_generator,
@ -51,6 +51,8 @@ impl<'a> System<'a> for Sys {
) {
timer.start();
let mut server_emitter = server_event_bus.emitter();
// Fetch any generated `TerrainChunk`s and insert them into the terrain.
// Also, send the chunk data to anybody that is close by.
'insert_terrain_chunks: while let Some((key, res)) = chunk_generator.recv_new_chunk() {
@ -196,16 +198,19 @@ impl<'a> System<'a> for Sys {
item,
primary_ability: ability_drain.next(),
secondary_ability: ability_drain.next(),
block_ability: Some(comp::CharacterAbility::BasicBlock),
block_ability: None,
dodge_ability: Some(comp::CharacterAbility::Roll),
})
} else {
Some(ItemConfig {
// We need the empty item so npcs can attack
item: Item::empty(),
primary_ability: Some(CharacterAbility::BasicMelee {
buildup_duration: Duration::from_millis(50),
recover_duration: Duration::from_millis(50),
base_damage: 1,
buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(300),
base_damage: 2,
range: 3.5,
max_angle: 60.0,
}),
secondary_ability: None,
block_ability: None,
@ -299,6 +304,8 @@ impl<'a> System<'a> for Sys {
buildup_duration: Duration::from_millis(800),
recover_duration: Duration::from_millis(200),
base_damage: 13,
range: 3.5,
max_angle: 60.0,
}),
secondary_ability: None,
block_ability: None,

View File

@ -47,6 +47,9 @@ impl MovementEventMapper {
const SFX_DIST_LIMIT_SQR: f32 = 20000.0;
let ecs = state.ecs();
let sfx_event_bus = ecs.read_resource::<EventBus<SfxEventItem>>();
let mut sfx_emitter = sfx_event_bus.emitter();
let player_position = ecs
.read_storage::<Pos>()
.get(player_entity)
@ -86,13 +89,11 @@ impl MovementEventMapper {
// Check for SFX config entry for this movement
if Self::should_emit(state, triggers.get_key_value(&mapped_event)) {
ecs.read_resource::<EventBus<SfxEventItem>>()
.emitter()
.emit(SfxEventItem::new(
mapped_event,
Some(pos.0),
Some(Self::get_volume_for_body_type(body)),
));
sfx_emitter.emit(SfxEventItem::new(
mapped_event,
Some(pos.0),
Some(Self::get_volume_for_body_type(body)),
));
// Set the new previous entity state
state.event = mapped_event;

View File

@ -53,8 +53,7 @@ impl ProgressionEventMapper {
if sfx_trigger_item.is_some() {
ecs.read_resource::<EventBus<SfxEventItem>>()
.emitter()
.emit(SfxEventItem::at_player_position(mapped_event));
.emit_now(SfxEventItem::at_player_position(mapped_event));
}
}

View File

@ -683,7 +683,7 @@ impl CharSelectionUi {
Mode::Create {
name,
body,
loadout,
loadout: _,
tool,
} => {
let mut to_select = false;

View File

@ -21,7 +21,6 @@ use common::{
ItemKind, Loadout,
},
figure::{DynaUnionizer, MatSegment, Material, Segment},
vol::SizedVol,
};
use dot_vox::DotVoxData;
use hashbrown::HashMap;

View File

@ -418,7 +418,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -660,7 +660,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -740,7 +740,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -820,7 +820,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -894,7 +894,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -968,7 +968,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -1042,7 +1042,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -1116,7 +1116,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -1190,7 +1190,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
@ -1264,7 +1264,7 @@ impl FigureMgr {
_ => continue,
};
if !character.equals(&last_character.0) {
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}

View File

@ -35,6 +35,10 @@ const LIGHT_DIST_RADIUS: f32 = 64.0; // The distance beyond which lights may not
const SHADOW_DIST_RADIUS: f32 = 8.0;
const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not be visible
/// Above this speed is considered running
/// Used for first person camera effects
const RUNNING_THRESHOLD: f32 = 0.7;
struct Skybox {
model: Model<SkyboxPipeline>,
locals: Consts<SkyboxLocals>,
@ -191,7 +195,7 @@ impl Scene {
let is_running = ecs
.read_storage::<comp::Vel>()
.get(scene_data.player_entity)
.map(|v| v.0.magnitude_squared() > 0.5);
.map(|v| v.0.magnitude_squared() > RUNNING_THRESHOLD.powi(2));
let on_ground = ecs
.read_storage::<comp::PhysicsState>()