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()