diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index d0858c0a6cd..f0da4d0a1e3 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -902,30 +902,25 @@ body
if(!istype(H))
usr << "This can only be done to instances of type /mob/living/carbon/human"
return
+ if(!ishumanbasic(H))
+ usr << "This can only be done to the basic human species \
+ at the moment."
+ return
if(!H)
usr << "Mob doesn't exist anymore"
return
- if(("tail_human" in H.dna.species.mutant_bodyparts) && ("ears" in H.dna.species.mutant_bodyparts))
- if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None")
- usr << "Put [H] on purrbation."
- H << "Something is nya~t right."
- log_admin("[key_name(usr)] has put [key_name(H)] on purrbation.")
- message_admins("[key_name(usr)] has put [key_name(H)] on purrbation.")
- H.dna.features["tail_human"] = "Cat"
- H.dna.features["ears"] = "Cat"
- else
- usr << "Removed [H] from purrbation."
- H << "You are no longer a cat."
- log_admin("[key_name(usr)] has removed [key_name(H)] from purrbation.")
- message_admins("[key_name(usr)] has removed [key_name(H)] from purrbation.")
- H.dna.features["tail_human"] = "None"
- H.dna.features["ears"] = "None"
- H.regenerate_icons()
- return
+ var/success = purrbation_toggle(H)
+ if(success)
+ usr << "Put [H] on purrbation."
+ log_admin("[key_name(usr)] has put [key_name(H)] on purrbation.")
+ message_admins("[key_name(usr)] has put [key_name(H)] on purrbation.")
- usr << "You can only put humans on purrbation."
+ else
+ usr << "Removed [H] from purrbation."
+ log_admin("[key_name(usr)] has removed [key_name(H)] from purrbation.")
+ message_admins("[key_name(usr)] has removed [key_name(H)] from purrbation.")
else if(href_list["adjustDamage"] && href_list["mobToDamage"])
if(!check_rights(0))
diff --git a/code/modules/admin/random.dm b/code/modules/admin/random.dm
new file mode 100644
index 00000000000..b3b8dafadec
--- /dev/null
+++ b/code/modules/admin/random.dm
@@ -0,0 +1,44 @@
+#define ON_PURRBATION(H) (!(H.dna.features["tail_human"] == "None" && H.dna.features["ears"] == "None"))
+
+/proc/mass_purrbation()
+ for(var/M in mob_list)
+ if(ishumanbasic(M))
+ purrbation_apply(M)
+ CHECK_TICK
+
+/proc/mass_remove_purrbation()
+ for(var/M in mob_list)
+ if(ishumanbasic(M))
+ purrbation_remove(M)
+ CHECK_TICK
+
+/proc/purrbation_toggle(mob/living/carbon/human/H)
+ if(!ishumanbasic(H))
+ return
+ if(!ON_PURRBATION(H))
+ purrbation_apply(H)
+ . = TRUE
+ else
+ purrbation_remove(H)
+ . = FALSE
+
+/proc/purrbation_apply(mob/living/carbon/human/H)
+ if(!istype(H))
+ return
+ if(ON_PURRBATION(H))
+ return
+ H << "Something is nya~t right."
+ H.dna.features["tail_human"] = "Cat"
+ H.dna.features["ears"] = "Cat"
+ H.regenerate_icons()
+ playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1)
+
+/proc/purrbation_remove(mob/living/carbon/human/H)
+ if(!istype(H))
+ return
+ if(!ON_PURRBATION(H))
+ return
+ H << "You are no longer a cat."
+ H.dna.features["tail_human"] = "None"
+ H.dna.features["ears"] = "None"
+ H.regenerate_icons()
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 0cea1623a77..10201b50bcb 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -64,6 +64,8 @@
The floor is lava! (DANGEROUS: extremely lame)
Change bomb cap
+ Mass Purrbation
+ Mass Remove Purrbation
"}
dat += "
"
@@ -573,6 +575,18 @@
CTF.TellGhost()
message_admins("[key_name_admin(usr)] has [ctf_enabled? "enabled" : "disabled"] CTF!")
notify_ghosts("CTF has been [ctf_enabled? "enabled" : "disabled"]!",'sound/effects/ghost2.ogg')
+ if("masspurrbation")
+ if(!check_rights(R_FUN))
+ return
+ mass_purrbation()
+ message_admins("[key_name_admin(usr)] has put everyone on \
+ purrbation!")
+ if("massremovepurrbation")
+ if(!check_rights(R_FUN))
+ return
+ mass_remove_purrbation()
+ message_admins("[key_name_admin(usr)] has removed everyone from \
+ purrbation.")
if(E)
E.processing = 0
diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
index 5432830eab4..276d8a4e381 100644
--- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm
+++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
@@ -8,6 +8,7 @@
response_help = "shoos"
response_disarm = "brushes aside"
response_harm = "squashes"
+ speak_emote = list("flutters")
maxHealth = 2
health = 2
harm_intent_damage = 1
@@ -18,6 +19,10 @@
ventcrawler = 2
mob_size = MOB_SIZE_TINY
gold_core_spawnable = 2
+ verb_say = "flutters"
+ verb_ask = "flutters inquisitively"
+ verb_exclaim = "flutters intensely"
+ verb_yell = "flutters intensely"
/mob/living/simple_animal/butterfly/New()
..()
diff --git a/sound/effects/meow1.ogg b/sound/effects/meow1.ogg
new file mode 100644
index 00000000000..c486bfd5db9
Binary files /dev/null and b/sound/effects/meow1.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 4fc1e9089d7..d8a524e8fc1 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -841,6 +841,7 @@
#include "code\modules\admin\IsBanned.dm"
#include "code\modules\admin\NewBan.dm"
#include "code\modules\admin\player_panel.dm"
+#include "code\modules\admin\random.dm"
#include "code\modules\admin\secrets.dm"
#include "code\modules\admin\sql_notes.dm"
#include "code\modules\admin\stickyban.dm"