From c449b229d56156e0a301df85fa61b0f3db1db120 Mon Sep 17 00:00:00 2001 From: danielkenji83 Date: Sat, 17 Feb 2024 19:09:32 -0300 Subject: [PATCH] Updates from review --- assets/common/abilities/axe/basic_guard.ron | 1 - .../common/abilities/hammer/basic_guard.ron | 1 - .../common/abilities/haniwa/soldier/guard.ron | 1 - .../common/abilities/shield/basic_guard.ron | 3 +- assets/common/abilities/sword/basic_guard.ron | 1 - .../abilities/sword/defensive_deflect.ron | 1 - .../abilities/sword/defensive_guard.ron | 3 +- common/src/combat.rs | 125 ++++++------------ common/src/comp/ability.rs | 18 +-- common/src/comp/character_state.rs | 61 ++------- common/src/states/basic_block.rs | 2 - .../src/audio/sfx/event_mapper/combat/mod.rs | 15 +-- 12 files changed, 68 insertions(+), 164 deletions(-) diff --git a/assets/common/abilities/axe/basic_guard.ron b/assets/common/abilities/axe/basic_guard.ron index cbf5e66629..806040ad62 100644 --- a/assets/common/abilities/axe/basic_guard.ron +++ b/assets/common/abilities/axe/basic_guard.ron @@ -10,7 +10,6 @@ BasicBlock( energy_cost: 5, energy_regen: 2.5, can_hold: true, - can_use_block_priority: true, blocked_attacks: ( melee: true, projectiles: false, diff --git a/assets/common/abilities/hammer/basic_guard.ron b/assets/common/abilities/hammer/basic_guard.ron index cbf5e66629..806040ad62 100644 --- a/assets/common/abilities/hammer/basic_guard.ron +++ b/assets/common/abilities/hammer/basic_guard.ron @@ -10,7 +10,6 @@ BasicBlock( energy_cost: 5, energy_regen: 2.5, can_hold: true, - can_use_block_priority: true, blocked_attacks: ( melee: true, projectiles: false, diff --git a/assets/common/abilities/haniwa/soldier/guard.ron b/assets/common/abilities/haniwa/soldier/guard.ron index 8181e8dd89..9c113d535e 100644 --- a/assets/common/abilities/haniwa/soldier/guard.ron +++ b/assets/common/abilities/haniwa/soldier/guard.ron @@ -10,7 +10,6 @@ BasicBlock( energy_cost: 0, energy_regen: 0, can_hold: true, - can_use_block_priority: true, blocked_attacks: ( melee: true, projectiles: true, diff --git a/assets/common/abilities/shield/basic_guard.ron b/assets/common/abilities/shield/basic_guard.ron index 41bfd29363..c83588e770 100644 --- a/assets/common/abilities/shield/basic_guard.ron +++ b/assets/common/abilities/shield/basic_guard.ron @@ -2,7 +2,7 @@ BasicBlock( buildup_duration: 0.45, recover_duration: 0.2, max_angle: 90.0, - block_strength: 1.0, + block_strength: 1.5, parry_window: ( buildup: true, recover: false, @@ -10,7 +10,6 @@ BasicBlock( energy_cost: 5.0, energy_regen: 5.0, can_hold: true, - can_use_block_priority: true, blocked_attacks: ( melee: true, projectiles: true, diff --git a/assets/common/abilities/sword/basic_guard.ron b/assets/common/abilities/sword/basic_guard.ron index cbf5e66629..806040ad62 100644 --- a/assets/common/abilities/sword/basic_guard.ron +++ b/assets/common/abilities/sword/basic_guard.ron @@ -10,7 +10,6 @@ BasicBlock( energy_cost: 5, energy_regen: 2.5, can_hold: true, - can_use_block_priority: true, blocked_attacks: ( melee: true, projectiles: false, diff --git a/assets/common/abilities/sword/defensive_deflect.ron b/assets/common/abilities/sword/defensive_deflect.ron index cbc6a7e633..c69db2c8da 100644 --- a/assets/common/abilities/sword/defensive_deflect.ron +++ b/assets/common/abilities/sword/defensive_deflect.ron @@ -10,7 +10,6 @@ BasicBlock( energy_cost: 2.5, energy_regen: 17.5, can_hold: false, - can_use_block_priority: false, blocked_attacks: ( melee: false, projectiles: true, diff --git a/assets/common/abilities/sword/defensive_guard.ron b/assets/common/abilities/sword/defensive_guard.ron index 8f2bf14b8d..2479779d3d 100644 --- a/assets/common/abilities/sword/defensive_guard.ron +++ b/assets/common/abilities/sword/defensive_guard.ron @@ -2,7 +2,7 @@ BasicBlock( buildup_duration: 0.4, recover_duration: 0.15, max_angle: 60.0, - block_strength: 1.1, + block_strength: 1.15, parry_window: ( buildup: true, recover: false, @@ -10,7 +10,6 @@ BasicBlock( energy_cost: 2.5, energy_regen: 17.5, can_hold: true, - can_use_block_priority: true, blocked_attacks: ( melee: true, projectiles: false, diff --git a/common/src/combat.rs b/common/src/combat.rs index 03b4d15f96..e32f018eca 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -58,8 +58,9 @@ pub const MAX_HEADSHOT_PRECISION: f32 = 1.0; pub const MAX_TOP_HEADSHOT_PRECISION: f32 = 0.5; pub const MAX_BEAM_DUR_PRECISION: f32 = 0.25; pub const MAX_MELEE_POISE_PRECISION: f32 = 0.5; -pub const MAX_BLOCK_POISE_COST: f32 = 25.0; +pub const MAX_BLOCK_POISE_COST: f32 = 50.0; pub const PARRY_BONUS_MULTIPLIER: f32 = 2.0; +pub const BLOCK_STRENGTH_MULTIPLIER: f32 = 5.0; #[derive(Copy, Clone)] pub struct AttackerInfo<'a> { @@ -144,6 +145,7 @@ impl Attack { pub fn compute_block_damage_decrement( attacker: Option<&AttackerInfo>, + damage_reduction: f32, target: &TargetInfo, source: AttackSource, dir: Dir, @@ -157,6 +159,7 @@ impl Attack { if let (Some(char_state), Some(ori), Some(inventory)) = (target.char_state, target.ori, target.inventory) { + let damage_value = damage.value * (1.0 - damage_reduction); let block_strength = block_strength(inventory, char_state); if ori.look_vec().angle_between(-dir.with_z(0.0)) < char_state.block_angle() && block_strength > 0.0 @@ -164,7 +167,7 @@ impl Attack { if char_state.is_parry(source) { let final_block_strength = block_strength * PARRY_BONUS_MULTIPLIER; let poise_change = Poise::apply_poise_reduction( - (damage.value.min(final_block_strength) * MAX_BLOCK_POISE_COST) + (damage_value.min(final_block_strength) * MAX_BLOCK_POISE_COST) / final_block_strength, target.inventory, msm, @@ -192,12 +195,11 @@ impl Attack { time, }, }); - damage.value.min(final_block_strength) + final_block_strength } else if char_state.is_block(source) { - let final_block_strength = block_strength; let poise_change = Poise::apply_poise_reduction( - (damage.value.min(final_block_strength) * MAX_BLOCK_POISE_COST) - / final_block_strength, + (damage_value.min(block_strength) * MAX_BLOCK_POISE_COST) + / block_strength, target.inventory, msm, target.char_state, @@ -218,7 +220,7 @@ impl Attack { time, }, }); - damage.value.min(final_block_strength) + block_strength } else { 0.0 } @@ -324,6 +326,7 @@ impl Attack { let block_damage_decrement = Attack::compute_block_damage_decrement( attacker.as_ref(), + damage_reduction, target, attack_source, dir, @@ -1124,10 +1127,10 @@ impl Damage { | DamageSource::Energy => { // Precise hit damage += precise_damage; - // Block - damage -= block_damage_decrement; // Armor damage *= 1.0 - damage_reduction; + // Block + damage -= f32::min(damage, block_damage_decrement); HealthChange { amount: -damage, @@ -1561,89 +1564,43 @@ pub fn precision_mult_from_flank(attack_dir: Vec3, target_ori: Option<&Ori> } pub fn block_strength(inventory: &Inventory, char_state: &CharacterState) -> f32 { - let equip_slot = if let CharacterState::BasicBlock(data) = char_state { - if data.static_data.can_use_block_priority { - get_block_equip_slot_by_priority(Some(inventory)) - } else { - get_block_equip_slot_by_tool(Some(inventory), data.static_data.ability_info.tool) - } - } else { - get_block_equip_slot_by_tool( - Some(inventory), - char_state.ability_info().and_then(|t| t.tool), - ) - }; + let equip_slot = get_equip_slot_by_tool( + Some(inventory), + char_state.ability_info().and_then(|t| t.tool), + ); - inventory - .equipped(equip_slot) + inventory.equipped(equip_slot) .map(|item| match &*item.kind() { - ItemKind::Tool(tool) => tool.stats(item.stats_durability_multiplier()).power * 10.0, + ItemKind::Tool(tool) => tool.stats(item.stats_durability_multiplier()).power, _ => 0.0, }) - .map_or(0.0, |weapon_block_strength| match char_state { - CharacterState::BasicBlock(data) => { - weapon_block_strength * data.static_data.block_strength - }, - CharacterState::ComboMelee2(data) => { - let capabilities = data.static_data.ability_info.ability_meta.capabilities; + .map_or(0.0, |tool_block_strength| match char_state { + CharacterState::BasicBlock(data) => data.static_data.block_strength, + CharacterState::RiposteMelee(_) => tool_block_strength, + _ => char_state + .ability_info() + .map(|ability| ability.ability_meta.capabilities) + .map_or(0.0, |capabilities| { + if capabilities.contains(Capability::PARRIES) + || capabilities.contains(Capability::PARRIES_MELEE) + { + return tool_block_strength; + } - if capabilities.contains(Capability::PARRIES) - || capabilities.contains(Capability::PARRIES_MELEE) - { - return weapon_block_strength; - } + if capabilities.contains(Capability::BLOCKS) { + return tool_block_strength * 0.5; + } - if capabilities.contains(Capability::BLOCKS) { - return weapon_block_strength * 0.5; - } - - 0.0 - }, - CharacterState::RiposteMelee(_) => weapon_block_strength, - CharacterState::Idle(_) - | CharacterState::Climb(_) - | CharacterState::Sit - | CharacterState::Dance - | CharacterState::Talk - | CharacterState::Glide(_) - | CharacterState::GlideWield(_) - | CharacterState::Stunned(_) - | CharacterState::Equipping(_) - | CharacterState::Wielding(_) - | CharacterState::Roll(_) - | CharacterState::BasicMelee(_) - | CharacterState::BasicRanged(_) - | CharacterState::Boost(_) - | CharacterState::DashMelee(_) - | CharacterState::ComboMeleeDeprecated(_) - | CharacterState::LeapMelee(_) - | CharacterState::LeapShockwave(_) - | CharacterState::ChargedRanged(_) - | CharacterState::ChargedMelee(_) - | CharacterState::RepeaterRanged(_) - | CharacterState::Shockwave(_) - | CharacterState::BasicBeam(_) - | CharacterState::BasicAura(_) - | CharacterState::Blink(_) - | CharacterState::BasicSummon(_) - | CharacterState::SelfBuff(_) - | CharacterState::SpriteSummon(_) - | CharacterState::UseItem(_) - | CharacterState::SpriteInteract(_) - | CharacterState::Wallrun(_) - | CharacterState::Skate(_) - | CharacterState::Music(_) - | CharacterState::FinisherMelee(_) - | CharacterState::DiveMelee(_) - | CharacterState::RapidMelee(_) => 0.0, - }) + 0.0 + }), + } * BLOCK_STRENGTH_MULTIPLIER) } -pub fn get_block_equip_slot_by_priority(inventory: Option<&Inventory>) -> EquipSlot { +pub fn get_equip_slot_by_block_priority(inventory: Option<&Inventory>) -> EquipSlot { inventory .map(get_weapon_kinds) .map_or( - EquipSlot::ActiveOffhand, + EquipSlot::ActiveMainhand, |weapon_kinds| match weapon_kinds { (Some(mainhand), Some(offhand)) => { if mainhand.block_priority() >= offhand.block_priority() { @@ -1654,19 +1611,19 @@ pub fn get_block_equip_slot_by_priority(inventory: Option<&Inventory>) -> EquipS }, (Some(_), None) => EquipSlot::ActiveMainhand, (None, Some(_)) => EquipSlot::ActiveOffhand, - (None, None) => EquipSlot::ActiveOffhand, + (None, None) => EquipSlot::ActiveMainhand, }, ) } -pub fn get_block_equip_slot_by_tool( +pub fn get_equip_slot_by_tool( inventory: Option<&Inventory>, tool_kind: Option, ) -> EquipSlot { inventory .map(get_weapon_kinds) .map_or( - EquipSlot::ActiveOffhand, + EquipSlot::ActiveMainhand, |weapon_kinds| match weapon_kinds { (mainhand, Some(_)) => { if mainhand == tool_kind { diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index ae707ce81c..6a5d880eab 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -196,7 +196,7 @@ impl ActiveAbilities { match ability { Ability::ToolGuard => { - let equip_slot = combat::get_block_equip_slot_by_priority(inv); + let equip_slot = combat::get_equip_slot_by_block_priority(inv); ability_set(equip_slot) .and_then(|abilities| { abilities @@ -393,7 +393,7 @@ impl Ability { }; match self { - Ability::ToolGuard => ability_set(combat::get_block_equip_slot_by_priority(inv)) + Ability::ToolGuard => ability_set(combat::get_equip_slot_by_block_priority(inv)) .and_then(|abilities| { abilities .guard(skillset, context) @@ -521,7 +521,7 @@ impl SpecifiedAbility { ability_set(EquipSlot::ActiveMainhand) .map(|abilities| ability_id(self, &abilities.secondary)) }), - Ability::ToolGuard => ability_set(combat::get_block_equip_slot_by_priority(inv)) + Ability::ToolGuard => ability_set(combat::get_equip_slot_by_block_priority(inv)) .and_then(|abilities| abilities.guard.as_ref().map(|a| ability_id(self, a))) .or_else(|| { ability_set(EquipSlot::ActiveMainhand) @@ -756,7 +756,6 @@ pub enum CharacterAbility { energy_cost: f32, energy_regen: f32, can_hold: bool, - can_use_block_priority: bool, blocked_attacks: AttackFilters, #[serde(default)] meta: AbilityMeta, @@ -1277,19 +1276,18 @@ impl CharacterAbility { ref mut recover_duration, // Do we want angle to be adjusted by range? max_angle: _, - // Block strength explicitly not modified by power, that will be a separate stat - block_strength: _, + ref mut block_strength, parry_window: _, ref mut energy_cost, energy_regen: _, can_hold: _, - can_use_block_priority: _, blocked_attacks: _, meta: _, } => { *buildup_duration /= stats.speed; *recover_duration /= stats.speed; *energy_cost /= stats.energy_efficiency; + *block_strength *= stats.power; }, Roll { ref mut energy_cost, @@ -2348,7 +2346,6 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { energy_cost, energy_regen, can_hold, - can_use_block_priority, blocked_attacks, meta: _, } => CharacterState::BasicBlock(basic_block::Data { @@ -2361,7 +2358,6 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { energy_cost: *energy_cost, energy_regen: *energy_regen, can_hold: *can_hold, - can_use_block_priority: *can_use_block_priority, blocked_attacks: *blocked_attacks, ability_info, }, @@ -3005,9 +3001,7 @@ bitflags::bitflags! { // If more are ever needed, first check if any not used anymore, as some were only used in intermediary stages so may be free pub struct Capability: u8 { // The ability will parry all blockable attacks in the buildup portion - const PARRIES = 0b01000000; - // There used to be a capability here, to keep ordering the same below this is now a placeholder - const PLACEHOLDER = 0b00000001; + const PARRIES = 0b00000001; // Allows blocking to interrupt the ability at any point const BLOCK_INTERRUPT = 0b00000010; // When the ability is in the buildup section, it counts as a block with 50% DR diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 4b02081d30..2e693f2c14 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -354,57 +354,20 @@ impl CharacterState { data.static_data.blocked_attacks.applies(attack_source) && matches!( self.stage_section(), - Some(StageSection::Buildup | StageSection::Action), + Some(StageSection::Buildup | StageSection::Action) ) }, - CharacterState::ComboMelee2(data) => { - data.static_data - .ability_info - .ability_meta - .capabilities - .contains(Capability::BLOCKS) - && matches!( - self.stage_section(), - Some(StageSection::Buildup | StageSection::Action), - ) - }, - CharacterState::Idle(_) - | CharacterState::Climb(_) - | CharacterState::Sit - | CharacterState::Dance - | CharacterState::Talk - | CharacterState::Glide(_) - | CharacterState::GlideWield(_) - | CharacterState::Stunned(_) - | CharacterState::Equipping(_) - | CharacterState::Wielding(_) - | CharacterState::Roll(_) - | CharacterState::BasicMelee(_) - | CharacterState::BasicRanged(_) - | CharacterState::Boost(_) - | CharacterState::DashMelee(_) - | CharacterState::ComboMeleeDeprecated(_) - | CharacterState::LeapMelee(_) - | CharacterState::LeapShockwave(_) - | CharacterState::ChargedRanged(_) - | CharacterState::ChargedMelee(_) - | CharacterState::RepeaterRanged(_) - | CharacterState::Shockwave(_) - | CharacterState::BasicBeam(_) - | CharacterState::BasicAura(_) - | CharacterState::Blink(_) - | CharacterState::BasicSummon(_) - | CharacterState::SelfBuff(_) - | CharacterState::SpriteSummon(_) - | CharacterState::UseItem(_) - | CharacterState::SpriteInteract(_) - | CharacterState::Wallrun(_) - | CharacterState::Skate(_) - | CharacterState::Music(_) - | CharacterState::FinisherMelee(_) - | CharacterState::DiveMelee(_) - | CharacterState::RiposteMelee(_) - | CharacterState::RapidMelee(_) => false, + _ => self + .ability_info() + .map(|ability| ability.ability_meta.capabilities) + .map_or(false, |capabilities| { + capabilities.contains(Capability::BLOCKS) + && matches!( + self.stage_section(), + Some(StageSection::Buildup | StageSection::Action) + ) + && matches!(attack_source, AttackSource::Melee) + }), } } diff --git a/common/src/states/basic_block.rs b/common/src/states/basic_block.rs index 0f494812ed..c352b9a449 100644 --- a/common/src/states/basic_block.rs +++ b/common/src/states/basic_block.rs @@ -37,8 +37,6 @@ pub struct StaticData { pub energy_regen: f32, /// Whether block can be held pub can_hold: bool, - /// Whether can choose higher priority weapon block - pub can_use_block_priority: bool, /// What kinds of attacks the block applies to pub blocked_attacks: AttackFilters, } diff --git a/voxygen/src/audio/sfx/event_mapper/combat/mod.rs b/voxygen/src/audio/sfx/event_mapper/combat/mod.rs index 32fd2098c1..5cdae03c80 100644 --- a/voxygen/src/audio/sfx/event_mapper/combat/mod.rs +++ b/voxygen/src/audio/sfx/event_mapper/combat/mod.rs @@ -146,14 +146,13 @@ impl CombatEventMapper { previous_state: &PreviousEntityState, inventory: &Inventory, ) -> SfxEvent { - let hand_info = character_state.ability_info().and_then(|a| a.hand); - - let equip_slot = match hand_info { - Some(HandInfo::TwoHanded) => EquipSlot::ActiveMainhand, - Some(HandInfo::MainHand) => EquipSlot::ActiveMainhand, - Some(HandInfo::OffHand) => EquipSlot::ActiveOffhand, - None => EquipSlot::ActiveMainhand, - }; + let equip_slot = character_state + .ability_info() + .and_then(|ability| ability.hand) + .map_or(EquipSlot::ActiveMainhand, |hand| match hand { + HandInfo::TwoHanded | HandInfo::MainHand => EquipSlot::ActiveMainhand, + HandInfo::OffHand => EquipSlot::ActiveOffhand, + }); if let Some(item) = inventory.equipped(equip_slot) { if let ItemKind::Tool(data) = &*item.kind() {