mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 04:26:03 +01:00
Merge remote-tracking branch 'tgstation/master' into upstream-6-2-2026
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
#define REINFORCEMENTS_COOLDOWN (30 SECONDS)
|
||||
|
||||
/// Calls all nearby mobs that share a faction to give backup in combat
|
||||
/datum/ai_planning_subtree/call_reinforcements
|
||||
/// Blackboard key containing something to say when calling reinforcements (takes precedence over emotes)
|
||||
@@ -21,8 +19,6 @@
|
||||
controller.queue_behavior(/datum/ai_behavior/perform_speech, call_say)
|
||||
else if(!isnull(call_emote))
|
||||
controller.queue_behavior(/datum/ai_behavior/perform_emote, call_emote)
|
||||
else
|
||||
controller.queue_behavior(/datum/ai_behavior/perform_emote, "cries for help!")
|
||||
|
||||
controller.queue_behavior(call_type)
|
||||
|
||||
@@ -30,20 +26,43 @@
|
||||
/datum/ai_planning_subtree/call_reinforcements/proc/decide_to_call(datum/ai_controller/controller)
|
||||
return controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET) && istype(controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET], /mob)
|
||||
|
||||
/datum/ai_planning_subtree/call_reinforcements/mining
|
||||
call_type = /datum/ai_behavior/call_reinforcements/mining
|
||||
|
||||
/// Call out to all mobs in the specified range for help
|
||||
/datum/ai_behavior/call_reinforcements
|
||||
/// How frequently can we call for reinforcements?
|
||||
var/cooldown = 30 SECONDS
|
||||
/// Range to call reinforcements from
|
||||
var/reinforcements_range = 15
|
||||
|
||||
/datum/ai_behavior/call_reinforcements/perform(seconds_per_tick, datum/ai_controller/controller)
|
||||
var/mob/pawn_mob = controller.pawn
|
||||
for(var/mob/other_mob in oview(reinforcements_range, pawn_mob))
|
||||
if(pawn_mob.faction_check_atom(other_mob) && !isnull(other_mob.ai_controller))
|
||||
// Add our current target to their retaliate list so that they'll attack our aggressor
|
||||
other_mob.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET])
|
||||
other_mob.ai_controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENT_TARGET, pawn_mob)
|
||||
if(!pawn_mob.faction_check_atom(other_mob) || isnull(other_mob.ai_controller))
|
||||
continue
|
||||
// Add our current target to their retaliate list so that they'll attack our aggressor
|
||||
other_mob.ai_controller.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET], world.time)
|
||||
other_mob.ai_controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENT_TARGET, pawn_mob)
|
||||
|
||||
controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN, world.time + REINFORCEMENTS_COOLDOWN)
|
||||
controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN, world.time + cooldown)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
#undef REINFORCEMENTS_COOLDOWN
|
||||
/// Does not force retaliation, but increases targeting priority instead
|
||||
/datum/ai_behavior/call_reinforcements/mining
|
||||
cooldown = 1 SECONDS
|
||||
reinforcements_range = 7
|
||||
|
||||
/datum/ai_behavior/call_reinforcements/mining/perform(seconds_per_tick, datum/ai_controller/controller)
|
||||
var/mob/pawn_mob = controller.pawn
|
||||
var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
|
||||
for(var/mob/other_mob in oview(reinforcements_range, pawn_mob))
|
||||
if(!pawn_mob.faction_check_atom(other_mob) || isnull(other_mob.ai_controller))
|
||||
continue
|
||||
var/list/existing_requests = other_mob.ai_controller.blackboard[BB_MINING_MOB_REINFORCEMENTS_REQUESTS]
|
||||
if (!existing_requests || !existing_requests[target])
|
||||
other_mob.ai_controller.set_blackboard_key_assoc_lazylist(BB_MINING_MOB_REINFORCEMENTS_REQUESTS, target, list())
|
||||
other_mob.ai_controller.add_blackboard_key_assoc(BB_MINING_MOB_REINFORCEMENTS_REQUESTS, target, world.time)
|
||||
|
||||
controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN, world.time + cooldown)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
failed_targeting(pawn)
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, final_target)
|
||||
controller.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, final_target, world.time)
|
||||
pawn.visible_message(span_warning("[pawn] glares grumpily at [final_target]!"))
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
set_movement_target(controller, target)
|
||||
|
||||
/datum/ai_behavior/mine_wall/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
var/mob/living/basic/living_pawn = controller.pawn
|
||||
var/turf/closed/mineral/target = controller.blackboard[target_key]
|
||||
var/is_gibtonite_turf = istype(target, /turf/closed/mineral/gibtonite)
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
var/target_key = BB_BASIC_MOB_CURRENT_TARGET
|
||||
/// Targeting strategy key to use
|
||||
var/strategy_key = BB_TARGETING_STRATEGY
|
||||
/// Behavior to use to find targets
|
||||
var/target_behavior = /datum/ai_behavior/find_potential_targets
|
||||
|
||||
/datum/ai_planning_subtree/simple_find_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
. = ..()
|
||||
controller.queue_behavior(/datum/ai_behavior/find_potential_targets, target_key, strategy_key, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
controller.queue_behavior(target_behavior, target_key, strategy_key, 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
|
||||
@@ -21,9 +23,8 @@
|
||||
target_key = BB_BASIC_MOB_FLEE_TARGET
|
||||
|
||||
/datum/ai_planning_subtree/simple_find_target/increased_range
|
||||
|
||||
/datum/ai_planning_subtree/simple_find_target/increased_range/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
controller.queue_behavior(/datum/ai_behavior/find_potential_targets/bigger_range, target_key, strategy_key, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION)
|
||||
target_behavior = /datum/ai_behavior/find_potential_targets/bigger_range
|
||||
|
||||
/datum/ai_planning_subtree/simple_find_target/hunt
|
||||
strategy_key = BB_HUNT_TARGETING_STRATEGY
|
||||
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
var/hiding_place_key = BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION
|
||||
/// do we check for faction?
|
||||
var/check_faction = FALSE
|
||||
/// Behavior to use to select our target
|
||||
var/target_behavior = /datum/ai_behavior/target_from_retaliate_list
|
||||
|
||||
/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, targeting_strategy_key, hiding_place_key, check_faction)
|
||||
controller.queue_behavior(target_behavior, 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
|
||||
@@ -43,6 +45,12 @@
|
||||
var/list/shitlist = controller.blackboard[shitlist_key]
|
||||
var/atom/existing_target = controller.blackboard[target_key]
|
||||
|
||||
var/datum/target_priority_strategy/priority_strategy = GET_TARGET_PRIORITY_STRATEGY(controller.blackboard[BB_TARGET_PRIORITY_STRATEGY])
|
||||
var/existing_priority = 0
|
||||
// If we have an existing target and its priority is higher than our new target's, don't switch focus
|
||||
if (priority_strategy && existing_target)
|
||||
existing_priority = priority_strategy.get_target_priority(controller, existing_target)
|
||||
|
||||
if (!check_faction)
|
||||
controller.set_blackboard_key(BB_TEMPORARILY_IGNORE_FACTION, TRUE)
|
||||
|
||||
@@ -53,13 +61,12 @@
|
||||
for(var/mob/living/potential_target as anything in shitlist)
|
||||
if(!targeting_strategy.can_attack(living_mob, potential_target, vision_range))
|
||||
continue
|
||||
// Strict comparasion because priority strategies might not care about retaliation, so this makes existing targets not override potential retaliates
|
||||
if (priority_strategy && priority_strategy.get_target_priority(controller, potential_target) < existing_priority)
|
||||
continue
|
||||
enemies_list += potential_target
|
||||
|
||||
if(!length(enemies_list))
|
||||
|
||||
if(existing_target)
|
||||
controller.clear_blackboard_key(target_key)
|
||||
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/atom/new_target = pick_final_target(controller, enemies_list)
|
||||
@@ -74,7 +81,10 @@
|
||||
|
||||
/// 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)
|
||||
var/datum/target_priority_strategy/priority_strategy = GET_TARGET_PRIORITY_STRATEGY(controller.blackboard[BB_TARGET_PRIORITY_STRATEGY])
|
||||
if (!priority_strategy)
|
||||
return pick(enemies_list)
|
||||
return priority_strategy.select_target(controller, enemies_list)
|
||||
|
||||
/datum/ai_behavior/target_from_retaliate_list/finish_action(datum/ai_controller/controller, succeeded, shitlist_key, target_key, targeting_strategy_key, hiding_location_key, check_faction)
|
||||
. = ..()
|
||||
|
||||
Reference in New Issue
Block a user