From 96d0ab85f1b9960030b12ded0174c2f68cdf643c Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Sat, 11 Apr 2026 08:12:21 -0400 Subject: [PATCH] Point Blank Guns Fixes (#22195) closes #22065 closes #22107 This PR fixes some bugs with point blank gunfire that made it not work as intended. It's now possible to shoot someone on the same tile as you (such as a Human Shield Hostage) if you click on them directly, otherwise your bullets will bypass them by shooting in the direction you declare. You can also no longer shoot people who have a one way glass window between you and them, the bullet will hit the glass first. Finally, you can also no longer accidentally shoot yourself if you sprint forwards in the same direction you are shooting (by running into your own bullets). Basically, you can now take a human shield, use them as cover, and then when security tries to run in you can execute the human shield by clicking on their head. Yes, you can also still shoot yourself if you deliberately click on your own sprite. Suicide by gun still works. https://github.com/user-attachments/assets/fbfe0eea-03ee-419a-b9ae-c08af79c1e15 --- code/modules/projectiles/projectile.dm | 17 +++++++++++++---- .../hellfirejag-point-blank-fixes.yml | 4 ++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 html/changelogs/hellfirejag-point-blank-fixes.yml diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 794cc6680fe..4b010a83ea4 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -531,6 +531,8 @@ /obj/projectile/proc/can_hit_target(atom/target, direct_target = FALSE, ignore_loc = FALSE, cross_failed = FALSE) if(QDELETED(target) || impacted[target.weak_reference]) return FALSE + if(target == firer && !ignore_source_check) + return FALSE if(!ignore_loc && (loc != target.loc) && !(can_hit_turfs && direct_target && loc == target)) return FALSE // if pass_flags match, pass through entirely - unless direct target is set. @@ -734,8 +736,9 @@ if(!log_override && firer && original && !do_not_log) log_combat(firer, original, "fired at", src, "from [get_area_name(src, TRUE)]") //note: mecha projectile logging is handled in /obj/item/mecha_parts/mecha_equipment/weapon/action(). try to keep these messages roughly the sameish just for consistency's sake. - if(direct_target && (get_dist(direct_target, get_turf(src)) <= 1)) // point blank shots - process_hit(get_turf(direct_target), direct_target) + var/atom/pb_target = direct_target || original + if(pb_target && (get_dist(pb_target, get_turf(src)) == 0)) // point blank shots + process_hit(get_turf(pb_target), pb_target) if(QDELETED(src)) return var/turf/starting = get_turf(src) @@ -978,7 +981,10 @@ if(target_loc) yo = target_loc.y - source_loc.y xo = target_loc.x - source_loc.x - set_angle(get_angle(src, target_loc) + deviation) + if(target_loc == source_loc) + set_angle(dir2angle(source_position.dir) + deviation) + else + set_angle(get_angle(src, target_loc) + deviation) return TRUE stack_trace("WARNING: Projectile [type] fired without a target or mouse parameters to aim with.") @@ -1004,7 +1010,10 @@ var/turf/target_loc = get_turf(target) var/dx = ((target_loc.x - source_loc.x) * world.icon_size) + (target.pixel_x - source.pixel_x) + (p_x - (world.icon_size / 2)) var/dy = ((target_loc.y - source_loc.y) * world.icon_size) + (target.pixel_y - source.pixel_y) + (target.pixel_z - source.pixel_z) + (p_y - (world.icon_size / 2)) - angle = ATAN2(dy, dx) + if(!dx && !dy) + angle = dir2angle(source.dir) + else + angle = ATAN2(dy, dx) return list(angle, p_x, p_y) if(!ismob(source) || !LAZYACCESS(modifiers, SCREEN_LOC)) diff --git a/html/changelogs/hellfirejag-point-blank-fixes.yml b/html/changelogs/hellfirejag-point-blank-fixes.yml new file mode 100644 index 00000000000..043d774b0d0 --- /dev/null +++ b/html/changelogs/hellfirejag-point-blank-fixes.yml @@ -0,0 +1,4 @@ +author: Hellfirejag +delete-after: True +changes: + - bugfix: "Fixed projectile hit detection for point-blank situations. It's no longer possible to run into your own projectiles. You can take a human shield and either shoot through your human shield, or kill them by clicking their head."