mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-20 14:45:05 +00:00
* 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>
152 lines
5.8 KiB
Plaintext
152 lines
5.8 KiB
Plaintext
/datum/component/squeak
|
|
var/static/list/default_squeak_sounds = list('sound/items/toysqueak1.ogg'=1, 'sound/items/toysqueak2.ogg'=1, 'sound/items/toysqueak3.ogg'=1)
|
|
var/list/override_squeak_sounds
|
|
var/mob/holder
|
|
|
|
var/squeak_chance = 100
|
|
var/volume = 30
|
|
|
|
// This is so shoes don't squeak every step
|
|
var/steps = 0
|
|
var/step_delay = 1
|
|
|
|
// This is to stop squeak spam from inhand usage
|
|
var/last_use = 0
|
|
var/use_delay = 20
|
|
|
|
///extra-range for this component's sound
|
|
var/sound_extra_range = -1
|
|
///when sounds start falling off for the squeak
|
|
var/sound_falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE
|
|
///sound exponent for squeak. Defaults to 10 as squeaking is loud and annoying enough.
|
|
var/sound_falloff_exponent = 10
|
|
|
|
///what we set connect_loc to if parent is an item
|
|
var/static/list/item_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(play_squeak_crossed),
|
|
)
|
|
|
|
|
|
/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override, extrarange, falloff_exponent, fallof_distance)
|
|
if(!isatom(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
RegisterSignals(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), PROC_REF(play_squeak))
|
|
if(ismovable(parent))
|
|
RegisterSignals(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT, COMSIG_PROJECTILE_BEFORE_FIRE), PROC_REF(play_squeak))
|
|
|
|
AddComponent(/datum/component/connect_loc_behalf, parent, item_connections)
|
|
RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, PROC_REF(disposing_react))
|
|
if(isitem(parent))
|
|
RegisterSignals(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), PROC_REF(play_squeak))
|
|
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, PROC_REF(use_squeak))
|
|
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip))
|
|
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop))
|
|
if(istype(parent, /obj/item/clothing/shoes))
|
|
RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, PROC_REF(step_squeak))
|
|
else if(isstructure(parent))
|
|
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(use_squeak))
|
|
|
|
if(istype(parent, /obj/item/organ/internal/liver))
|
|
// Liver squeaking is depending on them functioning like a clown's liver
|
|
RegisterSignal(parent, SIGNAL_REMOVETRAIT(TRAIT_COMEDY_METABOLISM), PROC_REF(on_comedy_metabolism_removal))
|
|
|
|
override_squeak_sounds = custom_sounds
|
|
if(chance_override)
|
|
squeak_chance = chance_override
|
|
if(volume_override)
|
|
volume = volume_override
|
|
if(isnum(step_delay_override))
|
|
step_delay = step_delay_override
|
|
if(isnum(use_delay_override))
|
|
use_delay = use_delay_override
|
|
if(isnum(extrarange))
|
|
sound_extra_range = extrarange
|
|
if(isnum(falloff_exponent))
|
|
sound_falloff_exponent = falloff_exponent
|
|
if(isnum(fallof_distance))
|
|
sound_falloff_distance = fallof_distance
|
|
|
|
/datum/component/squeak/UnregisterFromParent()
|
|
. = ..()
|
|
qdel(GetComponent(/datum/component/connect_loc_behalf))
|
|
|
|
/datum/component/squeak/proc/play_squeak()
|
|
SIGNAL_HANDLER
|
|
|
|
if(prob(squeak_chance))
|
|
if(!override_squeak_sounds)
|
|
playsound(parent, pick_weight(default_squeak_sounds), volume, TRUE, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance)
|
|
else
|
|
playsound(parent, pick_weight(override_squeak_sounds), volume, TRUE, sound_extra_range, sound_falloff_exponent, falloff_distance = sound_falloff_distance)
|
|
|
|
/datum/component/squeak/proc/step_squeak()
|
|
SIGNAL_HANDLER
|
|
|
|
if(steps > step_delay)
|
|
play_squeak()
|
|
steps = 0
|
|
else
|
|
steps++
|
|
|
|
/datum/component/squeak/proc/play_squeak_crossed(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
|
SIGNAL_HANDLER
|
|
|
|
if(isitem(arrived))
|
|
var/obj/item/I = arrived
|
|
if(I.item_flags & ABSTRACT)
|
|
return
|
|
if(arrived.movement_type & (FLYING|FLOATING) || !arrived.has_gravity())
|
|
return
|
|
if(ismob(arrived) && !arrived.density) // Prevents 10 overlapping mice from making an unholy sound while moving
|
|
return
|
|
var/atom/current_parent = parent
|
|
if(isturf(current_parent?.loc))
|
|
play_squeak()
|
|
|
|
/datum/component/squeak/proc/use_squeak()
|
|
SIGNAL_HANDLER
|
|
|
|
if(last_use + use_delay < world.time)
|
|
last_use = world.time
|
|
play_squeak()
|
|
|
|
/datum/component/squeak/proc/on_equip(datum/source, mob/equipper, slot)
|
|
SIGNAL_HANDLER
|
|
holder = equipper
|
|
RegisterSignal(holder, COMSIG_MOVABLE_DISPOSING, PROC_REF(disposing_react), override=TRUE)
|
|
RegisterSignal(holder, COMSIG_PARENT_QDELETING, PROC_REF(holder_deleted), override=TRUE)
|
|
//override for the preqdeleted is necessary because putting parent in hands sends the signal that this proc is registered towards,
|
|
//so putting an object in hands and then equipping the item on a clothing slot (without dropping it first)
|
|
//will always runtime without override = TRUE
|
|
|
|
/datum/component/squeak/proc/on_drop(datum/source, mob/user)
|
|
SIGNAL_HANDLER
|
|
UnregisterSignal(user, COMSIG_MOVABLE_DISPOSING)
|
|
UnregisterSignal(user, COMSIG_PARENT_QDELETING)
|
|
holder = null
|
|
|
|
///just gets rid of the reference to holder in the case that theyre qdeleted
|
|
/datum/component/squeak/proc/holder_deleted(datum/source, datum/possible_holder)
|
|
SIGNAL_HANDLER
|
|
if(possible_holder == holder)
|
|
holder = null
|
|
|
|
// Disposal pipes related shits
|
|
/datum/component/squeak/proc/disposing_react(datum/source, obj/structure/disposalholder/disposal_holder, obj/machinery/disposal/disposal_source)
|
|
SIGNAL_HANDLER
|
|
|
|
//We don't need to worry about unregistering this signal as it will happen for us automaticaly when the holder is qdeleted
|
|
RegisterSignal(disposal_holder, COMSIG_ATOM_DIR_CHANGE, PROC_REF(holder_dir_change))
|
|
|
|
/datum/component/squeak/proc/holder_dir_change(datum/source, old_dir, new_dir)
|
|
SIGNAL_HANDLER
|
|
|
|
//If the dir changes it means we're going through a bend in the pipes, let's pretend we bumped the wall
|
|
if(old_dir != new_dir)
|
|
play_squeak()
|
|
|
|
/datum/component/squeak/proc/on_comedy_metabolism_removal(datum/source, trait)
|
|
SIGNAL_HANDLER
|
|
|
|
qdel(src)
|