mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Address UX issues of contextual abilities.
This commit is contained in:
parent
e1f76e0127
commit
1782408676
@ -75,4 +75,6 @@ common-abilities-sword-reaching_charge = Charge
|
||||
common-abilities-sword-reaching_flurry = Lunging Flurry
|
||||
.desc = Make multiple rapid thrusts at your foe.
|
||||
common-abilities-sword-reaching_skewer = Skewer
|
||||
.desc = Lunge forward with enough force to pierce multiple foes.
|
||||
.desc = Lunge forward with enough force to pierce multiple foes.
|
||||
veloren-core-pseudo_abilities-sword-stance_ability = Sword Stance Ability
|
||||
.desc = When in a sword stance, this ability will have different effects.
|
@ -5,7 +5,7 @@ use crate::{
|
||||
self, aura, beam, buff,
|
||||
inventory::{
|
||||
item::{
|
||||
tool::{AbilityContext, AbilityItem, Stats, ToolKind},
|
||||
tool::{AbilityContext, AbilityItem, AuxiliaryAbilityKind, Stats, ToolKind},
|
||||
ItemKind,
|
||||
},
|
||||
slot::EquipSlot,
|
||||
@ -198,22 +198,25 @@ impl ActiveAbilities {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter_unlocked_abilities<'a>(
|
||||
pub fn iter_available_abilities<'a>(
|
||||
inv: Option<&'a Inventory>,
|
||||
skill_set: Option<&'a SkillSet>,
|
||||
equip_slot: EquipSlot,
|
||||
context: Option<AbilityContext>,
|
||||
) -> impl Iterator<Item = usize> + 'a {
|
||||
inv.and_then(|inv| inv.equipped(equip_slot))
|
||||
.into_iter()
|
||||
.flat_map(|i| &i.item_config_expect().abilities.abilities)
|
||||
.enumerate()
|
||||
.filter_map(move |(i, a)| {
|
||||
a.ability(context).and_then(|(skill, _)| {
|
||||
skill
|
||||
.map_or(true, |s| skill_set.map_or(false, |ss| ss.has_skill(s)))
|
||||
.then_some(i)
|
||||
})
|
||||
.filter_map(move |(i, a)| match a {
|
||||
AuxiliaryAbilityKind::Simple(skill, _) => skill
|
||||
.map_or(true, |s| skill_set.map_or(false, |ss| ss.has_skill(s)))
|
||||
.then_some(i),
|
||||
AuxiliaryAbilityKind::Contextualized(abilities) => abilities
|
||||
.values()
|
||||
.any(|(skill, _)| {
|
||||
skill.map_or(true, |s| skill_set.map_or(false, |ss| ss.has_skill(s)))
|
||||
})
|
||||
.then_some(i),
|
||||
})
|
||||
}
|
||||
|
||||
@ -221,13 +224,12 @@ impl ActiveAbilities {
|
||||
inv: Option<&'a Inventory>,
|
||||
skill_set: Option<&'a SkillSet>,
|
||||
) -> [AuxiliaryAbility; MAX_ABILITIES] {
|
||||
let mut iter =
|
||||
Self::iter_unlocked_abilities(inv, skill_set, EquipSlot::ActiveMainhand, None)
|
||||
.map(AuxiliaryAbility::MainWeapon)
|
||||
.chain(
|
||||
Self::iter_unlocked_abilities(inv, skill_set, EquipSlot::ActiveOffhand, None)
|
||||
.map(AuxiliaryAbility::OffWeapon),
|
||||
);
|
||||
let mut iter = Self::iter_available_abilities(inv, skill_set, EquipSlot::ActiveMainhand)
|
||||
.map(AuxiliaryAbility::MainWeapon)
|
||||
.chain(
|
||||
Self::iter_available_abilities(inv, skill_set, EquipSlot::ActiveOffhand)
|
||||
.map(AuxiliaryAbility::OffWeapon),
|
||||
);
|
||||
|
||||
[(); MAX_ABILITIES].map(|()| iter.next().unwrap_or(AuxiliaryAbility::Empty))
|
||||
}
|
||||
@ -263,6 +265,28 @@ impl Ability {
|
||||
.map(|i| &i.item_config_expect().abilities)
|
||||
};
|
||||
|
||||
let contextual_id = |auxiliary_kind: Option<&AuxiliaryAbilityKind<_>>, equip_slot| {
|
||||
matches!(
|
||||
auxiliary_kind,
|
||||
Some(AuxiliaryAbilityKind::Contextualized(_))
|
||||
)
|
||||
.then_some(
|
||||
match inv.and_then(|inv| inv.equipped(equip_slot)).and_then(|i| {
|
||||
if let ItemKind::Tool(tool) = &*i.kind() {
|
||||
Some(tool.kind)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
Some(ToolKind::Sword) => {
|
||||
Some("veloren.core.pseudo_abilities.sword.stance_ability")
|
||||
},
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
.flatten()
|
||||
};
|
||||
|
||||
match self {
|
||||
Ability::ToolPrimary => ability_set(EquipSlot::ActiveMainhand)
|
||||
.map(|abilities| abilities.primary.id.as_str()),
|
||||
@ -278,6 +302,10 @@ impl Ability {
|
||||
abilities
|
||||
.auxiliary(index, context)
|
||||
.map(|(_, ability)| ability.id.as_str())
|
||||
.or_else(|| contextual_id(
|
||||
abilities.abilities.get(index),
|
||||
EquipSlot::ActiveMainhand,
|
||||
))
|
||||
})
|
||||
},
|
||||
Ability::OffWeaponAux(index) => {
|
||||
@ -285,6 +313,10 @@ impl Ability {
|
||||
abilities
|
||||
.auxiliary(index, context)
|
||||
.map(|(_, ability)| ability.id.as_str())
|
||||
.or_else(|| contextual_id(
|
||||
abilities.abilities.get(index),
|
||||
EquipSlot::ActiveOffhand,
|
||||
))
|
||||
})
|
||||
},
|
||||
Ability::Empty => None,
|
||||
|
@ -106,7 +106,7 @@ pub struct Data {
|
||||
}
|
||||
|
||||
pub const STANCE_ENTER_TIME: Duration = Duration::from_millis(250);
|
||||
pub const STANCE_LEAVE_TIME: Duration = Duration::from_secs(3);
|
||||
pub const STANCE_LEAVE_TIME: Duration = Duration::from_secs(20);
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
||||
@ -382,7 +382,7 @@ impl Data {
|
||||
}
|
||||
|
||||
fn next_strike(update: &mut StateUpdate) {
|
||||
if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
let revert_to_wield = if let CharacterState::ComboMelee2(c) = &mut update.character {
|
||||
if update
|
||||
.energy
|
||||
.try_change_by(-c.static_data.energy_cost_per_strike)
|
||||
@ -392,6 +392,14 @@ fn next_strike(update: &mut StateUpdate) {
|
||||
c.start_next_strike = false;
|
||||
c.timer = Duration::default();
|
||||
c.stage_section = Some(StageSection::Buildup);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if revert_to_wield {
|
||||
update.character = CharacterState::Wielding(wielding::Data { is_sneaking: false });
|
||||
}
|
||||
}
|
||||
|
@ -902,11 +902,10 @@ impl<'a> Widget for Diary<'a> {
|
||||
}
|
||||
});
|
||||
|
||||
let main_weap_abilities = ActiveAbilities::iter_unlocked_abilities(
|
||||
let main_weap_abilities = ActiveAbilities::iter_available_abilities(
|
||||
Some(self.inventory),
|
||||
Some(self.skill_set),
|
||||
EquipSlot::ActiveMainhand,
|
||||
self.context,
|
||||
)
|
||||
.map(AuxiliaryAbility::MainWeapon)
|
||||
.map(|a| {
|
||||
@ -915,11 +914,10 @@ impl<'a> Widget for Diary<'a> {
|
||||
a,
|
||||
)
|
||||
});
|
||||
let off_weap_abilities = ActiveAbilities::iter_unlocked_abilities(
|
||||
let off_weap_abilities = ActiveAbilities::iter_available_abilities(
|
||||
Some(self.inventory),
|
||||
Some(self.skill_set),
|
||||
EquipSlot::ActiveOffhand,
|
||||
self.context,
|
||||
)
|
||||
.map(AuxiliaryAbility::OffWeapon)
|
||||
.map(|a| {
|
||||
|
@ -368,6 +368,7 @@ pub fn ability_image(imgs: &img_ids::Imgs, ability_id: &str) -> image::Id {
|
||||
"common.abilities.sword.reaching_charge" => imgs.sword_reaching_charge,
|
||||
"common.abilities.sword.reaching_flurry" => imgs.sword_reaching_flurry,
|
||||
"common.abilities.sword.reaching_skewer" => imgs.sword_reaching_skewer,
|
||||
"veloren.core.pseudo_abilities.sword.stance_ability" => imgs.sword,
|
||||
// Axe
|
||||
"common.abilities.axe.doublestrike" => imgs.twohaxe_m1,
|
||||
"common.abilities.axe.spin" => imgs.axespin,
|
||||
|
Loading…
Reference in New Issue
Block a user