diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm
index 8e5d0d5446fd5..32ba1a278e926 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -253,7 +253,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_BRAIN_TUMOR "brain_tumor"
#define TRAIT_PROSKATER "pro_skater"
#define TRAIT_PLUSHIELOVER "plushie lover"
-
+#define TRAIT_PETLOVER "pet lover"
///Trait for dryable items
#define TRAIT_DRYABLE "trait_dryable"
///Trait for dried items
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index b95624dcb8a12..4b25dc0546762 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -168,6 +168,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_BRAIN_TUMOR" = TRAIT_BRAIN_TUMOR,
"TRAIT_PROSKATER" = TRAIT_PROSKATER,
"TRAIT_PLUSHIELOVER" = TRAIT_PLUSHIELOVER,
+ "TRAIT_PETLOVER" = TRAIT_PETLOVER,
"TRAIT_CAN_USE_NUKE" = TRAIT_CAN_USE_NUKE,
"TRACKED_SENSORS_TRAIT" = TRACKED_SENSORS_TRAIT,
"TRAIT_SUIT_SENSORS" = TRAIT_SUIT_SENSORS,
diff --git a/code/datums/traits/positive_quirk.dm b/code/datums/traits/positive_quirk.dm
index 568f536a7a244..1ace3c9f1b409 100644
--- a/code/datums/traits/positive_quirk.dm
+++ b/code/datums/traits/positive_quirk.dm
@@ -292,3 +292,18 @@
"hands" = ITEM_SLOT_HANDS,
)
H.equip_in_one_of_slots(B, slots , qdel_on_fail = TRUE)
+
+/datum/quirk/petlover
+ name = "Pet Lover"
+ desc = "You love the company and pressence of a pet. You start with a pet delivery beacon."
+ icon = "dog"
+ value = 1
+ mob_trait = TRAIT_PETLOVER
+ gain_text = "You can't wait to pet some adorable critters!."
+ lose_text = "You don't feel that passion for pets anymore."
+
+/datum/quirk/petlover/on_spawn()
+ var/mob/living/carbon/human/target = quirk_target
+ target.equip_to_slot_or_del(new /obj/item/choice_beacon/radial/pets(target), ITEM_SLOT_BACKPACK)
+ target.equip_to_slot_or_del(new /obj/item/pet_carrier(target), ITEM_SLOT_HANDS)
+ target.equip_to_slot_or_del(new /obj/item/clothing/neck/petcollar(target), ITEM_SLOT_BACKPACK)
diff --git a/code/game/objects/items/miscellaneous.dm b/code/game/objects/items/miscellaneous.dm
index 5c2164e3d10b4..0e5f91c75fa00 100644
--- a/code/game/objects/items/miscellaneous.dm
+++ b/code/game/objects/items/miscellaneous.dm
@@ -487,3 +487,58 @@
/obj/item/choice_beacon/janicart/generate_display_names()
return list("janitor cart" = /obj/vehicle/ridden/janicart/upgraded/keyless)
+
+/obj/item/choice_beacon/radial/pets
+ name = "Pets delivery beacon"
+ desc = "Summon your new friend!"
+ icon_state = "gangtool-pets"
+ var/static/list/pets_list = list( //havent included snake because the poison and foxes because the captain gets one because his status
+ /mob/living/simple_animal/pet/dog/corgi,
+ /mob/living/simple_animal/pet/dog/corgi/puppy,
+ /mob/living/simple_animal/pet/dog/bullterrier,
+ /mob/living/simple_animal/pet/dog/pug,
+ /mob/living/simple_animal/pet/cat,
+ /mob/living/simple_animal/pet/cat/kitten,
+ /mob/living/simple_animal/pet/dog/corgi/capybara,
+ /mob/living/simple_animal/mouse,
+ /mob/living/simple_animal/pet/hamster,
+ /mob/living/simple_animal/pet/penguin/baby,
+ /mob/living/simple_animal/cow,
+ /mob/living/simple_animal/chicken,
+ /mob/living/simple_animal/chick,
+ /mob/living/simple_animal/hostile/retaliate/frog,
+ /mob/living/basic/mothroach,
+ /mob/living/simple_animal/crab,
+ /mob/living/simple_animal/hostile/retaliate/goose,
+ /mob/living/simple_animal/parrot,
+ /mob/living/simple_animal/hostile/lizard,
+ )
+
+/obj/item/choice_beacon/radial/pets/generate_options(mob/living/target)
+ var/list/item_list = generate_item_list()
+ if(!length(item_list))
+ return
+ var/choice = show_radial_menu(target, src, item_list, radius = 36, require_near = TRUE)
+ if(!QDELETED(src) && !(isnull(choice)) && !target.incapacitated() && in_range(target,src))
+ for(var/V in pets_list)
+ var/atom/A = V
+ if(initial(A.name) == choice)
+ spawn_option(A,target)
+ uses--
+ if(!uses)
+ qdel(src)
+ else
+ balloon_alert(target, "[uses] use[uses > 1 ? "s" : ""] remaining")
+ to_chat(target, "[uses] use[uses > 1 ? "s" : ""] remaining on the [src].")
+ return
+
+/obj/item/choice_beacon/radial/pets/generate_item_list()
+ var/static/list/item_list
+ if(!item_list)
+ item_list = list()
+ for(var/mob/living/simple_animal/pet/friend as() in pets_list)
+ var/image/pets_icon = image(initial(friend.icon), initial(friend.icon_state))
+ var/datum/radial_menu_choice/choice = new
+ choice.image = pets_icon
+ item_list[initial(friend.name)] = choice
+ return item_list
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index d7467f636522b..97c28f2922494 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ