More work on parrots.

They now mimic speech! I've also fixed a few bugs (like a missing if(stat) check in life) I think all that's left is to tweak their speed a bit and if possible, see if I can make it so that parrots peck out human's eyes when they attack.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4657 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
johnsonmt88@gmail.com
2012-09-08 19:48:05 +00:00
parent 278aacd80a
commit 727c367de0
2 changed files with 71 additions and 46 deletions

View File

@@ -8,6 +8,10 @@
* Sub-types * Sub-types
*/ */
//TODO List:
// Make parrots faster (But not retardedly fast like when using byond's walk() procs)
// See if its possible for parrots to target a human's eyes (peck their eyes out)
/* /*
* Defines * Defines
*/ */
@@ -34,12 +38,12 @@
icon_dead = "chick_dead" icon_dead = "chick_dead"
pass_flags = PASSTABLE pass_flags = PASSTABLE
speak = list("Hi","Hello!","Cracker?","BAWWWWK george mellons griffing me") //TODO: make it pick up on what people are saying. speak = list("Hi","Hello!","Cracker?","BAWWWWK george mellons griffing me")
speak_emote = list("squawks","says","yells") speak_emote = list("squawks","says","yells")
emote_hear = list("squawks","bawks") emote_hear = list("squawks","bawks")
emote_see = list("flutters its wings") emote_see = list("flutters its wings")
speak_chance = 1 speak_chance = 8//4% (1 in 25) chance every tick
turns_per_move = 5 turns_per_move = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker/ meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker/
@@ -52,7 +56,9 @@
var/parrot_state = PARROT_WANDER //Hunt for a perch when created var/parrot_state = PARROT_WANDER //Hunt for a perch when created
var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick. var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick.
var/parrot_sleep_dur = 25 //Same as above, this is the var that physically counts down var/parrot_sleep_dur = 25 //Same as above, this is the var that physically counts down
var/parrot_dam_zone = list("chest", "head", "l_arm", "l_leg", "r_arm", "r_leg") //For humans, select a bodypart to attack TODO: pecking out a mob's eyes var/parrot_dam_zone = list("chest", "head", "l_arm", "l_leg", "r_arm", "r_leg") //For humans, select a bodypart to attack
var/list/speech_buffer = list()
//Headset for Poly to yell at engineers :) //Headset for Poly to yell at engineers :)
var/obj/item/device/radio/headset/ears = null var/obj/item/device/radio/headset/ears = null
@@ -73,26 +79,28 @@
/obj/machinery/suit_storage_unit, /obj/machinery/telecomms, \ /obj/machinery/suit_storage_unit, /obj/machinery/telecomms, \
/obj/machinery/teleport) /obj/machinery/teleport)
//Parrots are kleptomaniacs. These vars a used for just that.. holding items and storing items the parrot wants to steal. //Parrots are kleptomaniacs. These vars a used for just that.. holding items and storing a list of items the parrot wants to steal.
var/obj/item/held_item = null var/obj/item/held_item = null
var/list/desired_items = list(/obj/item/weapon/reagent_containers/food/snacks/cracker/, \ var/list/desired_items = list(/obj/item/weapon/reagent_containers/food/snacks/cracker/, \
/obj/item/smallDelivery, /obj/item/weapon/gift, \ /obj/item/smallDelivery, /obj/item/weapon/gift, \
/obj/item/weapon/soap, /obj/item/toy/spinningtoy, \ /obj/item/weapon/soap, /obj/item/toy, \
/obj/item/weapon/coin, /obj/item/weapon/stamp,\ /obj/item/weapon/coin, /obj/item/weapon/stamp, \
/obj/item/weapon/grenade) /obj/item/weapon/grenade, /obj/item/device/radio/headset, \
/obj/item/device/flash, /obj/item/device/soulstone, \
/obj/item/device/assembly, /obj/item/weapon/bananapeel, \
/obj/item/weapon/book, /obj/item/weapon/caution, \
/obj/item/weapon/cigpacket, /obj/item/weapon/handcuffs,\
/obj/item/weapon/pen, /obj/item/weapon/pinpointer)
/mob/living/simple_animal/parrot/New() /mob/living/simple_animal/parrot/New()
usr << "\red <B>Sorry parrots are not ready yet!</B>" usr << "\red Parrots are still a work in progress, use at your own risk."
del(src)
/*
..() ..()
parrot_sleep_dur = parrot_sleep_max //In case someone decides to change the max without changing the duration var parrot_sleep_dur = parrot_sleep_max //In case someone decides to change the max without changing the duration var
ears = new /obj/item/device/radio/headset/headset_eng(src)
verbs.Add(/mob/living/simple_animal/parrot/proc/steal_from_ground, \ verbs.Add(/mob/living/simple_animal/parrot/proc/steal_from_ground, \
/mob/living/simple_animal/parrot/proc/steal_from_mob, \ /mob/living/simple_animal/parrot/proc/steal_from_mob, \
/mob/living/simple_animal/parrot/proc/drop_held_item) /mob/living/simple_animal/parrot/proc/drop_held_item)
*/
/mob/living/simple_animal/parrot/Die() /mob/living/simple_animal/parrot/Die()
if(held_item) if(held_item)
held_item.loc = src.loc held_item.loc = src.loc
@@ -161,6 +169,7 @@
usr.drop_item() usr.drop_item()
item_to_add.loc = src item_to_add.loc = src
src.ears = item_to_add src.ears = item_to_add
usr << "You fit the headset onto [src]."
else else
..() ..()
@@ -234,19 +243,30 @@
/mob/living/simple_animal/parrot/Life() /mob/living/simple_animal/parrot/Life()
..() ..()
if(client) if(client || stat)
return //Lets not force players to move return //Lets not force players or dead/incap parrots to move
if(!isturf(src.loc) || !canmove || buckled || pulledby) if(!isturf(src.loc) || !canmove || buckled || pulledby)
return //If it can't move, dont let it move. (The buckled check probably isn't necessary) return //If it can't move, dont let it move. (The buckled check probably isn't necessary)
world << "State: [parrot_state]" //Parrot speech mimickry! Phrases that the parrot hears in mob/living/say() get added to speach_buffer.
//Every once in a while, the parrot picks one of the lines from the buffer and replaces an element of the 'speech' list.
//Then it clears the buffer to make sure they dont magically remember something from hours ago.
if(speech_buffer.len && prob(10))
// world << "New speech being added!"
if(speak.len)
speak.Remove(pick(speak))
speak.Add(pick(speech_buffer))
clearlist(speech_buffer)
// world << "State: [parrot_state]"
//Alright, here we go... down the slope //Alright, here we go... down the slope
//-----SLEEPING //-----SLEEPING
if(parrot_state == PARROT_PERCH) if(parrot_state == PARROT_PERCH)
world << "Perched" // world << "Perched"
if(parrot_perch.loc != src.loc) //Make sure someone hasnt moved our perch on us if(parrot_perch.loc != src.loc) //Make sure someone hasnt moved our perch on us
if(parrot_perch in view(src)) if(parrot_perch in view(src))
parrot_state = PARROT_SWOOP | PARROT_RETURN parrot_state = PARROT_SWOOP | PARROT_RETURN
@@ -256,11 +276,11 @@
return return
if(--parrot_sleep_dur) //Zzz if(--parrot_sleep_dur) //Zzz
world << "Perched: sleeping" // world << "Perched: sleeping"
return return
else else
world << "Perched: looking around" // world << "Perched: looking around"
parrot_sleep_dur = parrot_sleep_max //This way we only call the loop below once every [sleep_max] ticks. parrot_sleep_dur = parrot_sleep_max //This way we only call the loop below once every [sleep_max] ticks.
parrot_interest = search_for_item() parrot_interest = search_for_item()
if(parrot_interest) if(parrot_interest)
@@ -270,7 +290,7 @@
//-----WANDERING - This is basically a 'I dont know what to do yet' state //-----WANDERING - This is basically a 'I dont know what to do yet' state
else if(parrot_state == PARROT_WANDER) else if(parrot_state == PARROT_WANDER)
world << "Wander" // world << "Wander"
//Stop movement, we'll set it later //Stop movement, we'll set it later
walk(src, 0) walk(src, 0)
parrot_interest = null parrot_interest = null
@@ -278,13 +298,13 @@
//Wander around aimlessly. This will help keep the loops from searches down //Wander around aimlessly. This will help keep the loops from searches down
//and possibly move the mob into a new are in view of something they can use //and possibly move the mob into a new are in view of something they can use
if(prob(90)) if(prob(90))
world << "Wander: randomly" // world << "Wander: randomly"
step(src, pick(cardinal)) step(src, pick(cardinal))
return return
if(!held_item && !parrot_perch) //If we've got nothing to do.. look for something to do. if(!held_item && !parrot_perch) //If we've got nothing to do.. look for something to do.
world << "Wander: looking for perch or item" // world << "Wander: looking for perch or item"
world << parrot_interest // world << parrot_interest
var/atom/movable/AM = search_for_perch_and_item() //This handles checking through lists so we know it's either a perch or stealable item var/atom/movable/AM = search_for_perch_and_item() //This handles checking through lists so we know it's either a perch or stealable item
if(AM) if(AM)
if(istype(AM, /obj/item) || isliving(AM)) //If stealable item if(istype(AM, /obj/item) || isliving(AM)) //If stealable item
@@ -300,38 +320,37 @@
return return
return return
if(parrot_interest) if(parrot_interest && parrot_interest in view(src))
if(parrot_interest in view(src)) //Putting this in a seperate if so it doesnt run the 'in view' loop as often parrot_state = PARROT_SWOOP | PARROT_STEAL
parrot_state = PARROT_SWOOP | PARROT_STEAL return
return
if(parrot_perch) if(parrot_perch && parrot_perch in view(src))
world << "Wander: returning to perch" // world << "Wander: returning to perch"
parrot_state = PARROT_SWOOP | PARROT_RETURN parrot_state = PARROT_SWOOP | PARROT_RETURN
return return
else //Have an item but no perch? Find one! else //Have an item but no perch? Find one!
world << "Wander: looking for perch, holding item" // world << "Wander: looking for perch, holding item"
parrot_perch = search_for_perch() parrot_perch = search_for_perch()
if(parrot_perch) if(parrot_perch)
parrot_state = PARROT_SWOOP | PARROT_RETURN parrot_state = PARROT_SWOOP | PARROT_RETURN
return return
//-----STEALING //-----STEALING
else if(parrot_state == (PARROT_SWOOP | PARROT_STEAL)) else if(parrot_state == (PARROT_SWOOP | PARROT_STEAL))
world << "Steal" // world << "Steal"
walk(src,0) walk(src,0)
if(!parrot_interest || held_item) if(!parrot_interest || held_item)
world << "Steal: lost interest or holding an item" // world << "Steal: lost interest or holding an item"
parrot_state = PARROT_SWOOP | PARROT_RETURN parrot_state = PARROT_SWOOP | PARROT_RETURN
return return
if(!(parrot_interest in view(src))) if(!(parrot_interest in view(src)))
world << "Steal: interest not in view" // world << "Steal: interest not in view"
parrot_state = PARROT_SWOOP | PARROT_RETURN parrot_state = PARROT_SWOOP | PARROT_RETURN
return return
if(in_range(src, parrot_interest)) if(in_range(src, parrot_interest))
world << "Steal: stealing item" // world << "Steal: stealing item"
if(isliving(parrot_interest)) if(isliving(parrot_interest))
steal_from_mob() steal_from_mob()
else else
@@ -341,7 +360,7 @@
parrot_state = PARROT_SWOOP | PARROT_RETURN parrot_state = PARROT_SWOOP | PARROT_RETURN
return return
world << "Steal: swooping closer to target" // world << "Steal: swooping closer to target"
var/oldloc = src.loc var/oldloc = src.loc
step_towards(src, get_step_towards(src,parrot_interest)) step_towards(src, get_step_towards(src,parrot_interest))
if(src.loc == oldloc) //Check if the mob is stuck if(src.loc == oldloc) //Check if the mob is stuck
@@ -351,7 +370,7 @@
//-----RETURNING TO PERCH //-----RETURNING TO PERCH
else if(parrot_state == (PARROT_SWOOP | PARROT_RETURN)) else if(parrot_state == (PARROT_SWOOP | PARROT_RETURN))
world << "Return" // world << "Return"
walk(src, 0) walk(src, 0)
if(!parrot_perch || !isturf(parrot_perch.loc)) //Make sure the perch exists and somehow isnt inside of something else. if(!parrot_perch || !isturf(parrot_perch.loc)) //Make sure the perch exists and somehow isnt inside of something else.
world << "Return: no perch?" world << "Return: no perch?"
@@ -360,13 +379,13 @@
return return
if(in_range(src, parrot_perch)) if(in_range(src, parrot_perch))
world << "Return: landing" // world << "Return: landing"
src.loc = parrot_perch.loc src.loc = parrot_perch.loc
drop_held_item() drop_held_item()
parrot_state = PARROT_PERCH parrot_state = PARROT_PERCH
return return
world << "Return: returning to perch" // world << "Return: returning to perch"
var/oldloc = src.loc var/oldloc = src.loc
step_towards(src, get_step_towards(src,parrot_perch)) step_towards(src, get_step_towards(src,parrot_perch))
if(src.loc == oldloc) //Check if the mob is stuck if(src.loc == oldloc) //Check if the mob is stuck
@@ -375,13 +394,13 @@
//-----FLEEING //-----FLEEING
else if(parrot_state == (PARROT_SWOOP | PARROT_FLEE)) else if(parrot_state == (PARROT_SWOOP | PARROT_FLEE))
world << "Flee" // world << "Flee"
walk(src,0) walk(src,0)
if(!parrot_interest || !isliving(parrot_interest)) //Sanity if(!parrot_interest || !isliving(parrot_interest)) //Sanity
world << "Flee: lost interest" world << "Flee: lost interest"
parrot_state = PARROT_WANDER parrot_state = PARROT_WANDER
world << "Flee: fleeing" // world << "Flee: fleeing"
var/oldloc = src.loc var/oldloc = src.loc
step(src, get_step_away(src, parrot_interest)) step(src, get_step_away(src, parrot_interest))
if(src.loc == oldloc) //Check if the mob is stuck if(src.loc == oldloc) //Check if the mob is stuck
@@ -389,11 +408,11 @@
//-----ATTACKING //-----ATTACKING
else if(parrot_state == (PARROT_SWOOP | PARROT_ATTACK)) else if(parrot_state == (PARROT_SWOOP | PARROT_ATTACK))
world << "Attack" // world << "Attack"
//If we're attacking a nothing, an object, a turf or a ghost for some stupid reason, switch to wander //If we're attacking a nothing, an object, a turf or a ghost for some stupid reason, switch to wander
if(!parrot_interest || !isliving(parrot_interest)) if(!parrot_interest || !isliving(parrot_interest))
world << "Attack: lost interest" // world << "Attack: lost interest"
parrot_interest = null parrot_interest = null
parrot_state = PARROT_WANDER parrot_state = PARROT_WANDER
return return
@@ -405,7 +424,7 @@
//If the mob we've been chasing/attacking dies or falls into crit, check for loot! //If the mob we've been chasing/attacking dies or falls into crit, check for loot!
if(L.stat) if(L.stat)
world << "Attack: looting body" // world << "Attack: looting body"
parrot_interest = null parrot_interest = null
if(!held_item) if(!held_item)
held_item = steal_from_ground() held_item = steal_from_ground()
@@ -421,7 +440,7 @@
var/damage = rand(5,10) var/damage = rand(5,10)
if(ishuman(parrot_interest)) if(ishuman(parrot_interest))
world << "Attack: attacking human" // world << "Attack: attacking human"
var/mob/living/carbon/human/H = parrot_interest var/mob/living/carbon/human/H = parrot_interest
var/datum/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone))) var/datum/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
@@ -429,14 +448,14 @@
emote(pick("pecks [H]'s [affecting]", "cuts [H]'s [affecting] with its talons")) emote(pick("pecks [H]'s [affecting]", "cuts [H]'s [affecting] with its talons"))
else else
world << "Attack: attacking non-human" // world << "Attack: attacking non-human"
L.adjustBruteLoss(damage) L.adjustBruteLoss(damage)
emote(pick("pecks at [L]", "claws [L]")) emote(pick("pecks at [L]", "claws [L]"))
return return
//Otherwise, fly towards the mob! //Otherwise, fly towards the mob!
else else
world << "Attack: swooping towards the mob" // world << "Attack: swooping towards the mob"
var/oldloc = src.loc var/oldloc = src.loc
step_towards(src, get_step_towards(src,parrot_interest)) step_towards(src, get_step_towards(src,parrot_interest))
if(src.loc == oldloc) //Check if the mob is stuck if(src.loc == oldloc) //Check if the mob is stuck
@@ -444,7 +463,7 @@
//-----STATE MISHAP //-----STATE MISHAP
else //This should not happen. If it does lets reset everything and try again else //This should not happen. If it does lets reset everything and try again
world << "Unknown state: resetting to wander" // world << "Unknown state: resetting to wander"
walk(src,0) walk(src,0)
parrot_interest = null parrot_interest = null
parrot_perch = null parrot_perch = null
@@ -588,3 +607,7 @@
name = "Poly" name = "Poly"
desc = "Poly the Parrot. An expert on quantum cracker theory." desc = "Poly the Parrot. An expert on quantum cracker theory."
speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE") speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE")
/mob/living/simple_animal/parrot/Poly/New()
ears = new /obj/item/device/radio/headset/headset_eng(src)
..()

View File

@@ -27,7 +27,9 @@
usr.show_message(t, 1) usr.show_message(t, 1)
/mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2) /mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
if(!client) return if(!client) return
if (type) if (type)
if(type & 1 && (sdisabilities & BLIND || blinded || paralysis) )//Vision related if(type & 1 && (sdisabilities & BLIND || blinded || paralysis) )//Vision related
if (!( alt )) if (!( alt ))