Updates from review

This commit is contained in:
danielkenji83 2024-02-18 23:30:43 -03:00
parent 1271b5ff9a
commit 9d73fcfc3f
16 changed files with 99 additions and 117 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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"),
),
)

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,
},
)
}

View File

@ -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,
},

View File

@ -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)

View File

@ -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,

View File

@ -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