mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-21 20:11:04 +01:00
Animal Feeding and Hunger (#634)
changes: rscadd: "Added hunger and feeding system for simple animals, this includes cats, dogs, mice, lizards, chickens, cows, etc" rscadd: "Animals can now actually consume food instead of nibbling them eternally." rscadd: "Animals can now be hand-fed by using food on them." rscadd: "Animals will move more slowly when starving. Examining an animal will show if its hungry." Basically added a very simple metabolising system for animals, and fixed up various eating/feeding functions. They only metabolise food, any other reagents are just removed and ignored for now, since most chemicals were designed for carbon mobs and often aren't valid
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
universal_understand = 1
|
||||
mob_size = 1
|
||||
holder_type = /obj/item/weapon/holder/mouse
|
||||
digest_factor = 0.05
|
||||
|
||||
/mob/living/simple_animal/mouse/Life()
|
||||
..()
|
||||
@@ -75,6 +76,8 @@
|
||||
holder_type = /obj/item/weapon/holder/mouse/white
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/mouse/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
|
||||
get_scooped(M)
|
||||
|
||||
@@ -66,9 +66,29 @@
|
||||
var/supernatural = 0
|
||||
var/purge = 0
|
||||
|
||||
var/max_nutrition = 75
|
||||
var/nutrition_step = 0.2 //nutrition lost per tick and per step, calculated from mob_size, 0.4 is a fallback
|
||||
var/bite_factor = 0.4
|
||||
var/digest_factor = 0.2 //A multiplier on how quickly reagents are digested
|
||||
|
||||
/mob/living/simple_animal/New()
|
||||
..()
|
||||
verbs -= /mob/verb/observe
|
||||
if (mob_size)
|
||||
nutrition_step = mob_size * 0.05
|
||||
bite_factor = mob_size * 0.3
|
||||
max_nutrition *= 1 + (nutrition_step*3)//Max nutrition scales faster than costs, so bigger creatures eat less often
|
||||
reagents = new/datum/reagents(5*mob_size, src)
|
||||
else
|
||||
reagents = new/datum/reagents(20, src)
|
||||
nutrition = max_nutrition
|
||||
|
||||
/mob/living/simple_animal/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.nutrition && src.stat != DEAD)
|
||||
src.nutrition -= nutrition_step
|
||||
|
||||
|
||||
/mob/living/simple_animal/Login()
|
||||
if(src && src.client)
|
||||
@@ -78,6 +98,15 @@
|
||||
/mob/living/simple_animal/updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/examine(mob/user)
|
||||
..()
|
||||
if (!nutrition)
|
||||
user << "<span class='danger'>It looks starving!</span>"
|
||||
else if (nutrition < max_nutrition *0.5)
|
||||
user << "<span class='notice'>It looks hungry.</span>"
|
||||
else if ((reagents.total_volume > 0 && nutrition > max_nutrition *0.75) || nutrition > max_nutrition *0.9)
|
||||
user << "It looks full and contented."
|
||||
|
||||
/mob/living/simple_animal/Life()
|
||||
..()
|
||||
|
||||
@@ -104,7 +133,7 @@
|
||||
handle_paralysed()
|
||||
update_canmove()
|
||||
handle_supernatural()
|
||||
|
||||
process_food()
|
||||
//Movement
|
||||
if(!client && !stop_automated_movement && wander && !anchored)
|
||||
if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
|
||||
@@ -210,6 +239,40 @@
|
||||
if(purge)
|
||||
purge -= 1
|
||||
|
||||
|
||||
|
||||
//Simple reagent processing for simple animals
|
||||
//This allows animals to digest food, and only food
|
||||
//Most drugs, poisons etc, are designed to work on carbons and affect many values a simple animal doesnt have
|
||||
/mob/living/simple_animal/proc/process_food()
|
||||
|
||||
if (nutrition)
|
||||
nutrition -= nutrition_step//Bigger animals get hungry faster
|
||||
nutrition = max(0,min(nutrition, max_nutrition))//clamp the value
|
||||
else
|
||||
if (prob(3))
|
||||
src << "You feel hungry..."
|
||||
|
||||
|
||||
if (!reagents || !reagents.total_volume)
|
||||
return
|
||||
|
||||
for(var/datum/reagent/current in reagents.reagent_list)
|
||||
var/removed = min(current.metabolism*digest_factor, current.volume)
|
||||
if (istype(current, /datum/reagent/nutriment))//If its food, it feeds us
|
||||
var/datum/reagent/nutriment/N = current
|
||||
nutrition += removed*N.nutriment_factor
|
||||
current.remove_self(removed)//If its not food, it just does nothing. no fancy effects
|
||||
|
||||
/mob/living/simple_animal/proc/can_eat()
|
||||
if (nutrition > max_nutrition * 0.9)
|
||||
return 0//full
|
||||
|
||||
else if (nutrition > max_nutrition * 0.8)
|
||||
return 1//content
|
||||
|
||||
else return 2//hungry
|
||||
|
||||
/mob/living/simple_animal/gib()
|
||||
..(icon_gib,1)
|
||||
|
||||
@@ -284,7 +347,10 @@
|
||||
M.show_message("<span class='notice'>[user] applies the [MED] on [src].</span>")
|
||||
else
|
||||
user << "<span class='notice'>\The [src] is dead, medical items won't bring \him back to life.</span>"
|
||||
if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
|
||||
else if(istype(O, /obj/item/weapon/reagent_containers))
|
||||
..()
|
||||
|
||||
else if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
|
||||
if(istype(O, /obj/item/weapon/material/knife) || istype(O, /obj/item/weapon/material/knife/butch))
|
||||
harvest(user)
|
||||
else
|
||||
@@ -320,6 +386,9 @@
|
||||
tally = 1
|
||||
tally *= purge
|
||||
|
||||
if (!nutrition)
|
||||
tally += 4
|
||||
|
||||
return tally+config.animal_delay
|
||||
|
||||
/mob/living/simple_animal/Stat()
|
||||
|
||||
@@ -391,9 +391,13 @@
|
||||
var/datum/reagents/R = C.touching
|
||||
return trans_to_holder(R, amount, multiplier, copy)
|
||||
else
|
||||
var/datum/reagents/R = new /datum/reagents(amount)
|
||||
. = trans_to_holder(R, amount, multiplier, copy)
|
||||
R.touch_mob(target)
|
||||
//If the target has a reagent holder, we'll try to put it there instead. This allows feeding simple animals
|
||||
if(target.reagents && type == CHEM_BLOOD || type == CHEM_INGEST)
|
||||
return trans_to_holder(target.reagents, amount, multiplier, copy)
|
||||
else
|
||||
var/datum/reagents/R = new /datum/reagents(amount)
|
||||
. = trans_to_holder(R, amount, multiplier, copy)
|
||||
R.touch_mob(target)
|
||||
|
||||
/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it.
|
||||
if(!target || !target.simulated)
|
||||
|
||||
@@ -108,6 +108,32 @@
|
||||
On_Consume(M)
|
||||
return 1
|
||||
|
||||
else if (isanimal(M))
|
||||
var/mob/living/simple_animal/SA = M
|
||||
var/m_bitesize = bitesize * SA.bite_factor//Modified bitesize based on creature size
|
||||
var/amount_eaten = m_bitesize
|
||||
|
||||
if(reagents && SA.reagents)
|
||||
m_bitesize = min(m_bitesize, reagents.total_volume)
|
||||
//If the creature can't even stomach half a bite, then it eats nothing
|
||||
if (!SA.can_eat() || ((user.reagents.maximum_volume - user.reagents.total_volume) < m_bitesize * 0.5))
|
||||
amount_eaten = 0
|
||||
else
|
||||
amount_eaten = reagents.trans_to_mob(SA, m_bitesize, CHEM_INGEST)
|
||||
else
|
||||
return 0//The target creature can't eat
|
||||
|
||||
if (amount_eaten)
|
||||
bitecount++
|
||||
if (amount_eaten >= m_bitesize)
|
||||
user.visible_message("<span class='notice'>[user] feeds [M] [src].</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] feeds [M] a tiny bit of [src]. <b>It looks full.</b></span>")
|
||||
On_Consume(M)
|
||||
return 1
|
||||
else
|
||||
user << "<span class='danger'>[M.name] can't stomach anymore food!</span>"
|
||||
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/examine(mob/user)
|
||||
@@ -206,10 +232,34 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/attack_generic(var/mob/living/user)
|
||||
if(!isanimal(user) && !isalien(user))
|
||||
return
|
||||
user.visible_message("<b>[user]</b> nibbles away at \the [src].","You nibble away at \the [src].")
|
||||
bitecount++
|
||||
|
||||
var/amount_eaten = bitesize
|
||||
var/m_bitesize = bitesize
|
||||
|
||||
if (isanimal(user))
|
||||
var/mob/living/simple_animal/SA = user
|
||||
m_bitesize = bitesize * SA.bite_factor//Modified bitesize based on creature size
|
||||
amount_eaten = m_bitesize
|
||||
if (!SA.can_eat())
|
||||
user << "<span class='danger'>You're too full to eat anymore!</span>"
|
||||
return
|
||||
|
||||
if(reagents && user.reagents)
|
||||
reagents.trans_to_mob(user, bitesize, CHEM_INGEST)
|
||||
m_bitesize = min(m_bitesize, reagents.total_volume)
|
||||
//If the creature can't even stomach half a bite, then it eats nothing
|
||||
if (((user.reagents.maximum_volume - user.reagents.total_volume) < m_bitesize * 0.5))
|
||||
amount_eaten = 0
|
||||
else
|
||||
amount_eaten = reagents.trans_to_mob(user, m_bitesize, CHEM_INGEST)
|
||||
if (amount_eaten)
|
||||
bitecount++
|
||||
if (amount_eaten < m_bitesize)
|
||||
user.visible_message("<span class='notice'><b>[user]</b> reluctantly nibbles a tiny part of \the [src].</span>","<span class='notice'>You reluctantly nibble a tiny part of \the [src]. <b>You can't stomach much more!</b>.</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'><b>[user]</b> nibbles away at \the [src].</span>","<span class='notice'>You nibble away at \the [src].</span>")
|
||||
else
|
||||
user << "<span class='danger'>You're too full to eat anymore!</span>"
|
||||
|
||||
spawn(5)
|
||||
if(!src && !user.client)
|
||||
user.custom_emote(1,"[pick("burps", "cries for more", "burps twice", "looks at the area where the food was")]")
|
||||
|
||||
Reference in New Issue
Block a user