diff --git a/code/datums/martial.dm b/code/datums/martial.dm
index 32cff9c168c..71dca89f54f 100644
--- a/code/datums/martial.dm
+++ b/code/datums/martial.dm
@@ -482,6 +482,7 @@
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
icon = 'icons/obj/weapons.dmi'
icon_state = "bostaff0"
+ block_chance = 50
/obj/item/weapon/twohanded/bostaff/update_icon()
icon_state = "bostaff[wielded]"
@@ -539,8 +540,7 @@
return ..()
return ..()
-/obj/item/weapon/twohanded/bostaff/IsShield()
+/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
if(wielded)
- return 1
- else
- return 0
+ return ..()
+ return 0
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 97dfc82ffd8..372262aeb30 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -286,12 +286,12 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
containername = "tactical armor crate"
/datum/supply_packs/security/armory/laserarmor
- name = "Ablative Armor Crate"
+ name = "Reflector Vest Crate"
contains = list(/obj/item/clothing/suit/armor/laserproof,
/obj/item/clothing/suit/armor/laserproof) // Only two vests to keep costs down for balance
cost = 20
containertype = /obj/structure/closet/crate/secure/plasma
- containername = "ablative armor crate"
+ containername = "reflector vest crate"
/////// Weapons: Specialist
diff --git a/code/game/gamemodes/abduction/abduction_gear.dm b/code/game/gamemodes/abduction/abduction_gear.dm
index 75f2066ba27..a14280395e6 100644
--- a/code/game/gamemodes/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/abduction/abduction_gear.dm
@@ -77,9 +77,10 @@
M.regenerate_icons()
return
-/obj/item/clothing/suit/armor/abductor/vest/IsShield()
+/obj/item/clothing/suit/armor/abductor/vest/hit_reaction()
DeactivateStealth()
return 0
+
/obj/item/clothing/suit/armor/abductor/vest/IsReflect()
DeactivateStealth()
return 0
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index 59f08343ef0..4640b1fe26c 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -227,6 +227,7 @@
flags = ABSTRACT | NODROP
icon = 'icons/obj/weapons.dmi'
icon_state = "ling_shield"
+ block_chance = 50
var/remaining_uses //Set by the changeling ability.
@@ -238,7 +239,7 @@
/obj/item/clothing/head/helmet/space/changeling/dropped()
qdel(src)
-/obj/item/weapon/shield/changeling/IsShield()
+/obj/item/weapon/shield/changeling/hit_reaction()
if(remaining_uses < 1)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
@@ -248,7 +249,7 @@
return 0
else
remaining_uses--
- return 1
+ return ..()
/***************************************\
diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm
index 8294e1831eb..9f1c99cea84 100644
--- a/code/game/gamemodes/objective_items.dm
+++ b/code/game/gamemodes/objective_items.dm
@@ -59,8 +59,8 @@
difficulty = 5
excludefromjob = list("Captain")
-/datum/objective_item/steal/ablative
- name = "an ablative armor vest"
+/datum/objective_item/steal/reflector
+ name = "a reflector vest"
targetitem = /obj/item/clothing/suit/armor/laserproof
difficulty = 3
excludefromjob = list("Head of Security", "Warden")
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index bfbd12f0b99..a033392c4fc 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -99,13 +99,15 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
var/sharpness = IS_BLUNT
var/toolspeed = 1
+ var/block_chance = 0
+ var/hit_reaction_chance = 0 //If you want to have something unrelated to blocking/armour piercing etc. Maybe not needed, but trying to think ahead/allow more freedom
+
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
if(((src in target) && !target_self) || ((!istype(target.loc, /turf)) && (!istype(target, /turf)) && (not_inside)) || is_type_in_list(target, can_be_placed_into))
return 0
else
return 1
-
/obj/item/device
icon = 'icons/obj/device.dmi'
@@ -315,6 +317,12 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency
+/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0)
+ if(prob(final_block_chance))
+ owner.visible_message("[owner] blocks [attack_text] with [src]!")
+ return 1
+ return 0
+
/obj/item/proc/talk_into(mob/M, input, channel, spans)
return
@@ -372,9 +380,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
/obj/item/proc/ui_action_click()
attack_self(usr)
-/obj/item/proc/IsShield()
- return 0
-
/obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit
return 0
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index b5042a9f868..4552aff3498 100755
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -288,7 +288,7 @@
origin_tech = null
attack_verb = list("attacked", "struck", "hit")
-/obj/item/weapon/twohanded/dualsaber/toy/IsShield()
+/obj/item/weapon/twohanded/dualsaber/toy/hit_reaction()
return 0
/obj/item/weapon/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 4a79da30820..f3ce9565824 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -55,15 +55,16 @@
embedded_impact_pain_multiplier = 10
flags = NOSHIELD
origin_tech = "magnets=3;syndicate=4"
+ block_chance = 50
var/hacked = 0
/obj/item/weapon/melee/energy/sword/New()
if(item_color == null)
item_color = pick("red", "blue", "green", "purple")
-/obj/item/weapon/melee/energy/sword/IsShield()
+/obj/item/weapon/melee/energy/sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
if(active)
- return 1
+ return ..()
return 0
/obj/item/weapon/melee/energy/attack_self(mob/living/carbon/user)
@@ -136,7 +137,7 @@
icon_state = "esaw_0"
item_color = null
-/obj/item/weapon/melee/energy/sword/cyborg/saw/IsShield()
+/obj/item/weapon/melee/energy/sword/cyborg/saw/hit_reaction()
return 0
/obj/item/weapon/melee/energy/sword/saber
diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm
index e1ce991115a..08bd5d773f1 100644
--- a/code/game/objects/items/weapons/shields.dm
+++ b/code/game/objects/items/weapons/shields.dm
@@ -1,5 +1,6 @@
/obj/item/weapon/shield
name = "shield"
+ block_chance = 50
/obj/item/weapon/shield/riot
name = "riot shield"
@@ -17,8 +18,6 @@
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
-/obj/item/weapon/shield/riot/IsShield()
- return 1
/obj/item/weapon/shield/riot/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/melee/baton))
@@ -49,8 +48,10 @@
attack_verb = list("shoved", "bashed")
var/active = 0
-/obj/item/weapon/shield/energy/IsShield()
- return (active)
+/obj/item/weapon/shield/energy/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
+ if(active)
+ return ..()
+ return 0
/obj/item/weapon/shield/energy/IsReflect()
return (active)
@@ -91,8 +92,10 @@
w_class = 3
var/active = 0
-/obj/item/weapon/shield/riot/tele/IsShield()
- return (active)
+/obj/item/weapon/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
+ if(active)
+ return ..()
+ return 0
/obj/item/weapon/shield/riot/tele/attack_self(mob/living/user)
active = !active
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index b685d8da477..650e78dac30 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -115,13 +115,16 @@
/obj/item/weapon/twohanded/offhand/wield()
qdel(src)
-/obj/item/weapon/twohanded/offhand/IsShield()//if the actual twohanded weapon is a shield, we count as a shield too!
+/obj/item/weapon/twohanded/offhand/hit_reaction()//if the actual twohanded weapon is a shield, we count as a shield too!
var/mob/user = loc
- if(!istype(user)) return 0
+ if(!istype(user))
+ return 0
var/obj/item/I = user.get_active_hand()
- if(I == src) I = user.get_inactive_hand()
- if(!I) return 0
- return I.IsShield()
+ if(I == src)
+ I = user.get_inactive_hand()
+ if(!I)
+ return 0
+ return I.hit_reaction()
///////////Two hand required objects///////////////
//This is for objects that require two hands to even pick up
@@ -209,6 +212,7 @@
origin_tech = "magnets=3;syndicate=4"
item_color = "green"
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ block_chance = 50
var/hacked = 0
/obj/item/weapon/twohanded/dualsaber/New()
@@ -240,11 +244,10 @@
else
user.adjustStaminaLoss(25)
-/obj/item/weapon/twohanded/dualsaber/IsShield()
+/obj/item/weapon/twohanded/dualsaber/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
if(wielded)
- return 1
- else
- return 0
+ return ..()
+ return 0
/obj/item/weapon/twohanded/dualsaber/attack_hulk(mob/living/carbon/human/user) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up
if(wielded)
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 7b30c4a03e0..667fc9e1b16 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -64,9 +64,7 @@
throwforce = 10
w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
-
-/obj/item/weapon/claymore/IsShield()
- return 1
+ block_chance = 50
/obj/item/weapon/claymore/suicide_act(mob/user)
user.visible_message("[user] is falling on the [src.name]! It looks like \he's trying to commit suicide.")
@@ -84,6 +82,7 @@
w_class = 3
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ block_chance = 50
/obj/item/weapon/katana/cursed
slot_flags = null
@@ -92,9 +91,6 @@
user.visible_message("[user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.")
return(BRUTELOSS)
-/obj/item/weapon/katana/IsShield()
- return 1
-
/obj/item/weapon/wirerod
name = "wired rod"
desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit."
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 00c9497c731..3504afd1c98 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -220,8 +220,6 @@ BLIND // can't see anything
if(blood_DNA)
. += image("icon"='icons/effects/blood.dmi', "icon_state"="[blood_overlay_type]blood")
-
-
//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 4bda702b96b..b2219ef32e9 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -134,11 +134,8 @@
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
action_button_name = "Toggle Armor"
unacidable = 1
+ hit_reaction_chance = 50
-/obj/item/clothing/suit/armor/reactive/IsShield()
- if(active)
- return 1
- return 0
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
src.active = !( src.active )
@@ -159,6 +156,46 @@
src.item_state = "reactiveoff"
..()
+/obj/item/clothing/suit/armor/reactive/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
+ if(!active)
+ return 0
+ if(prob(hit_reaction_chance))
+ var/mob/living/carbon/human/H = owner
+ owner.visible_message("The reactive teleport system flings [H] clear of [attack_text]!")
+ var/list/turfs = new/list()
+ for(var/turf/T in orange(6, H))
+ if(T.density)
+ continue
+ if(T.x>world.maxx-6 || T.x<6)
+ continue
+ if(T.y>world.maxy-6 || T.y<6)
+ continue
+ turfs += T
+ if(!turfs.len)
+ turfs += pick(/turf in orange(6, src))
+ var/turf/picked = pick(turfs)
+ if(!isturf(picked))
+ return
+ if(H.buckled)
+ H.buckled.unbuckle_mob()
+ H.forceMove(picked)
+ return 1
+ return 0
+
+/obj/item/clothing/suit/armor/reactive/fire
+ name = "reactive incendiary armor"
+
+
+/obj/item/clothing/suit/armor/reactive/fire/hit_reaction(mob/living/carbon/human/owner, attack_text)
+ if(prob(hit_reaction_chance))
+ owner.visible_message("The [src] blocks the [attack_text], sending out jets of flame!")
+ for(var/mob/living/carbon/C in range(6, owner))
+ if(C != owner)
+ C.fire_stacks += 8
+ C.IgniteMob()
+ owner.fire_stacks = -20
+ return 1
+ return 0
//All of the armor below is mostly unused
diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm
index 5a66c2d61a0..25a2027e4c7 100644
--- a/code/modules/clothing/under/jobs/civilian.dm
+++ b/code/modules/clothing/under/jobs/civilian.dm
@@ -59,6 +59,9 @@
fitted = FEMALE_UNIFORM_TOP
can_adjust = 0
+/obj/item/clothing/under/rank/clown/hit_reaction()
+ playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1)
+ return 0
/obj/item/clothing/under/rank/head_of_personnel
desc = "It's a jumpsuit worn by someone who works in the position of \"Head of Personnel\"."
diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm
index a2839eeb6ec..2c344adf61f 100644
--- a/code/modules/holodeck/items.dm
+++ b/code/modules/holodeck/items.dm
@@ -31,9 +31,9 @@
New()
item_color = "red"
-/obj/item/weapon/holo/esword/IsShield()
+/obj/item/weapon/holo/esword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
if(active)
- return 1
+ return ..()
return 0
/obj/item/weapon/holo/esword/attack(target as mob, mob/user as mob)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index e5e66dd7e27..d5a265800e6 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -82,41 +82,25 @@ emp_act
//End Here
/mob/living/carbon/human/proc/check_shields(damage = 0, attack_text = "the attack", atom/movable/AM, thrown_proj = 0, armour_penetration = 0)
- var/block_chance = 50 + 30*thrown_proj - round(damage / 3) //thrown things are easier to block
+ var/block_chance_modifier = 30*thrown_proj - round(damage / 3) //thrown things are easier to block
if(AM)
if(AM.flags & NOSHIELD) //weapon ignores shields altogether
return 0
- var/blocker
- if(l_hand)
- if(l_hand.IsShield())
- block_chance -= Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100) //So armour piercing blades can still be parried by other blades, for example
- if(prob(block_chance))
- blocker = l_hand
- if(r_hand)
- if(r_hand.IsShield())
- block_chance -= Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)
- if(prob(block_chance))
- blocker = r_hand
- if(blocker)
- visible_message("[src] blocks [attack_text] with [blocker]!", \
- "[src] blocks [attack_text] with [blocker]!")
- return 1
+ if(l_hand && !istype(l_hand, /obj/item/clothing))
+ var/final_block_chance = l_hand.block_chance - (Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
+ if(l_hand.hit_reaction(src, attack_text, final_block_chance))
+ return 1
+ if(r_hand && !istype(r_hand, /obj/item/clothing))
+ var/final_block_chance = r_hand.block_chance - (Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts
+ if(r_hand.hit_reaction(src, attack_text, final_block_chance))
+ return 1
if(wear_suit)
- if(wear_suit.IsShield() && (prob(50)))
- visible_message("The reactive teleport system flings [src] clear of [attack_text]!", \
- "The reactive teleport system flings [src] clear of [attack_text]!")
- var/list/turfs = new/list()
- for(var/turf/T in orange(6, src))
- if(T.density) continue
- if(T.x>world.maxx-6 || T.x<6) continue
- if(T.y>world.maxy-6 || T.y<6) continue
- turfs += T
- if(!turfs.len) turfs += pick(/turf in orange(6, src))
- var/turf/picked = pick(turfs)
- if(!isturf(picked)) return
- if(buckled)
- buckled.unbuckle_mob()
- forceMove(picked)
+ var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
+ if(wear_suit.hit_reaction(src, attack_text, final_block_chance))
+ return 1
+ if(w_uniform)
+ var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
+ if(w_uniform.hit_reaction(src, attack_text, final_block_chance))
return 1
return 0
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index c1a304e6b72..98d72daabdd 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -884,7 +884,7 @@
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H)
if(!istype(M)) //sanity check for drones.
return
- if((M != H) && H.check_shields(0, M.name))
+ if((M != H) && M.a_intent != "help" && H.check_shields(0, M.name))
add_logs(M, H, "attempted to touch")
H.visible_message("[M] attempted to touch [H]!")
return 0
@@ -1005,8 +1005,8 @@
// Allows you to put in item-specific reactions based on species
if(user != H)
user.do_attack_animation(H)
- if(H.check_shields(I.force, "the [I.name]", I, 0, I.armour_penetration))
- return 0
+ if(H.check_shields(I.force, "the [I.name]", I, 0, I.armour_penetration))
+ return 0
if(I.attack_verb && I.attack_verb.len)
H.visible_message("[user] has [pick(I.attack_verb)] [H] in the [hit_area] with [I]!", \