From 4d5f2dfcbe26bd5059520da1d1fd9e1d5814a363 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 16 Aug 2024 00:22:27 -0400 Subject: [PATCH 1/9] Add an animal husbandry skill --- mods/content/fantasy/datum/skills.dm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mods/content/fantasy/datum/skills.dm b/mods/content/fantasy/datum/skills.dm index 38e64bbc83d..9b368e9843d 100644 --- a/mods/content/fantasy/datum/skills.dm +++ b/mods/content/fantasy/datum/skills.dm @@ -5,6 +5,8 @@ #define SKILL_SCULPTING /decl/skill/crafting/sculpting #define SKILL_ARTIFICE /decl/skill/crafting/artifice +#define SKILL_HUSBANDRY /decl/skill/service/husbandry + /decl/skill/Initialize() . = ..() // Rename the default skill levels. @@ -216,6 +218,17 @@ "Master" = "You're a specialized gardener. You can care for even the most exotic, fragile, or dangerous plants." ) +/decl/skill/service/husbandry + name = "Animal Husbandry" + desc = "Your ability to raise and care for animals." + levels = list( + "Unskilled" = "You know next to nothing about animals. You can feed and clean up after them, but you know nothing about their biology, their behavior, or raising their young.", + "Basic" = "You've cared for farm animals before. You can care for the basic needs of an animal, and know how to do things like milk a cow or shear a sheep.
- Cows will not flee when you try to milk them.", + "Trained" = "You are proficient at animal handling, and can delicately handle even skittish animals without frightening them.
- Passive animals will not flee when you pick them up.", + "Experienced" = "You are an experienced animal caretaker with an encyclopedic knowledge of animals.", + "Master" = "You're a specialized animal caretaker. You can care for even the most exotic, fragile, or dangerous animals." + ) + /decl/skill/service/cooking name = "Cooking" desc = "Describes your skill at preparing meals and other consumable goods. This includes mixing alcoholic beverages." From 8b68b54637b8a8c5cb269a956713c9d6eeab911d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 21 Aug 2024 17:26:46 -0400 Subject: [PATCH 2/9] Add skill-check for judging a chicken's age --- .../simple_animal/friendly/farm_animals.dm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 57f294e53af..07255801fbf 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -194,6 +194,24 @@ ai = /datum/mob_controller/chick holder_type = /obj/item/holder var/amount_grown = 0 + var/decl/skill/examine_skill = SKILL_BOTANY // for maps that change the default skills, or for alien eggs that need science/medical/anatomy instead + var/examine_difficulty = SKILL_ADEPT + +/mob/living/simple_animal/chick/examine(mob/user, distance, infix, suffix) + . = ..() + if(!user.skill_check(examine_skill, examine_difficulty)) + var/decl/skill/examine_skill_decl = GET_DECL(examine_skill) + to_chat(user, SPAN_SUBTLE("If you knew more about [lowertext(examine_skill_decl.name)], you could learn additional information about this.")) + return + switch(amount_grown) + if(0 to 20) + to_chat(user, SPAN_NOTICE("It's still young.")) + if(20 to 40) + to_chat(user, SPAN_NOTICE("It's starting to grow in its adult feathers.")) + if(40 to 80) + to_chat(user, SPAN_NOTICE("It's grown in almost all its adult feathers.")) + if(80 to 100) + to_chat(user, SPAN_NOTICE("It's almost fully grown.")) /datum/mob_controller/chick emote_speech = list("Cherp.","Cherp?","Chirrup.","Cheep!") From d97667ba6a2cbee7a818efda8b2ef453b1befa15 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 21 Aug 2024 17:36:00 -0400 Subject: [PATCH 3/9] Add egg candling --- .../simple_animal/friendly/farm_animals.dm | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 07255801fbf..0c3ed519830 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -348,6 +348,46 @@ var/global/chicken_count = 0 /obj/item/food/egg var/amount_grown = 0 + var/decl/skill/examine_skill = SKILL_BOTANY // for maps that change the default skills, or for alien eggs that need science/medical/anatomy instead + var/examine_difficulty = SKILL_ADEPT + +/obj/item/food/egg/examine(mob/user, distance, infix, suffix) + . = ..() + if(isnull(examine_difficulty) || !ispath(examine_skill)) + return + if(!user.skill_check(examine_skill, examine_difficulty)) + var/decl/skill/examine_skill_decl = GET_DECL(examine_skill) + to_chat(user, SPAN_SUBTLE("If you knew more about [lowertext(examine_skill_decl.name)], you could learn additional information about this.")) + return + if(distance > 1) + to_chat(user, SPAN_SUBTLE("You're too far away to learn anything about this.")) + return + if(!user.get_held_slot_for_item(src)) + to_chat(user, SPAN_NOTICE("You need to be holding \the [src] to examine it closer.")) + return + // need a lit candle or lantern to check + var/too_hot = FALSE + var/obj/item/candle // not necessarily an actual candle, just a light source that won't fry the egg + for(var/obj/item/I in user.get_held_items()) + if(I.light_power && I.light_range) // we have a light! todo: minimum power? + if(I.get_heat() >= /obj/item/flame/fuelled/lighter::lit_heat) // lighters are too hot! + too_hot = TRUE + candle = I + if(!too_hot) + break + if(too_hot) + to_chat(user, SPAN_WARNING("You can't use \the [candle] to examine \the [src], that would fry it!")) + return + else if(!candle) + to_chat(user, SPAN_NOTICE("You need to be holding a light source to examine this closer.")) + return + switch(amount_grown) + if(0) + to_chat(user, SPAN_NOTICE("\The [src] is unfertilized.")) + if(10 to 80) + to_chat(user, SPAN_NOTICE("There's something growing inside \the [src].")) + if(80 to 100) + to_chat(user, SPAN_NOTICE("\The [src] is about to hatch!")) /obj/item/food/egg/Destroy() if(amount_grown) From 1d29a2ea2c3fbf9bc25fd5054f5dd40aee8d4501 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 21 Aug 2024 17:36:34 -0400 Subject: [PATCH 4/9] Add a skill check to cow milking --- .../simple_animal/friendly/farm_animals.dm | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 0c3ed519830..8c753b14317 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -134,6 +134,9 @@ "looks at you with a resigned expression", "seems resigned to its fate" ) + var/decl/skill/milking_skill = SKILL_BOTANY + var/milking_skill_req = SKILL_BASIC + var/impatience = 0 // if you fail to milk it, this goes up. if it gets too high it'll flee /datum/mob_controller/cow emote_speech = list("moo?","moo","MOOOOOO") @@ -150,25 +153,68 @@ QDEL_NULL(udder) . = ..() -/mob/living/simple_animal/cow/attackby(var/obj/item/O, var/mob/user) - var/obj/item/chems/glass/G = O - if(stat == CONSCIOUS && istype(G) && ATOM_IS_OPEN_CONTAINER(G)) - if(G.reagents.total_volume >= G.volume) - to_chat(user, SPAN_WARNING("\The [O] is full.")) +/mob/living/simple_animal/cow/attackby(var/obj/item/used_item, var/mob/user) + var/obj/item/chems/container = used_item + if(stat == CONSCIOUS && istype(container) && ATOM_IS_OPEN_CONTAINER(container)) + if(get_automove_target()) + if(user.skill_check(milking_skill, SKILL_PROF)) + to_chat(user, SPAN_NOTICE("\The [src] goes still at your touch.")) + stop_automove() + else + to_chat(user, SPAN_WARNING("Wait for \the [src] to stop moving before you try milking it.")) + return TRUE + if(container.reagents.total_volume >= container.volume) + to_chat(user, SPAN_WARNING("\The [container] is full.")) + return TRUE + // Cows don't like being milked if you're unskilled. + if(user.skill_fail_prob(milking_skill, 40, milking_skill_req)) + if(impatience > 3) + visible_message(SPAN_WARNING("\The [src] bellows and flees from \the [user]!")) + flee(user, upset = TRUE) + else + visible_message(SPAN_WARNING("\The [src] huffs and moves away from \the [user].")) + flee(user, upset = FALSE) + impatience++ return TRUE if(!udder.total_volume) to_chat(user, SPAN_WARNING("The udder is dry. Wait a bit longer.")) return TRUE - user.visible_message(SPAN_NOTICE("\The [user] milks \the [src] using \the [O].")) - udder.trans_type_to(G, /decl/material/liquid/drink/milk, rand(5,10)) - if(G.reagents.total_volume >= G.volume) - to_chat(user, SPAN_NOTICE("\The [O] is full.")) + user.visible_message(SPAN_NOTICE("\The [user] starts milking \the [src] into \the [container]."), SPAN_NOTICE("You start milking \the [src] into \the [container].")) + if(!user.do_skilled(milking_skill, 4 SECONDS, milking_skill_req)) + user.visible_message(SPAN_NOTICE("\The [user] stops milking \the [src]."), SPAN_NOTICE("You stop milking \the [src].")) + return TRUE + user.visible_message(SPAN_NOTICE("\The [user] milks \the [src] into \the [container]."), SPAN_NOTICE("You milk \the [src] into \the [container].")) + udder.trans_type_to(container, /decl/material/liquid/drink/milk, rand(5,10)) + if(container.reagents.total_volume >= container.volume) + to_chat(user, SPAN_NOTICE("\The [container] is full.")) return TRUE . = ..() +/mob/living/simple_animal/cow/proc/flee(atom/target, upset = FALSE) + var/static/datum/automove_metadata/_cow_flee_automove_metadata = new( + _move_delay = null, + _acceptable_distance = 7, + _avoid_target = TRUE + ) + var/static/datum/automove_metadata/_cow_annoyed_automove_metadata = new( + _move_delay = null, + _acceptable_distance = 2, + _avoid_target = TRUE + ) + if(upset) + set_moving_quickly() + else + set_moving_slowly() + start_automove(target, metadata = upset ? _cow_flee_automove_metadata : _cow_annoyed_automove_metadata) + /mob/living/simple_animal/cow/handle_living_non_stasis_processes() - if((. = ..()) && udder && prob(5)) + . = ..() + if(!.) + return + if(udder && prob(5)) udder.add_reagent(/decl/material/liquid/drink/milk, rand(5, 10)) + if(!get_automove_target() && impatience > 0 && prob(10)) // if not fleeing, 10% chance to regain patience + impatience-- /mob/living/simple_animal/cow/default_disarm_interaction(mob/user) if(stat != DEAD && !HAS_STATUS(src, STAT_WEAK)) From 11aea9d53aacbd0984550d3f4f0b1c8148f6c005 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 21 Aug 2024 17:38:15 -0400 Subject: [PATCH 5/9] Add a skill check to goat milking --- .../simple_animal/friendly/farm_animals.dm | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 8c753b14317..bdb1418cdb6 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -11,7 +11,10 @@ natural_weapon = /obj/item/natural_weapon/hooves butchery_data = /decl/butchery_data/animal/ruminant/goat ai = /datum/mob_controller/aggressive/goat + // TODO: milkable extension to combine goat/cow behavior? var/datum/reagents/udder = null + var/decl/skill/milking_skill = SKILL_BOTANY + var/milking_skill_req = SKILL_BASIC /datum/mob_controller/aggressive/goat expected_type = /mob/living/simple_animal/hostile/goat @@ -104,17 +107,37 @@ if((. = ..()) && stat == CONSCIOUS && udder && prob(5)) udder.add_reagent(/decl/material/liquid/drink/milk, rand(5, 10)) -/mob/living/simple_animal/hostile/goat/attackby(var/obj/item/O, var/mob/user) - var/obj/item/chems/glass/G = O - if(stat == CONSCIOUS && istype(G) && ATOM_IS_OPEN_CONTAINER(G)) - user.visible_message("[user] milks [src] using \the [O].") - var/transfered = udder.trans_type_to(G, /decl/material/liquid/drink/milk, rand(5,10)) - if(G.reagents.total_volume >= G.volume) - to_chat(user, "\The [O] is full.") - if(!transfered) - to_chat(user, "The udder is dry. Wait a bit longer...") - else - ..() +/mob/living/simple_animal/hostile/goat/attackby(var/obj/item/used_item, var/mob/user) + var/obj/item/chems/container = used_item + if(stat == CONSCIOUS && istype(container) && ATOM_IS_OPEN_CONTAINER(container)) + if(ai?.is_enemy(user)) + if(user.skill_check(milking_skill, SKILL_PROF)) + to_chat(user, SPAN_NOTICE("\The [src] goes still at your touch.")) + ai.remove_enemy(user) + stop_automove() + else + to_chat(user, SPAN_DANGER("You can't milk \the [src] while it's trying to attack you!")) + return TRUE + if(container.reagents.total_volume >= container.volume) + to_chat(user, SPAN_WARNING("\The [container] is full.")) + return TRUE + // Goats REALLY don't like being milked if you're unskilled. + if(user.skill_fail_prob(milking_skill, 40, milking_skill_req)) + ai?.retaliate() + return TRUE + if(!udder.total_volume) + to_chat(user, SPAN_WARNING("The udder is dry. Wait a bit longer.")) + return TRUE + user.visible_message(SPAN_NOTICE("\The [user] starts milking \the [src] into \the [container]."), SPAN_NOTICE("You start milking \the [src] into \the [container].")) + if(!user.do_skilled(milking_skill, 4 SECONDS, milking_skill_req)) + user.visible_message(SPAN_NOTICE("\The [user] stops milking \the [src]."), SPAN_NOTICE("You stop milking \the [src].")) + return TRUE + user.visible_message(SPAN_NOTICE("\The [user] milks \the [src] into \the [container]."), SPAN_NOTICE("You milk \the [src] into \the [container].")) + udder.trans_type_to(container, /decl/material/liquid/drink/milk, rand(5,10)) + if(container.reagents.total_volume >= container.volume) + to_chat(user, SPAN_NOTICE("\The [container] is full.")) + return TRUE + . = ..() //cow /mob/living/simple_animal/cow From 60b5d12ae13291bfcb63a1f64b6f8c8e4304718d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 21 Aug 2024 17:44:27 -0400 Subject: [PATCH 6/9] Add animal husbandry skill overrides for Shaded Hills --- mods/content/fantasy/datum/skills.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mods/content/fantasy/datum/skills.dm b/mods/content/fantasy/datum/skills.dm index 9b368e9843d..054fddfecef 100644 --- a/mods/content/fantasy/datum/skills.dm +++ b/mods/content/fantasy/datum/skills.dm @@ -224,11 +224,16 @@ levels = list( "Unskilled" = "You know next to nothing about animals. You can feed and clean up after them, but you know nothing about their biology, their behavior, or raising their young.", "Basic" = "You've cared for farm animals before. You can care for the basic needs of an animal, and know how to do things like milk a cow or shear a sheep.
- Cows will not flee when you try to milk them.", - "Trained" = "You are proficient at animal handling, and can delicately handle even skittish animals without frightening them.
- Passive animals will not flee when you pick them up.", + "Trained" = "You are proficient at animal handling, and can delicately handle even skittish animals without frightening them.
- Passive animals will not flee when you pick them up.", // TODO: Implement this benefit "Experienced" = "You are an experienced animal caretaker with an encyclopedic knowledge of animals.", "Master" = "You're a specialized animal caretaker. You can care for even the most exotic, fragile, or dangerous animals." ) +/obj/item/food/egg/examine_skill = SKILL_HUSBANDRY +/mob/living/simple_animal/chick/examine_skill = SKILL_HUSBANDRY +/mob/living/simple_animal/cow/milking_skill = SKILL_HUSBANDRY +/mob/living/simple_animal/hostile/goat/milking_skill = SKILL_HUSBANDRY + /decl/skill/service/cooking name = "Cooking" desc = "Describes your skill at preparing meals and other consumable goods. This includes mixing alcoholic beverages." From 6bef0aaca68da4cfaaea9ac893cf8e4da5503223 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 21 Aug 2024 18:03:31 -0400 Subject: [PATCH 7/9] Make passive mobs try to escape when scooped --- code/datums/ai/_ai.dm | 5 +++++ code/datums/ai/passive.dm | 17 +++++++++++++++++ code/modules/mob_holder/holder_mobs.dm | 19 +++++++++++-------- mods/content/fantasy/datum/skills.dm | 3 ++- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/code/datums/ai/_ai.dm b/code/datums/ai/_ai.dm index 2633bc9bcf3..8720a796012 100644 --- a/code/datums/ai/_ai.dm +++ b/code/datums/ai/_ai.dm @@ -256,6 +256,11 @@ /datum/mob_controller/proc/check_memory(mob/speaker, message) return FALSE +/// General-purpose scooping reaction proc, used by /passive. +/// Returns TRUE if the scoop should proceed, FALSE if it should be canceled. +/datum/mob_controller/proc/scooped_by(mob/initiator) + return TRUE + // Enemy tracking - used on /aggressive /datum/mob_controller/proc/get_enemies() return _enemies diff --git a/code/datums/ai/passive.dm b/code/datums/ai/passive.dm index 6e959cea6a2..e28d0336aaf 100644 --- a/code/datums/ai/passive.dm +++ b/code/datums/ai/passive.dm @@ -54,3 +54,20 @@ if(istype(source)) flee_target = weakref(source) update_targets() + +/datum/mob_controller/passive + var/decl/skill/scooping_skill // If overridden (on a subtype, on a map/downstream, etc) check this skill to see if scooping should succeed uncontested. + var/scooping_skill_req = SKILL_ADEPT + +/datum/mob_controller/passive/scooped_by(mob/living/initiator) + if(is_friend(initiator)) + return TRUE + if(is_enemy(initiator) || (scooping_skill && initiator.skill_fail_prob(scooping_skill, 50, scooping_skill_req))) // scary, try to wriggle away + retaliate(initiator) // run! run like the wind! + if(!initiator.skill_fail_prob(SKILL_HAULING, 100, SKILL_EXPERT)) + to_chat(initiator, SPAN_WARNING("\The [body] tries to wriggle out of your grasp, but you hold on tight!")) + return TRUE + to_chat(initiator, SPAN_WARNING("\The [body] wriggles out of your grasp!")) + initiator.drop_from_inventory(body) + return FALSE + return TRUE \ No newline at end of file diff --git a/code/modules/mob_holder/holder_mobs.dm b/code/modules/mob_holder/holder_mobs.dm index d07a128335c..f2ba2cc988c 100644 --- a/code/modules/mob_holder/holder_mobs.dm +++ b/code/modules/mob_holder/holder_mobs.dm @@ -23,17 +23,20 @@ H.w_class = get_object_size() if(initiator == src) if(!target.equip_to_slot_if_possible(H, slot_back_str, del_on_fail=0, disable_warning=1)) - to_chat(initiator, "You can't climb onto [target]!") - return - to_chat(target, "\The [src] clambers onto you!") - to_chat(initiator, "You climb up onto \the [target]!") + to_chat(initiator, SPAN_WARNING("You can't climb onto [target]!")) + return FALSE + to_chat(target, SPAN_NOTICE("\The [src] clambers onto you!")) + to_chat(initiator, SPAN_NOTICE("You climb up onto \the [target]!")) else if(!target.put_in_hands(H)) - to_chat(initiator, "Your hands are full!") - return + to_chat(initiator, SPAN_WARNING("Your hands are full!")) + return FALSE + + if(!ai?.scooped_by(initiator)) + return FALSE // The AI canceled the scooping. - to_chat(initiator, "You scoop up \the [src]!") - to_chat(src, "\The [initiator] scoops you up!") + to_chat(initiator, SPAN_NOTICE("You scoop up \the [src]!")) + to_chat(src, SPAN_NOTICE("\The [initiator] scoops you up!")) forceMove(H) reset_offsets(0) diff --git a/mods/content/fantasy/datum/skills.dm b/mods/content/fantasy/datum/skills.dm index 054fddfecef..a2e6fa90f4b 100644 --- a/mods/content/fantasy/datum/skills.dm +++ b/mods/content/fantasy/datum/skills.dm @@ -224,7 +224,7 @@ levels = list( "Unskilled" = "You know next to nothing about animals. You can feed and clean up after them, but you know nothing about their biology, their behavior, or raising their young.", "Basic" = "You've cared for farm animals before. You can care for the basic needs of an animal, and know how to do things like milk a cow or shear a sheep.
- Cows will not flee when you try to milk them.", - "Trained" = "You are proficient at animal handling, and can delicately handle even skittish animals without frightening them.
- Passive animals will not flee when you pick them up.", // TODO: Implement this benefit + "Trained" = "You are proficient at animal handling, and can delicately handle even skittish animals without frightening them.
- Passive animals will not flee when you pick them up.", "Experienced" = "You are an experienced animal caretaker with an encyclopedic knowledge of animals.", "Master" = "You're a specialized animal caretaker. You can care for even the most exotic, fragile, or dangerous animals." ) @@ -233,6 +233,7 @@ /mob/living/simple_animal/chick/examine_skill = SKILL_HUSBANDRY /mob/living/simple_animal/cow/milking_skill = SKILL_HUSBANDRY /mob/living/simple_animal/hostile/goat/milking_skill = SKILL_HUSBANDRY +/datum/mob_controller/passive/scooping_skill = SKILL_HUSBANDRY /decl/skill/service/cooking name = "Cooking" From f4a2b0f61111b3e2ba69e53be987d49b6c6f2989 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 21 Aug 2024 18:24:06 -0400 Subject: [PATCH 8/9] Make chicken eggs more fertile but slower-growing and less frequent --- .../living/simple_animal/friendly/farm_animals.dm | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index bdb1418cdb6..ee8e609154b 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -296,7 +296,8 @@ /mob/living/simple_animal/chick/handle_living_non_stasis_processes() if((. = ..())) - amount_grown += rand(1,2) + if(prob(50)) // should take around 4 or 5 minutes to grow up, give or take + amount_grown += rand(1, 2) if(amount_grown >= 100) new /mob/living/simple_animal/fowl/chicken(src.loc) qdel(src) @@ -364,10 +365,10 @@ var/global/chicken_count = 0 if(istype(O, /obj/item/food)) //feedin' dem chickens var/obj/item/food/G = O if(findtext(G.get_grown_tag(), "wheat")) // includes chopped, crushed, dried etc. - if(!stat && eggsleft < 8) + if(!stat && eggsleft < 4) user.visible_message(SPAN_NOTICE("[user] feeds \the [O] to \the [src]! It clucks happily."), SPAN_NOTICE("You feed \the [O] to \the [src]! It clucks happily."), SPAN_NOTICE("You hear clucking.")) qdel(O) - eggsleft += rand(1, 4) + eggsleft += rand(1, 2) else to_chat(user, SPAN_NOTICE("\The [src] doesn't seem hungry!")) else @@ -376,13 +377,13 @@ var/global/chicken_count = 0 ..() /mob/living/simple_animal/fowl/chicken/handle_living_non_stasis_processes() - if((. = ..()) && prob(3) && eggsleft > 0) + if((. = ..()) && prob(1) && eggsleft > 0) visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]") eggsleft-- var/obj/item/food/egg/E = new(get_turf(src)) E.pixel_x = rand(-6,6) E.pixel_y = rand(-6,6) - if(chicken_count < MAX_CHICKENS && prob(10)) + if(chicken_count < MAX_CHICKENS && prob(30)) E.amount_grown = 1 START_PROCESSING(SSobj, E) @@ -465,7 +466,8 @@ var/global/chicken_count = 0 /obj/item/food/egg/Process() if(isturf(loc)) - amount_grown += rand(1,2) + if(prob(50)) + amount_grown++ if(amount_grown >= 100) visible_message("[src] hatches with a quiet cracking sound.") new /mob/living/simple_animal/chick(get_turf(src)) From 5134bf7be8b385ec2f20526380bf8e1aae21e1eb Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 21 Aug 2024 19:03:44 -0400 Subject: [PATCH 9/9] Add minimum animal husbandry skill levels to farmer and forester --- maps/shaded_hills/jobs/inn.dm | 1 + maps/shaded_hills/jobs/wilderness.dm | 1 + 2 files changed, 2 insertions(+) diff --git a/maps/shaded_hills/jobs/inn.dm b/maps/shaded_hills/jobs/inn.dm index 11adfde1a96..5d3209ffebd 100644 --- a/maps/shaded_hills/jobs/inn.dm +++ b/maps/shaded_hills/jobs/inn.dm @@ -86,6 +86,7 @@ outfit_type = /decl/outfit/job/shaded_hills/farmer min_skill = list( SKILL_HAULING = SKILL_ADEPT, // farming can be demanding work + SKILL_HUSBANDRY = SKILL_ADEPT, // must be able to pick up and milk animals SKILL_BOTANY = SKILL_ADEPT, // must be skilled enough to have plants reliably survive when planted ) skill_points = 18 diff --git a/maps/shaded_hills/jobs/wilderness.dm b/maps/shaded_hills/jobs/wilderness.dm index c1562cd9ca5..2ae6a03ef70 100644 --- a/maps/shaded_hills/jobs/wilderness.dm +++ b/maps/shaded_hills/jobs/wilderness.dm @@ -56,6 +56,7 @@ outfit_type = /decl/outfit/job/shaded_hills/forester min_skill = list( SKILL_HAULING = SKILL_ADEPT, // overall physical activity + SKILL_HUSBANDRY = SKILL_BASIC, // handling and caring for animals SKILL_BOTANY = SKILL_BASIC, // growing and harvesting plants, trees, etc SKILL_COOKING = SKILL_BASIC, // butchery SKILL_CARPENTRY = SKILL_ADEPT, // tree felling