diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 59305a5de3f..17f53a6d578 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -21,7 +21,7 @@ if (stat == CONSCIOUS && (src in dead_mob_list)) //Defib fix update_revive() return - + /mob/living/carbon/human/proc/update_revive() // handles revival through other means than cloning or adminbus (defib, IPC repair) stat = CONSCIOUS dead_mob_list -= src @@ -29,7 +29,7 @@ mob_list |= src ear_deaf = 0 tod = 0 - timeofdeath = 0 + timeofdeath = 0 /mob/living/carbon/human/getBrainLoss() if(species && species.flags & NO_INTORGANS) return @@ -139,7 +139,7 @@ var/datum/organ/external/O = pick(candidates) O.mutate() src << "Something is not right with your [O.display_name]..." - O.add_autopsy_data("Mutation", amount) + O.add_autopsy_data("Mutation", amount) return else if (prob(heal_prob)) @@ -292,7 +292,8 @@ This function restores all organs. //Handle BRUTE and BURN damage handle_suit_punctures(damagetype, damage) - if(blocked >= 2) return 0 + blocked = (100-blocked)/100 + if(blocked <= 0) return 0 var/datum/organ/external/organ = null if(isorgan(def_zone)) @@ -302,8 +303,7 @@ This function restores all organs. organ = get_organ(check_zone(def_zone)) if(!organ) return 0 - if(blocked) - damage = (damage/(blocked+1)) + damage = damage * blocked switch(damagetype) if(BRUTE) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 29ec501ba7a..b5fc2673286 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -185,9 +185,6 @@ emp_act buckled.unbuckle() src.loc = picked return 1 - if(species.flags & HAS_CHITTIN && (prob(50 - round(damage / 3)))) - visible_message("\red The [attack_text] bounces off [src]' natural armor!") - return 1 return 0 /mob/living/carbon/human/emp_act(severity) @@ -206,14 +203,6 @@ emp_act /mob/living/carbon/human/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone) if(!I || !user) return 0 - var/target_zone = def_zone? check_zone(def_zone) : get_zone_with_miss_chance(user.zone_sel.selecting, src) - - if(user == src) // Attacking yourself can't miss - target_zone = user.zone_sel.selecting - if(!target_zone && !src.stat && !I.discrete) - visible_message("\red [user] misses [src] with \the [I]!") - return 0 - if(istype(I, /obj/item/weapon/butch/meatcleaver) && src.stat == DEAD && user.a_intent == "harm") var/obj/item/weapon/reagent_containers/food/snacks/meat/human/newmeat = new /obj/item/weapon/reagent_containers/food/snacks/meat/human(get_turf(src.loc)) newmeat.name = src.real_name + newmeat.name @@ -235,7 +224,7 @@ emp_act del(src) - var/datum/organ/external/affecting = get_organ(target_zone) + var/datum/organ/external/affecting = get_organ(ran_zone(user.zone_sel.selecting)) if (!affecting) return 0 if(affecting.status & ORGAN_DESTROYED) @@ -267,11 +256,11 @@ emp_act var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") var/weapon_sharp = is_sharp(I) var/weapon_edge = has_edge(I) - if ((weapon_sharp || weapon_edge) && prob(getarmor(target_zone, "melee"))) + if ((weapon_sharp || weapon_edge) && prob(getarmor(user.zone_sel.selecting, "melee"))) weapon_sharp = 0 weapon_edge = 0 - if(armor >= 2) return 0 + if(armor >= 100) return 0 if(!I.force) return 0 var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) @@ -348,25 +337,13 @@ emp_act /mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5) if(istype(AM,/obj/)) var/obj/O = AM + var/zone = ran_zone("chest", 65) var/dtype = BRUTE if(istype(O,/obj/item/weapon)) var/obj/item/weapon/W = O dtype = W.damtype var/throw_damage = O.throwforce*(speed/5) - var/zone - if (istype(O.thrower, /mob/living)) - var/mob/living/L = O.thrower - zone = check_zone(L.zone_sel.selecting) - else - zone = ran_zone("chest",75) //Hits a random part of the body, geared towards the chest - - //check if we hit - if (O.throw_source) - var/distance = get_dist(O.throw_source, loc) - zone = get_zone_with_miss_chance(zone, src, min(15*(distance-2), 0)) - else - zone = get_zone_with_miss_chance(zone, src, 15) /* if(!zone) visible_message("\blue \The [O] misses [src] narrowly!") @@ -383,8 +360,8 @@ emp_act src.visible_message("\red [src] has been hit in the [hit_area] by [O].") var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here - if(armor < 2) - apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O) + + apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O) if(ismob(O.thrower)) var/mob/M = O.thrower diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm index f7e21bc376c..f8e171147fe 100644 --- a/code/modules/mob/living/carbon/species.dm +++ b/code/modules/mob/living/carbon/species.dm @@ -457,7 +457,10 @@ language = "Chittin" unarmed_type = /datum/unarmed_attack/claws - flags = IS_WHITELISTED | HAS_CHITTIN + + brute_mod = 0.8 + + flags = IS_WHITELISTED bloodflags = BLOOD_GREEN bodyflags = FEET_CLAWS diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index ce1ab84b253..9126dc6bd95 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -9,29 +9,30 @@ standard 0 if fail */ /mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/used_weapon = null, var/sharp = 0, var/edge = 0) - if(!damage || (blocked >= 2)) return 0 + blocked = (100-blocked)/100 + if(!damage || (blocked <= 0)) return 0 switch(damagetype) if(BRUTE) - adjustBruteLoss(damage/(blocked+1)) + adjustBruteLoss(damage * blocked) if(BURN) if(M_RESIST_HEAT in mutations) damage = 0 - adjustFireLoss(damage/(blocked+1)) + adjustFireLoss(damage * blocked) if(TOX) - adjustToxLoss(damage/(blocked+1)) + adjustToxLoss(damage * blocked) if(OXY) - adjustOxyLoss(damage/(blocked+1)) + adjustOxyLoss(damage * blocked) if(CLONE) - adjustCloneLoss(damage/(blocked+1)) + adjustCloneLoss(damage * blocked) if(HALLOSS) - adjustHalLoss(damage/(blocked+1)) + adjustHalLoss(damage * blocked) if(STAMINA) - adjustStaminaLoss(damage/(blocked+1)) + adjustStaminaLoss(damage * blocked) updatehealth() return 1 /mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/halloss = 0, var/def_zone = null, var/blocked = 0, var/stamina = 0) - if(blocked >= 2) return 0 + if(blocked >= 100) return 0 if(brute) apply_damage(brute, BRUTE, def_zone, blocked) if(burn) apply_damage(burn, BURN, def_zone, blocked) if(tox) apply_damage(tox, TOX, def_zone, blocked) @@ -44,27 +45,28 @@ /mob/living/proc/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0) - if(!effect || (blocked >= 2)) return 0 + blocked = (100-blocked)/100 + if(!effect || (blocked <= 0)) return 0 switch(effecttype) if(STUN) - Stun(effect/(blocked+1)) + Stun(effect * blocked) if(WEAKEN) - Weaken(effect/(blocked+1)) + Weaken(effect * blocked) if(PARALYZE) - Paralyse(effect/(blocked+1)) + Paralyse(effect * blocked) 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 + radiation += max(effect * ((100-run_armor_check(null, "rad", "Your clothes feel warm.", "Your clothes feel warm."))/100),0)//Rads auto check armor if(STUTTER) if(status_flags & CANSTUN) // stun is usually associated with stutter - stuttering = max(stuttering,(effect/(blocked+1))) + stuttering = max(stuttering,(effect * blocked)) if(EYE_BLUR) - eye_blurry = max(eye_blurry,(effect/(blocked+1))) + eye_blurry = max(eye_blurry,(effect * blocked)) if(DROWSY) - drowsyness = max(drowsyness,(effect/(blocked+1))) + drowsyness = max(drowsyness,(effect * blocked)) if(JITTER) - jitteriness = max(jitteriness,(effect/(blocked+1))) + jitteriness = max(jitteriness,(effect * blocked)) updatehealth() return 1 @@ -79,7 +81,7 @@ return ..() /mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0, var/stamina = 0, var/jitter = 0) - if(blocked >= 2) return 0 + if(blocked >= 100) return 0 if(stun) apply_effect(stun, STUN, blocked) if(weaken) apply_effect(weaken, WEAKEN, blocked) if(paralyze) apply_effect(paralyze, PARALYZE, blocked) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 73c5f3b1857..52019fc923e 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -12,25 +12,18 @@ */ /mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/absorb_text = null, var/soften_text = null) var/armor = getarmor(def_zone, attack_flag) - var/absorb = 0 - if(prob(armor)) - absorb += 1 - if(prob(armor)) - absorb += 1 - if(absorb >= 2) - if(absorb_text) - show_message("[absorb_text]") - else - show_message("\red Your armor absorbs the blow!") - return 2 - if(absorb == 1) - if(absorb_text) - show_message("[soften_text]",4) - else - show_message("\red Your armor softens the blow!") - return 1 - return 0 + if(armor >= 100) + if(absorb_text) + src << "[absorb_text]" + else + src << "Your armor absorbs the blow!" + else if(armor > 0) + if(soften_text) + src << "[soften_text]" + else + src << "Your armor softens the blow!" + return armor //if null is passed for def_zone, then this should return something appropriate for all zones (e.g. area effect damage) /mob/living/proc/getarmor(var/def_zone, var/type) @@ -73,21 +66,20 @@ */ //Armor - var/absorb = run_armor_check(def_zone, P.flag) + var/armor = run_armor_check(def_zone, P.flag) var/proj_sharp = is_sharp(P) var/proj_edge = has_edge(P) if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.flag))) proj_sharp = 0 proj_edge = 0 - if(!P.nodamage) - apply_damage(P.damage, P.damage_type, def_zone, absorb, 0, P, sharp=proj_sharp, edge=proj_edge) - - P.on_hit(src, absorb, def_zone) - if(istype(P, /obj/item/projectile/beam/lightning)) + if(istype(P, /obj/item/projectile/beam/lightning)) //Stupid snowflake lightning gun. if(P.damage >= 200) src.dust() - return absorb + + if(!P.nodamage) + apply_damage(P.damage, P.damage_type, def_zone, armor) + return P.on_hit(src, armor, def_zone) //Handles the effects of "stun" weapons /mob/living/proc/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null) @@ -117,6 +109,7 @@ /mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve if(istype(AM,/obj/)) var/obj/O = AM + var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest var/dtype = BRUTE if(istype(O,/obj/item/weapon)) var/obj/item/weapon/W = O @@ -138,10 +131,9 @@ return */ src.visible_message("\red [src] has been hit by [O].") - var/armor = run_armor_check(null, "melee") + var/armor = run_armor_check(zone, "melee") - if(armor < 2) - apply_damage(throw_damage, dtype, null, armor, is_sharp(O), has_edge(O), O) + apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O) O.throwing = 0 //it hit, so stop moving diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 1a38e98071c..5edeeb1a69a 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -172,71 +172,24 @@ proc/hasorgans(A) // If "chest" was passed in as zone, then on a "miss" will return "head", "l_arm", or "r_arm" // 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 +/proc/ran_zone(zone, probability = 80) - 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" - -// Emulates targetting a specific body part, and miss chances -// May return null if missed -// miss_chance_mod may be negative. -/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0) zone = check_zone(zone) - // 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("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 - miss_chance = max(miss_chance + miss_chance_mod, 0) - if(prob(miss_chance)) - if(prob(70)) - return null - else - var/t = rand(1, 10) - 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(prob(probability)) + return zone + + var/t = rand(1, 18) // randomly pick a different zone, or maybe the same one + switch(t) + if(1) return "head" + if(2) return "chest" + if(3 to 6) return "l_arm" + if(7 to 10) return "r_arm" + if(11 to 14) return "l_leg" + if(15 to 18) return "r_leg" return zone - /proc/stars(n, pr) if (pr == null) pr = 25 diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index a38fadbe457..88c87486c3f 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -75,14 +75,14 @@ /obj/effect/accelerated_particle/proc/toxmob(var/mob/living/M) - var/radiation = (energy*2) -/* if(istype(M,/mob/living/carbon/human)) + /*var/radiation = (energy*2) + if(istype(M,/mob/living/carbon/human)) if(M:wear_suit) //TODO: check for radiation protection radiation = round(radiation/2,1) if(istype(M,/mob/living/carbon/monkey)) if(M:wear_suit) //TODO: check for radiation protection radiation = round(radiation/2,1)*/ - M.apply_effect((radiation*3),IRRADIATE,0) + M.apply_effect((energy*6),IRRADIATE,0) M.updatehealth() //M << "\red You feel odd." return diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 38fa509e660..970a5c1ea1a 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -76,12 +76,10 @@ qdel(src) proc/on_hit(var/atom/target, var/blocked = 0) - if(blocked >= 2) return 0//Full block if(!isliving(target)) return 0 if(isanimal(target)) return 0 var/mob/living/L = target - L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked, stamina, jitter) // add in AGONY! - return 1 + return L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked, stamina, jitter) proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. if(!istype(target) || !istype(user)) @@ -111,21 +109,8 @@ //Lower accurancy/longer range tradeoff. Distance matters a lot here, so at // close distance, actually RAISE the chance to hit. - var/distance = get_dist(starting,loc) - var/miss_modifier = -30 - if (istype(shot_from,/obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often. - var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim - if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew - miss_modifier += -30 - if(istype(src, /obj/item/projectile/beam/lightning)) //Lightning is quite accurate - miss_modifier += -200 - def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier) - var/turf/simulated/floor/f = get_turf(A.loc) - if(f && istype(f)) - f.break_tile() - f.hotspot_expose(1000,CELL_VOLUME) - else - def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 8*distance) + var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. + def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. /* if(!def_zone) visible_message("\blue \The [src] misses [M] narrowly!")