Skip to content

Commit

Permalink
basic cats and mini kitchen helpers (tgstation#79800)
Browse files Browse the repository at this point in the history
## About The Pull Request
this pr transforms cats into basic pets! cats now have some new
behavior. they can carry fish and hunted mice in their mouths to deliver
it to kittens, and kittens will eat them.


![catmouse](https://github.com/tgstation/tgstation/assets/138636438/8f146be4-c7b2-41d3-8301-734be49b5efc)

![catfish](https://github.com/tgstation/tgstation/assets/138636438/f8df54f2-9183-406d-afbd-f90f415f7f3d)

if a kitten sees you holding food, it will point at you and meow loudly
until u give it the food.
becareful when putting male cats near each other, there is a small
chance they get into a heated argument and meow loudly at each other
until one of them flees.
also added a new small cat house for cats. cats will use these homes if
u build one near them (using 5 wood planks)


![cathouse](https://github.com/tgstation/tgstation/assets/138636438/9515a78c-fdfe-461b-bad2-6b497117c694)

Chefs can craft the cake cat and breadcat. these are useful cats because
they can help the chef around in the kitchen. they will turn stoves and
grills off when food is ready, so they dont burn. and the cake cat will
help the chef decorate his donuts

## Why It's Good For The Game
refactors cats into basic mobs and gives them a deeper ai

## Changelog
:cl:
refactor: cats are now basic pets. please report any bugs.
add: the cake cat and bread cat can now help the chef around in the
kitchen
/:cl:
  • Loading branch information
Ben10Omintrix authored Nov 29, 2023
1 parent 3516674 commit ce6f272
Show file tree
Hide file tree
Showing 52 changed files with 968 additions and 400 deletions.
2 changes: 1 addition & 1 deletion _maps/RandomRuins/SpaceRuins/derelict_sulaco.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@
/turf/open/floor/carpet,
/area/ruin/space/has_grav/derelictsulaco)
"BQ" = (
/mob/living/simple_animal/pet/cat{
/mob/living/basic/pet/cat{
name = "Jonesy";
desc = "Old and grumpy cat- wait, how the hell is he still alive?!"
},
Expand Down
2 changes: 1 addition & 1 deletion _maps/RandomRuins/SpaceRuins/mrow_thats_right.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@
/obj/structure/bed/dogbed{
name = "kitty bed"
},
/mob/living/simple_animal/pet/cat/space,
/mob/living/basic/pet/cat/space,
/turf/open/floor/carpet,
/area/ruin/space/has_grav/powered/cat_man)
"aS" = (
Expand Down
2 changes: 1 addition & 1 deletion _maps/RandomZLevels/moonoutpost19.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -5120,7 +5120,7 @@
},
/area/awaymission/moonoutpost19/research)
"HP" = (
/mob/living/simple_animal/pet/cat/space{
/mob/living/basic/pet/cat/space{
desc = "With survival instincts like these, it's no wonder cats survived to the 26th century.";
name = "Jones"
},
Expand Down
2 changes: 1 addition & 1 deletion _maps/map_files/Birdshot/birdshot.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -36376,7 +36376,7 @@
},
/obj/machinery/airalarm/directional/north,
/obj/structure/bed/dogbed/runtime,
/mob/living/simple_animal/pet/cat/runtime,
/mob/living/basic/pet/cat/runtime,
/turf/open/floor/iron/white/small,
/area/station/command/heads_quarters/cmo)
"mVt" = (
Expand Down
2 changes: 1 addition & 1 deletion _maps/map_files/Deltastation/DeltaStation2.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -81835,7 +81835,7 @@
/obj/effect/turf_decal/tile/neutral/half/contrasted{
dir = 1
},
/mob/living/simple_animal/pet/cat/runtime,
/mob/living/basic/pet/cat/runtime,
/turf/open/floor/iron,
/area/station/command/heads_quarters/cmo)
"utK" = (
Expand Down
2 changes: 1 addition & 1 deletion _maps/map_files/IceBoxStation/IceBoxStation.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -73215,7 +73215,7 @@
/obj/structure/bed/dogbed/runtime,
/obj/item/toy/cattoy,
/obj/machinery/newscaster/directional/north,
/mob/living/simple_animal/pet/cat/runtime,
/mob/living/basic/pet/cat/runtime,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/cmo)
"wwn" = (
Expand Down
2 changes: 1 addition & 1 deletion _maps/map_files/MetaStation/MetaStation.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -26189,7 +26189,7 @@
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 4
},
/mob/living/simple_animal/pet/cat/runtime,
/mob/living/basic/pet/cat/runtime,
/turf/open/floor/iron/white,
/area/station/command/heads_quarters/cmo)
"juV" = (
Expand Down
2 changes: 1 addition & 1 deletion _maps/map_files/NorthStar/north_star.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -71828,7 +71828,7 @@
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 5
},
/mob/living/simple_animal/pet/cat/runtime,
/mob/living/basic/pet/cat/runtime,
/turf/open/floor/iron/white,
/area/station/command/heads_quarters/cmo)
"sPk" = (
Expand Down
4 changes: 2 additions & 2 deletions _maps/map_files/tramstation/tramstation.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -32242,7 +32242,7 @@
desc = "A comfy-looking cat bed. You can even strap your pet in, in case the gravity turns off.";
name = "cat bed"
},
/mob/living/simple_animal/pet/cat/jerry,
/mob/living/basic/pet/cat/jerry,
/turf/open/floor/iron,
/area/station/maintenance/tram/mid)
"kxF" = (
Expand Down Expand Up @@ -51713,7 +51713,7 @@
/obj/structure/bed/dogbed/runtime,
/obj/structure/sign/clock/directional/north,
/obj/machinery/light/cold/directional/north,
/mob/living/simple_animal/pet/cat/runtime,
/mob/living/basic/pet/cat/runtime,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/cmo)
"rsz" = (
Expand Down
2 changes: 1 addition & 1 deletion _maps/shuttles/emergency_hugcage.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/escape)
"Hf" = (
/mob/living/simple_animal/pet/cat/kitten,
/mob/living/basic/pet/cat/kitten,
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/escape)
"IH" = (
Expand Down
2 changes: 1 addition & 1 deletion _maps/virtual_domains/pipedream.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -1819,7 +1819,7 @@
/turf/open/floor/plating,
/area/virtual_domain)
"Ym" = (
/mob/living/simple_animal/pet/cat/space,
/mob/living/basic/pet/cat/space,
/obj/structure/bed/dogbed{
name = "cat bed"
},
Expand Down
28 changes: 28 additions & 0 deletions code/__DEFINES/ai/monsters.dm
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,34 @@
/// Key for the next time we can cast a spell
#define BB_WIZARD_SPELL_COOLDOWN "BB_wizard_spell_cooldown"


//cat AI keys
/// key that holds the target we will battle over our turf
#define BB_TRESSPASSER_TARGET "tresspasser_target"
/// key that holds angry meows
#define BB_HOSTILE_MEOWS "hostile_meows"
/// key that holds the mouse target
#define BB_MOUSE_TARGET "mouse_target"
/// key that holds our dinner target
#define BB_CAT_FOOD_TARGET "cat_food_target"
/// key that holds the food we must deliver
#define BB_FOOD_TO_DELIVER "food_to_deliver"
/// key that holds things we can hunt
#define BB_HUNTABLE_PREY "huntable_prey"
/// key that holds target kitten to feed
#define BB_KITTEN_TO_FEED "kitten_to_feed"
/// key that holds our hungry meows
#define BB_HUNGRY_MEOW "hungry_meows"
/// key that holds maximum distance food is to us so we can pursue it
#define BB_MAX_DISTANCE_TO_FOOD "max_distance_to_food"
/// key that holds the stove we must turn off
#define BB_STOVE_TARGET "stove_target"
/// key that holds the donut we will decorate
#define BB_DONUT_TARGET "donut_target"
/// key that holds our home...
#define BB_CAT_HOME "cat_home"
/// key that holds the human we will beg
#define BB_HUMAN_BEG_TARGET "human_beg_target"
//netguardians
/// rocket launcher
#define BB_NETGUARDIAN_ROCKET_ABILITY "netguardian_rocket"
2 changes: 1 addition & 1 deletion code/__DEFINES/is_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list(

#define isdrone(A) (istype(A, /mob/living/basic/drone))

#define iscat(A) (istype(A, /mob/living/simple_animal/pet/cat))
#define iscat(A) (istype(A, /mob/living/basic/pet/cat))

#define isdog(A) (istype(A, /mob/living/basic/pet/dog))

Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/traits/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_MOB_BREEDER "mob_breeder"
/// Trait given to mobs that we do not want to mindswap
#define TRAIT_NO_MINDSWAP "no_mindswap"
///trait given to food that can be baked by /datum/component/bakeable
#define TRAIT_BAKEABLE "bakeable"

/// Trait given to foam darts that have an insert in them
#define TRAIT_DART_HAS_INSERT "dart_has_insert"
Expand Down
1 change: 1 addition & 0 deletions code/_globalvars/traits/_traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_TRANSFORM_ACTIVE" = TRAIT_TRANSFORM_ACTIVE,
"TRAIT_UNCATCHABLE" = TRAIT_UNCATCHABLE,
"TRAIT_WIELDED" = TRAIT_WIELDED,
"TRAIT_BAKEABLE" = TRAIT_BAKEABLE,
),
/obj/item/ammo_casing = list(
"TRAIT_DART_HAS_INSERT" = TRAIT_DART_HAS_INSERT,
Expand Down
6 changes: 5 additions & 1 deletion code/datums/ai/basic_mobs/basic_subtrees/find_food.dm
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
/// similar to finding a target but looks for food types in the // the what?
/datum/ai_planning_subtree/find_food
///behavior we use to find the food
var/datum/ai_behavior/finding_behavior = /datum/ai_behavior/find_and_set/in_list
///key of foods list
var/food_list_key = BB_BASIC_FOODS

/datum/ai_planning_subtree/find_food/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
if(controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET))
// Busy with something
return

controller.queue_behavior(/datum/ai_behavior/find_and_set/in_list, BB_BASIC_MOB_CURRENT_TARGET, controller.blackboard[BB_BASIC_FOODS])
controller.queue_behavior(finding_behavior, BB_BASIC_MOB_CURRENT_TARGET, controller.blackboard[food_list_key])
8 changes: 8 additions & 0 deletions code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@
emote_hear = list("rawrs.","grumbles.","grawls.", "stomps!")
emote_see = list("stares ferociously.")

/datum/ai_planning_subtree/random_speech/cats
speech_chance = 10
speak = list(
"mrawww!",
"meow!",
"maw!",
)

/datum/ai_planning_subtree/random_speech/blackboard //literal tower of babel, subtree form
speech_chance = 1

Expand Down
7 changes: 7 additions & 0 deletions code/datums/ai/generic/find_and_set.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@
var/mob/living/living_pawn = controller.pawn
return locate(locate_path) in living_pawn.held_items

/datum/ai_behavior/find_and_set/in_hands/given_list

/datum/ai_behavior/find_and_set/in_hands/given_list/search_tactic(datum/ai_controller/controller, locate_paths)
var/list/found = typecache_filter_list(controller.pawn, locate_paths)
if(length(found))
return pick(found)

/**
* Variant of find and set that takes a list of things to find.
*/
Expand Down
4 changes: 2 additions & 2 deletions code/datums/ai/hunting_behavior/hunting_behaviors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@
if(!valid_dinner(living_mob, possible_dinner, hunt_range))
continue
controller.set_blackboard_key(hunting_target_key, possible_dinner)
finish_action(controller, TRUE)
finish_action(controller, TRUE, hunting_target_key)
return

finish_action(controller, FALSE)
finish_action(controller, FALSE, hunting_target_key)

/datum/ai_behavior/find_hunt_target/proc/valid_dinner(mob/living/source, atom/dinner, radius)
if(isliving(dinner))
Expand Down
3 changes: 3 additions & 0 deletions code/datums/components/bakeable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
src.required_bake_time = required_bake_time
src.positive_result = positive_result
src.added_reagents = added_reagents
if(positive_result)
ADD_TRAIT(parent, TRAIT_BAKEABLE, REF(src))

// Inherit the new values passed to the component
/datum/component/bakeable/InheritComponent(datum/component/bakeable/new_comp, original, bake_result, required_bake_time, positive_result, use_large_steam_sprite)
Expand All @@ -45,6 +47,7 @@

/datum/component/bakeable/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_ITEM_OVEN_PLACED_IN, COMSIG_ITEM_OVEN_PROCESS, COMSIG_ATOM_EXAMINE))
REMOVE_TRAIT(parent, TRAIT_BAKEABLE, REF(src))

/// Signal proc for [COMSIG_ITEM_OVEN_PLACED_IN] when baking starts (parent enters an oven)
/datum/component/bakeable/proc/on_baking_start(datum/source, atom/used_oven, mob/baker)
Expand Down
32 changes: 32 additions & 0 deletions code/datums/elements/consumable_mob.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* element for mobs that can be consumed!
*/
/datum/element/consumable_mob
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
///reagents to give our consumer
var/list/reagents_list

/datum/element/consumable_mob/Attach(datum/target, list/reagents_list)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
if(isnull((reagents_list)))
stack_trace("No valid reagents list provided!")

src.reagents_list = reagents_list
RegisterSignal(target, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_consume))

/datum/element/consumable_mob/Detach(datum/target)
. = ..()
UnregisterSignal(target, COMSIG_ATOM_ATTACK_HAND)

/datum/element/consumable_mob/proc/on_consume(atom/movable/source, mob/living/consumer)
SIGNAL_HANDLER
if(!consumer.combat_mode || !consumer.reagents)
return
for(var/reagent_type in reagents_list)
if(isnull(reagents_list[reagent_type]))
return
consumer.reagents.add_reagent(reagent_type, reagents_list[reagent_type])

4 changes: 2 additions & 2 deletions code/datums/memory/_memory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@
/mob/living/basic/mouse,
/mob/living/basic/mushroom,
/mob/living/basic/parrot,
/mob/living/basic/pet/cat,
/mob/living/basic/pet/cat/cak,
/mob/living/basic/pet/dog/breaddog,
/mob/living/basic/pet/dog/corgi,
/mob/living/basic/pet/dog/pug,
Expand All @@ -277,8 +279,6 @@
/mob/living/basic/stickman,
/mob/living/basic/stickman/dog,
/mob/living/simple_animal/hostile/megafauna/dragon/lesser,
/mob/living/simple_animal/pet/cat,
/mob/living/simple_animal/pet/cat/cak,
/obj/item/food/sausage/american,
/obj/item/skub,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"oh, let me guess, you're a big fan of those japanese tourist bots",
)
input_obj_or_mob = list(
/mob/living/simple_animal/pet/cat,
/mob/living/basic/pet/cat,
)
output_organs = list(
/obj/item/organ/internal/ears/cat,
Expand Down
14 changes: 0 additions & 14 deletions code/game/objects/items/devices/laserpointer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -270,20 +270,6 @@
target_felinid.visible_message(span_notice("[target_felinid] looks briefly distracted by the light."), span_warning("You're briefly tempted by the shiny light..."))
else
target_felinid.visible_message(span_notice("[target_felinid] stares at the light."), span_warning("You stare at the light..."))

//cats! - chance for any cat near the target to pounce at the light, stepping to the target
for(var/mob/living/simple_animal/pet/cat/target_kitty in view(1, targloc))
if(target_kitty.stat == DEAD)
continue
if(prob(effectchance * diode.rating))
if(target_kitty.resting)
target_kitty.set_resting(FALSE, instant = TRUE)
target_kitty.visible_message(span_notice("[target_kitty] pounces on the light!"), span_warning("LIGHT!"))
target_kitty.Move(targloc)
target_kitty.Immobilize(1 SECONDS)
else
target_kitty.visible_message(span_notice("[target_kitty] looks uninterested in your games."), span_warning("You spot [user] shining [src] at you. How insulting!"))

//The pointer is shining, change its sprite to show
icon_state = "pointer_[pointer_icon_state]"

Expand Down
1 change: 1 addition & 0 deletions code/game/objects/items/stacks/sheets/sheet_types.dm
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 2 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_DOORS), \
new/datum/stack_recipe("wooden stairs frame", /obj/structure/stairs_frame/wood, 10, time = 5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_STRUCTURE), \
new/datum/stack_recipe("wooden fence", /obj/structure/railing/wooden_fence, 2, time = 5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_STRUCTURE), \
new/datum/stack_recipe("cat house", /obj/structure/cat_house, 5, time = 5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_STRUCTURE), \
new/datum/stack_recipe("coffin", /obj/structure/closet/crate/coffin, 5, time = 1.5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_FURNITURE), \
new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 1.5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_FURNITURE), \
new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 1.5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_TOOLS), \
Expand Down
46 changes: 46 additions & 0 deletions code/game/objects/structures/cat_house.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/obj/structure/cat_house
name = "cat house"
desc = "cozy home for cats"
icon = 'icons/mob/simple/pets.dmi'
icon_state = "cat_house"
density = TRUE
anchored = TRUE
///cat residing in this house
var/mob/living/resident_cat

/obj/structure/cat_house/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_ATOM_ATTACK_BASIC_MOB, PROC_REF(enter_home))

/obj/structure/cat_house/proc/enter_home(datum/source, mob/living/attacker)
SIGNAL_HANDLER

if(isnull(resident_cat) && istype(attacker, /mob/living/basic/pet/cat))
attacker.forceMove(src)
return
if(resident_cat == attacker)
attacker.forceMove(drop_location())

/obj/structure/cat_house/Entered(atom/movable/mover)
. = ..()
if(!istype(mover, /mob/living/basic/pet/cat))
return
resident_cat = mover
update_appearance(UPDATE_OVERLAYS)

/obj/structure/cat_house/Exited(atom/movable/mover)
. = ..()
if(mover != resident_cat)
return
resident_cat = null
update_appearance(UPDATE_OVERLAYS)

/obj/structure/cat_house/update_overlays()
. = ..()
if(isnull(resident_cat))
return
var/image/cat_icon = image(icon = resident_cat.icon, icon_state = resident_cat.icon_state, layer = LOW_ITEM_LAYER)
cat_icon.transform = cat_icon.transform.Scale(0.7, 0.7)
cat_icon.pixel_x = 0
cat_icon.pixel_y = -9
. += cat_icon
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
possible_shapes = list(
/mob/living/basic/carp,
/mob/living/basic/mouse,
/mob/living/basic/pet/cat,
/mob/living/basic/pet/dog/corgi,
/mob/living/basic/pet/fox,
/mob/living/simple_animal/bot/secbot,
/mob/living/simple_animal/pet/cat,
)
2 changes: 1 addition & 1 deletion code/modules/antagonists/traitor/objectives/kill_pet.dm
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/mob/living/basic/pet/dog/corgi/puppy/ian
),
JOB_CAPTAIN = /mob/living/basic/pet/fox/renault,
JOB_CHIEF_MEDICAL_OFFICER = /mob/living/simple_animal/pet/cat/runtime,
JOB_CHIEF_MEDICAL_OFFICER = /mob/living/basic/pet/cat/runtime,
JOB_CHIEF_ENGINEER = /mob/living/basic/parrot/poly,
JOB_QUARTERMASTER = list(
/mob/living/basic/gorilla/cargorilla,
Expand Down
Loading

0 comments on commit ce6f272

Please sign in to comment.