mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-21 20:26:48 +01:00
Merge pull request #6870 from VOREStation/pol-aibash
Makes AI give up bashing if nothing to bash
This commit is contained in:
@@ -20,6 +20,11 @@
|
||||
#define MOVEMENT_FAILED 0 // Move() returned false for whatever reason and the mob didn't move.
|
||||
#define MOVEMENT_SUCCESSFUL 1 // Move() returned true and the mob hopefully moved.
|
||||
|
||||
// Results of pre-attack checks
|
||||
#define ATTACK_ON_COOLDOWN -1 // Recently attacked and needs to try again soon.
|
||||
#define ATTACK_FAILED 0 // Something else went wrong! Maybe they moved away!
|
||||
#define ATTACK_SUCCESSFUL 1 // We attacked (or tried to, misses count too)
|
||||
|
||||
// Reasons for targets to not be valid. Based on why, the AI responds differently.
|
||||
#define AI_TARGET_VALID 0 // We can fight them.
|
||||
#define AI_TARGET_INVIS 1 // They were in field of view but became invisible. Switch to STANCE_BLINDFIGHT if no other viable targets exist.
|
||||
|
||||
@@ -70,21 +70,21 @@
|
||||
/datum/ai_holder/proc/melee_attack(atom/A)
|
||||
pre_melee_attack(A)
|
||||
. = holder.IAttack(A)
|
||||
if(.)
|
||||
if(. == ATTACK_SUCCESSFUL)
|
||||
post_melee_attack(A)
|
||||
|
||||
// Ditto.
|
||||
/datum/ai_holder/proc/ranged_attack(atom/A)
|
||||
pre_ranged_attack(A)
|
||||
. = holder.IRangedAttack(A)
|
||||
if(.)
|
||||
if(. == ATTACK_SUCCESSFUL)
|
||||
post_ranged_attack(A)
|
||||
|
||||
// Most mobs probably won't have this defined but we don't care.
|
||||
/datum/ai_holder/proc/special_attack(atom/movable/AM)
|
||||
pre_special_attack(AM)
|
||||
. = holder.ISpecialAttack(AM)
|
||||
if(.)
|
||||
if(. == ATTACK_SUCCESSFUL)
|
||||
post_special_attack(AM)
|
||||
|
||||
// Called when within striking/shooting distance, however cooldown is not considered.
|
||||
@@ -218,7 +218,6 @@
|
||||
|
||||
var/dir_to_target = get_dir(holder, target_atom)
|
||||
holder.face_atom(target_atom)
|
||||
ai_log("breakthrough() : Exiting", AI_LOG_DEBUG)
|
||||
|
||||
// Sometimes the mob will try to hit something diagonally, and generally this fails.
|
||||
// So instead we will try two more times with some adjustments if the attack fails.
|
||||
@@ -274,32 +273,32 @@
|
||||
for(var/obj/structure/window/W in problem_turf)
|
||||
if(W.dir == reverse_dir[holder.dir]) // So that windows get smashed in the right order
|
||||
ai_log("destroy_surroundings() : Attacking side window.", AI_LOG_INFO)
|
||||
return holder.IAttack(W)
|
||||
return melee_attack(W)
|
||||
|
||||
else if(W.is_fulltile())
|
||||
ai_log("destroy_surroundings() : Attacking full tile window.", AI_LOG_INFO)
|
||||
return holder.IAttack(W)
|
||||
return melee_attack(W)
|
||||
|
||||
// Kill hull shields in the way.
|
||||
for(var/obj/effect/energy_field/shield in problem_turf)
|
||||
if(shield.density) // Don't attack shields that are already down.
|
||||
ai_log("destroy_surroundings() : Attacking hull shield.", AI_LOG_INFO)
|
||||
return holder.IAttack(shield)
|
||||
return melee_attack(shield)
|
||||
|
||||
// Kill common obstacle in the way like tables.
|
||||
var/obj/structure/obstacle = locate(/obj/structure, problem_turf)
|
||||
if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
|
||||
ai_log("destroy_surroundings() : Attacking generic structure.", AI_LOG_INFO)
|
||||
return holder.IAttack(obstacle)
|
||||
return melee_attack(obstacle)
|
||||
|
||||
for(var/obj/machinery/door/D in problem_turf) // Required since firelocks take up the same turf.
|
||||
if(D.density)
|
||||
ai_log("destroy_surroundings() : Attacking closed door.", AI_LOG_INFO)
|
||||
return holder.IAttack(D)
|
||||
return melee_attack(D)
|
||||
|
||||
ai_log("destroy_surroundings() : Exiting due to nothing to attack.", AI_LOG_INFO)
|
||||
return FALSE // Nothing to attack.
|
||||
return ATTACK_FAILED // Nothing to attack.
|
||||
|
||||
// Override for special behaviour.
|
||||
/datum/ai_holder/proc/can_violently_breakthrough()
|
||||
return violent_breakthrough
|
||||
return violent_breakthrough
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
var/home_low_priority = FALSE // If true, the mob will not go home unless it has nothing better to do, e.g. its following someone.
|
||||
var/max_home_distance = 3 // How far the mob can go away from its home before being told to go_home().
|
||||
// Note that there is a 'BYOND cap' of 14 due to limitations of get_/step_to().
|
||||
|
||||
// Wandering.
|
||||
var/wander = FALSE // If true, the mob will randomly move in the four cardinal directions when idle.
|
||||
var/wander_delay = 0 // How many ticks until the mob can move a tile in handle_wander_movement().
|
||||
var/base_wander_delay = 2 // What the above var gets set to when it wanders. Note that a tick happens every half a second.
|
||||
var/wander_when_pulled = FALSE // If the mob will refrain from wandering if someone is pulling it.
|
||||
|
||||
// Breakthrough
|
||||
var/failed_breakthroughs = 0 // How many times we've failed to breakthrough something lately
|
||||
|
||||
/datum/ai_holder/proc/walk_to_destination()
|
||||
ai_log("walk_to_destination() : Entering.",AI_LOG_TRACE)
|
||||
@@ -90,7 +91,9 @@
|
||||
// step_to(holder, A)
|
||||
if(holder.IMove(get_step_to(holder, A)) == MOVEMENT_FAILED)
|
||||
ai_log("walk_path() : Failed to move, attempting breakthrough.", AI_LOG_INFO)
|
||||
breakthrough(A) // We failed to move, time to smash things.
|
||||
if(!breakthrough(A) && failed_breakthroughs++ >= 5) // We failed to move, time to smash things.
|
||||
give_up_movement()
|
||||
failed_breakthroughs = 0
|
||||
return
|
||||
|
||||
if(move_once() == FALSE) // Start walking the path.
|
||||
@@ -106,7 +109,9 @@
|
||||
ai_log("walk_path() : Going to IMove().", AI_LOG_TRACE)
|
||||
if(holder.IMove(get_step_to(holder, A)) == MOVEMENT_FAILED )
|
||||
ai_log("walk_path() : Failed to move, attempting breakthrough.", AI_LOG_INFO)
|
||||
breakthrough(A) // We failed to move, time to smash things.
|
||||
if(!breakthrough(A) && failed_breakthroughs++ >= 5) // We failed to move, time to smash things.
|
||||
give_up_movement()
|
||||
failed_breakthroughs = 0
|
||||
|
||||
ai_log("walk_path() : Exited.", AI_LOG_TRACE)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
/mob/living/simple_mob/IAttack(atom/A)
|
||||
if(!canClick()) // Still on cooldown from a "click".
|
||||
return FALSE
|
||||
return ATTACK_ON_COOLDOWN
|
||||
return attack_target(A) // This will set click cooldown.
|
||||
|
||||
/mob/living/proc/IRangedAttack(atom/A)
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/mob/living/simple_mob/IRangedAttack(atom/A)
|
||||
if(!canClick()) // Still on cooldown from a "click".
|
||||
return FALSE
|
||||
return ATTACK_ON_COOLDOWN
|
||||
return shoot_target(A)
|
||||
|
||||
// Test if the AI is allowed to attempt a ranged attack.
|
||||
|
||||
@@ -3,26 +3,24 @@
|
||||
set waitfor = FALSE // For attack animations. Don't want the AI processor to get held up.
|
||||
|
||||
if(!A.Adjacent(src))
|
||||
return FALSE
|
||||
return ATTACK_FAILED
|
||||
var/turf/their_T = get_turf(A)
|
||||
|
||||
face_atom(A)
|
||||
|
||||
if(melee_attack_delay)
|
||||
// their_T.color = "#FF0000"
|
||||
melee_pre_animation(A)
|
||||
. = ATTACK_SUCCESSFUL //Shoving this in here as a 'best guess' since this proc is about to sleep and return and we won't be able to know the real value
|
||||
handle_attack_delay(A, melee_attack_delay) // This will sleep this proc for a bit, which is why waitfor is false.
|
||||
|
||||
// Cooldown testing is done at click code (for players) and interface code (for AI).
|
||||
setClickCooldown(get_attack_speed())
|
||||
|
||||
// Returns a value, but will be lost if
|
||||
. = do_attack(A, their_T)
|
||||
|
||||
if(melee_attack_delay)
|
||||
melee_post_animation(A)
|
||||
// their_T.color = "#FFFFFF"
|
||||
|
||||
|
||||
|
||||
// This does the actual attack.
|
||||
// This is a seperate proc for the purposes of attack animations.
|
||||
|
||||
Reference in New Issue
Block a user