mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
[MIRROR] Fixes quickswap letting you keep clothing traits (#542)
* Fixes quickswap letting you keep clothing traits (#52790) Unequipping clothing via quickswap now properly calls dropped(), so you lose any traits you get for wearing them. This fixes being able to use the quickswap hotkey to keep traits and other properties like krav maga, sec/med/diagnostic hud's, and whatever else without actually wearing the clothing. Fixes: #52788 Fixes: #50798 Why It's Good For The Game Honestly for my money, a quickswap hotkey is lame and overly gamey, which is funny because the kind of player who would be into that is exactly the kind of player I'd suspect of quietly abusing a bug like this bug for the last several months, but I digress. Changelog cl Ryll/Shaps fix: Quickswapping clothing now properly unequips the swapped-out clothing, removing any traits they granted while worn /cl * Fixes quickswap letting you keep clothing traits Co-authored-by: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com>
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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, "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>")
|
||||
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, "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>")
|
||||
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, "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>")
|
||||
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, "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>")
|
||||
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, "<span class='warning'>You need a suit before you can attach this [I.name]!</span>")
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, "<span class='warning'>You are unable to equip that!</span>")
|
||||
else if(!disable_warning)
|
||||
to_chat(src, "<span class='warning'>You are unable to equip that!</span>")
|
||||
return FALSE
|
||||
equip_to_slot(W, slot, initial, redraw_mob, swap) //This proc should not ever fail.
|
||||
return TRUE
|
||||
|
||||
Reference in New Issue
Block a user