[MIRROR] Lightgeist AI [MDB IGNORE] (#22874)

* Lightgeist AI (#77287)

## About The Pull Request

The lightgeist AI controller was marked as "these aren't intended to
exist outside of player control" but this is actually untrue.
Lightgiests can appear under AI control either from a rare vent clog
event or in the "patch of eden" lavaland ruin.

As they heal things by "attacking" them, I made it so that they will
target wounded creatures to "attack" them, though they will only heal
them quite slowly, significantly less efficiently or effectively than a
medibot (for example).
While making this change I also added a couple more parameters to their
"healing hands" component, now they can no longer repair beepsky or heal
cyborg limbs. It's fleshies only.

Lightgeists will attempt to heal _anything_ they can see which is both
injured and has healable damage, which is notable because while this
makes the "Patch of Eden" ruin a nice place of respite for a wounded
miner you should be careful to let them finish up before you leave.
If they follow you out, they will attempt to heal any of the fauna that
you are attacking. Worse still, most Lavaland mobs are not signatories
of the Geneva convention and have no compunctions against killing field
medics.

The majority of listed file changes in this PR is that I made some
attempt at splitting our massive list of blackboard keys across several
files, in order to cause myself a headache based on which of my (or
other people's) open basic mob AI PRs gets merged first.
Also I fixed a bug where the goliath attack forecast would runtime if it
killed a mob which qdels itself on death (guess how I found that out).

## Why It's Good For The Game

Adds a bit more character to a lavaland area and rare event.

## Changelog

🆑
add: Lightgeists under AI control will selflessly heal any wounded
creature that they see.
balance: Lightgeists can no longer repair non-organic tissue.
/🆑

* Lightgeist AI

---------

Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
SkyratBot
2023-08-04 22:48:42 +02:00
committed by GitHub
parent a18792eaa3
commit fe12ecddb5
17 changed files with 404 additions and 365 deletions
@@ -65,15 +65,55 @@
complete_text = "%TARGET%'s wounds mend together.",\
)
/mob/living/basic/lightgeist/melee_attack(atom/target, list/modifiers)
if (isliving(target))
faction |= REF(target) // Anyone we heal will treat us as a friend
return ..()
/mob/living/basic/lightgeist/ghost()
. = ..()
if(.)
death()
/// This is a bit neutered since these aren't intended to exist outside of player control, but it's a bit weird to just have these guys be completely stationary.
/// No attacking or anything like that, though. Just something so they seem alive.
/datum/ai_controller/basic_controller/lightgeist
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/lightgeist,
)
ai_traits = STOP_MOVING_WHEN_PULLED
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk/less_walking
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/basic_melee_attack_subtree/lightgeist, // We heal things by attacking them
)
/// Attack only mobs who have damage that we can heal, I think this is specific enough not to be a generic type
/datum/targetting_datum/lightgeist
/// Types of mobs we can heal, not in a blackboard key because there is no point changing this at runtime because the component will already exist
var/heal_biotypes = MOB_ORGANIC | MOB_MINERAL
/// Type of limb we can heal
var/required_bodytype = BODYTYPE_ORGANIC
/datum/targetting_datum/lightgeist/can_attack(mob/living/living_mob, mob/living/target)
if (!isliving(target) || target.stat == DEAD)
return FALSE
if (!(heal_biotypes & target.mob_biotypes))
return FALSE
if (!iscarbon(target))
return target.getBruteLoss() > 0 || target.getFireLoss() > 0
var/mob/living/carbon/carbon_target = target
for (var/obj/item/bodypart/part in carbon_target.bodyparts)
if (!part.brute_dam && !part.burn_dam)
continue
if (!(part.bodytype & required_bodytype))
continue
return TRUE
return FALSE
/datum/ai_planning_subtree/basic_melee_attack_subtree/lightgeist
melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/lightgeist
/datum/ai_behavior/basic_melee_attack/lightgeist
action_cooldown = 5 SECONDS