mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-15 04:01:41 +00:00
[MIRROR] Pet Command Component + Regal Rats can order their subjects around [MDB IGNORE] (#18131)
* Pet Command Component + Regal Rats can order their subjects around (#71590) ## About The Pull Request Another atomisation of #71421 but I had a fun idea while I was testing it. This adds a component based on the existing system for giving instructions to tamed carp or dogs, but hopefully more modular. It also gives it to the rat minions of a regal rat. The basic function allows the mob to listen and react to spoken commands, which passes things to its AI blackboard. Additionally if you alt-click a commandable mob it will show a radial menu which both allows you to select a command, and also contains tooltips explaining what they do and what audible words trigger it. <details> <summary>Video</summary> https://user-images.githubusercontent.com/7483112/204308693-0eccebec-75c9-411c-81c5-5aa0d682d1a5.mp4 </details> Now if you riot some rats, you can alt click on them individually to give them specific orders (more useful for other creatures than rats), or you can speak out loud to command your legion. Rats aren't very smart so you can't give them many instructions, but this is expandable for other creatures. Additional change: Mice don't squeak if stepped on by other mice because this made an absolutely unholy noise and I am not sure there's a way to get non-dense mobs to spread out. ## Why It's Good For The Game Allows for giving more mobs the ability to be tamed and instructable by their owner, without copy/pasting code which lives inside a specific mob. Yelling at your rats to give them commands is funny. It also adds the possibility of telling your rats to stop biting someone if they have agreed to your demands, allowing for more courtly roleplay. When Regal Rat is converted to a basic mob its AI can also give other AIs instructions by yelling at them which I think is a good feature. ## Changelog 🆑 add: The followers of Regal Rats will now respond to simple instructions, if given by their rightful lord. Except frogs. They're too busy licking themselves and watching the colours. /🆑 * Pet Command Component + Regal Rats can order their subjects around Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
124
code/datums/components/pet_commands/pet_commands_basic.dm
Normal file
124
code/datums/components/pet_commands/pet_commands_basic.dm
Normal file
@@ -0,0 +1,124 @@
|
||||
// None of these are really complex enough to merit their own file
|
||||
|
||||
/**
|
||||
* # Pet Command: Idle
|
||||
* Tells a pet to resume its idle behaviour, usually staying put where you leave it
|
||||
*/
|
||||
/datum/pet_command/idle
|
||||
command_name = "Stay"
|
||||
command_desc = "Command your pet to stay idle in this location."
|
||||
radial_icon = 'icons/testing/turf_analysis.dmi'
|
||||
radial_icon_state = "red_arrow"
|
||||
command_key = PET_COMMAND_IDLE
|
||||
speech_commands = list("sit", "stay", "stop")
|
||||
command_feedback = "sits"
|
||||
|
||||
/datum/pet_command/idle/execute_action(datum/ai_controller/controller)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING // This cancels further AI planning
|
||||
|
||||
/**
|
||||
* # Pet Command: Stop
|
||||
* Tells a pet to exit command mode and resume its normal behaviour, which includes regular target-seeking and what have you
|
||||
*/
|
||||
/datum/pet_command/free
|
||||
command_name = "Loose"
|
||||
command_desc = "Allow your pet to resume its natural behaviours."
|
||||
radial_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
radial_icon_state = "repulse"
|
||||
command_key = PET_COMMAND_NONE
|
||||
speech_commands = list("free", "loose")
|
||||
command_feedback = "relaxes"
|
||||
|
||||
/datum/pet_command/free/execute_action(datum/ai_controller/controller)
|
||||
return // Just move on to the next planning subtree.
|
||||
|
||||
/**
|
||||
* # Pet Command: Follow
|
||||
* Tells a pet to follow you until you tell it to do something else
|
||||
*/
|
||||
/datum/pet_command/follow
|
||||
command_name = "Follow"
|
||||
command_desc = "Command your pet to accompany you."
|
||||
radial_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
radial_icon_state = "summons"
|
||||
command_key = PET_COMMAND_FOLLOW
|
||||
speech_commands = list("heel", "follow")
|
||||
|
||||
/datum/pet_command/follow/set_command_active(mob/living/parent, mob/living/commander)
|
||||
. = ..()
|
||||
set_command_target(parent, commander)
|
||||
|
||||
/datum/pet_command/follow/execute_action(datum/ai_controller/controller)
|
||||
controller.queue_behavior(/datum/ai_behavior/pet_follow_friend, BB_CURRENT_PET_TARGET)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
/**
|
||||
* # Pet Command: Attack
|
||||
* Tells a pet to chase and bite the next thing you point at
|
||||
*/
|
||||
/datum/pet_command/point_targetting/attack
|
||||
command_name = "Attack"
|
||||
command_desc = "Command your pet to attack things that you point out to it."
|
||||
radial_icon = 'icons/effects/effects.dmi'
|
||||
radial_icon_state = "bite"
|
||||
|
||||
command_key = PET_COMMAND_ATTACK
|
||||
speech_commands = list("attack", "sic", "kill")
|
||||
command_feedback = "growl"
|
||||
pointed_reaction = "growls"
|
||||
/// Balloon alert to display if providing an invalid target
|
||||
var/refuse_reaction = "shakes head"
|
||||
/// Attack behaviour to use, generally you will want to override this to add some kind of cooldown
|
||||
var/attack_behaviour = /datum/ai_behavior/basic_melee_attack
|
||||
|
||||
// Refuse to target things we can't target, chiefly other friends
|
||||
/datum/pet_command/point_targetting/attack/set_command_target(mob/living/parent, atom/target)
|
||||
if (!target)
|
||||
return
|
||||
var/mob/living/living_parent = parent
|
||||
if (!living_parent.ai_controller)
|
||||
return
|
||||
var/datum/targetting_datum/targeter = living_parent.ai_controller.blackboard[targetting_datum_key]
|
||||
if (!targeter)
|
||||
return
|
||||
if (!targeter.can_attack(living_parent, target))
|
||||
refuse_target(parent, target)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/// Display feedback about not targetting something
|
||||
/datum/pet_command/point_targetting/attack/proc/refuse_target(mob/living/parent, atom/target)
|
||||
var/mob/living/living_parent = parent
|
||||
living_parent.balloon_alert_to_viewers("[refuse_reaction]")
|
||||
living_parent.visible_message(span_notice("[living_parent] refuses to attack [target]."))
|
||||
|
||||
/datum/pet_command/point_targetting/attack/execute_action(datum/ai_controller/controller)
|
||||
controller.queue_behavior(attack_behaviour, BB_CURRENT_PET_TARGET, targetting_datum_key)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
/**
|
||||
* # Pet Command: Targetted Ability
|
||||
* Tells a pet to use some kind of ability on the next thing you point at
|
||||
*/
|
||||
/datum/pet_command/point_targetting/use_ability
|
||||
command_name = "Use ability"
|
||||
command_desc = "Command your pet to use one of its special skills on something that you point out to it."
|
||||
radial_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
radial_icon_state = "projectile"
|
||||
command_key = PET_COMMAND_USE_ABILITY
|
||||
speech_commands = list("shoot", "blast", "cast")
|
||||
command_feedback = "growl"
|
||||
pointed_reaction = "growls"
|
||||
/// Blackboard key where a reference to some kind of mob ability is stored
|
||||
var/pet_ability_key
|
||||
|
||||
/datum/pet_command/point_targetting/use_ability/execute_action(datum/ai_controller/controller)
|
||||
if (!pet_ability_key)
|
||||
return
|
||||
var/datum/action/cooldown/using_action = controller.blackboard[pet_ability_key]
|
||||
if (QDELETED(using_action))
|
||||
return
|
||||
// We don't check if the target exists because we want to 'sit attentively' if we've been instructed to attack but not given one yet
|
||||
// We also don't check if the cooldown is over because there's no way a pet owner can know that, the behaviour will handle it
|
||||
controller.queue_behavior(/datum/ai_behavior/pet_use_ability, pet_ability_key, targetting_datum_key)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
Reference in New Issue
Block a user