mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 09:42:29 +00:00
Nearsighted severity sources (with unit test) + status_effect/grouped minor rework (#88591)
# About The Pull Request ## Nearsighted Sources Nearsighted now associates/tracks severity applied by each source. Previously, nearsighted only used a single variable which had to be shared by every source, which caused problems for things like scarred eyes which needed independent behaviour. This implementation allows sources with different severity levels to coexist without needing workarounds There are now two different severity types for nearsightedness: * Correctable: Can be mitigated with vision correction (like glasses) * Absolute: Cannot be mitigated from any source, used for scarred eyes Which can allow nearsighted sources to not be affected by vision correction. Also, since there is no more technical conflict between the two quirks, I've made it so that nearsighted and scarred eye can be selected together (as a QOL change) There is also a new unit test for this new behaviour (nearsighted_effect) that checks application and removal ## status_effect/grouped minor rework Grouped status effects now have `source_added()` and `source_removed()` procs, which are called whenever a source is added or removed from the effect I did this because the previous implementation was somewhat unwieldy. Inherited status effects would recieve the _currently existing_ effect through merge_with_existing, and require them to modify the existing effect's properties, which is odd and not intuitive to work with (the proc's `src` was not the existing effect) It not being called for every source also made users repeat code in `on_creation()` and `merge_with_existing()` for every source added. This new interface should prevent repetition and be generally more intuitive to work with. # Changelog 🆑 refactor: Nearsighted has been reworked to track severity applied from each source, as well as allow "non-correctable" nearsightedness (for things like scarred eyes). qol: The above being possible now means that you can select the Nearsighted and Scarred eye quirks together fix: Any bug that would occur from becoming nearsighted with a scarred eye should be fixed now code: status_effect/grouped merging code has been improved (i hope) /🆑
This commit is contained in:
@@ -73,9 +73,18 @@
|
||||
/// Is the mob blind from the passed source or sources?
|
||||
#define is_blind_from(sources) has_status_effect_from_source(/datum/status_effect/grouped/blindness, sources)
|
||||
|
||||
/// Causes the mob to become nearsighted via the passed source
|
||||
/// We are not nearsighted right now.
|
||||
#define NEARSIGHTED_DISABLED 0
|
||||
/// Something is correcting our vision, but we are still a bit nearsighted.
|
||||
#define NEARSIGHTED_CORRECTED 1
|
||||
/// We are fully nearsighted.
|
||||
#define NEARSIGHTED_ENABLED 2
|
||||
|
||||
/// Simplified macro that causes the mob to become nearsighted (with correction possible) via the passed source.
|
||||
#define become_nearsighted(source) apply_status_effect(/datum/status_effect/grouped/nearsighted, source)
|
||||
/// Cures the mob's nearsightedness from the passed source, removing nearsighted wholesale if no sources are left
|
||||
/// Causes the mob to become nearsighted from the passed source by a severity, which may be corrected with glasses.
|
||||
#define assign_nearsightedness(source, amount, correctable) apply_status_effect(/datum/status_effect/grouped/nearsighted, source, amount, correctable)
|
||||
/// Cures the mob's nearsightedness from the passed source, removing nearsighted wholesale if no sources are left.
|
||||
#define cure_nearsighted(source) remove_status_effect(/datum/status_effect/grouped/nearsighted, source)
|
||||
|
||||
/// Is the mob nearsighted?
|
||||
@@ -89,7 +98,7 @@
|
||||
var/datum/status_effect/grouped/nearsighted/nearsight = has_status_effect(/datum/status_effect/grouped/nearsighted)
|
||||
if(isnull(nearsight))
|
||||
return FALSE
|
||||
return nearsight.should_be_nearsighted()
|
||||
return (nearsight.should_be_nearsighted() > NEARSIGHTED_CORRECTED)
|
||||
|
||||
// Status effect application helpers.
|
||||
// These are macros for easier use of adjust_timed_status_effect and set_timed_status_effect.
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
// Shifted to glob so they are generated at world start instead of risking players doing preference stuff before the subsystem inits
|
||||
GLOBAL_LIST_INIT_TYPED(quirk_blacklist, /list/datum/quirk, list(
|
||||
list(/datum/quirk/item_quirk/blindness, /datum/quirk/item_quirk/nearsighted, /datum/quirk/item_quirk/scarred_eye),
|
||||
list(/datum/quirk/item_quirk/blindness, /datum/quirk/item_quirk/nearsighted),
|
||||
list(/datum/quirk/item_quirk/blindness, /datum/quirk/item_quirk/scarred_eye),
|
||||
list(/datum/quirk/item_quirk/blindness, /datum/quirk/item_quirk/fluoride_stare),
|
||||
list(/datum/quirk/item_quirk/blindness, /datum/quirk/touchy),
|
||||
list(/datum/quirk/jolly, /datum/quirk/depression, /datum/quirk/apathetic, /datum/quirk/hypersensitive),
|
||||
|
||||
@@ -12,15 +12,9 @@
|
||||
/datum/status_effect/grouped/hooked/proc/still_exists()
|
||||
return !QDELETED(src)
|
||||
|
||||
/datum/status_effect/grouped/hooked/on_creation(mob/living/new_owner, datum/beam/fishing_line/source)
|
||||
. = ..()
|
||||
if(!.) //merged with an existing effect
|
||||
return
|
||||
/datum/status_effect/grouped/hooked/source_added(datum/beam/fishing_line/source)
|
||||
RegisterSignal(source, COMSIG_QDELETING, PROC_REF(on_fishing_line_deleted))
|
||||
|
||||
/datum/status_effect/grouped/hooked/merge_with_existing(datum/status_effect/grouped/hooked/existing, datum/beam/fishing_line/source)
|
||||
existing.RegisterSignal(source, COMSIG_QDELETING, PROC_REF(on_fishing_line_deleted))
|
||||
|
||||
/datum/status_effect/grouped/hooked/proc/on_fishing_line_deleted(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
owner.remove_status_effect(type, source)
|
||||
|
||||
@@ -2,69 +2,6 @@
|
||||
/// There are no reason why these cannot be blinded, it is simply for "design reasons" (these things shouldn't be blinded)
|
||||
#define CAN_BE_BLIND(mob) (!isanimal_or_basicmob(mob) && !isbrain(mob) && !isrevenant(mob))
|
||||
|
||||
/// Nearsighted
|
||||
/datum/status_effect/grouped/nearsighted
|
||||
id = "nearsighted"
|
||||
tick_interval = STATUS_EFFECT_NO_TICK
|
||||
alert_type = null
|
||||
// This is not "remove on fullheal" as in practice,
|
||||
// fullheal should instead remove all the sources and in turn cure this
|
||||
|
||||
/// Static list of signals that, when received, we force an update to our nearsighted overlay
|
||||
var/static/list/update_signals = list(
|
||||
SIGNAL_ADDTRAIT(TRAIT_NEARSIGHTED_CORRECTED),
|
||||
SIGNAL_REMOVETRAIT(TRAIT_NEARSIGHTED_CORRECTED),
|
||||
SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS),
|
||||
SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS),
|
||||
)
|
||||
/// How severe is our nearsightedness right now
|
||||
var/overlay_severity = 2
|
||||
|
||||
/datum/status_effect/grouped/nearsighted/on_apply()
|
||||
RegisterSignals(owner, update_signals, PROC_REF(update_nearsightedness))
|
||||
update_nearsighted_overlay()
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/grouped/nearsighted/on_remove()
|
||||
UnregisterSignal(owner, update_signals)
|
||||
owner.clear_fullscreen(id)
|
||||
return ..()
|
||||
|
||||
/// Signal proc for when we gain or lose [TRAIT_NEARSIGHTED_CORRECTED] - (temporarily) disable the overlay if we're correcting it
|
||||
/datum/status_effect/grouped/nearsighted/proc/update_nearsightedness(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
update_nearsighted_overlay()
|
||||
|
||||
/// Checks if we should be nearsighted currently, or if we should clear the overlay
|
||||
/datum/status_effect/grouped/nearsighted/proc/should_be_nearsighted()
|
||||
if (ishuman(owner))
|
||||
var/mob/living/carbon/human/human_owner = owner
|
||||
if (human_owner.get_eye_scars())
|
||||
return TRUE
|
||||
if(HAS_TRAIT(owner, TRAIT_NEARSIGHTED_CORRECTED))
|
||||
return FALSE
|
||||
if(HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Updates our nearsightd overlay, either removing it if we have the trait or adding it if we don't
|
||||
/datum/status_effect/grouped/nearsighted/proc/update_nearsighted_overlay()
|
||||
if(should_be_nearsighted())
|
||||
owner.overlay_fullscreen(id, /atom/movable/screen/fullscreen/impaired, overlay_severity)
|
||||
else
|
||||
owner.clear_fullscreen(id)
|
||||
|
||||
/// Sets the severity of our nearsighted overlay
|
||||
/datum/status_effect/grouped/nearsighted/proc/set_nearsighted_severity(to_value)
|
||||
if(!isnum(to_value))
|
||||
return
|
||||
if(overlay_severity == to_value)
|
||||
return
|
||||
|
||||
overlay_severity = to_value
|
||||
update_nearsighted_overlay()
|
||||
|
||||
/// Blindness
|
||||
/datum/status_effect/grouped/blindness
|
||||
id = "blindness"
|
||||
131
code/datums/status_effects/debuffs/vision/nearsighted.dm
Normal file
131
code/datums/status_effects/debuffs/vision/nearsighted.dm
Normal file
@@ -0,0 +1,131 @@
|
||||
/// Maximum severity level possible.
|
||||
#define MAX_SEVERITY 3
|
||||
|
||||
/// Nearsighted
|
||||
/datum/status_effect/grouped/nearsighted
|
||||
id = "nearsighted"
|
||||
tick_interval = STATUS_EFFECT_NO_TICK
|
||||
alert_type = null
|
||||
// This is not "remove on fullheal" as in practice,
|
||||
// fullheal should instead remove all the sources and in turn cure this
|
||||
|
||||
/// Static list of signals that, when received, we force an update to our nearsighted overlay
|
||||
var/static/list/update_signals = list(
|
||||
SIGNAL_ADDTRAIT(TRAIT_NEARSIGHTED_CORRECTED),
|
||||
SIGNAL_REMOVETRAIT(TRAIT_NEARSIGHTED_CORRECTED),
|
||||
SIGNAL_ADDTRAIT(TRAIT_SIGHT_BYPASS),
|
||||
SIGNAL_REMOVETRAIT(TRAIT_SIGHT_BYPASS),
|
||||
)
|
||||
|
||||
/* ("source_id" = num) */
|
||||
/// Associated list of sources with their supplied severity level. Cannot be corrected with glasses.
|
||||
var/absolute_sources = list()
|
||||
/// Associated list of sources with their supplied severity level. Can be corrected with glasses.
|
||||
var/correctable_sources = list()
|
||||
|
||||
/// Highest severity value in [var/absolute_sources].
|
||||
var/absolute_severity = 0
|
||||
/// Highest severity value in [var/correctable_sources].
|
||||
var/correctable_severity = 0
|
||||
|
||||
/datum/status_effect/grouped/nearsighted/source_added(source, severity = 2, correctable = TRUE)
|
||||
set_severity(source, severity, correctable)
|
||||
|
||||
/datum/status_effect/grouped/nearsighted/source_removed(source, removing)
|
||||
if(correctable_sources[source])
|
||||
correctable_sources -= source
|
||||
recalculate_severity(correctable=TRUE)
|
||||
if(absolute_sources[source])
|
||||
absolute_sources -= source
|
||||
recalculate_severity(correctable=FALSE)
|
||||
if(!removing) //so the overlay doesn't update twice
|
||||
update_nearsighted_overlay()
|
||||
|
||||
/datum/status_effect/grouped/nearsighted/on_apply()
|
||||
RegisterSignals(owner, update_signals, PROC_REF(update_nearsightedness))
|
||||
update_nearsighted_overlay()
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/grouped/nearsighted/on_remove()
|
||||
UnregisterSignal(owner, update_signals)
|
||||
owner.clear_fullscreen(id)
|
||||
return ..()
|
||||
|
||||
/// Signal proc for when we gain or lose [TRAIT_NEARSIGHTED_CORRECTED] - (temporarily) disable the overlay if we're correcting it
|
||||
/datum/status_effect/grouped/nearsighted/proc/update_nearsightedness(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
update_nearsighted_overlay()
|
||||
|
||||
/// Checks if we should be nearsighted currently, or if we should clear the overlay
|
||||
/datum/status_effect/grouped/nearsighted/proc/should_be_nearsighted()
|
||||
if(HAS_TRAIT(owner, TRAIT_SIGHT_BYPASS))
|
||||
return NEARSIGHTED_DISABLED
|
||||
if(HAS_TRAIT(owner, TRAIT_NEARSIGHTED_CORRECTED))
|
||||
return NEARSIGHTED_CORRECTED
|
||||
return NEARSIGHTED_ENABLED
|
||||
|
||||
/// Updates our nearsightd overlay, either removing it if we have the trait or adding it if we don't
|
||||
/datum/status_effect/grouped/nearsighted/proc/update_nearsighted_overlay()
|
||||
var/severity = get_severity()
|
||||
if(severity <= 0) // We aren't nearsighted
|
||||
owner.clear_fullscreen(id)
|
||||
else
|
||||
owner.overlay_fullscreen(id, /atom/movable/screen/fullscreen/impaired, severity)
|
||||
|
||||
/// Gets the severity value that would be used when calculating impairment.
|
||||
/datum/status_effect/grouped/nearsighted/proc/get_severity()
|
||||
var/are_we_nearsighted = should_be_nearsighted()
|
||||
|
||||
if(!are_we_nearsighted)
|
||||
return 0
|
||||
|
||||
var/final_severity = absolute_severity
|
||||
if(are_we_nearsighted != NEARSIGHTED_CORRECTED) //We don't have corrective vision
|
||||
final_severity = max(absolute_severity, correctable_severity)
|
||||
|
||||
final_severity = min(final_severity, MAX_SEVERITY)
|
||||
|
||||
return final_severity
|
||||
|
||||
/// Sets the severity of a source. Recalculates the severity variables if there is a change
|
||||
/datum/status_effect/grouped/nearsighted/proc/set_severity(source, new_severity, correctable = FALSE)
|
||||
if(!source)
|
||||
return
|
||||
if(!isnum(new_severity))
|
||||
return
|
||||
|
||||
var/list/to_search = correctable ? correctable_sources : absolute_sources
|
||||
if(to_search[source] == new_severity)
|
||||
return
|
||||
|
||||
if(new_severity > 0)
|
||||
to_search[source] = new_severity
|
||||
else
|
||||
to_search -= source
|
||||
|
||||
recalculate_severity(correctable)
|
||||
|
||||
/* If we have no more of this source, let's remove it (and potentially ourselves) */
|
||||
if(!absolute_sources[source] && !correctable_sources[source])
|
||||
owner.remove_status_effect(type, source) //this will update our overlay as well if we're still around
|
||||
else
|
||||
update_nearsighted_overlay()
|
||||
|
||||
/datum/status_effect/grouped/nearsighted/proc/recalculate_severity(correctable)
|
||||
if(isnull(correctable))
|
||||
CRASH("was not provided with an argument (this needs to be explicit)")
|
||||
|
||||
var/highest_severity = 0
|
||||
var/list/to_search = correctable ? correctable_sources : absolute_sources
|
||||
|
||||
for(var/existing_source in to_search)
|
||||
var/candidate = to_search[existing_source]
|
||||
if(candidate > highest_severity)
|
||||
highest_severity = candidate
|
||||
|
||||
if(correctable)
|
||||
correctable_severity = highest_severity
|
||||
else
|
||||
absolute_severity = highest_severity
|
||||
|
||||
#undef MAX_SEVERITY
|
||||
@@ -7,20 +7,41 @@
|
||||
/// A list of all sources applying this status effect. Sources are a list of keys
|
||||
var/list/sources = list()
|
||||
|
||||
/datum/status_effect/grouped/on_creation(mob/living/new_owner, source)
|
||||
/datum/status_effect/grouped/on_creation(mob/living/new_owner, source, ...)
|
||||
//Get our supplied arguments, without new_owner
|
||||
var/list/new_source_args = args.Copy(2)
|
||||
|
||||
var/datum/status_effect/grouped/existing = new_owner.has_status_effect(type)
|
||||
if(existing)
|
||||
existing.sources |= source
|
||||
merge_with_existing(existing, source)
|
||||
existing.source_added(arglist(new_source_args))
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
sources |= source
|
||||
return ..()
|
||||
/* We are the original */
|
||||
|
||||
/datum/status_effect/grouped/proc/merge_with_existing(datum/status_effect/grouped/existing, source)
|
||||
. = ..()
|
||||
if(.)
|
||||
sources |= source
|
||||
source_added(arglist(new_source_args))
|
||||
|
||||
/**
|
||||
* Called after a source is added to the status effect,
|
||||
* this includes the first source added after creation.
|
||||
*/
|
||||
/datum/status_effect/grouped/proc/source_added(source, ...)
|
||||
return
|
||||
|
||||
/**
|
||||
* Called after a source is removed from the status effect. \
|
||||
* `removing` will be TRUE if this is the last source, which means
|
||||
* the effect will be deleted.
|
||||
*/
|
||||
/datum/status_effect/grouped/proc/source_removed(source, removing)
|
||||
return
|
||||
|
||||
/datum/status_effect/grouped/before_remove(source)
|
||||
sources -= source
|
||||
return !length(sources)
|
||||
var/was_last_source = !length(sources)
|
||||
source_removed(source, was_last_source)
|
||||
return was_last_source
|
||||
|
||||
@@ -313,18 +313,14 @@
|
||||
apply_scarring_effects()
|
||||
|
||||
/obj/item/organ/eyes/proc/apply_scarring_effects()
|
||||
if (!owner)
|
||||
if(!owner)
|
||||
return
|
||||
var/datum/status_effect/grouped/nearsighted/nearsightedness = owner.is_nearsighted()
|
||||
// Even if eyes have enough health, our owner still becomes nearsighted
|
||||
if (scarring & RIGHT_EYE_SCAR)
|
||||
owner.become_nearsighted(TRAIT_RIGHT_EYE_SCAR)
|
||||
if (scarring & LEFT_EYE_SCAR)
|
||||
owner.become_nearsighted(TRAIT_LEFT_EYE_SCAR)
|
||||
if (isnull(nearsightedness)) // We aren't nearsighted from any other source
|
||||
nearsightedness = owner.is_nearsighted()
|
||||
nearsightedness.set_nearsighted_severity(1)
|
||||
if ((scarring & RIGHT_EYE_SCAR) && (scarring & LEFT_EYE_SCAR))
|
||||
if(scarring & RIGHT_EYE_SCAR)
|
||||
owner.assign_nearsightedness(TRAIT_RIGHT_EYE_SCAR, 1, FALSE)
|
||||
if(scarring & LEFT_EYE_SCAR)
|
||||
owner.assign_nearsightedness(TRAIT_LEFT_EYE_SCAR, 1, FALSE)
|
||||
if((scarring & RIGHT_EYE_SCAR) && (scarring & LEFT_EYE_SCAR))
|
||||
owner.become_blind(EYE_SCARRING_TRAIT)
|
||||
owner.update_body()
|
||||
|
||||
@@ -370,10 +366,6 @@
|
||||
damaged = FALSE
|
||||
// clear nearsightedness from damage
|
||||
owner.cure_nearsighted(EYE_DAMAGE)
|
||||
// if we're still nearsighted, reset its severity
|
||||
// this is kinda icky, ideally we'd track severity to source but that's way more complex
|
||||
var/datum/status_effect/grouped/nearsighted/nearsightedness = owner.is_nearsighted()
|
||||
nearsightedness?.set_nearsighted_severity(1)
|
||||
// and cure blindness from damage
|
||||
owner.cure_blind(EYE_DAMAGE)
|
||||
return
|
||||
@@ -388,10 +380,8 @@
|
||||
|
||||
else
|
||||
// become nearsighted from damage
|
||||
owner.become_nearsighted(EYE_DAMAGE)
|
||||
// update the severity of our nearsightedness based on our eye damage
|
||||
var/datum/status_effect/grouped/nearsighted/nearsightedness = owner.is_nearsighted()
|
||||
nearsightedness.set_nearsighted_severity(damage > high_threshold ? 3 : 2)
|
||||
var/severity = damage > high_threshold ? 3 : 2
|
||||
owner.assign_nearsightedness(EYE_DAMAGE, severity, TRUE)
|
||||
|
||||
damaged = TRUE
|
||||
|
||||
|
||||
@@ -63,11 +63,11 @@
|
||||
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 nearsighted is added and disabled correctly
|
||||
* Unit test to check that the nearsighted quirk is added and disabled correctly
|
||||
*/
|
||||
/datum/unit_test/nearsightedness
|
||||
/datum/unit_test/nearsighted_quirk
|
||||
|
||||
/datum/unit_test/nearsightedness/Run()
|
||||
/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)
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
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.overlay_severity, 2, "After taking minor eye damage, the dummy's nearsightedness was the incorrect severity.")
|
||||
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)
|
||||
@@ -137,11 +137,120 @@
|
||||
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.overlay_severity, 3, "After taking major eye damage, the dummy's nearsightedness was the incorrect severity.")
|
||||
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
|
||||
|
||||
@@ -1914,7 +1914,6 @@
|
||||
#include "code\datums\status_effects\buffs\food\grant_trait.dm"
|
||||
#include "code\datums\status_effects\buffs\food\haste.dm"
|
||||
#include "code\datums\status_effects\buffs\food\speech.dm"
|
||||
#include "code\datums\status_effects\debuffs\blindness.dm"
|
||||
#include "code\datums\status_effects\debuffs\choke.dm"
|
||||
#include "code\datums\status_effects\debuffs\confusion.dm"
|
||||
#include "code\datums\status_effects\debuffs\cursed.dm"
|
||||
@@ -1949,6 +1948,8 @@
|
||||
#include "code\datums\status_effects\debuffs\slime\slime_food.dm"
|
||||
#include "code\datums\status_effects\debuffs\slime\slime_leech.dm"
|
||||
#include "code\datums\status_effects\debuffs\slime\slimed.dm"
|
||||
#include "code\datums\status_effects\debuffs\vision\blindness.dm"
|
||||
#include "code\datums\status_effects\debuffs\vision\nearsighted.dm"
|
||||
#include "code\datums\storage\storage.dm"
|
||||
#include "code\datums\storage\storage_interface.dm"
|
||||
#include "code\datums\storage\subtypes\backpack.dm"
|
||||
|
||||
Reference in New Issue
Block a user