From 0fa68bcc9dec932a2d78f46034fd0211bf64bdbd Mon Sep 17 00:00:00 2001 From: nevimer <77420409+nevimer@users.noreply.github.com> Date: Tue, 25 May 2021 07:51:35 -0400 Subject: [PATCH] adds atom_say starting point, working build --- code/__HELPERS/game.dm | 51 ++++++++++++++++++++++++++++ code/game/atoms.dm | 19 +++++++++++ code/modules/mob/say.dm | 4 +-- code/modules/mob/typing_indicator.dm | 26 ++++++++++---- 4 files changed, 92 insertions(+), 8 deletions(-) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 8b013064f77..6cdad235481 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -637,3 +637,54 @@ datum/projectile_data min(list_y), max(list_x), max(list_y)) + +/proc/recursive_mob_check(var/atom/O, var/list/L = list(), var/recursion_limit = 3, var/client_check = 1, var/sight_check = 1, var/include_radio = 1) + + //GLOB.debug_mob += O.contents.len + if(!recursion_limit) + return L + for(var/atom/A in O.contents) + + if(ismob(A)) + var/mob/M = A + if(client_check && !M.client) + L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio) + continue + if(sight_check && !isInSight(A, O)) + continue + L |= M + //log_world("[recursion_limit] = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])") + + else if(include_radio && istype(A, /obj/item/radio)) + if(sight_check && !isInSight(A, O)) + continue + L |= A + + if(isobj(A) || ismob(A)) + L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio) + return L + +/proc/get_mobs_in_view(var/R, var/atom/source, var/include_clientless = FALSE) + // Returns a list of mobs in range of R from source. Used in radio and say code. + + var/turf/T = get_turf(source) + var/list/hear = list() + + if(!T) + return hear + + var/list/range = hear(R, T) + + for(var/atom/A in range) + if(ismob(A)) + var/mob/M = A + if(M.client || include_clientless) + hear += M + //log_world("Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])") + else if(istype(A, /obj/item/radio)) + hear += A + + if(isobj(A) || ismob(A)) + hear |= recursive_mob_check(A, hear, 3, 1, 0, 1) + + return hear diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 055196b7b41..378ee3c2f10 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -13,6 +13,8 @@ var/throwpass = 0 var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom. var/simulated = 1 //filter for actions - used by lighting overlays + var/bubble_icon = "normal" ///what icon the atom uses for speechbubbles + var/atom_say_verb = "says" var/fluorescent // Shows up under a UV light. var/list/atom_colours //used to store the different colors on an atom @@ -748,3 +750,20 @@ /atom/proc/is_incorporeal() return FALSE + +/atom/proc/atom_say(message) + if(!message) + return + var/list/speech_bubble_hearers = list() + for(var/mob/M in get_mobs_in_view(7, src)) + M.show_message("[src] [atom_say_verb], \"[message]\"", 2, null, 1) + if(M.client) + speech_bubble_hearers += M.client + + if(length(speech_bubble_hearers)) + var/image/I = generate_speech_bubble(src, "[bubble_icon][say_test(message)]", FLY_LAYER) + I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA + INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30) + +/atom/proc/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list()) + return diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 8116b5c5ab7..fa03fee1a34 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -126,7 +126,7 @@ return get_turf(src) -/mob/proc/say_test(var/text) +/proc/say_test(var/text) var/ending = copytext_char(text, length_char(text)) if (ending == "?") return "1" @@ -164,7 +164,7 @@ var/alert_result = alert(src, "You dont know the langauge you are about to speak, instead you will speak Babel. Do you want to?", "Unknown Language Alert","No","Yes") if(alert_result == "Yes") return GLOB.all_languages[LANGUAGE_GIBBERISH] - else + else if(isliving(src)) var/mob/living/caller = src return GLOB.all_languages[caller.default_language] diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm index 99dce06280f..02dde267ebc 100644 --- a/code/modules/mob/typing_indicator.dm +++ b/code/modules/mob/typing_indicator.dm @@ -1,15 +1,29 @@ +/proc/generate_speech_bubble(var/bubble_loc, var/speech_state, var/set_layer = FLOAT_LAYER) + var/image/I = image('icons/mob/talk_vr.dmi', bubble_loc, speech_state, set_layer) //VOREStation Edit - talk_vr.dmi instead of talk.dmi for right-side icons + I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE) //VOREStation Edit + if(istype(bubble_loc, /atom/movable)) + var/atom/movable/AM = bubble_loc + var/x_scale = AM.get_icon_scale_x() + if(abs(x_scale) < 2) // reset transform on bubbles, except for the Very Large + I.pixel_z = (AM.icon_expected_height * (x_scale-1)) + I.appearance_flags |= RESET_TRANSFORM + + return I + +/mob/proc/init_typing_indicator(var/set_state = "typing") + typing_indicator = new + typing_indicator.appearance = generate_speech_bubble(null, set_state) + typing_indicator.appearance_flags |= (RESET_COLOR|PIXEL_SCALE) //VOREStation Edit + /mob/proc/set_typing_indicator(var/state) //Leaving this here for mobs. if(!is_preference_enabled(/datum/client_preference/show_typing_indicator)) - cut_overlay(typing_indicator, TRUE) + if(typing_indicator) + cut_overlay(typing_indicator, TRUE) return if(!typing_indicator) - typing_indicator = new - //typing_indicator.icon = 'icons/mob/talk_vr.dmi' //VOREStation Edit - Looks better on the right with job icons. - //typing_indicator.icon_state = "typing" - typing_indicator.icon = 'icons/mob/talk_vr.dmi' //VOREStation Edit - talk_vr.dmi instead of talk.dmi for right-side icons - typing_indicator.icon_state = "[speech_bubble_appearance()]_typing" + init_typing_indicator("[speech_bubble_appearance()]_typing") if(state && !typing) add_overlay(typing_indicator, TRUE)