diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 0f091a56549..6a965571625 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -282,6 +282,77 @@ emp_act
bloody_body(src)
return 1
+//this proc handles being hit by a thrown atom
+/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5)
+ if(istype(AM,/obj/))
+ var/obj/O = AM
+ var/dtype = BRUTE
+ if(istype(O,/obj/item/weapon))
+ var/obj/item/weapon/W = O
+ dtype = W.damtype
+ var/throw_damage = O.throwforce*(speed/5)
+
+ var/zone
+ if (istype(O.thrower, /mob/living))
+ var/mob/living/L = O.thrower
+ zone = check_zone(L.zone_sel.selecting)
+ else
+ zone = ran_zone("chest",75) //Hits a random part of the body, geared towards the chest
+
+ //check if we hit
+ if (O.throw_source)
+ var/distance = get_dist(O.throw_source, loc)
+ zone = get_zone_with_miss_chance(zone, src, min(15*(distance-2), 0))
+ else
+ zone = get_zone_with_miss_chance(zone, src, 15)
+
+ if(!zone)
+ visible_message("\blue \The [O] misses [src] narrowly!")
+ return
+
+ O.throwing = 0 //it hit, so stop moving
+
+ if ((O.thrower != src) && check_shields(throw_damage, "[O]"))
+ return
+
+ var/datum/organ/external/affecting = get_organ(zone)
+ var/hit_area = affecting.display_name
+
+ src.visible_message("\red [src] has been hit in the [hit_area] by [O].")
+ var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here
+
+ if(armor < 2)
+ apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O)
+
+ if(ismob(O.thrower))
+ var/mob/M = O.thrower
+ var/client/assailant = M.client
+ if(assailant)
+ src.attack_log += text("\[[time_stamp()]\] Has been hit with a [O], thrown by [M.name] ([assailant.ckey])")
+ M.attack_log += text("\[[time_stamp()]\] Hit [src.name] ([src.ckey]) with a thrown [O]")
+ if(!istype(src,/mob/living/simple_animal/mouse))
+ msg_admin_attack("[src.name] ([src.ckey]) was hit by a [O], thrown by [M.name] ([assailant.ckey]) (JMP)")
+
+ // Begin BS12 momentum-transfer code.
+ if(O.throw_source && speed >= 15)
+ var/obj/item/weapon/W = O
+ var/momentum = speed/2
+ var/dir = get_dir(O.throw_source, src)
+
+ visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
+ src.throw_at(get_edge_target_turf(src,dir),1,momentum)
+
+ if(!W || !src) return
+
+ if(W.loc == src && W.sharp) //Projectile is embedded and suitable for pinning.
+ var/turf/T = near_wall(dir,2)
+
+ if(T)
+ src.loc = T
+ visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!")
+ src.anchored = 1
+ src.pinned += O
+
/mob/living/carbon/human/proc/bloody_hands(var/mob/living/source, var/amount = 2)
if (gloves)
gloves.add_blood(source)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 9779e7bb634..8b9bfccb879 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -75,36 +75,23 @@
dtype = W.damtype
var/throw_damage = O.throwforce*(speed/5)
- var/zone
- if (istype(O.thrower, /mob/living))
- var/mob/living/L = O.thrower
- zone = check_zone(L.zone_sel.selecting)
- else
- zone = ran_zone("chest",75) //Hits a random part of the body, geared towards the chest
-
+ var/miss_chance = 15
if (O.throw_source)
var/distance = get_dist(O.throw_source, loc)
- zone = get_zone_with_miss_chance(zone, src, min(15*(distance-2), 0))
- else
- zone = get_zone_with_miss_chance(zone, src, 15)
-
- if(!zone)
+ miss_chance = min(15*(distance-2), 0)
+
+ if (prob(miss_chance))
visible_message("\blue \The [O] misses [src] narrowly!")
return
- O.throwing = 0 //it hit, so stop moving
-
- if (istype(src, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- if (H.check_shields(throw_damage, "[O]"))
- return
-
src.visible_message("\red [src] has been hit by [O].")
- var/armor = run_armor_check(zone, "melee", "Your armor has protected your [zone].", "Your armor has softened the hit to your [zone].")
+ var/armor = run_armor_check(null, "melee")
if(armor < 2)
- apply_damage(throw_damage, dtype, zone, 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
+
if(ismob(O.thrower))
var/mob/M = O.thrower
var/client/assailant = M.client
@@ -124,12 +111,11 @@
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
if(!W || !src) return
-
- if(istype(W.loc,/mob/living) && W.sharp) //Projectile is embedded and suitable for pinning.
-
- if(!istype(src,/mob/living/carbon/human)) //Handles embedding for non-humans and simple_animals.
- O.loc = src
- src.embedded += O
+
+ if(W.sharp) //Projectile is suitable for pinning.
+ //Handles embedding for non-humans and simple_animals.
+ O.loc = src
+ src.embedded += O
var/turf/T = near_wall(dir,2)