diff --git a/code/datums/components/pet_commands/pet_command.dm b/code/datums/components/pet_commands/pet_command.dm index aa8ff403c95..a3adcd53a12 100644 --- a/code/datums/components/pet_commands/pet_command.dm +++ b/code/datums/components/pet_commands/pet_command.dm @@ -15,7 +15,7 @@ /// If true, command will not appear in radial menu and can only be accessed through speech var/hidden = FALSE /// Speech strings to listen out for - var/list/speech_commands = list() + VAR_PROTECTED/list/speech_commands = list() /// Shown above the mob's head when it hears you var/command_feedback /// How close a mob needs to be to a target to respond to a command @@ -26,10 +26,14 @@ var/targeting_strategy_key = BB_PET_TARGETING_STRATEGY /// our pointed reaction we play var/pointed_reaction + /// The regex for finding our commands in speech + VAR_PRIVATE/regex/command_regex /datum/pet_command/New(mob/living/parent) . = ..() parent_uid = parent.UID() + if(length(speech_commands)) + command_regex = regex("\\b([speech_commands.Join("|")])\\b", "i") /// Register a new guy we want to listen to /datum/pet_command/proc/add_new_friend(mob/living/tamer) @@ -73,11 +77,8 @@ * if check_verbosity is true, skip the match if there spoken_text is way longer than the match */ /datum/pet_command/proc/find_command_in_text(spoken_text, check_verbosity = FALSE) - for(var/command as anything in speech_commands) - if(!findtext(spoken_text, command)) - continue - if(check_verbosity && length(spoken_text) > length(command) + MAX_NAME_LEN) - continue + var/valid_length = check_verbosity ? length(spoken_text) > MAX_NAME_LEN : TRUE + if(command_regex.Find(spoken_text) && valid_length) return TRUE return FALSE @@ -173,7 +174,6 @@ parent.ai_controller.cancel_actions() if(!look_for_target(friend, potential_target) || !set_command_target(parent, potential_target)) return FALSE - parent.visible_message("[parent] follows [friend]'s gesture towards [potential_target] [pointed_reaction]!") + var/suffix = pointed_reaction ? " [pointed_reaction]" : "" + parent.visible_message("[parent] follows [friend]'s gesture towards [potential_target][suffix]!") return TRUE - - diff --git a/code/datums/components/pet_commands/pet_commands_basic.dm b/code/datums/components/pet_commands/pet_commands_basic.dm index 1003deb3c5e..3017cd731e9 100644 --- a/code/datums/components/pet_commands/pet_commands_basic.dm +++ b/code/datums/components/pet_commands/pet_commands_basic.dm @@ -8,7 +8,7 @@ command_name = "Stay" command_desc = "Command your pet to stay idle in this location." speech_commands = list("sit", "stay", "stop") - command_feedback = "sits" + command_feedback = "sits." /datum/pet_command/idle/execute_action(datum/ai_controller/controller) return SUBTREE_RETURN_FINISH_PLANNING // This cancels further AI planning diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm index 4289622d227..6463b91f966 100644 --- a/code/modules/mob/living/basic/minebots/minebot_ai.dm +++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm @@ -172,7 +172,11 @@ living_pawn.face_atom(target) - RegisterSignal(target, COMSIG_MINE_EXPOSE_GIBTONITE, PROC_REF(on_mine_expose_gibtonite), override = TRUE) + var/turf/simulated/mineral/mineral_target = target + if(istype(mineral_target) && istype(mineral_target.ore, /datum/ore/gibtonite)) + // Duplicate signals can occur when a minebot previously tried to mine a + // turf and failed (e.g. something else was hit by the kpa projectile) + RegisterSignal(mineral_target, COMSIG_MINE_EXPOSE_GIBTONITE, PROC_REF(on_mine_expose_gibtonite), override = TRUE) living_pawn.RangedAttack(target) living_pawn.a_intent = old_intent @@ -182,6 +186,7 @@ /datum/ai_behavior/minebot_mine_turf/proc/on_mine_expose_gibtonite(datum/source, mob/living/instigator) SIGNAL_HANDLER // COMSIG_MINE_EXPOSE_GIBTONITE + UnregisterSignal(source, COMSIG_MINE_EXPOSE_GIBTONITE) instigator.emote("me", EMOTE_VISIBLE, "yelps!") instigator.ai_controller.set_blackboard_key(BB_MINEBOT_GIBTONITE_RUN, source)