ID:2473054
 
(See the best response by Nadrew.)
Code:
    FLOOR

icon = 'floor.dmi'
layer = TURF_LAYER

DIGITAL_VOID
icon_state = "VOID"

Entered(mob/M as mob)

..()
if(!ismob(M)) return
if(!M.client) return

var/filter_outline = 0

if(M.filters.len && M.filter_obj.len)
for(var/obj/filter/drop_shadow/digital_white_outline/F in M.filter_obj)
filter_outline = 1

if(!filter_outline)
M.filter_obj += new /obj/filter/drop_shadow/digital_white_outline
for(var/obj/filter/drop_shadow/digital_white_outline/F in M.filter_obj)
world << "DEBUG: Applying Digital Outline Filter"
M.filters += F.filters

return

Exited(mob/M as mob)

..()
if(!ismob(M)) return
if(!M.client) return

if(!istype(M.loc, /turf/FLOOR/DIGITAL_VOID))

if(M.filters.len && M.filter_obj)

var/ii = 0

while(ii < M.filter_obj.len)
ii++

var/obj/filter/X

if(M.filter_obj[ii])
X = M.filter_obj[ii]
if(istype(X,/obj/filter/drop_shadow/digital_white_outline))
world << "DEBUG: Removing Digital Outline Filter"
M.filter_obj -= X
M.filters -= M.filters[ii]

return


Problem description:

So I'm trying to work with filters for the first time and this problem really hasn't come up before.

This code is for this area here... https://i.imgur.com/mzs3Gzu.png

So when the player enters the area, they get a white drop_shadow filter applied to them which gives them a small white outline.

And when they leave the area, it removes that outline.

In my Exited() proc there, I use the ...
if(!istype(M.loc, /turf/FLOOR/DIGITAL_VOID))


To confirm that the player has not just stepped from 1 tile to another in the area.

But I've noticed a problem. In locations in the area where I have have multiple turfs overlapping, that line gets triggered.

So eventhough there is a DIGITAL_VOID turf at that location, because there is another turf like lets say... DIGITAL_PATH at the same coordinate, it triggers the exited proc and removes the glow.

Is there a better way to go about checking the turf at the mob's location than this that would prevent this from happening?
Best response
There cannot be two turfs at the same location, that's not how it works. When you place one turf on top of another in the map editor it simply replaces one with the other and if there are transparent parts on the new one, it'll add the old one as a visual underlay.

However, you don't actually need to be using the turf/Entered() and Exited() procs here, you actually want area/Entered() and Exited().

/area types can cover large regions of your map and contain many turfs, when using Enter()/Entered() and Exit()/Exited() it'll only trigger once, and not for every tile within said area.

area/myregion
Entered(mob/M)
if(ismob(M) && M.client)
M << "You entered the region!"
return ..()
Exited(mob/M)
if(ismob(M) && M.client)
M << "You left the region!"
return ..()


Now if you cover a swath of your map with this area you'll see that message only when entering and exiting the region.
In response to Nadrew
Nadrew wrote:
if there are transparent parts on the new one, it'll add the old one as a visual underlay.

Wow. I had no idea it processed the turfs like that.

I guess I'll need to use areas then. Simple enough I suppose.