It took me a while to wrap my head around the issue. I realize you can do this with other mods (not using a turtle), at the same time I completely respect wanting to figure out how to get a turtle to do it for you. 'nuf said on that.
As a courtesy to others who wish to reply, I am posting your code in the following spoiler:
Original Code
-- Recipes to build
recipes = {
storagecell = {
redstone = {1,3,9,11},
quartzcrystal = {2,5,7,10},
mebasicprocessor = {6}
},
storagesegment = {
redstone = {1,3,9,11},
mebasicprocessor = {2},
glass = {6},
storagecell = {5,6,10}
},
storageblock = {
glowstone = {1,3,9,11},
storagesegment = {5,6,10},
glass = {6},
meadvancedprocessor = {2}
},
me16kstorage = {
glass = {1,3},
redstone = {2,5,7},
storageblock = {6},
iron = {9,10,11}
}
}
appen1 = "appeng.materials." -- Need theese to get the correct name from applied energistics
appen2 = ".name"
chest = peripheral.wrap("left")
function getSlot(slot)
local info = chest.getStackInSlot(slot)
if info then
return info
else
return false
end
end
function split(inputstr, sep) -- splits a string into a table
if sep == nil then
sep = "%s"
end
t={} ; i=1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
t[i] = str
i = i + 1
end
return t
end
function getName(slot) -- Returns the name, And if its applied energistics remove the long names
local convert = {
appen1.."quartzcrystal"..appen2,
appen1.."mebasicprocessor"..appen2,
appen1.."storagecell"..appen2,
appen1.."storagesegment"..appen2,
appen1.."storageblock"..appen2,
appen1.."meadvancedprocessor"..appen2
}
local info = getSlot(slot)
if info then
info.name = string.lower(info.name)
for k,v in pairs(convert) do -- Search through table and find appen names
if info.name == v then
info.name = split(info.name, ".")
info.name = info.name[3]
return info.name
end
end
return info.name
else
return false
end
end
function getQty(slot)
local info = getSlot(slot)
if info then
return info.qty
else
return false
end
end
function getChest() -- Returns the entire inventory of the chest as a table for faster access
local size = chest.getInventorySize()
local content = {}
chest.condenseItems()
for i = 1, size do
local name = getName(i)
local qty = getQty(i)
if name then
if content[name] then
content[name] = content[name] + qty
else
content[name] = qty
end
else
break
end
end
return content
end
function getRecipe(name) -- Creates a table which displays needed item and quantity instead of need item and position as recipes does
local recipe = {}
for k,v in pairs(name) do
if recipe[k] then
recipe[k] = recipe[k] + #v
else
recipe[k] = #v
end
end
return recipe
end
function compare(name, qty) -- Checks if name is in the chest, aswell as the correct quantity or more
local content = getChest()
local foundName = ""
local foundQty = 0
for k,v in pairs(content) do
if k == name then
if v >= qty then
return true
else
foundQty = v or 0
end
else
foundName = k
end
end
return false, foundQty
end
function printT(t)
for k,v in pairs(t) do
print(k..": "..v)
end
end
function gotRecipe(recipe, amount) -- Checks a recipe if everything is in the chest, Returns missing materials
amount = amount or 1
local missing = {}
local content = getChest()
local recipe = getRecipe(recipe)
for itemName,itemQty in pairs(recipe) do
found, qty = compare(itemName, itemQty * amount)
if not found then
if missing[itemName] then
missing[itemName] = missing[itemName] + ((itemQty*amount)-qty)
else
missing[itemName] = itemQty*amount-qty
end
end
end
return missing
end
function isRecipe(name) -- Checks if name is a recipe in this code or not
if recipes[name] then
return true
else
return false
end
end
function gotEnough(recipe, amount)
amount = amount or 1
local missing = gotRecipe(recipe, amount)
if missing then
for k,v in pairs(missing) do
if isRecipe(k) then
end
end
end
end
What you are trying to do is create some sort of database which, when queried properly, can tell you what recipes you could make based on your current inventory levels. In addition, there are hierarchical needs as well, e.g.: I want to make x which takes 1 crafted y and 3 headstone. Hmm. Do I have what I need to make the crafted y?
In your current code, you are limited to hard coded tables. I would recommend you come up with a structure you are happy with for an individual recipe and then store a table of recipes to a file, reading the file whenever that is necessary. Then you could write routines to add/edit/delete recipes from/to the file.
You may need to create several tables. One being a table of all ingredients you currently have. Another being a table with recipes. That way you can check the ingredients as you select a recipe. For each ingredient, you should also have a flag which you set to decide if the ingredient is elemental (cannot be crafted, must be supplied) or can be crafted with recipe id[x]. That way if it finds the ingredient, it is happy, but if it does not, it further checks to see if it has to request it or if the turtle can craft it itself.
Here is my concept of the algorithm:
I want to make Recipe ID "Thingy".
local availableInventoryTable {} – – structure is { {itemID,quantity}, {itemID,quantity} , etc }
local missingInventoryTable {} – structure is { {itemID,quantity}, {itemID,quantity} , etc }
function checkIngredients(recipeID) – returns table of need or false- Load table of requirements
- requirement = {item, recipeID} where recipeID= nil if elemental
- for each requirement, check inventory
- found
- deduct from available inventory and move to next requirement
- not found
- can I craft it? get recipeID
- need = checkIngredients(recipeID) (this is a recursive call)
- if need = false that means I can make it and I have updated availableInventoryTable
- if need is a table, then update missingInventoryTable
- I can't craft it, add requirement to need – structure is { {itemID,quantity}, {itemID,quantity} , etc }
- return false if we have ingredients or we can craft ingredients
- return need if we are missing ingredients.
Useage:
currentInvetoryTable structure is { {itemD,quantity}, {itemD,quantity} , etc }
availableInventoryTable {}= currentInventoryTablelocal need = checkIngredients(recipeID)
if need ==false then
[indent=1]I have everything[/indent]
else
[indent=1]for k,v in pairs(need) do[/indent]
[indent=2]
missingInventoryTable.k = missingInventoryTable.k + v[/indent]
[indent=1]
end[/indent]
[indent=1]
do something to notify user of missing Inventory[/indent]
end
This is all highly conceptual, and I can see that you have begun implementing portions of these ideas. However, consider what I am saying and see if that helps you.
As for your code itself, you follow decent indentation style, and your choice of naming functions and variables goes a long way towards making self-documenting code.
Also, just some advice: people on this site are willing to help – but they all volunteer. Try not to get snippy, especially when you drop code which takes time to sort through.