//** Shield Helpers //These are shared by various items that have shield-like behaviour //bad_arc is the ABSOLUTE arc of directions from which we cannot block. If you want to fix it to e.g. the user's facing you will need to rotate the dirs yourself. /proc/check_shield_arc(mob/user, var/bad_arc, atom/damage_source = null, mob/attacker = null) //check attack direction var/attack_dir = 0 //direction from the user to the source of the attack if(istype(damage_source, /obj/item/projectile)) var/obj/item/projectile/P = damage_source attack_dir = get_dir(get_turf(user), P.starting) else if(attacker) attack_dir = get_dir(get_turf(user), get_turf(attacker)) else if(damage_source) attack_dir = get_dir(get_turf(user), get_turf(damage_source)) if(!(attack_dir && (attack_dir & bad_arc))) return 1 return 0 /proc/default_parry_check(mob/user, mob/attacker, atom/damage_source) //parry only melee attacks if(istype(damage_source, /obj/item/projectile) || (attacker && get_dist(user, attacker) > 1) || user.incapacitated()) return 0 //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 if(!check_shield_arc(user, bad_arc, damage_source, attacker)) return 0 return 1 /obj/item/weapon/shield name = "shield" var/base_block_chance = 50 /obj/item/weapon/shield/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") if(user.incapacitated()) return 0 //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 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/weapon/shield/proc/get_block_chance(mob/user, var/damage, atom/damage_source = null, mob/attacker = null) return base_block_chance /obj/item/weapon/shield/riot name = "riot shield" desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder." icon = 'icons/obj/weapons.dmi' icon_state = "riot" flags = CONDUCT slot_flags = SLOT_BACK force = 5.0 throwforce = 5.0 throw_speed = 1 throw_range = 4 w_class = 4.0 origin_tech = list(TECH_MATERIAL = 2) matter = list("glass" = 7500, DEFAULT_WALL_MATERIAL = 1000) attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time /obj/item/weapon/shield/riot/handle_shield(mob/user) . = ..() if(.) playsound(user.loc, 'sound/weapons/Genhit.ogg', 50, 1) /obj/item/weapon/shield/riot/get_block_chance(mob/user, var/damage, atom/damage_source = null, mob/attacker = null) if(istype(damage_source, /obj/item/projectile)) var/obj/item/projectile/P = damage_source //plastic shields do not stop bullets or lasers, even in space. Will block beanbags, rubber bullets, and stunshots just fine though. if((is_sharp(P) && damage > 10) || istype(P, /obj/item/projectile/beam)) return 0 return base_block_chance /obj/item/weapon/shield/riot/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/melee/baton)) if(cooldown < world.time - 25) user.visible_message("[user] bashes [src] with [W]!") playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1) cooldown = world.time else ..() /* * Energy Shield */ /obj/item/weapon/shield/energy name = "energy combat shield" desc = "A shield capable of stopping most projectile and melee attacks. It can be retracted, expanded, and stored anywhere." icon = 'icons/obj/weapons.dmi' icon_state = "eshield0" // eshield1 for expanded slot_flags = SLOT_EARS flags = CONDUCT force = 3.0 throwforce = 5.0 throw_speed = 1 throw_range = 4 w_class = 2 origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 3, TECH_ILLEGAL = 4) attack_verb = list("shoved", "bashed") var/active = 0 /obj/item/weapon/shield/energy/handle_shield(mob/user) if(!active) return 0 //turn it on first! . = ..() if(.) var/datum/effect/effect/system/spark_spread/spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread) spark_system.set_up(5, 0, user.loc) spark_system.start() playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1) /obj/item/weapon/shield/energy/get_block_chance(mob/user, var/damage, atom/damage_source = null, mob/attacker = null) if(istype(damage_source, /obj/item/projectile)) var/obj/item/projectile/P = damage_source if((is_sharp(P) && damage > 10) || istype(P, /obj/item/projectile/beam)) return (base_block_chance - round(damage / 3)) //block bullets and beams using the old block chance return base_block_chance /obj/item/weapon/shield/energy/attack_self(mob/living/user as mob) if ((CLUMSY in user.mutations) && prob(50)) user << "You beat yourself in the head with [src]." user.take_organ_damage(5) active = !active if (active) force = 10 update_icon() w_class = 4 slot_flags = null playsound(user, 'sound/weapons/saberon.ogg', 50, 1) user << "\The [src] is now active." else force = 3 update_icon() w_class = 1 slot_flags = SLOT_EARS playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) user << "\The [src] can now be concealed." if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user H.update_inv_l_hand() H.update_inv_r_hand() add_fingerprint(user) return /obj/item/weapon/shield/energy/update_icon() icon_state = "eshield[active]" if(active) set_light(1.5, 1.5, "#006AFF") else set_light(0) /obj/item/weapon/cloaking_device name = "cloaking device" desc = "Use this to become invisible to the human eye." icon = 'icons/obj/device.dmi' icon_state = "shield0" var/active = 0.0 flags = CONDUCT item_state = "electronic" throwforce = 10.0 throw_speed = 2 throw_range = 10 w_class = 2.0 origin_tech = list(TECH_MAGNET = 3, TECH_ILLEGAL = 4) /obj/item/weapon/cloaking_device/attack_self(mob/user as mob) src.active = !( src.active ) if (src.active) user << "\The [src] is now active." src.icon_state = "shield1" else user << "\The [src] is now inactive." src.icon_state = "shield0" src.add_fingerprint(user) return /obj/item/weapon/cloaking_device/emp_act(severity) active = 0 icon_state = "shield0" if(ismob(loc)) loc:update_icons() ..() /obj/item/weapon/shield/riot/tele name = "telescopic shield" desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." icon = 'icons/obj/weapons.dmi' icon_state = "teleriot0" slot_flags = null force = 3 throwforce = 3 throw_speed = 3 throw_range = 4 w_class = 3 var/active = 0 /* /obj/item/weapon/shield/energy/IsShield() if(active) return 1 else return 0 */ /obj/item/weapon/shield/riot/tele/attack_self(mob/living/user) active = !active icon_state = "teleriot[active]" playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) if(active) force = 8 throwforce = 5 throw_speed = 2 w_class = 4 slot_flags = SLOT_BACK user << "You extend \the [src]." else force = 3 throwforce = 3 throw_speed = 3 w_class = 3 slot_flags = null user << "[src] can now be concealed." if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user H.update_inv_l_hand() H.update_inv_r_hand() add_fingerprint(user) return