mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-01 04:21:42 +00:00
## 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 /🆑
70 lines
3.3 KiB
Plaintext
70 lines
3.3 KiB
Plaintext
/// Sets the BB target to a mob which you can see and who has recently attacked you
|
|
/datum/ai_planning_subtree/target_retaliate
|
|
/// Blackboard key which tells us how to select valid targets
|
|
var/targetting_datum_key = BB_TARGETTING_DATUM
|
|
/// Blackboard key in which to store selected target
|
|
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
|
|
/// Blackboard key in which to store selected target's hiding place
|
|
var/hiding_place_key = BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION
|
|
|
|
/datum/ai_planning_subtree/target_retaliate/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
. = ..()
|
|
controller.queue_behavior(/datum/ai_behavior/target_from_retaliate_list, BB_BASIC_MOB_RETALIATE_LIST, target_key, targetting_datum_key, hiding_place_key)
|
|
|
|
/// Places a mob which you can see and who has recently attacked you into some 'run away from this' AI keys
|
|
/// Can use a different targetting datum than you use to select attack targets
|
|
/// Not required if fleeing is the only target behaviour or uses the same target datum
|
|
/datum/ai_planning_subtree/target_retaliate/to_flee
|
|
targetting_datum_key = BB_FLEE_TARGETTING_DATUM
|
|
target_key = BB_BASIC_MOB_FLEE_TARGET
|
|
hiding_place_key = BB_BASIC_MOB_FLEE_TARGET_HIDING_LOCATION
|
|
|
|
/**
|
|
* Picks a target from a provided list of atoms who have been pissing you off
|
|
* You will probably need /datum/element/ai_retaliate to take advantage of this unless you're populating the blackboard yourself
|
|
*/
|
|
/datum/ai_behavior/target_from_retaliate_list
|
|
action_cooldown = 2 SECONDS
|
|
/// How far can we see stuff?
|
|
var/vision_range = 9
|
|
|
|
/datum/ai_behavior/target_from_retaliate_list/perform(seconds_per_tick, datum/ai_controller/controller, shitlist_key, target_key, targetting_datum_key, hiding_location_key)
|
|
. = ..()
|
|
var/mob/living/living_mob = controller.pawn
|
|
var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
|
|
if(!targetting_datum)
|
|
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
|
|
|
|
var/list/enemies_list = controller.blackboard[shitlist_key]
|
|
if (!length(enemies_list))
|
|
finish_action(controller, succeeded = FALSE)
|
|
return
|
|
|
|
if (controller.blackboard[target_key] in enemies_list) // Don't bother changing
|
|
finish_action(controller, succeeded = FALSE)
|
|
return
|
|
|
|
var/atom/new_target = pick_final_target(controller, enemies_list)
|
|
controller.set_blackboard_key(target_key, new_target)
|
|
|
|
var/atom/potential_hiding_location = targetting_datum.find_hidden_mobs(living_mob, new_target)
|
|
|
|
if(potential_hiding_location) //If they're hiding inside of something, we need to know so we can go for that instead initially.
|
|
controller.set_blackboard_key(hiding_location_key, potential_hiding_location)
|
|
|
|
finish_action(controller, succeeded = TRUE)
|
|
|
|
/// Returns true if this target is valid for attacking based on current conditions
|
|
/datum/ai_behavior/target_from_retaliate_list/proc/can_attack_target(mob/living/living_mob, atom/target, datum/targetting_datum/targetting_datum)
|
|
if (!target)
|
|
return FALSE
|
|
if (target == living_mob)
|
|
return FALSE
|
|
if (!can_see(living_mob, target, vision_range))
|
|
return FALSE
|
|
return targetting_datum.can_attack(living_mob, target)
|
|
|
|
/// Returns the desired final target from the filtered list of enemies
|
|
/datum/ai_behavior/target_from_retaliate_list/proc/pick_final_target(datum/ai_controller/controller, list/enemies_list)
|
|
return pick(enemies_list)
|