From 29b6d829cf528e1be03fd627aeabe019ba3a49e6 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Sat, 29 Jan 2022 04:37:00 -0600 Subject: [PATCH] Fixes balloon alerts sourced on turfs (heavy rain edition) (#64472) Balloon alerts sourced from turfs will now properly only show on one turf. get_atom_on_turf() will now CRASH() if passed a turf instead of an atom/movable. I look through all uses and made sure any place that may send a turf won't, but it SHOULD be fine. --- code/__HELPERS/turfs.dm | 29 ++++++++++++++------- code/datums/chatmessage.dm | 2 +- code/modules/balloon_alert/balloon_alert.dm | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm index 554ccd69e0a..5da17c67f31 100644 --- a/code/__HELPERS/turfs.dm +++ b/code/__HELPERS/turfs.dm @@ -98,17 +98,26 @@ Turf and target are separate in case you want to teleport some distance from a t return destination /** - * Returns the atom sitting on the turf. - * 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/atom_on_turf, stop_type) - var/atom/turf_to_check = atom_on_turf - while(turf_to_check?.loc && !isturf(turf_to_check.loc)) - turf_to_check = turf_to_check.loc - if(stop_type && istype(turf_to_check, stop_type)) + * Returns the top-most atom sitting on the turf. + * 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. + * + * Arguments + * * something_in_turf - a movable within the turf, somewhere. + * * stop_type - optional - stops looking if stop_type is found in the turf, returning that type (if found). + **/ +/proc/get_atom_on_turf(atom/movable/something_in_turf, stop_type) + if(!istype(something_in_turf)) + CRASH("get_atom_on_turf was not passed an /atom/movable! Got [isnull(something_in_turf) ? "null":"type: [something_in_turf.type]"]") + + var/atom/movable/topmost_thing = something_in_turf + + while(topmost_thing?.loc && !isturf(topmost_thing.loc)) + topmost_thing = topmost_thing.loc + if(stop_type && istype(topmost_thing, stop_type)) break - return turf_to_check + + return topmost_thing ///Returns the turf located at the map edge in the specified direction relative to target_atom used for mass driver /proc/get_edge_target_turf(atom/target_atom, direction) diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 6e8cdaededb..1e578a0ae2d 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -170,7 +170,7 @@ approx_lines = max(1, mheight / CHAT_MESSAGE_APPROX_LHEIGHT) // Translate any existing messages upwards, apply exponential decay factors to timers - message_loc = get_atom_on_turf(target) + message_loc = isturf(target) ? target : get_atom_on_turf(target) if (owned_by.seen_messages) var/idx = 1 var/combined_height = approx_lines diff --git a/code/modules/balloon_alert/balloon_alert.dm b/code/modules/balloon_alert/balloon_alert.dm index 8a25206ed0f..c2737226078 100644 --- a/code/modules/balloon_alert/balloon_alert.dm +++ b/code/modules/balloon_alert/balloon_alert.dm @@ -42,7 +42,7 @@ var/atom/movable/movable_source = src bound_width = movable_source.bound_width - var/image/balloon_alert = image(loc = get_atom_on_turf(src), layer = ABOVE_MOB_LAYER) + var/image/balloon_alert = image(loc = isturf(src) ? src : get_atom_on_turf(src), layer = ABOVE_MOB_LAYER) balloon_alert.plane = BALLOON_CHAT_PLANE balloon_alert.alpha = 0 balloon_alert.appearance_flags = RESET_ALPHA|RESET_COLOR|RESET_TRANSFORM