Overflow slots as slots

This commit is contained in:
Sam 2023-08-18 14:00:57 -04:00
parent 93ca630a13
commit d01997ca56
11 changed files with 109 additions and 1 deletions

View File

@ -9,5 +9,5 @@ ItemDef(
),
quality: Debug,
tags: [],
slots: 900,
slots: 1,
)

View File

@ -1119,6 +1119,13 @@ impl Client {
pub fn swap_slots(&mut self, a: Slot, b: Slot) {
match (a, b) {
(Slot::Overflow(o), Slot::Inventory(inv))
| (Slot::Inventory(inv), Slot::Overflow(o)) => {
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryEvent(
InventoryEvent::OverflowMove(o, inv),
)));
},
(Slot::Overflow(_), _) | (_, Slot::Overflow(_)) => {},
(Slot::Equip(equip), slot) | (slot, Slot::Equip(equip)) => self.control_action(
ControlAction::InventoryAction(InventoryAction::Swap(equip, slot)),
),
@ -1138,6 +1145,9 @@ impl Client {
Slot::Inventory(inv) => self.send_msg(ClientGeneral::ControlEvent(
ControlEvent::InventoryEvent(InventoryEvent::Drop(inv)),
)),
Slot::Overflow(o) => self.send_msg(ClientGeneral::ControlEvent(
ControlEvent::InventoryEvent(InventoryEvent::OverflowDrop(o)),
)),
}
}
@ -1173,6 +1183,7 @@ impl Client {
InventoryEvent::SplitSwap(inv1, inv2),
)))
},
(Slot::Overflow(_), _) | (_, Slot::Overflow(_)) => {},
}
}
@ -1184,6 +1195,9 @@ impl Client {
Slot::Inventory(inv) => self.send_msg(ClientGeneral::ControlEvent(
ControlEvent::InventoryEvent(InventoryEvent::SplitDrop(inv)),
)),
Slot::Overflow(o) => self.send_msg(ClientGeneral::ControlEvent(
ControlEvent::InventoryEvent(InventoryEvent::OverflowSplitDrop(o)),
)),
}
}
@ -1393,6 +1407,7 @@ impl Client {
if let Some(item) = match item {
Slot::Equip(equip_slot) => inv.equipped(equip_slot),
Slot::Inventory(invslot) => inv.get(invslot),
Slot::Overflow(_) => None,
} {
item.has_durability()
} else {

View File

@ -31,6 +31,9 @@ pub enum InventoryEvent {
craft_event: CraftEvent,
craft_sprite: Option<VolumePos>,
},
OverflowMove(usize, InvSlotId),
OverflowDrop(usize),
OverflowSplitDrop(usize),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
@ -86,6 +89,11 @@ impl From<InventoryEvent> for InventoryManip {
craft_event,
craft_sprite,
},
InventoryEvent::OverflowMove(o, inv) => {
Self::Swap(Slot::Overflow(o), Slot::Inventory(inv))
},
InventoryEvent::OverflowDrop(o) => Self::Drop(Slot::Overflow(o)),
InventoryEvent::OverflowSplitDrop(o) => Self::SplitDrop(Slot::Overflow(o)),
}
}
}

View File

@ -524,11 +524,38 @@ impl Inventory {
*self.slot_mut(b).unwrap() = slot_a;
}
/// Moves an item from an overflow slot to an inventory slot
pub fn move_overflow_item(&mut self, overflow: usize, inv_slot: InvSlotId) {
match self.slot(inv_slot) {
Some(Some(_)) => {
warn!("Attempted to move from overflow slot to a filled inventory slot");
return;
},
None => {
warn!("Attempted to move from overflow slot to a non-existent inventory slot");
return;
},
Some(None) => {},
};
let item = self.overflow_items.remove(overflow);
*self.slot_mut(inv_slot).unwrap() = Some(item);
}
/// Remove an item from the slot
pub fn remove(&mut self, inv_slot_id: InvSlotId) -> Option<Item> {
self.slot_mut(inv_slot_id).and_then(|item| item.take())
}
/// Remove an item from an overflow slot
pub fn overflow_remove(&mut self, overflow_slot: usize) -> Option<Item> {
if overflow_slot < self.overflow_items.len() {
Some(self.overflow_items.remove(overflow_slot))
} else {
None
}
}
/// Remove just one item from the slot
pub fn take(
&mut self,
@ -579,6 +606,34 @@ impl Inventory {
}
}
/// Takes half of the items from an overflow slot
pub fn overflow_take_half(
&mut self,
overflow_slot: usize,
ability_map: &AbilityMap,
msm: &MaterialStatManifest,
) -> Option<Item> {
if let Some(item) = self.overflow_items.get_mut(overflow_slot) {
if item.is_stackable() && item.amount() > 1 {
let mut return_item = item.duplicate(ability_map, msm);
let returning_amount = item.amount() / 2;
item.decrease_amount(returning_amount).ok()?;
return_item.set_amount(returning_amount).expect(
"return_item.amount() = item.amount() / 2 < item.amount() (since \
item.amount() 1) item.max_amount() = return_item.max_amount(), since \
return_item is a duplicate of item",
);
Some(return_item)
} else if overflow_slot < self.overflow_items.len() {
Some(self.overflow_items.remove(overflow_slot))
} else {
None
}
} else {
None
}
}
/// Takes all items from the inventory
pub fn drain(&mut self) -> impl Iterator<Item = Item> + '_ {
self.slots_mut()
@ -781,6 +836,15 @@ impl Inventory {
self.loadout.swap_slots(slot_a, slot_b, time);
Vec::new()
},
(Slot::Overflow(overflow_slot), Slot::Inventory(inv_slot))
| (Slot::Inventory(inv_slot), Slot::Overflow(overflow_slot)) => {
self.move_overflow_item(overflow_slot, inv_slot);
Vec::new()
},
// Items from overflow slots cannot be equipped until moved into a real inventory slot
(Slot::Overflow(_), Slot::Equip(_)) | (Slot::Equip(_), Slot::Overflow(_)) => Vec::new(),
// Items cannot be moved between overflow slots
(Slot::Overflow(_), Slot::Overflow(_)) => Vec::new(),
}
}
@ -976,6 +1040,8 @@ impl Inventory {
self.loadout
.repair_item_at_slot(equip_slot, ability_map, msm);
},
// Items in overflow slots cannot be repaired until they are moved to a real slot
Slot::Overflow(_) => {},
}
}

View File

@ -15,6 +15,7 @@ pub enum SlotError {
pub enum Slot {
Inventory(InvSlotId),
Equip(EquipSlot),
Overflow(usize),
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
@ -111,6 +112,7 @@ impl Slot {
match (self, item_kind) {
(Self::Inventory(_), _) => true,
(Self::Equip(slot), item_kind) => slot.can_hold(item_kind),
(Self::Overflow(_), _) => true,
}
}
}

View File

@ -1030,6 +1030,8 @@ impl RepairRecipeBook {
if let Some(item) = match item {
Slot::Equip(slot) => inv.equipped(slot),
Slot::Inventory(slot) => inv.get(slot),
// Items in overflow slots cannot be repaired until item is moved to a real slot
Slot::Overflow(_) => None,
} {
if let Some(repair_recipe) = self.repair_recipe(item) {
repair_recipe

View File

@ -1141,6 +1141,9 @@ pub fn handle_manipulate_loadout(
let inv_manip = InventoryManip::Use(slot);
output_events.emit_server(ServerEvent::InventoryManip(data.entity, inv_manip));
},
InventoryAction::Use(Slot::Overflow(_)) => {
// Items in overflow slots cannot be used until moved to a real slot
},
InventoryAction::ToggleSpriteLight(pos, enable) => {
if matches!(pos.kind, Volume::Terrain) {
let sprite_interact = sprite_interact::SpriteInteractKind::ToggleLight(enable);

View File

@ -559,6 +559,8 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
}
Some(InventoryUpdateEvent::Used)
},
// Items in overflow slots cannot be used
Slot::Overflow(_) => None,
};
drop(inventories);
@ -663,6 +665,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
let item = match slot {
Slot::Inventory(slot) => inventory.take_half(slot, &ability_map, &msm),
Slot::Equip(_) => None,
Slot::Overflow(_) => None,
};
if let Some(item) = item {
@ -686,6 +689,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
let item = match slot {
Slot::Inventory(slot) => inventory.remove(slot),
Slot::Equip(slot) => inventory.replace_loadout_item(slot, None, time),
Slot::Overflow(slot) => inventory.overflow_remove(slot),
};
// FIXME: We should really require the drop and write to be atomic!
@ -717,6 +721,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
let item = match slot {
Slot::Inventory(slot) => inventory.take_half(slot, ability_map, &msm),
Slot::Equip(_) => None,
Slot::Overflow(o) => inventory.overflow_take_half(o, ability_map, &msm),
};
// FIXME: We should really require the drop and write to be atomic!

View File

@ -1576,6 +1576,7 @@ impl<'a> Widget for Crafting<'a> {
modifier: craft_slot_2.and_then(|slot| match slot {
Slot::Inventory(slot) => Some(slot),
Slot::Equip(_) => None,
Slot::Overflow(_) => None,
}),
});
}
@ -1736,6 +1737,7 @@ impl<'a> Widget for Crafting<'a> {
.and_then(|slot| match slot {
Slot::Inventory(slot) => self.inventory.get(slot),
Slot::Equip(_) => None,
Slot::Overflow(_) => None,
})
.and_then(|item| item.item_definition_id().itemdef_id().map(String::from))
{
@ -1746,6 +1748,7 @@ impl<'a> Widget for Crafting<'a> {
.and_then(|slot| match slot {
Slot::Inventory(slot) => self.inventory.get(slot),
Slot::Equip(_) => None,
Slot::Overflow(_) => None,
})
.and_then(|item| {
item.item_definition_id().itemdef_id().map(String::from)
@ -1769,6 +1772,7 @@ impl<'a> Widget for Crafting<'a> {
if let Some(item) = match craft_slot_1 {
Some(Slot::Inventory(slot)) => self.inventory.get(slot),
Some(Slot::Equip(slot)) => self.inventory.equipped(slot),
Some(Slot::Overflow(_)) => None,
None => None,
} {
if let Some(recipe) = self.client.repair_recipe_book().repair_recipe(item) {

View File

@ -286,6 +286,7 @@ impl CraftSlot {
match self.slot {
Some(Slot::Inventory(slot)) => inv.get(slot),
Some(Slot::Equip(slot)) => inv.equipped(slot),
Some(Slot::Overflow(_)) => None,
None => None,
}
}

View File

@ -1753,6 +1753,7 @@ impl PlayState for SessionState {
move_allowed = false;
}
},
Slot::Overflow(_) => {},
}
};
}
@ -2021,6 +2022,7 @@ impl PlayState for SessionState {
let item = match item {
Slot::Equip(slot) => inventory.equipped(slot),
Slot::Inventory(slot) => inventory.get(slot),
Slot::Overflow(_) => None,
}?;
let repair_recipe =
client.repair_recipe_book().repair_recipe(item)?;