diff --git a/assets/voxygen/item_image_manifest.ron b/assets/voxygen/item_image_manifest.ron
index afc2378592..58dde6e4f9 100644
--- a/assets/voxygen/item_image_manifest.ron
+++ b/assets/voxygen/item_image_manifest.ron
@@ -54,6 +54,13 @@
         "voxel.weapon.shield.wood-0",
         (0.0, 0.0, 0.0), (-90.0, 90.0, 0.0), 2.4,
     ),
+    // Lanterns
+    Lantern(Black0): Png(
+        "element.icons.lantern_black-0",        
+    ),
+    Lantern(Green0): Png(
+        "element.icons.lantern_green-0",        
+    ),
     // Other
     Utility(Collar): Png(
         "element.icons.collar",
@@ -251,13 +258,6 @@
     Armor(Neck(Neck0)): Png(
         "element.icons.neck-0",        
     ),
-    // Lanterns
-    Armor(Lantern(Black0)): Png(
-        "element.icons.lantern_black-0",        
-    ),
-    Armor(Lantern(Green0)): Png(
-        "element.icons.lantern_green-0",        
-    ),
     // Tabards
     Armor(Tabard(Admin)): Png(
         "element.icons.tabard_admin",        
diff --git a/client/src/lib.rs b/client/src/lib.rs
index 1cbe9a72ce..1e4aea04b6 100644
--- a/client/src/lib.rs
+++ b/client/src/lib.rs
@@ -244,21 +244,21 @@ impl Client {
         // Can't fail
     }
 
-    pub fn use_inventory_slot(&mut self, slot: usize) {
+    pub fn use_slot(&mut self, slot: comp::slot::Slot) {
         self.postbox
             .send_message(ClientMsg::ControlEvent(ControlEvent::InventoryManip(
                 InventoryManip::Use(slot),
             )));
     }
 
-    pub fn swap_inventory_slots(&mut self, a: usize, b: usize) {
+    pub fn swap_slots(&mut self, a: comp::slot::Slot, b: comp::slot::Slot) {
         self.postbox
             .send_message(ClientMsg::ControlEvent(ControlEvent::InventoryManip(
                 InventoryManip::Swap(a, b),
             )));
     }
 
-    pub fn drop_inventory_slot(&mut self, slot: usize) {
+    pub fn drop_slot(&mut self, slot: comp::slot::Slot) {
         self.postbox
             .send_message(ClientMsg::ControlEvent(ControlEvent::InventoryManip(
                 InventoryManip::Drop(slot),
diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs
index 49c5cf8658..6daf98e1cf 100644
--- a/common/src/comp/controller.rs
+++ b/common/src/comp/controller.rs
@@ -1,4 +1,4 @@
-use crate::{sync::Uid, util::Dir};
+use crate::{comp::inventory::slot::Slot, sync::Uid, util::Dir};
 use specs::{Component, FlaggedStorage};
 use specs_idvs::IDVStorage;
 use std::time::Duration;
@@ -11,9 +11,9 @@ pub const DEFAULT_HOLD_DURATION: Duration = Duration::from_millis(200);
 pub enum InventoryManip {
     Pickup(Uid),
     Collect(Vec3<i32>),
-    Use(usize),
-    Swap(usize, usize),
-    Drop(usize),
+    Use(Slot),
+    Swap(Slot, Slot),
+    Drop(Slot),
 }
 
 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
diff --git a/common/src/comp/inventory/item/armor.rs b/common/src/comp/inventory/item/armor.rs
index b212474273..74885598be 100644
--- a/common/src/comp/inventory/item/armor.rs
+++ b/common/src/comp/inventory/item/armor.rs
@@ -188,13 +188,6 @@ pub enum Neck {
 pub const ALL_NECKS: [Neck; 1] = [Neck::Neck0];
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 #[repr(u32)]
-pub enum Lantern {
-    Black0 = 1,
-    Green0 = 2,
-}
-pub const ALL_LANTERNS: [Lantern; 2] = [Lantern::Black0, Lantern::Green0];
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
-#[repr(u32)]
 pub enum Head {
     Leather0 = 1,
     AssaMask0 = 2,
@@ -218,7 +211,6 @@ pub enum Armor {
     Back(Back),
     Ring(Ring),
     Neck(Neck),
-    Lantern(Lantern),
     Head(Head),
     Tabard(Tabard),
 }
diff --git a/common/src/comp/inventory/item/mod.rs b/common/src/comp/inventory/item/mod.rs
index 0fa256a5ef..42dcdd6a01 100644
--- a/common/src/comp/inventory/item/mod.rs
+++ b/common/src/comp/inventory/item/mod.rs
@@ -36,12 +36,21 @@ pub enum Ingredient {
     Grass,
 }
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+#[repr(u32)]
+pub enum Lantern {
+    Black0 = 1,
+    Green0 = 2,
+}
+pub const ALL_LANTERNS: [Lantern; 2] = [Lantern::Black0, Lantern::Green0];
+
 fn default_amount() -> u32 { 1 }
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub enum ItemKind {
     /// Something wieldable
     Tool(tool::Tool),
+    Lantern(Lantern),
     Armor {
         kind: armor::Armor,
         stats: armor::Stats,
diff --git a/common/src/comp/inventory/mod.rs b/common/src/comp/inventory/mod.rs
index c5ee442e96..e7e126ed96 100644
--- a/common/src/comp/inventory/mod.rs
+++ b/common/src/comp/inventory/mod.rs
@@ -1,4 +1,5 @@
 pub mod item;
+pub mod slot;
 
 use crate::assets;
 use item::{Consumable, Item, ItemKind};
@@ -36,7 +37,9 @@ impl Inventory {
     /// new group. Returns the item again if no space was found.
     pub fn push(&mut self, item: Item) -> Option<Item> {
         let item = match item.kind {
-            ItemKind::Tool(_) | ItemKind::Armor { .. } => self.add_to_first_empty(item),
+            ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Lantern(_) => {
+                self.add_to_first_empty(item)
+            },
             ItemKind::Utility {
                 kind: item_kind,
                 amount: new_amount,
@@ -239,7 +242,9 @@ impl Inventory {
         if let Some(Some(item)) = self.slots.get_mut(cell) {
             let mut return_item = item.clone();
             match &mut item.kind {
-                ItemKind::Tool(_) | ItemKind::Armor { .. } => self.remove(cell),
+                ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Lantern(_) => {
+                    self.remove(cell)
+                },
                 ItemKind::Utility { kind, amount } => {
                     if *amount <= 1 {
                         self.remove(cell)
diff --git a/common/src/comp/inventory/slot.rs b/common/src/comp/inventory/slot.rs
new file mode 100644
index 0000000000..25730c626b
--- /dev/null
+++ b/common/src/comp/inventory/slot.rs
@@ -0,0 +1,250 @@
+use crate::{comp, comp::item};
+use comp::{Inventory, Loadout};
+
+#[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,
+}
+
+#[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 {
+        use item::ItemKind;
+        match (self, item_kind) {
+            (Self::Armor(slot), ItemKind::Armor { kind, .. }) => slot.can_hold(kind),
+            (Self::Mainhand, ItemKind::Tool(_)) => true,
+            (Self::Offhand, ItemKind::Tool(_)) => true,
+            (Self::Lantern, ItemKind::Lantern(_)) => true,
+            _ => false,
+        }
+    }
+}
+
+impl ArmorSlot {
+    fn can_hold(self, armor: &item::armor::Armor) -> bool {
+        use item::armor::Armor;
+        match (self, armor) {
+            (Self::Head, Armor::Head(_)) => true,
+            (Self::Neck, Armor::Neck(_)) => true,
+            (Self::Shoulders, Armor::Shoulder(_)) => true,
+            (Self::Chest, Armor::Chest(_)) => true,
+            (Self::Hands, Armor::Hand(_)) => true,
+            (Self::Ring, Armor::Ring(_)) => true,
+            (Self::Back, Armor::Back(_)) => true,
+            (Self::Belt, Armor::Belt(_)) => true,
+            (Self::Legs, Armor::Pants(_)) => true,
+            (Self::Feet, Armor::Foot(_)) => true,
+            (Self::Tabard, Armor::Tabard(_)) => true,
+            _ => false,
+        }
+    }
+}
+
+// TODO: shouldn't need this
+fn item_config(item: item::Item) -> comp::ItemConfig {
+    let mut abilities = if let item::ItemKind::Tool(tool) = &item.kind {
+        tool.get_abilities()
+    } else {
+        Vec::new()
+    }
+    .into_iter();
+
+    comp::ItemConfig {
+        item,
+        ability1: abilities.next(),
+        ability2: abilities.next(),
+        ability3: abilities.next(),
+        block_ability: Some(comp::CharacterAbility::BasicBlock),
+        dodge_ability: Some(comp::CharacterAbility::Roll),
+    }
+}
+
+fn loadout_replace(
+    equip_slot: EquipSlot,
+    item: Option<item::Item>,
+    loadout: &mut Loadout,
+) -> 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),
+        EquipSlot::Mainhand => {
+            replace(&mut loadout.active_item, item.map(item_config)).map(|i| i.item)
+        },
+        EquipSlot::Offhand => {
+            replace(&mut loadout.second_item, item.map(item_config)).map(|i| i.item)
+        },
+    }
+}
+
+#[must_use]
+fn loadout_insert(
+    equip_slot: EquipSlot,
+    item: item::Item,
+    loadout: &mut Loadout,
+) -> Option<item::Item> {
+    loadout_replace(equip_slot, Some(item), loadout)
+}
+
+pub fn loadout_remove(equip_slot: EquipSlot, loadout: &mut Loadout) -> Option<item::Item> {
+    loadout_replace(equip_slot, None, loadout)
+}
+
+fn swap_inventory_loadout(
+    inventory_slot: usize,
+    equip_slot: EquipSlot,
+    inventory: &mut Inventory,
+    loadout: &mut Loadout,
+) {
+    // Check if loadout slot can hold item
+    if inventory
+        .get(inventory_slot)
+        .map_or(true, |item| equip_slot.can_hold(&item.kind))
+    {
+        // Take item from loadout
+        let from_equip = loadout_remove(equip_slot, loadout);
+        // 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
+            inventory
+                .insert(inventory_slot, item)
+                .unwrap_or_else(|i| Some(i))
+        } else {
+            inventory.remove(inventory_slot)
+        };
+        // Put item from the inventory in loadout
+        if let Some(item) = from_inv {
+            loadout_insert(equip_slot, item, loadout).unwrap_none(); // Can never fail
+        }
+    }
+}
+
+fn swap_loadout(slot_a: EquipSlot, slot_b: EquipSlot, loadout: &mut Loadout) {
+    // Get items from the slots
+    let item_a = loadout_remove(slot_a, loadout);
+    let item_b = loadout_remove(slot_b, loadout);
+    // Check if items can go in the other slots
+    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))
+    {
+        // Swap
+        loadout_replace(slot_b, item_a, loadout).unwrap_none();
+        loadout_replace(slot_a, item_b, loadout).unwrap_none();
+    } else {
+        // Otherwise put the items back
+        loadout_replace(slot_a, item_a, loadout).unwrap_none();
+        loadout_replace(slot_b, item_b, loadout).unwrap_none();
+    }
+}
+
+// Should this report if a change actually occurred? (might be useful when
+// minimizing network use)
+pub fn swap(
+    slot_a: Slot,
+    slot_b: Slot,
+    inventory: Option<&mut Inventory>,
+    loadout: Option<&mut Loadout>,
+) {
+    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))) {
+                swap_inventory_loadout(inv_slot, equip_slot, inventory, loadout);
+            }
+        },
+
+        (Slot::Equip(slot_a), Slot::Equip(slot_b)) => {
+            loadout.map(|l| swap_loadout(slot_a, slot_b, l));
+        },
+    }
+}
+
+pub fn equip(slot: usize, inventory: &mut Inventory, loadout: &mut Loadout) {
+    use item::{armor::Armor, ItemKind};
+
+    let equip_slot = inventory.get(slot).and_then(|i| match &i.kind {
+        ItemKind::Tool(_) => Some(EquipSlot::Mainhand),
+        ItemKind::Armor { kind, .. } => Some(EquipSlot::Armor(match kind {
+            Armor::Head(_) => ArmorSlot::Head,
+            Armor::Neck(_) => ArmorSlot::Neck,
+            Armor::Shoulder(_) => ArmorSlot::Shoulders,
+            Armor::Chest(_) => ArmorSlot::Chest,
+            Armor::Hand(_) => ArmorSlot::Hands,
+            Armor::Ring(_) => ArmorSlot::Ring,
+            Armor::Back(_) => ArmorSlot::Back,
+            Armor::Belt(_) => ArmorSlot::Belt,
+            Armor::Pants(_) => ArmorSlot::Legs,
+            Armor::Foot(_) => ArmorSlot::Feet,
+            Armor::Tabard(_) => ArmorSlot::Tabard,
+        })),
+        ItemKind::Lantern(_) => Some(EquipSlot::Lantern),
+        _ => 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 {
+            swap_loadout(EquipSlot::Mainhand, EquipSlot::Offhand, loadout);
+        }
+
+        swap_inventory_loadout(slot, equip_slot, inventory, loadout);
+    }
+}
+
+pub fn unequip(slot: EquipSlot, inventory: &mut Inventory, loadout: &mut Loadout) {
+    loadout_remove(slot, loadout) // Remove item from loadout
+        .and_then(|i| inventory.push(i)) // Insert into inventory
+        .and_then(|i| loadout_insert(slot, i, loadout)) // If that fails put back in loadout
+        .unwrap(); // Never fails
+}
diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs
index 00079da365..09f88a6a08 100644
--- a/common/src/comp/mod.rs
+++ b/common/src/comp/mod.rs
@@ -31,7 +31,7 @@ pub use controller::{
 pub use energy::{Energy, EnergySource};
 pub use inputs::CanBuild;
 pub use inventory::{
-    item, item::Item, Inventory, InventoryUpdate, InventoryUpdateEvent, MAX_PICKUP_RANGE_SQR,
+    item, item::Item, slot, Inventory, InventoryUpdate, InventoryUpdateEvent, MAX_PICKUP_RANGE_SQR,
 };
 pub use last::Last;
 pub use location::{Waypoint, WaypointArea};
diff --git a/common/src/lib.rs b/common/src/lib.rs
index 70df9a2c1d..df969e5af4 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -2,6 +2,7 @@
 #![type_length_limit = "1664759"]
 #![feature(
     arbitrary_enum_discriminant,
+    option_unwrap_none,
     bool_to_option,
     label_break_value,
     trait_alias,
diff --git a/server/src/events/inventory_manip.rs b/server/src/events/inventory_manip.rs
index 7174c15e64..9181ce12f5 100644
--- a/server/src/events/inventory_manip.rs
+++ b/server/src/events/inventory_manip.rs
@@ -1,6 +1,10 @@
 use crate::{Server, StateExt};
 use common::{
-    comp::{self, item, Pos, MAX_PICKUP_RANGE_SQR},
+    comp::{
+        self, item,
+        slot::{self, Slot},
+        Pos, MAX_PICKUP_RANGE_SQR,
+    },
     sync::WorldSyncExt,
     terrain::block::Block,
     vol::{ReadVol, Vox},
@@ -83,162 +87,145 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
             }
         },
 
-        comp::InventoryManip::Use(slot_idx) => {
-            let item_opt = state
-                .ecs()
-                .write_storage::<comp::Inventory>()
-                .get_mut(entity)
-                .and_then(|inv| inv.take(slot_idx));
+        comp::InventoryManip::Use(slot) => {
+            let mut inventories = state.ecs().write_storage::<comp::Inventory>();
+            let inventory = if let Some(inventory) = inventories.get_mut(entity) {
+                inventory
+            } else {
+                error!("Can't manipulate inventory, entity doesn't have one");
+                return;
+            };
 
-            let mut event = comp::InventoryUpdateEvent::Used;
+            let mut maybe_effect = None;
 
-            if let Some(item) = item_opt {
-                match &item.kind {
-                    item::ItemKind::Tool(tool) => {
-                        if let Some(loadout) =
-                            state.ecs().write_storage::<comp::Loadout>().get_mut(entity)
-                        {
-                            // Insert old item into inventory
-                            if let Some(old_item) = loadout.active_item.take() {
-                                state
-                                    .ecs()
-                                    .write_storage::<comp::Inventory>()
-                                    .get_mut(entity)
-                                    .map(|inv| inv.insert(slot_idx, old_item.item));
-                            }
-
-                            let mut abilities = tool.get_abilities();
-                            let mut ability_drain = abilities.drain(..);
-                            let active_item = comp::ItemConfig {
-                                item,
-                                ability1: ability_drain.next(),
-                                ability2: ability_drain.next(),
-                                ability3: ability_drain.next(),
-                                block_ability: Some(comp::CharacterAbility::BasicBlock),
-                                dodge_ability: Some(comp::CharacterAbility::Roll),
-                            };
-                            loadout.active_item = Some(active_item);
+            let event = match slot {
+                Slot::Inventory(slot) => {
+                    use item::ItemKind;
+                    // Check if item is equipable
+                    if inventory.get(slot).map_or(false, |i| match &i.kind {
+                        ItemKind::Tool(_) | ItemKind::Armor { .. } | ItemKind::Lantern(_) => true,
+                        _ => false,
+                    }) {
+                        if let Some(loadout) = state.ecs().write_storage().get_mut(entity) {
+                            slot::equip(slot, inventory, loadout);
+                            Some(comp::InventoryUpdateEvent::Used)
+                        } else {
+                            None
                         }
-                    },
-
-                    item::ItemKind::Consumable { kind, effect, .. } => {
-                        event = comp::InventoryUpdateEvent::Consumed(*kind);
-                        state.apply_effect(entity, *effect);
-                    },
-
-                    item::ItemKind::Armor { kind, .. } => {
-                        if let Some(loadout) =
-                            state.ecs().write_storage::<comp::Loadout>().get_mut(entity)
-                        {
-                            use comp::item::armor::Armor::*;
-                            let slot = match kind.clone() {
-                                Shoulder(_) => &mut loadout.shoulder,
-                                Chest(_) => &mut loadout.chest,
-                                Belt(_) => &mut loadout.belt,
-                                Hand(_) => &mut loadout.hand,
-                                Pants(_) => &mut loadout.pants,
-                                Foot(_) => &mut loadout.foot,
-                                Back(_) => &mut loadout.back,
-                                Ring(_) => &mut loadout.ring,
-                                Neck(_) => &mut loadout.neck,
-                                Lantern(_) => &mut loadout.lantern,
-                                Head(_) => &mut loadout.head,
-                                Tabard(_) => &mut loadout.tabard,
-                            };
-
-                            // Insert old item into inventory
-                            if let Some(old_item) = slot.take() {
-                                state
-                                    .ecs()
-                                    .write_storage::<comp::Inventory>()
-                                    .get_mut(entity)
-                                    .map(|inv| inv.insert(slot_idx, old_item));
-                            }
-
-                            *slot = Some(item);
-                        }
-                    },
-
-                    item::ItemKind::Utility { kind, .. } => match kind {
-                        comp::item::Utility::Collar => {
-                            let reinsert = if let Some(pos) =
-                                state.read_storage::<comp::Pos>().get(entity)
-                            {
-                                if (
-                                    &state.read_storage::<comp::Alignment>(),
-                                    &state.read_storage::<comp::Agent>(),
-                                )
-                                    .join()
-                                    .filter(|(alignment, _)| {
-                                        alignment == &&comp::Alignment::Owned(entity)
-                                    })
-                                    .count()
-                                    >= 3
+                    } else if let Some(item) = inventory.take(slot) {
+                        match &item.kind {
+                            ItemKind::Consumable { kind, effect, .. } => {
+                                maybe_effect = Some(*effect);
+                                Some(comp::InventoryUpdateEvent::Consumed(*kind))
+                            },
+                            ItemKind::Utility {
+                                kind: comp::item::Utility::Collar,
+                                ..
+                            } => {
+                                let reinsert = if let Some(pos) =
+                                    state.read_storage::<comp::Pos>().get(entity)
                                 {
-                                    true
-                                } else if let Some(tameable_entity) = {
-                                    let nearest_tameable = (
-                                        &state.ecs().entities(),
-                                        &state.ecs().read_storage::<comp::Pos>(),
-                                        &state.ecs().read_storage::<comp::Alignment>(),
+                                    if (
+                                        &state.read_storage::<comp::Alignment>(),
+                                        &state.read_storage::<comp::Agent>(),
                                     )
                                         .join()
-                                        .filter(|(_, wild_pos, _)| {
-                                            wild_pos.0.distance_squared(pos.0) < 5.0f32.powf(2.0)
+                                        .filter(|(alignment, _)| {
+                                            alignment == &&comp::Alignment::Owned(entity)
                                         })
-                                        .filter(|(_, _, alignment)| {
-                                            alignment == &&comp::Alignment::Wild
-                                        })
-                                        .min_by_key(|(_, wild_pos, _)| {
-                                            (wild_pos.0.distance_squared(pos.0) * 100.0) as i32
-                                        })
-                                        .map(|(entity, _, _)| entity);
-                                    nearest_tameable
-                                } {
-                                    let _ = state
-                                        .ecs()
-                                        .write_storage()
-                                        .insert(tameable_entity, comp::Alignment::Owned(entity));
-                                    let _ = state
-                                        .ecs()
-                                        .write_storage()
-                                        .insert(tameable_entity, comp::Agent::default());
-                                    false
+                                        .count()
+                                        >= 3
+                                    {
+                                        true
+                                    } else if let Some(tameable_entity) = {
+                                        let nearest_tameable = (
+                                            &state.ecs().entities(),
+                                            &state.ecs().read_storage::<comp::Pos>(),
+                                            &state.ecs().read_storage::<comp::Alignment>(),
+                                        )
+                                            .join()
+                                            .filter(|(_, wild_pos, _)| {
+                                                wild_pos.0.distance_squared(pos.0)
+                                                    < 5.0f32.powf(2.0)
+                                            })
+                                            .filter(|(_, _, alignment)| {
+                                                alignment == &&comp::Alignment::Wild
+                                            })
+                                            .min_by_key(|(_, wild_pos, _)| {
+                                                (wild_pos.0.distance_squared(pos.0) * 100.0) as i32
+                                            })
+                                            .map(|(entity, _, _)| entity);
+                                        nearest_tameable
+                                    } {
+                                        let _ = state.ecs().write_storage().insert(
+                                            tameable_entity,
+                                            comp::Alignment::Owned(entity),
+                                        );
+                                        let _ = state
+                                            .ecs()
+                                            .write_storage()
+                                            .insert(tameable_entity, comp::Agent::default());
+                                        false
+                                    } else {
+                                        true
+                                    }
                                 } else {
                                     true
+                                };
+
+                                if reinsert {
+                                    let _ = state
+                                        .ecs()
+                                        .write_storage::<comp::Inventory>()
+                                        .get_mut(entity)
+                                        .map(|inv| inv.insert(slot, item));
                                 }
-                            } else {
-                                true
-                            };
 
-                            if reinsert {
-                                let _ = state
-                                    .ecs()
-                                    .write_storage::<comp::Inventory>()
-                                    .get_mut(entity)
-                                    .map(|inv| inv.insert(slot_idx, item));
-                            }
-                        },
-                    },
-                    _ => {
-                        let _ = state
-                            .ecs()
-                            .write_storage::<comp::Inventory>()
-                            .get_mut(entity)
-                            .map(|inv| inv.insert(slot_idx, item));
-                    },
-                }
+                                Some(comp::InventoryUpdateEvent::Used)
+                            },
+                            _ => {
+                                // TODO: this doesn't work for stackable items
+                                inventory.insert(slot, item).unwrap();
+                                None
+                            },
+                        }
+                    } else {
+                        None
+                    }
+                },
+                Slot::Equip(slot) => {
+                    if let Some(loadout) = state.ecs().write_storage().get_mut(entity) {
+                        slot::unequip(slot, inventory, loadout);
+                        Some(comp::InventoryUpdateEvent::Used)
+                    } else {
+                        error!("Entity doesn't have a loadout, can't unequip...");
+                        None
+                    }
+                },
+            };
+
+            drop(inventories);
+            if let Some(effect) = maybe_effect {
+                state.apply_effect(entity, effect);
+            }
+            if let Some(event) = event {
+                state.write_component(entity, comp::InventoryUpdate::new(event));
             }
-
-            state.write_component(entity, comp::InventoryUpdate::new(event));
         },
 
         comp::InventoryManip::Swap(a, b) => {
-            state
-                .ecs()
-                .write_storage::<comp::Inventory>()
-                .get_mut(entity)
-                .map(|inv| inv.swap_slots(a, b));
+            let ecs = state.ecs();
+            let mut inventories = ecs.write_storage();
+            let mut loadouts = ecs.write_storage();
+            let inventory = inventories.get_mut(entity);
+            let loadout = loadouts.get_mut(entity);
+
+            slot::swap(a, b, inventory, loadout);
+
+            // :/
+            drop(loadouts);
+            drop(inventories);
+
             state.write_component(
                 entity,
                 comp::InventoryUpdate::new(comp::InventoryUpdateEvent::Swapped),
@@ -246,11 +233,18 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
         },
 
         comp::InventoryManip::Drop(slot) => {
-            let item = state
-                .ecs()
-                .write_storage::<comp::Inventory>()
-                .get_mut(entity)
-                .and_then(|inv| inv.remove(slot));
+            let item = match slot {
+                Slot::Inventory(slot) => state
+                    .ecs()
+                    .write_storage::<comp::Inventory>()
+                    .get_mut(entity)
+                    .and_then(|inv| inv.remove(slot)),
+                Slot::Equip(slot) => state
+                    .ecs()
+                    .write_storage()
+                    .get_mut(entity)
+                    .and_then(|ldt| slot::loadout_remove(slot, ldt)),
+            };
 
             if let (Some(item), Some(pos)) =
                 (item, state.ecs().read_storage::<comp::Pos>().get(entity))
diff --git a/voxygen/src/hud/bag.rs b/voxygen/src/hud/bag.rs
index d7d54e61e3..09f8209ee8 100644
--- a/voxygen/src/hud/bag.rs
+++ b/voxygen/src/hud/bag.rs
@@ -1,9 +1,8 @@
 use super::{
     img_ids::{Imgs, ImgsRot},
     item_imgs::ItemImgs,
-    slots::{ArmorSlot, InventorySlot, SlotManager},
-    Event as HudEvent, Show, CRITICAL_HP_COLOR, LOW_HP_COLOR, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN,
-    XP_COLOR,
+    slots::{ArmorSlot, EquipSlot, InventorySlot, SlotManager},
+    Show, CRITICAL_HP_COLOR, LOW_HP_COLOR, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, XP_COLOR,
 };
 use crate::{
     i18n::VoxygenLocalization,
@@ -135,7 +134,6 @@ pub struct State {
 }
 
 pub enum Event {
-    HudEvent(HudEvent),
     Stats,
     Close,
 }
@@ -350,7 +348,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Head, [45.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Head), [45.0; 2])
                 .mid_top_with_margin_on(state.ids.bg_frame, 60.0)
                 .with_icon(self.imgs.head_bg, Vec2::new(32.0, 40.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -363,7 +361,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Neck, [45.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Neck), [45.0; 2])
                 .mid_bottom_with_margin_on(state.ids.head_slot, -55.0)
                 .with_icon(self.imgs.necklace_bg, Vec2::new(40.0, 31.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -377,7 +375,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Chest, [85.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Chest), [85.0; 2])
                 .mid_bottom_with_margin_on(state.ids.neck_slot, -95.0)
                 .with_icon(self.imgs.chest_bg, Vec2::new(64.0, 42.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -388,7 +386,7 @@ impl<'a> Widget for Bag<'a> {
                 |item| (item.name(), item.description()),
             );
             slot_maker
-                .fabricate(ArmorSlot::Shoulders, [70.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Shoulders), [70.0; 2])
                 .bottom_left_with_margins_on(state.ids.chest_slot, 0.0, -80.0)
                 .with_icon(self.imgs.shoulders_bg, Vec2::new(60.0, 36.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -401,7 +399,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Hands, [70.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Hands), [70.0; 2])
                 .bottom_right_with_margins_on(state.ids.chest_slot, 0.0, -80.0)
                 .with_icon(self.imgs.hands_bg, Vec2::new(55.0, 60.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -414,7 +412,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Belt, [45.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Belt), [45.0; 2])
                 .mid_bottom_with_margin_on(state.ids.chest_slot, -55.0)
                 .with_icon(self.imgs.belt_bg, Vec2::new(40.0, 23.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -427,7 +425,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Legs, [85.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Legs), [85.0; 2])
                 .mid_bottom_with_margin_on(state.ids.belt_slot, -95.0)
                 .with_icon(self.imgs.legs_bg, Vec2::new(48.0, 70.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -438,7 +436,7 @@ impl<'a> Widget for Bag<'a> {
                 |item| (item.name(), item.description()),
             );
             slot_maker
-                .fabricate(ArmorSlot::Lantern, [45.0; 2])
+                .fabricate(EquipSlot::Lantern, [45.0; 2])
                 .bottom_right_with_margins_on(state.ids.shoulders_slot, -55.0, 0.0)
                 .with_icon(self.imgs.lantern_bg, Vec2::new(24.0, 38.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -451,7 +449,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Ring, [45.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Ring), [45.0; 2])
                 .bottom_left_with_margins_on(state.ids.hands_slot, -55.0, 0.0)
                 .with_icon(self.imgs.ring_bg, Vec2::new(36.0, 40.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -464,7 +462,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Back, [45.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Back), [45.0; 2])
                 .down_from(state.ids.lantern_slot, 10.0)
                 .with_icon(self.imgs.back_bg, Vec2::new(33.0, 40.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -477,7 +475,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Feet, [45.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Feet), [45.0; 2])
                 .down_from(state.ids.ring_slot, 10.0)
                 .with_icon(self.imgs.feet_bg, Vec2::new(32.0, 40.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -490,7 +488,7 @@ impl<'a> Widget for Bag<'a> {
                     (item.name(), item.description())
                 });
             slot_maker
-                .fabricate(ArmorSlot::Tabard, [70.0; 2])
+                .fabricate(EquipSlot::Armor(ArmorSlot::Tabard), [70.0; 2])
                 .top_right_with_margins_on(state.ids.bg_frame, 80.5, 53.0)
                 .with_icon(self.imgs.tabard_bg, Vec2::new(60.0, 60.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -501,7 +499,7 @@ impl<'a> Widget for Bag<'a> {
                 |item| (item.name(), item.description()),
             );
             slot_maker
-                .fabricate(ArmorSlot::Mainhand, [85.0; 2])
+                .fabricate(EquipSlot::Mainhand, [85.0; 2])
                 .bottom_right_with_margins_on(state.ids.back_slot, -95.0, 0.0)
                 .with_icon(self.imgs.mainhand_bg, Vec2::new(75.0, 75.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -512,7 +510,7 @@ impl<'a> Widget for Bag<'a> {
                 |item| (item.name(), item.description()),
             );
             slot_maker
-                .fabricate(ArmorSlot::Offhand, [85.0; 2])
+                .fabricate(EquipSlot::Offhand, [85.0; 2])
                 .bottom_left_with_margins_on(state.ids.feet_slot, -95.0, 0.0)
                 .with_icon(self.imgs.offhand_bg, Vec2::new(75.0, 75.0), Some(UI_MAIN))
                 .with_tooltip(self.tooltip_manager, title, desc, &item_tooltip)
@@ -681,9 +679,6 @@ impl<'a> Widget for Bag<'a> {
             }
         }
 
-        // Drop selected item
-        //    if ui.widget_input(ui.window).clicks().left().next().is_some() {
-
         // Stats Button
         if Button::image(self.imgs.button)
             .w_h(92.0, 22.0)
diff --git a/voxygen/src/hud/item_imgs.rs b/voxygen/src/hud/item_imgs.rs
index 647c91d3ac..3c76f58087 100644
--- a/voxygen/src/hud/item_imgs.rs
+++ b/voxygen/src/hud/item_imgs.rs
@@ -4,7 +4,7 @@ use common::{
     comp::item::{
         armor::Armor,
         tool::{Tool, ToolKind},
-        Consumable, Ingredient, Item, ItemKind, Utility,
+        Consumable, Ingredient, Item, ItemKind, Lantern, Utility,
     },
     figure::Segment,
 };
@@ -20,6 +20,7 @@ use vek::*;
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub enum ItemKey {
     Tool(ToolKind),
+    Lantern(Lantern),
     Armor(Armor),
     Utility(Utility),
     Consumable(Consumable),
@@ -30,6 +31,7 @@ impl From<&Item> for ItemKey {
     fn from(item: &Item) -> Self {
         match &item.kind {
             ItemKind::Tool(Tool { kind, .. }) => ItemKey::Tool(kind.clone()),
+            ItemKind::Lantern(kind) => ItemKey::Lantern(kind.clone()),
             ItemKind::Armor { kind, .. } => ItemKey::Armor(kind.clone()),
             ItemKind::Utility { kind, .. } => ItemKey::Utility(kind.clone()),
             ItemKind::Consumable { kind, .. } => ItemKey::Consumable(kind.clone()),
diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs
index 44eaea390f..93e67ff70f 100644
--- a/voxygen/src/hud/mod.rs
+++ b/voxygen/src/hud/mod.rs
@@ -232,11 +232,9 @@ pub enum Event {
     ToggleDebug(bool),
     UiScale(ScaleChange),
     CharacterSelection,
-    UseInventorySlot(usize),
-    SwapInventorySlots(usize, usize),
-    SwapInventoryArmor(usize, slots::ArmorSlot),
-    SwapArmorSlots(slots::ArmorSlot, slots::ArmorSlot),
-    DropInventorySlot(usize),
+    UseSlot(comp::slot::Slot),
+    SwapSlots(comp::slot::Slot, comp::slot::Slot),
+    DropSlot(comp::slot::Slot),
     Logout,
     Quit,
     ChangeLanguage(LanguageMetadata),
@@ -1660,7 +1658,6 @@ impl Hud {
             )
             .set(self.ids.bag, ui_widgets)
             {
-                Some(bag::Event::HudEvent(event)) => events.push(event),
                 Some(bag::Event::Stats) => self.show.stats = !self.show.stats,
                 Some(bag::Event::Close) => {
                     self.show.bag(false);
@@ -1961,30 +1958,32 @@ impl Hud {
 
         // Maintain slot manager
         for event in self.slot_manager.maintain(ui_widgets) {
+            use comp::slot::Slot;
             use slots::SlotKind;
+            let to_slot = |slot_kind| match slot_kind {
+                SlotKind::Inventory(i) => Some(Slot::Inventory(i.0)),
+                SlotKind::Equip(e) => Some(Slot::Equip(e)),
+                //SlotKind::Hotbar(h) => None,
+            };
             match event {
-                slot::Event::Dragged(SlotKind::Inventory(from), SlotKind::Inventory(to)) => {
-                    // Swap between inventory slots
-                    events.push(Event::SwapInventorySlots(from.0, to.0));
+                slot::Event::Dragged(a, b) => {
+                    // Swap between slots
+                    if let (Some(a), Some(b)) = (to_slot(a), to_slot(b)) {
+                        events.push(Event::SwapSlots(a, b));
+                    }
                 },
-                slot::Event::Dragged(SlotKind::Armor(from), SlotKind::Armor(to)) => {
-                    // Swap between two armor slots
-                    events.push(Event::SwapArmorSlots(from, to));
+                slot::Event::Dropped(from) => {
+                    // Drop item
+                    if let Some(from) = to_slot(from) {
+                        events.push(Event::DropSlot(from));
+                    }
                 },
-                slot::Event::Dragged(SlotKind::Inventory(inv), SlotKind::Armor(arm))
-                | slot::Event::Dragged(SlotKind::Armor(arm), SlotKind::Inventory(inv)) => {
-                    // Swap between inventory and armor slot
-                    events.push(Event::SwapInventoryArmor(inv.0, arm));
+                slot::Event::Used(from) => {
+                    // Item used (selected and then clicked again)
+                    if let Some(from) = to_slot(from) {
+                        events.push(Event::UseSlot(from));
+                    }
                 },
-                slot::Event::Dropped(SlotKind::Inventory(from)) => {
-                    // Drop item from inventory
-                    events.push(Event::DropInventorySlot(from.0));
-                },
-                slot::Event::Used(SlotKind::Inventory(inv)) => {
-                    // Item in inventory used (selected and then clicked again)
-                    events.push(Event::UseInventorySlot(inv.0));
-                },
-                _ => {},
             }
         }
 
diff --git a/voxygen/src/hud/slots.rs b/voxygen/src/hud/slots.rs
index 398abca975..3e22307cbd 100644
--- a/voxygen/src/hud/slots.rs
+++ b/voxygen/src/hud/slots.rs
@@ -3,10 +3,12 @@ use crate::ui::slot::{self, SlotKey, SumSlot};
 use common::comp::{item::ItemKind, Inventory, Loadout};
 use conrod_core::image;
 
+pub use common::comp::slot::{ArmorSlot, EquipSlot};
+
 #[derive(Clone, Copy, PartialEq)]
 pub enum SlotKind {
     Inventory(InventorySlot),
-    Armor(ArmorSlot),
+    Equip(EquipSlot),
     /*Hotbar(HotbarSlot),
      *Spellbook(SpellbookSlot), TODO */
 }
@@ -16,24 +18,6 @@ pub type SlotManager = slot::SlotManager<SlotKind>;
 #[derive(Clone, Copy, PartialEq)]
 pub struct InventorySlot(pub usize);
 
-#[derive(Clone, Copy, PartialEq)]
-pub enum ArmorSlot {
-    Head,
-    Neck,
-    Shoulders,
-    Chest,
-    Hands,
-    Ring,
-    Lantern,
-    Back,
-    Belt,
-    Legs,
-    Feet,
-    Mainhand,
-    Offhand,
-    Tabard,
-}
-
 /*#[derive(Clone, Copy, PartialEq)]
 pub enum HotbarSlot {
     One,
@@ -59,7 +43,7 @@ impl SlotKey<Inventory, ItemImgs> for InventorySlot {
         source
             .get(self.0)
             .and_then(|item| match item.kind {
-                ItemKind::Tool { .. } | ItemKind::Armor { .. } => None,
+                ItemKind::Tool { .. } | ItemKind::Lantern(_) | ItemKind::Armor { .. } => None,
                 ItemKind::Utility { amount, .. }
                 | ItemKind::Consumable { amount, .. }
                 | ItemKind::Ingredient { amount, .. } => Some(amount),
@@ -72,26 +56,25 @@ impl SlotKey<Inventory, ItemImgs> for InventorySlot {
     }
 }
 
-impl SlotKey<Loadout, ItemImgs> for ArmorSlot {
+impl SlotKey<Loadout, ItemImgs> for EquipSlot {
     type ImageKey = ItemKey;
 
     fn image_key(&self, source: &Loadout) -> Option<Self::ImageKey> {
         let item = match self {
-            ArmorSlot::Shoulders => source.shoulder.as_ref(),
-            ArmorSlot::Chest => source.chest.as_ref(),
-            ArmorSlot::Belt => source.belt.as_ref(),
-            ArmorSlot::Hands => source.hand.as_ref(),
-            ArmorSlot::Legs => source.pants.as_ref(),
-            ArmorSlot::Feet => source.foot.as_ref(),
-            ArmorSlot::Back => source.back.as_ref(),
-            ArmorSlot::Ring => source.ring.as_ref(),
-            ArmorSlot::Neck => source.neck.as_ref(),
-            ArmorSlot::Head => source.head.as_ref(),
-            ArmorSlot::Lantern => source.lantern.as_ref(),
-            ArmorSlot::Tabard => source.tabard.as_ref(),
-            ArmorSlot::Mainhand => source.active_item.as_ref().map(|i| &i.item),
-            ArmorSlot::Offhand => source.second_item.as_ref().map(|i| &i.item),
-            _ => None,
+            EquipSlot::Armor(ArmorSlot::Shoulders) => source.shoulder.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Chest) => source.chest.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Belt) => source.belt.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Hands) => source.hand.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Legs) => source.pants.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Feet) => source.foot.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Back) => source.back.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Ring) => source.ring.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Neck) => source.neck.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Head) => source.head.as_ref(),
+            EquipSlot::Armor(ArmorSlot::Tabard) => source.tabard.as_ref(),
+            EquipSlot::Mainhand => source.active_item.as_ref().map(|i| &i.item),
+            EquipSlot::Offhand => source.second_item.as_ref().map(|i| &i.item),
+            EquipSlot::Lantern => source.lantern.as_ref(),
         };
 
         item.map(Into::into)
@@ -132,8 +115,8 @@ impl From<InventorySlot> for SlotKind {
     fn from(inventory: InventorySlot) -> Self { Self::Inventory(inventory) }
 }
 
-impl From<ArmorSlot> for SlotKind {
-    fn from(armor: ArmorSlot) -> Self { Self::Armor(armor) }
+impl From<EquipSlot> for SlotKind {
+    fn from(equip: EquipSlot) -> Self { Self::Equip(equip) }
 }
 
 //impl From<HotbarSlot> for SlotKind {
diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs
index 7bfac88f5e..6c3d24a37a 100644
--- a/voxygen/src/scene/figure/load.rs
+++ b/voxygen/src/scene/figure/load.rs
@@ -12,9 +12,9 @@ use common::{
         dragon, fish_medium, fish_small,
         humanoid::{Body, BodyType, EyeColor, Eyebrows, Race, Skin},
         item::{
-            armor::{Armor, Back, Belt, Chest, Foot, Hand, Head, Lantern, Pants, Shoulder, Tabard},
+            armor::{Armor, Back, Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Tabard},
             tool::{Tool, ToolKind},
-            ItemKind,
+            ItemKind, Lantern,
         },
         object,
         quadruped_medium::{BodyType as QMBodyType, Species as QMSpecies},
@@ -701,21 +701,18 @@ impl HumArmorLanternSpec {
     }
 
     pub fn mesh_lantern(&self, body: &Body, loadout: &Loadout) -> Mesh<FigurePipeline> {
-        let spec = if let Some(ItemKind::Armor {
-            kind: Armor::Lantern(lantern),
-            ..
-        }) = loadout.lantern.as_ref().map(|i| &i.kind)
-        {
-            match self.0.map.get(&lantern) {
-                Some(spec) => spec,
-                None => {
-                    error!("No lantern specification exists for {:?}", lantern);
-                    return load_mesh("not_found", Vec3::new(-4.0, -3.5, 2.0));
-                },
-            }
-        } else {
-            &self.0.default
-        };
+        let spec =
+            if let Some(ItemKind::Lantern(lantern)) = loadout.lantern.as_ref().map(|i| &i.kind) {
+                match self.0.map.get(&lantern) {
+                    Some(spec) => spec,
+                    None => {
+                        error!("No lantern specification exists for {:?}", lantern);
+                        return load_mesh("not_found", Vec3::new(-4.0, -3.5, 2.0));
+                    },
+                }
+            } else {
+                &self.0.default
+            };
 
         let lantern_segment = color_segment(
             graceful_load_mat_segment(&spec.vox_spec.0),
diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs
index 380a108603..80b121c897 100644
--- a/voxygen/src/session.rs
+++ b/voxygen/src/session.rs
@@ -643,22 +643,9 @@ impl PlayState for SessionState {
                         global_state.settings.graphics.max_fps = fps;
                         global_state.settings.save_to_file_warn();
                     },
-                    HudEvent::UseInventorySlot(x) => self.client.borrow_mut().use_inventory_slot(x),
-                    HudEvent::SwapInventorySlots(a, b) => {
-                        self.client.borrow_mut().swap_inventory_slots(a, b)
-                    },
-                    HudEvent::SwapInventoryArmor(inv_slot, armor_slot) => {
-                        // Swapping between inventory and armor slot
-                        // TODO: don't do this
-                        self.client.borrow_mut().use_inventory_slot(inv_slot)
-                    },
-                    HudEvent::SwapArmorSlots(from, to) => {
-                        // Only works with rings currently
-                        // TODO: implement
-                    },
-                    HudEvent::DropInventorySlot(x) => {
-                        self.client.borrow_mut().drop_inventory_slot(x)
-                    },
+                    HudEvent::UseSlot(x) => self.client.borrow_mut().use_slot(x),
+                    HudEvent::SwapSlots(a, b) => self.client.borrow_mut().swap_slots(a, b),
+                    HudEvent::DropSlot(x) => self.client.borrow_mut().drop_slot(x),
                     HudEvent::ChangeFOV(new_fov) => {
                         global_state.settings.graphics.fov = new_fov;
                         global_state.settings.save_to_file_warn();
diff --git a/voxygen/src/ui/widgets/slot.rs b/voxygen/src/ui/widgets/slot.rs
index 59576ce5b3..0da5ceae01 100644
--- a/voxygen/src/ui/widgets/slot.rs
+++ b/voxygen/src/ui/widgets/slot.rs
@@ -153,9 +153,9 @@ where
             }
         }
 
-        // If dragging and mouse if released check if there is a slot widget under the
+        // If dragging and mouse is released check if there is a slot widget under the
         // mouse
-        if let ManagerState::Dragging(id, slot, content_img) = &self.state {
+        if let ManagerState::Dragging(_, slot, content_img) = &self.state {
             let content_img = *content_img;
             let input = &ui.global_input().current;
             if let mouse::ButtonPosition::Up = input.mouse.buttons.left() {