diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 99bfadbddae..1bba4042d0c 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -193,6 +193,9 @@ return hear +/proc/is_same_root_atom(atom/one, atom/two) + return get_atom_on_turf(one) == get_atom_on_turf(two) + /proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios) . = list() // Returns a list of mobs who can hear any of the radios given in @radios @@ -212,17 +215,33 @@ var/turf/speaker = get_turf(R) if(speaker) for(var/turf/T in hear(R.canhear_range,speaker)) - speaker_coverage[T] = T + var/obj/item/radio/oldR = speaker_coverage[T] + if(!istype(oldR)) + speaker_coverage[T] = R + continue + if(oldR.canhear_range < R.canhear_range) + speaker_coverage[T] = R // Try to find all the players who can hear the message for(var/A in GLOB.player_list + GLOB.hear_radio_list) var/mob/M = A - if(M) - var/turf/ear = get_turf(M) - if(ear) - // Ghostship is magic: Ghosts can hear radio chatter from anywhere - if(speaker_coverage[ear] || (isobserver(M) && M.get_preference(PREFTOGGLE_CHAT_GHOSTRADIO))) - . |= M // Since we're already looping through mobs, why bother using |= ? This only slows things down. + if(!M) + continue + var/turf/ear = get_turf(M) + if(!ear) + continue + // Ghostship is magic: Ghosts can hear radio chatter from anywhere + if(isobserver(M) && M.get_preference(PREFTOGGLE_CHAT_GHOSTRADIO)) + . |= M + continue + if(!speaker_coverage[ear]) + continue + var/obj/item/radio/R = speaker_coverage[ear] + if(!istype(R) || R.canhear_range > 0) + . |= M + continue + if(is_same_root_atom(M, speaker_coverage[ear])) + . |= M return . /proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index c4b030380c2..19ec5637a14 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -485,12 +485,12 @@ //For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf. //Optional arg 'type' to stop once it reaches a specific type instead of a turf. /proc/get_atom_on_turf(atom/movable/M, stop_type) - var/atom/loc = M - while(loc?.loc && !isturf(loc.loc)) - loc = loc.loc - if(stop_type && istype(loc, stop_type)) + var/atom/current = M + while(current?.loc && !isturf(current.loc)) + current = current.loc + if(stop_type && istype(current, stop_type)) break - return loc + return current /* Returns 1 if the chain up to the area contains the given typepath