mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'sam/combo-comp' into 'master'
Combo now persists as a compnent, rather than a field on a state See merge request veloren/veloren!1828
This commit is contained in:
commit
cb267ac3ee
@ -17,6 +17,7 @@ sum_type! {
|
||||
Buffs(comp::Buffs),
|
||||
Auras(comp::Auras),
|
||||
Energy(comp::Energy),
|
||||
Combo(comp::Combo),
|
||||
Health(comp::Health),
|
||||
Poise(comp::Poise),
|
||||
LightEmitter(comp::LightEmitter),
|
||||
@ -50,6 +51,7 @@ sum_type! {
|
||||
Buffs(PhantomData<comp::Buffs>),
|
||||
Auras(PhantomData<comp::Auras>),
|
||||
Energy(PhantomData<comp::Energy>),
|
||||
Combo(PhantomData<comp::Combo>),
|
||||
Health(PhantomData<comp::Health>),
|
||||
Poise(PhantomData<comp::Poise>),
|
||||
LightEmitter(PhantomData<comp::LightEmitter>),
|
||||
@ -83,6 +85,7 @@ impl sync::CompPacket for EcsCompPacket {
|
||||
EcsCompPacket::Buffs(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Auras(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Energy(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Combo(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Health(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::Poise(comp) => sync::handle_insert(comp, entity, world),
|
||||
EcsCompPacket::LightEmitter(comp) => sync::handle_insert(comp, entity, world),
|
||||
@ -114,6 +117,7 @@ impl sync::CompPacket for EcsCompPacket {
|
||||
EcsCompPacket::Buffs(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Auras(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Energy(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Combo(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Health(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::Poise(comp) => sync::handle_modify(comp, entity, world),
|
||||
EcsCompPacket::LightEmitter(comp) => sync::handle_modify(comp, entity, world),
|
||||
@ -145,6 +149,7 @@ impl sync::CompPacket for EcsCompPacket {
|
||||
EcsCompPhantom::Buffs(_) => sync::handle_remove::<comp::Buffs>(entity, world),
|
||||
EcsCompPhantom::Auras(_) => sync::handle_remove::<comp::Auras>(entity, world),
|
||||
EcsCompPhantom::Energy(_) => sync::handle_remove::<comp::Energy>(entity, world),
|
||||
EcsCompPhantom::Combo(_) => sync::handle_remove::<comp::Combo>(entity, world),
|
||||
EcsCompPhantom::Health(_) => sync::handle_remove::<comp::Health>(entity, world),
|
||||
EcsCompPhantom::Poise(_) => sync::handle_remove::<comp::Poise>(entity, world),
|
||||
EcsCompPhantom::LightEmitter(_) => {
|
||||
|
@ -86,6 +86,13 @@ impl Attack {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_combo_increment(self) -> Self {
|
||||
self.with_effect(
|
||||
AttackEffect::new(None, CombatEffect::Combo(1))
|
||||
.with_requirement(CombatRequirement::AnyDamage),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn effects(&self) -> impl Iterator<Item = &AttackEffect> { self.effects.iter() }
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@ -195,6 +202,14 @@ impl Attack {
|
||||
});
|
||||
}
|
||||
},
|
||||
CombatEffect::Combo(c) => {
|
||||
if let Some(attacker_entity) = attacker_info.map(|a| a.entity) {
|
||||
emit(ServerEvent::ComboChange {
|
||||
entity: attacker_entity,
|
||||
change: *c,
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -303,6 +318,14 @@ impl Attack {
|
||||
});
|
||||
}
|
||||
},
|
||||
CombatEffect::Combo(c) => {
|
||||
if let Some(attacker_entity) = attacker_info.map(|a| a.entity) {
|
||||
emit(ServerEvent::ComboChange {
|
||||
entity: attacker_entity,
|
||||
change: c,
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,6 +391,7 @@ pub enum CombatEffect {
|
||||
EnergyReward(f32),
|
||||
Lifesteal(f32),
|
||||
Poise(f32),
|
||||
Combo(i32),
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
@ -1216,7 +1216,6 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
||||
ability_info,
|
||||
},
|
||||
stage: 1,
|
||||
combo: 0,
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
next_stage: false,
|
||||
|
39
common/src/comp/combo.rs
Normal file
39
common/src/comp/combo.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Combo {
|
||||
counter: u32,
|
||||
last_increase: f64,
|
||||
}
|
||||
|
||||
impl Default for Combo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
counter: 0,
|
||||
last_increase: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Combo {
|
||||
pub fn counter(&self) -> u32 { self.counter }
|
||||
|
||||
pub fn last_increase(&self) -> f64 { self.last_increase }
|
||||
|
||||
pub fn reset(&mut self) { self.counter = 0; }
|
||||
|
||||
pub fn increase_by(&mut self, amount: u32, time: f64) {
|
||||
self.counter = self.counter.saturating_add(amount);
|
||||
self.last_increase = time;
|
||||
}
|
||||
|
||||
pub fn decrease_by(&mut self, amount: u32) {
|
||||
self.counter = self.counter.saturating_sub(amount);
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Combo {
|
||||
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
|
||||
}
|
@ -8,6 +8,7 @@ pub mod buff;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod character_state;
|
||||
#[cfg(not(target_arch = "wasm32"))] pub mod chat;
|
||||
pub mod combo;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod controller;
|
||||
#[cfg(not(target_arch = "wasm32"))] mod energy;
|
||||
@ -58,6 +59,7 @@ pub use self::{
|
||||
chat::{
|
||||
ChatMode, ChatMsg, ChatType, Faction, SpeechBubble, SpeechBubbleType, UnresolvedChatMsg,
|
||||
},
|
||||
combo::Combo,
|
||||
controller::{
|
||||
Climb, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip, Input,
|
||||
InventoryManip, LoadoutManip, MountState, Mounting, SlotManip,
|
||||
|
@ -143,6 +143,10 @@ pub enum ServerEvent {
|
||||
entity: EcsEntity,
|
||||
change: comp::EnergyChange,
|
||||
},
|
||||
ComboChange {
|
||||
entity: EcsEntity,
|
||||
change: i32,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct EventBus<E> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
item::MaterialStatManifest, Beam, Body, CharacterState, ControlAction, Controller,
|
||||
item::MaterialStatManifest, Beam, Body, CharacterState, Combo, ControlAction, Controller,
|
||||
ControllerInputs, Energy, Health, Inventory, LoadoutManip, Melee, Ori, PhysicsState, Pos,
|
||||
StateUpdate, Stats, Vel,
|
||||
},
|
||||
@ -68,6 +68,7 @@ pub struct JoinData<'a> {
|
||||
pub updater: &'a LazyUpdate,
|
||||
pub stats: &'a Stats,
|
||||
pub msm: &'a MaterialStatManifest,
|
||||
pub combo: &'a Combo,
|
||||
}
|
||||
|
||||
type RestrictedMut<'a, C> = PairedStorage<
|
||||
@ -95,6 +96,7 @@ pub struct JoinStruct<'a> {
|
||||
pub melee_attack: Option<&'a Melee>,
|
||||
pub beam: Option<&'a Beam>,
|
||||
pub stat: &'a Stats,
|
||||
pub combo: &'a Combo,
|
||||
}
|
||||
|
||||
impl<'a> JoinData<'a> {
|
||||
@ -123,6 +125,7 @@ impl<'a> JoinData<'a> {
|
||||
updater,
|
||||
dt,
|
||||
msm,
|
||||
combo: j.combo,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,8 +109,6 @@ pub struct Data {
|
||||
pub static_data: StaticData,
|
||||
/// Indicates what stage the combo is in
|
||||
pub stage: u32,
|
||||
/// Number of consecutive strikes
|
||||
pub combo: u32,
|
||||
/// Timer for each stage
|
||||
pub timer: Duration,
|
||||
/// Checks what section a stage is in
|
||||
@ -127,9 +125,6 @@ impl CharacterBehavior for Data {
|
||||
handle_move(data, &mut update, 0.3);
|
||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||
handle_interrupt(data, &mut update, self.static_data.is_interruptible);
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
roll.was_combo = Some((self.stage, self.combo));
|
||||
}
|
||||
match update.character {
|
||||
CharacterState::ComboMelee(_) => {},
|
||||
_ => {
|
||||
@ -142,7 +137,11 @@ impl CharacterBehavior for Data {
|
||||
|
||||
let speed_modifer = 1.0
|
||||
+ self.static_data.max_speed_increase
|
||||
* (1.0 - self.static_data.speed_increase.powi(self.combo as i32));
|
||||
* (1.0
|
||||
- self
|
||||
.static_data
|
||||
.speed_increase
|
||||
.powi(data.combo.counter() as i32));
|
||||
|
||||
match self.stage_section {
|
||||
StageSection::Buildup => {
|
||||
@ -170,7 +169,7 @@ impl CharacterBehavior for Data {
|
||||
+ (self
|
||||
.static_data
|
||||
.scales_from_combo
|
||||
.min(self.combo / self.static_data.num_stages)
|
||||
.min(data.combo.counter() / self.static_data.num_stages)
|
||||
as f32)
|
||||
* self.static_data.stage_data[stage_index].damage_increase;
|
||||
|
||||
@ -178,7 +177,7 @@ impl CharacterBehavior for Data {
|
||||
+ (self
|
||||
.static_data
|
||||
.scales_from_combo
|
||||
.min(self.combo / self.static_data.num_stages)
|
||||
.min(data.combo.counter() / self.static_data.num_stages)
|
||||
as f32)
|
||||
* self.static_data.stage_data[stage_index].poise_damage_increase;
|
||||
let poise = AttackEffect::new(
|
||||
@ -196,7 +195,7 @@ impl CharacterBehavior for Data {
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
let energy = self.static_data.max_energy_gain.min(
|
||||
self.static_data.initial_energy_gain
|
||||
+ self.combo as f32 * self.static_data.energy_increase,
|
||||
+ data.combo.counter() as f32 * self.static_data.energy_increase,
|
||||
);
|
||||
let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy))
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
@ -214,7 +213,8 @@ impl CharacterBehavior for Data {
|
||||
.with_crit(0.5, 1.3)
|
||||
.with_effect(energy)
|
||||
.with_effect(poise)
|
||||
.with_effect(knockback);
|
||||
.with_effect(knockback)
|
||||
.with_combo_increment();
|
||||
|
||||
data.updater.insert(data.entity, Melee {
|
||||
attack,
|
||||
@ -288,7 +288,6 @@ impl CharacterBehavior for Data {
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
next_stage: false,
|
||||
..*self
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
@ -311,7 +310,6 @@ impl CharacterBehavior for Data {
|
||||
update.character = CharacterState::ComboMelee(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
stage: self.stage,
|
||||
combo: self.combo + 1,
|
||||
timer: self.timer,
|
||||
stage_section: self.stage_section,
|
||||
next_stage: self.next_stage,
|
||||
|
@ -36,8 +36,8 @@ pub struct Data {
|
||||
pub was_wielded: bool,
|
||||
/// Was sneaking
|
||||
pub was_sneak: bool,
|
||||
/// Was combo, .0 is stage, .1 is combo counter
|
||||
pub was_combo: Option<(u32, u32)>,
|
||||
/// Was in state with combo
|
||||
pub was_combo: Option<(AbilityKey, u32)>,
|
||||
}
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
@ -114,13 +114,10 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
if self.was_wielded {
|
||||
if let Some((key, stage)) = self.was_combo {
|
||||
resume_combo(data, &mut update, key, stage);
|
||||
} else if self.was_wielded {
|
||||
update.character = CharacterState::Wielding;
|
||||
let combo_data = self.was_combo;
|
||||
|
||||
if let Some(combo_data) = combo_data {
|
||||
continue_combo(data, &mut update, combo_data);
|
||||
}
|
||||
} else if self.was_sneak {
|
||||
update.character = CharacterState::Sneak;
|
||||
} else {
|
||||
@ -130,13 +127,10 @@ impl CharacterBehavior for Data {
|
||||
},
|
||||
_ => {
|
||||
// If it somehow ends up in an incorrect stage section
|
||||
if self.was_wielded {
|
||||
if let Some((key, stage)) = self.was_combo {
|
||||
resume_combo(data, &mut update, key, stage);
|
||||
} else if self.was_wielded {
|
||||
update.character = CharacterState::Wielding;
|
||||
let combo_data = self.was_combo;
|
||||
|
||||
if let Some(combo_data) = combo_data {
|
||||
continue_combo(data, &mut update, combo_data);
|
||||
}
|
||||
} else if self.was_sneak {
|
||||
update.character = CharacterState::Sneak;
|
||||
} else {
|
||||
|
@ -529,7 +529,17 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
})
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
if data.character.is_wield() {
|
||||
if let CharacterState::ComboMelee(c) = data.character {
|
||||
update.character = (
|
||||
&ability,
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false),
|
||||
)
|
||||
.into();
|
||||
if let CharacterState::Roll(roll) = &mut update.character {
|
||||
roll.was_combo = Some((c.static_data.ability_info.key, c.stage));
|
||||
roll.was_wielded = true;
|
||||
}
|
||||
} else if data.character.is_wield() {
|
||||
update.character = (
|
||||
&ability,
|
||||
AbilityInfo::from_key(data, AbilityKey::Dodge, false),
|
||||
@ -576,6 +586,16 @@ pub fn handle_interrupt(data: &JoinData, update: &mut StateUpdate, attacks_inter
|
||||
handle_dodge_input(data, update);
|
||||
}
|
||||
|
||||
pub fn resume_combo(data: &JoinData, update: &mut StateUpdate, key: AbilityKey, stage: u32) {
|
||||
if ability_key_is_pressed(data, key) {
|
||||
handle_interrupt(data, update, true);
|
||||
}
|
||||
// If other states are introduced that progress through stages, add them here
|
||||
if let CharacterState::ComboMelee(c) = &mut update.character {
|
||||
c.stage = stage;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ability_key_is_pressed(data: &JoinData, ability_key: AbilityKey) -> bool {
|
||||
match ability_key {
|
||||
AbilityKey::Mouse1 => data.inputs.primary.is_pressed(),
|
||||
@ -586,14 +606,6 @@ pub fn ability_key_is_pressed(data: &JoinData, ability_key: AbilityKey) -> bool
|
||||
}
|
||||
}
|
||||
|
||||
pub fn continue_combo(data: &JoinData, update: &mut StateUpdate, combo_data: (u32, u32)) {
|
||||
handle_ability1_input(data, update);
|
||||
if let CharacterState::ComboMelee(data) = &mut update.character {
|
||||
data.stage = combo_data.0;
|
||||
data.combo = combo_data.1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines what portion a state is in. Used in all attacks (eventually). Is
|
||||
/// used to control aspects of animation code, as well as logic within the
|
||||
/// character states.
|
||||
|
@ -9,8 +9,8 @@ use common::{
|
||||
item::MaterialStatManifest,
|
||||
slot::{EquipSlot, Slot},
|
||||
},
|
||||
Beam, Body, CharacterState, Controller, Energy, Health, Inventory, Melee, Mounting, Ori,
|
||||
PhysicsState, Poise, PoiseState, Pos, StateUpdate, Stats, Vel,
|
||||
Beam, Body, CharacterState, Combo, Controller, Energy, Health, Inventory, Melee, Mounting,
|
||||
Ori, PhysicsState, Poise, PoiseState, Pos, StateUpdate, Stats, Vel,
|
||||
},
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
metrics::SysMetrics,
|
||||
@ -66,6 +66,7 @@ pub struct ReadData<'a> {
|
||||
mountings: ReadStorage<'a, Mounting>,
|
||||
stats: ReadStorage<'a, Stats>,
|
||||
msm: Read<'a, MaterialStatManifest>,
|
||||
combos: ReadStorage<'a, Combo>,
|
||||
}
|
||||
|
||||
/// ## Character Behavior System
|
||||
@ -121,6 +122,7 @@ impl<'a> System<'a> for Sys {
|
||||
body,
|
||||
physics,
|
||||
stat,
|
||||
combo,
|
||||
) in (
|
||||
&read_data.entities,
|
||||
&read_data.uids,
|
||||
@ -135,6 +137,7 @@ impl<'a> System<'a> for Sys {
|
||||
&read_data.bodies,
|
||||
&read_data.physics_states,
|
||||
&read_data.stats,
|
||||
&read_data.combos,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
@ -253,6 +256,7 @@ impl<'a> System<'a> for Sys {
|
||||
melee_attack: read_data.melee_attacks.get(entity),
|
||||
beam: read_data.beams.get(entity),
|
||||
stat: &stat,
|
||||
combo: &combo,
|
||||
};
|
||||
|
||||
for action in actions {
|
||||
|
@ -127,6 +127,7 @@ impl State {
|
||||
ecs.register::<comp::Buffs>();
|
||||
ecs.register::<comp::Auras>();
|
||||
ecs.register::<comp::Energy>();
|
||||
ecs.register::<comp::Combo>();
|
||||
ecs.register::<comp::Health>();
|
||||
ecs.register::<comp::Poise>();
|
||||
ecs.register::<comp::CanBuild>();
|
||||
|
@ -1,13 +1,13 @@
|
||||
use common::{
|
||||
comp::{
|
||||
skills::{GeneralSkill, Skill},
|
||||
Body, CharacterState, Energy, EnergyChange, EnergySource, Health, Poise, PoiseChange,
|
||||
PoiseSource, Pos, Stats,
|
||||
Body, CharacterState, Combo, Energy, EnergyChange, EnergySource, Health, Poise,
|
||||
PoiseChange, PoiseSource, Pos, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
metrics::SysMetrics,
|
||||
outcome::Outcome,
|
||||
resources::DeltaTime,
|
||||
resources::{DeltaTime, Time},
|
||||
span,
|
||||
uid::Uid,
|
||||
};
|
||||
@ -20,11 +20,13 @@ use vek::Vec3;
|
||||
|
||||
const ENERGY_REGEN_ACCEL: f32 = 10.0;
|
||||
const POISE_REGEN_ACCEL: f32 = 2.0;
|
||||
const COMBO_DECAY_START: f64 = 5.0; // seconds
|
||||
|
||||
#[derive(SystemData)]
|
||||
pub struct ReadData<'a> {
|
||||
entities: Entities<'a>,
|
||||
dt: Read<'a, DeltaTime>,
|
||||
time: Read<'a, Time>,
|
||||
server_bus: Read<'a, EventBus<ServerEvent>>,
|
||||
metrics: ReadExpect<'a, SysMetrics>,
|
||||
positions: ReadStorage<'a, Pos>,
|
||||
@ -43,6 +45,7 @@ impl<'a> System<'a> for Sys {
|
||||
WriteStorage<'a, Health>,
|
||||
WriteStorage<'a, Poise>,
|
||||
WriteStorage<'a, Energy>,
|
||||
WriteStorage<'a, Combo>,
|
||||
Write<'a, Vec<Outcome>>,
|
||||
);
|
||||
|
||||
@ -54,6 +57,7 @@ impl<'a> System<'a> for Sys {
|
||||
mut healths,
|
||||
mut poises,
|
||||
mut energies,
|
||||
mut combos,
|
||||
mut outcomes,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
@ -256,6 +260,13 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
}
|
||||
|
||||
// Decay combo
|
||||
for (_, mut combo) in (&read_data.entities, &mut combos).join() {
|
||||
if combo.counter() > 0 && read_data.time.0 - combo.last_increase() > COMBO_DECAY_START {
|
||||
combo.reset();
|
||||
}
|
||||
}
|
||||
|
||||
read_data.metrics.stats_ns.store(
|
||||
start_time.elapsed().as_nanos() as u64,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
|
@ -20,6 +20,7 @@ use common::{
|
||||
event::{EventBus, ServerEvent},
|
||||
lottery::Lottery,
|
||||
outcome::Outcome,
|
||||
resources::Time,
|
||||
rtsim::RtSimEntity,
|
||||
terrain::{Block, TerrainGrid},
|
||||
uid::{Uid, UidAllocator},
|
||||
@ -880,3 +881,15 @@ fn handle_exp_gain(
|
||||
exp: exp_reward as i32,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn handle_combo_change(server: &Server, entity: EcsEntity, change: i32) {
|
||||
let ecs = &server.state.ecs();
|
||||
if let Some(mut combo) = ecs.write_storage::<comp::Combo>().get_mut(entity) {
|
||||
if change > 0 {
|
||||
let time = ecs.read_resource::<Time>();
|
||||
combo.increase_by(change as u32, time.0);
|
||||
} else {
|
||||
combo.decrease_by(change.abs() as u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,9 @@ use entity_creation::{
|
||||
handle_loaded_character_data, handle_shockwave, handle_shoot,
|
||||
};
|
||||
use entity_manipulation::{
|
||||
handle_aura, handle_buff, handle_damage, handle_delete, handle_destroy, handle_energy_change,
|
||||
handle_explosion, handle_knockback, handle_land_on_ground, handle_poise, handle_respawn,
|
||||
handle_aura, handle_buff, handle_combo_change, handle_damage, handle_delete, handle_destroy,
|
||||
handle_energy_change, handle_explosion, handle_knockback, handle_land_on_ground, handle_poise,
|
||||
handle_respawn,
|
||||
};
|
||||
use group_manip::handle_group;
|
||||
use interaction::{
|
||||
@ -182,6 +183,9 @@ impl Server {
|
||||
ServerEvent::EnergyChange { entity, change } => {
|
||||
handle_energy_change(&self, entity, change)
|
||||
},
|
||||
ServerEvent::ComboChange { entity, change } => {
|
||||
handle_combo_change(&self, entity, change)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,6 +178,7 @@ impl StateExt for State {
|
||||
.with(comp::CharacterState::default())
|
||||
.with(inventory)
|
||||
.with(comp::Buffs::default())
|
||||
.with(comp::Combo::default())
|
||||
}
|
||||
|
||||
fn create_object(&mut self, pos: comp::Pos, object: comp::object::Body) -> EcsEntityBuilder {
|
||||
@ -269,6 +270,7 @@ impl StateExt for State {
|
||||
comp::Alignment::Owned(self.read_component_copied(entity).unwrap()),
|
||||
);
|
||||
self.write_component(entity, comp::Buffs::default());
|
||||
self.write_component(entity, comp::Combo::default());
|
||||
|
||||
// Make sure physics components are updated
|
||||
self.write_component(entity, comp::ForceUpdate);
|
||||
|
@ -1,9 +1,9 @@
|
||||
use super::SysTimer;
|
||||
use common::{
|
||||
comp::{
|
||||
Auras, BeamSegment, Body, Buffs, CanBuild, CharacterState, Collider, Energy, Gravity,
|
||||
Group, Health, Inventory, Item, LightEmitter, Mass, MountState, Mounting, Ori, Player,
|
||||
Poise, Pos, Scale, Shockwave, Stats, Sticky, Vel,
|
||||
Auras, BeamSegment, Body, Buffs, CanBuild, CharacterState, Collider, Combo, Energy,
|
||||
Gravity, Group, Health, Inventory, Item, LightEmitter, Mass, MountState, Mounting, Ori,
|
||||
Player, Poise, Pos, Scale, Shockwave, Stats, Sticky, Vel,
|
||||
},
|
||||
span,
|
||||
uid::Uid,
|
||||
@ -50,6 +50,7 @@ pub struct TrackedComps<'a> {
|
||||
pub buffs: ReadStorage<'a, Buffs>,
|
||||
pub auras: ReadStorage<'a, Auras>,
|
||||
pub energy: ReadStorage<'a, Energy>,
|
||||
pub combo: ReadStorage<'a, Combo>,
|
||||
pub health: ReadStorage<'a, Health>,
|
||||
pub poise: ReadStorage<'a, Poise>,
|
||||
pub can_build: ReadStorage<'a, CanBuild>,
|
||||
@ -104,6 +105,10 @@ impl<'a> TrackedComps<'a> {
|
||||
.get(entity)
|
||||
.cloned()
|
||||
.map(|c| comps.push(c.into()));
|
||||
self.combo
|
||||
.get(entity)
|
||||
.cloned()
|
||||
.map(|c| comps.push(c.into()));
|
||||
self.health
|
||||
.get(entity)
|
||||
.cloned()
|
||||
@ -183,6 +188,7 @@ pub struct ReadTrackers<'a> {
|
||||
pub buffs: ReadExpect<'a, UpdateTracker<Buffs>>,
|
||||
pub auras: ReadExpect<'a, UpdateTracker<Auras>>,
|
||||
pub energy: ReadExpect<'a, UpdateTracker<Energy>>,
|
||||
pub combo: ReadExpect<'a, UpdateTracker<Combo>>,
|
||||
pub health: ReadExpect<'a, UpdateTracker<Health>>,
|
||||
pub poise: ReadExpect<'a, UpdateTracker<Poise>>,
|
||||
pub can_build: ReadExpect<'a, UpdateTracker<CanBuild>>,
|
||||
@ -217,6 +223,7 @@ impl<'a> ReadTrackers<'a> {
|
||||
.with_component(&comps.uid, &*self.buffs, &comps.buffs, filter)
|
||||
.with_component(&comps.uid, &*self.auras, &comps.auras, filter)
|
||||
.with_component(&comps.uid, &*self.energy, &comps.energy, filter)
|
||||
.with_component(&comps.uid, &*self.combo, &comps.combo, filter)
|
||||
.with_component(&comps.uid, &*self.health, &comps.health, filter)
|
||||
.with_component(&comps.uid, &*self.poise, &comps.poise, filter)
|
||||
.with_component(&comps.uid, &*self.can_build, &comps.can_build, filter)
|
||||
@ -258,6 +265,7 @@ pub struct WriteTrackers<'a> {
|
||||
buffs: WriteExpect<'a, UpdateTracker<Buffs>>,
|
||||
auras: WriteExpect<'a, UpdateTracker<Auras>>,
|
||||
energy: WriteExpect<'a, UpdateTracker<Energy>>,
|
||||
combo: WriteExpect<'a, UpdateTracker<Combo>>,
|
||||
health: WriteExpect<'a, UpdateTracker<Health>>,
|
||||
poise: WriteExpect<'a, UpdateTracker<Poise>>,
|
||||
can_build: WriteExpect<'a, UpdateTracker<CanBuild>>,
|
||||
@ -286,6 +294,7 @@ fn record_changes(comps: &TrackedComps, trackers: &mut WriteTrackers) {
|
||||
trackers.buffs.record_changes(&comps.buffs);
|
||||
trackers.auras.record_changes(&comps.auras);
|
||||
trackers.energy.record_changes(&comps.energy);
|
||||
trackers.combo.record_changes(&comps.combo);
|
||||
trackers.health.record_changes(&comps.health);
|
||||
trackers.poise.record_changes(&comps.poise);
|
||||
trackers.can_build.record_changes(&comps.can_build);
|
||||
@ -327,6 +336,7 @@ fn record_changes(comps: &TrackedComps, trackers: &mut WriteTrackers) {
|
||||
log_counts!(player, "Players");
|
||||
log_counts!(stats, "Stats");
|
||||
log_counts!(energy, "Energies");
|
||||
log_counts!(combo, "Combos");
|
||||
log_vounts!(health, "Healths");
|
||||
log_vounts!(poise, "Poises");
|
||||
log_counts!(light_emitter, "Light emitters");
|
||||
@ -353,6 +363,7 @@ pub fn register_trackers(world: &mut World) {
|
||||
world.register_tracker::<Buffs>();
|
||||
world.register_tracker::<Auras>();
|
||||
world.register_tracker::<Energy>();
|
||||
world.register_tracker::<Combo>();
|
||||
world.register_tracker::<Health>();
|
||||
world.register_tracker::<Poise>();
|
||||
world.register_tracker::<CanBuild>();
|
||||
|
@ -135,7 +135,6 @@ fn matches_ability_stage() {
|
||||
ability_info: empty_ability_info(),
|
||||
},
|
||||
stage: 1,
|
||||
combo: 0,
|
||||
timer: Duration::default(),
|
||||
stage_section: states::utils::StageSection::Swing,
|
||||
next_stage: false,
|
||||
@ -194,7 +193,6 @@ fn ignores_different_ability_stage() {
|
||||
ability_info: empty_ability_info(),
|
||||
},
|
||||
stage: 1,
|
||||
combo: 0,
|
||||
timer: Duration::default(),
|
||||
stage_section: states::utils::StageSection::Swing,
|
||||
next_stage: false,
|
||||
|
Loading…
Reference in New Issue
Block a user