Skip to content

Commit

Permalink
Xeno strains unit test (#5725)
Browse files Browse the repository at this point in the history
# About the pull request

Adds a unit test for xeno strains.
I could have included this in #5542, but I thought it would be better in
its own PR in order to keep the checks and everything separate.

The removed sprites for the Trapper, Charger, Gardener, and Watcher
strains are (as far as I'm able to tell) completely identical to that of
the base caste, and are only there in order to make the old system work
properly.

Currently, this includes the following tests:
- Checking that the `caste_type` variable on each
`/mob/living/carbon/xenomorph` subtype has a corresponding entry in
`GLOB.xeno_datum_list`. (Not really strain related but I figured no harm
in including it)
- Checking that each `/datum/xeno_strain` subtype has its own `name` and
`description`.
- Making sure that each strain's `actions_to_add` and
`actions_to_remove` lists are added and removed from the xeno properly.
(Taking into account any which are re-added.)
- Making sure that the strain's `behavior_delegate_type` is successfully
added to the xeno.
- If the strain doesn't have an `icon_state_prefix`, going through the
xeno's `icon` file and double checking that there aren't strain sprites
in there (That is, sprites beginning with the strain's name). If there
are any, then `icon_state_prefix` should probably be set to use them.
- If the strain *does* have an `icon_state_prefix`, making sure that the
xeno's sprite actually got changed to the strain version.

# Explain why it's good for the game

More unit tests! (woo)

# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>

Put screenshots and videos here with an empty line between the
screenshots and the `<details>` tags.

</details>


# Changelog
:cl:
code: Added a unit test for xeno strains.
/:cl:
  • Loading branch information
SabreML authored Feb 19, 2024
1 parent 534d770 commit 53ebed1
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 1 deletion.
4 changes: 4 additions & 0 deletions code/__HELPERS/text.dm
Original file line number Diff line number Diff line change
Expand Up @@ -381,3 +381,7 @@
if(.)
return
return 0

/// Check if the string `haystack` begins with the string `needle`.
/proc/string_starts_with(haystack, needle)
return (copytext(haystack, 1, length(needle) + 1) == needle)
2 changes: 2 additions & 0 deletions code/controllers/subsystem/minimap.dm
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ SUBSYSTEM_DEF(minimaps)
owner?.client?.remove_from_screen(map)
minimap_displayed = FALSE

UnregisterSignal(target, COMSIG_MOVABLE_Z_CHANGED)

/**
* Updates the map when the owner changes zlevel
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@
ability_name = "view tacmap"

var/mob/living/carbon/xenomorph/queen/tracked_queen
var/hivenumber

/datum/action/xeno_action/onclick/tacmap/Destroy()
tracked_queen = null
Expand All @@ -505,6 +506,7 @@
/datum/action/xeno_action/onclick/tacmap/give_to(mob/living/carbon/xenomorph/xeno)
. = ..()

hivenumber = xeno.hive.hivenumber
RegisterSignal(xeno.hive, COMSIG_HIVE_NEW_QUEEN, PROC_REF(handle_new_queen))

if(!xeno.hive.living_xeno_queen)
Expand All @@ -516,6 +518,10 @@

handle_new_queen(new_queen = xeno.hive.living_xeno_queen)

/datum/action/xeno_action/onclick/tacmap/remove_from(mob/living/carbon/xenomorph/xeno)
. = ..()
UnregisterSignal(GLOB.hive_datum[hivenumber], COMSIG_HIVE_NEW_QUEEN)

/// handles the addition of a new queen, hiding if appropriate
/datum/action/xeno_action/onclick/tacmap/proc/handle_new_queen(datum/hive_status/hive, mob/living/carbon/xenomorph/queen/new_queen)
SIGNAL_HANDLER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
hivelord.can_stack_builds = TRUE
hivelord.recalculate_plasma()

hivelord.client.change_view(10, src)
hivelord.client?.change_view(10, src)

hivelord.set_resin_build_order(GLOB.resin_build_order_hivelord_whisperer)
for(var/datum/action/xeno_action/action in hivelord.actions)
Expand Down
1 change: 1 addition & 0 deletions code/modules/unit_tests/_unit_tests.dm
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
#include "tgui_create_message.dm"
#include "timer_sanity.dm"
#include "tutorials.dm"
#include "xeno_strains.dm"

// Unit tests backend
#include "focus_only_tests.dm"
Expand Down
59 changes: 59 additions & 0 deletions code/modules/unit_tests/xeno_strains.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/datum/unit_test/xeno_strains

/datum/unit_test/xeno_strains/Run()
for(var/mob/living/carbon/xenomorph/caste_mob as anything in subtypesof(/mob/living/carbon/xenomorph))
var/datum/caste_datum/caste_datum = GLOB.xeno_datum_list[initial(caste_mob.caste_type)]
if(!caste_datum)
// not really strain related but may as well have this in here
TEST_FAIL("[caste_mob] has no `/datum/caste_datum`! (Possible mismatch of `caste_type`)")
continue

for(var/datum/xeno_strain/strain_path as anything in caste_datum.available_strains)
// Check for these, but test the strain either way.
if(!initial(strain_path.name))
TEST_FAIL("[strain_path] has no name!")
if(!initial(strain_path.description))
TEST_FAIL("[strain_path] has no description!")

test_strain(caste_mob, strain_path)

/datum/unit_test/xeno_strains/proc/test_strain(mob_path, strain_path)
var/mob/living/carbon/xenomorph/fred = allocate(mob_path)
var/datum/xeno_strain/strain = new strain_path()

strain._add_to_xeno(fred)

// Actions which should have been removed.
var/list/removed_actions = strain.actions_to_remove
// Exclude any actions which are in both strain lists (re-added afterwards).
removed_actions -= (removed_actions & strain.actions_to_add)

// Actions which should have been added.
var/list/added_actions = strain.actions_to_add.Copy()

for(var/datum/action/action as anything in fred.actions)
if(action.type in removed_actions)
TEST_FAIL("[strain.type] failed to remove [action.type] when added to a Xenomorph!")
if(action.type in added_actions)
// Remove this action from `added_actions`.
added_actions -= action.type
// If there's anything left in `added_actions`, then something wasn't given to the xeno.
if(length(added_actions))
TEST_FAIL("[strain.type] failed to give the following actions when added to a Xenomorph: [json_encode(added_actions)]")

// If the strain has a `/datum/behavior_delegate`, but it wasn't applied to the xeno.
if(strain.behavior_delegate_type && !istype(fred.behavior_delegate, strain.behavior_delegate_type))
TEST_FAIL("[strain.type]'s behavior_delegate was not applied when added to a Xenomorph!")

// If the strain doesn't have a custom icon state set.
if(!strain.icon_state_prefix)
// Check if any of the sprites in the xeno's .dmi file belong to this strain.
// If there are any, it probably means that someone just forgot to add an `icon_state_prefix` to the strain.
for(var/icon_state in icon_states(fred.icon))
if(string_starts_with(icon_state, strain.name)) // (This won't catch everything, but it should get the easy ones.)
TEST_FAIL("[fred.icon] contains sprites for [strain.type] that aren't being used!")
break

// If the strain *does* have a custom icon state set, but the xeno's sprite wasn't changed to it.
else if(!string_starts_with(fred.icon_state, strain.icon_state_prefix))
TEST_FAIL("[strain.type]'s icon_state_prefix was not applied when added to a Xenomorph!")
Binary file modified icons/mob/xenos/boiler.dmi
Binary file not shown.
Binary file modified icons/mob/xenos/crusher.dmi
Binary file not shown.
Binary file modified icons/mob/xenos/drone.dmi
Binary file not shown.
Binary file modified icons/mob/xenos/facehugger.dmi
Binary file not shown.

0 comments on commit 53ebed1

Please sign in to comment.