diff --git a/code/game/objects/items/robot/robot_upgrades_vr.dm b/code/game/objects/items/robot/robot_upgrades_vr.dm
new file mode 100644
index 0000000000..80ca38113b
--- /dev/null
+++ b/code/game/objects/items/robot/robot_upgrades_vr.dm
@@ -0,0 +1,23 @@
+/*
+
+/obj/item/borg/upgrade/reset/action/proc/resetborg(var/mob/living/silicon/robot/R)
+ if(..()) return 0
+ R.uneq_all()
+ R.modtype = initial(R.modtype)
+ R.hands.icon_state = initial(R.hands.icon_state)
+ R.icon = 'icons/mob/robots.dmi'
+ R.pixel_x = initial(pixel_x)
+ R.pixel_y = initial(pixel_y)
+
+ R.notify_ai(ROBOT_NOTIFICATION_MODULE_RESET, R.module.name)
+ R.module.Reset(R)
+ qdel(R.module)
+ R.module = null
+ R.updatename("Default")
+*/
+
+//Make it so reset module doesn't bug up borgs. Not a huge problem, but should be added in before launch.
+
+//Could probably do
+//if(attempt_vr(src,"resetborg(var/mob/living/silicon/robot/R)",args)) return //VOREStation Code
+//or something like that
\ No newline at end of file
diff --git a/code/global_vr.dm b/code/global_vr.dm
new file mode 100644
index 0000000000..58936d9486
--- /dev/null
+++ b/code/global_vr.dm
@@ -0,0 +1,4 @@
+/hook/startup/proc/modules_vr()
+ robot_module_types += "Medihound"
+ robot_module_types += "K9"
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm
new file mode 100644
index 0000000000..3c58ec7442
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm
@@ -0,0 +1,284 @@
+/obj/item/weapon/dogborg/jaws/big
+ name = "combat jaws"
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "jaws"
+ desc = "The jaws of the law."
+ flags = CONDUCT
+ force = 10
+ throwforce = 0
+ hitsound = 'sound/weapons/bite.ogg'
+ attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
+ w_class = 3
+
+/obj/item/weapon/dogborg/jaws/small
+ name = "puppy jaws"
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "smalljaws"
+ desc = "The jaws of a small dog."
+ flags = CONDUCT
+ force = 5
+ throwforce = 0
+ hitsound = 'sound/weapons/bite.ogg'
+ attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
+ w_class = 3
+ var/emagged = 0
+
+/obj/item/weapon/dogborg/jaws/small/attack_self(mob/user)
+ var/mob/living/silicon/robot.R = user
+ if(R.emagged)
+ emagged = !emagged
+ if(emagged)
+ name = "combat jaws"
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "jaws"
+ desc = "The jaws of the law."
+ flags = CONDUCT
+ force = 10
+ throwforce = 0
+ hitsound = 'sound/weapons/bite.ogg'
+ attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
+ w_class = 3
+ else
+ name = "puppy jaws"
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "smalljaws"
+ desc = "The jaws of a small dog."
+ flags = CONDUCT
+ force = 5
+ throwforce = 0
+ hitsound = 'sound/weapons/bite.ogg'
+ attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
+ w_class = 3
+ update_icon()
+
+
+//Boop //New and improved, now a simple reagent sniffer.
+/obj/item/device/dogborg/boop_module
+ name = "boop module"
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "nose"
+ desc = "The BOOP module, a simple reagent and atmosphere sniffer."
+ flags = CONDUCT
+ force = 0
+ throwforce = 0
+ attack_verb = list("nuzzled", "nosed", "booped")
+ w_class = 1
+
+/obj/item/device/dogborg/boop_module/New()
+ ..()
+ flags |= NOBLUDGEON //No more attack messages
+
+/obj/item/device/dogborg/boop_module/attack_self(mob/user)
+ if (!( istype(user.loc, /turf) ))
+ return
+
+ var/datum/gas_mixture/environment = user.loc.return_air()
+
+ var/pressure = environment.return_pressure()
+ var/total_moles = environment.total_moles
+
+ user.visible_message("[user] sniffs the air.", "You sniff the air...")
+
+ user << "\blue Smells like:"
+ if(abs(pressure - ONE_ATMOSPHERE) < 10)
+ user << "\blue Pressure: [round(pressure,0.1)] kPa"
+ else
+ user << "\red Pressure: [round(pressure,0.1)] kPa"
+ if(total_moles)
+ for(var/g in environment.gas)
+ user << "\blue [gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]%"
+ user << "\blue Temperature: [round(environment.temperature-T0C,0.1)]°C ([round(environment.temperature,0.1)]K)"
+
+/obj/item/device/dogborg/boop_module/afterattack(obj/O, mob/user as mob, proximity)
+ if(!proximity)
+ return
+ if (user.stat)
+ return
+ if(!istype(O))
+ return
+
+ user.visible_message("[user] sniffs at \the [O.name].", "You sniff \the [O.name]...")
+
+ if(!isnull(O.reagents))
+ var/dat = ""
+ if(O.reagents.reagent_list.len > 0)
+ for (var/datum/reagent/R in O.reagents.reagent_list)
+ dat += "\n \t \blue [R]"
+
+ if(dat)
+ user << "\blue Your BOOP module indicates: [dat]"
+ else
+ user << "\blue No active chemical agents smelled in [O]."
+ else
+ user << "\blue No significant chemical agents smelled in [O]."
+
+ return
+
+
+//Delivery
+/*
+/obj/item/weapon/storage/bag/borgdelivery
+ name = "fetching storage"
+ desc = "Fetch the thing!"
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "dbag"
+ w_class = 5
+ max_w_class = 2
+ max_combined_w_class = 2
+ storage_slots = 1
+ collection_mode = 0
+ can_hold = list() // any
+ cant_hold = list(/obj/item/weapon/disk/nuclear)
+*/
+
+/obj/item/device/dogborg/dog_zapper //TODO
+ name = "paws of life"
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "defibpaddles0"
+ desc = "Zappy paws. For fixing cardiac arrest."
+ flags = CONDUCT
+ force = 0
+ throwforce = 0
+ hitsound = 'sound/weapons/bite.ogg'
+ attack_verb = list("batted", "pawed", "bopped", "whapped")
+ w_class = 1
+ var/charge = 0
+ var/charge_required = 1000
+ var/charge_per = 100
+ var/state = 0 //0 = Off, 1 = Charging, 2 = Ready
+
+ //[round(((world.realtime - src.disconnect_time) / 10) / 60)]
+
+/obj/item/device/dogborg/dog_zapper/attack_self(mob/user)
+ switch(state)
+ if(0) // Was off when clicked
+ if(charge < charge_required) //Turned on and now charging
+ state = 1
+ //TODO Change Icon
+ //TODO Start charging
+ user << "[name] now charging."
+ else //Turned on and was already charged
+ state = 2
+ user << "[name] now READY."
+ if(1) // Was charging when clicked
+ state = 0
+ //TODO Change Icon
+ user << "[name] now turned off."
+ if(2) // Was ready when clicked
+ state = 0
+ //TODO Change Icon
+ user << "[name] now turned off (fully charged)."
+/*
+/obj/item/device/dogborg/dog_zapper/proc/charge()
+ var/mob/living/silicon/robot.R = usr
+
+ do
+ R.cell.charge -= charge_per
+ charge += charge_per
+ sleep(1)
+ while(state = 1 && charge < charge_required && (R.cell.charge > (charge_required - charge)))
+
+ if(charge = charge_required)
+ usr << "[name] now READY."
+
+
+/obj/item/device/dogborg/dog_zapper/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity)
+*/
+//Tongue stuff
+/obj/item/device/dogborg/tongue
+ name = "synthetic tongue"
+ desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "synthtongue"
+ hitsound = 'sound/effects/attackblob.ogg'
+ var/emagged = 0
+
+/obj/item/device/dogborg/tongue/New()
+ ..()
+ flags |= NOBLUDGEON //No more attack messages
+
+/obj/item/device/dogborg/tongue/attack_self(mob/user)
+ var/mob/living/silicon/robot.R = user
+ if(R.emagged)
+ emagged = !emagged
+ if(emagged)
+ name = "hacked tongue of doom"
+ desc = "Your tongue has been upgraded successfully. Congratulations."
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "syndietongue"
+ else
+ name = "synthetic tongue"
+ desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "synthtongue"
+ update_icon()
+
+/obj/item/device/dogborg/tongue/afterattack(atom/target, mob/user, proximity)
+ if(!proximity)
+ return
+ if(user.client && (target in user.client.screen))
+ user << "You need to take that [target.name] off before cleaning it!"
+ else if(istype(target,/obj/effect/decal/cleanable))
+ user.visible_message("[user] begins to lick off \the [target.name].", "You begin to lick off \the [target.name]...")
+ if(do_after (user, 50))
+ user << "You finish licking off \the [target.name]."
+ del(target)
+ var/mob/living/silicon/robot.R = user
+ R.cell.charge = R.cell.charge + 50
+ else if(istype(target,/obj/item))
+ if(istype(target,/obj/item/trash))
+ user.visible_message("[user] nibbles away at \the [target.name].", "You begin to nibble away at \the [target.name]...")
+ if(do_after (user, 50))
+ user.visible_message("[user] finishes eating \the [target.name].", "You finish eating \the [target.name].")
+ user << "You finish off \the [target.name]."
+ del(target)
+ var/mob/living/silicon/robot.R = user
+ R.cell.charge = R.cell.charge + 250
+ return
+ if(istype(target,/obj/item/weapon/cell))
+ user.visible_message("[user] begins cramming \the [target.name] down its throat.", "You begin cramming \the [target.name] down your throat...")
+ if(do_after (user, 50))
+ user.visible_message("[user] finishes gulping down \the [target.name].", "You finish swallowing \the [target.name].")
+ user << "You finish off \the [target.name], and gain some charge!"
+ var/mob/living/silicon/robot.R = user
+ var/obj/item/weapon/cell.C = target
+ R.cell.charge = R.cell.charge + (C.maxcharge / 3)
+ del(target)
+ return
+ user.visible_message("[user] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...")
+ if(do_after (user, 50))
+ user << "You clean \the [target.name]."
+ var/obj/effect/decal/cleanable/C = locate() in target
+ del(C)
+ target.clean_blood()
+ else if(ishuman(target))
+ if(src.emagged)
+ var/mob/living/silicon/robot.R = user
+ var/mob/living/L = target
+ if(R.cell.charge <= 666)
+ return
+ L.Stun(4) // normal stunbaton is force 7 gimme a break good sir!
+ L.Weaken(4)
+ L.apply_effect(STUTTER, 4)
+ L.visible_message("[user] has shocked [L] with its tongue!", \
+ "[user] has shocked you with its tongue! You can feel the betrayal.")
+ playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+ R.cell.charge = R.cell.charge - 666
+ else
+ user.visible_message("\the [user] affectionally licks all over \the [target]'s face!", "You affectionally lick all over \the [target]'s face!")
+ playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
+ return
+ else if(istype(target, /obj/structure/window))
+ user.visible_message("[user] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...")
+ if(do_after (user, 50))
+ user << "You clean \the [target.name]."
+ target.color = initial(target.color)
+ //target.SetOpacity(initial(target.opacity)) //Apparantly this doesn't work?
+ else
+ user.visible_message("[user] begins to lick \the [target.name] clean...", "You begin to lick \the [target.name] clean...")
+ if(do_after (user, 50))
+ user << "You clean \the [target.name]."
+ var/obj/effect/decal/cleanable/C = locate() in target
+ del(C)
+ target.clean_blood()
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm
new file mode 100644
index 0000000000..1d2746bdec
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm
@@ -0,0 +1,427 @@
+//Sleeper
+/obj/item/device/dogborg/sleeper
+ name = "Medbelly"
+ desc = "Equipment for medical hound. A mounted sleeper that stabilizes patients and can inject reagents in the borg's reserves."
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "sleeper"
+ w_class = 1
+ var/mob/living/carbon/patient = null
+ var/mob/living/silicon/robot/hound = null
+ var/inject_amount = 10
+ var/min_health = -100
+ var/cleaning = 0
+ var/patient_laststat = null
+ var/mob_energy = 30000 //Energy gained from digesting mobs (including PCs)
+ var/list/injection_chems = list("dexalin", "bicaridine", "kelotane","anti_toxin", "alkysine", "imidazoline", "spaceacillin", "paracetamol") //The borg is able to heal every damage type. As a nerf, they use 750 charge per injection.
+ var/eject_port = "ingestion"
+ var/list/items_preserved = list()
+
+/obj/item/device/dogborg/sleeper/New()
+ ..()
+ flags |= NOBLUDGEON //No more attack messages
+
+/obj/item/device/dogborg/sleeper/Exit(atom/movable/O)
+ return 0
+
+/obj/item/device/dogborg/sleeper/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity)
+ hound = loc
+ if(!proximity)
+ return
+ if(!ishuman(target))
+ return
+ if(target.buckled)
+ user << "\red The user is buckled and can not be put into your [src.name]."
+ return
+ if(patient)
+ user << "\red Your [src.name] is already occupied."
+ return
+ user.visible_message("[hound.name] is ingesting [target.name] into their [src.name].", "You start ingesting [target] into your [src]...")
+ if(!patient && ishuman(target) && !target.buckled && do_after (user, 50))
+
+ if(!proximity) return //If they moved away, you can't eat them.
+
+ if(patient) return //If you try to eat two people at once, you can only eat one.
+
+ else //If you don't have someone in you, proceed.
+ target.forceMove(src)
+ target.reset_view(src)
+ update_patient()
+ processing_objects.Add(src)
+ user.visible_message("[hound.name]'s medical pod lights up as [target.name] slips inside into their [src.name].", "Your medical pod lights up as [target] slips into your [src]. Life support functions engaged.")
+ message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "JMP" : "null"])")
+ playsound(hound, 'sound/vore/gulp.ogg', 100, 1) //POLARISTODO
+
+/obj/item/device/dogborg/sleeper/proc/go_out(var/target)
+ hound = src.loc
+ if(length(contents) > 0)
+ hound.visible_message("[hound.name] empties out their contents via their [eject_port] port.", "You empty your contents via your [eject_port] port.")
+ if(target)
+ if(ishuman(target))
+ var/mob/living/carbon/human/person = target
+ person.forceMove(get_turf(src))
+ person.reset_view()
+ else
+ var/obj/T = target
+ T.loc = hound.loc
+ else
+ for(var/C in contents)
+ if(ishuman(C))
+ var/mob/living/carbon/human/person = C
+ person.forceMove(get_turf(src))
+ person.reset_view()
+ else
+ var/obj/T = C
+ T.loc = hound.loc
+ items_preserved.Cut()
+ cleaning = 0
+ playsound(loc, 'sound/effects/splat.ogg', 50, 1)
+ update_patient()
+ else //You clicked eject with nothing in you, let's just reset stuff to be sure.
+ items_preserved.Cut()
+ cleaning = 0
+ update_patient()
+
+/obj/item/device/dogborg/sleeper/proc/drain(var/amt = 3) //Slightly reduced cost (before, it was always injecting inaprov)
+ hound.cell.charge = hound.cell.charge - amt
+
+/obj/item/device/dogborg/sleeper/attack_self(mob/user)
+ if(..())
+ return
+ sleeperUI(user)
+
+/obj/item/device/dogborg/sleeper/proc/sleeperUI(mob/user)
+ var/dat
+ dat += "
Injector
"
+
+ if(patient && !(patient.stat & DEAD)) //Why inject dead people with innaprov? Dundonuffin in Bay.
+ dat += "Inject Inaprovaline"
+ else
+ dat += "Inject Inaprovaline"
+ if(patient && patient.health > min_health)
+ for(var/re in injection_chems)
+ var/datum/reagent/C = chemical_reagents_list[re]
+ if(C)
+ dat += "
Inject [C.name]"
+ else
+ for(var/re in injection_chems)
+ var/datum/reagent/C = chemical_reagents_list[re]
+ if(C)
+ dat += "
Inject [C.name]"
+
+ dat += "Sleeper Status
"
+ dat += "Refresh"
+ dat += "Eject All"
+ dat += "Eject port: [eject_port]"
+ if(!cleaning)
+ dat += "Self-Clean"
+ else
+ dat += "Self-Clean"
+
+ dat += ""
+
+ //Cleaning and there are still un-preserved items
+ if(cleaning && length(contents - items_preserved))
+ dat += "
Self-cleaning mode. [length(contents - items_preserved)] object(s) remaining."
+
+ //There are no items to be processed other than un-preserved items
+ else if(cleaning && length(items_preserved))
+ dat += "
Self-cleaning done. Eject remaining objects now."
+
+ //Preserved items count when the list is populated
+ if(length(items_preserved))
+ dat += "
[length(items_preserved)] uncleanable object(s)."
+
+ if(!patient)
+ dat += "Sleeper Unoccupied"
+ else
+ dat += "[patient.name] => "
+
+ switch(patient.stat)
+ if(0)
+ dat += "
Conscious"
+ if(1)
+ dat += "
Unconscious"
+ else
+ dat += "
DEAD"
+
+ dat += text("[]\t-Pulse, bpm: []
", (patient.pulse == PULSE_NONE || patient.pulse == PULSE_THREADY ? "
" : ""), patient.get_pulse(GETPULSE_TOOL))
+ dat += text("[]\t-Overall Health %: []
", (patient.health > 0 ? "" : ""), round(patient.health))
+ dat += text("[]\t-Brute Damage %: []
", (patient.getBruteLoss() < 60 ? "" : ""), patient.getBruteLoss())
+ dat += text("[]\t-Respiratory Damage %: []
", (patient.getOxyLoss() < 60 ? "" : ""), patient.getOxyLoss())
+ dat += text("[]\t-Toxin Content %: []
", (patient.getToxLoss() < 60 ? "" : ""), patient.getToxLoss())
+ dat += text("[]\t-Burn Severity %: []
", (patient.getFireLoss() < 60 ? "" : ""), patient.getFireLoss())
+
+ if(round(patient.paralysis / 4) >= 1)
+ dat += text("
Patient paralyzed for: []
", round(patient.paralysis / 4) >= 1 ? "[round(patient.paralysis / 4)] seconds" : "None")
+ if(patient.getBrainLoss())
+ dat += "Significant brain damage detected.
"
+ if(patient.getCloneLoss())
+ dat += "Patient may be improperly cloned.
"
+ if(patient.reagents.reagent_list.len)
+ for(var/datum/reagent/R in patient.reagents.reagent_list)
+ dat += "[R.name]:
[round(R.volume, 0.1)] units
"
+ dat += " "
+
+ var/datum/browser/popup = new(user, "sleeper", "Sleeper Console", 520, 540) //Set up the popup browser window
+ popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
+ popup.set_content(dat)
+ popup.open()
+ return
+
+/obj/item/device/dogborg/sleeper/Topic(href, href_list)
+ if(..() || usr == patient)
+ return
+ usr.set_machine(src)
+ if(href_list["refresh"])
+ update_patient()
+ src.updateUsrDialog()
+ sleeperUI(usr)
+ return
+ if(href_list["eject"])
+ go_out()
+ sleeperUI(usr)
+ return
+ if(href_list["clean"])
+ if(!cleaning)
+ var/confirm = alert(usr, "You are about to engage self-cleaning mode. This will fill your [src] with caustic enzymes to remove any objects or biomatter, and convert them into energy. Are you sure?", "Confirmation", "Self-Clean", "Cancel")
+ if(confirm == "Self-Clean")
+ cleaning = 1
+ drain(500)
+ processing_objects.Add(src)
+ sleeperUI(usr)
+ if(patient)
+ patient << "[hound.name]'s [src.name] fills with caustic enzymes around you!"
+ return
+ if(cleaning)
+ sleeperUI(usr)
+ return
+ if(href_list["port"])
+ switch(eject_port)
+ if("ingestion")
+ eject_port = "disposal"
+ if("disposal")
+ eject_port = "ingestion"
+ sleeperUI(usr)
+ return
+
+ if(patient && !(patient.stat & DEAD)) //What is bitwise NOT? ... Thought it was tilde.
+ if(href_list["inject"] == "inaprovaline" || patient.health > min_health)
+ inject_chem(usr, href_list["inject"])
+ else
+ usr << "ERROR: Subject is not in stable condition for injections."
+ else
+ usr << "ERROR: Subject cannot metabolise chemicals."
+
+ src.updateUsrDialog()
+ sleeperUI(usr) //Needs a callback to boop the page to refresh.
+ return
+
+/obj/item/device/dogborg/sleeper/proc/inject_chem(mob/user, chem)
+ if(patient && patient.reagents)
+ if(chem in injection_chems + "inaprovaline")
+ if(hound.cell.charge < 800) //This is so borgs don't kill themselves with it.
+ hound << "You don't have enough power to synthesize fluids."
+ return
+ else if(patient.reagents.get_reagent_amount(chem) + 10 >= 20) //Preventing people from accidentally killing themselves by trying to inject too many chemicals!
+ hound << "Your stomach is currently too full of fluids to secrete more fluids of this kind."
+ else if(patient.reagents.get_reagent_amount(chem) + 10 <= 20) //No overdoses for you
+ patient.reagents.add_reagent(chem, inject_amount)
+ drain(750) //-750 charge per injection
+ var/units = round(patient.reagents.get_reagent_amount(chem))
+ hound << "Injecting [units] unit\s of [chemical_reagents_list[chem]] into occupant." //If they were immersed, the reagents wouldn't leave with them.
+
+//For if the dogborg's existing patient uh, doesn't make it.
+/obj/item/device/dogborg/sleeper/proc/update_patient()
+
+ //Well, we HAD one, what happened to them?
+ if(patient in contents)
+ if(patient_laststat != patient.stat)
+ if(patient.stat & DEAD)
+ hound.sleeper_r = 1
+ hound.sleeper_g = 0
+ patient_laststat = patient.stat
+ else
+ hound.sleeper_r = 0
+ hound.sleeper_g = 1
+ patient_laststat = patient.stat
+ //Update icon
+ hound.updateicon()
+ //Return original patient
+ return(patient)
+
+ //Check for a new patient
+ else
+ for(var/mob/living/carbon/human/C in contents)
+ patient = C
+ if(patient.stat & DEAD)
+ hound.sleeper_r = 1
+ hound.sleeper_g = 0
+ patient_laststat = patient.stat
+ else
+ hound.sleeper_r = 0
+ hound.sleeper_g = 1
+ patient_laststat = patient.stat
+ //Update icon and return new patient
+ hound.updateicon()
+ return(C)
+
+ //Cleaning looks better with red on, even with nobody in it
+ if(cleaning && !patient)
+ hound.sleeper_r = 1
+ hound.sleeper_g = 0
+
+ //Couldn't find anyone, and not cleaning
+ else if(!cleaning && !patient)
+ hound.sleeper_r = 0
+ hound.sleeper_g = 0
+
+ patient_laststat = null
+ patient = null
+ hound.updateicon()
+ return
+
+//Gurgleborg process
+/obj/item/device/dogborg/sleeper/proc/clean_cycle()
+
+ //Sanity? Maybe not required. More like if indigestible person OOC escapes.
+ for(var/I in items_preserved)
+ if(!(I in contents))
+ items_preserved -= I
+
+ var/list/touchable_items = contents - items_preserved
+
+ //Belly is entirely empty
+ if(!length(contents))
+ hound << "Your [src.name] is now clean. Ending self-cleaning cycle."
+ cleaning = 0
+ update_patient()
+ return
+
+ if(prob(10))
+ var/churnsound = pick(
+ 'sound/vore/digest1.ogg',
+ 'sound/vore/digest2.ogg',
+ 'sound/vore/digest3.ogg',
+ 'sound/vore/digest4.ogg',
+ 'sound/vore/digest5.ogg',
+ 'sound/vore/digest6.ogg',
+ 'sound/vore/digest7.ogg',
+ 'sound/vore/digest8.ogg',
+ 'sound/vore/digest9.ogg',
+ 'sound/vore/digest10.ogg',
+ 'sound/vore/digest11.ogg',
+ 'sound/vore/digest12.ogg')
+ for(var/mob/outhearer in range(1,hound))
+ outhearer << sound(churnsound)
+ for(var/mob/inhearer in contents)
+ inhearer << sound(churnsound)
+ //If the timing is right, and there are items to be touched
+ if(air_master.current_cycle%2==1 && length(touchable_items))
+
+ //Burn all the mobs or add them to the exclusion list
+ for(var/mob/living/carbon/human/T in (touchable_items))
+ if((T.status_flags & GODMODE) || !T.digestable)
+ src.items_preserved += T
+ else
+ T.adjustBruteLoss(2)
+ T.adjustFireLoss(3)
+ src.update_patient()
+
+ //Pick a random item to deal with (if there are any)
+ var/atom/target = pick(touchable_items)
+
+ //Handle the target being a mob
+ if(ishuman(target))
+ var/mob/living/carbon/human/T = target
+
+ //Mob is now dead
+ if(T.stat & DEAD)
+ message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "JMP" : "null"])")
+ hound << "You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems."
+ T << "You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems."
+ src.drain(-30000) //Fueeeeellll
+ var/deathsound = pick(
+ 'sound/vore/death1.ogg',
+ 'sound/vore/death2.ogg',
+ 'sound/vore/death3.ogg',
+ 'sound/vore/death4.ogg',
+ 'sound/vore/death5.ogg',
+ 'sound/vore/death6.ogg',
+ 'sound/vore/death7.ogg',
+ 'sound/vore/death8.ogg',
+ 'sound/vore/death9.ogg',
+ 'sound/vore/death10.ogg')
+ for(var/mob/hearer in range(1,src.hound))
+ hearer << deathsound
+ T << deathsound
+ //Spill(T) //TODOPOLARIS
+ T.Del()
+ src.update_patient()
+
+ //Handle the target being anything but a /mob/living/carbon/human
+ else
+ var/obj/T = target
+
+ //If the object is in the items_preserved global list //POLARISTODO
+
+ if(T.type in important_items)
+ src.items_preserved += T
+
+ //If the object is not one to preserve
+ else
+ //Special case for PDAs as they are dumb. TODO fix Del on PDAs to be less dumb.
+ if (istype(T, /obj/item/device/pda))
+ var/obj/item/device/pda/PDA = T
+ if (PDA.id)
+ PDA.id.loc = src
+ PDA.id = null
+ T.Del()
+
+ //Special case for IDs to make them digested
+ //else if (istype(T, /obj/item/weapon/card/id))
+ //var/obj/item/weapon/card/id/ID = T
+ //ID.digest() //Need the digest proc, first.
+
+ //Anything not perserved, PDA, or ID
+ else
+ //Spill(T) //Needs the spill proc to be added
+ T.Del()
+ src.update_patient()
+ src.hound.cell.charge += 10
+ return
+
+/obj/item/device/dogborg/sleeper/process()
+
+ if(cleaning) //We're cleaning, return early after calling this as we don't care about the patient.
+ src.clean_cycle()
+ return
+
+ if(patient) //We're caring for the patient. Medical emergency! Or endo scene.
+ update_patient()
+ if(patient.health < 0)
+ patient.adjustOxyLoss(-1) //Heal some oxygen damage if they're in critical condition
+ patient.updatehealth()
+ patient.AdjustStunned(-4)
+ patient.AdjustWeakened(-4)
+ src.drain()
+ if((patient.reagents.get_reagent_amount("inaprovaline") < 5) && (patient.health < patient.maxHealth)) //Stop pumping full HP people full of drugs. Don't heal people you're digesting, meanie.
+ patient.reagents.add_reagent("inaprovaline", 5)
+ return
+
+ if(!patient && !cleaning) //We think we're done working.
+ if(!update_patient()) //One last try to find someone
+ processing_objects.Remove(src)
+ return
+
+/mob/living/silicon/robot
+ var/sleeper_g
+ var/sleeper_r
+
+/obj/item/device/dogborg/sleeper/K9 //The K9 portabrig
+ name = "Brig-Belly"
+ desc = "Equipment for a K9 unit. A mounted portable-brig that holds criminals."
+ icon = 'icons/mob/dogborg_vr.dmi'
+ icon_state = "sleeper"
+ inject_amount = 10
+ min_health = -100
+ injection_chems = null //So they don't have all the same chems as the medihound!
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot_modules_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules_vr.dm
new file mode 100644
index 0000000000..e6d298cee2
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/robot_modules_vr.dm
@@ -0,0 +1,71 @@
+/hook/startup/proc/robot_modules_vr()
+ robot_modules["Medihound"] = /obj/item/weapon/robot_module/medihound
+ robot_modules["K9"] = /obj/item/weapon/robot_module/knine
+ return 1
+
+
+/obj/item/weapon/robot_module/knine
+ name = "k9 robot module"
+ sprites = list("K9 hound" = "k9")
+ channels = list("Security" = 1)
+ networks = list(NETWORK_SECURITY)
+ can_be_pushed = 0
+
+/obj/item/weapon/robot_module/knine/New(var/mob/living/silicon/robot/R)
+ src.modules += new /obj/item/device/flash(src)
+ src.modules += new /obj/item/weapon/handcuffs/cyborg(src) //You need cuffs to be a proper sec borg!
+ src.modules += new /obj/item/weapon/dogborg/jaws/big(src) //In case there's some kind of hostile mob.
+ src.modules += new /obj/item/weapon/melee/baton/robot(src) //Since the pounce module refused to work, they get a stunbaton instead.
+ src.modules += new /obj/item/device/dogborg/boop_module(src) //Boop people on the nose.
+ src.modules += new /obj/item/device/dogborg/tongue(src) //This is so they can clean up bloody evidence after it's examined, and so they can lick crew.
+ src.modules += new /obj/item/taperoll/police(src) //Block out crime scenes.
+ src.modules += new /obj/item/device/dogborg/sleeper/K9(src) //Eat criminals. Bring them to the brig.
+ src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg(src) //They /are/ a security borg, after all.
+ src.modules += new /obj/item/borg/sight/hud/sec(src) //Security hud to see criminals.
+ src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src) //Emag. Not a big problem.
+ R.icon = 'icons/mob/widerobot_vr.dmi'
+ R.hands.icon = 'icons/mob/screen1_robot_vr.dmi'
+ R.icon_state = "k9"
+ R.pixel_x = -16
+ ..()
+
+/obj/item/weapon/robot_module/knine/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
+ var/obj/item/device/flash/F = locate() in src.modules
+ if(F.broken)
+ F.broken = 0
+ F.times_used = 0
+ F.icon_state = "flash"
+ else if(F.times_used)
+ F.times_used--
+ var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in src.modules
+ if(T.power_supply.charge < T.power_supply.maxcharge)
+ T.power_supply.give(T.charge_cost * amount)
+ T.update_icon()
+ else
+ T.charge_tick = 0
+ var/obj/item/weapon/melee/baton/robot/B = locate() in src.modules
+ if(B && B.bcell)
+ B.bcell.give(amount)
+
+
+/obj/item/weapon/robot_module/medihound
+ name = "MediHound module"
+ channels = list("Medical" = 1)
+ networks = list(NETWORK_MEDICAL)
+ can_be_pushed = 0
+ sprites = list("Medical Hound" = "medihound")
+
+/obj/item/weapon/robot_module/medihound/New(var/mob/living/silicon/robot/R)
+ src.modules += new /obj/item/weapon/dogborg/jaws/small(src) //In case a patient is being attacked by carp.
+ src.modules += new /obj/item/device/dogborg/boop_module(src) //Boop the crew.
+ src.modules += new /obj/item/device/dogborg/tongue(src) //Clean up bloody items by licking them, and eat rubbish for minor energy.
+ src.modules += new /obj/item/device/healthanalyzer(src) // See who's hurt specificially.
+ src.modules += new /obj/item/device/dogborg/sleeper(src) //So they can nom people and heal them
+ src.modules += new /obj/item/borg/sight/hud/med(src) //See who's hurt generally.
+ src.modules += new /obj/item/weapon/extinguisher/mini(src) //So they can put burning patients out.
+ src.modules += new /obj/item/weapon/reagent_containers/syringe(src) //In case the chemist is nice!
+ R.icon = 'icons/mob/widerobot_vr.dmi'
+ R.hands.icon = 'icons/mob/screen1_robot_vr.dmi'
+ R.icon_state = "medihound"
+ R.pixel_x = -16
+ ..()
\ No newline at end of file
diff --git a/icons/mob/dogborg_vr.dmi b/icons/mob/dogborg_vr.dmi
new file mode 100644
index 0000000000..ea5a095bb9
Binary files /dev/null and b/icons/mob/dogborg_vr.dmi differ
diff --git a/icons/mob/screen1_robot_vr.dmi b/icons/mob/screen1_robot_vr.dmi
new file mode 100644
index 0000000000..310df85058
Binary files /dev/null and b/icons/mob/screen1_robot_vr.dmi differ
diff --git a/icons/mob/widerobot_vr.dmi b/icons/mob/widerobot_vr.dmi
new file mode 100644
index 0000000000..096d18c948
Binary files /dev/null and b/icons/mob/widerobot_vr.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 6df9398b99..0085f19409 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -13,6 +13,7 @@
#include "code\_macros.dm"
#include "code\_unit_tests.dm"
#include "code\global.dm"
+#include "code\global_vr.dm"
#include "code\hub.dm"
#include "code\names.dm"
#include "code\stylesheet.dm"
@@ -651,6 +652,7 @@
#include "code\game\objects\items\robot\robot_items.dm"
#include "code\game\objects\items\robot\robot_parts.dm"
#include "code\game\objects\items\robot\robot_upgrades.dm"
+#include "code\game\objects\items\robot\robot_upgrades_vr.dm"
#include "code\game\objects\items\stacks\matter_synth.dm"
#include "code\game\objects\items\stacks\medical.dm"
#include "code\game\objects\items\stacks\nanopaste.dm"
@@ -1435,8 +1437,11 @@
#include "code\modules\mob\living\silicon\robot\robot_damage.dm"
#include "code\modules\mob\living\silicon\robot\robot_items.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
+#include "code\modules\mob\living\silicon\robot\robot_modules_vr.dm"
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
#include "code\modules\mob\living\silicon\robot\syndicate.dm"
+#include "code\modules\mob\living\silicon\robot\dogborg\dog_modules_vr.dm"
+#include "code\modules\mob\living\silicon\robot\dogborg\dog_sleeper_vr.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_console.dm"