veloren_voxygen/hud/
hotbar.rs1use common::comp::{
2 self,
3 inventory::item::{Item, item_key::ItemKey},
4};
5use serde::{Deserialize, Serialize};
6
7use super::HudInfo;
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
10pub enum Slot {
11 #[default]
12 One = 0,
13 Two = 1,
14 Three = 2,
15 Four = 3,
16 Five = 4,
17 Six = 5,
18 Seven = 6,
19 Eight = 7,
20 Nine = 8,
21 Ten = 9,
22}
23
24#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
25pub enum SlotContents {
26 Inventory(u64, ItemKey),
27 Ability(usize),
28}
29
30#[derive(Clone, Default)]
31pub struct State {
32 pub slots: [Option<SlotContents>; 10],
33 inputs: [bool; 10],
34 pub currently_selected_slot: Slot,
35}
36
37impl State {
38 pub fn new(slots: [Option<SlotContents>; 10]) -> Self {
39 Self {
40 slots,
41 inputs: [false; 10],
42 currently_selected_slot: Slot::default(),
43 }
44 }
45
46 pub fn process_input(&mut self, slot: Slot, state: bool) -> bool {
48 let slot = slot as usize;
49 let just_pressed = !self.inputs[slot] && state;
50 self.inputs[slot] = state;
51 just_pressed
52 }
53
54 pub fn get(&self, slot: Slot) -> Option<SlotContents> { self.slots[slot as usize].clone() }
55
56 pub fn swap(&mut self, a: Slot, b: Slot) { self.slots.swap(a as usize, b as usize); }
57
58 pub fn clear_slot(&mut self, slot: Slot) { self.slots[slot as usize] = None; }
59
60 pub fn add_inventory_link(&mut self, slot: Slot, item: &Item) {
61 self.slots[slot as usize] = Some(SlotContents::Inventory(
62 item.item_hash(),
63 ItemKey::from(item),
64 ));
65 }
66
67 pub fn maintain_abilities(&mut self, client: &client::Client, info: &HudInfo) {
71 use specs::WorldExt;
72 if let Some(active_abilities) = client
73 .state()
74 .ecs()
75 .read_storage::<comp::ActiveAbilities>()
76 .get(info.viewpoint_entity)
77 {
78 use common::comp::ability::AuxiliaryAbility;
79 for ((i, ability), hotbar_slot) in active_abilities
80 .auxiliary_set(
81 client.inventories().get(info.viewpoint_entity),
82 client
83 .state()
84 .read_storage::<comp::SkillSet>()
85 .get(info.viewpoint_entity),
86 )
87 .iter()
88 .enumerate()
89 .zip(self.slots.iter_mut())
90 {
91 if matches!(ability, AuxiliaryAbility::Empty) {
92 if matches!(hotbar_slot, Some(SlotContents::Ability(_))) {
93 *hotbar_slot = None;
95 }
96 } else {
97 *hotbar_slot = Some(SlotContents::Ability(i));
99 }
100 }
101 } else {
102 self.slots
103 .iter_mut()
104 .filter(|slot| matches!(slot, Some(SlotContents::Ability(_))))
105 .for_each(|slot| *slot = None)
106 }
107 }
108}
109
110impl Slot {
111 const SLOTS: [Slot; 10] = [
112 Slot::One,
113 Slot::Two,
114 Slot::Three,
115 Slot::Four,
116 Slot::Five,
117 Slot::Six,
118 Slot::Seven,
119 Slot::Eight,
120 Slot::Nine,
121 Slot::Ten,
122 ];
123
124 pub fn next_slot(&mut self) {
125 let current_slot = *self as usize;
126 let next_slot = (current_slot + 1) % 10;
127 *self = Self::SLOTS[next_slot];
128 }
129
130 pub fn previous_slot(&mut self) {
131 let current_slot = *self as usize;
132 let previous_slot = (current_slot + 10 - 1) % 10;
133 *self = Self::SLOTS[previous_slot];
134 }
135}