Dual wielding weapons of the same kind added as a context

This commit is contained in:
Sam 2023-04-23 01:47:31 -04:00
parent 9cedf854de
commit 0ecf4fbe87
6 changed files with 103 additions and 86 deletions

View File

@ -5,92 +5,92 @@
Tool(Sword): ( Tool(Sword): (
primary: Contextualized( primary: Contextualized(
pseudo_id: "veloren.core.pseudo_abilities.sword.double_slash", pseudo_id: "veloren.core.pseudo_abilities.sword.double_slash",
abilities: { abilities: [
None: (None, "common.abilities.sword.basic_double_slash"), ([Stance(Sword(Heavy))], (None, "common.abilities.sword.heavy_double_slash")),
Stance(Sword(Heavy)): (None, "common.abilities.sword.heavy_double_slash"), ([Stance(Sword(Agile))], (None, "common.abilities.sword.agile_double_slash")),
Stance(Sword(Agile)): (None, "common.abilities.sword.agile_double_slash"), ([Stance(Sword(Defensive))], (None, "common.abilities.sword.defensive_double_slash")),
Stance(Sword(Defensive)): (None, "common.abilities.sword.defensive_double_slash"), ([Stance(Sword(Crippling))], (None, "common.abilities.sword.crippling_double_slash")),
Stance(Sword(Crippling)): (None, "common.abilities.sword.crippling_double_slash"), ([Stance(Sword(Cleaving))], (None, "common.abilities.sword.cleaving_double_slash")),
Stance(Sword(Cleaving)): (None, "common.abilities.sword.cleaving_double_slash"), ([], (None, "common.abilities.sword.basic_double_slash")),
}, ],
), ),
secondary: Contextualized( secondary: Contextualized(
pseudo_id: "veloren.core.pseudo_abilities.sword.secondary_ability", pseudo_id: "veloren.core.pseudo_abilities.sword.secondary_ability",
abilities: { abilities: [
None: (None, "common.abilities.sword.basic_thrust"), ([Stance(Sword(Heavy))], (None, "common.abilities.sword.heavy_slam")),
Stance(Sword(Heavy)): (None, "common.abilities.sword.heavy_slam"), ([Stance(Sword(Agile))], (None, "common.abilities.sword.agile_perforate")),
Stance(Sword(Agile)): (None, "common.abilities.sword.agile_perforate"), ([Stance(Sword(Defensive))], (None, "common.abilities.sword.defensive_vital_jab")),
Stance(Sword(Defensive)): (None, "common.abilities.sword.defensive_vital_jab"), ([Stance(Sword(Crippling))], (None, "common.abilities.sword.crippling_deep_rend")),
Stance(Sword(Crippling)): (None, "common.abilities.sword.crippling_deep_rend"), ([Stance(Sword(Cleaving))], (None, "common.abilities.sword.cleaving_spiral_slash")),
Stance(Sword(Cleaving)): (None, "common.abilities.sword.cleaving_spiral_slash"), ([], (None, "common.abilities.sword.basic_thrust")),
}, ],
), ),
abilities: [ abilities: [
Contextualized( Contextualized(
pseudo_id: "veloren.core.pseudo_abilities.sword.crescent_slash", pseudo_id: "veloren.core.pseudo_abilities.sword.crescent_slash",
abilities: { abilities: [
None: (Sword(CrescentSlash), "common.abilities.sword.basic_crescent_slash"), ([Stance(Sword(Heavy))], (Sword(CrescentSlash), "common.abilities.sword.heavy_crescent_slash")),
Stance(Sword(Heavy)): (Sword(CrescentSlash), "common.abilities.sword.heavy_crescent_slash"), ([Stance(Sword(Agile))], (Sword(CrescentSlash), "common.abilities.sword.agile_crescent_slash")),
Stance(Sword(Agile)): (Sword(CrescentSlash), "common.abilities.sword.agile_crescent_slash"), ([Stance(Sword(Defensive))], (Sword(CrescentSlash), "common.abilities.sword.defensive_crescent_slash")),
Stance(Sword(Defensive)): (Sword(CrescentSlash), "common.abilities.sword.defensive_crescent_slash"), ([Stance(Sword(Crippling))], (Sword(CrescentSlash), "common.abilities.sword.crippling_crescent_slash")),
Stance(Sword(Crippling)): (Sword(CrescentSlash), "common.abilities.sword.crippling_crescent_slash"), ([Stance(Sword(Cleaving))], (Sword(CrescentSlash), "common.abilities.sword.cleaving_crescent_slash")),
Stance(Sword(Cleaving)): (Sword(CrescentSlash), "common.abilities.sword.cleaving_crescent_slash"), ([], (Sword(CrescentSlash), "common.abilities.sword.basic_crescent_slash")),
}, ],
), ),
Contextualized( Contextualized(
pseudo_id: "veloren.core.pseudo_abilities.sword.fell_strike", pseudo_id: "veloren.core.pseudo_abilities.sword.fell_strike",
abilities: { abilities: [
None: (Sword(FellStrike), "common.abilities.sword.basic_fell_strike"), ([Stance(Sword(Heavy))], (Sword(FellStrike), "common.abilities.sword.heavy_fell_strike")),
Stance(Sword(Heavy)): (Sword(FellStrike), "common.abilities.sword.heavy_fell_strike"), ([Stance(Sword(Agile))], (Sword(FellStrike), "common.abilities.sword.agile_fell_strike")),
Stance(Sword(Agile)): (Sword(FellStrike), "common.abilities.sword.agile_fell_strike"), ([Stance(Sword(Defensive))], (Sword(FellStrike), "common.abilities.sword.defensive_fell_strike")),
Stance(Sword(Defensive)): (Sword(FellStrike), "common.abilities.sword.defensive_fell_strike"), ([Stance(Sword(Crippling))], (Sword(FellStrike), "common.abilities.sword.crippling_fell_strike")),
Stance(Sword(Crippling)): (Sword(FellStrike), "common.abilities.sword.crippling_fell_strike"), ([Stance(Sword(Cleaving))], (Sword(FellStrike), "common.abilities.sword.cleaving_fell_strike")),
Stance(Sword(Cleaving)): (Sword(FellStrike), "common.abilities.sword.cleaving_fell_strike"), ([], (Sword(FellStrike), "common.abilities.sword.basic_fell_strike")),
}, ],
), ),
Contextualized( Contextualized(
pseudo_id: "veloren.core.pseudo_abilities.sword.skewer", pseudo_id: "veloren.core.pseudo_abilities.sword.skewer",
abilities: { abilities: [
None: (Sword(Skewer), "common.abilities.sword.basic_skewer"), ([Stance(Sword(Heavy))], (Sword(Skewer), "common.abilities.sword.heavy_skewer")),
Stance(Sword(Heavy)): (Sword(Skewer), "common.abilities.sword.heavy_skewer"), ([Stance(Sword(Agile))], (Sword(Skewer), "common.abilities.sword.agile_skewer")),
Stance(Sword(Agile)): (Sword(Skewer), "common.abilities.sword.agile_skewer"), ([Stance(Sword(Defensive))], (Sword(Skewer), "common.abilities.sword.defensive_skewer")),
Stance(Sword(Defensive)): (Sword(Skewer), "common.abilities.sword.defensive_skewer"), ([Stance(Sword(Crippling))], (Sword(Skewer), "common.abilities.sword.crippling_skewer")),
Stance(Sword(Crippling)): (Sword(Skewer), "common.abilities.sword.crippling_skewer"), ([Stance(Sword(Cleaving))], (Sword(Skewer), "common.abilities.sword.cleaving_skewer")),
Stance(Sword(Cleaving)): (Sword(Skewer), "common.abilities.sword.cleaving_skewer"), ([], (Sword(Skewer), "common.abilities.sword.basic_skewer")),
}, ],
), ),
Contextualized( Contextualized(
pseudo_id: "veloren.core.pseudo_abilities.sword.cascade", pseudo_id: "veloren.core.pseudo_abilities.sword.cascade",
abilities: { abilities: [
None: (Sword(Cascade), "common.abilities.sword.basic_cascade"), ([Stance(Sword(Heavy))], (Sword(Cascade), "common.abilities.sword.heavy_cascade")),
Stance(Sword(Heavy)): (Sword(Cascade), "common.abilities.sword.heavy_cascade"), ([Stance(Sword(Agile))], (Sword(Cascade), "common.abilities.sword.agile_cascade")),
Stance(Sword(Agile)): (Sword(Cascade), "common.abilities.sword.agile_cascade"), ([Stance(Sword(Defensive))], (Sword(Cascade), "common.abilities.sword.defensive_cascade")),
Stance(Sword(Defensive)): (Sword(Cascade), "common.abilities.sword.defensive_cascade"), ([Stance(Sword(Crippling))], (Sword(Cascade), "common.abilities.sword.crippling_cascade")),
Stance(Sword(Crippling)): (Sword(Cascade), "common.abilities.sword.crippling_cascade"), ([Stance(Sword(Cleaving))], (Sword(Cascade), "common.abilities.sword.cleaving_cascade")),
Stance(Sword(Cleaving)): (Sword(Cascade), "common.abilities.sword.cleaving_cascade"), ([], (Sword(Cascade), "common.abilities.sword.basic_cascade")),
}, ],
), ),
Contextualized( Contextualized(
pseudo_id: "veloren.core.pseudo_abilities.sword.cross_cut", pseudo_id: "veloren.core.pseudo_abilities.sword.cross_cut",
abilities: { abilities: [
None: (Sword(CrossCut), "common.abilities.sword.basic_cross_cut"), ([Stance(Sword(Heavy))], (Sword(CrossCut), "common.abilities.sword.heavy_cross_cut")),
Stance(Sword(Heavy)): (Sword(CrossCut), "common.abilities.sword.heavy_cross_cut"), ([Stance(Sword(Agile))], (Sword(CrossCut), "common.abilities.sword.agile_cross_cut")),
Stance(Sword(Agile)): (Sword(CrossCut), "common.abilities.sword.agile_cross_cut"), ([Stance(Sword(Defensive))], (Sword(CrossCut), "common.abilities.sword.defensive_cross_cut")),
Stance(Sword(Defensive)): (Sword(CrossCut), "common.abilities.sword.defensive_cross_cut"), ([Stance(Sword(Crippling))], (Sword(CrossCut), "common.abilities.sword.crippling_cross_cut")),
Stance(Sword(Crippling)): (Sword(CrossCut), "common.abilities.sword.crippling_cross_cut"), ([Stance(Sword(Cleaving))], (Sword(CrossCut), "common.abilities.sword.cleaving_cross_cut")),
Stance(Sword(Cleaving)): (Sword(CrossCut), "common.abilities.sword.cleaving_cross_cut"), ([], (Sword(CrossCut), "common.abilities.sword.basic_cross_cut")),
}, ],
), ),
Contextualized( Contextualized(
pseudo_id: "veloren.core.pseudo_abilities.sword.finisher", pseudo_id: "veloren.core.pseudo_abilities.sword.finisher",
abilities: { abilities: [
None: (Sword(Finisher), "common.abilities.sword.basic_mighty_strike"), ([Stance(Sword(Heavy))], (Sword(Finisher), "common.abilities.sword.heavy_guillotine")),
Stance(Sword(Heavy)): (Sword(Finisher), "common.abilities.sword.heavy_guillotine"), ([Stance(Sword(Agile))], (Sword(Finisher), "common.abilities.sword.agile_hundred_cuts")),
Stance(Sword(Agile)): (Sword(Finisher), "common.abilities.sword.agile_hundred_cuts"), ([Stance(Sword(Defensive))], (Sword(Finisher), "common.abilities.sword.defensive_counter")),
Stance(Sword(Defensive)): (Sword(Finisher), "common.abilities.sword.defensive_counter"), ([Stance(Sword(Crippling))], (Sword(Finisher), "common.abilities.sword.crippling_mutilate")),
Stance(Sword(Crippling)): (Sword(Finisher), "common.abilities.sword.crippling_mutilate"), ([Stance(Sword(Cleaving))], (Sword(Finisher), "common.abilities.sword.cleaving_bladestorm")),
Stance(Sword(Cleaving)): (Sword(Finisher), "common.abilities.sword.cleaving_bladestorm"), ([], (Sword(Finisher), "common.abilities.sword.basic_mighty_strike")),
}, ],
), ),
Simple(Sword(HeavySweep), "common.abilities.sword.heavy_sweep"), Simple(Sword(HeavySweep), "common.abilities.sword.heavy_sweep"),
Simple(Sword(HeavyPommelStrike), "common.abilities.sword.heavy_pommel_strike"), Simple(Sword(HeavyPommelStrike), "common.abilities.sword.heavy_pommel_strike"),

View File

@ -4,7 +4,14 @@
use crate::{ use crate::{
assets::{self, Asset, AssetExt, AssetHandle}, assets::{self, Asset, AssetExt, AssetHandle},
comp::{ comp::{
ability::Stance, item::DurabilityMultiplier, skills::Skill, CharacterAbility, SkillSet, ability::Stance,
inventory::{
item::{DurabilityMultiplier, ItemKind},
slot::EquipSlot,
Inventory,
},
skills::Skill,
CharacterAbility, SkillSet,
}, },
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
@ -347,20 +354,15 @@ impl<T> AbilityKind<T> {
AbilityKind::Contextualized { AbilityKind::Contextualized {
pseudo_id: _, pseudo_id: _,
abilities, abilities,
} => { } => abilities
// In the event that the ability from the current context is not unlocked with
// the required skill, try falling back to the ability from this input that does
// not require a context
abilities
.iter() .iter()
.find_map(|(req_contexts, (s, a))| { .filter_map(|(req_contexts, (s, a))| unlocked(*s, a).map(|a| (req_contexts, a)))
.find_map(|(req_contexts, a)| {
req_contexts req_contexts
.iter() .iter()
.all(|req| contexts.contains(req)) .all(|req| contexts.contains(req))
.then_some((s, a)) .then_some(a)
}) }),
.and_then(|(s, a)| unlocked(*s, a))
},
} }
} }
} }
@ -372,16 +374,31 @@ pub enum AbilityContext {
/// `AbilityContext::Stance(Stance::None)` in the ability map config /// `AbilityContext::Stance(Stance::None)` in the ability map config
/// files(s). /// files(s).
Stance(Stance), Stance(Stance),
DualWieldingSameKind,
} }
impl AbilityContext { impl AbilityContext {
pub fn from(stance: Option<&Stance>) -> Vec<Self> { pub fn from(stance: Option<&Stance>, inv: Option<&Inventory>) -> Vec<Self> {
let mut contexts = Vec::new(); let mut contexts = Vec::new();
match stance { match stance {
Some(Stance::None) => {}, Some(Stance::None) => {},
Some(stance) => contexts.push(AbilityContext::Stance(*stance)), Some(stance) => contexts.push(AbilityContext::Stance(*stance)),
None => {}, None => {},
} }
if let Some(inv) = inv {
let tool_kind = |slot| {
inv.equipped(slot).and_then(|i| {
if let ItemKind::Tool(tool) = &*i.kind() {
Some(tool.kind)
} else {
None
}
})
};
if tool_kind(EquipSlot::ActiveMainhand) == tool_kind(EquipSlot::ActiveOffhand) {
contexts.push(AbilityContext::DualWieldingSameKind)
}
}
contexts contexts
} }
} }

View File

@ -1107,7 +1107,7 @@ fn handle_ability(
output_events: &mut OutputEvents, output_events: &mut OutputEvents,
input: InputKind, input: InputKind,
) -> bool { ) -> bool {
let contexts = AbilityContext::from(data.stance); let contexts = AbilityContext::from(data.stance, data.inventory);
if let Some(ability_input) = input.into() { if let Some(ability_input) = input.into() {
if let Some((ability, from_offhand)) = data if let Some((ability, from_offhand)) = data
.active_abilities .active_abilities

View File

@ -757,7 +757,7 @@ impl<'a> AgentData<'a> {
); );
let attack_failed = if attempt_attack { let attack_failed = if attempt_attack {
let contexts = AbilityContext::from(self.stance); let contexts = AbilityContext::from(self.stance, Some(self.inventory));
let extract_ability = |input: AbilityInput| { let extract_ability = |input: AbilityInput| {
AbilityData::from_ability( AbilityData::from_ability(
&self &self
@ -1437,7 +1437,7 @@ impl<'a> AgentData<'a> {
enum ActionStateConditions { enum ActionStateConditions {
ConditionStaffCanShockwave = 0, ConditionStaffCanShockwave = 0,
} }
let contexts = AbilityContext::from(self.stance); let contexts = AbilityContext::from(self.stance, Some(self.inventory));
let extract_ability = |input: AbilityInput| { let extract_ability = |input: AbilityInput| {
self.active_abilities self.active_abilities
.activate_ability( .activate_ability(

View File

@ -3018,7 +3018,7 @@ impl Hud {
bodies.get(entity), bodies.get(entity),
) { ) {
let stance = stances.get(entity); let stance = stances.get(entity);
let contexts = AbilityContext::from(stance); let contexts = AbilityContext::from(stance, Some(inventory));
match Skillbar::new( match Skillbar::new(
client, client,
&info, &info,
@ -3522,7 +3522,7 @@ impl Hud {
bodies.get(entity), bodies.get(entity),
poises.get(entity), poises.get(entity),
) { ) {
let contexts = AbilityContext::from(stances.get(entity)); let contexts = AbilityContext::from(stances.get(entity), Some(inventory));
for event in Diary::new( for event in Diary::new(
&self.show, &self.show,
client, client,

View File

@ -931,7 +931,7 @@ impl FigureMgr {
let second_tool_spec = second_tool_spec.as_deref(); let second_tool_spec = second_tool_spec.as_deref();
let hands = (active_tool_hand, second_tool_hand); let hands = (active_tool_hand, second_tool_hand);
let contexts = AbilityContext::from(stance); let contexts = AbilityContext::from(stance, inventory);
let ability_id = character.and_then(|c| { let ability_id = character.and_then(|c| {
c.ability_info() c.ability_info()