ID:2007448
 
Resolved
locate(/obj) in area did not work correctly in many cases.
BYOND Version:509
Operating System:Linux
Web Browser:Chrome 47.0.2526.106
Applies to:Dream Daemon
Status: Resolved (509.1319)

This issue has been resolved.
Descriptive Problem Summary:
locate() in area does not work, returning null

Numbered Steps to Reproduce Problem:
1. attempt to use locate() to find an object in an area
2. receive null

Code Snippet (if applicable) to Reproduce Problem:
/world
maxx = 20
maxy = 20

/world/New()
var/obj/find = new /obj(locate(1,1,1))

var/obj/locatefind1 = locate(/obj) in world
var/obj/locatefind2 = locate(/obj) in find.loc.loc // area
var/obj/locatefind3 = locate(/obj) in find.loc // turf

world.log << "Search object: [find]|[find.type]|\ref[find]"
world.log << "Found object 1: [locatefind1]|[locatefind1 ? locatefind1.type : "*null*"]|\ref[locatefind1]"
world.log << "Found object 2: [locatefind2]|[locatefind2 ? locatefind2.type : "*null*"]|\ref[locatefind2]"
world.log << "Found object 3: [locatefind3]|[locatefind3 ? locatefind3.type : "*null*"]|\ref[locatefind3]"
del(src)


Expected Results:

Search object: the obj|/obj|[ref]
Found object 1: the obj|/obj|[ref]
Found object 2: the obj|/obj|[ref]
Found object 3: the obj|/obj|[ref]


Actual Results:

Search object: the obj|/obj|[0x2000000]
Found object 1: the obj|/obj|[0x2000000]
Found object 2: |*null*|[0x0]
Found object 3: the obj|/obj|[0x2000000]


Does the problem occur:
Every time? Or how often?Every time
In other games? N/A
In other user accounts? Unknown
On other computers? Unknown

When does the problem NOT occur? Unknown

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked?
Working in 509.1305 and earlier
Broken in 509.1306 and on

Workarounds: loop over turfs in the area?

Iterating over the objects in the area works correctly; the following consistently finds the object across all tested versions, including 1305, 1306, and 1318.
for(var/obj/O in find.loc.loc)
world.log << "iteration found [O]|[O.type]|\ref[O]"
Descriptive Problem Summary:
Given area instance A, locate(/obj) in A will return null regardless of whether or not an object is in this area. This only applies to /obj and its subtypes (possibly /mob, did not test), locate(/turf) in area still functions as intended.

Previously, locate(/obj) in A returned an instance of an object if there was one in the area.

Interestingly, the object is present in A.contents.

Numbered Steps to Reproduce Problem:
1. Take the instance of any area (A)
2. Attempt to locate an object subtype in it.
3. Receive null.

Code Snippet (if applicable) to Reproduce Problem:
/area/myArea
name = "my area"

/mob/verb/find_that_object()
var/area/A = locate(/area/myArea) in world
if (A)
var/obj/O = locate() in A
world << "Found object ([O.name])" // runtime error: cannot read null.name


Expected Results:
O should not be null if an obj is in A area.

Actual Results:
O is null.

Does the problem occur:
Yes.

When does the problem NOT occur?
No.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked?
Code was originally written for (and worked in) 507. Did not test with 508.

Workarounds:
A less efficient option is still available, by replacing the locate() with:
var/obj/O = null
for (var/obj/temp in A)
O = temp
break

In response to Marquesas
Aaaand this is a duplicate. Great.
In response to Marquesas
The version that this was introduced in is the same version http://www.byond.com/forum/?post=1860571 was fixed in.

Reading back through that report, Lummox's "fixed" results show it finding null:

locate at 1,1,1 took 0 ds (found )
proc_locate at 1,1,1 took 0 ds (found the find)
locate at 50,1,1 took 0 ds (found )
proc_locate at 50,1,1 took 0 ds (found the find)
locate at 1,50,1 took 0 ds (found )
proc_locate at 1,50,1 took 0 ds (found the find)
locate at 50,50,1 took 0 ds (found )
proc_locate at 50,50,1 took 0 ds (found the find)
locate at 1,1,1 took 0 ds (found )
proc_locate at 1,1,1 took 0 ds (found the find)
locate at 50,1,1 took 0 ds (found )
proc_locate at 50,1,1 took 0 ds (found the find)
locate at 1,50,1 took 0 ds (found )
proc_locate at 1,50,1 took 0 ds (found the find)
locate at 50,50,1 took 0 ds (found )
proc_locate at 50,50,1 took 0 ds (found the find)
I did some testing and the only time it found anything was if I searched for the types /atom and /turf. /atom/movable failed to return anything, as did /mob and /obj.

With this in mind, I believe that it's only checking index 1 of the container's contents if the container is an area.
You can't place two turfs on the same tile, one will be absorbed by the other as an underlay/overlay.
Found the issue. I'll mark this fixed once I decide which version it's going in.
Lummox JR resolved issue with message:
locate(/obj) in area did not work correctly in many cases.