mirror of
https://github.com/S4mpsa/InfOS.git
synced 2025-09-08 22:59:38 -04:00
Rework assembly line code to support parallels and data banks
This commit is contained in:
parent
9f86c28d46
commit
51c1d57ba5
@ -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)
|
||||
|
@ -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%
|
122
Programs/Assembly Line/assemblyClient.lua
Normal file
122
Programs/Assembly Line/assemblyClient.lua
Normal 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)
|
@ -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
|
39
Programs/Assembly Line/dictionary.lua
Normal file
39
Programs/Assembly Line/dictionary.lua
Normal 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
|
||||
-- }
|
@ -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",
|
||||
}
|
167
Programs/Assembly Line/recipeServer.lua
Normal file
167
Programs/Assembly Line/recipeServer.lua
Normal 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
|
@ -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
|
124
Programs/Assembly Line/util.lua
Normal file
124
Programs/Assembly Line/util.lua
Normal 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
38
Programs/autofeeder.lua
Normal 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
|
Loading…
x
Reference in New Issue
Block a user