mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-21 04:48:18 +01:00
Essential Pet Interactions (#7633)
tweak: "Pets have more discipline regarding food. They will no longer beg for food, seek it out, run towards it, steal it, or eat like there's an endless void in their stomachs. They'll still eat food on their tile if sufficiently hungry, and you can still feed pets by hand, if you'd like. Chefs, rejoice!"
tweak: "Corgi stomach capacity adjusted to a way more sane level."
rscdel: "Removed guilty messages about pets starving when you examine them; they won't go hungry in a single shift, don't worry."
rscadd: "You can brush most friendly animals. Combs work for fuzzy and feathered animals, rags work on other ones."
tweak: "There's a small chance that when you pet a guard dog (like Columbo) on help intent (and aren't his master), he won't immediately maul your face off; instead, he will growl at you to warn you not to do that. I still don't recommend it."
tweak: "Like other pets, baby carp can eat now. But not a lot."
This commit is contained in:
@@ -43,7 +43,8 @@
|
||||
friendly = "pinches"
|
||||
attacktext = "pinched"
|
||||
resistance = 9
|
||||
|
||||
canbrush = TRUE
|
||||
brush = /obj/item/reagent_containers/glass/rag
|
||||
|
||||
/mob/living/simple_animal/familiar/pike
|
||||
name = "space pike"
|
||||
@@ -64,7 +65,8 @@
|
||||
maxHealth = 100
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
|
||||
canbrush = TRUE
|
||||
brush = /obj/item/reagent_containers/glass/rag
|
||||
meat_type = /obj/item/reagent_containers/food/snacks/carpmeat
|
||||
|
||||
min_oxy = 0
|
||||
@@ -134,6 +136,7 @@
|
||||
mob_size = 4.5 //weight based on Chanthangi goats
|
||||
density = 0
|
||||
wizardy_spells = list(/spell/aoe_turf/smoke)
|
||||
canbrush = TRUE
|
||||
|
||||
meat_type = /obj/item/reagent_containers/food/snacks/meat
|
||||
meat_amount = 6
|
||||
@@ -178,6 +181,7 @@
|
||||
density = 0
|
||||
|
||||
wizardy_spells = list(/spell/targeted/subjugation)
|
||||
canbrush = TRUE
|
||||
|
||||
meat_type = /obj/item/reagent_containers/food/snacks/meat
|
||||
butchering_products = list(/obj/item/stack/material/animalhide/cat = 2)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
meat_type = /obj/item/reagent_containers/food/snacks/meat/adhomai
|
||||
meat_amount = 2
|
||||
hunger_enabled = FALSE
|
||||
canbrush = TRUE
|
||||
var/eggsleft = 0
|
||||
|
||||
/mob/living/simple_animal/ice_tunneler/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
@@ -62,11 +63,9 @@
|
||||
attacktext = "kicked"
|
||||
health = 200
|
||||
maxHealth = 200
|
||||
|
||||
autoseek_food = 0
|
||||
beg_for_food = 0
|
||||
mob_size = 15
|
||||
|
||||
canbrush = TRUE
|
||||
has_udder = TRUE
|
||||
milk_type = "fatshouter_milk"
|
||||
|
||||
|
||||
@@ -34,10 +34,16 @@
|
||||
minbodytemp = 0
|
||||
|
||||
mob_size = 4
|
||||
metabolic_factor = 0 // NEVER EAT HA HA HA - geeves
|
||||
max_nutrition = 40
|
||||
metabolic_factor = 0.2
|
||||
bite_factor = 0.6 //Carp got big bites
|
||||
|
||||
stomach_size_mult = 3 //They're just baby
|
||||
|
||||
density = TRUE
|
||||
pass_flags = PASSTABLE
|
||||
canbrush = TRUE
|
||||
brush = /obj/item/reagent_containers/glass/rag
|
||||
|
||||
possession_candidate = TRUE
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
var/mob/living/simple_animal/rat/rattarget = null
|
||||
seek_speed = 5
|
||||
pass_flags = PASSTABLE
|
||||
canbrush = TRUE
|
||||
possession_candidate = 1
|
||||
emote_sounds = list('sound/effects/creatures/cat_meow.ogg', 'sound/effects/creatures/cat_meow2.ogg')
|
||||
butchering_products = list(/obj/item/stack/material/animalhide/cat = 2)
|
||||
@@ -45,7 +46,6 @@
|
||||
if(snack.stat != DEAD && prob(65))//The probability allows her to not get stuck target the first rat, reducing exploits
|
||||
rattarget = snack
|
||||
movement_target = snack
|
||||
foodtarget = 0 //chasing mice takes precedence over eating food
|
||||
if(prob(15))
|
||||
audible_emote(pick("hisses and spits!","mrowls fiercely!","eyes [snack] hungrily."))
|
||||
|
||||
@@ -104,9 +104,6 @@
|
||||
if (prob(75))
|
||||
break//usually only kill one rat per proc
|
||||
|
||||
/mob/living/simple_animal/cat/beg(var/atom/thing, var/atom/holder)
|
||||
visible_emote("licks [get_pronoun(POSESSIVE_ADJECTIVE)] lips and hungrily glares at [holder]'s [thing.name]",0)
|
||||
|
||||
/mob/living/simple_animal/cat/Released()
|
||||
//A thrown cat will immediately attack mice near where it lands
|
||||
handle_movement_target()
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
response_harm = "kicks"
|
||||
see_in_dark = 5
|
||||
mob_size = 3.5
|
||||
max_nutrition = 80 //Dogs are insatiable eating monsters. This scales with their mob size too
|
||||
stomach_size_mult = 30
|
||||
max_nutrition = 70 //Dogs are insatiable eating monsters. This scales with their mob size too
|
||||
stomach_size_mult = 8
|
||||
seek_speed = 6
|
||||
possession_candidate = 1
|
||||
|
||||
canbrush = TRUE
|
||||
holder_type = /obj/item/holder/corgi
|
||||
|
||||
butchering_products = list(/obj/item/stack/material/animalhide/corgi = 3)
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
/mob/living/simple_animal/corgi/Initialize()
|
||||
. = ..()
|
||||
nutrition = max_nutrition * 0.3 //Ian doesn't start with a full belly so will be hungry at roundstart
|
||||
nutrition = max_nutrition * 0.8 //They can start a little hungry, but let's no go crazy
|
||||
|
||||
//IAN! SQUEEEEEEEEE~
|
||||
/mob/living/simple_animal/corgi/Ian
|
||||
@@ -61,9 +61,6 @@
|
||||
set_dir(i)
|
||||
sleep(1)
|
||||
|
||||
/mob/living/simple_animal/corgi/beg(var/atom/thing, var/atom/holder)
|
||||
visible_emote("stares at the [thing] that [holder] has with sad puppy eyes.",0)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/corgi
|
||||
name = "Corgi meat"
|
||||
desc = "Tastes like... well you know..."
|
||||
@@ -77,7 +74,6 @@
|
||||
)
|
||||
scan_interval = max_scan_interval
|
||||
movement_target = null
|
||||
foodtarget = 0
|
||||
stop_automated_movement = 0
|
||||
turns_since_scan = 0
|
||||
|
||||
|
||||
@@ -25,14 +25,12 @@
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 5
|
||||
udder = null
|
||||
canbrush = TRUE
|
||||
emote_sounds = list('sound/effects/creatures/goat.ogg')
|
||||
has_udder = TRUE
|
||||
|
||||
butchering_products = list(/obj/item/stack/material/animalhide = 3)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/beg(var/atom/thing, var/atom/holder)
|
||||
visible_emote("butts insistently at [holder]'s legs and reaches towards their [thing].",0)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goat/Life()
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -82,7 +80,7 @@
|
||||
icon_dead = "cow_dead"
|
||||
icon_gib = "cow_gib"
|
||||
speak = list("moo?","moo","MOOOOOO")
|
||||
speak_emote = list("moos","moos hauntingly")
|
||||
speak_emote = list("moos")
|
||||
emote_hear = list("brays")
|
||||
emote_see = list("shakes its head")
|
||||
speak_chance = 1
|
||||
@@ -95,10 +93,9 @@
|
||||
response_harm = "kicks"
|
||||
attacktext = "kicked"
|
||||
health = 250
|
||||
autoseek_food = 0
|
||||
beg_for_food = 0
|
||||
mob_size = 20//based on mass of holstein fresian dairy cattle, what the sprite is based on
|
||||
emote_sounds = list('sound/effects/creatures/cow.ogg')
|
||||
canbrush = TRUE
|
||||
has_udder = TRUE
|
||||
butchering_products = list(/obj/item/stack/material/animalhide = 8)
|
||||
|
||||
@@ -142,10 +139,9 @@
|
||||
var/amount_grown = 0
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
holder_type = /obj/item/holder/chick
|
||||
autoseek_food = 0
|
||||
beg_for_food = 0
|
||||
density = 0
|
||||
mob_size = 0.75//just a rough estimate, the real value should be way lower
|
||||
canbrush = TRUE
|
||||
hunger_enabled = FALSE
|
||||
emote_sounds = list('sound/effects/creatures/chick.ogg')
|
||||
|
||||
@@ -195,6 +191,7 @@
|
||||
density = 0
|
||||
mob_size = 2
|
||||
hunger_enabled = FALSE
|
||||
canbrush = TRUE
|
||||
|
||||
var/static/chicken_count = 0
|
||||
emote_sounds = list('sound/effects/creatures/chicken.ogg', 'sound/effects/creatures/chicken_bwak.ogg')
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
mob_size = 4
|
||||
max_nutrition = 90
|
||||
max_nutrition = 80
|
||||
holder_type = /obj/item/holder/fox
|
||||
emote_sounds = list()
|
||||
butchering_products = list(/obj/item/stack/material/animalhide = 3)
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
attacktext = "kicked"
|
||||
health = 250
|
||||
maxHealth = 250
|
||||
canbrush = TRUE
|
||||
brush = /obj/item/reagent_containers/glass/rag
|
||||
|
||||
autoseek_food = FALSE
|
||||
beg_for_food = FALSE
|
||||
mob_size = 15
|
||||
|
||||
has_udder = TRUE
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
holder_type = /obj/item/holder/lizard
|
||||
density = 0
|
||||
seek_speed = 0.75
|
||||
canbrush = TRUE
|
||||
brush = /obj/item/reagent_containers/glass/rag
|
||||
|
||||
butchering_products = list(/obj/item/stack/material/animalhide/lizard = 2)
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
density = 0
|
||||
holder_type = /obj/item/holder/mushroom
|
||||
mob_size = 2
|
||||
canbrush = TRUE
|
||||
brush = /obj/item/reagent_containers/glass/rag
|
||||
|
||||
/mob/living/simple_animal/mushroom/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
max_scan_interval = 20
|
||||
seek_speed = 1
|
||||
max_nutrition = 17
|
||||
|
||||
canbrush = TRUE
|
||||
can_pull_size = 1
|
||||
can_pull_mobs = MOB_PULL_NONE
|
||||
|
||||
@@ -135,9 +135,6 @@
|
||||
/mob/living/simple_animal/rat/speak_audio()
|
||||
squeak_soft(0)
|
||||
|
||||
/mob/living/simple_animal/rat/beg(var/atom/thing, var/atom/holder)
|
||||
squeak_soft(0)
|
||||
visible_emote("squeaks timidly, sniffs the air and gazes longingly up at \the [thing.name].",0)
|
||||
|
||||
/mob/living/simple_animal/rat/attack_hand(mob/living/carbon/human/M as mob)
|
||||
if (src.stat == DEAD)//If the mouse is dead, we don't pet it, we just pickup the corpse on click
|
||||
|
||||
@@ -173,6 +173,8 @@
|
||||
pass_flags = PASSTABLE
|
||||
density = 0
|
||||
mob_size = 2
|
||||
canbrush = TRUE
|
||||
brush = /obj/item/reagent_containers/glass/rag
|
||||
|
||||
/mob/living/simple_animal/tindalos
|
||||
name = "tindalos"
|
||||
@@ -184,3 +186,5 @@
|
||||
pass_flags = PASSTABLE
|
||||
density = 0
|
||||
mob_size = 1.5
|
||||
canbrush = TRUE
|
||||
brush = /obj/item/reagent_containers/glass/rag
|
||||
@@ -209,7 +209,13 @@
|
||||
target_mob = null
|
||||
if(M.a_intent == I_HURT)
|
||||
audible_emote("[pick(sad_emote)].",0)
|
||||
return
|
||||
return
|
||||
if(M.a_intent == I_HELP && prob(40)) //chance that they won't immediately kill anyone who pets them. But only a chance.
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
target_mob = null
|
||||
audible_emote("growls at [M].")
|
||||
to_chat(M, span("warning", "Maybe you should keep your hands to yourself..."))
|
||||
return
|
||||
|
||||
if(M.a_intent == I_HURT && retribution) //assume he wants to hurt us.
|
||||
|
||||
@@ -244,7 +250,8 @@
|
||||
if(user == master)
|
||||
target_mob = null
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
audible_emote("[pick(sad_emote)].",0)
|
||||
if(!istype(O, brush)) //we don't get sad if we're brushed!
|
||||
audible_emote("[pick(sad_emote)].",0)
|
||||
|
||||
/mob/living/simple_animal/hostile/commanded/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve
|
||||
..()
|
||||
|
||||
@@ -37,9 +37,8 @@
|
||||
response_disarm = "pushes"
|
||||
|
||||
hunger_enabled = 1 //so you can feed your dog or something
|
||||
autoseek_food = 0
|
||||
beg_for_food = 0
|
||||
max_nutrition = 120
|
||||
canbrush = TRUE
|
||||
|
||||
known_commands = list("stay", "stop", "attack", "follow")
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
response_harm = "swats"
|
||||
stop_automated_movement = 1
|
||||
universal_speak = 1
|
||||
canbrush = TRUE
|
||||
|
||||
flying = TRUE
|
||||
|
||||
|
||||
@@ -80,24 +80,22 @@
|
||||
var/digest_factor = 0.2 //A multiplier on how quickly reagents are digested
|
||||
var/stomach_size_mult = 5
|
||||
|
||||
//Food behaviour vars
|
||||
var/autoseek_food = 1//If 0. this animal will not automatically eat
|
||||
var/beg_for_food = 1//If 0, this animal will not show interest in food held by a person
|
||||
var/min_scan_interval = 1//Minimum and maximum number of procs between a foodscan. Animals will slow down if there's no food around for a while
|
||||
//Seeking/Moving behaviour vars
|
||||
var/min_scan_interval = 1//Minimum and maximum number of procs between a scan
|
||||
var/max_scan_interval = 15
|
||||
var/scan_interval = 5//current scan interval, clamped between min and max
|
||||
//It gradually increases up to max when its left alone, to save performance
|
||||
//It will drop back to 1 if it spies any food.
|
||||
//This short time makes animals more responsive to interactions and more fun to play with
|
||||
|
||||
var/seek_speed = 2//How many tiles per second the animal will move towards food
|
||||
var/seek_speed = 2//How many tiles per second the animal will move towards something
|
||||
var/seek_move_delay
|
||||
var/scan_range = 6//How far around the animal will look for food
|
||||
var/foodtarget = 0
|
||||
//Used to control how often ian scans for nearby food
|
||||
var/scan_range = 6//How far around the animal will look for something
|
||||
|
||||
var/kitchen_tag = "animal" //Used for cooking with animals
|
||||
|
||||
//brushing
|
||||
var/canbrush = FALSE //can we brush this beautiful creature?
|
||||
var/brush = /obj/item/haircomb //What can we brush it with? Use a rag for things with scales/carapaces/etc
|
||||
|
||||
//Napping
|
||||
var/can_nap = 0
|
||||
var/icon_rest = null
|
||||
@@ -112,20 +110,6 @@
|
||||
|
||||
var/list/butchering_products //if anything else is created when butchering this creature, like bones and leather
|
||||
|
||||
/mob/living/simple_animal/proc/beg(var/atom/thing, var/atom/holder)
|
||||
visible_emote("gazes longingly at [holder]'s [thing]",0)
|
||||
|
||||
/mob/living/simple_animal/proc/steal_food(var/obj/item/reagent_containers/food/snacks/F, var/mob/living/carbon/human/H)
|
||||
if(!F || !H)
|
||||
return
|
||||
H.visible_message(
|
||||
span("warning", "\the [src] grabs \the [F] with its teeth and steals it from \the [H] hands. Taking a bite and dropping it on the floor."),
|
||||
span("warning", "\the [src] grabs \the [F] with its teeth and steals it from your hands. Taking a bite and dropping it on the floor.")
|
||||
)
|
||||
H.drop_from_inventory(F)
|
||||
UnarmedAttack(F)
|
||||
if (get_turf(F) == loc)
|
||||
set_dir(pick(NORTH, SOUTH, EAST, WEST, NORTH, NORTH))//Face a random direction when eating, but mostly upwards
|
||||
|
||||
/mob/living/simple_animal/proc/update_nutrition_stats()
|
||||
nutrition_step = mob_size * 0.03 * metabolic_factor
|
||||
@@ -173,13 +157,6 @@
|
||||
/mob/living/simple_animal/examine(mob/user)
|
||||
..()
|
||||
|
||||
if (hunger_enabled)
|
||||
if (!nutrition)
|
||||
to_chat(user, "<span class='danger'>It looks starving!</span>")
|
||||
else if (nutrition < max_nutrition *0.5)
|
||||
to_chat(user, "<span class='notice'>It looks hungry.</span>")
|
||||
else if ((reagents.total_volume > 0 && nutrition > max_nutrition *0.75) || nutrition > max_nutrition *0.9)
|
||||
to_chat(user, "It looks full and contented.")
|
||||
if (stat == DEAD)
|
||||
to_chat(user, "<span class='danger'>It looks dead.</span>")
|
||||
if (health < maxHealth * 0.5)
|
||||
@@ -204,7 +181,6 @@
|
||||
handle_paralysed()
|
||||
update_canmove()
|
||||
handle_supernatural()
|
||||
autoseek_food = nutrition / max_nutrition <= 0.05 ? TRUE : initial(autoseek_food)
|
||||
process_food()
|
||||
|
||||
//Movement
|
||||
@@ -261,7 +237,6 @@
|
||||
|
||||
/mob/living/simple_animal/think()
|
||||
..()
|
||||
handle_foodscanning()
|
||||
if(!stop_automated_movement && wander && !anchored)
|
||||
if(isturf(loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
|
||||
if(turns_since_move >= turns_per_move && !(stop_automated_movement_when_pulled && pulledby)) //Some animals don't move when pulled
|
||||
@@ -313,6 +288,13 @@
|
||||
if (!stat || prob(0.5))
|
||||
wake_up()
|
||||
|
||||
//Eating in tile
|
||||
for(var/obj/item/reagent_containers/food/snacks/S in src.loc)
|
||||
if(can_eat() && (nutrition < max_nutrition * 0.3)) //Only when sufficiently hungry
|
||||
UnarmedAttack(S)
|
||||
else
|
||||
break
|
||||
|
||||
/mob/living/simple_animal/proc/handle_supernatural()
|
||||
if(purge)
|
||||
purge -= 1
|
||||
@@ -428,7 +410,10 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user)
|
||||
/mob/living/simple_animal/attackby(obj/item/O, mob/user)
|
||||
if(istype(O, /obj/item/reagent_containers/glass/rag)) //You can't milk an udder with a rag.
|
||||
attacked_with_item(O, user)
|
||||
return
|
||||
if(has_udder)
|
||||
var/obj/item/reagent_containers/glass/G = O
|
||||
if(stat == CONSCIOUS && istype(G) && G.is_open_container())
|
||||
@@ -453,11 +438,16 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
attacked_with_item(O, user)
|
||||
|
||||
//TODO: refactor mob attackby(), attacked_by(), and friends.
|
||||
/mob/living/simple_animal/proc/attacked_with_item(var/obj/item/O, var/mob/user)
|
||||
/mob/living/simple_animal/proc/attacked_with_item(obj/item/O, mob/user)
|
||||
if(istype(O, /obj/item/trap/animal))
|
||||
O.attack(src, user)
|
||||
return
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
if(istype(O, brush) && canbrush) //Brushing animals
|
||||
visible_message(span("notice", "[user] gently brushes [src] with \the [O]."))
|
||||
if(prob(15) && !istype(src, /mob/living/simple_animal/hostile)) //Aggressive animals don't purr before biting your face off.
|
||||
visible_message(span("notice", "[src] [speak_emote.len ? pick(speak_emote) : "rumbles"] happily.")) //purring
|
||||
return
|
||||
if(!O.force)
|
||||
visible_message("<span class='notice'>[user] gently taps [src] with \the [O].</span>")
|
||||
poke()
|
||||
@@ -613,7 +603,7 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
user.visible_message("<span class='danger'>[user] butchers \the [src] messily!</span>")
|
||||
gib()
|
||||
|
||||
|
||||
/*
|
||||
//Code to handle finding and nomming nearby food items
|
||||
/mob/living/simple_animal/proc/handle_foodscanning()
|
||||
if (client || !hunger_enabled || !autoseek_food)
|
||||
@@ -679,7 +669,7 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
beg(movement_target, movement_target.loc)
|
||||
else
|
||||
scan_interval = max(min_scan_interval, min(scan_interval+1, max_scan_interval))//If nothing is happening, ian's scanning frequency slows down to save processing
|
||||
|
||||
*/
|
||||
|
||||
//For picking up small animals
|
||||
/mob/living/simple_animal/MouseDrop(atom/over_object)
|
||||
@@ -710,7 +700,6 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
wander = 0
|
||||
walk_to(src,0)
|
||||
movement_target = null
|
||||
foodtarget = 0
|
||||
update_icons()
|
||||
|
||||
//Wakes the mob up from sleeping
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
|
||||
var/m_bitesize = bitesize * SA.bite_factor//Modified bitesize based on creature size
|
||||
var/amount_eaten = m_bitesize
|
||||
SA.scan_interval = SA.min_scan_interval//Feeding an animal will make it suddenly care about food
|
||||
m_bitesize = min(m_bitesize, reagents.total_volume)
|
||||
|
||||
if (!SA.can_eat() || ((user.reagents.maximum_volume - user.reagents.total_volume) < m_bitesize * 0.5))
|
||||
|
||||
Reference in New Issue
Block a user