diff --git a/common/src/combat.rs b/common/src/combat.rs index 2ef0a1f0fc..3d699c019c 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -11,7 +11,8 @@ use crate::{ }, poise::PoiseChange, skills::{SkillGroupKind, SkillSet}, - Body, EnergyChange, EnergySource, Health, HealthChange, HealthSource, Inventory, Stats, + Body, Energy, EnergyChange, EnergySource, Health, HealthChange, HealthSource, Inventory, + Stats, }, event::ServerEvent, uid::Uid, @@ -71,8 +72,9 @@ impl Attack { target_group: GroupTarget, attacker_entity: EcsEntity, target_entity: EcsEntity, - inventory: Option<&Inventory>, + target_inventory: Option<&Inventory>, attacker_uid: Uid, + attacker_energy: Option<&Energy>, dir: Dir, target_dodging: bool, ) -> Vec { @@ -86,7 +88,7 @@ impl Attack { .filter(|d| !(matches!(d.target, Some(GroupTarget::OutOfGroup)) && target_dodging)) { let change = damage.damage.modify_damage( - inventory, + target_inventory, Some(attacker_uid), is_crit, self.crit_multiplier, @@ -141,7 +143,7 @@ impl Attack { }); }, AttackEffect::Poise(p) => { - let change = PoiseChange::from_attack(*p, inventory); + let change = PoiseChange::from_attack(*p, target_inventory); server_events.push(ServerEvent::PoiseChange { entity: target_entity, change, @@ -172,6 +174,20 @@ impl Attack { { if match &effect.requirement { Some(CombatRequirement::AnyDamage) => accumulated_damage != 0.0, + Some(CombatRequirement::SufficientEnergy(r)) => { + if attacker_energy.map_or(true, |e| e.current() >= *r) { + server_events.push(ServerEvent::EnergyChange { + entity: attacker_entity, + change: EnergyChange { + amount: -(*r as i32), + source: EnergySource::Ability, + }, + }); + true + } else { + false + } + }, None => true, } { match effect.effect { @@ -216,7 +232,7 @@ impl Attack { }); }, AttackEffect::Poise(p) => { - let change = PoiseChange::from_attack(p, inventory); + let change = PoiseChange::from_attack(p, target_inventory); server_events.push(ServerEvent::PoiseChange { entity: target_entity, change, @@ -299,6 +315,7 @@ pub enum AttackEffect { #[derive(Clone, Debug, Serialize, Deserialize)] pub enum CombatRequirement { AnyDamage, + SufficientEnergy(u32), } #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] diff --git a/common/src/states/basic_beam.rs b/common/src/states/basic_beam.rs index b4de42bf78..ccaab77a04 100644 --- a/common/src/states/basic_beam.rs +++ b/common/src/states/basic_beam.rs @@ -138,7 +138,9 @@ impl CharacterBehavior for Data { let damage = DamageComponent::new(damage, Some(GroupTarget::OutOfGroup)) .with_effect(lifesteal); let heal = EffectComponent::new(Some(GroupTarget::InGroup), heal) - /*.with_requirement(CombatRequirement::SufficientEnergy(self.static_data.energy_cost))*/; + .with_requirement(CombatRequirement::SufficientEnergy( + self.static_data.energy_cost, + )); let attack = Attack::default() .with_damage(damage) .with_effect(energy) diff --git a/common/sys/src/beam.rs b/common/sys/src/beam.rs index 6fa408b253..96d50d8c81 100644 --- a/common/sys/src/beam.rs +++ b/common/sys/src/beam.rs @@ -175,6 +175,7 @@ impl<'a> System<'a> for Sys { b, inventory_b_maybe, owner_uid, + energies.get(beam_owner), ori.0, false, ); @@ -187,77 +188,6 @@ impl<'a> System<'a> for Sys { server_emitter.emit(event); } } - - // for (target, damage) in beam_segment.damages.iter() { - // if let Some(target) = target { - // if *target != target_group { - // continue; - // } - // } - - // // Modify damage - // let change = damage.modify_damage( - // inventories.get(b), - // beam_segment.owner, - // false, - // 0.0, - // ); - - // match target { - // Some(GroupTarget::OutOfGroup) => { - // server_emitter.emit(ServerEvent::Damage { - // entity: b, change }); if - // let Some(entity) = beam_owner { - // server_emitter.emit(ServerEvent::Damage { - // entity, - // change: HealthChange { - // amount: (-change.amount as f32 - // * beam_segment.lifesteal_eff) - // as i32, - // cause: HealthSource::Heal { - // by: beam_segment.owner, - // }, - // }, - // }); - // - // server_emitter.emit(ServerEvent::EnergyChange { - // entity, - // change: EnergyChange { - // amount: beam_segment.energy_regen - // as i32, - // source: EnergySource::HitEnemy, - // }, - // }); - // } - // }, - // Some(GroupTarget::InGroup) => { - // if let Some(energy) = beam_owner.and_then(|o| - // energies.get(o)) { if - // energy.current() > beam_segment.energy_cost { - // - // server_emitter.emit(ServerEvent::EnergyChange { - // entity: beam_owner.unwrap(), /* - // If it's able to get an energy - // * component, the entity exists */ - // change: EnergyChange { - // amount: - // -(beam_segment.energy_cost as i32), // Stamina use - // source: - // EnergySource::Ability, - // }, }); - // server_emitter - // .emit(ServerEvent::Damage { - // entity: b, change }); - // } } - // }, - // None => {}, - // } - - // // Adds entities that were hit to the hit_entities - // list on the beam, sees if // it needs - // to purge the hit_entities list - // hit_entities.push(*uid_b); - // } } } } diff --git a/common/sys/src/melee.rs b/common/sys/src/melee.rs index 675e5f5a92..187cff1f24 100644 --- a/common/sys/src/melee.rs +++ b/common/sys/src/melee.rs @@ -1,5 +1,5 @@ use common::{ - comp::{group, Body, CharacterState, Health, Inventory, MeleeAttack, Ori, Pos, Scale}, + comp::{group, Body, CharacterState, Energy, Health, Inventory, MeleeAttack, Ori, Pos, Scale}, event::{EventBus, LocalEvent, ServerEvent}, metrics::SysMetrics, span, @@ -26,6 +26,7 @@ impl<'a> System<'a> for Sys { ReadStorage<'a, Scale>, ReadStorage<'a, Body>, ReadStorage<'a, Health>, + ReadStorage<'a, Energy>, ReadStorage<'a, Inventory>, ReadStorage<'a, group::Group>, WriteStorage<'a, MeleeAttack>, @@ -45,6 +46,7 @@ impl<'a> System<'a> for Sys { scales, bodies, healths, + energies, inventories, groups, mut attacking_storage, @@ -133,6 +135,7 @@ impl<'a> System<'a> for Sys { b, inventory_b_maybe, *uid, + energies.get(entity), dir, is_dodge, ); diff --git a/common/sys/src/projectile.rs b/common/sys/src/projectile.rs index bae042cecd..06ea65802c 100644 --- a/common/sys/src/projectile.rs +++ b/common/sys/src/projectile.rs @@ -1,5 +1,7 @@ use common::{ - comp::{projectile, Group, HealthSource, Inventory, Ori, PhysicsState, Pos, Projectile, Vel}, + comp::{ + projectile, Energy, Group, HealthSource, Inventory, Ori, PhysicsState, Pos, Projectile, Vel, + }, event::{EventBus, ServerEvent}, metrics::SysMetrics, resources::DeltaTime, @@ -29,6 +31,7 @@ impl<'a> System<'a> for Sys { WriteStorage<'a, Projectile>, ReadStorage<'a, Inventory>, ReadStorage<'a, Group>, + ReadStorage<'a, Energy>, ); fn run( @@ -46,6 +49,7 @@ impl<'a> System<'a> for Sys { mut projectiles, inventories, groups, + energies, ): Self::SystemData, ) { let start_time = std::time::Instant::now(); @@ -110,6 +114,7 @@ impl<'a> System<'a> for Sys { target_entity, inventories.get(target_entity), owner, + energies.get(owner_entity), ori.0, false, );