From b04be7bcda690e8e79556e4554ebce15d00ea7de Mon Sep 17 00:00:00 2001 From: Geeves Date: Wed, 21 Jul 2021 14:19:39 +0200 Subject: [PATCH] Balloon Alerts (#12020) --- aurorastation.dme | 1 + code/_helpers/game.dm | 4 ++ code/_helpers/text.dm | 7 ++ code/modules/balloon_alert/balloon_alert.dm | 78 +++++++++++++++++++++ code/modules/projectiles/guns/projectile.dm | 4 ++ html/changelogs/geeves-balloon_alerts.yml | 7 ++ 6 files changed, 101 insertions(+) create mode 100644 code/modules/balloon_alert/balloon_alert.dm create mode 100644 html/changelogs/geeves-balloon_alerts.yml diff --git a/aurorastation.dme b/aurorastation.dme index 6a33e48a8e9..f00642aaa28 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -1356,6 +1356,7 @@ #include "code\modules\background\religion\vaurca.dm" #include "code\modules\background\space_sectors\space_sector.dm" #include "code\modules\background\space_sectors\tauceti.dm" +#include "code\modules\balloon_alert\balloon_alert.dm" #include "code\modules\battlemonsters\datum_core.dm" #include "code\modules\battlemonsters\datum_elements.dm" #include "code\modules\battlemonsters\datum_monsters.dm" diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index 6fe43923af6..1f77b3a376d 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -525,6 +525,10 @@ datum/projectile_data else return (cult.current_antagonists.len > spookiness_threshold) +/// Removes an image from a client's `.images`. Useful as a callback. +/proc/remove_image_from_client(image/image, client/remove_from) + remove_from?.images -= image + /proc/remove_images_from_clients(image/I, list/show_to) for(var/client/C in show_to) C.images -= I diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index 655a8a817bd..94c680f23dd 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -1,5 +1,12 @@ #define SMALL_FONTS(FONTSIZE, MSG) "[MSG]" +/// Macro from Lummox used to get height from a MeasureText proc +#define WXH_TO_HEIGHT(x) text2num(copytext(x, findtextEx(x, "x") + 1)) + +#define SPAN_RED(x) "[x]" +#define SPAN_YELLOW(x) "[x]" +#define SPAN_GREEN(x) "[x]" + /* * Holds procs designed to help with filtering text * Contains groups: diff --git a/code/modules/balloon_alert/balloon_alert.dm b/code/modules/balloon_alert/balloon_alert.dm new file mode 100644 index 00000000000..47560677c89 --- /dev/null +++ b/code/modules/balloon_alert/balloon_alert.dm @@ -0,0 +1,78 @@ +#define BALLOON_TEXT_WIDTH 200 +#define BALLOON_TEXT_SPAWN_TIME (0.2 SECONDS) +#define BALLOON_TEXT_FADE_TIME (0.1 SECONDS) +#define BALLOON_TEXT_FULLY_VISIBLE_TIME (0.7 SECONDS) +#define BALLOON_TEXT_TOTAL_LIFETIME (BALLOON_TEXT_SPAWN_TIME + BALLOON_TEXT_FULLY_VISIBLE_TIME + BALLOON_TEXT_FADE_TIME) + +/// Creates text that will float from the atom upwards to the viewer. +/atom/proc/balloon_alert(mob/viewer, text) + SHOULD_NOT_SLEEP(TRUE) + + INVOKE_ASYNC(src, .proc/balloon_alert_perform, viewer, text) + +/// Create balloon alerts (text that floats up) to everything within range. +/// Will only display to people who can see. +/atom/proc/balloon_alert_to_viewers(message, self_message, vision_distance = 7, list/ignored_mobs) + SHOULD_NOT_SLEEP(TRUE) + + var/list/hearers = list() + var/list/objs = list() + get_mobs_and_objs_in_view_fast(get_turf(src), vision_distance, hearers, objs, ONLY_GHOSTS_IN_VIEW) + hearers -= ignored_mobs + + for(var/mob/hearer as anything in hearers - src) + if(is_blind(hearer)) + continue + balloon_alert(hearer, message) + balloon_alert(src, self_message) + +// Do not use. +// MeasureText blocks. I have no idea for how long. +// I would've made the maptext_height update on its own, but I don't know +// if this would look bad on laggy clients. +/atom/proc/balloon_alert_perform(mob/viewer, text) + var/client/viewer_client = viewer.client + if (isnull(viewer_client)) + return + + var/bound_width = world.icon_size + if (ismovable(src)) + 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) + balloon_alert.alpha = 0 + balloon_alert.maptext = SMALL_FONTS(7, "[text]") + balloon_alert.maptext_x = (BALLOON_TEXT_WIDTH - bound_width) * -0.5 + balloon_alert.maptext_height = WXH_TO_HEIGHT(viewer_client?.MeasureText(text, null, BALLOON_TEXT_WIDTH)) + balloon_alert.maptext_width = BALLOON_TEXT_WIDTH + + viewer_client?.images += balloon_alert + + animate( + balloon_alert, + pixel_y = world.icon_size * 1.2, + time = BALLOON_TEXT_TOTAL_LIFETIME, + easing = SINE_EASING | EASE_OUT, + ) + + animate( + alpha = 255, + time = BALLOON_TEXT_SPAWN_TIME, + easing = CUBIC_EASING | EASE_OUT, + flags = ANIMATION_PARALLEL, + ) + + animate( + alpha = 0, + time = BALLOON_TEXT_FULLY_VISIBLE_TIME, + easing = CUBIC_EASING | EASE_IN, + ) + + addtimer(CALLBACK(GLOBAL_PROC, .proc/remove_image_from_client, balloon_alert, viewer_client), BALLOON_TEXT_TOTAL_LIFETIME) + +#undef BALLOON_TEXT_FADE_TIME +#undef BALLOON_TEXT_FULLY_VISIBLE_TIME +#undef BALLOON_TEXT_SPAWN_TIME +#undef BALLOON_TEXT_TOTAL_LIFETIME +#undef BALLOON_TEXT_WIDTH \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index c34de1b0a38..6723f9fe898 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -88,6 +88,7 @@ if(prob(jam_chance)) playsound(src.loc, 'sound/items/trayhit2.ogg', 50, TRUE) to_chat(user, "\The [src] jams!") + balloon_alert(user, SPAN_RED("JAM")) jam_num = rand(2, 5) // gotta attackself two to five times to unjam return TRUE @@ -220,8 +221,11 @@ jam_num-- if(!jam_num) visible_message(SPAN_DANGER("\The [user] unjams \the [src]!")) + balloon_alert(user, SPAN_GREEN("CLEAR")) playsound(src.loc, 'sound/weapons/unjam.ogg', 100, TRUE) unjam_cooldown = world.time + else + balloon_alert(user, SPAN_YELLOW("CLICK")) else if(unjam_cooldown + 2 SECONDS > world.time) return else if(firemodes.len > 1) diff --git a/html/changelogs/geeves-balloon_alerts.yml b/html/changelogs/geeves-balloon_alerts.yml new file mode 100644 index 00000000000..1dadb3d00de --- /dev/null +++ b/html/changelogs/geeves-balloon_alerts.yml @@ -0,0 +1,7 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Added balloon alerts, messages that appear on the screen to convey information quickly without using the chat." + - rscadd: "Added balloon alerts to gun jamming and unjamming so you don't need to look at the chat."