diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm
index b344368341..eb18d09eb3 100644
--- a/code/_helpers/global_lists_vr.dm
+++ b/code/_helpers/global_lists_vr.dm
@@ -1,3 +1,15 @@
+/**
+ * VOREStation global lists
+*/
+
+//stores numeric player size options indexed by name
+var/global/list/player_sizes_list = list(
+ "Macro" = RESIZE_HUGE,
+ "Big" = RESIZE_BIG,
+ "Normal" = RESIZE_NORMAL,
+ "Small" = RESIZE_SMALL,
+ "Tiny" = RESIZE_TINY)
+
//Important items that are preserved when people are digested, cryo'd, etc.
var/global/list/important_items = list(
/obj/item/weapon/hand_tele,
@@ -60,4 +72,4 @@ var/global/list/struggle_sounds = list(
"Squish1" = 'sound/vore/squish1.ogg',
"Squish2" = 'sound/vore/squish2.ogg',
"Squish3" = 'sound/vore/squish3.ogg',
- "Squish4" = 'sound/vore/squish4.ogg')
\ No newline at end of file
+ "Squish4" = 'sound/vore/squish4.ogg')
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index b731905e5f..e0150e2ab1 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -28,11 +28,11 @@
var/mob/living/carbon/human/H = target
switch(type)
if("feet")
- if(!H.shoes)
+ if(!H.shoes || H.get_effective_size() < RESIZE_SMALL)
affecting = H.get_organ(pick("l_leg", "r_leg"))
H.Weaken(3)
if("l_hand", "r_hand")
- if(!H.gloves)
+ if(!H.gloves || H.get_effective_size() < RESIZE_SMALL)
affecting = H.get_organ(type)
H.Stun(3)
if(affecting)
diff --git a/code/modules/hydroponics/seed_datums_vr.dm b/code/modules/hydroponics/seed_datums_vr.dm
new file mode 100644
index 0000000000..ff66b960d6
--- /dev/null
+++ b/code/modules/hydroponics/seed_datums_vr.dm
@@ -0,0 +1,34 @@
+
+//Vore Originals
+
+/datum/seed/size
+ name = "microm"
+ seed_name = "Shrinking Mushroom"
+ display_name = "Shrinking mushroom trees"
+ mutants = list("megam")
+ kitchen_tag = "microm"
+ chems = list("microcillin" = list(1,20))
+
+/datum/seed/size/New()
+ ..()
+ set_trait(TRAIT_HARVEST_REPEAT,1)
+ set_trait(TRAIT_MATURATION,6)
+ set_trait(TRAIT_PRODUCTION,6)
+ set_trait(TRAIT_YIELD,3)
+ set_trait(TRAIT_POTENCY,15)
+ set_trait(TRAIT_PRODUCT_ICON,"sizeshroom")
+ set_trait(TRAIT_PRODUCT_COLOUR,"#DA00DA")
+ set_trait(TRAIT_PLANT_ICON,"tree")
+
+
+/datum/seed/size/megam
+ name = "megam"
+ seed_name = "Mega Mushroom"
+ display_name = "Mega mushroom trees"
+ mutants = list("microm")
+ kitchen_tag = "megam"
+ chems = list("macrocillin" = list(1,20))
+
+/datum/seed/size/megam/New()
+ ..()
+ set_trait(TRAIT_PRODUCT_COLOUR,"#DADA00")
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 56a47f918b..370a63c8e4 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -56,6 +56,11 @@
switch(M.a_intent)
if(I_HELP)
+
+ // VOREStation Edit - Begin
+ if (istype(H) && attempt_to_scoop(H))
+ return 0;
+ // VOREStation Edit - End
if(istype(H) && health < config.health_threshold_crit && health > config.health_threshold_dead)
if(!H.check_has_mouth())
H << "You don't have a mouth, you cannot perform CPR!"
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 0a21d4d5bc..026bd9681e 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -23,7 +23,9 @@
var/g_skin = 0
var/b_skin = 0
- var/size_multiplier = 1 //multiplier for the mob's icon size
+ // VoreStation (Moved to /mob/living)
+ // var/size_multiplier = 1 //multiplier for the mob's icon size
+
var/damage_multiplier = 1 //multiplies melee combat damage
var/icon_update = 1 //whether icon updating shall take place
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index b3fa6e43ea..d4a79bc3ee 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -88,6 +88,13 @@ default behaviour is:
if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && !dense && can_move_mob(tmob, 1, 0)) // mutual brohugs all around!
var/turf/oldloc = loc
forceMove(tmob.loc)
+
+ // VOREStation Edit - Begin
+ // In case of micros, we don't swap positions; instead occupying the same square!
+ if (handle_micro_bump_helping(tmob)) return
+ // TODO - Check if we need to do something about the slime.UpdateFeed() we are skipping below.
+ // VOREStation Edit - End
+
tmob.forceMove(oldloc)
now_pushing = 0
for(var/mob/living/carbon/slime/slime in view(1,tmob))
@@ -101,6 +108,12 @@ default behaviour is:
if(a_intent == I_HELP || src.restrained())
now_pushing = 0
return
+
+ // VOREStation Edit - Begin
+ // Handle grabbing, stomping, and such of micros!
+ if(handle_micro_bump_other(tmob)) return
+ // VOREStation Edit - End
+
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
if(prob(40) && !(FAT in src.mutations))
src << "You fail to push [tmob]'s fat ass out of the way."
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Vore_vr.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Vore_vr.dm
new file mode 100644
index 0000000000..c45e18121e
--- /dev/null
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Vore_vr.dm
@@ -0,0 +1,140 @@
+
+////////////////////////////
+/// NW's shrinking serum ///
+////////////////////////////
+
+/datum/reagent/macrocillin
+ name = "Macrocillin"
+ id = "macrocillin"
+ description = "Glowing yellow liquid."
+ reagent_state = LIQUID
+ color = "#FFFF00" // rgb: 255, 255, 0
+ metabolism = 2.5
+
+/datum/reagent/macrocillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ for(var/size in list(RESIZE_SMALL, RESIZE_NORMAL, RESIZE_BIG, RESIZE_HUGE))
+ if(M.size_multiplier < size)
+ M.resize(size)
+ M << "You grow!"
+ break
+ return
+
+/datum/reagent/microcillin
+ name = "Microcillin"
+ id = "microcillin"
+ description = "Murky purple liquid."
+ reagent_state = LIQUID
+ color = "#800080"
+ metabolism = 2.5
+
+/datum/reagent/microcillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ for(var/size in list(RESIZE_BIG, RESIZE_NORMAL, RESIZE_SMALL, RESIZE_TINY))
+ if(M.size_multiplier > size)
+ M.resize(size)
+ M << "You shrink!"
+ break;
+ return
+
+
+/datum/reagent/normalcillin
+ name = "Normalcillin"
+ id = "normalcillin"
+ description = "Translucent cyan liquid."
+ reagent_state = LIQUID
+ color = "#00FFFF"
+ metabolism = 2.5
+
+/datum/reagent/normalcillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ if(M.size_multiplier > RESIZE_BIG)
+ M.resize(RESIZE_BIG)
+ M << "You shrink!"
+ else if(M.size_multiplier > RESIZE_NORMAL)
+ M.resize(RESIZE_NORMAL)
+ M << "You shrink!"
+ else if(M.size_multiplier < RESIZE_NORMAL)
+ M.resize(RESIZE_NORMAL)
+ M << "You grow!"
+ else if(M.size_multiplier < RESIZE_SMALL)
+ M.resize(RESIZE_SMALL)
+ M << "You grow!"
+ return
+
+
+/datum/reagent/sizeoxadone
+ name = "Sizeoxadone"
+ id = "sizeoxadone"
+ description = "A volatile liquid used as a precursor to size-altering chemicals. Causes dizziness if taken unprocessed."
+ reagent_state = LIQUID
+ color = "#1E90FF"
+ overdose = REAGENTS_OVERDOSE
+
+/datum/reagent/sizeoxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ M.make_dizzy(1)
+ if(!M.confused) M.confused = 1
+ M.confused = max(M.confused, 20)
+ return
+
+
+////////////////////////// Anti-Noms Drugs //////////////////////////
+
+/datum/reagent/ickypak
+ name = "Ickypak"
+ id = "ickypak"
+ description = "A foul-smelling green liquid, for inducing muscle contractions to expel accidentally ingested things."
+ reagent_state = LIQUID
+ color = "#0E900E"
+ overdose = REAGENTS_OVERDOSE
+
+/datum/reagent/ickypak/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ M.make_dizzy(1)
+ M.adjustHalLoss(2)
+
+ for(var/I in M.vore_organs)
+ var/datum/belly/B = M.vore_organs[I]
+ for(var/atom/movable/A in B.internal_contents)
+ if(isliving(A))
+ var/mob/living/P = A
+ if(P.absorbed)
+ continue
+ if(prob(5))
+ playsound(M, 'sound/effects/splat.ogg', 50, 1)
+ B.release_specific_contents(A)
+ return
+
+
+/datum/reagent/unsorbitol
+ name = "Unsorbitol"
+ id = "unsorbitol"
+ description = "A frothy pink liquid, for causing cellular-level hetrogenous structure separation."
+ reagent_state = LIQUID
+ color = "#EF77E5"
+ overdose = REAGENTS_OVERDOSE
+
+/datum/reagent/unsorbitol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ M.make_dizzy(1)
+ M.adjustHalLoss(1)
+ if(!M.confused) M.confused = 1
+ M.confused = max(M.confused, 20)
+ M.hallucination += 15
+
+ for(var/I in M.vore_organs)
+ var/datum/belly/B = M.vore_organs[I]
+
+ if(B.digest_mode == DM_ABSORB) //Turn off absorbing on bellies
+ B.digest_mode = DM_HOLD
+
+ for(var/mob/living/P in B.internal_contents)
+ if(!P.absorbed)
+ continue
+
+ else if(prob(1))
+ playsound(M, 'sound/vore/schlorp.ogg', 50, 1)
+ P.absorbed = 0
+ M.visible_message("Something spills into [M]'s [lowertext(B.name)]!")
+ return
diff --git a/code/modules/reagents/Chemistry-Recipes_vr.dm b/code/modules/reagents/Chemistry-Recipes_vr.dm
new file mode 100644
index 0000000000..ec8d8ceb87
--- /dev/null
+++ b/code/modules/reagents/Chemistry-Recipes_vr.dm
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////////////
+/// Micro/Macro chemicals
+
+/datum/chemical_reaction/sizeoxadone
+ name = "sizeoxadone"
+ id = "sizeoxadone"
+ result = "sizeoxadone"
+ required_reagents = list("clonexadone" = 1, "tramadol" = 3, "phoron" = 1)
+ catalysts = list("phoron" = 5)
+ result_amount = 5
+
+/datum/chemical_reaction/macrocillin
+ name = "Macrocillin"
+ id = "macrocillin"
+ result = "macrocillin"
+ // POLARISTODO requires_heating = 1
+ required_reagents = list("sizeoxadone" = 20, "diethylamine" = 20)
+ result_amount = 1
+
+/datum/chemical_reaction/microcillin
+ name = "Microcillin"
+ id = "microcillin"
+ result = "microcillin"
+ // POLARISTODO requires_heating = 1
+ required_reagents = list("sizeoxadone" = 20, "sodiumchloride" = 20)
+ result_amount = 1
+
+/datum/chemical_reaction/normalcillin
+ name = "Normalcillin"
+ id = "normalcillin"
+ result = "normalcillin"
+ // POLARISTODO requires_heating = 1
+ required_reagents = list("sizeoxadone" = 20, "leporazine" = 20)
+ result_amount = 1
+
+/datum/chemical_reaction/dontcrossthebeams
+ name = "Don't Cross The Beams"
+ id = "dontcrossthebeams"
+ result = null
+ required_reagents = list("microcillin" = 1, "macrocillin" = 1)
+
+/datum/chemical_reaction/dontcrossthebeams/on_reaction(var/datum/reagents/holder, var/created_volume)
+ var/location = get_turf(holder.my_atom)
+ playsound(location, 'sound/weapons/gauss_shoot.ogg', 50, 1)
+ var/datum/effect/effect/system/grav_pull/s = new /datum/effect/effect/system/grav_pull
+ s.set_up(3, 3, location)
+ s.start()
+ holder.clear_reagents()
+
+///////////////////////////////////////////////////////////////////////////////////
+/// Vore Drugs
+
+/datum/chemical_reaction/ickypak
+ name = "Ickypak"
+ id = "ickypak"
+ result = "ickypak"
+ required_reagents = list("hyperzine" = 4, "fluorosurfactant" = 1)
+ result_amount = 5
+
+/datum/chemical_reaction/unsorbitol
+ name = "Unsorbitol"
+ id = "unsorbitol"
+ result = "unsorbitol"
+ required_reagents = list("mutagen" = 3, "lipozine" = 2)
+ result_amount = 5
diff --git a/code/modules/reagents/reagent_containers/glass/bottle_vr.dm b/code/modules/reagents/reagent_containers/glass/bottle_vr.dm
new file mode 100644
index 0000000000..ee4e60058f
--- /dev/null
+++ b/code/modules/reagents/reagent_containers/glass/bottle_vr.dm
@@ -0,0 +1,22 @@
+/obj/item/weapon/reagent_containers/glass/bottle/ickypak
+ name = "ickypak bottle"
+ desc = "A small bottle of ickypak. The smell alone makes you gag."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "bottle-3"
+
+/obj/item/weapon/reagent_containers/glass/bottle/ickypak/New()
+ ..()
+ reagents.add_reagent("ickypak", 60)
+ update_icon()
+
+
+/obj/item/weapon/reagent_containers/glass/bottle/unsorbitol
+ name = "unsorbitol bottle"
+ desc = "A small bottle of unsorbitol. Sickeningly sweet."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "bottle-3"
+
+/obj/item/weapon/reagent_containers/glass/bottle/unsorbitol/New()
+ ..()
+ reagents.add_reagent("unsorbitol", 60)
+ update_icon()
diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm
index cf156ee7b7..4c7324570d 100644
--- a/code/modules/vore/eating/living_vr.dm
+++ b/code/modules/vore/eating/living_vr.dm
@@ -65,7 +65,7 @@
//Things we can eat with vore code
var/list/vore_items = list(
/obj/item/weapon/grab,
- /obj/item/weapon/holder)
+ /obj/item/weapon/holder/micro)
if(!(I.type in vore_items))
return 0
@@ -106,11 +106,19 @@
else
log_debug("[attacker] attempted to feed [G.affecting] to [src] ([src.type]) but it failed.")
-
//Handle case: /obj/item/weapon/holder
- if(/obj/item/weapon/holder)
- return 1
+ if(/obj/item/weapon/holder/micro)
+ var/obj/item/weapon/holder/H = I
+ if(!isliving(user)) return 0 // Return 0 to continue upper procs
+ var/mob/living/attacker = user // Typecast to living
+
+ if (is_vore_predator(src))
+ for (var/mob/living/M in H.contents)
+ attacker.eat_held_mob(attacker, M, src)
+ return 1 //Return 1 to exit upper procs
+ else
+ log_debug("[attacker] attempted to feed [H.contents] to [src] ([src.type]) but it is not predator-capable")
return 0
diff --git a/code/modules/vore/resizing/grav_pull_vr.dm b/code/modules/vore/resizing/grav_pull_vr.dm
new file mode 100644
index 0000000000..921d1ab2b9
--- /dev/null
+++ b/code/modules/vore/resizing/grav_pull_vr.dm
@@ -0,0 +1,63 @@
+//
+// Gravity Pull effect which draws in movable objects to its center.
+// In this case, "number" refers to the range. directions is ignored.
+//
+/datum/effect/effect/system/grav_pull
+ var/pull_radius = 3
+ var/pull_anchored = 0
+ var/break_windows = 0
+
+/datum/effect/effect/system/grav_pull/set_up(range, num, loca)
+ pull_radius = range
+ number = num
+ if(istype(loca, /turf/))
+ location = loca
+ else
+ location = get_turf(loca)
+
+/datum/effect/effect/system/grav_pull/start()
+ spawn(0)
+ if(holder)
+ src.location = get_turf(holder)
+ for(var/i=0, i < number, i++)
+ do_pull()
+ sleep(25)
+
+/datum/effect/effect/system/grav_pull/proc/do_pull()
+ //following is adapted from supermatter and singulo code
+ if(defer_powernet_rebuild != 2)
+ defer_powernet_rebuild = 1
+
+ // Let's just make this one loop.
+ for(var/atom/X in orange(pull_radius, location))
+ // Movable atoms only
+ if(istype(X, /atom/movable))
+ if(istype(X, /obj/effect/overlay)) continue
+ if(X && !istype(X, /mob/living/carbon/human))
+ if(break_windows && istype(X, /obj/structure/window)) //shatter windows
+ var/obj/structure/window/W = X
+ W.ex_act(2.0)
+
+ if(istype(X, /obj))
+ var/obj/O = X
+ if(O.anchored)
+ if (!pull_anchored) continue // Don't pull anchored stuff unless configured
+ step_towards(X, location) // step just once if anchored
+ continue
+
+ step_towards(X, location) // Step twice
+ step_towards(X, location)
+
+ else if(istype(X,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = X
+ if(istype(H.shoes,/obj/item/clothing/shoes/magboots))
+ var/obj/item/clothing/shoes/magboots/M = H.shoes
+ if(M.magpulse)
+ step_towards(H, location) //step just once with magboots
+ continue
+ step_towards(H, location) //step twice
+ step_towards(H, location)
+
+ if(defer_powernet_rebuild != 2)
+ defer_powernet_rebuild = 0
+ return
diff --git a/code/modules/vore/resizing/holder_micro_vr.dm b/code/modules/vore/resizing/holder_micro_vr.dm
new file mode 100644
index 0000000000..5cdecd9039
--- /dev/null
+++ b/code/modules/vore/resizing/holder_micro_vr.dm
@@ -0,0 +1,33 @@
+// Micro Holders - Extends /obj/item/weapon/holder
+
+/obj/item/weapon/holder/micro
+ name = "micro"
+ desc = "Another crewmember, small enough to fit in your hand."
+ icon_state = "micro"
+ slot_flags = SLOT_FEET | SLOT_HEAD | SLOT_ID
+ w_class = 2
+ item_icons = null // Override value from parent. We don't have magic sprites.
+ pixel_y = 0 // Override value from parent.
+
+/obj/item/weapon/holder/micro/examine(var/mob/user)
+ for(var/mob/living/M in contents)
+ M.examine(user)
+
+/obj/item/weapon/holder/MouseDrop(mob/M as mob)
+ ..()
+ if(M != usr) return
+ if(usr == src) return
+ if(!Adjacent(usr)) return
+ if(istype(M,/mob/living/silicon/ai)) return
+ for(var/mob/living/carbon/human/O in contents)
+ O.show_inv(usr)
+
+/obj/item/weapon/holder/micro/attack_self(var/mob/living/user)
+ for(var/mob/living/carbon/human/M in contents)
+ M.help_shake_act(user)
+
+/obj/item/weapon/holder/micro/update_state()
+ // If any items have been dropped by contained mob, drop them to floor.
+ for(var/obj/O in contents)
+ O.forceMove(get_turf(src))
+ ..()
diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm
new file mode 100644
index 0000000000..c81051a3f8
--- /dev/null
+++ b/code/modules/vore/resizing/resize_vr.dm
@@ -0,0 +1,191 @@
+
+//these aren't defines so they can stay in this file
+var/const/RESIZE_HUGE = 2
+var/const/RESIZE_BIG = 1.5
+var/const/RESIZE_NORMAL = 1
+var/const/RESIZE_SMALL = 0.5
+var/const/RESIZE_TINY = 0.25
+
+//average
+var/const/RESIZE_A_HUGEBIG = (RESIZE_HUGE + RESIZE_BIG) / 2
+var/const/RESIZE_A_BIGNORMAL = (RESIZE_BIG + RESIZE_NORMAL) / 2
+var/const/RESIZE_A_NORMALSMALL = (RESIZE_NORMAL + RESIZE_SMALL) / 2
+var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
+
+// Adding needed defines to /mob/living
+// Note: Polaris had this on /mob/living/carbon/human We need it higher up for animals and stuff.
+/mob/living
+ var/size_multiplier = 1 //multiplier for the mob's icon size
+
+// Define holder_type on types we want to be scoop-able
+/mob/living/carbon/human
+ holder_type = /obj/item/weapon/holder/micro
+
+/**
+ * Scale up the size of a mob's icon by the size_multiplier.
+ * NOTE: mob/living/carbon/human/update_icons() has a more complicated system and
+ * is already applying this transform. BUT, it does not call ..()
+ * as long as that is true, we should be fine. If that changes we need to
+ * re-evaluate.
+ */
+/mob/living/update_icons()
+ ASSERT(!ishuman(src))
+ var/matrix/M = matrix()
+ M.Scale(size_multiplier)
+ M.Translate(0, 16*(size_multiplier-1))
+ src.transform = M
+
+/**
+ * Get the effective size of a mob.
+ * Currently this is based only on size_multiplier for micro/macro stuff,
+ * but in the future we may also incorporate the "mob_size", so that
+ * a macro mouse is still only effectively "normal" or a micro dragon is still large etc.
+ */
+/mob/living/proc/get_effective_size()
+ return src.size_multiplier
+
+/**
+ * Resizes the mob immediately to the desired mod, animating it growing/shrinking.
+ * It can be used by anything that calls it.
+ */
+/mob/living/proc/resize(var/new_size)
+ var/matrix/resize = matrix() // Defines the matrix to change the player's size
+ resize.Scale(new_size) //Change the size of the matrix
+
+ if(new_size >= RESIZE_NORMAL)
+ resize.Translate(0, -1 * (1 - new_size) * 16) //Move the player up in the tile so their feet align with the bottom
+
+ animate(src, transform = resize, time = 5) //Animate the player resizing
+ size_multiplier = new_size //Change size_multiplier so that other items can interact with them
+
+/**
+ * Verb proc for a command that lets players change their size OOCly.
+ * Ace was here! Redid this a little so we'd use math for shrinking characters. This is the old code.
+ */
+/mob/living/proc/set_size()
+ set name = "Set Character Size"
+ set category = "Vore"
+ var/nagmessage = "DO NOT ABUSE THESE COMMANDS. They are not here for you to play with. \
+ We were originally going to remove them but kept them for popular demand. \
+ Do not abuse their existence outside of ERP scenes where they apply, \
+ or reverting OOCly unwanted changes like someone lolshooting the crew with a shrink ray. -Ace"
+
+ var/size_name = input(nagmessage, "Pick a Size") in player_sizes_list
+ if (size_name && player_sizes_list[size_name])
+ src.resize(player_sizes_list[size_name])
+ message_admins("[key_name(src)] used the resize command in-game to be [size_name]. \
+ ([src ? "JMP" : "null"])")
+
+/** Add the set_size() proc to usable verbs. */
+/hook/living_new/proc/resize_setup(mob/living/M)
+ M.verbs += /mob/living/proc/set_size
+ return 1
+
+/**
+ * Attempt to scoop up this mob up into M's hands, if the size difference is large enough.
+ * @return false if normal code should continue, 1 to prevent normal code.
+ */
+/mob/living/proc/attempt_to_scoop(var/mob/living/carbon/human/M)
+ if(!istype(M))
+ return 0;
+ if(M.get_effective_size() - src.get_effective_size() >= 0.75)
+ var/obj/item/weapon/holder/m_holder = get_scooped(M)
+ if (m_holder)
+ return 1
+ else
+ return 0; // Unable to scoop, let other code run
+
+/**
+ * Handle bumping into someone with helping intent.
+ * Called from /mob/living/Bump() in the 'brohugs all around' section.
+ * @return false if normal code should continue, 1 to prevent normal code.
+ * // TODO - can the now_pushing = 0 be moved up? What does it do anyway?
+ */
+/mob/living/proc/handle_micro_bump_helping(var/mob/living/tmob)
+ if(src.get_effective_size() <= RESIZE_A_SMALLTINY && tmob.get_effective_size() <= RESIZE_A_SMALLTINY)
+ // Both small! Go ahead and
+ now_pushing = 0
+ return 1
+ if(abs(src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
+ now_pushing = 0
+ if(src.get_effective_size() > tmob.get_effective_size())
+ var/mob/living/carbon/human/M = src
+ if(0) // POLARISTODO istaur(src) && M.taur_style == 2)
+ src << "You carefully slither around [tmob]."
+ tmob << "[src]'s huge tail slithers past beside you!"
+ else
+ src << "You carefully step over [tmob]."
+ tmob << "[src] steps over you carefully!"
+ if(tmob.get_effective_size() > src.get_effective_size())
+ var/mob/living/carbon/human/M = tmob
+ if(0) // POLARISTODO istaur(src) && M.taur == 2)
+ src << "You jump over [tmob]'s thick tail."
+ tmob << "[src] bounds over your tail."
+ else
+ src << "You run between [tmob]'s legs."
+ tmob << "[src] runs between your legs."
+ return 1
+
+/**
+ * Handle bumping into someone without mutual help intent.
+ * Called from /mob/living/Bump()
+ * NW was here, adding even more options for stomping!
+ *
+ * @return false if normal code should continue, 1 to prevent normal code.
+ */
+/mob/living/proc/handle_micro_bump_other(var/mob/living/tmob)
+ ASSERT(istype(tmob)) // Baby don't hurt me
+
+ if(src.a_intent == I_DISARM && src.canmove && !src.buckled)
+ // If bigger than them by at least 0.75, move onto them and print message.
+ if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
+ now_pushing = 0
+ src.forceMove(tmob.loc)
+ tmob.Stun(4)
+
+ var/mob/living/carbon/human/M = src
+ if(0) // POLARISTODO istaur(src) && M.taur_style == 2)
+ src << "You carefully squish [tmob] under your tail!"
+ tmob << "[src] pins you under their tail!"
+ else
+ src << "You pin [tmob] beneath your foot!"
+ tmob << "[src] pins you beneath their foot!"
+ return 1
+
+ if(src.a_intent == I_HURT && src.canmove && !src.buckled)
+ if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
+ now_pushing = 0
+ src.forceMove(tmob.loc)
+ tmob.apply_damage(10, HALLOSS)
+
+ var/mob/living/carbon/human/M = src
+ if(0) // POLARISTODO istaur(src) && M.taur_style == 2)
+ src << "You steamroller over [tmob] with your heavy tail!"
+ tmob << "[src] ploughs you down mercilessly with their heavy tail!"
+ else
+ src << "You bring your foot down heavily upon [tmob]!"
+ tmob << "[src] steps carelessly on your body!"
+ return 1
+
+ if(src.a_intent == I_GRAB && src.canmove && !src.buckled)
+ if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
+ now_pushing = 0
+ src.forceMove(tmob.loc)
+
+ var/mob/living/carbon/human/M = src
+ if(istype(M) && !M.shoes)
+ // User is a human (capable of scooping) and not wearing shoes! Scoop into foot slot!
+ equip_to_slot_if_possible(tmob.get_scooped(M), slot_shoes, 0, 1)
+ if(0) // POLARISTODO M.taur == 2)
+ src << "You wrap up [tmob] with your powerful tail!"
+ tmob << "[src] binds you with their powerful tail!"
+ else
+ src << "You clench your toes around [tmob]'s body!"
+ tmob << "[src] grabs your body with their toes!"
+ else if(0) // POLARISTODO istaur(src) && M.taur_style == 2)
+ src << "You carefully squish [tmob] under your tail!"
+ tmob << "[src] pins you under their tail!"
+ else
+ src << "You pin [tmob] beneath your foot!"
+ tmob << "[src] pins you beneath their foot!"
+ return 1
diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm
new file mode 100644
index 0000000000..6e2510b28f
--- /dev/null
+++ b/code/modules/vore/resizing/sizegun_vr.dm
@@ -0,0 +1,76 @@
+//
+// Size Gun
+//
+
+/obj/item/weapon/gun/energy/sizegun
+ name = "shrink ray"
+ desc = "A highly advanced ray gun with two settings: Shrink and Grow. Warning: Do not insert into mouth."
+ icon = 'icons/obj/gun_vr.dmi'
+ icon_state = "sizegun-shrink100" // Someone can probably do better. -Ace
+ item_state = null //so the human update icon uses the icon_state instead
+ fire_sound = 'sound/weapons/wave.ogg'
+ charge_cost = 100
+ projectile_type = /obj/item/projectile/beam/shrinklaser
+ origin_tech = "redspace=1;bluespace=4"
+ modifystate = "sizegun-shrink"
+ self_recharge = 1
+ firemodes = list(
+ list(mode_name = "grow",
+ projectile_type = /obj/item/projectile/beam/growlaser,
+ modifystate = "sizegun-grow",
+ fire_sound = 'sound/weapons/pulse3.ogg'
+ ),
+ list(mode_name = "shrink",
+ projectile_type = /obj/item/projectile/beam/shrinklaser,
+ modifystate = "sizegun-shrink",
+ fire_sound = 'sound/weapons/wave.ogg'
+ ))
+
+//
+// Beams for size gun
+//
+
+/obj/item/projectile/beam/shrinklaser
+ name = "shrink beam"
+ icon_state = "laser"
+ nodamage = 1
+ damage = 0
+ check_armour = "laser"
+
+/obj/item/projectile/beam/shrinklaser/on_hit(var/atom/target, var/blocked = 0)
+ if(istype(target, /mob/living))
+ var/mob/living/M = target
+ switch(M.size_multiplier)
+ if(RESIZE_HUGE to INFINITY)
+ M.resize(RESIZE_BIG)
+ if(RESIZE_BIG to RESIZE_HUGE)
+ M.resize(RESIZE_NORMAL)
+ if(RESIZE_NORMAL to RESIZE_BIG)
+ M.resize(RESIZE_SMALL)
+ if((0 - INFINITY) to RESIZE_NORMAL)
+ M.resize(RESIZE_TINY)
+ M.update_icons()
+ return 1
+
+
+/obj/item/projectile/beam/growlaser
+ name = "growth beam"
+ icon_state = "bluelaser"
+ nodamage = 1
+ damage = 0
+ check_armour = "laser"
+
+/obj/item/projectile/beam/growlaser/on_hit(var/atom/target, var/blocked = 0)
+ if(istype(target, /mob/living))
+ var/mob/living/M = target
+ switch(M.size_multiplier)
+ if(RESIZE_BIG to RESIZE_HUGE)
+ M.resize(RESIZE_HUGE)
+ if(RESIZE_NORMAL to RESIZE_BIG)
+ M.resize(RESIZE_BIG)
+ if(RESIZE_SMALL to RESIZE_NORMAL)
+ M.resize(RESIZE_NORMAL)
+ if((0 - INFINITY) to RESIZE_TINY)
+ M.resize(RESIZE_SMALL)
+ M.update_icons()
+ return 1
diff --git a/icons/obj/gun_vr.dmi b/icons/obj/gun_vr.dmi
new file mode 100644
index 0000000000..f90f7b2a91
Binary files /dev/null and b/icons/obj/gun_vr.dmi differ
diff --git a/sound/weapons/gauss_shoot.ogg b/sound/weapons/gauss_shoot.ogg
new file mode 100644
index 0000000000..c9a4036b94
Binary files /dev/null and b/sound/weapons/gauss_shoot.ogg differ
diff --git a/vorestation.dme b/vorestation.dme
index 8fe9400a3f..e446ba7d88 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1200,6 +1200,7 @@
#include "code\modules\hydroponics\seed.dm"
#include "code\modules\hydroponics\seed_controller.dm"
#include "code\modules\hydroponics\seed_datums.dm"
+#include "code\modules\hydroponics\seed_datums_vr.dm"
#include "code\modules\hydroponics\seed_machines.dm"
#include "code\modules\hydroponics\seed_mobs.dm"
#include "code\modules\hydroponics\seed_packets.dm"
@@ -1668,6 +1669,7 @@
#include "code\modules\reagents\Chemistry-Readme.dm"
#include "code\modules\reagents\Chemistry-Reagents.dm"
#include "code\modules\reagents\Chemistry-Recipes.dm"
+#include "code\modules\reagents\Chemistry-Recipes_vr.dm"
#include "code\modules\reagents\reagent_containers.dm"
#include "code\modules\reagents\reagent_dispenser.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Core.dm"
@@ -1676,6 +1678,7 @@
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Medicine.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Other.dm"
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Toxins.dm"
+#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Vore_vr.dm"
#include "code\modules\reagents\dispenser\_defines.dm"
#include "code\modules\reagents\dispenser\cartridge.dm"
#include "code\modules\reagents\dispenser\cartridge_presets.dm"
@@ -1705,6 +1708,7 @@
#include "code\modules\reagents\reagent_containers\food\drinks\bottle\robot.dm"
#include "code\modules\reagents\reagent_containers\food\snacks\meat.dm"
#include "code\modules\reagents\reagent_containers\glass\bottle.dm"
+#include "code\modules\reagents\reagent_containers\glass\bottle_vr.dm"
#include "code\modules\reagents\reagent_containers\glass\bottle\robot.dm"
#include "code\modules\recycling\conveyor2.dm"
#include "code\modules\recycling\disposal-construction.dm"
@@ -1892,6 +1896,10 @@
#include "code\modules\vore\eating\vorehooks_vr.dm"
#include "code\modules\vore\eating\vorepanel_vr.dm"
#include "code\modules\vore\weight\fitness_machines_vr.dm"
+#include "code\modules\vore\resizing\grav_pull_vr.dm"
+#include "code\modules\vore\resizing\holder_micro_vr.dm"
+#include "code\modules\vore\resizing\resize_vr.dm"
+#include "code\modules\vore\resizing\sizegun_vr.dm"
#include "code\modules\xgm\xgm_gas_data.dm"
#include "code\modules\xgm\xgm_gas_mixture.dm"
#include "code\unit_tests\loadout_tests.dm"