diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 3df56854d04..b48b65f0fcf 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -376,9 +376,14 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s // 510 doesn't have this flag, so this shim will turn it into a no-op if it doesn't exist. #ifndef SEE_BLACKNESS #define SEE_BLACKNESS 0 -#endif +#endif #define DEFAULT_SIGHT (SEE_SELF|SEE_BLACKNESS) #define isStationLevel(Z) ((Z) in config.station_levels) #define isNotStationLevel(Z) !isStationLevel(Z) + +//Affects the chance that armour will block an attack. Should be between 0 and 1. +//If set to 0, then armor will always prevent the same amount of damage, always, with no randomness whatsoever. +//Of course, this will affect code that checks for blocked < 100, as blocked will be less likely to actually be 100. +#define ARMOR_BLOCK_CHANCE_MULT 1.0 diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 45d81202be6..5eb3f39a199 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -196,3 +196,6 @@ #define TASTE_NORMAL 1 //anything below 15% #define TASTE_DULL 0.5 //anything below 30% #define TASTE_NUMB 0.1 //anything below 150% + +//helper for inverting armor blocked values into a multiplier +#define BLOCKED_MULT(blocked) max(1 - (blocked/100), 0) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 5e6ed22b924..1395ef58188 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -458,7 +458,7 @@ else randmuti(src.connected.occupant) - src.connected.occupant.apply_effect(((src.radiation_intensity*3)+src.radiation_duration*3), IRRADIATE, check_protection = 0) + src.connected.occupant.apply_effect(((src.radiation_intensity*3)+src.radiation_duration*3), IRRADIATE, blocked = 0) src.connected.locked = lock_state return 1 // return 1 forces an update to all Nano uis attached to src @@ -552,7 +552,7 @@ block = miniscrambletarget(num2text(selected_ui_target), src.radiation_intensity, src.radiation_duration) src.connected.occupant.dna.SetUISubBlock(src.selected_ui_block,src.selected_ui_subblock,block) src.connected.occupant.UpdateAppearance() - src.connected.occupant.apply_effect((src.radiation_intensity+src.radiation_duration), IRRADIATE, check_protection = 0) + src.connected.occupant.apply_effect((src.radiation_intensity+src.radiation_duration), IRRADIATE, blocked = 0) else if (prob(20+src.radiation_intensity)) randmutb(src.connected.occupant) @@ -560,7 +560,7 @@ else randmuti(src.connected.occupant) src.connected.occupant.UpdateAppearance() - src.connected.occupant.apply_effect(((src.radiation_intensity*2)+src.radiation_duration), IRRADIATE, check_protection = 0) + src.connected.occupant.apply_effect(((src.radiation_intensity*2)+src.radiation_duration), IRRADIATE, blocked = 0) src.connected.locked = lock_state return 1 // return 1 forces an update to all Nano uis attached to src @@ -617,10 +617,10 @@ //testing("Irradiated SE block [real_SE_block]:[src.selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!") connected.occupant.dna.SetSESubBlock(real_SE_block,selected_se_subblock,block) - src.connected.occupant.apply_effect((src.radiation_intensity+src.radiation_duration), IRRADIATE, check_protection = 0) + src.connected.occupant.apply_effect((src.radiation_intensity+src.radiation_duration), IRRADIATE, blocked = 0) domutcheck(src.connected.occupant,src.connected) else - src.connected.occupant.apply_effect(((src.radiation_intensity*2)+src.radiation_duration), IRRADIATE, check_protection = 0) + src.connected.occupant.apply_effect(((src.radiation_intensity*2)+src.radiation_duration), IRRADIATE, blocked = 0) if (prob(80-src.radiation_duration)) //testing("Random bad mut!") randmutb(src.connected.occupant) @@ -742,7 +742,7 @@ src.connected.occupant.dna.SE = buf.dna.SE src.connected.occupant.dna.UpdateSE() domutcheck(src.connected.occupant,src.connected) - src.connected.occupant.apply_effect(rand(20,50), IRRADIATE, check_protection = 0) + src.connected.occupant.apply_effect(rand(20,50), IRRADIATE, blocked = 0) return 1 if (bufferOption == "createInjector") diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 80ca2e7fc68..857363e8c39 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -225,9 +225,9 @@ var/hadevent = 0 if(isNotStationLevel(T.z)) continue if(istype(H,/mob/living/carbon/human)) - H.apply_effect((rand(15,75)),IRRADIATE,0) + H.apply_effect((rand(15,75)),IRRADIATE, blocked = H.getarmor(null, "rad")) if (prob(5)) - H.apply_effect((rand(90,150)),IRRADIATE,0) + H.apply_effect((rand(90,150)),IRRADIATE, blocked = H.getarmor(null, "rad")) if (prob(25)) if (prob(75)) randmutb(H) diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index ef55457fe6e..3ccb6e3bcca 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -256,7 +256,9 @@ meteordrop = /obj/item/weapon/ore/uranium /obj/effect/meteor/irradiated/meteor_effect() - new /obj/effect/decal/cleanable/greenglow(get_turf(src)) //todo: make this irradiate the place it lands + new /obj/effect/decal/cleanable/greenglow(get_turf(src)) + for(var/mob/living/L in view(5, src)) + L.apply_effect(40, IRRADIATE, blocked = L.getarmor(null, "rad")) /obj/effect/meteor/golden name = "golden meteor" diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 50181e10ad9..42c8d17e258 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -377,7 +377,7 @@ /obj/machinery/door/airlock/uranium/proc/radiate() for(var/mob/living/L in range (3,src)) - L.apply_effect(15,IRRADIATE,0) + L.apply_effect(15,IRRADIATE, blocked = L.getarmor(null, "rad")) return diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 9f46306cce5..bd56729b5ef 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -900,9 +900,7 @@ if(. != PROCESS_KILL) for(var/mob/living/carbon/M in view(chassis)) if(istype(M,/mob/living/carbon/human)) - M.apply_effect((rad_per_cycle*3),IRRADIATE,0) - else - M.apply_effect(rad_per_cycle, IRRADIATE) + M.apply_effect((rad_per_cycle*3),IRRADIATE, blocked = M.getarmor(null, "rad")) //This is pretty much just for the death-ripley so that it is harmless diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 7bef4ecce71..bcd2eea3849 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -942,11 +942,11 @@ var/global/list/obj/item/device/pda/PDAs = list() message += "Large clouds of noxious smoke billow forth from your [P]!" if(i>=65 && i<=75) //Weaken if(M && isliving(M)) - M.apply_effects(0,1) + M.apply_effects(weaken = 1) message += "Your [P] flashes with a blinding white light! You feel weaker." if(i>=75 && i<=85) //Stun and stutter if(M && isliving(M)) - M.apply_effects(1,0,0,0,1) + M.apply_effects(stun = 1, stutter = 1) message += "Your [P] flashes with a blinding white light! You feel weaker." if(i>=85) //Sparks spark(P.loc, 2) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 163a34a2a0a..50f9746f8dc 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -12,22 +12,24 @@ /obj/item/borg/stun/apply_hit_effect(mob/living/M, mob/living/silicon/robot/user, var/hit_zone) if(!istype(user)) - return + return 0 user.visible_message("\The [user] has prodded \the [M] with \a [src]!") if(!user.cell || !user.cell.checked_use(1250)) //Slightly more than a baton. - return + return 0 playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) - + 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 0 + /obj/item/borg/overdrive name = "overdrive" icon = 'icons/obj/decals.dmi' diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index c023a3b0cb5..dd91c2210a7 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -66,7 +66,7 @@ /obj/item/weapon/dnainjector/proc/inject(mob/M as mob, mob/user as mob) if(istype(M,/mob/living)) var/mob/living/L = M - L.apply_effect(rand(5,20), IRRADIATE, check_protection = 0) + L.apply_effect(rand(5,20), IRRADIATE, blocked = 0) if (!(NOCLONE in M.mutations)) // prevents drained people from having their DNA changed if (buf.types & DNA2_BUF_UI) diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm index 3abb839e637..9c4e053829e 100644 --- a/code/game/objects/items/weapons/material/material_weapons.dm +++ b/code/game/objects/items/weapons/material/material_weapons.dm @@ -65,7 +65,7 @@ return ..() /obj/item/weapon/material/apply_hit_effect() - ..() + . = ..() if(!unbreakable) if(material.is_brittle()) health = 0 @@ -92,7 +92,7 @@ Commenting this out pending rebalancing of radiation based on small objects. if(!material.radioactivity) return for(var/mob/living/L in range(1,src)) - L.apply_effect(round(material.radioactivity/30),IRRADIATE,0) + L.apply_effect(round(material.radioactivity/30),IRRADIATE, blocked = L.getarmor(null, "rad")) */ /* diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm index b2e58cdad5b..24ed0206bd4 100644 --- a/code/game/objects/items/weapons/traps.dm +++ b/code/game/objects/items/weapons/traps.dm @@ -73,7 +73,7 @@ //armour var/blocked = L.run_armor_check(target_zone, "melee") - if(blocked >= 2) + if(blocked >= 100) return var/success = L.apply_damage(30, BRUTE, target_zone, blocked, src) @@ -81,19 +81,18 @@ return 0 //trap the victim in place - if(!blocked) - set_dir(L.dir) - can_buckle = 1 - buckle_mob(L) - L << "The steel jaws of \the [src] bite into you, trapping you in place!" - deployed = 0 - can_buckle = initial(can_buckle) - playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)//Really loud snapping sound + set_dir(L.dir) + can_buckle = 1 + buckle_mob(L) + L << "The steel jaws of \the [src] bite into you, trapping you in place!" + deployed = 0 + can_buckle = initial(can_buckle) + playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1)//Really loud snapping sound - if (istype(L, /mob/living/simple_animal/hostile/bear)) - var/mob/living/simple_animal/hostile/bear/bear = L - bear.anger += 15//Beartraps make bears really angry - bear.instant_aggro() + if (istype(L, /mob/living/simple_animal/hostile/bear)) + var/mob/living/simple_animal/hostile/bear/bear = L + bear.anger += 15//Beartraps make bears really angry + bear.instant_aggro() /obj/item/weapon/beartrap/Crossed(AM as mob|obj) if(deployed && isliving(AM)) diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm index 1637ac8b776..c3c77cd6050 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm @@ -73,19 +73,21 @@ padding_material = null update_icon() -/obj/item/weapon/stool/attack(mob/M as mob, mob/user as mob) - if (prob(5) && istype(M,/mob/living)) - user.visible_message("[user] breaks [src] over [M]'s back!") +/obj/item/weapon/stool/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone) + if (prob(5)) + user.visible_message("[user] breaks [src] over [target]'s back!") user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - user.do_attack_animation(M) - + user.do_attack_animation(target) + user.remove_from_mob(src) dismantle() qdel(src) - var/mob/living/T = M - T.Weaken(10) - T.apply_damage(20) + + var/blocked = target.run_armor_check(hit_zone, "melee") + target.Weaken(10 * BLOCKED_MULT(blocked)) + target.apply_damage(20, BRUTE, hit_zone, blocked, src) return + ..() /obj/item/weapon/stool/ex_act(severity) diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 5232a6a7b20..30d312f7d71 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -151,7 +151,7 @@ occupant.apply_effect(6, STUN, blocked) occupant.apply_effect(6, WEAKEN, blocked) occupant.apply_effect(6, STUTTER, blocked) - occupant.apply_damage(10, BRUTE, def_zone) + occupant.apply_damage(10, BRUTE, def_zone, blocked) playsound(src.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) if(istype(A, /mob/living)) var/mob/living/victim = A @@ -160,7 +160,7 @@ victim.apply_effect(6, STUN, blocked) victim.apply_effect(6, WEAKEN, blocked) victim.apply_effect(6, STUTTER, blocked) - victim.apply_damage(10, BRUTE, def_zone) + victim.apply_damage(10, BRUTE, def_zone, blocked) if(pulling) occupant.visible_message("[pulling] has thrusted \the [name] into \the [A], throwing \the [occupant] out of it!") diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 8482a982b8c..a84962f6df9 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -217,25 +217,7 @@ if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) var/obj/item/weapon/grab/G = W if(istype(G.affecting,/mob/living)) - var/mob/living/M = G.affecting - var/state = G.state - qdel(W) //gotta delete it here because if window breaks, it won't get deleted - switch (state) - if(1) - M.visible_message("[user] slams [M] against \the [src]!") - M.apply_damage(7) - hit(10) - if(2) - M.visible_message("[user] bashes [M] against \the [src]!") - if (prob(50)) - M.Weaken(1) - M.apply_damage(10) - hit(25) - if(3) - M.visible_message("[user] crushes [M] against \the [src]!") - M.Weaken(5) - M.apply_damage(20) - hit(50) + grab_smash_attack(G, BRUTE) return if(W.flags & NOBLUDGEON) return @@ -285,6 +267,32 @@ ..() return +/obj/structure/window/proc/grab_smash_attack(obj/item/weapon/grab/G, var/damtype = BRUTE) + var/mob/living/M = G.affecting + var/mob/living/user = G.assailant + + var/state = G.state + qdel(G) //gotta delete it here because if window breaks, it won't get deleted + + var/def_zone = ran_zone("head", 20) + var/blocked = M.run_armor_check(def_zone, "melee") + switch (state) + if(1) + M.visible_message("[user] slams [M] against \the [src]!") + M.apply_damage(7, damtype, def_zone, blocked, src) + hit(10) + if(2) + M.visible_message("[user] bashes [M] against \the [src]!") + if (prob(50)) + M.Weaken(1) + M.apply_damage(10, damtype, def_zone, blocked, src) + hit(25) + if(3) + M.visible_message("[user] crushes [M] against \the [src]!") + M.Weaken(5) + M.apply_damage(20, damtype, def_zone, blocked, src) + hit(50) + /obj/structure/window/proc/hit(var/damage, var/sound_effect = 1) if(reinf) damage *= 0.5 take_damage(damage) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 33754cc3909..69aa5cc6735 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -242,7 +242,7 @@ return for(var/mob/living/L in range(3,src)) - L.apply_effect(total_radiation, IRRADIATE,0) + L.apply_effect(total_radiation, IRRADIATE, blocked = L.getarmor(null, "rad")) return total_radiation /turf/simulated/wall/proc/burn(temperature) diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index a016d6200e2..95739d8769a 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -43,9 +43,9 @@ if(istype(C,/mob/living/carbon/human)) var/mob/living/carbon/human/H = C - H.apply_effect((rand(15,30)),IRRADIATE,0) + H.apply_effect((rand(15,30)),IRRADIATE,blocked = H.getarmor(null, "rad")) if(prob(4)) - H.apply_effect((rand(20,60)),IRRADIATE,0) + H.apply_effect((rand(20,60)),IRRADIATE,blocked = H.getarmor(null, "rad")) if (prob(75)) randmutb(H) // Applies bad mutation domutcheck(H,null,MUTCHK_FORCED) diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 041723a95a2..d53052a0694 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -159,25 +159,7 @@ if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) var/obj/item/weapon/grab/G = W if(istype(G.affecting,/mob/living)) - var/mob/living/M = G.affecting - var/state = G.state - qdel(W) //gotta delete it here because if window breaks, it won't get deleted - switch (state) - if(1) - M.visible_message("[user] slams [M] against \the [src]!") - M.apply_damage(7) - hit(10) - if(2) - M.visible_message("[user] bashes [M] against \the [src]!") - if (prob(50)) - M.Weaken(1) - M.apply_damage(10) - hit(25) - if(3) - M.visible_message("[user] crushes [M] against \the [src]!") - M.Weaken(5) - M.apply_damage(20) - hit(50) + grab_smash_attack(G, HALLOSS) return if(W.flags & NOBLUDGEON) return diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 20732bb630c..6a07e889fc4 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -346,7 +346,7 @@ flick("flash",M.flash) if(prob(50)) M.Stun(5) - M.apply_effect(25, IRRADIATE) + M.apply_effect(25, IRRADIATE, blocked = M.getarmor(null, "rad")) if(prob(3)) excavate_find(prob(5), finds[1]) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 2ca2c9f90eb..26a6dde41a2 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -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 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 8e0403271d3..a99e3c9db9b 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -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" diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index e682bbc53ff..60eeda91110 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -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()]\] Disarmed [src.name] ([src.ckey])") @@ -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("[M] has pushed [src]!") else visible_message("[M] attempted to push [src]!") diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index ae0b7fd41bc..9dd3581c2a7 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -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) \ No newline at end of file + ..(rads) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 8052767ad83..b3f287255f9 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -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("[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!") organ.dislocate(1) return 1 @@ -327,7 +324,7 @@ emp_act src.visible_message("[src] has been hit in the [hit_area] by [O].") 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) diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index 5630f97711b..713406eed7d 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -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("[target] gives way slightly.") 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("[target] [pick("slumps", "falls", "drops")] down to the ground!") else diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 84414c15f00..ae375a999fc 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -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 \ No newline at end of file + total_radiation = 0 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 105332f82e4..85b04873ffe 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -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 diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 61ca2bf6a20..5dae43d44b5 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -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("[absorb_text]") else show_message("Your armor absorbs the blow!") - 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("[soften_text]") else show_message("Your armor softens the blow!") - 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("[src] has been hit by [O].") 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 diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 83d203ec19c..4d89435379a 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -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() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index d2d100308c3..9cc866f2b44 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -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("[src] was shocked by [source]!", "You are shocked by [source]!", "You hear an electrical crack.") \ No newline at end of file + visible_message("[src] was shocked by [source]!", "You are shocked by [source]!", "You hear an electrical crack.") diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm index 95d32958383..f157ac115e1 100644 --- a/code/modules/mob/mob_grab_specials.dm +++ b/code/modules/mob/mob_grab_specials.dm @@ -52,7 +52,7 @@ attacker.visible_message("[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!") var/armor = target.run_armor_check(target, "melee") - if(armor < 2) + if(armor < 100) target << "You feel extreme pain!" 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("[target] [target.species.knockout_message]") diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 365b610dfe9..ae0c70e1fd7 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -405,7 +405,7 @@ //produces a tiny amount of radiation when in use if (prob(2*power_output)) for (var/mob/living/L in range(src, 5)) - L.apply_effect(1, IRRADIATE) //should amount to ~5 rads per minute at max safe power + L.apply_effect(1, IRRADIATE, blocked = L.getarmor(null, "rad")) //should amount to ~5 rads per minute at max safe power ..() /obj/machinery/power/port_gen/pacman/super/explode() @@ -414,7 +414,7 @@ for (var/mob/living/L in range(src, 10)) //should really fall with the square of the distance, but that makes the rads value drop too fast //I dunno, maybe physics works different when you live in 2D -- SM radiation also works like this, apparently - L.apply_effect(max(20, round(rads/get_dist(L,src))), IRRADIATE) + L.apply_effect(max(20, round(rads/get_dist(L,src))), IRRADIATE, blocked = L.getarmor(null, "rad")) explosion(src.loc, 3, 3, 5, 3) qdel(src) diff --git a/code/modules/power/singularity/act.dm b/code/modules/power/singularity/act.dm index dae21030860..7b31f15a2da 100644 --- a/code/modules/power/singularity/act.dm +++ b/code/modules/power/singularity/act.dm @@ -32,7 +32,7 @@ if(prob(current_size*5) && hand.w_class >= ((11-current_size)/2) && u_equip(hand)) step_towards(hand, src) src << "The [S] pulls \the [hand] from your grip!" - apply_effect(current_size * 3, IRRADIATE) + apply_effect(current_size * 3, IRRADIATE, blocked = getarmor(null, "rad")) if(shoes) if(shoes.item_flags & NOSLIP) return 0 ..() diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index b52b3800593..9f81006c24f 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -60,7 +60,7 @@ /obj/effect/accelerated_particle/proc/toxmob(var/mob/living/M) var/radiation = (energy*2) - M.apply_effect((radiation*3),IRRADIATE,0) + M.apply_effect((radiation*3),IRRADIATE,blocked = M.getarmor(null, "rad")) M.updatehealth() //M << "\red You feel odd." return diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 08a3eeaad62..4d8cab94bd8 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -432,7 +432,7 @@ for(var/mob/living/M in view(toxrange, src.loc)) if(M.status_flags & GODMODE) continue - M.apply_effect(rand(radiationmin,radiation), IRRADIATE) + M.apply_effect(rand(radiationmin,radiation), IRRADIATE, blocked = M.getarmor(null, "rad")) toxdamage = (toxdamage - (toxdamage*M.getarmor(null, "rad"))) M.apply_effect(toxdamage, TOX) return @@ -466,7 +466,7 @@ /obj/singularity/proc/smwave() for(var/mob/living/M in view(10, src.loc)) if(prob(67)) - M.apply_effect(rand(energy), IRRADIATE) + M.apply_effect(rand(energy), IRRADIATE, blocked = M.getarmor(null, "rad")) M << "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat." M << "Miraculously, it fails to kill you." else diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index e44365a5e7d..c14ce2a96cd 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -14,7 +14,7 @@ reagents.my_atom = src /obj/item/projectile/bullet/chemdart/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) - if(blocked < 2 && isliving(target)) + if(blocked < 100 && isliving(target)) var/mob/living/L = target if(L.can_inject(target_zone=def_zone)) reagents.trans_to_mob(L, reagent_amount, CHEM_BLOOD) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 30177e4d171..5bac8ad89af 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -75,7 +75,7 @@ //TODO: make it so this is called more reliably, instead of sometimes by bullet_act() and sometimes not /obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) - if(blocked >= 2) return 0//Full block + if(blocked >= 100) return 0//Full block if(!isliving(target)) return 0 if(isanimal(target)) return 0 var/mob/living/L = target @@ -84,7 +84,10 @@ var/obj/item/organ/external/organ = H.get_organ(def_zone) var/armor = H.getarmor_organ(organ, check_armour) agony = max(0, agony - armor) - L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, incinerate, blocked) // add in AGONY! + + L.apply_effects(stun, weaken, paralyze, 0, stutter, eyeblur, drowsy, agony, incinerate, blocked) // add in AGONY! + //radiation protection is handled separately from other armour types. + L.apply_effect(irradiate, IRRADIATE, L.getarmor(null, "rad")) return 1 //called when the projectile stops flying because it collided with something diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 7a12583a55f..5f0fad963d4 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -100,7 +100,7 @@ var/mob/living/carbon/human/H = M if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) if(prob(15)) - M.apply_effect((rand(30,80)),IRRADIATE) + H.apply_effect((rand(30,80)),IRRADIATE,blocked = H.getarmor(null, "rad")) M.Weaken(5) for (var/mob/V in viewers(src)) V.show_message("[M] writhes in pain as \his vacuoles boil.", 3, "You hear the crunching of leaves.", 2) @@ -185,17 +185,17 @@ check_armour = "energy" embed = 0 damage_type = HALLOSS - + /obj/item/projectile/magic/fireball name = "fireball" icon_state = "fireball" damage = 20 damage_type = BURN - + /obj/item/projectile/magic/fireball/on_impact(var/atom/A) explosion(A, 0, 0, 4) ..() - + /obj/item/projectile/magic/teleport //literaly bluespace crystal code, because i am lazy and it seems to work name = "bolt of teleportation" icon = 'icons/obj/projectiles.dmi' @@ -209,6 +209,6 @@ if(isliving(hit_atom)) blink_mob(hit_atom) return ..() - + /obj/item/projectile/magic/teleport/proc/blink_mob(mob/living/L) do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg') diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index ece0edb41b4..c87951f304c 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -303,14 +303,14 @@ taste_description = "the color blue, and regret" /datum/reagent/radium/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - M.apply_effect(10 * removed, IRRADIATE, 0) // Radium may increase your chances to cure a disease + M.apply_effect(10 * removed, IRRADIATE, blocked = 0) // Radium may increase your chances to cure a disease if(M.virus2.len) for(var/ID in M.virus2) var/datum/disease2/disease/V = M.virus2[ID] if(prob(5)) M.antibodies |= V.antigen if(prob(50)) - M.apply_effect(50, IRRADIATE, check_protection = 0) // curing it that way may kill you instead + M.apply_effect(50, IRRADIATE, blocked = 0) // curing it that way may kill you instead var/absorbed = 0 var/obj/item/organ/diona/nutrients/rad_organ = locate() in M.internal_organs if(rad_organ && !rad_organ.is_broken()) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index e674dbdd4aa..a27880b5547 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -1546,7 +1546,7 @@ /datum/reagent/ethanol/vodka/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() - M.apply_effect(max(M.total_radiation - 1 * removed, 0), IRRADIATE, check_protection = 0) + M.apply_effect(max(M.total_radiation - 1 * removed, 0), IRRADIATE, blocked = 0) /datum/reagent/ethanol/whiskey name = "Whiskey" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index 186f6fe173d..d01721543c5 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -179,7 +179,7 @@ affect_ingest(M, alien, removed) /datum/reagent/uranium/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - M.apply_effect(5 * removed, IRRADIATE, 0) + M.apply_effect(5 * removed, IRRADIATE, blocked = 0) /datum/reagent/uranium/touch_turf(var/turf/T) if(volume >= 3) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index b8a0f9a2704..decaec1ba9f 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -307,7 +307,7 @@ randmutg(M) domutcheck(M, null) M.UpdateAppearance() - M.apply_effect(10 * removed, IRRADIATE, 0) + M.apply_effect(10 * removed, IRRADIATE, blocked = 0) /datum/reagent/slimejelly name = "Slime Jelly" diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index 2094f646eb1..e78c44b558c 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -127,7 +127,7 @@ // You are going to knock someone out for longer if they are not wearing a helmet. var/weaken_duration = 0 - if(blocked < 2) + if(blocked < 100) weaken_duration = smash_duration + min(0, force - target.getarmor(hit_zone, "melee") + 10) var/mob/living/carbon/human/H = target @@ -148,6 +148,8 @@ var/obj/item/weapon/broken_bottle/B = smash(target.loc, target) user.put_in_active_hand(B) + return blocked + /obj/item/weapon/reagent_containers/food/drinks/bottle/bullet_act() smash(loc) diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm index 7ffeffa8eb3..82714e2939c 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm @@ -14,7 +14,7 @@ C.adjustBruteLoss(rand(5,25) * weakness) C.adjustFireLoss(rand(5,25) * weakness) C.adjustBrainLoss(rand(5,25) * weakness) - C.apply_effect(25 * weakness, IRRADIATE) + C.apply_effect(25 * weakness, IRRADIATE, blocked = C.getarmor(null, "rad")) C.nutrition -= min(50 * weakness, C.nutrition) C.make_dizzy(6 * weakness) C.weakened += 6 * weakness diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_radiate.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_radiate.dm index 4310ffb2e71..dc175d934ea 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_radiate.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_radiate.dm @@ -26,6 +26,6 @@ if(holder) var/turf/T = get_turf(holder) for (var/mob/living/M in range(src.effectrange,T)) - M.apply_effect(radiation_amount * 25,IRRADIATE,0) + M.apply_effect(radiation_amount * 25,IRRADIATE,blocked = M.getarmor(null, "rad")) M.updatehealth() return 1 diff --git a/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm b/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm index f0016a2525a..5f90c20864d 100644 --- a/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm +++ b/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm @@ -200,7 +200,7 @@ if(!rad_shield) //irradiate nearby mobs for(var/mob/living/M in view(7,src)) - M.apply_effect(radiation / 25, IRRADIATE, 0) + M.apply_effect(radiation / 25, IRRADIATE, blocked = M.getarmor(null, "rad")) else t_left_radspike = pick(10,15,25) diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index b1c9da7911d..1af5b2627fc 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -275,7 +275,7 @@ var/rads = (power / 10) * ( 1 / (radius**2) ) if (!(l in oview(rad_range, src)) && !(l in range(src, round(rad_range * 2/3)))) continue - l.apply_effect(rads, IRRADIATE) + l.apply_effect(rads, IRRADIATE, blocked = l.getarmor(null, "rad")) power -= (power/DECAY_FACTOR)**3 //energy losses due to radiation @@ -356,7 +356,7 @@ user.drop_from_inventory(W) Consume(W) - user.apply_effect(150, IRRADIATE) + user.apply_effect(150, IRRADIATE, blocked = user.getarmor(null, "rad")) /obj/machinery/power/supermatter/Bumped(atom/AM as mob|obj) @@ -397,7 +397,7 @@ else l.show_message("You hear an uneartly ringing and notice your skin is covered in fresh radiation burns.", 2) var/rads = 500 * sqrt( 1 / (get_dist(l, src) + 1) ) - l.apply_effect(rads, IRRADIATE) + l.apply_effect(rads, IRRADIATE, blocked = l.getarmor(null, "rad")) /obj/machinery/power/supermatter/proc/supermatter_pull() diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index bb5f8531e75..6e6f91200d9 100644 --- a/code/modules/tables/interactions.dm +++ b/code/modules/tables/interactions.dm @@ -82,10 +82,12 @@ if(occupied) user << "There's \a [occupied] in the way." return - if (G.state < 2) + if (G.state >= GRAB_AGGRESSIVE) if(user.a_intent == I_HURT) - if (prob(15)) M.Weaken(5) - M.apply_damage(8,def_zone = "head") + var/blocked = M.run_armor_check("head", "melee") + if (prob(30 * BLOCKED_MULT(blocked))) + M.Weaken(5) + M.apply_damage(8, BRUTE, "head", blocked) visible_message("[G.assailant] slams [G.affecting]'s face against \the [src]!") if(material) playsound(loc, material.tableslam_noise, 50, 1) @@ -97,9 +99,8 @@ if(prob(50)) M.visible_message("\The [S] slices [M]'s face messily!", "\The [S] slices your face messily!") - M.apply_damage(10, def_zone = "head") - if(prob(2)) - M.embed(S, def_zone = "head") + M.apply_damage(10, BRUTE, "head", blocked) + M.standard_weapon_hit_effects(S, G.assailant, 10, blocked, "head") else user << "You need a better grip to do that!" return diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index f4c8fc7544b..29be350563e 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -150,8 +150,9 @@ var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm") H.apply_effects(5, 5) - for(var/i = 0, i < rand(1,3), i++) - H.apply_damage(rand(1,5), BRUTE, pick(parts)) + for(var/i = 0, i < rand(1,5), i++) + var/def_zone = pick(parts) + H.apply_damage(rand(5,10), BRUTE, def_zone, H.run_armor_check(def_zone, "melee")) /obj/vehicle/train/cargo/trolley/RunOver(var/mob/living/carbon/human/H) ..() @@ -177,7 +178,7 @@ if(user != load) return 0 - if(user.restrained()) + if(user.restrained()) return 0 if(is_train_head()) diff --git a/code/modules/vehicles/train.dm b/code/modules/vehicles/train.dm index 6df631e0399..2fbdcfb444c 100644 --- a/code/modules/vehicles/train.dm +++ b/code/modules/vehicles/train.dm @@ -53,8 +53,9 @@ if(istype(A, /mob/living)) var/mob/living/M = A visible_message("[src] knocks over [M]!") + var/def_zone = ran_zone() M.apply_effects(5, 5) //knock people down if you hit them - M.apply_damages(22 / move_delay) // and do damage according to how fast the train is going + M.apply_damage(22 / move_delay, BRUTE, def_zone, M.run_armor_check(def_zone, "melee")) // and do damage according to how fast the train is going if(istype(load, /mob/living/carbon/human)) var/mob/living/D = load D << "You hit [M]!" diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index a0961310c11..ed510d4a449 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -98,7 +98,7 @@ maxm = 3 badness = 2 activate(var/mob/living/carbon/mob,var/multiplier) - mob.apply_effect(2*multiplier, IRRADIATE, check_protection = 0) + mob.apply_effect(2*multiplier, IRRADIATE, blocked = 0) /datum/disease2/effect/deaf name = "Dead Ear Syndrome" diff --git a/html/changelogs/alberky-PR-2954.yml b/html/changelogs/alberky-PR-2954.yml new file mode 100644 index 00000000000..fdc4b89683c --- /dev/null +++ b/html/changelogs/alberky-PR-2954.yml @@ -0,0 +1,6 @@ +author: Alberyk + +delete-after: True + +changes: + - tweak: "Ports baystation12 armor system: Armor now has a chance to either block an attack or absorb a fixed portion of damage, instead of randomly blocking either nothing, half, or full damage."