mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
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:
@@ -8,6 +8,10 @@
|
||||
* 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
|
||||
*/
|
||||
@@ -34,12 +38,12 @@
|
||||
icon_dead = "chick_dead"
|
||||
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")
|
||||
emote_hear = list("squawks","bawks")
|
||||
emote_see = list("flutters its wings")
|
||||
|
||||
speak_chance = 1
|
||||
speak_chance = 8//4% (1 in 25) chance every tick
|
||||
turns_per_move = 5
|
||||
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_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_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 :)
|
||||
var/obj/item/device/radio/headset/ears = null
|
||||
@@ -73,26 +79,28 @@
|
||||
/obj/machinery/suit_storage_unit, /obj/machinery/telecomms, \
|
||||
/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/list/desired_items = list(/obj/item/weapon/reagent_containers/food/snacks/cracker/, \
|
||||
/obj/item/smallDelivery, /obj/item/weapon/gift, \
|
||||
/obj/item/weapon/soap, /obj/item/toy/spinningtoy, \
|
||||
/obj/item/weapon/coin, /obj/item/weapon/stamp,\
|
||||
/obj/item/weapon/grenade)
|
||||
/obj/item/weapon/soap, /obj/item/toy, \
|
||||
/obj/item/weapon/coin, /obj/item/weapon/stamp, \
|
||||
/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()
|
||||
usr << "\red <B>Sorry parrots are not ready yet!</B>"
|
||||
del(src)
|
||||
/*
|
||||
usr << "\red Parrots are still a work in progress, use at your own risk."
|
||||
..()
|
||||
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, \
|
||||
/mob/living/simple_animal/parrot/proc/steal_from_mob, \
|
||||
/mob/living/simple_animal/parrot/proc/drop_held_item)
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/parrot/Die()
|
||||
if(held_item)
|
||||
held_item.loc = src.loc
|
||||
@@ -161,6 +169,7 @@
|
||||
usr.drop_item()
|
||||
item_to_add.loc = src
|
||||
src.ears = item_to_add
|
||||
usr << "You fit the headset onto [src]."
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -234,19 +243,30 @@
|
||||
/mob/living/simple_animal/parrot/Life()
|
||||
..()
|
||||
|
||||
if(client)
|
||||
return //Lets not force players to move
|
||||
if(client || stat)
|
||||
return //Lets not force players or dead/incap parrots to move
|
||||
|
||||
if(!isturf(src.loc) || !canmove || buckled || pulledby)
|
||||
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
|
||||
|
||||
//-----SLEEPING
|
||||
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 in view(src))
|
||||
parrot_state = PARROT_SWOOP | PARROT_RETURN
|
||||
@@ -256,11 +276,11 @@
|
||||
return
|
||||
|
||||
if(--parrot_sleep_dur) //Zzz
|
||||
world << "Perched: sleeping"
|
||||
// world << "Perched: sleeping"
|
||||
return
|
||||
|
||||
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_interest = search_for_item()
|
||||
if(parrot_interest)
|
||||
@@ -270,7 +290,7 @@
|
||||
|
||||
//-----WANDERING - This is basically a 'I dont know what to do yet' state
|
||||
else if(parrot_state == PARROT_WANDER)
|
||||
world << "Wander"
|
||||
// world << "Wander"
|
||||
//Stop movement, we'll set it later
|
||||
walk(src, 0)
|
||||
parrot_interest = null
|
||||
@@ -278,13 +298,13 @@
|
||||
//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
|
||||
if(prob(90))
|
||||
world << "Wander: randomly"
|
||||
// world << "Wander: randomly"
|
||||
step(src, pick(cardinal))
|
||||
return
|
||||
|
||||
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 << parrot_interest
|
||||
// world << "Wander: looking for perch or item"
|
||||
// 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
|
||||
if(AM)
|
||||
if(istype(AM, /obj/item) || isliving(AM)) //If stealable item
|
||||
@@ -300,38 +320,37 @@
|
||||
return
|
||||
return
|
||||
|
||||
if(parrot_interest)
|
||||
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
|
||||
return
|
||||
if(parrot_interest && parrot_interest in view(src))
|
||||
parrot_state = PARROT_SWOOP | PARROT_STEAL
|
||||
return
|
||||
|
||||
if(parrot_perch)
|
||||
world << "Wander: returning to perch"
|
||||
if(parrot_perch && parrot_perch in view(src))
|
||||
// world << "Wander: returning to perch"
|
||||
parrot_state = PARROT_SWOOP | PARROT_RETURN
|
||||
return
|
||||
|
||||
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()
|
||||
if(parrot_perch)
|
||||
parrot_state = PARROT_SWOOP | PARROT_RETURN
|
||||
return
|
||||
//-----STEALING
|
||||
else if(parrot_state == (PARROT_SWOOP | PARROT_STEAL))
|
||||
world << "Steal"
|
||||
// world << "Steal"
|
||||
walk(src,0)
|
||||
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
|
||||
return
|
||||
|
||||
if(!(parrot_interest in view(src)))
|
||||
world << "Steal: interest not in view"
|
||||
// world << "Steal: interest not in view"
|
||||
parrot_state = PARROT_SWOOP | PARROT_RETURN
|
||||
return
|
||||
|
||||
if(in_range(src, parrot_interest))
|
||||
world << "Steal: stealing item"
|
||||
// world << "Steal: stealing item"
|
||||
if(isliving(parrot_interest))
|
||||
steal_from_mob()
|
||||
else
|
||||
@@ -341,7 +360,7 @@
|
||||
parrot_state = PARROT_SWOOP | PARROT_RETURN
|
||||
return
|
||||
|
||||
world << "Steal: swooping closer to target"
|
||||
// world << "Steal: swooping closer to target"
|
||||
var/oldloc = src.loc
|
||||
step_towards(src, get_step_towards(src,parrot_interest))
|
||||
if(src.loc == oldloc) //Check if the mob is stuck
|
||||
@@ -351,7 +370,7 @@
|
||||
|
||||
//-----RETURNING TO PERCH
|
||||
else if(parrot_state == (PARROT_SWOOP | PARROT_RETURN))
|
||||
world << "Return"
|
||||
// world << "Return"
|
||||
walk(src, 0)
|
||||
if(!parrot_perch || !isturf(parrot_perch.loc)) //Make sure the perch exists and somehow isnt inside of something else.
|
||||
world << "Return: no perch?"
|
||||
@@ -360,13 +379,13 @@
|
||||
return
|
||||
|
||||
if(in_range(src, parrot_perch))
|
||||
world << "Return: landing"
|
||||
// world << "Return: landing"
|
||||
src.loc = parrot_perch.loc
|
||||
drop_held_item()
|
||||
parrot_state = PARROT_PERCH
|
||||
return
|
||||
|
||||
world << "Return: returning to perch"
|
||||
// world << "Return: returning to perch"
|
||||
var/oldloc = src.loc
|
||||
step_towards(src, get_step_towards(src,parrot_perch))
|
||||
if(src.loc == oldloc) //Check if the mob is stuck
|
||||
@@ -375,13 +394,13 @@
|
||||
|
||||
//-----FLEEING
|
||||
else if(parrot_state == (PARROT_SWOOP | PARROT_FLEE))
|
||||
world << "Flee"
|
||||
// world << "Flee"
|
||||
walk(src,0)
|
||||
if(!parrot_interest || !isliving(parrot_interest)) //Sanity
|
||||
world << "Flee: lost interest"
|
||||
parrot_state = PARROT_WANDER
|
||||
|
||||
world << "Flee: fleeing"
|
||||
// world << "Flee: fleeing"
|
||||
var/oldloc = src.loc
|
||||
step(src, get_step_away(src, parrot_interest))
|
||||
if(src.loc == oldloc) //Check if the mob is stuck
|
||||
@@ -389,11 +408,11 @@
|
||||
|
||||
//-----ATTACKING
|
||||
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(!parrot_interest || !isliving(parrot_interest))
|
||||
world << "Attack: lost interest"
|
||||
// world << "Attack: lost interest"
|
||||
parrot_interest = null
|
||||
parrot_state = PARROT_WANDER
|
||||
return
|
||||
@@ -405,7 +424,7 @@
|
||||
|
||||
//If the mob we've been chasing/attacking dies or falls into crit, check for loot!
|
||||
if(L.stat)
|
||||
world << "Attack: looting body"
|
||||
// world << "Attack: looting body"
|
||||
parrot_interest = null
|
||||
if(!held_item)
|
||||
held_item = steal_from_ground()
|
||||
@@ -421,7 +440,7 @@
|
||||
var/damage = rand(5,10)
|
||||
|
||||
if(ishuman(parrot_interest))
|
||||
world << "Attack: attacking human"
|
||||
// world << "Attack: attacking human"
|
||||
var/mob/living/carbon/human/H = parrot_interest
|
||||
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"))
|
||||
|
||||
else
|
||||
world << "Attack: attacking non-human"
|
||||
// world << "Attack: attacking non-human"
|
||||
L.adjustBruteLoss(damage)
|
||||
emote(pick("pecks at [L]", "claws [L]"))
|
||||
return
|
||||
|
||||
//Otherwise, fly towards the mob!
|
||||
else
|
||||
world << "Attack: swooping towards the mob"
|
||||
// world << "Attack: swooping towards the mob"
|
||||
var/oldloc = src.loc
|
||||
step_towards(src, get_step_towards(src,parrot_interest))
|
||||
if(src.loc == oldloc) //Check if the mob is stuck
|
||||
@@ -444,7 +463,7 @@
|
||||
|
||||
//-----STATE MISHAP
|
||||
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)
|
||||
parrot_interest = null
|
||||
parrot_perch = null
|
||||
@@ -588,3 +607,7 @@
|
||||
name = "Poly"
|
||||
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")
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/New()
|
||||
ears = new /obj/item/device/radio/headset/headset_eng(src)
|
||||
..()
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
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)
|
||||
|
||||
if(!client) return
|
||||
|
||||
if (type)
|
||||
if(type & 1 && (sdisabilities & BLIND || blinded || paralysis) )//Vision related
|
||||
if (!( alt ))
|
||||
|
||||
Reference in New Issue
Block a user