diff --git a/code/__DEFINES/living.dm b/code/__DEFINES/living.dm index a8e6b86f8de2..cfdfbedc9faa 100644 --- a/code/__DEFINES/living.dm +++ b/code/__DEFINES/living.dm @@ -117,6 +117,11 @@ /// Just be sure to call update_limbless_locomotion() after applying / removal #define TRAIT_NO_LEG_AID "no_leg_aid" +/// Attach to a turf to have whispers project across it if the speaker is facing it +/// (basically expanding the range of whispers by one tile in the direction of the speaker) +/// Used to allow people to whisper across desks/tables since they otherwise are too distant +#define TRAIT_TURF_PROJECTS_WHISPERS "projects_whispers" + #define COLOR_BLOOD "#c90000" /// Helper for picking between left or right when given a value diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 0d6d2bfd8696..f6e8544458a9 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -54,7 +54,14 @@ ) AddElement(/datum/element/connect_loc, loc_connections) - var/static/list/give_turf_traits = list(TRAIT_TURF_IGNORE_SLOWDOWN, TRAIT_TURF_IGNORE_SLIPPERY, TRAIT_IMMERSE_STOPPED) + // NON-MODULE CHANGE + var/static/list/give_turf_traits = list( + TRAIT_TURF_IGNORE_SLOWDOWN, + TRAIT_TURF_IGNORE_SLIPPERY, + TRAIT_IMMERSE_STOPPED, + TRAIT_TURF_PROJECTS_WHISPERS, + ) + AddElement(/datum/element/give_turf_traits, give_turf_traits) register_context() diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index 140e62c5d4a6..bbedc517ed15 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -279,6 +279,12 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/message = "" var/raw_dist = get_dist(speaker, src) + // NON-MODULE CHANGE - check for projected whispers, calculate distance from the projected tile if so + if(message_mods[WHISPER_MODE] && message_range != INFINITY) + var/turf/in_front = get_step(speaker, speaker.dir) + if(in_front && HAS_TRAIT(in_front, TRAIT_TURF_PROJECTS_WHISPERS)) + raw_dist = min(raw_dist, get_dist(in_front, src)) + // Infinite range implies something like telecomms, ie something that should never be distance modified if(!HAS_TRAIT(src, TRAIT_GOOD_HEARING) && message_range != INFINITY) // How far we are we outside the message range? @@ -388,6 +394,13 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/list/in_view = get_hearers_in_view(message_range + whisper_range, source) var/list/listening = get_hearers_in_range(message_range + whisper_range, source) + // NON-MODULE CHANGE - check for projected whispers, add new potential hearers if so + if(is_speaker_whispering) + var/turf/in_front = get_step(src, dir) + if(in_front && HAS_TRAIT(in_front, TRAIT_TURF_PROJECTS_WHISPERS)) + in_view |= get_hearers_in_view(message_range + whisper_range, in_front) + listening |= get_hearers_in_range(message_range + whisper_range, in_front) + // Pre-process listeners to account for line-of-sight for(var/atom/movable/listening_movable as anything in listening) if(!(listening_movable in in_view) && !HAS_TRAIT(listening_movable, TRAIT_XRAY_HEARING))