Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function dirToNum(d)
- assert(type(d) == "string", "Expected string, got " .. type(d))
- d = d:lower()
- if d == "north" then
- return 0
- elseif d == "east" then
- return 1
- elseif d == "south" then
- return 2
- elseif d == "west" then
- return 3
- else
- error('"' .. d .. '"' .. " is an unrecognized direction")
- end
- end
- function numToDir(n)
- assert(type(n) == "number", "Expected number, got " .. type(n))
- n = n % 4
- if n == 0 then
- return "north"
- elseif n == 1 then
- return "east"
- elseif n == 2 then
- return "south"
- elseif n == 3 then
- return "west"
- end
- end
- function getUpVector()
- return new(0, 1, 0)
- end
- function getDownVector()
- return new(0, -1, 0)
- end
- function getNorthVector()
- return new(0, 0, -1, 0)
- end
- function getSouthVector()
- return new(0, 0, 1, 2)
- end
- function getWestVector()
- return new(-1, 0, 0, 3)
- end
- function getEastVector()
- return new(1, 0, 0, 1)
- end
- local pos = {}
- pos.__index = pos
- function new(x, y, z, dir)
- if type(dir) == "string" then
- dir = dirToNum(dir)
- end
- local t = {
- ["x"] = x or 0,
- ["y"] = y or 0,
- ["z"] = z or 0,
- ["dir"] = dir or 0
- }
- t.dir = t.dir % 4
- setmetatable(t, pos)
- return t
- end
- function fromGPS(loadDir)
- if not loadDir then loadDir = false end
- local coords = {gps.locate()}
- assert(coords ~= nil, "Cannot load pos from GPS. There is no modem. ")
- local t = new(coords[1], coords[2], coords[3])
- if loadDir then
- if not turtle.forward() then
- repeat until not turtle.dig()
- if not turtle.forward() then error("must be able to go forward to load dir!") end
- end
- local newCoords = {gps.locate()}
- local newT = new(newCoords[1], newCoords[2], newCoords[3])
- local changeInCoords = newT - t;
- turtle.back()
- if changeInCoords == new(0, 0, -1) then
- t:set(nil, nil, nil, "north")
- elseif changeInCoords == new(1, 0, 0) then
- t:set(nil, nil, nil, "east")
- elseif changeInCoords == new(0, 0, 1) then
- t:set(nil, nil, nil, "south")
- elseif changeInCoords == new(-1, 0, 0) then
- t:set(nil, nil, nil, "west")
- end
- end
- return t
- end
- function isPos(t)
- return getmetatable(t) == pos
- end
- function pos:set(x, y, z, dir)
- if isPos(x) then
- self.x = x.x
- self.y = x.y
- self.z = x.z
- self.dir = x.dir
- else
- self.x = x or self.x
- self.y = y or self.y
- self.z = z or self.z
- if type(dir) == "number" then
- self.dir = dir % 4
- elseif type(dir) == "string" then
- self.dir = dirToNum(dir)
- end
- end
- end
- function pos:clone()
- return new(self.x, self.y, self.z, self.dir)
- end
- function pos:replace(newPos, keepDir)
- assert(isPos(newPos), "Cannot replace pos with non-pos")
- if not keepDir then keepDir = false end
- self.x = newPos.x
- self.y = newPos.y
- self.z = newPos.z
- if not keepDir then self.dir = newPos.dir end
- return self
- end
- function pos:change()
- end
- function pos:getForwardVector()
- if self.dir == 0 then
- return new(0, 0, -1, 0)
- elseif self.dir == 1 then
- return new(1, 0, 0, 1)
- elseif self.dir == 2 then
- return new(0, 0, 1, 2)
- elseif self.dir == 3 then
- return new(-1, 0, 0, 3)
- end
- end
- function pos:getBackwardVector()
- return self:getForwardVector() * -1
- end
- function pos:getLeftVector()
- if self.dir == 0 then
- return new(-1, 0, 0, 3)
- elseif self.dir == 1 then
- return new(0, 0, -1, 0)
- elseif self.dir == 2 then
- return new(1, 0, 0, 1)
- elseif self.dir == 3 then
- return new(0, 0, 1, 2)
- end
- end
- function pos:getRightVector()
- return self:getLeftVector() * -1
- end
- function pos.__add(a,b)
- assert(isPos(a) and isPos(b), "Can't add pos to non-pos")
- return new(a.x + b.x, a.y + b.y, a.z + b.z, a.dir)
- end
- function pos.__sub(a,b)
- assert(isPos(a) and isPos(b), "Can't sub pos from non-pos")
- return new(a.x - b.x, a.y - b.y, a.z - b.z, a.dir)
- end
- function pos.__mul(a,b)
- if isPos(a) and type(b) == "number" then
- return new(a.x * b, a.y * b, a.z * b)
- elseif isPos(b) and type(a) == "number" then
- return new(b.x * a, b.y * a, b.z * a)
- else
- error("expected pos and number")
- end
- end
- function pos.__div(a,b)
- assert(isPos(a) and type(b) == "number", "Cannot divide pos by non-number")
- return new(a.x / b, a.y / b, a.z / b)
- end
- function pos.__eq(a,b)
- assert(isPos(a) and isPos(b), "Can't compare pos with non-pos")
- return a.x == b.x and a.y == b.y and a.z == b.z
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement