Files
Bubberstation/code/datums/elements/ai_flee_while_injured.dm
MrMelbert ed2f04f486 Experiment with replacing weakrefs in AI blackboard with deleting signals, ideally making it easier to work with and harder to cause hard deletes (#74791)
## About The Pull Request

Replaces weakref usage in AI blackboards with deleting signals

All blackboard var setting must go through setters rather than directly

## Why It's Good For The Game

This both makes it a ton easier to develop AI for, and also makes it
harder for hard deletes to sneak in, as has been seen with recent 515
prs showing hard deletes in AI blackboards

(To quantify "making it easier to develop AI", I found multiple bugs in
existing AI code due to the usage of weakrefs.)

I'm looking for `@Jacquerel` `@tralezab` 's opinions on the matter, also
maybe `@LemonInTheDark` if they're interested

## Changelog

🆑 Melbert
refactor: Mob ai refactored once again
/🆑
2023-04-23 17:07:17 -06:00

46 lines
1.6 KiB
Plaintext

/**
* Attached to a mob with an AI controller, simply sets a flag on whether or not to run away based on current health values.
*/
/datum/element/ai_flee_while_injured
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
/// Health value to end fleeing if at or above
var/stop_fleeing_at
/// Health value to start fleeing if at or below
var/start_fleeing_below
/datum/element/ai_flee_while_injured/Attach(datum/target, stop_fleeing_at = 1, start_fleeing_below = 0.5)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
var/mob/living/living_target = target
if(!living_target.ai_controller)
return ELEMENT_INCOMPATIBLE
src.stop_fleeing_at = stop_fleeing_at
src.start_fleeing_below = start_fleeing_below
RegisterSignal(target, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(on_health_changed))
/datum/element/ai_flee_while_injured/Detach(datum/source)
. = ..()
UnregisterSignal(source, COMSIG_LIVING_HEALTH_UPDATE)
/// When the mob's health changes, check what the blackboard state should be
/datum/element/ai_flee_while_injured/proc/on_health_changed(mob/living/source)
SIGNAL_HANDLER
if (!source.ai_controller)
return
var/current_health_percentage = source.health / source.maxHealth
if (source.ai_controller.blackboard[BB_BASIC_MOB_FLEEING])
if (current_health_percentage < stop_fleeing_at)
return
source.ai_controller.CancelActions() // Stop fleeing go back to whatever you were doing
source.ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, FALSE)
return
if (current_health_percentage > start_fleeing_below)
return
source.ai_controller.CancelActions()
source.ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, TRUE)