makes the pinguin a basic animal (#76790)

## About The Pull Request
the penguin now is a basic animal and also now he can go and layed
penguin eggs to make penguin babys also the baby have a new behavier he
will now go and looked for his mom and when he found his mom he will
went to her and be happy when he close to his mom or if he mom is died
he will went to her body and he will be sad and also i putted this
behavier in the baby chicken. also now the pinguen mom will go and
looked for her eggs and when she find a egg she will putted it in the
middile of her legs and walked with it
![penguin with a
eggs](https://github.com/tgstation/tgstation/assets/138636438/e5f3d741-edc0-438f-b1b3-9e4ed2280532)


## Why It's Good For The Game
the pinguen now is a advance ai
## Changelog
the pinguen now have a more advance    

🆑
refactor: the penguin is a basic animal
add: the penguin now layed eggs
add: the penguin and the chicken babys will go look for adult penguin or
chicken and be happy when he is near the adult
/🆑
This commit is contained in:
Ben10Omintrix
2023-07-18 13:03:00 -06:00
committed by GitHub
parent 12102ae0a6
commit b06e940341
20 changed files with 310 additions and 78 deletions
+2 -2
View File
@@ -2548,7 +2548,7 @@
/turf/open/misc/asteroid/snow/snow_cabin,
/area/awaymission/cabin/caves)
"jp" = (
/mob/living/simple_animal/pet/penguin/baby,
/mob/living/basic/pet/penguin/baby/permanent,
/turf/open/misc/ice/smooth,
/area/awaymission/cabin/snowforest)
"jq" = (
@@ -3561,7 +3561,7 @@
/turf/open/misc/asteroid/snow/snow_cabin,
/area/awaymission/cabin/caves)
"rH" = (
/mob/living/simple_animal/pet/penguin/emperor,
/mob/living/basic/pet/penguin/emperor,
/turf/open/misc/ice/smooth,
/area/awaymission/cabin/snowforest)
"so" = (
@@ -23541,7 +23541,7 @@
pixel_x = -6;
pixel_y = -3
},
/mob/living/simple_animal/pet/penguin/baby,
/mob/living/basic/pet/penguin/baby/permanent,
/turf/open/misc/asteroid/snow/standard_air,
/area/station/science/research)
"hyY" = (
@@ -35315,7 +35315,7 @@
/area/station/command/bridge)
"lkP" = (
/obj/structure/flora/grass/green/style_random,
/mob/living/simple_animal/pet/penguin/emperor{
/mob/living/basic/pet/penguin/emperor{
name = "Club"
},
/turf/open/misc/asteroid/snow/standard_air,
+1 -1
View File
@@ -60289,7 +60289,7 @@
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
"vHl" = (
/mob/living/simple_animal/pet/penguin/baby{
/mob/living/basic/pet/penguin/baby/permanent{
dir = 8
},
/turf/open/floor/grass,
+2 -2
View File
@@ -23567,7 +23567,7 @@
/turf/open/floor/iron/white/herringbone,
/area/station/medical/patients_rooms)
"gdd" = (
/mob/living/simple_animal/pet/penguin/emperor{
/mob/living/basic/pet/penguin/emperor{
desc = "Spaghetti.";
name = "Spaghetti"
},
@@ -55498,7 +55498,7 @@
/turf/open/floor/iron/white,
/area/station/science/lobby)
"onY" = (
/mob/living/simple_animal/pet/penguin/baby{
/mob/living/basic/pet/penguin/baby/permanent{
dir = 8
},
/turf/open/floor/fake_snow{
+1 -1
View File
@@ -111,7 +111,7 @@
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/escape)
"hH" = (
/mob/living/simple_animal/pet/penguin/baby,
/mob/living/basic/pet/penguin/baby/permanent,
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/escape)
"iI" = (
+8
View File
@@ -284,6 +284,14 @@
///Current partner target
#define BB_BABIES_TARGET "BB_babies_target"
///Finding adult mob
///key holds the adult we found
#define BB_FOUND_MOM "BB_found_mom"
///list of types of mobs we will look for
#define BB_FIND_MOM_TYPES "BB_find_mom_types"
///list of types of mobs we must ignore
#define BB_IGNORE_MOM_TYPES "BB_ignore_mom_types"
// Bileworm AI keys
#define BB_BILEWORM_SPEW_BILE "BB_bileworm_spew_bile"
+2 -2
View File
@@ -59,13 +59,13 @@ GLOBAL_LIST_INIT(phobia_mobs, list(
"birds" = typecacheof(list(
/mob/living/basic/chick,
/mob/living/basic/chicken,
/mob/living/basic/pet/penguin,
/mob/living/simple_animal/parrot,
/mob/living/simple_animal/pet/penguin,
)),
"conspiracies" = typecacheof(list(
/mob/living/simple_animal/bot/secbot,
/mob/living/simple_animal/drone,
/mob/living/simple_animal/pet/penguin,
/mob/living/basic/pet/penguin,
)),
"doctors" = typecacheof(list(/mob/living/simple_animal/bot/medbot)),
"insects" = typecacheof(list(
@@ -0,0 +1,28 @@
/datum/ai_behavior/find_mom
///range to look for the mom
var/look_range = 7
/datum/ai_behavior/find_mom/perform(seconds_per_tick, datum/ai_controller/controller, mom_key, ignore_mom_key, found_mom)
. = ..()
var/mob/living_pawn = controller.pawn
var/list/mom_types = controller.blackboard[mom_key]
var/list/all_moms = list()
var/list/ignore_types = controller.blackboard[ignore_mom_key]
if(!length(mom_types))
finish_action(controller, FALSE)
return
for(var/mob/mother in oview(look_range, living_pawn))
if(!is_type_in_list(mother, mom_types))
continue
if(is_type_in_list(mother, ignore_types)) //so the not permanent baby and the permanent baby subtype dont followed each other
continue
all_moms += mother
if(length(all_moms))
controller.set_blackboard_key(found_mom, pick(all_moms))
finish_action(controller, TRUE)
return
finish_action(controller, FALSE)
@@ -0,0 +1,25 @@
/datum/ai_planning_subtree/look_for_adult
///how far we must be from the mom
var/minimum_distance = 1
/datum/ai_planning_subtree/look_for_adult/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/mob/target = controller.blackboard[BB_FOUND_MOM]
var/mob/baby = controller.pawn
if(QDELETED(target))
controller.queue_behavior(/datum/ai_behavior/find_mom, BB_FIND_MOM_TYPES, BB_IGNORE_MOM_TYPES, BB_FOUND_MOM)
return
if(get_dist(target, baby) > minimum_distance)
controller.queue_behavior(/datum/ai_behavior/travel_towards, BB_FOUND_MOM)
return SUBTREE_RETURN_FINISH_PLANNING
if(!SPT_PROB(15, seconds_per_tick))
return
if(target.stat == DEAD)
controller.queue_behavior(/datum/ai_behavior/perform_emote, "cries for their parent!")
else
controller.queue_behavior(/datum/ai_behavior/perform_emote, "dances around their parent!")
return SUBTREE_RETURN_FINISH_PLANNING
@@ -175,3 +175,8 @@
emote_hear = list("howls.", "barks.", "screams.")
emote_see = list("shakes their head.", "shivers.")
speak = list("Ack-Ack", "Ack-Ack-Ack-Ackawoooo", "Geckers", "Awoo", "Tchoff")
/datum/ai_planning_subtree/random_speech/penguin
speech_chance = 5
speak = list("Gah Gah!", "NOOT NOOT!", "NOOT!", "Noot", "noot", "Prah!", "Grah!")
emote_hear = list("squawks", "gakkers")
+4
View File
@@ -162,6 +162,10 @@ GLOBAL_VAR_INIT(chicks_from_eggs, 0)
icon_state = "egg-yellow"
inhand_icon_state = "egg-yellow"
/obj/item/food/egg/penguin_egg
icon = 'icons/mob/simple/penguins.dmi'
icon_state = "penguin_egg"
/obj/item/food/egg/fertile
name = "fertile-looking egg"
desc = "An egg! It looks fertilized.\nQuite how you can tell this just by looking at it is a mystery."
+6 -1
View File
@@ -95,7 +95,12 @@ GLOBAL_LIST_INIT(adventure_loot_generator_index,generate_generator_index())
/datum/adventure_loot_generator/pet
id = "pets"
var/carrier_type = /obj/item/pet_carrier/biopod
var/list/possible_pets = list(/mob/living/simple_animal/pet/cat/space,/mob/living/basic/pet/dog/corgi,/mob/living/simple_animal/pet/penguin/baby,/mob/living/basic/pet/dog/pug)
var/list/possible_pets = list(
/mob/living/basic/pet/dog/corgi,
/mob/living/basic/pet/dog/pug,
/mob/living/basic/pet/penguin/baby,
/mob/living/simple_animal/pet/cat/space,
)
/datum/adventure_loot_generator/pet/generate()
var/obj/item/pet_carrier/carrier = new carrier_type()
+3 -3
View File
@@ -104,15 +104,15 @@
mobtype = /mob/living/simple_animal/holodeck_monkey
/obj/effect/holodeck_effect/mobspawner/penguin
mobtype = /mob/living/simple_animal/pet/penguin/emperor
mobtype = /mob/living/basic/pet/penguin/emperor/neuter
/obj/effect/holodeck_effect/mobspawner/penguin/Initialize(mapload)
if(prob(1))
mobtype = /mob/living/simple_animal/pet/penguin/emperor/shamebrero
mobtype = /mob/living/basic/pet/penguin/emperor/shamebrero/neuter
return ..()
/obj/effect/holodeck_effect/mobspawner/penguin_baby
mobtype = /mob/living/simple_animal/pet/penguin/baby
mobtype = /mob/living/basic/pet/penguin/baby/permanent
/obj/effect/holodeck_effect/mobspawner/crab/jon
mobtype = /mob/living/simple_animal/crab/jon
@@ -28,6 +28,7 @@
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
gold_core_spawnable = FRIENDLY_SPAWN
ai_controller = /datum/ai_controller/basic_controller/chick
/// What we grow into.
var/grow_as = /mob/living/basic/chicken
@@ -62,3 +63,17 @@
/// Variant of chick that just spawns in the holodeck so you can pet it. Doesn't grow up.
/mob/living/basic/chick/permanent
grow_as = null
/datum/ai_controller/basic_controller/chick
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
BB_FIND_MOM_TYPES = list(/mob/living/basic/chicken),
)
ai_traits = 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/look_for_adult,
)
@@ -0,0 +1,199 @@
/mob/living/basic/pet/penguin
icon = 'icons/mob/simple/penguins.dmi'
gender = FEMALE
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "bops"
response_disarm_simple = "bop"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
faction = list(FACTION_NEUTRAL)
ai_controller = /datum/ai_controller/basic_controller/penguin
///it can lay an egg?
var/can_lay_eggs = TRUE
///the egg it carries
var/obj/carried_egg
/mob/living/basic/pet/penguin/Initialize(mapload)
. = ..()
AddElement(/datum/element/ai_retaliate)
AddElement(/datum/element/ai_flee_while_injured)
AddElement(/datum/element/pet_bonus, "honks happily!")
AddElement(/datum/element/waddling)
if(!can_lay_eggs)
return
AddComponent(\
/datum/component/egg_layer,\
/obj/item/food/egg/penguin_egg,\
list(/obj/item/food/fishmeat),\
lay_messages = EGG_LAYING_MESSAGES,\
eggs_left = 0,\
eggs_added_from_eating = 1,\
max_eggs_held = 1,\
egg_laid_callback = CALLBACK(src, PROC_REF(lay_penguin_egg)),\
)
/mob/living/basic/pet/penguin/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
. = ..()
if(!.)
return
if(!proximity_flag)
return
if(!istype(attack_target, /obj/item/food/egg/penguin_egg))
return
remove_egg() //to check if we already have a egg
var/obj/item/egg_target = attack_target
egg_target.forceMove(src)
carried_egg = attack_target
add_overlay("penguin_egg_overlay")
RegisterSignal(egg_target, COMSIG_QDELETING, PROC_REF(on_hatch_egg))
/mob/living/basic/pet/penguin/death(gibbed)
. = ..()
remove_egg()
/mob/living/basic/pet/penguin/proc/lay_penguin_egg(obj/item/penguin_egg)
if(prob(35))
penguin_egg.AddComponent(\
/datum/component/fertile_egg,\
embryo_type = /mob/living/basic/pet/penguin/baby,\
minimum_growth_rate = 1,\
maximum_growth_rate = 2,\
total_growth_required = 400,\
current_growth = 0,\
location_allowlist = typecacheof(list(/turf, /mob/living/basic/pet/penguin)),\
)
/mob/living/basic/pet/penguin/proc/on_hatch_egg()
SIGNAL_HANDLER
remove_egg()
/mob/living/basic/pet/penguin/proc/remove_egg()
if(isnull(carried_egg))
return
carried_egg.forceMove(get_turf(src))
UnregisterSignal(carried_egg, COMSIG_QDELETING)
carried_egg = null
cut_overlay("penguin_egg_overlay")
/datum/ai_controller/basic_controller/penguin
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
)
ai_traits = 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_and_hunt_target/penguin_egg,
/datum/ai_planning_subtree/random_speech/penguin,
)
/datum/ai_planning_subtree/find_and_hunt_target/penguin_egg
target_key = BB_LOW_PRIORITY_HUNTING_TARGET
hunting_behavior = /datum/ai_behavior/hunt_target/penguin_egg
finding_behavior = /datum/ai_behavior/find_hunt_target/penguin_egg
hunt_targets = list(/obj/item/food/egg/penguin_egg)
hunt_range = 7
/datum/ai_behavior/find_hunt_target/penguin_egg/valid_dinner(mob/living/source, atom/dinner, radius)
return can_see(source, dinner, radius) && !(dinner in source.contents)
/datum/ai_behavior/hunt_target/penguin_egg
hunt_cooldown = 15 SECONDS
always_reset_target = TRUE
/datum/ai_behavior/hunt_target/penguin_egg/target_caught(mob/living/basic/hunter, obj/item/food/egg/target)
hunter.UnarmedAttack(target, TRUE)
/mob/living/basic/pet/penguin/emperor
name = "emperor penguin"
real_name = "penguin"
desc = "Emperor of all she surveys."
icon_state = "penguin"
icon_living = "penguin"
icon_dead = "penguin_dead"
gold_core_spawnable = FRIENDLY_SPAWN
/mob/living/basic/pet/penguin/emperor/neuter
can_lay_eggs = FALSE
/mob/living/basic/pet/penguin/emperor/shamebrero
name = "shamebrero penguin"
icon_state = "penguin_shamebrero"
icon_living = "penguin_shamebrero"
gold_core_spawnable = NO_SPAWN
unique_pet = TRUE
/mob/living/basic/pet/penguin/emperor/shamebrero/neuter
can_lay_eggs = FALSE
/mob/living/basic/pet/penguin/baby
name = "penguin chick"
real_name = "penguin"
desc = "Can't fly and barely waddles, yet the prince of all chicks."
icon_state = "penguin_baby"
icon_living = "penguin_baby"
icon_dead = "penguin_baby_dead"
density = FALSE
pass_flags = PASSMOB
mob_size = MOB_SIZE_SMALL
butcher_results = list(/obj/item/organ/internal/ears/penguin = 1, /obj/item/food/meat/slab/penguin = 1)
ai_controller = /datum/ai_controller/basic_controller/penguin/baby
can_lay_eggs = FALSE
///will it grow up?
var/can_grow_up = TRUE
/mob/living/basic/pet/penguin/baby/Initialize(mapload)
. = ..()
if(!can_grow_up)
return
var/list/weight_mobtypes = list(
/mob/living/basic/pet/penguin/emperor = 5,
/mob/living/basic/pet/penguin/emperor/shamebrero = 1,
)
var/grown_type = pick_weight(weight_mobtypes)
AddComponent(\
/datum/component/growth_and_differentiation,\
growth_time = null,\
growth_path = grown_type,\
growth_probability = 100,\
lower_growth_value = 0.5,\
upper_growth_value = 1,\
signals_to_kill_on = list(COMSIG_MOB_CLIENT_LOGIN),\
optional_checks = CALLBACK(src, PROC_REF(ready_to_grow)),\
)
/mob/living/basic/pet/penguin/baby/proc/ready_to_grow()
return (stat == CONSCIOUS)
/datum/ai_controller/basic_controller/penguin/baby
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
BB_FIND_MOM_TYPES = list(/mob/living/basic/pet/penguin),
BB_IGNORE_MOM_TYPES = list(/mob/living/basic/pet/penguin/baby),
)
ai_traits = 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/look_for_adult,
)
/mob/living/basic/pet/penguin/baby/permanent
can_grow_up = FALSE
@@ -1,59 +0,0 @@
//Penguins
/mob/living/simple_animal/pet/penguin
gender = MALE
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "bops"
response_disarm_simple = "bop"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
speak = list("Gah Gah!", "NOOT NOOT!", "NOOT!", "Noot", "noot", "Prah!", "Grah!")
speak_emote = list("squawks", "gakkers")
emote_hear = list("squawk!", "gakkers!", "noots.","NOOTS!")
emote_see = list("shakes his beak.", "flaps his wings.","preens himself.")
faction = list(FACTION_PENGUIN)
minbodytemp = 0
speak_chance = 1
turns_per_move = 10
icon = 'icons/mob/simple/penguins.dmi'
butcher_results = list(/obj/item/organ/internal/ears/penguin = 1, /obj/item/food/meat/slab/penguin = 3)
footstep_type = FOOTSTEP_MOB_BAREFOOT
/mob/living/simple_animal/pet/penguin/Initialize(mapload)
. = ..()
AddElement(/datum/element/pet_bonus, "honks happily!")
AddElement(/datum/element/waddling)
/mob/living/simple_animal/pet/penguin/emperor
name = "Emperor penguin"
real_name = "penguin"
desc = "Emperor of all he surveys."
icon_state = "penguin"
icon_living = "penguin"
icon_dead = "penguin_dead"
gold_core_spawnable = FRIENDLY_SPAWN
butcher_results = list(/obj/item/organ/internal/ears/penguin = 1, /obj/item/food/meat/slab/penguin = 3)
/mob/living/simple_animal/pet/penguin/emperor/shamebrero
name = "Shamebrero penguin"
desc = "Shameful of all he surveys."
icon_state = "penguin_shamebrero"
icon_living = "penguin_shamebrero"
gold_core_spawnable = NO_SPAWN
unique_pet = TRUE
/mob/living/simple_animal/pet/penguin/baby
speak = list("gah", "noot noot", "noot!", "noot", "squeee!", "noo!")
name = "Penguin chick"
real_name = "penguin"
desc = "Can't fly and barely waddles, yet the prince of all chicks."
icon_state = "penguin_baby"
icon_living = "penguin_baby"
icon_dead = "penguin_baby_dead"
density = FALSE
pass_flags = PASSMOB
mob_size = MOB_SIZE_SMALL
butcher_results = list(/obj/item/organ/internal/ears/penguin = 1, /obj/item/food/meat/slab/penguin = 1)
@@ -270,10 +270,6 @@
/mob/living/simple_animal/pet/cat/space,
/mob/living/simple_animal/pet/gondola,
/mob/living/simple_animal/pet/gondola/gondolapod,
/mob/living/simple_animal/pet/penguin,
/mob/living/simple_animal/pet/penguin/baby,
/mob/living/simple_animal/pet/penguin/emperor,
/mob/living/simple_animal/pet/penguin/emperor/shamebrero,
/mob/living/simple_animal/revenant,
/mob/living/simple_animal/robot_customer,
/mob/living/simple_animal/shade,
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

+3 -1
View File
@@ -766,6 +766,7 @@
#include "code\datums\ai\bane\bane_subtrees.dm"
#include "code\datums\ai\basic_mobs\base_basic_controller.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\basic_attacking.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\find_parent.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\nearest_targetting.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\pick_up_item.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\run_away_from_target.dm"
@@ -780,6 +781,7 @@
#include "code\datums\ai\basic_mobs\basic_subtrees\attack_obstacle_in_path.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\find_food.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\find_paper_and_write.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\find_parent.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\flee_target.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\opportunistic_ventcrawler.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\simple_attack_target.dm"
@@ -4053,6 +4055,7 @@
#include "code\modules\mob\living\basic\lavaland\goliath\tentacle.dm"
#include "code\modules\mob\living\basic\pets\dog.dm"
#include "code\modules\mob\living\basic\pets\fox.dm"
#include "code\modules\mob\living\basic\pets\penguin.dm"
#include "code\modules\mob\living\basic\pets\pet.dm"
#include "code\modules\mob\living\basic\ruin_defender\stickman.dm"
#include "code\modules\mob\living\basic\space_fauna\ant.dm"
@@ -4276,7 +4279,6 @@
#include "code\modules\mob\living\simple_animal\friendly\crab.dm"
#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm"
#include "code\modules\mob\living\simple_animal\friendly\gondola.dm"
#include "code\modules\mob\living\simple_animal\friendly\penguin.dm"
#include "code\modules\mob\living\simple_animal\friendly\pet.dm"
#include "code\modules\mob\living\simple_animal\friendly\robot_customer.dm"
#include "code\modules\mob\living\simple_animal\friendly\sloth.dm"
@@ -0,0 +1,4 @@
/mob/living/simple_animal/pet/penguin : /mob/living/basic/pet/penguin{@OLD}
/mob/living/simple_animal/pet/penguin/emperor : /mob/living/basic/pet/penguin/emperor{@OLD}
/mob/living/simple_animal/pet/penguin/emperor/shamebrero : /mob/living/basic/pet/penguin/emperor/shamebrero{@OLD}
/mob/living/simple_animal/pet/penguin/baby : /mob/living/basic/pet/penguin/baby/permanent{@OLD}