diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index ba85f7838b3..f36745fd00d 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -18408,10 +18408,7 @@
name = "\improper Garden"
})
"aPj" = (
-/mob/living/simple_animal/chicken{
- name = "Featherbottom";
- real_name = "Featherbottom"
- },
+/mob/living/simple_animal/chicken/featherbottom,
/turf/simulated/floor/grass,
/area/hallway/secondary/construction{
name = "\improper Garden"
@@ -19653,10 +19650,7 @@
dir = 8
},
/obj/structure/window/reinforced,
-/mob/living/simple_animal/chicken{
- name = "Kentucky";
- real_name = "Kentucky"
- },
+/mob/living/simple_animal/chicken/kentucky,
/turf/simulated/floor/grass,
/area/hallway/secondary/construction{
name = "\improper Garden"
@@ -21461,10 +21455,7 @@
name = "\improper Garden"
})
"aWe" = (
-/mob/living/simple_animal/cow{
- name = "Betsy";
- real_name = "Betsy"
- },
+/mob/living/simple_animal/cow/betsy,
/turf/simulated/floor/grass,
/area/hallway/secondary/construction{
name = "\improper Garden"
diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index a173aaf24b7..b6c15282bc1 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -27362,9 +27362,7 @@
/turf/simulated/floor/plating,
/area/maintenance/fsmaint)
"bjx" = (
-/mob/living/simple_animal/cow{
- name = "Betsy"
- },
+/mob/living/simple_animal/cow/betsy,
/turf/simulated/floor/grass,
/area/hydroponics)
"bjy" = (
@@ -78461,9 +78459,7 @@
/area/hydroponics)
"dnE" = (
/obj/machinery/hydroponics/soil,
-/mob/living/simple_animal/chicken{
- name = "Commander Clucky"
- },
+/mob/living/simple_animal/chicken/clucky,
/turf/simulated/floor/grass,
/area/hydroponics)
"dnF" = (
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index c39babad9f6..bd5028fd5f5 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -839,6 +839,11 @@
to_chat(src, "You can speak to your fellow borers by prefixing your messages with ':bo'. Check out your Borer tab to see your abilities.")
to_chat(src, "For more information, check the wiki page: ([GLOB.configuration.url.wiki_url]/index.php/Cortical_Borer)")
+/mob/living/simple_animal/borer/npc_safe(mob/user)
+ if(!jobban_isbanned(user, ROLE_BORER) && !jobban_isbanned(user, ROLE_SYNDICATE))
+ return TRUE
+ return FALSE
+
/proc/create_borer_mind(key)
var/datum/mind/M = new /datum/mind(key)
M.assigned_role = "Cortical Borer"
diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
index 336f0ce42d2..3eba95aaa16 100644
--- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm
+++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
@@ -26,3 +26,6 @@
/mob/living/simple_animal/butterfly/New()
..()
color = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
+
+/mob/living/simple_animal/butterfly/npc_safe(mob/user)
+ return TRUE
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index 75b120c888d..d3fa2a2d753 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -94,6 +94,9 @@
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/npc_safe(mob/user)
+ return TRUE
+
/mob/living/simple_animal/pet/cat/Life()
..()
make_babies()
@@ -226,6 +229,11 @@
. = ..()
ADD_TRAIT(src, TRAIT_NOBREATH, SPECIES_TRAIT)
+/mob/living/simple_animal/pet/cat/Syndi/npc_safe(mob/user)
+ if(GAMEMODE_IS_NUCLEAR)
+ return TRUE
+ return FALSE
+
/mob/living/simple_animal/pet/cat/cak
name = "Keeki"
desc = "It's a cat made out of cake."
diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm
index 4a51ce62d4e..ad43f5b5ef3 100644
--- a/code/modules/mob/living/simple_animal/friendly/crab.dm
+++ b/code/modules/mob/living/simple_animal/friendly/crab.dm
@@ -31,6 +31,9 @@
if(Process_Spacemove(east_vs_west))
Move(get_step(src, east_vs_west), east_vs_west)
+/mob/living/simple_animal/crab/npc_safe(mob/user)
+ return TRUE
+
//COFFEE! SQUEEEEEEEEE!
/mob/living/simple_animal/crab/Coffee
name = "Coffee"
diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm
index 41a568559e0..79964fd582d 100644
--- a/code/modules/mob/living/simple_animal/friendly/diona.dm
+++ b/code/modules/mob/living/simple_animal/friendly/diona.dm
@@ -301,3 +301,8 @@
to_chat(src, "scream, chirp")
..()
+
+/mob/living/simple_animal/diona/npc_safe(mob/user)
+ if(!jobban_isbanned(user, ROLE_NYMPH))
+ return TRUE
+ return FALSE
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index 3eb0a2f5d6a..948146083d3 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -23,6 +23,9 @@
footstep_type = FOOTSTEP_MOB_CLAW
var/next_spin_message = 0
+/mob/living/simple_animal/pet/dog/npc_safe(mob/user)
+ return TRUE
+
/mob/living/simple_animal/pet/dog/verb/chasetail()
set name = "Chase your tail"
set desc = "d'awwww."
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 109c4043f5e..92e2b09a7a4 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -175,6 +175,18 @@
else
..()
+
+/mob/living/simple_animal/cow/npc_safe(mob/user)
+ return TRUE
+
+/mob/living/simple_animal/cow/betsy
+ name = "Betsy"
+ real_name = "Betsy"
+ unique_pet = TRUE
+
+/mob/living/simple_animal/cow/betsy/npc_safe(mob/user) // depriving the chef of his animals is not cool
+ return FALSE
+
/mob/living/simple_animal/chick
name = "\improper chick"
desc = "Adorable! They make such a racket though."
@@ -222,6 +234,10 @@
mind.transfer_to(C)
qdel(src)
+
+/mob/living/simple_animal/chick/npc_safe(mob/user)
+ return TRUE
+
#define MAX_CHICKENS 50
GLOBAL_VAR_INIT(chicken_count, 0)
@@ -320,6 +336,32 @@ GLOBAL_VAR_INIT(chicken_count, 0)
else
STOP_PROCESSING(SSobj, src)
+/mob/living/simple_animal/chicken/npc_safe(mob/user)
+ return TRUE
+
+/mob/living/simple_animal/chicken/clucky
+ name = "Commander Clucky"
+ real_name = "Commander Clucky"
+ unique_pet = TRUE
+
+/mob/living/simple_animal/chicken/clucky/npc_safe(mob/user) // depriving the chef of his animals is not cool
+ return FALSE
+
+/mob/living/simple_animal/chicken/kentucky
+ name = "Kentucky"
+ real_name = "Kentucky"
+ unique_pet = TRUE
+
+/mob/living/simple_animal/chicken/kentucky/npc_safe(mob/user)
+ return FALSE
+
+/mob/living/simple_animal/chicken/featherbottom
+ name = "Featherbottom"
+ real_name = "Featherbottom"
+ unique_pet = TRUE
+
+/mob/living/simple_animal/chicken/featherbottom/npc_safe(mob/user)
+ return FALSE
/mob/living/simple_animal/pig
name = "pig"
diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm
index d1a3f430353..37d1f47e5b6 100644
--- a/code/modules/mob/living/simple_animal/friendly/fox.dm
+++ b/code/modules/mob/living/simple_animal/friendly/fox.dm
@@ -44,3 +44,8 @@
/mob/living/simple_animal/pet/dog/fox/Syndifox/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_NOBREATH, SPECIES_TRAIT)
+
+/mob/living/simple_animal/pet/dog/fox/Syndifox/npc_safe(mob/user)
+ if(GAMEMODE_IS_NUCLEAR)
+ return TRUE
+ return FALSE
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index e924ea9eed7..60ae380461a 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -163,6 +163,7 @@
//TOM IS ALIVE! SQUEEEEEEEE~K :)
/mob/living/simple_animal/mouse/brown/Tom
name = "Tom"
+ real_name = "Tom"
desc = "Jerry the cat is not amused."
response_help = "pets"
response_disarm = "gently pushes aside"
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index fd3b3227d0c..300c3ae0e44 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -680,6 +680,9 @@
update_held_icon()
I.forceMove(src)
+/mob/living/simple_animal/parrot/npc_safe(mob/user)
+ return TRUE
+
/*
* Sub-types
*/
@@ -718,6 +721,9 @@
clean_speak += "Danger! Crystal hyperstructure integrity faltering! Integrity: [rand(75, 99)]%" // Has to be here cause of the `rand()`.
..()
+/mob/living/simple_animal/parrot/Poly/npc_safe(mob/user) // Hello yes, I have universal speak and I follow people around and shout out antags
+ return FALSE
+
/mob/living/simple_animal/parrot/handle_message_mode(message_mode, list/message_pieces, verb, used_radios)
if(message_mode && istype(ears))
ears.talk_into(src, message_pieces, message_mode, verb)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index d1ce3158bcd..5e54b575513 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -641,3 +641,6 @@
/mob/living/simple_animal/Login()
..()
walk(src, 0) // if mob is moving under ai control, then stop AI movement
+
+/mob/living/simple_animal/proc/npc_safe(mob/user)
+ return FALSE
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index c6cceea3842..3448ea52462 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1107,12 +1107,11 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
to_chat(src, "You can't respawn as an NPC before the game starts!")
return
- if((usr in GLOB.respawnable_list) && (stat==2 || istype(usr,/mob/dead/observer)))
+ if((usr in GLOB.respawnable_list) && (stat == DEAD || isobserver(usr)))
var/list/creatures = list("Mouse")
- for(var/mob/living/L in GLOB.alive_mob_list)
- if(safe_respawn(L.type) && L.stat!=2)
- if(!L.key)
- creatures += L
+ for(var/mob/living/simple_animal/L in GLOB.alive_mob_list)
+ if(L.npc_safe(src) && L.stat != DEAD && !L.key)
+ creatures += L
var/picked = input("Please select an NPC to respawn as", "Respawn as NPC") as null|anything in creatures
switch(picked)
if("Mouse")
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index fb08abb0977..49c707cbd84 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -267,42 +267,3 @@
to_chat(pai, "You have become a pAI! Your name is [pai.name].")
pai.update_pipe_vision()
qdel(src)
-
-/mob/proc/safe_respawn(MP)
- if(!MP)
- return 0
-
- if(!GAMEMODE_IS_NUCLEAR)
- if(ispath(MP, /mob/living/simple_animal/pet/cat/Syndi))
- return 0
- if(ispath(MP, /mob/living/simple_animal/pet/cat))
- return 1
- if(ispath(MP, /mob/living/simple_animal/pet/dog/corgi))
- return 1
- if(ispath(MP, /mob/living/simple_animal/crab))
- return 1
- if(ispath(MP, /mob/living/simple_animal/chicken))
- return 1
- if(ispath(MP, /mob/living/simple_animal/cow))
- return 1
- if(ispath(MP, /mob/living/simple_animal/parrot))
- return 1
- if(!GAMEMODE_IS_NUCLEAR)
- if(ispath(MP, /mob/living/simple_animal/pet/dog/fox/Syndifox))
- return 0
- if(ispath(MP, /mob/living/simple_animal/pet/dog/fox))
- return 1
- if(ispath(MP, /mob/living/simple_animal/chick))
- return 1
- if(ispath(MP, /mob/living/simple_animal/pet/dog/pug))
- return 1
- if(ispath(MP, /mob/living/simple_animal/butterfly))
- return 1
-
- if(ispath(MP, /mob/living/simple_animal/borer) && !jobban_isbanned(src, ROLE_BORER) && !jobban_isbanned(src, ROLE_SYNDICATE))
- return 1
-
- if(ispath(MP, /mob/living/simple_animal/diona) && !jobban_isbanned(src, ROLE_NYMPH))
- return 1
-
- return 0