Ports baystation armor system (#2954)

Ports Baystation12/Baystation12#12658

Changing how the calculation of armor works , instead of just being a check if it is protected fully, half or nothing. Making armor more reliable and less rng dependant.

Also, uranium meteors will irradiate nearby people when they explode.
This commit is contained in:
Alberyk
2017-07-15 10:24:03 -03:00
committed by skull132
parent 41e39f52d1
commit 2f949ecb45
52 changed files with 274 additions and 248 deletions
@@ -6,7 +6,7 @@
return ..()
/mob/living/carbon/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
if(!effective_force || blocked >= 2)
if(!effective_force || blocked >= 100)
return 0
//Hulk modifier
@@ -16,7 +16,7 @@
//Apply weapon damage
var/weapon_sharp = is_sharp(I)
var/weapon_edge = has_edge(I)
if(prob(getarmor(hit_zone, "melee"))) //melee armour provides a chance to turn sharp/edge weapon attacks into blunt ones
if(prob(blocked)) //armour provides a chance to turn sharp/edge weapon attacks into blunt ones
weapon_sharp = 0
weapon_edge = 0
@@ -24,9 +24,9 @@
//Melee weapon embedded object code.
if (I && I.damtype == BRUTE && !I.anchored && !is_robot_module(I))
var/damage = effective_force
var/damage = effective_force //just the effective damage used for sorting out embedding, no further damage is applied here
if (blocked)
damage /= blocked+1
damage *= BLOCKED_MULT(blocked)
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
+15 -18
View File
@@ -150,7 +150,6 @@
if(!blinded)
flick("flash", flash)
var/shielded = 0
var/b_loss = null
var/f_loss = null
@@ -160,6 +159,7 @@
switch (severity)
if (1.0)
b_loss += 500
f_loss = 100
if (!prob(getarmor(null, "bomb")))
gib()
return
@@ -171,40 +171,37 @@
//user.throw_at(target, 200, 4)
if (2.0)
if (!shielded)
b_loss += 60
f_loss += 60
if (prob(getarmor(null, "bomb")))
b_loss = b_loss/1.5
f_loss = f_loss/1.5
b_loss = 60
f_loss = 60
if (!istype(l_ear, /obj/item/clothing/ears/earmuffs) && !istype(r_ear, /obj/item/clothing/ears/earmuffs))
ear_damage += 30
ear_deaf += 120
if (prob(70) && !shielded)
if (prob(70))
Paralyse(10)
if(3.0)
b_loss += 30
if (prob(getarmor(null, "bomb")))
b_loss = b_loss/2
b_loss = 30
if (!istype(l_ear, /obj/item/clothing/ears/earmuffs) && !istype(r_ear, /obj/item/clothing/ears/earmuffs))
ear_damage += 15
ear_deaf += 60
if (prob(50) && !shielded)
if (prob(50))
Paralyse(10)
// factor in armour
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.9, f_loss * 0.9, used_weapon = "Explosive blast")
update |= take_blast.take_damage(b_loss * 0.7, f_loss * 0.7, used_weapon = "Explosive blast")
// distribute the remaining 10% on all limbs equally
b_loss *= 0.1
f_loss *= 0.1
// distribute the remaining 30% on all limbs equally (including the one already dealt damage)
b_loss *= 0.3
f_loss *= 0.3
var/weapon_message = "Explosive Blast"
@@ -273,12 +273,12 @@
if(H.gloves && istype(H.gloves,/obj/item/clothing/gloves/force))
var/obj/item/clothing/gloves/force/X = H.gloves
real_damage *= X.amplification
var/armour = run_armor_check(affecting, "melee")
var/armour = run_armor_check(hit_zone, "melee")
// Apply additional unarmed effects.
attack.apply_effects(H, src, armour, rand_damage, hit_zone)
// Finally, apply damage to target
apply_damage(real_damage, (attack.deal_halloss ? HALLOSS : BRUTE), affecting, armour, sharp=attack.sharp, edge=attack.edge)
apply_damage(real_damage, (attack.deal_halloss ? HALLOSS : BRUTE), hit_zone, armour, sharp=attack.sharp, edge=attack.edge)
if(I_DISARM)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Disarmed [src.name] ([src.ckey])</font>")
@@ -319,7 +319,7 @@
var/armor_check = run_armor_check(affecting, "melee")
apply_effect(3, WEAKEN, armor_check)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(armor_check < 2)
if(armor_check < 100)
visible_message("<span class='danger'>[M] has pushed [src]!</span>")
else
visible_message("<span class='warning'>[M] attempted to push [src]!</span>")
@@ -361,8 +361,8 @@ This function restores all organs.
src.invisibility = 0
//Handle other types of damage
if(!stat && damagetype != BRUTE && damagetype != BURN)
if(damagetype == HALLOSS && !(species && (species.flags & NO_PAIN)))
if(damagetype != BRUTE && damagetype != BURN)
if(!stat && damagetype == HALLOSS && !(species && (species.flags & NO_PAIN)))
if ((damage > 25 && prob(20)) || (damage > 50 && prob(60)))
emote("scream")
@@ -372,7 +372,7 @@ This function restores all organs.
//Handle BRUTE and BURN damage
handle_suit_punctures(damagetype, damage, def_zone)
if(blocked >= 2) return 0
if(blocked >= 100) return 0
var/obj/item/organ/external/organ = null
if(isorgan(def_zone))
@@ -383,7 +383,7 @@ This function restores all organs.
if(!organ) return 0
if(blocked)
damage = (damage/(blocked+1))
damage *= BLOCKED_MULT(blocked)
switch(damagetype)
if(BRUTE)
@@ -405,4 +405,4 @@ This function restores all organs.
/mob/living/carbon/human/apply_radiation(var/rads)
if (species && rads > 0)
rads = rads * species.radiation_mod
..(rads)
..(rads)
@@ -22,8 +22,8 @@ emp_act
if(shield_check < 0)
return shield_check
else
P.on_hit(src, 2, def_zone)
return 2
P.on_hit(src, 100, def_zone)
return 100
//Shrapnel
if(P.can_embed())
@@ -110,7 +110,7 @@ emp_act
if(gear && istype(gear ,/obj/item/clothing))
var/obj/item/clothing/C = gear
if(istype(C) && C.body_parts_covered & def_zone.body_part && C.armor)
protection += C.armor[type]
protection = add_armor(protection, C.armor[type])
return protection
/mob/living/carbon/human/proc/check_head_coverage()
@@ -151,9 +151,6 @@ emp_act
..()
/mob/living/carbon/human/resolve_item_attack(obj/item/I, mob/living/user, var/target_zone)
if(check_attack_throat(I, user))
return null
if(user == src) // Attacking yourself can't miss
return target_zone
@@ -258,9 +255,9 @@ emp_act
return 1
/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 >= 2)
if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100)
return 0
if(prob(W.force / (blocked+1)))
if(prob(W.force * BLOCKED_MULT(blocked)))
visible_message("<span class='danger'>[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!</span>")
organ.dislocate(1)
return 1
@@ -327,7 +324,7 @@ emp_act
src.visible_message("<span class='warning'>[src] has been hit in the [hit_area] by [O].</span>")
var/armor = run_armor_check(affecting, "melee", O.armor_penetration, "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)
if(armor < 100)
apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O)
if(ismob(O.thrower))
@@ -346,7 +343,7 @@ emp_act
var/sharp = is_sharp(I)
var/damage = throw_damage
if (armor)
damage /= armor+1
damage *= BLOCKED_MULT(armor)
//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)
@@ -48,7 +48,7 @@ var/global/list/sparring_attack_cache = list()
var/stun_chance = rand(0, 100)
if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance
if(attack_damage >= 5 && armour < 100 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance
switch(zone) // strong punches can have effects depending on where they hit
if("head", "mouth", "eyes")
// Induce blurriness
@@ -83,7 +83,7 @@ var/global/list/sparring_attack_cache = list()
if(!target.lying)
target.visible_message("<span class='warning'>[target] gives way slightly.</span>")
target.apply_effect(attack_damage*3, AGONY, armour)
else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armour < 2) // Chance to get the usual throwdown as well (25% standard chance)
else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armour < 100) // 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
+26 -26
View File
@@ -1,36 +1,36 @@
/*
apply_damage(a,b,c)
args
a:damage - How much damage to take
b:damage_type - What type of damage to take, brute, burn
c:def_zone - Where to take the damage if its brute or burn
apply_damage() args
damage - How much damage to take
damage_type - What type of damage to take, brute, burn
def_zone - Where to take the damage if its brute or burn
Returns
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
if(!damage || (blocked >= 100)) return 0
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage/(blocked+1))
adjustBruteLoss(damage * BLOCKED_MULT(blocked))
if(BURN)
if(COLD_RESISTANCE in mutations) damage = 0
adjustFireLoss(damage/(blocked+1))
adjustFireLoss(damage * BLOCKED_MULT(blocked))
if(TOX)
adjustToxLoss(damage/(blocked+1))
adjustToxLoss(damage * BLOCKED_MULT(blocked))
if(OXY)
adjustOxyLoss(damage/(blocked+1))
adjustOxyLoss(damage * BLOCKED_MULT(blocked))
if(CLONE)
adjustCloneLoss(damage/(blocked+1))
adjustCloneLoss(damage * BLOCKED_MULT(blocked))
if(HALLOSS)
adjustHalLoss(damage/(blocked+1))
adjustHalLoss(damage * BLOCKED_MULT(blocked))
flash_weak_pain()
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)
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)
@@ -41,29 +41,29 @@
/mob/living/proc/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0, var/check_protection = 1)
if(!effect || (blocked >= 2)) return 0
/mob/living/proc/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
if(!effect || (blocked >= 100)) return 0
switch(effecttype)
if(STUN)
Stun(effect/(blocked+1))
Stun(effect * BLOCKED_MULT(blocked))
if(WEAKEN)
Weaken(effect/(blocked+1))
Weaken(effect * BLOCKED_MULT(blocked))
if(PARALYZE)
Paralyse(effect/(blocked+1))
Paralyse(effect * BLOCKED_MULT(blocked))
if(AGONY)
adjustHalLoss(effect) //Changed this to use the wrapper function, it shouldn't directly alter the value
adjustHalLoss(effect * BLOCKED_MULT(blocked)) //Changed this to use the wrapper function, it shouldn't directly alter the value
if(IRRADIATE)
var/rad_protection = check_protection ? getarmor(null, "rad")/100 : 0
apply_radiation(max((1-rad_protection)*effect/(blocked+1),0))//Rads auto check armor
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+1)))
stuttering = max(stuttering, effect * BLOCKED_MULT(blocked))
if(EYE_BLUR)
eye_blurry = max(eye_blurry,(effect/(blocked+1)))
eye_blurry = max(eye_blurry, effect * BLOCKED_MULT(blocked))
if(DROWSY)
drowsyness = max(drowsyness,(effect/(blocked+1)))
drowsyness = max(drowsyness, effect * BLOCKED_MULT(blocked))
if(INCINERATE)
adjust_fire_stacks(effect/(blocked+1))
adjust_fire_stacks(effect * BLOCKED_MULT(blocked))
IgniteMob()
updatehealth()
return 1
@@ -86,4 +86,4 @@
/mob/living/proc/apply_radiation(var/rads)
total_radiation += rads
if (total_radiation < 0)
total_radiation = 0
total_radiation = 0
-1
View File
@@ -296,7 +296,6 @@ default behaviour is:
/mob/living/proc/adjustHalLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
halloss = min(max(halloss + amount, 0),(maxHealth*2))
/mob/living/carbon/adjustHalLoss(var/amount, var/ignoreImmunity = 0)//An inherited version so this doesnt affect cyborgs
+41 -32
View File
@@ -1,14 +1,13 @@
/*
run_armor_check(a,b)
args
a:def_zone - What part is getting hit, if null will check entire body
b:attack_flag - What type of attack, bullet, laser, energy, melee
run_armor_check() args
def_zone - What part is getting hit, if null will check entire body
attack_flag - The type of armour to be checked
armour_pen - reduces the effectiveness of armour
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
0 - no block
1 - halfblock
2 - fullblock
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
@@ -18,34 +17,45 @@
return 0 //might as well just skip the processing
var/armor = getarmor(def_zone, attack_flag)
var/absorb = 0
//Roll armour
if(prob(armor))
absorb += 1
if(prob(armor))
absorb += 1
if(armour_pen >= armor)
return 0 //effective_armor is going to be 0, fullblock is going to be 0, blocked is going to 0, let's save ourselves the trouble
//Roll penetration
if(prob(armour_pen))
absorb -= 1
if(prob(armour_pen))
absorb -= 1
var/effective_armor = (armor - armour_pen)/100
var/fullblock = (effective_armor*effective_armor) * ARMOR_BLOCK_CHANCE_MULT
if(absorb >= 2)
if(fullblock >= 1 || prob(fullblock*100))
if(absorb_text)
show_message("[absorb_text]")
show_message("<span class='warning'>[absorb_text]</span>")
else
show_message("<span class='warning'>Your armor absorbs the blow!</span>")
return 2
if(absorb == 1)
if(absorb_text)
show_message("[soften_text]",4)
return 100
//this makes it so that X armour blocks X% damage, when including the chance of hard block.
//I double checked and this formula will also ensure that a higher effective_armor
//will always result in higher (non-fullblock) damage absorption too, which is also a nice property
//In particular, blocked will increase from 0 to 50 as effective_armor increases from 0 to 0.999 (if it is 1 then we never get here because ofc)
//and the average damage absorption = (blocked/100)*(1-fullblock) + 1.0*(fullblock) = effective_armor
var/blocked = (effective_armor - fullblock)/(1 - fullblock)*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 1
return 0
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)
@@ -81,7 +91,7 @@
var/absorb = run_armor_check(def_zone, P.check_armour, P.armor_penetration)
var/proj_sharp = is_sharp(P)
var/proj_edge = has_edge(P)
if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.check_armour)))
if ((proj_sharp || proj_edge) && prob(absorb))
proj_sharp = 0
proj_edge = 0
@@ -132,7 +142,7 @@
//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)
if(!effective_force || blocked >= 2)
if(!effective_force || blocked >= 100)
return 0
//Hulk modifier
@@ -142,7 +152,7 @@
//Apply weapon damage
var/weapon_sharp = is_sharp(I)
var/weapon_edge = has_edge(I)
if(prob(max(getarmor(hit_zone, "melee") - I.armor_penetration, 0))) //melee armour provides a chance to turn sharp/edge weapon attacks into blunt ones
if(prob(blocked)) //armour provides a chance to turn sharp/edge weapon attacks into blunt ones
weapon_sharp = 0
weapon_edge = 0
@@ -169,8 +179,7 @@
src.visible_message("<span class='warning'>[src] has been hit by [O].</span>")
var/armor = run_armor_check(null, "melee")
if(armor < 2)
apply_damage(throw_damage, dtype, null, armor, is_sharp(O), has_edge(O), O)
apply_damage(throw_damage, dtype, null, armor, is_sharp(O), has_edge(O), O)
O.throwing = 0 //it hit, so stop moving
+18 -12
View File
@@ -110,9 +110,9 @@
if(BURN)
adjustFireLoss(Proj.damage)
Proj.on_hit(src,2)
Proj.on_hit(src,100)
updatehealth()
return 2
return 100
/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now
@@ -270,20 +270,26 @@
if(!blinded)
flick("flash", flash)
var/brute
var/burn
switch(severity)
if(1.0)
if (stat != 2)
adjustBruteLoss(100)
adjustFireLoss(100)
if(!anchored)
gib()
brute = 400
burn = 100
if(!anchored && !prob(getarmor(null, "bomb")))
gib()
if(2.0)
if (stat != 2)
adjustBruteLoss(60)
adjustFireLoss(60)
brute = 60
burn = 60
if(3.0)
if (stat != 2)
adjustBruteLoss(30)
brute = 30
var/protection = BLOCKED_MULT(getarmor(null, "bomb"))
brute *= protection
burn *= protection
adjustBruteLoss(brute)
adjustFireLoss(burn)
updatehealth()
@@ -477,18 +477,21 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
/mob/living/simple_animal/ex_act(severity)
if(!blinded)
flick("flash", flash)
var/damage
switch (severity)
if (1.0)
apply_damage(500, BRUTE)
gib()
return
damage = 500
if(!prob(getarmor(null, "bomb")))
gib()
if (2.0)
apply_damage(60, BRUTE)
damage = 120
if(3.0)
apply_damage(30, BRUTE)
damage = 30
adjustBruteLoss(damage * BLOCKED_MULT(getarmor(null, "bomb")))
/mob/living/simple_animal/proc/SA_attackable(target_mob)
if (isliving(target_mob))
@@ -685,8 +688,8 @@ mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
src << span("notice","You are now [resting ? "resting" : "getting up"]")
update_icons()
//Todo: add snowflakey shit to it.
/mob/living/simple_animal/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null, var/tesla_shock = 0)
apply_damage(shock_damage, BURN)
visible_message("<span class='warning'>[src] was shocked by [source]!</span>", "<span class='danger'>You are shocked by [source]!</span>", "<span class='notice'>You hear an electrical crack.</span>")
visible_message("<span class='warning'>[src] was shocked by [source]!</span>", "<span class='danger'>You are shocked by [source]!</span>", "<span class='notice'>You hear an electrical crack.</span>")
+2 -2
View File
@@ -52,7 +52,7 @@
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 < 2)
if(armor < 100)
target << "<span class='danger'>You feel extreme pain!</span>"
affecting.adjustHalLoss(Clamp(0, 60-affecting.halloss, 30)) //up to 60 halloss
@@ -97,7 +97,7 @@
target.apply_damage(damage, BRUTE, "head", armor)
attacker.apply_damage(10, BRUTE, "head", attacker.run_armor_check("head", "melee"))
if(!armor && target.headcheck("head") && prob(damage))
if(armor < 25 && target.headcheck("head") && prob(damage))
target.apply_effect(20, PARALYZE)
target.visible_message("<span class='danger'>[target] [target.species.knockout_message]</span>")