Optimized radio code broadcasting code.

Rather than calling a function on every single radio object which expensively collects hearers(in closets etc.), the proc will now instead build a list of radios. This list is then passed to another proc, which iterates through all clients in the world, and checks if the client's mob can hear the message.

Note that I did shallow testing, but deeper issues may still be present with stuff like pAIs which I wasn't able to test on my single player server. If any other problems are found, please notify me.


git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4019 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
CIB123@gmail.com
2012-07-09 15:16:00 +00:00
parent ae23259f3e
commit b687b75bca
7 changed files with 80 additions and 59 deletions

View File

@@ -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

View File

@@ -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 ###### */

View File

@@ -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)

View File

@@ -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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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)