diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 1c8f252ed41..e717b93623a 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -83,27 +83,31 @@
if(!..()) //a check failed or the item has already found its slot
return
- var/current_equip
+ var/obj/item/current_equip
var/not_handled = FALSE //Added in case we make this type path deeper one day
switch(slot)
if(ITEM_SLOT_BELT)
if (belt && swap)
+ belt.dropped(src, TRUE)
current_equip = belt
belt = I
update_inv_belt()
if(ITEM_SLOT_ID)
if (wear_id && swap)
+ wear_id.dropped(src, TRUE)
current_equip = wear_id
wear_id = I
sec_hud_set_ID()
update_inv_wear_id()
if(ITEM_SLOT_EARS)
if (ears && swap)
+ ears.dropped(src, TRUE)
current_equip = ears
ears = I
update_inv_ears()
if(ITEM_SLOT_EYES)
if (glasses && swap)
+ glasses.dropped(src, TRUE)
current_equip = glasses
glasses = I
var/obj/item/clothing/glasses/G = I
@@ -118,16 +122,19 @@
update_inv_glasses()
if(ITEM_SLOT_GLOVES)
if (gloves && swap)
+ gloves.dropped(src, TRUE)
current_equip = gloves
gloves = I
update_inv_gloves()
if(ITEM_SLOT_FEET)
if (shoes && swap)
+ shoes.dropped(src, TRUE)
current_equip = shoes
shoes = I
update_inv_shoes()
if(ITEM_SLOT_OCLOTHING)
if (wear_suit && swap)
+ wear_suit.dropped(src, TRUE)
current_equip = wear_suit
wear_suit = I
if(I.flags_inv & HIDEJUMPSUIT)
@@ -138,6 +145,7 @@
update_inv_wear_suit()
if(ITEM_SLOT_ICLOTHING)
if (w_uniform && swap)
+ w_uniform.dropped(src, TRUE)
current_equip = w_uniform
w_uniform = I
update_suit_sensors()
@@ -150,6 +158,7 @@
update_inv_pockets()
if(ITEM_SLOT_SUITSTORE)
if (s_store && swap)
+ s_store.dropped(src, TRUE)
current_equip = s_store
s_store = I
update_inv_s_store()
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index df83aea6a9b..1a235723b76 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -920,50 +920,44 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(!I.species_exception || !is_type_in_list(src, I.species_exception))
return FALSE
+ var/obj/item/replaced_item = H.get_item_by_slot(slot)
+
+ // if there's an item in the slot we want, only allow past this if we're trying to swap and the item being replaced isn't NODROP or ABSTRACT
+ if(replaced_item && (!swap || (HAS_TRAIT(replaced_item, TRAIT_NODROP) || (replaced_item.item_flags & ABSTRACT))))
+ return FALSE
+
+ // this check prevents us from equipping something to a slot it doesn't support, WITH the exceptions of storage slots (pockets, suit storage, and backpacks)
+ // we don't require having those slots defined in the item's slot_flags, so we'll rely on their own checks further down
+ if(!(I.slot_flags & slot))
+ var/excused = FALSE
+ // Anything that's small or smaller can fit into a pocket by default
+ if((slot == ITEM_SLOT_RPOCKET || slot == ITEM_SLOT_LPOCKET) && I.w_class <= WEIGHT_CLASS_SMALL)
+ excused = TRUE
+ else if(slot == ITEM_SLOT_SUITSTORE || slot == ITEM_SLOT_BACKPACK)
+ excused = TRUE
+ if(!excused)
+ return FALSE
+
switch(slot)
if(ITEM_SLOT_HANDS)
if(H.get_empty_held_indexes())
return TRUE
return FALSE
if(ITEM_SLOT_MASK)
- if(H.wear_mask && !swap)
- return FALSE
- if(!(I.slot_flags & ITEM_SLOT_MASK))
- return FALSE
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_NECK)
- if(H.wear_neck && !swap)
- return FALSE
- if( !(I.slot_flags & ITEM_SLOT_NECK) )
- return FALSE
return TRUE
if(ITEM_SLOT_BACK)
- if(H.back && !swap)
- return FALSE
- if( !(I.slot_flags & ITEM_SLOT_BACK) )
- return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_OCLOTHING)
- if(H.wear_suit && !swap)
- return FALSE
- if( !(I.slot_flags & ITEM_SLOT_OCLOTHING) )
- return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_GLOVES)
- if(H.gloves && !swap)
- return FALSE
- if( !(I.slot_flags & ITEM_SLOT_GLOVES) )
- return FALSE
if(H.num_hands < 2)
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_FEET)
- if(H.shoes && !swap)
- return FALSE
- if( !(I.slot_flags & ITEM_SLOT_FEET) )
- return FALSE
if(H.num_legs < 2)
return FALSE
if(DIGITIGRADE in species_traits)
@@ -972,23 +966,14 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_BELT)
- if(H.belt && !swap)
- return FALSE
-
var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST)
if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC))
if(!disable_warning)
to_chat(H, "You need a jumpsuit before you can attach this [I.name]!")
return FALSE
- if(!(I.slot_flags & ITEM_SLOT_BELT))
- return
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_EYES)
- if(H.glasses && !swap)
- return FALSE
- if(!(I.slot_flags & ITEM_SLOT_EYES))
- return FALSE
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
@@ -996,43 +981,26 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_HEAD)
- if(H.head && !swap)
- return FALSE
- if(!(I.slot_flags & ITEM_SLOT_HEAD))
- return FALSE
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_EARS)
- if(H.ears && !swap)
- return FALSE
- if(!(I.slot_flags & ITEM_SLOT_EARS))
- return FALSE
if(!H.get_bodypart(BODY_ZONE_HEAD))
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_ICLOTHING)
- if(H.w_uniform && !swap)
- return FALSE
- if( !(I.slot_flags & ITEM_SLOT_ICLOTHING) )
- return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_ID)
- if(H.wear_id && !swap)
- return FALSE
-
var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_CHEST)
if(!H.w_uniform && !nojumpsuit && (!O || O.status != BODYPART_ROBOTIC))
if(!disable_warning)
to_chat(H, "You need a jumpsuit before you can attach this [I.name]!")
return FALSE
- if( !(I.slot_flags & ITEM_SLOT_ID) )
- return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(ITEM_SLOT_LPOCKET)
if(HAS_TRAIT(I, TRAIT_NODROP)) //Pockets aren't visible, so you can't move TRAIT_NODROP items into them.
return FALSE
- if(H.l_store)
+ if(H.l_store) // no pocket swaps at all
return FALSE
var/obj/item/bodypart/O = H.get_bodypart(BODY_ZONE_L_LEG)
@@ -1041,8 +1009,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(!disable_warning)
to_chat(H, "You need a jumpsuit before you can attach this [I.name]!")
return FALSE
- if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_LPOCKET) )
- return TRUE
+ return TRUE
if(ITEM_SLOT_RPOCKET)
if(HAS_TRAIT(I, TRAIT_NODROP))
return FALSE
@@ -1055,14 +1022,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(!disable_warning)
to_chat(H, "You need a jumpsuit before you can attach this [I.name]!")
return FALSE
- if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_RPOCKET) )
- return TRUE
- return FALSE
+ return TRUE
if(ITEM_SLOT_SUITSTORE)
if(HAS_TRAIT(I, TRAIT_NODROP))
return FALSE
- if(H.s_store && !swap)
- return FALSE
if(!H.wear_suit)
if(!disable_warning)
to_chat(H, "You need a suit before you can attach this [I.name]!")
@@ -1079,25 +1042,20 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return TRUE
return FALSE
if(ITEM_SLOT_HANDCUFFED)
- if(H.handcuffed)
- return FALSE
if(!istype(I, /obj/item/restraints/handcuffs))
return FALSE
if(H.num_hands < 2)
return FALSE
return TRUE
if(ITEM_SLOT_LEGCUFFED)
- if(H.legcuffed)
- return FALSE
if(!istype(I, /obj/item/restraints/legcuffs))
return FALSE
if(H.num_legs < 2)
return FALSE
return TRUE
if(ITEM_SLOT_BACKPACK)
- if(H.back)
- if(SEND_SIGNAL(H.back, COMSIG_TRY_STORAGE_CAN_INSERT, I, H, TRUE))
- return TRUE
+ if(H.back && SEND_SIGNAL(H.back, COMSIG_TRY_STORAGE_CAN_INSERT, I, H, TRUE))
+ return TRUE
return FALSE
return FALSE //Unsupported slot
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index dfcd3a826ee..2248c225816 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -49,26 +49,30 @@
I.plane = ABOVE_HUD_PLANE
I.appearance_flags |= NO_CLIENT_COLOR
var/not_handled = FALSE
- var/current_equip
+ var/obj/item/current_equip
switch(slot)
if(ITEM_SLOT_BACK)
if (back && swap)
+ back.dropped(src, TRUE)
current_equip = back
back = I
update_inv_back()
if(ITEM_SLOT_MASK)
if (wear_mask && swap)
+ wear_mask.dropped(src, TRUE)
current_equip = wear_mask
wear_mask = I
wear_mask_update(I, toggle_off = 0)
if(ITEM_SLOT_HEAD)
if (head && swap)
+ head.dropped(src, TRUE)
current_equip = head
head = I
SEND_SIGNAL(src, COMSIG_CARBON_EQUIP_HAT, I)
head_update(I)
if(ITEM_SLOT_NECK)
if (wear_neck && swap)
+ wear_neck.dropped(src, TRUE)
current_equip = wear_neck
wear_neck = I
update_inv_neck(I)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index d5df002705c..bd5e4ffe28c 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -336,9 +336,8 @@
if(!W.mob_can_equip(src, null, slot, disable_warning, bypass_equip_delay_self, swap))
if(qdel_on_fail)
qdel(W)
- else
- if(!disable_warning)
- to_chat(src, "You are unable to equip that!")
+ else if(!disable_warning)
+ to_chat(src, "You are unable to equip that!")
return FALSE
equip_to_slot(W, slot, initial, redraw_mob, swap) //This proc should not ever fail.
return TRUE