diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm
index 1e00f454caa..d0f37526174 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -180,13 +180,14 @@
CRASH("Someone passed nothing to manual_emote(), fix it")
log_message(text, LOG_EMOTE)
- text = "[src] " + text
+
+ var/ghost_text = "[src] " + text //Sin I know
for(var/mob/M in GLOB.dead_mob_list)
if(!M.client || isnewplayer(M))
continue
var/T = get_turf(src)
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null)))
- M.show_message(text)
+ M.show_message("[FOLLOW_LINK(M, src)] [ghost_text]")
- visible_message(text)
+ visible_message(text, visible_message_flags = EMOTE_MESSAGE)
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 1993930826c..5092da4f73e 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -70,6 +70,9 @@
switch(mode)
if(0)
if(M.health >= 0)
+ if(isanimal(M))
+ M.attack_hand(user) //This enables borgs to get the floating heart icon and mob emote from simple_animal's that have petbonus == true.
+ return
if(user.zone_selected == BODY_ZONE_HEAD)
user.visible_message("[user] playfully boops [M] on the head!", \
"You playfully boop [M] on the head!")
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 0fb4963fb02..2fbe32b38c7 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -323,7 +323,7 @@ All foods are distributed among various categories. Use common sense.
if(bitecount >= 5)
var/sattisfaction_text = pick("burps from enjoyment", "yaps for more", "woofs twice", "looks at the area where \the [src] was")
if(sattisfaction_text)
- M.emote(sattisfaction_text)
+ M.manual_emote(sattisfaction_text)
qdel(src)
diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm
index 3a72c46f181..dea1da2530a 100644
--- a/code/modules/holiday/easter.dm
+++ b/code/modules/holiday/easter.dm
@@ -49,6 +49,8 @@
icon_prefix = "rabbit"
feedMessages = list("It nibbles happily.","It noms happily.")
layMessage = list("hides an egg.","scampers around suspiciously.","begins making a huge racket.","begins shuffling.")
+ pet_bonus = TRUE
+ pet_bonus_emote = "hops around happily!"
/mob/living/simple_animal/chicken/rabbit/space
icon_prefix = "s_rabbit"
diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm
index 8f2b22b2e7d..ebcdb3be1f2 100644
--- a/code/modules/mob/living/simple_animal/animal_defense.dm
+++ b/code/modules/mob/living/simple_animal/animal_defense.dm
@@ -4,11 +4,14 @@
..()
switch(M.a_intent)
if("help")
- if (health > 0)
- visible_message("[M] [response_help_continuous] [src].", \
- "[M] [response_help_continuous] you.", null, null, M)
- to_chat(M, "You [response_help_simple] [src].")
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
+ if (stat == DEAD)
+ return
+ visible_message("[M] [response_help_continuous] [src].", \
+ "[M] [response_help_continuous] you.", null, null, M)
+ to_chat(M, "You [response_help_simple] [src].")
+ playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
+ if(pet_bonus)
+ funpet(M)
if("grab")
grabbedby(M)
@@ -27,6 +30,16 @@
updatehealth()
return TRUE
+/**
+*This is used to make certain mobs (pet_bonus == TRUE) emote when pet, make a heart emoji at their location, and give the petter a moodlet.
+*
+*/
+/mob/living/simple_animal/proc/funpet(mob/petter)
+ new /obj/effect/temp_visual/heart(loc)
+ if(prob(33))
+ manual_emote("[pet_bonus_emote]")
+ SEND_SIGNAL(petter, COMSIG_ADD_MOOD_EVENT, src, /datum/mood_event/pet_animal, src)
+
/mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user)
. = ..()
if(!.)
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index 362726c5500..3d3ffaf646c 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -38,6 +38,8 @@
collar_type = "cat"
can_be_held = TRUE
held_state = "cat2"
+ pet_bonus = TRUE
+ pet_bonus_emote = "purrs!"
footstep_type = FOOTSTEP_MOB_CLAW
@@ -240,27 +242,6 @@
stop_automated_movement = 1
walk_to(src,movement_target,0,3)
-/mob/living/simple_animal/pet/cat/attack_hand(mob/living/carbon/human/M)
- . = ..()
- switch(M.a_intent)
- if("help")
- wuv(1, M)
- if("harm")
- wuv(-1, M)
-
-/mob/living/simple_animal/pet/cat/proc/wuv(change, mob/M)
- if(change)
- if(change > 0)
- if(M && stat != DEAD)
- new /obj/effect/temp_visual/heart(loc)
- manual_emote("purrs!")
- if(flags_1 & HOLOGRAM_1)
- return
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, src, /datum/mood_event/pet_animal, src)
- else
- if(M && stat != DEAD)
- manual_emote("hisses!")
-
/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."
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index 4b1dfe54469..56c8771501d 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -17,6 +17,8 @@
speak_chance = 1
turns_per_move = 10
can_be_held = TRUE
+ pet_bonus = TRUE
+ pet_bonus_emote = "woofs happily!"
var/turns_since_scan = 0
var/obj/movement_target
@@ -630,22 +632,3 @@
..()
make_babies()
-
-/mob/living/simple_animal/pet/dog/attack_hand(mob/living/carbon/human/M)
- . = ..()
- switch(M.a_intent)
- if("help")
- wuv(1,M)
- if("harm")
- wuv(-1,M)
-
-/mob/living/simple_animal/pet/dog/proc/wuv(change, mob/M)
- if(change)
- if(change > 0)
- if(M && stat != DEAD) // Added check to see if this mob (the dog) is dead to fix issue 2454
- new /obj/effect/temp_visual/heart(loc)
- manual_emote("yaps happily!")
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, src, /datum/mood_event/pet_animal, src)
- else
- if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case)
- manual_emote("growls!")
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 b016d92c4f0..e45f18a7abe 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -144,6 +144,8 @@
tame_chance = 25
bonus_tame_chance = 15
footstep_type = FOOTSTEP_MOB_SHOE
+ pet_bonus = TRUE
+ pet_bonus_emote = "moos happily!"
/mob/living/simple_animal/cow/Initialize()
udder = new()
@@ -263,6 +265,8 @@
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
gold_core_spawnable = FRIENDLY_SPAWN
+ pet_bonus = TRUE
+ pet_bonus_emote = "chirps!"
footstep_type = FOOTSTEP_MOB_CLAW
diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm
index 8af6b2a6ef5..8a8a844d703 100644
--- a/code/modules/mob/living/simple_animal/friendly/fox.dm
+++ b/code/modules/mob/living/simple_animal/friendly/fox.dm
@@ -23,6 +23,8 @@
gold_core_spawnable = FRIENDLY_SPAWN
can_be_held = TRUE
held_state = "fox"
+ pet_bonus = TRUE
+ pet_bonus_emote = "pants and yaps happily!"
footstep_type = FOOTSTEP_MOB_CLAW
diff --git a/code/modules/mob/living/simple_animal/friendly/gondola.dm b/code/modules/mob/living/simple_animal/friendly/gondola.dm
index 54e8dad7edb..2e75ecd8824 100644
--- a/code/modules/mob/living/simple_animal/friendly/gondola.dm
+++ b/code/modules/mob/living/simple_animal/friendly/gondola.dm
@@ -28,6 +28,8 @@
maxHealth = 200
health = 200
del_on_death = TRUE
+ pet_bonus = TRUE
+ pet_bonus_emote = "smiles!"
//Gondolas don't make footstep sounds
@@ -62,6 +64,7 @@
/mob/living/simple_animal/pet/gondola/IsVocal() //Gondolas are the silent walker.
return FALSE
+
#undef GONDOLA_HEIGHT
#undef GONDOLA_COLOR
#undef GONDOLA_MOUSTACHE
diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm
index c854936c7d2..4c0fa8452a3 100644
--- a/code/modules/mob/living/simple_animal/friendly/lizard.dm
+++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm
@@ -27,6 +27,8 @@
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
var/static/list/edibles = typecacheof(list(/mob/living/simple_animal/butterfly, /mob/living/simple_animal/hostile/cockroach)) //list of atoms, however turfs won't affect AI, but will affect consumption.
+ pet_bonus = TRUE
+ pet_bonus_emote = "sticks its tongue out contentedly!"
/mob/living/simple_animal/hostile/lizard/CanAttack(atom/the_target)//Can we actually attack a possible target?
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
diff --git a/code/modules/mob/living/simple_animal/friendly/penguin.dm b/code/modules/mob/living/simple_animal/friendly/penguin.dm
index 8376f6741eb..bdf29239a11 100644
--- a/code/modules/mob/living/simple_animal/friendly/penguin.dm
+++ b/code/modules/mob/living/simple_animal/friendly/penguin.dm
@@ -18,6 +18,8 @@
turns_per_move = 10
icon = 'icons/mob/penguins.dmi'
butcher_results = list(/obj/item/organ/ears/penguin = 1, /obj/item/reagent_containers/food/snacks/meat/slab/penguin = 3)
+ pet_bonus = TRUE
+ pet_bonus_emote = "honks happily!"
footstep_type = FOOTSTEP_MOB_BAREFOOT
@@ -55,3 +57,4 @@
pass_flags = PASSMOB
mob_size = MOB_SIZE_SMALL
butcher_results = list(/obj/item/organ/ears/penguin = 1, /obj/item/reagent_containers/food/snacks/meat/slab/penguin = 1)
+
diff --git a/code/modules/mob/living/simple_animal/friendly/sloth.dm b/code/modules/mob/living/simple_animal/friendly/sloth.dm
index adf0f5bd8a5..f9e2abf94d6 100644
--- a/code/modules/mob/living/simple_animal/friendly/sloth.dm
+++ b/code/modules/mob/living/simple_animal/friendly/sloth.dm
@@ -26,6 +26,8 @@
speed = 10
glide_size = 2
held_state = "sloth"
+ pet_bonus = TRUE
+ pet_bonus_emote = "slowly smiles!"
footstep_type = FOOTSTEP_MOB_CLAW
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index f8f33e53078..cf1aaa19609 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -335,7 +335,7 @@
/mob/living/simple_animal/hostile/proc/Aggro()
vision_range = aggro_vision_range
if(target && emote_taunt.len && prob(taunt_chance))
- emote("[pick(emote_taunt)] at [target].")
+ manual_emote("[pick(emote_taunt)] at [target].")
taunt_chance = max(taunt_chance-7,2)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index bdea8468daf..78e282f15c9 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -154,6 +154,12 @@
///Generic flags
var/simple_mob_flags = NONE
+ /// Used for making mobs show a heart emoji and give a mood boost when pet.
+ var/pet_bonus = FALSE
+ /// A string for an emote used when pet_bonus == true for the mob being pet.
+ var/pet_bonus_emote = ""
+
+
/mob/living/simple_animal/Initialize()
. = ..()
GLOB.simple_animals[AIStatus] += src