Merge pull request #10110 from mwerezak/shields

Better shield handling
This commit is contained in:
Chinsky
2015-09-03 20:38:48 +03:00
13 changed files with 213 additions and 131 deletions
+41 -3
View File
@@ -63,6 +63,26 @@
armor = list(melee = 10, bullet = 10, laser = 80, energy = 50, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0
/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")
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
var/obj/item/projectile/P = damage_source
var/reflectchance = 40 - round(damage/3)
if(!(def_zone in list("chest", "groin")))
reflectchance /= 2
if(P.starting && prob(reflectchance))
visible_message("<span class='danger'>\The [user]'s [src.name] reflects [attack_text]!</span>")
// Find a turf near or on the original location to bounce to
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(user)
// redirect the projectile
P.redirect(new_x, new_y, curloc, user)
return PROJECTILE_CONTINUE // complete projectile permutation
/obj/item/clothing/suit/armor/swat
name = "swat suit"
desc = "A heavily armored suit that protects against moderate damage. Used in special operations."
@@ -113,9 +133,27 @@
slowdown = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/suit/armor/reactive/IsShield()
if(active)
return 1
/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")
if(prob(50))
user.visible_message("<span class='danger'>The reactive teleport system flings [user] clear of the attack!</span>")
var/list/turfs = new/list()
for(var/turf/T in orange(6, user))
if(istype(T,/turf/space)) continue
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))
var/turf/picked = pick(turfs)
if(!isturf(picked)) return
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, user.loc)
spark_system.start()
playsound(user.loc, "sparks", 50, 1)
user.loc = picked
return PROJECTILE_FORCE_MISS
return 0
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user as mob)
+8 -2
View File
@@ -252,8 +252,14 @@
New()
item_color = "red"
/obj/item/weapon/holo/esword/IsShield()
if(active)
/obj/item/weapon/holo/esword/handle_shield(mob/user, 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("<span class='danger'>\The [user] parries [attack_text] with \the [src]!</span>")
var/datum/effect/effect/system/spark_spread/spark_system = new /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)
return 1
return 0
@@ -19,8 +19,7 @@
// Should this all be in Touch()?
if(istype(H))
if((H != src) && check_shields(0, H.name))
visible_message("\red <B>[H] attempted to touch [src]!</B>")
if(H != src && check_shields(0, null, H, H.zone_sel.selecting, H.name))
H.do_attack_animation(src)
return 0
@@ -16,30 +16,14 @@ emp_act
var/obj/item/organ/external/organ = get_organ()
//Shields
if(check_shields(P.damage, "the [P.name]"))
P.on_hit(src, 2, def_zone)
return 2
//Laserproof armour
if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/armor/laserproof))
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
var/reflectchance = 40 - round(P.damage/3)
if(!(def_zone in list("chest", "groin")))
reflectchance /= 2
if(prob(reflectchance))
visible_message("\red <B>\The [P] gets reflected by \the [src]'s [wear_suit.name]!</B>")
// Find a turf near or on the original location to bounce to
if(P.starting)
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(src)
// redirect the projectile
P.redirect(new_x, new_y, curloc, src)
return PROJECTILE_CONTINUE // complete projectile permutation
//Shields
var/shield_check = check_shields(P.damage, P, null, def_zone, "the [P.name]")
if(shield_check)
if(shield_check < 0)
return shield_check
else
P.on_hit(src, 2, def_zone)
return 2
//Shrapnel
if(P.can_embed())
@@ -148,33 +132,11 @@ emp_act
return gear
return null
/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/attack_text = "the attack")
if(l_hand && istype(l_hand, /obj/item/weapon))//Current base is the prob(50-d/3)
var/obj/item/weapon/I = l_hand
if(I.IsShield() && (prob(50 - round(damage / 3))))
visible_message("\red <B>[src] blocks [attack_text] with the [l_hand.name]!</B>")
return 1
if(r_hand && istype(r_hand, /obj/item/weapon))
var/obj/item/weapon/I = r_hand
if(I.IsShield() && (prob(50 - round(damage / 3))))
visible_message("\red <B>[src] blocks [attack_text] with the [r_hand.name]!</B>")
return 1
if(wear_suit && istype(wear_suit, /obj/item/))
var/obj/item/I = wear_suit
if(I.IsShield() && (prob(35)))
visible_message("\red <B>The reactive teleport system flings [src] clear of [attack_text]!</B>")
var/list/turfs = new/list()
for(var/turf/T in orange(6))
if(istype(T,/turf/space)) continue
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))
var/turf/picked = pick(turfs)
if(!isturf(picked)) return
src.loc = picked
return 1
/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
return 0
/mob/living/carbon/human/emp_act(severity)
@@ -206,7 +168,7 @@ emp_act
if(user.a_intent == "disarm") effective_force = round(I.force/2)
var/hit_area = affecting.name
if((user != src) && check_shields(effective_force, "the [I.name]"))
if((user != src) && check_shields(effective_force, I, user, target_zone, "the [I.name]"))
return 0
if(istype(I,/obj/item/weapon/card/emag))
@@ -329,15 +291,19 @@ emp_act
miss_chance = max(15*(distance-2), 0)
zone = get_zone_with_miss_chance(zone, src, miss_chance, ranged_attack=1)
if(zone && O.thrower != src)
var/shield_check = check_shields(throw_damage, O, thrower, zone, "[O]")
if(shield_check == PROJECTILE_FORCE_MISS)
zone = null
else if(shield_check)
return
if(!zone)
visible_message("\blue \The [O] misses [src] narrowly!")
visible_message("<span class='notice'>\The [O] misses [src] narrowly!</span>")
return
O.throwing = 0 //it hit, so stop moving
if ((O.thrower != src) && check_shields(throw_damage, "[O]"))
return
var/obj/item/organ/external/affecting = get_organ(zone)
var/hit_area = affecting.name
+1
View File
@@ -24,6 +24,7 @@
adjustCloneLoss(damage/(blocked+1))
if(HALLOSS)
adjustHalLoss(damage/(blocked+1))
flash_weak_pain()
updatehealth()
return 1
@@ -50,7 +50,6 @@
/mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone)
flash_weak_pain()
//Being hit while using a cloaking device
var/obj/item/weapon/cloaking_device/C = locate((/obj/item/weapon/cloaking_device) in src)
@@ -237,7 +237,7 @@
var/hit_area = affecting.name
if((user != target) && H.check_shields(7, "the [src.name]"))
if((user != target) && H.check_shields(7, src, user, "\the [src]"))
return
if (target != user && H.getarmor(target_zone, "melee") > 5 && prob(50))