From 170baf15c7a43f6b80b9d014fba49479538dcbf6 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Tue, 19 Aug 2014 14:20:32 -0400 Subject: [PATCH 1/5] Improves rand_zone() and miss chance procs --- code/modules/mob/mob_helpers.dm | 55 +++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 388f2bf7a4b..ec4bffb2ab1 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -131,26 +131,32 @@ proc/hasorgans(A) zone = "head" return zone -// Returns zone with a certain probability. -// If the probability misses, returns "chest" instead. -// If "chest" was passed in as zone, then on a "miss" will return "head", "l_arm", or "r_arm" +// Returns zone with a certain probability. If the probability fails, or no zone is specified, then a random body part is chosen. // Do not use this if someone is intentionally trying to hit a specific body part. // Use get_zone_with_miss_chance() for that. /proc/ran_zone(zone, probability) - zone = check_zone(zone) - if(!probability) probability = 90 - if(probability == 100) return zone + if (zone) + zone = check_zone(zone) + if (prob(probability)) + return zone - if(zone == "chest") - if(prob(probability)) return "chest" - var/t = rand(1, 9) - switch(t) - if(1 to 3) return "head" - if(4 to 6) return "l_arm" - if(7 to 9) return "r_arm" - - if(prob(probability * 0.75)) return zone - return "chest" + var/ran_zone = zone + while (ran_zone == zone) + ran_zone = pick ( + 20; "head", + 40; "chest", + 30; "groin", + 30; "l_arm", + 30; "r_arm", + 30; "l_leg", + 30; "r_leg", + 10; "l_hand", + 10; "r_hand", + 10; "l_foot", + 10; "r_foot", + ) + + return ran_zone // Emulates targetting a specific body part, and miss chances // May return null if missed @@ -168,6 +174,8 @@ proc/hasorgans(A) miss_chance = 20 if("r_leg") miss_chance = 20 + if("groin") + miss_chance = 20 if("l_arm") miss_chance = 20 if("r_arm") @@ -185,18 +193,19 @@ proc/hasorgans(A) if(prob(70)) return null else - var/t = rand(1, 10) + 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 "l_foot" - if(6) return "r_foot" - if(7) return "l_hand" - if(8) return "r_hand" - if(9) return "l_leg" - if(10) return "r_leg" + 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 zone From 1477fe17abcdb8083dbf1289e0fb2f08a42141e0 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 22 Aug 2014 00:02:50 -0400 Subject: [PATCH 2/5] Fixes apply_effect() used without armour checks --- .../structures/stool_bed_chair_nest/chairs.dm | 20 ++++++++----- .../stool_bed_chair_nest/wheelchair.dm | 20 ++++++++----- .../mob/living/carbon/human/human_damage.dm | 4 +++ .../reagent_containers/food/drinks/bottle.dm | 30 ++----------------- 4 files changed, 33 insertions(+), 41 deletions(-) diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 115806277cd..b8b2d9a40b3 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -138,17 +138,23 @@ if(propelled) var/mob/living/occupant = buckled_mob unbuckle() + + var/def_zone = ran_zone() + var/blocked = occupant.run_armor_check(def_zone, "melee") occupant.throw_at(A, 3, propelled) - occupant.apply_effect(6, STUN, 0) - occupant.apply_effect(6, WEAKEN, 0) - occupant.apply_effect(6, STUTTER, 0) + occupant.apply_effect(6, STUN, blocked) + occupant.apply_effect(6, WEAKEN, blocked) + occupant.apply_effect(6, STUTTER, blocked) + occupant.apply_damage(10, BRUTE, def_zone, blocked) playsound(src.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) if(istype(A, /mob/living)) var/mob/living/victim = A - victim.apply_effect(6, STUN, 0) - victim.apply_effect(6, WEAKEN, 0) - victim.apply_effect(6, STUTTER, 0) - victim.take_organ_damage(10) + def_zone = ran_zone() + blocked = victim.run_armor_check(def_zone, "melee") + victim.apply_effect(6, STUN, blocked) + victim.apply_effect(6, WEAKEN, blocked) + victim.apply_effect(6, STUTTER, blocked) + victim.apply_damage(10, BRUTE, def_zone, blocked) occupant.visible_message("[occupant] crashed into \the [A]!") /obj/structure/stool/bed/chair/office/light diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 705351acfc4..80a4540f754 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -142,16 +142,22 @@ else if (propelled) occupant.throw_at(A, 3, propelled) - occupant.apply_effect(6, STUN, 0) - occupant.apply_effect(6, WEAKEN, 0) - occupant.apply_effect(6, STUTTER, 0) + var/def_zone = ran_zone() + var/blocked = occupant.run_armor_check(def_zone, "melee") + occupant.throw_at(A, 3, propelled) + occupant.apply_effect(6, STUN, blocked) + occupant.apply_effect(6, WEAKEN, blocked) + occupant.apply_effect(6, STUTTER, blocked) + occupant.apply_damage(10, BRUTE, def_zone) playsound(src.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) if(istype(A, /mob/living)) var/mob/living/victim = A - victim.apply_effect(6, STUN, 0) - victim.apply_effect(6, WEAKEN, 0) - victim.apply_effect(6, STUTTER, 0) - victim.take_organ_damage(10) + def_zone = ran_zone() + blocked = victim.run_armor_check(def_zone, "melee") + victim.apply_effect(6, STUN, blocked) + victim.apply_effect(6, WEAKEN, blocked) + victim.apply_effect(6, STUTTER, blocked) + victim.apply_damage(10, BRUTE, def_zone) if(pulling) occupant.visible_message("[pulling] has thrusted \the [name] into \the [A], throwing \the [occupant] out of it!") diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index bc6d2832e6a..01caff57e5a 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -165,6 +165,10 @@ hud_updateflag |= 1 << HEALTH_HUD updatehealth() + +/* +In most cases it makes more sense to use apply_damage() instead! And make sure to check armour if applicable. +*/ //Damages ONE external organ, organ gets randomly selected from damagable ones. //It automatically updates damage overlays if necesary //It automatically updates health status diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index 35b776af287..9e5dbbb4d4d 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -49,32 +49,8 @@ var/armor_duration = 0 //The more force the bottle has, the longer the duration. //Calculating duration and calculating damage. - if(ishuman(target)) - - var/mob/living/carbon/human/H = target - var/headarmor = 0 // Target's head armour - armor_block = H.run_armor_check(affecting, "melee") // For normal attack damage - - //If they have a hat/helmet and the user is targeting their head. - if(istype(H.head, /obj/item/clothing/head) && affecting == "head") - - // If their head has an armour value, assign headarmor to it, else give it 0. - if(H.head.armor["melee"]) - headarmor = H.head.armor["melee"] - else - headarmor = 0 - else - headarmor = 0 - - //Calculate the weakening duration for the target. - armor_duration = (duration - headarmor) + force - - else - //Only humans can have armour, right? - armor_block = target.run_armor_check(affecting, "melee") - if(affecting == "head") - armor_duration = duration + force - armor_duration /= 10 + armor_block = target.run_armor_check(affecting, "melee") + armor_duration = duration + force - target.getarmor(affecting, "melee") //Apply the damage! target.apply_damage(force, BRUTE, affecting, armor_block, sharp=0) @@ -88,7 +64,7 @@ else O.show_message(text("\red [target] hit himself with a bottle of [src.name] on the head!"), 1) //Weaken the target for the duration that we calculated and divide it by 5. if(armor_duration) - target.apply_effect(min(armor_duration, 10) , WEAKEN) // Never weaken more than a flash! + target.apply_effect(min(armor_duration, 10) , WEAKEN, armor_block) // Never weaken more than a flash! else //Default attack message and don't weaken the target. From ec52bf830ddc3659c5ccb6cc0c30460479f6c73c Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 22 Aug 2014 01:12:07 -0400 Subject: [PATCH 3/5] 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 From c8f2d040a1936e594a03f160aeb182d53c3fba59 Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 22 Aug 2014 01:15:17 -0400 Subject: [PATCH 4/5] Fix for rad suits not protecting against radiation Rad suits were not providing complete protection from radiation. This is probably not the best solution. Better solutions would be to either add the HANDS and FEET coverage flags as done here in addition to updating the sprite to reflect the additional coverage, or to add radiation proof gloves and boots as part of the radiation suit set (potentially problematic for taj and unathi engineers). --- code/modules/clothing/suits/utility.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 91153fee0fa..e75b3126902 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -102,7 +102,7 @@ w_class = 4//bulky item gas_transfer_coefficient = 0.90 permeability_coefficient = 0.50 - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS|FEET allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/head/radiation,/obj/item/clothing/mask/gas) slowdown = 1.5 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100) From aa97002e8848a86b19abeea93271681ee81f232e Mon Sep 17 00:00:00 2001 From: mwerezak Date: Fri, 22 Aug 2014 15:08:53 -0400 Subject: [PATCH 5/5] Removes comment, adjusts rel_sizes --- code/modules/mob/mob_helpers.dm | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 17f1717f580..08f80ceaabf 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -145,13 +145,13 @@ var/list/global/base_miss_chance = list( //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, + "head" = 25, + "chest" = 70, "groin" = 30, - "l_leg" = 30, - "r_leg" = 30, - "l_arm" = 30, - "r_arm" = 30, + "l_leg" = 25, + "r_leg" = 25, + "l_arm" = 25, + "r_arm" = 25, "l_hand" = 10, "r_hand" = 10, "l_foot" = 10, @@ -191,21 +191,6 @@ var/list/global/organ_rel_size = list( organ_rel_size["l_foot"]; "l_foot", organ_rel_size["r_foot"]; "r_foot", ) -/* - ran_zone = pick ( - 20; "head", - 40; "chest", - 30; "groin", - 30; "l_arm", - 30; "r_arm", - 30; "l_leg", - 30; "r_leg", - 10; "l_hand", - 10; "r_hand", - 10; "l_foot", - 10; "r_foot", - ) -*/ return ran_zone