diff --git a/code/defines/procs/gamehelpers.dm b/code/defines/procs/gamehelpers.dm index 10e1dc7adbd..9925ee0072f 100644 --- a/code/defines/procs/gamehelpers.dm +++ b/code/defines/procs/gamehelpers.dm @@ -219,6 +219,31 @@ return hear + +/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios) + // Returns a list of mobs who can hear any of the radios given in @radios + + var/list/hearers = list() + + // Try to find all the players who can hear the message + for(var/key in client_list) + var/client/C = client_list[key] + var/mob/M = C.mob + if(!M) continue + + var/atom/ear = M.get_ear() + if(!ear) continue + + // Now see if they're near any broadcasting radio + for(var/obj/item/device/radio/R in radios) + var/turf/radio_loc = get_turf(R) + if(ear in view(R.canhear_range,radio_loc)) + hearers += M + break + + return hearers + + #define SIGN(X) ((X<0)?-1:1) proc diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index bee35cac592..e2f7f1a58b1 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -208,15 +208,15 @@ var/list/recentmessages = list() // global list of recent messages broadcasted : var/display_freq = connection.frequency - var/list/receive = list() + var/list/obj/item/device/radio/radios = list() // --- Broadcast only to intercom devices --- if(data == 1) for (var/obj/item/device/radio/intercom/R in connection.devices["[RADIO_CHAT]"]) - - receive |= R.send_hear(display_freq) + if(R.receive_range(display_freq) > 0) + radios += R // --- Broadcast only to intercoms and station-bounced radios --- @@ -227,7 +227,8 @@ var/list/recentmessages = list() // global list of recent messages broadcasted : if(istype(R, /obj/item/device/radio/headset)) continue - receive |= R.send_hear(display_freq) + if(R.receive_range(display_freq) > 0) + radios += R // --- Broadcast to syndicate radio! --- @@ -237,15 +238,19 @@ var/list/recentmessages = list() // global list of recent messages broadcasted : for (var/obj/item/device/radio/R in syndicateconnection.devices["[RADIO_CHAT]"]) - receive |= R.send_hear(SYND_FREQ) - + if(R.receive_range(SYND_FREQ) > 0) + radios += R // --- Broadcast to ALL radio devices --- else for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"]) + if(R.receive_range(display_freq) > 0) + radios += R - receive |= R.send_hear(display_freq) + + // Get a list of mobs who can hear from the radios we collected. + var/list/receive = get_mobs_in_radio_ranges(radios) /* ###### Organize the receivers into categories for displaying the message ###### */ diff --git a/code/game/objects/radio/intercom.dm b/code/game/objects/radio/intercom.dm index 5a5db05bb4d..0c25ddba7c0 100644 --- a/code/game/objects/radio/intercom.dm +++ b/code/game/objects/radio/intercom.dm @@ -4,6 +4,7 @@ icon_state = "intercom" anchored = 1 w_class = 4.0 + canhear_range = 4 var/number = 0 var/anyai = 1 var/mob/living/silicon/ai/ai = list() @@ -26,31 +27,21 @@ send_hear(freq) + var/range = receive_range(freq) + + if(range > 0) + return get_mobs_in_view(canhear_range, src) + + receive_range(freq) if (!(src.wires & WIRE_RECEIVE)) - return + return 0 if (!src.listening) - return + return 0 if(freq == SYND_FREQ) if(!(src.syndie)) - return//Prevents broadcast of messages over devices lacking the encryption - /* - var/turf/T = get_turf(src) - var/list/hear = hearers(7, T) - var/list/V - //find mobs in lockers, cryo and intellycards - for(var/mob/M in world) - if (isturf(M.loc)) - continue //if M can hear us it is already was found by hearers() - if (!M.client) - continue //skip monkeys and leavers - if (!V) //lasy initialisation - V = view(7, T) - if (get_turf(M) in V) //this slow, but I don't think we'd have a lot of wardrobewhores every round --rastaf0 - hear+=M - */ - //return hear + return 0//Prevents broadcast of messages over devices lacking the encryption - return get_mobs_in_view(4, src) + return canhear_range hear_talk(mob/M as mob, msg) diff --git a/code/game/objects/radio/radio.dm b/code/game/objects/radio/radio.dm index 5d0a08dc06a..61f163e7233 100644 --- a/code/game/objects/radio/radio.dm +++ b/code/game/objects/radio/radio.dm @@ -619,27 +619,23 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use return null return */ -/obj/item/device/radio/proc/send_hear(freq) - /* - I'm removing this because this is apparently a REALLY REALLY bad thing and causes - people's transmissions to get cut off. This also means radios have no delay. A - fair price to pay for reliable radios. -- Doohl - if(last_transmission && world.time < (last_transmission + TRANSMISSION_DELAY)) - return - last_transmission = world.time - */ +/obj/item/device/radio/proc/receive_range(freq) + // check if this radio can receive on the given frequency, and if so, + // what the range is in which mobs will hear the radio + // returns: 0 if can't receive, range otherwise + if (!(wires & WIRE_RECEIVE)) - return + return 0 if(freq == SYND_FREQ) if(!(src.syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys - return + return 0 if (!on) - return + return 0 if (!freq) //recieved on main frequency if (!listening) - return + return 0 else var/accept = (freq==frequency && listening) if (!accept) @@ -649,28 +645,16 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use accept = 1 break if (!accept) - return + return 0 - /* // UURAAAGH ALL THE CPUS, WASTED. ALL OF THEM. NO. -- Doohl - var/turf/T = get_turf(src) - var/list/hear = hearers(1, T) - var/list/V - //find mobs in lockers, cryo and intellicards, brains, MMIs, and so on. - for (var/mob/M in world) - if (isturf(M.loc)) - continue //if M can hear us it is already was found by hearers() - if (!M.client) - continue //skip monkeys and leavers - if (!V) //lasy initialisation - V = view(1, T) - if (get_turf(M) in V) //this slow, but I don't think we'd have a lot of wardrobewhores every round --rastaf0 - hear+=M - */ + return canhear_range - /* Instead, let's individually search potential containers for mobs! More verbose but a LOT more efficient and less laggy */ - // Check gamehelpers.dm for the proc definition: +/obj/item/device/radio/proc/send_hear(freq) + var/range = receive_range(freq) + + if(range > 0) + return get_mobs_in_view(canhear_range, src) - return get_mobs_in_view(canhear_range, src) /obj/item/device/radio/examine() set src in view() diff --git a/code/global.dm b/code/global.dm index d082619af1e..71bacc5204d 100644 --- a/code/global.dm +++ b/code/global.dm @@ -11,6 +11,10 @@ var/global/list/processing_objects = list() var/global/list/active_diseases = list() //items that ask to be called every cycle +// This list will map client ckeys to client objects +// It will be automatically kept up to date by client/New and client/Del +var/global/list/client_list = list() + var/global/defer_powernet_rebuild = 0 // true if net rebuild will be called manually after an event var/global/list/global_map = null diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 90d1c2b6bd4..e4042500c0c 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -95,6 +95,8 @@ host = key world.update_status() + client_list[ckey] = src + ..() //calls mob.Login() //Admin Authorisation @@ -109,6 +111,8 @@ //DISCONNECT// ////////////// /client/Del() + client_list.Remove(ckey) + spawn(0) if(holder) del(holder) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 5f6d33e9900..2b8f31f0cd7 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -70,3 +70,11 @@ /mob/proc/emote(var/act) return + +/mob/proc/get_ear() + // returns an atom representing a location on the map from which this + // mob can hear things + + // should be overloaded for all mobs whose "ear" is separate from their "mob" + + return get_turf(src) \ No newline at end of file