Вы находитесь на странице: 1из 14

local local local local local local

LOC = {} LOC_F = "wti/loc.wti" WRLD = {} WRLD_F = "wti/wrld.wti" UPD = {} UPD_F = "wti/upd.wti"

function load() local f = io.open(LOC_F, "r") if (not f) then print("Location not set! Initializing...") initLoc() else LOC = textutils.unserialize(f:read("*a")) f:close() end f = io.open(WRLD_F, "r") if (not f) then print("World data not initialized! Initializing...") f = io.open(WRLD_F, "w") f:write(textutils.serialize({})) f:close() else local wrldStr = f:read("*a") WRLD = textutils.unserialize(wrldStr) f:close() end f = io.open(UPD_F, "r") if (not f) then print("Update file not initialized! Initializing...") f = io.open(UPD_F, "w") f:write(textutils.serialize({})) f:close() else local updStr = f:read("*a") UPD = textutils.unserialize(updStr) f:close() end end function initLoc(sx, sy, sz, sd, soy) sx = sx or 0 sy = sy or 0 sz = sz or 0 sd = sd or 1 soy = soy or 1 LOC.x = sx LOC.y = sy LOC.z = sz LOC.dir = sd LOC.onY = soy saveLoc() end function saveLoc() local f = io.open(LOC_F, "w") if (not f) then print("Can't open file to save location!") else

f:write(textutils.serialize(LOC)) f:close() end end function saveUpd() local f = io.open(UPD_F, "w") if (not f) then print("Can't open file to save update data!") else f:write(textutils.serialize(UPD)) f:close() end end function saveWrld() local f = io.open(WRLD_F, "w") if (not f) then print("Unable to open world data file for saving!") else f:write(textutils.serialize(WRLD)) f:close() end end function checkFuel() if (turtle.getFuelLevel == 0) then print("OUT OF FUEL") while (os.pullEvent() or turtle.getFuelLevel > 0) do sleep(1) end end end function up(dist, bDig) dist = dist or 1 bDig = bDig or false if (dist < 0) then return down(math.abs(dist), bDig) end for i=1,dist do if (not turtle.up()) then if (not (bDig and digUp() and turtle.up())) then saveLoc() detectUp() return false else LOC.z = LOC.z + 1 end else LOC.z = LOC.z + 1 end end saveLoc() return true end function down(dist, bDig) dist = dist or 1 bDig = bDig or false if (dist < 0) then return up(math.abs(dist), bDig)

end for i=1,dist do if (not turtle.down()) then if (not (bDig and digDown() and turtle.down())) then saveLoc() detectDown() return false else LOC.z = LOC.z - 1 end else LOC.z = LOC.z - 1 end end saveLoc() return true end function forward(dist, bDig) dist = dist or 1 bDig = bDig or false if (dist < 0) then return back(math.abs(dist), bDig) end for i=1,dist do if (not turtle.forward()) then if (not (bDig and dig() and turtle.forward())) then saveLoc() detect() return false elseif (LOC.onY == 1) then LOC.y = LOC.y + LOC.dir else LOC.x = LOC.x + LOC.dir end elseif (LOC.onY == 1) then LOC.y = LOC.y + LOC.dir else LOC.x = LOC.x + LOC.dir end end saveLoc() return true end function back(dist, bDig) dist = dist or 1 bDig = bDig or false if (dist < 0) then return forward(math.abs(dist), bDig) end for i=1,dist do if (not turtle.back()) then if (not bDig) then saveLoc() tRight(2) detect() tRight(2) return false elseif (not (tRight(2) and dig() and turtle.forward() and tRight(2))) then saveLoc()

detect() tRight(2) return false elseif (LOC.onY == 1) then LOC.y = LOC.y - LOC.dir else LOC.x = LOC.x - LOC.dir end elseif (LOC.onY == 1) then LOC.y = LOC.y - LOC.dir --change else LOC.x = LOC.x - LOC.dir end end saveLoc() return true end function goLeft(dist, bDig) dist = dist or 1 bDig = bDig or false if (dist < 0) then return goRight(math.abs(dist), bDig) end tLeft() if (not forward(dist, bDig)) then tRight() return false else tRight() return true end end function goRight(dist, bDig) dist = dist or 1 bDig = bDig or false if (dist < 0) then return goLeft(math.abs(dist), bDig) end tRight() if (not forward(dist, bDig)) then tLeft() return false else tLeft() return true end end function tLeft(num) num = num or 1 for i=1,num do if (turtle.turnLeft()) then if (LOC.onY == 1) then LOC.dir = -1 * LOC.dir end LOC.onY = 1 - LOC.onY else return false end end saveLoc()

return true end function tRight(num) num = num or 1 for i=1,num do if (turtle.turnRight()) then if (LOC.onY == 0) then LOC.dir = -1 * LOC.dir end LOC.onY = 1 - LOC.onY else return false end end saveLoc() return true end function setUpd(x, y, z, val) if (not UPD[x]) then UPD[x] = {} end if (not UPD[x][y]) then UPD[x][y] = {} end UPD[x][y][z] = val saveUpd() end function setWrld(x, y, z, val) if (not WRLD[x]) then WRLD[x] = {} end if (not WRLD[x][y]) then WRLD[x][y] = {} end if (WRLD[x][y][z] == nil) then WRLD[x][y][z] = val elseif (WRLD[x][y][z] ~= val) then setUpd(x, y, z, val) WRLD[x][y][z] = val end saveWrld() end function detect() local ret = turtle.detect() local sx = LOC.x + ((1-LOC.onY)*LOC.dir) local sy = LOC.y + (LOC.onY*LOC.dir) local sz = LOC.z setWrld(sx, sy, sz, ret) return ret end function detectUp() local ret = turtle.detectUp() local sx = LOC.x local sy = LOC.y local sz = LOC.z + 1 setWrld(sx, sy, sz, ret) return ret end function detectDown() local ret = turtle.detectDown()

local sx = LOC.x local sy = LOC.y local sz = LOC.z - 1 setWrld(sx, sy, sz, ret) return ret end function dig() for i=1,20 do if (not detect()) then return true elseif (not turtle.dig()) then return false else sleep(0.4) end end return true end function digUp() for i=1,10 do if (not detectUp()) then return true elseif (not turtle.digUp()) then return false else sleep(0.4) end end return true end function digDown() for i=1,10 do if (not detectDown()) then return true elseif (not turtle.digDown()) then return false else sleep(0.4) end end return true end function digFromCorner(x, y, z) if (y < 0) then tRight(2) x = -1 * x end local vertDig = nil local vertMove = nil if (z > 0) then vertDig = digUp vertMove = up else vertDig = digDown vertMove = down end local turn = nil local oppTurn = nil if (x > 0) then turn = tRight

oppTurn = tLeft else turn = tLeft oppTurn = tRight end x = math.abs(x) y = math.abs(y) z = math.abs(z) for i=0,z do for j=0,x do for k=1,y do if (not dig()) then return false --Eventually handle? else if (not forward()) then return false end end end if(j ~= x) then turn() if (not dig()) then return false else if (not forward()) then return false else turn() end end local tmp = turn turn = oppTurn oppTurn = tmp end end if (i ~= z) then if (not vertDig()) then return false else if (not vertMove()) then return false else turn(2) end end end end return true end function isBlocked(x,y,z) if (not WRLD[x]) then return nil end if (not WRLD[x][y]) then return nil else return WRLD[x][y][z]

end end function goTo(x,y,z,bDig) bDig = bDig or false local dx = tonumber(x)-LOC.x local dy = tonumber(y)-LOC.y local dz = tonumber(z)-LOC.z local dist = dx+dy+dz if (dist == 0) then return true end local bDone = false local nIt = 0 while (--[[(not bDone) and--]] (nIt < 10)) do if (math.abs(dist) == 1) then if (LOC.onY == 0) then if (LOC.dir == -1) then wti.tRight() else wti.tLeft() end elseif (LOC.dir == -1) then wti.tRight(2) end if (dx ~= 0) then return goRight(dx, bDig) elseif (dy ~= 0) then return forward(dy, bDig) elseif (dz ~= 0) then return up(dz, bDig) end else local path = calcPath(calcMoves(LOC.x, LOC.y, LOC.z, x, y, z, bDig)) for i=1,#path do if (not goTo(path[i].x, path[i].y, path[i].z, bD ig)) then --bDone = false --[[if (bDig) then bDig = false end--]] break end end if (LOC.x == x and LOC.y == y and LOC.z == z) then return true end end nIt = nIt + 1 sleep(0.5) end return false end function calcMoves(px, py, pz, tx, ty, tz, bDig) -- Based on some code of LMelior but made it work and improved way beyond his code, still thx LMelior! bDig = bDig or false px = px or LOC.x

py = py or LOC.y pz = pz or LOC.z --[[ PRE: mapmat is a 2d array px is the player's current x py is the player's current y tx is the target x ty is the target y Note: all the x and y are the x and y to be used in the table. By this I mean, if the table is 3 by 2, the x can be 1,2,3 and the y can be 1 or 2. --]] --[[ POST: closedlist is a list with the checked nodes. It will return nil if all the available nodes have been checked but the target h asn't been found. --]] -- variables local openlist={} alize table to store possible moves local closedlist={} alize table to store checked gridsquares local listk=1 counter local closedk=0 dlist counter local tempH=math.abs(px-tx)+math.abs(py-ty) + math.abs(pz-tz) local tempG=0 openlist[1]={x=px, y=py, z=pz, g=0, h=tempH, f=0+tempH ,par=1} -- Make starting point in list --local xsize=table.getn(mapmat[1]) ontal map size --local ysize=table.getn(mapmat) -- vertical map size local curbase={} nt square from which to check possible moves local basis=1 of current base -- Growing loop while listk>0 do -- Get the lowest f of the openlist local lowestF=openlist[listk].f basis=listk for k=listk,1,-1 do if openlist[k].f<lowestF then lowestF=openlist[k].f basis=k end end closedk=closedk+1 table.insert(closedlist,closedk,openlist[basis]) curbase=closedlist[closedk] ne current base from which to grow list -- defi -- Initi -- Initi -- List -- Close

-- horiz

-- Curre -- Index

local rightOK=true local leftOK=true eans defining if they're OK to add local downOK=true t be reset for each while loop) local upOK=true local forwardOK=true local backOK=true

-- Bool -- (mus

-- Look through closedlist if closedk>0 then for k=1,closedk do if closedlist[k].x==curbase.x+1 and closedlist[k].y==cur base.y and closedlist[k].z==curbase.z then rightOK=false end if closedlist[k].x==curbase.x-1 and closedlist[k].y==cur base.y and closedlist[k].z==curbase.z then leftOK=false end if closedlist[k].x==curbase.x and closedlist[k].y==curba se.y+1 and closedlist[k].z==curbase.z then forwardOK=false end if closedlist[k].x==curbase.x and closedlist[k].y==curba se.y-1 and closedlist[k].z==curbase.z then backOK=false end if closedlist[k].x==curbase.x and closedlist[k].y==curba se.y and closedlist[k].z==curbase.z-1 then downOK=false end if closedlist[k].x==curbase.x and closedlist[k].y==curba se.y and closedlist[k].z==curbase.z+1 then upOK=false end end end --[[ -- Check if next points are on the map and within moving distanc e if curbase.x+1>xsize then rightOK=false end if curbase.x-1<1 then leftOK=false end if curbase.y+1>ysize then downOK=false end if curbase.y-1<1 then upOK=false end]]--- If it IS on the map, check map for obstacles --(Lua returns an error if you try to access a table position th at doesn't exist, so you can't combine it with above) --[[ if curbase.x+1<=xsize and mapmat[curbase.y][curbase.x+1]~=0 then

rightOK=false end if curbase.x-1>=1 and mapmat[curbase.y][curbase.x-1]~=0 then leftOK=false end if curbase.y+1<=ysize and mapmat[curbase.y+1][curbase.x]~=0 then downOK=false end if curbase.y-1>=1 and mapmat[curbase.y-1][curbase.x]~=0 then upOK=false end]]---IMPLEMENT ISBLOCKED if (not bDig) then local bBlocked = isBlocked(curbase.x+1, curbase.y, curba se.z) if (bBlocked) then rightOK=false end bBlocked = isBlocked(curbase.x-1, curbase.y, curbase.z) if (bBlocked) then leftOK=false end bBlocked = isBlocked(curbase.x, curbase.y+1, curbase.z) if (bBlocked) then forwardOK=false end bBlocked = isBlocked(curbase.x, curbase.y-1, curbase.z) if (bBlocked) then backOK=false end bBlocked = isBlocked(curbase.x, curbase.y, curbase.z+1) if (bBlocked) then upOK=false end bBlocked = isBlocked(curbase.x, curbase.y, curbase.z-1) if (bBlocked) then downOK=false end end

-- check if the move from the current base is shorter then from the former parrent tempG=curbase.g+1 for k=1,listk do if rightOK and openlist[k].x==curbase.x+1 and openlist[k].y= =curbase.y and openlist[k].z==curbase.z and openlist[k].g>tempG then tempH=math.abs((curbase.x+1)-tx)+math.abs(curbase.y-ty)+ math.abs(curbase.z-tz) table.insert(openlist,k,{x=curbase.x+1, y=curbase.y, z=c urbase.z, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) rightOK=false end if leftOK and openlist[k].x==curbase.x-1 and openlist[k].y== curbase.y and openlist[k].z==curbase.z and openlist[k].g>tempG then

tempH=math.abs((curbase.x-1)-tx)+math.abs(curbase.y-ty)+ math.abs(curbase.z-tz) table.insert(openlist,k,{x=curbase.x-1, y=curbase.y, z=c urbase.z, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) leftOK=false end if backOK and openlist[k].x==curbase.x and openlist[k].y==cu rbase.y-1 and openlist[k].z==curbase.z and openlist[k].g>tempG then tempH=math.abs((curbase.x)-tx)+math.abs(curbase.y-1-ty)+ math.abs(curbase.z-tz) table.insert(openlist,k,{x=curbase.x, y=curbase.y-1, z=c urbase.z, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) backOK=false end if forwardOK and openlist[k].x==curbase.x and openlist[k].y= =curbase.y+1 and openlist[k].z==curbase.z and openlist[k].g>tempG then tempH=math.abs((curbase.x)-tx)+math.abs(curbase.y+1-ty)+ math.abs(curbase.z-tz) table.insert(openlist,k,{x=curbase.x, y=curbase.y+1, z=c urbase.z, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) forwardOK=false end if upOK and openlist[k].x==curbase.x and openlist[k].y== curbase.y and openlist[k].z==curbase.z+1 and openlist[k].g>tempG then tempH=math.abs((curbase.x)-tx)+math.abs(curbase.y-ty)+ma th.abs(curbase.z+1-tz) table.insert(openlist,k,{x=curbase.x, y=curbase.y, z=cur base.z+1, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) upOK=false end if downOK and openlist[k].x==curbase.x and openlist[k].y ==curbase.y and openlist[k].z==curbase.z-1 and openlist[k].g>tempG then tempH=math.abs((curbase.x)-tx)+math.abs(curbase.y-ty)+ma th.abs(curbase.z-1-tz) table.insert(openlist,k,{x=curbase.x, y=curbase.y, z=cur base.z-1, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) downOK=false end end -- Add points to openlist -- Add point to the right of current base point if rightOK then listk=listk+1 tempH=math.abs((curbase.x+1)-tx)+math.abs(curbase.y-ty)+ math.abs(curbase.z-tz) table.insert(openlist,listk,{x=curbase.x+1, y=curbase.y, z=curbase.z, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) end -- Add point to the left of current base point if leftOK then listk=listk+1 tempH=math.abs((curbase.x-1)-tx)+math.abs(curbase.y-ty)+ math.abs(curbase.z-tz) table.insert(openlist,listk,{x=curbase.x-1, y=curbase.y,

z=curbase.z, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) end -- Add point in front of current base point if forwardOK then listk=listk+1 tempH=math.abs(curbase.x-tx)+math.abs((curbase.y+1)-ty)+ math.abs(curbase.z-tz) table.insert(openlist,listk,{x=curbase.x, y=curbase.y+1, z=curbase.z, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) end -- Add point behind current base point if backOK then listk=listk+1 tempH=math.abs(curbase.x-tx)+math.abs((curbase.y-1)-ty)+ math.abs(curbase.z-tz) table.insert(openlist,listk,{x=curbase.x, y=curbase.y-1, z=curbase.z, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) end -- Add point above current base point if upOK then listk=listk+1 tempH=math.abs(curbase.x-tx)+math.abs((curbase.y)-ty)+ma th.abs(curbase.z+1-tz) table.insert(openlist,listk,{x=curbase.x, y=curbase.y, z =curbase.z+1, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) end -- Add point below current base point if downOK then listk=listk+1 tempH=math.abs(curbase.x-tx)+math.abs((curbase.y)-ty)+ma th.abs(curbase.z-1-tz) table.insert(openlist,listk,{x=curbase.x, y=curbase.y, z =curbase.z-1, g=tempG, h=tempH, f=tempG+tempH, par=closedk}) end table.remove(openlist,basis) listk=listk-1 if closedlist[closedk].x==tx and closedlist[closedk].y==ty and c losedlist[closedk].z==tz then return closedlist end end return nil end function calcPath(closedlist) --[[ PRE: closedlist is a list with the checked nodes. OR nil if all the available nodes have been checked but the target hasn't been f ound. --]] --[[ POST: path is a list with all the x and y coords of the nodes of the path to the targe t. OR nil if closedlist==nil

--]] if closedlist==nil then return nil end local path={} local pathIndex={} local last=table.getn(closedlist) table.insert(pathIndex,1,last) local i=1 while pathIndex[i]>1 do i=i+1 table.insert(pathIndex,i,closedlist[pathIndex[i-1]].par) end for n=table.getn(pathIndex),1,-1 do table.insert(path,{x=closedlist[pathIndex[n]].x, y=closedlist[pathI ndex[n]].y, z=closedlist[pathIndex[n]].z}) end closedlist=nil return path end function minDist(x1, y1, z1, x2, y2, z2) return math.abs(x2-x1)+math.abs(y2-y1)+math.abs(z2-z1) end function digCube(x1, y1, z1, x2, y2, z2) local bP1 = (minDist(LOC.x, LOC.y, LOC.z, x1, y1, z1) <= minDist(LOC.x, LOC.y, LOC.z, x2, y2, z2)) local dx = x2 - x1 local dy = y2 - y1 local dz = z2 - z1 if (bP1) then if (not goTo(x1, y1, z1, true)) then return false else return digFromCorner(dx, dy, dz) end else if (not goTo(x2, y2, z2, true)) then return false else return digFromCorner(-1 * dx, -1 * dy, -1 * dz) end end end function getLoc() return LOC end load()

Вам также может понравиться