diff --git a/farms/superTreefarm.lua b/farms/superTreefarm.lua index c08c8a2..9076a94 100644 --- a/farms/superTreefarm.lua +++ b/farms/superTreefarm.lua @@ -49,7 +49,11 @@ local retain = Util.transpose { SENSOR, } -local state = Util.readTable('usr/config/superTreefarm') or { } +-- filters are separated by | +local state = Util.readTable('usr/config/superTreefarm') or { + logFilter = 'log', + saplingFilter = 'sapling', +} local clock = os.clock() @@ -69,13 +73,22 @@ local function refuel() return true end +-- lua regex wtf +local function mMatch(s, m) + for _,v in pairs(Util.split(m, '(.-)|')) do + if s:match(v) then + return true + end + end +end + local function makeCharcoal() local slots = turtle.getSummedInventory() local function getLogSlot() local maxslot = { count = 0 } for k,slot in pairs(slots) do - if string.match(k, 'minecraft:log') then + if mMatch(k, state.logFilter) then if slot.count > maxslot.count then maxslot = slot end @@ -112,7 +125,7 @@ local function makeCharcoal() local count = inv[1] and inv[1].count or 0 if count < 32 then for key, slot in pairs(turtle.getSummedInventory()) do - if string.match(key, 'minecraft:log') then + if mMatch(key, state.logFilter) then if turtle.dropDown(key, 32-count) then count = count + slot.count if count >= 32 then @@ -160,6 +173,8 @@ local function createChests() setState('chest', pt) turtle.dropDown(DIRT) + + return end return true end @@ -169,7 +184,7 @@ local function getSaplings() local saplings = { } for _, slot in pairs(slots) do - if slot.name == SAPLING then + if mMatch(slot.name, state.saplingFilter) then table.insert(saplings, slot) end end @@ -184,17 +199,28 @@ end local function dropOffItems() local slots = turtle.getSummedInventory() + local function checkLogs() + for k,v in pairs(slots) do + if mMatch(k, state.logFilter) and v.count > 16 then + return true + end + end + end + if state.chest and slots[CHARCOAL] and slots[CHARCOAL].count >= MIN_CHARCOAL and - (turtle.getItemCount(LOG) > 16 or - turtle.getItemCount(LOG2) > 16) then + checkLogs() then print('Storing logs') turtle.pathfind(Point.above(state.chest)) for k,v in pairs(turtle.getInventory()) do - if v.count > 0 and not retain[v.name] and not retain[v.key] then + if v.count > 0 and + not retain[v.name] and + not retain[v.key] and + not mMatch(v.key, state.saplingFilter) then + turtle.select(k) turtle.dropDown() end @@ -235,7 +261,7 @@ local function findDroppedSaplings() b.x = Util.round(b.x) + turtle.point.x b.y = math.ceil(b.y) + turtle.point.y b.z = Util.round(b.z) + turtle.point.z - if b.y == 0 and string.find(b.displayName, 'sapling', 1, true) then + if b.y == 0 and mMatch(b.displayName, state.saplingFilter) then b.sapling = true acc[makeKey(b)] = b end @@ -268,7 +294,7 @@ local function getPlantLocations(blocks) local key = makeKey(sapling) local b = blocks[key] if b then - if b.name == SAPLING then + if mMatch(b.name, state.saplingFilter) then blocks[key] = nil else b.plant = true @@ -322,7 +348,7 @@ local function fellTrees(blocks) elseif pt.plant then local s = randomSapling() - if pt.name and pt.name ~= SAPLING then + if pt.name and not mMatch(pt.name, state.saplingFilter) then turtle.digDownAt(pt) end if s then @@ -346,7 +372,7 @@ end local function fell() local function filter(b) - return b.name == LOG or b.name == LOG2 or b.name == SAPLING + return mMatch(b.name, state.logFilter) or mMatch(b.name, state.saplingFilter) end local fuel = turtle.getFuelLevel() diff --git a/milo/apis/craft2.lua b/milo/apis/craft2.lua index b2d3e8c..d91708c 100644 --- a/milo/apis/craft2.lua +++ b/milo/apis/craft2.lua @@ -128,17 +128,22 @@ local function machineCraft(recipe, storage, machineName, request, count, item) return end + local pending = item.pending[recipe.result] or 0 + local list = machine.adapter.list() for k in pairs(recipe.ingredients) do if list[k] then - request.status = 'machine in use' - request.statusCode = Craft.STATUS_WARNING + if pending > 0 then + request.status = 'processing' + request.statusCode = Craft.STATUS_INFO + else + request.status = 'machine in use' + request.statusCode = Craft.STATUS_WARNING + end return end end - local pending = item.pending[recipe.result] or 0 - if count > 0 then local xferred = { } for k,v in pairs(recipe.ingredients) do @@ -187,6 +192,10 @@ local function turtleCraft(recipe, storage, request, count) request.statusCode = Craft.STATUS_ERROR failed = true _G._syslog('failed to export: ' .. item.name) +-- _G._p4 = recipe +-- _G._p = storage +-- _G._p2 = request +--read() end end) end @@ -223,7 +232,7 @@ local function turtleCraft(recipe, storage, request, count) end function Craft.processPending(item, storage) - for _, key in pairs(Util.keys(item.pending)) do + for _, key in pairs(Util.keys(item.pending)) do local count = item.pending[key] local imported = storage.activity[key] if imported then @@ -332,7 +341,7 @@ function Craft.craftRecipeInternal(recipe, count, storage, origItem, path) return 0 end if origItem.forceCrafting and crafted < iqty then - canCraft = math.floor((itemCount + crafted) / icount) + canCraft = math.min(canCraft, math.floor((itemCount + crafted) / icount)) end if crafted > 0 then craftedIngredient = true @@ -467,28 +476,29 @@ function Craft.getResourceList4(inRecipe, items, count) end -- given a certain quantity, return how many of those can be crafted -function Craft.getCraftableAmount(inRecipe, inCount, items, missing) - local function sumItems(recipe, summedItems, count, path) +function Craft.getCraftableAmount(inRecipe, limit, items) + local allIngredients = { } + + local function sumItems(recipe, count, path) local canCraft = 0 for _ = 1, count do - for _, item in Craft.ingredients(recipe) do - local summedItem = summedItems[item.key] or Craft.getItemCount(items, item.key) + for iKey, iCount in pairs(Craft.sumIngredients(recipe)) do + local quantity = allIngredients[iKey] or Craft.getItemCount(items, iKey) - local irecipe = findValidRecipe(item.key, path) - if irecipe and summedItem <= 0 then - local p = Util.shallowCopy(path) - p[irecipe.result] = true - summedItem = summedItem + sumItems(irecipe, summedItems, item.count, p) - end - if summedItem <= 0 then - if missing and not irecipe then - missing.name = item.key + if quantity < iCount then + local irecipe = findValidRecipe(iKey, path) + if irecipe then + local p = Util.shallowCopy(path) + p[irecipe.result] = true + quantity = quantity + sumItems(irecipe, iCount - quantity, p) end + end + if quantity < iCount then return canCraft end - if not recipe.craftingTools or not recipe.craftingTools[item.key] then - summedItems[item.key] = summedItem - item.count + if not recipe.craftingTools or not recipe.craftingTools[iKey] then + allIngredients[iKey] = quantity - iCount end end canCraft = canCraft + recipe.count @@ -498,7 +508,7 @@ function Craft.getCraftableAmount(inRecipe, inCount, items, missing) end local path = { [ inRecipe.result ] = true } - return sumItems(inRecipe, { }, math.ceil(inCount / inRecipe.count), path) + return sumItems(inRecipe, math.ceil(limit / inRecipe.count), path) end function Craft.loadRecipes() diff --git a/milo/apis/init.lua b/milo/apis/init.lua index 8f1504a..c89b208 100644 --- a/milo/apis/init.lua +++ b/milo/apis/init.lua @@ -238,6 +238,12 @@ function Milo:learnRecipe() return false, 'No recipe defined' end + for _,v in pairs(ingredients) do + if v.count > 1 then + return false, 'Too many items' + end + end + turtle.select(1) if not turtle.craft() then return false, 'Failed to craft' diff --git a/milo/plugins/brewingStandView.lua b/milo/plugins/brewingStandView.lua index c0cebda..8f2d971 100644 --- a/milo/plugins/brewingStandView.lua +++ b/milo/plugins/brewingStandView.lua @@ -25,9 +25,10 @@ local wizardPage = UI.WizardPage { }, } +-- Brewing stand shows as Cauldron is Minecraft 1.10 function wizardPage:isValidType(node) local m = device[node.name] - return m and m.type == 'minecraft:brewing_stand'and { + return m and (m.type == 'minecraft:brewing_stand' or m.type == 'Cauldron') and { name = 'Brewing Stand', value = 'brewingStand', category = 'machine', diff --git a/milo/plugins/jobMonitor.lua b/milo/plugins/jobMonitor.lua index 3fb1f36..6d00f3c 100644 --- a/milo/plugins/jobMonitor.lua +++ b/milo/plugins/jobMonitor.lua @@ -132,11 +132,13 @@ local function createPage(node) v.index = #t for k2,v2 in pairs(v.ingredients or { }) do if v2.key ~= v.key --[[and v2.statusCode ]] then - table.insert(t, v2) - if not v2.displayName then - v2.displayName = itemDB:getName(k2) + if v2.need > 0 or v2.statusCode then + table.insert(t, v2) + if not v2.displayName then + v2.displayName = itemDB:getName(k2) + end + v2.index = #t end - v2.index = #t end end end diff --git a/milo/plugins/potionImportTask.lua b/milo/plugins/potionImportTask.lua index cd9dc2d..e747a17 100644 --- a/milo/plugins/potionImportTask.lua +++ b/milo/plugins/potionImportTask.lua @@ -10,12 +10,8 @@ local PotionImportTask = { brewQueue = { }, } -local function filter(a) - return a.adapter.type == 'minecraft:brewing_stand' -end - function PotionImportTask:cycle(context) - for bs in context.storage:filterActive('brewingStand', filter) do + for bs in context.storage:filterActive('brewingStand') do if bs.adapter.getBrewTime() == 0 then local list = bs.adapter.list() diff --git a/milo/plugins/transferView.lua b/milo/plugins/transferView.lua new file mode 100644 index 0000000..343e528 --- /dev/null +++ b/milo/plugins/transferView.lua @@ -0,0 +1,123 @@ +local Ansi = require('ansi') +local Milo = require('milo') +local Tasks = require('milo.taskRunner') +local UI = require('ui') +local Util = require('util') + +local colors = _G.colors +local device = _G.device + +local context = Milo:getContext() + +--[[ Configuration Screen ]] +local wizardPage = UI.WizardPage { + title = 'Transfer Inventory', + index = 2, + backgroundColor = colors.cyan, + grid = UI.ScrollingGrid { + y = 2, ey = -2, + values = context.storage.nodes, + columns = { + { key = 'suffix', width = 4, align = 'right' }, + { heading = 'Name', key = 'displayName' }, + { heading = 'Type', key = 'mtype', width = 4 }, + { heading = 'Pri', key = 'priority', width = 3 }, + }, + sortColumn = 'displayName', + help = 'Double-click to set target', + }, +} + +function wizardPage:isValidType(node) + local m = device[node.name] + return m and m.pullItems and { + name = 'Transfer', + value = 'xfer', + category = 'custom', + help = 'Transfer contents', + } +end + +function wizardPage:isValidFor(node) + return node.mtype == 'xfer' +end + +function wizardPage:setNode(node) + self.node = node + + local t = Util.filter(context.storage.nodes, function(v) + return v.mtype ~= 'ignore' and device[v.name] and v.mtype ~= 'hidden' + end) + + self.grid:setValues(t) +end + +function wizardPage.grid:getDisplayValues(row) + row = Util.shallowCopy(row) + local t = { row.name:match(':(.+)_(%d+)$') } + if #t ~= 2 then + t = { row.name:match('(.+)_(%d+)$') } + end + if t and #t == 2 then + row.name, row.suffix = table.unpack(t) + row.name = row.name .. '_' .. row.suffix + end + row.displayName = row.displayName or row.name + return row +end + +function wizardPage.grid:getRowTextColor(row, selected) + if row.name == self.parent.node.target then + return colors.yellow + end + return UI.Grid:getRowTextColor(row, selected) +end + +function wizardPage:eventHandler(event) + if event.type == 'grid_select' then + self.node.target = event.selected.name + self.grid:draw() + end + return UI.Page.eventHandler(self, event) +end + +UI:getPage('nodeWizard').wizard:add({ transferChest = wizardPage }) + +local function transfer(node) + local tasks = Tasks({ + errorMsg = 'TRANSFER error: ' + }) + + local target = context.storage.nodes[node.target] + if not target or not target.adapter or not target.adapter.online then + error(string.format('TRANSFER: target %s is not online', node.target)) + end + + for k in pairs(node.adapter.list()) do + tasks:add(function() + node.adapter.pushItems(node.target, k) + end) + end + + function tasks:onError(msg) + _G._syslog('TRANSFER error: ' .. msg) + end + tasks:run() +end + +--[[ Task ]]-- +local Task = { + name = 'transfer', + priority = 99, +} + +function Task:cycle() + for node in context.storage:filterActive('xfer') do + local s, m = pcall(transfer, node) + if not s and m then + _G._syslog('TRANSFER error:' .. m) + end + end +end + +Milo:registerTask(Task)