mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 16:05:07 +00:00
[MIRROR] Fixes dog AI lockups when fetching things, adds growling noises for dog attack mode [MDB IGNORE] (#12105)
* Improves dog AI resilience (#65384) About The Pull Request AI dogs currently have a nasty habit of getting stuck when trying to fetch items sometimes, rendering their AI behavior basically dead as they're stuck in a state where they're unable to accept any commands/inputs from their environment. This PR fixes that by adding some more robust checks to make sure a failed fetch attempt doesn't softlock the pups. This PR also adds some growling sounds for dogs in harass mode who are guarding against someone not within biting distance. Why It's Good For The Game Fixes some edge cases where dog AI would stop working entirely. Makes dog AI's in attack mode more conspicuous, and less reliant on text spam to show that. Changelog cl Ryll/Shaps fix: Dog AI's should no longer lock up and become unresponsive after failed fetch attempts soundadd: Dogs in harass mode that are guarding against someone will now make growling sounds /cl * Fixes dog AI lockups when fetching things, adds growling noises for dog attack mode Co-authored-by: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com>
This commit is contained in:
@@ -161,6 +161,7 @@
|
||||
#define BB_DOG_ORDER_MODE "BB_DOG_ORDER_MODE"
|
||||
#define BB_DOG_PLAYING_DEAD "BB_DOG_PLAYING_DEAD"
|
||||
#define BB_DOG_HARASS_TARGET "BB_DOG_HARASS_TARGET"
|
||||
#define BB_DOG_HARASS_FRUSTRATION "BB_DOG_HARASS_FRUSTRATION"
|
||||
|
||||
/// Basically, what is our vision/hearing range for picking up on things to fetch/
|
||||
#define AI_DOG_VISION_RANGE 10
|
||||
@@ -171,7 +172,9 @@
|
||||
/// After being ordered to heel, we spend this long chilling out
|
||||
#define AI_DOG_HEEL_DURATION 20 SECONDS
|
||||
/// After either being given a verbal order or a pointing order, ignore further of each for this duration
|
||||
#define AI_DOG_COMMAND_COOLDOWN 2 SECONDS
|
||||
#define AI_DOG_COMMAND_COOLDOWN 2 SECONDS
|
||||
/// If the dog is set to harass someone but doesn't bite them for this long, give up
|
||||
#define AI_DOG_HARASS_FRUSTRATE_TIME 50 SECONDS
|
||||
|
||||
// dog command modes (what pointing at something/someone does depending on the last order the dog heard)
|
||||
/// Don't do anything (will still react to stuff around them though)
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
/datum/ai_behavior/simple_equip/finish_action(datum/ai_controller/controller, success)
|
||||
. = ..()
|
||||
controller.blackboard[BB_FETCH_TARGET] = null
|
||||
if(!success)
|
||||
controller.blackboard[BB_FETCH_DELIVER_TO] = null
|
||||
|
||||
/datum/ai_behavior/simple_equip/proc/pickup_item(datum/ai_controller/controller, obj/item/target)
|
||||
var/atom/pawn = controller.pawn
|
||||
@@ -82,6 +84,7 @@
|
||||
|
||||
/datum/ai_behavior/deliver_item/finish_action(datum/ai_controller/controller, success)
|
||||
. = ..()
|
||||
controller.blackboard[BB_FETCH_TARGET] = null
|
||||
controller.blackboard[BB_FETCH_DELIVER_TO] = null
|
||||
|
||||
/// Actually drop the fetched item to the target
|
||||
@@ -98,7 +101,7 @@
|
||||
controller.pawn.visible_message(span_notice("[controller.pawn] delivers [carried_item] to [return_target]."))
|
||||
|
||||
carried_item.forceMove(get_turf(return_target))
|
||||
controller.blackboard -= BB_SIMPLE_CARRY_ITEM
|
||||
controller.blackboard[BB_SIMPLE_CARRY_ITEM] = null
|
||||
return TRUE
|
||||
|
||||
/// This behavior involves either eating a snack we can reach, or begging someone holding a snack
|
||||
@@ -184,21 +187,34 @@
|
||||
finish_action(controller, TRUE)
|
||||
return
|
||||
|
||||
if(!controller.blackboard[BB_DOG_HARASS_FRUSTRATION])
|
||||
controller.blackboard[BB_DOG_HARASS_FRUSTRATION] = world.time
|
||||
else if(controller.blackboard[BB_DOG_HARASS_FRUSTRATION] + AI_DOG_HARASS_FRUSTRATE_TIME < world.time) // if we haven't actually bit them in a while, give up
|
||||
living_pawn.visible_message(span_danger("[living_pawn] yawns and seems to lose interest in harassing [harass_target]."))
|
||||
finish_action(controller, FALSE)
|
||||
return
|
||||
|
||||
// subtypes of this behavior can change behavior for how eager/averse the pawn is to attack the target as opposed to falling back/making noise/getting help
|
||||
if(in_range(living_pawn, living_target))
|
||||
attack(controller, living_target)
|
||||
else if(DT_PROB(50, delta_time))
|
||||
else if(DT_PROB(15, delta_time))
|
||||
living_pawn.manual_emote("[pick("barks", "growls", "stares")] menacingly at [harass_target]!")
|
||||
if(DT_PROB(40, delta_time))
|
||||
playsound(living_pawn, pick('sound/creatures/dog/growl1.ogg', 'sound/creatures/dog/growl2.ogg'), 50, TRUE, -1)
|
||||
|
||||
/datum/ai_behavior/harass/finish_action(datum/ai_controller/controller, succeeded)
|
||||
. = ..()
|
||||
controller.blackboard[BB_DOG_HARASS_TARGET] = null
|
||||
controller.blackboard[BB_DOG_HARASS_FRUSTRATION] = null
|
||||
|
||||
/// A proc representing when the mob is pushed to actually attack the target. Again, subtypes can be used to represent different attacks from different animals, or it can be some other generic behavior
|
||||
/datum/ai_behavior/harass/proc/attack(datum/ai_controller/controller, mob/living/living_target)
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
if(!istype(living_pawn))
|
||||
return
|
||||
|
||||
controller.blackboard[BB_DOG_HARASS_FRUSTRATION] = world.time
|
||||
|
||||
// make sure the pawn gets some temporary strength boost to actually attack the target instead of pathetically nuzzling them.
|
||||
var/old_melee_lower = living_pawn.melee_damage_lower
|
||||
var/old_melee_upper = living_pawn.melee_damage_upper
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
BB_FETCH_IGNORE_LIST = list(),\
|
||||
BB_DOG_ORDER_MODE = DOG_COMMAND_NONE,\
|
||||
BB_DOG_PLAYING_DEAD = FALSE,\
|
||||
BB_DOG_HARASS_TARGET = null)
|
||||
BB_DOG_HARASS_TARGET = null,\
|
||||
BB_DOG_HARASS_FRUSTRATION = null,\
|
||||
BB_VISION_RANGE = AI_DOG_VISION_RANGE)
|
||||
ai_movement = /datum/ai_movement/jps
|
||||
planning_subtrees = list(/datum/ai_planning_subtree/dog)
|
||||
|
||||
@@ -202,7 +204,7 @@
|
||||
var/command
|
||||
if(findtext(spoken_text, "heel") || findtext(spoken_text, "sit") || findtext(spoken_text, "stay"))
|
||||
command = COMMAND_HEEL
|
||||
else if(findtext(spoken_text, "fetch") || findtext(spoken_text, "get it"))
|
||||
else if(findtext(spoken_text, "fetch"))
|
||||
command = COMMAND_FETCH
|
||||
else if(findtext(spoken_text, "attack") || findtext(spoken_text, "sic"))
|
||||
command = COMMAND_ATTACK
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
pawn.visible_message(span_notice("[pawn] [blackboard[BB_HOSTILE_ATTACK_WORD]] at [commander]'s command, and [pawn.p_they()] stop[pawn.p_s()] obediently, awaiting further orders."))
|
||||
blackboard[BB_HOSTILE_ORDER_MODE] = HOSTILE_COMMAND_NONE
|
||||
CancelActions()
|
||||
// fetch: whatever the commander points to, try and bring it back
|
||||
// follow: whatever the commander points to, try and bring it back
|
||||
if(COMMAND_FOLLOW)
|
||||
pawn.visible_message(span_notice("[pawn] [blackboard[BB_HOSTILE_ATTACK_WORD]] at [commander]'s command, and [pawn.p_they()] follow[pawn.p_s()] slightly in anticipation."))
|
||||
CancelActions()
|
||||
|
||||
@@ -27,3 +27,5 @@ can_shake.ogg adapted from https://freesound.org/people/mcmast/sounds/456703/
|
||||
splatter.ogg adapted from https://freesound.org/people/Rocktopus/sounds/233418/
|
||||
hohoho.ogg and hehe.ogg are cut from a recording by Nanakisan on freesound: https://freesound.org/people/Nanakisan/sounds/253534/
|
||||
mbox_full.ogg and mbox_end.ogg make use of The Ragtime Drummer by James Lent, in the public domain
|
||||
|
||||
growl1.ogg and growl2.ogg in /sound/creatures/dog are adapted from Glitchedtones's Freesound shih-tzu uploads https://freesound.org/people/Glitchedtones/
|
||||
|
||||
BIN
sound/creatures/dog/growl1.ogg
Normal file
BIN
sound/creatures/dog/growl1.ogg
Normal file
Binary file not shown.
BIN
sound/creatures/dog/growl2.ogg
Normal file
BIN
sound/creatures/dog/growl2.ogg
Normal file
Binary file not shown.
Reference in New Issue
Block a user