mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Sword M1 abilities
This commit is contained in:
parent
61f0b424b9
commit
57806d7be9
@ -84,7 +84,7 @@
|
||||
Contextualized(
|
||||
pseudo_id: "veloren.core.psuedo_abilities.sword.finisher",
|
||||
abilities: {
|
||||
None: (Sword(Finisher), "common.abilities.sword.basic_finisher"),
|
||||
None: (Sword(Finisher), "common.abilities.sword.basic_mighty_strike"),
|
||||
Stance(Sword(Heavy)): (Sword(Finisher), "common.abilities.sword.heavy_guillotine"),
|
||||
Stance(Sword(Agile)): (Sword(Finisher), "common.abilities.sword.agile_hundred_cuts"),
|
||||
Stance(Sword(Defensive)): (Sword(Finisher), "common.abilities.sword.defensive_counter"),
|
||||
|
@ -3,7 +3,7 @@ ComboMelee2(
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 5,
|
||||
damage: 3,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 5,
|
||||
@ -11,7 +11,7 @@ ComboMelee2(
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
buildup_duration: 0.15,
|
||||
buildup_duration: 0.1,
|
||||
swing_duration: 0.05,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.1,
|
||||
@ -20,18 +20,18 @@ ComboMelee2(
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 10,
|
||||
damage: 6,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 7.5,
|
||||
energy_regen: 5,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
buildup_duration: 0.1,
|
||||
swing_duration: 0.1,
|
||||
swing_duration: 0.05,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.2,
|
||||
recover_duration: 0.1,
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
|
@ -23,7 +23,7 @@ ComboMelee2(
|
||||
damage: 10,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 7.5,
|
||||
energy_regen: 10,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
|
@ -10,8 +10,9 @@ ComboMelee2(
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
buildup_duration: 0.15,
|
||||
buildup_duration: 0.2,
|
||||
swing_duration: 0.05,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.1,
|
||||
@ -23,15 +24,16 @@ ComboMelee2(
|
||||
damage: 10,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 7.5,
|
||||
energy_regen: 5,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
buildup_duration: 0.1,
|
||||
buildup_duration: 0.15,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.2,
|
||||
recover_duration: 0.25,
|
||||
ori_modifier: 0.6,
|
||||
),
|
||||
],
|
||||
|
@ -10,6 +10,7 @@ ComboMelee2(
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
damage_effect: Some(RefreshBuff(0.1, Bleeding)),
|
||||
),
|
||||
buildup_duration: 0.15,
|
||||
swing_duration: 0.05,
|
||||
@ -23,10 +24,11 @@ ComboMelee2(
|
||||
damage: 10,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 7.5,
|
||||
energy_regen: 10,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
damage_effect: Some(RefreshBuff(0.1, Bleeding)),
|
||||
),
|
||||
buildup_duration: 0.1,
|
||||
swing_duration: 0.1,
|
||||
|
@ -3,7 +3,7 @@ ComboMelee2(
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 5,
|
||||
damage: 4,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 5,
|
||||
@ -20,10 +20,10 @@ ComboMelee2(
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 10,
|
||||
damage: 8,
|
||||
poise: 0,
|
||||
knockback: 0,
|
||||
energy_regen: 7.5,
|
||||
energy_regen: 10,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
@ -36,4 +36,10 @@ ComboMelee2(
|
||||
),
|
||||
],
|
||||
energy_cost_per_strike: 0,
|
||||
meta: (
|
||||
capabilities: (
|
||||
// Buildup blocks melee attacks at 50% strength
|
||||
bits: 0b00000100,
|
||||
),
|
||||
),
|
||||
)
|
@ -3,15 +3,15 @@ ComboMelee2(
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 5,
|
||||
poise: 0,
|
||||
damage: 10,
|
||||
poise: 5,
|
||||
knockback: 0,
|
||||
energy_regen: 5,
|
||||
energy_regen: 10,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
buildup_duration: 0.15,
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.05,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.1,
|
||||
@ -20,15 +20,15 @@ ComboMelee2(
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 10,
|
||||
poise: 0,
|
||||
damage: 15,
|
||||
poise: 10,
|
||||
knockback: 0,
|
||||
energy_regen: 7.5,
|
||||
energy_regen: 15,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
buildup_duration: 0.1,
|
||||
buildup_duration: 0.2,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.2,
|
||||
|
@ -199,6 +199,7 @@ impl Attack {
|
||||
) -> bool {
|
||||
// TODO: Maybe move this higher and pass it as argument into this function?
|
||||
let msm = &MaterialStatManifest::load().read();
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let AttackOptions {
|
||||
target_dodging,
|
||||
@ -219,7 +220,7 @@ impl Attack {
|
||||
matches!(attack_effect.target, Some(GroupTarget::OutOfGroup))
|
||||
&& (target_dodging || !may_harm)
|
||||
};
|
||||
let is_crit = thread_rng().gen::<f32>() < self.crit_chance;
|
||||
let is_crit = rng.gen::<f32>() < self.crit_chance;
|
||||
let mut is_applied = false;
|
||||
let mut accumulated_damage = 0.0;
|
||||
for damage in self
|
||||
@ -360,7 +361,7 @@ impl Attack {
|
||||
}
|
||||
},
|
||||
CombatEffect::Buff(b) => {
|
||||
if thread_rng().gen::<f32>() < b.chance {
|
||||
if rng.gen::<f32>() < b.chance {
|
||||
emit(ServerEvent::Buff {
|
||||
entity: target.entity,
|
||||
buff_change: BuffChange::Add(b.to_buff(
|
||||
@ -452,6 +453,14 @@ impl Attack {
|
||||
});
|
||||
}
|
||||
},
|
||||
CombatEffect::RefreshBuff(chance, b) => {
|
||||
if rng.gen::<f32>() < *chance {
|
||||
emit(ServerEvent::Buff {
|
||||
entity: target.entity,
|
||||
buff_change: BuffChange::Refresh(*b),
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -528,7 +537,7 @@ impl Attack {
|
||||
}
|
||||
},
|
||||
CombatEffect::Buff(b) => {
|
||||
if thread_rng().gen::<f32>() < b.chance {
|
||||
if rng.gen::<f32>() < b.chance {
|
||||
emit(ServerEvent::Buff {
|
||||
entity: target.entity,
|
||||
buff_change: BuffChange::Add(b.to_buff(
|
||||
@ -609,6 +618,14 @@ impl Attack {
|
||||
},
|
||||
// Only has an effect when attached to a damage
|
||||
CombatEffect::BuildupsVulnerable => {},
|
||||
CombatEffect::RefreshBuff(chance, b) => {
|
||||
if rng.gen::<f32>() < chance {
|
||||
emit(ServerEvent::Buff {
|
||||
entity: target.entity,
|
||||
buff_change: BuffChange::Refresh(b),
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -742,9 +759,12 @@ pub enum CombatEffect {
|
||||
Combo(i32),
|
||||
// If the attack hits the target while they are in the buildup portion of a character state,
|
||||
// deal double damage Only has an effect when attached to a damage, otherwise does nothing
|
||||
// if only attached to the attack TODO: Maybe try to make it do something if tied to
|
||||
// if only attached to the attack
|
||||
// TODO: Maybe try to make it do something if tied to
|
||||
// attack, not sure if it should double count in that instance?
|
||||
BuildupsVulnerable,
|
||||
// Resets duration of all buffs of this buffkind, with some probability
|
||||
RefreshBuff(f32, BuffKind),
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
@ -2842,8 +2842,8 @@ bitflags::bitflags! {
|
||||
const ROLL_INTERRUPT = 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 parry
|
||||
const BUILDUP_PARRIES = 0b00000100;
|
||||
// When the ability is in the buildup section, it counts as a block with 50% DR
|
||||
const BUILDUP_BLOCKS = 0b00000100;
|
||||
// When in the ability, an entity only receives half as much poise damage
|
||||
const POISE_RESISTANT = 0b00001000;
|
||||
// WHen in the ability, an entity only receives half as much knockback
|
||||
|
@ -258,6 +258,8 @@ pub enum BuffChange {
|
||||
any_required: Vec<BuffCategory>,
|
||||
none_required: Vec<BuffCategory>,
|
||||
},
|
||||
// Refreshes durations of all buffs with this kind
|
||||
Refresh(BuffKind),
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
@ -284,30 +284,34 @@ impl CharacterState {
|
||||
}
|
||||
|
||||
pub fn block_strength(&self) -> Option<f32> {
|
||||
let strength = match self {
|
||||
CharacterState::BasicBlock(c) => c.static_data.block_strength,
|
||||
_ => return None,
|
||||
};
|
||||
Some(strength)
|
||||
}
|
||||
|
||||
pub fn is_parry(&self) -> bool {
|
||||
let from_capability = if let Some(capabilities) = self
|
||||
.ability_info()
|
||||
.map(|a| a.ability_meta)
|
||||
.map(|m| m.capabilities)
|
||||
{
|
||||
capabilities.contains(Capability::BUILDUP_PARRIES)
|
||||
&& matches!(self.stage_section(), Some(StageSection::Buildup))
|
||||
(capabilities.contains(Capability::BUILDUP_BLOCKS)
|
||||
&& matches!(self.stage_section(), Some(StageSection::Buildup)))
|
||||
.then_some(0.5)
|
||||
} else {
|
||||
false
|
||||
None
|
||||
};
|
||||
let from_state = match self {
|
||||
CharacterState::BasicBlock(c) => Some(c.static_data.block_strength),
|
||||
_ => None,
|
||||
};
|
||||
match (from_capability, from_state) {
|
||||
(Some(a), Some(b)) => Some(a.max(b)),
|
||||
(Some(a), None) | (None, Some(a)) => Some(a),
|
||||
(None, None) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_parry(&self) -> bool {
|
||||
match self {
|
||||
CharacterState::BasicBlock(c) => c.is_parry(),
|
||||
CharacterState::RiposteMelee(c) => matches!(c.stage_section, StageSection::Buildup),
|
||||
_ => false,
|
||||
};
|
||||
from_capability || from_state
|
||||
}
|
||||
}
|
||||
|
||||
/// In radians
|
||||
|
@ -1156,6 +1156,17 @@ pub fn handle_buff(server: &mut Server, entity: EcsEntity, buff_change: buff::Bu
|
||||
buffs.remove(id);
|
||||
}
|
||||
},
|
||||
BuffChange::Refresh(kind) => {
|
||||
let (buff_comp_kinds, buff_comp_buffs) = buffs.parts();
|
||||
if let Some(buff_ids) = buff_comp_kinds.get(&kind) {
|
||||
for id in buff_ids {
|
||||
if let Some(buff) = buff_comp_buffs.get_mut(id) {
|
||||
// Resets buff timer to the original duration
|
||||
buff.time = buff.data.duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1259,25 +1270,7 @@ pub fn handle_parry_hook(server: &Server, defender: EcsEntity, attacker: Option<
|
||||
});
|
||||
true
|
||||
},
|
||||
char_state => {
|
||||
// If the character state is not one of the ones above, if it parried because it
|
||||
// had the capability to parry in its buildup, subtract 5 energy from the
|
||||
// defender
|
||||
if char_state
|
||||
.ability_info()
|
||||
.map(|info| info.ability_meta)
|
||||
.map_or(false, |meta| {
|
||||
meta.capabilities
|
||||
.contains(comp::ability::Capability::BUILDUP_PARRIES)
|
||||
})
|
||||
{
|
||||
server_eventbus.emit_now(ServerEvent::EnergyChange {
|
||||
entity: defender,
|
||||
change: -5.0,
|
||||
});
|
||||
}
|
||||
false
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
if return_to_wield {
|
||||
*char_state =
|
||||
|
@ -45,7 +45,14 @@ impl Animation for ComboAnimation {
|
||||
|
||||
for strike in 0..=current_strike {
|
||||
match ability_id {
|
||||
Some("common.abilities.sword.balanced_combo") => {
|
||||
Some(
|
||||
"common.abilities.sword.basic_double_slash"
|
||||
| "common.abilities.sword.heavy_double_slash"
|
||||
| "common.abilities.sword.agile_double_slash"
|
||||
| "common.abilities.sword.defensive_double_slash"
|
||||
| "common.abilities.sword.crippling_double_slash"
|
||||
| "common.abilities.sword.cleaving_double_slash",
|
||||
) => {
|
||||
let (move1, move2, move2alt) = if strike == current_strike {
|
||||
match stage_section {
|
||||
Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0),
|
||||
|
Loading…
Reference in New Issue
Block a user