diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index d9fd71f5fca..ea5a48f4366 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -524,9 +524,12 @@ var/list/global/slot_flags_enumeration = list(
//If a negative value is returned, it should be treated as a special return value for bullet_act() and handled appropriately.
//For non-projectile attacks this usually means the attack is blocked.
//Otherwise should return 0 to indicate that the attack is not affected in any way.
-/obj/item/proc/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/proc/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
return 0
+/obj/item/proc/can_shield_back()
+ return
+
/obj/item/proc/get_loc_turf()
var/atom/L = loc
while(L && !istype(L, /turf/))
diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm
index 48c5ddb9890..5fd76f533c2 100644
--- a/code/game/objects/items/weapons/material/swords.dm
+++ b/code/game/objects/items/weapons/material/swords.dm
@@ -19,7 +19,7 @@
drop_sound = 'sound/items/drop/sword.ogg'
pickup_sound = 'sound/items/pickup/sword.ogg'
-/obj/item/material/sword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/material/sword/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
var/parry_bonus = 1
if(ishuman(user))
diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm
index a271adb6dc9..3d006eae207 100644
--- a/code/game/objects/items/weapons/material/twohanded.dm
+++ b/code/game/objects/items/weapons/material/twohanded.dm
@@ -80,7 +80,7 @@
return unwield()
//Allow a small chance of parrying melee attacks when wielded - maybe generalize this to other weapons someday
-/obj/item/material/twohanded/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/material/twohanded/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(wielded && default_parry_check(user, attacker, damage_source) && prob(parry_chance))
user.visible_message("\The [user] parries [attack_text] with \the [src]!")
playsound(user.loc, 'sound/weapons/punchmiss.ogg', 50, 1)
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 563b7a7ae8d..831a214dee3 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -62,7 +62,7 @@
add_fingerprint(user)
return
-/obj/item/melee/energy/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/melee/energy/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(active && default_parry_check(user, attacker, damage_source) && prob(50))
user.visible_message("\The [user] parries [attack_text] with \the [src]!")
diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm
index dfb098eba24..758deb33e06 100644
--- a/code/game/objects/items/weapons/shields.dm
+++ b/code/game/objects/items/weapons/shields.dm
@@ -39,18 +39,25 @@
)
var/base_block_chance = 50
-/obj/item/shield/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/shield/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(user.incapacitated())
return 0
+ var/shield_dir = reverse_dir[user.dir]
+ if(on_back)
+ shield_dir = user.dir
+
//block as long as they are not directly behind us
- var/bad_arc = reverse_direction(user.dir) //arc of directions from which we cannot block
+ var/bad_arc = shield_dir //arc of directions from which we cannot block
if(check_shield_arc(user, bad_arc, damage_source, attacker))
if(prob(get_block_chance(user, damage, damage_source, attacker)))
user.visible_message("\The [user] blocks [attack_text] with \the [src]!")
return 1
return 0
+/obj/item/shield/can_shield_back()
+ return TRUE
+
/obj/item/shield/proc/get_block_chance(mob/user, var/damage, atom/damage_source = null, mob/attacker = null)
return base_block_chance
@@ -139,7 +146,7 @@
var/shield_power = 150
var/active = 0
-/obj/item/shield/energy/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/shield/energy/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(!active)
return 0 //turn it on first!
@@ -150,8 +157,12 @@
spark(user.loc, 5)
playsound(user.loc, 'sound/weapons/blade.ogg', 50, 1)
+ var/shield_dir = reverse_dir[user.dir]
+ if(on_back)
+ shield_dir = user.dir
+
//block as long as they are not directly behind us
- var/bad_arc = reverse_direction(user.dir) //arc of directions from which we cannot block
+ var/bad_arc = shield_dir //arc of directions from which we cannot block
if(check_shield_arc(user, bad_arc, damage_source, attacker))
if(prob(get_block_chance(user, damage, damage_source, attacker)))
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index a413769e820..a3358aac98c 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -200,7 +200,7 @@
playsound(src.loc, "shatter", 70, 1)
qdel(src)
-/obj/item/clothing/suit/armor/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/clothing/suit/armor/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(!material) // No point checking for reflection.
return ..()
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 58e5f30013c..f4c10a9461e 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -130,7 +130,7 @@
siemens_coefficient = 0
pocket_slots = 4
-/obj/item/clothing/suit/armor/laserproof/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/clothing/suit/armor/laserproof/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
var/obj/item/projectile/P = damage_source
@@ -200,7 +200,7 @@
slowdown = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
-/obj/item/clothing/suit/armor/reactive/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/clothing/suit/armor/reactive/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(prob(50))
user.visible_message("The reactive teleport system flings [user] clear of the attack!")
var/list/turfs = new/list()
diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm
index da507ae92c2..55bbf9a4694 100644
--- a/code/modules/holodeck/HolodeckObjects.dm
+++ b/code/modules/holodeck/HolodeckObjects.dm
@@ -263,7 +263,7 @@
New()
item_color = "red"
-/obj/item/holo/esword/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+/obj/item/holo/esword/handle_shield(mob/user, var/on_back, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(active && default_parry_check(user, attacker, damage_source) && prob(50))
user.visible_message("\The [user] parries [attack_text] with \the [src]!")
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 18878cdba97..f7b63e645bc 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -168,10 +168,17 @@ emp_act
return null
/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/atom/damage_source = null, var/mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
- for(var/obj/item/shield in list(l_hand, r_hand, wear_suit))
- if(!shield) continue
- . = shield.handle_shield(src, damage, damage_source, attacker, def_zone, attack_text)
- if(.) return
+ for(var/obj/item/shield in list(l_hand, r_hand, wear_suit, back))
+ if(!shield)
+ continue
+ if(!shield.can_shield_back())
+ continue
+ var/is_on_back = FALSE
+ if(back && back == shield)
+ is_on_back = TRUE
+ . = shield.handle_shield(src, is_on_back, damage, damage_source, attacker, def_zone, attack_text)
+ if(.)
+ return
return 0
/mob/living/carbon/human/emp_act(severity)
diff --git a/html/changelogs/geeves-back_shield.yml b/html/changelogs/geeves-back_shield.yml
new file mode 100644
index 00000000000..3006ad2622d
--- /dev/null
+++ b/html/changelogs/geeves-back_shield.yml
@@ -0,0 +1,6 @@
+author: Geeves
+
+delete-after: True
+
+changes:
+ - rscadd: "A shield worn on your back will now properly defend you from penetration in the rear."
\ No newline at end of file