mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 01:34:01 +00:00
This PR aims to clean or bring up to date portions of code about dna, the dna console and mutations. This includes taking care of or removing some of the awful choices like the pratically useless `datum/mutation/human` pathing, or the class variable, in favor of using sources to avoid potential issues with extraneous sources of a mutation. The files changed are over a hundred just because I removed the `datum/mutation/human` path, but the actual bulk of the code is mainly shared between the datum/dna.dm, _mutations.dm and dna_console.dm. Mutation shitcode is hurting my future plans for infusions a little. Also it's a much needed refactor. Drafted 'till I'm sure it works without issues. 🆑 refactor: Refactored mutation code backend. Report any issue. /🆑
257 lines
14 KiB
Plaintext
257 lines
14 KiB
Plaintext
#define HAS_SCREEN_OVERLAY(mob, type) (locate(type) in flatten_list(mob.screens))
|
|
#define HAS_CLIENT_COLOR(mob, type) (locate(type) in mob.client_colours)
|
|
|
|
/**
|
|
* Unit test to check that blindness adds the correct status effects, overlays, and client colors
|
|
*
|
|
* Also checks that blindness is added and removed correctly when it should and shouldn't be
|
|
*/
|
|
/datum/unit_test/blindness
|
|
|
|
/datum/unit_test/blindness/Run()
|
|
var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
|
|
var/obj/item/clothing/glasses/blindfold/blindfold = new(dummy.loc)
|
|
TEST_ASSERT(!dummy.is_blind(), "Dummy was blind on initialize, and shouldn't be.")
|
|
|
|
// Become blind
|
|
dummy.become_blind("unit_test")
|
|
check_if_blind(dummy)
|
|
// Cure their blindness immediately
|
|
dummy.cure_blind("unit_test")
|
|
check_if_not_blind(dummy)
|
|
|
|
// Become blindfolded, this one should blind us
|
|
dummy.equip_to_slot_if_possible(blindfold, ITEM_SLOT_EYES)
|
|
check_if_blind(dummy, status_message = "after being blindfolded")
|
|
// Become quirk blinded and mutation blindness, these shouldn't do anything since we're already blind
|
|
// Have to do a transfer here so we don't get a blindfold
|
|
var/datum/quirk/item_quirk/blindness/quirk = allocate(/datum/quirk/item_quirk/blindness)
|
|
quirk.add_to_holder(dummy, quirk_transfer = TRUE)
|
|
dummy.dna.add_mutation(/datum/mutation/blind, "TEST")
|
|
|
|
// Remove the blindfold. We should remain blinded
|
|
QDEL_NULL(blindfold)
|
|
check_if_blind(dummy, status_message = "after removing their blindfold BUT still being blinded")
|
|
// Remove the quirk. We should remain blinded again
|
|
dummy.remove_quirk(/datum/quirk/item_quirk/blindness)
|
|
check_if_blind(dummy, status_message = "after removing their quirk BUT still being blinded")
|
|
// Remove the mutation, this should unblind us
|
|
dummy.dna.remove_mutation(/datum/mutation/blind, "TEST")
|
|
check_if_not_blind(dummy, status_message = "after removing their blind mutation and having no sources of blindness left")
|
|
|
|
// Temp blindness
|
|
dummy.set_temp_blindness(10 SECONDS)
|
|
check_if_blind(dummy, status_message = "after being temporarily blinded")
|
|
// Now aheal, remove the temp blindness
|
|
dummy.fully_heal(ALL)
|
|
TEST_ASSERT(!dummy.has_status_effect(/datum/status_effect/temporary_blindness), "Dummy still had the temp blindness effect after being fullhealed.")
|
|
// Check that it worked out
|
|
check_if_not_blind(dummy, status_message = "after being ahealed while temporarily blinded")
|
|
|
|
/datum/unit_test/blindness/proc/check_if_blind(mob/living/carbon/human/dummy, status_message = "despite being made blind")
|
|
// Check for the status effect, duh
|
|
TEST_ASSERT(dummy.is_blind(), "Dummy, [status_message], did not have the blind status effect.")
|
|
// Being more technical, we need to check for client color and screen overlays
|
|
TEST_ASSERT(HAS_CLIENT_COLOR(dummy, /datum/client_colour/monochrome), "Dummy, [status_message], did not have the monochrome client color.")
|
|
TEST_ASSERT(HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/blind), "Dummy, [status_message], did not have a blind screen overlay in their list of screens.")
|
|
|
|
/datum/unit_test/blindness/proc/check_if_not_blind(mob/living/carbon/human/dummy, status_message = "after being cured of blindness")
|
|
// Check for no status effect
|
|
TEST_ASSERT(!dummy.is_blind(), "Dummy, [status_message], still had the blindness status effect.")
|
|
// Check that the client color and screen overlay are gone
|
|
TEST_ASSERT(!HAS_CLIENT_COLOR(dummy, /datum/client_colour/monochrome), "Dummy, [status_message], still had the monochrome client color.")
|
|
TEST_ASSERT(!HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/blind), "Dummy, [status_message], still had the blind sceen overlay.")
|
|
|
|
/**
|
|
* Unit test to check that the nearsighted quirk is added and disabled correctly
|
|
*/
|
|
/datum/unit_test/nearsighted_quirk
|
|
|
|
/datum/unit_test/nearsighted_quirk/Run()
|
|
var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
|
|
var/obj/item/clothing/glasses/regular/glasses = allocate(/obj/item/clothing/glasses/regular)
|
|
|
|
// Become quirk nearsighted
|
|
// Have to do a transfer here so we don't get glasses
|
|
var/datum/quirk/item_quirk/nearsighted/quirk = allocate(/datum/quirk/item_quirk/nearsighted)
|
|
quirk.add_to_holder(dummy, quirk_transfer = TRUE)
|
|
TEST_ASSERT(dummy.is_nearsighted(), "Dummy is not nearsighted after gaining the nearsighted quirk.")
|
|
TEST_ASSERT(HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy didn't gain the nearsighted overlay after becoming nearsighted.")
|
|
TEST_ASSERT(dummy.is_nearsighted_currently(), "Dummy is not currently nearsighted, after gaining the nearsighted quirk.")
|
|
// Become naturally nearsighted
|
|
dummy.become_nearsighted("unit_test")
|
|
|
|
// Equip the prescription glasses, they should disable nearsighted
|
|
dummy.equip_to_slot_if_possible(glasses, ITEM_SLOT_EYES)
|
|
TEST_ASSERT(dummy.is_nearsighted(), "Dummy was no longer nearsighted after putting on glasses. They should still be nearsighted, but it should be disabled.")
|
|
TEST_ASSERT(!HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy still had the nearsighted overlay, even though they were wearing glasses.")
|
|
TEST_ASSERT(!dummy.is_nearsighted_currently(), "Dummy was nearsighted currently even though they were wearing glasses.")
|
|
|
|
// Remove the glasses
|
|
QDEL_NULL(glasses)
|
|
TEST_ASSERT(HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy still had the nearsighted overlay, even though they were wearing glasses.")
|
|
TEST_ASSERT(dummy.is_nearsighted_currently(), "Dummy is not currently nearsighted, after removing their glasses.")
|
|
|
|
// And remove nearsightedness wholesale
|
|
dummy.remove_quirk(/datum/quirk/item_quirk/nearsighted)
|
|
dummy.cure_nearsighted("unit_test")
|
|
TEST_ASSERT(!dummy.is_nearsighted(), "Dummy is still nearsighted after being cured of it.")
|
|
TEST_ASSERT(!HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy still had the nearsighted overlay after being cured of it.")
|
|
|
|
/**
|
|
* Unit test to ensure eyes are properly blinded and nearsighted by eye damage
|
|
*/
|
|
/datum/unit_test/eye_damage
|
|
|
|
/datum/unit_test/eye_damage/Run()
|
|
var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
|
|
var/obj/item/organ/eyes/eyes = dummy.get_organ_slot(ORGAN_SLOT_EYES)
|
|
TEST_ASSERT_NOTNULL(eyes, "Eye damage unit test spawned a dummy without eyes!")
|
|
|
|
// Test blindness due to eye damage
|
|
// Cause critical eye damage
|
|
var/critical_damage = eyes.maxHealth
|
|
eyes.set_organ_damage(critical_damage) // ~50 damage
|
|
TEST_ASSERT(dummy.is_blind(), "After sustaining critical eye damage ([critical_damage]), the dummy was not blind.")
|
|
// Heal eye damage
|
|
eyes.set_organ_damage(0)
|
|
TEST_ASSERT(!dummy.is_blind(), "After healing from critical eye damage, the dummy was not unblinded.")
|
|
|
|
// Test nearsightedness due to eye damage
|
|
var/datum/status_effect/grouped/nearsighted/nearsightedness
|
|
// Cause minor eye damage
|
|
var/minor_damage = eyes.maxHealth * 0.5
|
|
eyes.apply_organ_damage(minor_damage) //~25 ddamage
|
|
TEST_ASSERT(dummy.is_nearsighted(), "After sustaining minor eye damage ([minor_damage]), the dummy was not nearsighted.")
|
|
// Check that the severity is correct
|
|
nearsightedness = dummy.is_nearsighted()
|
|
TEST_ASSERT_EQUAL(nearsightedness.get_severity(), 2, "After taking minor eye damage, the dummy's nearsightedness was the incorrect severity.")
|
|
nearsightedness = null
|
|
// Heal eye damage
|
|
eyes.set_organ_damage(0)
|
|
TEST_ASSERT(!dummy.is_nearsighted(), "After curing eye damage, the dummy was still nearsighted.")
|
|
|
|
// Cause major eye damage
|
|
var/major_damage = eyes.maxHealth * 0.7
|
|
eyes.apply_organ_damage(major_damage) //~35 damage
|
|
TEST_ASSERT(dummy.is_nearsighted(), "After sustaining major eye damage ([major_damage]), the dummy was not nearsighted.")
|
|
// Check that the severity is correct
|
|
nearsightedness = dummy.is_nearsighted()
|
|
TEST_ASSERT_EQUAL(nearsightedness.get_severity(), 3, "After taking major eye damage, the dummy's nearsightedness was the incorrect severity.")
|
|
nearsightedness = null
|
|
// Heal eye damage
|
|
eyes.set_organ_damage(0)
|
|
TEST_ASSERT(!dummy.is_nearsighted(), "After curing eye damage, the dummy was still nearsighted.")
|
|
|
|
#define CORRECTABLE_SOURCE "\[CORRECTABLE SOURCE\]"
|
|
#define ABSOLUTE_SOURCE "\[ABSOLUTE SOURCE\]"
|
|
/datum/unit_test/nearsighted_effect
|
|
/*!
|
|
* This tests [/datum/status_effect/grouped/nearsighted]
|
|
* * Application (correctable/absolute)
|
|
* * Removal (absolute/correctable)
|
|
*/
|
|
/datum/unit_test/nearsighted_effect/Run()
|
|
var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent)
|
|
var/datum/status_effect/grouped/nearsighted/myopia
|
|
|
|
/* APPLICATION */
|
|
// Let's test regular nearsightedness first
|
|
dummy.assign_nearsightedness(CORRECTABLE_SOURCE, 2, TRUE)
|
|
validate_correctable_severity(dummy, "after being given [CORRECTABLE_SOURCE]", 2, list(
|
|
CORRECTABLE_SOURCE = 2,
|
|
))
|
|
|
|
myopia = dummy.is_nearsighted()
|
|
TEST_ASSERT_EQUAL(myopia.get_severity(), 2, "Final severity amount was incorrect when checked with only correctable nearsightedness.")
|
|
|
|
// We'll test if the glasses work as expected...
|
|
validate_glasses_behaviour(dummy, "after being given [CORRECTABLE_SOURCE]", 0, 2)
|
|
|
|
// Let's apply an absolute source, we'll test two things at once
|
|
dummy.assign_nearsightedness(ABSOLUTE_SOURCE, 1, FALSE)
|
|
validate_absolute_severity(dummy, "after being given [ABSOLUTE_SOURCE]", 1, list(
|
|
ABSOLUTE_SOURCE = 1,
|
|
))
|
|
|
|
myopia = dummy.is_nearsighted()
|
|
TEST_ASSERT_EQUAL(myopia.get_severity(), 2, "Final severity amount wasn't equal to [CORRECTABLE_SOURCE] when a smaller absolute source was present.")
|
|
|
|
// Do the glasses still work after adding an absolute source?
|
|
validate_glasses_behaviour(dummy, "after being given [ABSOLUTE_SOURCE]", 1, 2)
|
|
|
|
/* REMOVAL */
|
|
//There are two different ways a source can be removed, let's test both of them
|
|
dummy.cure_nearsighted(ABSOLUTE_SOURCE)
|
|
validate_absolute_severity(dummy, "after removing [ABSOLUTE_SOURCE]", 0, list())
|
|
|
|
myopia = dummy.is_nearsighted()
|
|
TEST_ASSERT_NOTNULL(myopia, "Dummy lost nearsightedness after removing [CORRECTABLE_SOURCE] even though there were still sources left.")
|
|
|
|
//After this, the effect should be removed.
|
|
dummy.assign_nearsightedness(CORRECTABLE_SOURCE, 0, TRUE)
|
|
TEST_ASSERT(!dummy.is_nearsighted(), "Dummy was still nearsighted after all sources were removed.")
|
|
|
|
/datum/unit_test/nearsighted_effect/proc/validate_source_contents(checking, status, list/current_sources, list/expected_sources)
|
|
TEST_ASSERT_EQUAL(length(current_sources), length(expected_sources), "[checking] had a different amount of contents than expected [status].")
|
|
//We'll copy the list to make sure we got all the sources
|
|
var/list/hopefully_empty_result = expected_sources.Copy()
|
|
for(var/expected_source in expected_sources)
|
|
var/expected_severity = expected_sources[expected_source]
|
|
TEST_ASSERT_NOTNULL(current_sources[expected_source], "[expected_source] wasn't in [checking] [status].")
|
|
TEST_ASSERT_EQUAL(current_sources[expected_source], expected_severity, "The severity for [expected_source] in [checking] [status] wasn't as expected.")
|
|
hopefully_empty_result -= expected_source
|
|
TEST_ASSERT(!length(hopefully_empty_result), "[checking] has all the sources we wanted [status], but there were unexpected extra sources.")
|
|
|
|
/datum/unit_test/nearsighted_effect/proc/validate_correctable_severity(mob/living/carbon/human/dummy, status, expected_final_severity, list/expected_sources)
|
|
//! This proc expects the dummy to be nearsighted
|
|
var/datum/status_effect/grouped/nearsighted/myopia = dummy.is_nearsighted()
|
|
TEST_ASSERT_NOTNULL(myopia, "Dummy was not nearsighted when given correctable nearsightedness [status].")
|
|
|
|
validate_source_contents("correctable sources", status, myopia.correctable_sources, expected_sources)
|
|
TEST_ASSERT_EQUAL(myopia.correctable_severity, expected_final_severity, "The determined correctable severity [status] was wrong.")
|
|
|
|
/datum/unit_test/nearsighted_effect/proc/validate_absolute_severity(mob/living/carbon/human/dummy, status, expected_final_severity, list/expected_sources)
|
|
//! This proc expects the dummy to be nearsighted
|
|
var/datum/status_effect/grouped/nearsighted/myopia = dummy.is_nearsighted()
|
|
TEST_ASSERT_NOTNULL(myopia, "Dummy was not nearsighted when given absolute nearsightedness [status].")
|
|
|
|
validate_source_contents("absolute sources", status, myopia.absolute_sources, expected_sources)
|
|
TEST_ASSERT_EQUAL(myopia.absolute_severity, expected_final_severity, "The determined absolute severity [status] was wrong.")
|
|
|
|
/// Makes sure that having vision corrected affects the dummy and preserves vision
|
|
/datum/unit_test/nearsighted_effect/proc/validate_glasses_behaviour(mob/living/carbon/human/dummy, status, expected_severity_with, expected_severity_without)
|
|
//! This proc expects the dummy to be nearsighted
|
|
var/obj/item/clothing/glasses/regular/prescriptions = allocate(/obj/item/clothing/glasses/regular)
|
|
dummy.equip_to_slot_if_possible(prescriptions, ITEM_SLOT_EYES)
|
|
var/datum/status_effect/grouped/nearsighted/myopia = dummy.is_nearsighted()
|
|
|
|
TEST_ASSERT_NOTNULL(myopia, "Dummy no longer had the nearsighted status after putting on glasses. They should still be nearsighted.")
|
|
TEST_ASSERT(!dummy.is_nearsighted_currently(), "Dummy was nearsighted currently [status] even though they were wearing glasses.")
|
|
TEST_ASSERT_EQUAL(myopia.get_severity(), expected_severity_with, "get_severity() returned an impossible severity amount when putting on glasses [status].")
|
|
|
|
// Check their overlay, they might need to lose it
|
|
if(expected_severity_with == 0)
|
|
TEST_ASSERT(!HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy still had the nearsighted overlay when putting glasses on [status].")
|
|
else
|
|
TEST_ASSERT(HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy lost the nearsighted overlay when putting glasses on [status].")
|
|
|
|
// Now take them off
|
|
QDEL_NULL(prescriptions)
|
|
TEST_ASSERT(dummy.is_nearsighted_currently(), "Dummy didn't become nearsighted currently [status] even though they weren't wearing glasses.")
|
|
TEST_ASSERT_EQUAL(myopia.get_severity(), expected_severity_without, "get_severity() returned an impossible severity amount when taking off glasses [status].")
|
|
|
|
// Check their overlay again, they may or may not should still have it
|
|
if(expected_severity_without != 0)
|
|
TEST_ASSERT(HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired), "Dummy had the nearsighted overlay when putting glasses on [status].")
|
|
else //If the bottom condition is hit, what are we even doing man
|
|
TEST_ASSERT(!HAS_SCREEN_OVERLAY(dummy, /atom/movable/screen/fullscreen/impaired),
|
|
"Dummy had the nearsighted overlay when putting glasses on [status].")
|
|
|
|
|
|
#undef CORRECTABLE_SOURCE
|
|
#undef ABSOLUTE_SOURCE
|
|
|
|
#undef HAS_SCREEN_OVERLAY
|
|
#undef HAS_CLIENT_COLOR
|