Tweaking drake AI further.

This commit is contained in:
MistakeNot4892
2022-08-27 15:10:18 +10:00
parent c3f79cca8d
commit d6fdf48a05
5 changed files with 59 additions and 54 deletions

View File

@@ -4,7 +4,7 @@
var/hostile = FALSE // Do we try to hurt others?
var/retaliate = FALSE // Attacks whatever struck it first. Mobs will still attack back if this is false but hostile is true.
var/mauling = FALSE // Attacks unconscious mobs
var/ignore_incapacitated = FALSE // If it's interested in attacking targets that are STUNNED.
var/ignore_incapacitated = FALSE // If it's interested in attacking targets that are STUNNED.
var/handle_corpse = FALSE // Allows AI to acknowledge corpses (e.g. nurse spiders)
var/atom/movable/target = null // The thing (mob or object) we're trying to kill.
@@ -132,7 +132,7 @@
return FALSE
if(L.incapacitated(INCAPACITATION_STUNNED)) // Are they stunned and do we care?
if(ignore_incapacitated)
return FALSE
return FALSE
if(holder.IIsAlly(L))
return FALSE
return TRUE
@@ -166,7 +166,7 @@
ai_log("lose_target() : Entering.", AI_LOG_TRACE)
if(target)
ai_log("lose_target() : Had a target, checking if still valid.", AI_LOG_DEBUG)
if(!can_attack(target, FALSE)) /// If it's not valid to chase, don't keep looking.
if(!can_attack(target, FALSE)) /// If it's not valid to chase, don't keep looking.
remove_target()
return find_target()
ai_log("lose_target() : Had a target, setting to null and LTT.", AI_LOG_DEBUG)
@@ -251,6 +251,7 @@
if(holder.IIsAlly(attacker)) // I'll overlook it THIS time...
ai_log("react_to_attack() : Was attacked by [attacker], but they were an ally.", AI_LOG_TRACE)
return FALSE
holder.IWasAttackedBy(attacker)
if(target) // Already fighting someone. Switching every time we get hit would impact our combat performance.
if(!retaliate) // If we don't get to fight back, we don't fight back...
ai_log("react_to_attack() : Was attacked by [attacker], but we already have a target.", AI_LOG_TRACE)

View File

@@ -1184,3 +1184,6 @@
/mob/living/proc/get_snow_footprint_state()
if(!hovering) // Flying things shouldn't make footprints.
return "snow_footprints"
/mob/living/proc/IWasAttackedBy(var/mob/living/attacker)
return

View File

@@ -5,8 +5,6 @@
// if(!P.SA_vulnerability || P.SA_vulnerability == intelligence_level)
if(P.SA_vulnerability & mob_class)
P.damage += P.SA_bonus_damage
if(P.firer)
IWasAttackedBy(P.firer)
. = ..()
@@ -49,10 +47,6 @@
apply_damage(damage = harm_intent_damage, damagetype = BRUTE, def_zone = null, blocked = armor, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE)
L.visible_message(SPAN_WARNING("\The [L] [response_harm] \the [src]!"))
L.do_attack_animation(src)
IWasAttackedBy(L)
/mob/living/simple_mob/proc/IWasAttackedBy(var/mob/living/attacker)
return
// When somoene clicks us with an item in hand
/mob/living/simple_mob/attackby(var/obj/item/O, var/mob/user)
@@ -120,8 +114,6 @@
if(supernatural && istype(O,/obj/item/nullrod))
effective_force *= 2
purge = 3
if(user)
IWasAttackedBy(user)
if(O.force <= resistance)
to_chat(user, SPAN_WARNING("This weapon is ineffective, it does no damage."))
return 2 //???

View File

@@ -224,11 +224,11 @@ var/global/list/last_drake_howl = list()
var/sitting = FALSE
var/next_spit = 0
var/spit_cooldown = 8 SECONDS
var/next_alpha_check = 0
var/dominance = 0 // A score used to determine pack leader.
var/next_leader_check = 0
var/charisma = 0 // A score used to determine pack leader.
var/stored_sap = 0
var/max_stored_sap = 60
var/attacked_by_human = FALSE
var/attacked_by_neutral = FALSE
var/list/original_armor
@@ -246,7 +246,7 @@ var/global/list/last_drake_howl = list()
/mob/living/simple_mob/animal/sif/grafadreka/Initialize()
dominance = rand(5, 15)
charisma = rand(5, 15)
stored_sap = rand(20, 30)
nutrition = rand(400,500)
@@ -408,14 +408,13 @@ var/global/list/last_drake_howl = list()
/mob/living/simple_mob/animal/sif/grafadreka/do_tame(var/obj/O, var/mob/user)
. = ..()
if(attacked_by_human && ishuman(user) && ((user in tamers) || (user in friends)))
attacked_by_human = FALSE
attacked_by_neutral = FALSE
/mob/living/simple_mob/animal/sif/grafadreka/handle_special()
..()
if(client || world.time >= next_alpha_check)
next_alpha_check = world.time + (60 SECONDS)
check_alpha_status()
if(client || world.time >= next_leader_check)
next_leader_check = world.time + (60 SECONDS)
check_leader_status()
/mob/living/simple_mob/animal/sif/grafadreka/do_help_interaction(atom/A)
@@ -494,23 +493,23 @@ var/global/list/last_drake_howl = list()
return ..()
/mob/living/simple_mob/animal/sif/grafadreka/proc/get_local_alpha()
/mob/living/simple_mob/animal/sif/grafadreka/proc/get_pack_leader()
var/pack = FALSE
var/mob/living/simple_mob/animal/sif/grafadreka/alpha
var/mob/living/simple_mob/animal/sif/grafadreka/leader
if(!is_baby)
alpha = src
for(var/mob/living/simple_mob/animal/sif/grafadreka/beta in hearers(7, loc))
if(beta == src || beta.is_baby || beta.stat == DEAD)
leader = src
for(var/mob/living/simple_mob/animal/sif/grafadreka/follower in hearers(7, loc))
if(follower == src || follower.is_baby || follower.stat == DEAD || follower.faction != faction)
continue
pack = TRUE
if(beta.dominance > alpha.dominance)
alpha = beta
if(!leader || follower.charisma > leader.charisma)
leader = follower
if(pack)
return alpha
return leader
/mob/living/simple_mob/animal/sif/grafadreka/proc/check_alpha_status()
var/mob/living/simple_mob/animal/sif/grafadreka/alpha = get_local_alpha()
if(src == alpha)
/mob/living/simple_mob/animal/sif/grafadreka/proc/check_leader_status()
var/mob/living/simple_mob/animal/sif/grafadreka/leader = get_pack_leader()
if(src == leader)
add_modifier(/datum/modifier/ace, 60 SECONDS)
else
remove_modifiers_of_type(/datum/modifier/ace)
@@ -521,14 +520,13 @@ var/global/list/last_drake_howl = list()
stat("Nutrition:", "[nutrition]/[max_nutrition]")
stat("Stored sap:", "[stored_sap]/[max_stored_sap]")
/mob/living/simple_mob/animal/sif/grafadreka/proc/can_bite(var/mob/living/M)
return istype(M) && (M.lying || M.confused || M.incapacitated())
/mob/living/simple_mob/animal/sif/grafadreka/apply_bonus_melee_damage(atom/A, damage_amount)
// Melee attack on incapacitated or prone enemies bites instead of slashing
var/last_attack_was_claws = attacking_with_claws
attacking_with_claws = TRUE
if(isliving(A))
var/mob/living/M = A
if(M.lying || M.incapacitated())
attacking_with_claws = FALSE
attacking_with_claws = !can_bite(A)
if(last_attack_was_claws != attacking_with_claws)
if(attacking_with_claws) // Use claws.
@@ -575,15 +573,12 @@ var/global/list/last_drake_howl = list()
/mob/living/simple_mob/animal/sif/grafadreka/Login()
. = ..()
if(client && !is_baby)
dominance = INFINITY // Let players lead by default.
else // But not if they are a baby.
dominance = 0
charisma = (client && !is_baby) ? INFINITY : 0
/mob/living/simple_mob/animal/sif/grafadreka/Logout()
. = ..()
if(!client)
dominance = rand(5, 15)
charisma = rand(5, 15)
/datum/say_list/grafadreka
speak = list("Chff!","Skhh.", "Rrrss...")

View File

@@ -12,7 +12,7 @@
if(.)
var/mob/living/M = A
if(M.lying || M.incapacitated())
if(M.lying || M.confused || M.incapacitated())
return FALSE // They're already stunned, go bite their nipples off.
for(var/mobtype in stun_immune_types)
@@ -21,21 +21,35 @@
/mob/living/simple_mob/animal/sif/grafadreka/IIsAlly(mob/living/L)
. = ..()
// Avoid humans unless we're very hungry, very angry, or they are small).
if(!. && ishuman(L) && !attacked_by_human)
. = !issmall(L) && (nutrition > max_nutrition * 0.15)
// If we're starving or we've been attacked by a neutral party, all bets are off.
if(!. && (nutrition > max_nutrition * 0.15) && !attacked_by_neutral)
// Robots aren't every tasty.
if(isrobot(L))
return TRUE
// We don't normally target anything bigger than us.
if(L.mob_size > mob_size)
return TRUE
// Leave humans alone generally, unless they look like a snack.
if(ishuman(L) && !issmall(L))
return TRUE
// Avoid cannibalism.
if(istype(L, /mob/living/simple_mob/animal/sif/grafadreka))
return TRUE
/mob/living/simple_mob/animal/sif/grafadreka/proc/IDoInteraction(var/obj/item/target)
set waitfor = FALSE
face_atom(target)
do_interaction(target)
/mob/living/simple_mob/animal/sif/grafadreka/proc/is_supposedly_neutral(var/mob/living/person)
return istype(person) && (ishuman(person) || isrobot(person) || person.faction == "station")
// If we get attacked by a nominally neutral mob, set us to angery mode.
/mob/living/simple_mob/animal/sif/grafadreka/IWasAttackedBy(var/mob/living/attacker)
if(ishuman(attacker))
attacked_by_human = TRUE
if(istype(ai_holder, /datum/ai_holder/simple_mob/intentional/grafadreka))
var/datum/ai_holder/simple_mob/intentional/grafadreka/drake_brain = ai_holder
drake_brain.hostile = TRUE
. = ..()
if(is_supposedly_neutral(attacker))
attacked_by_neutral = TRUE
ai_holder.hostile = TRUE
/datum/ai_holder/simple_mob/intentional/grafadreka
hostile = TRUE
@@ -50,11 +64,11 @@
/datum/ai_holder/simple_mob/intentional/grafadreka/should_flee(force)
. = ..()
if(!. && ismob(target))
if(!. && isliving(target))
var/mob/living/prey = target
var/mob/living/simple_mob/animal/sif/grafadreka/drake = holder
// If they're incapacitated, don't need to spit on them again.
if(!istype(drake) || prey.lying || prey.incapacitated())
if(!istype(drake) || drake.can_bite(prey))
return FALSE
// We can spit at them - disengage so you can pew pew.
if(get_dist(target, holder) <= 1 && drake.has_sap(2) && (world.time >= drake.next_spit))
@@ -84,7 +98,7 @@
if(!leader)
var/mob/living/simple_mob/animal/sif/grafadreka/drake = holder
if(istype(drake))
set_follow(drake.get_local_alpha())
set_follow(drake.get_pack_leader())
return ..()
/datum/ai_holder/simple_mob/intentional/grafadreka/handle_stance_strategical()
@@ -172,7 +186,7 @@
/mob/living/simple_mob/animal/sif/grafadreka/hatchling/IWasAttackedBy(var/mob/living/attacker)
. = ..()
if(attacked_by_human)
if(is_supposedly_neutral(attacker))
for(var/mob/living/simple_mob/animal/sif/grafadreka/friend in viewers(world.view, src))
if(friend == src || !IIsAlly(friend))
continue