From 7b4d5718892abca92dec4827b6715e5dc5eeb692 Mon Sep 17 00:00:00 2001 From: Arokha Sieyes Date: Sat, 11 Jun 2016 22:05:01 -0400 Subject: [PATCH] Makes communicators great again --- code/_helpers/global_lists.dm | 1 + .../devices/communicator/communicator.dm | 67 +++++++++++++++---- code/modules/mob/living/voice/voice.dm | 8 ++- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 1a1eced63a1..9a90a3676b7 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -11,6 +11,7 @@ var/global/list/human_mob_list = list() //List of all human mobs and sub-type var/global/list/silicon_mob_list = list() //List of all silicon mobs, including clientless var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player +var/global/list/listening_objects = list() //List of all objects which care about receiving messages (communicators, radios, etc) var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index bc80bc9db36..e7831391361 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -17,6 +17,8 @@ var/global/list/obj/item/device/communicator/all_communicators = list() origin_tech = list(TECH_ENGINEERING = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2, TECH_DATA = 2) matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10) + var/video_range = 4 + var/list/voice_mobs = list() var/list/voice_requests = list() var/list/voice_invites = list() @@ -474,6 +476,24 @@ var/global/list/obj/item/device/communicator/all_communicators = list() name = "[owner]'s [initial(name)]" + +// Proc: add_communicating() +// Parameters: 1 (comm - the communicator to add to communicating) +// Description: Used when this communicator gets a new communicator to relay say/me messages to +/obj/item/device/communicator/proc/add_communicating(obj/item/device/communicator/comm) + if(!comm || !istype(comm)) return + + communicating |= comm + listening_objects |= src + +// Proc: del_communicating() +// Parameters: 1 (comm - the communicator to remove from communicating) +// Description: Used when this communicator is being asked to stop relaying say/me messages to another +/obj/item/device/communicator/proc/del_communicating(obj/item/device/communicator/comm) + if(!comm || !istype(comm)) return + + communicating.Remove(comm) + // Proc: open_connection() // Parameters: 2 (user - the person who initiated the connecting being opened, candidate - the communicator or observer that will connect to the device) // Description: Typechecks the candidate, then calls the correct proc for further connecting. @@ -507,8 +527,8 @@ var/global/list/obj/item/device/communicator/all_communicators = list() comm.visible_message("\icon[src] Connection to [src] at [exonet.address] established.") sleep(20) - communicating |= comm - comm.communicating |= src + src.add_communicating(comm) + comm.add_communicating(src) // Proc: open_connection_to_ghost() // Parameters: 2 (user - the person who initiated this, candidate - the ghost that will be turned into a voice mob) @@ -530,6 +550,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() new_voice.mind = candidate.mind //Transfer the mind, if any. new_voice.ckey = candidate.ckey //Finally, bring the client over. voice_mobs.Add(new_voice) + listening_objects |= src var/obj/screen/blackness = new() //Makes a black screen, so the candidate can't see what's going on before actually 'connecting' to the communicator. blackness.screen_loc = ui_entire_screen @@ -586,10 +607,13 @@ var/global/list/obj/item/device/communicator/all_communicators = list() continue comm.visible_message("\icon[src] [reason].") visible_message("\icon[src] [reason].") - comm.communicating.Remove(src) - communicating.Remove(comm) + src.del_communicating(comm) + comm.del_communicating(src) update_icon() + if(voice_mobs.len == 0 && communicating.len == 0) + listening_objects.Remove(src) + // Proc: request() // Parameters: 1 (candidate - the ghost or communicator wanting to call the device) // Description: Response to a communicator or observer trying to call the device. Adds them to the list of requesters @@ -675,6 +699,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list() voice_invites.Cut() all_communicators -= src processing_objects -= src + listening_objects.Remove(src) if(exonet) exonet.remove_address() exonet = null @@ -700,10 +725,18 @@ var/global/list/obj/item/device/communicator/all_communicators = list() /obj/item/device/communicator/see_emote(mob/living/M, text) var/rendered = "\icon[src] [text]" for(var/obj/item/device/communicator/comm in communicating) - for(var/mob/mob in viewers(get_turf(comm))) //We can't use visible_message(), or else we will get an infinite loop if two communicators hear each other. - mob.show_message(rendered) - for(var/mob/living/voice/V in comm.contents) - V.show_message(rendered) + var/turf/T = get_turf(comm) + if(!T) return + var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) //Range of 3 since it's a tiny video display + var/list/mobs_to_relay = in_range["mobs"] + + for(var/mob/mob in mobs_to_relay) //We can't use visible_message(), or else we will get an infinite loop if two communicators hear each other. + var/dst = get_dist(get_turf(mob),get_turf(comm)) + if(dst <= video_range) + mob.show_message(rendered) + else + mob << "You can barely see some movement on \the [src]'s display." + ..() // Proc: hear_talk() @@ -712,9 +745,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() // Description: Relays the speech to all linked communicators. /obj/item/device/communicator/hear_talk(mob/living/M, text, verb, datum/language/speaking) for(var/obj/item/device/communicator/comm in communicating) - var/list/mobs_to_relay = list() - mobs_to_relay |= viewers(get_turf(comm)) - mobs_to_relay |= comm.contents //Needed so ghost-callers can see speech. + + var/turf/T = get_turf(comm) + if(!T) return + var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) + var/list/mobs_to_relay = in_range["mobs"] + for(var/mob/mob in mobs_to_relay) //Can whoever is hearing us understand? if(!mob.say_understands(M, speaking)) @@ -736,7 +772,12 @@ var/global/list/obj/item/device/communicator/all_communicators = list() /obj/item/device/communicator/show_message(msg, type, alt, alt_type) var/rendered = "\icon[src] [msg]" for(var/obj/item/device/communicator/comm in communicating) - for(var/mob/mob in hearers(get_turf(comm))) //Ditto for audible messages. + var/turf/T = get_turf(comm) + if(!T) return + var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) + var/list/mobs_to_relay = in_range["mobs"] + + for(var/mob/mob in mobs_to_relay) mob.show_message(rendered) ..() @@ -822,4 +863,4 @@ var/global/list/obj/item/device/communicator/all_communicators = list() usr << "You can't do that because you are dead!" return - src.attack_self(usr) \ No newline at end of file + src.attack_self(usr) diff --git a/code/modules/mob/living/voice/voice.dm b/code/modules/mob/living/voice/voice.dm index a9f5dbd60a3..a27b0ffc948 100644 --- a/code/modules/mob/living/voice/voice.dm +++ b/code/modules/mob/living/voice/voice.dm @@ -107,7 +107,7 @@ // Proc: say() // Parameters: 4 (generic say() arguments) // Description: Adds a speech bubble to the communicator device, then calls ..() to do the real work. -/mob/living/voice/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="") +/mob/living/voice/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/whispering=0) //Speech bubbles. if(comm) var/speech_bubble_test = say_test(message) @@ -119,4 +119,8 @@ M << speech_bubble src << speech_bubble - ..(message, speaking, verb, alt_name) //mob/living/say() can do the actual talking. \ No newline at end of file + ..(message, speaking, verb, alt_name, whispering) //mob/living/say() can do the actual talking. + +/mob/living/voice/custom_emote(var/m_type=1,var/message = null,var/range=world.view) + if(!comm) return + ..(m_type,message,comm.video_range)