mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Updates from review
This commit is contained in:
parent
1271b5ff9a
commit
9d73fcfc3f
@ -2,7 +2,7 @@ BasicBlock(
|
||||
buildup_duration: 0.25,
|
||||
recover_duration: 0.2,
|
||||
max_angle: 60.0,
|
||||
block_strength: 1.0,
|
||||
block_strength: 5.0,
|
||||
parry_window: (
|
||||
buildup: true,
|
||||
recover: false,
|
||||
|
@ -2,7 +2,7 @@ BasicBlock(
|
||||
buildup_duration: 0.25,
|
||||
recover_duration: 0.2,
|
||||
max_angle: 60.0,
|
||||
block_strength: 1.0,
|
||||
block_strength: 5.0,
|
||||
parry_window: (
|
||||
buildup: true,
|
||||
recover: false,
|
||||
|
@ -2,7 +2,7 @@ BasicBlock(
|
||||
buildup_duration: 0.25,
|
||||
recover_duration: 0.25,
|
||||
max_angle: 90.0,
|
||||
block_strength: 1.0,
|
||||
block_strength: 5.0,
|
||||
parry_window: (
|
||||
buildup: false,
|
||||
recover: false,
|
||||
|
@ -3,6 +3,7 @@ RiposteMelee(
|
||||
buildup_duration: 0.7,
|
||||
swing_duration: 0.3,
|
||||
recover_duration: 0.2,
|
||||
block_strength: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 30,
|
||||
|
@ -2,7 +2,7 @@ BasicBlock(
|
||||
buildup_duration: 0.45,
|
||||
recover_duration: 0.2,
|
||||
max_angle: 90.0,
|
||||
block_strength: 1.5,
|
||||
block_strength: 10.0,
|
||||
parry_window: (
|
||||
buildup: true,
|
||||
recover: false,
|
||||
|
@ -26,7 +26,7 @@ ComboMelee2(
|
||||
],
|
||||
energy_cost_per_strike: 0,
|
||||
meta: (
|
||||
// // The ability will parry all blockable attacks in the buildup portion
|
||||
// The ability will parry all blockable attacks in the buildup portion
|
||||
capabilities: ("PARRIES"),
|
||||
),
|
||||
)
|
@ -2,7 +2,7 @@ BasicBlock(
|
||||
buildup_duration: 0.25,
|
||||
recover_duration: 0.2,
|
||||
max_angle: 60.0,
|
||||
block_strength: 1.0,
|
||||
block_strength: 5.0,
|
||||
parry_window: (
|
||||
buildup: true,
|
||||
recover: false,
|
||||
|
@ -2,7 +2,7 @@ BasicBlock(
|
||||
buildup_duration: 0.4,
|
||||
recover_duration: 0.2,
|
||||
max_angle: 45.0,
|
||||
block_strength: 1.0,
|
||||
block_strength: 5.0,
|
||||
parry_window: (
|
||||
buildup: true,
|
||||
recover: false,
|
||||
|
@ -2,7 +2,7 @@ BasicBlock(
|
||||
buildup_duration: 0.4,
|
||||
recover_duration: 0.15,
|
||||
max_angle: 60.0,
|
||||
block_strength: 1.15,
|
||||
block_strength: 5.75,
|
||||
parry_window: (
|
||||
buildup: true,
|
||||
recover: false,
|
||||
|
@ -3,6 +3,7 @@ RiposteMelee(
|
||||
buildup_duration: 0.4,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.2,
|
||||
block_strength: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 18,
|
||||
|
@ -6,9 +6,9 @@ ItemDef(
|
||||
hands: One,
|
||||
stats: (
|
||||
equip_time_secs: 0.3,
|
||||
power: 0.4,
|
||||
power: 0.5,
|
||||
effect_power: 1.0,
|
||||
speed: 0.8,
|
||||
speed: 1.0,
|
||||
range: 1.0,
|
||||
energy_efficiency: 1.0,
|
||||
buff_strength: 1.0,
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
||||
},
|
||||
outcome::Outcome,
|
||||
resources::{Secs, Time},
|
||||
states::utils::StageSection,
|
||||
states::utils::{HandInfo, StageSection},
|
||||
uid::{IdMaps, Uid},
|
||||
util::Dir,
|
||||
};
|
||||
@ -60,7 +60,7 @@ 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 = 50.0;
|
||||
pub const PARRY_BONUS_MULTIPLIER: f32 = 2.0;
|
||||
pub const BLOCK_STRENGTH_MULTIPLIER: f32 = 5.0;
|
||||
pub const FALLBACK_BLOCK_STRENGTH: f32 = 5.0;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct AttackerInfo<'a> {
|
||||
@ -159,71 +159,52 @@ impl Attack {
|
||||
if let (Some(char_state), Some(ori), Some(inventory)) =
|
||||
(target.char_state, target.ori, target.inventory)
|
||||
{
|
||||
let is_parry = char_state.is_parry(source);
|
||||
let is_block = char_state.is_block(source);
|
||||
let damage_value = damage.value * (1.0 - damage_reduction);
|
||||
let block_strength = block_strength(inventory, char_state);
|
||||
let mut block_strength = block_strength(inventory, char_state);
|
||||
|
||||
if ori.look_vec().angle_between(-dir.with_z(0.0)) < char_state.block_angle()
|
||||
&& (is_parry || is_block)
|
||||
&& block_strength > 0.0
|
||||
{
|
||||
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)
|
||||
/ final_block_strength,
|
||||
target.inventory,
|
||||
msm,
|
||||
target.char_state,
|
||||
target.stats,
|
||||
);
|
||||
if is_parry {
|
||||
block_strength *= PARRY_BONUS_MULTIPLIER;
|
||||
|
||||
emit_outcome(Outcome::Block {
|
||||
parry: true,
|
||||
pos: target.pos,
|
||||
uid: target.uid,
|
||||
});
|
||||
emitters.emit(ParryHookEvent {
|
||||
defender: target.entity,
|
||||
attacker: attacker.map(|a| a.entity),
|
||||
source,
|
||||
});
|
||||
emitters.emit(PoiseChangeEvent {
|
||||
entity: target.entity,
|
||||
change: PoiseChange {
|
||||
amount: -poise_change,
|
||||
impulse: *dir,
|
||||
by: attacker.map(|x| (*x).into()),
|
||||
cause: Some(damage.source),
|
||||
time,
|
||||
},
|
||||
});
|
||||
final_block_strength
|
||||
} else if char_state.is_block(source) {
|
||||
let poise_change = Poise::apply_poise_reduction(
|
||||
(damage_value.min(block_strength) * MAX_BLOCK_POISE_COST)
|
||||
/ block_strength,
|
||||
target.inventory,
|
||||
msm,
|
||||
target.char_state,
|
||||
target.stats,
|
||||
);
|
||||
emit_outcome(Outcome::Block {
|
||||
parry: false,
|
||||
pos: target.pos,
|
||||
uid: target.uid,
|
||||
});
|
||||
emitters.emit(PoiseChangeEvent {
|
||||
entity: target.entity,
|
||||
change: PoiseChange {
|
||||
amount: -poise_change,
|
||||
impulse: *dir,
|
||||
by: attacker.map(|x| (*x).into()),
|
||||
cause: Some(damage.source),
|
||||
time,
|
||||
},
|
||||
});
|
||||
block_strength
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
|
||||
let poise_cost =
|
||||
(damage_value / block_strength).min(1.0) * MAX_BLOCK_POISE_COST;
|
||||
|
||||
let poise_change = Poise::apply_poise_reduction(
|
||||
poise_cost,
|
||||
target.inventory,
|
||||
msm,
|
||||
target.char_state,
|
||||
target.stats,
|
||||
);
|
||||
|
||||
emit_outcome(Outcome::Block {
|
||||
parry: is_parry,
|
||||
pos: target.pos,
|
||||
uid: target.uid,
|
||||
});
|
||||
emitters.emit(PoiseChangeEvent {
|
||||
entity: target.entity,
|
||||
change: PoiseChange {
|
||||
amount: -poise_change,
|
||||
impulse: *dir,
|
||||
by: attacker.map(|x| (*x).into()),
|
||||
cause: Some(damage.source),
|
||||
time,
|
||||
},
|
||||
});
|
||||
block_strength
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
@ -248,8 +229,7 @@ impl Attack {
|
||||
.clamp(0.0, 1.0);
|
||||
let raw_damage_reduction =
|
||||
Damage::compute_damage_reduction(Some(damage), target.inventory, target.stats, msm);
|
||||
let damage_reduction = (1.0 - attacker_penetration) * raw_damage_reduction;
|
||||
1.0 - (1.0 - damage_reduction)
|
||||
(1.0 - attacker_penetration) * raw_damage_reduction
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
@ -1130,7 +1110,7 @@ impl Damage {
|
||||
// Armor
|
||||
damage *= 1.0 - damage_reduction;
|
||||
// Block
|
||||
damage -= f32::min(damage, block_damage_decrement);
|
||||
damage = f32::max(damage - block_damage_decrement, 0.0);
|
||||
|
||||
HealthChange {
|
||||
amount: -damage,
|
||||
@ -1564,36 +1544,41 @@ pub fn precision_mult_from_flank(attack_dir: Vec3<f32>, target_ori: Option<&Ori>
|
||||
}
|
||||
|
||||
pub fn block_strength(inventory: &Inventory, char_state: &CharacterState) -> f32 {
|
||||
let equip_slot = get_equip_slot_by_tool(
|
||||
Some(inventory),
|
||||
char_state.ability_info().and_then(|t| t.tool),
|
||||
);
|
||||
|
||||
inventory.equipped(equip_slot)
|
||||
char_state
|
||||
.ability_info()
|
||||
.and_then(|a| match a.hand {
|
||||
Some(HandInfo::TwoHanded | HandInfo::MainHand) => Some(EquipSlot::ActiveMainhand),
|
||||
Some(HandInfo::OffHand) => Some(EquipSlot::ActiveOffhand),
|
||||
None => None,
|
||||
})
|
||||
.and_then(|slot| inventory.equipped(slot))
|
||||
.map(|item| match &*item.kind() {
|
||||
ItemKind::Tool(tool) => tool.stats(item.stats_durability_multiplier()).power,
|
||||
_ => 0.0,
|
||||
})
|
||||
.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;
|
||||
}
|
||||
CharacterState::RiposteMelee(data) => data.static_data.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::BLOCKS) {
|
||||
return tool_block_strength * 0.5;
|
||||
}
|
||||
if capabilities.contains(Capability::BLOCKS) {
|
||||
return tool_block_strength * 0.5;
|
||||
}
|
||||
|
||||
0.0
|
||||
}),
|
||||
} * BLOCK_STRENGTH_MULTIPLIER)
|
||||
0.0
|
||||
})
|
||||
* FALLBACK_BLOCK_STRENGTH
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_equip_slot_by_block_priority(inventory: Option<&Inventory>) -> EquipSlot {
|
||||
@ -1615,25 +1600,3 @@ pub fn get_equip_slot_by_block_priority(inventory: Option<&Inventory>) -> EquipS
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_equip_slot_by_tool(
|
||||
inventory: Option<&Inventory>,
|
||||
tool_kind: Option<ToolKind>,
|
||||
) -> EquipSlot {
|
||||
inventory
|
||||
.map(get_weapon_kinds)
|
||||
.map_or(
|
||||
EquipSlot::ActiveMainhand,
|
||||
|weapon_kinds| match weapon_kinds {
|
||||
(mainhand, Some(_)) => {
|
||||
if mainhand == tool_kind {
|
||||
EquipSlot::ActiveMainhand
|
||||
} else {
|
||||
EquipSlot::ActiveOffhand
|
||||
}
|
||||
},
|
||||
(Some(_), None) => EquipSlot::ActiveMainhand,
|
||||
(None, None) => EquipSlot::ActiveOffhand,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -203,7 +203,13 @@ impl ActiveAbilities {
|
||||
.guard(Some(skill_set), context)
|
||||
.map(|(a, i)| (a.ability.clone(), i))
|
||||
})
|
||||
.map(|(ability, i)| (scale_ability(ability, equip_slot), true, spec_ability(i)))
|
||||
.map(|(ability, i)| {
|
||||
(
|
||||
scale_ability(ability, equip_slot),
|
||||
matches!(equip_slot, EquipSlot::ActiveOffhand),
|
||||
spec_ability(i),
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
ability_set(EquipSlot::ActiveMainhand)
|
||||
.and_then(|abilities| {
|
||||
@ -1003,6 +1009,7 @@ pub enum CharacterAbility {
|
||||
buildup_duration: f32,
|
||||
swing_duration: f32,
|
||||
recover_duration: f32,
|
||||
block_strength: f32,
|
||||
melee_constructor: MeleeConstructor,
|
||||
#[serde(default)]
|
||||
meta: AbilityMeta,
|
||||
@ -1657,6 +1664,7 @@ impl CharacterAbility {
|
||||
ref mut buildup_duration,
|
||||
ref mut swing_duration,
|
||||
ref mut recover_duration,
|
||||
ref mut block_strength,
|
||||
ref mut melee_constructor,
|
||||
meta: _,
|
||||
} => {
|
||||
@ -1664,6 +1672,7 @@ impl CharacterAbility {
|
||||
*swing_duration /= stats.speed;
|
||||
*recover_duration /= stats.speed;
|
||||
*energy_cost /= stats.energy_efficiency;
|
||||
*block_strength *= stats.power;
|
||||
*melee_constructor = melee_constructor.adjusted_by_stats(stats);
|
||||
},
|
||||
RapidMelee {
|
||||
@ -2911,6 +2920,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
buildup_duration,
|
||||
swing_duration,
|
||||
recover_duration,
|
||||
block_strength,
|
||||
melee_constructor,
|
||||
meta: _,
|
||||
} => CharacterState::RiposteMelee(riposte_melee::Data {
|
||||
@ -2918,6 +2928,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||
swing_duration: Duration::from_secs_f32(*swing_duration),
|
||||
recover_duration: Duration::from_secs_f32(*recover_duration),
|
||||
block_strength: *block_strength,
|
||||
melee_constructor: *melee_constructor,
|
||||
ability_info,
|
||||
},
|
||||
|
@ -321,9 +321,13 @@ impl CharacterState {
|
||||
Some(StageSection::Buildup | StageSection::Action)
|
||||
)
|
||||
});
|
||||
let from_capability = !matches!(
|
||||
let from_capability = matches!(
|
||||
attack_source,
|
||||
AttackSource::GroundShockwave | AttackSource::UndodgeableShockwave
|
||||
AttackSource::Melee
|
||||
| AttackSource::Projectile
|
||||
| AttackSource::Beam
|
||||
| AttackSource::AirShockwave
|
||||
| AttackSource::Explosion
|
||||
) && self
|
||||
.ability_info()
|
||||
.map(|a| a.ability_meta.capabilities)
|
||||
|
@ -25,7 +25,7 @@ pub struct StaticData {
|
||||
pub recover_duration: Duration,
|
||||
/// Max angle (45.0 will give you a 90.0 angle window)
|
||||
pub max_angle: f32,
|
||||
/// What percentage of block strength is effective
|
||||
/// What percentage of power is effective
|
||||
pub block_strength: f32,
|
||||
/// What durations are considered a parry
|
||||
pub parry_window: ParryWindow,
|
||||
|
@ -18,6 +18,8 @@ pub struct StaticData {
|
||||
pub swing_duration: Duration,
|
||||
/// How long the state has until exiting
|
||||
pub recover_duration: Duration,
|
||||
/// What percentage of power is effective
|
||||
pub block_strength: f32,
|
||||
/// Used to construct the Melee attack
|
||||
pub melee_constructor: MeleeConstructor,
|
||||
/// What key is used to press ability
|
||||
|
Loading…
Reference in New Issue
Block a user