mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
Targeting Datums Renamed (and global) (#79513)
## About The Pull Request [Implements the backend required to make targeting datums global](https://github.com/tgstation/tgstation/commit/6901ead12e419530b7f646ea21094d4432d7385e) It's inconsistent with the rest of basic ai for these to have a high degree of state, plus like, such a waste yaknow? [Implements GET_TARGETING_STRATEGY](https://github.com/tgstation/tgstation/commit/d79c29134d03424a9f8bacd64c08cb41775fe8c0) Regexes used: new.*(/datum/targetting_datum[^,(]*)\(*\)* -> GET_TARGETING_STRATEGY($1) Renamed all instances of targetting to targeting (also targetting datum -> targeting strategy) I've used GET_TARGETING_STRATEGY at the source where the keys are actually used, rather then in the listing. This works out just fine. ## Why It's Good For The Game Not a misspelled name through the whole codebase, very slightly less memory load for basically no downside (slight cpu cost maybe but not a significant one. --------- Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
This commit is contained in:
co-authored by
John Willard
parent
c6c1f3a578
commit
9696dd1a1d
@@ -2,9 +2,9 @@
|
||||
action_cooldown = 0.2 SECONDS // We gotta check unfortunately often because we're in a race condition with nextmove
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/basic_melee_attack/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
. = ..()
|
||||
if(!controller.blackboard_key_exists(targetting_datum_key))
|
||||
if(!controller.blackboard[targeting_strategy_key])
|
||||
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
|
||||
|
||||
//Hiding location is priority
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
set_movement_target(controller, target)
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/basic_melee_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
if (isliving(controller.pawn))
|
||||
var/mob/living/pawn = controller.pawn
|
||||
if (world.time < pawn.next_move)
|
||||
@@ -22,15 +22,15 @@
|
||||
|
||||
. = ..()
|
||||
var/mob/living/basic/basic_mob = controller.pawn
|
||||
//targetting datum will kill the action if not real anymore
|
||||
//targeting strategy will kill the action if not real anymore
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
|
||||
if(!targetting_datum.can_attack(basic_mob, target))
|
||||
if(!targeting_strategy.can_attack(basic_mob, target))
|
||||
finish_action(controller, FALSE, target_key)
|
||||
return
|
||||
|
||||
var/hiding_target = targetting_datum.find_hidden_mobs(basic_mob, target) //If this is valid, theyre hidden in something!
|
||||
var/hiding_target = targeting_strategy.find_hidden_mobs(basic_mob, target) //If this is valid, theyre hidden in something!
|
||||
|
||||
controller.set_blackboard_key(hiding_location_key, hiding_target)
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
basic_mob.melee_attack(target)
|
||||
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/basic_melee_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
|
||||
. = ..()
|
||||
if(!succeeded)
|
||||
controller.clear_blackboard_key(target_key)
|
||||
@@ -54,30 +54,30 @@
|
||||
///do we care about avoiding friendly fire?
|
||||
var/avoid_friendly_fire = FALSE
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
. = ..()
|
||||
var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key]
|
||||
if(QDELETED(target))
|
||||
return FALSE
|
||||
set_movement_target(controller, target)
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/basic_ranged_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
var/mob/living/basic/basic_mob = controller.pawn
|
||||
//targetting datum will kill the action if not real anymore
|
||||
//targeting strategy will kill the action if not real anymore
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
|
||||
if(!targetting_datum.can_attack(basic_mob, target, chase_range))
|
||||
if(!targeting_strategy.can_attack(basic_mob, target, chase_range))
|
||||
finish_action(controller, FALSE, target_key)
|
||||
return
|
||||
|
||||
var/atom/hiding_target = targetting_datum.find_hidden_mobs(basic_mob, target) //If this is valid, theyre hidden in something!
|
||||
var/atom/hiding_target = targeting_strategy.find_hidden_mobs(basic_mob, target) //If this is valid, theyre hidden in something!
|
||||
var/atom/final_target = hiding_target ? hiding_target : target
|
||||
|
||||
if(!can_see(basic_mob, final_target, required_distance))
|
||||
return
|
||||
|
||||
if(avoid_friendly_fire && check_friendly_in_path(basic_mob, target, targetting_datum))
|
||||
if(avoid_friendly_fire && check_friendly_in_path(basic_mob, target, targeting_strategy))
|
||||
adjust_position(basic_mob, target)
|
||||
return ..()
|
||||
|
||||
@@ -85,17 +85,17 @@
|
||||
basic_mob.RangedAttack(final_target)
|
||||
return ..() //only start the cooldown when the shot is shot
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/basic_ranged_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
|
||||
. = ..()
|
||||
if(!succeeded)
|
||||
controller.clear_blackboard_key(target_key)
|
||||
|
||||
/datum/ai_behavior/basic_ranged_attack/proc/check_friendly_in_path(mob/living/source, atom/target, datum/targetting_datum/targetting_datum)
|
||||
/datum/ai_behavior/basic_ranged_attack/proc/check_friendly_in_path(mob/living/source, atom/target, datum/targeting_strategy/targeting_strategy)
|
||||
var/list/turfs_list = calculate_trajectory(source, target)
|
||||
for(var/turf/possible_turf as anything in turfs_list)
|
||||
|
||||
for(var/mob/living/potential_friend in possible_turf)
|
||||
if(!targetting_datum.can_attack(source, potential_friend))
|
||||
if(!targeting_strategy.can_attack(source, potential_friend))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
+6
-6
@@ -7,16 +7,16 @@
|
||||
/// Static typecache list of potentially dangerous objs
|
||||
var/static/list/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha))
|
||||
|
||||
/datum/ai_behavior/find_potential_targets/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/find_potential_targets/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
. = ..()
|
||||
var/mob/living/living_mob = controller.pawn
|
||||
var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
|
||||
if(!targetting_datum)
|
||||
if(!targeting_strategy)
|
||||
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
|
||||
|
||||
var/atom/current_target = controller.blackboard[target_key]
|
||||
if (targetting_datum.can_attack(living_mob, current_target, vision_range))
|
||||
if (targeting_strategy.can_attack(living_mob, current_target, vision_range))
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
var/list/filtered_targets = list()
|
||||
|
||||
for(var/atom/pot_target in potential_targets)
|
||||
if(targetting_datum.can_attack(living_mob, pot_target))//Can we attack it?
|
||||
if(targeting_strategy.can_attack(living_mob, pot_target))//Can we attack it?
|
||||
filtered_targets += pot_target
|
||||
continue
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
var/atom/target = pick_final_target(controller, filtered_targets)
|
||||
controller.set_blackboard_key(target_key, target)
|
||||
|
||||
var/atom/potential_hiding_location = targetting_datum.find_hidden_mobs(living_mob, target)
|
||||
var/atom/potential_hiding_location = targeting_strategy.find_hidden_mobs(living_mob, 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)
|
||||
@@ -18,7 +18,7 @@
|
||||
. = ..()
|
||||
var/obj/machinery/atmospherics/components/unary/vent_pump/entry_vent = controller.blackboard[target_key] || controller.blackboard[BB_ENTRY_VENT_TARGET]
|
||||
var/mob/living/cached_pawn = controller.pawn
|
||||
if(HAS_TRAIT(cached_pawn, TRAIT_MOVE_VENTCRAWLING) || !controller.blackboard[BB_CURRENTLY_TARGETTING_VENT] || !is_vent_valid(entry_vent))
|
||||
if(HAS_TRAIT(cached_pawn, TRAIT_MOVE_VENTCRAWLING) || !controller.blackboard[BB_CURRENTLY_TARGETING_VENT] || !is_vent_valid(entry_vent))
|
||||
return
|
||||
|
||||
if(!cached_pawn.can_enter_vent(entry_vent, provide_feedback = FALSE)) // we're an AI we scoff at feedback
|
||||
@@ -30,7 +30,7 @@
|
||||
finish_action(controller, FALSE, target_key)
|
||||
return
|
||||
|
||||
controller.set_blackboard_key(BB_CURRENTLY_TARGETTING_VENT, FALSE) // must be done here because we have a do_after sleep in handle_ventcrawl unfortunately and double dipping could lead to erroneous suicide pill calls.
|
||||
controller.set_blackboard_key(BB_CURRENTLY_TARGETING_VENT, FALSE) // must be done here because we have a do_after sleep in handle_ventcrawl unfortunately and double dipping could lead to erroneous suicide pill calls.
|
||||
cached_pawn.handle_ventcrawl(entry_vent)
|
||||
if(!HAS_TRAIT(cached_pawn, TRAIT_MOVE_VENTCRAWLING)) //something failed and we ARE NOT IN THE VENT even though the earlier check said we were good to go! odd.
|
||||
finish_action(controller, FALSE, target_key)
|
||||
@@ -134,5 +134,5 @@
|
||||
controller.clear_blackboard_key(target_key)
|
||||
controller.clear_blackboard_key(BB_ENTRY_VENT_TARGET)
|
||||
controller.clear_blackboard_key(BB_EXIT_VENT_TARGET)
|
||||
controller.set_blackboard_key(BB_CURRENTLY_TARGETTING_VENT, FALSE) // just in case
|
||||
controller.set_blackboard_key(BB_CURRENTLY_TARGETING_VENT, FALSE) // just in case
|
||||
|
||||
|
||||
@@ -12,19 +12,19 @@
|
||||
var/mob/living/pawn = controller.pawn
|
||||
if (LAZYLEN(pawn.do_afters))
|
||||
return
|
||||
controller.queue_behavior(melee_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
controller.queue_behavior(melee_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
|
||||
/// Attack something which is already adjacent to us without moving
|
||||
/datum/ai_behavior/basic_melee_attack/opportunistic
|
||||
action_cooldown = 0.2 SECONDS // We gotta check unfortunately often because we're in a race condition with nextmove
|
||||
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/opportunistic/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
if (!controller.blackboard_key_exists(targetting_datum_key))
|
||||
/datum/ai_behavior/basic_melee_attack/opportunistic/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
if (!controller.blackboard_key_exists(targeting_strategy_key))
|
||||
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
|
||||
return controller.blackboard_key_exists(target_key)
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/opportunistic/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
/datum/ai_behavior/basic_melee_attack/opportunistic/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
|
||||
var/atom/movable/atom_pawn = controller.pawn
|
||||
if(!atom_pawn.CanReach(controller.blackboard[target_key]))
|
||||
finish_action(controller, TRUE, target_key) // Don't clear target
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
return FALSE
|
||||
if (basic_mob.see_invisible < object.invisibility)
|
||||
return FALSE
|
||||
var/list/whitelist = basic_mob.ai_controller.blackboard[BB_OBSTACLE_TARGETTING_WHITELIST]
|
||||
var/list/whitelist = basic_mob.ai_controller.blackboard[BB_OBSTACLE_TARGETING_WHITELIST]
|
||||
if(whitelist && !is_type_in_typecache(object, whitelist))
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/// Add or remove people to our retaliation shitlist just on an arbitrary whim
|
||||
/datum/ai_planning_subtree/capricious_retaliate
|
||||
/// Blackboard key which tells us how to select valid targets
|
||||
var/targetting_datum_key = BB_TARGETTING_DATUM
|
||||
var/targeting_strategy_key = BB_TARGETING_STRATEGY
|
||||
/// Whether we should skip checking faction for our decision
|
||||
var/ignore_faction = TRUE
|
||||
|
||||
/datum/ai_planning_subtree/capricious_retaliate/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
controller.queue_behavior(/datum/ai_behavior/capricious_retaliate, targetting_datum_key, ignore_faction)
|
||||
controller.queue_behavior(/datum/ai_behavior/capricious_retaliate, targeting_strategy_key, ignore_faction)
|
||||
|
||||
/// Add or remove people to our retaliation shitlist just on an arbitrary whim
|
||||
/datum/ai_behavior/capricious_retaliate
|
||||
action_cooldown = 1 SECONDS
|
||||
|
||||
/datum/ai_behavior/capricious_retaliate/perform(seconds_per_tick, datum/ai_controller/controller, targetting_datum_key, ignore_faction)
|
||||
/datum/ai_behavior/capricious_retaliate/perform(seconds_per_tick, datum/ai_controller/controller, targeting_strategy_key, ignore_faction)
|
||||
. = ..()
|
||||
var/atom/pawn = controller.pawn
|
||||
if (controller.blackboard_key_exists(BB_BASIC_MOB_RETALIATE_LIST))
|
||||
@@ -35,10 +35,10 @@
|
||||
var/aggro_range = controller.blackboard[BB_AGGRO_RANGE] || 9
|
||||
var/list/potential_targets = hearers(aggro_range, get_turf(pawn)) - pawn
|
||||
if (!length(potential_targets))
|
||||
failed_targetting(controller, pawn, ignore_faction)
|
||||
failed_targeting(controller, pawn, ignore_faction)
|
||||
return
|
||||
|
||||
var/datum/targetting_datum/target_helper = controller.blackboard[targetting_datum_key]
|
||||
var/datum/targeting_strategy/target_helper = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
|
||||
var/mob/living/final_target = null
|
||||
if (ignore_faction)
|
||||
@@ -49,7 +49,7 @@
|
||||
final_target = test_target
|
||||
|
||||
if (isnull(final_target))
|
||||
failed_targetting(controller, pawn, ignore_faction)
|
||||
failed_targeting(controller, pawn, ignore_faction)
|
||||
return
|
||||
|
||||
controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, final_target)
|
||||
@@ -57,7 +57,7 @@
|
||||
finish_action(controller, TRUE, ignore_faction)
|
||||
|
||||
/// Called if we try but fail to target something
|
||||
/datum/ai_behavior/capricious_retaliate/proc/failed_targetting(datum/ai_controller/controller, atom/pawn, ignore_faction)
|
||||
/datum/ai_behavior/capricious_retaliate/proc/failed_targeting(datum/ai_controller/controller, atom/pawn, ignore_faction)
|
||||
finish_action(controller, FALSE, ignore_faction)
|
||||
pawn.visible_message(span_notice("[pawn] grumbles.")) // We're pissed off but with no outlet to vent our frustration upon
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
return SUBTREE_RETURN_FINISH_PLANNING //we gotta get out of here.
|
||||
|
||||
/// Try to escape from your current target, without performing any other actions.
|
||||
/// Reads from some fleeing-specific targetting keys rather than the current mob target.
|
||||
/// Reads from some fleeing-specific targeting keys rather than the current mob target.
|
||||
/datum/ai_planning_subtree/flee_target/from_flee_key
|
||||
target_key = BB_BASIC_MOB_FLEE_TARGET
|
||||
hiding_place_key = BB_BASIC_MOB_FLEE_TARGET_HIDING_LOCATION
|
||||
|
||||
@@ -15,6 +15,6 @@
|
||||
controller.queue_behavior(/datum/ai_behavior/travel_towards, BB_ENTRY_VENT_TARGET)
|
||||
return
|
||||
|
||||
controller.set_blackboard_key(BB_CURRENTLY_TARGETTING_VENT, TRUE)
|
||||
controller.set_blackboard_key(BB_CURRENTLY_TARGETING_VENT, TRUE)
|
||||
controller.queue_behavior(/datum/ai_behavior/crawl_through_vents, BB_ENTRY_VENT_TARGET)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING // we are going into this vent... no distractions
|
||||
|
||||
@@ -14,30 +14,30 @@
|
||||
. = ..()
|
||||
if(!controller.blackboard_key_exists(target_key))
|
||||
return
|
||||
controller.queue_behavior(attack_behavior, target_key, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION, max_range, min_range)
|
||||
controller.queue_behavior(attack_behavior, target_key, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION, max_range, min_range)
|
||||
|
||||
/// How often will we try to perform our ranged attack?
|
||||
/datum/ai_behavior/ranged_skirmish
|
||||
action_cooldown = 1 SECONDS
|
||||
|
||||
/datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, max_range, min_range)
|
||||
/datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key, max_range, min_range)
|
||||
. = ..()
|
||||
var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key]
|
||||
return !QDELETED(target)
|
||||
|
||||
/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, max_range, min_range)
|
||||
/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key, max_range, min_range)
|
||||
. = ..()
|
||||
var/atom/target = controller.blackboard[target_key]
|
||||
if (QDELETED(target))
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
|
||||
var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
|
||||
if(!targetting_datum.can_attack(controller.pawn, target))
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
if(!targeting_strategy.can_attack(controller.pawn, target))
|
||||
finish_action(controller, succeeded = FALSE)
|
||||
return
|
||||
|
||||
var/hiding_target = targetting_datum.find_hidden_mobs(controller.pawn, target)
|
||||
var/hiding_target = targeting_strategy.find_hidden_mobs(controller.pawn, target)
|
||||
controller.set_blackboard_key(hiding_location_key, hiding_target)
|
||||
|
||||
target = hiding_target || target
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
. = ..()
|
||||
if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
|
||||
return
|
||||
controller.queue_behavior(melee_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
controller.queue_behavior(melee_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
if (end_planning)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions.
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
. = ..()
|
||||
if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
|
||||
return
|
||||
controller.queue_behavior(ranged_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
controller.queue_behavior(ranged_attack_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions.
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
. = ..()
|
||||
if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING])
|
||||
return
|
||||
controller.queue_behavior(/datum/ai_behavior/find_potential_targets/nearest, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
controller.queue_behavior(/datum/ai_behavior/find_potential_targets/nearest, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
|
||||
/// Find the nearest thing on our list of 'things which have done damage to me' and set it as the flee target
|
||||
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee
|
||||
var/targeting_key = BB_TARGETTING_DATUM
|
||||
var/targeting_key = BB_TARGETING_STRATEGY
|
||||
|
||||
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
@@ -18,4 +18,4 @@
|
||||
controller.queue_behavior(/datum/ai_behavior/target_from_retaliate_list/nearest, BB_BASIC_MOB_RETALIATE_LIST, BB_BASIC_MOB_CURRENT_TARGET, targeting_key, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
|
||||
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee/from_flee_key
|
||||
targeting_key = BB_FLEE_TARGETTING_DATUM
|
||||
targeting_key = BB_FLEE_TARGETING_STRATEGY
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/datum/ai_planning_subtree/simple_find_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
controller.queue_behavior(/datum/ai_behavior/find_potential_targets, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
controller.queue_behavior(/datum/ai_behavior/find_potential_targets, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
|
||||
// Prevents finding a target if a human is nearby
|
||||
/datum/ai_planning_subtree/simple_find_target/not_while_observed
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
/datum/ai_planning_subtree/simple_find_wounded_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
controller.queue_behavior(/datum/ai_behavior/find_potential_targets/most_wounded, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
controller.queue_behavior(/datum/ai_behavior/find_potential_targets/most_wounded, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/datum/ai_planning_subtree/target_retaliate
|
||||
operational_datums = list(/datum/element/ai_retaliate, /datum/component/ai_retaliate_advanced)
|
||||
/// Blackboard key which tells us how to select valid targets
|
||||
var/targetting_datum_key = BB_TARGETTING_DATUM
|
||||
var/targeting_strategy_key = BB_TARGETING_STRATEGY
|
||||
/// 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
|
||||
@@ -12,16 +12,16 @@
|
||||
|
||||
/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, check_faction)
|
||||
controller.queue_behavior(/datum/ai_behavior/target_from_retaliate_list, BB_BASIC_MOB_RETALIATE_LIST, target_key, targeting_strategy_key, hiding_place_key, check_faction)
|
||||
|
||||
/datum/ai_planning_subtree/target_retaliate/check_faction
|
||||
check_faction = TRUE
|
||||
|
||||
/// 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
|
||||
/// Can use a different targeting strategy 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
|
||||
targeting_strategy_key = BB_FLEE_TARGETING_STRATEGY
|
||||
target_key = BB_BASIC_MOB_FLEE_TARGET
|
||||
hiding_place_key = BB_BASIC_MOB_FLEE_TARGET_HIDING_LOCATION
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
/// 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, check_faction)
|
||||
/datum/ai_behavior/target_from_retaliate_list/perform(seconds_per_tick, datum/ai_controller/controller, shitlist_key, target_key, targeting_strategy_key, hiding_location_key, check_faction)
|
||||
. = ..()
|
||||
var/mob/living/living_mob = controller.pawn
|
||||
var/datum/targetting_datum/targetting_datum = controller.blackboard[targetting_datum_key]
|
||||
if(!targetting_datum)
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
if(!targeting_strategy)
|
||||
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
|
||||
|
||||
var/list/shitlist = controller.blackboard[shitlist_key]
|
||||
@@ -47,13 +47,13 @@
|
||||
if (!check_faction)
|
||||
controller.set_blackboard_key(BB_TEMPORARILY_IGNORE_FACTION, TRUE)
|
||||
|
||||
if (!QDELETED(existing_target) && (locate(existing_target) in shitlist) && targetting_datum.can_attack(living_mob, existing_target, vision_range))
|
||||
if (!QDELETED(existing_target) && (locate(existing_target) in shitlist) && targeting_strategy.can_attack(living_mob, existing_target, vision_range))
|
||||
finish_action(controller, succeeded = TRUE, check_faction = check_faction)
|
||||
return
|
||||
|
||||
var/list/enemies_list = list()
|
||||
for(var/mob/living/potential_target as anything in shitlist)
|
||||
if(!targetting_datum.can_attack(living_mob, potential_target, vision_range))
|
||||
if(!targeting_strategy.can_attack(living_mob, potential_target, vision_range))
|
||||
continue
|
||||
enemies_list += potential_target
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
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)
|
||||
var/atom/potential_hiding_location = targeting_strategy.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)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// The most basic AI tree which just finds a guy and then runs at them to click them
|
||||
/datum/ai_controller/basic_controller/simple_hostile
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
@@ -14,7 +14,7 @@
|
||||
/// Find a target, walk at target, attack intervening obstacles
|
||||
/datum/ai_controller/basic_controller/simple_hostile_obstacles
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
|
||||
+16
-15
@@ -1,18 +1,19 @@
|
||||
///Datum for basic mobs to define what they can attack.
|
||||
/datum/targetting_datum
|
||||
///Datum for basic mobs to define what they can attack.GET_TARGETING_STRATEGY\((/[^,]*)\),
|
||||
///Global, just like ai_behaviors
|
||||
/datum/targeting_strategy
|
||||
|
||||
///Returns true or false depending on if the target can be attacked by the mob
|
||||
/datum/targetting_datum/proc/can_attack(mob/living/living_mob, atom/target, vision_range)
|
||||
/datum/targeting_strategy/proc/can_attack(mob/living/living_mob, atom/target, vision_range)
|
||||
return
|
||||
|
||||
///Returns something the target might be hiding inside of
|
||||
/datum/targetting_datum/proc/find_hidden_mobs(mob/living/living_mob, atom/target)
|
||||
/datum/targeting_strategy/proc/find_hidden_mobs(mob/living/living_mob, atom/target)
|
||||
var/atom/target_hiding_location
|
||||
if(istype(target.loc, /obj/structure/closet) || istype(target.loc, /obj/machinery/disposal) || istype(target.loc, /obj/machinery/sleeper))
|
||||
target_hiding_location = target.loc
|
||||
return target_hiding_location
|
||||
|
||||
/datum/targetting_datum/basic
|
||||
/datum/targeting_strategy/basic
|
||||
/// When we do our basic faction check, do we look for exact faction matches?
|
||||
var/check_factions_exactly = FALSE
|
||||
/// Whether we care for seeing the target or not
|
||||
@@ -22,7 +23,7 @@
|
||||
/// If this blackboard key is TRUE, makes us only target wounded mobs
|
||||
var/target_wounded_key
|
||||
|
||||
/datum/targetting_datum/basic/can_attack(mob/living/living_mob, atom/the_target, vision_range)
|
||||
/datum/targeting_strategy/basic/can_attack(mob/living/living_mob, atom/the_target, vision_range)
|
||||
var/datum/ai_controller/basic_controller/our_controller = living_mob.ai_controller
|
||||
|
||||
if(isnull(our_controller))
|
||||
@@ -82,29 +83,29 @@
|
||||
return FALSE
|
||||
|
||||
/// Returns true if the mob and target share factions
|
||||
/datum/targetting_datum/basic/proc/faction_check(datum/ai_controller/controller, mob/living/living_mob, mob/living/the_target)
|
||||
/datum/targeting_strategy/basic/proc/faction_check(datum/ai_controller/controller, mob/living/living_mob, mob/living/the_target)
|
||||
if (controller.blackboard[BB_ALWAYS_IGNORE_FACTION] || controller.blackboard[BB_TEMPORARILY_IGNORE_FACTION])
|
||||
return FALSE
|
||||
return living_mob.faction_check_atom(the_target, exact_match = check_factions_exactly)
|
||||
|
||||
/// Subtype more forgiving for items.
|
||||
/// Careful, this can go wrong and keep a mob hyper-focused on an item it can't lose aggro on
|
||||
/datum/targetting_datum/basic/allow_items
|
||||
/datum/targeting_strategy/basic/allow_items
|
||||
|
||||
/datum/targetting_datum/basic/allow_items/can_attack(mob/living/living_mob, atom/the_target, vision_range)
|
||||
/datum/targeting_strategy/basic/allow_items/can_attack(mob/living/living_mob, atom/the_target, vision_range)
|
||||
. = ..()
|
||||
if(isitem(the_target))
|
||||
// trust fall exercise
|
||||
return TRUE
|
||||
|
||||
/// Subtype which searches for mobs of a size relative to ours
|
||||
/datum/targetting_datum/basic/of_size
|
||||
/datum/targeting_strategy/basic/of_size
|
||||
/// If true, we will return mobs which are smaller than us. If false, larger.
|
||||
var/find_smaller = TRUE
|
||||
/// If true, we will return mobs which are the same size as us.
|
||||
var/inclusive = TRUE
|
||||
|
||||
/datum/targetting_datum/basic/of_size/can_attack(mob/living/owner, atom/target, vision_range)
|
||||
/datum/targeting_strategy/basic/of_size/can_attack(mob/living/owner, atom/target, vision_range)
|
||||
if(!isliving(target))
|
||||
return FALSE
|
||||
. = ..()
|
||||
@@ -119,14 +120,14 @@
|
||||
return !find_smaller
|
||||
|
||||
// This is just using the default values but the subtype makes it clearer
|
||||
/datum/targetting_datum/basic/of_size/ours_or_smaller
|
||||
/datum/targeting_strategy/basic/of_size/ours_or_smaller
|
||||
|
||||
/datum/targetting_datum/basic/of_size/larger
|
||||
/datum/targeting_strategy/basic/of_size/larger
|
||||
find_smaller = FALSE
|
||||
inclusive = FALSE
|
||||
|
||||
/// Makes the mob only attack their own faction. Useful mostly if their attacks do something helpful (e.g. healing touch).
|
||||
/datum/targetting_datum/basic/same_faction
|
||||
/datum/targeting_strategy/basic/same_faction
|
||||
|
||||
/datum/targetting_datum/basic/same_faction/faction_check(mob/living/living_mob, mob/living/the_target)
|
||||
/datum/targeting_strategy/basic/same_faction/faction_check(mob/living/living_mob, mob/living/the_target)
|
||||
return !..() // inverts logic to ONLY target mobs that share a faction
|
||||
+7
-7
@@ -1,12 +1,12 @@
|
||||
/// Don't target an atom in our friends list (or turfs), anything else is fair game
|
||||
/datum/targetting_datum/basic/not_friends
|
||||
/datum/targeting_strategy/basic/not_friends
|
||||
/// Stop regarding someone as a valid target once they pass this stat level, setting it to DEAD means you will happily attack corpses
|
||||
var/attack_until_past_stat = HARD_CRIT
|
||||
/// If we can try to closed turfs or not
|
||||
var/attack_closed_turf = FALSE
|
||||
|
||||
///Returns true or false depending on if the target can be attacked by the mob
|
||||
/datum/targetting_datum/basic/not_friends/can_attack(mob/living/living_mob, atom/target, vision_range)
|
||||
/datum/targeting_strategy/basic/not_friends/can_attack(mob/living/living_mob, atom/target, vision_range)
|
||||
if(attack_closed_turf && isclosedturf(target))
|
||||
return TRUE
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
return ..()
|
||||
|
||||
///friends dont care about factions
|
||||
/datum/targetting_datum/basic/not_friends/faction_check(mob/living/living_mob, mob/living/the_target)
|
||||
/datum/targeting_strategy/basic/not_friends/faction_check(mob/living/living_mob, mob/living/the_target)
|
||||
return FALSE
|
||||
|
||||
/datum/targetting_datum/basic/not_friends/attack_closed_turfs
|
||||
/datum/targeting_strategy/basic/not_friends/attack_closed_turfs
|
||||
attack_closed_turf = TRUE
|
||||
|
||||
/// Subtype that allows us to target items while deftly avoiding attacking our allies. Be careful when it comes to targetting items as an AI could get trapped targetting something it can't destroy.
|
||||
/datum/targetting_datum/basic/not_friends/allow_items
|
||||
/// Subtype that allows us to target items while deftly avoiding attacking our allies. Be careful when it comes to targeting items as an AI could get trapped targeting something it can't destroy.
|
||||
/datum/targeting_strategy/basic/not_friends/allow_items
|
||||
|
||||
/datum/targetting_datum/basic/not_friends/allow_items/can_attack(mob/living/living_mob, atom/the_target, vision_range)
|
||||
/datum/targeting_strategy/basic/not_friends/allow_items/can_attack(mob/living/living_mob, atom/the_target, vision_range)
|
||||
. = ..()
|
||||
if(isitem(the_target))
|
||||
// trust fall exercise
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Find mobs who are holding the bb configurable object type
|
||||
*
|
||||
* This is an extension of basic targeting behaviour, that allows you to
|
||||
* only target the mob if they have a specific item in their hand.
|
||||
*
|
||||
*/
|
||||
/datum/targeting_strategy/basic/holding_object
|
||||
/// BB key that holds the target typepath to use
|
||||
var/target_item_key = BB_TARGET_HELD_ITEM
|
||||
|
||||
///Returns true or false depending on if the target can be attacked by the mob
|
||||
/datum/targeting_strategy/basic/holding_object/can_attack(mob/living/living_mob, atom/target, vision_range)
|
||||
var/datum/ai_controller/controller = living_mob.ai_controller
|
||||
var/object_type_path = controller.blackboard[target_item_key]
|
||||
|
||||
if (object_type_path == null)
|
||||
return FALSE // no op
|
||||
if(!ismob(target))
|
||||
return FALSE // no hands no problems
|
||||
|
||||
// Look at me, type casting like a grown up
|
||||
var/mob/targetmob = target
|
||||
// Check if our parent behaviour agrees we can attack this target (we ignore faction by default)
|
||||
var/can_attack = ..()
|
||||
if(can_attack && targetmob.is_holding_item_of_type(object_type_path))
|
||||
return TRUE // they have the item
|
||||
// No valid target
|
||||
return FALSE
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Find mobs who are holding the configurable object type
|
||||
*
|
||||
* This is an extension of basic targeting behaviour, that allows you to
|
||||
* only target the mob if they have a specific item in their hand.
|
||||
*
|
||||
*/
|
||||
/datum/targetting_datum/basic/holding_object
|
||||
// We will find mobs who are holding this object in their hands
|
||||
var/object_type_path = null
|
||||
|
||||
/**
|
||||
* Create an instance of the holding object targeting datum
|
||||
*
|
||||
* * object_type_path Pass an object type path, this will be compared to the items
|
||||
* in targets hands to filter the target list.
|
||||
*/
|
||||
/datum/targetting_datum/basic/holding_object/New(object_type_path)
|
||||
if (!ispath(object_type_path))
|
||||
stack_trace("trying to create an item targeting datum with no valid typepath")
|
||||
// Leaving object type as null will make this basically a noop
|
||||
return
|
||||
src.object_type_path = object_type_path
|
||||
|
||||
///Returns true or false depending on if the target can be attacked by the mob
|
||||
/datum/targetting_datum/basic/holding_object/can_attack(mob/living/living_mob, atom/target, vision_range)
|
||||
if (object_type_path == null)
|
||||
return FALSE // no op
|
||||
if(!ismob(target))
|
||||
return FALSE // no hands no problems
|
||||
|
||||
// Look at me, type casting like a grown up
|
||||
var/mob/targetmob = target
|
||||
// Check if our parent behaviour agrees we can attack this target (we ignore faction by default)
|
||||
var/can_attack = ..()
|
||||
if(can_attack && targetmob.is_holding_item_of_type(object_type_path))
|
||||
return TRUE // they have the item
|
||||
// No valid target
|
||||
return FALSE
|
||||
Reference in New Issue
Block a user