From ebc0227176b5213f379eefc3f5c6aa7be2d09c0a Mon Sep 17 00:00:00 2001 From: Tastyfish Date: Mon, 5 Dec 2022 15:13:13 -0500 Subject: [PATCH] Makes dog a basic mob [MDB IGNORE] (#70799) About The Pull Request Made a basic version of the pet base called /mob/living/basic/pet. It's significantly more stripped down from the old simple_animal one, because its half collar stuff and... Made the collar slot a component that you could theoretically remove from a pet to disable the behavior, or add to any other living mob as long as you set up the icon states for the collar (or not, the visuals are optional). The corgi's collar strippable slot is now generally the pet collar slot, and in theory could be used for other pet stripping screens. I also gutted the extra access card code from /mob/living/basic/pet as it's only being used by corgis. Having a physical ID is now just inherent to corgis, as they're the only ones that could equip it anyway. Ported the make_babies() function from simple_animals to a new subtree and associated behavior, called /datum/ai_planning_subtree/make_babies that uses blackboards to know the animal-specific info. Note that it's marginally improved, as the female walks to the male first instead of bluespace reproduction. Tweaked and improved the dog AI to work as a basic mob, including making /datum/idle_behavior/idle_dog fully functional. Made a /datum/ai_planning_subtree/random_speech/dog that pulls the dynamic speech and emotes to support dog fashion. I've tested base collars across multiple pet types. For dogs, I've tested general behavior, fetching, reproduction, dog fashion, and deadchat_plays, covering all the oddities I'm aware of. image Why It's Good For The Game Very big mob converted to a basic mob. Changelog cl fix: Lisa no longer uses bluespace when interacting with Ian. refactor: A large portion of dog code was re-written; please report any strange bugs. /cl --- .../IceRuins/icemoon_underground_mailroom.dmm | 2 +- .../map_files/Deltastation/DeltaStation2.dmm | 4 +- .../map_files/IceBoxStation/IceBoxStation.dmm | 4 +- _maps/map_files/KiloStation/KiloStation.dmm | 2 +- _maps/map_files/MetaStation/MetaStation.dmm | 10 +- .../maintenance_lowerdorm_2.dmm | 2 +- _maps/map_files/tramstation/tramstation.dmm | 6 +- code/__DEFINES/ai.dm | 9 + .../signals/signals_mob/signals_mob_living.dm | 6 + code/__DEFINES/is_helpers.dm | 4 +- code/__DEFINES/strippable.dm | 2 +- code/datums/ai/babies/babies_behaviors.dm | 77 +++++ code/datums/ai/babies/babies_subtrees.dm | 34 ++ .../basic_subtrees/speech_subtree.dm | 13 + code/datums/ai/dog/dog_controller.dm | 70 ++-- code/datums/ai/idle_behaviors/idle_dog.dm | 9 +- code/datums/brain_damage/severe.dm | 2 +- code/datums/components/creamed.dm | 2 +- code/datums/diseases/transformation.dm | 2 +- code/datums/dog_fashion.dm | 16 +- code/datums/holocall.dm | 2 +- code/datums/memory/memory.dm | 6 +- code/datums/station_traits/neutral_traits.dm | 6 +- code/game/machinery/washing_machine.dm | 6 +- .../objects/effects/spawners/gibspawner.dm | 2 +- .../objects/structures/petrified_statue.dm | 2 +- .../heretic/magic/eldritch_shapeshift.dm | 2 +- .../traitor/objectives/kill_pet.dm | 6 +- code/modules/cargo/packs/livestock.dm | 12 +- code/modules/events/ghost_role/sentience.dm | 1 + code/modules/events/holiday/halloween.dm | 2 +- .../experisci/experiment/experiments.dm | 2 +- code/modules/explorer_drone/loot.dm | 2 +- .../recipes/tablecraft/recipes_bread.dm | 2 +- code/modules/holiday/holidays.dm | 2 +- code/modules/holodeck/holo_effect.dm | 6 +- .../jobs/job_types/head_of_personnel.dm | 2 +- .../friendly => basic/pets}/dog.dm | 307 ++++++++++-------- code/modules/mob/living/basic/pets/pet.dm | 150 +++++++++ code/modules/mob/living/death.dm | 1 + code/modules/mob/living/living.dm | 7 +- .../mob/living/simple_animal/friendly/cat.dm | 15 +- .../living/simple_animal/friendly/gondola.dm | 4 - .../mob/living/simple_animal/friendly/pet.dm | 159 ++++++--- code/modules/mob/transform_procs.dm | 4 +- .../reagents/chemistry/recipes/others.dm | 2 +- code/modules/research/experimentor.dm | 12 +- .../xenobiology/crossbreeding/_mobs.dm | 9 +- .../xenobiology/crossbreeding/chilling.dm | 2 +- .../vatgrowing/samples/cell_lines/common.dm | 4 +- .../spell_types/shapeshift/shapechange.dm | 2 +- code/modules/unit_tests/mindbound_actions.dm | 3 +- .../unit_tests/simple_animal_freeze.dm | 14 - code/modules/unit_tests/strippable.dm | 2 +- tgstation.dme | 5 +- tgui/packages/tgui/interfaces/StripMenu.tsx | 2 +- tools/UpdatePaths/Scripts/70799_dog.txt | 1 + 57 files changed, 729 insertions(+), 315 deletions(-) create mode 100644 code/datums/ai/babies/babies_behaviors.dm create mode 100644 code/datums/ai/babies/babies_subtrees.dm rename code/modules/mob/living/{simple_animal/friendly => basic/pets}/dog.dm (73%) create mode 100644 code/modules/mob/living/basic/pets/pet.dm create mode 100644 tools/UpdatePaths/Scripts/70799_dog.txt diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm index 7ab76dc075a..5a9f25c7d29 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_mailroom.dmm @@ -227,7 +227,7 @@ dir = 4 }, /obj/item/pressure_plate/hologrid{ - reward = /mob/living/simple_animal/pet/dog/bullterrier + reward = /mob/living/basic/pet/dog/bullterrier }, /turf/open/floor/plating, /area/ruin/powered/mailroom) diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index a98f4bd8f87..74499feea31 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -48819,7 +48819,7 @@ "lNN" = ( /obj/effect/turf_decal/tile/red/anticorner/contrasted, /obj/structure/bed/dogbed/mcgriff, -/mob/living/simple_animal/pet/dog/pug/mcgriff, +/mob/living/basic/pet/dog/pug/mcgriff, /turf/open/floor/iron, /area/station/security/warden) "lNR" = ( @@ -55213,7 +55213,7 @@ "nuY" = ( /obj/structure/bed/dogbed/ian, /obj/machinery/airalarm/directional/east, -/mob/living/simple_animal/pet/dog/corgi/ian, +/mob/living/basic/pet/dog/corgi/ian, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) "nvo" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index e0eaa6a086f..e1c97776635 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -28188,7 +28188,7 @@ /obj/structure/bed/dogbed/mcgriff, /obj/item/food/beef_wellington_slice, /obj/structure/cable, -/mob/living/simple_animal/pet/dog/pug/mcgriff, +/mob/living/basic/pet/dog/pug/mcgriff, /turf/open/floor/iron/showroomfloor, /area/station/security/warden) "iFm" = ( @@ -32685,7 +32685,7 @@ /area/station/ai_monitored/turret_protected/aisat/hallway) "jXB" = ( /obj/structure/bed/dogbed/ian, -/mob/living/simple_animal/pet/dog/corgi/ian{ +/mob/living/basic/pet/dog/corgi/ian{ dir = 8 }, /turf/open/floor/iron, diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index bb8be61045b..8c39fed3be5 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -41950,7 +41950,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 8 }, -/mob/living/simple_animal/pet/dog/corgi/ian{ +/mob/living/basic/pet/dog/corgi/ian{ dir = 8 }, /turf/open/floor/wood, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 80c03069fa8..84d2d1b56a2 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -17387,7 +17387,7 @@ "gvl" = ( /obj/machinery/status_display/evac/directional/north, /obj/structure/bed/dogbed/ian, -/mob/living/simple_animal/pet/dog/corgi/ian, +/mob/living/basic/pet/dog/corgi/ian, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) "gvm" = ( @@ -19082,7 +19082,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 9 }, -/mob/living/simple_animal/pet/dog/corgi/puppy/void{ +/mob/living/basic/pet/dog/corgi/puppy/void{ dir = 4 }, /turf/open/floor/grass, @@ -30820,7 +30820,7 @@ desc = "An ancient piece of machinery, made from an unknown metal by an unknown maker."; name = "\improper Ancient Relic" }, -/mob/living/simple_animal/pet/dog/corgi{ +/mob/living/basic/pet/dog/corgi{ desc = "Make sure you give him plenty of bellyrubs, or he'll melt your skin off."; name = "\improper Keeper of the Ark" }, @@ -47440,7 +47440,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 5 }, -/mob/living/simple_animal/pet/dog/corgi/puppy/slime, +/mob/living/basic/pet/dog/corgi/puppy/slime, /turf/open/floor/grass, /area/station/science/research) "qPT" = ( @@ -50297,7 +50297,7 @@ /obj/machinery/firealarm/directional/west{ pixel_y = 26 }, -/mob/living/simple_animal/pet/dog/pug/mcgriff, +/mob/living/basic/pet/dog/pug/mcgriff, /obj/effect/turf_decal/trimline/dark_red/filled/line{ dir = 9 }, diff --git a/_maps/map_files/tramstation/modular_pieces/maintenance_lowerdorm_2.dmm b/_maps/map_files/tramstation/modular_pieces/maintenance_lowerdorm_2.dmm index 5a7c2e0f818..6ead81a7ea7 100644 --- a/_maps/map_files/tramstation/modular_pieces/maintenance_lowerdorm_2.dmm +++ b/_maps/map_files/tramstation/modular_pieces/maintenance_lowerdorm_2.dmm @@ -56,7 +56,7 @@ /turf/closed/mineral/random/stationside/asteroid/porus, /area/station/maintenance/department/crew_quarters/dorms) "fL" = ( -/mob/living/simple_animal/pet/dog/bullterrier{ +/mob/living/basic/pet/dog/bullterrier{ desc = "walter"; name = "walter" }, diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 0dc706e0649..76fd06adb30 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -4512,7 +4512,7 @@ dir = 4 }, /obj/structure/bed/dogbed/mcgriff, -/mob/living/simple_animal/pet/dog/pug/mcgriff, +/mob/living/basic/pet/dog/pug/mcgriff, /turf/open/floor/glass/reinforced, /area/station/security/warden) "bMb" = ( @@ -22129,7 +22129,7 @@ /obj/structure/bed/dogbed/ian, /obj/machinery/computer/security/telescreen/entertainment/directional/north, /obj/machinery/firealarm/directional/east, -/mob/living/simple_animal/pet/dog/corgi/ian, +/mob/living/basic/pet/dog/corgi/ian, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) "ibg" = ( @@ -41047,7 +41047,7 @@ dir = 6 }, /obj/structure/bed/dogbed/ian, -/mob/living/simple_animal/pet/dog/pug{ +/mob/living/basic/pet/dog/pug{ desc = "A pug with an insatiable appetite for pasta and pasta-adjacent piping."; name = "Spaghetti" }, diff --git a/code/__DEFINES/ai.dm b/code/__DEFINES/ai.dm index 622cc84134e..1f879efb01e 100644 --- a/code/__DEFINES/ai.dm +++ b/code/__DEFINES/ai.dm @@ -165,6 +165,7 @@ #define BB_DOG_PLAYING_DEAD "BB_DOG_PLAYING_DEAD" #define BB_DOG_HARASS_TARGET "BB_DOG_HARASS_TARGET" #define BB_DOG_HARASS_FRUSTRATION "BB_DOG_HARASS_FRUSTRATION" +#define BB_DOG_IS_SLOW "BB_DOG_IS_SLOW" /// Basically, what is our vision/hearing range for picking up on things to fetch/ #define AI_DOG_VISION_RANGE 10 @@ -222,6 +223,14 @@ ///list of foods this mob likes #define BB_BASIC_FOODS "BB_basic_foods" +///Baby-making blackboard +///Types of animal we can make babies with. +#define BB_BABIES_PARTNER_TYPES "BB_babies_partner" +///Types of animal that we make as a baby. +#define BB_BABIES_CHILD_TYPES "BB_babies_child" +///Current partner target +#define BB_BABIES_TARGET "BB_babies_target" + ///Bileworm AI keys #define BB_BILEWORM_SPEW_BILE "BB_bileworm_spew_bile" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index 2a2ea576470..954d2a8a24e 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -40,6 +40,8 @@ #define COMSIG_LIVING_TRY_SYRINGE "living_try_syringe" ///From living/Life(). (deltatime, times_fired) #define COMSIG_LIVING_LIFE "living_life" +///From living/set_resting(): (new_resting, silent, instant) +#define COMSIG_LIVING_RESTING "living_resting" ///from base of element/bane/activate(): (item/weapon, mob/user) #define COMSIG_LIVING_BANED "living_baned" @@ -47,6 +49,10 @@ ///from base of mob/living/death(): (gibbed) #define COMSIG_LIVING_DEATH "living_death" +///from base of mob/living/gib(): (no_brain, no_organs, no_bodyparts) +///Note that it is fired regardless of whether the mob was dead beforehand or not. +#define COMSIG_LIVING_GIBBED "living_gibbed" + ///from base of mob/living/Write_Memory(): (dead, gibbed) #define COMSIG_LIVING_WRITE_MEMORY "living_write_memory" #define COMPONENT_DONT_WRITE_MEMORY (1<<0) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 25708399de0..ef7f6752e36 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -147,9 +147,9 @@ GLOBAL_LIST_INIT(turfs_openspace, typecacheof(list( #define iscat(A) (istype(A, /mob/living/simple_animal/pet/cat)) -#define isdog(A) (istype(A, /mob/living/simple_animal/pet/dog)) +#define isdog(A) (istype(A, /mob/living/basic/pet/dog)) -#define iscorgi(A) (istype(A, /mob/living/simple_animal/pet/dog/corgi)) +#define iscorgi(A) (istype(A, /mob/living/basic/pet/dog/corgi)) #define ishostile(A) (istype(A, /mob/living/simple_animal/hostile)) diff --git a/code/__DEFINES/strippable.dm b/code/__DEFINES/strippable.dm index a660e827842..9988861dbf9 100644 --- a/code/__DEFINES/strippable.dm +++ b/code/__DEFINES/strippable.dm @@ -18,7 +18,7 @@ #define STRIPPABLE_ITEM_RHAND "right_hand" #define STRIPPABLE_ITEM_HANDCUFFS "handcuffs" #define STRIPPABLE_ITEM_LEGCUFFS "legcuffs" -#define STRIPPABLE_ITEM_CORGI_COLLAR "corgi_collar" +#define STRIPPABLE_ITEM_PET_COLLAR "pet_collar" #define STRIPPABLE_ITEM_PARROT_HEADSET "parrot_headset" /// This slot is not obscured. diff --git a/code/datums/ai/babies/babies_behaviors.dm b/code/datums/ai/babies/babies_behaviors.dm new file mode 100644 index 00000000000..c1269001e9b --- /dev/null +++ b/code/datums/ai/babies/babies_behaviors.dm @@ -0,0 +1,77 @@ +/** + * Find a compatible, living partner, if we're also alone. + */ +/datum/ai_behavior/find_partner + action_cooldown = 40 SECONDS + + /// Range to look. + var/range = 7 + + /// Maximum number of children + var/max_children = 3 + +/datum/ai_behavior/find_partner/perform(delta_time, datum/ai_controller/controller, target_key, partner_types_key, child_types_key) + . = ..() + + var/mob/pawn_mob = controller.pawn + var/list/partner_types = controller.blackboard[partner_types_key] + var/list/child_types = controller.blackboard[child_types_key] + + var/mob/living/partner + var/children = 0 + for(var/mob/other in oview(range, pawn_mob)) + if(other.stat != CONSCIOUS) //Check if it's conscious FIRST. + continue + var/is_child = is_type_in_list(other, child_types) + if(is_child) //Check for children SECOND. + children++ + else if(is_type_in_list(other, partner_types)) + if(other.ckey) + continue + else if(!is_child && other.gender == MALE && !(other.flags_1 & HOLOGRAM_1)) //Better safe than sorry ;_; + partner = other + + //shyness check. we're not shy in front of things that share a faction with us. + else if(isliving(other) && !pawn_mob.faction_check_mob(other)) + finish_action(controller, FALSE) + return + + if(partner && children < max_children) + controller.blackboard[target_key] = WEAKREF(partner) + + finish_action(controller, TRUE) + +/** + * Reproduce. + */ +/datum/ai_behavior/make_babies + action_cooldown = 40 SECONDS + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT + +/datum/ai_behavior/make_babies/setup(datum/ai_controller/controller, target_key, child_types_key) + var/datum/weakref/weak_target = controller.blackboard[target_key] + var/atom/target = weak_target?.resolve() + if(!target) + return FALSE + controller.current_movement_target = target + return TRUE + +/datum/ai_behavior/make_babies/perform(delta_time, datum/ai_controller/controller, target_key, child_types_key) + . = ..() + var/datum/weakref/weak_target = controller.blackboard[target_key] + var/mob/target = weak_target?.resolve() + if(!target || target.stat != CONSCIOUS) + finish_action(controller, FALSE, target_key) + return + + var/child_type = pick_weight(controller.blackboard[child_types_key]) + var/turf/turf_loc = get_turf(controller.pawn.loc) + if(turf_loc) + new child_type(turf_loc) + + finish_action(controller, TRUE, target_key) + +/datum/ai_behavior/make_babies/finish_action(datum/ai_controller/controller, succeeded, target_key) + . = ..() + + controller.blackboard -= target_key diff --git a/code/datums/ai/babies/babies_subtrees.dm b/code/datums/ai/babies/babies_subtrees.dm new file mode 100644 index 00000000000..8095ca3a49e --- /dev/null +++ b/code/datums/ai/babies/babies_subtrees.dm @@ -0,0 +1,34 @@ +/** + * Reproduce with a similar mob. + */ +/datum/ai_planning_subtree/make_babies + var/chance = 5 + +/datum/ai_planning_subtree/make_babies/SelectBehaviors(datum/ai_controller/controller, delta_time) + . = ..() + + if(controller.pawn.gender != FEMALE || !DT_PROB(chance, delta_time)) + return + + var/partner_types = controller.blackboard[BB_BABIES_PARTNER_TYPES] + var/baby_types = controller.blackboard[BB_BABIES_CHILD_TYPES] + + if(!partner_types || !baby_types) + return + + // Baby can't reproduce + if(is_type_in_list(controller.pawn, baby_types)) + return + + var/datum/weakref/weak_target = controller.blackboard[BB_BABIES_TARGET] + var/atom/target = weak_target?.resolve() + + // Find target + if(!target || QDELETED(target)) + controller.queue_behavior(/datum/ai_behavior/find_partner, BB_BABIES_TARGET, BB_BABIES_PARTNER_TYPES, BB_BABIES_CHILD_TYPES) + return + + // Do target + if(target) + controller.queue_behavior(/datum/ai_behavior/make_babies, BB_BABIES_TARGET, BB_BABIES_CHILD_TYPES) + return SUBTREE_RETURN_FINISH_PLANNING diff --git a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm index c0aaacfce3e..0ade512ca2b 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm @@ -89,3 +89,16 @@ /datum/ai_planning_subtree/random_speech/cow/wisdom/New() . = ..() speak = GLOB.wisdoms //Done here so it's setup properly + +/datum/ai_planning_subtree/random_speech/dog + speech_chance = 1 + +/datum/ai_planning_subtree/random_speech/dog/SelectBehaviors(datum/ai_controller/controller, delta_time) + if(!isdog(controller.pawn)) + return + + // Stay in sync with dog fashion. + var/mob/living/basic/pet/dog/dog_pawn = controller.pawn + dog_pawn.update_dog_speech(src) + + return ..() diff --git a/code/datums/ai/dog/dog_controller.dm b/code/datums/ai/dog/dog_controller.dm index bfb31511d2d..84e9f621a27 100644 --- a/code/datums/ai/dog/dog_controller.dm +++ b/code/datums/ai/dog/dog_controller.dm @@ -1,17 +1,22 @@ /datum/ai_controller/dog - blackboard = list(\ - BB_SIMPLE_CARRY_ITEM = null,\ - BB_FETCH_TARGET = null,\ - BB_FETCH_DELIVER_TO = null,\ - BB_DOG_FRIENDS = list(),\ - BB_FETCH_IGNORE_LIST = list(),\ - BB_DOG_ORDER_MODE = DOG_COMMAND_NONE,\ - BB_DOG_PLAYING_DEAD = FALSE,\ - BB_DOG_HARASS_TARGET = null,\ - BB_DOG_HARASS_FRUSTRATION = null,\ - BB_VISION_RANGE = AI_DOG_VISION_RANGE) + blackboard = list( + BB_SIMPLE_CARRY_ITEM = null, + BB_FETCH_TARGET = null, + BB_FETCH_DELIVER_TO = null, + BB_DOG_FRIENDS = list(), + BB_FETCH_IGNORE_LIST = list(), + BB_DOG_ORDER_MODE = DOG_COMMAND_NONE, + BB_DOG_PLAYING_DEAD = FALSE, + BB_DOG_HARASS_TARGET = null, + BB_DOG_HARASS_FRUSTRATION = null, + BB_VISION_RANGE = AI_DOG_VISION_RANGE, + ) ai_movement = /datum/ai_movement/jps - planning_subtrees = list(/datum/ai_planning_subtree/dog) + idle_behavior = /datum/idle_behavior/idle_dog + planning_subtrees = list( + /datum/ai_planning_subtree/random_speech/dog, + /datum/ai_planning_subtree/dog, + ) COOLDOWN_DECLARE(heel_cooldown) COOLDOWN_DECLARE(command_cooldown) @@ -51,13 +56,6 @@ return FALSE return ..() -/datum/ai_controller/dog/get_access() - var/mob/living/simple_animal/simple_pawn = pawn - if(!istype(simple_pawn)) - return - - return simple_pawn.access_card - /// Someone has thrown something, see if it's someone we care about and start listening to the thrown item so we can see if we want to fetch it when it lands /datum/ai_controller/dog/proc/listened_throw(datum/source, mob/living/carbon/carbon_thrower) SIGNAL_HANDLER @@ -285,3 +283,37 @@ if(living_pawn.buckled) queue_behavior(/datum/ai_behavior/resist)//in case they are in bed or something queue_behavior(/datum/ai_behavior/harass) + + +/** + * Same thing but with make tiny corgis and use access cards. + */ +/datum/ai_controller/dog/corgi + blackboard = list( + BB_SIMPLE_CARRY_ITEM = null, + BB_FETCH_TARGET = null, + BB_FETCH_DELIVER_TO = null, + BB_DOG_FRIENDS = list(), + BB_FETCH_IGNORE_LIST = list(), + BB_DOG_ORDER_MODE = DOG_COMMAND_NONE, + BB_DOG_PLAYING_DEAD = FALSE, + BB_DOG_HARASS_TARGET = null, + BB_DOG_HARASS_FRUSTRATION = null, + BB_VISION_RANGE = AI_DOG_VISION_RANGE, + + BB_BABIES_PARTNER_TYPES = list(/mob/living/basic/pet/dog), + BB_BABIES_CHILD_TYPES = list(/mob/living/basic/pet/dog/corgi/puppy = 95, /mob/living/basic/pet/dog/corgi/puppy/void = 5), + ) + + planning_subtrees = list( + /datum/ai_planning_subtree/random_speech/dog, + /datum/ai_planning_subtree/make_babies, + /datum/ai_planning_subtree/dog, + ) + +/datum/ai_controller/dog/corgi/get_access() + var/mob/living/basic/pet/dog/corgi/corgi_pawn = pawn + if(!istype(corgi_pawn)) + return + + return corgi_pawn.access_card diff --git a/code/datums/ai/idle_behaviors/idle_dog.dm b/code/datums/ai/idle_behaviors/idle_dog.dm index fd27bc6968e..96396aa8af9 100644 --- a/code/datums/ai/idle_behaviors/idle_dog.dm +++ b/code/datums/ai/idle_behaviors/idle_dog.dm @@ -13,9 +13,12 @@ var/obj/item/carry_item = controller.blackboard[BB_SIMPLE_CARRY_ITEM] living_pawn.visible_message(span_notice("[living_pawn] gently teethes on \the [carry_item] in [living_pawn.p_their()] mouth."), vision_distance=COMBAT_MESSAGE_RANGE) - if(DT_PROB(5, delta_time) && (living_pawn.mobility_flags & MOBILITY_MOVE)) + // Custom movement rate, for old corgis, etc. + var/move_chance = controller.blackboard[BB_DOG_IS_SLOW] ? 2.5 : 5 + + if(DT_PROB(move_chance, delta_time) && (living_pawn.mobility_flags & MOBILITY_MOVE)) var/move_dir = pick(GLOB.alldirs) living_pawn.Move(get_step(living_pawn, move_dir), move_dir) - else if(DT_PROB(10, delta_time)) - living_pawn.manual_emote(pick("dances around.","chases [living_pawn.p_their()] tail!")) + else if(DT_PROB(2, delta_time)) + living_pawn.manual_emote(pick("dances around.", "chases [living_pawn.p_their()] tail!")) living_pawn.AddComponent(/datum/component/spinny) diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index 96a9cfaaea3..3ac45f41584 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -170,7 +170,7 @@ for(var/mob/M in oview(owner, 7)) if(!isliving(M)) //ghosts ain't people continue - if((istype(M, /mob/living/simple_animal/pet)) || M.ckey) + if(istype(M, /mob/living/simple_animal/pet) || istype(M, /mob/living/basic/pet) || M.ckey) return FALSE return TRUE diff --git a/code/datums/components/creamed.dm b/code/datums/components/creamed.dm index e2ff48e770c..a561b5e6675 100644 --- a/code/datums/components/creamed.dm +++ b/code/datums/components/creamed.dm @@ -1,6 +1,6 @@ GLOBAL_LIST_INIT(creamable, typecacheof(list( /mob/living/carbon/human, - /mob/living/simple_animal/pet/dog/corgi, + /mob/living/basic/pet/dog/corgi, /mob/living/silicon/ai))) /** diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index fb8d07550c2..4d6d0031e06 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -268,7 +268,7 @@ stage3 = list("Must... eat... chocolate....", "YAP") stage4 = list("Visions of washing machines assail your mind!") stage5 = list("AUUUUUU!!!") - new_form = /mob/living/simple_animal/pet/dog/corgi + new_form = /mob/living/basic/pet/dog/corgi /datum/disease/transformation/corgi/stage_act(delta_time, times_fired) diff --git a/code/datums/dog_fashion.dm b/code/datums/dog_fashion.dm index 267c7f2354a..7daffcfc204 100644 --- a/code/datums/dog_fashion.dm +++ b/code/datums/dog_fashion.dm @@ -17,20 +17,22 @@ name = replacetext(name, "REAL_NAME", M.real_name) desc = replacetext(desc, "NAME", name) -/datum/dog_fashion/proc/apply(mob/living/simple_animal/pet/dog/D) +/datum/dog_fashion/proc/apply(mob/living/basic/pet/dog/D) if(name) D.name = name if(desc) D.desc = desc - if(emote_see) - D.emote_see = string_list(emote_see) - if(emote_hear) - D.emote_hear = string_list(emote_hear) - if(speak) - D.speak = string_list(speak) if(speak_emote) D.speak_emote = string_list(speak_emote) +/datum/dog_fashion/proc/apply_to_speech(datum/ai_planning_subtree/random_speech/speech) + if(emote_see) + speech.emote_see = string_list(emote_see) + if(emote_hear) + speech.emote_hear = string_list(emote_hear) + if(speak) + speech.speak = string_list(speak) + /datum/dog_fashion/proc/get_overlay(dir) if(icon_file && obj_icon_state) var/image/corgI = image(icon_file, obj_icon_state, dir = dir) diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index 4200236fcbd..e9be0b517eb 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -377,7 +377,7 @@ nonhuman_mobtype = /mob/living/simple_animal/hostile/gorilla /datum/preset_holoimage/corgi - nonhuman_mobtype = /mob/living/simple_animal/pet/dog/corgi + nonhuman_mobtype = /mob/living/basic/pet/dog/corgi /datum/preset_holoimage/clown outfit_type = /datum/outfit/job/clown diff --git a/code/datums/memory/memory.dm b/code/datums/memory/memory.dm index f9a8129c4ab..a77e82d280b 100644 --- a/code/datums/memory/memory.dm +++ b/code/datums/memory/memory.dm @@ -66,9 +66,9 @@ /mob/living/simple_animal/hostile/megafauna/dragon/lesser, /mob/living/simple_animal/hostile/gorilla, /mob/living/simple_animal/parrot, - /mob/living/simple_animal/pet/dog/corgi, + /mob/living/basic/pet/dog/corgi, /mob/living/simple_animal/crab, - /mob/living/simple_animal/pet/dog/pug, + /mob/living/basic/pet/dog/pug, /mob/living/simple_animal/pet/cat, /mob/living/basic/mouse, /mob/living/simple_animal/chicken, @@ -77,7 +77,7 @@ /mob/living/simple_animal/pet/fox, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/pet/cat/cak, - /mob/living/simple_animal/pet/dog/breaddog, + /mob/living/basic/pet/dog/breaddog, /mob/living/simple_animal/chick, /mob/living/basic/cow/wisdom, /obj/item/skub, diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index 1f598c6ce6a..6eeafa607d8 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -38,8 +38,8 @@ report_message = "Ian has gone exploring somewhere in the station." /datum/station_trait/ian_adventure/on_round_start() - for(var/mob/living/simple_animal/pet/dog/corgi/dog in GLOB.mob_list) - if(!(istype(dog, /mob/living/simple_animal/pet/dog/corgi/ian) || istype(dog, /mob/living/simple_animal/pet/dog/corgi/puppy/ian))) + for(var/mob/living/basic/pet/dog/corgi/dog in GLOB.mob_list) + if(!(istype(dog, /mob/living/basic/pet/dog/corgi/ian) || istype(dog, /mob/living/basic/pet/dog/corgi/puppy/ian))) continue // Makes this station trait more interesting. Ian probably won't go anywhere without a little external help. @@ -59,7 +59,7 @@ do_smoke(location=adventure_turf) /// Moves the new dog somewhere safe, equips it with the old one's inventory and makes it deadchat_playable. -/datum/station_trait/ian_adventure/proc/do_corgi_respawn(mob/living/simple_animal/pet/dog/corgi/old_dog, mob/living/simple_animal/pet/dog/corgi/new_dog, gibbed, lives_left) +/datum/station_trait/ian_adventure/proc/do_corgi_respawn(mob/living/basic/pet/dog/corgi/old_dog, mob/living/basic/pet/dog/corgi/new_dog, gibbed, lives_left) SIGNAL_HANDLER var/turf/current_turf = get_turf(new_dog) diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 89a1eca71ed..5354689d307 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -276,6 +276,10 @@ GLOBAL_LIST_INIT(dye_registry, list( investigate_log("has been gibbed by a washing machine.", INVESTIGATE_DEATHS) gib() +/mob/living/basic/pet/machine_wash(obj/machinery/washing_machine/washer) + washer.bloody_mess = TRUE + gib() + /obj/item/machine_wash(obj/machinery/washing_machine/washer) if(washer.color_source) dye_item(washer.color_source.dye_color) @@ -369,7 +373,7 @@ GLOBAL_LIST_INIT(dye_registry, list( if(L.buckled || L.has_buckled_mobs()) return if(state_open) - if(istype(L, /mob/living/simple_animal/pet)) + if(istype(L, /mob/living/simple_animal/pet) || istype(L, /mob/living/basic/pet)) L.forceMove(src) update_appearance() return diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index ffb3223ea17..86dd2bac70b 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -69,7 +69,7 @@ return ..() /obj/effect/gibspawner/generic/animal - gib_mob_type = /mob/living/simple_animal/pet + gib_mob_type = /mob/living/basic/pet diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm index 592bbbf6a14..e7eb93a26b7 100644 --- a/code/game/objects/structures/petrified_statue.dm +++ b/code/game/objects/structures/petrified_statue.dm @@ -88,7 +88,7 @@ S.add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY) return TRUE -/mob/living/simple_animal/pet/dog/corgi/petrify(statue_timer) +/mob/living/basic/pet/dog/corgi/petrify(statue_timer) if(!isturf(loc)) return FALSE var/obj/structure/statue/petrified/S = new (loc, src, statue_timer) diff --git a/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm b/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm index 2275fa9f413..18f5a981999 100644 --- a/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm +++ b/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm @@ -13,7 +13,7 @@ possible_shapes = list( /mob/living/basic/mouse, - /mob/living/simple_animal/pet/dog/corgi, + /mob/living/basic/pet/dog/corgi, /mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/bot/secbot, /mob/living/simple_animal/pet/fox, diff --git a/code/modules/antagonists/traitor/objectives/kill_pet.dm b/code/modules/antagonists/traitor/objectives/kill_pet.dm index 6dd27e541c3..f62a823d1c4 100644 --- a/code/modules/antagonists/traitor/objectives/kill_pet.dm +++ b/code/modules/antagonists/traitor/objectives/kill_pet.dm @@ -19,8 +19,8 @@ /// Possible heads mapped to their pet type. Can be a list of possible pets var/list/possible_heads = list( JOB_HEAD_OF_PERSONNEL = list( - /mob/living/simple_animal/pet/dog/corgi/ian, - /mob/living/simple_animal/pet/dog/corgi/puppy/ian + /mob/living/basic/pet/dog/corgi/ian, + /mob/living/basic/pet/dog/corgi/puppy/ian ), JOB_CAPTAIN = /mob/living/simple_animal/pet/fox/renault, JOB_CHIEF_MEDICAL_OFFICER = /mob/living/simple_animal/pet/cat/runtime, @@ -57,7 +57,7 @@ /mob/living/simple_animal/hostile/retaliate/bat/sgt_araneus ), JOB_WARDEN = list( - /mob/living/simple_animal/pet/dog/pug/mcgriff + /mob/living/basic/pet/dog/pug/mcgriff ) ) diff --git a/code/modules/cargo/packs/livestock.dm b/code/modules/cargo/packs/livestock.dm index f91dfcb01a8..a1f6b33930b 100644 --- a/code/modules/cargo/packs/livestock.dm +++ b/code/modules/cargo/packs/livestock.dm @@ -61,7 +61,7 @@ one dog from the millions of Ian's noble bloodline. Comes with a cute collar!" cost = CARGO_CRATE_VALUE * 10 access_view = ACCESS_HOP - contains = list(/mob/living/simple_animal/pet/dog/corgi, + contains = list(/mob/living/basic/pet/dog/corgi, /obj/item/clothing/neck/petcollar, ) crate_name = "corgi crate" @@ -69,10 +69,10 @@ /datum/supply_pack/critter/corgi/generate() . = ..() if(prob(50)) - var/mob/living/simple_animal/pet/dog/corgi/D = locate() in . + var/mob/living/basic/pet/dog/corgi/D = locate() in . if(D.gender == FEMALE) qdel(D) - new /mob/living/simple_animal/pet/dog/corgi/lisa(.) + new /mob/living/basic/pet/dog/corgi/lisa(.) /datum/supply_pack/critter/cow name = "Cow Crate" @@ -123,7 +123,7 @@ desc = "Corgi fit for a king, this corgi comes in a unique color to signify their superiority. \ Comes with a cute collar!" cost = CARGO_CRATE_VALUE * 11 - contains = list(/mob/living/simple_animal/pet/dog/corgi/exoticcorgi, + contains = list(/mob/living/basic/pet/dog/corgi/exoticcorgi, /obj/item/clothing/neck/petcollar, ) crate_name = "exotic corgi crate" @@ -166,7 +166,7 @@ name = "Pug Crate" desc = "Like a normal dog, but... squished. Contains one pug. Comes with a nice collar!" cost = CARGO_CRATE_VALUE * 10 - contains = list(/mob/living/simple_animal/pet/dog/pug, + contains = list(/mob/living/basic/pet/dog/pug, /obj/item/clothing/neck/petcollar, ) crate_name = "pug crate" @@ -176,7 +176,7 @@ desc = "Like a normal dog, but with a head the shape of an egg. Contains one bull terrier. \ Comes with a nice collar!" cost = CARGO_CRATE_VALUE * 10 - contains = list(/mob/living/simple_animal/pet/dog/bullterrier, + contains = list(/mob/living/basic/pet/dog/bullterrier, /obj/item/clothing/neck/petcollar, ) crate_name = "bull terrier crate" diff --git a/code/modules/events/ghost_role/sentience.dm b/code/modules/events/ghost_role/sentience.dm index 4c4ea1ff22d..a26a787ff84 100644 --- a/code/modules/events/ghost_role/sentience.dm +++ b/code/modules/events/ghost_role/sentience.dm @@ -1,4 +1,5 @@ GLOBAL_LIST_INIT(high_priority_sentience, typecacheof(list( + /mob/living/basic/pet, /mob/living/simple_animal/pet, /mob/living/simple_animal/parrot, /mob/living/simple_animal/hostile/lizard, diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm index abb7a69daf2..b0b9aa35264 100644 --- a/code/modules/events/holiday/halloween.dm +++ b/code/modules/events/holiday/halloween.dm @@ -16,7 +16,7 @@ if(b) new /obj/item/storage/spooky(b) - for(var/mob/living/simple_animal/pet/dog/corgi/ian/Ian in GLOB.mob_living_list) + for(var/mob/living/basic/pet/dog/corgi/ian/Ian in GLOB.mob_living_list) Ian.place_on_head(new /obj/item/bedsheet(Ian)) for(var/mob/living/simple_animal/parrot/poly/Poly in GLOB.mob_living_list) new /mob/living/simple_animal/parrot/poly/ghost(Poly.loc) diff --git a/code/modules/experisci/experiment/experiments.dm b/code/modules/experisci/experiment/experiments.dm index 2ab2660a8e3..e41f1764021 100644 --- a/code/modules/experisci/experiment/experiments.dm +++ b/code/modules/experisci/experiment/experiments.dm @@ -39,7 +39,7 @@ description = "We need to see how the body functions from the earliest moments. Some cytology experiments will help us gain this understanding." total_requirement = 3 max_requirement_per_type = 2 - possible_types = list(/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/retaliate/snake, /mob/living/simple_animal/pet/cat, /mob/living/simple_animal/pet/dog/corgi, /mob/living/basic/cow, /mob/living/simple_animal/chicken) + possible_types = list(/mob/living/simple_animal/hostile/carp, /mob/living/simple_animal/hostile/retaliate/snake, /mob/living/simple_animal/pet/cat, /mob/living/basic/pet/dog/corgi, /mob/living/basic/cow, /mob/living/simple_animal/chicken) /datum/experiment/scanning/random/cytology/medium/one name = "Advanced Cytology Scanning Experiment One" diff --git a/code/modules/explorer_drone/loot.dm b/code/modules/explorer_drone/loot.dm index eac77fddb60..9518337f266 100644 --- a/code/modules/explorer_drone/loot.dm +++ b/code/modules/explorer_drone/loot.dm @@ -95,7 +95,7 @@ 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/simple_animal/pet/dog/corgi,/mob/living/simple_animal/pet/penguin/baby,/mob/living/simple_animal/pet/dog/pug) + 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) /datum/adventure_loot_generator/pet/generate() var/obj/item/pet_carrier/carrier = new carrier_type() diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm index ed39ff22140..688eee0bfb7 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm @@ -142,7 +142,7 @@ /datum/reagent/blood = 30, /datum/reagent/teslium = 1 //To shock the whole thing into life ) - result = /mob/living/simple_animal/pet/dog/breaddog + result = /mob/living/basic/pet/dog/breaddog subcategory = CAT_BREAD ////////////////////////////////////////////////TOAST//////////////////////////////////////////////// diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm index 3ad306c7143..9d498919b8e 100644 --- a/code/modules/holiday/holidays.dm +++ b/code/modules/holiday/holidays.dm @@ -743,7 +743,7 @@ for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines) Monitor.icon_state_on = "entertainment_xmas" - for(var/mob/living/simple_animal/pet/dog/corgi/ian/Ian in GLOB.mob_living_list) + for(var/mob/living/basic/pet/dog/corgi/ian/Ian in GLOB.mob_living_list) Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian)) diff --git a/code/modules/holodeck/holo_effect.dm b/code/modules/holodeck/holo_effect.dm index f8deccea4f3..4d14fc929cf 100644 --- a/code/modules/holodeck/holo_effect.dm +++ b/code/modules/holodeck/holo_effect.dm @@ -88,9 +88,9 @@ /mob/living/basic/rabbit, ) mobtype += pick( - /mob/living/simple_animal/pet/dog/corgi, - /mob/living/simple_animal/pet/dog/corgi/puppy, - /mob/living/simple_animal/pet/dog/pug, + /mob/living/basic/pet/dog/corgi, + /mob/living/basic/pet/dog/corgi/puppy, + /mob/living/basic/pet/dog/pug, ) mobtype += pick( /mob/living/simple_animal/pet/cat, diff --git a/code/modules/jobs/job_types/head_of_personnel.dm b/code/modules/jobs/job_types/head_of_personnel.dm index 9cac2406d84..4d2ec8e60c6 100644 --- a/code/modules/jobs/job_types/head_of_personnel.dm +++ b/code/modules/jobs/job_types/head_of_personnel.dm @@ -79,7 +79,7 @@ /datum/job/head_of_personnel/get_mail_goodies(mob/recipient) . = ..() // Strange Reagent if the pet is dead. - for(var/mob/living/simple_animal/pet/dog/corgi/ian/staff_pet in GLOB.dead_mob_list) + for(var/mob/living/basic/pet/dog/corgi/ian/staff_pet in GLOB.dead_mob_list) . += list(/datum/reagent/medicine/strange_reagent = 20) break diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/basic/pets/dog.dm similarity index 73% rename from code/modules/mob/living/simple_animal/friendly/dog.dm rename to code/modules/mob/living/basic/pets/dog.dm index cc7c2ef3756..71f6c4a5e00 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/basic/pets/dog.dm @@ -1,6 +1,6 @@ //Dogs. -/mob/living/simple_animal/pet/dog +/mob/living/basic/pet/dog mob_biotypes = MOB_ORGANIC|MOB_BEAST response_help_continuous = "pets" response_help_simple = "pet" @@ -8,33 +8,30 @@ response_disarm_simple = "bop" response_harm_continuous = "kicks" response_harm_simple = "kick" - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") speak_emote = list("barks", "woofs") - emote_hear = list("barks!", "woofs!", "yaps.","pants.") - emote_see = list("shakes their head.", "chases their tail.","shivers.") faction = list("neutral") see_in_dark = 5 - speak_chance = 1 - turns_per_move = 10 can_be_held = TRUE ai_controller = /datum/ai_controller/dog - stop_automated_movement = TRUE ///In the case 'melee_damage_upper' is somehow raised above 0 attack_verb_continuous = "bites" attack_verb_simple = "bite" attack_sound = 'sound/weapons/bite.ogg' attack_vis_effect = ATTACK_EFFECT_BITE - footstep_type = FOOTSTEP_MOB_CLAW - -/mob/living/simple_animal/pet/dog/Initialize(mapload) +/mob/living/basic/pet/dog/Initialize(mapload) . = ..() AddElement(/datum/element/pet_bonus, "woofs happily!") - add_cell_sample() + AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) + +/mob/living/basic/pet/dog/proc/update_dog_speech(datum/ai_planning_subtree/random_speech/speech) + speech.speak = string_list(list("YAP", "Woof!", "Bark!", "AUUUUUU")) + speech.emote_hear = string_list(list("barks!", "woofs!", "yaps.","pants.")) + speech.emote_see = string_list(list("shakes [p_their()] head.", "chases [p_their()] tail.","shivers.")) //Corgis and pugs are now under one dog subtype -/mob/living/simple_animal/pet/dog/corgi +/mob/living/basic/pet/dog/corgi name = "\improper corgi" real_name = "corgi" desc = "They're a corgi." @@ -43,35 +40,39 @@ icon_dead = "corgi_dead" held_state = "corgi" butcher_results = list(/obj/item/food/meat/slab/corgi = 3, /obj/item/stack/sheet/animalhide/corgi = 1) - childtype = list(/mob/living/simple_animal/pet/dog/corgi/puppy = 95, /mob/living/simple_animal/pet/dog/corgi/puppy/void = 5) - animal_species = /mob/living/simple_animal/pet/dog gold_core_spawnable = FRIENDLY_SPAWN - collar_type = "corgi" + collar_icon_state = "corgi" + ai_controller = /datum/ai_controller/dog/corgi var/obj/item/inventory_head var/obj/item/inventory_back + /// Access card for Ian. + var/obj/item/card/id/access_card = null var/shaved = FALSE var/nofur = FALSE //Corgis that have risen past the material plane of existence. + /// Is this corgi physically slow due to age, etc? + var/is_slow = FALSE -/mob/living/simple_animal/pet/dog/corgi/add_cell_sample() - AddElement(/datum/element/swabable, CELL_LINE_TABLE_CORGI, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) - -/mob/living/simple_animal/pet/dog/corgi/Destroy() +/mob/living/basic/pet/dog/corgi/Destroy() QDEL_NULL(inventory_head) QDEL_NULL(inventory_back) + QDEL_NULL(access_card) return ..() -/mob/living/simple_animal/pet/dog/corgi/gib() +/mob/living/basic/pet/dog/corgi/gib() if(inventory_head) inventory_head.forceMove(drop_location()) inventory_head = null if(inventory_back) inventory_back.forceMove(drop_location()) inventory_back = null + if(access_card) + access_card.forceMove(drop_location()) + access_card = null return ..() -/mob/living/simple_animal/pet/dog/corgi/deadchat_plays(mode = ANARCHY_MODE, cooldown = 12 SECONDS) +/mob/living/basic/pet/dog/corgi/deadchat_plays(mode = ANARCHY_MODE, cooldown = 12 SECONDS) . = AddComponent(/datum/component/deadchat_control/cardinal_movement, mode, list( - "speak" = CALLBACK(src, PROC_REF(handle_automated_speech), TRUE), + "speak" = CALLBACK(src, PROC_REF(bork)), "wear_hat" = CALLBACK(src, PROC_REF(find_new_hat)), "drop_hat" = CALLBACK(src, PROC_REF(drop_hat)), "spin" = CALLBACK(src, TYPE_PROC_REF(/mob, emote), "spin")), cooldown, CALLBACK(src, PROC_REF(stop_deadchat_plays))) @@ -79,10 +80,17 @@ if(. == COMPONENT_INCOMPATIBLE) return - stop_automated_movement = TRUE + // Stop all automated behavior. + QDEL_NULL(ai_controller) + +///Deadchat bark. +/mob/living/basic/pet/dog/corgi/proc/bork() + var/emote = pick("barks!", "woofs!", "yaps.","pants.") + + manual_emote(emote) ///Deadchat plays command that picks a new hat for Ian. -/mob/living/simple_animal/pet/dog/corgi/proc/find_new_hat() +/mob/living/basic/pet/dog/corgi/proc/find_new_hat() if(!isturf(loc)) return var/list/possible_headwear = list() @@ -102,7 +110,7 @@ visible_message(span_notice("[src] puts [inventory_head] on [p_their()] own head, somehow.")) ///Deadchat plays command that drops the current hat off Ian. -/mob/living/simple_animal/pet/dog/corgi/proc/drop_hat() +/mob/living/basic/pet/dog/corgi/proc/drop_hat() if(!inventory_head) return visible_message(span_notice("[src] vigorously shakes [p_their()] head, dropping [inventory_head] to the ground.")) @@ -111,7 +119,13 @@ update_corgi_fluff() regenerate_icons() -/mob/living/simple_animal/pet/dog/corgi/handle_atom_del(atom/A) +///Turn AI back on. +/mob/living/basic/pet/dog/corgi/proc/stop_deadchat_plays() + var/controller_type = initial(ai_controller) + ai_controller = new controller_type(src) + ai_controller?.blackboard[BB_DOG_IS_SLOW] = is_slow + +/mob/living/basic/pet/dog/corgi/handle_atom_del(atom/A) if(A == inventory_head) inventory_head = null update_corgi_fluff() @@ -122,7 +136,7 @@ regenerate_icons() return ..() -/mob/living/simple_animal/pet/dog/pug +/mob/living/basic/pet/dog/pug name = "\improper pug" real_name = "pug" desc = "They're a pug." @@ -132,19 +146,21 @@ icon_dead = "pug_dead" butcher_results = list(/obj/item/food/meat/slab/pug = 3) gold_core_spawnable = FRIENDLY_SPAWN - collar_type = "pug" + collar_icon_state = "pug" held_state = "pug" -/mob/living/simple_animal/pet/dog/pug/add_cell_sample() +/mob/living/basic/pet/dog/pug/Initialize(mapload) + . = ..() + AddElement(/datum/element/swabable, CELL_LINE_TABLE_PUG, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) -/mob/living/simple_animal/pet/dog/pug/mcgriff +/mob/living/basic/pet/dog/pug/mcgriff name = "McGriff" desc = "This dog can tell something smells around here, and that something is CRIME!" gold_core_spawnable = NO_SPAWN unique_pet = TRUE -/mob/living/simple_animal/pet/dog/bullterrier +/mob/living/basic/pet/dog/bullterrier name = "\improper bull terrier" real_name = "bull terrier" desc = "They're a bull terrier." @@ -154,44 +170,53 @@ icon_dead = "bullterrier_dead" butcher_results = list(/obj/item/food/meat/slab/corgi = 3) // Would feel redundant to add more new dog meats. gold_core_spawnable = FRIENDLY_SPAWN - collar_type = "bullterrier" + collar_icon_state = "bullterrier" held_state = "bullterrier" -/mob/living/simple_animal/pet/dog/corgi/exoticcorgi +/mob/living/basic/pet/dog/corgi/exoticcorgi name = "Exotic Corgi" desc = "As cute as they are colorful!" icon = 'icons/mob/simple/pets.dmi' icon_state = "corgigrey" icon_living = "corgigrey" icon_dead = "corgigrey_dead" - animal_species = /mob/living/simple_animal/pet/dog/corgi/exoticcorgi nofur = TRUE -/mob/living/simple_animal/pet/dog/Initialize(mapload) +/mob/living/basic/pet/dog/Initialize(mapload) . = ..() var/dog_area = get_area(src) for(var/obj/structure/bed/dogbed/D in dog_area) if(D.update_owner(src)) //No muscling in on my turf you fucking parrot break -/mob/living/simple_animal/pet/dog/corgi/Initialize(mapload) +/mob/living/basic/pet/dog/corgi/Initialize(mapload) . = ..() regenerate_icons() AddElement(/datum/element/strippable, GLOB.strippable_corgi_items) + AddElement(/datum/element/swabable, CELL_LINE_TABLE_CORGI, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) + RegisterSignal(src, COMSIG_MOB_TRIED_ACCESS, PROC_REF(on_tried_access)) -/mob/living/simple_animal/pet/dog/corgi/exoticcorgi/Initialize(mapload) +/** + * Handler for COMSIG_MOB_TRIED_ACCESS + */ +/mob/living/basic/pet/dog/corgi/proc/on_tried_access(mob/accessor, obj/locked_thing) + SIGNAL_HANDLER + + return locked_thing?.check_access(access_card) ? ACCESS_ALLOWED : ACCESS_DISALLOWED + +/mob/living/basic/pet/dog/corgi/exoticcorgi/Initialize(mapload) . = ..() var/newcolor = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY) -/mob/living/simple_animal/pet/dog/corgi/death(gibbed) +/mob/living/basic/pet/dog/corgi/death(gibbed) ..(gibbed) regenerate_icons() GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( /datum/strippable_item/corgi_head, /datum/strippable_item/corgi_back, - /datum/strippable_item/corgi_collar, + /datum/strippable_item/pet_collar, /datum/strippable_item/corgi_id, ))) @@ -199,21 +224,21 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( key = STRIPPABLE_ITEM_HEAD /datum/strippable_item/corgi_head/get_item(atom/source) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return return corgi_source.inventory_head /datum/strippable_item/corgi_head/finish_equip(atom/source, obj/item/equipping, mob/user) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return corgi_source.place_on_head(equipping, user) /datum/strippable_item/corgi_head/finish_unequip(atom/source, mob/user) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return @@ -222,11 +247,47 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( corgi_source.update_corgi_fluff() corgi_source.regenerate_icons() +/datum/strippable_item/pet_collar + key = STRIPPABLE_ITEM_PET_COLLAR + +/datum/strippable_item/pet_collar/get_item(atom/source) + var/mob/living/basic/pet/pet_source = source + if (!istype(pet_source)) + return + + return pet_source.collar + +/datum/strippable_item/pet_collar/try_equip(atom/source, obj/item/equipping, mob/user) + . = ..() + if (!.) + return FALSE + + if (!istype(equipping, /obj/item/clothing/neck/petcollar)) + to_chat(user, span_warning("That's not a collar.")) + return FALSE + + return TRUE + +/datum/strippable_item/pet_collar/finish_equip(atom/source, obj/item/equipping, mob/user) + var/mob/living/basic/pet/pet_source = source + if (!istype(pet_source)) + return + + pet_source.add_collar(equipping, user) + +/datum/strippable_item/pet_collar/finish_unequip(atom/source, mob/user) + var/mob/living/basic/pet/pet_source = source + if (!istype(pet_source)) + return + + var/obj/collar = pet_source.remove_collar(user.drop_location()) + user.put_in_hands(collar) + /datum/strippable_item/corgi_back key = STRIPPABLE_ITEM_BACK /datum/strippable_item/corgi_back/get_item(atom/source) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return @@ -249,7 +310,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( return TRUE /datum/strippable_item/corgi_back/finish_equip(atom/source, obj/item/equipping, mob/user) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return @@ -259,7 +320,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( corgi_source.regenerate_icons() /datum/strippable_item/corgi_back/finish_unequip(atom/source, mob/user) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return @@ -268,50 +329,11 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( corgi_source.update_corgi_fluff() corgi_source.regenerate_icons() -/datum/strippable_item/corgi_collar - key = STRIPPABLE_ITEM_CORGI_COLLAR - -/datum/strippable_item/corgi_collar/get_item(atom/source) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source - if (!istype(corgi_source)) - return - - return corgi_source.pcollar - -/datum/strippable_item/corgi_collar/try_equip(atom/source, obj/item/equipping, mob/user) - . = ..() - if (!.) - return FALSE - - if (!istype(equipping, /obj/item/clothing/neck/petcollar)) - to_chat(user, span_warning("That's not a collar.")) - return FALSE - - return TRUE - -/datum/strippable_item/corgi_collar/finish_equip(atom/source, obj/item/equipping, mob/user) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source - if (!istype(corgi_source)) - return - - corgi_source.add_collar(equipping, user) - corgi_source.update_corgi_fluff() - -/datum/strippable_item/corgi_collar/finish_unequip(atom/source, mob/user) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source - if (!istype(corgi_source)) - return - - user.put_in_hands(corgi_source.pcollar) - corgi_source.pcollar = null - corgi_source.update_corgi_fluff() - corgi_source.regenerate_icons() - /datum/strippable_item/corgi_id key = STRIPPABLE_ITEM_ID /datum/strippable_item/corgi_id/get_item(atom/source) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return @@ -329,7 +351,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( return TRUE /datum/strippable_item/corgi_id/finish_equip(atom/source, obj/item/equipping, mob/user) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return @@ -337,7 +359,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( corgi_source.access_card = equipping /datum/strippable_item/corgi_id/finish_unequip(atom/source, mob/user) - var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source + var/mob/living/basic/pet/dog/corgi/corgi_source = source if (!istype(corgi_source)) return @@ -346,7 +368,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( corgi_source.update_corgi_fluff() corgi_source.regenerate_icons() -/mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type) +/mob/living/basic/pet/dog/corgi/getarmor(def_zone, type) var/armorval = 0 if(def_zone) @@ -364,7 +386,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( armorval += inventory_back.armor.getRating(type) return armorval*0.5 -/mob/living/simple_animal/pet/dog/corgi/attackby(obj/item/O, mob/user, params) +/mob/living/basic/pet/dog/corgi/attackby(obj/item/O, mob/user, params) if (istype(O, /obj/item/razor)) if (shaved) to_chat(user, span_warning("You can't shave this corgi, [p_they()] has already been shaved!")) @@ -392,7 +414,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( //Many hats added, Some will probably be removed, just want to see which ones are popular. // > some will probably be removed -/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/living/user) +/mob/living/basic/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/living/user) if(inventory_head) if(user) to_chat(user, span_warning("You can't put more than one hat on [src]!")) @@ -434,15 +456,12 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( return valid -/mob/living/simple_animal/pet/dog/corgi/proc/update_corgi_fluff() +/mob/living/basic/pet/dog/corgi/proc/update_corgi_fluff() // First, change back to defaults name = real_name desc = initial(desc) // BYOND/DM doesn't support the use of initial on lists. - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") speak_emote = list("barks", "woofs") - emote_hear = list("barks!", "woofs!", "yaps.","pants.") - emote_see = list("shakes [p_their()] head.", "chases [p_their()] tail.","shivers.") desc = initial(desc) set_light(0) @@ -454,8 +473,19 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( var/datum/dog_fashion/DF = new inventory_back.dog_fashion(src) DF.apply(src) +/mob/living/basic/pet/dog/corgi/update_dog_speech(datum/ai_planning_subtree/random_speech/speech) + ..() + + if(inventory_head?.dog_fashion) + var/datum/dog_fashion/DF = new inventory_head.dog_fashion(src) + DF.apply_to_speech(speech) + + if(inventory_back?.dog_fashion) + var/datum/dog_fashion/DF = new inventory_back.dog_fashion(src) + DF.apply_to_speech(speech) + //IAN! SQUEEEEEEEEE~ -/mob/living/simple_animal/pet/dog/corgi/ian +/mob/living/basic/pet/dog/corgi/ian name = "Ian" real_name = "Ian" //Intended to hold the name without altering it. gender = MALE @@ -473,7 +503,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( var/memory_saved = FALSE var/saved_head //path -/mob/living/simple_animal/pet/dog/corgi/ian/Initialize(mapload) +/mob/living/basic/pet/dog/corgi/ian/Initialize(mapload) . = ..() //parent call must happen first to ensure IAN //is not in nullspace when child puppies spawn @@ -481,7 +511,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( if(age == 0) var/turf/target = get_turf(loc) if(target) - new /mob/living/simple_animal/pet/dog/corgi/puppy/ian(target) + new /mob/living/basic/pet/dog/corgi/puppy/ian(target) Write_Memory(FALSE) return INITIALIZE_HINT_QDEL else if(age == record_age) @@ -490,20 +520,21 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( held_state = "old_corgi" icon_dead = "old_corgi_dead" desc = "At a ripe old age of [record_age], Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP - turns_per_move = 20 + ai_controller?.blackboard[BB_DOG_IS_SLOW] = TRUE + is_slow = TRUE -/mob/living/simple_animal/pet/dog/corgi/ian/Life(delta_time = SSMOBS_DT, times_fired) +/mob/living/basic/pet/dog/corgi/ian/Life(delta_time = SSMOBS_DT, times_fired) if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) Write_Memory(FALSE) memory_saved = TRUE ..() -/mob/living/simple_animal/pet/dog/corgi/ian/death() +/mob/living/basic/pet/dog/corgi/ian/death() if(!memory_saved) Write_Memory(TRUE) ..() -/mob/living/simple_animal/pet/dog/corgi/ian/proc/Read_Memory() +/mob/living/basic/pet/dog/corgi/ian/proc/Read_Memory() if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Ian.sav") S["age"] >> age @@ -525,7 +556,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( if(saved_head) place_on_head(new saved_head) -/mob/living/simple_animal/pet/dog/corgi/ian/Write_Memory(dead, gibbed) +/mob/living/basic/pet/dog/corgi/ian/Write_Memory(dead, gibbed) . = ..() if(!.) return @@ -548,14 +579,14 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) -/mob/living/simple_animal/pet/dog/corgi/ian/narsie_act() +/mob/living/basic/pet/dog/corgi/ian/narsie_act() playsound(src, 'sound/magic/demon_dies.ogg', 75, TRUE) - var/mob/living/simple_animal/pet/dog/corgi/narsie/N = new(loc) + var/mob/living/basic/pet/dog/corgi/narsie/N = new(loc) N.setDir(dir) investigate_log("has been gibbed by Nar'Sie.", INVESTIGATE_DEATHS) gib() -/mob/living/simple_animal/pet/dog/corgi/narsie +/mob/living/basic/pet/dog/corgi/narsie name = "Nars-Ian" desc = "Ia! Ia!" icon_state = "narsian" @@ -567,10 +598,17 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( unique_pet = TRUE held_state = "narsian" -/mob/living/simple_animal/pet/dog/corgi/narsie/Life(delta_time = SSMOBS_DT, times_fired) +/mob/living/basic/pet/dog/corgi/narsie/Life(delta_time = SSMOBS_DT, times_fired) ..() for(var/mob/living/simple_animal/pet/P in range(1, src)) - if(P != src && !istype(P,/mob/living/simple_animal/pet/dog/corgi/narsie)) + if(P != src && !istype(P,/mob/living/basic/pet/dog/corgi/narsie)) + visible_message(span_warning("[src] devours [P]!"), \ + "DELICIOUS SOULS") + playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE) + narsie_act() + P.gib() + for(var/mob/living/basic/pet/P in range(1, src)) + if(P != src && !istype(P,/mob/living/basic/pet/dog/corgi/narsie)) visible_message(span_warning("[src] devours [P]!"), \ "DELICIOUS SOULS") playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE) @@ -578,18 +616,20 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( P.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) P.gib() -/mob/living/simple_animal/pet/dog/corgi/narsie/update_corgi_fluff() +/mob/living/basic/pet/dog/corgi/narsie/update_corgi_fluff() ..() - speak = list("Tari'karat-pasnar!", "IA! IA!", "BRRUUURGHGHRHR") speak_emote = list("growls", "barks ominously") - emote_hear = list("barks echoingly!", "woofs hauntingly!", "yaps in an eldritch manner.", "mutters something unspeakable.") - emote_see = list("communes with the unnameable.", "ponders devouring some souls.", "shakes.") -/mob/living/simple_animal/pet/dog/corgi/narsie/narsie_act() +/mob/living/basic/pet/dog/corgi/narsie/update_dog_speech(datum/ai_planning_subtree/random_speech/speech) + speech.speak = string_list(list("Tari'karat-pasnar!", "IA! IA!", "BRRUUURGHGHRHR")) + speech.emote_hear = string_list(list("barks echoingly!", "woofs hauntingly!", "yaps in an eldritch manner.", "mutters something unspeakable.")) + speech.emote_see = string_list(list("communes with the unnameable.", "ponders devouring some souls.", "shakes.")) + +/mob/living/basic/pet/dog/corgi/narsie/narsie_act() adjustBruteLoss(-maxHealth) -/mob/living/simple_animal/pet/dog/corgi/regenerate_icons() +/mob/living/basic/pet/dog/corgi/regenerate_icons() ..() if(inventory_head) var/image/head_icon @@ -634,7 +674,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( -/mob/living/simple_animal/pet/dog/corgi/puppy +/mob/living/basic/pet/dog/corgi/puppy name = "\improper corgi puppy" real_name = "corgi" desc = "They're a corgi puppy!" @@ -644,24 +684,24 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( density = FALSE pass_flags = PASSMOB mob_size = MOB_SIZE_SMALL - collar_type = "puppy" + collar_icon_state = "puppy" //puppies cannot wear anything. -/mob/living/simple_animal/pet/dog/corgi/puppy/Topic(href, href_list) +/mob/living/basic/pet/dog/corgi/puppy/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) to_chat(usr, span_warning("You can't fit this on [src], [p_they()] [p_are()] too small!")) return ..() //PUPPY IAN! SQUEEEEEEEEE~ -/mob/living/simple_animal/pet/dog/corgi/puppy/ian +/mob/living/basic/pet/dog/corgi/puppy/ian name = "Ian" real_name = "Ian" gender = MALE desc = "He's the HoP's beloved corgi puppy." -/mob/living/simple_animal/pet/dog/corgi/puppy/void //Tribute to the corgis born in nullspace +/mob/living/basic/pet/dog/corgi/puppy/void //Tribute to the corgis born in nullspace name = "\improper void puppy" real_name = "voidy" desc = "A corgi puppy that has been infused with deep space energy. It's staring back..." @@ -670,20 +710,20 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( icon_living = "void_puppy" icon_dead = "void_puppy_dead" nofur = TRUE - unsuitable_atmos_damage = 0 - minbodytemp = TCMB - maxbodytemp = T0C + 40 held_state = "void_puppy" -/mob/living/simple_animal/pet/dog/corgi/puppy/void/Initialize(mapload) +/mob/living/basic/pet/dog/corgi/puppy/void/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_AI_BAGATTACK, INNATE_TRAIT) + RemoveElement(/datum/element/atmos_requirements) + RemoveElement(/datum/element/basic_body_temp_sensitive) + AddElement(/datum/element/basic_body_temp_sensitive, TCMB, T0C + 40) -/mob/living/simple_animal/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0, continuous_move = FALSE) +/mob/living/basic/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0, continuous_move = FALSE) return 1 //Void puppies can navigate space. //LISA! SQUEEEEEEEEE~ -/mob/living/simple_animal/pet/dog/corgi/lisa +/mob/living/basic/pet/dog/corgi/lisa name = "Lisa" real_name = "Lisa" gender = FEMALE @@ -703,17 +743,13 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( var/puppies = 0 //Lisa already has a cute bow! -/mob/living/simple_animal/pet/dog/corgi/lisa/Topic(href, href_list) +/mob/living/basic/pet/dog/corgi/lisa/Topic(href, href_list) if(href_list["remove_inv"] || href_list["add_inv"]) to_chat(usr, span_warning("[src] already has a cute bow!")) return ..() -/mob/living/simple_animal/pet/dog/corgi/lisa/Life(delta_time = SSMOBS_DT, times_fired) - . = ..() - make_babies() - -/mob/living/simple_animal/pet/dog/breaddog //Most of the code originates from Cak +/mob/living/basic/pet/dog/breaddog //Most of the code originates from Cak name = "Kobun" desc = "It is a dog made out of bread. 'The universe is definitely half full'." icon_state = "breaddog" @@ -723,7 +759,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( health = 50 maxHealth = 50 gender = NEUTER - harm_intent_damage = 10 + damage_coeff = list(BRUTE = 3, BURN = 3, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) butcher_results = list(/obj/item/organ/internal/brain = 1, /obj/item/organ/internal/heart = 1, /obj/item/food/breadslice = 3, \ /obj/item/food/meat/slab = 2) response_harm_continuous = "takes a bite out of" @@ -732,10 +768,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( held_state = "breaddog" worn_slot_flags = ITEM_SLOT_HEAD -/mob/living/simple_animal/pet/dog/breaddog/add_cell_sample() - return - -/mob/living/simple_animal/pet/dog/breaddog/CheckParts(list/parts) +/mob/living/basic/pet/dog/breaddog/CheckParts(list/parts) ..() var/obj/item/organ/internal/brain/candidate = locate(/obj/item/organ/internal/brain) in contents if(!candidate || !candidate.brainmob || !candidate.brainmob.mind) @@ -750,7 +783,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( to_chat(src, span_notice("Your name is now [new_name]!")) name = new_name -/mob/living/simple_animal/pet/dog/breaddog/Life(delta_time = SSMOBS_DT, times_fired) +/mob/living/basic/pet/dog/breaddog/Life(delta_time = SSMOBS_DT, times_fired) ..() if(stat) return @@ -761,7 +794,7 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( for(var/mob/living/carbon/humanoid_entities in view(3, src)) //Mood aura which stay as long you do not wear Sanallite as hat or carry(I will try to make it work with hat someday(obviously weaker than normal one)) humanoid_entities.add_mood_event("kobun", /datum/mood_event/kobun) -/mob/living/simple_animal/pet/dog/breaddog/attack_hand(mob/living/user, list/modifiers) +/mob/living/basic/pet/dog/breaddog/attack_hand(mob/living/user, list/modifiers) ..() if(user.combat_mode && user.reagents && !stat) user.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4) diff --git a/code/modules/mob/living/basic/pets/pet.dm b/code/modules/mob/living/basic/pets/pet.dm new file mode 100644 index 00000000000..ea8181628b3 --- /dev/null +++ b/code/modules/mob/living/basic/pets/pet.dm @@ -0,0 +1,150 @@ +/mob/living/basic/pet + icon = 'icons/mob/simple/pets.dmi' + mob_size = MOB_SIZE_SMALL + mob_biotypes = MOB_ORGANIC|MOB_BEAST + blood_volume = BLOOD_VOLUME_NORMAL + + /// if the mob is protected from being renamed by collars. + var/unique_pet = FALSE + /// If the mob has collar sprites, this is the base of the icon states. + var/collar_icon_state = null + /// We have a seperate _rest collar icon state when the pet is resting. + var/has_collar_resting_icon_state = FALSE + + /// Our collar + var/obj/item/clothing/neck/petcollar/collar + +/mob/living/basic/pet/Initialize(mapload) + . = ..() + + // String assoc list returns a cached list, so this is like a static list to pass into the element below. + var/static/list/habitable_atmos = list( + "min_oxy" = 5, + "max_oxy" = 0, + "min_plas" = 0, + "max_plas" = 1, + "min_co2" = 0, + "max_co2" = 5, + "min_n2" = 0, + "max_n2" = 0, + ) + + AddElement(/datum/element/atmos_requirements, atmos_requirements = habitable_atmos, unsuitable_atmos_damage = 1) + AddElement(/datum/element/basic_body_temp_sensitive) + + /// Can set the collar var beforehand to start the pet with a collar. + if(collar) + collar = new(src) + + update_icon(UPDATE_OVERLAYS) + +/mob/living/basic/pet/Destroy() + . = ..() + + QDEL_NULL(collar) + +/mob/living/basic/pet/attackby(obj/item/thing, mob/user, params) + if(istype(thing, /obj/item/clothing/neck/petcollar) && !collar) + add_collar(thing, user) + return TRUE + + if(istype(thing, /obj/item/newspaper) && !stat) + user.visible_message(span_notice("[user] baps [name] on the nose with the rolled up [thing].")) + dance_rotate(src) + return TRUE + + return ..() + +/mob/living/basic/pet/update_overlays() + . = ..() + + if(!collar || !collar_icon_state) + return + + // Determine which status tag to add to the middle of the icon state. + var/dead_tag = stat == DEAD ? "_dead" : null + var/rest_tag = has_collar_resting_icon_state && resting ? "_rest" : null + var/stat_tag = dead_tag || rest_tag || "" + + . += mutable_appearance(icon, "[collar_icon_state][stat_tag]collar") + . += mutable_appearance(icon, "[collar_icon_state][stat_tag]tag") + +/mob/living/basic/pet/gib() + . = ..() + + remove_collar(drop_location(), update_visuals = FALSE) + +/mob/living/basic/pet/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) + . = ..() + if(!.) + return + + update_icon(UPDATE_OVERLAYS) + +/mob/living/basic/pet/death(gibbed) + . = ..() + add_memory_in_range(src, 7, MEMORY_PET_DEAD, list(DETAIL_DEUTERAGONIST = src), story_value = STORY_VALUE_AMAZING, memory_flags = MEMORY_CHECK_BLIND_AND_DEAF) //Protagonist is the person memorizing it + +/mob/living/basic/pet/handle_atom_del(atom/deleting_atom) + . = ..() + + if(deleting_atom != collar) + return + + collar = null + + if(QDELETED(src)) + return + + update_icon(UPDATE_OVERLAYS) + +/mob/living/basic/pet/update_stat() + . = ..() + + update_icon(UPDATE_OVERLAYS) + +/mob/living/basic/pet/set_resting(new_resting, silent, instant) + . = ..() + + if(!has_collar_resting_icon_state) + return + + update_icon(UPDATE_OVERLAYS) + +/** + * Add a collar to the pet. + * + * Arguments: + * * new_collar - the collar. + * * user - the user that did it. + */ +/mob/living/basic/pet/proc/add_collar(obj/item/clothing/neck/petcollar/new_collar, mob/user) + if(QDELETED(new_collar) || collar) + return + if(!user.transferItemToLoc(new_collar, src)) + return + + collar = new_collar + if(collar_icon_state) + update_icon(UPDATE_OVERLAYS) + + to_chat(user, span_notice("You put [new_collar] around [src]'s neck.")) + if(new_collar.tagname && !unique_pet) + fully_replace_character_name(null, "\proper [new_collar.tagname]") + +/** + * Remove the collar from the pet. + */ +/mob/living/basic/pet/proc/remove_collar(atom/new_loc, update_visuals = TRUE) + if(!collar) + return + + var/obj/old_collar = collar + + collar.forceMove(new_loc) + collar = null + + if(collar_icon_state && update_visuals) + update_icon(UPDATE_OVERLAYS) + + return old_collar diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 7a2ac852b01..a4c33126782 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -20,6 +20,7 @@ spread_bodyparts(no_brain, no_organs) spawn_gibs(no_bodyparts) + SEND_SIGNAL(src, COMSIG_LIVING_GIBBED, no_brain, no_organs, no_bodyparts) qdel(src) /mob/living/proc/gib_animation() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 6f8c2b6d25c..182f8befe79 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -588,6 +588,7 @@ to_chat(src, span_notice("You stand up.")) get_up(instant) + SEND_SIGNAL(src, COMSIG_LIVING_RESTING, new_resting, silent, instant) update_resting() @@ -1363,9 +1364,9 @@ /mob/living/simple_animal/hostile/megafauna/dragon/lesser, /mob/living/simple_animal/hostile/gorilla, /mob/living/simple_animal/parrot, - /mob/living/simple_animal/pet/dog/corgi, + /mob/living/basic/pet/dog/corgi, /mob/living/simple_animal/crab, - /mob/living/simple_animal/pet/dog/pug, + /mob/living/basic/pet/dog/pug, /mob/living/simple_animal/pet/cat, /mob/living/basic/mouse, /mob/living/simple_animal/chicken, @@ -1374,7 +1375,7 @@ /mob/living/simple_animal/pet/fox, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/pet/cat/cak, - /mob/living/simple_animal/pet/dog/breaddog, + /mob/living/basic/pet/dog/breaddog, /mob/living/simple_animal/chick, ) new_mob = new picked_animal(loc) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 7f3545f9ae7..8dab8456ded 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -31,7 +31,8 @@ mobility_flags = MOBILITY_FLAGS_REST_CAPABLE_DEFAULT var/mob/living/basic/mouse/movement_target gold_core_spawnable = FRIENDLY_SPAWN - collar_type = "cat" + collar_icon_state = "cat" + has_collar_resting_icon_state = TRUE can_be_held = TRUE held_state = "cat2" ///only for attacking rats @@ -72,7 +73,7 @@ icon_state = "breadcat" icon_living = "breadcat" icon_dead = "breadcat_dead" - collar_type = null + collar_icon_state = null held_state = "breadcat" butcher_results = list(/obj/item/food/meat/slab = 2, /obj/item/organ/internal/ears/cat = 1, /obj/item/organ/external/tail/cat = 1, /obj/item/food/breadslice/plain = 1) @@ -86,12 +87,13 @@ icon_state = "original" icon_living = "original" icon_dead = "original_dead" - collar_type = null + collar_icon_state = null unique_pet = TRUE held_state = "original" /mob/living/simple_animal/pet/cat/original/add_cell_sample() return + /mob/living/simple_animal/pet/cat/kitten name = "kitten" desc = "D'aaawwww." @@ -101,7 +103,7 @@ density = FALSE pass_flags = PASSMOB mob_size = MOB_SIZE_SMALL - collar_type = "kitten" + collar_icon_state = "kitten" //RUNTIME IS ALIVE! SQUEEEEEEEE~ /mob/living/simple_animal/pet/cat/runtime @@ -199,11 +201,8 @@ return if (resting) icon_state = "[icon_living]_rest" - collar_type = "[initial(collar_type)]_rest" else icon_state = "[icon_living]" - collar_type = "[initial(collar_type)]" - regenerate_icons() /mob/living/simple_animal/pet/cat/Life(delta_time = SSMOBS_DT, times_fired) @@ -215,7 +214,7 @@ manual_emote(pick("sits down.", "crouches on [p_their()] hind legs.", "looks alert.")) set_resting(TRUE) icon_state = "[icon_living]_sit" - collar_type = "[initial(collar_type)]_sit" + cut_overlays() // No collar support in sitting state else if(DT_PROB(0.5, delta_time)) if (resting) manual_emote(pick("gets up and meows.", "walks around.", "stops resting.")) diff --git a/code/modules/mob/living/simple_animal/friendly/gondola.dm b/code/modules/mob/living/simple_animal/friendly/gondola.dm index 0506f991ca8..31ff9067fd1 100644 --- a/code/modules/mob/living/simple_animal/friendly/gondola.dm +++ b/code/modules/mob/living/simple_animal/friendly/gondola.dm @@ -63,10 +63,6 @@ /mob/living/simple_animal/pet/gondola/can_speak(allow_mimes = FALSE) return FALSE // Gondolas are the silent walker. -/// Special handling for gondolas, as they don't use icon_states and instead rely on overlays. The parent of this proc deletes all our overlays, so we're overriding it. -/mob/living/simple_animal/pet/gondola/regenerate_icons() - return - #undef GONDOLA_HEIGHT #undef GONDOLA_COLOR #undef GONDOLA_MOUSTACHE diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm index 592d411786a..58b1d13ab01 100644 --- a/code/modules/mob/living/simple_animal/friendly/pet.dm +++ b/code/modules/mob/living/simple_animal/friendly/pet.dm @@ -3,77 +3,138 @@ mob_size = MOB_SIZE_SMALL mob_biotypes = MOB_ORGANIC|MOB_BEAST blood_volume = BLOOD_VOLUME_NORMAL - var/unique_pet = FALSE // if the mob can be renamed - var/obj/item/clothing/neck/petcollar/pcollar - var/collar_type //if the mob has collar sprites, define them. -/mob/living/simple_animal/pet/handle_atom_del(atom/A) - if(A == pcollar) - pcollar = null - return ..() + /// if the mob is protected from being renamed by collars. + var/unique_pet = FALSE + /// If the mob has collar sprites, this is the base of the icon states. + var/collar_icon_state + /// We have a seperate _rest collar icon state when the pet is resting. + var/has_collar_resting_icon_state = FALSE -/mob/living/simple_animal/pet/proc/add_collar(obj/item/clothing/neck/petcollar/P, mob/user) - if(QDELETED(P) || pcollar) - return - if(!user.transferItemToLoc(P, src)) - return - pcollar = P - regenerate_icons() - to_chat(user, span_notice("You put the [P] around [src]'s neck.")) - if(P.tagname && !unique_pet) - fully_replace_character_name(null, "\proper [P.tagname]") - -/mob/living/simple_animal/pet/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/clothing/neck/petcollar) && !pcollar) - add_collar(O, user) - return - - if(istype(O, /obj/item/newspaper)) - if(!stat) - user.visible_message(span_notice("[user] baps [name] on the nose with the rolled up [O].")) - dance_rotate(src) - else - ..() + /// Our collar + var/obj/item/clothing/neck/petcollar/collar /mob/living/simple_animal/pet/Initialize(mapload) . = ..() - if(pcollar) - pcollar = new(src) - regenerate_icons() + + /// Can set the collar var beforehand to start the pet with a collar. + if(collar) + collar = new(src) + + update_icon(UPDATE_OVERLAYS) /mob/living/simple_animal/pet/Destroy() - QDEL_NULL(pcollar) + . = ..() + + QDEL_NULL(collar) QDEL_NULL(access_card) + +/mob/living/simple_animal/pet/attackby(obj/item/thing, mob/user, params) + if(istype(thing, /obj/item/clothing/neck/petcollar) && !collar) + add_collar(thing, user) + return TRUE + + if(istype(thing, /obj/item/newspaper) && !stat) + user.visible_message(span_notice("[user] baps [name] on the nose with the rolled up [thing].")) + dance_rotate(src) + return TRUE + return ..() +/mob/living/simple_animal/pet/update_overlays() + . = ..() + + if(!collar || !collar_icon_state) + return + + // Determine which status tag to add to the middle of the icon state. + var/dead_tag = stat == DEAD ? "_dead" : null + var/rest_tag = has_collar_resting_icon_state && resting ? "_rest" : null + var/stat_tag = dead_tag || rest_tag || "" + + . += mutable_appearance(icon, "[collar_icon_state][stat_tag]collar") + . += mutable_appearance(icon, "[collar_icon_state][stat_tag]tag") + /mob/living/simple_animal/pet/gib() - if(pcollar) - pcollar.forceMove(drop_location()) - pcollar = null + . = ..() + if(access_card) access_card.forceMove(drop_location()) access_card = null - return ..() + + remove_collar(drop_location(), update_visuals = FALSE) /mob/living/simple_animal/pet/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) . = ..() if(!.) return - if(collar_type) - collar_type = "[initial(collar_type)]" - regenerate_icons() + update_icon(UPDATE_OVERLAYS) /mob/living/simple_animal/pet/death(gibbed) . = ..() - if(collar_type) - collar_type = "[initial(collar_type)]_dead" - regenerate_icons() - add_memory_in_range(src, 7, MEMORY_PET_DEAD, list(DETAIL_DEUTERAGONIST = src), story_value = STORY_VALUE_AMAZING, memory_flags = MEMORY_CHECK_BLIND_AND_DEAF) //Protagonist is the person memorizing it -/mob/living/simple_animal/pet/regenerate_icons() - cut_overlays() - if(pcollar && collar_type) - add_overlay("[collar_type]collar") - add_overlay("[collar_type]tag") +/mob/living/simple_animal/pet/handle_atom_del(atom/deleting_atom) + . = ..() + + if(deleting_atom != collar) + return + + collar = null + + if(QDELETED(src)) + return + + update_icon(UPDATE_OVERLAYS) + +/mob/living/simple_animal/pet/update_stat() + . = ..() + + update_icon(UPDATE_OVERLAYS) + +/mob/living/simple_animal/pet/set_resting(new_resting, silent, instant) + . = ..() + + if(!has_collar_resting_icon_state) + return + + update_icon(UPDATE_OVERLAYS) + +/** + * Add a collar to the pet. + * + * Arguments: + * * new_collar - the collar. + * * user - the user that did it. + */ +/mob/living/simple_animal/pet/proc/add_collar(obj/item/clothing/neck/petcollar/new_collar, mob/user) + if(QDELETED(new_collar) || collar) + return + if(!user.transferItemToLoc(new_collar, src)) + return + + collar = new_collar + if(collar_icon_state) + update_icon(UPDATE_OVERLAYS) + + to_chat(user, span_notice("You put [new_collar] around [src]'s neck.")) + if(new_collar.tagname && !unique_pet) + fully_replace_character_name(null, "\proper [new_collar.tagname]") + +/** + * Remove the collar from the pet. + */ +/mob/living/simple_animal/pet/proc/remove_collar(atom/new_loc, update_visuals = TRUE) + if(!collar) + return + + var/obj/old_collar = collar + + collar.forceMove(new_loc) + collar = null + + if(collar_icon_state && update_visuals) + update_icon(UPDATE_OVERLAYS) + + return old_collar diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 634597cf0b1..b8102bb60ce 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -264,7 +264,7 @@ for(var/t in bodyparts) //this really should not be necessary qdel(t) - var/mob/living/simple_animal/pet/dog/corgi/new_corgi = new /mob/living/simple_animal/pet/dog/corgi (loc) + var/mob/living/basic/pet/dog/corgi/new_corgi = new /mob/living/basic/pet/dog/corgi (loc) new_corgi.set_combat_mode(TRUE) new_corgi.key = key @@ -368,7 +368,7 @@ //Good mobs! if(ispath(MP, /mob/living/simple_animal/pet/cat)) return TRUE - if(ispath(MP, /mob/living/simple_animal/pet/dog/corgi)) + if(ispath(MP, /mob/living/basic/pet/dog/corgi)) return TRUE if(ispath(MP, /mob/living/simple_animal/crab)) return TRUE diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index c64069721e0..40d470e4c82 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -562,7 +562,7 @@ /datum/chemical_reaction/corgium/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) var/location = get_turf(holder.my_atom) for(var/i in rand(1, created_volume) to created_volume) // More lulz. - new /mob/living/simple_animal/pet/dog/corgi(location) + new /mob/living/basic/pet/dog/corgi(location) ..() //monkey powder heehoo diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 86ad8b92e42..cfcef788dc3 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -94,7 +94,7 @@ /obj/machinery/rnd/experimentor/Initialize(mapload) . = ..() - tracked_ian_ref = WEAKREF(locate(/mob/living/simple_animal/pet/dog/corgi/ian) in GLOB.mob_living_list) + tracked_ian_ref = WEAKREF(locate(/mob/living/basic/pet/dog/corgi/ian) in GLOB.mob_living_list) tracked_runtime_ref = WEAKREF(locate(/mob/living/simple_animal/pet/cat/runtime) in GLOB.mob_living_list) critical_items_typecache = typecacheof(list( @@ -498,7 +498,7 @@ tracked_ian.forceMove(loc) investigate_log("Experimentor has stolen Ian!", INVESTIGATE_EXPERIMENTOR) //...if anyone ever fixes it... else - new /mob/living/simple_animal/pet/dog/corgi(loc) + new /mob/living/basic/pet/dog/corgi(loc) investigate_log("Experimentor has spawned a new corgi.", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) if(globalMalf > 36 && globalMalf < 50) @@ -616,8 +616,8 @@ /obj/item/relic/proc/corgicannon(mob/user) playsound(src, SFX_SPARKS, rand(25,50), TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - var/mob/living/simple_animal/pet/dog/corgi/C = new/mob/living/simple_animal/pet/dog/corgi(get_turf(user)) - C.throw_at(pick(oview(10,user)), 10, rand(3,8), callback = CALLBACK(src, PROC_REF(throwSmoke), C)) + var/mob/living/basic/pet/dog/corgi/sad_corgi = new(get_turf(user)) + sad_corgi.throw_at(pick(oview(10,user)), 10, rand(3,8), callback = CALLBACK(src, PROC_REF(throwSmoke), sad_corgi)) warn_admins(user, "Corgi Cannon", 0) /obj/item/relic/proc/clean(mob/user) @@ -642,12 +642,12 @@ /mob/living/simple_animal/parrot/natural, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/pet/cat, - /mob/living/simple_animal/pet/dog/corgi, + /mob/living/basic/pet/dog/corgi, + /mob/living/basic/pet/dog/pug, /mob/living/simple_animal/crab, /mob/living/simple_animal/pet/fox, /mob/living/simple_animal/hostile/lizard, /mob/living/basic/mouse, - /mob/living/simple_animal/pet/dog/pug, /mob/living/simple_animal/hostile/bear, /mob/living/simple_animal/hostile/bee, /mob/living/simple_animal/hostile/carp, diff --git a/code/modules/research/xenobiology/crossbreeding/_mobs.dm b/code/modules/research/xenobiology/crossbreeding/_mobs.dm index cbaabdf35d5..ecf18cd027d 100644 --- a/code/modules/research/xenobiology/crossbreeding/_mobs.dm +++ b/code/modules/research/xenobiology/crossbreeding/_mobs.dm @@ -38,7 +38,7 @@ Slimecrossing Mobs return //Slime corgi - Chilling Pink -/mob/living/simple_animal/pet/dog/corgi/puppy/slime +/mob/living/basic/pet/dog/corgi/puppy/slime name = "\improper slime corgi puppy" real_name = "slime corgi puppy" desc = "An unbearably cute pink slime corgi puppy." @@ -48,5 +48,8 @@ Slimecrossing Mobs nofur = TRUE gold_core_spawnable = NO_SPAWN speak_emote = list("blorbles", "bubbles", "borks") - emote_hear = list("bubbles!", "splorts.", "splops!") - emote_see = list("gets goop everywhere.", "flops.", "jiggles!") + +/mob/living/basic/pet/dog/corgi/puppy/slime/update_dog_speech(datum/ai_planning_subtree/random_speech/speech) + speech.speak = string_list(list()) + speech.emote_hear = string_list(list("bubbles!", "splorts.", "splops!")) + speech.emote_see = string_list(list("gets goop everywhere.", "flops.", "jiggles!")) diff --git a/code/modules/research/xenobiology/crossbreeding/chilling.dm b/code/modules/research/xenobiology/crossbreeding/chilling.dm index 378e4767bf1..18f5a2849ca 100644 --- a/code/modules/research/xenobiology/crossbreeding/chilling.dm +++ b/code/modules/research/xenobiology/crossbreeding/chilling.dm @@ -269,7 +269,7 @@ Chilling extracts: /obj/item/slimecross/chilling/pink/do_effect(mob/user) user.visible_message(span_notice("[src] cracks like an egg, and an adorable puppy comes tumbling out!")) - new /mob/living/simple_animal/pet/dog/corgi/puppy/slime(get_turf(user)) + new /mob/living/basic/pet/dog/corgi/puppy/slime(get_turf(user)) ..() /obj/item/slimecross/chilling/gold diff --git a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm index 402c0a5ade4..0b3cf60d648 100644 --- a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm +++ b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm @@ -128,7 +128,7 @@ /datum/reagent/consumable/coco = -2) virus_suspectibility = 1 - resulting_atoms = list(/mob/living/simple_animal/pet/dog/corgi = 1) + resulting_atoms = list(/mob/living/basic/pet/dog/corgi = 1) /datum/micro_organism/cell_line/pug desc = "Squat canid cells" @@ -146,7 +146,7 @@ /datum/reagent/consumable/coco = -2) virus_suspectibility = 3 - resulting_atoms = list(/mob/living/simple_animal/pet/dog/pug = 1) + resulting_atoms = list(/mob/living/basic/pet/dog/pug = 1) /datum/micro_organism/cell_line/bear //bears can't really compete directly with more powerful creatures, so i made it possible to grow them real fast. desc = "Ursine cells" diff --git a/code/modules/spells/spell_types/shapeshift/shapechange.dm b/code/modules/spells/spell_types/shapeshift/shapechange.dm index 2b52826b367..d7b2f36da64 100644 --- a/code/modules/spells/spell_types/shapeshift/shapechange.dm +++ b/code/modules/spells/spell_types/shapeshift/shapechange.dm @@ -12,7 +12,7 @@ possible_shapes = list( /mob/living/basic/mouse, - /mob/living/simple_animal/pet/dog/corgi, + /mob/living/basic/pet/dog/corgi, /mob/living/simple_animal/hostile/carp/ranged/chaos, /mob/living/simple_animal/bot/secbot/ed209, /mob/living/simple_animal/hostile/giant_spider/viper/wizard, diff --git a/code/modules/unit_tests/mindbound_actions.dm b/code/modules/unit_tests/mindbound_actions.dm index 703144e2203..b9c934bc1e8 100644 --- a/code/modules/unit_tests/mindbound_actions.dm +++ b/code/modules/unit_tests/mindbound_actions.dm @@ -5,9 +5,8 @@ /datum/unit_test/actions_moved_on_mind_transfer /datum/unit_test/actions_moved_on_mind_transfer/Run() - var/mob/living/carbon/human/wizard = allocate(/mob/living/carbon/human/consistent) - var/mob/living/simple_animal/pet/dog/corgi/wizard_dog = allocate(/mob/living/simple_animal/pet/dog/corgi) + var/mob/living/basic/pet/dog/corgi/wizard_dog = allocate(/mob/living/basic/pet/dog/corgi) wizard.mind_initialize() var/datum/action/cooldown/spell/pointed/projectile/fireball/fireball = new(wizard.mind) diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 90aff229a33..995ebf3837a 100644 --- a/code/modules/unit_tests/simple_animal_freeze.dm +++ b/code/modules/unit_tests/simple_animal_freeze.dm @@ -357,20 +357,6 @@ /mob/living/simple_animal/pet/cat/original, /mob/living/simple_animal/pet/cat/runtime, /mob/living/simple_animal/pet/cat/space, - /mob/living/simple_animal/pet/dog, - /mob/living/simple_animal/pet/dog/breaddog, - /mob/living/simple_animal/pet/dog/bullterrier, - /mob/living/simple_animal/pet/dog/corgi, - /mob/living/simple_animal/pet/dog/corgi/exoticcorgi, - /mob/living/simple_animal/pet/dog/corgi/ian, - /mob/living/simple_animal/pet/dog/corgi/lisa, - /mob/living/simple_animal/pet/dog/corgi/narsie, - /mob/living/simple_animal/pet/dog/corgi/puppy, - /mob/living/simple_animal/pet/dog/corgi/puppy/ian, - /mob/living/simple_animal/pet/dog/corgi/puppy/slime, - /mob/living/simple_animal/pet/dog/corgi/puppy/void, - /mob/living/simple_animal/pet/dog/pug, - /mob/living/simple_animal/pet/dog/pug/mcgriff, /mob/living/simple_animal/pet/fox, /mob/living/simple_animal/pet/fox/renault, /mob/living/simple_animal/pet/gondola, diff --git a/code/modules/unit_tests/strippable.dm b/code/modules/unit_tests/strippable.dm index 96a879777f2..bb697de424c 100644 --- a/code/modules/unit_tests/strippable.dm +++ b/code/modules/unit_tests/strippable.dm @@ -57,5 +57,5 @@ ADD_TRAIT(rouny, TRAIT_PRESERVE_UI_WITHOUT_CLIENT, TRAIT_SOURCE_UNIT_TESTS) TEST_ASSERT_EQUAL(strip_menu.ui_status(rouny, ui_state), UI_INTERACTIVE, "Being within range as a xeno was not interactive.") - var/mob/living/simple_animal/pet/dog/corgi/corgi = allocate(/mob/living/simple_animal/pet/dog/corgi, run_loc_floor_bottom_left) + var/mob/living/basic/pet/dog/corgi/corgi = allocate(/mob/living/basic/pet/dog/corgi, run_loc_floor_bottom_left) TEST_ASSERT_EQUAL(strip_menu.ui_status(corgi, ui_state), UI_UPDATE, "Being within range as a corgi was not update-only.") diff --git a/tgstation.dme b/tgstation.dme index ae84070b2a8..a2de506ed82 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -704,6 +704,8 @@ #include "code\datums\ai\_ai_planning_subtree.dm" #include "code\datums\ai\_item_behaviors.dm" #include "code\datums\ai\telegraph_effects.dm" +#include "code\datums\ai\babies\babies_behaviors.dm" +#include "code\datums\ai\babies\babies_subtrees.dm" #include "code\datums\ai\bane\bane_behaviors.dm" #include "code\datums\ai\bane\bane_controller.dm" #include "code\datums\ai\bane\bane_subtrees.dm" @@ -3600,6 +3602,8 @@ #include "code\modules\mob\living\basic\lavaland\bileworm\bileworm_instrument.dm" #include "code\modules\mob\living\basic\lavaland\bileworm\bileworm_loot.dm" #include "code\modules\mob\living\basic\lavaland\bileworm\bileworm_vileworm.dm" +#include "code\modules\mob\living\basic\pets\dog.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\vermin\cockroach.dm" #include "code\modules\mob\living\basic\vermin\mothroach.dm" @@ -3771,7 +3775,6 @@ #include "code\modules\mob\living\simple_animal\friendly\butterfly.dm" #include "code\modules\mob\living\simple_animal\friendly\cat.dm" #include "code\modules\mob\living\simple_animal\friendly\crab.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\gondola.dm" diff --git a/tgui/packages/tgui/interfaces/StripMenu.tsx b/tgui/packages/tgui/interfaces/StripMenu.tsx index 6deb96983bd..a3534736e2e 100644 --- a/tgui/packages/tgui/interfaces/StripMenu.tsx +++ b/tgui/packages/tgui/interfaces/StripMenu.tsx @@ -105,7 +105,7 @@ const SLOTS: Record< image: 'inventory-mask.png', }, - corgi_collar: { + pet_collar: { displayName: 'collar', gridSpot: getGridSpotKey([1, 2]), image: 'inventory-collar.png', diff --git a/tools/UpdatePaths/Scripts/70799_dog.txt b/tools/UpdatePaths/Scripts/70799_dog.txt new file mode 100644 index 00000000000..5fa46436466 --- /dev/null +++ b/tools/UpdatePaths/Scripts/70799_dog.txt @@ -0,0 +1 @@ +/mob/living/simple_animal/pet/dog/@SUBTYPES : /mob/living/basic/pet/dog/@SUBTYPES {@OLD}