diff --git a/Libraries/ARWidgets.lua b/Libraries/ARWidgets.lua index 8624a5b..550a5d1 100644 --- a/Libraries/ARWidgets.lua +++ b/Libraries/ARWidgets.lua @@ -218,7 +218,7 @@ function ARWidgets.fluidMonitor(glasses, x, y, fluidMap) end end local function refreshDatabase(itemList) - filteredList = {} + local filteredList = {} for i = 1, #itemList, 1 do if i % 200 == 0 then os.sleep() end if itemList[i].size >= 100 then filteredList[itemList[i].label] = itemList[i].size end @@ -310,9 +310,9 @@ function ARWidgets.itemTicker(glasses, x, y, w) local divisor1 = ARG.hudRectangle(glasses, x+w - 118, y+20, 2, 12, hudColour) local divisor2 = ARG.hudRectangle(glasses, x+w - 64, y+20, 2, 12, hudColour) local bottomDataStripe = ARG.hudRectangle(glasses, x+w - 168, y+30, 168, 1, workingColour) - uniqueItems = ARG.hudText(glasses, "", x, y, workingColour, 0.75) - totalItems = ARG.hudText(glasses, "", x, y, workingColour, 0.75) - patterns = ARG.hudText(glasses, "", x, y, workingColour, 0.75) + local uniqueItems = ARG.hudText(glasses, "", x, y, workingColour, 0.75) + local totalItems = ARG.hudText(glasses, "", x, y, workingColour, 0.75) + local patterns = ARG.hudText(glasses, "", x, y, workingColour, 0.75) uniqueItems.setPosition((x+w-114)*1.33333, (y+22)*1.33333) totalItems.setPosition((x+w-168)*1.33333, (y+22)*1.33333) patterns.setPosition((x+w-60)*1.33333, (y+22)*1.33333) diff --git a/Programs/Assembly Line/assemble.lua b/Programs/Assembly Line/assemble.lua deleted file mode 100644 index 8a654d7..0000000 --- a/Programs/Assembly Line/assemble.lua +++ /dev/null @@ -1,282 +0,0 @@ -comp=require("component"); event=require("event"); screen=require("term"); computer = require("computer"); thread = require("thread") -dict=require("dictionary"); line = require("transport"); config = require("configure") -function machine(address) - machineAddress = comp.get(address) - if(machineAddress ~= nil) then return comp.proxy(machineAddress) else return nil end -end -function findAddress(type) - for address, component in comp.list() do - if component == type then return address end - end -end -recipes = {} -fluidMap = {["fluid.molten.solderingalloy"] = {index = 81, size = 144}, - ["fluid.lubricant"] = {index = 80, size = 250}, - ["IC2 Coolant"] = {index = 79, size = 1000}, - ["fluid.molten.styrenebutadienerubber"] = {index = 78, size = 720}, - ["fluid.molten.niobiumtitanium"] = {index = 77, size = 144}, - ["fluid.molten.tritanium"] = {index = 76, size = 144}, - ["fluid.Neon"] = {index = 75, size = 1000} - -} -local function addRecipe(slot, source, sourceSide) - if source.getStackInSlot(sourceSide, slot) ~= nil then - --screen.write("Adding a recipe\n") - local pattern = source.getStackInSlot(sourceSide, slot) - recipes[pattern.output] = {} - recipes[pattern.output]["label"] = pattern.output - recipes[pattern.output]["time"] = pattern.time - recipes[pattern.output]["inputs"] = 0 - recipes[pattern.output]["fluids"] = 0 - recipes[pattern.output]["tier"] = voltageToTier(pattern.eu) - if pattern.inputItems ~= nil then - local items = pattern.inputItems - for i = 1, #items, 1 do - --screen.write("Item "..i.." :"..items[i][1].." - "..items[i][2].."\n") - recipes[pattern.output]["input"..i] = {name = items[i][1], amount = items[i][2]} - recipes[pattern.output]["inputs"] = recipes[pattern.output]["inputs"] + 1 - end - end - if pattern.inputFluids ~= nil then - local fluids = pattern.inputFluids - for i = 1, #fluids do - --screen.write("Fluid "..i.." :"..fluids[i][1].." - "..fluids[i][2].."\n") - recipes[pattern.output]["fluid"..i] = {name = fluids[i][1], amount = fluids[i][2]} - recipes[pattern.output]["fluids"] = recipes[pattern.output]["fluids"] + 1 - end - end - end -end -function getRecipes(assemblyData) - if assemblyData["data"] ~= nil then - for i = 1, 16 do - addRecipe(i, assemblyData["data"], 0) - end - end -end -function copyPattern(interface, slot, recipe, database) - for i = 1, recipe.inputs, 1 do - local item = recipe["input"..i] - local name = item.name - if dictionary[name] ~= nil then name = dictionary[name] end - interface.setInterfacePatternInput(slot, database, databaseMap[name], item.amount, i) - end -end -local latestRecipe = {} -function processRecipe(assemblyData, recipe) - local inventory, database = assemblyData["inventory"], assemblyData["database"] - local needsConfiguring = false - if latestRecipe ~= nil then - if latestRecipe.label ~= recipe.label then - needsConfiguring = true - if latestRecipe.inputs ~= nil then - if latestRecipe.inputs > recipe.inputs then - line.clearInterfaces(assemblyData, recipe.inputs + 1, latestRecipe.inputs, latestRecipe.fluids - recipe.fluids, 4) - elseif latestRecipe.fluids > recipe.fluids then - line.clearInterfaces(assemblyData, 0, 0, recipe.fluids + 1, latestRecipe.fluids) - end - end - end - else - needsConfiguring = true - end - if needsConfiguring then - for i = 1, recipe["inputs"], 1 do - local item = recipe["input"..i] - local name = item.name - if dictionary[name] ~= nil then name = dictionary[name] end - if databaseMap[name] == nil then screen.write(" Updating database..."); updateDatabase(assemblyData, databaseMap); end - assemblyData["input"..i].setInterfaceConfiguration(1, database.address, databaseMap[name], item.amount) - screen.write(".") - end - for i = 1, recipe["fluids"], 1 do - local fluid = recipe["fluid"..i] - assemblyData["fluid"..i].setInterfaceConfiguration(1, database.address, fluidMap[fluid.name].index, fluid.amount/fluidMap[fluid.name].size) - screen.write(".") - end - if assemblyData["input15"].getInterfacePattern(1) ~= nil then - copyPattern(assemblyData["input15"], 1, recipe, database.address) - end - end - screen.write(" Inserting ...") - for i = 1, recipe["inputs"], 1 do - local item = recipe["input"..i] - assemblyData["inputTransposer"..i].transferItem(0, 1, item.amount, 1, 16) - screen.write(".") - end - for i = 1, recipe["fluids"], 1 do - local fluid = recipe["fluid"..i] - assemblyData["fluidTransposer"..i].transferItem(0, 1, fluid.amount/fluidMap[fluid.name].size, 1, 1) - screen.write(".") - end - os.sleep(1) - for i = 1, recipe["fluids"], 1 do - local fluid = recipe["fluid"..i] - assemblyData["fluidTransposer"..i].transferItem(1, 0, fluid.amount/fluidMap[fluid.name].size, 2, 9) - screen.write(".") - end - local recipeTicks = (recipe.time / math.pow(2, assemblyData.tier - recipe.tier)) - if needsConfiguring == false then - os.sleep(recipeTicks / 20 - 1.5) - end - latestRecipe = recipe - line.waitForAssemblyline(recipeTicks - 50 , assemblyData["controller"]) -end -function matchRecipe(recipeList, assemblyData, priority) - priority = priority or nil - local network = assemblyData["items"].getItemsInNetwork() - local size = #network * 2 - if size == 0 then size = 1 end - foundItems = {} - for i = 1, #network, 1 do - foundItems[network[i].label] = network[i].size end - for i = 1, 15, 1 do - if assemblyData["inputTransposer"..i].getStackInSlot(0, 1) ~= nil then - local interfaceItem = assemblyData["inputTransposer"..i].getStackInSlot(0, 1) - if interfaceItem.size ~= nil then - if foundItems[interfaceItem.label] == nil then - foundItems[interfaceItem.label] = interfaceItem.size - else - foundItems[interfaceItem.label] = foundItems[interfaceItem.label] + interfaceItem.size - end - end - end - end - for recipeLabel, v in pairs(recipeList) do - local recipe, found = recipeList[recipeLabel], 0 - local inputs = recipe.inputs - if debugMode then screen.write("Checking match for: "..recipeLabel.." with required N of "..recipe.inputs.."\n") end - for i = 1, inputs, 1 do - local label, requiredAmount = recipe["input"..i].name, recipe["input"..i].amount - if dictionary[label] ~= nil then label = dictionary[label] end - if debugMode then screen.write(" Searching for "..requiredAmount.." "..label) end - if foundItems[label] == nil then if debugMode then screen.write("\n") end break - else - local existingAmount = foundItems[label] - if existingAmount >= requiredAmount then - found = found + 1 - if debugMode then screen.write(" | Found!: "..label.." N: "..found.."\n") end - else if debugMode then screen.write(" | Didn't find enough: "..existingAmount.."\n") end - end - end - end - if found == inputs then - if priority == nil then - return recipe - else - if priority.label == recipe.label then return recipe end - end - end - end - return nil -end -function voltageToTier(voltage) - local maxTier = 15 - local tier = maxTier - voltage = voltage - 1 - local tierVoltage = 32 * math.pow(4, tier - 1) - while voltage % tierVoltage == voltage do - tier = tier - 1 - tierVoltage = 32 * math.pow(4, tier - 1) - end - return tier + 1 -end -function getControllerTier(assemblyData) - local controller = assemblyData["controller"] - return voltageToTier(math.floor(string.gsub(string.sub(controller.getSensorInformation()[4], 1, string.find(controller.getSensorInformation()[4], "/")-1), "([^0-9]+)", "") + 0)) -end -function refreshDatabase(assemblyData, databaseRef) - local database = assemblyData["database"] - local i = 2 - local entry = database.get(i) - while database.get(i) ~= nil do - screen.write(".") - databaseRef[entry.label] = i - i = i + 1 - entry = database.get(i) - end -end -function updateDatabase(assemblyData, databaseMap) - local chestSide = 5 - if assemblyData["inventory"] ~= nil and assemblyData["database"] ~= nil then - local inventory, database = assemblyData["inventory"], assemblyData["database"] - for i = 1, inventory.getInventorySize(chestSide), 1 do - if inventory.getStackInSlot(chestSide, i) ~= nil then - inventory.store(chestSide, i, database.address, 1) - local hash = database.computeHash(1) - database.clear(1) - local index = database.indexOf(hash) - if index < 0 then - local j = 2 - while database.get(j) ~= nil do - j = j + 1 - end - inventory.store(chestSide, i, database.address, j) - databaseMap[inventory.getStackInSlot(chestSide, i).label] = j - end - end - end - end -end -function split(s, sep) - local fields = {}; local sep = sep or " "; local pattern = string.format("([^%s]+)", sep) - string.gsub(s, pattern, function(c) fields[#fields + 1] = c end) - return fields -end -function buildAssembly() - screen.write("Starting Assembly Line initalization...") - local assemblyStructure = {} - local file = io.open("addresses", "r") - if file == nil then - screen.write(" no address configuration found, configuring:\n") - config.getAddresses() - file = io.lines("addresses") - else - file = io.lines("addresses") - end - for line in file do - screen.write(".") - local tokens = split(line, ",") - assemblyStructure[tokens[1]] = machine(tokens[2]) - end - screen.write("\n") - return assemblyStructure -end -function startAssembly(assemblyData) - assemblyData["tier"] = getControllerTier(assemblyData) - screen.write("Fetching recipes ... "); getRecipes(assemblyData); screen.write("Done") - databaseMap = {} - screen.write(" | Refreshing database ..."); refreshDatabase(assemblyData, databaseMap); screen.write(" Done") - screen.write(" | Clearing interfaces ... "); line.clearInterfaces(assemblyData); screen.write("Done") - debugMode = false - local cyclesSinceRefresh = 0 - local configured = false - screen.write(" | Beginning operation\n") - while true do - local foundRecipe = matchRecipe(recipes, assemblyData) - if foundRecipe ~= nil then - screen.write("Starting assembly of "..foundRecipe.label.." ...") - processRecipe(assemblyData, foundRecipe) - screen.write(" Done!\n") - configured = true - else - if cyclesSinceRefresh > 20 then - getRecipes(assemblyData) - cyclesSinceRefresh = 0 - end - cyclesSinceRefresh = cyclesSinceRefresh + 1 - if configured then - configured = false - line.clearInterfaces(assemblyData) - latestRecipe = nil - end - os.sleep(5) - end - end -end -local assemblyLine = buildAssembly() -startAssembly(assemblyLine) - ---Things to add: ---Make pattern match check for item sums instead of on a stack basis ---Add sanity check that everything was moved 100% \ No newline at end of file diff --git a/Programs/Assembly Line/assemblyClient.lua b/Programs/Assembly Line/assemblyClient.lua new file mode 100644 index 0000000..eaedadf --- /dev/null +++ b/Programs/Assembly Line/assemblyClient.lua @@ -0,0 +1,122 @@ +comp=require("component"); event=require("event"); screen=require("term"); computer = require("computer"); thread = require("thread") +local AU = require("util") +local AT = require("transport") +local S = require("serialization"); local uc = require("unicode") +local D = require("dictionary") +local network = comp.modem +local id, AD +local function requestID() + network.broadcast(100, "requestID") + local _, _, _, _, _, messageType, value = event.pull("modem_message"); + while messageType ~= "sendID" do + _, _, _, _, _, messageType, value = event.pull("modem_message") + os.sleep(0.2) + end + return value +end + +function checkRepeat(recipe) + local correctItems = 0 + for i = 1, recipe.inputs, 1 do + if AT.isEmpty(AD["inputTransposer"..i], 16) then + if AT.check(AD["inputTransposer"..i], recipe["input"..i].name, recipe["input"..i].amount) then + correctItems = correctItems + 1 + else return false end + else return false end + end + for i = 1, recipe.fluids, 1 do + if AT.isEmpty(AD["fluidTransposer"..i], 1) then + if AT.check(AD["fluidTransposer"..i], fluidMap[recipe["fluid"..i].name].name, recipe["fluid"..i].amount / fluidMap[recipe["fluid"..i].name].size) then + correctItems = correctItems + 1 + else return false end + else return false end + end + if correctItems == recipe.inputs + recipe.fluids then return true else return false end +end + +local function processRecipe(recipe) + local database, interface = AD.database, AD.input1 + local function insert() + for i = 1, recipe.fluids, 1 do AT.move(AD["fluidTransposer"..i], recipe["fluid"..i].amount / fluidMap[recipe["fluid"..i].name].size, 1) end + for i = 1, recipe.inputs, 1 do AT.move(AD["inputTransposer"..i], recipe["input"..i].amount, 16) end + for i = 1, recipe.fluids, 1 do AT.empty(AD["fluidTransposer"..i]) end + end + for i = 1, recipe.inputs, 1 do + database.clear(i) + interface.store({label = recipe["input"..i].name}, database.address, i, 1) + end + for i = 1, recipe.fluids, 1 do + database.clear(20+i) + interface.store({label = fluidMap[recipe["fluid"..i].name].name}, database.address, 20+i, 1) + end + for i = 1, recipe.inputs, 1 do + AT.set(AD["input"..i], database, i, recipe["input"..i].amount) + end + for i = 1, recipe.fluids, 1 do + AT.set(AD["fluid"..i], database, 20+i, recipe["fluid"..i].amount / fluidMap[recipe["fluid"..i].name].size) + end + ::insertRecipes:: + insert() + while checkRepeat(recipe) do + insert() + end + local wait = computer.uptime() + while not AD.controller.hasWork() and computer.uptime() < wait + 5 do + os.sleep(0.2) + end + if not AD.controller.hasWork() then + screen.write(" ... Error with starting assembly!") + network.broadcast(id, "jammed") + else + screen.write(" ... Assembly Started") + while AD.controller.hasWork() do os.sleep(0.1) end + if checkRepeat(recipe) then goto insertRecipes end + end + AT.clearAll(AD) + screen.write(" ... finished task!\n") + network.broadcast(id, "complete") +end + +local function processMessage(localAddress, remoteAddress, port, distance, type, eventType, value2, value3) + if eventType == "startAssembly" then + local recipe = S.unserialize(value2) + screen.write("Starting assembly of "..recipe.label) + processRecipe(recipe) + elseif eventType == "clear" then + AT.clearAll(AD) + end +end + +local function quit() + screen.write("Quitting...") + event.ignore("modem_message", processMessage) + event.ignore("key_up", processKey) + os.exit() +end + +function processKey(event, address, key, code, player) + local value = uc.char(key) + if value == "." then + quit() + end +end + +local function startAssembly() + network.open(100) + local storedID = io.open("ID", "r") + if storedID == nil then + id = requestID() + storedID = io.open("ID", "w") + storedID:write(id) + else + for line in io.lines("ID") do id = line + 0 end + end + storedID:close() + network.open(id) + AD = AU.buildClient() + AT.clearAll(AD) +end + +startAssembly() +event.listen("modem_message", processMessage) +event.listen("key_up", processKey) \ No newline at end of file diff --git a/Programs/Assembly Line/configure.lua b/Programs/Assembly Line/configure.lua deleted file mode 100644 index e851997..0000000 --- a/Programs/Assembly Line/configure.lua +++ /dev/null @@ -1,93 +0,0 @@ -comp=require("component"); event=require("event"); screen=require("term"); computer = require("computer"); thread = require("thread") - -function findAccess(type) - for address, component in comp.list() do - if component == type then - if type ~= "me_interface" then - return address - else - if comp.proxy(address).getItemsInNetwork ~= nil then - return address - end - end - end - end - return nil -end -local configure = {} - -function configure.getAddresses() - local file = io.open("addresses", "w") - local a, b, c - for item = 1, 15, 1 do - screen.write("Add item interface "..item.." ") - a, b, c = event.pull() - while a ~= "component_added" do - a, b, c = event.pull() - os.sleep() - end - screen.write(b.."\n") - file:write("input"..item..","..b.."\n") - end - for fluid = 1, 4, 1 do - screen.write("Add fluid interface "..fluid.." ") - a, b, c = event.pull() - while a ~= "component_added" do - a, b, c = event.pull() - end - screen.write(b.."\n") - file:write("fluid"..fluid..","..b.."\n") - end - for itemTransposer = 1, 15, 1 do - screen.write("Add item transposer "..itemTransposer.." ") - a, b, c = event.pull() - while a ~= "component_added" do - a, b, c = event.pull() - os.sleep() - end - screen.write(b.."\n") - file:write("inputTransposer"..itemTransposer..","..b.."\n") - end - for fluidTransposer = 1, 4, 1 do - screen.write("Add fluid transposer "..fluidTransposer.." ") - a, b, c = event.pull() - while a ~= "component_added" do - a, b, c = event.pull() - end - screen.write(b.."\n") - file:write("fluidTransposer"..fluidTransposer..","..b.."\n") - end - screen.write("Add data access hatch ") - a, b, c = event.pull() - while a ~= "component_added" do - a, b, c = event.pull() - end - screen.write(b.."\n") - file:write("data,"..b.."\n") - - local networkAccess = findAccess("me_interface") - if networkAccess == nil then - screen.write("Can't find a valid interface! Exiting...\n") - os.exit() - else file:write("items,"..networkAccess.."\n") end - os.sleep(0.5) - local databaseAccess = comp.database - if databaseAccess == nil then - screen.write("Can't find a valid database! Exiting...\n") - os.exit() - else file:write("database,"..databaseAccess.address.."\n") end - - local chestAccess = comp.inventory_controller - if chestAccess == nil then - screen.write("Can't find a valid inventory controller! Exiting...\n") - os.exit() - else file:write("inventory,"..chestAccess.address.."\n") end - - local controller = comp.gt_machine - if controller == nil then - screen.write("Can't find a valid Assembly Line! Exiting...\n") - os.exit() - else file:write("controller,"..controller.address.."\n") end - screen.write("All done!\n") - end -return configure \ No newline at end of file diff --git a/Programs/Assembly Line/dictionary.lua b/Programs/Assembly Line/dictionary.lua new file mode 100644 index 0000000..a0f8024 --- /dev/null +++ b/Programs/Assembly Line/dictionary.lua @@ -0,0 +1,39 @@ +fluidMap = { + ["fluid.molten.solderingalloy"] = {name = "gt.metaitem.99.314.name", size = 144}, + ["fluid.lubricant"] = {name = "gt.Volumetric_Flask.name", size = 250}, + ["IC2 Coolant"] = {name = "Coolant Cell", size = 1000}, + ["fluid.molten.styrenebutadienerubber"] = {name = "gt.metaitem.99.635.name", size = 144}, + ["fluid.molten.niobiumtitanium"] = {name = "gt.metaitem.99.360.name", size = 144}, + ["fluid.molten.tritanium"] = {name = "gt.metaitem.99.329.name", size = 144}, + ["fluid.Neon"] = {name = "Neon Cell", size = 1000}, + ["fluid.molten.naquadria"] = {name = "gt.metaitem.99.327.name", size = 144} +} + +dictionary = { + ["gt.metaitem.01.32705.name"] = "gt.metaitem.03.32084.name", --IV + ["gt.metaitem.03.32086.name"] = "gt.metaitem.03.32084.name", + ["gt.metaitem.03.32089.name"] = "gt.metaitem.03.32084.name", + + ["gt.metaitem.03.32085.name"] = "gt.metaitem.03.32083.name", --EV + ["gt.metaitem.01.32704.name"] = "gt.metaitem.03.32083.name", +} + +-- dictlist = { +-- {"Nanoprocessor Assembly","Quantumprocessor","Workstation"}, --EV +-- {"Crystalprocessor","Elite Nanocomputer","Quantumprocessor Assembly","Mainframe"}, --IV +-- {"Master Quantumcomputer","Wetwareprocessor","Crystalprocessor Assembly","Nanoprocessor Mainframe"}, -- LuV +-- {"Bioprocessor","Wetwareprocessor Assembly","Ultimate Crystalcomputer","Quantumprocessor Mainframe"}, --ZPM +-- {"Wetware Supercomputer","Bioprocessor Assembly","Crystalprocessor Mainframe"}, -- UV +-- {"Wetware Mainframe","Bioware Supercomputer"}, -- UHV +-- {"Bio Mainframe"} -- UEV +-- } + +-- dictlist = { +-- {"gt.metaitem.03.32083.name","gt.metaitem.03.32085.name","gt.metaitem.01.32704.name"}, --EV +-- {"gt.metaitem.03.32089.name","gt.metaitem.03.32086.name","gt.metaitem.03.32084.name","gt.metaitem.01.32705.name"}, --IV +-- {"gt.metaitem.03.32087.name","gt.metaitem.03.32092.name","gt.metaitem.03.32096.name","gt.metaitem.01.32706.name"}, -- LuV +-- {"gt.metaitem.03.32097.name","gt.metaitem.03.32093.name","gt.metaitem.03.32090.name","gt.metaitem.03.32088.name"}, --ZPM +-- {"gt.metaitem.03.32091.name"}, -- UV +-- {"gt.metaitem.03.32095.name","gt.metaitem.03.32099.name"}, -- UHV +-- {"gt.metaitem.03.32120.name"} -- UEV +-- } \ No newline at end of file diff --git a/Programs/Assembly Line/oreDict.lua b/Programs/Assembly Line/oreDict.lua deleted file mode 100644 index 9f2df0d..0000000 --- a/Programs/Assembly Line/oreDict.lua +++ /dev/null @@ -1,28 +0,0 @@ --- dictlist = { --- {"Nanoprocessor Assembly","Quantumprocessor","Workstation"}, --EV --- {"Crystalprocessor","Elite Nanocomputer","Quantumprocessor Assembly","Mainframe"}, --IV --- {"Master Quantumcomputer","Wetwareprocessor","Crystalprocessor Assembly","Nanoprocessor Mainframe"}, -- LuV --- {"Bioprocessor","Wetwareprocessor Assembly","Ultimate Crystalcomputer","Quantumprocessor Mainframe"}, --ZPM --- {"Wetware Supercomputer","Bioprocessor Assembly","Crystalprocessor Mainframe"}, -- UV --- {"Wetware Mainframe","Bioware Supercomputer"}, -- UHV --- {"Bio Mainframe"} -- UEV --- } - -dictlist = { - {"gt.metaitem.03.32083.name","gt.metaitem.03.32085.name","gt.metaitem.01.32704.name"}, --EV - {"gt.metaitem.03.32089.name","gt.metaitem.03.32086.name","gt.metaitem.03.32084.name","gt.metaitem.01.32705.name"}, --IV - {"gt.metaitem.03.32087.name","gt.metaitem.03.32092.name","gt.metaitem.03.32096.name","gt.metaitem.01.32706.name"}, -- LuV - {"gt.metaitem.03.32097.name","gt.metaitem.03.32093.name","gt.metaitem.03.32090.name","gt.metaitem.03.32088.name"}, --ZPM - {"gt.metaitem.03.32091.name"}, -- UV - {"gt.metaitem.03.32095.name","gt.metaitem.03.32099.name"}, -- UHV - {"gt.metaitem.03.32120.name"} -- UEV -} - -dictionary = { - ["gt.metaitem.01.32705.name"] = "gt.metaitem.03.32084.name", --IV - ["gt.metaitem.03.32086.name"] = "gt.metaitem.03.32084.name", - ["gt.metaitem.03.32089.name"] = "gt.metaitem.03.32084.name", - - ["gt.metaitem.03.32085.name"] = "gt.metaitem.03.32083.name", --EV - ["gt.metaitem.01.32704.name"] = "gt.metaitem.03.32083.name", -} \ No newline at end of file diff --git a/Programs/Assembly Line/recipeServer.lua b/Programs/Assembly Line/recipeServer.lua new file mode 100644 index 0000000..fc02f4e --- /dev/null +++ b/Programs/Assembly Line/recipeServer.lua @@ -0,0 +1,167 @@ +comp=require("component"); event=require("event"); screen=require("term"); computer = require("computer"); thread = require("thread"); uc = require("unicode") +AU = require("util") +local S = require("serialization") +local D = require("dictionary") +local network = comp.modem +local mainChannel = 100 +-- mainChannel = Main channel for bi-directional communication + +local knownAssemblyLines = 0 +local assemblyStatus = {} +local run = true +local function getIDs() + local knownIDs = io.open("IDs", "r") + if knownIDs == nil then + knownAssemblyLines = 0 + else + for line in io.lines("IDs") do + knownAssemblyLines = knownAssemblyLines + 1 + network.open(mainChannel+knownAssemblyLines) + assemblyStatus[mainChannel+knownAssemblyLines] = false + end + end +end +local function contains(t, value) + for k, v in pairs(t) do + if v == value then return true end + end + return false +end +local function getFree() + for i = mainChannel, mainChannel + knownAssemblyLines, 1 do + if assemblyStatus[i] == false then return i end + end + return nil +end + +local function processMessage(type, localAddress, remoteAddress, port, distance, eventType, value2, value3) + if eventType == "requestID" then + knownAssemblyLines = knownAssemblyLines + 1 + local newID = mainChannel + knownAssemblyLines + assemblyStatus[newID] = false + network.broadcast(mainChannel, "sendID", newID) + local knownIDs = io.open("IDs", "a") + knownIDs:write(newID.."\n") + knownIDs:close() + elseif eventType == "complete" then + assemblyStatus[port] = false + end +end + +local function quit() + screen.write("Quitting...") + event.ignore("modem_message", processMessage) + event.ignore("key_up", processKey) + run = false +end + +function processKey(event, address, key, code, player) + local value = uc.char(key) + if value == "." then + quit() + elseif value == "a" then + AU.getRecipes(RL) + end +end + +function startAssembly(assemblyport, recipe) + assemblyStatus[assemblyport] = recipe.label + network.broadcast(assemblyport, "startAssembly", S.serialize(recipe)) +end +local function spairs(t, order) + local keys = {} + for k in pairs(t) do keys[#keys+1] = k end + if order then table.sort(keys, function(a, b) return order(t, a, b) end) else table.sort(keys) end + local i = 0 + return function() + i = i + 1 + if keys[i] then return keys[i], t[keys[i] ] end + end +end +function matchRecipe(recipes) + local items = comp.me_interface.getItemsInNetwork() + local foundItems = {} + if #items > 0 then for i = 1, #items, 1 do foundItems[items[i].label] = items[i].size end end + for outputLabel, recipe in spairs(recipes, function(t,a,b) return t[b].inputs < t[a].inputs end) do + local found = 0 + local craftable = 1000 + for i = 1, recipe.inputs, 1 do + local label, requiredAmount = recipe["input"..i].name, recipe["input"..i].amount + if dictionary[label] ~= nil then label = dictionary[label] end + if foundItems[label] == nil then break + else + local existingAmount = foundItems[label] + if existingAmount >= requiredAmount then + found = found + 1 + craftable = math.min(math.floor(existingAmount/requiredAmount), craftable) + end + end + end + for i = 1, recipe.fluids, 1 do + local label, requiredAmount + if fluidMap[recipe["fluid"..i].name] ~= nil then + label, requiredAmount = fluidMap[recipe["fluid"..i].name].name, recipe["fluid"..i].amount / fluidMap[recipe["fluid"..i].name].size + else + break + end + if foundItems[label] == nil then break + else + local existingAmount = foundItems[label] + if existingAmount >= requiredAmount then + found = found + 1 + craftable = math.min(math.floor(existingAmount/requiredAmount), craftable) + end + end + end + if found == recipe.inputs + recipe.fluids then return recipe, craftable end + end + return nil +end +RL = {} +local function scheduleTasks() + local recipe, craftable = matchRecipe(RL) + if recipe ~= nil then + if craftable <= 8 then + if not contains(assemblyStatus, recipe.label) then + local taskid = getFree() + if taskid ~= nil then + screen.write("Started assembly of "..recipe.label.." with AL #"..taskid.."\n") + startAssembly(taskid, recipe) + else + screen.write("No free assembly lines.\n") + end + end + return true + else + while craftable > 0 do + local taskid = getFree() + if taskid ~= nil then + startAssembly(taskid, recipe) + screen.write("Started assembly of "..recipe.label.." with AL #"..taskid.."\n") + else + screen.write("No free assembly lines.\n") + end + craftable = craftable - 8 + end + end + return true + else + return false + end +end + +--"gt.metaitem.01.32606.name" +local function initializeServer() + network.open(mainChannel) + getIDs() + AU.getRecipes(RL) +end + +initializeServer() +event.listen("modem_message", processMessage) +event.listen("key_up", processKey) + +while run do + scheduleTasks() + os.sleep(2) +end \ No newline at end of file diff --git a/Programs/Assembly Line/transport.lua b/Programs/Assembly Line/transport.lua index c745b5a..b46c60e 100644 --- a/Programs/Assembly Line/transport.lua +++ b/Programs/Assembly Line/transport.lua @@ -1,41 +1,38 @@ -local comp=require("component"); local event=require("event"); local screen=require("term"); local computer = require("computer") +comp=require("component"); event=require("event"); screen=require("term"); computer = require("computer"); thread = require("thread") local transport = {} -function transport.waitForAssemblyline(time, assemblyController) - local startTime = computer.uptime() - --Wait for assembling to start - while not assemblyController.hasWork() and computer.uptime() < startTime + 10 do - os.sleep(0.3) +function transport.set(interface, database, databaseSlot, amount) + interface.setInterfaceConfiguration(1, database.address, databaseSlot, amount) +end +function transport.move(transposer, amount, slot) + transposer.transferItem(0, 1, amount, 1, slot) +end +function transport.empty(transposer) + transposer.transferItem(1, 0, 64, 2, 9) +end +function transport.clear(interface) + interface.setInterfaceConfiguration(1, comp.database.address, 1, 0) +end +function transport.check(transposer, item, amount) + local itemstack = transposer.getStackInSlot(0, 1) + if itemstack == nil then return false else + if itemstack.label == item and itemstack.size >= amount then return true else return false end end +end +function transport.isEmpty(transposer, slot) + local itemstack = transposer.getStackInSlot(1, slot) + if itemstack == nil then return true else return false end +end +function transport.clearAll(assemblydata) + for i = 1, 15, 1 do + if assemblydata["input"..i].getInterfaceConfiguration(1) ~= nil then + transport.clear(assemblydata["input"..i]) + end end - if not assemblyController.hasWork() then - screen.write(" Error with starting assembly!") - else - screen.write(" Process started ...") - local progress = assemblyController.getWorkMaxProgress() - assemblyController.getWorkProgress() - while computer.uptime() < (startTime + (time / 20)) and progress > 100 and assemblyController.hasWork() do - os.sleep(0.1) - progress = assemblyController.getWorkMaxProgress() - assemblyController.getWorkProgress() + for i = 1, 4, 1 do + if assemblydata["fluid"..i].getInterfaceConfiguration(1) ~= nil then + transport.clear(assemblydata["fluid"..i]) end end end - -function transport.clearInterfaces(assemblyData, itemFrom, itemTo, fluidFrom, fluidTo) - itemFrom = itemFrom or 1 - itemTo = itemTo or 15 - fluidFrom = fluidFrom or 1 - fluidTo = fluidTo or 4 - local database = assemblyData["database"] - if itemFrom > 0 then - for i = itemFrom, itemTo, 1 do - if assemblyData["input"..i].getInterfaceConfiguration(1) ~= nil then assemblyData["input"..i].setInterfaceConfiguration(1, database.address, 1, 0) end - end - end - if fluidFrom > 0 then - for i = fluidFrom, fluidTo, 1 do - if assemblyData["fluid"..i].getInterfaceConfiguration(1) ~= nil then assemblyData["fluid"..i].setInterfaceConfiguration(1, database.address, 1, 0) end - end - end -end - return transport \ No newline at end of file diff --git a/Programs/Assembly Line/util.lua b/Programs/Assembly Line/util.lua new file mode 100644 index 0000000..2193dea --- /dev/null +++ b/Programs/Assembly Line/util.lua @@ -0,0 +1,124 @@ +comp=require("component"); event=require("event"); screen=require("term"); computer = require("computer"); thread = require("thread") + +local assemblyUtil = {} + +local function addEntries(file, prompt, amount, type) + local a, b, c + for i = 1, amount, 1 do + screen.write(prompt.." "..i.." ") + a, b, c = event.pull() + while a ~= "component_added" do a, b, c = event.pull(); os.sleep() end + file:write(type..i..","..b.."\n") + screen.write(b.."\n") + end +end +local function addAuxilary(file, proxy, type) + if proxy == nil then + screen.write("Cant find a valid "..type.."! Exiting...\n") + os.exit() + else + file:write(type..","..proxy.address.."\n") + end +end +local function split(s, sep) + local fields = {}; local sep = sep or " "; local pattern = string.format("([^%s]+)", sep) + string.gsub(s, pattern, function(c) fields[#fields + 1] = c end) + return fields +end +local function proxy(address) + machineAddress = comp.get(address) + if(machineAddress ~= nil) then return comp.proxy(machineAddress) else return nil end +end +local function configureClient() + local file = io.open("addresses", "w") + addEntries(file, "Add item interface", 15, "input") + addEntries(file, "Add fluid interface", 4, "fluid") + addEntries(file, "Add item transposer", 15, "inputTransposer") + addEntries(file, "Add fluid transposer", 4, "fluidTransposer") + addAuxilary(file, comp.me_interface, "items") + addAuxilary(file, comp.database, "database") + addAuxilary(file, comp.gt_machine, "controller") +end +function assemblyUtil.buildClient() + screen.write("Starting Assembly Line initalization...") + local assemblyStructure = {} + local file = io.open("addresses", "r") + if file == nil then + screen.write(" no address configuration found, configuring:\n") + configureClient() + file = io.lines("addresses") + else + file = io.lines("addresses") + end + for line in file do + screen.write(".") + local tokens = split(line, ",") + assemblyStructure[tokens[1]] = proxy(tokens[2]) + end + screen.write("\n") + return assemblyStructure +end +local function voltageToTier(voltage) + local maxTier = 15 + local tier = maxTier + voltage = voltage - 1 + local tierVoltage = 32 * math.pow(4, tier - 1) + while voltage % tierVoltage == voltage do + tier = tier - 1 + tierVoltage = 32 * math.pow(4, tier - 1) + end + return tier + 1 +end +function copyPattern(interface, slot, recipe, database) + for i = 1, recipe.inputs, 1 do + local item = recipe["input"..i] + local name = item.name + if dictionary[name] ~= nil then name = dictionary[name] end + interface.setInterfacePatternInput(slot, database, databaseMap[name], item.amount, i) + end +end +function getControllerTier(assemblyData) + local controller = assemblyData["controller"] + return voltageToTier(math.floor(string.gsub(string.sub(controller.getSensorInformation()[4], 1, string.find(controller.getSensorInformation()[4], "/")-1), "([^0-9]+)", "") + 0)) +end +local function addRecipe(recipelist, slot, source, sourceSide) + if source.getStackInSlot(sourceSide, slot) ~= nil then + local pattern = source.getStackInSlot(sourceSide, slot) + recipelist[pattern.output] = {} + recipelist[pattern.output]["label"] = pattern.output + recipelist[pattern.output]["time"] = pattern.time + recipelist[pattern.output]["inputs"] = 0 + recipelist[pattern.output]["fluids"] = 0 + recipelist[pattern.output]["tier"] = voltageToTier(pattern.eu) + if pattern.inputItems ~= nil then + local items = pattern.inputItems + for i = 1, #items, 1 do + recipelist[pattern.output]["input"..i] = {name = items[i][1], amount = items[i][2]} + recipelist[pattern.output]["inputs"] = recipelist[pattern.output]["inputs"] + 1 + end + end + if pattern.inputFluids ~= nil then + local fluids = pattern.inputFluids + for i = 1, #fluids do + recipelist[pattern.output]["fluid"..i] = {name = fluids[i][1], amount = fluids[i][2]} + recipelist[pattern.output]["fluids"] = recipelist[pattern.output]["fluids"] + 1 + end + end + end +end +function assemblyUtil.getRecipes(recipelist) + for address, type in pairs(comp.list()) do + if type == "transposer" then + local dataSource = proxy(address) + for side = 0, 5 do + if dataSource.getInventorySize(side) ~= nil then + local slots = dataSource.getInventorySize(side) + for slot = 1, slots, 1 do + addRecipe(recipelist, slot, dataSource, side) + end + end + end + end + end +end +return assemblyUtil \ No newline at end of file diff --git a/Programs/autofeeder.lua b/Programs/autofeeder.lua new file mode 100644 index 0000000..7d5161c --- /dev/null +++ b/Programs/autofeeder.lua @@ -0,0 +1,38 @@ +Comp=require("component") +local transposer = Comp.transposer +local players = {["Sampsa"] = 3, ["Dark"] = 2} +local function findEmptyCans(player) + local allItems = transposer.getAllStacks(players[player]).getAll() + for i = 0, 39, 1 do if allItems[i].label == "Tin Can" then return i + 1 end end + return nil +end + +local function checkLevel(player) + local itemStack = transposer.getStackInSlot(players[player], 19) + if itemStack ~= nil then return itemStack.size else return nil end +end + +local function transferFood(player) + transposer.transferItem(0, players[player], 64, 1, 19) +end +local function transferEmpty(player) + local slot = findEmptyCans(player) + if slot ~= nil then transposer.transferItem(players[player], 0, 64, slot, 2) end +end + +local function check(player) + if transposer.getInventorySize(players[player]) == 40 then + local inInventory = checkLevel(player) + if inInventory ~= nil then + if inInventory < 40 then transferFood(player) end + os.sleep(0.2) + transferEmpty(player) + end + end +end + +while true do + check("Sampsa") + check("Dark") + os.sleep(2) +end \ No newline at end of file