mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +01:00
Some more armor tweaks (#30398)
* summary * (required) * undef * oh this is unused, nice * ok but.. why * a tiny bit more * Update human_defense.dm * Update mass_hallucination.dm
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
/// Chance for mob to avoid being affected by rad storm
|
||||
#define RAD_STORM_AVOID_CHANCE 40
|
||||
/// Chance to additionally apply good or bad mutation
|
||||
#define RAD_STORM_ADDITIONAL_MUT_CHANCE 50
|
||||
/// Chance to apply bad mutation. When failed will apply good mutation instead
|
||||
#define RAD_STORM_BAD_MUT_CHANCE 90
|
||||
/// Amount of radiation mob receives when affected
|
||||
#define RAD_STORM_RAD_AMOUNT 400
|
||||
|
||||
//Radiation storms occur when the station passes through an irradiated area, and irradiate anyone not standing in protected areas (maintenance, emergency storage, etc.)
|
||||
/datum/weather/rad_storm
|
||||
name = "radiation storm"
|
||||
@@ -41,30 +50,26 @@
|
||||
if(!SSmapping.maint_all_access)
|
||||
SSmapping.make_maint_all_access()
|
||||
|
||||
/datum/weather/rad_storm/weather_act(mob/living/L)
|
||||
if(!prob(60))
|
||||
/datum/weather/rad_storm/weather_act(mob/living/carbon/human/human)
|
||||
if(!istype(human) || HAS_TRAIT(human, TRAIT_RADIMMUNE) || prob(RAD_STORM_AVOID_CHANCE))
|
||||
return
|
||||
|
||||
if(!ishuman(L))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = L
|
||||
var/resist = H.getarmor(null, RAD)
|
||||
if(HAS_TRAIT(H, TRAIT_RADIMMUNE) || resist == INFINITY)
|
||||
var/resist = human.getarmor(armor_type = RAD)
|
||||
if(resist == INFINITY)
|
||||
return
|
||||
|
||||
if(prob(max(0, 100 - ARMOUR_VALUE_TO_PERCENTAGE(resist))))
|
||||
L.base_rad_act(L ,400 , BETA_RAD)
|
||||
if(HAS_TRAIT(H, TRAIT_GENELESS))
|
||||
human.base_rad_act(human, RAD_STORM_RAD_AMOUNT, BETA_RAD)
|
||||
if(HAS_TRAIT(human, TRAIT_GENELESS))
|
||||
return
|
||||
randmuti(H) // Applies bad mutation
|
||||
if(prob(50))
|
||||
if(prob(90))
|
||||
randmutb(H)
|
||||
randmuti(human) // Applies appearance mutation
|
||||
if(prob(RAD_STORM_ADDITIONAL_MUT_CHANCE))
|
||||
if(prob(RAD_STORM_BAD_MUT_CHANCE))
|
||||
randmutb(human) // Applies bad mutation
|
||||
else
|
||||
randmutg(H)
|
||||
randmutg(human) // Applies good mutation
|
||||
|
||||
domutcheck(H, MUTCHK_FORCED)
|
||||
domutcheck(human, MUTCHK_FORCED)
|
||||
|
||||
/datum/weather/rad_storm/end()
|
||||
if(..())
|
||||
@@ -82,3 +87,8 @@
|
||||
post_status(STATUS_DISPLAY_ALERT, "radiation")
|
||||
else
|
||||
post_status(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME)
|
||||
|
||||
#undef RAD_STORM_AVOID_CHANCE
|
||||
#undef RAD_STORM_ADDITIONAL_MUT_CHANCE
|
||||
#undef RAD_STORM_BAD_MUT_CHANCE
|
||||
#undef RAD_STORM_RAD_AMOUNT
|
||||
|
||||
@@ -296,10 +296,7 @@
|
||||
if(HAS_TRAIT(occupant, TRAIT_GENELESS))
|
||||
return TRUE
|
||||
|
||||
var/radiation_protection = occupant.run_armor_check(null, RAD)
|
||||
if(radiation_protection > NEGATE_MUTATION_THRESHOLD)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return occupant.run_armor_check(armor_type = RAD) > NEGATE_MUTATION_THRESHOLD
|
||||
|
||||
/obj/machinery/computer/scan_consolenew
|
||||
name = "\improper DNA Modifier access console"
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/organ/external/target_part = H.get_organ(ran_zone("chest"))
|
||||
H.apply_damage(10, BRUTE, "chest", H.run_armor_check(target_part, MELEE))
|
||||
H.apply_damage(10, BRUTE, BODY_ZONE_CHEST, H.run_armor_check(target_part, MELEE))
|
||||
|
||||
//blood splatters
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter(H.drop_location(), splatter_dir, H.dna.species.blood_color)
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
* * user - The attacking user
|
||||
*/
|
||||
/obj/item/melee/classic_baton/proc/on_non_silicon_stun(mob/living/target, mob/living/user)
|
||||
var/armour = target.run_armor_check("chest", armor_penetration_percentage = stamina_armor_pen) // returns their chest melee armour
|
||||
var/armour = target.run_armor_check(BODY_ZONE_CHEST, armor_penetration_percentage = stamina_armor_pen) // returns their chest melee armour
|
||||
var/percentage_reduction = 0
|
||||
if(ishuman(target))
|
||||
percentage_reduction = (100 - ARMOUR_VALUE_TO_PERCENTAGE(armour)) / 100
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
var/mob/living/carbon/M = G.assailant
|
||||
C_imp_in.visible_message("<span class='warning'>[C_imp_in] suddenly shocks [M] from their wrists and slips out of their grab!</span>")
|
||||
M.Stun(2 SECONDS) //Drops the grab
|
||||
M.apply_damage(2, BURN, "r_hand", M.run_armor_check("r_hand", "energy"))
|
||||
M.apply_damage(2, BURN, "l_hand", M.run_armor_check("l_hand", "energy"))
|
||||
M.apply_damage(2, BURN, BODY_ZONE_PRECISE_R_HAND, M.run_armor_check(BODY_ZONE_PRECISE_R_HAND, ENERGY))
|
||||
M.apply_damage(2, BURN, BODY_ZONE_PRECISE_L_HAND, M.run_armor_check(BODY_ZONE_PRECISE_L_HAND, ENERGY))
|
||||
C_imp_in.SetStunned(0) //This only triggers if they are grabbed, to have them break out of the grab, without the large stun time.
|
||||
C_imp_in.SetWeakened(0)
|
||||
playsound(C_imp_in.loc, "sound/weapons/egloves.ogg", 75, 1)
|
||||
|
||||
@@ -50,11 +50,11 @@
|
||||
if(!ishuman(target))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!prob(embed_prob - ARMOUR_VALUE_TO_PERCENTAGE(H.getarmor(null, BOMB))))
|
||||
to_chat(H, "<span class='warning'>Shrapnel bounces off your armor!</span>")
|
||||
var/mob/living/carbon/human/human = target
|
||||
if(!prob(embed_prob - ARMOUR_VALUE_TO_PERCENTAGE(human.getarmor(armor_type = BOMB))))
|
||||
to_chat(human, "<span class='warning'>Shrapnel bounces off your armor!</span>")
|
||||
return
|
||||
H.try_embed_object(new_possible_embed)
|
||||
human.try_embed_object(new_possible_embed)
|
||||
|
||||
/obj/item/projectile/bullet/shrapnel/on_range()
|
||||
var/obj/item/we_missed = new embedded_type(get_turf(src)) // we missed, lets toss the shrapnel
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
var/mob/living/carbon/M = G.assailant
|
||||
user.visible_message("<span class='warning'>[user] spits acid at [M]'s face and slips out of their grab!</span>")
|
||||
M.Stun(2 SECONDS) //Drops the grab
|
||||
M.apply_damage(5, BURN, "head", M.run_armor_check("head", "melee"))
|
||||
M.apply_damage(5, BURN, BODY_ZONE_HEAD, M.run_armor_check(BODY_ZONE_HEAD, MELEE))
|
||||
user.SetStunned(0) //This only triggers if they are grabbed, to have them break out of the grab, without the large stun time. If you use biodegrade as an antistun without being grabbed, it will not work
|
||||
user.SetWeakened(0)
|
||||
playsound(user.loc, 'sound/weapons/sear.ogg', 50, TRUE)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/mob/living/carbon/M = G.assailant
|
||||
user.visible_message("<span class='warning'>[user] suddenly hits [M] in the face and slips out of their grab!</span>")
|
||||
M.Stun(2 SECONDS) //Drops the grab
|
||||
M.apply_damage(5, BRUTE, "head", M.run_armor_check("head", "melee"))
|
||||
M.apply_damage(5, BRUTE, BODY_ZONE_HEAD, M.run_armor_check(BODY_ZONE_HEAD, MELEE))
|
||||
playsound(user.loc, 'sound/weapons/punch1.ogg', 25, TRUE, -1)
|
||||
user.revive()
|
||||
user.updatehealth("revive sting")
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
var/atom/throw_target = get_edge_target_turf(L, get_dir(src, get_step_away(L, src)))
|
||||
L.throw_at(throw_target, 4, 4)
|
||||
var/limb_to_hit = L.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
|
||||
var/armor = L.run_armor_check(def_zone = limb_to_hit, attack_flag = MELEE, armor_penetration_percentage = 50)
|
||||
var/armor = L.run_armor_check(def_zone = limb_to_hit, armor_type = MELEE, armor_penetration_percentage = 50)
|
||||
L.apply_damage(40, BRUTE, limb_to_hit, armor)
|
||||
|
||||
// Below here is edited from Bubblegum
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
/// at least 75% rad armor is required to be immune to this event
|
||||
#define RAD_ARMOR_TO_IMMUNITY 150
|
||||
|
||||
/datum/event/mass_hallucination/setup()
|
||||
announceWhen = rand(0, 20)
|
||||
|
||||
/datum/event/mass_hallucination/start()
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.stat == DEAD)
|
||||
for(var/mob/living/carbon/human/human as anything in GLOB.human_list)
|
||||
if(human.stat == DEAD)
|
||||
continue
|
||||
var/turf/T = get_turf(H)
|
||||
if(!is_station_level(T?.z))
|
||||
var/turf/turf = get_turf(human)
|
||||
if(!is_station_level(turf?.z))
|
||||
continue
|
||||
var/armor = H.getarmor(type = RAD)
|
||||
if(HAS_TRAIT(H, TRAIT_RADIMMUNE) || armor >= 150) // Leave radiation-immune species/rad armored players completely unaffected
|
||||
if(HAS_TRAIT(human, TRAIT_RADIMMUNE) || human.getarmor(armor_type = RAD) >= RAD_ARMOR_TO_IMMUNITY) // Leave radiation-immune species/rad armored players completely unaffected
|
||||
continue
|
||||
H.AdjustHallucinate(rand(50 SECONDS, 100 SECONDS))
|
||||
human.AdjustHallucinate(rand(50 SECONDS, 100 SECONDS))
|
||||
|
||||
/datum/event/mass_hallucination/announce()
|
||||
GLOB.minor_announcement.Announce("The [station_name()] is passing through a minor radiation field. Be advised that acute exposure to space radiation can induce hallucinogenic episodes.")
|
||||
|
||||
#undef RAD_ARMOR_TO_IMMUNITY
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
D.visible_message("<span class='danger'>[A] suplexes [D]!</span>", \
|
||||
"<span class='userdanger'>[A] suplexes [D]!</span>")
|
||||
D.forceMove(A.loc)
|
||||
var/armor_block = D.run_armor_check(null, MELEE)
|
||||
var/armor_block = D.run_armor_check(armor_type = MELEE)
|
||||
D.apply_damage(30, BRUTE, null, armor_block)
|
||||
D.apply_effect(12 SECONDS, WEAKEN, armor_block)
|
||||
add_attack_logs(A, D, "Melee attacked with [src] (SUPLEX)")
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
D.SpinAnimation(10,1)
|
||||
spawn(3)
|
||||
armor_block = A.run_armor_check(null, MELEE)
|
||||
armor_block = A.run_armor_check(armor_type = MELEE)
|
||||
A.apply_effect(8 SECONDS, WEAKEN, armor_block)
|
||||
return
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did
|
||||
new /obj/effect/temp_visual/kinetic_blast(get_turf(L))
|
||||
var/backstab_dir = get_dir(user, L)
|
||||
var/def_check = L.getarmor(type = BOMB)
|
||||
var/def_check = L.getarmor(armor_type = BOMB)
|
||||
if((user.dir & backstab_dir) && (L.dir & backstab_dir))
|
||||
if(!QDELETED(C))
|
||||
C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item
|
||||
|
||||
@@ -376,7 +376,7 @@ RESTRICT_TYPE(/mob/living/basic)
|
||||
visible_message("<span class='warning'>[src] looks unharmed.</span>")
|
||||
return FALSE
|
||||
else
|
||||
apply_damage(damage, damagetype, null, getarmor(null, armorcheck))
|
||||
apply_damage(damage, damagetype, null, getarmor(armor_type = armorcheck))
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@
|
||||
var/atom/throw_target = get_edge_target_turf(L, get_dir(src, get_step_away(L, src)))
|
||||
L.throw_at(throw_target, 4, 4)
|
||||
var/limb_to_hit = L.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
|
||||
var/armor = L.run_armor_check(def_zone = limb_to_hit, attack_flag = MELEE, armor_penetration_percentage = 50)
|
||||
var/armor = L.run_armor_check(def_zone = limb_to_hit, armor_type = MELEE, armor_penetration_percentage = 50)
|
||||
L.apply_damage(40, BRUTE, limb_to_hit, armor)
|
||||
|
||||
// Tendril-spawned Legion remains, the charred skeletons of those whose bodies sank into laval or fell into chasms.
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
H.apply_effect(10 SECONDS, KNOCKDOWN, H.run_armor_check(null, MELEE))
|
||||
H.apply_effect(10 SECONDS, KNOCKDOWN, H.run_armor_check(armor_type = MELEE))
|
||||
H.apply_damage(40, STAMINA)
|
||||
else
|
||||
L.Weaken(5 SECONDS)
|
||||
|
||||
@@ -160,39 +160,37 @@ emp_act
|
||||
|
||||
affecting.droplimb(FALSE, damtype)
|
||||
|
||||
/mob/living/carbon/human/getarmor(def_zone, type)
|
||||
var/armorval = 0
|
||||
var/organnum = 0
|
||||
|
||||
/// This proc calculates armor value for humans.
|
||||
/// If null is passed for def_zone, then this will return something appropriate for all zones (e.g. area effect damage)
|
||||
/mob/living/carbon/human/getarmor(def_zone, armor_type)
|
||||
// If a specific bodypart is targetted, check if it exists, how that bodypart is protected and return the value
|
||||
if(def_zone)
|
||||
if(is_external_organ(def_zone))
|
||||
return getarmor_organ(def_zone, type)
|
||||
var/obj/item/organ/external/affecting = get_organ(def_zone)
|
||||
return __getarmor_bodypart(def_zone, armor_type)
|
||||
var/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.
|
||||
return __getarmor_bodypart(affecting, armor_type)
|
||||
|
||||
//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
|
||||
for(var/obj/item/organ/external/organ in bodyparts)
|
||||
armorval += getarmor_organ(organ, type)
|
||||
organnum++
|
||||
// If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
|
||||
var/armor
|
||||
var/mob_bodyparts
|
||||
for(var/obj/item/organ/external/part as anything in bodyparts)
|
||||
armor += __getarmor_bodypart(part, armor_type)
|
||||
mob_bodyparts++
|
||||
|
||||
return (armorval/max(organnum, 1))
|
||||
return armor / mob_bodyparts
|
||||
|
||||
/// This is an internal proc, returns the armor value for a particular bodypart [/obj/item/organ/external].
|
||||
/// Use `getarmor()` instead
|
||||
/mob/living/carbon/human/proc/__getarmor_bodypart(obj/item/organ/external/def_zone, armor_type)
|
||||
// Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
|
||||
var/list/obj/item/worn_items = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, l_ear, r_ear, wear_id, neck)
|
||||
|
||||
//this proc returns the armour value for a particular external organ.
|
||||
/mob/living/carbon/human/proc/getarmor_organ(obj/item/organ/external/def_zone, type)
|
||||
if(!type || !def_zone) return 0
|
||||
var/protection = 0
|
||||
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, l_ear, r_ear, wear_id, neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
|
||||
for(var/bp in body_parts)
|
||||
if(!bp) continue
|
||||
if(bp && isclothing(bp))
|
||||
var/obj/item/clothing/C = bp
|
||||
if(C.body_parts_covered & def_zone.body_part)
|
||||
protection += C.armor.getRating(type)
|
||||
protection += physiology.armor.getRating(type)
|
||||
return protection
|
||||
for(var/obj/item/thing in worn_items)
|
||||
if(thing?.body_parts_covered & def_zone.body_part)
|
||||
. += thing.armor.getRating(armor_type)
|
||||
|
||||
. += physiology.armor.getRating(armor_type)
|
||||
|
||||
//this proc returns the Siemens coefficient of electrical resistivity for a particular external organ.
|
||||
/mob/living/carbon/human/proc/get_siemens_coefficient_organ(obj/item/organ/external/def_zone)
|
||||
@@ -208,17 +206,6 @@ emp_act
|
||||
|
||||
return siemens_coefficient
|
||||
|
||||
/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 && isclothing(bp))
|
||||
var/obj/item/clothing/C = bp
|
||||
if(C.body_parts_covered & HEAD)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/proc/check_reflect(def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance var of the object
|
||||
if(wear_suit && isitem(wear_suit))
|
||||
var/obj/item/I = wear_suit
|
||||
@@ -485,7 +472,14 @@ emp_act
|
||||
if(!I.force)
|
||||
return //item force is zero
|
||||
|
||||
var/armor = run_armor_check(affecting, MELEE, "<span class='warning'>Your armour has protected your [hit_area].</span>", "<span class='warning'>Your armour has softened hit to your [hit_area].</span>", armor_penetration_flat = I.armor_penetration_flat, armor_penetration_percentage = I.armor_penetration_percentage)
|
||||
var/armor = run_armor_check(
|
||||
def_zone = affecting,
|
||||
armor_type = MELEE,
|
||||
absorb_text = "Your armor has protected your [hit_area].",
|
||||
soften_text = "Your armor has softened hit to your [hit_area].",
|
||||
armor_penetration_flat = I.armor_penetration_flat,
|
||||
armor_penetration_percentage = I.armor_penetration_percentage,
|
||||
)
|
||||
if(armor == INFINITY)
|
||||
return
|
||||
|
||||
@@ -667,8 +661,7 @@ emp_act
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
var/obj/item/organ/external/affecting = get_organ(ran_zone(L.zone_selected))
|
||||
var/armor_block = run_armor_check(affecting, MELEE)
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, MELEE))
|
||||
updatehealth("larva attack")
|
||||
|
||||
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
|
||||
var/brute_loss = 0
|
||||
var/burn_loss = 0
|
||||
var/bomb_armor = ARMOUR_VALUE_TO_PERCENTAGE(getarmor(null, BOMB))
|
||||
var/bomb_armor = ARMOUR_VALUE_TO_PERCENTAGE(getarmor(armor_type = BOMB))
|
||||
var/list/valid_limbs = list("l_arm", "l_leg", "r_arm", "r_leg")
|
||||
var/limbs_amount = 1
|
||||
var/limb_loss_chance = 50
|
||||
|
||||
@@ -1123,7 +1123,7 @@
|
||||
|
||||
amount -= RAD_BACKGROUND_RADIATION // This will always be at least 1 because of how skin protection is calculated
|
||||
|
||||
var/blocked = getarmor(null, RAD)
|
||||
var/blocked = getarmor(armor_type = RAD)
|
||||
if(blocked == INFINITY) // Full protection, go no further.
|
||||
return
|
||||
if(amount > RAD_BURN_THRESHOLD)
|
||||
|
||||
@@ -1,38 +1,43 @@
|
||||
|
||||
/*
|
||||
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
|
||||
|
||||
Returns
|
||||
0 - no block
|
||||
1 - halfblock
|
||||
2 - fullblock
|
||||
/**
|
||||
* Returns final, affected by `armor_penetration_flat` and `armor_penetration_percentage`, armor value of specific armor type
|
||||
*
|
||||
* * def_zone - What part is getting hit, if not set will check armor of entire body
|
||||
* * armor_type - What type of armor is used. MELEE, BULLET, MAGIC etc.
|
||||
* * absorb_text - Text displayed when your armor makes you immune (armor is INFINITY)
|
||||
* * soften_text - Text displayed when 0 < armor < INFINITY. So armor protected us from some damage
|
||||
* * penetrated_text - Text displayed when armor penetration decreases non 0 armor to 0. So it's completely penetrated
|
||||
* * armor_penetration_percentage - % of armor value that is penetrated. Does nothing if armor <= 0. Happens before flat AP
|
||||
* * armor_penetration_flat - armor value that is penetrated. Does nothing if armor <= 0. Occurs after percentage AP
|
||||
*/
|
||||
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = MELEE, absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armor_penetration_flat = 0, penetrated_text = "Your armor was penetrated!", armor_penetration_percentage = 0)
|
||||
var/armor = getarmor(def_zone, attack_flag)
|
||||
/mob/living/proc/run_armor_check(
|
||||
def_zone,
|
||||
armor_type = MELEE,
|
||||
absorb_text = "Your armor absorbs the blow!",
|
||||
soften_text = "Your armor softens the blow!",
|
||||
penetrated_text = "Your armor was penetrated!",
|
||||
armor_penetration_flat,
|
||||
armor_penetration_percentage,
|
||||
)
|
||||
. = getarmor(def_zone, armor_type)
|
||||
|
||||
if(armor == INFINITY)
|
||||
if(. == INFINITY)
|
||||
to_chat(src, "<span class='userdanger'>[absorb_text]</span>")
|
||||
return armor
|
||||
if(armor <= 0)
|
||||
return armor
|
||||
return
|
||||
if(. <= 0)
|
||||
return
|
||||
if(!armor_penetration_flat && !armor_penetration_percentage)
|
||||
to_chat(src, "<span class='userdanger'>[soften_text]</span>")
|
||||
return armor
|
||||
return
|
||||
|
||||
var/armor_original = armor
|
||||
armor = max(0, (armor * ((100 - armor_penetration_percentage) / 100)) - armor_penetration_flat)
|
||||
if(armor_original <= armor)
|
||||
. = max(0, . * (100 - armor_penetration_percentage) / 100 - armor_penetration_flat)
|
||||
if(.)
|
||||
to_chat(src, "<span class='userdanger'>[soften_text]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='userdanger'>[penetrated_text]</span>")
|
||||
|
||||
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(def_zone, type)
|
||||
/// Returns armor value of our mob.
|
||||
/// As u can see, mobs have no armor by default so we override this proc on mob subtypes if we add them any armor
|
||||
/mob/living/proc/getarmor(def_zone, armor_type)
|
||||
return 0
|
||||
|
||||
/mob/living/proc/is_mouth_covered(head_only = FALSE, mask_only = FALSE)
|
||||
@@ -124,7 +129,7 @@
|
||||
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
if(isitem(AM))
|
||||
var/obj/item/thrown_item = AM
|
||||
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
|
||||
var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
|
||||
var/nosell_hit = SEND_SIGNAL(thrown_item, COMSIG_MOVABLE_IMPACT_ZONE, src, zone, throwingdatum) // TODO: find a better way to handle hitpush and skipcatch for humans
|
||||
if(nosell_hit)
|
||||
skipcatch = TRUE
|
||||
@@ -140,7 +145,14 @@
|
||||
visible_message("<span class='danger'>[src] is hit by [thrown_item]!</span>", "<span class='userdanger'>You're hit by [thrown_item]!</span>")
|
||||
if(!thrown_item.throwforce)
|
||||
return
|
||||
var/armor = run_armor_check(zone, MELEE, "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].", thrown_item.armor_penetration_flat, armor_penetration_percentage = thrown_item.armor_penetration_percentage)
|
||||
var/armor = run_armor_check(
|
||||
def_zone = zone,
|
||||
armor_type = MELEE,
|
||||
absorb_text = "Your armor has protected your [parse_zone(zone)].",
|
||||
soften_text = "Your armor has softened hit to your [parse_zone(zone)].",
|
||||
armor_penetration_flat = thrown_item.armor_penetration_flat,
|
||||
armor_penetration_percentage = thrown_item.armor_penetration_percentage,
|
||||
)
|
||||
apply_damage(thrown_item.throwforce, thrown_item.damtype, zone, armor, thrown_item.sharp, thrown_item)
|
||||
if(QDELETED(src)) //Damage can delete the mob.
|
||||
return
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
visible_message("<span class='warning'>[src] looks unharmed.</span>")
|
||||
return FALSE
|
||||
else
|
||||
apply_damage(damage, damagetype, null, getarmor(null, armorcheck))
|
||||
apply_damage(damage, damagetype, null, getarmor(armor_type = armorcheck))
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj)
|
||||
@@ -94,7 +94,7 @@
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
var/bomb_armor = getarmor(null, BOMB)
|
||||
var/bomb_armor = getarmor(armor_type = BOMB)
|
||||
switch(severity)
|
||||
if(1)
|
||||
if(prob(bomb_armor))
|
||||
|
||||
@@ -738,16 +738,13 @@
|
||||
"<span class='userdanger'>[src] drives over you!</span>")
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
|
||||
var/damage = rand(5,15)
|
||||
H.apply_damage(2*damage, BRUTE, "head", run_armor_check("head", MELEE))
|
||||
H.apply_damage(2*damage, BRUTE, "chest", run_armor_check("chest", MELEE))
|
||||
H.apply_damage(0.5*damage, BRUTE, "l_leg", run_armor_check("l_leg", MELEE))
|
||||
H.apply_damage(0.5*damage, BRUTE, "r_leg", run_armor_check("r_leg", MELEE))
|
||||
H.apply_damage(0.5*damage, BRUTE, "l_arm", run_armor_check("l_arm", MELEE))
|
||||
H.apply_damage(0.5*damage, BRUTE, "r_arm", run_armor_check("r_arm", MELEE))
|
||||
|
||||
|
||||
|
||||
var/damage = rand(5, 15)
|
||||
H.apply_damage(2 * damage, BRUTE, BODY_ZONE_HEAD, run_armor_check(BODY_ZONE_HEAD, MELEE))
|
||||
H.apply_damage(2 * damage, BRUTE, BODY_ZONE_CHEST, run_armor_check(BODY_ZONE_CHEST, MELEE))
|
||||
H.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_L_LEG, run_armor_check(BODY_ZONE_L_LEG, MELEE))
|
||||
H.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_R_LEG, run_armor_check(BODY_ZONE_R_LEG, MELEE))
|
||||
H.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_L_ARM, run_armor_check(BODY_ZONE_L_ARM, MELEE))
|
||||
H.apply_damage(0.5 * damage, BRUTE, BODY_ZONE_R_ARM, run_armor_check(BODY_ZONE_R_ARM, MELEE))
|
||||
|
||||
if(NO_BLOOD in H.dna.species.species_traits)//Does the run over mob have blood?
|
||||
return//If it doesn't it shouldn't bleed (Though a check should be made eventually for things with liquid in them, like slime people.)
|
||||
|
||||
@@ -166,22 +166,22 @@
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type)
|
||||
/mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, armor_type)
|
||||
var/armorval = 0
|
||||
|
||||
if(def_zone)
|
||||
if(def_zone == "head")
|
||||
if(inventory_head)
|
||||
armorval = inventory_head.armor.getRating(type)
|
||||
armorval = inventory_head.armor.getRating(armor_type)
|
||||
else
|
||||
if(inventory_back)
|
||||
armorval = inventory_back.armor.getRating(type)
|
||||
armorval = inventory_back.armor.getRating(armor_type)
|
||||
return armorval
|
||||
else
|
||||
if(inventory_head)
|
||||
armorval += inventory_head.armor.getRating(type)
|
||||
armorval += inventory_head.armor.getRating(armor_type)
|
||||
if(inventory_back)
|
||||
armorval += inventory_back.armor.getRating(type)
|
||||
armorval += inventory_back.armor.getRating(armor_type)
|
||||
return armorval * 0.5
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/item_interaction(mob/living/user, obj/item/O, list/modifiers)
|
||||
|
||||
@@ -338,7 +338,7 @@ Difficulty: Hard
|
||||
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] tramples you into the ground!</span>")
|
||||
forceMove(get_turf(L))
|
||||
var/limb_to_hit = L.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
|
||||
L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, MELEE, null, null, armor_penetration_flat, armor_penetration_percentage))
|
||||
L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, MELEE, armor_penetration_flat = armor_penetration_flat, armor_penetration_percentage = armor_penetration_percentage))
|
||||
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, TRUE)
|
||||
shake_camera(L, 4, 3)
|
||||
shake_camera(src, 2, 3)
|
||||
|
||||
@@ -321,7 +321,7 @@ Difficulty: Hard
|
||||
to_chat(L, "<span class='userdanger'>[src] rends you!</span>")
|
||||
playsound(T, attack_sound, 100, TRUE, -1)
|
||||
var/limb_to_hit = L.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
|
||||
L.apply_damage(second_life ? 20 : 10, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, MELEE, null, null, armor_penetration_flat, armor_penetration_percentage))
|
||||
L.apply_damage(second_life ? 20 : 10, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, MELEE, armor_penetration_flat = armor_penetration_flat, armor_penetration_percentage = armor_penetration_percentage))
|
||||
SLEEP_CHECK_DEATH(3)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness)
|
||||
|
||||
@@ -357,8 +357,8 @@ Difficulty: Very Hard
|
||||
loot += pick_n_take(choices)
|
||||
|
||||
/obj/item/projectile/colossus
|
||||
name ="death bolt"
|
||||
icon_state= "chronobolt"
|
||||
name = "death bolt"
|
||||
icon_state = "chronobolt"
|
||||
damage = 25
|
||||
armor_penetration_percentage = 100
|
||||
speed = 2
|
||||
|
||||
@@ -762,7 +762,7 @@ Difficulty: Hard
|
||||
playsound(target,'sound/weapons/sear.ogg', 50, TRUE, -4)
|
||||
to_chat(target, "<span class='userdanger'>You're struck by \a [name]!</span>")
|
||||
var/limb_to_hit = target.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
|
||||
var/armor = target.run_armor_check(limb_to_hit, MELEE, "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!")
|
||||
var/armor = target.run_armor_check(limb_to_hit, MELEE, "Your armor absorbs [src]!", "Your armor blocks part of [src]!", "Your armor was penetrated by [src]!", 50)
|
||||
target.apply_damage(damage, BURN, limb_to_hit, armor)
|
||||
if(ishostile(target))
|
||||
var/mob/living/simple_animal/hostile/H = target //mobs find and damage you...
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
else
|
||||
// Target prioritization by spider type. BRUTE spiders prioritize lower armor values, POISON spiders prioritize poisonable targets
|
||||
if(ai_target_method == TS_DAMAGE_BRUTE)
|
||||
var/theirarmor = C.getarmor(type = MELEE)
|
||||
var/theirarmor = C.getarmor(armor_type = MELEE)
|
||||
// Example values: Assistant: 2, Engineer w/ Hardsuit: 10, Sec Officer with armor: 19, HoS: 48, Deathsquad: 80
|
||||
if(theirarmor < 10)
|
||||
targets1 += C
|
||||
|
||||
@@ -403,7 +403,7 @@
|
||||
var/obj/item/clothing/hat = attacker.head
|
||||
if(istype(hat))
|
||||
damage += hat.force * 3
|
||||
affecting.apply_damage(damage*rand(90, 110)/100, BRUTE, "head", affected.run_armor_check(affecting, MELEE))
|
||||
affecting.apply_damage(damage * rand(90, 110) / 100, BRUTE, BODY_ZONE_HEAD, affected.run_armor_check(affecting, MELEE))
|
||||
playsound(assailant.loc, "swing_hit", 25, TRUE, -1)
|
||||
add_attack_logs(assailant, affecting, "Headbutted")
|
||||
return
|
||||
|
||||
@@ -459,7 +459,7 @@
|
||||
M.gets_drilled(K.firer)
|
||||
if(modifier)
|
||||
for(var/mob/living/L in range(1, target_turf) - K.firer - target)
|
||||
var/armor = L.run_armor_check(K.def_zone, K.flag, null, null, K.armor_penetration_flat, K.armor_penetration_percentage)
|
||||
var/armor = L.run_armor_check(K.def_zone, K.flag, armor_penetration_flat = K.armor_penetration_flat, armor_penetration_percentage = K.armor_penetration_percentage)
|
||||
L.apply_damage(K.damage * modifier, K.damage_type, K.def_zone, armor)
|
||||
to_chat(L, "<span class='userdanger'>You're struck by a [K.name]!</span>")
|
||||
|
||||
@@ -563,7 +563,7 @@
|
||||
var/kill_modifier = 1
|
||||
if(K.pressure_decrease_active)
|
||||
kill_modifier *= K.pressure_decrease
|
||||
var/armor = L.run_armor_check(K.def_zone, K.flag, null, null, K.armor_penetration_flat, K.armor_penetration_percentage)
|
||||
var/armor = L.run_armor_check(K.def_zone, K.flag, armor_penetration_flat = K.armor_penetration_flat, armor_penetration_percentage = K.armor_penetration_percentage)
|
||||
L.apply_damage(bounties_reaped[L.type]*kill_modifier, K.damage_type, K.def_zone, armor)
|
||||
|
||||
/obj/item/borg/upgrade/modkit/bounty/proc/get_kill(mob/living/L)
|
||||
|
||||
@@ -302,6 +302,7 @@
|
||||
volume = 120
|
||||
armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 75, ACID = 50) //Weak melee protection, because you can wear it on your head
|
||||
slot_flags = ITEM_SLOT_HEAD
|
||||
body_parts_covered = HEAD
|
||||
prefered_slot_flags = ITEM_SLOT_IN_BACKPACK
|
||||
resistance_flags = NONE
|
||||
blocks_emissive = EMISSIVE_BLOCK_GENERIC
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
return FALSE
|
||||
target.visible_message("<span class='danger'>[user] pushes [target]'s head into [src]!</span>", \
|
||||
"<span class='userdanger'>[user] pushes your head into [src]! The heat is agonizing!</span>")
|
||||
var/armor = target.run_armor_check(def_zone = BODY_ZONE_HEAD, attack_flag = MELEE, armor_penetration_percentage = 50)
|
||||
var/armor = target.run_armor_check(def_zone = BODY_ZONE_HEAD, armor_type = MELEE, armor_penetration_percentage = 50)
|
||||
target.apply_damage(40, BURN, BODY_ZONE_HEAD, armor)
|
||||
target.adjust_fire_stacks(5)
|
||||
target.IgniteMob()
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
return FALSE
|
||||
target.visible_message("<span class='danger'>[user] hammers [target]'s head with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] hammers your head with [src]! Did somebody get the license plate on that car?</span>")
|
||||
var/armor = target.run_armor_check(def_zone = BODY_ZONE_HEAD, attack_flag = MELEE, armor_penetration_percentage = 50)
|
||||
var/armor = target.run_armor_check(def_zone = BODY_ZONE_HEAD, armor_type = MELEE, armor_penetration_percentage = 50)
|
||||
target.apply_damage(40, BRUTE, BODY_ZONE_HEAD, armor)
|
||||
target.Weaken(4 SECONDS)
|
||||
target.emote("scream")
|
||||
|
||||
Reference in New Issue
Block a user