diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 94199066e55..16551c819d9 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -25,26 +25,6 @@ // Garbage collection var/gc_destroyed=null -/atom/proc/throw_impact(atom/hit_atom, var/speed) - if(istype(hit_atom,/mob/living)) - var/mob/living/M = hit_atom - M.hitby(src,speed) - - else if(isobj(hit_atom)) - var/obj/O = hit_atom - if(!O.anchored) - step(O, src.dir) - O.hitby(src,speed) - - else if(isturf(hit_atom)) - var/turf/T = hit_atom - if(T.density) - spawn(2) - step(src, turn(src.dir, 180)) - if(istype(src,/mob/living)) - var/mob/living/M = src - M.turf_collision(T, speed) - /atom/Del() // Pass to Destroy(). if(!gc_destroyed) @@ -265,6 +245,8 @@ its easier to just keep the beam vertical. /atom/proc/hitby(atom/movable/AM as mob|obj) + if (density) + AM.throwing = 0 return /atom/proc/add_hiddenprint(mob/living/M as mob) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 63ccc18fcc6..8d89ad23f8e 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -30,7 +30,6 @@ /atom/movable/Bump(var/atom/A as mob|obj|turf|area, yes) if(src.throwing) src.throw_impact(A) - src.throwing = 0 if ((A && yes)) A.last_bumped = world.time @@ -50,6 +49,29 @@ return 1 return 0 +//called when src is thrown into hit_atom +/atom/movable/proc/throw_impact(atom/hit_atom, var/speed) + if(istype(hit_atom,/mob/living)) + var/mob/living/M = hit_atom + M.hitby(src,speed) + + else if(isobj(hit_atom)) + var/obj/O = hit_atom + if(!O.anchored) + step(O, src.dir) + O.hitby(src,speed) + + else if(isturf(hit_atom)) + src.throwing = 0 + var/turf/T = hit_atom + if(T.density) + spawn(2) + step(src, turn(src.dir, 180)) + if(istype(src,/mob/living)) + var/mob/living/M = src + M.turf_collision(T, speed) + +//decided whether a movable atom being thrown can pass through the turf it is in. /atom/movable/proc/hit_check(var/speed) if(src.throwing) for(var/atom/A in get_turf(src)) @@ -57,12 +79,9 @@ if(istype(A,/mob/living)) if(A:lying) continue src.throw_impact(A,speed) - if(src.throwing == 1) - src.throwing = 0 if(isobj(A)) if(A.density && !A.throwpass) // **TODO: Better behaviour for windows which are dense, but shouldn't always stop movement src.throw_impact(A,speed) - src.throwing = 0 /atom/movable/proc/throw_at(atom/target, range, speed) if(!target || !src) return 0 @@ -155,8 +174,8 @@ a = get_area(src.loc) //done throwing, either because it hit something or it finished moving - src.throwing = 0 if(isobj(src)) src.throw_impact(get_turf(src),speed) + src.throwing = 0 //Overlays diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 2d342a7a8a3..88440c4eef1 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -475,6 +475,7 @@ return /obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper + ..() src.log_message("Hit by [A].",1) call((proc_res["dynhitby"]||src), "dynhitby")(A) return diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 2b5f1671fac..422d622da6f 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -68,6 +68,7 @@ src.dust() return absorb +//this proc handles being hit by a thrown atom /mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve if(istype(AM,/obj/)) var/obj/O = AM @@ -81,11 +82,27 @@ //run to-hit check here + var/throw_damage = O.throwforce*(speed/5) + + //def_zone = get_zone_with_miss_chance(zone, src, 15*AM.throwing_dist_travelled) + zone = get_zone_with_miss_chance(zone, src) //TODO: store the location of the thrower and adjust miss chance with distance + + if(!zone) + visible_message("\blue \The [AM] misses [src] narrowly!") + return + + AM.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 hit to your [zone].") + var/armor = run_armor_check(zone, "melee", "Your armor has protected your [zone].", "Your armor has softened the hit to your [zone].") if(armor < 2) - apply_damage(O.throwforce*(speed/5), dtype, zone, armor, is_sharp(O), has_edge(O), O) + apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O) if(!O.fingerprintslast) return @@ -108,7 +125,7 @@ if(speed >= 15) var/obj/item/weapon/W = O var/momentum = speed/2 - var/dir = get_dir(M,src) + var/dir = get_dir(M,src) //TODO: store the location of the thrower and move this out of the fingerprintslast block 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) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index f95b55f97c1..c094fb5335e 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -178,7 +178,11 @@ proc/hasorgans(A) */ return zone - +// Returns zone with a certain probability. +// If the probability misses, returns "chest" instead. +// If "chest" was passed in as zone, then on a "miss" will return "head", "l_arm", or "r_arm" +// Do not use this if someone is intentionally trying to hit a specific body part. +// Use get_zone_with_miss_chance() for that. /proc/ran_zone(zone, probability) zone = check_zone(zone) if(!probability) probability = 90