This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
moomoomoo3O9's profile picture

Block Selection Using Immibis's Adventure Map Interface

Started by moomoomoo3O9, 20 January 2014 - 11:06 AM
moomoomoo3O9 #1
Posted 20 January 2014 - 12:06 PM
I saw Immibis's Adventure Map Interface, and I loved it. I wrote a few Worldedit-esque programs, some that emulated //removenear (which could be changed to replacenear by adding a variable), some that were used like //set using the adventure map interface, one that made flat bedrock and emptied the chunk within X radius…etc. (So I do know a decent amount about coding in CC, even if I didn't make an account here)

I want to make a program functionally similar to WorldEdit's normal cuboid selector (because the poly or spheroid selector is far beyond my ability) but I need to know how to use the normalized direction vector from a player (ent.getLooking(x, y, z) returns it) to find out what block the player is looking at. From what I understand, what needs to be done is:

1) Extend out the vector linearly. (This is where I have a problem!)
2) Detect all blocks within that line. (This is trivial if I can get the co-ords)
3) If the line hits a block, end it (break or return)

So, does anyone with more knowledge than me about vectors know how that would be written?

(And if anyone wants to help me in programming this, I would love to see how someone who's a better coder than me could do it)
Edited on 20 January 2014 - 11:31 AM
moomoomoo3O9 #2
Posted 25 January 2014 - 12:45 PM
I figured it out, so in case anyone wants to do something similar, I'll post the code here!
Code

tArgs={...}
username=tArgs[1]
--the only argument should be the username of the player.
for k,v in pairs(peripheral.getNames()) do
if peripheral.getType(v)=="adventure map interface" then
  p=peripheral.wrap(v)
end
end
--fancy way of wrapping the adventure map interface no matter what side it's on
pl=p.getPlayerByName(username)
ent=pl.asEntity()
px,py,pz=ent.getPosition()
x,y,z=ent.getLooking()
--define the player and get the direction he's looking in and his location
py=py+1.62
--the player's eyes are 1.62 blocks above his feet
mult=0
--multiplier to extend out the line from ent.getLooking()
iteration=0
--this will prevent a too long without yielding error
while true do
iteration=iteration+1
if iteration==100000 then
  break
end
fx=math.floor(x*mult+px)
fy=math.floor(y*mult+py)
fz=math.floor(z*mult+pz)
if w.getBlockID(fx,fy,fz)~=0 then
  break
--add the line's coordinates and multiply the original direction by the multiplier until it hits a block, then stop
else
  mult=mult+0.005
--add .005 to it until it hits the block (this could be raised/lowered, but 0.005 doesn't take too many iterations)
end
end
print("x="..x*mult+px)
print("y="..y*mult+py)
print("z="..z*mult+pz)
--prints out the coordinates
surferpup #3
Posted 26 January 2014 - 11:52 AM
Just a note on this section of your code:


--this will prevent a too long without yielding error
iteration=iteration+1
if iteration==100000 then
  break
end

You could have replaced that entire block with:

sleep(0)

The sleep(0) will also prevent a too long without yielding, as any call to sleep yields, if even for just a split second.
Edited on 26 January 2014 - 10:53 AM
moomoomoo3O9 #4
Posted 27 January 2014 - 03:55 PM
Just a note on this section of your code:


--this will prevent a too long without yielding error
iteration=iteration+1
if iteration==100000 then
  break
end

You could have replaced that entire block with:

sleep(0)

The sleep(0) will also prevent a too long without yielding, as any call to sleep yields, if even for just a split second.
Actually, that code shouldn't occur at all if the code is working correctly, it's so your computer doesn't pointlessly calculate to find a block that doesn't exist. (I.E. The player is looking into the sky)
surferpup #5
Posted 27 January 2014 - 04:30 PM
Actually, that code shouldn't occur at all if the code is working correctly, it's so your computer doesn't pointlessly calculate to find a block that doesn't exist. (I.E. The player is looking into the sky)

According to the comment in the code I was referring to, the intent of the coder was to figure out how to avoid going too long without yielding. The iteration loop can easily be replaced with a sleep(0) if you are concerned about going too long without yielding rather than what was used. There are, of course, far better ways of dealing with yielding issues, I was commenting on the one chosen.
Edited on 27 January 2014 - 03:33 PM
moomoomoo3O9 #6
Posted 27 January 2014 - 05:13 PM
Actually, that code shouldn't occur at all if the code is working correctly, it's so your computer doesn't pointlessly calculate to find a block that doesn't exist. (I.E. The player is looking into the sky)

According to the comment in the code I was referring to, the intent of the coder was to figure out how to avoid going too long without yielding. The iteration loop can easily be replaced with a sleep(0) if you are concerned about going too long without yielding rather than what was used. There are, of course, far better ways of dealing with yielding issues, I was commenting on the one chosen.
Ah I see, sorry for being unclear.