Converts farm animals to basic mobs (#30244)

* Converts farm animals to basic mobs

* Update paths, removes excess file

* CI

---------

Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
This commit is contained in:
PollardTheDragon
2025-09-19 11:26:43 -04:00
committed by GitHub
parent e529ce7a23
commit b52f6cc6c0
28 changed files with 620 additions and 493 deletions
@@ -0,0 +1,257 @@
/mob/living/basic/chick
name = "chick"
desc = "Adorable! They make such a racket though."
icon_state = "chick"
icon_living = "chick"
icon_dead = "chick_dead"
icon_gib = "chick_gib"
gender = FEMALE
mob_biotypes = MOB_ORGANIC | MOB_BEAST
speak_emote = list("cheeps")
density = FALSE
butcher_results = list(/obj/item/food/meat/chicken = 1)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "pecks"
attack_verb_simple = "peck"
health = 3
maxHealth = 3
ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
holder_type = /obj/item/holder/chicken
can_hide = TRUE
gold_core_spawnable = FRIENDLY_SPAWN
step_type = FOOTSTEP_MOB_CLAW
ai_controller = /datum/ai_controller/basic_controller/chicken/chick
/// How grown up are we?
var/amount_grown = 0
/mob/living/basic/chick/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
scatter_atom()
/// Basic mobs need a language otherwise their speech is garbled
add_language("Galactic Common")
set_default_language(GLOB.all_languages["Galactic Common"])
/mob/living/basic/chick/scatter_atom(x_offset, y_offset)
pixel_x = rand(-6, 6) + x_offset
pixel_y = rand(0, 10) + y_offset
/mob/living/basic/chick/Life(seconds, times_fired)
. = ..()
if(.)
amount_grown += rand(1,2)
if(amount_grown >= 100)
var/mob/living/basic/chicken/C = new /mob/living/basic/chicken(loc)
if(name != initial(name))
C.name = name
if(mind)
mind.transfer_to(C)
for(var/atom/movable/AM in contents)
AM.forceMove(C)
qdel(src)
/mob/living/basic/chick/valid_respawn_target_for(mob/user)
return TRUE
/mob/living/basic/chick/attack_hand(mob/living/carbon/human/M)
if(M.a_intent == INTENT_HELP)
get_scooped(M, TRUE)
..()
#define MAX_CHICKENS 50
GLOBAL_VAR_INIT(chicken_count, 0)
/mob/living/basic/chicken
name = "chicken"
desc = "Hopefully the eggs are good this season."
gender = FEMALE
mob_biotypes = MOB_ORGANIC | MOB_BEAST
icon_state = "chicken_brown"
icon_living = "chicken_brown"
icon_dead = "chicken_brown_dead"
speak_emote = list("clucks", "croons")
density = FALSE
butcher_results = list(/obj/item/food/meat/chicken = 2)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "pecks"
attack_verb_simple = "peck"
friendly_verb_continuous = "headbutts"
friendly_verb_simple = "headbutt"
health = 15
maxHealth = 15
ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
holder_type = /obj/item/holder/chicken
can_hide = TRUE
gold_core_spawnable = FRIENDLY_SPAWN
step_type = FOOTSTEP_MOB_CLAW
ai_controller = /datum/ai_controller/basic_controller/chicken
/// What type of egg do we lay?
var/egg_type = /obj/item/food/egg
/// How many eggs do we have left to lay?
var/eggsleft = 0
/// Are the eggs fertile?
var/eggsFertile = TRUE
/// What can the chicken eat?
var/static/list/edibles = list(
/obj/item/food/grown/wheat,
)
/// What color chicken are we?
var/body_color
/// Prefix for icon determining colors
var/icon_prefix = "chicken"
/// What colors can chickens be?
var/list/validColors = list("brown", "black", "white")
/// What message to play when laying an egg?
var/list/layMessage = EGG_LAYING_MESSAGES
/mob/living/basic/chicken/Initialize(mapload)
. = ..()
if(!body_color)
body_color = pick(validColors)
icon_state = "[icon_prefix]_[body_color]"
icon_living = "[icon_prefix]_[body_color]"
icon_dead = "[icon_prefix]_[body_color]_dead"
AddElement(/datum/element/wears_collar)
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/pet_bonus, "cluck")
// Have all eating components share the same exact list per mob subtype
var/static/list/static_food_types
if(!static_food_types)
static_food_types = edibles.Copy()
AddElement(/datum/element/basic_eating, food_types_ = static_food_types)
RegisterSignal(src, COMSIG_MOB_PRE_EAT, PROC_REF(on_eat))
ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(edibles))
scatter_atom()
update_appearance(UPDATE_ICON_STATE)
GLOB.chicken_count++
/// Basic mobs need a language otherwise their speech is garbled
add_language("Galactic Common")
set_default_language(GLOB.all_languages["Galactic Common"])
/mob/living/basic/chicken/scatter_atom(x_offset, y_offset)
pixel_x = rand(-6, 6) + x_offset
pixel_y = rand(0, 10) + y_offset
/mob/living/basic/chicken/death(gibbed)
// Only execute the below if we successfully died
. = ..(gibbed)
if(!.)
return
GLOB.chicken_count--
/mob/living/basic/chicken/proc/on_eat(atom/target, mob/feeder)
SIGNAL_HANDLER // COMSIG_MOB_PRE_EAT
if(stat == CONSCIOUS && eggsleft < 8)
eggsleft += rand(1, 4)
else
to_chat(feeder, "<span class='warning'>[src] doesn't seem hungry!</span>")
return COMSIG_MOB_CANCEL_EAT
/mob/living/basic/chicken/attack_hand(mob/living/carbon/human/M)
if(M.a_intent == INTENT_HELP)
get_scooped(M, TRUE)
..()
/mob/living/basic/chicken/Life(seconds, times_fired)
. = ..()
if((. && prob(3) && eggsleft > 0) && egg_type)
visible_message("[src] [pick(layMessage)]")
eggsleft--
var/obj/item/E = new egg_type(get_turf(src))
E.scatter_atom()
if(eggsFertile)
if(GLOB.chicken_count < MAX_CHICKENS && prob(25))
START_PROCESSING(SSobj, E)
/obj/item/food/egg/process()
if(isturf(loc))
amount_grown += rand(1,2)
if(amount_grown >= 100)
visible_message("[src] hatches with a quiet cracking sound.")
new /mob/living/basic/chick(get_turf(src))
STOP_PROCESSING(SSobj, src)
qdel(src)
else
STOP_PROCESSING(SSobj, src)
/mob/living/basic/chicken/valid_respawn_target_for(mob/user)
return TRUE
/mob/living/basic/chicken/clucky
name = "Commander Clucky"
real_name = "Commander Clucky"
/mob/living/basic/chicken/clucky/valid_respawn_target_for(mob/user) // depriving the chef of his animals is not cool
return FALSE
/mob/living/basic/chicken/kentucky
name = "Kentucky"
real_name = "Kentucky"
/mob/living/basic/chicken/kentucky/valid_respawn_target_for(mob/user)
return FALSE
/mob/living/basic/chicken/featherbottom
name = "Featherbottom"
real_name = "Featherbottom"
/mob/living/basic/chicken/featherbottom/valid_respawn_target_for(mob/user)
return FALSE
/datum/ai_controller/basic_controller/chicken
blackboard = list(
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
)
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/random_speech/chicken,
)
/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_controller/basic_controller/chicken/chick
planning_subtrees = list(
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/random_speech/chick,
)
/datum/ai_planning_subtree/random_speech/chick
speech_chance = 15
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 its tiny wings")
#undef MAX_CHICKENS
@@ -0,0 +1,131 @@
// goat
/mob/living/basic/goat
name = "goat"
desc = "Not known for their pleasant disposition."
icon_state = "goat"
icon_living = "goat"
icon_dead = "goat_dead"
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 4)
speak_emote = list("brays")
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
faction = list("neutral", "jungle")
mob_biotypes = MOB_ORGANIC | MOB_BEAST
health = 40
maxHealth = 40
melee_damage_lower = 1
melee_damage_upper = 2
blood_volume = BLOOD_VOLUME_NORMAL
gender = FEMALE
step_type = FOOTSTEP_MOB_SHOE
ai_controller = /datum/ai_controller/basic_controller/goat
/// What can the goat eat?
var/static/list/edibles = list(
/obj/structure/glowshroom,
/obj/structure/spacevine,
)
/// The goat's udder
var/obj/item/udder/cow/udder
/mob/living/basic/goat/Initialize(mapload)
. = ..()
udder = new()
AddElement(/datum/element/wears_collar)
AddElement(/datum/element/ai_retaliate)
ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(edibles))
RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(on_pre_attack))
RegisterSignal(src, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move))
/mob/living/basic/goat/Destroy()
QDEL_NULL(udder)
return ..()
/mob/living/basic/goat/melee_attack(atom/target, list/modifiers, ignore_cooldown)
. = ..()
if(. && isdiona(target))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/NB = pick(H.bodyparts)
H.visible_message("<span class='warning'>[src] takes a big chomp out of [H]!</span>", "<span class='userdanger'>[src] takes a big chomp out of your [NB.name]!</span>")
NB.droplimb()
/mob/living/basic/goat/proc/on_pre_attack(datum/source, atom/target)
SIGNAL_HANDLER // COMSIG_HOSTILE_PRE_ATTACKINGTARGET
if(is_type_in_list(target, edibles))
eat_plant(list(target))
return COMPONENT_HOSTILE_NO_ATTACK
/mob/living/basic/goat/proc/on_move(datum/source, atom/entering_loc)
SIGNAL_HANDLER // COMSIG_MOVABLE_PRE_MOVE
if(!isturf(entering_loc) || stat == DEAD)
return
var/list/edible_plants = list()
for(var/obj/target in entering_loc)
if(is_type_in_list(target, edibles))
edible_plants += target
INVOKE_ASYNC(src, PROC_REF(eat_plant), edible_plants)
/mob/living/basic/goat/Life(seconds, times_fired)
. = ..()
if(stat == CONSCIOUS)
udder.generateMilk()
/mob/living/basic/goat/item_interaction(mob/living/user, obj/item/O, list/modifiers)
if(stat == CONSCIOUS && istype(O, /obj/item/reagent_containers/glass))
udder.milkAnimal(O, user)
return ITEM_INTERACT_COMPLETE
/mob/living/basic/goat/proc/eat_plant(list/plants)
var/eaten = FALSE
for(var/atom/target as anything in plants)
if(istype(target, /obj/structure/spacevine))
var/obj/structure/spacevine/vine = target
vine.eat(src)
eaten = TRUE
if(istype(target, /obj/structure/glowshroom))
qdel(target)
eaten = TRUE
if(eaten && prob(10))
say("Nom") // bon appetit
playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE)
/mob/living/basic/goat/chef
name = "Pete"
desc = "Pete, the Chef's pet goat from the Caribbean. Not known for their pleasant disposition."
/// Goats are normally content to sorta hang around and crunch any plant in sight, but they will go ape on someone who attacks them.
/datum/ai_controller/basic_controller/goat
blackboard = list(
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
)
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/capricious_retaliate, // Capricious like Capra, get it?
/datum/ai_planning_subtree/target_retaliate,
/datum/ai_planning_subtree/find_food,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/random_speech/goat,
)
/datum/ai_planning_subtree/random_speech/goat
speech_chance = 3
emote_hear = list("brays.")
emote_see = list("shakes their head.", "stamps a foot.", "glares around.")
speak = list("EHEHEHEHEH", "eh?")
@@ -0,0 +1,51 @@
/mob/living/basic/goose
name = "goose"
desc = "A pretty goose. Would make a nice comforter."
icon_state = "goose"
icon_living = "goose"
icon_dead = "goose_dead"
speak_emote = list("quacks")
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 6)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "pecks"
attack_verb_simple = "peck"
health = 50
maxHealth = 50
mob_biotypes = MOB_ORGANIC | MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
step_type = FOOTSTEP_MOB_CLAW
ai_controller = /datum/ai_controller/basic_controller/goose
/mob/living/basic/goose/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
AddElement(/datum/element/ai_retaliate)
/// Basic mobs need a language otherwise their speech is garbled
add_language("Galactic Common")
set_default_language(GLOB.all_languages["Galactic Common"])
/datum/ai_controller/basic_controller/goose
blackboard = list(
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
)
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/random_speech/goose,
)
/datum/ai_planning_subtree/random_speech/goose
speech_chance = 2
speak = list("quack?", "quack", "QUACK")
emote_see = list("flaps it's wings.")
@@ -0,0 +1,56 @@
/mob/living/basic/seal
name = "seal"
desc = "A beautiful white seal."
icon_state = "seal"
icon_living = "seal"
icon_dead = "seal_dead"
speak_emote = list("urks")
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 6)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
health = 50
maxHealth = 50
mob_biotypes = MOB_ORGANIC | MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
blood_volume = BLOOD_VOLUME_NORMAL
ai_controller = /datum/ai_controller/basic_controller/seal
/mob/living/basic/seal/walrus
name = "walrus"
desc = "A big brown walrus."
icon_state = "walrus"
icon_living = "walrus"
icon_dead = "walrus_dead"
/mob/living/basic/seal/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
AddElement(/datum/element/ai_retaliate)
/// Basic mobs need a language otherwise their speech is garbled
add_language("Galactic Common")
set_default_language(GLOB.all_languages["Galactic Common"])
/datum/ai_controller/basic_controller/seal
blackboard = list(
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
)
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/random_speech/seal,
)
/datum/ai_planning_subtree/random_speech/seal
speech_chance = 2
speak = list("Urk?", "urk.", "URK!")
emote_see = list("flops around.")
@@ -0,0 +1,52 @@
/mob/living/basic/turkey
name = "turkey"
desc = "Benjamin Franklin would be proud."
icon_state = "turkey"
icon_living = "turkey"
icon_dead = "turkey_dead"
icon_resting = "turkey_rest"
speak_emote = list("gobble")
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 4)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "pecks"
attack_verb_simple = "peck"
health = 50
maxHealth = 50
mob_biotypes = MOB_ORGANIC | MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
step_type = FOOTSTEP_MOB_CLAW
ai_controller = /datum/ai_controller/basic_controller/turkey
/mob/living/basic/turkey/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
AddElement(/datum/element/ai_retaliate)
/// Basic mobs need a language otherwise their speech is garbled
add_language("Galactic Common")
set_default_language(GLOB.all_languages["Galactic Common"])
/datum/ai_controller/basic_controller/turkey
blackboard = list(
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
)
ai_traits = AI_FLAG_STOP_MOVING_WHEN_PULLED
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/random_speech/turkey,
)
/datum/ai_planning_subtree/random_speech/turkey
speech_chance = 2
speak = list("gobble?", "gobble", "GOBBLE")
emote_see = list("struts around.")
@@ -0,0 +1,27 @@
/obj/item/udder
name = "udder"
/obj/item/udder/Initialize(mapload)
. = ..()
create_reagents(50)
/obj/item/udder/proc/generateMilk()
if(prob(5))
reagents.add_reagent("milk", rand(5, 10))
/obj/item/udder/proc/milkAnimal(obj/O, mob/user)
var/obj/item/reagent_containers/glass/G = O
if(G.reagents.total_volume >= G.volume)
to_chat(user, "<span class='danger'>[O] is full.</span>")
return
var/transfered = reagents.trans_to(O, rand(5,10))
if(transfered)
user.visible_message("[user] milks [src] using \the [O].", "<span class='notice'>You milk [src] using \the [O].</span>")
else
to_chat(user, "<span class='danger'>The udder is dry. Wait a bit longer...</span>")
/obj/item/udder/cow
/obj/item/udder/cow/Initialize(mapload)
. = ..()
reagents.add_reagent("milk", 20)
@@ -44,7 +44,7 @@
unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/
)
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/chick, /mob/living/basic/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/hostile/poison/bees)
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/basic/chick, /mob/living/basic/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/hostile/poison/bees)
suicide_messages = list(
"is attempting to bite their tongue off!",
@@ -48,7 +48,7 @@
"eyes" = /obj/item/organ/internal/eyes/unathi //3 darksight.
)
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/basic/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken,
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/basic/lizard, /mob/living/basic/chick, /mob/living/basic/chicken,
/mob/living/simple_animal/crab, /mob/living/basic/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/hostile/poison/bees)
suicide_messages = list(
@@ -38,7 +38,7 @@
unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/
)
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/basic/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken,
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/basic/lizard, /mob/living/basic/chick, /mob/living/basic/chicken,
/mob/living/simple_animal/crab, /mob/living/basic/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/hostile/poison/bees)
suicide_messages = list(
@@ -1,448 +0,0 @@
//goat
/mob/living/simple_animal/hostile/retaliate/goat
name = "goat"
desc = "Not known for their pleasant disposition."
icon_state = "goat"
icon_living = "goat"
icon_dead = "goat_dead"
speak = list("EHEHEHEHEH","eh?")
speak_emote = list("brays")
emote_hear = list("brays")
emote_see = list("shakes its head", "stamps a foot", "glares around")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 4)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
faction = list("neutral", "jungle")
mob_biotypes = MOB_ORGANIC | MOB_BEAST
attack_same = TRUE
attacktext = "kicks"
attack_sound = 'sound/weapons/punch1.ogg'
health = 40
maxHealth = 40
melee_damage_lower = 1
melee_damage_upper = 2
stop_automated_movement_when_pulled = TRUE
blood_volume = BLOOD_VOLUME_NORMAL
var/obj/item/udder/cow/udder = null
gender = FEMALE
footstep_type = FOOTSTEP_MOB_SHOE
/mob/living/simple_animal/hostile/retaliate/goat/Initialize(mapload)
. = ..()
udder = new()
AddElement(/datum/element/wears_collar)
/mob/living/simple_animal/hostile/retaliate/goat/Destroy()
QDEL_NULL(udder)
return ..()
/mob/living/simple_animal/hostile/retaliate/goat/handle_automated_movement()
. = ..()
//chance to go crazy and start wacking stuff
if(!length(enemies) && prob(1))
Retaliate()
if(length(enemies) && prob(10))
enemies = list()
LoseTarget()
visible_message("<span class='notice'>[src] calms down.</span>")
eat_plants()
if(!pulledby)
for(var/direction in shuffle(GLOB.alldirs))
var/step = get_step(src, direction)
if(step)
if(locate(/obj/structure/spacevine) in step || locate(/obj/structure/glowshroom) in step)
Move(step, get_dir(src, step))
/mob/living/simple_animal/hostile/retaliate/goat/Life(seconds, times_fired)
. = ..()
if(stat == CONSCIOUS)
udder.generateMilk()
/mob/living/simple_animal/hostile/retaliate/goat/Retaliate()
..()
visible_message("<span class='danger'>[src] gets an evil-looking gleam in their eye.</span>")
/mob/living/simple_animal/hostile/retaliate/goat/Move()
. = ..()
if(stat == CONSCIOUS)
eat_plants()
/mob/living/simple_animal/hostile/retaliate/goat/item_interaction(mob/living/user, obj/item/O, list/modifiers)
if(stat == CONSCIOUS && istype(O, /obj/item/reagent_containers/glass))
udder.milkAnimal(O, user)
return ITEM_INTERACT_COMPLETE
/mob/living/simple_animal/hostile/retaliate/goat/proc/eat_plants()
var/eaten = FALSE
var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc
if(SV)
SV.eat(src)
eaten = TRUE
var/obj/structure/glowshroom/GS = locate(/obj/structure/glowshroom) in loc
if(GS)
qdel(GS)
eaten = TRUE
if(eaten && prob(10))
say("Nom")
/mob/living/simple_animal/hostile/retaliate/goat/AttackingTarget()
. = ..()
if(. && isdiona(target))
var/mob/living/carbon/human/H = target
var/obj/item/organ/external/NB = pick(H.bodyparts)
H.visible_message("<span class='warning'>[src] takes a big chomp out of [H]!</span>", "<span class='userdanger'>[src] takes a big chomp out of your [NB.name]!</span>")
NB.droplimb()
/mob/living/simple_animal/hostile/retaliate/goat/chef
name = "Pete"
desc = "Pete, the Chef's pet goat from the Caribbean. Not known for their pleasant disposition."
unique_pet = TRUE
/mob/living/simple_animal/chick
name = "chick"
desc = "Adorable! They make such a racket though."
icon_state = "chick"
icon_living = "chick"
icon_dead = "chick_dead"
icon_gib = "chick_gib"
gender = FEMALE
mob_biotypes = MOB_ORGANIC | MOB_BEAST
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
speak_emote = list("cheeps")
emote_hear = list("cheeps")
emote_see = list("pecks at the ground","flaps its tiny wings")
density = FALSE
speak_chance = 2
turns_per_move = 2
butcher_results = list(/obj/item/food/meat/chicken = 1)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 3
maxHealth = 3
ventcrawler = VENTCRAWLER_ALWAYS
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
holder_type = /obj/item/holder/chicken
can_hide = TRUE
gold_core_spawnable = FRIENDLY_SPAWN
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/chick/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
scatter_atom()
/mob/living/simple_animal/chick/scatter_atom(x_offset, y_offset)
pixel_x = rand(-6, 6) + x_offset
pixel_y = rand(0, 10) + y_offset
/mob/living/simple_animal/chick/Life(seconds, times_fired)
. =..()
if(.)
amount_grown += rand(1,2)
if(amount_grown >= 100)
var/mob/living/simple_animal/chicken/C = new /mob/living/simple_animal/chicken(loc)
if(name != initial(name))
C.name = name
if(mind)
mind.transfer_to(C)
for(var/atom/movable/AM in contents)
AM.forceMove(C)
qdel(src)
/mob/living/simple_animal/chick/npc_safe(mob/user)
return TRUE
/mob/living/simple_animal/chick/attack_hand(mob/living/carbon/human/M)
if(M.a_intent == INTENT_HELP)
get_scooped(M, TRUE)
..()
#define MAX_CHICKENS 50
GLOBAL_VAR_INIT(chicken_count, 0)
/mob/living/simple_animal/chicken
name = "chicken"
desc = "Hopefully the eggs are good this season."
gender = FEMALE
mob_biotypes = MOB_ORGANIC | MOB_BEAST
icon_state = "chicken_brown"
icon_living = "chicken_brown"
icon_dead = "chicken_brown_dead"
speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.")
speak_emote = list("clucks","croons")
emote_hear = list("clucks")
emote_see = list("pecks at the ground","flaps its wings viciously")
density = FALSE
speak_chance = 2
turns_per_move = 3
butcher_results = list(/obj/item/food/meat/chicken = 2)
var/egg_type = /obj/item/food/egg
var/food_type = /obj/item/food/grown/wheat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 15
maxHealth = 15
ventcrawler = VENTCRAWLER_ALWAYS
var/eggsleft = 0
var/eggsFertile = TRUE
var/body_color
var/icon_prefix = "chicken"
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
holder_type = /obj/item/holder/chicken
can_hide = TRUE
var/list/feedMessages = list("It clucks happily.","It clucks happily.")
var/list/layMessage = EGG_LAYING_MESSAGES
var/list/validColors = list("brown","black","white")
gold_core_spawnable = FRIENDLY_SPAWN
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/chicken/Initialize(mapload)
. = ..()
if(!body_color)
body_color = pick(validColors)
icon_state = "[icon_prefix]_[body_color]"
icon_living = "[icon_prefix]_[body_color]"
icon_dead = "[icon_prefix]_[body_color]_dead"
AddElement(/datum/element/wears_collar)
scatter_atom()
update_appearance(UPDATE_ICON_STATE)
GLOB.chicken_count += 1
/mob/living/simple_animal/chicken/scatter_atom(x_offset, y_offset)
pixel_x = rand(-6, 6) + x_offset
pixel_y = rand(0, 10) + y_offset
/mob/living/simple_animal/chicken/death(gibbed)
// Only execute the below if we successfully died
. = ..(gibbed)
if(!.)
return
GLOB.chicken_count -= 1
/mob/living/simple_animal/chicken/item_interaction(mob/living/user, obj/item/O, list/modifiers)
if(istype(O, food_type)) //feedin' dem chickens
if(stat == CONSCIOUS && eggsleft < 8)
var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]"
user.visible_message(feedmsg)
user.drop_item()
qdel(O)
eggsleft += rand(1, 4)
//world << eggsleft
else
to_chat(user, "<span class='warning'>[name] doesn't seem hungry!</span>")
return ITEM_INTERACT_COMPLETE
/mob/living/simple_animal/chicken/attack_hand(mob/living/carbon/human/M)
if(M.a_intent == INTENT_HELP)
get_scooped(M, TRUE)
..()
/mob/living/simple_animal/chicken/Life(seconds, times_fired)
. = ..()
if((. && prob(3) && eggsleft > 0) && egg_type)
visible_message("[src] [pick(layMessage)]")
eggsleft--
var/obj/item/E = new egg_type(get_turf(src))
E.scatter_atom()
if(eggsFertile)
if(GLOB.chicken_count < MAX_CHICKENS && prob(25))
START_PROCESSING(SSobj, E)
/obj/item/food/egg/process()
if(isturf(loc))
amount_grown += rand(1,2)
if(amount_grown >= 100)
visible_message("[src] hatches with a quiet cracking sound.")
new /mob/living/simple_animal/chick(get_turf(src))
STOP_PROCESSING(SSobj, src)
qdel(src)
else
STOP_PROCESSING(SSobj, src)
/mob/living/simple_animal/chicken/npc_safe(mob/user)
return TRUE
/mob/living/simple_animal/chicken/clucky
name = "Commander Clucky"
real_name = "Commander Clucky"
unique_pet = TRUE
/mob/living/simple_animal/chicken/clucky/npc_safe(mob/user) // depriving the chef of his animals is not cool
return FALSE
/mob/living/simple_animal/chicken/kentucky
name = "Kentucky"
real_name = "Kentucky"
unique_pet = TRUE
/mob/living/simple_animal/chicken/kentucky/npc_safe(mob/user)
return FALSE
/mob/living/simple_animal/chicken/featherbottom
name = "Featherbottom"
real_name = "Featherbottom"
unique_pet = TRUE
/mob/living/simple_animal/chicken/featherbottom/npc_safe(mob/user)
return FALSE
/mob/living/simple_animal/turkey
name = "turkey"
desc = "Benjamin Franklin would be proud."
icon_state = "turkey"
icon_living = "turkey"
icon_dead = "turkey_dead"
icon_resting = "turkey_rest"
speak = list("gobble?","gobble","GOBBLE")
speak_emote = list("gobble")
emote_see = list("struts around")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 4)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "pecks"
health = 50
maxHealth = 50
mob_biotypes = MOB_ORGANIC | MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/turkey/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
/mob/living/simple_animal/goose
name = "goose"
desc = "A pretty goose. Would make a nice comforter."
icon_state = "goose"
icon_living = "goose"
icon_dead = "goose_dead"
speak = list("quack?","quack","QUACK")
speak_emote = list("quacks")
// emote_hear = list("brays")
emote_see = list("flaps it's wings")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 6)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 50
maxHealth = 50
mob_biotypes = MOB_ORGANIC | MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/goose/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
/mob/living/simple_animal/seal
name = "seal"
desc = "A beautiful white seal."
icon_state = "seal"
icon_living = "seal"
icon_dead = "seal_dead"
speak = list("Urk?","urk","URK")
speak_emote = list("urks")
// emote_hear = list("brays")
emote_see = list("flops around")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 6)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 50
maxHealth = 50
mob_biotypes = MOB_ORGANIC | MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
blood_volume = BLOOD_VOLUME_NORMAL
/mob/living/simple_animal/seal/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
/mob/living/simple_animal/walrus
name = "walrus"
desc = "A big brown walrus."
icon_state = "walrus"
icon_living = "walrus"
icon_dead = "walrus_dead"
speak = list("Urk?","urk","URK")
speak_emote = list("urks")
// emote_hear = list("brays")
emote_see = list("flops around")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/food/meat = 6)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 50
maxHealth = 50
mob_biotypes = MOB_ORGANIC | MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
blood_volume = BLOOD_VOLUME_NORMAL
/mob/living/simple_animal/walrus/Initialize(mapload)
. = ..()
AddElement(/datum/element/wears_collar)
/obj/item/udder
name = "udder"
/obj/item/udder/Initialize(mapload)
. = ..()
create_reagents(50)
/obj/item/udder/proc/generateMilk()
if(prob(5))
reagents.add_reagent("milk", rand(5, 10))
/obj/item/udder/proc/milkAnimal(obj/O, mob/user)
var/obj/item/reagent_containers/glass/G = O
if(G.reagents.total_volume >= G.volume)
to_chat(user, "<span class='danger'>[O] is full.</span>")
return
var/transfered = reagents.trans_to(O, rand(5,10))
if(transfered)
user.visible_message("[user] milks [src] using \the [O].", "<span class='notice'>You milk [src] using \the [O].</span>")
else
to_chat(user, "<span class='danger'>The udder is dry. Wait a bit longer...</span>")
/obj/item/udder/cow
/obj/item/udder/cow/Initialize(mapload)
. = ..()
reagents.add_reagent("milk", 20)
#undef MAX_CHICKENS