Skip to content

Instantly share code, notes, and snippets.

@Tyderion
Last active December 21, 2015 11:19
Show Gist options
  • Save Tyderion/6298119 to your computer and use it in GitHub Desktop.
Save Tyderion/6298119 to your computer and use it in GitHub Desktop.
rednet.open("back")
local master = 0
term.clear()
local commandkeys = {
keys.leftCtrl,
keys.rightControl,
keys.leftShift,
keys.rightShift,
keys.leftAlt,
keys.rightAlt
}
local function debug(text,tx, ty )
local x,y = term.getCursorPos()
term.setCursorPos(tx,ty)
term.clearLine()
print(json.encode(text))
read()
term.setCursorPos(x,y)
end
local tMenu = {
["Categories"] = {
["Build"] = {
["Stone"] = {"Cobble", "Stone", "Bricks", "Fences"},
["Wood"] = { "Logs", "Sticks", "Planks", "Slabs", "Bricks"},
},
["Items"] = {
["Useful"] = { "Torch"},
["Dusts"] = {"Redstone", "Glowstone"}
}
}
}
local searchList = {}
local numberOfAvailableResources = 0
local searchResult = {}
local searchString = ""
local isSearching = false
local statusMessage = ""
local statusMessage1 = ""
local searchX, searchY = 20,3
term.setCursorBlink(true)
local function searchResource(string)
local result = {}
for _, fullName in ipairs(searchList) do
if #string > 0 then
if string.match(string.lower(fullName), string.lower(string)) then
result[#result+1] = fullName
end
else
result[#result+1] = fullName
end
end
return result
end
local function getResources()
rednet.send(master, "getResourceList")
while true do
id, answer = rednet.receive(10)
if id == master then
-- print(answer)
tMenu.Categories = json.decode(answer)
-- print(json.encodePretty(tMenu.Categories))
break
end
end
numberOfAvailableResources = 0
for catname, sub in pairs(tMenu.Categories) do
for subname, resources in pairs(sub) do
for i, resource in ipairs(resources) do
local fullname = catname .. ":" .. subname .. ":" .. resource
searchList[#searchList+1] =fullname
numberOfAvailableResources = numberOfAvailableResources + 1
end
end
end
end
local function establishMaster()
while master == 0 do
print("Trying to reach master")
rednet.broadcast("master")
id, msg = rednet.receive(10)
if msg == "yes" then
master = id
sleep(1)
getResources()
end
end
end
local function shutdown()
term.setBackgroundColor(colors.black)
term.setCursorPos(1,1)
term.clear()
end
local function isCommandKey(code)
local x,y = term.getCursorPos()
for _,key in ipairs(commandkeys) do
-- term.setCursorPos(10,5)
-- term.write(key)
if key == code then
-- term.setCursorPos(x, y)
return true
end
end
-- term.setCursorPos(x, y)
return false
end
local function drawTextRectangle( x,y, text, width )
-- body
local length = width or #text
local line = "+"
line = line .. string.rep("-", length)
line = line .. "+"
if #text < length then
local diff = length - #text
local left = diff
local right = 0
if diff % 2 == 0 then
left = diff/2
right = diff/2
else
left = diff/2
right = diff/2+1
end
text = string.rep(" ", left) .. text .. string.rep(" ", right)
elseif #text > length then
text = string.sub(text, 1,length)
end
term.setCursorPos(x,y)
term.write(line)
term.setCursorPos(x,y+1)
term.write("|"..text.."|")
term.setCursorPos(x,y+2)
term.write(line)
end
local function drawTextRectangleSelected( x,y, text, width )
term.setBackgroundColor(colors.white)
term.setTextColor(colors.black)
drawTextRectangle(x,y,text, width)
term.setBackgroundColor(colors.black)
end
local function drawTextRectangleDeselected( x,y, text, width )
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
drawTextRectangle(x,y,text, width)
end
local function drawHelp(x,y)
term.setCursorPos(x,y)
term.write("ArrowKeys = Select, Enter = Order")
end
local selectedCategory = "None"
local numSelectedCategory = 0
local selectedSubCategory = "None"
local numSelectedSubCategory = 0
local selectedResource = 0
local width, height = term.getSize()
local function drawResourceList(resourceList, xStart, yStart)
local list = table.sort(resourceList, function(a,b) return string.lower(a) < string.lower(b) end)
local currentx = xStart
local currenty = yStart
local start = 1
local heightDiff = (yStart + selectedResource * 3) - (height - 2)
if heightDiff > 0 then
start = math.ceil(heightDiff/3)
end
for num, name in ipairs(resourceList) do
if (num >= start) then
if num == selectedResource then
drawTextRectangleSelected(currentx, currenty, name)
else
drawTextRectangleDeselected(currentx, currenty, name)
end
currenty = currenty + 3
end
end
end
local function drawSubCategory(list, xStart, yStart)
local currentx = xStart
local currenty = yStart
local heightDiff = (yStart + numSelectedSubCategory * 3) - (height - 2)
local start = 1
if heightDiff > 0 then
start = math.ceil(heightDiff/3)+1
end
local num = 1
for name, resources in pairs(list) do
if num >= start then
if name == selectedSubCategory then
drawTextRectangleSelected(currentx, currenty, name, 7)
drawResourceList(resources, xStart + 9, yStart)
else
drawTextRectangleDeselected(currentx, currenty, name, 7)
end
currenty = currenty + 3
end
num = num + 1
end
end
local function drawMenu(tMenu, xStart, yStart)
local currentx = xStart
local currenty = yStart
-- for category, value in pairs(tMenu) do
if height > 15 then
local title = "Categories"
drawTextRectangleDeselected(currentx, currenty, title)
-- drawHelp(currentx + 12, 1)
-- yStart = yStart + 3
currenty = currenty + 3
end
local heightDiff = (currenty + numSelectedCategory * 3) - (height - 2)
local start = 1
if heightDiff > 0 then
start = math.ceil(heightDiff/3)+1
end
local num = 1
for subname, subCategory in pairs(tMenu.Categories) do
if num >= start then
if subname == selectedCategory then
drawTextRectangleSelected(currentx, currenty, subname,5)
drawSubCategory(subCategory, xStart + 8, currenty)
else
drawTextRectangleDeselected(currentx, currenty, subname,5)
end
currenty = currenty + 3
end
num = num + 1
end
end
local function drawFoundResources()
local currentx = 1
local currenty = 1
if height > 15 then
local title = "Search results"
drawTextRectangleDeselected(currentx, currenty, title)
currenty = currenty + 3
end
drawResourceList(searchResult, currentx, currenty)
end
local function drawSearchBar()
term.setTextColor(colors.white)
local x,y = term.getCursorPos()
term.setCursorPos(searchX, searchY)
term.write(searchString)
end
local function drawStatus()
local x,y = term.getCursorPos()
term.setCursorPos(17,1)
term.write(statusMessage)
term.setCursorPos(17,2)
term.write(statusMessage1)
term.setCursorPos(x,y)
end
function redraw()
term.clear()
if #searchResult < numberOfAvailableResources then
drawFoundResources()
else
drawMenu(tMenu, 1,1)
end
drawSearchBar()
drawStatus()
end
local function selectCategory(direction)
local lastCategory = "None"
local returnNext = false
for category, _ in pairs(tMenu.Categories) do
if category == selectedCategory then
if direction == "up" then
if lastCategory == "None" then
break
end
selectedCategory = lastCategory
numSelectedCategory = numSelectedCategory - 1
break
else
returnNext = true
end
elseif returnNext then
selectedCategory = category
numSelectedCategory = numSelectedCategory + 1
break
end
lastCategory = category
end
end
local function selectFirstCategory()
for category, _ in pairs(tMenu.Categories) do
selectedCategory = category
break
end
end
local function selectFirstSubCategory()
for category, _ in pairs(tMenu.Categories[selectedCategory]) do
selectedSubCategory = category
break
end
end
local function selectSubCategory(direction)
local lastCategory = "None"
local returnNext = false
for category, _ in pairs(tMenu.Categories[selectedCategory]) do
if category == selectedSubCategory then
if direction == "up" then
if lastCategory == "None" then
break
end
selectedSubCategory = lastCategory
numSelectedSubCategory = numSelectedSubCategory - 1
break
else
returnNext = true
end
elseif returnNext then
selectedSubCategory = category
numSelectedSubCategory = numSelectedSubCategory + 1
break
end
lastCategory = category
end
end
local lastOrder = {
["amount"]= 0,
["time"]= 0,
["name"]= "None",
["fullName"]= "None"
}
local lastTimer = 0
local orderSent = true
local clearTimer = 0
local function send(name, fullName, amount)
statusMessage = "ordering " .. amount .. " of " .. name
-- redraw()
rednet.send(master, "getRess:" .. fullName .. "-" .. amount)
while true do
id, answer = rednet.receive(10)
if id == master then
statusMessage1 = answer
break
end
end
clearTimer = os.startTimer(5)
end
-- local sendCoroutine = coroutine.create(send)
local function sendOrder()
if (lastOrder.amount > 0 and lastOrder.name ~= "None") then
send(lastOrder.name, lastOrder.fullName,lastOrder.amount)
lastOrder = {
["amount"]= 0,
["time"]= 0,
["name"]= "None",
["fullName"]= "None"
}
end
end
local function order()
term.setCursorPos(12,15)
local materialname = "None"
local name = "None"
if isSearching == true then
name = searchResult[selectedResource]
materialname = searchResult[selectedResource]
else
name = tMenu.Categories[selectedCategory][selectedSubCategory][selectedResource]
materialname = selectedCategory .. ":" .. selectedSubCategory .. ":" .. name
end
local now = os.clock()
-- debug("timediff: " .. now-lastOrder.time, 12, 12)
if lastOrder.name == name and now - lastOrder.time < 2 then
lastOrder.amount = lastOrder.amount + 1
else
lastTimer = "none"
sendOrder()
lastOrder = {
["amount"] = 1,
["time"] = os.clock(),
["name"] = name,
["fullName"] = materialname
}
end
lastTimer = os.startTimer(2)
end
local renderTimer = 0
local renderTime = 0.1
local function run( )
establishMaster()
renderTimer = os.startTimer(renderTime)
if selectedCategory == "None" then selectFirstCategory() end
searchResult = searchResource(searchString)
redraw()
local lastKey
term.setCursorPos(searchX, searchY)
while true do
local event, p1, p2, p3, p4, p5 = os.pullEventRaw()
if (event == "key") then
if (isCommandKey(lastKey)) then
if p1 == keys.t then
shutdown()
break
end
elseif isCommandKey(p1) then
-- Do stuff with command keys?
else
if p1 == keys.down then
if isSearching == true then
if selectedResource < #searchResult then
selectedResource = selectedResource + 1
end
else
if selectedSubCategory == "None" then
selectCategory("down")
elseif selectedResource == 0 then
selectSubCategory("down")
else
if selectedResource < #tMenu.Categories[selectedCategory][selectedSubCategory] then
selectedResource = selectedResource + 1
end
end
end
else
if p1 == keys.up then
if isSearching == true then
if selectedResource > 1 then
selectedResource = selectedResource - 1
end
else
if selectedSubCategory == "None" then
selectCategory("up")
elseif selectedResource == 0 then
selectSubCategory("up")
else
if selectedResource > 1 then
selectedResource = selectedResource - 1
end
end
end
elseif p1 == keys.right then
if selectedSubCategory == "None" then
selectFirstSubCategory()
else
selectedResource = 1
end
elseif p1 == keys.left then
if selectedResource > 0 then
selectedResource = 0
elseif selectedSubCategory ~= "None" then
selectedSubCategory = "None"
end
elseif p1 == keys.enter then
if selectedResource > 0 then
order()
end
elseif p1 == keys.backspace then
local x,y = term.getCursorPos()
if x > searchX then
searchString = string.sub(searchString, 1, #searchString-1)
else
isSearching = false
selectedResource = 0
end
else
local str = keys.getName(p1)
if str ~= nil then
if string.match("abcdefghijklmnopqrstuvwxyz", keys.getName(p1)) then
searchString = searchString .. str
end
end
end
end
end
lastKey = p1
searchResult = searchResource(searchString)
-- debug(#searchResult .. " <? " .. numberOfAvailableResources, 11, 11)
if #searchResult < numberOfAvailableResources and selectedResource == 0 then
selectedResource = 1
isSearching = true
end
elseif (event == "timer") then
if lastTimer == p1 then
sendOrder()
elseif renderTimer == p1 then
redraw()
renderTimer = os.startTimer(renderTime)
elseif clearTimer == p1 then
statusMessage1 = ""
statusMessage = ""
end
end
redraw()
-- sleep(0.1)
end
end
-- getResources()
run()
-- print("args:")
-- for i=1,#args do
-- print(i..":"..args[i])
-- end
-- print("flags:")
-- for k,v in pairs(flags) do
-- print(k..(v=="" and "" or "="..v))
-- end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment