diff --git a/code/__HELPERS/view.dm b/code/__HELPERS/view.dm index dc25dcc0249..30e8bc8f9f9 100644 --- a/code/__HELPERS/view.dm +++ b/code/__HELPERS/view.dm @@ -20,8 +20,23 @@ view_info[2] *= world.icon_size return view_info -/proc/in_view_range(mob/user, atom/A) - var/list/view_range = getviewsize(user.client.view) - var/turf/source = get_turf(user) - var/turf/target = get_turf(A) - return ISINRANGE(target.x, source.x - view_range[1], source.x + view_range[1]) && ISINRANGE(target.y, source.y - view_range[1], source.y + view_range[1]) +/** +* Frustrated with bugs in can_see(), this instead uses viewers for a much more effective approach. +* ### Things to note: +* - Src/source must be a mob. `viewers()` returns mobs. +* - Adjacent objects are always considered visible. +*/ + +/// The default tile-distance between two atoms for one to consider the other as visible. +#define DEFAULT_SIGHT_DISTANCE 7 + +/// Basic check to see if the src object can see the target object. +#define CAN_I_SEE(target) ((src in viewers(DEFAULT_SIGHT_DISTANCE, target)) || in_range(target, src)) + + +/// Checks the visibility between two other objects. +#define CAN_THEY_SEE(target, source) ((source in viewers(DEFAULT_SIGHT_DISTANCE, target)) || in_range(target, source)) + + +/// Further checks distance between source and target. +#define CAN_SEE_RANGED(target, source, dist) ((source in viewers(dist, target)) || in_range(target, source)) diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm index 33b713e8a57..1faa04ceacc 100644 --- a/code/datums/components/fullauto.dm +++ b/code/datums/components/fullauto.dm @@ -249,7 +249,7 @@ if(get_dist(shooter, target) <= 0) target = get_step(shooter, shooter.dir) //Shoot in the direction faced if the mouse is on the same tile as we are. target_loc = target - else if(!in_view_range(shooter, target)) + else if(!CAN_THEY_SEE(target, shooter)) stop_autofiring() //Elvis has left the building. return FALSE shooter.face_atom(target) diff --git a/code/datums/components/ranged_mob_full_auto.dm b/code/datums/components/ranged_mob_full_auto.dm index a33b705d548..ff3bfcfe60f 100644 --- a/code/datums/components/ranged_mob_full_auto.dm +++ b/code/datums/components/ranged_mob_full_auto.dm @@ -56,7 +56,7 @@ if (get_dist(living_parent, target) <= 0) set_target(get_step(living_parent, living_parent.dir)) // Shoot in the direction faced if the mouse is on the same tile as we are. target_loc = target - else if (!in_view_range(living_parent, target)) + else if (!CAN_THEY_SEE(target, living_parent)) stop_firing() return FALSE // Can't see shit diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index bdd64910528..ab5a5350357 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -409,7 +409,7 @@ COOLDOWN_START(src, coin_regen_cd, coin_regen_rate) /obj/item/gun/energy/marksman_revolver/afterattack_secondary(atom/target, mob/living/user, params) - if(!can_see(user, get_turf(target), length = 9)) + if(!CAN_THEY_SEE(target, user)) return ..() if(max_coins && coin_count <= 0)