From e82a4972ccb07e3960552d7db9759d6135f2ed52 Mon Sep 17 00:00:00 2001 From: Mothblocks <35135081+Mothblocks@users.noreply.github.com> Date: Thu, 15 Apr 2021 21:18:07 -0700 Subject: [PATCH] Fixes edge cases revolving who can strip and who can't (#58445) Fixes all simple mobs being able to strip, as well as being able to strip when your hands are blocked (e.g. cuffed). Fixes #58260. --- code/__DEFINES/traits.dm | 3 +++ code/datums/elements/strippable.dm | 4 ++++ code/modules/mob/living/carbon/alien/alien.dm | 1 + code/modules/mob/living/carbon/human/species.dm | 2 +- .../mob/living/carbon/human/species_types/monkeys.dm | 2 +- code/modules/mob/living/silicon/robot/robot.dm | 2 ++ .../mob/living/simple_animal/simple_animal.dm | 1 + code/modules/tgui/status_composers.dm | 8 +++++++- code/modules/unit_tests/strippable.dm | 12 +++++++++++- 9 files changed, 31 insertions(+), 4 deletions(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 910f17554dc..9c1f1555085 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -328,6 +328,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_ROYAL_METABOLISM "royal_metabolism" #define TRAIT_PRETENDER_ROYAL_METABOLISM "pretender_royal_metabolism" +/// This mob can strip other mobs. +#define TRAIT_CAN_STRIP "can_strip" + // If present on a mob or mobmind, allows them to "suplex" an immovable rod // turning it into a glorified potted plant, and giving them an // achievement. Can also be used on rod-form wizards. diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm index 43d856a561b..df36d6aacf5 100644 --- a/code/datums/elements/strippable.dm +++ b/code/datums/elements/strippable.dm @@ -76,9 +76,11 @@ /datum/strippable_item/proc/try_equip(atom/source, obj/item/equipping, mob/user) if(SEND_SIGNAL(user, COMSIG_TRY_STRIP, source, equipping) & COMPONENT_CANT_STRIP) return FALSE + if (HAS_TRAIT(equipping, TRAIT_NODROP)) to_chat(user, "You can't put [equipping] on [source], it's stuck to your hand!") return FALSE + return TRUE /// Start the equipping process. This is the proc you should yield in. @@ -492,7 +494,9 @@ /datum/strip_menu/ui_status(mob/user, datum/ui_state/state) return min( ui_status_only_living(user, owner), + ui_status_user_has_free_hands(user, owner), ui_status_user_is_adjacent(user, owner), + HAS_TRAIT(user, TRAIT_CAN_STRIP) ? UI_INTERACTIVE : UI_UPDATE, max( ui_status_user_is_conscious_and_lying_down(user), ui_status_user_is_abled(user, owner), diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 572c8125b62..f5a87b0e583 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -31,6 +31,7 @@ create_internal_organs() + ADD_TRAIT(src, TRAIT_CAN_STRIP, INNATE_TRAIT) ADD_TRAIT(src, TRAIT_NEVER_WOUNDED, INNATE_TRAIT) ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index cb413b176dc..5b920e27eda 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -138,7 +138,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) ///Species-only traits. Can be found in [code/__DEFINES/DNA.dm] var/list/species_traits = list() ///Generic traits tied to having the species. - var/list/inherent_traits = list(TRAIT_ADVANCEDTOOLUSER) + var/list/inherent_traits = list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP) /// List of biotypes the mob belongs to. Used by diseases. var/inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID ///List of factions the mob gain upon gaining this species. diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm index d61bf58af39..f660954000e 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -12,7 +12,7 @@ meat = /obj/item/food/meat/slab/monkey knife_butcher_results = list(/obj/item/food/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1) species_traits = list(HAS_FLESH,HAS_BONE,NO_UNDERWEAR,LIPS,NOEYESPRITES,NOBLOODOVERLAY,NOTRANSSTING, NOAUGMENTS) - inherent_traits = list(TRAIT_VENTCRAWLER_NUDE, TRAIT_PRIMITIVE, TRAIT_WEAK_SOUL) + inherent_traits = list(TRAIT_VENTCRAWLER_NUDE, TRAIT_PRIMITIVE, TRAIT_WEAK_SOUL, TRAIT_CAN_STRIP) no_equip = list(ITEM_SLOT_EARS, ITEM_SLOT_EYES, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | ERT_SPAWN | SLIME_EXTRACT liked_food = MEAT | FRUIT diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 86ba93e56e2..5ec9304e13d 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -3,6 +3,8 @@ spark_system.set_up(5, 0, src) spark_system.attach(src) + ADD_TRAIT(src, TRAIT_CAN_STRIP, INNATE_TRAIT) + wires = new /datum/wires/robot(src) AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES) AddElement(/datum/element/ridable, /datum/component/riding/creature/cyborg) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index c82c99b67bd..5bd885b979b 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -189,6 +189,7 @@ if(dextrous) AddComponent(/datum/component/personal_crafting) ADD_TRAIT(src, TRAIT_ADVANCEDTOOLUSER, ROUNDSTART_TRAIT) + ADD_TRAIT(src, TRAIT_CAN_STRIP, ROUNDSTART_TRAIT) if(is_flying_animal) ADD_TRAIT(src, TRAIT_MOVE_FLYING, ROUNDSTART_TRAIT) diff --git a/code/modules/tgui/status_composers.dm b/code/modules/tgui/status_composers.dm index 3e59f3f70f7..5cd5a8b008c 100644 --- a/code/modules/tgui/status_composers.dm +++ b/code/modules/tgui/status_composers.dm @@ -2,6 +2,7 @@ /proc/default_ui_state(mob/user, atom/source) return min( ui_status_user_is_abled(user, source), + ui_status_user_has_free_hands(user, source), ui_status_user_is_advanced_tool_user(user), ui_status_only_living(user), max( @@ -47,7 +48,12 @@ /proc/ui_status_user_is_abled(mob/user, atom/source) return user.shared_ui_interaction(source) -/// Returns a UI status such that advanced tool users will be able to update, +/// Returns a UI status such that those without blocked hands will be able to interact, +/// but everyone else can only watch. +/proc/ui_status_user_has_free_hands(mob/user, atom/source) + return HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) ? UI_UPDATE : UI_INTERACTIVE + +/// Returns a UI status such that advanced tool users will be able to interact, /// but everyone else can only watch. /proc/ui_status_user_is_advanced_tool_user(mob/user) return ISADVANCEDTOOLUSER(user) ? UI_INTERACTIVE : UI_UPDATE diff --git a/code/modules/unit_tests/strippable.dm b/code/modules/unit_tests/strippable.dm index ce31972fc4a..2fa5e4f1f2a 100644 --- a/code/modules/unit_tests/strippable.dm +++ b/code/modules/unit_tests/strippable.dm @@ -22,8 +22,15 @@ user.set_body_position(STANDING_UP) TEST_ASSERT_EQUAL(strip_menu.ui_status(user, ui_state), UI_UPDATE, "Being too far away while standing up was not update-only.") - user.set_body_position(LYING_DOWN) + var/handcuffs = allocate(/obj/item/restraints/handcuffs, user) user.forceMove(target.loc) + user.set_handcuffed(handcuffs) + user.update_handcuffed() + TEST_ASSERT_EQUAL(strip_menu.ui_status(user, ui_state), UI_UPDATE, "Being within range but cuffed was not update-only.") + user.set_handcuffed(null) + qdel(handcuffs) + + user.set_body_position(LYING_DOWN) user.death() TEST_ASSERT_EQUAL(strip_menu.ui_status(user, ui_state), UI_UPDATE, "Being within range but dead was not update-only.") @@ -49,3 +56,6 @@ var/mob/living/carbon/alien/rouny = allocate(/mob/living/carbon/alien, run_loc_floor_bottom_left) ADD_TRAIT(rouny, TRAIT_PRESERVE_UI_WITHOUT_CLIENT, TRAIT_SOURCE_UNIT_TESTS) TEST_ASSERT_EQUAL(strip_menu.ui_status(rouny, ui_state), UI_INTERACTIVE, "Being within range as a xeno was not interactive.") + + var/mob/living/simple_animal/pet/dog/corgi/corgi = allocate(/mob/living/simple_animal/pet/dog/corgi, run_loc_floor_bottom_left) + TEST_ASSERT_EQUAL(strip_menu.ui_status(corgi, ui_state), UI_UPDATE, "Being within range as a corgi was not update-only.")