Skip to content

Instantly share code, notes, and snippets.

@leonmax
Last active August 29, 2015 14:02
Show Gist options
  • Save leonmax/cc74375860aad2b9a101 to your computer and use it in GitHub Desktop.
Save leonmax/cc74375860aad2b9a101 to your computer and use it in GitHub Desktop.
nav module for turtle in computercraft
local SlotManager = {}
SlotManager.__index = SlotManager
function SlotManager.new()
local self = setmetatable({}, SlotManager)
self.selectedSlot = 1
return self
end
function SlotManager:select(s)
if s == nil or s <= 0 or s > 16 then
s = 1
end
turtle.select(s)
self.selectedSlot = s
print("selected slot "..s)
end
function SlotManager:getSelected()
if self.selectedSlot == nil or self.selectedSlot < 1 or self.selectedSlot >= 16 then
self.selectedSlot = 1
end
return self.selectedSlot
end
function SlotManager:reloadSlot(slot)
local origin = self:getSelected()
print("reload slot original selected slot "..origin)
if slot == nil or slot <= 0 or slot > 16 then
slot = origin
end
local result = false
for from=1,16 do
if from ~= slot then
turtle.select(from)
if (turtle.getItemCount(slot) == 0 or turtle.compareTo(slot)) and
turtle.getItemCount(from) > 0 then
print("transfer from slot "..from.." to "..slot)
turtle.transferTo(slot)
turtle.select(slot)
result = true
break
end
end
end
turtle.select(origin)
return result
end
local slotmgr = SlotManager.new()
local Walker = {}
Walker.__index = Walker
function Walker.new()
local self = setmetatable({}, Walker)
return self
end
function Walker:beforeMove()
end
function Walker:afterMove()
end
walker = Walker.new()
local Placer = {}
Placer.__index = Placer
function Placer.new()
local self = setmetatable({}, Placer)
self.slotmgr = slotmgr
return self
end
function Placer:placeDown()
local success = turtle.placeDown(1)
if success then
print("placed a block below")
end
return success
end
function Placer:beforeMove()
end
function Placer:afterMove()
if not turtle.detectDown() then
if not self:placeDown() then
if self.slotmgr:reloadSlot() then
self:placeDown()
end
end
end
end
placer = Placer.new()
local FRONT = vector.new( 0, 1, 0)
local RIGHT = vector.new( 1, 0, 0)
local BACK = vector.new( 0, -1, 0)
local LEFT = vector.new(-1, 0, 0)
local UP = vector.new( 0, 0, 1)
local DOWN = vector.new( 0, 0, -1)
Navigator = {}
Navigator.__index = Navigator
function Navigator.new()
local self = setmetatable({}, Navigator)
self.startPos = self:locate()
print("I'm at: ("..self.pos:tostring().."), remain fuel: "..self:checkfuel())
self.dir = FRONT
self.startDir = FRONT
self.actor = walker
return self
end
function Navigator:with(actor)
self.actor = actor
return self
end
function Navigator:checkfuel()
fuel = turtle.getFuelLevel()
if fuel == 0 then
print("I'm EXHAUSTED! Feed me!")
return 0
else
print("remain fuel "..fuel)
return fuel
end
end
function Navigator:locate(coordinate)
--local x, y, z = gps.locate(5)
if x ~= nil then
self.pos = vector.new(x, y, z)
elseif coordinate ~= nil and coordinate.x ~= nil then
self.pos = coordinate
print("Manually input coordinate: ("..self.pos:tostring()..")")
elseif self.pos == nil or self.pos.x == nil then
self.pos = vector.new()
print("Totally lost, assume at: ("..self.pos:tostring()..")")
end
return self.pos
end
function Navigator:relative(coordinate)
if coordinate == nil or coordinate.x == nil then
coordinate = self.startPos
end
return self:locate() - coordinate
end
function Navigator:beforeMove()
self.actor:beforeMove()
end
function Navigator:afterMove(dir, moveSuccess)
if moveSuccess then
self.pos = self.pos + dir
self.actor:afterMove()
return dir
else
return vector.new()
end
end
function Navigator:forward1()
self:beforeMove()
local result = turtle.forward()
return self:afterMove(self.dir, result)
end
function Navigator:back1()
self:beforeMove()
local result = turtle.back()
return self:afterMove(-self.dir, result)
end
function Navigator:up1()
self:beforeMove()
local result = turtle.up()
return self:afterMove(UP, result)
end
function Navigator:down1()
self:beforeMove()
local result = turtle.down()
return self:afterMove(DOWN, result)
end
function Navigator:move(distance, vert)
local moved = vector.new()
for i=1, math.abs(distance) do
local result = nil
if vert~=nil and (vert==true or vert==1) then
if distance >= 0 then
result = self:up1()
else
result = self:down1()
end
else
if distance >= 0 then
result = self:forward1()
else
result = self:back1()
end
end
if result:length() == 0 then break end
moved = moved + result
end
if moved:length() ~= 0 then
print("move "..moved:length().." blocks")
end
return moved
end
function Navigator:forward(distance)
return self:move(distance)
end
function Navigator:back(distance)
return self:move(-distance)
end
function Navigator:up(distance)
return self:move(distance, true)
end
function Navigator:down(distance)
return self:move(-distance, true)
end
function Navigator:right(step)
if self.dir == LEFT then
self.dir = FRONT
print("original front")
elseif self.dir == FRONT then
self.dir = RIGHT
print("original right")
elseif self.dir == RIGHT then
self.dir = BACK
print("original back")
elseif self.dir == BACK then
self.dir = LEFT
print("original left")
end
turtle.turnRight()
if step == nil or step == 0 then
return vector.new()
end
return self:move(step)
end
function Navigator:left(step)
if self.dir == LEFT then
self.dir = BACK
print("original back")
elseif self.dir == BACK then
self.dir = RIGHT
print("original right")
elseif self.dir == RIGHT then
self.dir = FRONT
print("original front")
elseif self.dir == FRONT then
self.dir = LEFT
print("original left")
end
turtle.turnLeft()
if step == nil or step == 0 then
return vector.new()
end
return self:move(step)
end
function Navigator:cover(x, y, z)
pos = vector.new()
print("covering "..x.." X "..y)
for row=0,x,2 do
pos = pos + self:forward(y)
self:right()
if x - row >= 1 then
pos = pos + self:forward1()
end
self:right()
pos = pos + self:forward(y)
self:left()
if x - row >= 2 then
pos = pos + self:forward1()
end
self:left()
end
pos = pos + self:to(-x,0,0)
return pos
end
function Navigator:wall(x, y, z)
pos = vector.new()
for height=1, z do
pos = pos + self:up1() + self:to(x, y, 0) + self:to(-x, -y, 0)
end
return pos
--self:to(vector.new(0, 0, 0))
end
function Navigator:to(x, y, z)
pos = vector.new()
if x ~= 0 then
pos = pos + self:right(x)
self:left()
end
pos = pos + self:move(y) + self:move(z, true)
return pos
end
function Navigator:callby(name, ...)
pos = Navigator[name](self, ...)
print("I'm at: ("..pos:tostring()..") dir: ("..self.dir:tostring()..")")
print("I'm at: ("..self:locate():tostring()..")")
end
agent = Navigator.new(actor.walker)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment