diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index 1311ca1589..bcdb1af8ed 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -1,14 +1,18 @@ SUBSYSTEM_DEF(mobs) name = "Mobs" priority = 100 - flags = SS_KEEP_TIMING|SS_NO_INIT + flags = SS_KEEP_TIMING runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() + var/static/list/clients_by_zlevel[][] /datum/controller/subsystem/mobs/stat_entry() ..("P:[GLOB.mob_living_list.len]") +/datum/controller/subsystem/mobs/Initialize(start_timeofday) + clients_by_zlevel = new /list(world.maxz,0) + return ..() /datum/controller/subsystem/mobs/fire(resumed = 0) var/seconds = wait * 0.1 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 4d7a417e53..3e0f0112ff 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -254,6 +254,12 @@ loc = destination if(!same_loc) + var/turf/oldturf = get_turf(oldloc) + var/turf/destturf = get_turf(destination) + var/old_z = (oldturf ? oldturf.z : null) + var/dest_z = (destturf ? destturf.z : null) + if (old_z != dest_z) + onTransitZ(old_z, dest_z) destination.Entered(src, oldloc) if(destarea && old_area != destarea) destarea.Entered(src, oldloc) @@ -276,6 +282,11 @@ old_area.Exited(src, null) loc = null +/atom/movable/proc/onTransitZ(old_z,new_z) + for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. + var/atom/movable/AM = item + AM.onTransitZ(old_z,new_z) + //Called whenever an object moves and by mobs when they attempt to move themselves through space //And when an object or action applies a force on src, see newtonian_move() below //Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 90b1327b9e..bfa89db368 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1190,6 +1190,9 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C refill_canister = /obj/item/vending_refill/games +/obj/machinery/vending/onTransitZ() + return + #undef STANDARD_CHARGE #undef CONTRABAND_CHARGE #undef COIN_CHARGE \ No newline at end of file diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 54c43cdcea..1d7b32e3a2 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -130,9 +130,12 @@ return if(destination_z) + var/old_z = A.z A.x = destination_x A.y = destination_y A.z = destination_z + if (old_z != destination_z) + A.onTransitZ(old_z, destination_z) if(isliving(A)) var/mob/living/L = A diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index 23d6bdba50..fe25dc9439 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -140,6 +140,9 @@ /atom/movable/lighting_object/blob_act() return +/atom/movable/lighting_object/onTransitZ() + return + // Override here to prevent things accidentally moving around overlays. /atom/movable/lighting_object/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE) if(harderforce) diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 4c772a7019..8e58da8e05 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -81,3 +81,6 @@ WD.add_fingerprint(user) dump_box_contents() qdel(src) + +/obj/structure/ore_box/onTransitZ() + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm index 35e83a8e04..9fd2cbf8de 100644 --- a/code/modules/mob/living/carbon/human/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive.dm @@ -828,7 +828,7 @@ return pick(/area/hallway, /area/crew_quarters/locker) /mob/living/carbon/human/interactive/proc/target_filter(target) - var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/light, /obj/structure/cable, /obj/machinery/atmospherics) + var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/lighting_object, /obj/structure/cable, /obj/machinery/atmospherics) var/list/L = target for(var/atom/A in target) // added a bunch of "junk" that clogs up the general find procs if(is_type_in_list(A,filtered_targets)) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 1f0895a7f5..0aafef753f 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -8,6 +8,18 @@ if((movement_type & FLYING) && !floating) //TODO: Better floating float(on = TRUE) + if (client || registered_z) // This is a temporary error tracker to make sure we've caught everything + var/turf/T = get_turf(src) + if (client && registered_z != T.z) +#ifdef TESTING + message_admins("[src] [ADMIN_FLW(src)] has somehow ended up in Z-level [T.z] despite being registered in Z-level [registered_z]. If you could ask them how that happened and notify coderbus, it would be appreciated.") +#endif + log_game("Z-TRACKING: [src] has somehow ended up in Z-level [T.z] despite being registered in Z-level [registered_z].") + update_z(T.z) + else if (!client && registered_z) + log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.") + update_z(null) + if (notransform) return if(!loc) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3ca234434c..f589ecbb20 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1039,4 +1039,19 @@ if(.) if(client) reset_perspective(destination) - update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. \ No newline at end of file + update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. + +/mob/living/proc/update_z(new_z) // 1+ to register, null to unregister + if (registered_z != new_z) + if (registered_z) + SSmobs.clients_by_zlevel[registered_z] -= src + if (client) + if (new_z) + SSmobs.clients_by_zlevel[new_z] += src + registered_z = new_z + else + registered_z = null + +/mob/living/onTransitZ(old_z,new_z) + ..() + update_z(new_z) \ No newline at end of file diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 3b5ae247df..50f2ce4db0 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -77,4 +77,6 @@ var/last_words //used for database logging - var/list/obj/effect/proc_holder/abilities = list() \ No newline at end of file + var/list/obj/effect/proc_holder/abilities = list() + + var/registered_z \ No newline at end of file diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 97ffa72aec..ffdd37bdca 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -13,6 +13,10 @@ update_damage_hud() update_health_hud() + if (loc) + var/turf/T = get_turf(src) + update_z(T.z) + //Vents if(ventcrawler) to_chat(src, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.") diff --git a/code/modules/mob/living/logout.dm b/code/modules/mob/living/logout.dm index a3479aac89..9b998b2d89 100644 --- a/code/modules/mob/living/logout.dm +++ b/code/modules/mob/living/logout.dm @@ -1,6 +1,14 @@ +<<<<<<< HEAD /mob/living/Logout() if(ranged_ability && client) ranged_ability.remove_mousepointer(client) ..() +======= +/mob/living/Logout() + update_z(null) + if(ranged_ability && client) + ranged_ability.remove_mousepointer(client) + ..() +>>>>>>> de51ac3... Player Z-tracking, again (#33216) if(!key && mind) //key and mind have become separated. mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body. \ No newline at end of file diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 15f0dbb011..c7a77f9457 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -89,15 +89,23 @@ All ShuttleMove procs go here return loc = newT + return TRUE // Called on atoms after everything has been moved /atom/movable/proc/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) + + var/turf/newT = get_turf(src) + if (newT.z != oldT.z) + onTransitZ(oldT.z, newT.z) + if(light) update_light() if(rotation) shuttleRotate(rotation) + + update_parallax_contents() return TRUE @@ -328,9 +336,6 @@ All ShuttleMove procs go here /atom/movable/lighting_object/onShuttleMove() return FALSE -/atom/movable/light/onShuttleMove() - return FALSE - /obj/docking_port/stationary/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) if(!moving_dock.can_move_docking_ports || old_dock == src) return FALSE