diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index dae22df48eb..07c8778c535 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -171,25 +171,19 @@ return ..() /obj/item/card/id/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) - if (isitem(old_loc)) - UnregisterSignal(old_loc, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) - if (ismob(old_loc.loc)) - UnregisterSignal(old_loc.loc, list(COMSIG_MOVABLE_POINTED, COMSIG_MOB_RETRIEVE_ACCESS)) + if(isitem(old_loc)) + unequip_from_item_loc(old_loc) . = ..() - if (!isitem(loc)) - return - RegisterSignal(loc, COMSIG_ITEM_EQUIPPED, PROC_REF(on_loc_equipped)) - RegisterSignal(loc, COMSIG_ITEM_DROPPED, PROC_REF(on_loc_dropped)) - if (ismob(loc.loc)) - var/mob/wearer = loc.loc - // Equip chain shenanigans - UnregisterSignal(wearer, list(COMSIG_MOVABLE_POINTED, COMSIG_MOB_RETRIEVE_ACCESS)) - on_loc_equipped(loc, wearer, wearer.get_slot_by_item(loc)) + if(isitem(loc)) + equip_to_item_loc(loc) /obj/item/card/id/equipped(mob/user, slot) . = ..() if (slot & ITEM_SLOT_ID) RegisterSignal(user, COMSIG_MOVABLE_POINTED, PROC_REF(on_pointed)) + if(ishuman(user)) + var/mob/living/carbon/human/as_human = user + as_human.update_visible_name() if (slot & (ITEM_SLOT_ID|ITEM_SLOT_HANDS)) RegisterSignal(user, COMSIG_MOB_RETRIEVE_ACCESS, PROC_REF(retrieve_access)) if (slot & ITEM_SLOT_POCKETS) @@ -198,15 +192,12 @@ /obj/item/card/id/dropped(mob/user) UnregisterSignal(user, list(COMSIG_MOVABLE_POINTED, COMSIG_MOB_RETRIEVE_ACCESS)) - return ..() - -/obj/item/card/id/equipped(mob/user, slot, initial = FALSE) - . = ..() - if(!(slot & ITEM_SLOT_ID)) - return + if(isitem(loc)) + equip_to_item_loc(loc) // "dropped" into an item, like a worn wallet if(ishuman(user)) var/mob/living/carbon/human/as_human = user as_human.update_visible_name() + return ..() /obj/item/card/id/dropped(mob/user, silent = FALSE) . = ..() @@ -220,6 +211,22 @@ return honorific_title return registered_name +/// ID card is being equipped to an item (like a pda or wallet) +/obj/item/card/id/proc/equip_to_item_loc(atom/new_loc) + RegisterSignal(new_loc, COMSIG_ITEM_EQUIPPED, PROC_REF(on_loc_equipped), override = TRUE) + RegisterSignal(new_loc, COMSIG_ITEM_DROPPED, PROC_REF(on_loc_dropped), override = TRUE) + if (ismob(new_loc.loc)) + var/mob/wearer = new_loc.loc + // Equip chain shenanigans + UnregisterSignal(wearer, list(COMSIG_MOVABLE_POINTED, COMSIG_MOB_RETRIEVE_ACCESS)) + on_loc_equipped(new_loc, wearer, wearer.get_slot_by_item(new_loc)) + +/// ID card is being unequipped from an item (like a pda or wallet) +/obj/item/card/id/proc/unequip_from_item_loc(atom/old_loc) + UnregisterSignal(old_loc, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) + if (ismob(old_loc.loc)) + UnregisterSignal(old_loc.loc, list(COMSIG_MOVABLE_POINTED, COMSIG_MOB_RETRIEVE_ACCESS)) + /obj/item/card/id/proc/on_loc_equipped(datum/source, mob/equipper, slot) SIGNAL_HANDLER diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 93f2059e84e..97db5a18b7a 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -195,6 +195,7 @@ #include "hydroponics_harvest.dm" #include "hydroponics_self_mutations.dm" #include "hydroponics_validate_genes.dm" +#include "id_access.dm" #include "inhands.dm" #include "interaction_door.dm" #include "interaction_silicon.dm" diff --git a/code/modules/unit_tests/id_access.dm b/code/modules/unit_tests/id_access.dm new file mode 100644 index 00000000000..1a25cd29851 --- /dev/null +++ b/code/modules/unit_tests/id_access.dm @@ -0,0 +1,52 @@ +/datum/unit_test/id_access + +/datum/unit_test/id_access/Run() + var/mob/living/carbon/human/consistent/subject = EASY_ALLOCATE() + subject.equip_to_appropriate_slot(new /obj/item/clothing/under/color/grey) + var/obj/item/card/id/advanced/card = EASY_ALLOCATE() + + card.set_access(list(ACCESS_HYDROPONICS), FORCE_ADD_ALL) + TEST_ASSERT_EQUAL(length(card.GetAccess()), 1, "ID card access length incorrect after setting access.") + + subject.put_in_hands(card) + TEST_ASSERT(check_access(subject, ACCESS_HYDROPONICS), "Subject did not have the access on holding ID card.") + subject.dropItemToGround(card) + TEST_ASSERT(check_access(subject, null), "Subject still had access after dropping ID card.") + subject.equip_to_appropriate_slot(card) + TEST_ASSERT(check_access(subject, ACCESS_HYDROPONICS), "Subject did not have the access on equipping ID card.") + subject.dropItemToGround(card) + TEST_ASSERT(check_access(subject, null), "Subject still had access after unequipping ID card.") + + var/obj/item/storage/wallet/wallet = EASY_ALLOCATE() + card.forceMove(wallet) + subject.equip_to_appropriate_slot(wallet) + TEST_ASSERT(check_access(subject, ACCESS_HYDROPONICS), "Subject did not have the access on equipping wallet with ID card inside.") + subject.dropItemToGround(wallet) + TEST_ASSERT(check_access(subject, null), "Subject still had access after unequipping wallet with ID card inside.") + subject.equip_to_appropriate_slot(wallet) + click_wrapper(subject, card) // withdraw id card from wallet + TEST_ASSERT(card.loc == subject && card == subject.get_active_held_item(), "Subject failed to withdraw ID card from wallet.") + click_wrapper(subject, wallet) // reinsert id card into wallet + TEST_ASSERT(card.loc == wallet, "Subject failed to reinsert ID card into wallet.") + TEST_ASSERT(check_access(subject, ACCESS_HYDROPONICS), "Subject did not have the access after reinserting ID card into equipped wallet.") + subject.dropItemToGround(wallet) + + var/obj/item/modular_computer/pda/pda = EASY_ALLOCATE() + pda.insert_id(card) + subject.equip_to_appropriate_slot(pda) + TEST_ASSERT(check_access(subject, ACCESS_HYDROPONICS), "Subject did not have the access on equipping PDA with ID card inside.") + subject.dropItemToGround(pda) + TEST_ASSERT(check_access(subject, null), "Subject still had access after unequipping PDA with ID card inside.") + subject.equip_to_appropriate_slot(pda) + pda.remove_id(subject) + TEST_ASSERT(card.loc == subject && card == subject.get_active_held_item(), "Subject failed to withdraw ID card from PDA.") + click_wrapper(subject, pda) // reinsert id card into pda + TEST_ASSERT(card.loc == pda, "Subject failed to reinsert ID card into PDA.") + TEST_ASSERT(check_access(subject, ACCESS_HYDROPONICS), "Subject did not have the access after reinserting ID card into equipped PDA.") + subject.dropItemToGround(pda) + +/datum/unit_test/id_access/proc/check_access(mob/living/carbon/human/consistent/subject, expected) + var/list/subject_access = subject.get_access() + if(isnull(expected)) + return length(subject_access) == 0 + return length(subject_access) == 1 && subject_access[1] == expected