From 67fefdde4322dd3628728b96dfa1a730d6e562e9 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Fri, 28 Feb 2025 19:00:47 +0100 Subject: [PATCH] Implements a quirk spawn validity unit test and fixes a runtime preventing cyborg dogtag quirk from working roundstart (#89728) ## About The Pull Request Fixes a roundstart-exclusive runtime in the cyborg dogtag quirk, makes sure that spawning with a fishing toolbox (from a settler quirk) doesn't runtime and implements a unit test which ensures that all quirks set up correctly for ***both*** roundstart and latejoin mobs. The cyborg tag issue is just too stupid and may float up again, considering how easy it is to accidentally fetch owner's client instead of using the passed one. ## Changelog :cl: fix: Cyborg pre-screening dogtags should once again be given to crew with the quirk of the same name. /:cl: --- .../components/adjust_fishing_difficulty.dm | 4 +-- code/datums/mocking/client.dm | 7 ++++ code/datums/quirks/negative_quirks/addict.dm | 2 +- .../quirks/neutral_quirks/borg_ready.dm | 2 +- .../datums/quirks/neutral_quirks/foreigner.dm | 2 ++ code/modules/unit_tests/quirks.dm | 33 +++++++++++++++++++ 6 files changed, 46 insertions(+), 4 deletions(-) diff --git a/code/datums/components/adjust_fishing_difficulty.dm b/code/datums/components/adjust_fishing_difficulty.dm index 4e329b03940..d4b7b28492c 100644 --- a/code/datums/components/adjust_fishing_difficulty.dm +++ b/code/datums/components/adjust_fishing_difficulty.dm @@ -96,9 +96,9 @@ if(challenge) UnregisterSignal(challenge, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY) else - RegisterSignal(user, COMSIG_MOB_BEGIN_FISHING, PROC_REF(on_minigame_started)) + RegisterSignal(user, COMSIG_MOB_BEGIN_FISHING, PROC_REF(on_minigame_started), TRUE) if(challenge) - RegisterSignal(challenge, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY, PROC_REF(adjust_difficulty)) + RegisterSignal(challenge, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY, PROC_REF(adjust_difficulty), TRUE) challenge?.update_difficulty() /datum/component/adjust_fishing_difficulty/proc/on_minigame_started(mob/living/source, datum/fishing_challenge/challenge) diff --git a/code/datums/mocking/client.dm b/code/datums/mocking/client.dm index 4b724ef705e..8819cacb920 100644 --- a/code/datums/mocking/client.dm +++ b/code/datums/mocking/client.dm @@ -21,6 +21,10 @@ /// The key for this mock interface var/key = "mockclient" + /// Mock ban cache to avoid runtimes when testing bans + var/ban_cache = null + var/ban_cache_start = 0 + /// client prefs var/fps var/hotkeys @@ -51,3 +55,6 @@ /datum/client_interface/proc/update_ambience_pref() return + +/datum/client_interface/proc/get_award_status(achievement_type, mob/user, value = 1) + return FALSE diff --git a/code/datums/quirks/negative_quirks/addict.dm b/code/datums/quirks/negative_quirks/addict.dm index 8574c6060d6..09b25ef46b2 100644 --- a/code/datums/quirks/negative_quirks/addict.dm +++ b/code/datums/quirks/negative_quirks/addict.dm @@ -102,7 +102,7 @@ return ..() /datum/quirk/item_quirk/addict/remove() - if(quirk_holder && reagent_instance) + if(!QDELETED(quirk_holder) && reagent_instance) for(var/addiction_type in subtypesof(/datum/addiction)) quirk_holder.mind.remove_addiction_points(addiction_type, MAX_ADDICTION_POINTS) diff --git a/code/datums/quirks/neutral_quirks/borg_ready.dm b/code/datums/quirks/neutral_quirks/borg_ready.dm index 371e02a03c5..f623dd47de0 100644 --- a/code/datums/quirks/neutral_quirks/borg_ready.dm +++ b/code/datums/quirks/neutral_quirks/borg_ready.dm @@ -8,7 +8,7 @@ medical_record_text = "Patient is a registered brain donor for Robotics research." /datum/quirk/item_quirk/borg_ready/add_unique(client/client_source) - if(is_banned_from(quirk_holder.ckey, JOB_CYBORG)) + if(is_banned_from(client_source.ckey, JOB_CYBORG)) return FALSE var/obj/item/clothing/accessory/dogtag/borg_ready/borgtag = new(get_turf(quirk_holder)) give_item_to_holder(borgtag, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) diff --git a/code/datums/quirks/neutral_quirks/foreigner.dm b/code/datums/quirks/neutral_quirks/foreigner.dm index da317a7e66a..7cdb85cace5 100644 --- a/code/datums/quirks/neutral_quirks/foreigner.dm +++ b/code/datums/quirks/neutral_quirks/foreigner.dm @@ -15,6 +15,8 @@ human_holder.grant_language(/datum/language/uncommon, source = LANGUAGE_QUIRK) /datum/quirk/foreigner/remove() + if(QDELETED(quirk_holder)) + return var/mob/living/carbon/human/human_holder = quirk_holder human_holder.remove_blocked_language(/datum/language/common) if(ishumanbasic(human_holder)) diff --git a/code/modules/unit_tests/quirks.dm b/code/modules/unit_tests/quirks.dm index cca2c312cfe..69630f66291 100644 --- a/code/modules/unit_tests/quirks.dm +++ b/code/modules/unit_tests/quirks.dm @@ -75,3 +75,36 @@ if(!isnull(species_to_test[last_species])) TEST_ASSERT(!(species_to_test[last_species] in quirk.mail_goodies), \ "Blood deficiency quirk did not update correctly for [species_type]! ([last_species] did not get its blood bag removed)") + +/// Ensures that all quirks correctly initialized when added +/datum/unit_test/quirk_validity + +/datum/unit_test/quirk_validity/Run() + // Required for language quirks to function properly + // Assigning this manually as config is empty + GLOB.uncommon_roundstart_languages = list(/datum/language/uncommon) + + for (var/datum/quirk/quirk_type as anything in subtypesof(/datum/quirk)) + if (initial(quirk_type.abstract_parent_type) == quirk_type) + continue + + var/mob/dead/new_player/abstract_player = allocate(/mob/dead/new_player) + var/datum/client_interface/roundstart_mock_client = new() + abstract_player.mock_client = roundstart_mock_client + roundstart_mock_client.prefs = new(roundstart_mock_client) + var/mob/living/carbon/human/new_character = allocate(/mob/living/carbon/human/consistent) + new_character.mind_initialize() + abstract_player.new_character = new_character + if (!new_character.add_quirk(quirk_type, roundstart_mock_client)) + TEST_FAIL("Failed to initialize quirk [quirk_type] on a roundstart character!") + + var/mob/living/carbon/human/latejoin_character = allocate(/mob/living/carbon/human/consistent) + var/datum/client_interface/latejoin_mock_client = new() + latejoin_mock_client.prefs = new(latejoin_mock_client) + latejoin_character.mock_client = latejoin_mock_client + latejoin_character.mind_initialize() + if (!latejoin_character.add_quirk(quirk_type, latejoin_mock_client)) + TEST_FAIL("Failed to initialize quirk [quirk_type] on a latejoin character!") + + // Clean up after ourselves + GLOB.uncommon_roundstart_languages.Cut()