diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index 428819f8972..56cdf2fa03e 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -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 diff --git a/code/game/sound.dm b/code/game/sound.dm index 6bd53aba7ab..b63d23c3846 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -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()) diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index 6dcd4e98ca2..d3631f24d03 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -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]") diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 70380a8d554..67d20923ca9 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -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) diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index 1ada14b84be..e23021e9146 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -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() diff --git a/code/modules/mob/dead/observer/logout.dm b/code/modules/mob/dead/observer/logout.dm index a941a4beaad..41e2035d617 100644 --- a/code/modules/mob/dead/observer/logout.dm +++ b/code/modules/mob/dead/observer/logout.dm @@ -1,4 +1,5 @@ /mob/dead/observer/Logout() + update_z(null) if (client) client.images -= (GLOB.ghost_images_default+GLOB.ghost_images_simple) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 309e9d9fe42..0ba5b4c56de 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -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. diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 24eeac3d21b..298fee46cdc 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -108,3 +108,5 @@ var/list/mousemove_intercept_objects var/datum/click_intercept + + var/registered_z