mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
Most hostile mobs can no longer be trapped by closets, chairs, and aggro grabs (#91652)
This commit is contained in:
@@ -33,12 +33,18 @@
|
||||
if(. & AI_UNABLE_TO_RUN)
|
||||
return .
|
||||
var/mob/living/living_pawn = pawn
|
||||
if(!(ai_traits & CAN_ACT_WHILE_DEAD))
|
||||
// Unroll for flags here
|
||||
if((ai_traits & CAN_ACT_IN_STASIS) && (living_pawn.stat || INCAPACITATED_IGNORING(living_pawn, INCAPABLE_STASIS)))
|
||||
return AI_UNABLE_TO_RUN
|
||||
if(IS_DEAD_OR_INCAP(living_pawn))
|
||||
return AI_UNABLE_TO_RUN
|
||||
if (living_pawn.stat && !(ai_traits & CAN_ACT_WHILE_DEAD))
|
||||
return AI_UNABLE_TO_RUN
|
||||
|
||||
var/ignore_incap_flags = NONE
|
||||
if((ai_traits & CAN_ACT_IN_STASIS))
|
||||
ignore_incap_flags |= INCAPABLE_STASIS
|
||||
if((ai_traits & CAN_ACT_WHILE_GRABBED))
|
||||
ignore_incap_flags |= INCAPABLE_GRAB
|
||||
|
||||
if(INCAPACITATED_IGNORING(living_pawn, ignore_incap_flags))
|
||||
return AI_UNABLE_TO_RUN
|
||||
|
||||
if(ai_traits & PAUSE_DURING_DO_AFTER && LAZYLEN(living_pawn.do_afters))
|
||||
return AI_UNABLE_TO_RUN | AI_PREVENT_CANCEL_ACTIONS //dont erase targets post a do_after
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/// Generically try to escape from being trapped
|
||||
/datum/ai_planning_subtree/escape_captivity
|
||||
/// Targeting strategy for use deciding if we can attack a mob grabbing us
|
||||
var/targeting_strategy_key = BB_TARGETING_STRATEGY
|
||||
/// If true we will never attack objects
|
||||
var/pacifist = FALSE
|
||||
|
||||
/datum/ai_planning_subtree/escape_captivity/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
|
||||
if (living_pawn.buckled && !ismob(living_pawn.buckled))
|
||||
if (!pacifist && !living_pawn.can_hold_items() || living_pawn.usable_hands < 1) // If we don't have hands then prioritise slapping the shit out of whatever we are attached to
|
||||
controller.queue_behavior(/datum/ai_behavior/break_out_of_object, living_pawn.buckled)
|
||||
else
|
||||
controller.queue_behavior(/datum/ai_behavior/resist)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
if (!isturf(living_pawn.loc) && !ismob(living_pawn.loc))
|
||||
var/atom/contained_in = living_pawn.loc
|
||||
var/attack_effective = FALSE
|
||||
if (!pacifist)
|
||||
if (isbasicmob(living_pawn)) // Currently this literally only works for basic mobs because it's hard to check for anyone else but it's ok because only they use this subtree
|
||||
var/mob/living/basic/basic_pawn = living_pawn
|
||||
attack_effective = basic_pawn.obj_damage > contained_in.damage_deflection
|
||||
if (attack_effective)
|
||||
controller.queue_behavior(/datum/ai_behavior/break_out_of_object, contained_in)
|
||||
else
|
||||
controller.queue_behavior(/datum/ai_behavior/resist)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
var/mob/puller = living_pawn.pulledby
|
||||
if (puller && puller.grab_state > GRAB_PASSIVE)
|
||||
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
|
||||
var/friends_list = controller.blackboard[BB_FRIENDS_LIST] || list()
|
||||
// Only resist grabs from mobs that aren't in our faction
|
||||
if (targeting_strategy?.can_attack(living_pawn, puller) && !(puller in friends_list))
|
||||
controller.queue_behavior(/datum/ai_behavior/resist)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
if (HAS_TRAIT(living_pawn, TRAIT_RESTRAINED))
|
||||
controller.queue_behavior(/datum/ai_behavior/resist)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
/// Keep attacking an object while it is our loc or while we are buckled to it
|
||||
/datum/ai_behavior/break_out_of_object
|
||||
action_cooldown = 0.2 SECONDS
|
||||
|
||||
/datum/ai_behavior/break_out_of_object/setup(datum/ai_controller/controller, atom/target)
|
||||
if (!should_attack_target(controller, target))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/ai_behavior/break_out_of_object/perform(seconds_per_tick, datum/ai_controller/controller, atom/target_atom)
|
||||
if (!should_attack_target(controller, target_atom))
|
||||
return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
|
||||
controller.ai_interact(target = target_atom, combat_mode = TRUE)
|
||||
return AI_BEHAVIOR_DELAY
|
||||
|
||||
/datum/ai_behavior/break_out_of_object/proc/should_attack_target(datum/ai_controller/controller, atom/target)
|
||||
if (QDELETED(target))
|
||||
return FALSE
|
||||
var/mob/living/pawn = controller.pawn
|
||||
if (!pawn.CanReach(target))
|
||||
return FALSE
|
||||
return pawn.loc == target || pawn.buckled == target
|
||||
|
||||
/datum/ai_planning_subtree/escape_captivity/pacifist
|
||||
pacifist = TRUE
|
||||
@@ -10,6 +10,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/simple_hostile
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
)
|
||||
@@ -17,6 +18,7 @@
|
||||
/// Find a target, walk at target, attack intervening obstacles
|
||||
/datum/ai_controller/basic_controller/simple/simple_hostile_obstacles
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
@@ -25,6 +27,7 @@
|
||||
/// Find a target, walk at target, attack intervening obstacles
|
||||
/datum/ai_controller/basic_controller/simple/simple_ranged
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/maintain_distance,
|
||||
/datum/ai_planning_subtree/ranged_skirmish,
|
||||
@@ -32,6 +35,7 @@
|
||||
|
||||
/datum/ai_controller/basic_controller/simple/simple_ranged_retaliate
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/target_retaliate,
|
||||
/datum/ai_planning_subtree/maintain_distance,
|
||||
/datum/ai_planning_subtree/ranged_skirmish,
|
||||
@@ -40,6 +44,7 @@
|
||||
/// Find a target, walk towards it AND shoot it
|
||||
/datum/ai_controller/basic_controller/simple/simple_skirmisher
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/ranged_skirmish,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
@@ -49,6 +54,7 @@
|
||||
/// Use an ability on target on cooldown
|
||||
/datum/ai_controller/basic_controller/simple/simple_ability
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/maintain_distance,
|
||||
/datum/ai_planning_subtree/targeted_mob_ability,
|
||||
@@ -56,6 +62,7 @@
|
||||
|
||||
/datum/ai_controller/basic_controller/simple/simple_ability_retaliate
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/target_retaliate,
|
||||
/datum/ai_planning_subtree/maintain_distance,
|
||||
/datum/ai_planning_subtree/targeted_mob_ability,
|
||||
@@ -64,6 +71,7 @@
|
||||
/// Use an ability on target on cooldown, then try to punch them
|
||||
/datum/ai_controller/basic_controller/simple/simple_ability_melee
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/targeted_mob_ability,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path,
|
||||
@@ -73,6 +81,7 @@
|
||||
/// Use an ability on target on cooldown, then try to shoot them
|
||||
/datum/ai_controller/basic_controller/simple/simple_ability_ranged
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/maintain_distance,
|
||||
/datum/ai_planning_subtree/targeted_mob_ability,
|
||||
@@ -81,7 +90,7 @@
|
||||
|
||||
/// Fight back if attacked
|
||||
/datum/ai_controller/basic_controller/simple/simple_retaliate
|
||||
ai_traits = STOP_MOVING_WHEN_PULLED
|
||||
ai_traits = DEFAULT_AI_FLAGS | STOP_MOVING_WHEN_PULLED
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/target_retaliate,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
@@ -89,8 +98,9 @@
|
||||
|
||||
/// Get pissed at random people for no reason
|
||||
/datum/ai_controller/basic_controller/simple/simple_capricious
|
||||
ai_traits = STOP_MOVING_WHEN_PULLED
|
||||
ai_traits = DEFAULT_AI_FLAGS | STOP_MOVING_WHEN_PULLED
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/capricious_retaliate,
|
||||
/datum/ai_planning_subtree/target_retaliate,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
@@ -98,7 +108,7 @@
|
||||
|
||||
/// Runs away from anyone it sees
|
||||
/datum/ai_controller/basic_controller/simple/simple_fearful
|
||||
ai_traits = STOP_MOVING_WHEN_PULLED
|
||||
ai_traits = PASSIVE_AI_FLAGS
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/simple_find_nearest_target_to_flee,
|
||||
/datum/ai_planning_subtree/flee_target,
|
||||
@@ -106,7 +116,7 @@
|
||||
|
||||
/// Runs away when attacked
|
||||
/datum/ai_controller/basic_controller/simple/simple_skittish
|
||||
ai_traits = STOP_MOVING_WHEN_PULLED
|
||||
ai_traits = PASSIVE_AI_FLAGS
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
|
||||
/datum/ai_planning_subtree/flee_target,
|
||||
@@ -120,6 +130,7 @@
|
||||
)
|
||||
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/escape_captivity,
|
||||
/datum/ai_planning_subtree/pet_planning,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user