mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-03 21:42:06 +00:00
## About The Pull Request Now we can make basic mobs with hands easily so I did, they don't actually use their hands for anything with AI. In the future we can come back and share the monkey AI where they pick up items to hit people with, but frankly few weapons are more deadly than a gorilla's fists. IIRC I didn't really change their behaviour much, this is mostly just a straight conversion. Main difference is that they will prioritise eating nearby bananas and fruit salads over punching people. When I make these conversions nowadays I need to decide between "does this attack at the speed that it did as an NPC mob or the speed it did as a player?" I am arbitrarily deciding that gorillas are usually not players and electing for the former, but tell me if you disagree. I also made "show basic inhand sprites" into a component shared by Gorillas, Drones, and Dextrous Guardians (all also now available to become basic, once I get around to it), And I added an AI behaviour to run a basic emote. This is similar but different to "random speech", which kind of sucks and needs rewriting anyway. Gorillas don't speak, only ooga. ## Why It's Good For The Game https://www.youtube.com/watch?v=npuuTBlEb1U ## Changelog 🆑 refactor: Gorillas now use the basic mob framework. Please report any unusual side effects. /🆑
234 lines
8.4 KiB
Plaintext
234 lines
8.4 KiB
Plaintext
/datum/ai_planning_subtree/random_speech
|
|
//The chance of an emote occurring each second
|
|
var/speech_chance = 0
|
|
///Hearable emotes
|
|
var/list/emote_hear = list()
|
|
///Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
|
|
var/list/emote_see = list()
|
|
///Possible lines of speech the AI can have
|
|
var/list/speak = list()
|
|
///The sound effects associated with this speech, if any
|
|
var/list/sound = list()
|
|
|
|
/datum/ai_planning_subtree/random_speech/New()
|
|
. = ..()
|
|
if(speak)
|
|
speak = string_list(speak)
|
|
if(sound)
|
|
sound = string_list(sound)
|
|
if(emote_hear)
|
|
emote_hear = string_list(emote_hear)
|
|
if(emote_see)
|
|
emote_see = string_list(emote_see)
|
|
|
|
/datum/ai_planning_subtree/random_speech/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
if(!SPT_PROB(speech_chance, seconds_per_tick))
|
|
return
|
|
speak(controller)
|
|
|
|
/// Actually perform an action
|
|
/datum/ai_planning_subtree/random_speech/proc/speak(datum/ai_controller/controller)
|
|
var/audible_emotes_length = emote_hear?.len
|
|
var/non_audible_emotes_length = emote_see?.len
|
|
var/speak_lines_length = speak?.len
|
|
|
|
var/total_choices_length = audible_emotes_length + non_audible_emotes_length + speak_lines_length
|
|
|
|
var/random_number_in_range = rand(1, total_choices_length)
|
|
var/sound_to_play = length(sound) > 0 ? pick(sound) : null
|
|
|
|
if(random_number_in_range <= audible_emotes_length)
|
|
controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_hear), sound_to_play)
|
|
else if(random_number_in_range <= (audible_emotes_length + non_audible_emotes_length))
|
|
controller.queue_behavior(/datum/ai_behavior/perform_emote, pick(emote_see))
|
|
else
|
|
controller.queue_behavior(/datum/ai_behavior/perform_speech, pick(speak), sound_to_play)
|
|
|
|
/datum/ai_planning_subtree/random_speech/insect
|
|
speech_chance = 5
|
|
sound = list('sound/creatures/chitter.ogg')
|
|
emote_hear = list("chitters.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/mothroach
|
|
speech_chance = 15
|
|
emote_hear = list("flutters.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/mouse
|
|
speech_chance = 1
|
|
speak = list("Squeak!", "SQUEAK!", "Squeak?")
|
|
sound = list('sound/creatures/mousesqueek.ogg')
|
|
emote_hear = list("squeaks.")
|
|
emote_see = list("runs in a circle.", "shakes.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/frog
|
|
speech_chance = 3
|
|
emote_see = list("jumps in a circle.", "shakes.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/lizard // all of these have to be three words long or i'm killing you. you're dead.
|
|
speech_chance = 3
|
|
emote_hear = list("stamps around some.", "hisses a bit.")
|
|
emote_see = list("blehs the tongue.", "tilts the head.", "does a spin.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/sheep
|
|
speech_chance = 5
|
|
speak = list("baaa","baaaAAAAAH!","baaah")
|
|
sound = list('sound/creatures/sheep1.ogg', 'sound/creatures/sheep2.ogg', 'sound/creatures/sheep3.ogg')
|
|
emote_hear = list("bleats.")
|
|
emote_see = list("shakes her head.", "stares into the distance.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/rabbit
|
|
speech_chance = 10
|
|
speak = list("Mrrp.", "CHIRP!", "Mrrp?") // rabbits make some weird noises dude i don't know what to tell you
|
|
emote_hear = list("hops.")
|
|
emote_see = list("hops around.", "bounces up and down.")
|
|
|
|
/// For the easter subvariant of rabbits, these ones actually speak catchphrases.
|
|
/datum/ai_planning_subtree/random_speech/rabbit/easter
|
|
speak = list(
|
|
"Hop into Easter!",
|
|
"Come get your eggs!",
|
|
"Prizes for everyone!",
|
|
)
|
|
|
|
/// These ones have a space mask on, so their catchphrases are muffled.
|
|
/datum/ai_planning_subtree/random_speech/rabbit/easter/space
|
|
speak = list(
|
|
"Hmph mmph mmmph!",
|
|
"Mmphe mmphe mmphe!",
|
|
"Hmm mmm mmm!",
|
|
)
|
|
|
|
/datum/ai_planning_subtree/random_speech/chicken
|
|
speech_chance = 15 // really talkative ladies
|
|
speak = list("Cluck!", "BWAAAAARK BWAK BWAK BWAK!", "Bwaak bwak.")
|
|
sound = list('sound/creatures/clucks.ogg', 'sound/creatures/bagawk.ogg')
|
|
emote_hear = list("clucks.", "croons.")
|
|
emote_see = list("pecks at the ground.","flaps her wings viciously.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/chick
|
|
speech_chance = 4
|
|
speak = list("Cherp.", "Cherp?", "Chirrup.", "Cheep!")
|
|
sound = list('sound/creatures/chick_peep.ogg')
|
|
emote_hear = list("cheeps.")
|
|
emote_see = list("pecks at the ground.","flaps her tiny wings.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/cow
|
|
speech_chance = 1
|
|
speak = list("moo?","moo","MOOOOOO")
|
|
sound = list('sound/creatures/cow.ogg')
|
|
emote_hear = list("brays.")
|
|
emote_see = list("shakes her head.")
|
|
|
|
///unlike normal cows, wisdom cows speak of wisdom and won't shut the fuck up
|
|
/datum/ai_planning_subtree/random_speech/cow/wisdom
|
|
speech_chance = 15
|
|
|
|
/datum/ai_planning_subtree/random_speech/cow/wisdom/New()
|
|
. = ..()
|
|
speak = GLOB.wisdoms //Done here so it's setup properly
|
|
sound = list()
|
|
|
|
/datum/ai_planning_subtree/random_speech/deer
|
|
speech_chance = 1
|
|
speak = list("Weeeeeeee?", "Weeee", "WEOOOOOOOOOO")
|
|
emote_hear = list("brays.")
|
|
emote_see = list("shakes her head.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/dog
|
|
speech_chance = 1
|
|
|
|
/datum/ai_planning_subtree/random_speech/dog/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
if(!isdog(controller.pawn))
|
|
return
|
|
|
|
// Stay in sync with dog fashion.
|
|
var/mob/living/basic/pet/dog/dog_pawn = controller.pawn
|
|
dog_pawn.update_dog_speech(src)
|
|
|
|
return ..()
|
|
|
|
/datum/ai_planning_subtree/random_speech/faithless
|
|
speech_chance = 1
|
|
emote_see = list("wails.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/garden_gnome
|
|
speech_chance = 5
|
|
speak = list("Gnot a gnelf!", "Gnot a gnoblin!", "Howdy chum!")
|
|
emote_hear = list("snores.", "burps.")
|
|
emote_see = list("blinks.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/tree
|
|
speech_chance = 3
|
|
emote_see = list("photosynthesizes angrily.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/pig
|
|
speech_chance = 3
|
|
speak = list("oink?","oink","snurf")
|
|
sound = list('sound/creatures/pig1.ogg', 'sound/creatures/pig2.ogg')
|
|
emote_hear = list("snorts.")
|
|
emote_see = list("sniffs around.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/pony
|
|
speech_chance = 3
|
|
sound = list('sound/creatures/pony/whinny01.ogg', 'sound/creatures/pony/whinny02.ogg', 'sound/creatures/pony/whinny03.ogg')
|
|
emote_hear = list("whinnies!")
|
|
emote_see = list("horses around.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/pony/tamed
|
|
speech_chance = 3
|
|
sound = list('sound/creatures/pony/snort.ogg')
|
|
emote_hear = list("snorts.")
|
|
emote_see = list("snorts.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/killer_tomato
|
|
speech_chance = 3
|
|
emote_hear = list("gnashes.", "growls lowly.", "snarls.")
|
|
emote_see = list("salivates.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/ant
|
|
speech_chance = 1
|
|
speak = list("BZZZZT!", "CHTCHTCHT!", "Bzzz", "ChtChtCht")
|
|
sound = list('sound/creatures/chitter.ogg')
|
|
emote_hear = list("buzzes.", "clacks.")
|
|
emote_see = list("shakes their head.", "twitches their antennae.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/fox
|
|
speech_chance = 1
|
|
speak = list("Ack-Ack", "Ack-Ack-Ack-Ackawoooo", "Geckers", "Awoo", "Tchoff")
|
|
emote_hear = list("howls.", "barks.", "screams.")
|
|
emote_see = list("shakes their head.", "shivers.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/crab
|
|
speech_chance = 1
|
|
sound = list('sound/creatures/claw_click.ogg')
|
|
emote_hear = list("clicks.")
|
|
emote_see = list("clacks.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/penguin
|
|
speech_chance = 5
|
|
speak = list("Gah Gah!", "NOOT NOOT!", "NOOT!", "Noot", "noot", "Prah!", "Grah!")
|
|
emote_hear = list("squawks", "gakkers")
|
|
|
|
/datum/ai_planning_subtree/random_speech/bear
|
|
speech_chance = 5
|
|
emote_hear = list("rawrs.","grumbles.","grawls.", "stomps!")
|
|
emote_see = list("stares ferociously.")
|
|
|
|
/datum/ai_planning_subtree/random_speech/blackboard //literal tower of babel, subtree form
|
|
speech_chance = 1
|
|
|
|
/datum/ai_planning_subtree/random_speech/blackboard/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
|
var/list/speech_lines = controller.blackboard[BB_BASIC_MOB_SPEAK_LINES]
|
|
if(isnull(speech_lines))
|
|
return ..()
|
|
|
|
// Note to future developers: this behaviour a singleton so this probably doesn't work as you would expect
|
|
// The whole speech tree really needs to be refactored because this isn't how we use AI data these days
|
|
speak = speech_lines[BB_EMOTE_SAY] || list()
|
|
emote_see = speech_lines[BB_EMOTE_SEE] || list()
|
|
emote_hear = speech_lines[BB_EMOTE_HEAR] || list()
|
|
sound = speech_lines[BB_EMOTE_SOUND] || list()
|
|
speech_chance = speech_lines[BB_SPEAK_CHANCE] ? speech_lines[BB_SPEAK_CHANCE] : initial(speech_chance)
|
|
|
|
return ..()
|