mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-29 16:10:02 +01:00
Reworks armor damage reduction + armor components + more goodies. (#11106)
Ports Baystation12/Baystation12#27254 and Baystation12/Baystation12#24787 and everything inbetween I guess. Note that this PR makes guns and armor overall stronger. Lasers also once again do organ damage.
This commit is contained in:
@@ -61,7 +61,7 @@
|
||||
sleeping = 0
|
||||
willfully_sleeping = FALSE
|
||||
|
||||
/mob/living/carbon/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
|
||||
/mob/living/carbon/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/hit_zone)
|
||||
var/t_him = "it"
|
||||
if (src.gender == MALE)
|
||||
t_him = "him"
|
||||
@@ -85,12 +85,12 @@
|
||||
"<span class='danger'>You attack [src] with [I], but they do not respond... Maybe they have S.S.D?</span>")
|
||||
else if(client && willfully_sleeping)
|
||||
user.visible_message("<span class='danger'>[user] attacked [src] with [I] waking [t_him] up!</span>", \
|
||||
"<span class='danger'>You attack [src] with [I], waking [t_him] up!</span>")
|
||||
"<span class='danger'>You attack [src] with [I], waking [t_him] up!</span>")
|
||||
sleeping = 0
|
||||
willfully_sleeping = FALSE
|
||||
|
||||
|
||||
if(!effective_force || blocked >= 100)
|
||||
if(!effective_force)
|
||||
return 0
|
||||
|
||||
//Hulk modifier
|
||||
@@ -99,19 +99,14 @@
|
||||
|
||||
//Apply weapon damage
|
||||
var/damage_flags = I.damage_flags()
|
||||
if(prob(blocked)) //armor provides a chance to turn sharp/edge weapon attacks into blunt ones
|
||||
damage_flags &= ~DAM_SHARP
|
||||
damage_flags &= ~DAM_EDGE
|
||||
|
||||
apply_damage(effective_force, I.damtype, hit_zone, blocked, used_weapon=I, damage_flags = damage_flags)
|
||||
apply_damage(effective_force, I.damtype, hit_zone, I, damage_flags)
|
||||
|
||||
//Melee weapon embedded object code.
|
||||
if (I && I.damtype == BRUTE && !I.anchored && !is_robot_module(I))
|
||||
var/damage = effective_force //just the effective damage used for sorting out embedding, no further damage is applied here
|
||||
if (blocked)
|
||||
damage *= BLOCKED_MULT(blocked)
|
||||
damage *= 1 - get_blocked_ratio(hit_zone, I.damtype, I.damage_flags(), I.armor_penetration, I.force)
|
||||
|
||||
if (I.can_embed)//If this weapon is allowed to embed in people
|
||||
if(I.can_embed)//If this weapon is allowed to embed in people
|
||||
//blunt objects should really not be embedding in things unless a huge amount of force is involved
|
||||
var/sharp = damage_flags & DAM_SHARP
|
||||
var/edge = damage_flags & DAM_EDGE
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
if (severity)
|
||||
damage_factor = (1 / severity)
|
||||
|
||||
var/armorval = getarmor(null, "bomb")
|
||||
var/armorval = get_blocked_ratio(BP_CHEST, BRUTE, DAM_DISPERSED, damage = damage)
|
||||
if (armorval)
|
||||
damage_factor *= (1 - (armorval * 0.01))
|
||||
|
||||
|
||||
@@ -233,15 +233,8 @@
|
||||
if (1.0)
|
||||
b_loss += 500
|
||||
f_loss = 100
|
||||
if (!prob(getarmor(null, "bomb")))
|
||||
gib()
|
||||
return
|
||||
else
|
||||
var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
|
||||
throw_at(target, 200, 4)
|
||||
//return
|
||||
// var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src)))
|
||||
//user.throw_at(target, 200, 4)
|
||||
var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
|
||||
throw_at(target, 200, 4)
|
||||
|
||||
if (2.0)
|
||||
b_loss = 60
|
||||
@@ -261,46 +254,15 @@
|
||||
if (prob(50))
|
||||
Paralyse(10)
|
||||
|
||||
// factor in armor
|
||||
var/protection = BLOCKED_MULT(getarmor(null, "bomb"))
|
||||
b_loss *= protection
|
||||
f_loss *= protection
|
||||
|
||||
var/update = 0
|
||||
|
||||
// focus most of the blast on one organ
|
||||
var/obj/item/organ/external/take_blast = pick(organs)
|
||||
update |= take_blast.take_damage(b_loss * 0.7, f_loss * 0.7, used_weapon = "Explosive blast")
|
||||
apply_damage(0.7 * b_loss, BRUTE, null, DAM_EXPLODE, used_weapon = "Explosive blast")
|
||||
apply_damage(0.7 * f_loss, BURN, null, DAM_EXPLODE, used_weapon = "Explosive blast")
|
||||
|
||||
// distribute the remaining 30% on all limbs equally (including the one already dealt damage)
|
||||
b_loss *= 0.3
|
||||
f_loss *= 0.3
|
||||
apply_damage(0.3 * b_loss, BRUTE, null, DAM_EXPLODE | DAM_DISPERSED, used_weapon = "Explosive blast")
|
||||
apply_damage(0.3 * f_loss, BURN, null, DAM_EXPLODE | DAM_DISPERSED, used_weapon = "Explosive blast")
|
||||
|
||||
var/weapon_message = "Explosive Blast"
|
||||
|
||||
for(var/obj/item/organ/external/temp in organs)
|
||||
switch(temp.name)
|
||||
if(BP_HEAD)
|
||||
update |= temp.take_damage(b_loss * 0.2, f_loss * 0.2, used_weapon = weapon_message)
|
||||
if(BP_CHEST)
|
||||
update |= temp.take_damage(b_loss * 0.4, f_loss * 0.4, used_weapon = weapon_message)
|
||||
if(BP_L_ARM)
|
||||
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
|
||||
if(BP_R_ARM)
|
||||
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
|
||||
if(BP_L_LEG)
|
||||
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
|
||||
if(BP_R_LEG)
|
||||
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
|
||||
if(BP_R_FOOT)
|
||||
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
|
||||
if(BP_L_FOOT)
|
||||
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
|
||||
if(BP_R_ARM)
|
||||
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
|
||||
if(BP_L_ARM)
|
||||
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
|
||||
if(update) UpdateDamageIcon()
|
||||
UpdateDamageIcon()
|
||||
|
||||
/mob/living/carbon/human/proc/implant_loyalty(mob/living/carbon/human/M, override = FALSE) // Won't override by default.
|
||||
if(!config.use_loyalty_implants && !override) return // Nuh-uh.
|
||||
@@ -1988,15 +1950,17 @@
|
||||
return BULLET_IMPACT_METAL
|
||||
return BULLET_IMPACT_MEAT
|
||||
|
||||
/mob/living/carbon/human/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage)
|
||||
/mob/living/carbon/human/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage, var/blocked_ratio)
|
||||
..()
|
||||
if(blocked_ratio > 0.7)
|
||||
return
|
||||
switch(get_bullet_impact_effect_type(def_zone))
|
||||
if(BULLET_IMPACT_MEAT)
|
||||
if(P.damage_type == BRUTE)
|
||||
var/hit_dir = get_dir(P.starting, src)
|
||||
var/obj/effect/decal/cleanable/blood/B = blood_splatter(get_step(src, hit_dir), src, 1, hit_dir)
|
||||
B.icon_state = pick("dir_splatter_1","dir_splatter_2")
|
||||
var/scale = min(1, round(P.damage / 50, 0.2))
|
||||
var/scale = min(1, round(damage / 50, 0.2))
|
||||
var/matrix/M = new()
|
||||
B.transform = M.Scale(scale)
|
||||
|
||||
@@ -2011,9 +1975,9 @@
|
||||
src.adjustToxLoss(-damage)
|
||||
to_chat(src, SPAN_NOTICE("You can feel flow of energy which makes you regenerate."))
|
||||
|
||||
src.apply_effect((rand(15,30)),IRRADIATE,blocked = src.getarmor(null, "rad"))
|
||||
apply_damage((rand(15,30)), IRRADIATE, damage_flags = DAM_DISPERSED)
|
||||
if(prob(4))
|
||||
src.apply_effect((rand(20,60)),IRRADIATE,blocked = src.getarmor(null, "rad"))
|
||||
apply_damage((rand(20,60)), IRRADIATE, damage_flags = DAM_DISPERSED)
|
||||
if (prob(75))
|
||||
randmutb(src) // Applies bad mutation
|
||||
domutcheck(src,null,MUTCHK_FORCED)
|
||||
|
||||
@@ -52,9 +52,8 @@
|
||||
|
||||
msg_admin_attack("[key_name_admin(M)] stungloved [src.name] ([src.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[M.x];Y=[M.y];Z=[M.z]'>JMP</a>)",ckey=key_name(M),ckey_target=key_name(src))
|
||||
|
||||
var/armorblock = run_armor_check(M.zone_sel.selecting, "energy")
|
||||
apply_effects(5,5,0,0,5,0,0,0,0,armorblock)
|
||||
apply_damage(rand(5,25), BURN, M.zone_sel.selecting,armorblock)
|
||||
apply_effects(5,5,0,0,5,0,0,0,0)
|
||||
apply_damage(rand(5,25), BURN, M.zone_sel.selecting)
|
||||
|
||||
if(prob(15))
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
@@ -84,7 +83,6 @@
|
||||
visible_message("<span class='danger'>[H] has attempted to punch [src]!</span>")
|
||||
return 0
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(H.zone_sel.selecting))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
|
||||
if(HULK in H.mutations)
|
||||
damage += 5
|
||||
@@ -93,10 +91,10 @@
|
||||
|
||||
visible_message("<span class='danger'>[H] has punched [src]!</span>")
|
||||
|
||||
apply_damage(damage, PAIN, affecting, armor_block)
|
||||
apply_damage(damage, PAIN, affecting)
|
||||
if(damage >= 9)
|
||||
visible_message("<span class='danger'>[H] has weakened [src]!</span>")
|
||||
apply_effect(4, WEAKEN, armor_block)
|
||||
apply_effect(4, WEAKEN)
|
||||
|
||||
return
|
||||
|
||||
@@ -284,12 +282,11 @@
|
||||
var/obj/item/clothing/gloves/force/X = H.gloves
|
||||
real_damage *= X.amplification
|
||||
|
||||
var/armor = run_armor_check(hit_zone, "melee")
|
||||
// Apply additional unarmed effects.
|
||||
attack.apply_effects(H, src, armor, rand_damage, hit_zone)
|
||||
attack.apply_effects(H, src, rand_damage, hit_zone)
|
||||
|
||||
// Finally, apply damage to target
|
||||
apply_damage(real_damage, hit_dam_type, hit_zone, armor, damage_flags = damage_flags)
|
||||
apply_damage(real_damage, hit_dam_type, hit_zone, damage_flags = damage_flags)
|
||||
|
||||
|
||||
if(M.resting && src.help_up_offer)
|
||||
@@ -375,7 +372,7 @@
|
||||
var/randn = rand(1, 100)
|
||||
if(randn <= 25)
|
||||
if(H.gloves && istype(H.gloves,/obj/item/clothing/gloves/force))
|
||||
apply_effect(6, WEAKEN, run_armor_check(affecting, "melee"))
|
||||
apply_effect(6, WEAKEN)
|
||||
playsound(loc, 'sound/weapons/push_connect.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] hurls [src] to the floor!</span>")
|
||||
step_away(src,M,15)
|
||||
@@ -384,7 +381,7 @@
|
||||
return
|
||||
|
||||
else
|
||||
var/armor_check = run_armor_check(affecting, "melee")
|
||||
var/armor_check = 100 * get_blocked_ratio(affecting, BRUTE, damage = 20)
|
||||
apply_effect(3, WEAKEN, armor_check)
|
||||
if(armor_check < 100)
|
||||
visible_message("<span class='danger'>[M] has pushed [src]!</span>")
|
||||
@@ -406,7 +403,7 @@
|
||||
sleep(1)
|
||||
step_away(src,M,15)
|
||||
sleep(1)
|
||||
apply_effect(1, WEAKEN, run_armor_check(affecting, "melee"))
|
||||
apply_effect(1, WEAKEN, get_blocked_ratio(M.zone_sel.selecting, BRUTE, damage = 20)*100)
|
||||
return
|
||||
|
||||
//See about breaking grips or pulls
|
||||
@@ -506,8 +503,7 @@
|
||||
if(!dam_zone)
|
||||
dam_zone = pick(organs)
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
updatehealth()
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
ChangeToHusk()
|
||||
|
||||
UpdateDamageIcon() // to fix that darn overlay bug
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/get_total_health()
|
||||
var/amount = maxHealth - getFireLoss() - getBruteLoss() - getOxyLoss() - getToxLoss() - getBrainLoss()
|
||||
@@ -323,7 +322,8 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t
|
||||
updatehealth()
|
||||
BITSET(hud_updateflag, HEALTH_HUD)
|
||||
speech_problem_flag = 1
|
||||
if(update) UpdateDamageIcon()
|
||||
if(update)
|
||||
UpdateDamageIcon()
|
||||
|
||||
// damage MANY external organs, in random order
|
||||
/mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/damage_flags, var/used_weapon = null)
|
||||
@@ -383,63 +383,76 @@ This function restores all organs.
|
||||
zone = BP_HEAD
|
||||
return organs_by_name[zone]
|
||||
|
||||
/mob/living/carbon/human/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/obj/used_weapon = null, var/damage_flags)
|
||||
//visible_message("Hit debug. [damage] | [damagetype] | [def_zone] | [blocked] | [sharp] | [used_weapon]")
|
||||
/mob/living/carbon/human/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone, var/obj/used_weapon, var/damage_flags, var/armor_pen, var/silent = FALSE)
|
||||
if (invisibility == INVISIBILITY_LEVEL_TWO && back && (istype(back, /obj/item/rig)))
|
||||
if(damage > 0)
|
||||
to_chat(src, "<span class='danger'>You are now visible.</span>")
|
||||
src.invisibility = 0
|
||||
|
||||
var/obj/item/organ/external/organ = get_organ(def_zone)
|
||||
if(!organ)
|
||||
if(isorgan(def_zone))
|
||||
organ = def_zone
|
||||
else
|
||||
if(!def_zone)
|
||||
if(damage_flags & DAM_DISPERSED)
|
||||
var/old_damage = damage
|
||||
var/tally
|
||||
silent = TRUE // Will damage a lot of organs, probably, so avoid spam.
|
||||
for(var/zone in organ_rel_size)
|
||||
tally += organ_rel_size[zone]
|
||||
for(var/zone in organ_rel_size)
|
||||
damage = old_damage * organ_rel_size[zone]/tally
|
||||
def_zone = zone
|
||||
. = .() || .
|
||||
return
|
||||
def_zone = ran_zone(def_zone)
|
||||
organ = get_organ(check_zone(def_zone))
|
||||
|
||||
//Handle other types of damage
|
||||
if(damagetype != BRUTE && damagetype != BURN)
|
||||
if(!(damagetype in list(BRUTE, BURN, PAIN, CLONE)))
|
||||
if(!stat && damagetype == PAIN)
|
||||
if((damage > 25 && prob(20)) || (damage > 50 && prob(60)))
|
||||
emote("scream")
|
||||
return ..()
|
||||
|
||||
..(damage, damagetype, def_zone, blocked)
|
||||
return 1
|
||||
if(!organ)
|
||||
return FALSE
|
||||
|
||||
//Handle BRUTE and BURN damage
|
||||
handle_suit_punctures(damagetype, damage, def_zone)
|
||||
|
||||
if(blocked >= 100)
|
||||
return 0
|
||||
|
||||
var/obj/item/organ/external/organ = null
|
||||
if(isorgan(def_zone))
|
||||
organ = def_zone
|
||||
else
|
||||
if(!def_zone) def_zone = ran_zone(def_zone)
|
||||
organ = get_organ(check_zone(def_zone))
|
||||
if(!organ)
|
||||
return 0
|
||||
|
||||
if(blocked)
|
||||
damage *= BLOCKED_MULT(blocked)
|
||||
var/list/after_armor = modify_damage_by_armor(def_zone, damage, damagetype, damage_flags, src, armor_pen, silent)
|
||||
damage = after_armor[1]
|
||||
damagetype = after_armor[2]
|
||||
damage_flags = after_armor[3]
|
||||
if(!damage)
|
||||
return FALSE
|
||||
|
||||
if(damage > 15 && prob(damage*4) && organ.can_feel_pain())
|
||||
make_adrenaline(round(damage/10))
|
||||
|
||||
switch(damagetype)
|
||||
|
||||
if(BRUTE)
|
||||
damageoverlaytemp = 20
|
||||
if(damage > 0)
|
||||
damage *= species.brute_mod
|
||||
if(organ.take_damage(damage, 0, damage_flags, used_weapon))
|
||||
UpdateDamageIcon()
|
||||
|
||||
organ.take_damage(damage, 0, damage_flags, used_weapon)
|
||||
UpdateDamageIcon()
|
||||
if(BURN)
|
||||
damageoverlaytemp = 20
|
||||
if(damage > 0)
|
||||
damage *= species.burn_mod
|
||||
if(organ.take_damage(0, damage, damage_flags, used_weapon))
|
||||
UpdateDamageIcon()
|
||||
organ.take_damage(0, damage, damage_flags, used_weapon)
|
||||
UpdateDamageIcon()
|
||||
if(PAIN)
|
||||
organ.add_pain(damage)
|
||||
if(CLONE)
|
||||
organ.add_genetic_damage(damage)
|
||||
|
||||
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
|
||||
updatehealth()
|
||||
BITSET(hud_updateflag, HEALTH_HUD)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/apply_radiation(var/rads)
|
||||
if(species && rads > 0)
|
||||
|
||||
@@ -43,11 +43,13 @@ emp_act
|
||||
|
||||
//Shrapnel
|
||||
if(!(species.flags & NO_EMBED) && P.can_embed())
|
||||
var/armor = getarmor_organ(organ, "bullet")
|
||||
var/armor = get_blocked_ratio(def_zone, BRUTE, P.damage_flags(), armor_pen = P.armor_penetration, damage = P.damage)*100
|
||||
if(prob(20 + max(P.damage + P.embed_chance - armor, -10)))
|
||||
P.do_embed(organ)
|
||||
|
||||
return (..(P , def_zone))
|
||||
var/blocked = ..(P, def_zone)
|
||||
|
||||
return blocked
|
||||
|
||||
/mob/living/carbon/human/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone)
|
||||
var/obj/item/organ/external/affected = get_organ(check_zone(def_zone))
|
||||
@@ -78,27 +80,37 @@ emp_act
|
||||
|
||||
..(stun_amount, agony_amount, def_zone)
|
||||
|
||||
/mob/living/carbon/human/getarmor(var/def_zone, var/type)
|
||||
var/armorval = 0
|
||||
var/total = 0
|
||||
/mob/living/carbon/human/get_blocked_ratio(def_zone, damage_type, damage_flags, armor_pen, damage)
|
||||
if(!def_zone && (damage_flags & DAM_DISPERSED))
|
||||
var/tally
|
||||
for(var/zone in organ_rel_size)
|
||||
tally += organ_rel_size[zone]
|
||||
for(var/zone in organ_rel_size)
|
||||
def_zone = zone
|
||||
. += .() * organ_rel_size/tally
|
||||
return
|
||||
return ..()
|
||||
|
||||
if(def_zone)
|
||||
if(isorgan(def_zone))
|
||||
return getarmor_organ(def_zone, type)
|
||||
var/obj/item/organ/external/affecting = get_organ(def_zone)
|
||||
if(affecting)
|
||||
return getarmor_organ(affecting, type)
|
||||
//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/organ_name in organs_by_name)
|
||||
if (organ_name in organ_rel_size)
|
||||
var/obj/item/organ/external/organ = organs_by_name[organ_name]
|
||||
if(organ)
|
||||
var/weight = organ_rel_size[organ_name]
|
||||
armorval += getarmor_organ(organ, type) * weight
|
||||
total += weight
|
||||
return (armorval/max(total, 1))
|
||||
/mob/living/carbon/human/get_armors_by_zone(obj/item/organ/external/def_zone, damage_type, damage_flags)
|
||||
. = ..()
|
||||
if(!def_zone)
|
||||
def_zone = ran_zone()
|
||||
if(!istype(def_zone))
|
||||
def_zone = get_organ(check_zone(def_zone))
|
||||
if(!def_zone)
|
||||
return
|
||||
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
|
||||
for(var/obj/item/clothing/gear in protective_gear)
|
||||
if(gear.accessories && length(gear.accessories))
|
||||
for(var/obj/item/clothing/accessory/bling in gear.accessories)
|
||||
if(bling.body_parts_covered & def_zone.body_part)
|
||||
var/armor = bling.GetComponent(/datum/component/armor)
|
||||
if(armor)
|
||||
. += armor
|
||||
if(gear.body_parts_covered & def_zone.body_part)
|
||||
var/armor = gear.GetComponent(/datum/component/armor)
|
||||
if(armor)
|
||||
. += armor
|
||||
|
||||
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
|
||||
/mob/living/carbon/human/proc/get_siemens_coefficient_organ(var/obj/item/organ/external/def_zone)
|
||||
@@ -123,30 +135,16 @@ emp_act
|
||||
results.Add(C)
|
||||
return results
|
||||
|
||||
//this proc returns the armor value for a particular external organ.
|
||||
/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type)
|
||||
if(!type || !def_zone) return 0
|
||||
var/protection = 0
|
||||
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
|
||||
for(var/obj/item/clothing/gear in protective_gear)
|
||||
if(!isnull(gear.armor) && gear.body_parts_covered & def_zone.body_part)
|
||||
protection = add_armor(protection, gear.armor[type])
|
||||
for(var/obj/item/clothing/accessory/A in gear.accessories)
|
||||
if(!isnull(A.armor) && A.body_parts_covered & def_zone.body_part)
|
||||
protection = add_armor(protection, A.armor[type])
|
||||
|
||||
return protection
|
||||
|
||||
/mob/living/carbon/human/proc/check_head_coverage()
|
||||
|
||||
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
|
||||
for(var/bp in body_parts)
|
||||
if(!bp) continue
|
||||
if(!bp)
|
||||
continue
|
||||
if(bp && istype(bp ,/obj/item/clothing))
|
||||
var/obj/item/clothing/C = bp
|
||||
if(C.body_parts_covered & HEAD)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/check_head_airtight_coverage()
|
||||
var/list/clothing = list(head, wear_mask, wear_suit)
|
||||
@@ -231,19 +229,18 @@ emp_act
|
||||
|
||||
if(user == src) // Attacking yourself can't miss
|
||||
target_zone = user.zone_sel.selecting
|
||||
if(!target_zone)
|
||||
visible_message("<span class='danger'>[user] misses [src] with \the [I]!</span>")
|
||||
return 0
|
||||
|
||||
//var/obj/item/organ/external/affecting = get_organ(target_zone)
|
||||
if(!hit_zone)
|
||||
visible_message("<span class='danger'>[user] misses [src] with \the [I]!</span>")
|
||||
return
|
||||
|
||||
if(check_shields(I.force, I, user, target_zone, "the [I.name]"))
|
||||
return null
|
||||
return
|
||||
|
||||
var/obj/item/organ/external/affecting = get_organ(hit_zone)
|
||||
if (!affecting || affecting.is_stump())
|
||||
to_chat(user, "<span class='danger'>They are missing that limb!</span>")
|
||||
return null
|
||||
return
|
||||
|
||||
return hit_zone
|
||||
|
||||
@@ -253,13 +250,9 @@ emp_act
|
||||
return //should be prevented by attacked_with_item() but for sanity.
|
||||
|
||||
visible_message("<span class='danger'>[src] has been [LAZYPICK(I.attack_verb, "attacked")] in the [affecting.name] with [I] by [user]!</span>")
|
||||
return standard_weapon_hit_effects(I, user, effective_force, hit_zone)
|
||||
|
||||
var/blocked = run_armor_check(hit_zone, "melee", I.armor_penetration, "Your armor has protected your [affecting.name].", "Your armor has softened the blow to your [affecting.name].")
|
||||
standard_weapon_hit_effects(I, user, effective_force, blocked, hit_zone)
|
||||
|
||||
return blocked
|
||||
|
||||
/mob/living/carbon/human/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
|
||||
/mob/living/carbon/human/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/hit_zone)
|
||||
var/obj/item/organ/external/affecting = get_organ(hit_zone)
|
||||
if(!affecting)
|
||||
return 0
|
||||
@@ -273,23 +266,21 @@ emp_act
|
||||
// Handle striking to cripple.
|
||||
if(user.a_intent == I_DISARM)
|
||||
effective_force /= 2 //half the effective force
|
||||
if(!..(I, user, effective_force, blocked, hit_zone))
|
||||
return 0
|
||||
if(!..(I, user, effective_force, hit_zone))
|
||||
return FALSE
|
||||
|
||||
attack_joint(affecting, I, blocked) //but can dislocate joints
|
||||
|
||||
else if(!..())
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
// forceglove amplification
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/X = user
|
||||
if(X.gloves && istype(X.gloves,/obj/item/clothing/gloves/force))
|
||||
var/obj/item/clothing/gloves/force/G = X.gloves
|
||||
effective_force *= G.amplification
|
||||
|
||||
if(effective_force > 10 || effective_force >= 5 && prob(33))
|
||||
forcesay(hit_appends) //forcesay checks stat already
|
||||
|
||||
if((I.damtype == BRUTE || I.damtype == PAIN) && prob(25 + (effective_force * 2)))
|
||||
if(!stat)
|
||||
if(headcheck(hit_zone))
|
||||
@@ -326,7 +317,7 @@ emp_act
|
||||
if(BP_CHEST)
|
||||
bloody_body(src)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/blocked)
|
||||
if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100)
|
||||
@@ -396,12 +387,8 @@ emp_act
|
||||
var/obj/item/organ/external/affecting = get_organ(zone)
|
||||
var/hit_area = affecting.name
|
||||
|
||||
src.visible_message("<span class='warning'>[src] has been hit in the [hit_area] by [O].</span>", "<span class='warning'><font size='2'>You're hit in the [hit_area] by [O]!</font></span>")
|
||||
var/armor = run_armor_check(affecting, "melee", O.armor_penetration, "Your armor has protected your [hit_area].", "Your armor has softened the hit to your [hit_area].") //I guess "melee" is the best fit here
|
||||
|
||||
if(armor < 100)
|
||||
var/damage_flags = O.damage_flags()
|
||||
apply_damage(throw_damage, dtype, zone, armor, O, damage_flags = damage_flags)
|
||||
src.visible_message("<span class='warning'>[src] has been hit in the [hit_area] by [O].</span>", "<span class='warning'><font size=2>You're hit in the [hit_area] by [O]!</font></span>")
|
||||
apply_damage(throw_damage, dtype, zone, used_weapon = O, damage_flags = O.damage_flags(), armor_pen = O.armor_penetration)
|
||||
|
||||
if(ismob(O.thrower))
|
||||
var/mob/M = O.thrower
|
||||
@@ -418,12 +405,11 @@ emp_act
|
||||
if (!is_robot_module(I))
|
||||
var/sharp = is_sharp(I)
|
||||
var/damage = throw_damage
|
||||
if (armor)
|
||||
damage *= BLOCKED_MULT(armor)
|
||||
damage *= (1 - get_blocked_ratio(zone, BRUTE, O.damage_flags(), O.armor_penetration, damage))
|
||||
|
||||
//blunt objects should really not be embedding in things unless a huge amount of force is involved
|
||||
var/embed_chance = sharp? damage/I.w_class : damage/(I.w_class*3)
|
||||
var/embed_threshold = sharp? 5*I.w_class : 15*I.w_class
|
||||
var/embed_chance = sharp ? damage/I.w_class : damage/(I.w_class*3)
|
||||
var/embed_threshold = sharp ? 5*I.w_class : 15*I.w_class
|
||||
|
||||
//Sharp objects will always embed if they do enough damage.
|
||||
//Thrown sharp objects have some momentum already and have a small chance to embed even if the damage is below the threshold
|
||||
@@ -432,7 +418,7 @@ emp_act
|
||||
|
||||
// Begin BS12 momentum-transfer code.
|
||||
var/mass = 1.5
|
||||
if(istype(O, /obj/item))
|
||||
if(isitem(O))
|
||||
var/obj/item/I = O
|
||||
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
|
||||
var/momentum = speed*mass
|
||||
|
||||
@@ -1018,11 +1018,11 @@ mob/living/carbon/human/proc/change_monitor()
|
||||
|
||||
last_special = world.time + 20
|
||||
|
||||
src.drop_from_inventory(O)
|
||||
drop_from_inventory(O)
|
||||
O.replaced(src)
|
||||
src.update_body()
|
||||
src.updatehealth()
|
||||
src.UpdateDamageIcon()
|
||||
update_body()
|
||||
updatehealth()
|
||||
UpdateDamageIcon()
|
||||
|
||||
update_body()
|
||||
updatehealth()
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
attack_verb = list("bit", "chomped on")
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
shredding = 0
|
||||
sharp = 1
|
||||
edge = 1
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
damage = 5
|
||||
attack_name = "sharp bite"
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
eye_attack_text_victim = "sharp claws"
|
||||
attack_sound = 'sound/weapons/slice.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
sharp = 1
|
||||
edge = 1
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
damage = 5
|
||||
attack_name = "claws"
|
||||
|
||||
@@ -64,13 +64,13 @@
|
||||
/datum/unarmed_attack/claws/strong
|
||||
attack_verb = list("slashed")
|
||||
damage = 10
|
||||
shredding = 1
|
||||
shredding = TRUE
|
||||
attack_name = "strong claws"
|
||||
|
||||
/datum/unarmed_attack/bite/strong
|
||||
attack_verb = list("mauled")
|
||||
damage = 10
|
||||
shredding = 1
|
||||
shredding = TRUE
|
||||
attack_name = "strong bite"
|
||||
|
||||
/datum/unarmed_attack/slime_glomp
|
||||
@@ -110,7 +110,7 @@
|
||||
damage = 7
|
||||
attack_sound = 'sound/weapons/smash.ogg'
|
||||
attack_name = "heavy fist"
|
||||
shredding = 1
|
||||
shredding = TRUE
|
||||
|
||||
/datum/unarmed_attack/industrial/heavy
|
||||
damage = 9
|
||||
@@ -125,7 +125,7 @@
|
||||
damage = 12
|
||||
attack_sound = 'sound/weapons/beartrap_shut.ogg'
|
||||
attack_name = "power fist"
|
||||
shredding = 1
|
||||
shredding = TRUE
|
||||
|
||||
/datum/unarmed_attack/terminator/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armor,var/attack_damage,var/zone)
|
||||
..()
|
||||
@@ -148,10 +148,10 @@
|
||||
attack_verb = list("cleaved", "plowed", "swiped")
|
||||
attack_noun = list("massive claws")
|
||||
damage = 25
|
||||
sharp = 1
|
||||
edge = 1
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
attack_name = "massive claws"
|
||||
shredding = 1
|
||||
shredding = TRUE
|
||||
|
||||
/datum/unarmed_attack/claws/cleave/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armor,var/attack_damage,var/zone)
|
||||
..()
|
||||
@@ -172,9 +172,9 @@
|
||||
attack_verb = list("mauled","gored","perforated")
|
||||
attack_noun = list("mandibles")
|
||||
damage = 35
|
||||
shredding = 1
|
||||
sharp = 1
|
||||
edge = 1
|
||||
shredding = TRUE
|
||||
sharp = TRUE
|
||||
edge = TRUE
|
||||
attack_name = "mandibles"
|
||||
|
||||
/datum/unarmed_attack/bite/infectious
|
||||
@@ -188,7 +188,7 @@
|
||||
to_chat(user, SPAN_WARNING("You feel that \the [target] has been already infected!"))
|
||||
|
||||
var/infection_chance = 80
|
||||
infection_chance -= target.run_armor_check(zone,"melee")
|
||||
infection_chance -= target.get_blocked_ratio(zone, BRUTE, damage_flags = DAM_SHARP|DAM_EDGE, damage = damage)*100
|
||||
if(prob(infection_chance))
|
||||
if(target.reagents)
|
||||
var/trioxin_amount = REAGENT_VOLUME(target.reagents, /decl/reagent/toxin/trioxin)
|
||||
@@ -200,7 +200,7 @@
|
||||
damage = 15
|
||||
attack_sound = 'sound/weapons/heavysmash.ogg'
|
||||
attack_name = "crushing fist"
|
||||
shredding = 1
|
||||
shredding = TRUE
|
||||
|
||||
/datum/unarmed_attack/shocking
|
||||
attack_verb = list("prodded", "touched")
|
||||
|
||||
@@ -766,7 +766,7 @@ var/global/list/golem_types = list(SPECIES_GOLEM_COAL,
|
||||
/datum/species/golem/uranium/handle_environment_special(var/mob/living/carbon/human/H)
|
||||
if(prob(25))
|
||||
for(var/mob/living/L in view(7, H))
|
||||
L.apply_effect(150, IRRADIATE, blocked = L.getarmor(null, "rad"))
|
||||
L.apply_damage(150, IRRADIATE, damage_flags = DAM_DISPERSED)
|
||||
|
||||
/datum/species/golem/homunculus
|
||||
name = SPECIES_GOLEM_MEAT
|
||||
|
||||
@@ -43,18 +43,19 @@ var/global/list/sparring_attack_cache = list()
|
||||
/datum/unarmed_attack/proc/get_unarmed_damage()
|
||||
return damage
|
||||
|
||||
/datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armor,var/attack_damage,var/zone)
|
||||
/datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/attack_damage,var/zone)
|
||||
|
||||
if(target.stat == DEAD)
|
||||
return
|
||||
|
||||
var/stun_chance = rand(0, 100)
|
||||
var/armor = target.get_blocked_ratio(zone, BRUTE)
|
||||
var/pain_message = TRUE
|
||||
|
||||
if(!target.can_feel_pain())
|
||||
pain_message = FALSE
|
||||
|
||||
if(attack_damage >= 5 && armor < 100 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance
|
||||
if(attack_damage >= 5 && armor < 1 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance
|
||||
switch(zone) // strong punches can have effects depending on where they hit
|
||||
if(BP_HEAD, BP_MOUTH, BP_EYES)
|
||||
// Induce blurriness
|
||||
@@ -92,12 +93,12 @@ var/global/list/sparring_attack_cache = list()
|
||||
if(pain_message)
|
||||
target.visible_message("<span class='warning'>[target] gives way slightly.</span>")
|
||||
target.apply_effect(attack_damage*3, PAIN, armor)
|
||||
else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armor < 100) // Chance to get the usual throwdown as well (25% standard chance)
|
||||
else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armor < 1) // Chance to get the usual throwdown as well (25% standard chance)
|
||||
if(!target.lying)
|
||||
target.visible_message("<span class='danger'>[target] [pick("slumps", "falls", "drops")] down to the ground!</span>")
|
||||
else
|
||||
target.visible_message("<span class='danger'>[target] has been weakened!</span>")
|
||||
target.apply_effect(3, WEAKEN, armor)
|
||||
target.apply_effect(3, WEAKEN, armor*100)
|
||||
|
||||
/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
|
||||
var/obj/item/organ/external/affecting = target.get_organ(zone)
|
||||
|
||||
@@ -183,7 +183,7 @@ There are several things that need to be remembered:
|
||||
|
||||
//DAMAGE OVERLAYS
|
||||
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_raw list (as a list of icons).
|
||||
/mob/living/carbon/human/UpdateDamageIcon(var/update_icons=1)
|
||||
/mob/living/carbon/human/UpdateDamageIcon(var/update_icons = 1)
|
||||
// first check whether something actually changed about damage appearance
|
||||
var/damage_appearance = ""
|
||||
|
||||
|
||||
@@ -8,36 +8,46 @@
|
||||
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/damage_flags)
|
||||
if(!damage || (blocked >= 100))
|
||||
return 0
|
||||
/mob/living/proc/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone, var/used_weapon, var/damage_flags = 0, var/armor_pen, var/silent = FALSE)
|
||||
if(!damage)
|
||||
return FALSE
|
||||
|
||||
var/list/after_armor = modify_damage_by_armor(def_zone, damage, damagetype, damage_flags, src, armor_pen, silent)
|
||||
damage = after_armor[1]
|
||||
damagetype = after_armor[2]
|
||||
damage_flags = after_armor[3] // args modifications in case of parent calls
|
||||
if(!damage)
|
||||
return FALSE
|
||||
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
adjustBruteLoss(damage * BLOCKED_MULT(blocked))
|
||||
adjustBruteLoss(damage)
|
||||
if(BURN)
|
||||
if(COLD_RESISTANCE in mutations)
|
||||
damage = 0
|
||||
adjustFireLoss(damage * BLOCKED_MULT(blocked))
|
||||
adjustFireLoss(damage)
|
||||
if(TOX)
|
||||
adjustToxLoss(damage * BLOCKED_MULT(blocked))
|
||||
adjustToxLoss(damage)
|
||||
if(OXY)
|
||||
adjustOxyLoss(damage * BLOCKED_MULT(blocked))
|
||||
adjustOxyLoss(damage)
|
||||
if(CLONE)
|
||||
adjustCloneLoss(damage * BLOCKED_MULT(blocked))
|
||||
adjustCloneLoss(damage)
|
||||
if(PAIN)
|
||||
adjustHalLoss(damage * BLOCKED_MULT(blocked))
|
||||
updatehealth()
|
||||
return 1
|
||||
adjustHalLoss(damage)
|
||||
if(IRRADIATE)
|
||||
apply_radiation(damage)
|
||||
|
||||
/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)
|
||||
if(blocked >= 100) return 0
|
||||
updatehealth()
|
||||
return TRUE
|
||||
|
||||
/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, var/damage_flags = 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)
|
||||
if(oxy) apply_damage(oxy, OXY, def_zone, blocked)
|
||||
if(clone) apply_damage(clone, CLONE, def_zone, blocked)
|
||||
if(halloss) apply_damage(halloss, PAIN, def_zone, blocked)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
|
||||
if(!effect || (blocked >= 100)) return 0
|
||||
@@ -50,9 +60,6 @@
|
||||
Paralyse(effect * BLOCKED_MULT(blocked))
|
||||
if(PAIN)
|
||||
adjustHalLoss(effect * BLOCKED_MULT(blocked)) //Changed this to use the wrapper function, it shouldn't directly alter the value
|
||||
if(IRRADIATE)
|
||||
var/rad_protection = blocked ? getarmor(null, "rad")/100 : 0
|
||||
apply_radiation(max((1-rad_protection) * BLOCKED_MULT(blocked),0))//Rads auto check armor
|
||||
if(STUTTER)
|
||||
if(status_flags & CANSTUN) // stun is usually associated with stutter
|
||||
stuttering = max(stuttering, effect * BLOCKED_MULT(blocked))
|
||||
@@ -71,7 +78,6 @@
|
||||
if(stun) apply_effect(stun, STUN, blocked)
|
||||
if(weaken) apply_effect(weaken, WEAKEN, blocked)
|
||||
if(paralyze) apply_effect(paralyze, PARALYZE, blocked)
|
||||
if(irradiate) apply_effect(irradiate, IRRADIATE, blocked)
|
||||
if(stutter) apply_effect(stutter, STUTTER, blocked)
|
||||
if(eyeblur) apply_effect(eyeblur, EYE_BLUR, blocked)
|
||||
if(drowsy) apply_effect(drowsy, DROWSY, blocked)
|
||||
|
||||
@@ -1,58 +1,23 @@
|
||||
/mob/living/proc/modify_damage_by_armor(def_zone, damage, damage_type, damage_flags, mob/living/victim, armor_pen, silent = FALSE)
|
||||
var/list/armors = get_armors_by_zone(def_zone, damage_type, damage_flags)
|
||||
. = args.Copy(2)
|
||||
for(var/armor in armors)
|
||||
var/datum/component/armor/armor_datum = armor
|
||||
. = armor_datum.apply_damage_modifications(arglist(.))
|
||||
|
||||
/*
|
||||
run_armor_check() args
|
||||
def_zone - What part is getting hit, if null will check entire body
|
||||
attack_flag - The type of armor to be checked
|
||||
armor_pen - reduces the effectiveness of armor
|
||||
absorb_text - shown if the armor check is 100% successful
|
||||
soften_text - shown if the armor check is more than 0% successful and less than 100%
|
||||
Returns
|
||||
a blocked amount between 0 - 100, representing the success of the armor check.
|
||||
*/
|
||||
#define MOB_FIRE_LIGHT_RANGE 3 //These control the intensity and range of light given off by a mob which is on fire
|
||||
#define MOB_FIRE_LIGHT_POWER 2
|
||||
|
||||
/mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/armor_pen = 0, var/absorb_text = null, var/soften_text = null)
|
||||
if(armor_pen >= 100)
|
||||
return 0 //might as well just skip the processing
|
||||
|
||||
var/armor = getarmor(def_zone, attack_flag)
|
||||
|
||||
if(armor_pen >= armor)
|
||||
return 0 //effective_armor is going to be 0
|
||||
|
||||
var/blocked = (armor - armor_pen)
|
||||
|
||||
if(blocked >= 100)
|
||||
if(absorb_text)
|
||||
show_message("<span class='warning'>[absorb_text]</span>")
|
||||
else
|
||||
show_message("<span class='warning'>Your armor absorbs the blow!</span>")
|
||||
return 100
|
||||
|
||||
if(blocked > 20)
|
||||
//Should we show this every single time?
|
||||
if(soften_text)
|
||||
show_message("<span class='warning'>[soften_text]</span>")
|
||||
else
|
||||
show_message("<span class='warning'>Your armor softens the blow!</span>")
|
||||
|
||||
return round(blocked, 1)
|
||||
|
||||
//Adds two armor values together.
|
||||
//If armor_a and armor_b are between 0-100 the result will always also be between 0-100.
|
||||
/proc/add_armor(var/armor_a, var/armor_b)
|
||||
if(armor_a >= 100 || armor_b >= 100)
|
||||
return 100 //adding to infinite protection doesn't make it any bigger
|
||||
|
||||
var/protection_a = 1/(BLOCKED_MULT(armor_a)) - 1
|
||||
var/protection_b = 1/(BLOCKED_MULT(armor_b)) - 1
|
||||
return 100 - 1/(protection_a + protection_b + 1)*100
|
||||
|
||||
//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)
|
||||
return 0
|
||||
/mob/living/proc/get_blocked_ratio(def_zone, damage_type, damage_flags, armor_pen, damage)
|
||||
var/list/armors = get_armors_by_zone(def_zone, damage_type, damage_flags)
|
||||
. = 0
|
||||
for(var/armor in armors)
|
||||
var/datum/component/armor/armor_datum = armor
|
||||
. = 1 - (1 - .) * (1 - armor_datum.get_blocked(damage_type, damage_flags, armor_pen, damage)) // multiply the amount we let through
|
||||
. = min(1, .)
|
||||
|
||||
/mob/living/proc/get_armors_by_zone(def_zone, damage_type, damage_flags)
|
||||
. = list()
|
||||
var/natural_armor = GetComponent(/datum/component/armor)
|
||||
if(natural_armor)
|
||||
. += natural_armor
|
||||
|
||||
/mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone, var/used_weapon = null)
|
||||
|
||||
@@ -80,19 +45,15 @@
|
||||
return
|
||||
|
||||
//Armor
|
||||
var/absorb = run_armor_check(def_zone, P.check_armor, P.armor_penetration)
|
||||
var/damage = P.damage
|
||||
var/flags = P.damage_flags()
|
||||
var/damaged
|
||||
if(prob(absorb))
|
||||
if(P.damage_flags & DAM_SHARP || P.damage_flags & DAM_SHARP || P.damage_flags & DAM_LASER)
|
||||
P.damage_flags &= ~DAM_SHARP
|
||||
P.damage_flags &= ~DAM_EDGE
|
||||
P.damage_flags &= ~DAM_LASER
|
||||
|
||||
if(!P.nodamage)
|
||||
damaged = apply_damage(P.damage, P.damage_type, def_zone, absorb, 0, P, damage_flags = P.damage_flags, used_weapon = P)
|
||||
bullet_impact_visuals(P, def_zone, damaged)
|
||||
P.on_hit(src, absorb, def_zone)
|
||||
return absorb
|
||||
damaged = apply_damage(damage, P.damage_type, def_zone, damage_flags = P.damage_flags(), used_weapon = P, armor_pen = P.armor_penetration)
|
||||
if(damaged || P.nodamage) // Run the block computation if we did damage or if we only use armor for effects (nodamage)
|
||||
. = get_blocked_ratio(def_zone, P.damage_type, flags, P.armor_penetration, P.damage)
|
||||
bullet_impact_visuals(P, def_zone, damage, .)
|
||||
P.on_hit(src, ., def_zone)
|
||||
|
||||
/mob/living/proc/aura_check(var/type)
|
||||
if(!auras)
|
||||
@@ -117,7 +78,7 @@
|
||||
break
|
||||
|
||||
//For visuals, blood splatters and so on.
|
||||
/mob/living/proc/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage)
|
||||
/mob/living/proc/bullet_impact_visuals(var/obj/item/projectile/P, var/def_zone, var/damage, var/blocked_ratio)
|
||||
var/list/impact_sounds = LAZYACCESS(P.impact_sounds, get_bullet_impact_effect_type(def_zone))
|
||||
if(length(impact_sounds))
|
||||
playsound(src, pick(impact_sounds), 75)
|
||||
@@ -136,7 +97,7 @@
|
||||
apply_effect(stun_amount, EYE_BLUR)
|
||||
|
||||
if(agony_amount)
|
||||
apply_damage(agony_amount, PAIN, def_zone, 0, used_weapon)
|
||||
apply_damage(agony_amount, PAIN, def_zone, 0, used_weapon = used_weapon)
|
||||
apply_effect(agony_amount / 10, STUTTER)
|
||||
apply_effect(agony_amount / 10, EYE_BLUR)
|
||||
|
||||
@@ -159,8 +120,7 @@
|
||||
/mob/living/proc/hit_with_weapon(obj/item/I, mob/living/user, var/effective_force, var/hit_zone, var/ground_zero)
|
||||
visible_message("<span class='danger'>[src] has been [LAZYPICK(I.attack_verb,"attacked")] with [I] by [user]!</span>")
|
||||
|
||||
var/blocked = run_armor_check(hit_zone, "melee")
|
||||
standard_weapon_hit_effects(I, user, effective_force, blocked, hit_zone)
|
||||
. = standard_weapon_hit_effects(I, user, effective_force, hit_zone)
|
||||
|
||||
if(I.damtype == BRUTE && prob(33) && I.force) // Added blood for whacking non-humans too
|
||||
var/turf/simulated/location = get_turf(src)
|
||||
@@ -169,9 +129,9 @@
|
||||
return blocked
|
||||
|
||||
//returns 0 if the effects failed to apply for some reason, 1 otherwise.
|
||||
/mob/living/proc/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
|
||||
/mob/living/proc/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/hit_zone)
|
||||
if(!effective_force || blocked >= 100)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
//Hulk modifier
|
||||
if(HULK in user.mutations)
|
||||
@@ -185,13 +145,13 @@
|
||||
|
||||
apply_damage(effective_force, I.damtype, hit_zone, blocked, used_weapon=I, damage_flags = damage_flags)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//this proc handles being hit by a thrown atom
|
||||
/mob/living/hitby(atom/movable/AM, var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve
|
||||
if(!aura_check(AURA_TYPE_THROWN, AM, speed))
|
||||
return
|
||||
if(istype(AM,/obj/))
|
||||
if(isobj(AM))
|
||||
var/obj/O = AM
|
||||
var/dtype = O.damtype
|
||||
var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
|
||||
@@ -207,10 +167,7 @@
|
||||
return
|
||||
|
||||
src.visible_message("<span class='warning'>[src] has been hit by [O].</span>")
|
||||
var/armor = run_armor_check(null, "melee")
|
||||
|
||||
var/damage_flags = O.damage_flags()
|
||||
apply_damage(throw_damage, dtype, null, armor, O, damage_flags = damage_flags)
|
||||
apply_damage(throw_damage, dtype, null, damage_flags = O.damage_flags(), used_weapon = O)
|
||||
|
||||
O.throwing = 0 //it hit, so stop moving
|
||||
|
||||
@@ -236,7 +193,8 @@
|
||||
visible_message("<span class='warning'>[src] staggers under the impact!</span>","<span class='warning'>You stagger under the impact!</span>")
|
||||
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
||||
|
||||
if(!O || !src) return
|
||||
if(!O || !src)
|
||||
return
|
||||
|
||||
if(O.sharp) //Projectile is suitable for pinning.
|
||||
//Handles embedding for non-humans and simple_animals.
|
||||
@@ -301,6 +259,9 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
#define MOB_FIRE_LIGHT_RANGE 3 //These control the intensity and range of light given off by a mob which is on fire
|
||||
#define MOB_FIRE_LIGHT_POWER 2
|
||||
|
||||
/mob/living/proc/set_on_fire()
|
||||
to_chat(src, SPAN_DANGER(FONT_LARGE("You're set on fire!")))
|
||||
on_fire = TRUE
|
||||
|
||||
@@ -17,8 +17,4 @@
|
||||
M.apply_effect(5, STUTTER)
|
||||
M.stun_effect_act(0, 70, check_zone(hit_zone), src)
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.forcesay(hit_appends)
|
||||
|
||||
return FALSE
|
||||
@@ -282,22 +282,14 @@
|
||||
if(1.0)
|
||||
brute = 400
|
||||
burn = 100
|
||||
if(!anchored && !prob(getarmor(null, "bomb")))
|
||||
gib()
|
||||
if(2.0)
|
||||
brute = 60
|
||||
burn = 60
|
||||
if(3.0)
|
||||
brute = 30
|
||||
|
||||
var/protection = BLOCKED_MULT(getarmor(null, "bomb"))
|
||||
brute *= protection
|
||||
burn *= protection
|
||||
|
||||
adjustBruteLoss(brute)
|
||||
adjustFireLoss(burn)
|
||||
|
||||
updatehealth()
|
||||
apply_damage(brute, BRUTE, damage_flags = DAM_EXPLODE)
|
||||
apply_damage(burn, BURN, damage_flags = DAM_EXPLODE)
|
||||
|
||||
/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised)
|
||||
if(!next_alarm_notice)
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/commanded/bear/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone)
|
||||
. = ..()
|
||||
if(!.)
|
||||
if(.)
|
||||
src.emote("roars in rage!")
|
||||
|
||||
/mob/living/simple_animal/hostile/commanded/bear/attack_hand(mob/living/carbon/human/M as mob)
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
target_mob = null
|
||||
audible_emote("[pick(sad_emote)].",0)
|
||||
return
|
||||
if(!. && retribution)
|
||||
if(. && retribution)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
target_mob = user
|
||||
allowed_targets += user //fuck this guy in particular.
|
||||
|
||||
@@ -485,7 +485,7 @@
|
||||
var/mob/living/carbon/human/H = parrot_interest
|
||||
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
|
||||
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), damage_flags = DAM_SHARP)
|
||||
H.apply_damage(damage, BRUTE, affecting, damage_flags = DAM_SHARP)
|
||||
visible_emote(pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons."))
|
||||
|
||||
else
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
var/datum/weakref/original_body
|
||||
var/datum/weakref/possessed_body
|
||||
|
||||
/mob/living/simple_animal/shade/bluespace/apply_damage(var/damage, var/damagetype, var/def_zone, var/blocked, var/used_weapon, var/damage_flags)
|
||||
/mob/living/simple_animal/shade/bluespace/apply_damage(var/damage, var/damagetype, var/def_zone, var/blocked, var/used_weapon, var/damage_flags, var/armor_pen, var/silent = FALSE)
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/shade/bluespace/adjustBruteLoss()
|
||||
|
||||
@@ -549,7 +549,7 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
user.do_attack_animation(src)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/apply_damage(damage, damagetype, def_zone, blocked, used_weapon, damage_flags)
|
||||
/mob/living/simple_animal/apply_damage(damage, damagetype, def_zone, blocked, used_weapon, damage_flags, armor_pen, silent = FALSE)
|
||||
. = ..()
|
||||
handle_blood_overlay()
|
||||
|
||||
@@ -614,8 +614,6 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
damage = 500
|
||||
if(!prob(getarmor(null, "bomb")))
|
||||
gib()
|
||||
|
||||
if (2.0)
|
||||
damage = 120
|
||||
@@ -623,7 +621,7 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(3.0)
|
||||
damage = 30
|
||||
|
||||
adjustBruteLoss(damage * BLOCKED_MULT(getarmor(null, "bomb")))
|
||||
apply_damage(damage, BRUTE, damage_flags = DAM_EXPLODE)
|
||||
|
||||
/mob/living/simple_animal/proc/SA_attackable(target_mob)
|
||||
if (isliving(target_mob))
|
||||
|
||||
@@ -371,7 +371,7 @@
|
||||
if(hit_zone == BP_EYES)
|
||||
attack_eye(affecting, assailant)
|
||||
else if(hit_zone == BP_HEAD)
|
||||
headbut(affecting, assailant)
|
||||
headbutt(affecting, assailant)
|
||||
else
|
||||
dislocate(affecting, assailant, hit_zone)
|
||||
|
||||
|
||||
@@ -55,8 +55,8 @@
|
||||
return
|
||||
|
||||
attacker.visible_message("<span class='danger'>[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!</span>")
|
||||
var/armor = target.run_armor_check(target, "melee")
|
||||
if(armor < 100)
|
||||
var/armor = 100 * target.get_blocked_ratio(target, BRUTE, damage = 30)
|
||||
if(armor < 70)
|
||||
to_chat(target, "<span class='danger'>You feel extreme pain!</span>")
|
||||
affecting.adjustHalLoss(Clamp(0, 60-affecting.getHalLoss(), 30)) //up to 60 halloss
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
attack.handle_eye_attack(attacker, target)
|
||||
|
||||
/obj/item/grab/proc/headbut(mob/living/carbon/human/target, mob/living/carbon/human/attacker)
|
||||
/obj/item/grab/proc/headbutt(mob/living/carbon/human/target, mob/living/carbon/human/attacker)
|
||||
if(!istype(attacker))
|
||||
return
|
||||
if(target.lying)
|
||||
@@ -104,9 +104,8 @@
|
||||
if(istype(hat))
|
||||
damage += hat.force * 3
|
||||
|
||||
var/armor = target.run_armor_check(BP_HEAD, "melee")
|
||||
target.apply_damage(damage, BRUTE, BP_HEAD, armor)
|
||||
attacker.apply_damage(10, BRUTE, BP_HEAD, attacker.run_armor_check(BP_HEAD, "melee"))
|
||||
target.apply_damage(damage, BRUTE, BP_HEAD)
|
||||
attacker.apply_damage(10, BRUTE, BP_HEAD)
|
||||
|
||||
if(armor < 25 && target.headcheck(BP_HEAD) && prob(damage))
|
||||
target.apply_effect(20, PARALYZE)
|
||||
|
||||
Reference in New Issue
Block a user