Fixes human armor value for full body effects not being weighted by body part

This was an issue because it meant that not having hand or feet
protection reduced the player's protection from full body effects much
more than it should have, and meant that not having your hands protected
was just as bad as not having your chest protected.
This commit is contained in:
mwerezak
2014-08-22 01:12:07 -04:00
parent 1477fe17ab
commit ec52bf830d
3 changed files with 69 additions and 47 deletions

View File

@@ -84,7 +84,7 @@ emp_act
/mob/living/carbon/human/getarmor(var/def_zone, var/type)
var/armorval = 0
var/organnum = 0
var/total = 0
if(def_zone)
if(isorgan(def_zone))
@@ -94,10 +94,13 @@ emp_act
//If a specific bodypart is targetted, check how that bodypart is protected and return the value.
//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
for(var/datum/organ/external/organ in organs)
armorval += getarmor_organ(organ, type)
organnum++
return (armorval/max(organnum, 1))
for(var/organ_name in organs_by_name)
if (organ_name in organ_rel_size)
var/datum/organ/external/organ = organs_by_name[organ_name]
var/weight = organ_rel_size[organ_name]
armorval += getarmor_organ(organ, type) * weight
total += weight
return (armorval/max(total, 1))
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/datum/organ/external/def_zone)
@@ -117,11 +120,10 @@ emp_act
/mob/living/carbon/human/proc/getarmor_organ(var/datum/organ/external/def_zone, var/type)
if(!type) return 0
var/protection = 0
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
for(var/bp in body_parts)
if(!bp) continue
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform)
for(var/gear in protective_gear)
if(gear && istype(gear ,/obj/item/clothing))
var/obj/item/clothing/C = gear
if(C.body_parts_covered & def_zone.body_part)
protection += C.armor[type]
return protection

View File

@@ -52,7 +52,8 @@
if(AGONY)
halloss += effect // Useful for objects that cause "subdual" damage. PAIN!
if(IRRADIATE)
radiation += max((((effect - (effect*(getarmor(null, "rad")/100))))/(blocked+1)),0)//Rads auto check armor
var/rad_protection = getarmor(null, "rad")/100
radiation += max((1-rad_protection)*effect/(blocked+1),0)//Rads auto check armor
if(STUTTER)
if(status_flags & CANSTUN) // stun is usually associated with stutter
stuttering = max(stuttering,(effect/(blocked+1)))

View File

@@ -119,8 +119,44 @@ proc/hasorgans(A)
return ishuman(A)
/proc/hsl2rgb(h, s, l)
return
return //TODO: Implement
/*
Miss Chance
*/
//TODO: Integrate defence zones and targeting body parts with the actual organ system, move these into organ definitions.
//The base miss chance for the different defence zones
var/list/global/base_miss_chance = list(
"head" = 40,
"chest" = 10,
"groin" = 20,
"l_leg" = 20,
"r_leg" = 20,
"l_arm" = 20,
"r_arm" = 20,
"l_hand" = 50,
"r_hand" = 50,
"l_foot" = 50,
"r_foot" = 50,
)
//Used to weight organs when an organ is hit randomly (i.e. not a directed, aimed attack).
//Also used to weight the protection value that armour provides for covering that body part when calculating protection from full-body effects.
var/list/global/organ_rel_size = list(
"head" = 20,
"chest" = 40,
"groin" = 30,
"l_leg" = 30,
"r_leg" = 30,
"l_arm" = 30,
"r_arm" = 30,
"l_hand" = 10,
"r_hand" = 10,
"l_foot" = 10,
"r_foot" = 10,
)
/proc/check_zone(zone)
if(!zone) return "chest"
@@ -142,6 +178,20 @@ proc/hasorgans(A)
var/ran_zone = zone
while (ran_zone == zone)
ran_zone = pick (
organ_rel_size["head"]; "head",
organ_rel_size["chest"]; "chest",
organ_rel_size["groin"]; "groin",
organ_rel_size["l_arm"]; "l_arm",
organ_rel_size["r_arm"]; "r_arm",
organ_rel_size["l_leg"]; "l_leg",
organ_rel_size["r_leg"]; "r_leg",
organ_rel_size["l_hand"]; "l_hand",
organ_rel_size["r_hand"]; "r_hand",
organ_rel_size["l_foot"]; "l_foot",
organ_rel_size["r_foot"]; "r_foot",
)
/*
ran_zone = pick (
20; "head",
40; "chest",
@@ -155,6 +205,7 @@ proc/hasorgans(A)
10; "l_foot",
10; "r_foot",
)
*/
return ran_zone
@@ -167,45 +218,13 @@ proc/hasorgans(A)
// you can only miss if your target is standing and not restrained
if(!target.buckled && !target.lying)
var/miss_chance = 10
switch(zone)
if("head")
miss_chance = 40
if("l_leg")
miss_chance = 20
if("r_leg")
miss_chance = 20
if("groin")
miss_chance = 20
if("l_arm")
miss_chance = 20
if("r_arm")
miss_chance = 20
if("l_hand")
miss_chance = 50
if("r_hand")
miss_chance = 50
if("l_foot")
miss_chance = 50
if("r_foot")
miss_chance = 50
if (zone in base_miss_chance)
miss_chance = base_miss_chance[zone]
miss_chance = max(miss_chance + miss_chance_mod, 0)
if(prob(miss_chance))
if(prob(70))
return null
else
var/t = rand(1, 11)
switch(t)
if(1) return "head"
if(2) return "l_arm"
if(3) return "r_arm"
if(4) return "chest"
if(5) return "groin"
if(6) return "l_foot"
if(7) return "r_foot"
if(8) return "l_hand"
if(9) return "r_hand"
if(10) return "l_leg"
if(11) return "r_leg"
return pick(base_miss_chance)
return zone