diff --git a/code/game/objects/items/devices/personal_shield_generator_vr.dm b/code/game/objects/items/devices/personal_shield_generator_vr.dm
new file mode 100644
index 00000000000..cff54a33d53
--- /dev/null
+++ b/code/game/objects/items/devices/personal_shield_generator_vr.dm
@@ -0,0 +1,364 @@
+//backpack item
+/obj/item/device/personal_shield_generator
+ name = "personal shield generator"
+ desc = "A personal shield generator."
+ icon = 'icons/obj/items_vr.dmi' //Placeholder
+ icon_state = "shield_pack" //Placeholder
+ item_state = "defibunit" //Placeholder
+ slot_flags = SLOT_BACK
+ force = 5
+ throwforce = 6
+ preserve_item = 1
+ w_class = ITEMSIZE_HUGE //It's a giant shield generator!!!
+ unacidable = TRUE
+ origin_tech = list(TECH_BIO = 4, TECH_POWER = 2) //Set this to better stuff later.
+ action_button_name = "Toggle Shield"
+
+ var/obj/item/weapon/gun/energy/gun/generator/active_weapon
+ var/obj/item/weapon/cell/device/bcell = null
+ var/generator_hit_cost = 100 // Power used when a special effect (such as a bullet being blocked) is performed!
+ var/generator_active_cost = 10 // Power used when turned on.
+ var/has_weapon = 1
+ var/shield_active = 0 // If the shield gen is active.
+ var/energy_modifier = 25 // 40 damage absorbed per 1000 charge. If the charge used is > the cell's remaining charge, the excess is dealt to the user!
+
+/obj/item/device/personal_shield_generator/get_cell()
+ return bcell
+
+/obj/item/device/personal_shield_generator/New() //starts without a cell for rnd
+ ..()
+ if(ispath(bcell))
+ bcell = new bcell(src)
+
+ if(has_weapon)
+ if(ispath(active_weapon))
+ active_weapon = new active_weapon(src, src)
+ active_weapon.power_supply = bcell
+ else
+ active_weapon = new(src, src)
+ active_weapon.power_supply = bcell
+ else
+ verbs -= /obj/item/device/personal_shield_generator/verb/weapon_toggle
+ update_icon()
+
+/obj/item/device/personal_shield_generator/Destroy()
+ . = ..()
+ QDEL_NULL(active_weapon)
+ QDEL_NULL(bcell)
+
+/obj/item/device/personal_shield_generator/loaded //starts with a cell
+ bcell = /obj/item/weapon/cell/device/weapon/recharge
+
+
+/obj/item/device/personal_shield_generator/update_icon()
+ if(shield_active)
+ icon_state = "shield_back_active"
+ else
+ icon_state = "shield_pack"
+
+/obj/item/device/personal_shield_generator/examine(mob/user)
+ . = ..()
+ if(Adjacent(user))
+ . += "The installed cell has has a power rating of [bcell.maxcharge] and is [round(bcell.percent() )]% charged ."
+ . += "It reads that it can take [bcell.charge/energy_modifier] more damage before the shield goes down."
+ if(bcell.self_recharge && bcell.charge_amount)
+ . += "This model is self charging and will take [bcell.maxcharge/bcell.charge_amount] seconds to fully charge from empty."
+
+
+/* //This would be cool, but we need sprites.
+ cut_overlays()
+
+ if(has_weapon && active_weapon && active_weapon.loc == src) //in case gun gets destroyed somehow.
+ add_overlay("[initial(icon_state)]-paddles")
+ if(bcell)
+ if(bcell.check_charge(generator_hit_cost)) //Can we take a blow?
+ add_overlay("[initial(icon_state)]-powered")
+ else if(has_weapon && active_weapon)
+ if(bcell.check_charge(active_weapon.charge_cost)) //We got enough to go pew pew?
+ add_overlay("[initial(icon_state)]-powered")
+
+ var/ratio = CEILING(bcell.percent()/25, 1) * 25
+ add_overlay("[initial(icon_state)]-charge[ratio]")
+ else
+ add_overlay("[initial(icon_state)]-nocell")
+*/
+
+/obj/item/device/personal_shield_generator/ui_action_click()
+ toggle_shield()
+
+/obj/item/device/personal_shield_generator/attack_hand(mob/user)
+ if(loc == user)
+ toggle_shield()
+ else
+ ..()
+
+/obj/item/device/personal_shield_generator/AltClick(mob/living/user)
+ weapon_toggle()
+
+/obj/item/device/personal_shield_generator/MouseDrop()
+ if(ismob(src.loc))
+ if(!CanMouseDrop(src))
+ return
+ var/mob/M = src.loc
+ if(!M.unEquip(src))
+ return
+ src.add_fingerprint(usr)
+ M.put_in_any_hand_if_possible(src)
+
+
+/obj/item/device/personal_shield_generator/attackby(obj/item/weapon/W, mob/user, params) //This should never happen unless admin spawns in an empty one.
+ if(W == active_weapon)
+ reattach_gun(user)
+ else if(istype(W, /obj/item/weapon/cell))
+ if(bcell)
+ to_chat(user, "\The [src] already has a cell.")
+ else if(!istype(W, /obj/item/weapon/cell/device/weapon)) //Weapon cells only!
+ to_chat(user, "This cell will not fit in the device.")
+ else
+ if(!user.unEquip(W))
+ return
+ W.forceMove(src)
+ bcell = W
+ to_chat(user, "You install a cell in \the [src].")
+ update_icon()
+
+ else if(W.is_screwdriver())
+ if(bcell)
+ if(istype(bcell, /obj/item/weapon/cell/device/weapon/recharge)) //No stealing self charging batteries!
+ to_chat(user, "You can not remove the cell from \the [src] without destroying the unit.")
+ return
+ else
+ bcell.update_icon()
+ bcell.forceMove(get_turf(src.loc))
+ bcell = null
+ to_chat(user, "You remove the cell from \the [src].")
+ update_icon()
+ else
+ return ..()
+
+/* //TODO
+/obj/item/device/personal_shield_generator/emag_act(var/remaining_charges, var/mob/user)
+ if(active_weapon)
+ . = active_weapon.emag_act(user)
+ update_icon()
+ return
+*/
+
+//Gun stuff
+
+
+/obj/item/device/personal_shield_generator/verb/toggle_shield()
+ set name = "Toggle Shield"
+ set category = "Object"
+
+ var/mob/living/carbon/human/user = usr
+
+ if(user.last_special > world.time)
+ return
+ user.last_special = world.time + 10 //No spamming!
+
+ if(!bcell || !bcell.check_charge(generator_hit_cost))
+ to_chat(user, "You require a charged cell to do this!")
+ return
+
+ if(!slot_check())
+ to_chat(user, "You need to equip [src] before starting the shield up!")
+ return
+ else
+ if(shield_active)
+ shield_active = !shield_active //Deactivate the shield!
+ to_chat(user, "You deactive the shield!")
+ user.remove_modifiers_of_type(/datum/modifier/shield_projection)
+ STOP_PROCESSING(SSobj, src)
+ else
+ shield_active = !shield_active
+ to_chat(user, "You activate the shield!")
+ user.add_modifier(/datum/modifier/shield_projection)
+ START_PROCESSING(SSobj, src) //Let's only bother draining power when we're being used!
+ update_icon()
+
+/obj/item/device/personal_shield_generator/verb/weapon_toggle() //Make this work on Alt-Click
+ set name = "Toggle Gun"
+ set category = "Object"
+
+ var/mob/living/carbon/human/user = usr
+
+ if(user.last_special > world.time)
+ return
+ user.last_special = world.time + 10 //No spamming!
+ if(!active_weapon)
+ to_chat(user, "The gun is missing!")
+ return
+
+ if(active_weapon.loc != src)
+ reattach_gun(user) //Remove from their hands and back onto the defib unit
+ return
+
+ if(!slot_check())
+ to_chat(user, "You need to equip [src] before taking out [active_weapon].")
+ else
+ if(!usr.put_in_hands(active_weapon)) //Detach the gun into the user's hands
+ to_chat(user, "You need a free hand to hold the gun!")
+ update_icon() //success
+
+/obj/item/device/personal_shield_generator/process()
+ if(shield_active)
+ bcell.use(generator_active_cost)
+ if(bcell.charge < generator_hit_cost) //Out of charge...
+ shield_active = 0
+ if(istype(loc, /mob/living/carbon/human)) //We on someone? Tell them it turned off.
+ var/mob/living/carbon/human/user = loc
+ to_chat(user, "The shield deactivates.!")
+ user.remove_modifiers_of_type(/datum/modifier/shield_projection)
+ STOP_PROCESSING(SSobj, src)
+
+
+
+//checks that the base unit is in the correct slot to be used
+/obj/item/device/personal_shield_generator/proc/slot_check()
+ var/mob/M = loc
+ if(!istype(M))
+ return 0 //not equipped
+
+ if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_back) == src)
+ return 1
+ if((slot_flags & SLOT_BELT) && M.get_equipped_item(slot_belt) == src)
+ return 1
+ //RIGSuit compatability. This shouldn't be possible, however, except for select RIGs.
+ if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_s_store) == src)
+ return 1
+ if((slot_flags & SLOT_BELT) && M.get_equipped_item(slot_s_store) == src)
+ return 1
+
+ return 0
+
+/obj/item/device/personal_shield_generator/dropped(mob/user)
+ ..()
+ reattach_gun(user) //A gun attached to a base unit should never exist outside of their base unit or the mob equipping the base unit
+
+/obj/item/device/personal_shield_generator/proc/reattach_gun(mob/user)
+ if(!active_weapon) return
+
+ if(ismob(active_weapon.loc))
+ var/mob/M = active_weapon.loc
+ if(M.drop_from_inventory(active_weapon, src))
+ to_chat(user, "\The [active_weapon] snaps back into the main unit.")
+ else
+ active_weapon.forceMove(src)
+
+ update_icon()
+
+/*
+ Base Unit Subtypes
+*/
+
+/obj/item/device/personal_shield_generator/belt
+ name = "personal shield generator"
+ desc = "A personal shield generator."
+ icon_state = "shield_back_active"
+ item_state = "shield_pack"
+ w_class = ITEMSIZE_LARGE //No putting these in backpacks!
+ slot_flags = SLOT_BELT
+ origin_tech = list(TECH_BIO = 5, TECH_POWER = 3)
+ has_weapon = 0 //No gun with the belt!
+
+/obj/item/device/personal_shield_generator/belt/loaded
+ bcell = /obj/item/weapon/cell/device/weapon/recharge
+
+/obj/item/device/personal_shield_generator/belt/update_icon()
+ if(shield_active)
+ icon_state = "shield_back_active"
+ else
+ icon_state = "shield_pack"
+
+
+//The gun
+
+/obj/item/weapon/gun/energy/gun/generator //The gun attached to the personal shield generator.
+ name = "energy gun"
+ desc = "Another bestseller of Lawson Arms, the LAEP80 Thor is a versatile energy based pistol, capable of switching between low and high \
+ capacity projectile settings. In other words: Stun or Kill."
+ description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, often sold alongside MarsTech projectile \
+ weapons to security and law enforcement agencies."
+ icon_state = "egunstun"
+ item_state = null //so the human update icon uses the icon_state instead.
+ fire_delay = 8
+ use_external_power = TRUE
+ cell_type = null //No cell! It runs off the cell in the shield_gen!
+
+ projectile_type = /obj/item/projectile/beam/stun/med
+ modifystate = "egunstun"
+
+ firemodes = list(
+ list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="egunstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
+ list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="egunkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
+ ) //Zero charge_cost since it's handled per shot.
+
+ var/obj/item/device/personal_shield_generator/shield_generator //The generator we are linked to!
+ var/wielded = 0
+ var/cooldown = 0
+ var/busy = 0
+
+/obj/item/weapon/gun/energy/gun/generator/New(newloc, obj/item/device/personal_shield_generator/shield_gen)
+ ..(newloc)
+ shield_generator = shield_gen
+ power_supply = shield_generator.bcell
+
+/* //Unused. Use for large guns.
+/obj/item/weapon/gun/energy/gun/generator/update_held_icon()
+ var/mob/living/M = loc
+ if(istype(M) && M.item_is_in_hands(src) && !M.hands_are_full())
+ wielded = 1
+ name = "[initial(name)] (wielded)"
+ else
+ wielded = 0
+ name = initial(name)
+ update_icon()
+ ..()
+*/
+
+/obj/item/weapon/gun/energy/gun/generator/proc/can_use(mob/user, mob/M)
+ if(busy)
+ return 0
+ if(!check_charge(charge_cost))
+ to_chat(user, "\The [src] doesn't have enough charge left to do that.")
+ return 0
+ if(!wielded && !isrobot(user))
+ to_chat(user, "You need to wield the gun with both hands before you can use it on someone!")
+ return 0
+ if(cooldown)
+ to_chat(user, "\The [src] are re-energizing!")
+ return 0
+ return 1
+
+/* //TODO: Emp act.
+/obj/item/weapon/shockpaddles/emp_act(severity)
+ var/new_safety = rand(0, 1)
+ if(safety != new_safety)
+ safety = new_safety
+ if(safety)
+ make_announcement("beeps, \"Safety protocols enabled!\"", "notice")
+ playsound(src, 'sound/machines/defib_safetyon.ogg', 50, 0)
+ else
+ make_announcement("beeps, \"Safety protocols disabled!\"", "warning")
+ playsound(src, 'sound/machines/defib_safetyoff.ogg', 50, 0)
+ update_icon()
+ ..()
+*/
+
+/obj/item/weapon/gun/energy/gun/generator/dropped(mob/user)
+ ..() //update twohanding
+ if(shield_generator)
+ shield_generator.reattach_gun(user)
+
+/obj/item/weapon/gun/energy/proc/check_charge(var/charge_amt) //In case using any other guns.
+ return 0
+
+/obj/item/weapon/gun/energy/proc/checked_use(var/charge_amt) //In case using any other guns.
+ return 0
+
+/obj/item/weapon/gun/energy/gun/generator/check_charge(var/charge_amt)
+ return (shield_generator.bcell && shield_generator.bcell.check_charge(charge_amt))
+
+/obj/item/weapon/gun/energy/gun/generator/checked_use(var/charge_amt)
+ return (shield_generator.bcell && shield_generator.bcell.checked_use(charge_amt))
\ No newline at end of file
diff --git a/code/modules/mob/_modifiers/modifiers.dm b/code/modules/mob/_modifiers/modifiers.dm
index 56422efdf66..2fc4ef03e3f 100644
--- a/code/modules/mob/_modifiers/modifiers.dm
+++ b/code/modules/mob/_modifiers/modifiers.dm
@@ -64,6 +64,10 @@
var/siemens_coefficient = null // Similar to above two vars but 0 = full protection, to be consistant with siemens numbers everywhere else.
var/vision_flags // Vision flags to add to the mob. SEE_MOB, SEE_OBJ, etc.
+ var/energy_based // Sees if the modifier is based on something electronic based.
+ var/energy_cost // How much the modifier uses per action/special effect blocked. For base values.
+ var/energy_modifier // How much energy is used when numbers are involed. For values, such as taking damage. Ex: (Damage*energy_modifier)
+ var/obj/item/weapon/cell/energy_source = null // The source of the above.
/datum/modifier/New(var/new_holder, var/new_origin)
holder = new_holder
diff --git a/code/modules/mob/_modifiers/modifiers_vr.dm b/code/modules/mob/_modifiers/modifiers_vr.dm
index a56bc5d2e0a..ab486c3b705 100644
--- a/code/modules/mob/_modifiers/modifiers_vr.dm
+++ b/code/modules/mob/_modifiers/modifiers_vr.dm
@@ -30,4 +30,70 @@
if(water_floor.depth < 1) //You're not in deep enough water anymore.
expire(silent = FALSE)
else
- expire(silent = FALSE)
\ No newline at end of file
+ expire(silent = FALSE)
+
+
+
+
+
+
+
+
+
+/datum/modifier/shield_projection
+ name = "Shield Projection"
+ desc = "You are currently protected by a shield, rendering nigh impossible to hit you through conventional means."
+
+ on_created_text = "Your shield generator buzzes on."
+ on_expired_text = "Your shield generator buzzes off."
+ mob_overlay_state = "repel_missiles" //Looks alright, I guess. Placeholder.
+ stacks = MODIFIER_STACK_FORBID //No stacking shields. If you put one one your belt and backpack it won't work.
+
+ siemens_coefficient = 2 //Stun weapons drain 100% charge per damage. They're good at blocking lasers and bullets but not good at blocking stun beams!
+ incoming_brute_damage_percent = 0
+ incoming_fire_damage_percent = 0
+ incoming_hal_damage_percent = 0
+ energy_based = 1
+ energy_cost = 99999 //This is changed to the shield_genertor's energy_cost.
+ energy_modifier = 50 //This is how much battery is used per damage unit absorbed. Higher damage means higher charge use per damage absorbed. Changed below!
+ var/obj/item/device/personal_shield_generator/shield_generator //This is the shield generator you're wearing!
+
+
+/datum/modifier/shield_projection/on_applied()
+ return
+
+/datum/modifier/shield_projection/on_expire()
+ return
+
+/datum/modifier/shield_projection/check_if_valid() //Let's check to make sure you got the stuff and set the vars.
+ if(ishuman(holder)) //Only humans can use this!
+ var/mob/living/carbon/human/H = holder
+ if(istype(H.get_equipped_item(slot_back), /obj/item/device/personal_shield_generator))
+ shield_generator = H.get_equipped_item(slot_back) //Sets the var on the modifier that the shield gen is their back shield gen.
+ energy_source = shield_generator.bcell
+ energy_cost = shield_generator.generator_hit_cost
+ energy_modifier = shield_generator.energy_modifier
+ else if(istype(H.get_equipped_item(slot_belt), /obj/item/device/personal_shield_generator))
+ shield_generator = H.get_equipped_item(slot_belt) //No need for other checks. If they got hit by this, they just turned it on.
+ energy_source = shield_generator.bcell
+ energy_cost = shield_generator.generator_hit_cost
+ energy_modifier = shield_generator.energy_modifier
+ else if(istype(H.get_equipped_item(slot_s_store), /obj/item/device/personal_shield_generator) ) //Rigsuits.
+ shield_generator = H.get_equipped_item(slot_s_store)
+ energy_source = shield_generator.bcell
+ energy_cost = shield_generator.generator_hit_cost
+ energy_modifier = shield_generator.energy_modifier
+ else
+ expire(silent = TRUE)
+ else
+ expire(silent = TRUE)
+
+/datum/modifier/shield_projection/tick() //When the shield generator runs out of charge, it'll remove this naturally.
+ if(holder.stat == DEAD)
+ expire(silent = TRUE) //If you're dead the generator stops protecting you but keeps running.
+ if(!shield_generator || !shield_generator.slot_check()) //No shield to begin with/shield is not on them any longer.
+ expire(silent = FALSE)
+ var/shield_efficiency = 1-(energy_source.charge/energy_source.maxcharge) //0 = complete resistance. 1 = no resistance.
+ incoming_brute_damage_percent = shield_efficiency //Less charge means less resistance!
+ incoming_fire_damage_percent = shield_efficiency
+ incoming_hal_damage_percent = shield_efficiency
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index a3554a262f7..e3aa906bf83 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -115,8 +115,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_brute_damage_percent
if(nif && nif.flag_check(NIF_C_BRUTEARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
take_overall_damage(amount, 0)
@@ -133,8 +137,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_fire_damage_percent
if(nif && nif.flag_check(NIF_C_BURNARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
take_overall_damage(0, amount)
@@ -153,8 +161,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_brute_damage_percent
if(nif && nif.flag_check(NIF_C_BRUTEARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
@@ -175,8 +187,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_fire_damage_percent
if(nif && nif.flag_check(NIF_C_BURNARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
@@ -497,8 +513,12 @@ This function restores all organs.
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*damage)
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*damage)
damage *= M.incoming_brute_damage_percent
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
@@ -510,8 +530,12 @@ This function restores all organs.
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*damage)
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*damage)
damage *= M.incoming_fire_damage_percent
if(organ.take_damage(0, damage, sharp, edge, used_weapon))
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 1988405272f..ce93ed26472 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -37,6 +37,18 @@ emp_act
var/armor = getarmor_organ(organ, "bullet")
if(!prob(armor/2)) //Even if the armor doesn't stop the bullet from hurting you, it might stop it from embedding.
var/hit_embed_chance = P.embed_chance + (P.damage - armor) //More damage equals more chance to embed
+
+ //Modifiers can make bullets less likely to embed!
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_cost) //We use energy_cost here for special effects, such as embedding.
+ hit_embed_chance = hit_embed_chance*M.incoming_damage_percent
+ if(P.damage_type == BRUTE && (!isnull(M.incoming_brute_damage_percent)))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_cost)
+ hit_embed_chance = hit_embed_chance*M.incoming_brute_damage_percent
+
if(prob(max(hit_embed_chance, 0)))
var/obj/item/weapon/material/shard/shrapnel/SP = new()
SP.name = (P.name != "shrapnel")? "[P.name] shrapnel" : "shrapnel"
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index cc0d773af26..2fe479ccafc 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -192,8 +192,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_brute_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -219,8 +223,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_oxy_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_oxy_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -243,8 +251,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_tox_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_tox_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -273,8 +285,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_fire_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -298,8 +314,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_clone_damage_percent))
+ if(M.energy_based)
+ M.energy_source.use(M.energy_modifier*amount)
amount *= M.incoming_clone_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -331,6 +351,9 @@
if(status_flags & GODMODE) return 0 //godmode
if(amount > 0)
for(var/datum/modifier/M in modifiers)
+ if(M.energy_based && (!isnull(M.incoming_hal_damage_percent) || !isnull(M.disable_duration_percent)))
+ M.energy_source.use(M.energy_modifier*amount) // Cost of the Damage absorbed.
+ M.energy_source.use(M.energy_cost) // Cost of the Effect absorbed.
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_hal_damage_percent))
diff --git a/icons/obj/items_vr.dmi b/icons/obj/items_vr.dmi
index ca82649d883..2c2758763cc 100644
Binary files a/icons/obj/items_vr.dmi and b/icons/obj/items_vr.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index fb34f310a1c..91f03dda54f 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1199,6 +1199,7 @@
#include "code\game\objects\items\devices\multitool.dm"
#include "code\game\objects\items\devices\paicard.dm"
#include "code\game\objects\items\devices\paicard_vr.dm"
+#include "code\game\objects\items\devices\personal_shield_generator_vr.dm"
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\spy_bug.dm"