mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-23 03:57:48 +01:00
Mouse Ray
It turns things into mice (if they have the spontaneous TF preference enabled) Also wiggles a few things around to allow for some shenanigans with this, namely: if you are TFed into a thing, damage you take is relayed to your original body proportionally to the comparable HP. MEANING, if you have been TFed into a mouse, you have 20 HP. Your human body has 100. You have 1/5th the HP as a mouse. If you as a mouse take 5 damage, your human body takes 25. Be careful! Additionally, if you as a mouse, or your human body dies, both die. Your TFed body being destroyed undoes the transformation. (But also you're probably dead at that point anyway) This allows for, in the case of digestion, your equipment to go where it ought to go. Lastly, the building blocks are in place for this to be fluffed into other kinds of metamorphosis rays, should staff feel like doing such. I will probably also trick out the /admin variant of this with a bunch of mob types tomorrow when I'm not sleeby
This commit is contained in:
@@ -72,6 +72,8 @@
|
||||
|
||||
handle_vision()
|
||||
|
||||
handle_tf_holder() //VOREStation Addition
|
||||
|
||||
/mob/living/proc/handle_breathing()
|
||||
return
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -378,7 +378,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
|
||||
@@ -1063,14 +1063,14 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
if((status & ORGAN_BROKEN) || cannot_break)
|
||||
return
|
||||
|
||||
if(owner)
|
||||
owner.visible_message(\
|
||||
"<span class='danger'>You hear a loud cracking sound coming from \the [owner].</span>",\
|
||||
"<span class='danger'>Something feels like it shattered in your [name]!</span>",\
|
||||
"<span class='danger'>You hear a sickening crack.</span>")
|
||||
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(\
|
||||
"<span class='danger'>You hear a loud cracking sound coming from \the [owner].</span>",\
|
||||
"<span class='danger'>Something feels like it shattered in your [name]!</span>",\
|
||||
"<span class='danger'>You hear a sickening crack.</span>")
|
||||
owner.emote("scream")
|
||||
jostle_bone() //VOREStation Edit End
|
||||
|
||||
playsound(src, "fracture", 10, 1, -2)
|
||||
status |= ORGAN_BROKEN
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/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
|
||||
var/cooldown = 0
|
||||
var/cooldown_time = 15 SECONDS
|
||||
var/tf_admin_pref_override = FALSE
|
||||
var/tf_allow_select = FALSE
|
||||
var/tf_possible_types = list(
|
||||
"mouse" = /mob/living/simple_mob/animal/passive/mouse,
|
||||
"woof" = /mob/living/simple_mob/vore/woof)
|
||||
|
||||
/obj/item/weapon/gun/energy/mouseray/admin
|
||||
name = "experimental metamorphosis ray"
|
||||
tf_admin_pref_override = TRUE
|
||||
cooldown_time = 5 SECONDS
|
||||
tf_allow_select = TRUE
|
||||
charge_cost = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/mouseray/woof
|
||||
name = "woof ray"
|
||||
tf_type = /mob/living/simple_mob/vore/woof
|
||||
|
||||
/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, "<span class='notice'>You selected [choice].</span>")
|
||||
|
||||
/obj/item/weapon/gun/energy/mouseray/Fire(atom/target, mob/living/user, clickparams, pointblank, reflex)
|
||||
if(world.time < cooldown)
|
||||
to_chat(usr, "<span class='warning'>\The [src] isn't ready yet.</span>")
|
||||
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)
|
||||
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
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 710 B |
@@ -3976,6 +3976,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\update_icons_vr.dm"
|
||||
|
||||
Reference in New Issue
Block a user