From ec52bf830ddc3659c5ccb6cc0c30460479f6c73c Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 22 Aug 2014 01:12:07 -0400 Subject: [PATCH] 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. --- .../mob/living/carbon/human/human_defense.dm | 22 +++-- code/modules/mob/living/damage_procs.dm | 3 +- code/modules/mob/mob_helpers.dm | 91 +++++++++++-------- 3 files changed, 69 insertions(+), 47 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 407b83c9c34..7406c693b53 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -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 diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 5431a2775ad..cc76d40c654 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -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))) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index ec4bffb2ab1..17f1717f580 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -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