Basic mobs targeting, attacks, and pig migration. (#28987)

* Basic mobs targeting, attacks, and pig migration.

* run updatepaths

* fix duplicate macro def

* Update code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm

Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>

---------

Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
This commit is contained in:
warriorstar-orion
2025-04-15 10:45:56 -04:00
committed by GitHub
parent 5da3694877
commit efc8adb6dd
44 changed files with 1190 additions and 69 deletions
+1
View File
@@ -29,6 +29,7 @@
#include "test_dynamic_budget.dm"
#include "test_elements.dm"
#include "test_emotes.dm"
#include "test_ensure_subtree_operational_datum.dm"
#include "test_init_sanity.dm"
#include "test_log_format.dm"
#include "test_map_templates.dm"
@@ -0,0 +1,64 @@
/// The subtree that requires the operational datum.
#define REQUIRED_SUBTREE "required_subtree"
/// The list of typepaths of applicable operational datums that would satisfy the requirement.
#define REQUIRED_OPERATIONAL_DATUMS "required_operational_datums"
/// Unit Test that ensure that if we add a specific planning subtree to a basic mob's planning tree, that we also have the operational datum needed for it (component/element).
/// This can be extended to other "mandatory" operational datums for certain subtrees to work.
/datum/game_test/ensure_subtree_operational_datum
/// Associated list of mobs that we need to test this on. Key is the typepath of the mob, value is a list of the planning subtree and the operational datums that are required for it.
var/list/testable_mobs = list()
/datum/game_test/ensure_subtree_operational_datum/Run()
gather_testable_mobs()
test_applicable_mobs()
/// First, look for all mobs that have a planning subtree that requires an element, then add it to the list for stuff to test afterwards. Done like this to not have one mumbo proc that's hard to read.
/datum/game_test/ensure_subtree_operational_datum/proc/gather_testable_mobs()
for(var/mob/living/basic/checkable_mob as anything in subtypesof(/mob/living/basic))
var/datum/ai_controller/testable_controller = initial(checkable_mob.ai_controller)
if(isnull(testable_controller))
continue
// we can't do inital() memes on lists so it's allocation time
testable_controller = allocate(testable_controller)
var/list/ai_planning_subtrees = testable_controller.planning_subtrees // list of instantiated datums. easy money
if(!length(ai_planning_subtrees))
continue
for(var/datum/ai_planning_subtree/testable_subtree as anything in ai_planning_subtrees)
var/list/necessary_datums = testable_subtree.operational_datums
if(isnull(necessary_datums))
continue
testable_mobs[checkable_mob] = list(
REQUIRED_OPERATIONAL_DATUMS = necessary_datums,
REQUIRED_SUBTREE = testable_subtree.type,
)
/// Then, test the mobs that we've found
/datum/game_test/ensure_subtree_operational_datum/proc/test_applicable_mobs()
for(var/mob/living/basic/checkable_mob as anything in testable_mobs)
var/list/checkable_mob_data = testable_mobs[checkable_mob]
checkable_mob = allocate(checkable_mob)
var/datum/ai_planning_subtree/test_subtree = checkable_mob_data[REQUIRED_SUBTREE]
var/list/trait_sources = GET_TRAIT_SOURCES(checkable_mob, TRAIT_SUBTREE_REQUIRED_OPERATIONAL_DATUM)
if(!length(trait_sources)) // yes yes we could use `COUNT_TRAIT_SOURCES` but why invoke the same macro twice
TEST_FAIL("The mob [checkable_mob] ([checkable_mob.type]) does not have ANY instances of TRAIT_SUBTREE_REQUIRED_OPERATIONAL_DATUM, but has a planning subtree ([test_subtree]) that requires it!")
continue
var/has_element = FALSE
var/list/testable_operational_datums = checkable_mob_data[REQUIRED_OPERATIONAL_DATUMS]
for(var/iterable in trait_sources)
if(iterable in testable_operational_datums)
has_element = TRUE
break
if(!has_element)
var/list/message_list = list("The mob [checkable_mob] ([checkable_mob.type]) has a planning subtree ([test_subtree]) that requires a component/element, but does not have any!")
message_list += "Needs one of the following to satisfy the requirement: ([testable_operational_datums.Join(", ")])"
TEST_FAIL(message_list.Join(" "))
#undef REQUIRED_SUBTREE
#undef REQUIRED_OPERATIONAL_DATUMS