diff --git a/code/modules/mob/living/simple_animal/friendly/fox_vr.dm b/code/modules/mob/living/simple_animal/friendly/fox_vr.dm
new file mode 100644
index 00000000000..a6c0065a287
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/friendly/fox_vr.dm
@@ -0,0 +1,308 @@
+/mob/living/simple_animal/fox
+ name = "Fox"
+ desc = "It's a fox. I wonder what it says?"
+ icon = 'icons/mob/fox_vr.dmi'
+ icon_state = "fox"
+ icon_living = "fox"
+ icon_dead = "fox_dead"
+ speak = list("Ack-Ack","Ack-Ack-Ack-Ackawoooo","Awoo","Tchoff")
+ speak_emote = list("geckers", "barks")
+ emote_hear = list("howls","barks")
+ emote_see = list("shakes its head", "shivers", "geckers")
+ speak_chance = 1
+ turns_per_move = 5
+ see_in_dark = 6
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/fox
+ response_help = "scritches"
+ response_disarm = "gently pushes aside"
+ response_harm = "kicks"
+ var/turns_since_scan = 0
+ var/mob/living/simple_animal/mouse/movement_target
+ var/mob/flee_target
+ min_oxy = 16 //Require atleast 16kPA oxygen
+ minbodytemp = 223 //Below -50 Degrees Celcius
+ maxbodytemp = 323 //Above 50 Degrees Celcius
+ mob_size = MOB_TINY
+
+/mob/living/simple_animal/fox/New()
+ if(!vore_organs.len)
+ var/datum/belly/B = new /datum/belly(src)
+ B.immutable = 1
+ B.name = "Stomach"
+ B.inside_flavor = "Slick foxguts. Cute on the outside, slimy on the inside!"
+ B.human_prey_swallow_time = swallowTime
+ B.nonhuman_prey_swallow_time = swallowTime
+ vore_organs[B.name] = B
+ vore_selected = B.name
+
+ B.emote_lists[DM_HOLD] = list(
+ "The foxguts knead and churn around you harmlessly.",
+ "With a loud glorp, some air shifts inside the belly.",
+ "A thick drop of warm bellyslime drips onto you from above.",
+ "The fox turns suddenly, causing you to shift a little.",
+ "During a moment of relative silence, you can hear the fox breathing.",
+ "The slimey stomach walls squeeze you lightly, then relax.")
+
+ B.emote_lists[DM_DIGEST] = list(
+ "The guts knead at you, trying to work you into thick soup.",
+ "You're ground on by the slimey walls, treated like a mouse.",
+ "The acrid air is hard to breathe, and stings at your lungs.",
+ "You can feel the acids coating you, ground in by the slick walls.",
+ "The fox's stomach churns hungrily over your form, trying to take you.",
+ "With a loud glorp, the stomach spills more acids onto you.")
+ ..()
+
+// All them complicated fox procedures.
+/mob/living/simple_animal/fox/Life()
+ //MICE!
+ if((loc) && isturf(loc))
+ if(!stat && !resting && !buckled)
+ for(var/mob/living/simple_animal/mouse/M in loc)
+ if(isPredator) //If the fox is a predator,
+ movement_target = null
+ custom_emote(1, "greedily stuffs [M] into their gaping maw!")
+ if(M in oview(1, src))
+ animal_nom(M)
+ else
+ M << "You just manage to slip away from [src]'s jaws before you can be sent to a fleshy prison!"
+ break
+ else
+ if(!M.stat)
+ M.splat()
+ visible_emote(pick("bites \the [M]!","toys with \the [M].","chomps on \the [M]!"))
+ movement_target = null
+ stop_automated_movement = 0
+ break
+ ..()
+
+ for(var/mob/living/simple_animal/mouse/snack in oview(src,5))
+ if(snack.stat < DEAD && prob(15))
+ audible_emote(pick("hunkers down!","acts stealthy!","eyes [snack] hungrily."))
+ break
+
+ if(!stat && !resting && !buckled) //SEE A MICRO AND ARE A PREDATOR, EAT IT!
+ for(var/mob/living/carbon/human/food in oview(src, 5))
+
+ if(food.size_multiplier <= RESIZE_A_SMALLTINY)
+ if(prob(10))
+ custom_emote(1, pick("eyes [food] hungrily!","licks their lips and turns towards [food] a little!","pants as they imagine [food] being in their belly."))
+ break
+ else
+ if(prob(5))
+ movement_target = food
+ break
+
+ for(var/mob/living/carbon/human/bellyfiller in oview(1, src))
+ if(bellyfiller in src.prey_excludes)
+ continue
+
+ if(bellyfiller.size_multiplier <= RESIZE_A_SMALLTINY && isPredator)
+ movement_target = null
+ custom_emote(1, pick("slurps [bellyfiller] with their slimey tongue.","looms over [bellyfiller] with their maw agape.","sniffs at [bellyfiller], their belly grumbling hungrily."))
+ sleep(10)
+ custom_emote(1, "starts to scoop [bellyfiller] into their maw!")
+ if(bellyfiller in oview(1, src))
+ animal_nom(bellyfiller)
+ else
+ bellyfiller << "You just manage to slip away from [src]'s jaws before you can be sent to a fleshy prison!"
+ break
+
+ if(!stat && !resting && !buckled)
+ turns_since_scan++
+ if (turns_since_scan > 5)
+ walk_to(src,0)
+ turns_since_scan = 0
+
+ if (flee_target) //fleeing takes precendence
+ handle_flee_target()
+ else
+ handle_movement_target()
+
+/mob/living/simple_animal/fox/proc/handle_movement_target()
+ //if our target is neither inside a turf or inside a human(???), stop
+ if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
+ movement_target = null
+ stop_automated_movement = 0
+ //if we have no target or our current one is out of sight/too far away
+ if( !movement_target || !(movement_target.loc in oview(src, 4)) )
+ movement_target = null
+ stop_automated_movement = 0
+ for(var/mob/living/simple_animal/mouse/snack in oview(src)) //search for a new target
+ if(isturf(snack.loc) && !snack.stat)
+ movement_target = snack
+ break
+
+ if(movement_target)
+ stop_automated_movement = 1
+ walk_to(src,movement_target,0,10)
+
+/mob/living/simple_animal/fox/proc/handle_flee_target()
+ //see if we should stop fleeing
+ if (flee_target && !(flee_target.loc in view(src)))
+ flee_target = null
+ stop_automated_movement = 0
+
+ if (flee_target)
+ if(prob(25)) say("GRRRRR!")
+ stop_automated_movement = 1
+ walk_away(src, flee_target, 7, 2)
+
+/mob/living/simple_animal/fox/proc/set_flee_target(atom/A)
+ if(A)
+ flee_target = A
+ turns_since_scan = 5
+
+/mob/living/simple_animal/fox/attackby(var/obj/item/O, var/mob/user)
+ . = ..()
+ if(O.force)
+ set_flee_target(user? user : src.loc)
+
+
+/mob/living/simple_animal/fox/attack_hand(mob/living/carbon/human/M as mob)
+ . = ..()
+ if(M.a_intent == "hurt")
+ set_flee_target(M)
+
+/mob/living/simple_animal/fox/ex_act()
+ . = ..()
+ set_flee_target(src.loc)
+
+/mob/living/simple_animal/fox/bullet_act(var/obj/item/projectile/proj)
+ . = ..()
+ set_flee_target(proj.firer? proj.firer : src.loc)
+
+/mob/living/simple_animal/fox/hitby(atom/movable/AM)
+ . = ..()
+ set_flee_target(AM.thrower? AM.thrower : src.loc)
+
+/mob/living/simple_animal/fox/MouseDrop(atom/over_object)
+
+ var/mob/living/carbon/H = over_object
+ if(!istype(H) || !Adjacent(H)) return ..()
+
+ if(H.a_intent == "help")
+ get_scooped(H)
+ return
+ else
+ return ..()
+
+/mob/living/simple_animal/fox/get_scooped(var/mob/living/carbon/grabber)
+ if (stat >= DEAD)
+ return //since the holder icon looks like a living cat
+ ..()
+
+//Basic friend AI
+/mob/living/simple_animal/fox/fluff
+ var/mob/living/carbon/human/friend
+ var/befriend_job = null
+
+/mob/living/simple_animal/fox/fluff/handle_movement_target()
+ if (friend)
+ var/follow_dist = 5
+ if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) //danger
+ follow_dist = 1
+ else if (friend.stat || friend.health <= 50) //danger or just sleeping
+ follow_dist = 2
+ var/near_dist = max(follow_dist - 2, 1)
+ var/current_dist = get_dist(src, friend)
+
+ if (movement_target != friend)
+ if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (friend in oview(src)))
+ //stop existing movement
+ walk_to(src,0)
+ turns_since_scan = 0
+
+ //walk to friend
+ stop_automated_movement = 1
+ movement_target = friend
+ walk_to(src, movement_target, near_dist, 4)
+
+ //already following and close enough, stop
+ else if (current_dist <= near_dist)
+ walk_to(src,0)
+ movement_target = null
+ stop_automated_movement = 0
+ if (prob(10))
+ say("Yap!")
+
+ if (!friend || movement_target != friend)
+ ..()
+
+/mob/living/simple_animal/fox/fluff/Life()
+ ..()
+ if (stat || !friend)
+ return
+ if (get_dist(src, friend) <= 1)
+ if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
+ if (prob((friend.stat < DEAD)? 50 : 15))
+ var/verb = pick("huffs", "whines", "yowls")
+ audible_emote(pick("[verb] in distress.", "[verb] anxiously."))
+ else
+ if (prob(5))
+ visible_emote(pick("nips [friend] affectionately.",
+ "yaps at [friend].",
+ "looks at [friend], wagging.",
+ "wags happily."))
+ else if (friend.health <= 50)
+ if (prob(10))
+ var/verb = pick("huffs", "whines", "yowls")
+ audible_emote("[verb] anxiously.")
+
+/mob/living/simple_animal/fox/fluff/verb/friend()
+ set name = "Become Friends"
+ set category = "IC"
+ set src in view(1)
+
+ if(friend && usr == friend)
+ set_dir(get_dir(src, friend))
+ say("Yap!")
+ return
+
+ if (!(ishuman(usr) && befriend_job && usr.job == befriend_job))
+ usr << "[src] ignores you."
+ return
+
+ friend = usr
+
+ set_dir(get_dir(src, friend))
+ say("Yap!")
+
+/obj/item/weapon/reagent_containers/food/snacks/meat/fox
+ name = "Fox meat"
+ desc = "The fox doesn't say a god damn thing, now."
+
+//Captain fox
+/mob/living/simple_animal/fox/fluff/Renault
+ name = "Renault"
+ desc = "Renault, the Captain's trustworthy fox. I wonder what it says?"
+ isPredator = 1
+ befriend_job = "Captain"
+
+/mob/living/simple_animal/fox/fluff/Renault/New()
+ if(!vore_organs.len)
+ var/datum/belly/B = new /datum/belly(src)
+ B.immutable = 1
+ B.name = "Stomach"
+ B.inside_flavor = "Slick foxguts. They seem somehow more regal than perhaps other foxes!"
+ B.human_prey_swallow_time = swallowTime
+ B.nonhuman_prey_swallow_time = swallowTime
+ vore_organs[B.name] = B
+ vore_selected = B.name
+
+ B.emote_lists[DM_HOLD] = list(
+ "Renault's stomach walls squeeze around you more tightly for a moment, before relaxing, as if testing you a bit.",
+ "There's a sudden squeezing as Renault presses a forepaw against his gut over you, squeezng you against the slick walls.",
+ "The 'head fox' has a stomach that seems to think you belong to it. It might be hard to argue, as it kneads at your form.",
+ "If being in the captain's fox is a promotion, it might not feel like one. The belly just coats you with more thick foxslime.",
+ "It doesn't seem like Renault wants to let you out. The stomach and owner possessively squeeze around you.",
+ "Renault's stomach walls squeeze closer, as he belches quietly, before swallowing more air. Does he do that on purpose?")
+
+ B.emote_lists[DM_DIGEST] = list(
+ "Renault's stomach walls grind hungrily inwards, kneading acids against your form, and treating you like any other food.",
+ "The captain's fox impatiently kneads and works acids against you, trying to claim your body for fuel.",
+ "The walls knead in firmly, squeezing and tossing you around briefly in disorienting aggression.",
+ "Renault belches, letting the remaining air grow more acrid. It burns your lungs with each breath.",
+ "A thick glob of acids drip down from above, adding to the pool of caustic fluids in Renault's belly.",
+ "There's a loud gurgle as the stomach declares the intent to make you a part of Renault.")
+
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/friendly/snake_vr.dm b/code/modules/mob/living/simple_animal/friendly/snake_vr.dm
new file mode 100644
index 00000000000..f53c8f46483
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/friendly/snake_vr.dm
@@ -0,0 +1,55 @@
+/mob/living/simple_animal/snake
+ name = "Snake"
+ desc = "A big thick snake."
+ icon = 'icons/mob/snake_vr.dmi'
+ icon_state = "snake"
+ icon_living = "snake"
+ icon_dead = "snake_dead"
+ speak_emote = list("hisses")
+ health = 20
+ maxHealth = 20
+ attacktext = "bites"
+ melee_damage_lower = 3
+ melee_damage_upper = 5
+ response_help = "pets"
+ response_disarm = "shoos"
+ response_harm = "kicks"
+ turns_per_move = 8 // SLOW-ASS MUTHAFUCKA
+
+//NOODLE IS HERE! SQUEEEEEEEE~
+/mob/living/simple_animal/snake/Noodle
+ name = "Noodle"
+ desc = "This snake is particularly chubby and demands nothing but the finest of treats."
+ isPredator = 1
+
+//Special snek-snax for Noodle!
+obj/item/weapon/reagent_containers/food/snacks/snakesnack
+ name = "Sugar mouse"
+ desc = "A little mouse treat made of coloured sugar. Noodle loves these!"
+ var/snack_colour
+ icon = 'icons/mob/snake_vr.dmi'
+ icon_state = "snack_yellow"
+
+obj/item/weapon/reagent_containers/food/snacks/snakesnack/New()
+ ..()
+ if(!snack_colour)
+ snack_colour = pick( list("yellow","green","pink","blue") )
+ icon_state = "snack_[snack_colour]"
+ desc = "A little mouse treat made of coloured sugar. Noodle loves these! This one is [snack_colour]."
+
+obj/item/weapon/storage/box/fluff/snakesnackbox
+ name = "Box of Snake Snax"
+ desc = "A box containing Noodle's special sugermouse treats."
+ icon = 'icons/mob/snake_vr.dmi'
+ icon_state = "sneksnakbox"
+ storage_slots = 7
+ New()
+ new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/snakesnack(src)
+ ..()
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 33fb8acd248..10908e074bc 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -106,7 +106,7 @@
/mob/living/simple_animal/hostile/proc/ListTargets(var/dist = 7)
- var/list/L = hearers(src, dist)
+ var/list/L = view(src, dist) //hearers(src, dist) <- This shit was broken and bad and caused a lot of lag because mobs would chase targets they can't see. -Spades
for (var/obj/mecha/M in mechas_list)
if (M.z == src.z && get_dist(src, M) <= dist)
diff --git a/code/modules/mob/living/simple_animal/hostile/vore/alien.dm b/code/modules/mob/living/simple_animal/hostile/vore/alien.dm
new file mode 100644
index 00000000000..ccb27f5b6e1
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/vore/alien.dm
@@ -0,0 +1,95 @@
+/mob/living/simple_animal/hostile/vore/alien
+ name = "alien hunter"
+ desc = "Hiss!"
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "xenohunter"
+ icon_living = "xenohunter"
+ icon_dead = "xenohunter-dead"
+ icon_gib = "gibbed-a"
+ response_help = "pokes"
+ response_disarm = "shoves"
+ response_harm = "hits"
+ speed = -1
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
+ maxHealth = 100
+ health = 100
+ harm_intent_damage = 5
+ melee_damage_lower = 25
+ melee_damage_upper = 25
+ attacktext = "slashed"
+ a_intent = "harm"
+ attack_sound = 'sound/weapons/bladeslice.ogg'
+ min_oxy = 0
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 0
+ min_co2 = 0
+ max_co2 = 0
+ min_n2 = 0
+ max_n2 = 0
+ unsuitable_atoms_damage = 15
+ faction = "alien"
+ environment_smash = 1
+ status_flags = CANPUSH
+ minbodytemp = 0
+ heat_damage_per_tick = 20
+ capacity = 1
+
+
+/mob/living/simple_animal/hostile/vore/alien/drone
+ name = "alien drone"
+ icon_state = "xenodrone"
+ icon_living = "xenodrone"
+ icon_dead = "xenodrone-dead"
+ health = 60
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+
+/mob/living/simple_animal/hostile/vore/alien/sentinel
+ name = "alien sentinel"
+ icon_state = "xenosentinel"
+ icon_living = "xenosentinel"
+ icon_dead = "xenosentinel-dead"
+ health = 120
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ ranged = 1
+ projectiletype = /obj/item/projectile/neurotox
+ projectilesound = 'sound/weapons/pierce.ogg'
+
+
+/mob/living/simple_animal/hostile/vore/alien/queen
+ name = "alien queen"
+ icon_state = "xenoqueen"
+ icon_living = "xenoqueen"
+ icon_dead = "xenoqueen-dead"
+ maxHealth = 250
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ ranged = 1
+ move_to_delay = 3
+ projectiletype = /obj/item/projectile/neurotox
+ projectilesound = 'sound/weapons/pierce.ogg'
+ rapid = 1
+ status_flags = 0
+
+/mob/living/simple_animal/hostile/vore/alien/queen/large
+ name = "alien empress"
+ icon = 'icons/mob/alienqueen.dmi'
+ icon_state = "queen_s"
+ icon_living = "queen_s"
+ icon_dead = "queen_dead"
+ move_to_delay = 4
+ maxHealth = 400
+ health = 400
+ pixel_x = -16
+ capacity = 3
+
+/obj/item/projectile/neurotox
+ damage = 30
+ icon_state = "toxin"
+
+/mob/living/simple_animal/hostile/vore/alien/death()
+ ..()
+ visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...")
+ playsound(src, 'sound/voice/hiss6.ogg', 100, 1)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/vore/bear.dm b/code/modules/mob/living/simple_animal/hostile/vore/bear.dm
new file mode 100644
index 00000000000..d843351d69c
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/vore/bear.dm
@@ -0,0 +1,170 @@
+//Space bears!
+/mob/living/simple_animal/hostile/vore/bear
+ name = "space bear"
+ desc = "RawrRawr!!"
+ icon_state = "spacebear"
+ icon_living = "spacebear"
+ icon_dead = "spacebear-dead"
+ icon_gib = "bear-gib"
+ speak = list("RAWR!","Rawr!","GRR!","Growl!")
+ speak_emote = list("growls", "roars")
+ emote_hear = list("rawrs","grumbles","grawls")
+ emote_see = list("stares ferociously", "stomps")
+ speak_chance = 1
+ turns_per_move = 5
+ see_in_dark = 6
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "pokes"
+ stop_automated_movement_when_pulled = 0
+ maxHealth = 60
+ health = 60
+ melee_damage_lower = 20
+ melee_damage_upper = 30
+
+ //Space bears aren't affected by atmos.
+ min_oxy = 0
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 0
+ min_co2 = 0
+ max_co2 = 0
+ min_n2 = 0
+ max_n2 = 0
+ minbodytemp = 0
+ var/stance_step = 0
+
+ faction = "russian"
+
+/mob/living/simple_animal/hostile/vore/bear/brown
+ name = "space bear"
+ desc = "RawrRawr!!"
+ icon_state = "brownbear"
+ icon_living = "brownbear"
+ icon_dead = "brownbear-dead"
+ icon_gib = "bear-gib"
+
+//SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!!
+/mob/living/simple_animal/hostile/vore/bear/Hudson
+ name = "Hudson"
+ desc = ""
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "pokes"
+
+/mob/living/simple_animal/hostile/vore/bear/Life()
+ . =..()
+ if(!.)
+ return
+/*
+ if(loc && istype(loc,/turf/space))
+ icon_state = "bear"
+ else
+ icon_state = "bearfloor"
+*/
+ switch(stance)
+
+ if(HOSTILE_STANCE_TIRED)
+ stop_automated_movement = 1
+ stance_step++
+ if(stance_step >= 10) //rests for 10 ticks
+ if(target_mob && target_mob in ListTargets(10))
+ stance = HOSTILE_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
+ else
+ stance = HOSTILE_STANCE_IDLE
+
+ if(HOSTILE_STANCE_ALERT)
+ stop_automated_movement = 1
+ var/found_mob = 0
+ if(target_mob && target_mob in ListTargets(10))
+ if(!(SA_attackable(target_mob)))
+ stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
+ stance_step++
+ found_mob = 1
+ src.set_dir(get_dir(src,target_mob)) //Keep staring at the mob
+
+ if(stance_step in list(1,4,7)) //every 3 ticks
+ var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
+ if(action)
+ custom_emote(1,action)
+ if(!found_mob)
+ stance_step--
+
+ if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
+ stance = HOSTILE_STANCE_IDLE
+ if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
+ stance = HOSTILE_STANCE_ATTACK
+
+ if(HOSTILE_STANCE_ATTACKING)
+ if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
+ custom_emote(1, "is worn out and needs to rest." )
+ stance = HOSTILE_STANCE_TIRED
+ stance_step = 0
+ walk(src, 0) //This stops the bear's walking
+ return
+
+
+
+/mob/living/simple_animal/hostile/vore/bear/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
+ stance = HOSTILE_STANCE_ALERT
+ stance_step = 6
+ target_mob = user
+ ..()
+
+/mob/living/simple_animal/hostile/vore/bear/attack_hand(mob/living/carbon/human/M as mob)
+ if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
+ stance = HOSTILE_STANCE_ALERT
+ stance_step = 6
+ target_mob = M
+ ..()
+/*
+/mob/living/simple_animal/hostile/vore/bear/Process_Spacemove(var/check_drift = 0)
+ return //No drifting in space for space bears!
+*/
+/mob/living/simple_animal/hostile/vore/bear/FindTarget() // TODO: Make it so if the target is laying down, the bear actually won't bother them.
+ . = ..()
+ if(.)
+ custom_emote(1,"stares alertly at [.]")
+ stance = HOSTILE_STANCE_ALERT
+
+/mob/living/simple_animal/hostile/vore/bear/LoseTarget()
+ ..(5)
+
+/mob/living/simple_animal/hostile/vore/bear/AttackingTarget()
+
+ // Need to snowflake the vode in the bear code here because of the snowflakey way bears work.
+ if(isliving(target_mob.loc)) //They're inside a mob, maybe us, ignore!
+ return
+
+ if(!isliving(target_mob)) //Can't eat 'em if they ain't alive. Prevents eating borgs/bots.
+ ..()
+ return
+
+ if(picky && target_mob.digestable && target_mob.lying && target_mob.size_multiplier >= min_size && target_mob.size_multiplier <= max_size && !(target_mob in prey_exclusions))
+ if(capacity)
+ var/check_size = target_mob.size_multiplier + fullness
+ if(check_size <= capacity)
+ animal_nom(target_mob)
+ else
+ animal_nom(target_mob)
+ return
+
+ // Original bear attack code.
+ if(!Adjacent(target_mob))
+ return
+ custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
+
+ var/damage = rand(20,30)
+
+ if(ishuman(target_mob))
+ var/mob/living/carbon/human/H = target_mob
+ var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG)
+ var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
+ H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
+ return H
+ else if(isliving(target_mob))
+ var/mob/living/L = target_mob
+ L.adjustBruteLoss(damage)
+ return L
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/vore/carp.dm b/code/modules/mob/living/simple_animal/hostile/vore/carp.dm
new file mode 100644
index 00000000000..f40938c5185
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/vore/carp.dm
@@ -0,0 +1,86 @@
+/mob/living/simple_animal/hostile/vore/carp
+ name = "space carp"
+ desc = "A voracious, fang-bearing creature that resembles a fish."
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "carp"
+ icon_living = "carp"
+ icon_dead = "carp_dead"
+ icon_gib = "carp_gib"
+ speak_chance = 0
+ turns_per_move = 5
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
+ response_help = "pets the"
+ response_disarm = "gently pushes aside the"
+ response_harm = "hits the"
+ speed = 4
+ maxHealth = 25
+ health = 25
+
+ harm_intent_damage = 8
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ attacktext = "bitten"
+ attack_sound = 'sound/weapons/bite.ogg'
+
+ capacity = 1
+ max_size = 0.5
+
+ //Space carp aren't affected by atmos.
+ min_oxy = 0
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 0
+ min_co2 = 0
+ max_co2 = 0
+ min_n2 = 0
+ max_n2 = 0
+ minbodytemp = 0
+
+ break_stuff_probability = 15
+
+ faction = "carp"
+
+/mob/living/simple_animal/hostile/vore/carp/Process_Spacemove(var/check_drift = 0)
+ return 1 //No drifting in space for space carp! //original comments do not steal
+
+/mob/living/simple_animal/hostile/vore/carp/FindTarget()
+ . = ..()
+ if(.)
+ custom_emote(1,"nashes at [.]")
+
+/mob/living/simple_animal/hostile/vore/carp/AttackingTarget()
+ . =..()
+ var/mob/living/L = .
+ if(istype(L))
+ if(prob(15))
+ L.Weaken(3)
+ L.visible_message("\the [src] knocks down \the [L]!")
+
+
+// ---------- Great White Carp ---------- //
+/mob/living/simple_animal/hostile/vore/large/carp
+ name = "great white carp"
+ desc = "You're going to need a bigger ship."
+ icon_dead = "megacarp-dead"
+ icon_living = "megacarp"
+ icon_state = "megacarp"
+ pixel_y = -16 // Center this completely since it's in space.
+ maxHealth = 600 // Boss
+ health = 600
+ speed = 3
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
+ meat_amount = 10
+ faction = "carp"
+ capacity = 2
+ max_size = 2
+ //Space carp aren't affected by atmos.
+ min_oxy = 0
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 0
+ min_co2 = 0
+ max_co2 = 0
+ min_n2 = 0
+ max_n2 = 0
+ minbodytemp = 0
+ break_stuff_probability = 15
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/vore/creature.dm b/code/modules/mob/living/simple_animal/hostile/vore/creature.dm
new file mode 100644
index 00000000000..59f52cd5ed0
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/vore/creature.dm
@@ -0,0 +1,19 @@
+/mob/living/simple_animal/hostile/vore/creature
+ name = "creature"
+ desc = "A sanity-destroying otherthing."
+ icon = 'icons/mob/critter.dmi'
+ speak_emote = list("gibbers")
+ icon_state = "otherthing"
+ icon_living = "otherthing"
+ icon_dead = "otherthing-dead"
+ health = 80
+ maxHealth = 80
+ melee_damage_lower = 25
+ melee_damage_upper = 50
+ attacktext = "chomped"
+ attack_sound = 'sound/weapons/bite.ogg'
+ faction = "creature"
+ speed = 4
+ capacity = 0
+ max_size = 2 // Max: 2
+ min_size = 0.25 // Min: 0.25
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/vore/mimic.dm b/code/modules/mob/living/simple_animal/hostile/vore/mimic.dm
new file mode 100644
index 00000000000..1a765b49d14
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/vore/mimic.dm
@@ -0,0 +1,197 @@
+//
+// Abstract Class
+//
+/mob/living/simple_animal/hostile/vore/mimic
+ name = "crate"
+ desc = "A rectangular steel crate."
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "crate"
+ icon_living = "crate"
+
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
+ response_help = "touches"
+ response_disarm = "pushes"
+ response_harm = "hits"
+ speed = 4
+ maxHealth = 250
+ health = 250
+
+ harm_intent_damage = 5
+ melee_damage_lower = 8
+ melee_damage_upper = 12
+ attacktext = "attacked"
+ attack_sound = 'sound/weapons/bite.ogg'
+
+ min_oxy = 0
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 0
+ min_co2 = 0
+ max_co2 = 0
+ min_n2 = 0
+ max_n2 = 0
+ minbodytemp = 0
+
+ capacity = 0
+
+ faction = "mimic"
+ move_to_delay = 8
+
+/mob/living/simple_animal/hostile/vore/mimic/FindTarget()
+ . = ..()
+ if(.)
+ audible_emote("growls at [.]")
+
+/mob/living/simple_animal/hostile/vore/mimic/death()
+ ..()
+ del(src)
+
+//
+// Crate Mimic
+//
+
+
+// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
+/mob/living/simple_animal/hostile/vore/mimic/crate
+
+ attacktext = "bitten"
+
+ stop_automated_movement = 1
+ wander = 0
+ var/attempt_open = 0
+
+// Pickup loot
+/mob/living/simple_animal/hostile/vore/mimic/crate/New()
+ ..()
+ for(var/obj/item/I in loc)
+ I.loc = src
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/DestroySurroundings()
+ ..()
+ if(prob(90))
+ icon_state = "[initial(icon_state)]open"
+ else
+ icon_state = initial(icon_state)
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/ListTargets()
+ if(attempt_open)
+ return ..()
+ return view(src, 1)
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/FindTarget()
+ . = ..()
+ if(.)
+ trigger()
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/AttackingTarget()
+ . = ..()
+ if(.)
+ icon_state = initial(icon_state)
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/proc/trigger()
+ if(!attempt_open)
+ visible_message("[src] starts to move!")
+ attempt_open = 1
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/adjustBruteLoss(var/damage)
+ trigger()
+ ..(damage)
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/LoseTarget()
+ ..()
+ icon_state = initial(icon_state)
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/LostTarget()
+ ..()
+ icon_state = initial(icon_state)
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/death()
+
+ var/obj/structure/closet/crate/C = new(get_turf(src))
+ // Put loot in crate
+ for(var/obj/O in src)
+ O.loc = C
+ ..()
+
+/mob/living/simple_animal/hostile/vore/mimic/crate/AttackingTarget()
+ . =..()
+ var/mob/living/L = .
+ if(istype(L))
+ if(prob(15))
+ L.Weaken(2)
+ L.visible_message("\the [src] knocks down \the [L]!")
+
+//
+// Copy Mimic
+//
+
+// var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate)
+// List now defined in projectile/animate.dm
+
+/mob/living/simple_animal/hostile/vore/mimic/copy
+
+ health = 100
+ maxHealth = 100
+ var/mob/living/creator = null // the creator
+ var/destroy_objects = 0
+ var/knockdown_people = 0
+
+/mob/living/simple_animal/hostile/vore/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator)
+ ..(loc)
+ CopyObject(copy, creator)
+
+/mob/living/simple_animal/hostile/vore/mimic/copy/death()
+
+ for(var/atom/movable/M in src)
+ M.loc = get_turf(src)
+ ..()
+
+/mob/living/simple_animal/hostile/vore/mimic/copy/ListTargets()
+ // Return a list of targets that isn't the creator
+ . = ..()
+ return . - creator
+
+/mob/living/simple_animal/hostile/vore/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator)
+
+ if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects))
+
+ O.loc = src
+ name = O.name
+ desc = O.desc
+ icon = O.icon
+ icon_state = O.icon_state
+ icon_living = icon_state
+
+ if(istype(O, /obj/structure))
+ health = (anchored * 50) + 50
+ destroy_objects = 1
+ if(O.density && O.anchored)
+ knockdown_people = 1
+ melee_damage_lower *= 2
+ melee_damage_upper *= 2
+ else if(istype(O, /obj/item))
+ var/obj/item/I = O
+ health = 15 * I.w_class
+ melee_damage_lower = 2 + I.force
+ melee_damage_upper = 2 + I.force
+ move_to_delay = 2 * I.w_class
+
+ maxHealth = health
+ if(creator)
+ src.creator = creator
+ faction = "\ref[creator]" // very unique
+ return 1
+ return
+
+/mob/living/simple_animal/hostile/vore/mimic/copy/DestroySurroundings()
+ if(destroy_objects)
+ ..()
+
+/mob/living/simple_animal/hostile/vore/mimic/copy/AttackingTarget()
+ . =..()
+ if(knockdown_people)
+ var/mob/living/L = .
+ if(istype(L))
+ if(prob(15))
+ L.Weaken(1)
+ L.visible_message("\the [src] knocks down \the [L]!")
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/vore/vore.dm b/code/modules/mob/living/simple_animal/hostile/vore/vore.dm
new file mode 100644
index 00000000000..650f621c604
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/vore/vore.dm
@@ -0,0 +1,148 @@
+/*
+--------------
+NOTES FOR DEVS
+--------------
+
+If your predator has a limited capacity, it should have sprites for every interval of its size, rounded to the nearest whole number.
+Example: If I have a snake predator who has a capacity of 3, I need sprites for snake-1, snake-2, and snake-3.
+
+Capacity should always be a whole number.
+
+Also max_size and min_size should never exceed capacity or the icon will break.
+
+Don't use ranged mobs for vore mobs.
+*/
+
+
+/mob/living/simple_animal/hostile/vore
+ name = "voracious lizard"
+ desc = "These gluttonous little bastards used to be regular lizards that were mutated by long-term exposure to phoron!"
+ icon_dead = "dino-dead"
+ icon_living = "dino"
+ icon_state = "dino"
+ icon = 'icons/mob/vore.dmi'
+ var/capacity = 1 // Zero is infinite. Do not set higher than you have icons to update.
+ var/max_size = 1 // Max: 2
+ var/min_size = 0.25 // Min: 0.25
+ var/picky = 1 // Won't eat undigestable prey by default
+ var/fullness = 0
+ swallowTime = 10 // Hungry little bastards.
+
+ // By default, this is what most vore mobs are capable of.
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "hits"
+ speed = 4
+ harm_intent_damage = 5
+ melee_damage_lower = 10
+ melee_damage_upper = 25
+ attacktext = "bitten"
+ attack_sound = 'sound/weapons/bite.ogg'
+ min_oxy = 5
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 1
+ min_co2 = 0
+ max_co2 = 5
+ min_n2 = 0
+ max_n2 = 0
+ minbodytemp = 270
+ maxbodytemp = 370
+ heat_damage_per_tick = 15
+ cold_damage_per_tick = 10
+ unsuitable_atoms_damage = 10
+
+/mob/living/simple_animal/hostile/vore/update_icons()
+ if(stat == DEAD)
+ return
+
+ if(capacity)
+ fullness = 0
+ for(var/I in vore_organs)
+ var/datum/belly/B = vore_organs[I]
+ for(var/mob/living/M in B.internal_contents)
+ fullness += M.size_multiplier
+ fullness = round(fullness, 1) // Because intervals of 0.25 are going to make sprite artists cry.
+ if(fullness)
+ if (fullness > capacity) // Player controlled.
+ icon_state = "[initial(icon_state)]-[capacity]"
+ else
+ icon_state = "[initial(icon_state)]-[fullness]"
+ else
+ icon_state = initial(icon_state)
+ ..()
+
+/mob/living/simple_animal/hostile/vore/New()
+
+ if(!vore_organs.len)
+ var/datum/belly/B = new /datum/belly(src)
+ B.immutable = 1
+ B.name = "Stomach"
+ B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [name]."
+ if (faction == "neutral")
+ B.digest_mode = "Hold" // Friendly slime-spawned mobs are neutral faction.
+ else
+ B.digest_mode = "Digest" // Though this usually doesn't happen.
+ vore_organs[B.name] = B
+ vore_selected = "Stomach"
+ B.vore_verb = "swallow"
+ B.emote_lists[DM_HOLD] = list(
+ "The insides knead at you gently for a moment.",
+ "The guts glorp wetly around you as some air shifts.",
+ "Your predator takes a deep breath and sighs, shifting you somewhat.",
+ "The stomach squeezes you tight for a moment, then relaxes.",
+ "During a moment of quiet, breathing becomes the most audible thing.",
+ "The warm slickness surrounds and kneads on you.")
+
+ B.emote_lists[DM_DIGEST] = list(
+ "The caustic acids eat away at your form.",
+ "The acrid air burns at your lungs.",
+ "Without a thought for you, the stomach grinds inwards painfully.",
+ "The guts treat you like food, squeezing to press more acids against you.",
+ "The onslaught against your body doesn't seem to be letting up; you're food now.",
+ "The insides work on you like they would any other food.")
+ ..()
+
+/mob/living/simple_animal/hostile/vore/AttackingTarget()
+ if(isliving(target_mob.loc)) //They're inside a mob, maybe us, ignore!
+ return
+
+ if(!isliving(target_mob)) //Can't eat 'em if they ain't alive. Prevents eating borgs/bots.
+ ..()
+ return
+
+ if(picky && !target_mob.digestable) //Don't eat people with nogurgle prefs
+ ..()
+ return
+
+ if(target_mob.lying && target_mob.size_multiplier >= min_size && target_mob.size_multiplier <= max_size && !(target_mob in prey_exclusions))
+ if(capacity)
+ var/check_size = target_mob.size_multiplier + fullness
+ if(check_size <= capacity)
+ animal_nom(target_mob)
+ target_mob = null
+ else
+ animal_nom(target_mob)
+ target_mob = null
+
+ ..()
+
+/mob/living/simple_animal/hostile/vore/death()
+ for(var/I in vore_organs)
+ var/datum/belly/B = vore_organs[I]
+ B.release_all_contents() // When your stomach is empty
+ ..() // then you have my permission to die.
+
+
+// ------- Big Preds ------- //
+
+/mob/living/simple_animal/hostile/vore/large
+ name = "giant snake"
+ desc = "Snakes. Why did it have to be snakes?"
+ icon = 'icons/mob/vore64x64.dmi'
+ icon_dead = "snake-dead"
+ icon_living = "snake"
+ icon_state = "snake"
+ pixel_x = -16
+ maxHealth = 200
+ health = 200
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm
new file mode 100644
index 00000000000..ec0d15bcd7e
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm
@@ -0,0 +1,3 @@
+/mob/living/simple_animal
+ // List of targets excluded (for now) from being eaten by this mob.
+ var/list/prey_exclusions = list()
diff --git a/icons/mob/fox_vr.dmi b/icons/mob/fox_vr.dmi
new file mode 100644
index 00000000000..79d1671408e
Binary files /dev/null and b/icons/mob/fox_vr.dmi differ
diff --git a/icons/mob/snake_vr.dmi b/icons/mob/snake_vr.dmi
new file mode 100644
index 00000000000..42631b85de9
Binary files /dev/null and b/icons/mob/snake_vr.dmi differ
diff --git a/icons/mob/vore.dmi b/icons/mob/vore.dmi
new file mode 100644
index 00000000000..fd2050b7a30
Binary files /dev/null and b/icons/mob/vore.dmi differ
diff --git a/icons/mob/vore64x64.dmi b/icons/mob/vore64x64.dmi
new file mode 100644
index 00000000000..550817b8394
Binary files /dev/null and b/icons/mob/vore64x64.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 11f067efc3b..658a8f5362c 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1499,6 +1499,7 @@
#include "code\modules\mob\living\simple_animal\parrot.dm"
#include "code\modules\mob\living\simple_animal\shade.dm"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
+#include "code\modules\mob\living\simple_animal\simple_animal_vr.dm"
#include "code\modules\mob\living\simple_animal\worm.dm"
#include "code\modules\mob\living\simple_animal\borer\borer.dm"
#include "code\modules\mob\living\simple_animal\borer\borer_captive.dm"
@@ -1511,10 +1512,12 @@
#include "code\modules\mob\living\simple_animal\friendly\corgi_vr.dm"
#include "code\modules\mob\living\simple_animal\friendly\crab.dm"
#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm"
+#include "code\modules\mob\living\simple_animal\friendly\fox_vr.dm"
#include "code\modules\mob\living\simple_animal\friendly\lizard.dm"
#include "code\modules\mob\living\simple_animal\friendly\mouse.dm"
#include "code\modules\mob\living\simple_animal\friendly\mushroom.dm"
#include "code\modules\mob\living\simple_animal\friendly\slime.dm"
+#include "code\modules\mob\living\simple_animal\friendly\snake_vr.dm"
#include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm"
#include "code\modules\mob\living\simple_animal\friendly\tomato.dm"
#include "code\modules\mob\living\simple_animal\hostile\alien.dm"
@@ -1534,6 +1537,12 @@
#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\drone.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
+#include "code\modules\mob\living\simple_animal\hostile\vore\alien.dm"
+#include "code\modules\mob\living\simple_animal\hostile\vore\bear.dm"
+#include "code\modules\mob\living\simple_animal\hostile\vore\carp.dm"
+#include "code\modules\mob\living\simple_animal\hostile\vore\creature.dm"
+#include "code\modules\mob\living\simple_animal\hostile\vore\mimic.dm"
+#include "code\modules\mob\living\simple_animal\hostile\vore\vore.dm"
#include "code\modules\mob\living\voice\voice.dm"
#include "code\modules\mob\new_player\login.dm"
#include "code\modules\mob\new_player\logout.dm"