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