From 47a6316b3237f86d32cd8baee26415a0ed48e7ec Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sat, 24 Sep 2022 22:56:35 +0200 Subject: [PATCH] [MIRROR] Removes persistence of items through changing species when not allowed to [MDB IGNORE] (#16356) * Removes persistence of items through changing species when not allowed to * fixes racist clothing Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: tastyfish --- code/_onclick/hud/screen_objects.dm | 2 +- code/datums/elements/strippable.dm | 16 ++-------- code/game/objects/items.dm | 5 ++-- code/modules/clothing/masks/muzzle.dm | 2 +- code/modules/clothing/neck/_neck.dm | 2 +- .../mob/living/carbon/human/inventory.dm | 4 +-- .../mob/living/carbon/human/species.dm | 2 +- code/modules/mob/mob.dm | 2 +- .../unit_tests/species_change_clothing.dm | 29 +++++++++++++++++++ .../modules/clothing/masks/breath.dm | 2 +- .../modules/novaya_ert/code/head.dm | 6 ++-- .../modules/novaya_ert/code/suit.dm | 6 ++-- .../modules/novaya_ert/code/uniform.dm | 2 +- 13 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 code/modules/unit_tests/species_change_clothing.dm diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index f5d04fe6738..43c08038eaa 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -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" diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm index 61c03563603..e6dd67c88ba 100644 --- a/code/datums/elements/strippable.dm +++ b/code/datums/elements/strippable.dm @@ -232,13 +232,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 @@ -255,13 +249,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)) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index ebeda84b8fe..51e5dcbef13 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -738,14 +738,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) diff --git a/code/modules/clothing/masks/muzzle.dm b/code/modules/clothing/masks/muzzle.dm index 7c2c5f46eaf..7f4544810f7 100644 --- a/code/modules/clothing/masks/muzzle.dm +++ b/code/modules/clothing/masks/muzzle.dm @@ -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...") diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 1fe765d585c..15c30e88fb1 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -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 ..() diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 824bda4e93a..9cdd58eb869 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -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) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index a20aaa5bb65..14a9d84e87f 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -424,7 +424,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) /** diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 97db6b9994d..5fe97d73c0c 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -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) diff --git a/code/modules/unit_tests/species_change_clothing.dm b/code/modules/unit_tests/species_change_clothing.dm new file mode 100644 index 00000000000..cad10f216a6 --- /dev/null +++ b/code/modules/unit_tests/species_change_clothing.dm @@ -0,0 +1,29 @@ +///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/morphing_human = allocate(/mob/living/carbon/human/dummy/consistent) + + 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) + + 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.") diff --git a/modular_skyrat/modules/customization/modules/clothing/masks/breath.dm b/modular_skyrat/modules/customization/modules/clothing/masks/breath.dm index c6061a7b4b1..4394f7c112f 100644 --- a/modular_skyrat/modules/customization/modules/clothing/masks/breath.dm +++ b/modular_skyrat/modules/customization/modules/clothing/masks/breath.dm @@ -101,7 +101,7 @@ worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/mask.dmi' icon_state = "hecu2" -/obj/item/clothing/mask/gas/hecu2/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning, bypass_equip_delay_self) +/obj/item/clothing/mask/gas/hecu2/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) if(is_species(M, /datum/species/teshari)) to_chat(M, span_warning("[src] is far too big for you!")) return FALSE diff --git a/modular_skyrat/modules/novaya_ert/code/head.dm b/modular_skyrat/modules/novaya_ert/code/head.dm index a06fe0cf180..8efa93b08b9 100644 --- a/modular_skyrat/modules/novaya_ert/code/head.dm +++ b/modular_skyrat/modules/novaya_ert/code/head.dm @@ -8,7 +8,7 @@ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH supports_variations_flags = CLOTHING_SNOUTED_VARIATION_NO_NEW_ICON -/obj/item/clothing/head/helmet/rus_helmet/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning, bypass_equip_delay_self) +/obj/item/clothing/head/helmet/rus_helmet/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) if(is_species(M, /datum/species/teshari)) to_chat(M, span_warning("[src] is far too big for you!")) return FALSE @@ -47,7 +47,7 @@ state += "-up" icon_state = state -/obj/item/clothing/head/helmet/nri_heavy/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning, bypass_equip_delay_self) +/obj/item/clothing/head/helmet/nri_heavy/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) if(is_species(M, /datum/species/teshari)) to_chat(M, span_warning("[src] is far too big for you!")) return FALSE @@ -82,7 +82,7 @@ visor_flags = STOPSPRESSUREDAMAGE slowdown = 0 -/obj/item/clothing/head/helmet/space/hev_suit/nri/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning, bypass_equip_delay_self) +/obj/item/clothing/head/helmet/space/hev_suit/nri/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) if(is_species(M, /datum/species/teshari)) to_chat(M, span_warning("[src] is far too big for you!")) return FALSE diff --git a/modular_skyrat/modules/novaya_ert/code/suit.dm b/modular_skyrat/modules/novaya_ert/code/suit.dm index 2364fafddfe..03d5ea35dcb 100644 --- a/modular_skyrat/modules/novaya_ert/code/suit.dm +++ b/modular_skyrat/modules/novaya_ert/code/suit.dm @@ -33,7 +33,7 @@ ), ) -/obj/item/clothing/suit/armor/vest/russian/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning, bypass_equip_delay_self) +/obj/item/clothing/suit/armor/vest/russian/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) if(is_species(M, /datum/species/teshari)) to_chat(M, span_warning("[src] is far too big for you!")) return FALSE @@ -52,7 +52,7 @@ equip_delay_self = 5 SECONDS supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION -/obj/item/clothing/suit/armor/heavy/nri/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning, bypass_equip_delay_self) +/obj/item/clothing/suit/armor/heavy/nri/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) if(is_species(M, /datum/species/teshari)) //racist armor to_chat(M, span_warning("[src] is far too big for you!")) return FALSE @@ -133,7 +133,7 @@ suit_name = "VOSKHOD" first_use = FALSE //No nice song. -/obj/item/clothing/suit/space/hev_suit/nri/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning, bypass_equip_delay_self) +/obj/item/clothing/suit/space/hev_suit/nri/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) if(is_species(M, /datum/species/teshari)) to_chat(M, span_warning("[src] is far too big for you!")) return FALSE diff --git a/modular_skyrat/modules/novaya_ert/code/uniform.dm b/modular_skyrat/modules/novaya_ert/code/uniform.dm index 6014af65043..e3c25fb9d59 100644 --- a/modular_skyrat/modules/novaya_ert/code/uniform.dm +++ b/modular_skyrat/modules/novaya_ert/code/uniform.dm @@ -12,7 +12,7 @@ random_sensor = FALSE can_adjust = FALSE -/obj/item/clothing/under/costume/nri/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning, bypass_equip_delay_self) +/obj/item/clothing/under/costume/nri/mob_can_equip(mob/living/M, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) if(is_species(M, /datum/species/teshari)) to_chat(M, span_warning("[src] is far too big for you!")) return FALSE