[READY] playsound performance (#40045)

tl;dr: we have lists of playermobs on the z-level, which generally have fewer player mobs to iterate through. If we use them, we can get rid of the z-level checks too. On the off-chance that something plays a sound in nullspace, we can skip pretty much everything. The client-check can go too, there are no playermobs without a client.
This commit is contained in:
vuonojenmustaturska
2018-09-08 13:27:01 +12:00
committed by oranges
parent 3585ff1560
commit f2ed477232
8 changed files with 53 additions and 14 deletions
+4
View File
@@ -6,6 +6,7 @@ SUBSYSTEM_DEF(mobs)
var/list/currentrun = list()
var/static/list/clients_by_zlevel[][]
var/static/list/dead_players_by_zlevel[][] = list(list()) // Needs to support zlevel 1 here, MaxZChanged only happens when z2 is created and new_players can login before that.
var/static/list/cubemonkeys = list()
/datum/controller/subsystem/mobs/stat_entry()
@@ -14,9 +15,12 @@ SUBSYSTEM_DEF(mobs)
/datum/controller/subsystem/mobs/proc/MaxZChanged()
if (!islist(clients_by_zlevel))
clients_by_zlevel = new /list(world.maxz,0)
dead_players_by_zlevel = new /list(world.maxz,0)
while (clients_by_zlevel.len < world.maxz)
clients_by_zlevel.len++
clients_by_zlevel[clients_by_zlevel.len] = list()
dead_players_by_zlevel.len++
dead_players_by_zlevel[dead_players_by_zlevel.len] = list()
/datum/controller/subsystem/mobs/fire(resumed = 0)
var/seconds = wait * 0.1
+11 -10
View File
@@ -5,26 +5,27 @@
var/turf/turf_source = get_turf(source)
if (!turf_source)
return
//allocate a channel if necessary now so its the same for everyone
channel = channel || open_sound_channel()
// Looping through the player list has the added bonus of working for mobs inside containers
var/sound/S = sound(get_sfx(soundin))
var/maxdistance = (world.view + extrarange)
var/list/listeners = GLOB.player_list
var/z = turf_source.z
var/list/listeners = SSmobs.clients_by_zlevel[z]
if(!ignore_walls) //these sounds don't carry through walls
listeners = listeners & hearers(maxdistance,turf_source)
for(var/P in listeners)
var/mob/M = P
if(!M || !M.client)
continue
var/distance = get_dist(M, turf_source)
if(distance <= maxdistance)
var/turf/T = get_turf(M)
if(T && T.z == turf_source.z)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S)
if(get_dist(M, turf_source) <= maxdistance)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S)
for(var/P in SSmobs.dead_players_by_zlevel[z])
var/mob/M = P
if(get_dist(M, turf_source) <= maxdistance)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S)
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, channel = 0, pressure_affected = TRUE, sound/S)
if(!client || !can_hear())
+2 -3
View File
@@ -66,9 +66,8 @@
if(src.mob)
var/mob/A = src.mob
A.x = tx
A.y = ty
A.z = tz
var/turf/T = locate(tx,ty,tz)
A.forceMove(T)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Coordiate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
+29
View File
@@ -30,6 +30,10 @@ INITIALIZE_IMMEDIATE(/mob/dead)
return
/mob/dead/forceMove(atom/destination)
var/turf/old_turf = get_turf(src)
var/turf/new_turf = get_turf(destination)
if (old_turf?.z != new_turf?.z)
onTransitZ(old_turf?.z, new_turf?.z)
loc = destination
/mob/dead/Stat()
@@ -93,3 +97,28 @@ INITIALIZE_IMMEDIATE(/mob/dead)
winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources
C << link("[addr]?server_hop=[key]")
/mob/dead/proc/update_z(new_z) // 1+ to register, null to unregister
if (registered_z != new_z)
if (registered_z)
SSmobs.dead_players_by_zlevel[registered_z] -= src
if (client)
if (new_z)
SSmobs.dead_players_by_zlevel[new_z] += src
registered_z = new_z
else
registered_z = null
/mob/dead/Login()
. = ..()
var/turf/T = get_turf(src)
if (isturf(T))
update_z(T.z)
/mob/dead/Logout()
update_z(null)
return ..()
/mob/dead/onTransitZ(old_z,new_z)
..()
update_z(new_z)
+4
View File
@@ -12,5 +12,9 @@
preferred_form = client.prefs.ghost_form
ghost_orbit = client.prefs.ghost_orbit
var/turf/T = get_turf(src)
if (isturf(T))
update_z(T.z)
update_icon(preferred_form)
updateghostimages()
+1
View File
@@ -1,4 +1,5 @@
/mob/dead/observer/Logout()
update_z(null)
if (client)
client.images -= (GLOB.ghost_images_default+GLOB.ghost_images_simple)
@@ -102,7 +102,6 @@
var/list/obj/effect/proc_holder/abilities = list()
var/registered_z
var/can_be_held = FALSE //whether this can be picked up and held.
var/radiation = 0 //If the mob is irradiated.
+2
View File
@@ -108,3 +108,5 @@
var/list/mousemove_intercept_objects
var/datum/click_intercept
var/registered_z