Rework assembly line code to support parallels and data banks

This commit is contained in:
Sampsa 2020-11-11 00:55:42 +02:00
parent 9f86c28d46
commit 51c1d57ba5
10 changed files with 524 additions and 440 deletions

View File

@ -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)

View File

@ -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%

View File

@ -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)

View File

@ -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

View File

@ -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
-- }

View File

@ -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",
}

View File

@ -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

View File

@ -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

View File

@ -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

38
Programs/autofeeder.lua Normal file
View File

@ -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