Route character state to Diary UI

This commit is contained in:
juliancoffee 2024-02-27 23:15:30 +02:00
parent 3283eb6916
commit 4dcf6215d2
7 changed files with 198 additions and 109 deletions

View File

@ -39,6 +39,11 @@ use std::{borrow::Cow, convert::TryFrom, time::Duration};
use super::shockwave::ShockwaveDodgeable; use super::shockwave::ShockwaveDodgeable;
pub const BASE_ABILITY_LIMIT: usize = 5; pub const BASE_ABILITY_LIMIT: usize = 5;
// FIXME: different AbilitySpec on same ToolKind share the same key
// FIXME: only really works with weapons, glider just fallback to (None, None),
// but maybe that's ok?
/// Descriptor to pick the right (auxiliary) ability set
pub type AuxiliaryKey = (Option<ToolKind>, Option<ToolKind>); pub type AuxiliaryKey = (Option<ToolKind>, Option<ToolKind>);
// TODO: Potentially look into storing previous ability sets for weapon // TODO: Potentially look into storing previous ability sets for weapon
@ -131,27 +136,38 @@ impl ActiveAbilities {
} }
} }
pub fn active_auxiliary_key(inv: Option<&Inventory>) -> AuxiliaryKey { pub fn active_auxiliary_key(
let tool_kind = |slot| { inv: Option<&Inventory>,
inv.and_then(|inv| inv.equipped(slot)) char_state: Option<&CharacterState>,
.and_then(|item| match &*item.kind() { ) -> AuxiliaryKey {
ItemKind::Tool(tool) => Some(tool.kind), let source = AbilitySource::determine(char_state);
_ => None,
})
};
( match source {
tool_kind(EquipSlot::ActiveMainhand), AbilitySource::Weapons => {
tool_kind(EquipSlot::ActiveOffhand), let tool_kind = |slot| {
) inv.and_then(|inv| inv.equipped(slot))
.and_then(|item| match &*item.kind() {
ItemKind::Tool(tool) => Some(tool.kind),
_ => None,
})
};
(
tool_kind(EquipSlot::ActiveMainhand),
tool_kind(EquipSlot::ActiveOffhand),
)
},
AbilitySource::Glider => (None, None),
}
} }
pub fn auxiliary_set( pub fn auxiliary_set(
&self, &self,
inv: Option<&Inventory>, inv: Option<&Inventory>,
skill_set: Option<&SkillSet>, skill_set: Option<&SkillSet>,
char_state: Option<&CharacterState>,
) -> Cow<Vec<AuxiliaryAbility>> { ) -> Cow<Vec<AuxiliaryAbility>> {
let aux_key = Self::active_auxiliary_key(inv); let aux_key = Self::active_auxiliary_key(inv, char_state);
self.auxiliary_sets self.auxiliary_sets
.get(&aux_key) .get(&aux_key)
@ -164,6 +180,7 @@ impl ActiveAbilities {
input: AbilityInput, input: AbilityInput,
inventory: Option<&Inventory>, inventory: Option<&Inventory>,
skill_set: Option<&SkillSet>, skill_set: Option<&SkillSet>,
char_state: Option<&CharacterState>,
) -> Ability { ) -> Ability {
match input { match input {
AbilityInput::Guard => self.guard.into(), AbilityInput::Guard => self.guard.into(),
@ -171,7 +188,7 @@ impl ActiveAbilities {
AbilityInput::Secondary => self.secondary.into(), AbilityInput::Secondary => self.secondary.into(),
AbilityInput::Movement => self.movement.into(), AbilityInput::Movement => self.movement.into(),
AbilityInput::Auxiliary(index) => self AbilityInput::Auxiliary(index) => self
.auxiliary_set(inventory, skill_set) .auxiliary_set(inventory, skill_set, char_state)
.get(index) .get(index)
.copied() .copied()
.map(|a| a.into()) .map(|a| a.into())
@ -191,7 +208,7 @@ impl ActiveAbilities {
context: &AbilityContext, context: &AbilityContext,
// bool is from_offhand // bool is from_offhand
) -> Option<(CharacterAbility, bool, SpecifiedAbility)> { ) -> Option<(CharacterAbility, bool, SpecifiedAbility)> {
let ability = self.get_ability(input, inv, Some(skill_set)); let ability = self.get_ability(input, inv, Some(skill_set), char_state);
let ability_set = |equip_slot| { let ability_set = |equip_slot| {
inv.and_then(|inv| inv.equipped(equip_slot)) inv.and_then(|inv| inv.equipped(equip_slot))
@ -232,40 +249,48 @@ impl ActiveAbilities {
}; };
let source = AbilitySource::determine(char_state); let source = AbilitySource::determine(char_state);
match source {
AbilitySource::Glider => match ability { match ability {
Ability::ToolGuard => None, Ability::ToolGuard => match source {
Ability::ToolPrimary => inst_ability(EquipSlot::Glider, false), AbilitySource::Weapons => {
Ability::ToolSecondary => inst_ability(EquipSlot::Glider, false),
Ability::SpeciesMovement => None,
Ability::MainWeaponAux(_) | Ability::OffWeaponAux(_) => None,
Ability::Empty => None,
},
AbilitySource::Weapons => match ability {
Ability::ToolGuard => {
let equip_slot = combat::get_equip_slot_by_block_priority(inv); let equip_slot = combat::get_equip_slot_by_block_priority(inv);
inst_ability(equip_slot, matches!(equip_slot, EquipSlot::ActiveOffhand)) inst_ability(equip_slot, matches!(equip_slot, EquipSlot::ActiveOffhand))
}, },
Ability::ToolPrimary => inst_ability(EquipSlot::ActiveMainhand, false), AbilitySource::Glider => None,
Ability::ToolSecondary => inst_ability(EquipSlot::ActiveOffhand, true)
.or_else(|| inst_ability(EquipSlot::ActiveMainhand, false)),
Ability::SpeciesMovement => matches!(body, Some(Body::Humanoid(_)))
.then(|| CharacterAbility::default_roll(char_state))
.map(|ability| {
(
ability.adjusted_by_skills(skill_set, None),
false,
spec_ability(None),
)
}),
Ability::MainWeaponAux(_) => inst_ability(EquipSlot::ActiveMainhand, false),
Ability::OffWeaponAux(_) => inst_ability(EquipSlot::ActiveOffhand, true),
Ability::Empty => None,
}, },
Ability::ToolPrimary => match source {
AbilitySource::Weapons => inst_ability(EquipSlot::ActiveMainhand, false),
AbilitySource::Glider => inst_ability(EquipSlot::Glider, false),
},
Ability::ToolSecondary => match source {
AbilitySource::Weapons => inst_ability(EquipSlot::ActiveOffhand, true)
.or_else(|| inst_ability(EquipSlot::ActiveMainhand, false)),
AbilitySource::Glider => inst_ability(EquipSlot::Glider, false),
},
Ability::MainWeaponAux(_) => match source {
AbilitySource::Weapons => inst_ability(EquipSlot::ActiveMainhand, false),
// TODO: add auxiliary abilities in the future?
AbilitySource::Glider => None,
},
Ability::OffWeaponAux(_) => match source {
AbilitySource::Weapons => inst_ability(EquipSlot::ActiveOffhand, true),
// TODO: add auxiliary abilities in the future?
AbilitySource::Glider => None,
},
Ability::Empty => None,
Ability::SpeciesMovement => matches!(body, Some(Body::Humanoid(_)))
.then(|| CharacterAbility::default_roll(char_state))
.map(|ability| {
(
ability.adjusted_by_skills(skill_set, None),
false,
spec_ability(None),
)
}),
} }
} }
pub fn iter_available_abilities<'a>( pub fn iter_available_abilities_on<'a>(
inv: Option<&'a Inventory>, inv: Option<&'a Inventory>,
skill_set: Option<&'a SkillSet>, skill_set: Option<&'a SkillSet>,
equip_slot: EquipSlot, equip_slot: EquipSlot,
@ -290,15 +315,66 @@ impl ActiveAbilities {
}) })
} }
pub fn all_available_abilities(
inv: Option<&Inventory>,
skill_set: Option<&SkillSet>,
char_state: Option<&CharacterState>,
) -> Vec<AuxiliaryAbility> {
let source = AbilitySource::determine(char_state);
match source {
AbilitySource::Weapons => {
// Check if uses combo of two "equal" weapons
let paired = inv
.and_then(|inv| {
let a = inv.equipped(EquipSlot::ActiveMainhand)?;
let b = inv.equipped(EquipSlot::ActiveOffhand)?;
if let (ItemKind::Tool(tool_a), ItemKind::Tool(tool_b)) =
(&*a.kind(), &*b.kind())
{
Some((a.ability_spec(), tool_a.kind, b.ability_spec(), tool_b.kind))
} else {
None
}
})
.is_some_and(|(a_spec, a_kind, b_spec, b_kind)| {
(a_spec, a_kind) == (b_spec, b_kind)
});
// If equal, just take the first
if paired {
Self::iter_available_abilities_on(inv, skill_set, EquipSlot::ActiveMainhand)
.map(AuxiliaryAbility::MainWeapon)
.collect()
} else {
Self::iter_available_abilities_on(inv, skill_set, EquipSlot::ActiveMainhand)
.map(AuxiliaryAbility::MainWeapon)
.chain(
Self::iter_available_abilities_on(
inv,
skill_set,
EquipSlot::ActiveOffhand,
)
.map(AuxiliaryAbility::OffWeapon),
)
.collect()
}
},
// TODO: add auxiliary abilities to gliders
AbilitySource::Glider => vec![],
}
}
fn default_ability_set<'a>( fn default_ability_set<'a>(
inv: Option<&'a Inventory>, inv: Option<&'a Inventory>,
skill_set: Option<&'a SkillSet>, skill_set: Option<&'a SkillSet>,
limit: Option<usize>, limit: Option<usize>,
) -> Vec<AuxiliaryAbility> { ) -> Vec<AuxiliaryAbility> {
let mut iter = Self::iter_available_abilities(inv, skill_set, EquipSlot::ActiveMainhand) let mut iter = Self::iter_available_abilities_on(inv, skill_set, EquipSlot::ActiveMainhand)
.map(AuxiliaryAbility::MainWeapon) .map(AuxiliaryAbility::MainWeapon)
.chain( .chain(
Self::iter_available_abilities(inv, skill_set, EquipSlot::ActiveOffhand) Self::iter_available_abilities_on(inv, skill_set, EquipSlot::ActiveOffhand)
.map(AuxiliaryAbility::OffWeapon), .map(AuxiliaryAbility::OffWeapon),
); );
@ -406,6 +482,7 @@ impl Ability {
Ability::ToolPrimary => inst_ability(EquipSlot::Glider), Ability::ToolPrimary => inst_ability(EquipSlot::Glider),
Ability::ToolSecondary => inst_ability(EquipSlot::Glider), Ability::ToolSecondary => inst_ability(EquipSlot::Glider),
Ability::SpeciesMovement => None, // TODO: Make not None Ability::SpeciesMovement => None, // TODO: Make not None
// TODO: add aux abilities to gliders in the future?
Ability::MainWeaponAux(_) | Ability::OffWeaponAux(_) => None, Ability::MainWeaponAux(_) | Ability::OffWeaponAux(_) => None,
Ability::Empty => None, Ability::Empty => None,
}, },
@ -415,8 +492,8 @@ impl Ability {
inst_ability(equip_slot) inst_ability(equip_slot)
}, },
Ability::ToolPrimary => inst_ability(EquipSlot::ActiveMainhand), Ability::ToolPrimary => inst_ability(EquipSlot::ActiveMainhand),
Ability::ToolSecondary => inst_ability(EquipSlot::ActiveMainhand) Ability::ToolSecondary => inst_ability(EquipSlot::ActiveOffhand)
.or_else(|| inst_ability(EquipSlot::ActiveOffhand)), .or_else(|| inst_ability(EquipSlot::ActiveMainhand)),
Ability::SpeciesMovement => None, // TODO: Make not None Ability::SpeciesMovement => None, // TODO: Make not None
Ability::MainWeaponAux(_) => inst_ability(EquipSlot::ActiveMainhand), Ability::MainWeaponAux(_) => inst_ability(EquipSlot::ActiveMainhand),
Ability::OffWeaponAux(_) => inst_ability(EquipSlot::ActiveOffhand), Ability::OffWeaponAux(_) => inst_ability(EquipSlot::ActiveOffhand),
@ -504,6 +581,7 @@ impl SpecifiedAbility {
Ability::ToolPrimary => inst_ability(EquipSlot::Glider), Ability::ToolPrimary => inst_ability(EquipSlot::Glider),
Ability::ToolSecondary => inst_ability(EquipSlot::Glider), Ability::ToolSecondary => inst_ability(EquipSlot::Glider),
Ability::SpeciesMovement => None, Ability::SpeciesMovement => None,
// TODO: add aux abilities to gliders in the future?
Ability::MainWeaponAux(_) | Ability::OffWeaponAux(_) => None, Ability::MainWeaponAux(_) | Ability::OffWeaponAux(_) => None,
Ability::Empty => None, Ability::Empty => None,
}, },
@ -524,14 +602,13 @@ impl SpecifiedAbility {
#[derive(Copy, Clone, Serialize, Deserialize, Debug)] #[derive(Copy, Clone, Serialize, Deserialize, Debug)]
pub enum PrimaryAbility { pub enum PrimaryAbility {
Tool, Tool,
Glider,
Empty, Empty,
} }
impl From<PrimaryAbility> for Ability { impl From<PrimaryAbility> for Ability {
fn from(primary: PrimaryAbility) -> Self { fn from(primary: PrimaryAbility) -> Self {
match primary { match primary {
PrimaryAbility::Tool | PrimaryAbility::Glider => Ability::ToolPrimary, PrimaryAbility::Tool => Ability::ToolPrimary,
PrimaryAbility::Empty => Ability::Empty, PrimaryAbility::Empty => Ability::Empty,
} }
} }
@ -540,14 +617,13 @@ impl From<PrimaryAbility> for Ability {
#[derive(Copy, Clone, Serialize, Deserialize, Debug)] #[derive(Copy, Clone, Serialize, Deserialize, Debug)]
pub enum SecondaryAbility { pub enum SecondaryAbility {
Tool, Tool,
Glider,
Empty, Empty,
} }
impl From<SecondaryAbility> for Ability { impl From<SecondaryAbility> for Ability {
fn from(primary: SecondaryAbility) -> Self { fn from(primary: SecondaryAbility) -> Self {
match primary { match primary {
SecondaryAbility::Tool | SecondaryAbility::Glider => Ability::ToolSecondary, SecondaryAbility::Tool => Ability::ToolSecondary,
SecondaryAbility::Empty => Ability::Empty, SecondaryAbility::Empty => Ability::Empty,
} }
} }

View File

@ -434,7 +434,8 @@ impl<'a> AgentData<'a> {
agent.combat_state.int_counters[IntCounters::Tactics as usize] = tactic as u8; agent.combat_state.int_counters[IntCounters::Tactics as usize] = tactic as u8;
let auxiliary_key = ActiveAbilities::active_auxiliary_key(Some(self.inventory)); let auxiliary_key =
ActiveAbilities::active_auxiliary_key(Some(self.inventory), Some(self.char_state));
let set_sword_ability = |controller: &mut Controller, slot, skill| { let set_sword_ability = |controller: &mut Controller, slot, skill| {
controller.push_event(ControlEvent::ChangeAbility { controller.push_event(ControlEvent::ChangeAbility {
slot, slot,
@ -1219,7 +1220,8 @@ impl<'a> AgentData<'a> {
agent.combat_state.int_counters[IntCounters::Tactic as usize] = tactic as u8; agent.combat_state.int_counters[IntCounters::Tactic as usize] = tactic as u8;
let auxiliary_key = ActiveAbilities::active_auxiliary_key(Some(self.inventory)); let auxiliary_key =
ActiveAbilities::active_auxiliary_key(Some(self.inventory), Some(self.char_state));
let set_axe_ability = |controller: &mut Controller, slot, skill| { let set_axe_ability = |controller: &mut Controller, slot, skill| {
controller.push_event(ControlEvent::ChangeAbility { controller.push_event(ControlEvent::ChangeAbility {
slot, slot,

View File

@ -37,7 +37,7 @@ use common::{
RollSkill, SceptreSkill, Skill, StaffSkill, SwimSkill, SwordSkill, SKILL_MODIFIERS, RollSkill, SceptreSkill, Skill, StaffSkill, SwimSkill, SwordSkill, SKILL_MODIFIERS,
}, },
skillset::{SkillGroupKind, SkillSet}, skillset::{SkillGroupKind, SkillSet},
Body, Energy, Health, Inventory, Poise, Body, CharacterState, Energy, Health, Inventory, Poise,
}, },
consts::{ENERGY_PER_LEVEL, HP_PER_LEVEL}, consts::{ENERGY_PER_LEVEL, HP_PER_LEVEL},
}; };
@ -212,6 +212,7 @@ pub struct Diary<'a> {
skill_set: &'a SkillSet, skill_set: &'a SkillSet,
active_abilities: &'a ActiveAbilities, active_abilities: &'a ActiveAbilities,
inventory: &'a Inventory, inventory: &'a Inventory,
char_state: &'a CharacterState,
health: &'a Health, health: &'a Health,
energy: &'a Energy, energy: &'a Energy,
poise: &'a Poise, poise: &'a Poise,
@ -258,6 +259,7 @@ impl<'a> Diary<'a> {
skill_set: &'a SkillSet, skill_set: &'a SkillSet,
active_abilities: &'a ActiveAbilities, active_abilities: &'a ActiveAbilities,
inventory: &'a Inventory, inventory: &'a Inventory,
char_state: &'a CharacterState,
health: &'a Health, health: &'a Health,
energy: &'a Energy, energy: &'a Energy,
poise: &'a Poise, poise: &'a Poise,
@ -280,6 +282,7 @@ impl<'a> Diary<'a> {
skill_set, skill_set,
active_abilities, active_abilities,
inventory, inventory,
char_state,
health, health,
energy, energy,
poise, poise,
@ -838,6 +841,7 @@ impl<'a> Widget for Diary<'a> {
self.inventory, self.inventory,
self.skill_set, self.skill_set,
self.context, self.context,
Some(self.char_state),
), ),
image_source: self.imgs, image_source: self.imgs,
slot_manager: Some(self.slot_manager), slot_manager: Some(self.slot_manager),
@ -851,9 +855,10 @@ impl<'a> Widget for Diary<'a> {
AbilityInput::Auxiliary(i), AbilityInput::Auxiliary(i),
Some(self.inventory), Some(self.inventory),
Some(self.skill_set), Some(self.skill_set),
Some(self.char_state),
) )
.ability_id( .ability_id(
None, Some(self.char_state),
Some(self.inventory), Some(self.inventory),
Some(self.skill_set), Some(self.skill_set),
self.context, self.context,
@ -917,61 +922,24 @@ impl<'a> Widget for Diary<'a> {
.set(state.ids.active_abilities_keys[i], ui); .set(state.ids.active_abilities_keys[i], ui);
} }
let same_weap_kinds = self let abilities: Vec<_> = ActiveAbilities::all_available_abilities(
.inventory
.equipped(EquipSlot::ActiveMainhand)
.zip(self.inventory.equipped(EquipSlot::ActiveOffhand))
.map_or(false, |(a, b)| {
if let (ItemKind::Tool(tool_a), ItemKind::Tool(tool_b)) =
(&*a.kind(), &*b.kind())
{
(a.ability_spec(), tool_a.kind) == (b.ability_spec(), tool_b.kind)
} else {
false
}
});
let main_weap_abilities = ActiveAbilities::iter_available_abilities(
Some(self.inventory), Some(self.inventory),
Some(self.skill_set), Some(self.skill_set),
EquipSlot::ActiveMainhand, Some(self.char_state),
) )
.map(AuxiliaryAbility::MainWeapon) .into_iter()
.map(|a| { .map(|a| {
( (
Ability::from(a).ability_id( Ability::from(a).ability_id(
None, Some(self.char_state),
Some(self.inventory), Some(self.inventory),
Some(self.skill_set), Some(self.skill_set),
self.context, self.context,
), ),
a, a,
) )
}); })
let off_weap_abilities = ActiveAbilities::iter_available_abilities( .collect();
Some(self.inventory),
Some(self.skill_set),
EquipSlot::ActiveOffhand,
)
.map(AuxiliaryAbility::OffWeapon)
.map(|a| {
(
Ability::from(a).ability_id(
None,
Some(self.inventory),
Some(self.skill_set),
self.context,
),
a,
)
});
let abilities: Vec<_> = if same_weap_kinds {
// When the weapons have the same ability kind take only the main weapons,
main_weap_abilities.collect()
} else {
main_weap_abilities.chain(off_weap_abilities).collect()
};
const ABILITIES_PER_PAGE: usize = 12; const ABILITIES_PER_PAGE: usize = 12;
@ -1072,12 +1040,27 @@ impl<'a> Widget for Diary<'a> {
self.inventory, self.inventory,
self.skill_set, self.skill_set,
self.context, self.context,
Some(self.char_state),
), ),
image_source: self.imgs, image_source: self.imgs,
slot_manager: Some(self.slot_manager), slot_manager: Some(self.slot_manager),
pulse: 0.0, pulse: 0.0,
}; };
let same_weap_kinds = self
.inventory
.equipped(EquipSlot::ActiveMainhand)
.zip(self.inventory.equipped(EquipSlot::ActiveOffhand))
.map_or(false, |(a, b)| {
if let (ItemKind::Tool(tool_a), ItemKind::Tool(tool_b)) =
(&*a.kind(), &*b.kind())
{
(a.ability_spec(), tool_a.kind) == (b.ability_spec(), tool_b.kind)
} else {
false
}
});
for (id_index, (ability_id, ability)) in abilities for (id_index, (ability_id, ability)) in abilities
.iter() .iter()
.skip(ability_start) .skip(ability_start)

View File

@ -81,6 +81,10 @@ impl State {
.state() .state()
.read_storage::<comp::SkillSet>() .read_storage::<comp::SkillSet>()
.get(info.viewpoint_entity), .get(info.viewpoint_entity),
client
.state()
.read_storage::<comp::CharacterState>()
.get(info.viewpoint_entity),
) )
.iter() .iter()
.enumerate() .enumerate()

View File

@ -3684,6 +3684,7 @@ impl Hud {
if let ( if let (
Some(skill_set), Some(skill_set),
Some(inventory), Some(inventory),
Some(char_state),
Some(health), Some(health),
Some(energy), Some(energy),
Some(body), Some(body),
@ -3691,6 +3692,7 @@ impl Hud {
) = ( ) = (
skill_sets.get(entity), skill_sets.get(entity),
inventories.get(entity), inventories.get(entity),
char_states.get(entity),
healths.get(entity), healths.get(entity),
energies.get(entity), energies.get(entity),
bodies.get(entity), bodies.get(entity),
@ -3704,6 +3706,7 @@ impl Hud {
skill_set, skill_set,
active_abilities.get(entity).unwrap_or(&Default::default()), active_abilities.get(entity).unwrap_or(&Default::default()),
inventory, inventory,
char_state,
health, health,
energy, energy,
poise, poise,
@ -4002,12 +4005,20 @@ impl Hud {
let me = info.viewpoint_entity; let me = info.viewpoint_entity;
if let Some(active_abilities) = active_abilities.get(me) { if let Some(active_abilities) = active_abilities.get(me) {
let ability_a = active_abilities let ability_a = active_abilities
.auxiliary_set(inventories.get(me), skill_sets.get(me)) .auxiliary_set(
inventories.get(me),
skill_sets.get(me),
char_states.get(me),
)
.get(a) .get(a)
.copied() .copied()
.unwrap_or(AuxiliaryAbility::Empty); .unwrap_or(AuxiliaryAbility::Empty);
let ability_b = active_abilities let ability_b = active_abilities
.auxiliary_set(inventories.get(me), skill_sets.get(me)) .auxiliary_set(
inventories.get(me),
skill_sets.get(me),
char_states.get(me),
)
.get(b) .get(b)
.copied() .copied()
.unwrap_or(AuxiliaryAbility::Empty); .unwrap_or(AuxiliaryAbility::Empty);
@ -4152,12 +4163,20 @@ impl Hud {
let me = info.viewpoint_entity; let me = info.viewpoint_entity;
if let Some(active_abilities) = active_abilities.get(me) { if let Some(active_abilities) = active_abilities.get(me) {
let ability_a = active_abilities let ability_a = active_abilities
.auxiliary_set(inventories.get(me), skill_sets.get(me)) .auxiliary_set(
inventories.get(me),
skill_sets.get(me),
char_states.get(me),
)
.get(a) .get(a)
.copied() .copied()
.unwrap_or(AuxiliaryAbility::Empty); .unwrap_or(AuxiliaryAbility::Empty);
let ability_b = active_abilities let ability_b = active_abilities
.auxiliary_set(inventories.get(me), skill_sets.get(me)) .auxiliary_set(
inventories.get(me),
skill_sets.get(me),
char_states.get(me),
)
.get(b) .get(b)
.copied() .copied()
.unwrap_or(AuxiliaryAbility::Empty); .unwrap_or(AuxiliaryAbility::Empty);

View File

@ -1028,7 +1028,7 @@ impl<'a> Skillbar<'a> {
// Helper // Helper
let tooltip_text = |slot| { let tooltip_text = |slot| {
let (hotbar, inventory, _, skill_set, active_abilities, _, contexts, _, _, _) = let (hotbar, inventory, _, skill_set, active_abilities, _, contexts, _, char_state, _) =
content_source; content_source;
hotbar.get(slot).and_then(|content| match content { hotbar.get(slot).and_then(|content| match content {
hotbar::SlotContents::Inventory(i, _) => inventory.get_by_hash(i).map(|item| { hotbar::SlotContents::Inventory(i, _) => inventory.get_by_hash(i).map(|item| {
@ -1039,7 +1039,7 @@ impl<'a> Skillbar<'a> {
}), }),
hotbar::SlotContents::Ability(i) => active_abilities hotbar::SlotContents::Ability(i) => active_abilities
.and_then(|a| { .and_then(|a| {
a.auxiliary_set(Some(inventory), Some(skill_set)) a.auxiliary_set(Some(inventory), Some(skill_set), char_state)
.get(i) .get(i)
.and_then(|a| { .and_then(|a| {
Ability::from(*a).ability_id( Ability::from(*a).ability_id(

View File

@ -165,7 +165,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
}, },
hotbar::SlotContents::Ability(i) => { hotbar::SlotContents::Ability(i) => {
let ability_id = active_abilities.and_then(|a| { let ability_id = active_abilities.and_then(|a| {
a.auxiliary_set(Some(inventory), Some(skillset)) a.auxiliary_set(Some(inventory), Some(skillset), *char_state)
.get(i) .get(i)
.and_then(|a| { .and_then(|a| {
Ability::from(*a).ability_id( Ability::from(*a).ability_id(
@ -246,6 +246,7 @@ type AbilitiesSource<'a> = (
&'a Inventory, &'a Inventory,
&'a SkillSet, &'a SkillSet,
&'a AbilityContext, &'a AbilityContext,
Option<&'a CharacterState>,
); );
impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot { impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
@ -253,7 +254,7 @@ impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
fn image_key( fn image_key(
&self, &self,
(active_abilities, inventory, skillset, contexts): &AbilitiesSource<'a>, (active_abilities, inventory, skillset, contexts, char_state): &AbilitiesSource<'a>,
) -> Option<(Self::ImageKey, Option<Color>)> { ) -> Option<(Self::ImageKey, Option<Color>)> {
let ability_id = match self { let ability_id = match self {
Self::Slot(index) => active_abilities Self::Slot(index) => active_abilities
@ -261,11 +262,15 @@ impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
AbilityInput::Auxiliary(*index), AbilityInput::Auxiliary(*index),
Some(inventory), Some(inventory),
Some(skillset), Some(skillset),
*char_state,
) )
.ability_id(None, Some(inventory), Some(skillset), contexts), .ability_id(*char_state, Some(inventory), Some(skillset), contexts),
Self::Ability(ability) => { Self::Ability(ability) => Ability::from(*ability).ability_id(
Ability::from(*ability).ability_id(None, Some(inventory), Some(skillset), contexts) *char_state,
}, Some(inventory),
Some(skillset),
contexts,
),
}; };
ability_id.map(|id| (String::from(id), None)) ability_id.map(|id| (String::from(id), None))