ID:162212
 
//get the turf something is eventually on (or null if none)
proc/getturf(var/atom/movable/A)
while(A && istype(A))
A = A.loc
if(isturf(A))
return A
return null

proc/isblocked(var/turf/start, var/turf/end)
start = getturf(start)
end = getturf(end)
if(!start || !end || start.z != end.z) return 0
var/dx = end.x - start.x
//special case: vertical alignment
if(dx == 0)
for(var/turf/T in block(start,end))
if(T.density)
return 1
return 0

var/dy = end.y - start.y
var/ratio = dy / dx
world << ratio
var/x = start.x
var/y = start.y
var/z = start.z
var/count = 0
var/turf/curturf
do
curturf = locate(x,y,z)
if(curturf.density) return 1
if(count < 1)
count += ratio
x++
else
y++
count--
while(curturf && curturf != end)
return 0


Because nobody else seems to know how to do this. Note that this is only one possible implementation, it does not give exactly the results that you have described. For example, in your example, it would not consider the northmost green tile to be unblocked.

This does, however, have the benefit of being quite fast. You probably don't want to try using it to generate a map of locations you can and can't teleport to, however. But, for determining whether the path between two turfs is unblocked, it works great.
~I'm replying here to the other thread too by the way.
Wow.
WOW.
Didn't expect such a great response from everyone. Thanks, and glad I asked. :)

Jtgibson, thanks for your suggestion of using opacity. I was actually thinking something like that might be a way to go. I'll definitely look into it.

Thanks to all who tried to help, whether they initially understood it or not :P I could have written the question clearer. Sorry.

And Garthor, I want to be one of your "fans". o_o
Thanks for spoon feeding me all the time. :)
It took me about 7 minutes but I think I understand it now.

*tear* I promised myself I wouldn't cry!

Cheers.
I've decided to go with Jtgibsons idea.
turf/DblClick()
for(var/turf/T in orange(src,12)) if(T.density) T.opacity=1
if(src in oview(12,usr)) usr.Move(src)
for(var/turf/t in orange(src,12)) if(t.density) t.opacity=initial(t.opacity)

I can get my head around this and it does precisely what I need.

Sorry for your hard work going to waste. :\
In response to Saucepan Man (#2)
Saucepan Man wrote:

From what I gather I'm supposed to use isblocked(usr,src) instead of usr.Move(src)
under turf/DblClick().

In the snippet of code that was provided, the isblocked() proc takes 2 turf atoms, but what you pass it is a mob(usr defaults to a /mob) and a turf(src), so in the end, what you should use is
isblocked(usr.loc,src)
as they should be both turfs, but a little error checking on the usr.loc, to make sure that the location of the usr is indeed a turf, is never a bad idea.
In response to Hassifa (#3)
Yeah i tried that first actually. Also doesn't work.
Its not getting past getturf() because end turfs and movable.
Even when I remove flags for that, it doesn't complete isblocked(). it displays the ratio on the screen, but about it.

:\
In response to Saucepan Man (#4)
oh DUH. I made indentation errors.
I feel dumb now.

Got it working, except it pretty much only ever allows NorthEast...
It also seems to ignore if there's a dens building in the way etc..
turf/DblClick()
if(!isblocked(usr.loc,src))
usr.Move(src)


It seems to work fine when there arent many dense things around. But as soon as there are, I cant even teleport to a non-dense space in front of me. :S
In response to Saucepan Man (#5)
Oopsies. That would be a result of me not thoroughly testing my code. I made the mistake of assuming dx and dy would be positive. Therefore, it would only work with tiles in the first quadrant (generally to the northeast). I fixed that, here:

proc/getturf(var/atom/movable/A)
while(A && istype(A))
A = A.loc
if(isturf(A))
return A
return null

proc/isblocked(var/turf/start, var/turf/end)
start = getturf(start)
end = getturf(end)
if(!start || !end || start.z != end.z) return 0
var/dx = end.x - start.x
//special case: vertical alignment
if(dx == 0)
for(var/turf/T in block(start,end))
if(T.density)
return 1
return 0

var/dy = end.y - start.y
var/ratio = abs(dy / dx)
var/x = start.x
var/y = start.y
var/z = start.z
var/count = 0
var/turf/curturf
var/xstep = dx>0?1:-1
var/ystep = dy>0?1:-1
do
curturf = locate(x,y,z)
if(curturf.density) return 1
if(count < 1)
count += ratio
x += xstep
else
y += ystep
count--
while(curturf && curturf != end)
return 0


That's what happens when I write code so damn late. I also leave in little debugging lines of code such as world<<ratio.
In response to Garthor (#6)
I like that you put that in. Made me realise it preferred positive numbers. Didn't know how to deal with it though cause Im a spoon. :O
Thanks.

Seriously, I want to be in a Garthor Fan Club