CC-navigation/netNav/explore.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)