2020-07-18 00:05:28 +00:00
|
|
|
use crate::{
|
|
|
|
comp,
|
2020-11-12 05:00:17 +00:00
|
|
|
comp::{item::{self, armor, tool::AbilityMap}, ItemConfig},
|
2020-07-18 00:05:28 +00:00
|
|
|
};
|
2020-08-06 08:04:03 +00:00
|
|
|
use comp::{Inventory, Loadout};
|
2020-07-06 14:23:08 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2020-06-21 14:26:06 +00:00
|
|
|
use tracing::warn;
|
2020-04-10 02:36:35 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
|
|
|
|
pub enum Slot {
|
|
|
|
Inventory(usize),
|
|
|
|
Equip(EquipSlot),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
|
|
|
|
pub enum EquipSlot {
|
|
|
|
Armor(ArmorSlot),
|
|
|
|
Mainhand,
|
|
|
|
Offhand,
|
|
|
|
Lantern,
|
2020-08-24 01:31:05 +00:00
|
|
|
Glider,
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
|
|
|
|
pub enum ArmorSlot {
|
|
|
|
Head,
|
|
|
|
Neck,
|
|
|
|
Shoulders,
|
|
|
|
Chest,
|
|
|
|
Hands,
|
|
|
|
Ring,
|
|
|
|
Back,
|
|
|
|
Belt,
|
|
|
|
Legs,
|
|
|
|
Feet,
|
|
|
|
Tabard,
|
|
|
|
}
|
|
|
|
|
|
|
|
//const ALL_ARMOR_SLOTS: [ArmorSlot; 11] = [
|
|
|
|
// Head, Neck, Shoulders, Chest, Hands, Ring, Back, Belt, Legs, Feet, Tabard,
|
|
|
|
//];
|
|
|
|
|
|
|
|
impl Slot {
|
|
|
|
pub fn can_hold(self, item_kind: &item::ItemKind) -> bool {
|
|
|
|
match (self, item_kind) {
|
|
|
|
(Self::Inventory(_), _) => true,
|
|
|
|
(Self::Equip(slot), item_kind) => slot.can_hold(item_kind),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EquipSlot {
|
|
|
|
fn can_hold(self, item_kind: &item::ItemKind) -> bool {
|
2020-07-18 00:05:28 +00:00
|
|
|
use armor::Armor;
|
2020-04-10 02:36:35 +00:00
|
|
|
use item::ItemKind;
|
|
|
|
match (self, item_kind) {
|
2020-07-18 00:05:28 +00:00
|
|
|
(Self::Armor(slot), ItemKind::Armor(Armor { kind, .. })) => slot.can_hold(kind),
|
2020-04-10 02:36:35 +00:00
|
|
|
(Self::Mainhand, ItemKind::Tool(_)) => true,
|
|
|
|
(Self::Offhand, ItemKind::Tool(_)) => true,
|
|
|
|
(Self::Lantern, ItemKind::Lantern(_)) => true,
|
2020-08-24 01:31:05 +00:00
|
|
|
(Self::Glider, ItemKind::Glider(_)) => true,
|
2020-04-10 02:36:35 +00:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ArmorSlot {
|
2020-07-18 00:05:28 +00:00
|
|
|
fn can_hold(self, armor: &item::armor::ArmorKind) -> bool {
|
|
|
|
use item::armor::ArmorKind;
|
2020-04-10 02:36:35 +00:00
|
|
|
match (self, armor) {
|
2020-07-18 00:05:28 +00:00
|
|
|
(Self::Head, ArmorKind::Head(_)) => true,
|
|
|
|
(Self::Neck, ArmorKind::Neck(_)) => true,
|
|
|
|
(Self::Shoulders, ArmorKind::Shoulder(_)) => true,
|
|
|
|
(Self::Chest, ArmorKind::Chest(_)) => true,
|
|
|
|
(Self::Hands, ArmorKind::Hand(_)) => true,
|
|
|
|
(Self::Ring, ArmorKind::Ring(_)) => true,
|
|
|
|
(Self::Back, ArmorKind::Back(_)) => true,
|
|
|
|
(Self::Belt, ArmorKind::Belt(_)) => true,
|
|
|
|
(Self::Legs, ArmorKind::Pants(_)) => true,
|
|
|
|
(Self::Feet, ArmorKind::Foot(_)) => true,
|
|
|
|
(Self::Tabard, ArmorKind::Tabard(_)) => true,
|
2020-04-10 02:36:35 +00:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-25 12:21:25 +00:00
|
|
|
/// Replace an equipment slot with an item. Return the item that was in the
|
2020-06-11 02:50:45 +00:00
|
|
|
/// slot, if any. Doesn't update the inventory.
|
2020-04-10 02:36:35 +00:00
|
|
|
fn loadout_replace(
|
|
|
|
equip_slot: EquipSlot,
|
|
|
|
item: Option<item::Item>,
|
|
|
|
loadout: &mut Loadout,
|
2020-11-12 05:00:17 +00:00
|
|
|
map: &AbilityMap,
|
2020-04-10 02:36:35 +00:00
|
|
|
) -> Option<item::Item> {
|
|
|
|
use std::mem::replace;
|
|
|
|
match equip_slot {
|
|
|
|
EquipSlot::Armor(ArmorSlot::Head) => replace(&mut loadout.head, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Neck) => replace(&mut loadout.neck, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Shoulders) => replace(&mut loadout.shoulder, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Chest) => replace(&mut loadout.chest, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Hands) => replace(&mut loadout.hand, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Ring) => replace(&mut loadout.ring, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Back) => replace(&mut loadout.back, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Belt) => replace(&mut loadout.belt, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Legs) => replace(&mut loadout.pants, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Feet) => replace(&mut loadout.foot, item),
|
|
|
|
EquipSlot::Armor(ArmorSlot::Tabard) => replace(&mut loadout.tabard, item),
|
|
|
|
EquipSlot::Lantern => replace(&mut loadout.lantern, item),
|
2020-08-24 01:31:05 +00:00
|
|
|
EquipSlot::Glider => replace(&mut loadout.glider, item),
|
2020-04-10 02:36:35 +00:00
|
|
|
EquipSlot::Mainhand => {
|
2020-11-12 05:00:17 +00:00
|
|
|
replace(&mut loadout.active_item, item.map(|item| ItemConfig::from((item, map)))).map(|i| i.item)
|
2020-04-10 02:36:35 +00:00
|
|
|
},
|
|
|
|
EquipSlot::Offhand => {
|
2020-11-12 05:00:17 +00:00
|
|
|
replace(&mut loadout.second_item, item.map(|item| ItemConfig::from((item, map)))).map(|i| i.item)
|
2020-04-10 02:36:35 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:12:37 +00:00
|
|
|
/// Insert an item into a loadout. If the specified slot is already occupied
|
|
|
|
/// the old item is returned.
|
2020-04-10 02:36:35 +00:00
|
|
|
#[must_use]
|
|
|
|
fn loadout_insert(
|
|
|
|
equip_slot: EquipSlot,
|
|
|
|
item: item::Item,
|
|
|
|
loadout: &mut Loadout,
|
2020-11-12 05:00:17 +00:00
|
|
|
map: &AbilityMap,
|
2020-04-10 02:36:35 +00:00
|
|
|
) -> Option<item::Item> {
|
2020-11-12 05:00:17 +00:00
|
|
|
loadout_replace(equip_slot, Some(item), loadout, map)
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 02:50:45 +00:00
|
|
|
/// Remove an item from a loadout.
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use veloren_common::{
|
|
|
|
/// comp::{
|
|
|
|
/// slot::{loadout_remove, EquipSlot},
|
|
|
|
/// Inventory,
|
|
|
|
/// },
|
|
|
|
/// LoadoutBuilder,
|
|
|
|
/// };
|
|
|
|
///
|
2020-09-17 23:02:14 +00:00
|
|
|
/// let mut inv = Inventory::new_empty();
|
2020-06-11 02:50:45 +00:00
|
|
|
///
|
|
|
|
/// let mut loadout = LoadoutBuilder::new()
|
|
|
|
/// .defaults()
|
2020-09-17 23:02:14 +00:00
|
|
|
/// .active_item(Some(LoadoutBuilder::default_item_config_from_str(
|
2020-06-11 02:50:45 +00:00
|
|
|
/// "common.items.weapons.sword.zweihander_sword_0",
|
|
|
|
/// )))
|
|
|
|
/// .build();
|
|
|
|
///
|
|
|
|
/// let slot = EquipSlot::Mainhand;
|
|
|
|
///
|
|
|
|
/// loadout_remove(slot, &mut loadout);
|
|
|
|
/// assert_eq!(None, loadout.active_item);
|
|
|
|
/// ```
|
2020-11-12 05:00:17 +00:00
|
|
|
pub fn loadout_remove(equip_slot: EquipSlot, loadout: &mut Loadout, map: &AbilityMap) -> Option<item::Item> {
|
|
|
|
loadout_replace(equip_slot, None, loadout, map)
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 02:50:45 +00:00
|
|
|
/// Swap item in an inventory slot with one in a loadout slot.
|
2020-04-10 02:36:35 +00:00
|
|
|
fn swap_inventory_loadout(
|
|
|
|
inventory_slot: usize,
|
|
|
|
equip_slot: EquipSlot,
|
|
|
|
inventory: &mut Inventory,
|
|
|
|
loadout: &mut Loadout,
|
2020-11-12 05:00:17 +00:00
|
|
|
map: &AbilityMap,
|
2020-04-10 02:36:35 +00:00
|
|
|
) {
|
|
|
|
// Check if loadout slot can hold item
|
|
|
|
if inventory
|
|
|
|
.get(inventory_slot)
|
2020-09-17 23:02:14 +00:00
|
|
|
.map_or(true, |item| equip_slot.can_hold(&item.kind()))
|
2020-04-10 02:36:35 +00:00
|
|
|
{
|
|
|
|
// Take item from loadout
|
2020-11-12 05:00:17 +00:00
|
|
|
let from_equip = loadout_remove(equip_slot, loadout, map);
|
2020-04-10 02:36:35 +00:00
|
|
|
// Swap with item in the inventory
|
|
|
|
let from_inv = if let Some(item) = from_equip {
|
|
|
|
// If this fails and we get item back as an err it will just be put back in the
|
|
|
|
// loadout
|
2020-06-11 18:44:03 +00:00
|
|
|
inventory.insert(inventory_slot, item).unwrap_or_else(Some)
|
2020-04-10 02:36:35 +00:00
|
|
|
} else {
|
|
|
|
inventory.remove(inventory_slot)
|
|
|
|
};
|
|
|
|
// Put item from the inventory in loadout
|
|
|
|
if let Some(item) = from_inv {
|
2020-11-12 05:00:17 +00:00
|
|
|
loadout_insert(equip_slot, item, loadout, map).unwrap_none(); // Can never fail
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:12:37 +00:00
|
|
|
/// Swap items in loadout. Does nothing if items are not compatible with their
|
|
|
|
/// new slots.
|
2020-11-12 05:00:17 +00:00
|
|
|
fn swap_loadout(slot_a: EquipSlot, slot_b: EquipSlot, loadout: &mut Loadout, map: &AbilityMap) {
|
2020-05-12 23:44:27 +00:00
|
|
|
// Ensure that the slots are not the same
|
2020-04-24 04:50:16 +00:00
|
|
|
if slot_a == slot_b {
|
|
|
|
warn!("Tried to swap equip slot with itself");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-10 02:36:35 +00:00
|
|
|
// Get items from the slots
|
2020-11-12 05:00:17 +00:00
|
|
|
let item_a = loadout_remove(slot_a, loadout, map);
|
|
|
|
let item_b = loadout_remove(slot_b, loadout, map);
|
2020-04-10 02:36:35 +00:00
|
|
|
// Check if items can go in the other slots
|
2020-09-17 23:02:14 +00:00
|
|
|
if item_a.as_ref().map_or(true, |i| slot_b.can_hold(&i.kind()))
|
|
|
|
&& item_b.as_ref().map_or(true, |i| slot_a.can_hold(&i.kind()))
|
2020-04-10 02:36:35 +00:00
|
|
|
{
|
|
|
|
// Swap
|
2020-11-12 05:00:17 +00:00
|
|
|
loadout_replace(slot_b, item_a, loadout, map).unwrap_none();
|
|
|
|
loadout_replace(slot_a, item_b, loadout, map).unwrap_none();
|
2020-04-10 02:36:35 +00:00
|
|
|
} else {
|
|
|
|
// Otherwise put the items back
|
2020-11-12 05:00:17 +00:00
|
|
|
loadout_replace(slot_a, item_a, loadout, map).unwrap_none();
|
|
|
|
loadout_replace(slot_b, item_b, loadout, map).unwrap_none();
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 02:50:45 +00:00
|
|
|
// TODO: Should this report if a change actually occurred? (might be useful when
|
2020-04-10 02:36:35 +00:00
|
|
|
// minimizing network use)
|
2020-06-11 02:50:45 +00:00
|
|
|
|
|
|
|
/// Swap items from two slots, regardless of if either is inventory or loadout.
|
2020-04-10 02:36:35 +00:00
|
|
|
pub fn swap(
|
|
|
|
slot_a: Slot,
|
|
|
|
slot_b: Slot,
|
|
|
|
inventory: Option<&mut Inventory>,
|
|
|
|
loadout: Option<&mut Loadout>,
|
2020-11-12 05:00:17 +00:00
|
|
|
map: &AbilityMap,
|
2020-04-10 02:36:35 +00:00
|
|
|
) {
|
|
|
|
match (slot_a, slot_b) {
|
|
|
|
(Slot::Inventory(slot_a), Slot::Inventory(slot_b)) => {
|
|
|
|
inventory.map(|i| i.swap_slots(slot_a, slot_b));
|
|
|
|
},
|
|
|
|
(Slot::Inventory(inv_slot), Slot::Equip(equip_slot))
|
|
|
|
| (Slot::Equip(equip_slot), Slot::Inventory(inv_slot)) => {
|
|
|
|
if let Some((inventory, loadout)) = loadout.and_then(|l| inventory.map(|i| (i, l))) {
|
2020-11-12 05:00:17 +00:00
|
|
|
swap_inventory_loadout(inv_slot, equip_slot, inventory, loadout, map);
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
(Slot::Equip(slot_a), Slot::Equip(slot_b)) => {
|
2020-11-12 05:00:17 +00:00
|
|
|
loadout.map(|l| swap_loadout(slot_a, slot_b, l, map));
|
2020-04-10 02:36:35 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-10 21:37:45 +00:00
|
|
|
/// Equip an item from a slot in inventory. The currently equipped item will go
|
|
|
|
/// into inventory. If the item is going to mainhand, put mainhand in
|
|
|
|
/// offhand and place offhand into inventory.
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use veloren_common::{
|
2020-08-28 01:02:17 +00:00
|
|
|
/// assets::Asset,
|
2020-06-10 21:37:45 +00:00
|
|
|
/// comp::{
|
|
|
|
/// slot::{equip, EquipSlot},
|
|
|
|
/// Inventory, Item,
|
|
|
|
/// },
|
|
|
|
/// LoadoutBuilder,
|
|
|
|
/// };
|
|
|
|
///
|
2020-09-17 23:02:14 +00:00
|
|
|
/// let boots = Item::new_from_asset_expect("common.items.testing.test_boots");
|
2020-06-10 21:37:45 +00:00
|
|
|
///
|
2020-09-17 23:02:14 +00:00
|
|
|
/// let mut inv = Inventory::new_empty();
|
|
|
|
/// inv.push(boots.duplicate());
|
2020-06-10 21:37:45 +00:00
|
|
|
///
|
|
|
|
/// let mut loadout = LoadoutBuilder::new().defaults().build();
|
|
|
|
///
|
|
|
|
/// equip(0, &mut inv, &mut loadout);
|
2020-09-17 23:02:14 +00:00
|
|
|
/// assert_eq!(Some(boots), loadout.foot);
|
2020-06-10 21:37:45 +00:00
|
|
|
/// ```
|
2020-11-12 05:00:17 +00:00
|
|
|
pub fn equip(slot: usize, inventory: &mut Inventory, loadout: &mut Loadout, map: &AbilityMap) {
|
2020-07-18 00:05:28 +00:00
|
|
|
use armor::Armor;
|
|
|
|
use item::{armor::ArmorKind, ItemKind};
|
2020-04-10 02:36:35 +00:00
|
|
|
|
2020-09-17 23:02:14 +00:00
|
|
|
let equip_slot = inventory.get(slot).and_then(|i| match &i.kind() {
|
2020-04-10 02:36:35 +00:00
|
|
|
ItemKind::Tool(_) => Some(EquipSlot::Mainhand),
|
2020-07-18 00:05:28 +00:00
|
|
|
ItemKind::Armor(Armor { kind, .. }) => Some(EquipSlot::Armor(match kind {
|
|
|
|
ArmorKind::Head(_) => ArmorSlot::Head,
|
|
|
|
ArmorKind::Neck(_) => ArmorSlot::Neck,
|
|
|
|
ArmorKind::Shoulder(_) => ArmorSlot::Shoulders,
|
|
|
|
ArmorKind::Chest(_) => ArmorSlot::Chest,
|
|
|
|
ArmorKind::Hand(_) => ArmorSlot::Hands,
|
|
|
|
ArmorKind::Ring(_) => ArmorSlot::Ring,
|
|
|
|
ArmorKind::Back(_) => ArmorSlot::Back,
|
|
|
|
ArmorKind::Belt(_) => ArmorSlot::Belt,
|
|
|
|
ArmorKind::Pants(_) => ArmorSlot::Legs,
|
|
|
|
ArmorKind::Foot(_) => ArmorSlot::Feet,
|
|
|
|
ArmorKind::Tabard(_) => ArmorSlot::Tabard,
|
2020-04-10 02:36:35 +00:00
|
|
|
})),
|
|
|
|
ItemKind::Lantern(_) => Some(EquipSlot::Lantern),
|
2020-08-24 01:31:05 +00:00
|
|
|
ItemKind::Glider(_) => Some(EquipSlot::Glider),
|
2020-04-10 02:36:35 +00:00
|
|
|
_ => None,
|
|
|
|
});
|
|
|
|
|
|
|
|
if let Some(equip_slot) = equip_slot {
|
|
|
|
// If item is going to mainhand, put mainhand in offhand and place offhand in
|
|
|
|
// inventory
|
|
|
|
if let EquipSlot::Mainhand = equip_slot {
|
2020-11-12 05:00:17 +00:00
|
|
|
swap_loadout(EquipSlot::Mainhand, EquipSlot::Offhand, loadout, map);
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
|
|
|
|
2020-11-12 05:00:17 +00:00
|
|
|
swap_inventory_loadout(slot, equip_slot, inventory, loadout, map);
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-10 21:37:45 +00:00
|
|
|
/// Unequip an item from slot and place into inventory. Will leave the item
|
|
|
|
/// equipped if inventory has no slots available.
|
2020-06-10 16:41:49 +00:00
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use veloren_common::{
|
|
|
|
/// comp::{
|
|
|
|
/// slot::{unequip, EquipSlot},
|
|
|
|
/// Inventory,
|
|
|
|
/// },
|
|
|
|
/// LoadoutBuilder,
|
|
|
|
/// };
|
|
|
|
///
|
2020-09-17 23:02:14 +00:00
|
|
|
/// let mut inv = Inventory::new_empty();
|
2020-06-10 16:41:49 +00:00
|
|
|
///
|
|
|
|
/// let mut loadout = LoadoutBuilder::new()
|
|
|
|
/// .defaults()
|
2020-09-17 23:02:14 +00:00
|
|
|
/// .active_item(Some(LoadoutBuilder::default_item_config_from_str(
|
2020-06-10 16:41:49 +00:00
|
|
|
/// "common.items.weapons.sword.zweihander_sword_0",
|
|
|
|
/// )))
|
|
|
|
/// .build();
|
|
|
|
///
|
|
|
|
/// let slot = EquipSlot::Mainhand;
|
|
|
|
///
|
|
|
|
/// unequip(slot, &mut inv, &mut loadout);
|
|
|
|
/// assert_eq!(None, loadout.active_item);
|
|
|
|
/// ```
|
2020-11-12 05:00:17 +00:00
|
|
|
pub fn unequip(slot: EquipSlot, inventory: &mut Inventory, loadout: &mut Loadout, map: &AbilityMap) {
|
|
|
|
loadout_remove(slot, loadout, map) // Remove item from loadout
|
2020-04-10 02:36:35 +00:00
|
|
|
.and_then(|i| inventory.push(i)) // Insert into inventory
|
2020-11-12 05:00:17 +00:00
|
|
|
.and_then(|i| loadout_insert(slot, i, loadout, map)) // If that fails put back in loadout
|
2020-04-10 02:59:28 +00:00
|
|
|
.unwrap_none(); // Never fails
|
2020-04-10 02:36:35 +00:00
|
|
|
}
|
2020-06-10 16:41:49 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2020-09-17 23:02:14 +00:00
|
|
|
use crate::{comp::Item, LoadoutBuilder};
|
2020-06-10 16:41:49 +00:00
|
|
|
|
|
|
|
#[test]
|
2020-06-11 02:50:45 +00:00
|
|
|
fn test_unequip_items_both_hands() {
|
2020-06-10 16:41:49 +00:00
|
|
|
let mut inv = Inventory {
|
|
|
|
slots: vec![None],
|
|
|
|
amount: 0,
|
|
|
|
};
|
|
|
|
|
2020-09-17 23:02:14 +00:00
|
|
|
let sword = LoadoutBuilder::default_item_config_from_str(
|
2020-06-10 16:41:49 +00:00
|
|
|
"common.items.weapons.sword.zweihander_sword_0",
|
2020-09-17 23:02:14 +00:00
|
|
|
);
|
2020-06-10 16:41:49 +00:00
|
|
|
|
|
|
|
let mut loadout = LoadoutBuilder::new()
|
|
|
|
.defaults()
|
2020-09-17 23:02:14 +00:00
|
|
|
.active_item(Some(sword.clone()))
|
|
|
|
.second_item(Some(sword.clone()))
|
2020-06-10 16:41:49 +00:00
|
|
|
.build();
|
|
|
|
|
2020-09-17 23:02:14 +00:00
|
|
|
assert_eq!(Some(sword.clone()), loadout.active_item);
|
2020-06-10 16:41:49 +00:00
|
|
|
unequip(EquipSlot::Mainhand, &mut inv, &mut loadout);
|
|
|
|
// We have space in the inventory, so this should have unequipped
|
|
|
|
assert_eq!(None, loadout.active_item);
|
|
|
|
|
|
|
|
unequip(EquipSlot::Offhand, &mut inv, &mut loadout);
|
|
|
|
// There is no more space in the inventory, so this should still be equipped
|
2020-09-17 23:02:14 +00:00
|
|
|
assert_eq!(Some(sword.clone()), loadout.second_item);
|
2020-06-11 02:50:45 +00:00
|
|
|
|
|
|
|
// Verify inventory
|
2020-09-17 23:02:14 +00:00
|
|
|
assert_eq!(inv.slots[0], Some(sword.item));
|
2020-06-11 02:50:45 +00:00
|
|
|
assert_eq!(inv.slots.len(), 1);
|
2020-06-10 16:41:49 +00:00
|
|
|
}
|
2020-06-10 21:37:45 +00:00
|
|
|
|
|
|
|
#[test]
|
2020-06-11 02:50:45 +00:00
|
|
|
fn test_equip_item() {
|
2020-09-17 23:02:14 +00:00
|
|
|
let boots: Option<comp::Item> = Some(Item::new_from_asset_expect(
|
2020-06-10 21:37:45 +00:00
|
|
|
"common.items.testing.test_boots",
|
|
|
|
));
|
|
|
|
|
2020-09-17 23:02:14 +00:00
|
|
|
let starting_sandles: Option<comp::Item> = Some(Item::new_from_asset_expect(
|
2020-06-10 21:37:45 +00:00
|
|
|
"common.items.armor.starter.sandals_0",
|
|
|
|
));
|
|
|
|
|
|
|
|
let mut inv = Inventory {
|
|
|
|
slots: vec![boots.clone()],
|
|
|
|
amount: 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut loadout = LoadoutBuilder::new().defaults().build();
|
|
|
|
|
|
|
|
// We should start with the starting sandles
|
|
|
|
assert_eq!(starting_sandles, loadout.foot);
|
|
|
|
equip(0, &mut inv, &mut loadout);
|
|
|
|
|
|
|
|
// We should now have the testing boots equiped
|
|
|
|
assert_eq!(boots, loadout.foot);
|
2020-06-11 02:50:45 +00:00
|
|
|
|
|
|
|
// Verify inventory
|
|
|
|
assert_eq!(inv.slots[0], starting_sandles);
|
|
|
|
assert_eq!(inv.slots.len(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_loadout_replace() {
|
2020-09-17 23:02:14 +00:00
|
|
|
let boots: Option<comp::Item> = Some(Item::new_from_asset_expect(
|
2020-06-11 02:50:45 +00:00
|
|
|
"common.items.testing.test_boots",
|
|
|
|
));
|
|
|
|
|
2020-09-17 23:02:14 +00:00
|
|
|
let starting_sandles: Option<comp::Item> = Some(Item::new_from_asset_expect(
|
2020-06-11 02:50:45 +00:00
|
|
|
"common.items.armor.starter.sandals_0",
|
|
|
|
));
|
|
|
|
|
|
|
|
let mut loadout = LoadoutBuilder::new().defaults().build();
|
|
|
|
|
|
|
|
// We should start with the starting sandles
|
|
|
|
assert_eq!(starting_sandles, loadout.foot);
|
|
|
|
|
|
|
|
// The swap should return the sandles
|
|
|
|
assert_eq!(
|
|
|
|
starting_sandles,
|
|
|
|
loadout_replace(
|
|
|
|
EquipSlot::Armor(ArmorSlot::Feet),
|
|
|
|
boots.clone(),
|
|
|
|
&mut loadout,
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
// We should now have the testing boots equiped
|
|
|
|
assert_eq!(boots, loadout.foot);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_loadout_remove() {
|
2020-09-17 23:02:14 +00:00
|
|
|
let sword = LoadoutBuilder::default_item_config_from_str(
|
2020-06-11 02:50:45 +00:00
|
|
|
"common.items.weapons.sword.zweihander_sword_0",
|
2020-09-17 23:02:14 +00:00
|
|
|
);
|
2020-06-11 02:50:45 +00:00
|
|
|
|
|
|
|
let mut loadout = LoadoutBuilder::new()
|
|
|
|
.defaults()
|
2020-09-17 23:02:14 +00:00
|
|
|
.active_item(Some(sword.clone()))
|
2020-06-11 02:50:45 +00:00
|
|
|
.build();
|
|
|
|
|
|
|
|
// The swap should return the sword
|
|
|
|
assert_eq!(
|
2020-09-17 23:02:14 +00:00
|
|
|
Some(sword.item),
|
2020-06-11 02:50:45 +00:00
|
|
|
loadout_remove(EquipSlot::Mainhand, &mut loadout,)
|
|
|
|
);
|
|
|
|
|
|
|
|
// We should now have nothing equiped
|
|
|
|
assert_eq!(None, loadout.active_item);
|
2020-06-10 21:37:45 +00:00
|
|
|
}
|
2020-06-10 16:41:49 +00:00
|
|
|
}
|