//Cat /mob/living/simple_animal/pet/cat name = "cat" desc = "Kitty!!" icon = 'icons/mob/pets.dmi' icon_state = "cat2" icon_living = "cat2" icon_dead = "cat2_dead" gender = MALE speak = list("Meow!", "Esp!", "Purr!", "HSSSSS") speak_emote = list("purrs", "meows") emote_hear = list("meows.", "mews.") emote_see = list("shakes its head.", "shivers.") speak_chance = 1 turns_per_move = 5 see_in_dark = 6 ventcrawler = VENTCRAWLER_ALWAYS pass_flags = PASSTABLE mob_size = MOB_SIZE_SMALL mob_biotypes = MOB_ORGANIC|MOB_BEAST minbodytemp = 200 maxbodytemp = 400 unsuitable_atmos_damage = 1 animal_species = /mob/living/simple_animal/pet/cat childtype = list(/mob/living/simple_animal/pet/cat/kitten) butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/organ/ears/cat = 1, /obj/item/organ/tail/cat = 1) response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" var/turns_since_scan = 0 var/mob/living/simple_animal/mouse/movement_target gold_core_spawnable = FRIENDLY_SPAWN collar_type = "cat" var/held_icon = "cat2" do_footstep = TRUE /mob/living/simple_animal/pet/cat/Initialize() . = ..() verbs += /mob/living/proc/lay_down /mob/living/simple_animal/pet/cat/ComponentInitialize() . = ..() AddElement(/datum/element/wuv, "purrs!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "hisses!", EMOTE_AUDIBLE) AddElement(/datum/element/mob_holder, held_icon) /mob/living/simple_animal/pet/cat/update_mobility() . = ..() if(client && stat != DEAD) if(!CHECK_MOBILITY(src, MOBILITY_STAND)) 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/space name = "space cat" desc = "It's a cat... in space!" icon_state = "spacecat" icon_living = "spacecat" icon_dead = "spacecat_dead" held_icon = "spacecat" unsuitable_atmos_damage = 0 minbodytemp = TCMB maxbodytemp = T0C + 40 /mob/living/simple_animal/pet/cat/original name = "Batsy" desc = "The product of alien DNA and bored geneticists." gender = FEMALE icon_state = "original" icon_living = "original" icon_dead = "original_dead" held_icon = "original" collar_type = null unique_pet = TRUE /mob/living/simple_animal/pet/cat/kitten name = "kitten" desc = "D'aaawwww." icon_state = "kitten" icon_living = "kitten" icon_dead = "kitten_dead" density = FALSE pass_flags = PASSMOB mob_size = MOB_SIZE_SMALL collar_type = "kitten" //RUNTIME IS ALIVE! SQUEEEEEEEE~ /mob/living/simple_animal/pet/cat/Runtime name = "Runtime" desc = "GCAT" icon_state = "cat" icon_living = "cat" icon_dead = "cat_dead" gender = FEMALE gold_core_spawnable = NO_SPAWN unique_pet = TRUE held_icon = "cat" var/list/family = list()//var restored from savefile, has count of each child type var/list/children = list()//Actual mob instances of children var/cats_deployed = 0 var/memory_saved = FALSE /mob/living/simple_animal/pet/cat/Runtime/Initialize() if(prob(5)) icon_state = "original" icon_living = "original" icon_dead = "original_dead" Read_Memory() . = ..() /mob/living/simple_animal/pet/cat/Runtime/Life() if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP) Deploy_The_Cats() if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) Write_Memory() memory_saved = TRUE ..() /mob/living/simple_animal/pet/cat/Runtime/make_babies() var/mob/baby = ..() if(baby) children += baby return baby /mob/living/simple_animal/pet/cat/Runtime/death() if(!memory_saved) Write_Memory(TRUE) ..() /mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory() if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") S["family"] >> family fdel("data/npc_saves/Runtime.sav") else var/json_file = file("data/npc_saves/Runtime.json") if(!fexists(json_file)) return var/list/json = json_decode(file2text(json_file)) family = json["family"] if(isnull(family)) family = list() /mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead) var/json_file = file("data/npc_saves/Runtime.json") var/list/file_data = list() family = list() if(!dead) for(var/mob/living/simple_animal/pet/cat/kitten/C in children) if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats continue if(C.type in family) family[C.type] += 1 else family[C.type] = 1 file_data["family"] = family fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) /mob/living/simple_animal/pet/cat/Runtime/proc/Deploy_The_Cats() cats_deployed = 1 for(var/cat_type in family) if(family[cat_type] > 0) for(var/i in 1 to min(family[cat_type],100)) //Limits to about 500 cats, you wouldn't think this would be needed (BUT IT IS) new cat_type(loc) /mob/living/simple_animal/pet/cat/Proc name = "Proc" gender = MALE gold_core_spawnable = NO_SPAWN unique_pet = TRUE /mob/living/simple_animal/pet/cat/Life() if(!stat && !buckled && !client) if(prob(1)) emote("me", EMOTE_VISIBLE, pick("stretches out for a belly rub.", "wags its tail.", "lies down.")) icon_state = "[icon_living]_rest" collar_type = "[initial(collar_type)]_rest" set_resting(TRUE) else if (prob(1)) emote("me", EMOTE_VISIBLE, pick("sits down.", "crouches on its hind legs.", "looks alert.")) icon_state = "[icon_living]_sit" collar_type = "[initial(collar_type)]_sit" set_resting(TRUE) else if (prob(1)) if (resting) emote("me", EMOTE_VISIBLE, pick("gets up and meows.", "walks around.", "stops resting.")) icon_state = "[icon_living]" collar_type = "[initial(collar_type)]" set_resting(FALSE) else emote("me", EMOTE_VISIBLE, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat.")) //MICE! if((src.loc) && isturf(src.loc)) if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled) for(var/mob/living/simple_animal/mouse/M in view(1,src)) if(!M.stat && Adjacent(M)) emote("me", EMOTE_VISIBLE, "splats \the [M]!") M.splat() movement_target = null stop_automated_movement = 0 break for(var/obj/item/toy/cattoy/T in view(1,src)) if (T.cooldown < (world.time - 400)) emote("me", EMOTE_VISIBLE, "bats \the [T] around with its paw!") T.cooldown = world.time ..() make_babies() if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled) turns_since_scan++ if(turns_since_scan > 5) walk_to(src,0) turns_since_scan = 0 if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) )) movement_target = null stop_automated_movement = 0 if( !movement_target || !(movement_target.loc in oview(src, 3)) ) movement_target = null stop_automated_movement = 0 for(var/mob/living/simple_animal/mouse/snack in oview(src,3)) if(isturf(snack.loc) && !snack.stat) movement_target = snack break if(movement_target) stop_automated_movement = 1 walk_to(src,movement_target,0,3) /mob/living/simple_animal/pet/cat/cak //I told you I'd do it, Remie name = "Keeki" desc = "It's a cat made out of cake." icon_state = "cak" icon_living = "cak" icon_dead = "cak_dead" health = 50 maxHealth = 50 gender = FEMALE harm_intent_damage = 10 butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 3, \ /obj/item/reagent_containers/food/snacks/meat/slab = 2) response_harm = "takes a bite out of" attacked_sound = 'sound/items/eatfood.ogg' deathmessage = "loses its false life and collapses!" death_sound = "bodyfall" held_icon = "cak" /mob/living/simple_animal/pet/cat/cak/CheckParts(list/parts) ..() var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents if(!B || !B.brainmob || !B.brainmob.mind) return B.brainmob.mind.transfer_to(src) to_chat(src, "You are a cak! You're a harmless cat/cake hybrid that everyone loves. People can take bites out of you if they're hungry, but you regenerate health \ so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \ free cake to the station!") var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Keeki.", "Name Change") if(new_name) to_chat(src, "Your name is now \"new_name\"!") name = new_name /mob/living/simple_animal/pet/cat/cak/Life() ..() if(stat) return if(health < maxHealth) adjustBruteLoss(-8) //Fast life regen for(var/obj/item/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts! if(!D.is_decorated) D.decorate_donut() /mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L) . = ..() if(.) //the attack was blocked return if(L.a_intent == INTENT_HARM && L.reagents && !stat) L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4) L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4) //Cat made /mob/living/simple_animal/pet/cat/custom_cat name = "White cat" //Incase it somehow gets spawned without an ID desc = "A cute white catto!" icon_state = "custom_cat" icon_living = "custom_cat" icon_dead = "custom_cat_dead" gender = FEMALE gold_core_spawnable = NO_SPAWN health = 50 //So people can't instakill it s maxHealth = 50 speak = list("Meowrowr!", "Mew!", "Miauen!") speak_emote = list("wigglepurrs", "mewls") emote_hear = list("meows.", "mews.") emote_see = list("looks at you eagerly for pets!", "wiggles enthusiastically.") gold_core_spawnable = NO_SPAWN var/pseudo_death = FALSE var/mob/living/carbon/human/origin /mob/living/simple_animal/pet/cat/custom_cat/death() if (pseudo_death == TRUE) //secret cat chem icon_state = "custom_cat_dead" Stun(1000) friendly = "deads at" return else ..()