diff --git a/_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm b/_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm index 5604f99d938..0c2b0495a91 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm @@ -5173,7 +5173,7 @@ name = "Animal Storage"; req_access = list(150) }, -/mob/living/simple_animal/chicken{ +/mob/living/basic/chicken{ faction = list("neutral","syndicate") }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ diff --git a/_maps/map_files/shuttles/emergency_jungle.dmm b/_maps/map_files/shuttles/emergency_jungle.dmm index fb69b98dc65..270b77e6165 100644 --- a/_maps/map_files/shuttles/emergency_jungle.dmm +++ b/_maps/map_files/shuttles/emergency_jungle.dmm @@ -316,7 +316,7 @@ dir = 1 }, /obj/structure/flora/junglebush, -/mob/living/simple_animal/hostile/retaliate/goat, +/mob/living/basic/goat, /turf/simulated/floor/grass, /area/shuttle/escape) "bA" = ( @@ -709,7 +709,7 @@ /obj/machinery/light/small{ dir = 4 }, -/mob/living/simple_animal/hostile/retaliate/goat, +/mob/living/basic/goat, /turf/simulated/floor/grass, /area/shuttle/escape) "qH" = ( diff --git a/_maps/map_files/stations/boxstation.dmm b/_maps/map_files/stations/boxstation.dmm index e3de69b4279..94e18d4fe36 100644 --- a/_maps/map_files/stations/boxstation.dmm +++ b/_maps/map_files/stations/boxstation.dmm @@ -16557,7 +16557,7 @@ }, /area/station/service/hydroponics) "bfE" = ( -/mob/living/simple_animal/hostile/retaliate/goat/chef, +/mob/living/basic/goat/chef, /turf/simulated/floor/plasteel{ icon_state = "showroomfloor" }, @@ -45752,7 +45752,7 @@ /area/station/service/hydroponics) "dnE" = ( /obj/machinery/hydroponics/soil, -/mob/living/simple_animal/chicken/clucky, +/mob/living/basic/chicken/clucky, /turf/simulated/floor/grass, /area/station/service/hydroponics) "dnF" = ( diff --git a/_maps/map_files/stations/cerestation.dmm b/_maps/map_files/stations/cerestation.dmm index 60b26a4ac64..955aa079e59 100644 --- a/_maps/map_files/stations/cerestation.dmm +++ b/_maps/map_files/stations/cerestation.dmm @@ -93581,7 +93581,7 @@ }, /area/station/service/clown/secret) "srW" = ( -/mob/living/simple_animal/hostile/retaliate/goat{ +/mob/living/basic/goat{ name = "Pete" }, /obj/machinery/hologram/holopad, @@ -97517,7 +97517,7 @@ /area/station/public/dorms) "thf" = ( /obj/structure/flora/ausbushes/sunnybush, -/mob/living/simple_animal/chicken/clucky, +/mob/living/basic/chicken/clucky, /turf/simulated/floor/grass, /area/station/service/hydroponics) "thi" = ( diff --git a/_maps/map_files/stations/deltastation.dmm b/_maps/map_files/stations/deltastation.dmm index fae3e814839..de725309142 100644 --- a/_maps/map_files/stations/deltastation.dmm +++ b/_maps/map_files/stations/deltastation.dmm @@ -13749,7 +13749,7 @@ /turf/simulated/floor/plasteel/dark, /area/station/engineering/atmos) "bdz" = ( -/mob/living/simple_animal/chicken/clucky, +/mob/living/basic/chicken/clucky, /turf/simulated/floor/grass, /area/station/service/kitchen) "bdA" = ( @@ -46459,7 +46459,7 @@ /area/station/science/research) "dxA" = ( /obj/structure/flora/ausbushes/fullgrass, -/mob/living/simple_animal/chick{ +/mob/living/basic/chick{ name = "Sins" }, /turf/simulated/floor/grass, @@ -86492,7 +86492,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/mob/living/simple_animal/hostile/retaliate/goat/chef, +/mob/living/basic/goat/chef, /obj/item/radio/intercom{ name = "north bump"; pixel_y = 28 diff --git a/_maps/map_files/stations/emeraldstation.dmm b/_maps/map_files/stations/emeraldstation.dmm index f413f808d90..b35279a717d 100644 --- a/_maps/map_files/stations/emeraldstation.dmm +++ b/_maps/map_files/stations/emeraldstation.dmm @@ -72539,7 +72539,7 @@ }, /area/station/security/armory/secure) "osA" = ( -/mob/living/simple_animal/hostile/retaliate/goat/chef, +/mob/living/basic/goat/chef, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 }, @@ -106745,7 +106745,7 @@ }, /area/station/security/interrogation) "vgz" = ( -/mob/living/simple_animal/chicken/clucky, +/mob/living/basic/chicken/clucky, /turf/simulated/floor/grass, /area/station/service/kitchen) "vgB" = ( diff --git a/_maps/map_files/stations/metastation.dmm b/_maps/map_files/stations/metastation.dmm index a8e6ae51372..b229ee37c1c 100644 --- a/_maps/map_files/stations/metastation.dmm +++ b/_maps/map_files/stations/metastation.dmm @@ -64935,7 +64935,7 @@ }, /area/station/science/rnd) "oHv" = ( -/mob/living/simple_animal/hostile/retaliate/goat/chef, +/mob/living/basic/goat/chef, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -71259,7 +71259,7 @@ /turf/simulated/floor/plating, /area/station/hallway/primary/fore/east) "qUq" = ( -/mob/living/simple_animal/chicken/clucky, +/mob/living/basic/chicken/clucky, /turf/simulated/floor/grass, /area/station/service/hydroponics) "qUX" = ( diff --git a/code/datums/spell_targeting/matter_eater_targeting.dm b/code/datums/spell_targeting/matter_eater_targeting.dm index a44d3b152b6..bb7efb91d0c 100644 --- a/code/datums/spell_targeting/matter_eater_targeting.dm +++ b/code/datums/spell_targeting/matter_eater_targeting.dm @@ -14,8 +14,8 @@ /mob/living/simple_animal/slime, /mob/living/carbon/alien/larva, /mob/living/simple_animal/slime, - /mob/living/simple_animal/chick, - /mob/living/simple_animal/chicken, + /mob/living/basic/chick, + /mob/living/basic/chicken, /mob/living/basic/lizard, /mob/living/basic/cow, /mob/living/simple_animal/spiderbot diff --git a/code/game/objects/structures/crates_lockers/crittercrate.dm b/code/game/objects/structures/crates_lockers/crittercrate.dm index 04bfe0d1a14..b1a8e7d9e08 100644 --- a/code/game/objects/structures/crates_lockers/crittercrate.dm +++ b/code/game/objects/structures/crates_lockers/crittercrate.dm @@ -51,9 +51,9 @@ /mob/living/simple_animal/pet/dog/corgi, /mob/living/simple_animal/pet/dog/corgi/lisa, - /mob/living/simple_animal/hostile/retaliate/goat, - /mob/living/simple_animal/turkey, - /mob/living/simple_animal/chick, + /mob/living/basic/goat, + /mob/living/basic/turkey, + /mob/living/basic/chick, /mob/living/simple_animal/pet/cat, /mob/living/simple_animal/pet/dog/pug, /mob/living/simple_animal/pet/dog/fox, @@ -77,15 +77,15 @@ /obj/structure/closet/critter/goat name = "goat crate" - content_mob = /mob/living/simple_animal/hostile/retaliate/goat + content_mob = /mob/living/basic/goat /obj/structure/closet/critter/turkey name = "turkey crate" - content_mob = /mob/living/simple_animal/turkey + content_mob = /mob/living/basic/turkey /obj/structure/closet/critter/chick name = "chicken crate" - content_mob = /mob/living/simple_animal/chick + content_mob = /mob/living/basic/chick /obj/structure/closet/critter/chick/populate_contents() amount = rand(1, 3) diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 7633872defb..e0189655921 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -82,7 +82,7 @@ icon_state = "lisacrate" /obj/structure/largecrate/goat/break_open() - new /mob/living/simple_animal/hostile/retaliate/goat(loc) + new /mob/living/basic/goat(loc) /obj/structure/largecrate/chick name = "chicken crate" @@ -91,7 +91,7 @@ /obj/structure/largecrate/chick/break_open() var/num = rand(4, 6) for(var/i in 1 to num) - new /mob/living/simple_animal/chick(loc) + new /mob/living/basic/chick(loc) /obj/structure/largecrate/cat name = "cat crate" diff --git a/code/modules/events/clogged_disposals.dm b/code/modules/events/clogged_disposals.dm index b75fcc10f6b..21812e8c5f8 100644 --- a/code/modules/events/clogged_disposals.dm +++ b/code/modules/events/clogged_disposals.dm @@ -46,7 +46,7 @@ // Retaliate mobs /mob/living/basic/clown = 5, /mob/living/basic/clown/goblin = 5, - /mob/living/simple_animal/hostile/retaliate/goat = 5, + /mob/living/basic/goat = 5, // Friendly /mob/living/simple_animal/mouse = 5, /mob/living/simple_animal/diona = 5, diff --git a/code/modules/mob/living/basic/farm_animals/chicken.dm b/code/modules/mob/living/basic/farm_animals/chicken.dm new file mode 100644 index 00000000000..005bfd5f5f8 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/chicken.dm @@ -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, "[src] doesn't seem hungry!") + 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 diff --git a/code/modules/mob/living/basic/farm_animals/goat.dm b/code/modules/mob/living/basic/farm_animals/goat.dm new file mode 100644 index 00000000000..39664321e2a --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/goat.dm @@ -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("[src] takes a big chomp out of [H]!", "[src] takes a big chomp out of your [NB.name]!") + 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?") diff --git a/code/modules/mob/living/basic/farm_animals/goose.dm b/code/modules/mob/living/basic/farm_animals/goose.dm new file mode 100644 index 00000000000..e51acaa4a31 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/goose.dm @@ -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.") diff --git a/code/modules/mob/living/basic/farm_animals/seal.dm b/code/modules/mob/living/basic/farm_animals/seal.dm new file mode 100644 index 00000000000..29d6138fd30 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/seal.dm @@ -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.") diff --git a/code/modules/mob/living/basic/farm_animals/turkey.dm b/code/modules/mob/living/basic/farm_animals/turkey.dm new file mode 100644 index 00000000000..9286d3f4429 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/turkey.dm @@ -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.") diff --git a/code/modules/mob/living/basic/farm_animals/udders.dm b/code/modules/mob/living/basic/farm_animals/udders.dm new file mode 100644 index 00000000000..83e472b2597 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/udders.dm @@ -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, "[O] is full.") + return + var/transfered = reagents.trans_to(O, rand(5,10)) + if(transfered) + user.visible_message("[user] milks [src] using \the [O].", "You milk [src] using \the [O].") + else + to_chat(user, "The udder is dry. Wait a bit longer...") + +/obj/item/udder/cow + +/obj/item/udder/cow/Initialize(mapload) + . = ..() + reagents.add_reagent("milk", 20) diff --git a/code/modules/mob/living/carbon/human/species/tajaran.dm b/code/modules/mob/living/carbon/human/species/tajaran.dm index 003d4f2131e..7d7f4b980ac 100644 --- a/code/modules/mob/living/carbon/human/species/tajaran.dm +++ b/code/modules/mob/living/carbon/human/species/tajaran.dm @@ -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!", diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm index 04e20ea2042..f96a9b805bc 100644 --- a/code/modules/mob/living/carbon/human/species/unathi.dm +++ b/code/modules/mob/living/carbon/human/species/unathi.dm @@ -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( diff --git a/code/modules/mob/living/carbon/human/species/vulpkanin.dm b/code/modules/mob/living/carbon/human/species/vulpkanin.dm index 5238db6d9e7..55286796834 100644 --- a/code/modules/mob/living/carbon/human/species/vulpkanin.dm +++ b/code/modules/mob/living/carbon/human/species/vulpkanin.dm @@ -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( diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm deleted file mode 100644 index dfc483deced..00000000000 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ /dev/null @@ -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("[src] calms down.") - - 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("[src] gets an evil-looking gleam in their eye.") - -/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("[src] takes a big chomp out of [H]!", "[src] takes a big chomp out of your [NB.name]!") - 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, "[name] doesn't seem hungry!") - - 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, "[O] is full.") - return - var/transfered = reagents.trans_to(O, rand(5,10)) - if(transfered) - user.visible_message("[user] milks [src] using \the [O].", "You milk [src] using \the [O].") - else - to_chat(user, "The udder is dry. Wait a bit longer...") - -/obj/item/udder/cow - -/obj/item/udder/cow/Initialize(mapload) - . = ..() - reagents.add_reagent("milk", 20) - -#undef MAX_CHICKENS diff --git a/code/modules/projectiles/projectile/magic_projectiles.dm b/code/modules/projectiles/projectile/magic_projectiles.dm index d79d92f1f48..c1c97b46cc4 100644 --- a/code/modules/projectiles/projectile/magic_projectiles.dm +++ b/code/modules/projectiles/projectile/magic_projectiles.dm @@ -197,7 +197,7 @@ GLOBAL_LIST_INIT(wabbajack_hostile_animals, list( "mushroom" = /mob/living/simple_animal/hostile/mushroom, "statue" = /mob/living/simple_animal/hostile/statue, "bat" = /mob/living/basic/scarybat, - "goat" = /mob/living/simple_animal/hostile/retaliate/goat, + "goat" = /mob/living/basic/goat, "kangaroo" = /mob/living/basic/kangaroo, "tomato" = /mob/living/basic/killertomato, "gorilla" = /mob/living/basic/gorilla, @@ -209,14 +209,14 @@ GLOBAL_LIST_INIT(wabbajack_docile_animals, list( "crab" = /mob/living/simple_animal/crab, "cat" = /mob/living/simple_animal/pet/cat, "mouse" = /mob/living/simple_animal/mouse, - "chicken" = /mob/living/simple_animal/chicken, + "chicken" = /mob/living/basic/chicken, "cow" = /mob/living/basic/cow, "lizard" = /mob/living/basic/lizard, "fox" = /mob/living/simple_animal/pet/dog/fox, - "chick" = /mob/living/simple_animal/chick, + "chick" = /mob/living/basic/chick, "pug" = /mob/living/simple_animal/pet/dog/pug, - "turkey" = /mob/living/simple_animal/turkey, - "seal" = /mob/living/simple_animal/seal, + "turkey" = /mob/living/basic/turkey, + "seal" = /mob/living/basic/seal, "bunny" = /mob/living/basic/bunny, "penguin" = /mob/living/basic/pet/penguin/emperor, )) diff --git a/paradise.dme b/paradise.dme index 013d2aa35dc..9e95ef103e7 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2446,6 +2446,12 @@ #include "code\modules\mob\living\basic\basic_emotes.dm" #include "code\modules\mob\living\basic\basic_mob.dm" #include "code\modules\mob\living\basic\posessed_object.dm" +#include "code\modules\mob\living\basic\farm_animals\chicken.dm" +#include "code\modules\mob\living\basic\farm_animals\goat.dm" +#include "code\modules\mob\living\basic\farm_animals\goose.dm" +#include "code\modules\mob\living\basic\farm_animals\seal.dm" +#include "code\modules\mob\living\basic\farm_animals\turkey.dm" +#include "code\modules\mob\living\basic\farm_animals\udders.dm" #include "code\modules\mob\living\basic\farm_animals\cow.dm" #include "code\modules\mob\living\basic\farm_animals\deer.dm" #include "code\modules\mob\living\basic\farm_animals\deer_ai.dm" @@ -2687,7 +2693,6 @@ #include "code\modules\mob\living\simple_animal\friendly\crab.dm" #include "code\modules\mob\living\simple_animal\friendly\diona_nymph.dm" #include "code\modules\mob\living\simple_animal\friendly\dog.dm" -#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm" #include "code\modules\mob\living\simple_animal\friendly\fox.dm" #include "code\modules\mob\living\simple_animal\friendly\friendly_emote.dm" #include "code\modules\mob\living\simple_animal\friendly\mouse.dm" diff --git a/sound/creatures/bagawk.ogg b/sound/creatures/bagawk.ogg new file mode 100644 index 00000000000..c275c4cbbc9 Binary files /dev/null and b/sound/creatures/bagawk.ogg differ diff --git a/sound/creatures/chick_peep.ogg b/sound/creatures/chick_peep.ogg new file mode 100644 index 00000000000..791246171a6 Binary files /dev/null and b/sound/creatures/chick_peep.ogg differ diff --git a/sound/creatures/clucks.ogg b/sound/creatures/clucks.ogg new file mode 100644 index 00000000000..e59afd424d8 Binary files /dev/null and b/sound/creatures/clucks.ogg differ diff --git a/tools/UpdatePaths/Scripts/30244_basic_farm_animals.txt b/tools/UpdatePaths/Scripts/30244_basic_farm_animals.txt new file mode 100644 index 00000000000..8917c70b76f --- /dev/null +++ b/tools/UpdatePaths/Scripts/30244_basic_farm_animals.txt @@ -0,0 +1,7 @@ +/mob/living/simple_animal/hostile/retaliate/goat/@SUBTYPES : /mob/living/basic/goat/@SUBTYPES{@OLD} +/mob/living/simple_animal/chick/@SUBTYPES : /mob/living/basic/chick/@SUBTYPES{@OLD} +/mob/living/simple_animal/chicken/@SUBTYPES : /mob/living/basic/chicken/@SUBTYPES{@OLD} +/mob/living/simple_animal/turkey/@SUBTYPES : /mob/living/basic/turkey/@SUBTYPES{@OLD} +/mob/living/simple_animal/goose/@SUBTYPES : /mob/living/basic/goose/@SUBTYPES{@OLD} +/mob/living/simple_animal/seal/@SUBTYPES : /mob/living/basic/seal/@SUBTYPES{@OLD} +/mob/living/simple_animal/walrus/@SUBTYPES : /mob/living/basic/seal/walrus/@SUBTYPES{@OLD} diff --git a/tools/ci/check_simplemob_additions.py b/tools/ci/check_simplemob_additions.py index 582f3d8e15d..df6dd933ac5 100644 --- a/tools/ci/check_simplemob_additions.py +++ b/tools/ci/check_simplemob_additions.py @@ -45,11 +45,6 @@ BURNDOWN_LIST = { "/mob/living/simple_animal/bot/secbot/griefsky/toy", "/mob/living/simple_animal/bot/secbot/ofitser", "/mob/living/simple_animal/bot/secbot/pingsky", - "/mob/living/simple_animal/chick", - "/mob/living/simple_animal/chicken", - "/mob/living/simple_animal/chicken/clucky", - "/mob/living/simple_animal/chicken/featherbottom", - "/mob/living/simple_animal/chicken/kentucky", "/mob/living/simple_animal/crab", "/mob/living/simple_animal/crab/coffee", "/mob/living/simple_animal/crab/evil", @@ -63,7 +58,6 @@ BURNDOWN_LIST = { "/mob/living/simple_animal/demon/slaughter/lesser", "/mob/living/simple_animal/diona", "/mob/living/simple_animal/drone", - "/mob/living/simple_animal/goose", "/mob/living/simple_animal/hostile", "/mob/living/simple_animal/hostile/ancient_robot_leg", "/mob/living/simple_animal/hostile/asteroid", @@ -170,8 +164,6 @@ BURNDOWN_LIST = { "/mob/living/simple_animal/hostile/retaliate/carp", "/mob/living/simple_animal/hostile/retaliate/carp/koi", "/mob/living/simple_animal/hostile/retaliate/carp/koi/honk", - "/mob/living/simple_animal/hostile/retaliate/goat", - "/mob/living/simple_animal/hostile/retaliate/goat/chef", "/mob/living/simple_animal/hostile/spaceinfected", "/mob/living/simple_animal/hostile/spaceinfected/default", "/mob/living/simple_animal/hostile/spaceinfected/default/ranged", @@ -231,7 +223,6 @@ BURNDOWN_LIST = { "/mob/living/simple_animal/pet/dog/fox/syndifox", "/mob/living/simple_animal/pet/dog/pug", "/mob/living/simple_animal/revenant", - "/mob/living/simple_animal/seal", "/mob/living/simple_animal/shade", "/mob/living/simple_animal/shade/cult", "/mob/living/simple_animal/shade/holy", @@ -242,8 +233,6 @@ BURNDOWN_LIST = { "/mob/living/simple_animal/slime/random", "/mob/living/simple_animal/slime/unit_test_dummy", "/mob/living/simple_animal/spiderbot", - "/mob/living/simple_animal/turkey", - "/mob/living/simple_animal/walrus", } }