diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm
index dea5206448..9eeb6b8b97 100644
--- a/code/modules/mob/living/simple_animal/simple_animal_vr.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm
@@ -32,6 +32,9 @@
var/vore_fullness = 0 // How "full" the belly is (controls icons)
var/vore_icons = 0 // Bitfield for which fields we have vore icons for.
+ var/mount_offset_x = 5 // Horizontal riding offset.
+ var/mount_offset_y = 8 // Vertical riding offset
+
// Release belly contents before being gc'd!
/mob/living/simple_animal/Destroy()
release_vore_contents()
@@ -241,3 +244,89 @@
if(a_intent == I_GRAB && isliving(A) && !has_hands)
animal_nom(A)
+
+// Riding
+/datum/riding/simple_animal
+ keytype = /obj/item/weapon/material/twohanded/fluff/riding_crop // Crack!
+ nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs.
+ key_name = "a riding crop" // What the 'keys' for the thing being rided on would be called.
+ only_one_driver = TRUE // If true, only the person in 'front' (first on list of riding mobs) can drive.
+
+/datum/riding/simple_animal/handle_vehicle_layer()
+ ridden.layer = initial(ridden.layer)
+
+/datum/riding/simple_animal/ride_check(mob/living/M)
+ var/mob/living/L = ridden
+ if(L.stat)
+ force_dismount(M)
+ return FALSE
+ return TRUE
+
+/datum/riding/simple_animal/force_dismount(mob/M)
+ . =..()
+ ridden.visible_message("[M] stops riding [ridden]!")
+
+/datum/riding/simple_animal/get_offsets(pass_index) // list(dir = x, y, layer)
+ var/mob/living/simple_animal/L = ridden
+ var/scale = L.size_multiplier
+
+ var/list/values = list(
+ "[NORTH]" = list(0, L.mount_offset_y*scale, ABOVE_MOB_LAYER),
+ "[SOUTH]" = list(0, L.mount_offset_y*scale, BELOW_MOB_LAYER),
+ "[EAST]" = list(-L.mount_offset_x*scale, L.mount_offset_y*scale, ABOVE_MOB_LAYER),
+ "[WEST]" = list(L.mount_offset_x*scale, L.mount_offset_y*scale, ABOVE_MOB_LAYER))
+
+ return values
+
+/mob/living/simple_animal/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE)
+ if(forced)
+ return ..() // Skip our checks
+ if(!riding_datum)
+ return FALSE
+ if(lying)
+ return FALSE
+ if(!ishuman(M))
+ return FALSE
+ if(M in buckled_mobs)
+ return FALSE
+ if(M.size_multiplier > size_multiplier * 1.2)
+ to_chat(src,"This isn't a pony show! You need to be bigger for them to ride.")
+ return FALSE
+
+ var/mob/living/carbon/human/H = M
+
+ if(H.loc != src.loc)
+ if(H.Adjacent(src))
+ H.forceMove(get_turf(src))
+
+ . = ..()
+ if(.)
+ buckled_mobs[H] = "riding"
+
+/mob/living/simple_animal/attack_hand(mob/user as mob)
+ if(riding_datum && LAZYLEN(buckled_mobs))
+ //We're getting off!
+ if(user in buckled_mobs)
+ riding_datum.force_dismount(user)
+ //We're kicking everyone off!
+ if(user == src)
+ for(var/rider in buckled_mobs)
+ riding_datum.force_dismount(rider)
+ else
+ . = ..()
+
+/mob/living/simple_animal/proc/animal_mount(var/mob/living/M in living_mobs(1))
+ set name = "Animal Mount/Dismount"
+ set category = "Abilities"
+ set desc = "Let people ride on you."
+
+ if(LAZYLEN(buckled_mobs))
+ for(var/rider in buckled_mobs)
+ riding_datum.force_dismount(rider)
+ return
+ if (stat != CONSCIOUS)
+ return
+ if(!can_buckle || !istype(M) || !M.Adjacent(src) || M.buckled)
+ return
+ if(buckle_mob(M))
+ visible_message("[M] starts riding [name]!")
diff --git a/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm b/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm
index b8801ea2c9..eb62a21086 100644
--- a/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm
+++ b/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm
@@ -49,6 +49,11 @@
minbodytemp = 150
maxbodytemp = 900
+ max_buckled_mobs = 1 //Yeehaw
+ can_buckle = TRUE
+ buckle_movable = TRUE
+ buckle_lying = FALSE
+
var/image/eye_layer = null
@@ -114,3 +119,12 @@
remove_eyes()
if(stat == CONSCIOUS && !resting)
add_eyes()
+
+/mob/living/simple_animal/hostile/corrupthound/Login()
+ . = ..()
+ if(!riding_datum)
+ riding_datum = new /datum/riding/simple_animal(src)
+ verbs |= /mob/living/simple_animal/proc/animal_mount
+
+/mob/living/simple_animal/hostile/corrupthound/MouseDrop_T(mob/living/M, mob/living/user)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/vore/deathclaw.dm b/code/modules/mob/living/simple_animal/vore/deathclaw.dm
index 2f99179bd9..91fe552ccc 100644
--- a/code/modules/mob/living/simple_animal/vore/deathclaw.dm
+++ b/code/modules/mob/living/simple_animal/vore/deathclaw.dm
@@ -22,6 +22,13 @@
pixel_x = -16
pixel_y = 0
+ max_buckled_mobs = 1 //Yeehaw
+ can_buckle = TRUE
+ buckle_movable = TRUE
+ buckle_lying = FALSE
+ mount_offset_x = 5
+ mount_offset_y = 30
+
// Activate Noms!
/mob/living/simple_animal/hostile/deathclaw
vore_active = 1
@@ -30,3 +37,12 @@
vore_min_size = RESIZE_SMALL
vore_pounce_chance = 0 // Beat them into crit before eating.
vore_icons = SA_ICON_LIVING
+
+/mob/living/simple_animal/hostile/deathclaw/Login()
+ . = ..()
+ if(!riding_datum)
+ riding_datum = new /datum/riding/simple_animal(src)
+ verbs |= /mob/living/simple_animal/proc/animal_mount
+
+/mob/living/simple_animal/hostile/deathclaw/MouseDrop_T(mob/living/M, mob/living/user)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/vore/dragon.dm b/code/modules/mob/living/simple_animal/vore/dragon.dm
index 7f64ee0da2..2d839fb149 100644
--- a/code/modules/mob/living/simple_animal/vore/dragon.dm
+++ b/code/modules/mob/living/simple_animal/vore/dragon.dm
@@ -30,6 +30,13 @@
pixel_x = -16
pixel_y = 0
+ max_buckled_mobs = 1 //Yeehaw
+ can_buckle = TRUE
+ buckle_movable = TRUE
+ buckle_lying = FALSE
+ mount_offset_x = -11
+ mount_offset_y = 16
+
/mob/living/simple_animal/hostile/dragon/Process_Spacemove(var/check_drift = 0)
return 1 //No drifting in space for space dragons!
@@ -49,3 +56,12 @@
maxHealth = 200
health = 200
faction = "virgo3b"
+
+/mob/living/simple_animal/hostile/dragon/Login()
+ . = ..()
+ if(!riding_datum)
+ riding_datum = new /datum/riding/simple_animal(src)
+ verbs |= /mob/living/simple_animal/proc/animal_mount
+
+/mob/living/simple_animal/hostile/dragon/MouseDrop_T(mob/living/M, mob/living/user)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/vore/hippo.dm b/code/modules/mob/living/simple_animal/vore/hippo.dm
index bfd28aafb5..ae9d8775e1 100644
--- a/code/modules/mob/living/simple_animal/vore/hippo.dm
+++ b/code/modules/mob/living/simple_animal/vore/hippo.dm
@@ -49,13 +49,19 @@
meat_amount = 10 //Infinite meat!
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
+ max_buckled_mobs = 1 //Yeehaw
+ can_buckle = TRUE
+ buckle_movable = TRUE
+ buckle_lying = FALSE
+ mount_offset_y = 20
+
// Activate Noms!
/mob/living/simple_animal/retaliate/hippo //I don't know why it's in a seperate line but everyone does it so i do it
vore_active = 1
vore_capacity = 1
vore_bump_chance = 15
vore_bump_emote = "lazily wraps its tentacles around"
- vore_standing_too = 1
+ vore_standing_too = 1
vore_ignores_undigestable = 0
vore_default_mode = DM_HOLD
vore_digest_chance = 10
@@ -64,3 +70,12 @@
vore_stomach_name = "rumen" //First stomach of a ruminant. It's where the pre digestion bacteria stuff happens. Very warm.
vore_stomach_flavor = "You are squeezed into the sweltering insides of the herbivore rumen."
vore_icons = SA_ICON_LIVING
+
+/mob/living/simple_animal/retaliate/hippo/Login()
+ . = ..()
+ if(!riding_datum)
+ riding_datum = new /datum/riding/simple_animal(src)
+ verbs |= /mob/living/simple_animal/proc/animal_mount
+
+/mob/living/simple_animal/retaliate/hippo/MouseDrop_T(mob/living/M, mob/living/user)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/vore/horse.dm b/code/modules/mob/living/simple_animal/vore/horse.dm
index 59bbfa4550..80cd80dd0e 100644
--- a/code/modules/mob/living/simple_animal/vore/horse.dm
+++ b/code/modules/mob/living/simple_animal/vore/horse.dm
@@ -31,7 +31,22 @@
meat_amount = 4
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
+ max_buckled_mobs = 1 //Yeehaw
+ can_buckle = TRUE
+ buckle_movable = TRUE
+ buckle_lying = FALSE
+ mount_offset_x = 0
+
// Activate Noms!
/mob/living/simple_animal/horse
vore_active = 1
vore_icons = SA_ICON_LIVING
+
+/mob/living/simple_animal/horse/Login()
+ . = ..()
+ if(!riding_datum)
+ riding_datum = new /datum/riding/simple_animal(src)
+ verbs |= /mob/living/simple_animal/proc/animal_mount
+
+/mob/living/simple_animal/horse/MouseDrop_T(mob/living/M, mob/living/user)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/vore/otie.dm b/code/modules/mob/living/simple_animal/vore/otie.dm
index 5220f861c5..c7d171ed84 100644
--- a/code/modules/mob/living/simple_animal/vore/otie.dm
+++ b/code/modules/mob/living/simple_animal/vore/otie.dm
@@ -46,6 +46,12 @@
pixel_x = -16
pixel_y = 0
+ max_buckled_mobs = 1 //Yeehaw
+ can_buckle = TRUE
+ buckle_movable = TRUE
+ buckle_lying = FALSE
+ mount_offset_y = 10
+
var/glowyeyes = FALSE
var/image/eye_layer = null
var/eyetype
@@ -382,4 +388,13 @@
/mob/living/simple_animal/otie/death(gibbed, deathmessage = "dies!")
.=..()
resting = 0
- icon_state = icon_dead
\ No newline at end of file
+ icon_state = icon_dead
+
+/mob/living/simple_animal/otie/Login()
+ . = ..()
+ if(!riding_datum)
+ riding_datum = new /datum/riding/simple_animal(src)
+ verbs |= /mob/living/simple_animal/proc/animal_mount
+
+/mob/living/simple_animal/otie/MouseDrop_T(mob/living/M, mob/living/user)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/vore/panther.dm b/code/modules/mob/living/simple_animal/vore/panther.dm
index 454ef4d927..45a18cf300 100644
--- a/code/modules/mob/living/simple_animal/vore/panther.dm
+++ b/code/modules/mob/living/simple_animal/vore/panther.dm
@@ -27,9 +27,24 @@
pixel_x = -16
pixel_y = 0
+ max_buckled_mobs = 1 //Yeehaw
+ can_buckle = TRUE
+ buckle_movable = TRUE
+ buckle_lying = FALSE
+ mount_offset_y = 12
+
// Activate Noms!
/mob/living/simple_animal/hostile/panther
vore_active = 1
vore_capacity = 2
vore_pounce_chance = 10
vore_icons = SA_ICON_LIVING | SA_ICON_REST
+
+/mob/living/simple_animal/hostile/panther/Login()
+ . = ..()
+ if(!riding_datum)
+ riding_datum = new /datum/riding/simple_animal(src)
+ verbs |= /mob/living/simple_animal/proc/animal_mount
+
+/mob/living/simple_animal/hostile/panther/MouseDrop_T(mob/living/M, mob/living/user)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/vore/rat.dm b/code/modules/mob/living/simple_animal/vore/rat.dm
index 40b1800aa0..1f6be2e3f4 100644
--- a/code/modules/mob/living/simple_animal/vore/rat.dm
+++ b/code/modules/mob/living/simple_animal/vore/rat.dm
@@ -36,6 +36,12 @@
pixel_x = -16
pixel_y = 0
+ max_buckled_mobs = 1 //Yeehaw
+ can_buckle = TRUE
+ buckle_movable = TRUE
+ buckle_lying = FALSE
+ mount_offset_y = 10
+
vore_active = TRUE
vore_capacity = 1
vore_pounce_chance = 45
@@ -159,3 +165,12 @@
/mob/living/simple_animal/hostile/rat/death()
playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 50, 1)
..()
+
+/mob/living/simple_animal/hostile/rat/Login()
+ . = ..()
+ if(!riding_datum)
+ riding_datum = new /datum/riding/simple_animal(src)
+ verbs |= /mob/living/simple_animal/proc/animal_mount
+
+/mob/living/simple_animal/hostile/rat/MouseDrop_T(mob/living/M, mob/living/user)
+ return
\ No newline at end of file
diff --git a/icons/mob/vore.dmi b/icons/mob/vore.dmi
index 0357739b9c..4479212c1b 100644
Binary files a/icons/mob/vore.dmi and b/icons/mob/vore.dmi differ
diff --git a/icons/mob/vore64x64.dmi b/icons/mob/vore64x64.dmi
index 8454da40d7..13a67edbe3 100644
Binary files a/icons/mob/vore64x64.dmi and b/icons/mob/vore64x64.dmi differ