Added recursive_mob_check() proc. It will recursively loop through an atom's contents and check for mobs, then it will loop through every atom in that atom's contents. It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects, being unable to hear people due to being in a box within a bag.

I then changed the get_mobs_in_view() to use this proc for gathering mobs and radios. 

The old system would loop through lists for a total of 5000 per function call, in an empty server. This new system will loop at around 1000 in an empty server.

I made get_mobs_in_radio_ranges() use a level parameter to help make it more effecient by only bothering with the mobs that are in the Z level that are getting the radio message.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4365 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
giacomand@gmail.com
2012-08-11 07:08:58 +00:00
parent 7dad6191e3
commit d5b3b537bf
2 changed files with 38 additions and 104 deletions
+37 -103
View File
@@ -119,116 +119,51 @@
//var/debug_mob = 0
// Will recursively loop through an atom's contents and check for mobs, then it will loop through every atom in that atom's contents.
// It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects,
// being unable to hear people due to being in a box within a bag.
/proc/recursive_mob_check(var/atom/O, var/list/L = list(), var/client_check = 1, var/sight_check = 1, var/include_radio = 1)
//debug_mob += O.contents.len
for(var/atom/A in O)
if(ismob(A))
var/mob/M = A
if(client_check && !M.client)
L = recursive_mob_check(A, L)
continue
if(sight_check && !isInSight(A, O))
continue
L += M
else if(include_radio && istype(A, /obj/item/device/radio))
if(sight_check && isInSight(A, O))
L += A
L = recursive_mob_check(A, L)
return L
// The old system would loop through lists for a total of 5000 per function call, in an empty server.
// This new system will loop at around 1000 in an empty server.
/proc/get_mobs_in_view(var/R, var/atom/source)
// 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 = hearers(R, T)
var/list/V = range(R, T)
// Search for closets:
for(var/obj/structure/closet/C in V)
for(var/mob/M in C.contents)
if(isInSight(source,C))
if(M.client)
hear += M
// Search for Mulebots. A person might be riding in it's load.
for(var/obj/machinery/bot/mulebot/C in V)
if(C.load && ismob(C.load))
if(isInSight(source,C))
var/mob/M = C.load
if(M.client)
hear += M
// Cryos:
for(var/obj/machinery/atmospherics/unary/cryo_cell/C in V)
if(C.occupant)
if(isInSight(source,C))
if(C.occupant.client)
hear += C.occupant
// Intelicards
for(var/obj/item/device/aicard/C in V)
for(var/mob/living/silicon/ai/M in C)
if(isInSight(source,C))
if(M.client)
hear += M
// Kind of a hacky fix, but should fix most cases without undo issues.
for(var/mob/M as mob in V)
for(var/obj/item/device/aicard/C in M.contents)
for(var/mob/living/silicon/ai/A in C)
if(isInSight(source,A))
if(A.client)
hear += A
// Soulstones
for(var/obj/item/device/soulstone/C in V)
for(var/mob/living/simple_animal/shade/M in C)
if(isInSight(source,C))
if(M.client)
hear += M
// Kind of a hacky fix, but should fix most cases without undo issues.
for(var/mob/M as mob in V)
for(var/obj/item/device/soulstone/C in M.contents)
for(var/mob/living/simple_animal/shade/A in C)
if(isInSight(source,A))
if(A.client)
hear += A
// Brains/MMIs/pAIs
for(var/mob/living/carbon/brain/C in player_list)
if(get_turf(C) in V)
if(isInSight(source,C))
hear += C
for(var/mob/living/silicon/pai/C in player_list)
if(get_turf(C) in V)
if(isInSight(source,C))
hear += C
/* -- Handled above. WHY IS THIS HERE? WHYYYYYYY
// Personal AIs
for(var/obj/item/device/paicard/C in V)
if(C.pai)
if(isInSight(source,C))
if(C.pai.client)
hear += C.pai
*/
// Exosuits
for(var/obj/mecha/C in V)
if(C.occupant)
if(isInSight(source,C))
if(C.occupant.client)
hear += C.occupant
// Disposal Machines
for(var/obj/machinery/disposal/C in V)
for(var/mob/M in C.contents)
if(isInSight(source,C))
if(M.client)
hear += M
//Borg rechargers
for(var/obj/machinery/recharge_station/C in V)
if(C.occupant)
if(isInSight(source,C))
if(C.occupant.client)
hear += C.occupant
for(var/obj/item/device/radio/theradio in V)
if(isInSight(source,theradio))
hear += theradio
var/list/hear = list()
var/list/range = range(R, T)
//debug_mob += range.len
for(var/turf/A in range)
hear += recursive_mob_check(A)
//world.log << "NEW: [debug_mob]"
//debug_mob = 0
return hear
/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios)
/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios, var/level = 0)
. = list()
// Returns a list of mobs who can hear any of the radios given in @radios
@@ -242,13 +177,12 @@
// Try to find all the players who can hear the message
for(var/mob/M in player_list)
var/turf/ear = get_turf(M)
if(ear)
if(isnull(level) || level == ear.z)
if(ear in speaker_coverage)
. += M
return .
#define SIGN(X) ((X<0)?-1:1)
proc
+1 -1
View File
@@ -255,7 +255,7 @@ var/list/recentmessages = list() // global list of recent messages broadcasted :
radios += R
// Get a list of mobs who can hear from the radios we collected.
var/list/receive = get_mobs_in_radio_ranges(radios)
var/list/receive = get_mobs_in_radio_ranges(radios, level)
/* ###### Organize the receivers into categories for displaying the message ###### */