diff --git a/common/src/combat.rs b/common/src/combat.rs index a1976d5246..e8fb6270da 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -131,6 +131,7 @@ impl Attack { source: AttackSource, dir: Dir, kind: DamageKind, + mut emit: impl FnMut(ServerEvent), mut emit_outcome: impl FnMut(Outcome), ) -> f32 { let damage_reduction = @@ -148,6 +149,10 @@ impl Attack { pos: target.pos, uid: target.uid, }); + emit(ServerEvent::Parry { + entity: target.entity, + energy_cost: data.static_data.energy_cost, + }); if parry { 1.0 } else { @@ -213,6 +218,7 @@ impl Attack { attack_source, dir, damage.damage.kind, + |e| emit(e), |o| emit_outcome(o), ); let change = damage.damage.calculate_health_change( diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 1415a74461..0e17a456c7 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -1572,13 +1572,14 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { recover_duration, max_angle, block_strength, - energy_cost: _, + energy_cost, } => CharacterState::BasicBlock(basic_block::Data { static_data: basic_block::StaticData { buildup_duration: Duration::from_secs_f32(*buildup_duration), recover_duration: Duration::from_secs_f32(*recover_duration), max_angle: *max_angle, block_strength: *block_strength, + energy_cost: *energy_cost as i32, ability_info, }, timer: Duration::default(), diff --git a/common/src/event.rs b/common/src/event.rs index 843c775f89..a3852dc1ea 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -167,6 +167,10 @@ pub enum ServerEvent { entity: EcsEntity, change: i32, }, + Parry { + entity: EcsEntity, + energy_cost: i32, + }, RequestSiteInfo { entity: EcsEntity, id: SiteId, diff --git a/common/src/states/basic_block.rs b/common/src/states/basic_block.rs index aca9b9edec..bfbcaf51d5 100644 --- a/common/src/states/basic_block.rs +++ b/common/src/states/basic_block.rs @@ -19,6 +19,8 @@ pub struct StaticData { pub block_strength: f32, /// What key is used to press ability pub ability_info: AbilityInfo, + /// Energy consumed to initiate the block + pub energy_cost: i32, } #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 57b3c6c302..6e96b72cd9 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -17,9 +17,9 @@ use common::{ self, aura, buff, chat::{KillSource, KillType}, inventory::item::MaterialStatManifest, - object, Alignment, Auras, Body, CharacterState, Energy, EnergyChange, Group, Health, - HealthChange, HealthSource, Inventory, Player, Poise, PoiseChange, PoiseSource, Pos, - SkillSet, Stats, + object, Alignment, Auras, Body, CharacterState, Energy, EnergyChange, EnergySource, Group, + Health, HealthChange, HealthSource, Inventory, Player, Poise, PoiseChange, PoiseSource, + Pos, SkillSet, Stats, }, event::{EventBus, ServerEvent}, lottery::{LootSpec, Lottery}, @@ -1206,6 +1206,19 @@ pub fn handle_combo_change(server: &Server, entity: EcsEntity, change: i32) { } } +pub fn handle_parry(server: &Server, entity: EcsEntity, energy_cost: i32) { + let ecs = &server.state.ecs(); + if let Some(mut character) = ecs.write_storage::().get_mut(entity) { + *character = CharacterState::Wielding; + }; + if let Some(mut energy) = ecs.write_storage::().get_mut(entity) { + energy.change_by(EnergyChange { + amount: energy_cost, + source: EnergySource::Ability, + }); + } +} + pub fn handle_teleport_to(server: &Server, entity: EcsEntity, target: Uid, max_range: Option) { let ecs = &server.state.ecs(); let mut positions = ecs.write_storage::(); diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index b4df9f7d6a..3aeb9e7d58 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -8,7 +8,8 @@ use entity_creation::{ use entity_manipulation::{ handle_aura, handle_bonk, handle_buff, handle_combo_change, handle_damage, handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook, handle_explosion, - handle_knockback, handle_land_on_ground, handle_poise, handle_respawn, handle_teleport_to, + handle_knockback, handle_land_on_ground, handle_parry, handle_poise, handle_respawn, + handle_teleport_to, }; use group_manip::handle_group; use information::handle_site_info; @@ -209,6 +210,10 @@ impl Server { ServerEvent::ComboChange { entity, change } => { handle_combo_change(self, entity, change) }, + ServerEvent::Parry { + entity, + energy_cost, + } => handle_parry(self, entity, energy_cost), ServerEvent::RequestSiteInfo { entity, id } => handle_site_info(self, entity, id), ServerEvent::MineBlock { entity, pos, tool } => { handle_mine_block(self, entity, pos, tool)