Removes persistence of items through changing species when not allowed to (#70008)

* Removes persistence of species-restricted items through changing

Makes use of item's mob_can_equip instead of mob's can_equip, making it take the item's restrictions into account.

Also, fixes the inventory's color, so it's properly red when you can't equip such an item, by making it also use mob_can_equip.

Finally, expands the species clothing unit test to take that into account, to prevent it breaking in the future.
This commit is contained in:
John Willard
2022-09-21 10:32:33 -07:00
committed by GitHub
parent 1f4e8eaab8
commit a0442ee002
9 changed files with 32 additions and 32 deletions
+1 -1
View File
@@ -179,7 +179,7 @@
var/image/item_overlay = image(holding)
item_overlay.alpha = 92
if(!user.can_equip(holding, slot_id, disable_warning = TRUE, bypass_equip_delay_self = TRUE))
if(!holding.mob_can_equip(user, slot_id, disable_warning = TRUE, bypass_equip_delay_self = TRUE))
item_overlay.color = "#FF0000"
else
item_overlay.color = "#00ff00"
+2 -14
View File
@@ -225,13 +225,7 @@
if (!ismob(source))
return FALSE
if (!equipping.mob_can_equip(
source,
user,
item_slot,
disable_warning = TRUE,
bypass_equip_delay_self = TRUE,
))
if (!equipping.mob_can_equip(source, item_slot, disable_warning = TRUE, bypass_equip_delay_self = TRUE))
to_chat(user, span_warning("\The [equipping] doesn't fit in that place!"))
return FALSE
@@ -248,13 +242,7 @@
if (!do_mob(user, source, get_equip_delay(equipping)))
return FALSE
if (!equipping.mob_can_equip(
source,
user,
item_slot,
disable_warning = TRUE,
bypass_equip_delay_self = TRUE,
))
if (!equipping.mob_can_equip(source, item_slot, disable_warning = TRUE, bypass_equip_delay_self = TRUE))
return FALSE
if (!user.temporarilyRemoveItemFromInventory(equipping))
+2 -3
View File
@@ -718,14 +718,13 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons
* Arguments:
* * disable_warning to TRUE if you wish it to not give you text outputs.
* * slot is the slot we are trying to equip to
* * equipper is the mob trying to equip the item
* * bypass_equip_delay_self for whether we want to bypass the equip delay
*/
/obj/item/proc/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
/obj/item/proc/mob_can_equip(mob/living/M, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE)
if(!M)
return FALSE
return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self)
return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self, ignore_equipped)
/obj/item/verb/verb_pickup()
set src in oview(1)
+1 -1
View File
@@ -64,7 +64,7 @@
if(victim.is_mouth_covered(head_only = TRUE))
to_chat(attacker, span_notice("[victim]'s mouth is covered."))
return
if(!mob_can_equip(victim, attacker, ITEM_SLOT_MASK))
if(!mob_can_equip(victim, ITEM_SLOT_MASK))
to_chat(attacker, span_notice("[victim] is already wearing somthing on their face."))
return
balloon_alert(attacker, "taping mouth...")
+1 -1
View File
@@ -307,7 +307,7 @@
icon_state = "petcollar"
var/tagname = null
/obj/item/clothing/neck/petcollar/mob_can_equip(mob/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
/obj/item/clothing/neck/petcollar/mob_can_equip(mob/M, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE)
if(!ismonkey(M))
return FALSE
return ..()
@@ -1,5 +1,5 @@
/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
return dna.species.can_equip(I, slot, disable_warning, src, bypass_equip_delay_self)
/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE)
return dna.species.can_equip(I, slot, disable_warning, src, bypass_equip_delay_self, ignore_equipped)
/mob/living/carbon/human/get_item_by_slot(slot_id)
switch(slot_id)
@@ -425,7 +425,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
/datum/species/proc/worn_items_fit_body_check(mob/living/carbon/wearer)
for(var/obj/item/equipped_item in wearer.get_all_worn_items())
var/equipped_item_slot = wearer.get_slot_by_item(equipped_item)
if(!can_equip(equipped_item, equipped_item_slot, H = wearer, bypass_equip_delay_self = TRUE, ignore_equipped = TRUE))
if(!equipped_item.mob_can_equip(wearer, equipped_item_slot, bypass_equip_delay_self = TRUE, ignore_equipped = TRUE))
wearer.dropItemToGround(equipped_item)
/**
+1 -1
View File
@@ -407,7 +407,7 @@
/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, qdel_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, bypass_equip_delay_self = FALSE, initial = FALSE)
if(!istype(W) || QDELETED(W)) //This qdeleted is to prevent stupid behavior with things that qdel during init, like say stacks
return FALSE
if(!W.mob_can_equip(src, null, slot, disable_warning, bypass_equip_delay_self))
if(!W.mob_can_equip(src, slot, disable_warning, bypass_equip_delay_self))
if(qdel_on_fail)
qdel(W)
else if(!disable_warning)
@@ -1,16 +1,29 @@
///Gives a Human lizard-incompatible shoes, then changes their species over to see if they drop the now incompatible shoes.
///Gives a Human lizard-incompatible shoes, then changes their species over to see if they drop the now incompatible shoes, testing if Digitigrade feet works.
///Gives a Monkey a collar, then changes their species to Human to see if item's restrictions works on species change.
/datum/unit_test/species_change_clothing
/datum/unit_test/species_change_clothing/Run()
// Test lizards as their own thing so we can get more coverage on their features
var/mob/living/carbon/human/human_to_lizard = allocate(/mob/living/carbon/human/dummy/consistent)
human_to_lizard.equipOutfit(/datum/outfit/job/assistant/consistent)
human_to_lizard.dna.features["legs"] = DIGITIGRADE_LEGS //you WILL have digitigrade legs
var/mob/living/carbon/human/morphing_human = allocate(/mob/living/carbon/human/dummy/consistent)
var/obj/item/human_shoes = human_to_lizard.get_item_by_slot(ITEM_SLOT_FEET)
morphing_human.equipOutfit(/datum/outfit/job/assistant/consistent)
morphing_human.dna.features["legs"] = DIGITIGRADE_LEGS //you WILL have digitigrade legs
var/obj/item/human_shoes = morphing_human.get_item_by_slot(ITEM_SLOT_FEET)
human_shoes.supports_variations_flags = NONE //do not fit lizards at all costs.
morphing_human.set_species(/datum/species/lizard)
var/obj/item/lizard_shoes = morphing_human.get_item_by_slot(ITEM_SLOT_FEET)
human_to_lizard.set_species(/datum/species/lizard)
var/obj/item/lizard_shoes = human_to_lizard.get_item_by_slot(ITEM_SLOT_FEET)
TEST_ASSERT_NOTEQUAL(human_shoes, lizard_shoes, "Lizard still has shoes after changing species.")
// Testing whether item-species restrictions properly blocks changing into a blacklisted species.
morphing_human.set_species(/datum/species/monkey)
var/obj/item/clothing/neck/petcollar/collar = new
morphing_human.equip_to_slot_or_del(collar, ITEM_SLOT_NECK)
var/obj/item/equipped_collar = morphing_human.get_item_by_slot(ITEM_SLOT_NECK)
morphing_human.set_species(/datum/species/human)
var/obj/item/human_collar = morphing_human.get_item_by_slot(ITEM_SLOT_NECK)
TEST_ASSERT_NOTEQUAL(equipped_collar, human_collar, "Human still has a Monkey collar after changing species.")