mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Maelstrom
This commit is contained in:
parent
0e771c9082
commit
ff15780c22
@ -147,24 +147,30 @@
|
||||
primary: Simple(None, "common.abilities.axe.triple_chop"),
|
||||
secondary: Simple(None, "common.abilities.axe.cleave"),
|
||||
abilities: [
|
||||
Simple(Some(Axe(BrutalSwing)), "common.abilities.axe.brutal_swing"),
|
||||
Simple(Some(Axe(Berserk)), "common.abilities.axe.berserk"),
|
||||
Simple(Some(Axe(RisingTide)), "common.abilities.axe.rising_tide"),
|
||||
Simple(Some(Axe(SavageSense)), "common.abilities.axe.savage_sense"),
|
||||
Simple(Some(Axe(AdrenalineRush)), "common.abilities.axe.adrenaline_rush"),
|
||||
Simple(Some(Axe(Execute)), "common.abilities.axe.execute"),
|
||||
Simple(Some(Axe(Rake)), "common.abilities.axe.rake"),
|
||||
Simple(Some(Axe(Bloodfeast)), "common.abilities.axe.bloodfeast"),
|
||||
Simple(Some(Axe(FierceRaze)), "common.abilities.axe.fierce_raze"),
|
||||
Simple(Some(Axe(Furor)), "common.abilities.axe.furor"),
|
||||
Simple(Some(Axe(Fracture)), "common.abilities.axe.fracture"),
|
||||
Simple(Some(Axe(Lacerate)), "common.abilities.axe.lacerate"),
|
||||
Simple(Some(Axe(SkullBash)), "common.abilities.axe.skull_bash"),
|
||||
Simple(Some(Axe(Sunder)), "common.abilities.axe.sunder"),
|
||||
Simple(Some(Axe(Plunder)), "common.abilities.axe.plunder"),
|
||||
Simple(Some(Axe(Defiance)), "common.abilities.axe.defiance"),
|
||||
Simple(Some(Axe(Keelhaul)), "common.abilities.axe.keelhaul"),
|
||||
Simple(Some(Axe(Bulkhead)), "common.abilities.axe.bulkhead"),
|
||||
Simple(Axe(BrutalSwing), "common.abilities.axe.brutal_swing"),
|
||||
Simple(Axe(Berserk), "common.abilities.axe.berserk"),
|
||||
Simple(Axe(RisingTide), "common.abilities.axe.rising_tide"),
|
||||
Simple(Axe(SavageSense), "common.abilities.axe.savage_sense"),
|
||||
Simple(Axe(AdrenalineRush), "common.abilities.axe.adrenaline_rush"),
|
||||
Contextualized(
|
||||
pseudo_id: "common.abilities.axe.execute",
|
||||
abilities: [
|
||||
([Combo(50)], (Axe(Maelstrom), "common.abilities.axe.maelstrom")),
|
||||
([], (Axe(Execute), "common.abilities.axe.execute")),
|
||||
],
|
||||
),
|
||||
Simple(Axe(Rake), "common.abilities.axe.rake"),
|
||||
Simple(Axe(Bloodfeast), "common.abilities.axe.bloodfeast"),
|
||||
Simple(Axe(FierceRaze), "common.abilities.axe.fierce_raze"),
|
||||
Simple(Axe(Furor), "common.abilities.axe.furor"),
|
||||
Simple(Axe(Fracture), "common.abilities.axe.fracture"),
|
||||
Simple(Axe(Lacerate), "common.abilities.axe.lacerate"),
|
||||
Simple(Axe(SkullBash), "common.abilities.axe.skull_bash"),
|
||||
Simple(Axe(Sunder), "common.abilities.axe.sunder"),
|
||||
Simple(Axe(Plunder), "common.abilities.axe.plunder"),
|
||||
Simple(Axe(Defiance), "common.abilities.axe.defiance"),
|
||||
Simple(Axe(Keelhaul), "common.abilities.axe.keelhaul"),
|
||||
Simple(Axe(Bulkhead), "common.abilities.axe.bulkhead"),
|
||||
],
|
||||
),
|
||||
Tool(Hammer): (
|
||||
|
@ -1,6 +1,6 @@
|
||||
FinisherMelee(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.6,
|
||||
buildup_duration: 0.5,
|
||||
swing_duration: 0.2,
|
||||
recover_duration: 0.4,
|
||||
melee_constructor: (
|
||||
|
@ -1,22 +1,18 @@
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 4,
|
||||
poise: 5,
|
||||
knockback: 0,
|
||||
energy_regen: 5,
|
||||
),
|
||||
range: 3.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
buildup_duration: 0.15,
|
||||
swing_duration: 0.05,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.1,
|
||||
ori_modifier: 0.6,
|
||||
FinisherMelee(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.5,
|
||||
swing_duration: 0.4,
|
||||
recover_duration: 0.2,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 75,
|
||||
poise: 100,
|
||||
knockback: 0,
|
||||
energy_regen: 0,
|
||||
),
|
||||
],
|
||||
energy_cost_per_strike: 0,
|
||||
range: 3.0,
|
||||
angle: 360.0,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
minimum_combo: 50,
|
||||
)
|
@ -11,7 +11,7 @@ use crate::{
|
||||
Inventory,
|
||||
},
|
||||
skills::Skill,
|
||||
CharacterAbility, SkillSet,
|
||||
CharacterAbility, Combo, SkillSet,
|
||||
},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
@ -361,7 +361,7 @@ impl<T> AbilityKind<T> {
|
||||
.find_map(|(req_contexts, a)| {
|
||||
req_contexts
|
||||
.iter()
|
||||
.all(|req| contexts.contains(req))
|
||||
.all(|req| req.fulfilled_by(contexts))
|
||||
.then_some(a)
|
||||
}),
|
||||
}
|
||||
@ -376,10 +376,15 @@ pub enum AbilityContext {
|
||||
/// files(s).
|
||||
Stance(Stance),
|
||||
DualWieldingSameKind,
|
||||
Combo(u32),
|
||||
}
|
||||
|
||||
impl AbilityContext {
|
||||
pub fn from(stance: Option<&Stance>, inv: Option<&Inventory>) -> Vec<Self> {
|
||||
pub fn from(
|
||||
stance: Option<&Stance>,
|
||||
inv: Option<&Inventory>,
|
||||
combo: Option<&Combo>,
|
||||
) -> Vec<Self> {
|
||||
let mut contexts = Vec::new();
|
||||
match stance {
|
||||
Some(Stance::None) => {},
|
||||
@ -400,8 +405,29 @@ impl AbilityContext {
|
||||
contexts.push(AbilityContext::DualWieldingSameKind)
|
||||
}
|
||||
}
|
||||
if let Some(combo) = combo {
|
||||
contexts.push(AbilityContext::Combo(combo.counter()));
|
||||
}
|
||||
contexts
|
||||
}
|
||||
|
||||
fn fulfilled_by(&self, contexts: &[AbilityContext]) -> bool {
|
||||
match self {
|
||||
basic_context @ Self::Stance(_) | basic_context @ Self::DualWieldingSameKind => {
|
||||
contexts.contains(basic_context)
|
||||
},
|
||||
Self::Combo(required) => contexts
|
||||
.iter()
|
||||
.filter_map(|context| {
|
||||
if let Self::Combo(combo) = context {
|
||||
Some(combo)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.any(|combo| combo >= required),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AbilitySet<AbilityItem> {
|
||||
|
@ -1204,7 +1204,7 @@ fn handle_ability(
|
||||
output_events: &mut OutputEvents,
|
||||
input: InputKind,
|
||||
) -> bool {
|
||||
let contexts = AbilityContext::from(data.stance, data.inventory);
|
||||
let contexts = AbilityContext::from(data.stance, data.inventory, data.combo);
|
||||
if let Some(ability_input) = input.into() {
|
||||
if let Some((ability, from_offhand)) = data
|
||||
.active_abilities
|
||||
|
@ -1359,7 +1359,7 @@ impl<'a> AgentData<'a> {
|
||||
enum ActionStateConditions {
|
||||
ConditionStaffCanShockwave = 0,
|
||||
}
|
||||
let contexts = AbilityContext::from(self.stance, Some(self.inventory));
|
||||
let contexts = AbilityContext::from(self.stance, Some(self.inventory), self.combo);
|
||||
let extract_ability = |input: AbilityInput| {
|
||||
self.active_abilities
|
||||
.activate_ability(
|
||||
|
@ -208,7 +208,7 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
|
||||
pub fn extract_ability(&self, input: AbilityInput) -> Option<AbilityData> {
|
||||
let context = AbilityContext::from(self.stance, Some(self.inventory));
|
||||
let context = AbilityContext::from(self.stance, Some(self.inventory), self.combo);
|
||||
AbilityData::from_ability(
|
||||
&self
|
||||
.active_abilities
|
||||
|
@ -37,10 +37,12 @@ impl Animation for ChargeswingAnimation {
|
||||
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.main.orientation = Quaternion::rotation_z(0.0);
|
||||
next.main_weapon_trail = true;
|
||||
next.second.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.second.orientation = Quaternion::rotation_z(0.0);
|
||||
next.off_weapon_trail = true;
|
||||
if matches!(stage_section, Some(StageSection::Action)) {
|
||||
next.main_weapon_trail = true;
|
||||
next.off_weapon_trail = true;
|
||||
}
|
||||
|
||||
match ability_id {
|
||||
Some(
|
||||
@ -237,16 +239,10 @@ impl Animation for ChargeswingAnimation {
|
||||
Some("common.abilities.axe.cleave") => {
|
||||
let (move1, move2, move3, tension) = match stage_section {
|
||||
Some(StageSection::Charge) => {
|
||||
next.main_weapon_trail = false;
|
||||
next.off_weapon_trail = false;
|
||||
(anim_time.min(1.0), 0.0, 0.0, (anim_time * 20.0).sin())
|
||||
},
|
||||
Some(StageSection::Action) => (1.0, anim_time.powi(2), 0.0, 0.0),
|
||||
Some(StageSection::Recover) => {
|
||||
next.main_weapon_trail = false;
|
||||
next.off_weapon_trail = false;
|
||||
(1.0, 1.0, anim_time, 0.0)
|
||||
},
|
||||
Some(StageSection::Recover) => (1.0, 1.0, anim_time, 0.0),
|
||||
_ => (0.0, 0.0, 0.0, 0.0),
|
||||
};
|
||||
let pullback = 1.0 - move3;
|
||||
|
@ -32,10 +32,12 @@ impl Animation for ComboAnimation {
|
||||
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.main.orientation = Quaternion::rotation_z(0.0);
|
||||
next.main_weapon_trail = true;
|
||||
next.second.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.second.orientation = Quaternion::rotation_z(0.0);
|
||||
next.off_weapon_trail = true;
|
||||
if matches!(stage_section, Some(StageSection::Action)) {
|
||||
next.main_weapon_trail = true;
|
||||
next.off_weapon_trail = true;
|
||||
}
|
||||
let multi_strike_pullback = 1.0
|
||||
- if matches!(stage_section, Some(StageSection::Recover)) {
|
||||
anim_time.powi(4)
|
||||
@ -882,17 +884,9 @@ impl Animation for ComboAnimation {
|
||||
Some("common.abilities.axe.triple_chop") => {
|
||||
let (move1, move2) = if strike == current_strike {
|
||||
match stage_section {
|
||||
Some(StageSection::Buildup) => {
|
||||
next.main_weapon_trail = false;
|
||||
next.off_weapon_trail = false;
|
||||
(anim_time, 0.0)
|
||||
},
|
||||
Some(StageSection::Buildup) => (anim_time, 0.0),
|
||||
Some(StageSection::Action) => (1.0, anim_time),
|
||||
Some(StageSection::Recover) => {
|
||||
next.main_weapon_trail = false;
|
||||
next.off_weapon_trail = false;
|
||||
(1.0, 1.0)
|
||||
},
|
||||
Some(StageSection::Recover) => (1.0, 1.0),
|
||||
_ => (0.0, 0.0),
|
||||
}
|
||||
} else {
|
||||
@ -972,17 +966,9 @@ impl Animation for ComboAnimation {
|
||||
},
|
||||
Some("common.abilities.axe.brutal_swing") => {
|
||||
let (move1, move2_raw) = match stage_section {
|
||||
Some(StageSection::Buildup) => {
|
||||
next.main_weapon_trail = false;
|
||||
next.off_weapon_trail = false;
|
||||
(anim_time, 0.0)
|
||||
},
|
||||
Some(StageSection::Buildup) => (anim_time, 0.0),
|
||||
Some(StageSection::Action) => (1.0, anim_time),
|
||||
Some(StageSection::Recover) => {
|
||||
next.main_weapon_trail = false;
|
||||
next.off_weapon_trail = false;
|
||||
(1.0, 1.0)
|
||||
},
|
||||
Some(StageSection::Recover) => (1.0, 1.0),
|
||||
_ => (0.0, 0.0),
|
||||
};
|
||||
let move1 = move1 * multi_strike_pullback;
|
||||
@ -1007,17 +993,9 @@ impl Animation for ComboAnimation {
|
||||
},
|
||||
Some("common.abilities.axe.rising_tide") => {
|
||||
let (move1, move2_raw) = match stage_section {
|
||||
Some(StageSection::Buildup) => {
|
||||
next.main_weapon_trail = false;
|
||||
next.off_weapon_trail = false;
|
||||
(anim_time, 0.0)
|
||||
},
|
||||
Some(StageSection::Buildup) => (anim_time, 0.0),
|
||||
Some(StageSection::Action) => (1.0, anim_time),
|
||||
Some(StageSection::Recover) => {
|
||||
next.main_weapon_trail = false;
|
||||
next.off_weapon_trail = false;
|
||||
(1.0, 1.0)
|
||||
},
|
||||
Some(StageSection::Recover) => (1.0, 1.0),
|
||||
_ => (0.0, 0.0),
|
||||
};
|
||||
let move1 = move1 * multi_strike_pullback;
|
||||
|
@ -26,10 +26,12 @@ impl Animation for FinisherMeleeAnimation {
|
||||
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.main.orientation = Quaternion::rotation_z(0.0);
|
||||
next.main_weapon_trail = true;
|
||||
next.second.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.second.orientation = Quaternion::rotation_z(0.0);
|
||||
next.off_weapon_trail = true;
|
||||
if matches!(stage_section, Some(StageSection::Action)) {
|
||||
next.main_weapon_trail = true;
|
||||
next.off_weapon_trail = true;
|
||||
}
|
||||
|
||||
match ability_id {
|
||||
Some("common.abilities.sword.basic_mighty_strike") => {
|
||||
@ -176,6 +178,46 @@ impl Animation for FinisherMeleeAnimation {
|
||||
next.control.position += Vec3::new(move2 * -3.0, move2 * 12.0, move2 * -17.0);
|
||||
next.control.orientation.rotate_z(move2 * 0.7);
|
||||
},
|
||||
Some("common.abilities.axe.maelstrom") => {
|
||||
let (move1, move2_raw, move3) = match stage_section {
|
||||
Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
|
||||
Some(StageSection::Action) => (1.0, anim_time, 0.0),
|
||||
Some(StageSection::Recover) => (1.0, 1.0, anim_time),
|
||||
_ => (0.0, 0.0, 0.0),
|
||||
};
|
||||
let pullback = 1.0 - move3;
|
||||
let move1 = move1 * pullback;
|
||||
let move2 = move2_raw * pullback;
|
||||
|
||||
next.hand_l.position = Vec3::new(s_a.ahl.0, s_a.ahl.1, s_a.ahl.2);
|
||||
next.hand_l.orientation =
|
||||
Quaternion::rotation_x(s_a.ahl.3) * Quaternion::rotation_y(s_a.ahl.4);
|
||||
next.hand_r.position = Vec3::new(s_a.ahr.0, s_a.ahr.1, s_a.ahr.2);
|
||||
next.hand_r.orientation =
|
||||
Quaternion::rotation_x(s_a.ahr.3) * Quaternion::rotation_z(s_a.ahr.5);
|
||||
|
||||
next.control.position = Vec3::new(s_a.ac.0, s_a.ac.1, s_a.ac.2);
|
||||
next.control.orientation = Quaternion::rotation_x(s_a.ac.3)
|
||||
* Quaternion::rotation_y(s_a.ac.4)
|
||||
* Quaternion::rotation_z(s_a.ac.5);
|
||||
|
||||
next.control.orientation.rotate_x(move1 * 0.9);
|
||||
next.chest.orientation.rotate_z(move1 * 1.2);
|
||||
next.head.orientation.rotate_z(move1 * -0.5);
|
||||
next.belt.orientation.rotate_z(move1 * -0.3);
|
||||
next.shorts.orientation.rotate_z(move1 * -0.7);
|
||||
next.control.position += Vec3::new(move1 * 4.0, move1 * -12.0, move1 * 11.0);
|
||||
|
||||
next.chest.orientation.rotate_z(move2 * -2.0);
|
||||
next.head.orientation.rotate_z(move2 * 0.9);
|
||||
next.belt.orientation.rotate_z(move2 * 0.4);
|
||||
next.shorts.orientation.rotate_z(move2 * 1.1);
|
||||
next.control.orientation.rotate_x(move2 * -5.0);
|
||||
next.control.position += Vec3::new(move2 * 5.0, move2 * 12.0, move2 * -17.0);
|
||||
next.control.orientation.rotate_y(move2 * -2.0);
|
||||
next.control.orientation.rotate_z(move2 * -1.0);
|
||||
next.torso.orientation.rotate_z(move2_raw * -4.0 * PI);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,12 @@ impl Animation for RapidMeleeAnimation {
|
||||
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.main.orientation = Quaternion::rotation_z(0.0);
|
||||
next.main_weapon_trail = true;
|
||||
next.second.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.second.orientation = Quaternion::rotation_z(0.0);
|
||||
next.off_weapon_trail = true;
|
||||
if matches!(stage_section, Some(StageSection::Action)) {
|
||||
next.main_weapon_trail = true;
|
||||
next.off_weapon_trail = true;
|
||||
}
|
||||
|
||||
match ability_id {
|
||||
Some(
|
||||
|
@ -25,10 +25,12 @@ impl Animation for RiposteMeleeAnimation {
|
||||
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.main.orientation = Quaternion::rotation_z(0.0);
|
||||
next.main_weapon_trail = true;
|
||||
next.second.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
next.second.orientation = Quaternion::rotation_z(0.0);
|
||||
next.off_weapon_trail = true;
|
||||
if matches!(stage_section, Some(StageSection::Action)) {
|
||||
next.main_weapon_trail = true;
|
||||
next.off_weapon_trail = true;
|
||||
}
|
||||
|
||||
match ability_id {
|
||||
Some("common.abilities.sword.defensive_riposte") => {
|
||||
|
@ -3047,6 +3047,7 @@ impl Hud {
|
||||
let bodies = ecs.read_storage::<comp::Body>();
|
||||
let poises = ecs.read_storage::<comp::Poise>();
|
||||
let combos = ecs.read_storage::<comp::Combo>();
|
||||
let combo = combos.get(entity);
|
||||
let time = ecs.read_resource::<Time>();
|
||||
let stances = ecs.read_storage::<comp::Stance>();
|
||||
let char_states = ecs.read_storage::<comp::CharacterState>();
|
||||
@ -3073,7 +3074,7 @@ impl Hud {
|
||||
bodies.get(entity),
|
||||
) {
|
||||
let stance = stances.get(entity);
|
||||
let contexts = AbilityContext::from(stance, Some(inventory));
|
||||
let contexts = AbilityContext::from(stance, Some(inventory), combo);
|
||||
match Skillbar::new(
|
||||
client,
|
||||
&info,
|
||||
@ -3100,7 +3101,7 @@ impl Hud {
|
||||
&msm,
|
||||
self.floaters.combo_floater,
|
||||
&contexts,
|
||||
combos.get(entity),
|
||||
combo,
|
||||
char_states.get(entity),
|
||||
stance,
|
||||
)
|
||||
@ -3581,7 +3582,7 @@ impl Hud {
|
||||
bodies.get(entity),
|
||||
poises.get(entity),
|
||||
) {
|
||||
let contexts = AbilityContext::from(stances.get(entity), Some(inventory));
|
||||
let contexts = AbilityContext::from(stances.get(entity), Some(inventory), combo);
|
||||
for event in Diary::new(
|
||||
&self.show,
|
||||
client,
|
||||
|
@ -39,9 +39,9 @@ use common::{
|
||||
inventory::slot::EquipSlot,
|
||||
item::{tool::AbilityContext, Hands, ItemKind, ToolKind},
|
||||
ship::{self, figuredata::VOXEL_COLLIDER_MANIFEST},
|
||||
Body, CharacterActivity, CharacterState, Collider, Controller, Health, Inventory, Item,
|
||||
ItemKey, Last, LightAnimation, LightEmitter, Object, Ori, PhysicsState, PoiseState, Pos,
|
||||
Scale, SkillSet, Stance, Vel,
|
||||
Body, CharacterActivity, CharacterState, Collider, Combo, Controller, Health, Inventory,
|
||||
Item, ItemKey, Last, LightAnimation, LightEmitter, Object, Ori, PhysicsState, PoiseState,
|
||||
Pos, Scale, SkillSet, Stance, Vel,
|
||||
},
|
||||
link::Is,
|
||||
mounting::{Rider, VolumeRider},
|
||||
@ -853,7 +853,7 @@ impl FigureMgr {
|
||||
inventory,
|
||||
item,
|
||||
light_emitter,
|
||||
(is_rider, is_volume_rider, collider, stance, skillset),
|
||||
(is_rider, is_volume_rider, collider, stance, skillset, combo),
|
||||
),
|
||||
) in (
|
||||
&ecs.entities(),
|
||||
@ -877,6 +877,7 @@ impl FigureMgr {
|
||||
ecs.read_storage::<Collider>().maybe(),
|
||||
ecs.read_storage::<Stance>().maybe(),
|
||||
ecs.read_storage::<SkillSet>().maybe(),
|
||||
ecs.read_storage::<Combo>().maybe(),
|
||||
),
|
||||
)
|
||||
.join()
|
||||
@ -1037,7 +1038,7 @@ impl FigureMgr {
|
||||
let second_tool_spec = second_tool_spec.as_deref();
|
||||
let hands = (active_tool_hand, second_tool_hand);
|
||||
|
||||
let contexts = AbilityContext::from(stance, inventory);
|
||||
let contexts = AbilityContext::from(stance, inventory, combo);
|
||||
|
||||
let ability_id = character.and_then(|c| {
|
||||
c.ability_info()
|
||||
|
Loading…
Reference in New Issue
Block a user