mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Changed to using slot maker for ability slots
This commit is contained in:
parent
fe80e365fa
commit
19a1a0adb2
@ -6,17 +6,25 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
game_input::GameInput,
|
||||
hud::{self, util},
|
||||
ui::{fonts::Fonts, ImageFrame, Tooltip, TooltipManager, Tooltipable},
|
||||
hud::{
|
||||
self,
|
||||
slots::{AbilitySlot, SlotManager},
|
||||
util,
|
||||
},
|
||||
ui::{
|
||||
fonts::Fonts,
|
||||
slot::{ContentSize, SlotMaker},
|
||||
ImageFrame, Tooltip, TooltipManager, Tooltipable,
|
||||
},
|
||||
GlobalState,
|
||||
};
|
||||
use conrod_core::{
|
||||
color, image,
|
||||
input::state::mouse::ButtonPosition,
|
||||
widget::{self, Button, Image, Rectangle, State, Text},
|
||||
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, UiCell, Widget, WidgetCommon,
|
||||
};
|
||||
use i18n::Localization;
|
||||
use vek::*;
|
||||
|
||||
use client::{self, Client};
|
||||
use common::{
|
||||
@ -40,7 +48,6 @@ use common::{
|
||||
},
|
||||
consts::{ENERGY_PER_LEVEL, HP_PER_LEVEL},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use inline_tweak::*;
|
||||
use std::borrow::Cow;
|
||||
|
||||
@ -213,7 +220,6 @@ widget_ids! {
|
||||
ability_page_left,
|
||||
ability_page_right,
|
||||
active_abilities[],
|
||||
active_abilities_bg[],
|
||||
active_abilities_keys[],
|
||||
main_weap_select,
|
||||
off_weap_select,
|
||||
@ -248,6 +254,7 @@ pub struct Diary<'a> {
|
||||
localized_strings: &'a Localization,
|
||||
rot_imgs: &'a ImgsRot,
|
||||
tooltip_manager: &'a mut TooltipManager,
|
||||
slot_manager: &'a mut SlotManager,
|
||||
pulse: f32,
|
||||
|
||||
#[conrod(common_builder)]
|
||||
@ -261,7 +268,6 @@ pub struct Diary<'a> {
|
||||
pub struct DiaryShow {
|
||||
pub skilltreetab: SelectedSkillTree,
|
||||
pub section: DiarySection,
|
||||
pub selected_ability: Option<AuxiliaryAbility>,
|
||||
}
|
||||
|
||||
impl Default for DiaryShow {
|
||||
@ -269,7 +275,6 @@ impl Default for DiaryShow {
|
||||
Self {
|
||||
skilltreetab: SelectedSkillTree::General,
|
||||
section: DiarySection::SkillTrees,
|
||||
selected_ability: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,6 +299,7 @@ impl<'a> Diary<'a> {
|
||||
localized_strings: &'a Localization,
|
||||
rot_imgs: &'a ImgsRot,
|
||||
tooltip_manager: &'a mut TooltipManager,
|
||||
slot_manager: &'a mut SlotManager,
|
||||
pulse: f32,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -314,6 +320,7 @@ impl<'a> Diary<'a> {
|
||||
localized_strings,
|
||||
rot_imgs,
|
||||
tooltip_manager,
|
||||
slot_manager,
|
||||
pulse,
|
||||
common: widget::CommonBuilder::default(),
|
||||
created_btns_top_l: 0,
|
||||
@ -347,8 +354,6 @@ pub enum Event {
|
||||
ChangeSkillTree(SelectedSkillTree),
|
||||
UnlockSkill(Skill),
|
||||
ChangeSection(DiarySection),
|
||||
SelectAbility(Option<AuxiliaryAbility>),
|
||||
ChangeAbility(usize, AuxiliaryAbility),
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
@ -360,8 +365,6 @@ pub enum DiarySection {
|
||||
|
||||
pub struct DiaryState {
|
||||
ids: Ids,
|
||||
dragged_ability: Option<AuxiliaryAbility>,
|
||||
id_ability_map: HashMap<widget::Id, AuxiliaryAbility>,
|
||||
ability_page: usize,
|
||||
}
|
||||
|
||||
@ -373,9 +376,6 @@ impl<'a> Widget for Diary<'a> {
|
||||
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
|
||||
DiaryState {
|
||||
ids: Ids::new(id_gen),
|
||||
dragged_ability: None,
|
||||
// Constructed during update sequence
|
||||
id_ability_map: HashMap::new(),
|
||||
ability_page: 0,
|
||||
}
|
||||
}
|
||||
@ -387,10 +387,6 @@ impl<'a> Widget for Diary<'a> {
|
||||
let widget::UpdateArgs { state, ui, .. } = args;
|
||||
let mut events = Vec::new();
|
||||
|
||||
state.update(|s| {
|
||||
s.id_ability_map.clear();
|
||||
});
|
||||
|
||||
// Tooltips
|
||||
let diary_tooltip = Tooltip::new({
|
||||
// Edge images [t, b, r, l]
|
||||
@ -834,6 +830,7 @@ impl<'a> Widget for Diary<'a> {
|
||||
},
|
||||
DiarySection::AbilitySelection => {
|
||||
use comp::ability::AbilityInput;
|
||||
|
||||
// Background Art
|
||||
Image::new(self.imgs.book_bg)
|
||||
.w_h(299.0 * 4.0, 184.0 * 4.0)
|
||||
@ -852,22 +849,38 @@ impl<'a> Widget for Diary<'a> {
|
||||
.top_right_with_margins_on(state.ids.spellbook_art, 0.0, 0.0)
|
||||
.set(state.ids.sb_page_right_align, ui);
|
||||
|
||||
// Display all active abilities on right of window
|
||||
// Display all active abilities on bottom of window
|
||||
state.update(|s| {
|
||||
s.ids
|
||||
.active_abilities
|
||||
.resize(MAX_ABILITIES, &mut ui.widget_id_generator())
|
||||
});
|
||||
state.update(|s| {
|
||||
s.ids
|
||||
.active_abilities_bg
|
||||
.resize(MAX_ABILITIES, &mut ui.widget_id_generator())
|
||||
});
|
||||
state.update(|s| {
|
||||
s.ids
|
||||
.active_abilities_keys
|
||||
.resize(MAX_ABILITIES, &mut ui.widget_id_generator())
|
||||
});
|
||||
|
||||
let mut slot_maker = SlotMaker {
|
||||
empty_slot: self.imgs.inv_slot,
|
||||
filled_slot: self.imgs.inv_slot,
|
||||
selected_slot: self.imgs.inv_slot_sel,
|
||||
background_color: Some(UI_MAIN),
|
||||
content_size: ContentSize {
|
||||
width_height_ratio: 1.0,
|
||||
max_fraction: tweak!(0.9),
|
||||
},
|
||||
selected_content_scale: 1.067,
|
||||
amount_font: self.fonts.cyri.conrod_id,
|
||||
amount_margins: Vec2::new(-4.0, 0.0),
|
||||
amount_font_size: self.fonts.cyri.scale(12),
|
||||
amount_text_color: TEXT_COLOR,
|
||||
content_source: &(self.active_abilities, self.inventory, self.skill_set),
|
||||
image_source: self.imgs,
|
||||
slot_manager: Some(self.slot_manager),
|
||||
pulse: 0.0,
|
||||
};
|
||||
|
||||
for i in 0..MAX_ABILITIES {
|
||||
let ability_id = self
|
||||
.active_abilities
|
||||
@ -877,11 +890,15 @@ impl<'a> Widget for Diary<'a> {
|
||||
Some(self.skill_set),
|
||||
)
|
||||
.ability_id(Some(self.inventory));
|
||||
let (ability_title, ability_desc) =
|
||||
util::ability_description(ability_id.unwrap_or(""));
|
||||
|
||||
let image_size = tweak!(80.0);
|
||||
let image_offsets = tweak!(92.0) * i as f64;
|
||||
let mut ability_slot =
|
||||
Image::new(self.imgs.inv_slot).w_h(image_size, image_size);
|
||||
|
||||
let slot = AbilitySlot::Slot(i);
|
||||
let mut ability_slot = slot_maker.fabricate(slot, [image_size; 2]);
|
||||
|
||||
if i == 0 {
|
||||
ability_slot = ability_slot.top_left_with_margins_on(
|
||||
state.ids.spellbook_skills_bg,
|
||||
@ -889,17 +906,10 @@ impl<'a> Widget for Diary<'a> {
|
||||
tweak!(32.0) + image_offsets,
|
||||
);
|
||||
} else {
|
||||
ability_slot = ability_slot
|
||||
.right_from(state.ids.active_abilities_bg[i - 1], tweak!(4.0))
|
||||
ability_slot =
|
||||
ability_slot.right_from(state.ids.active_abilities[i - 1], 4.0)
|
||||
}
|
||||
ability_slot.set(state.ids.active_abilities_bg[i], ui);
|
||||
let ability_image = ability_id
|
||||
.map_or(self.imgs.nothing, |id| util::ability_image(self.imgs, id));
|
||||
let (ability_title, ability_desc) =
|
||||
util::ability_description(ability_id.unwrap_or(""));
|
||||
if Button::image(ability_image)
|
||||
.w_h(image_size * tweak!(0.9), image_size * tweak!(0.9))
|
||||
.middle_of(state.ids.active_abilities_bg[i])
|
||||
ability_slot
|
||||
.with_tooltip(
|
||||
self.tooltip_manager,
|
||||
ability_title,
|
||||
@ -907,18 +917,8 @@ impl<'a> Widget for Diary<'a> {
|
||||
&diary_tooltip,
|
||||
TEXT_COLOR,
|
||||
)
|
||||
.set(state.ids.active_abilities[i], ui)
|
||||
.was_clicked()
|
||||
{
|
||||
events.push(Event::ChangeAbility(
|
||||
i,
|
||||
self.show
|
||||
.diary_fields
|
||||
.selected_ability
|
||||
.unwrap_or(AuxiliaryAbility::Empty),
|
||||
));
|
||||
events.push(Event::SelectAbility(None));
|
||||
}
|
||||
.set(state.ids.active_abilities[i], ui);
|
||||
|
||||
// Display Slot Keybinding
|
||||
let keys = &self.global_state.settings.controls;
|
||||
let key_layout = &self.global_state.window.key_layout;
|
||||
@ -1090,6 +1090,26 @@ impl<'a> Widget for Diary<'a> {
|
||||
let ability_start = state.ability_page * ABILITIES_PER_PAGE;
|
||||
let abilities_range = ability_start..(ability_start + ABILITIES_PER_PAGE);
|
||||
|
||||
let mut slot_maker = SlotMaker {
|
||||
empty_slot: self.imgs.inv_slot,
|
||||
filled_slot: self.imgs.inv_slot,
|
||||
selected_slot: self.imgs.inv_slot_sel,
|
||||
background_color: Some(UI_MAIN),
|
||||
content_size: ContentSize {
|
||||
width_height_ratio: 1.0,
|
||||
max_fraction: tweak!(1.0),
|
||||
},
|
||||
selected_content_scale: tweak!(1.067),
|
||||
amount_font: self.fonts.cyri.conrod_id,
|
||||
amount_margins: Vec2::new(-4.0, 0.0),
|
||||
amount_font_size: self.fonts.cyri.scale(12),
|
||||
amount_text_color: TEXT_COLOR,
|
||||
content_source: &(self.active_abilities, self.inventory, self.skill_set),
|
||||
image_source: self.imgs,
|
||||
slot_manager: Some(self.slot_manager),
|
||||
pulse: 0.0,
|
||||
};
|
||||
|
||||
for (id_index, (ability_id, ability)) in abilities
|
||||
.iter()
|
||||
.enumerate()
|
||||
@ -1098,26 +1118,15 @@ impl<'a> Widget for Diary<'a> {
|
||||
})
|
||||
.enumerate()
|
||||
{
|
||||
let map_id = state.ids.abilities[id_index];
|
||||
state.update(|s| {
|
||||
s.id_ability_map.insert(map_id, *ability);
|
||||
});
|
||||
|
||||
let ability_image = ability_id
|
||||
.map_or(self.imgs.nothing, |id| util::ability_image(self.imgs, id));
|
||||
let ability_color = if self.show.diary_fields.selected_ability != Some(*ability)
|
||||
{
|
||||
TEXT_COLOR
|
||||
} else {
|
||||
XP_COLOR
|
||||
};
|
||||
let (ability_title, ability_desc) =
|
||||
util::ability_description(ability_id.unwrap_or(""));
|
||||
|
||||
let (align_state, image_offsets) = if id_index < 6 {
|
||||
(state.ids.sb_page_left_align, 120.0 * id_index as f64)
|
||||
} else {
|
||||
(state.ids.sb_page_right_align, 120.0 * (id_index - 6) as f64)
|
||||
};
|
||||
|
||||
Image::new(if same_weap_kinds {
|
||||
self.imgs.ability_frame_dual
|
||||
} else {
|
||||
@ -1132,37 +1141,22 @@ impl<'a> Widget for Diary<'a> {
|
||||
.color(Some(UI_HIGHLIGHT_0))
|
||||
//.parent(state.ids.abilities[id_index])
|
||||
.set(state.ids.ability_frames[id_index], ui);
|
||||
if Button::image(ability_image)
|
||||
.w_h(100.0, 100.0)
|
||||
|
||||
let slot = AbilitySlot::Ability(*ability);
|
||||
slot_maker
|
||||
.fabricate(slot, [100.0; 2])
|
||||
.top_left_with_margins_on(align_state, 20.0 + image_offsets, 20.0)
|
||||
.set(state.ids.abilities[id_index], ui)
|
||||
.was_clicked()
|
||||
{
|
||||
if Some(*ability) != self.show.diary_fields.selected_ability {
|
||||
events.push(Event::SelectAbility(Some(*ability)));
|
||||
} else {
|
||||
events.push(Event::SelectAbility(None));
|
||||
}
|
||||
}
|
||||
.set(state.ids.abilities[id_index], ui);
|
||||
|
||||
if same_weap_kinds {
|
||||
if let AuxiliaryAbility::MainWeapon(slot) = ability {
|
||||
let ability = AuxiliaryAbility::OffWeapon(*slot);
|
||||
let map_id = state.ids.abilities_dual[id_index];
|
||||
state.update(|s| {
|
||||
s.id_ability_map.insert(map_id, ability);
|
||||
});
|
||||
if Button::image(ability_image)
|
||||
.w_h(100.0, 100.0)
|
||||
|
||||
let slot = AbilitySlot::Ability(ability);
|
||||
slot_maker
|
||||
.fabricate(slot, [100.0; 2])
|
||||
.top_right_with_margins_on(align_state, 20.0 + image_offsets, 20.0)
|
||||
.set(state.ids.abilities_dual[id_index], ui)
|
||||
.was_clicked()
|
||||
{
|
||||
if Some(ability) != self.show.diary_fields.selected_ability {
|
||||
events.push(Event::SelectAbility(Some(ability)));
|
||||
} else {
|
||||
events.push(Event::SelectAbility(None));
|
||||
}
|
||||
}
|
||||
.set(state.ids.abilities_dual[id_index], ui);
|
||||
}
|
||||
}
|
||||
// The page width...
|
||||
@ -1180,7 +1174,7 @@ impl<'a> Widget for Diary<'a> {
|
||||
.top_left_with_margins_on(state.ids.abilities[id_index], 5.0, 110.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(tweak!(28)))
|
||||
.color(ability_color)
|
||||
.color(TEXT_COLOR)
|
||||
.w(text_width)
|
||||
.graphics_for(state.ids.abilities[id_index])
|
||||
.set(state.ids.ability_titles[id_index], ui);
|
||||
@ -1192,56 +1186,12 @@ impl<'a> Widget for Diary<'a> {
|
||||
)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(tweak!(18)))
|
||||
.color(ability_color)
|
||||
.color(TEXT_COLOR)
|
||||
.w(text_width)
|
||||
.graphics_for(state.ids.abilities[id_index])
|
||||
.set(state.ids.ability_descs[id_index], ui);
|
||||
}
|
||||
|
||||
let mouse_pos = ui.global_input().current.mouse.xy;
|
||||
// Handle dragging
|
||||
if let Some(ability) = state.dragged_ability {
|
||||
let ability_id = Ability::from(ability).ability_id(Some(self.inventory));
|
||||
if let Some(ability_id) = ability_id {
|
||||
Image::new(util::ability_image(self.imgs, ability_id))
|
||||
.w_h(80.0, 80.0)
|
||||
.xy(mouse_pos)
|
||||
.set(state.ids.dragged_ability, ui);
|
||||
}
|
||||
}
|
||||
let input = &ui.global_input().current;
|
||||
match input.mouse.buttons.left() {
|
||||
// If mouse button was pushed down over some id
|
||||
ButtonPosition::Down(_, Some(id)) => {
|
||||
if state.dragged_ability.is_none() {
|
||||
if let Some(ability) = state.id_ability_map.get(id).copied() {
|
||||
state.update(|s| {
|
||||
s.dragged_ability = Some(ability);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
ButtonPosition::Up => {
|
||||
if let (Some(ability), Some(id)) =
|
||||
(state.dragged_ability, input.widget_under_mouse)
|
||||
{
|
||||
if let Some(index) = state
|
||||
.ids
|
||||
.active_abilities
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(i, slot_id)| (id == *slot_id).then_some(i))
|
||||
{
|
||||
events.push(Event::ChangeAbility(index, ability));
|
||||
}
|
||||
}
|
||||
state.update(|s| {
|
||||
s.dragged_ability = None;
|
||||
});
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
events
|
||||
},
|
||||
DiarySection::Stats => {
|
||||
|
@ -74,7 +74,9 @@ use client::Client;
|
||||
use common::{
|
||||
combat,
|
||||
comp::{
|
||||
self, fluid_dynamics,
|
||||
self,
|
||||
ability::AuxiliaryAbility,
|
||||
fluid_dynamics,
|
||||
inventory::{slot::InvSlotId, trade_pricing::TradePricing},
|
||||
item::{tool::ToolKind, ItemDesc, MaterialStatManifest, Quality},
|
||||
skillset::{skills::Skill, SkillGroupKind},
|
||||
@ -535,7 +537,7 @@ pub enum Event {
|
||||
RemoveBuff(BuffKind),
|
||||
UnlockSkill(Skill),
|
||||
RequestSiteInfo(SiteId),
|
||||
ChangeAbility(usize, comp::ability::AuxiliaryAbility),
|
||||
ChangeAbility(usize, AuxiliaryAbility),
|
||||
|
||||
SettingsChange(SettingsChange),
|
||||
AcknowledgePersistenceLoadError,
|
||||
@ -3132,6 +3134,7 @@ impl Hud {
|
||||
i18n,
|
||||
&self.rot_imgs,
|
||||
tooltip_manager,
|
||||
&mut self.slot_manager,
|
||||
self.pulse,
|
||||
)
|
||||
.set(self.ids.diary, ui_widgets)
|
||||
@ -3149,12 +3152,6 @@ impl Hud {
|
||||
diary::Event::ChangeSection(section) => {
|
||||
self.show.diary_fields.section = section;
|
||||
},
|
||||
diary::Event::SelectAbility(ability) => {
|
||||
self.show.diary_fields.selected_ability = ability;
|
||||
},
|
||||
diary::Event::ChangeAbility(slot, new_ability) => {
|
||||
events.push(Event::ChangeAbility(slot, new_ability))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3311,7 +3308,7 @@ impl Hud {
|
||||
// Maintain slot manager
|
||||
'slot_events: for event in self.slot_manager.maintain(ui_widgets) {
|
||||
use comp::slot::Slot;
|
||||
use slots::{InventorySlot, SlotKind::*};
|
||||
use slots::{AbilitySlot, InventorySlot, SlotKind::*};
|
||||
let to_slot = |slot_kind| match slot_kind {
|
||||
Inventory(InventorySlot {
|
||||
slot, ours: true, ..
|
||||
@ -3320,6 +3317,7 @@ impl Hud {
|
||||
Equip(e) => Some(Slot::Equip(e)),
|
||||
Hotbar(_) => None,
|
||||
Trade(_) => None,
|
||||
Ability(_) => None,
|
||||
};
|
||||
match event {
|
||||
slot::Event::Dragged(a, b) => {
|
||||
@ -3369,6 +3367,33 @@ impl Hud {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let (Ability(a), Ability(b)) = (a, b) {
|
||||
match (a, b) {
|
||||
(AbilitySlot::Ability(ability), AbilitySlot::Slot(index)) => {
|
||||
events.push(Event::ChangeAbility(index, ability));
|
||||
},
|
||||
(AbilitySlot::Slot(a), AbilitySlot::Slot(b)) => {
|
||||
let me = client.entity();
|
||||
if let Some(active_abilities) = active_abilities.get(me) {
|
||||
let ability_a = active_abilities
|
||||
.auxiliary_set(inventories.get(me), skill_sets.get(me))
|
||||
.get(a)
|
||||
.copied()
|
||||
.unwrap_or(AuxiliaryAbility::Empty);
|
||||
let ability_b = active_abilities
|
||||
.auxiliary_set(inventories.get(me), skill_sets.get(me))
|
||||
.get(b)
|
||||
.copied()
|
||||
.unwrap_or(AuxiliaryAbility::Empty);
|
||||
events.push(Event::ChangeAbility(a, ability_b));
|
||||
events.push(Event::ChangeAbility(b, ability_a));
|
||||
}
|
||||
},
|
||||
(AbilitySlot::Slot(index), _) => {
|
||||
events.push(Event::ChangeAbility(index, AuxiliaryAbility::Empty));
|
||||
},
|
||||
(_, _) => {},
|
||||
}
|
||||
}
|
||||
},
|
||||
slot::Event::Dropped(from) => {
|
||||
@ -3388,6 +3413,8 @@ impl Hud {
|
||||
}));
|
||||
}
|
||||
}
|
||||
} else if let Ability(AbilitySlot::Slot(index)) = from {
|
||||
events.push(Event::ChangeAbility(index, AuxiliaryAbility::Empty));
|
||||
}
|
||||
},
|
||||
slot::Event::SplitDropped(from) => {
|
||||
@ -3397,6 +3424,8 @@ impl Hud {
|
||||
} else if let Hotbar(h) = from {
|
||||
self.hotbar.clear_slot(h);
|
||||
events.push(Event::ChangeHotbarState(Box::new(self.hotbar.to_owned())));
|
||||
} else if let Ability(AbilitySlot::Slot(index)) = from {
|
||||
events.push(Event::ChangeAbility(index, AuxiliaryAbility::Empty));
|
||||
}
|
||||
},
|
||||
slot::Event::SplitDragged(a, b) => {
|
||||
@ -3440,6 +3469,33 @@ impl Hud {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let (Ability(a), Ability(b)) = (a, b) {
|
||||
match (a, b) {
|
||||
(AbilitySlot::Ability(ability), AbilitySlot::Slot(index)) => {
|
||||
events.push(Event::ChangeAbility(index, ability));
|
||||
},
|
||||
(AbilitySlot::Slot(a), AbilitySlot::Slot(b)) => {
|
||||
let me = client.entity();
|
||||
if let Some(active_abilities) = active_abilities.get(me) {
|
||||
let ability_a = active_abilities
|
||||
.auxiliary_set(inventories.get(me), skill_sets.get(me))
|
||||
.get(a)
|
||||
.copied()
|
||||
.unwrap_or(AuxiliaryAbility::Empty);
|
||||
let ability_b = active_abilities
|
||||
.auxiliary_set(inventories.get(me), skill_sets.get(me))
|
||||
.get(b)
|
||||
.copied()
|
||||
.unwrap_or(AuxiliaryAbility::Empty);
|
||||
events.push(Event::ChangeAbility(a, ability_b));
|
||||
events.push(Event::ChangeAbility(b, ability_a));
|
||||
}
|
||||
},
|
||||
(AbilitySlot::Slot(index), _) => {
|
||||
events.push(Event::ChangeAbility(index, AuxiliaryAbility::Empty));
|
||||
},
|
||||
(_, _) => {},
|
||||
}
|
||||
}
|
||||
},
|
||||
slot::Event::Used(from) => {
|
||||
@ -3475,6 +3531,8 @@ impl Hud {
|
||||
},
|
||||
hotbar::SlotContents::Ability(_) => {},
|
||||
});
|
||||
} else if let Ability(AbilitySlot::Slot(index)) = from {
|
||||
events.push(Event::ChangeAbility(index, AuxiliaryAbility::Empty));
|
||||
}
|
||||
},
|
||||
slot::Event::Request {
|
||||
|
@ -6,8 +6,9 @@ use super::{
|
||||
};
|
||||
use crate::ui::slot::{self, SlotKey, SumSlot};
|
||||
use common::comp::{
|
||||
ability::AbilityInput, slot::InvSlotId, Ability, ActiveAbilities, Body, Energy, Inventory,
|
||||
SkillSet,
|
||||
ability::{Ability, AbilityInput, AuxiliaryAbility},
|
||||
slot::InvSlotId,
|
||||
ActiveAbilities, Body, Energy, Inventory, SkillSet,
|
||||
};
|
||||
use conrod_core::{image, Color};
|
||||
use specs::Entity as EcsEntity;
|
||||
@ -20,6 +21,7 @@ pub enum SlotKind {
|
||||
Equip(EquipSlot),
|
||||
Hotbar(HotbarSlot),
|
||||
Trade(TradeSlot),
|
||||
Ability(AbilitySlot),
|
||||
/* Spellbook(SpellbookSlot), TODO */
|
||||
}
|
||||
|
||||
@ -192,6 +194,42 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum AbilitySlot {
|
||||
Slot(usize),
|
||||
Ability(AuxiliaryAbility),
|
||||
}
|
||||
|
||||
type AbilitiesSource<'a> = (&'a ActiveAbilities, &'a Inventory, &'a SkillSet);
|
||||
|
||||
impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
|
||||
type ImageKey = String;
|
||||
|
||||
fn image_key(
|
||||
&self,
|
||||
(active_abilities, inventory, skillset): &AbilitiesSource<'a>,
|
||||
) -> Option<(Self::ImageKey, Option<Color>)> {
|
||||
let ability_id = match self {
|
||||
Self::Slot(index) => active_abilities
|
||||
.get_ability(
|
||||
AbilityInput::Auxiliary(*index),
|
||||
Some(inventory),
|
||||
Some(skillset),
|
||||
)
|
||||
.ability_id(Some(inventory)),
|
||||
Self::Ability(ability) => Ability::from(*ability).ability_id(Some(inventory)),
|
||||
};
|
||||
|
||||
ability_id.map(|id| (String::from(id), None))
|
||||
}
|
||||
|
||||
fn amount(&self, _source: &AbilitiesSource) -> Option<u32> { None }
|
||||
|
||||
fn image_ids(ability_id: &Self::ImageKey, imgs: &img_ids::Imgs) -> Vec<image::Id> {
|
||||
vec![util::ability_image(imgs, ability_id)]
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InventorySlot> for SlotKind {
|
||||
fn from(inventory: InventorySlot) -> Self { Self::Inventory(inventory) }
|
||||
}
|
||||
@ -207,4 +245,10 @@ impl From<TradeSlot> for SlotKind {
|
||||
fn from(trade: TradeSlot) -> Self { Self::Trade(trade) }
|
||||
}
|
||||
|
||||
impl SumSlot for SlotKind {}
|
||||
impl From<AbilitySlot> for SlotKind {
|
||||
fn from(ability: AbilitySlot) -> Self { Self::Ability(ability) }
|
||||
}
|
||||
|
||||
impl SumSlot for SlotKind {
|
||||
fn is_ability(&self) -> bool { matches!(self, Self::Ability(_)) }
|
||||
}
|
||||
|
@ -19,7 +19,9 @@ pub trait SlotKey<C, I>: Copy {
|
||||
fn image_ids(key: &Self::ImageKey, source: &I) -> Vec<image::Id>;
|
||||
}
|
||||
|
||||
pub trait SumSlot: Sized + PartialEq + Copy + Send + 'static {}
|
||||
pub trait SumSlot: Sized + PartialEq + Copy + Send + 'static {
|
||||
fn is_ability(&self) -> bool;
|
||||
}
|
||||
|
||||
pub struct ContentSize {
|
||||
// Width divided by height
|
||||
@ -217,6 +219,12 @@ where
|
||||
let content_img = *content_img;
|
||||
let drag_amount = *drag_amount;
|
||||
|
||||
let dragged_size = if slot.is_ability() {
|
||||
[inline_tweak::tweak!(80.0); 2]
|
||||
} else {
|
||||
self.drag_img_size.map(|e| e as f64).into_array()
|
||||
};
|
||||
|
||||
// If we are dragging and we right click, drop half the stack
|
||||
// on the ground or into the slot under the cursor. This only
|
||||
// works with open slots or slots containing the same kind of
|
||||
@ -260,9 +268,8 @@ where
|
||||
|
||||
// Draw image of contents being dragged
|
||||
let [mouse_x, mouse_y] = input.mouse.xy;
|
||||
let size = self.drag_img_size.map(|e| e as f64).into_array();
|
||||
super::ghost_image::GhostImage::new(content_img)
|
||||
.wh(size)
|
||||
.wh(dragged_size)
|
||||
.xy([mouse_x, mouse_y])
|
||||
.set(self.drag_id, ui);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user