|
| 1 | +/// Amount of time to wait before executing attack if not specified |
| 2 | +#define DEFAULT_ATTACK_DELAY (0.4 SECONDS) |
| 3 | + |
1 | 4 | /datum/ai_behavior/basic_melee_attack |
2 | 5 | action_cooldown = 0.2 SECONDS // We gotta check unfortunately often because we're in a race condition with nextmove |
3 | | - behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION |
| 6 | + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION |
4 | 7 | ///do we finish this action after hitting once? |
5 | 8 | var/terminate_after_action = FALSE |
6 | 9 |
|
7 | 10 | /datum/ai_behavior/basic_melee_attack/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key) |
8 | 11 | . = ..() |
9 | 12 | if(!controller.blackboard[targeting_strategy_key]) |
10 | 13 | CRASH("No targeting strategy was supplied in the blackboard for [controller.pawn]") |
11 | | - |
12 | 14 | //Hiding location is priority |
13 | 15 | var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key] |
14 | 16 | if(QDELETED(target)) |
|
17 | 19 | set_movement_target(controller, target) |
18 | 20 |
|
19 | 21 | /datum/ai_behavior/basic_melee_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key) |
| 22 | + var/atom/target = controller.blackboard[target_key] |
| 23 | + if (isnull(target)) |
| 24 | + return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED |
| 25 | + var/atom/movable/movablepawn = controller.pawn |
| 26 | + if (!movablepawn.CanReach(target)) |
| 27 | + controller.clear_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER) |
| 28 | + return AI_BEHAVIOR_INSTANT |
| 29 | + |
| 30 | + var/can_attack_time = controller.blackboard[BB_BASIC_MOB_MELEE_COOLDOWN_TIMER] |
| 31 | + if (isnull(can_attack_time)) |
| 32 | + var/blackboard_delay = controller.blackboard[BB_BASIC_MOB_MELEE_DELAY] |
| 33 | + var/attack_delay = isnull(blackboard_delay) ? DEFAULT_ATTACK_DELAY : blackboard_delay |
| 34 | + controller.set_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER, world.time + attack_delay) |
| 35 | + return AI_BEHAVIOR_INSTANT |
| 36 | + if (can_attack_time > world.time) |
| 37 | + return AI_BEHAVIOR_INSTANT |
| 38 | + |
20 | 39 | if (isliving(controller.pawn)) |
21 | 40 | var/mob/living/pawn = controller.pawn |
22 | 41 | if (world.time < pawn.next_move) |
23 | 42 | return AI_BEHAVIOR_INSTANT |
24 | 43 |
|
25 | | - var/mob/living/basic/basic_mob = controller.pawn |
26 | | - //targeting strategy will kill the action if not real anymore |
27 | | - var/atom/target = controller.blackboard[target_key] |
28 | 44 | var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key]) |
29 | | - |
30 | | - if(!targeting_strategy.can_attack(basic_mob, target)) |
| 45 | + if(!targeting_strategy.can_attack(controller.pawn, target)) |
31 | 46 | return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED |
32 | 47 |
|
33 | | - var/hiding_target = targeting_strategy.find_hidden_mobs(basic_mob, target) //If this is valid, theyre hidden in something! |
| 48 | + var/hiding_target = targeting_strategy.find_hidden_mobs(controller.pawn, target) //If this is valid, theyre hidden in something! |
34 | 49 |
|
35 | 50 | controller.set_blackboard_key(hiding_location_key, hiding_target) |
36 | 51 |
|
37 | | - if(hiding_target) //Slap it! |
38 | | - basic_mob.melee_attack(hiding_target) |
39 | | - else |
40 | | - basic_mob.melee_attack(target) |
41 | | - |
| 52 | + var/atom/final_target = hiding_target || target |
| 53 | + controller.ai_interact(target = final_target, combat_mode = TRUE) |
42 | 54 | if(terminate_after_action) |
43 | 55 | return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED |
44 | 56 | return AI_BEHAVIOR_DELAY |
45 | 57 |
|
46 | 58 | /datum/ai_behavior/basic_melee_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key) |
47 | 59 | . = ..() |
| 60 | + controller.clear_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER) |
48 | 61 | if(!succeeded) |
49 | 62 | controller.clear_blackboard_key(target_key) |
50 | 63 |
|
|
66 | 79 |
|
67 | 80 | /datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key) |
68 | 81 | . = ..() |
| 82 | + if(HAS_TRAIT(controller.pawn, TRAIT_HANDS_BLOCKED)) |
| 83 | + return FALSE |
69 | 84 | var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key] |
70 | 85 | if(QDELETED(target)) |
71 | 86 | return FALSE |
|
147 | 162 |
|
148 | 163 | /datum/ai_behavior/basic_ranged_attack/avoid_friendly_fire |
149 | 164 | avoid_friendly_fire = TRUE |
| 165 | + |
| 166 | +#undef DEFAULT_ATTACK_DELAY |
0 commit comments