diff --git a/code/game/objects/random/misc_vr.dm b/code/game/objects/random/misc_vr.dm
index 21ca60771a..3f2644348d 100644
--- a/code/game/objects/random/misc_vr.dm
+++ b/code/game/objects/random/misc_vr.dm
@@ -114,6 +114,7 @@
prob(30);/obj/item/weapon/aliencoin/gold,
prob(20);/obj/item/weapon/aliencoin/phoron,
prob(5);/obj/item/capture_crystal,
+ prob(5);/obj/random/mouseray,
prob(5);/obj/item/device/perfect_tele,
prob(5);/obj/item/weapon/bluespace_harpoon,
prob(1);/obj/item/device/paicard,
diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm
index 4de01de0b4..f1ee401884 100644
--- a/code/game/objects/structures/trash_pile_vr.dm
+++ b/code/game/objects/structures/trash_pile_vr.dm
@@ -25,7 +25,8 @@
/obj/item/weapon/gun/projectile/pirate,
/obj/item/clothing/accessory/permit/gun,
/obj/item/weapon/gun/projectile/dartgun,
- /obj/item/clothing/gloves/black/bloodletter
+ /obj/item/clothing/gloves/black/bloodletter,
+ /obj/item/weapon/gun/energy/mouseray/metamorphosis
)
var/global/list/allocated_gamma = list()
@@ -269,7 +270,8 @@
prob(1);/obj/item/weapon/storage/secure/briefcase/trashmoney,
prob(1);/obj/item/device/survivalcapsule/popcabin,
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid,
- prob(1);/obj/item/capture_crystal)
+ prob(1);/obj/item/capture_crystal,
+ prob(1);/obj/item/weapon/gun/energy/mouseray)
var/obj/item/I = new path()
return I
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 1182dcf34b..6356bfb7b3 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -72,6 +72,8 @@
handle_vision()
+ handle_tf_holder() //VOREStation Addition
+
/mob/living/proc/handle_breathing()
return
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index bf23a03e68..e0f7d9a14b 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -32,6 +32,28 @@
nest = null
if(buckled)
buckled.unbuckle_mob(src, TRUE)
+ //VOREStation Addition Start
+ if(tf_mob_holder && tf_mob_holder.loc == src)
+ tf_mob_holder.ckey = ckey
+ if(isbelly(loc))
+ tf_mob_holder.loc = loc
+ tf_mob_holder.forceMove(loc)
+ else
+ var/turf/get_dat_turf = get_turf(src)
+ tf_mob_holder.loc = get_dat_turf
+ tf_mob_holder.forceMove(get_dat_turf)
+ QDEL_LIST_NULL(tf_mob_holder.vore_organs)
+ tf_mob_holder.vore_organs = list()
+ for(var/obj/belly/B as anything in vore_organs)
+ B.loc = tf_mob_holder
+ B.forceMove(tf_mob_holder)
+ B.owner = tf_mob_holder
+ tf_mob_holder.vore_organs |= B
+ vore_organs -= B
+
+ if(tf_mob_holder)
+ tf_mob_holder = null
+ //VOREStation Addition End
qdel(selected_image)
QDEL_NULL(vorePanel) //VOREStation Add
@@ -39,7 +61,6 @@
temp_language_sources = null //VOREStation Add
temp_languages = null //VOREStation Add
-
if(LAZYLEN(organs))
organs_by_name.Cut()
while(organs.len)
@@ -179,6 +200,13 @@
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
+ //VOREStation Additon Start
+ if(tf_mob_holder && tf_mob_holder.loc == src)
+ var/dmgmultiplier = tf_mob_holder.maxHealth / maxHealth
+ dmgmultiplier *= amount
+ tf_mob_holder.adjustBruteLoss(dmgmultiplier)
+ //VOREStation Additon End
+
bruteloss = min(max(bruteloss + amount, 0),(getMaxHealth()*2))
updatehealth()
@@ -252,7 +280,12 @@
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
amount *= M.incoming_healing_percent
-
+ //VOREStation Additon Start
+ if(tf_mob_holder && tf_mob_holder.loc == src)
+ var/dmgmultiplier = tf_mob_holder.maxHealth / maxHealth
+ dmgmultiplier *= amount
+ tf_mob_holder.adjustFireLoss(dmgmultiplier)
+ //VOREStation Additon End
fireloss = min(max(fireloss + amount, 0),(getMaxHealth()*2))
updatehealth()
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 94ff5ac52e..c4f52b6a1b 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -379,7 +379,7 @@
droplimb(0, DROPLIMB_EDGE)
else if(spread_dam && owner && parent && (brute_overflow || burn_overflow) && (brute_overflow >= 5 || burn_overflow >= 5) && !permutation) //No infinite damage loops.
var/brute_third = brute_overflow * 0.33
- var/burn_third = burn_overflow * 0.33
+ var/burn_third = burn_overflow * 0.33
if(children && children.len)
var/brute_on_children = brute_third / children.len
var/burn_on_children = burn_third / children.len
@@ -1064,6 +1064,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if((status & ORGAN_BROKEN) || cannot_break)
return
+<<<<<<< HEAD
if(owner)
//CHOMPEdit Begin
owner.custom_pain(pick(\
@@ -1073,7 +1074,16 @@ Note that amputating the affected organ does in fact remove the infection from t
//CHOMPEdit End
jostle_bone()
if(organ_can_feel_pain() && !isbelly(owner.loc))
+=======
+ if(owner) //VOREStation Edit Start
+ if(organ_can_feel_pain() && !isbelly(owner.loc) && !isliving(owner.loc))
+ owner.visible_message(\
+ "You hear a loud cracking sound coming from \the [owner].",\
+ "Something feels like it shattered in your [name]!",\
+ "You hear a sickening crack.")
+>>>>>>> 9b7e3a34f6... Merge pull request #13294 from Very-Soft/mouseray
owner.emote("scream")
+ jostle_bone() //VOREStation Edit End
playsound(src, "fracture", 10, 1, -2)
status |= ORGAN_BROKEN
diff --git a/code/modules/vore/mouseray.dm b/code/modules/vore/mouseray.dm
new file mode 100644
index 0000000000..4941a0c167
--- /dev/null
+++ b/code/modules/vore/mouseray.dm
@@ -0,0 +1,456 @@
+/obj/item/weapon/gun/energy/mouseray
+ name = "mouse ray"
+ desc = "A mysterious looking ray gun..."
+ icon = 'icons/obj/mouseray.dmi'
+ icon_state = "mouseray"
+ item_state = "mouseray"
+ item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_guns_vr.dmi')
+ fire_sound = 'sound/weapons/wave.ogg'
+ charge_cost = 240
+ projectile_type = /obj/item/projectile/beam/mouselaser
+ origin_tech = list(TECH_BLUESPACE = 4)
+ battery_lock = 1
+ firemodes = list()
+ var/tf_type = /mob/living/simple_mob/animal/passive/mouse //This type is what kind of mob it will try to turn people into!
+ var/cooldown = 0 //automatically set when used
+ var/cooldown_time = 15 SECONDS //the amount of time between shots
+ var/tf_admin_pref_override = FALSE //Overrides pref checks
+ var/tf_allow_select = FALSE //Toggles if the gun is able to pick between things in the 'tf_possible_types' variable
+ var/tf_possible_types = list( //The different types of mob the gun can pick between
+ "mouse" = /mob/living/simple_mob/animal/passive/mouse,
+ "rat" = /mob/living/simple_mob/animal/passive/mouse/rat,
+ "dust jumper" = /mob/living/simple_mob/vore/alienanimals/dustjumper
+ )
+
+/obj/item/weapon/gun/energy/mouseray/attack_self(mob/user)
+ . = ..()
+ if(tf_allow_select)
+ pick_type()
+
+/obj/item/weapon/gun/energy/mouseray/proc/pick_type()
+ var/choice = tgui_input_list(usr, "Select a type to turn things into.", "[src.name]", tf_possible_types)
+ if(!choice)
+ return
+ tf_type = tf_possible_types[choice]
+ to_chat(usr, "You selected [choice].")
+
+/obj/item/weapon/gun/energy/mouseray/Fire(atom/target, mob/living/user, clickparams, pointblank, reflex)
+ if(world.time < cooldown)
+ to_chat(usr, "\The [src] isn't ready yet.")
+ return
+ . = ..()
+
+/obj/item/weapon/gun/energy/mouseray/Fire_userless(atom/target)
+ if(world.time < cooldown)
+ return
+ . = ..()
+
+/obj/item/weapon/gun/energy/mouseray/consume_next_projectile()
+ . = ..()
+ var/obj/item/projectile/beam/mouselaser/G = .
+ cooldown = world.time + cooldown_time
+ if(tf_type)
+ G.tf_type = tf_type
+ if(tf_admin_pref_override)
+ G.tf_admin_pref_override = tf_admin_pref_override
+
+/obj/item/weapon/gun/energy/mouseray/update_icon()
+ if(charge_meter)
+ var/ratio = power_supply.charge / power_supply.maxcharge
+
+ //make sure that rounding down will not give us the empty state even if we have charge for a shot left.
+ if(power_supply.charge < charge_cost)
+ ratio = 0
+ else
+ ratio = max(round(ratio, 0.25) * 100, 25)
+
+ icon_state = "[initial(icon_state)][ratio]"
+
+/obj/item/projectile/beam/mouselaser
+ name = "metamorphosis beam"
+ icon_state = "xray"
+ nodamage = 1
+ damage = 0
+ range = 7
+ check_armour = "laser"
+ can_miss = FALSE
+ var/tf_type = /mob/living/simple_mob/animal/passive/mouse
+ var/tf_admin_pref_override = FALSE
+
+ muzzle_type = /obj/effect/projectile/muzzle/laser_omni
+ tracer_type = /obj/effect/projectile/tracer/laser_omni
+ impact_type = /obj/effect/projectile/impact/laser_omni
+
+/obj/item/projectile/beam/mouselaser/on_hit(var/atom/target)
+ var/mob/living/M = target
+ if(!istype(M))
+ return
+ if(target != firer) //If you shot yourself, you probably want to be TFed so don't bother with prefs.
+ if(!M.allow_spontaneous_tf && !tf_admin_pref_override)
+ return
+ if(M.tf_mob_holder)
+ var/mob/living/ourmob = M.tf_mob_holder
+ if(ourmob.ai_holder)
+ var/datum/ai_holder/our_AI = ourmob.ai_holder
+ our_AI.set_stance(STANCE_IDLE)
+ M.tf_mob_holder = null
+ ourmob.ckey = M.ckey
+ var/turf/get_dat_turf = get_turf(target)
+ ourmob.loc = get_dat_turf
+ ourmob.forceMove(get_dat_turf)
+ ourmob.vore_selected = M.vore_selected
+ M.vore_selected = null
+ for(var/obj/belly/B as anything in M.vore_organs)
+ B.loc = ourmob
+ B.forceMove(ourmob)
+ B.owner = ourmob
+ M.vore_organs -= B
+ ourmob.vore_organs += B
+
+ ourmob.Life(1)
+ if(ishuman(M))
+ for(var/obj/item/W in M)
+ if(istype(W, /obj/item/weapon/implant/backup) || istype(W, /obj/item/device/nif))
+ continue
+ M.drop_from_inventory(W)
+
+ qdel(target)
+ return
+ else
+ if(M.stat == DEAD) //We can let it undo the TF, because the person will be dead, but otherwise things get weird.
+ return
+ var/mob/living/new_mob = spawn_mob(M)
+ new_mob.faction = M.faction
+
+ if(new_mob && isliving(new_mob))
+ for(var/obj/belly/B as anything in new_mob.vore_organs)
+ new_mob.vore_organs -= B
+ qdel(B)
+ new_mob.vore_organs = list()
+ new_mob.name = M.name
+ new_mob.real_name = M.real_name
+ for(var/lang in M.languages)
+ new_mob.languages |= lang
+ M.copy_vore_prefs_to_mob(new_mob)
+ new_mob.vore_selected = M.vore_selected
+ new_mob.allow_spontaneous_tf = TRUE
+
+ for(var/obj/belly/B as anything in M.vore_organs)
+ B.loc = new_mob
+ B.forceMove(new_mob)
+ B.owner = new_mob
+ M.vore_organs -= B
+ new_mob.vore_organs += B
+
+ new_mob.ckey = M.ckey
+ if(M.ai_holder && new_mob.ai_holder)
+ var/datum/ai_holder/old_AI = M.ai_holder
+ old_AI.set_stance(STANCE_SLEEP)
+ var/datum/ai_holder/new_AI = new_mob.ai_holder
+ new_AI.hostile = old_AI.hostile
+ new_AI.retaliate = old_AI.retaliate
+ M.loc = new_mob
+ M.forceMove(new_mob)
+ new_mob.tf_mob_holder = M
+
+/obj/item/projectile/beam/mouselaser/proc/spawn_mob(var/mob/living/target)
+ if(!ispath(tf_type))
+ return
+ var/new_mob = new tf_type(get_turf(target))
+ return new_mob
+
+/mob/living
+ var/mob/living/tf_mob_holder = null
+
+/mob/living/proc/handle_tf_holder()
+ if(!tf_mob_holder)
+ return
+ if(stat != tf_mob_holder.stat)
+ if(stat == DEAD)
+ tf_mob_holder.death(FALSE, null)
+ if(tf_mob_holder.stat == DEAD)
+ death()
+
+/mob/living/proc/copy_vore_prefs_to_mob(var/mob/living/new_mob)
+ //For primarily copying vore preference settings from a carbon mob to a simplemob
+ //It can be used for other things, but be advised, if you're using it to put a simplemob into a carbon mob, you're gonna be overriding a bunch of prefs
+ new_mob.ooc_notes = ooc_notes
+ new_mob.digestable = digestable
+ new_mob.devourable = devourable
+ new_mob.absorbable = absorbable
+ new_mob.feeding = feeding
+ new_mob.can_be_drop_prey = can_be_drop_prey
+ new_mob.can_be_drop_pred = can_be_drop_pred
+ new_mob.allow_inbelly_spawning = allow_inbelly_spawning
+ new_mob.digest_leave_remains = digest_leave_remains
+ new_mob.allowmobvore = allowmobvore
+ new_mob.permit_healbelly = permit_healbelly
+ new_mob.noisy = noisy
+ new_mob.drop_vore = drop_vore
+ new_mob.stumble_vore = stumble_vore
+ new_mob.slip_vore = slip_vore
+ new_mob.resizable = resizable
+ new_mob.show_vore_fx = show_vore_fx
+ new_mob.step_mechanics_pref = step_mechanics_pref
+ new_mob.pickup_pref = pickup_pref
+ new_mob.vore_taste = vore_taste
+ new_mob.vore_smell = vore_smell
+ new_mob.nutrition_message_visible = nutrition_message_visible
+ new_mob.allow_spontaneous_tf = allow_spontaneous_tf
+
+/////SUBTYPES/////
+
+/obj/item/weapon/gun/energy/mouseray/medical //This just changes people back, it can't TF people into anything without shenanigans
+ name = "recombobulation ray"
+ desc = "The Type Gamma Medical Recombobulation ray! A mysterious looking ray gun! It works to change people who have had their form significantly altered back into their original forms!"
+
+ icon_state = "medray"
+ item_state = "mouseray"
+ charge_meter = FALSE
+ charge_cost = 0
+ tf_type = null
+ projectile_type = /obj/item/projectile/beam/mouselaser/reversion
+
+/obj/item/weapon/gun/energy/mouseray/medical/consume_next_projectile()
+ . = ..()
+ var/obj/item/projectile/beam/mouselaser/reversion/G = .
+ cooldown = world.time + cooldown_time
+ if(tf_admin_pref_override)
+ G.tf_admin_pref_override = tf_admin_pref_override
+
+
+/obj/item/projectile/beam/mouselaser/reversion
+ name = "recombobulation beam"
+ tf_admin_pref_override = FALSE
+
+/obj/item/projectile/beam/mouselaser/reversion/on_hit(var/atom/target)
+ var/mob/living/M = target
+ if(!istype(M))
+ return
+ if(target != firer) //If you shot yourself, you probably want to be TFed so don't bother with prefs.
+ if(!M.allow_spontaneous_tf && !tf_admin_pref_override)
+ firer.visible_message("\The [src] buzzes impolitely.")
+ return
+ if(M.tf_mob_holder)
+ var/mob/living/ourmob = M.tf_mob_holder
+ if(ourmob.ai_holder)
+ var/datum/ai_holder/our_AI = ourmob.ai_holder
+ our_AI.set_stance(STANCE_IDLE)
+ M.tf_mob_holder = null
+ ourmob.ckey = M.ckey
+ var/turf/get_dat_turf = get_turf(target)
+ ourmob.loc = get_dat_turf
+ ourmob.forceMove(get_dat_turf)
+ ourmob.vore_selected = M.vore_selected
+ M.vore_selected = null
+ for(var/obj/belly/B as anything in M.vore_organs)
+ B.loc = ourmob
+ B.forceMove(ourmob)
+ B.owner = ourmob
+ M.vore_organs -= B
+ ourmob.vore_organs += B
+
+ ourmob.Life(1)
+
+ if(ishuman(M))
+ for(var/obj/item/W in M)
+ if(istype(W, /obj/item/weapon/implant/backup) || istype(W, /obj/item/device/nif))
+ continue
+ M.drop_from_inventory(W)
+
+ qdel(target)
+ firer.visible_message("\The [shot_from] boops pleasantly.")
+ return
+ else
+ firer.visible_message("\The [shot_from] buzzes impolitely.")
+
+/obj/item/weapon/gun/energy/mouseray/admin //NEVER GIVE THIS TO ANYONE
+ name = "experimental metamorphosis ray"
+ tf_admin_pref_override = TRUE
+ cooldown_time = 5 SECONDS
+ tf_allow_select = TRUE
+ charge_meter = FALSE
+ charge_cost = 0
+ icon_state = "adminray"
+
+/obj/item/weapon/gun/energy/mouseray/metamorphosis
+ name = "metamorphosis ray"
+ tf_allow_select = TRUE
+ tf_possible_types = list(
+ "mouse" = /mob/living/simple_mob/animal/passive/mouse,
+ "rat" = /mob/living/simple_mob/animal/passive/mouse/rat,
+ "dust jumper" = /mob/living/simple_mob/vore/alienanimals/dustjumper,
+ "woof" = /mob/living/simple_mob/vore/woof,
+ "corgi" = /mob/living/simple_mob/animal/passive/dog/corgi,
+ "cat" = /mob/living/simple_mob/animal/passive/cat,
+ "chicken" = /mob/living/simple_mob/animal/passive/chicken,
+ "cow" = /mob/living/simple_mob/animal/passive/cow,
+ "lizard" = /mob/living/simple_mob/animal/passive/lizard,
+ "rabbit" = /mob/living/simple_mob/vore/rabbit,
+ "fox" = /mob/living/simple_mob/animal/passive/fox,
+ "fennec" = /mob/living/simple_mob/vore/fennec,
+ "cute fennec" = /mob/living/simple_mob/animal/passive/fennec,
+ "fennix" = /mob/living/simple_mob/vore/fennix,
+ "red panda" = /mob/living/simple_mob/vore/redpanda,
+ "opossum" = /mob/living/simple_mob/animal/passive/opossum,
+ "horse" = /mob/living/simple_mob/vore/horse,
+ "goose" = /mob/living/simple_mob/animal/space/goose,
+ "sheep" = /mob/living/simple_mob/vore/sheep
+ )
+
+/obj/item/weapon/gun/energy/mouseray/metamorphosis/advanced
+ name = "advanced metamorphosis ray"
+ tf_possible_types = list(
+ "mouse" = /mob/living/simple_mob/animal/passive/mouse,
+ "rat" = /mob/living/simple_mob/animal/passive/mouse/rat,
+ "giant rat" = /mob/living/simple_mob/vore/aggressive/rat,
+ "dust jumper" = /mob/living/simple_mob/vore/alienanimals/dustjumper,
+ "woof" = /mob/living/simple_mob/vore/woof,
+ "corgi" = /mob/living/simple_mob/animal/passive/dog/corgi,
+ "cat" = /mob/living/simple_mob/animal/passive/cat,
+ "chicken" = /mob/living/simple_mob/animal/passive/chicken,
+ "cow" = /mob/living/simple_mob/animal/passive/cow,
+ "lizard" = /mob/living/simple_mob/animal/passive/lizard,
+ "rabbit" = /mob/living/simple_mob/vore/rabbit,
+ "fox" = /mob/living/simple_mob/animal/passive/fox,
+ "fennec" = /mob/living/simple_mob/vore/fennec,
+ "cute fennec" = /mob/living/simple_mob/animal/passive/fennec,
+ "fennix" = /mob/living/simple_mob/vore/fennix,
+ "red panda" = /mob/living/simple_mob/vore/redpanda,
+ "opossum" = /mob/living/simple_mob/animal/passive/opossum,
+ "horse" = /mob/living/simple_mob/vore/horse,
+ "goose" = /mob/living/simple_mob/animal/space/goose,
+ "sheep" = /mob/living/simple_mob/vore/sheep,
+ "space bumblebee" = /mob/living/simple_mob/vore/bee,
+ "space bear" = /mob/living/simple_mob/animal/space/bear,
+ "voracious lizard" = /mob/living/simple_mob/vore/aggressive/dino,
+ "giant frog" = /mob/living/simple_mob/vore/aggressive/frog,
+ "jelly blob" = /mob/living/simple_mob/animal/space/jelly,
+ "wolf" = /mob/living/simple_mob/animal/wolf,
+ "direwolf" = /mob/living/simple_mob/animal/wolf/direwolf,
+ "great wolf" = /mob/living/simple_mob/vore/greatwolf,
+ "sect queen" = /mob/living/simple_mob/vore/sect_queen,
+ "sect drone" = /mob/living/simple_mob/vore/sect_drone,
+ "panther" = /mob/living/simple_mob/vore/aggressive/panther,
+ "giant snake" = /mob/living/simple_mob/vore/aggressive/giant_snake,
+ "deathclaw" = /mob/living/simple_mob/vore/aggressive/deathclaw,
+ "otie" = /mob/living/simple_mob/otie,
+ "mutated otie" =/mob/living/simple_mob/otie/feral,
+ "red otie" = /mob/living/simple_mob/otie/red,
+ "defanged xenomorph" = /mob/living/simple_mob/vore/xeno_defanged,
+ "catslug" = /mob/living/simple_mob/vore/alienanimals/catslug,
+ "teppi" = /mob/living/simple_mob/vore/alienanimals/teppi,
+ "monkey" = /mob/living/carbon/human/monkey,
+ "wolpin" = /mob/living/carbon/human/wolpin,
+ "sparra" = /mob/living/carbon/human/sparram,
+ "saru" = /mob/living/carbon/human/sergallingm,
+ "sobaka" = /mob/living/carbon/human/sharkm,
+ "farwa" = /mob/living/carbon/human/farwa,
+ "neaera" = /mob/living/carbon/human/neaera,
+ "stok" = /mob/living/carbon/human/stok,
+ "weretiger" = /mob/living/simple_mob/vore/weretiger,
+ "dragon" = /mob/living/simple_mob/vore/bigdragon/friendly,
+ "leopardmander" = /mob/living/simple_mob/vore/leopardmander
+ )
+
+/obj/item/weapon/gun/energy/mouseray/metamorphosis/advanced/random
+ name = "unstable metamorphosis ray"
+ tf_allow_select = FALSE
+
+/obj/item/weapon/gun/energy/mouseray/metamorphosis/advanced/random/Fire(atom/target, mob/living/user, clickparams, pointblank, reflex)
+ if(world.time < cooldown)
+ to_chat(usr, "\The [src] isn't ready yet.")
+ return
+ var/choice = pick(tf_possible_types)
+ tf_type = tf_possible_types[choice]
+ . = ..()
+
+/obj/item/weapon/gun/energy/mouseray/woof
+ name = "woof ray"
+ tf_type = /mob/living/simple_mob/vore/woof
+
+/obj/item/weapon/gun/energy/mouseray/corgi
+ name = "corgi ray"
+ tf_type = /mob/living/simple_mob/animal/passive/dog/corgi
+
+/obj/item/weapon/gun/energy/mouseray/cat
+ name = "cat ray"
+ tf_type = /mob/living/simple_mob/animal/passive/cat
+
+/obj/item/weapon/gun/energy/mouseray/chicken
+ name = "chicken ray"
+ tf_type = /mob/living/simple_mob/animal/passive/chicken
+
+/obj/item/weapon/gun/energy/mouseray/lizard
+ name = "lizard ray"
+ tf_type = /mob/living/simple_mob/animal/passive/lizard
+
+/obj/item/weapon/gun/energy/mouseray/rabbit
+ name = "rabbit ray"
+ tf_type = /mob/living/simple_mob/vore/rabbit
+
+/obj/item/weapon/gun/energy/mouseray/fennec
+ name = "fennec ray"
+ tf_type = /mob/living/simple_mob/animal/passive/fennec
+
+/obj/item/weapon/gun/energy/mouseray/monkey
+ name = "monkey ray"
+ tf_type = /mob/living/carbon/human/monkey
+
+/obj/item/weapon/gun/energy/mouseray/wolpin
+ name = "wolpin ray"
+ tf_type = /mob/living/carbon/human/wolpin
+
+/obj/item/weapon/gun/energy/mouseray/otie
+ name = "otie ray"
+ tf_type = /mob/living/simple_mob/otie
+
+/obj/item/weapon/gun/energy/mouseray/direwolf
+ name = "dire wolf ray"
+ tf_type = /mob/living/simple_mob/animal/wolf/direwolf
+
+/obj/item/weapon/gun/energy/mouseray/giantrat
+ name = "giant rat ray"
+ tf_type = /mob/living/simple_mob/vore/aggressive/rat
+
+/obj/item/weapon/gun/energy/mouseray/redpanda
+ name = "red panda ray"
+ tf_type = /mob/living/simple_mob/vore/redpanda
+
+/obj/item/weapon/gun/energy/mouseray/catslug
+ name = "catslug ray"
+ tf_type = /mob/living/simple_mob/vore/alienanimals/catslug
+
+/obj/item/weapon/gun/energy/mouseray/teppi
+ name = "teppi ray"
+ tf_type = /mob/living/simple_mob/vore/alienanimals/teppi
+
+
+/////RANDOM SPAWNER/////
+
+/obj/random/mouseray
+ name = "random ray"
+ icon = 'icons/mob/randomlandmarks.dmi'
+ icon_state = "fanc_trejur"
+ spawn_nothing_percentage = 0
+
+/obj/random/mainttoyloot/item_to_spawn()
+ return pick(prob(300);/obj/item/weapon/gun/energy/mouseray,
+ prob(50);/obj/item/weapon/gun/energy/mouseray/corgi,
+ prob(50);/obj/item/weapon/gun/energy/mouseray/woof,
+ prob(50);/obj/item/weapon/gun/energy/mouseray/cat,
+ prob(50);/obj/item/weapon/gun/energy/mouseray/chicken,
+ prob(50);/obj/item/weapon/gun/energy/mouseray/lizard,
+ prob(50);/obj/item/weapon/gun/energy/mouseray/rabbit,
+ prob(50);/obj/item/weapon/gun/energy/mouseray/fennec,
+ prob(5);/obj/item/weapon/gun/energy/mouseray/monkey,
+ prob(5);/obj/item/weapon/gun/energy/mouseray/wolpin,
+ prob(5);/obj/item/weapon/gun/energy/mouseray/otie,
+ prob(5);/obj/item/weapon/gun/energy/mouseray/direwolf,
+ prob(5);/obj/item/weapon/gun/energy/mouseray/giantrat,
+ prob(50);/obj/item/weapon/gun/energy/mouseray/redpanda,
+ prob(5);/obj/item/weapon/gun/energy/mouseray/catslug,
+ prob(5);/obj/item/weapon/gun/energy/mouseray/teppi,
+ prob(1);/obj/item/weapon/gun/energy/mouseray/metamorphosis,
+ prob(1);/obj/item/weapon/gun/energy/mouseray/metamorphosis/advanced/random
+ )
diff --git a/icons/mob/items/lefthand_guns_vr.dmi b/icons/mob/items/lefthand_guns_vr.dmi
index f2c51e21b9..20261bbbe1 100644
Binary files a/icons/mob/items/lefthand_guns_vr.dmi and b/icons/mob/items/lefthand_guns_vr.dmi differ
diff --git a/icons/mob/items/righthand_guns_vr.dmi b/icons/mob/items/righthand_guns_vr.dmi
index 7e899b2b99..f39b901489 100644
Binary files a/icons/mob/items/righthand_guns_vr.dmi and b/icons/mob/items/righthand_guns_vr.dmi differ
diff --git a/icons/obj/mouseray.dmi b/icons/obj/mouseray.dmi
new file mode 100644
index 0000000000..fdb4d9bb90
Binary files /dev/null and b/icons/obj/mouseray.dmi differ
diff --git a/maps/groundbase/gb-z1.dmm b/maps/groundbase/gb-z1.dmm
index 8a44ae02c3..e8d98c0e4c 100644
--- a/maps/groundbase/gb-z1.dmm
+++ b/maps/groundbase/gb-z1.dmm
@@ -18736,6 +18736,7 @@ lel
departmentType = 2;
pixel_y = 30
},
+/obj/item/weapon/gun/energy/mouseray/medical,
/turf/simulated/floor/tiled/white,
/area/groundbase/medical/equipment)
"To" = (
diff --git a/maps/stellar_delight/stellar_delight2.dmm b/maps/stellar_delight/stellar_delight2.dmm
index 73422b6915..fceb40e341 100644
--- a/maps/stellar_delight/stellar_delight2.dmm
+++ b/maps/stellar_delight/stellar_delight2.dmm
@@ -11064,6 +11064,7 @@
/obj/machinery/light{
dir = 4
},
+/obj/item/weapon/gun/energy/mouseray/medical,
/turf/simulated/floor/tiled/eris/white/bluecorner,
/area/medical/cmostore)
"yW" = (
diff --git a/maps/tether/tether-03-surface3.dmm b/maps/tether/tether-03-surface3.dmm
index d624ce5e1a..4afa20b0dd 100644
--- a/maps/tether/tether-03-surface3.dmm
+++ b/maps/tether/tether-03-surface3.dmm
@@ -588,6 +588,7 @@
/obj/machinery/status_display{
pixel_x = -32
},
+/obj/item/weapon/gun/energy/mouseray/medical,
/turf/simulated/floor/tiled/white,
/area/tether/surfacebase/medical/storage)
"aaT" = (
diff --git a/vorestation.dme b/vorestation.dme
index e5d66de0b2..2a05b60aed 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -4281,6 +4281,7 @@
#include "code\modules\virus2\isolator.dm"
#include "code\modules\virus2\items_devices.dm"
#include "code\modules\vore\hook-defs_vr.dm"
+#include "code\modules\vore\mouseray.dm"
#include "code\modules\vore\trycatch_vr.dm"
#include "code\modules\vore\appearance\preferences_vr.dm"
#include "code\modules\vore\appearance\sprite_accessories_taur_yw.dm"