mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added in-memory persistence of ability sets per weapon kind pair.
This commit is contained in:
parent
89bf41574c
commit
d86692c4fe
@ -9,15 +9,6 @@
|
|||||||
// TODO: Remove these
|
// TODO: Remove these
|
||||||
(Some(Axe(UnlockLeap)), "common.abilities.axe.leap"),
|
(Some(Axe(UnlockLeap)), "common.abilities.axe.leap"),
|
||||||
(Some(Hammer(UnlockLeap)), "common.abilities.hammer.leap"),
|
(Some(Hammer(UnlockLeap)), "common.abilities.hammer.leap"),
|
||||||
(Some(Bow(UnlockShotgun)), "common.abilities.bow.shotgun"),
|
|
||||||
(Some(Staff(UnlockShockwave)), "common.abilities.staff.fireshockwave"),
|
|
||||||
(Some(Sceptre(UnlockAura)), "common.abilities.sceptre.wardingaura"),
|
|
||||||
(Some(Sword(UnlockSpin)), "common.abilities.sword.spin"),
|
|
||||||
(Some(Axe(UnlockLeap)), "common.abilities.axe.leap"),
|
|
||||||
(Some(Hammer(UnlockLeap)), "common.abilities.hammer.leap"),
|
|
||||||
(Some(Bow(UnlockShotgun)), "common.abilities.bow.shotgun"),
|
|
||||||
(Some(Staff(UnlockShockwave)), "common.abilities.staff.fireshockwave"),
|
|
||||||
(Some(Sceptre(UnlockAura)), "common.abilities.sceptre.wardingaura"),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Tool(Axe): (
|
Tool(Axe): (
|
||||||
@ -39,6 +30,9 @@
|
|||||||
secondary: "common.abilities.bow.repeater",
|
secondary: "common.abilities.bow.repeater",
|
||||||
abilities: [
|
abilities: [
|
||||||
(Some(Bow(UnlockShotgun)), "common.abilities.bow.shotgun"),
|
(Some(Bow(UnlockShotgun)), "common.abilities.bow.shotgun"),
|
||||||
|
// TODO: Remove these
|
||||||
|
(Some(Staff(UnlockShockwave)), "common.abilities.staff.fireshockwave"),
|
||||||
|
(Some(Sceptre(UnlockAura)), "common.abilities.sceptre.wardingaura"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Tool(Staff): (
|
Tool(Staff): (
|
||||||
|
@ -27,7 +27,7 @@ use common::{
|
|||||||
group,
|
group,
|
||||||
invite::{InviteKind, InviteResponse},
|
invite::{InviteKind, InviteResponse},
|
||||||
skills::Skill,
|
skills::Skill,
|
||||||
slot::{InvSlotId, Slot},
|
slot::{EquipSlot, InvSlotId, Slot},
|
||||||
CharacterState, ChatMode, ControlAction, ControlEvent, Controller, ControllerInputs,
|
CharacterState, ChatMode, ControlAction, ControlEvent, Controller, ControllerInputs,
|
||||||
GroupManip, InputKind, InventoryAction, InventoryEvent, InventoryUpdateEvent,
|
GroupManip, InputKind, InventoryAction, InventoryEvent, InventoryUpdateEvent,
|
||||||
UtteranceKind,
|
UtteranceKind,
|
||||||
@ -1404,8 +1404,26 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_ability(&mut self, slot: usize, new_ability: comp::ability::AuxiliaryAbility) {
|
pub fn change_ability(&mut self, slot: usize, new_ability: comp::ability::AuxiliaryAbility) {
|
||||||
|
let auxiliary_key = self
|
||||||
|
.inventories()
|
||||||
|
.get(self.entity())
|
||||||
|
.map_or((None, None), |inv| {
|
||||||
|
let tool_kind = |slot| {
|
||||||
|
inv.equipped(slot).and_then(|item| match item.kind() {
|
||||||
|
comp::item::ItemKind::Tool(tool) => Some(tool.kind),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
tool_kind(EquipSlot::ActiveMainhand),
|
||||||
|
tool_kind(EquipSlot::ActiveOffhand),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::ChangeAbility {
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::ChangeAbility {
|
||||||
slot,
|
slot,
|
||||||
|
auxiliary_key,
|
||||||
new_ability,
|
new_ability,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,14 @@ use crate::{
|
|||||||
},
|
},
|
||||||
terrain::SpriteKind,
|
terrain::SpriteKind,
|
||||||
};
|
};
|
||||||
|
use hashbrown::HashMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DerefFlaggedStorage};
|
use specs::{Component, DerefFlaggedStorage};
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
use std::{convert::TryFrom, time::Duration};
|
use std::{convert::TryFrom, time::Duration};
|
||||||
|
|
||||||
pub const MAX_ABILITIES: usize = 5;
|
pub const MAX_ABILITIES: usize = 5;
|
||||||
|
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
|
||||||
// combinations and automatically reverting back to them on switching to that
|
// combinations and automatically reverting back to them on switching to that
|
||||||
@ -41,7 +43,7 @@ pub struct ActiveAbilities {
|
|||||||
pub primary: PrimaryAbility,
|
pub primary: PrimaryAbility,
|
||||||
pub secondary: SecondaryAbility,
|
pub secondary: SecondaryAbility,
|
||||||
pub movement: MovementAbility,
|
pub movement: MovementAbility,
|
||||||
pub abilities: [AuxiliaryAbility; MAX_ABILITIES],
|
pub auxiliary_sets: HashMap<AuxiliaryKey, [AuxiliaryAbility; MAX_ABILITIES]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for ActiveAbilities {
|
impl Component for ActiveAbilities {
|
||||||
@ -54,7 +56,7 @@ impl Default for ActiveAbilities {
|
|||||||
primary: PrimaryAbility::Tool,
|
primary: PrimaryAbility::Tool,
|
||||||
secondary: SecondaryAbility::Tool,
|
secondary: SecondaryAbility::Tool,
|
||||||
movement: MovementAbility::Species,
|
movement: MovementAbility::Species,
|
||||||
abilities: [AuxiliaryAbility::Empty; MAX_ABILITIES],
|
auxiliary_sets: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,22 +70,46 @@ impl ActiveAbilities {
|
|||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_ability(&mut self, slot: usize, new_ability: AuxiliaryAbility) {
|
pub fn change_ability(
|
||||||
if let Some(ability) = self.abilities.get_mut(slot) {
|
&mut self,
|
||||||
|
slot: usize,
|
||||||
|
auxiliary_key: AuxiliaryKey,
|
||||||
|
new_ability: AuxiliaryAbility,
|
||||||
|
) {
|
||||||
|
let auxiliary_set = self
|
||||||
|
.auxiliary_sets
|
||||||
|
.entry(auxiliary_key)
|
||||||
|
.or_insert([AuxiliaryAbility::Empty; 5]);
|
||||||
|
if let Some(ability) = auxiliary_set.get_mut(slot) {
|
||||||
*ability = new_ability;
|
*ability = new_ability;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ability(&self, input: AbilityInput) -> Ability {
|
pub fn get_ability(&self, input: AbilityInput, inventory: Option<&Inventory>) -> Ability {
|
||||||
match input {
|
match input {
|
||||||
AbilityInput::Primary => self.primary.into(),
|
AbilityInput::Primary => self.primary.into(),
|
||||||
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) => inventory
|
||||||
.abilities
|
.and_then(|inv| {
|
||||||
.get(index)
|
let tool_kind = |slot| {
|
||||||
.copied()
|
inv.equipped(slot).and_then(|item| match item.kind() {
|
||||||
.map(|a| a.into())
|
ItemKind::Tool(tool) => Some(tool.kind),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let aux_key = (
|
||||||
|
tool_kind(EquipSlot::ActiveMainhand),
|
||||||
|
tool_kind(EquipSlot::ActiveOffhand),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.auxiliary_sets
|
||||||
|
.get(&aux_key)
|
||||||
|
.and_then(|entry| entry.get(index))
|
||||||
|
.copied()
|
||||||
|
.map(|a| a.into())
|
||||||
|
})
|
||||||
.unwrap_or(Ability::Empty),
|
.unwrap_or(Ability::Empty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,7 +124,7 @@ impl ActiveAbilities {
|
|||||||
body: Option<&Body>,
|
body: Option<&Body>,
|
||||||
// bool is from_offhand
|
// bool is from_offhand
|
||||||
) -> Option<(CharacterAbility, bool)> {
|
) -> Option<(CharacterAbility, bool)> {
|
||||||
let ability = self.get_ability(input);
|
let ability = self.get_ability(input, inv);
|
||||||
|
|
||||||
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))
|
||||||
@ -168,6 +194,30 @@ impl ActiveAbilities {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter_aux_abilities<'a>(
|
||||||
|
&'a self,
|
||||||
|
inventory: Option<&'a Inventory>,
|
||||||
|
) -> impl Iterator<Item = &AuxiliaryAbility> + 'a {
|
||||||
|
inventory
|
||||||
|
.and_then(|inv| {
|
||||||
|
let tool_kind = |slot| {
|
||||||
|
inv.equipped(slot).and_then(|item| match item.kind() {
|
||||||
|
ItemKind::Tool(tool) => Some(tool.kind),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let aux_key = (
|
||||||
|
tool_kind(EquipSlot::ActiveMainhand),
|
||||||
|
tool_kind(EquipSlot::ActiveOffhand),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.auxiliary_sets.get(&aux_key)
|
||||||
|
})
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Maybe keep this for autopopulating a new combination of weapons?
|
// TODO: Maybe keep this for autopopulating a new combination of weapons?
|
||||||
// pub fn auto_update(&mut self, inv: Option<&Inventory>, skill_set:
|
// pub fn auto_update(&mut self, inv: Option<&Inventory>, skill_set:
|
||||||
// Option<&SkillSet>) { let main_abilities =
|
// Option<&SkillSet>) { let main_abilities =
|
||||||
|
@ -138,6 +138,7 @@ pub enum ControlEvent {
|
|||||||
Utterance(UtteranceKind),
|
Utterance(UtteranceKind),
|
||||||
ChangeAbility {
|
ChangeAbility {
|
||||||
slot: usize,
|
slot: usize,
|
||||||
|
auxiliary_key: ability::AuxiliaryKey,
|
||||||
new_ability: ability::AuxiliaryAbility,
|
new_ability: ability::AuxiliaryAbility,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -110,9 +110,13 @@ impl<'a> System<'a> for Sys {
|
|||||||
server_emitter.emit(ServerEvent::Sound { sound });
|
server_emitter.emit(ServerEvent::Sound { sound });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ControlEvent::ChangeAbility { slot, new_ability } => {
|
ControlEvent::ChangeAbility {
|
||||||
|
slot,
|
||||||
|
auxiliary_key,
|
||||||
|
new_ability,
|
||||||
|
} => {
|
||||||
if let Some(mut active_abilities) = active_abilities.get_mut(entity) {
|
if let Some(mut active_abilities) = active_abilities.get_mut(entity) {
|
||||||
active_abilities.change_ability(slot, new_ability);
|
active_abilities.change_ability(slot, auxiliary_key, new_ability);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -780,7 +780,7 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
for i in 0..MAX_ABILITIES {
|
for i in 0..MAX_ABILITIES {
|
||||||
let ability_id = self
|
let ability_id = self
|
||||||
.active_abilities
|
.active_abilities
|
||||||
.get_ability(AbilityInput::Auxiliary(i))
|
.get_ability(AbilityInput::Auxiliary(i), Some(self.inventory))
|
||||||
.ability_id(Some(self.inventory));
|
.ability_id(Some(self.inventory));
|
||||||
|
|
||||||
let image_size = 50.0;
|
let image_size = 50.0;
|
||||||
|
@ -70,8 +70,7 @@ impl State {
|
|||||||
{
|
{
|
||||||
use common::comp::ability::AuxiliaryAbility;
|
use common::comp::ability::AuxiliaryAbility;
|
||||||
for ((i, ability), hotbar_slot) in active_abilities
|
for ((i, ability), hotbar_slot) in active_abilities
|
||||||
.abilities
|
.iter_aux_abilities(client.inventories().get(client.entity()))
|
||||||
.iter()
|
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.zip(self.slots.iter_mut())
|
.zip(self.slots.iter_mut())
|
||||||
{
|
{
|
||||||
|
@ -607,8 +607,8 @@ impl<'a> Skillbar<'a> {
|
|||||||
.get_by_hash(i)
|
.get_by_hash(i)
|
||||||
.map(|item| (item.name(), item.description())),
|
.map(|item| (item.name(), item.description())),
|
||||||
hotbar::SlotContents::Ability(i) => active_abilities
|
hotbar::SlotContents::Ability(i) => active_abilities
|
||||||
.abilities
|
.iter_aux_abilities(Some(inventory))
|
||||||
.get(i)
|
.nth(i)
|
||||||
.and_then(|a| Ability::from(*a).ability_id(Some(inventory)))
|
.and_then(|a| Ability::from(*a).ability_id(Some(inventory)))
|
||||||
.map(util::ability_description),
|
.map(util::ability_description),
|
||||||
})
|
})
|
||||||
|
@ -141,8 +141,8 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
|||||||
},
|
},
|
||||||
hotbar::SlotContents::Ability(i) => {
|
hotbar::SlotContents::Ability(i) => {
|
||||||
let ability_id = active_abilities
|
let ability_id = active_abilities
|
||||||
.abilities
|
.iter_aux_abilities(Some(inventory))
|
||||||
.get(i)
|
.nth(i)
|
||||||
.and_then(|a| Ability::from(*a).ability_id(Some(inventory)));
|
.and_then(|a| Ability::from(*a).ability_id(Some(inventory)));
|
||||||
|
|
||||||
ability_id
|
ability_id
|
||||||
|
Loading…
Reference in New Issue
Block a user