Overflow slots displayed in bag

This commit is contained in:
Sam 2023-08-18 14:51:03 -04:00
parent d01997ca56
commit 632e922db6
4 changed files with 108 additions and 58 deletions

View File

@ -469,6 +469,20 @@ impl Inventory {
self.slot(inv_slot_id).and_then(Option::as_ref)
}
/// Get content of an overflow slot
pub fn get_overflow(&self, overflow: usize) -> Option<&Item> {
self.overflow_items.get(overflow)
}
/// Get content of any kind of slot
pub fn get_slot(&self, slot: Slot) -> Option<&Item> {
match slot {
Slot::Inventory(inv_slot) => self.get(inv_slot),
Slot::Equip(equip) => self.equipped(equip),
Slot::Overflow(overflow) => self.get_overflow(overflow),
}
}
/// Get item from inventory
pub fn get_by_hash(&self, item_hash: u64) -> Option<&Item> {
self.slots().flatten().find(|i| i.item_hash() == item_hash)

View File

@ -20,7 +20,7 @@ use common::{
assets::AssetExt,
combat::{combat_rating, perception_dist_multiplier_from_stealth, Damage},
comp::{
inventory::InventorySortOrder,
inventory::{slot::Slot, InventorySortOrder},
item::{ItemDef, ItemDesc, ItemI18n, MaterialStatManifest, Quality},
Body, Energy, Health, Inventory, Poise, SkillSet, Stats,
},
@ -308,9 +308,10 @@ impl<'a> InventoryScroller<'a> {
// Create available inventory slot widgets
if state.ids.inv_slots.len() < self.inventory.capacity() {
state.update(|s| {
s.ids
.inv_slots
.resize(self.inventory.capacity(), &mut ui.widget_id_generator());
s.ids.inv_slots.resize(
self.inventory.capacity() + self.inventory.overflow_items().count(),
&mut ui.widget_id_generator(),
);
});
}
if state.ids.inv_slot_names.len() < self.inventory.capacity() {
@ -363,7 +364,17 @@ impl<'a> InventoryScroller<'a> {
};
let mut i = 0;
let mut items = self.inventory.slots_with_id().collect::<Vec<_>>();
let mut items = self
.inventory
.slots_with_id()
.map(|(slot, item)| (Slot::Inventory(slot), item.as_ref()))
.chain(
self.inventory
.overflow_items()
.enumerate()
.map(|(i, item)| (Slot::Overflow(i), Some(item))),
)
.collect::<Vec<_>>();
if self.details_mode && !self.is_us {
items.sort_by_cached_key(|(_, item)| {
(

View File

@ -3887,9 +3887,18 @@ impl Hud {
'slot_events: for event in self.slot_manager.maintain(ui_widgets) {
use slots::{AbilitySlot, InventorySlot, SlotKind::*};
let to_slot = |slot_kind| match slot_kind {
Inventory(
i @ InventorySlot {
slot: Slot::Inventory(_) | Slot::Overflow(_),
ours: true,
..
},
) => Some(i.slot),
Inventory(InventorySlot {
slot, ours: true, ..
}) => Some(Slot::Inventory(slot)),
slot: Slot::Equip(_),
ours: true,
..
}) => None,
Inventory(InventorySlot { ours: false, .. }) => None,
Equip(e) => Some(Slot::Equip(e)),
Hotbar(_) => None,
@ -3913,21 +3922,27 @@ impl Hud {
Hotbar(h),
) = (a, b)
{
if let Some(item) = inventories
.get(info.viewpoint_entity)
.and_then(|inv| inv.get(slot))
{
self.hotbar.add_inventory_link(h, item);
events.push(Event::ChangeHotbarState(Box::new(self.hotbar.to_owned())));
if let Slot::Inventory(slot) = slot {
if let Some(item) = inventories
.get(info.viewpoint_entity)
.and_then(|inv| inv.get(slot))
{
self.hotbar.add_inventory_link(h, item);
events.push(Event::ChangeHotbarState(Box::new(
self.hotbar.to_owned(),
)));
}
}
} else if let (Hotbar(a), Hotbar(b)) = (a, b) {
self.hotbar.swap(a, b);
events.push(Event::ChangeHotbarState(Box::new(self.hotbar.to_owned())));
} else if let (Inventory(i), Trade(t)) = (a, b) {
if i.ours == t.ours {
if let Some(inventory) = inventories.get(t.entity) {
if let (Some(inventory), Slot::Inventory(slot)) =
(inventories.get(t.entity), i.slot)
{
events.push(Event::TradeAction(TradeAction::AddItem {
item: i.slot,
item: slot,
quantity: i.amount(inventory).unwrap_or(1),
ours: i.ours,
}));
@ -3973,18 +3988,20 @@ impl Hud {
(AbilitySlot::Ability(_), AbilitySlot::Ability(_)) => {},
}
} else if let (Inventory(i), Crafting(c)) = (a, b) {
// Add item to crafting input
if inventories
.get(info.viewpoint_entity)
.and_then(|inv| inv.get(i.slot))
.map_or(false, |item| {
(c.requirement)(item, client.component_recipe_book(), c.info)
})
{
self.show
.crafting_fields
.recipe_inputs
.insert(c.index, Slot::Inventory(i.slot));
if let Slot::Inventory(slot) = i.slot {
// Add item to crafting input
if inventories
.get(info.viewpoint_entity)
.and_then(|inv| inv.get(slot))
.map_or(false, |item| {
(c.requirement)(item, client.component_recipe_book(), c.info)
})
{
self.show
.crafting_fields
.recipe_inputs
.insert(c.index, i.slot);
}
}
} else if let (Equip(e), Crafting(c)) = (a, b) {
// Add item to crafting input
@ -4055,21 +4072,27 @@ impl Hud {
bypass_dialog: false,
});
} else if let (Inventory(i), Hotbar(h)) = (a, b) {
if let Some(item) = inventories
.get(info.viewpoint_entity)
.and_then(|inv| inv.get(i.slot))
{
self.hotbar.add_inventory_link(h, item);
events.push(Event::ChangeHotbarState(Box::new(self.hotbar.to_owned())));
if let Slot::Inventory(slot) = i.slot {
if let Some(item) = inventories
.get(info.viewpoint_entity)
.and_then(|inv| inv.get(slot))
{
self.hotbar.add_inventory_link(h, item);
events.push(Event::ChangeHotbarState(Box::new(
self.hotbar.to_owned(),
)));
}
}
} else if let (Hotbar(a), Hotbar(b)) = (a, b) {
self.hotbar.swap(a, b);
events.push(Event::ChangeHotbarState(Box::new(self.hotbar.to_owned())));
} else if let (Inventory(i), Trade(t)) = (a, b) {
if i.ours == t.ours {
if let Some(inventory) = inventories.get(t.entity) {
if let (Some(inventory), Slot::Inventory(slot)) =
(inventories.get(t.entity), i.slot)
{
events.push(Event::TradeAction(TradeAction::AddItem {
item: i.slot,
item: slot,
quantity: i.amount(inventory).unwrap_or(1) / 2,
ours: i.ours,
}));
@ -4253,24 +4276,26 @@ impl Hud {
match slot {
Inventory(i) => {
if let Some(inventory) = inventories.get(i.entity) {
let mut quantity = 1;
if auto_quantity {
do_auto_quantity(
inventory,
i.slot,
i.ours,
false,
&mut quantity,
);
let inv_quantity = i.amount(inventory).unwrap_or(1);
quantity = quantity.min(inv_quantity);
}
if let Slot::Inventory(slot) = i.slot {
let mut quantity = 1;
if auto_quantity {
do_auto_quantity(
inventory,
slot,
i.ours,
false,
&mut quantity,
);
let inv_quantity = i.amount(inventory).unwrap_or(1);
quantity = quantity.min(inv_quantity);
}
events.push(Event::TradeAction(TradeAction::AddItem {
item: i.slot,
quantity,
ours: i.ours,
}));
events.push(Event::TradeAction(TradeAction::AddItem {
item: slot,
quantity,
ours: i.ours,
}));
}
}
},
Trade(t) => {
@ -4530,7 +4555,7 @@ impl Hud {
) {
use slots::InventorySlot;
if let Some(slots::SlotKind::Inventory(InventorySlot {
slot: i,
slot: Slot::Inventory(i),
ours: true,
..
})) = slot_manager.selected()

View File

@ -36,7 +36,7 @@ pub type SlotManager = slot::SlotManager<SlotKind>;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct InventorySlot {
pub slot: InvSlotId,
pub slot: Slot,
pub entity: EcsEntity,
pub ours: bool,
}
@ -45,12 +45,12 @@ impl SlotKey<Inventory, ItemImgs> for InventorySlot {
type ImageKey = ItemKey;
fn image_key(&self, source: &Inventory) -> Option<(Self::ImageKey, Option<Color>)> {
source.get(self.slot).map(|i| (i.into(), None))
source.get_slot(self.slot).map(|i| (i.into(), None))
}
fn amount(&self, source: &Inventory) -> Option<u32> {
source
.get(self.slot)
.get_slot(self.slot)
.map(|item| item.amount())
.filter(|amount| *amount > 1)
}
@ -90,7 +90,7 @@ impl SlotKey<Inventory, ItemImgs> for TradeSlot {
fn image_key(&self, source: &Inventory) -> Option<(Self::ImageKey, Option<Color>)> {
self.invslot.and_then(|inv_id| {
InventorySlot {
slot: inv_id,
slot: Slot::Inventory(inv_id),
ours: self.ours,
entity: self.entity,
}
@ -102,7 +102,7 @@ impl SlotKey<Inventory, ItemImgs> for TradeSlot {
self.invslot
.and_then(|inv_id| {
InventorySlot {
slot: inv_id,
slot: Slot::Inventory(inv_id),
ours: self.ours,
entity: self.entity,
}