diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index 1171bd7bf79..bfc05a5d88f 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -2,6 +2,10 @@
name = "shield"
block_chance = 50
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
+ var/transparent = FALSE // makes beam projectiles pass through the shield
+
+/obj/item/shield/proc/on_shield_block(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0, attack_type = MELEE_ATTACK)
+ return TRUE
/obj/item/shield/riot
name = "riot shield"
@@ -19,7 +23,17 @@
materials = list(MAT_GLASS=7500, MAT_METAL=1000)
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
+ transparent = TRUE
+ max_integrity = 75
+/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ if(transparent && (hitby.pass_flags & PASSGLASS))
+ return FALSE
+ if(attack_type == THROWN_PROJECTILE_ATTACK)
+ final_block_chance += 30
+ if(attack_type == LEAP_ATTACK)
+ final_block_chance = 100
+ return ..()
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
@@ -27,14 +41,40 @@
user.visible_message("[user] bashes [src] with [W]!")
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
cooldown = world.time
+ else if(istype(W, /obj/item/stack/sheet/mineral/titanium))
+ if (obj_integrity >= max_integrity)
+ to_chat(user, "[src] is already in perfect condition.")
+ else
+ var/obj/item/stack/sheet/mineral/titanium/T = W
+ T.use(1)
+ obj_integrity = max_integrity
+ to_chat(user, "You repair [src] with [T].")
else
return ..()
-/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- if(attack_type == THROWN_PROJECTILE_ATTACK)
- final_block_chance += 30
- if(attack_type == LEAP_ATTACK)
- final_block_chance = 100
+/obj/item/shield/riot/examine(mob/user)
+ ..()
+ var/healthpercent = round((obj_integrity/max_integrity) * 100, 1)
+ switch(healthpercent)
+ if(50 to 99)
+ to_chat(user, "It looks slightly damaged.")
+ if(25 to 50)
+ to_chat(user, "It appears heavily damaged.")
+ if(0 to 25)
+ to_chat(user, "It's falling apart!")
+
+/obj/item/shield/riot/proc/shatter(mob/living/carbon/human/owner)
+ playsound(owner, 'sound/effects/glassbr3.ogg', 100)
+ new /obj/item/shard((get_turf(src)))
+
+/obj/item/shield/riot/on_shield_block(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0, attack_type = MELEE_ATTACK)
+ if (obj_integrity <= damage)
+ var/turf/T = get_turf(owner)
+ T.visible_message("[hitby] destroys [src]!")
+ shatter(owner)
+ qdel(src)
+ return FALSE
+ take_damage(damage)
return ..()
/obj/item/shield/riot/roman
@@ -44,11 +84,19 @@
item_state = "roman_shield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
+ transparent = FALSE
+ materials = list(MAT_METAL=8500)
+ max_integrity = 65
/obj/item/shield/riot/roman/fake
desc = "Bears an inscription on the inside: \"Romanes venio domus\". It appears to be a bit flimsy."
block_chance = 0
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
+ max_integrity = 30
+
+/obj/item/shield/riot/roman/shatter(mob/living/carbon/human/owner)
+ playsound(owner, 'sound/effects/grillehit.ogg', 100)
+ new /obj/item/stack/sheet/metal(get_turf(src))
/obj/item/shield/riot/buckler
name = "wooden buckler"
@@ -60,6 +108,74 @@
materials = list()
resistance_flags = FLAMMABLE
block_chance = 30
+ transparent = FALSE
+ max_integrity = 65
+
+/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
+ playsound(owner, 'sound/effects/bang.ogg', 50)
+ new /obj/item/stack/sheet/mineral/wood(get_turf(src))
+
+/obj/item/shield/riot/flash
+ name = "strobe shield"
+ desc = "A shield with a built in, high intensity light capable of blinding and disorienting suspects. Takes regular handheld flashes as bulbs."
+ icon_state = "flashshield"
+ item_state = "flashshield"
+ var/obj/item/assembly/flash/handheld/embedded_flash
+
+/obj/item/shield/riot/flash/Initialize()
+ . = ..()
+ embedded_flash = new(src)
+
+/obj/item/shield/riot/flash/attack(mob/living/M, mob/user)
+ . = embedded_flash.attack(M, user)
+ update_icon()
+
+/obj/item/shield/riot/flash/attack_self(mob/living/carbon/user)
+ . = embedded_flash.attack_self(user)
+ update_icon()
+
+/obj/item/shield/riot/flash/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ . = ..()
+ if (. && !embedded_flash.crit_fail)
+ embedded_flash.activate()
+ update_icon()
+
+
+/obj/item/shield/riot/flash/attackby(obj/item/W, mob/user)
+ if(istype(W, /obj/item/assembly/flash/handheld))
+ var/obj/item/assembly/flash/handheld/flash = W
+ if(flash.crit_fail)
+ to_chat(user, "No sense replacing it with a broken bulb.")
+ return
+ else
+ to_chat(user, "You begin to replace the bulb.")
+ if(do_after(user, 20, target = user))
+ if(flash.crit_fail || !flash || QDELETED(flash))
+ return
+ playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
+ qdel(embedded_flash)
+ embedded_flash = flash
+ flash.forceMove(src)
+ update_icon()
+ return
+ ..()
+
+/obj/item/shield/riot/flash/emp_act(severity)
+ . = ..()
+ embedded_flash.emp_act(severity)
+ update_icon()
+
+/obj/item/shield/riot/flash/update_icon()
+ if(!embedded_flash || embedded_flash.crit_fail)
+ icon_state = "riot"
+ item_state = "riot"
+ else
+ icon_state = "flashshield"
+ item_state = "flashshield"
+
+/obj/item/shield/riot/flash/examine(mob/user)
+ ..()
+ to_chat(user, "The mounted bulb has burnt out. You can try replacing it with a new one.")
/obj/item/shield/energy
name = "energy combat shield"
diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm
index 8ec25ab5c91..ff2874715ea 100644
--- a/code/modules/assembly/flash.dm
+++ b/code/modules/assembly/flash.dm
@@ -249,79 +249,15 @@
/obj/item/assembly/flash/armimplant/proc/cooldown()
overheat = FALSE
-/obj/item/assembly/flash/shield
- name = "strobe shield"
- desc = "A shield with a built in, high intensity light capable of blinding and disorienting suspects. Takes regular handheld flashes as bulbs."
- icon = 'icons/obj/items_and_weapons.dmi'
- icon_state = "flashshield"
- item_state = "flashshield"
- lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
- slot_flags = ITEM_SLOT_BACK
- force = 10
- throwforce = 5
- throw_speed = 2
- throw_range = 3
- w_class = WEIGHT_CLASS_BULKY
- materials = list(MAT_GLASS=7500, MAT_METAL=1000)
- attack_verb = list("shoved", "bashed")
- block_chance = 50
- armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
-
-/obj/item/assembly/flash/shield/flash_recharge(interval=10)
- if(times_used >= 4)
- burn_out()
- return FALSE
- return TRUE
-
-/obj/item/assembly/flash/shield/attackby(obj/item/W, mob/user)
- if(istype(W, /obj/item/assembly/flash/handheld))
- var/obj/item/assembly/flash/handheld/flash = W
- if(flash.crit_fail)
- to_chat(user, "No sense replacing it with a broken bulb.")
- return
- else
- to_chat(user, "You begin to replace the bulb.")
- if(do_after(user, 20, target = src))
- if(flash.crit_fail || !flash || QDELETED(flash))
- return
- crit_fail = FALSE
- times_used = 0
- playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
- update_icon()
- flash.crit_fail = TRUE
- flash.update_icon()
- return
- ..()
-
-/obj/item/assembly/flash/shield/update_icon(flash = FALSE)
- icon_state = "flashshield"
- item_state = "flashshield"
-
- if(crit_fail)
- icon_state = "riot"
- item_state = "riot"
- else if(flash)
- icon_state = "flashshield_flash"
- item_state = "flashshield_flash"
- addtimer(CALLBACK(src, .proc/update_icon), 5)
-
- if(holder)
- holder.update_icon()
-
-/obj/item/assembly/flash/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- activate()
- return ..()
-
/obj/item/assembly/flash/hypnotic
desc = "A modified flash device, programmed to emit a sequence of subliminal flashes that can send a vulnerable target into a hypnotic trance."
flashing_overlay = "flash-hypno"
light_color = LIGHT_COLOR_PINK
cooldown = 20
-
+
/obj/item/assembly/flash/hypnotic/burn_out()
return
-
+
/obj/item/assembly/flash/hypnotic/flash_carbon(mob/living/carbon/M, mob/user, power = 15, targeted = TRUE, generic_message = FALSE)
if(!istype(M))
return
@@ -337,25 +273,25 @@
if(M.hypnosis_vulnerable())
hypnosis = TRUE
if(user)
- user.visible_message("[user] blinds [M] with the flash!", "You hypno-flash [M]!")
-
+ user.visible_message("[user] blinds [M] with the flash!", "You hypno-flash [M]!")
+
if(!hypnosis)
to_chat(M, "The light makes you feel oddly relaxed...")
M.confused += min(M.confused + 10, 20)
M.dizziness += min(M.dizziness + 10, 20)
M.drowsyness += min(M.drowsyness + 10, 20)
- M.apply_status_effect(STATUS_EFFECT_PACIFY, 100)
+ M.apply_status_effect(STATUS_EFFECT_PACIFY, 100)
else
- M.apply_status_effect(/datum/status_effect/trance, 200, TRUE)
-
+ M.apply_status_effect(/datum/status_effect/trance, 200, TRUE)
+
else if(user)
user.visible_message("[user] fails to blind [M] with the flash!", "You fail to hypno-flash [M]!")
else
to_chat(M, "[src] fails to blind you!")
-
+
else if(M.flash_act())
to_chat(M, "Such a pretty light...")
M.confused += min(M.confused + 4, 20)
M.dizziness += min(M.dizziness + 4, 20)
M.drowsyness += min(M.drowsyness + 4, 20)
- M.apply_status_effect(STATUS_EFFECT_PACIFY, 40)
\ No newline at end of file
+ M.apply_status_effect(STATUS_EFFECT_PACIFY, 40)
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index 948b3cafd21..6e56e7d6029 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -47,7 +47,7 @@
/datum/crafting_recipe/strobeshield
name = "Strobe Shield"
- result = /obj/item/assembly/flash/shield
+ result = /obj/item/shield/riot/flash
reqs = list(/obj/item/wallframe/flasher = 1,
/obj/item/assembly/flash/handheld = 1,
/obj/item/shield/riot = 1)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index af8e9cf7dbc..df48f153570 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -105,6 +105,9 @@
if(!istype(I, /obj/item/clothing))
var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
+ if (istype(I, /obj/item/shield))
+ var/obj/item/shield/S = I
+ return S.on_shield_block(src, AM, attack_text, damage, attack_type)
return 1
if(wear_suit)
var/final_block_chance = wear_suit.block_chance - (CLAMP((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier