diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 805e6b8834f..8f301f17f01 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -83,6 +83,9 @@ if(opacity && isturf(loc)) var/turf/T = loc T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways. + + if(loc) + loc.InitializedOn(src) // Used for poolcontroller / pool to improve performance greatly. However it also open up path to other usage of observer pattern on turfs. ComponentInitialize() @@ -97,6 +100,8 @@ /atom/proc/ComponentInitialize() return +/atom/proc/InitializedOn(atom/A) // Proc for when something is initialized on a atom - Optional to call. Useful for observer pattern etc. + return /atom/proc/onCentcom() var/turf/T = get_turf(src) diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index 3d7f6a52e70..4fff66a43e7 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -11,18 +11,21 @@ icon_state = "airlock_control_standby" anchored = 1 //this is what I get for assuming /obj/machinery has anchored set to 1 by default var/list/linkedturfs = list() //List contains all of the linked pool turfs to this controller, assignment happens on New() + var/mobinpool = list() //List contains all of the mob in the pool, to prevent looping through the entire area to find mobs inside.. + var/decalinpool = list() // List containing all of the cleanable decals in pool var/linked_area = null var/temperature = NORMAL //The temperature of the pool, starts off on normal, which has no effects. var/temperaturecolor = "" //used for nanoUI fancyness var/srange = 5 //The range of the search for pool turfs, change this for bigger or smaller pools. var/list/linkedmist = list() //Used to keep track of created mist - var/deep_water = 0 //set to 1 to drown even standing people + var/deep_water = FALSE //set to 1 to drown even standing people /obj/machinery/poolcontroller/New() //This proc automatically happens on world start if(!linked_area) for(var/turf/simulated/floor/beach/water/W in range(srange,src)) //Search for /turf/simulated/floor/beach/water in the range of var/srange linkedturfs += W //Add found pool turfs to the central list. + W.linkedcontroller = src // And add the linked controller to itself. ..() //Changed to call parent as per MarkvA's recommendation /obj/machinery/poolcontroller/emag_act(user as mob) //Emag_act, this is called when it is hit with a cryptographic sequencer. @@ -48,21 +51,24 @@ ui_interact(user) /obj/machinery/poolcontroller/process() - updatePool() //Call the mob affecting/decal cleaning proc + processMob() //Call the mob affecting proc + cleanPool() //Call the decal cleaning proc -/obj/machinery/poolcontroller/proc/updatePool() - for(var/turf/T in linkedturfs) //Check for pool-turfs linked to the controller. - for(var/mob/M in T) //Check for mobs in the linked pool-turfs. - handleTemp(M) //handles pool temp effects on the swimmers +/obj/machinery/poolcontroller/proc/processMob() + for(var/M in mobinpool) //They're already typecasted when entering the turf + // Following two are sanity check. If the mob is no longer in the pool for whatever reason (Looking at you teleport), remove them + if(!istype(get_turf(M), /turf/simulated/floor/beach/water) && !istype(get_turf(M), /turf/unsimulated/beach/water)) // Water component when? + mobinpool -= M + continue + handleTemp(M) //handles pool temp effects on the swimmers + if(ishuman(M)) //Only human types will drown, to keep things simple for non-human mobs that live in the water + handleDrowning(M) - if(ishuman(M)) //Make sure they are human before typecasting. - var/mob/living/carbon/human/drownee = M //Typecast them as human. - handleDrowning(drownee) //Only human types will drown, to keep things simple for non-human mobs that live in the water - - for(var/obj/effect/decal/cleanable/decal in T) //Cleans up cleanable decals like blood and such +/obj/machinery/poolcontroller/proc/cleanPool() + for(var/obj/effect/decal/cleanable/decal in decalinpool) //Cleans up cleanable decals like blood and such + if(!QDELETED(decal)) animate(decal, alpha = 10, time = 20) - spawn(25) - qdel(decal) + QDEL_IN(decal, 25) /obj/machinery/poolcontroller/proc/handleTemp(var/mob/M) if(!M || isAIEye(M) || issilicon(M) || isobserver(M) || M.stat == DEAD) @@ -187,29 +193,17 @@ /obj/machinery/poolcontroller/seacontroller invisibility = 101 unacidable = 1 - name = "Sea Controller" desc = "A controller for the underwater portion of the sea. Players shouldn't see this." - deep_water = 1 //deep sea is deep water + deep_water = TRUE //deep sea is deep water -/obj/machinery/poolcontroller/seacontroller/New() +/obj/machinery/poolcontroller/seacontroller/Initialize() linked_area = get_area(src) + for(var/turf/unsimulated/beach/water/W in linked_area) + linkedturfs += W //Add found pool turfs to the central list. + W.linkedcontroller = src // And add the linked controller to itself. ..() -/obj/machinery/poolcontroller/seacontroller/updatePool() - for(var/turf/T in linked_area) - for(var/mob/M in T) - handleTemp(M) //handles pool temp effects on the swimmers - - if(ishuman(M)) //Make sure they are human before typecasting. - var/mob/living/carbon/human/drownee = M //Typecast them as human. - handleDrowning(drownee) //Only human types will drown, to keep things simple for non-human mobs that live in the water - - for(var/obj/effect/decal/cleanable/decal in T) - animate(decal, alpha = 10, time = 20) - spawn(25) - qdel(decal) - #undef FRIGID #undef COOL #undef NORMAL diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 39d4e19034c..6cfea0cb8f6 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -48,10 +48,11 @@ icon = 'icons/misc/beach2.dmi' icon_state = "sandwater" -/turf/simulated/floor/beach/water +/turf/simulated/floor/beach/water // TODO - Refactor water so they share the same parent type - Or alternatively component something like that name = "water" icon_state = "water" mouse_opacity = MOUSE_OPACITY_TRANSPARENT + var/obj/machinery/poolcontroller/linkedcontroller = null /turf/simulated/floor/beach/water/pry_tile(obj/item/C, mob/user, silent = FALSE) return //cannot pry off tiles of water @@ -61,6 +62,26 @@ ..() overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1) +/turf/simulated/floor/beach/water/Entered(atom/movable/AM, atom/OldLoc) + . = ..() + if(!linkedcontroller) + return + if(ismob(AM)) + linkedcontroller.mobinpool += AM + +/turf/simulated/floor/beach/water/Exited(atom/movable/AM, atom/newloc) + . = ..() + if(!linkedcontroller) + return + if(ismob(AM)) + linkedcontroller.mobinpool -= AM + +/turf/simulated/floor/beach/water/InitializedOn(atom/A) + if(!linkedcontroller) + return + if(istype(A, /obj/effect/decal/cleanable)) // Better a typecheck than looping through thousands of turfs everyday + linkedcontroller.decalinpool += A + /turf/simulated/floor/noslip name = "high-traction floor" icon_state = "noslip" diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm index aeea1e27659..b7c76359c46 100644 --- a/code/game/turfs/unsimulated/beach.dm +++ b/code/game/turfs/unsimulated/beach.dm @@ -35,6 +35,27 @@ name = "Shallow Water" icon_state = "seashallow" water_overlay_image = "water_shallow" + var/obj/machinery/poolcontroller/linkedcontroller = null + +/turf/unsimulated/beach/water/Entered(atom/movable/AM, atom/OldLoc) + . = ..() + if(!linkedcontroller) + return + if(ismob(AM)) + linkedcontroller.mobinpool += AM + +/turf/unsimulated/beach/water/Exited(atom/movable/AM, atom/newloc) + . = ..() + if(!linkedcontroller) + return + if(ismob(AM)) + linkedcontroller.mobinpool -= AM + +/turf/unsimulated/beach/water/InitializedOn(atom/A) + if(!linkedcontroller) + return + if(istype(A, /obj/effect/decal/cleanable)) // Better a typecheck than looping through thousands of turfs everyday + linkedcontroller.decalinpool += A /turf/unsimulated/beach/water/dense //for boundary "walls" density = 1