ID:2761293
 
world
fps = 30
view = 20

mob
icon = 'mob.dmi'
Login()
..()

turf
icon = 'turf.dmi'

var map/overworld = new(1)

map
var list/data
New(Z_LEVEL)
var x,y,mx=world.maxx,my=world.maxy
data = new/list(mx,my)
for(y = 1 to my)
for(x = 1 to mx)
data[x][y] = locate(x,y,Z_LEVEL)
proc
Ray(ANGLE,X,Y,MAX_STEPS)
var sx = sin(ANGLE), sy = cos(ANGLE)
var rx = X, ry = Y, max = data.len
var turf/turf, list/ret = new, object
for()
if(!MAX_STEPS){break}
MAX_STEPS--
if(rx >= max || 1 > rx){break}
if(ry >= max || 1 > ry){break}
turf = data[rx][ry]
ret += turf
for(object in turf.contents){ret+=object}
rx += sx
ry += sy
return ret

mob/verb/DEMO()
var list/l = overworld.Ray(rand(0,360),x,y,16) - src
world << "l.len = [l.len]"
for(var/o in l)
o:color="#F00"
spawn(3)
animate(o,color=null,time=6)


Created the demo above that lets you quickly send a ray across the map returning all the objects and turfs it encountered, it could be broken up into seperate procs or be given a BITFLAG to allow for what's needed.

I think having this type of thing built-in would be pretty epic, would be much easier and probably use correct math :D

It's super efficient too, able to send out thousands of rays a second with no hit to the cpu.
5000 rays all being sent at once didn't even cause the screen to freeze.



Averaged


Interesting concept, although I can see a lot of room for improvement, and there's a bug in the current implementation. For instance, you're not checking object bounds against the ray, but only adding them if they're in turf contents. You're also not checking if the object has already been added.

Another important thing is you're not actually doing full steps, but advancing only by sine and cosine. Since you can't use non-integer numerical indexes in a list, this code won't actually work with non-cardinal directions. What you need to be doing is stepping the line forward and watching where it crosses tile boundaries, then incrementing or decrementing rx/ry as needed.

I think you're right that ray-casting would be an excellent thing to do internally, though. The engine can do a lot of things under the hood to speed this process up. Additionally, it probably makes sense to have a way of casting a cone, or maybe having a way of getting all atoms within a convex polygon.
In response to Lummox JR
Having a built in way to grab atoms within a cone (a circle would be cool too) would be super cool