2020-04-11 06:33:06 +00:00
|
|
|
use super::{
|
|
|
|
hotbar::{self, Slot as HotbarSlot},
|
|
|
|
img_ids,
|
|
|
|
item_imgs::{ItemImgs, ItemKey},
|
|
|
|
};
|
2020-04-06 15:25:45 +00:00
|
|
|
use crate::ui::slot::{self, SlotKey, SumSlot};
|
2020-05-29 18:23:00 +00:00
|
|
|
use common::comp::{
|
|
|
|
item::{
|
2021-02-13 00:43:33 +00:00
|
|
|
tool::{AbilityMap, Hands, ToolKind},
|
2021-02-25 19:04:09 +00:00
|
|
|
ItemKind, MaterialStatManifest,
|
2020-05-29 18:23:00 +00:00
|
|
|
},
|
2021-01-08 19:12:09 +00:00
|
|
|
slot::InvSlotId,
|
|
|
|
Energy, Inventory,
|
2020-05-29 18:23:00 +00:00
|
|
|
};
|
2020-04-11 06:33:06 +00:00
|
|
|
use conrod_core::{image, Color};
|
2021-02-28 02:44:57 +00:00
|
|
|
use specs::Entity as EcsEntity;
|
2020-04-04 05:40:00 +00:00
|
|
|
|
2020-04-10 02:36:35 +00:00
|
|
|
pub use common::comp::slot::{ArmorSlot, EquipSlot};
|
|
|
|
|
2021-01-08 19:12:09 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
2020-04-06 15:25:45 +00:00
|
|
|
pub enum SlotKind {
|
2020-04-04 05:40:00 +00:00
|
|
|
Inventory(InventorySlot),
|
2020-04-10 02:36:35 +00:00
|
|
|
Equip(EquipSlot),
|
2020-04-11 06:33:06 +00:00
|
|
|
Hotbar(HotbarSlot),
|
2021-02-12 02:53:25 +00:00
|
|
|
Trade(TradeSlot),
|
2020-04-11 06:33:06 +00:00
|
|
|
/* Spellbook(SpellbookSlot), TODO */
|
2020-04-04 05:40:00 +00:00
|
|
|
}
|
|
|
|
|
2020-04-06 15:25:45 +00:00
|
|
|
pub type SlotManager = slot::SlotManager<SlotKind>;
|
2020-04-04 05:40:00 +00:00
|
|
|
|
2021-01-08 19:12:09 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
2021-02-28 02:44:57 +00:00
|
|
|
pub struct InventorySlot {
|
|
|
|
pub slot: InvSlotId,
|
2021-03-30 22:37:38 +00:00
|
|
|
pub entity: EcsEntity,
|
2021-02-28 02:44:57 +00:00
|
|
|
pub ours: bool,
|
|
|
|
}
|
2020-04-04 05:40:00 +00:00
|
|
|
|
2020-04-06 15:25:45 +00:00
|
|
|
impl SlotKey<Inventory, ItemImgs> for InventorySlot {
|
2020-04-04 05:40:00 +00:00
|
|
|
type ImageKey = ItemKey;
|
|
|
|
|
2020-04-11 06:33:06 +00:00
|
|
|
fn image_key(&self, source: &Inventory) -> Option<(Self::ImageKey, Option<Color>)> {
|
2021-02-28 02:44:57 +00:00
|
|
|
source.get(self.slot).map(|i| (i.into(), None))
|
2020-04-04 05:40:00 +00:00
|
|
|
}
|
|
|
|
|
2020-04-06 15:25:45 +00:00
|
|
|
fn amount(&self, source: &Inventory) -> Option<u32> {
|
2020-04-04 05:40:00 +00:00
|
|
|
source
|
2021-02-28 02:44:57 +00:00
|
|
|
.get(self.slot)
|
2020-09-17 23:02:14 +00:00
|
|
|
.map(|item| item.amount())
|
2020-04-04 05:40:00 +00:00
|
|
|
.filter(|amount| *amount > 1)
|
|
|
|
}
|
|
|
|
|
2021-02-16 01:05:54 +00:00
|
|
|
fn image_ids(key: &Self::ImageKey, source: &ItemImgs) -> Vec<image::Id> {
|
|
|
|
source.img_ids_or_not_found_img(key.clone())
|
2020-04-04 05:40:00 +00:00
|
|
|
}
|
2020-04-04 17:51:41 +00:00
|
|
|
}
|
|
|
|
|
2021-01-08 19:12:09 +00:00
|
|
|
impl SlotKey<Inventory, ItemImgs> for EquipSlot {
|
2020-04-04 17:51:41 +00:00
|
|
|
type ImageKey = ItemKey;
|
|
|
|
|
2021-01-08 19:12:09 +00:00
|
|
|
fn image_key(&self, source: &Inventory) -> Option<(Self::ImageKey, Option<Color>)> {
|
|
|
|
let item = source.equipped(*self);
|
2020-11-07 20:52:40 +00:00
|
|
|
item.map(|i| (i.into(), None))
|
2020-04-04 17:51:41 +00:00
|
|
|
}
|
|
|
|
|
2021-01-08 19:12:09 +00:00
|
|
|
fn amount(&self, _: &Inventory) -> Option<u32> { None }
|
2020-04-04 17:51:41 +00:00
|
|
|
|
2021-02-16 01:05:54 +00:00
|
|
|
fn image_ids(key: &Self::ImageKey, source: &ItemImgs) -> Vec<image::Id> {
|
|
|
|
source.img_ids_or_not_found_img(key.clone())
|
2020-04-04 17:51:41 +00:00
|
|
|
}
|
2020-04-04 05:40:00 +00:00
|
|
|
}
|
|
|
|
|
2021-02-12 02:53:25 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
|
|
pub struct TradeSlot {
|
|
|
|
pub index: usize,
|
|
|
|
pub quantity: u32,
|
|
|
|
pub invslot: Option<InvSlotId>,
|
2021-02-28 02:44:57 +00:00
|
|
|
pub entity: EcsEntity,
|
|
|
|
pub ours: bool,
|
2021-02-12 02:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl SlotKey<Inventory, ItemImgs> for TradeSlot {
|
|
|
|
type ImageKey = ItemKey;
|
|
|
|
|
|
|
|
fn image_key(&self, source: &Inventory) -> Option<(Self::ImageKey, Option<Color>)> {
|
2021-02-28 02:44:57 +00:00
|
|
|
self.invslot.and_then(|inv_id| {
|
|
|
|
InventorySlot {
|
|
|
|
slot: inv_id,
|
|
|
|
ours: self.ours,
|
2021-03-30 22:37:38 +00:00
|
|
|
entity: self.entity,
|
2021-02-28 02:44:57 +00:00
|
|
|
}
|
|
|
|
.image_key(source)
|
|
|
|
})
|
2021-02-12 02:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn amount(&self, source: &Inventory) -> Option<u32> {
|
|
|
|
self.invslot
|
2021-02-28 02:44:57 +00:00
|
|
|
.and_then(|inv_id| {
|
|
|
|
InventorySlot {
|
|
|
|
slot: inv_id,
|
|
|
|
ours: self.ours,
|
2021-03-30 22:37:38 +00:00
|
|
|
entity: self.entity,
|
2021-02-28 02:44:57 +00:00
|
|
|
}
|
|
|
|
.amount(source)
|
|
|
|
})
|
2021-02-12 02:53:25 +00:00
|
|
|
.map(|x| x.min(self.quantity))
|
|
|
|
}
|
|
|
|
|
2021-02-16 01:05:54 +00:00
|
|
|
fn image_ids(key: &Self::ImageKey, source: &ItemImgs) -> Vec<image::Id> {
|
|
|
|
source.img_ids_or_not_found_img(key.clone())
|
2021-02-12 02:53:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-11 06:33:06 +00:00
|
|
|
#[derive(Clone, PartialEq)]
|
|
|
|
pub enum HotbarImage {
|
|
|
|
Item(ItemKey),
|
2020-10-08 20:54:12 +00:00
|
|
|
FireAoe,
|
2020-05-29 18:23:00 +00:00
|
|
|
SnakeArrow,
|
2020-09-21 02:18:45 +00:00
|
|
|
SwordWhirlwind,
|
2020-09-21 20:45:50 +00:00
|
|
|
HammerLeap,
|
|
|
|
AxeLeapSlash,
|
|
|
|
BowJumpBurst,
|
2021-03-05 10:12:44 +00:00
|
|
|
SceptreAura,
|
2020-04-11 06:33:06 +00:00
|
|
|
}
|
2020-04-06 15:25:45 +00:00
|
|
|
|
2021-02-25 19:04:09 +00:00
|
|
|
type HotbarSource<'a> = (
|
|
|
|
&'a hotbar::State,
|
|
|
|
&'a Inventory,
|
|
|
|
&'a Energy,
|
|
|
|
&'a AbilityMap,
|
|
|
|
&'a MaterialStatManifest,
|
|
|
|
);
|
2020-04-11 06:33:06 +00:00
|
|
|
type HotbarImageSource<'a> = (&'a ItemImgs, &'a img_ids::Imgs);
|
|
|
|
|
|
|
|
impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
|
|
|
type ImageKey = HotbarImage;
|
|
|
|
|
|
|
|
fn image_key(
|
|
|
|
&self,
|
2021-02-25 19:04:09 +00:00
|
|
|
(hotbar, inventory, energy, ability_map, msm): &HotbarSource<'a>,
|
2020-04-11 06:33:06 +00:00
|
|
|
) -> Option<(Self::ImageKey, Option<Color>)> {
|
|
|
|
hotbar.get(*self).and_then(|contents| match contents {
|
|
|
|
hotbar::SlotContents::Inventory(idx) => inventory
|
|
|
|
.get(idx)
|
2020-11-07 20:52:40 +00:00
|
|
|
.map(|item| HotbarImage::Item(item.into()))
|
2020-04-11 06:33:06 +00:00
|
|
|
.map(|i| (i, None)),
|
2020-11-27 16:27:09 +00:00
|
|
|
hotbar::SlotContents::Ability3 => {
|
2021-03-24 02:04:21 +00:00
|
|
|
let hands = |equip_slot| match inventory.equipped(equip_slot).map(|i| i.kind()) {
|
|
|
|
Some(ItemKind::Tool(tool)) => Some(tool.hands),
|
2020-11-27 16:27:09 +00:00
|
|
|
_ => None,
|
|
|
|
};
|
|
|
|
|
2021-03-24 02:04:21 +00:00
|
|
|
let active_tool_hands = hands(EquipSlot::Mainhand);
|
|
|
|
let second_tool_hands = hands(EquipSlot::Offhand);
|
|
|
|
|
|
|
|
let equip_slot = match (active_tool_hands, second_tool_hands) {
|
|
|
|
(Some(_), _) => Some(EquipSlot::Mainhand),
|
|
|
|
(None, Some(_)) => Some(EquipSlot::Offhand),
|
|
|
|
(_, _) => None,
|
|
|
|
};
|
|
|
|
|
2021-03-24 04:54:25 +00:00
|
|
|
let tool =
|
|
|
|
equip_slot.and_then(|es| match inventory.equipped(es).map(|i| (i, i.kind())) {
|
2021-03-24 02:04:21 +00:00
|
|
|
Some((item, ItemKind::Tool(tool))) => Some((item, tool)),
|
|
|
|
_ => None,
|
2021-03-24 04:54:25 +00:00
|
|
|
});
|
2021-03-24 02:04:21 +00:00
|
|
|
|
2021-02-17 04:23:08 +00:00
|
|
|
tool.and_then(|(item, tool)| {
|
2021-02-13 00:43:33 +00:00
|
|
|
hotbar_image(tool.kind).map(|i| {
|
2020-11-27 16:27:09 +00:00
|
|
|
(
|
|
|
|
i,
|
2021-02-17 04:23:08 +00:00
|
|
|
if let Some(skill) = tool
|
2021-02-25 19:04:09 +00:00
|
|
|
.get_abilities(&msm, item.components(), ability_map)
|
2021-02-17 04:23:08 +00:00
|
|
|
.abilities
|
|
|
|
.get(0)
|
|
|
|
{
|
2021-02-12 20:32:08 +00:00
|
|
|
if energy.current() >= skill.1.get_energy_cost() {
|
2020-11-27 16:27:09 +00:00
|
|
|
Some(Color::Rgba(1.0, 1.0, 1.0, 1.0))
|
|
|
|
} else {
|
|
|
|
Some(Color::Rgba(0.3, 0.3, 0.3, 0.8))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Some(Color::Rgba(1.0, 1.0, 1.0, 1.0))
|
|
|
|
},
|
|
|
|
)
|
2020-05-29 18:23:00 +00:00
|
|
|
})
|
2020-11-27 16:27:09 +00:00
|
|
|
})
|
|
|
|
},
|
2021-02-13 00:43:33 +00:00
|
|
|
hotbar::SlotContents::Ability4 => {
|
2021-02-19 23:45:48 +00:00
|
|
|
let hands = |equip_slot| match inventory.equipped(equip_slot).map(|i| i.kind()) {
|
|
|
|
Some(ItemKind::Tool(tool)) => Some(tool.hands),
|
|
|
|
_ => None,
|
|
|
|
};
|
|
|
|
|
|
|
|
let active_tool_hands = hands(EquipSlot::Mainhand);
|
|
|
|
let second_tool_hands = hands(EquipSlot::Offhand);
|
2021-02-13 00:43:33 +00:00
|
|
|
|
|
|
|
let (equip_slot, skill_index) = match (active_tool_hands, second_tool_hands) {
|
2021-02-19 23:45:48 +00:00
|
|
|
(Some(Hands::Two), _) => (Some(EquipSlot::Mainhand), 1),
|
2021-03-24 02:04:21 +00:00
|
|
|
(Some(_), Some(Hands::One)) => (Some(EquipSlot::Offhand), 0),
|
2021-02-19 23:45:48 +00:00
|
|
|
(Some(Hands::One), _) => (Some(EquipSlot::Mainhand), 1),
|
2021-03-24 02:04:21 +00:00
|
|
|
(None, Some(_)) => (Some(EquipSlot::Offhand), 1),
|
2021-02-13 00:43:33 +00:00
|
|
|
(_, _) => (None, 0),
|
|
|
|
};
|
|
|
|
|
2021-02-17 04:23:08 +00:00
|
|
|
let tool =
|
|
|
|
match equip_slot.and_then(|es| inventory.equipped(es).map(|i| (i, i.kind()))) {
|
|
|
|
Some((item, ItemKind::Tool(tool))) => Some((item, tool)),
|
|
|
|
_ => None,
|
|
|
|
};
|
2021-02-13 00:43:33 +00:00
|
|
|
|
2021-02-17 04:23:08 +00:00
|
|
|
tool.and_then(|(item, tool)| {
|
2021-02-13 00:43:33 +00:00
|
|
|
hotbar_image(tool.kind).map(|i| {
|
|
|
|
(
|
|
|
|
i,
|
2021-02-17 04:23:08 +00:00
|
|
|
if let Some(skill) = tool
|
2021-02-25 19:04:09 +00:00
|
|
|
.get_abilities(&msm, item.components(), ability_map)
|
2021-02-17 04:23:08 +00:00
|
|
|
.abilities
|
|
|
|
.get(skill_index)
|
2021-02-13 00:43:33 +00:00
|
|
|
{
|
|
|
|
if energy.current() >= skill.1.get_energy_cost() {
|
|
|
|
Some(Color::Rgba(1.0, 1.0, 1.0, 1.0))
|
|
|
|
} else {
|
|
|
|
Some(Color::Rgba(0.3, 0.3, 0.3, 0.8))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Some(Color::Rgba(1.0, 1.0, 1.0, 1.0))
|
|
|
|
},
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
},
|
2020-04-11 06:33:06 +00:00
|
|
|
})
|
2020-04-06 15:25:45 +00:00
|
|
|
}
|
|
|
|
|
2021-02-25 19:04:09 +00:00
|
|
|
fn amount(&self, (hotbar, inventory, _, _, _): &HotbarSource<'a>) -> Option<u32> {
|
2020-04-11 06:33:06 +00:00
|
|
|
hotbar
|
|
|
|
.get(*self)
|
|
|
|
.and_then(|content| match content {
|
|
|
|
hotbar::SlotContents::Inventory(idx) => inventory.get(idx),
|
|
|
|
hotbar::SlotContents::Ability3 => None,
|
2021-02-13 00:43:33 +00:00
|
|
|
hotbar::SlotContents::Ability4 => None,
|
2020-04-11 06:33:06 +00:00
|
|
|
})
|
2020-09-17 23:02:14 +00:00
|
|
|
.map(|item| item.amount())
|
2020-04-06 15:25:45 +00:00
|
|
|
.filter(|amount| *amount > 1)
|
|
|
|
}
|
|
|
|
|
2021-02-16 01:05:54 +00:00
|
|
|
fn image_ids(
|
|
|
|
key: &Self::ImageKey,
|
|
|
|
(item_imgs, imgs): &HotbarImageSource<'a>,
|
|
|
|
) -> Vec<image::Id> {
|
2020-04-11 06:33:06 +00:00
|
|
|
match key {
|
2021-02-16 01:05:54 +00:00
|
|
|
HotbarImage::Item(key) => item_imgs.img_ids_or_not_found_img(key.clone()),
|
|
|
|
HotbarImage::SnakeArrow => vec![imgs.snake_arrow_0],
|
|
|
|
HotbarImage::FireAoe => vec![imgs.fire_aoe],
|
|
|
|
HotbarImage::SwordWhirlwind => vec![imgs.sword_whirlwind],
|
|
|
|
HotbarImage::HammerLeap => vec![imgs.hammerleap],
|
|
|
|
HotbarImage::AxeLeapSlash => vec![imgs.skill_axe_leap_slash],
|
|
|
|
HotbarImage::BowJumpBurst => vec![imgs.skill_bow_jump_burst],
|
2021-03-05 10:12:44 +00:00
|
|
|
HotbarImage::SceptreAura => vec![imgs.skill_sceptre_aura],
|
2020-04-11 06:33:06 +00:00
|
|
|
}
|
2020-04-06 15:25:45 +00:00
|
|
|
}
|
2020-04-11 06:33:06 +00:00
|
|
|
}
|
2020-04-06 15:25:45 +00:00
|
|
|
|
|
|
|
impl From<InventorySlot> for SlotKind {
|
2020-04-04 05:40:00 +00:00
|
|
|
fn from(inventory: InventorySlot) -> Self { Self::Inventory(inventory) }
|
|
|
|
}
|
|
|
|
|
2020-04-10 02:36:35 +00:00
|
|
|
impl From<EquipSlot> for SlotKind {
|
|
|
|
fn from(equip: EquipSlot) -> Self { Self::Equip(equip) }
|
2020-04-04 05:40:00 +00:00
|
|
|
}
|
|
|
|
|
2020-04-11 06:33:06 +00:00
|
|
|
impl From<HotbarSlot> for SlotKind {
|
|
|
|
fn from(hotbar: HotbarSlot) -> Self { Self::Hotbar(hotbar) }
|
|
|
|
}
|
2021-02-12 02:53:25 +00:00
|
|
|
impl From<TradeSlot> for SlotKind {
|
|
|
|
fn from(trade: TradeSlot) -> Self { Self::Trade(trade) }
|
|
|
|
}
|
2020-04-04 05:40:00 +00:00
|
|
|
|
2020-04-06 15:25:45 +00:00
|
|
|
impl SumSlot for SlotKind {}
|
2021-02-13 00:43:33 +00:00
|
|
|
|
|
|
|
fn hotbar_image(tool: ToolKind) -> Option<HotbarImage> {
|
|
|
|
match tool {
|
|
|
|
ToolKind::Staff => Some(HotbarImage::FireAoe),
|
|
|
|
ToolKind::Hammer => Some(HotbarImage::HammerLeap),
|
|
|
|
ToolKind::Axe => Some(HotbarImage::AxeLeapSlash),
|
|
|
|
ToolKind::Bow => Some(HotbarImage::BowJumpBurst),
|
|
|
|
ToolKind::Debug => Some(HotbarImage::SnakeArrow),
|
|
|
|
ToolKind::Sword => Some(HotbarImage::SwordWhirlwind),
|
2021-03-05 10:12:44 +00:00
|
|
|
ToolKind::Sceptre => Some(HotbarImage::SceptreAura),
|
2021-02-13 00:43:33 +00:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|