138 lines
3.1 KiB
Lua
138 lines
3.1 KiB
Lua
local tArgs = {...}
|
|
|
|
-- CONSTANTS
|
|
local REDNET_PROTOCOL = "NET_NAV:CONTROL"
|
|
|
|
-- VARIABLES
|
|
local minX, minY, minZ
|
|
local maxX, maxY, maxZ
|
|
local mapName
|
|
local states
|
|
local state, arguments
|
|
local idle
|
|
local startX, startY, startZ
|
|
|
|
-- CHECK MAP NAME
|
|
mapName = tArgs[1]
|
|
if type(mapName) ~= "string" then
|
|
printError("mapName must be string")
|
|
return
|
|
end
|
|
|
|
-- FIND AREA BOUNDARIES
|
|
minX, minY, minZ = unpack(tArgs, 2, 4)
|
|
minX, minY, minZ = tonumber(minX), tonumber(minY), tonumber(minZ)
|
|
maxX, maxY, maxZ = unpack(tArgs, 5, 7)
|
|
maxX, maxY, maxZ = tonumber(maxX), tonumber(maxY), tonumber(maxZ)
|
|
local function isInteger(var)
|
|
return type(var) == "number" and math.floor(var) == var
|
|
end
|
|
if not isInteger(minX) then printError("minX must be integer") return end
|
|
if not isInteger(minY) then printError("minX must be integer") return end
|
|
if not isInteger(minZ) then printError("minX must be integer") return end
|
|
if not isInteger(maxX) then printError("maxX must be integer") return end
|
|
if not isInteger(maxY) then printError("maxY must be integer") return end
|
|
if not isInteger(maxZ) then printError("maxZ must be integer") return end
|
|
if minX > maxX then minX, maxX = maxX, minX end
|
|
if minY > maxY then minY, maxY = maxY, minY end
|
|
if minZ > maxZ then minZ, maxZ = maxZ, minZ end
|
|
|
|
-- LOAD NETNAV API
|
|
if not netNav then
|
|
if not os.loadAPI("netNav") then
|
|
error("could not load netNav API")
|
|
end
|
|
end
|
|
|
|
-- OPEN REDNET
|
|
for _, side in ipairs({"left", "right"}) do
|
|
if peripheral.getType(side) == "modem" then
|
|
rednet.open(side)
|
|
end
|
|
end
|
|
if not rednet.isOpen() then
|
|
printError("Could not open rednet")
|
|
return
|
|
end
|
|
|
|
-- SET NETNAV MAP
|
|
netNav.setMap(mapName, 15)
|
|
|
|
-- SET UP STATES
|
|
local states = {
|
|
EXPLORE = function()
|
|
local x = math.random(minX, maxX)
|
|
local y = math.random(minY, maxY)
|
|
local z = math.random(minZ, maxZ)
|
|
netNav.goto(x, y, z)
|
|
end,
|
|
RETURN = function()
|
|
netNav.goto(startX, startY, startZ)
|
|
state = "IDLE"
|
|
end,
|
|
FOLLOW = function(xPos, yPos, zPos)
|
|
netNav.goto(xPos, yPos, zPos)
|
|
state = "IDLE"
|
|
end,
|
|
IDLE = function()
|
|
idle = true
|
|
while idle do
|
|
os.pullEvent()
|
|
end
|
|
end,
|
|
}
|
|
|
|
-- FIND START POSITION
|
|
startX, startY, startZ = gps.locate(1)
|
|
-- check coords valid
|
|
|
|
-- STATUS UPDATE FUNCTION
|
|
local function sendStatus(senderID)
|
|
local status = {
|
|
mapName,
|
|
senderID,
|
|
"PONG",
|
|
{netNav.getPosition()},
|
|
state,
|
|
arguments,
|
|
}
|
|
if senderID == -1 then
|
|
rednet.broadcast(status, REDNET_PROTOCOL)
|
|
else
|
|
rednet.send(senderID, status, REDNET_PROTOCOL)
|
|
end
|
|
end
|
|
|
|
-- DEFINE CONTROL ROUTINE
|
|
local function control()
|
|
while true do
|
|
local senderID, message = rednet.receive(REDNET_PROTOCOL)
|
|
if type(message) == "table" and message[1] == mapName then
|
|
local sentTo = message[2]
|
|
if sentTo == os.computerID() or sentTo == -1 then
|
|
local request = message[3]
|
|
if request == "PING" then
|
|
sendStatus(senderID)
|
|
elseif states[request] then
|
|
state, arguments = request, message[4]
|
|
netNav.stop()
|
|
idle = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- DEFINE MAIN ROUTINE
|
|
local function main()
|
|
state, arguments = "EXPLORE", {}
|
|
while true do
|
|
sendStatus(-1)
|
|
if states[state] then
|
|
states[state](unpack(arguments))
|
|
end
|
|
end
|
|
end
|
|
|
|
parallel.waitForAny(control, main)
|