This commit is contained in:
Crispy 2025-05-22 20:51:25 +02:00
commit 12ffbdc45d
76 changed files with 79368 additions and 0 deletions

3
computer/13/.settings Normal file
View file

@ -0,0 +1,3 @@
{
[ "motd.enable" ] = false,
}

101
computer/13/inventory.lua Normal file
View file

@ -0,0 +1,101 @@
pp = require("cc.pretty")
pFront = peripheral.wrap("front")
pDown = peripheral.wrap("bottom")
function findItems(item_list, target)
for i, v in pairs(item_list) do
if stripModname(v.name) == target then
return i
end
end
return nil
end
-- uses selected item
function insertForward(slot, count)
turtle.dropDown(count)
pFront.pullItems("bottom", 1, 64, slot)
end
function takeForward(slot)
-- pDown.pullItems("front", slot, 64, 1)
peripheral.call("bottom", "pullItems", "front", slot or 1)
turtle.suckDown()
end
function insertForwardDepot(count)
turtle.dropDown(count)
peripheral.call("front", "pullItem", "bottom")
end
function takeForwardDepot()
-- pDown.pullItems("front", slot, 64, 1)
peripheral.call("front", "pushItem", "bottom")
turtle.suckDown()
end
function takeItems(type, count)
item_list = pFront.list()
slot = findItems(item_list, type)
if slot == nil then
printError("could not find item " .. type .. " in chest")
return false
end
empty_slot = pFront.size()
-- todo error if not empty
pFront.pullItems("front", 1, 64, empty_slot) -- empty first slot
pFront.pullItems("front", slot, 64, 1) -- get target item to first slot
pFront.pullItems("front", empty_slot, 64, slot) -- empty last slot for next time
return turtle.suck(count)
end
function selectItem(name, has_nbt)
has_nbt = has_nbt or false
if name == nil or name == "nil" then
for i = 1,16 do
if turtle.getItemCount(i) == 0 then
turtle.select(i)
return
end
end
printError("no empty slot found")
return
end
for i = 1,16 do
detail = turtle.getItemDetail(i, true);
if detail and stripModname(detail.name) == name then
if has_nbt == (detail.nbt ~= nil) then
turtle.select(i)
return
end
end
end
printError("missing item", name, "nbt=", has_nbt)
end
function getMissing(needed_items)
missing = {}
for name,count in pairs(needed_items) do
missing[name] = count
end
target_contents = peripheral.call("front", "list")
for _, target_item in pairs(target_contents) do
for name, missing_count in pairs(missing) do
if stripModname(target_item.name) == name then
missing[name] = missing_count - target_item.count
if missing[name] < 1 then
missing[name] = nil
end
break
end
end
end
pp.pretty_print(missing)
return missing
end

View file

@ -0,0 +1,4 @@
keep_stocked = {
kelp = 10,
flint = 10
}

111
computer/13/machines.lua Normal file
View file

@ -0,0 +1,111 @@
require("inventory")
require("pathfinding")
function mill(extra_items)
-- 0.4 second/item
go_to(vector.new(-4,0,0),"south")
item_count = 0
if turtle.getItemCount() ~= 0 then
item_count = 1
end
insertForward(1, 1)
for _,item in pairs(extra_items) do
item_count = item_count + item.count
selectItem(item.name)
insertForward(1, item.count)
end
print(item_count,"items")
sleep(0.5)
sleep(0.4 * item_count)
for i = 1, 10 do
takeForward(i)
end
end
function deploy(extra_items, nbt)
-- extra_items should only be one item
go_to(vector.new(2,0,0), "south")
insertForwardDepot(1)
goUp()
goUp()
selectItem(extra_items[1].name, nbt)
turtle.dropUp(1)
peripheral.call("front", "pullItem", "top")
goDown()
goDown()
takeForwardDepot()
end
function deploy_tool(extra_items)
deploy(extra_items, true)
goUp()
goUp()
peripheral.call("front", "pushItem", "top")
turtle.suckUp()
end
function furnace(extra_items)
go_to(vector.new(1,0,0), "south")
item_count = 0
if turtle.getItemCount() ~= 0 then
item_count = 1
end
insertForward(1, 1)
for _,item in pairs(extra_items) do
item_count = item_count + item.count
selectItem(item.name)
insertForward(1, item.count)
end
wait_time = 10 * item_count
-- peripheral.call("front", "")
-- TODO refuel
sleep(wait_time)
takeForward(3)
end
function press(_)
go_to(vector.new(-1,0,0), "south")
insertForwardDepot(1)
sleep(1)
takeForwardDepot()
end
function compact(extra_items) end
function mix(extra_items)
go_to(vector.new(-3,0,0), "south")
insertForward(1, 1)
for _, item in pairs(extra_items) do
selectItem(item.name)
insertForward(nil, item.count)
end
goUp()
goUp()
goDown()
goDown()
sleep(10)
-- todo wait until ingredients are gone
takeForward(10)
end
function craft(extra_items)
slot = 5
for _, item in pairs(extra_items) do
slot = slot + 1
if slot == 9 then
slot = 10
elseif slot == 13 then
slot = 14
end
if item.name ~= "nil" then
selectItem(item.name)
turtle.transferTo(slot, 1)
end
end
turtle.craft()
end
return {
mill = mill,
deploy = deploy,
deploy_tool = deploy_tool,
furnace = furnace,
press = press,
compact = compact,
mix = mix,
craft = craft
}

View file

@ -0,0 +1,60 @@
require("recipes")
require("pathfinding")
iv = require("inventory")
-- belt recipe
getItems("minecraft:kelp", 4)
getItems("minecraft:charcoal", 1)
getItems("techreborn:rubber", 3)
-- furnace
go_to(vector.new(1,0,0), "south")
selectItem("minecraft:charcoal")
iv.insertForward(2)
selectItem("minecraft:kelp")
iv.insertForward(1)
sleep(40)
iv.takeForward(3)
selectItem("minecraft:dried_kelp")
for i = 1,3 do
-- deployer
go_to(vector.new(2,0,0), "south")
iv.insertForwardDepot(1)
go_to(vector.new(2,1,0), "south")
selectItem("techreborn:rubber")
turtle.dropUp(1)
goDown()
sleep(1)
iv.takeForwardDepot()
-- press
go_to(vector.new(-1,0,0), "south")
selectItem("minecraft:dried_kelp", true)
iv.insertForwardDepot(1)
sleep(1)
iv.takeForwardDepot()
-- deployer 2
selectItem("minecraft:dried_kelp", true)
print("selected partial belt")
go_to(vector.new(2,0,0), "south")
iv.insertForwardDepot(1)
go_to(vector.new(2,1,0), "south")
selectItem("minecraft:dried_kelp", false)
turtle.dropUp(1)
goDown()
sleep(1)
iv.takeForwardDepot()
-- press 2
selectItem("minecraft:dried_kelp", true)
go_to(vector.new(-1,0,0), "south")
iv.insertForwardDepot(1)
sleep(1)
iv.takeForwardDepot()
selectItem("minecraft:dried_kelp", true)
end
go_to(vector.new(0,0,0), "south")

128
computer/13/pathfinding.lua Normal file
View file

@ -0,0 +1,128 @@
pp = require("cc.pretty")
if _G.pos == nil then
_G.facing = "south"
_G.pos = vector.new(0,0,0)
file = fs.open("pos.txt", "r")
data = splitString(file.readAll())
_G.pos.x = tonumber(data[1])
_G.pos.y = tonumber(data[2])
_G.pos.z = tonumber(data[3])
_G.facing = data[4]
end
local up = vector.new(0,1,0)
local rightOf = {
south = "west",
west = "north",
north = "east",
east = "south"
}
local leftOf = {
west = "south",
north = "west",
east = "north",
south = "east"
}
local vecOf = {
north = vector.new(0,0,-1),
south = vector.new(0,0,1),
east = vector.new(1,0,0),
west = vector.new(-1,0,0),
}
function savePos()
fs.delete("pos.txt")
file = fs.open("pos.txt", "w")
file.write(_G.pos.x .. " " .. _G.pos.y .. " " .. _G.pos.z .. " " .. _G.facing)
end
function goUp()
if turtle.up() then
_G.pos.y = _G.pos.y + 1
savePos()
else
printError("failed to go up")
printError(pos)
end
end
function goDown()
if turtle.down() then
_G.pos.y = _G.pos.y - 1
savePos()
else
printError("failed to go down")
printError(pos)
end
end
function goLeft()
turtle.turnLeft()
_G.facing = leftOf[_G.facing]
savePos()
end
function goRight()
turtle.turnRight()
_G.facing = rightOf[_G.facing]
savePos()
end
function goForward()
if turtle.forward() then
_G.pos = _G.pos + vecOf[_G.facing]
savePos()
else
printError("failed to go forward")
printError(pos)
end
end
function goBack()
if turtle.back() then
_G.pos = _G.pos - vecOf[_G.facing]
savePos()
else
printError("failed to go backward")
printError(pos)
end
end
function stepTo(target)
local delta = target - _G.pos
-- print(delta)
if delta.y > 0 then
goUp()
elseif delta.y < 0 then
goDown()
elseif delta:dot(vecOf[_G.facing]) > 0 then
goForward()
elseif delta:dot(vecOf[_G.facing]:cross(up)) > 0 then
goRight()
else
goLeft()
end
end
function go_to(target, face)
while target ~= _G.pos do
stepTo(target)
-- print(_G.pos, _G.facing, target, face)
print(_G.pos, _G.facing)
end
if face and face ~= _G.facing then
if rightOf[_G.facing] == face then
goRight()
elseif leftOf[_G.facing] == face then
goLeft()
else
goRight()
goRight()
end
end
end

1
computer/13/pos.txt Normal file
View file

@ -0,0 +1 @@
0 0 0 south

83
computer/13/recipes.lua Normal file
View file

@ -0,0 +1,83 @@
pp = require("cc.pretty")
require("stringshit")
recipes = {}
function read_recipe(file)
product = file.readLine()
if product == nil then return nil end
base = nil
intermediate = nil
repeats = 1
while 1 do
line = file.readLine()
if string.sub(line, 1, 5) == "base " then
base = string.sub(line, 6)
elseif string.sub(line, 1, 13) == "intermediate " then
intermediate = string.sub(line, 14)
elseif string.sub(line, 1, 7) == "repeat " then
repeats = tonumber(string.sub(line, 8))
elseif line == "steps:" then
break
end
end
steps = {}
while 1 do
line = file.readLine()
if line == "" or line == nil then
break
end
words = splitString(line)
extra_items = {}
for i = 2, #words do
itemdata = splitString(words[i], ":")
table.insert(extra_items, {
name = itemdata[1],
count = tonumber(itemdata[2] or 1)
})
end
table.insert(steps, {
machine = words[1],
extra_items = extra_items
})
end
return {
product = product,
base = base,
intermediate = intermediate or base,
repeats = repeats,
steps = steps
}
end
function load_recipes()
file = fs.open("recipes.txt", "r")
if not file then
print("error: no recipes found")
return
end
recipes = {}
while 1 do
r = read_recipe(file)
if r == nil then break end
recipes[r.product] = r
end
return recipes
end
function ingredientsOf(recipe)
items = {}
for step_index = 1,#recipe.steps do
step = recipe.steps[step_index]
for _,item in pairs(step.extra_items) do
if item.name ~= "nil" then
old_sum = items[item.name] or 0
items[item.name] = old_sum + item.count * recipe.repeats
end
end
end
if recipe.base then
items[recipe.base] = (items[recipe.base] or 0) + 1
end
return items
end

117
computer/13/recipes.txt Normal file
View file

@ -0,0 +1,117 @@
belt_connector
base dried_kelp
intermediate dried_kelp
repeat 3
steps:
deploy rubber
press
deploy dried_kelp
press
dried_kelp
steps:
furnace kelp:8
rubber
steps:
mix sap:2
polished_rose_quartz
base rose_quartz
steps:
deploy_tool sand_paper
rose_quartz
steps:
mix quartz redstone:8
sand_paper
steps:
craft sand paper
paper
base sugar_cane
steps:
press
glass
steps:
furnace sand:8
sand
steps:
mill gravel:2
fluid_pipe
steps:
craft nil copper_sheet nil rubber rubber rubber nil copper_sheet
copper_sheet
base copper_ingot
steps:
press
andesite_alloy
steps:
craft andesite_alloy_block
note_block
steps:
craft birch_planks birch_planks birch_planks birch_planks redstone birch_planks birch_planks birch_planks birch_planks
birch_planks
steps:
craft birch_log
redstone
steps:
craft redstone_block
speaker
steps:
craft andesite_alloy andesite_alloy andesite_alloy andesite_alloy note_block andesite_alloy andesite_alloy polished_rose_quartz andesite_alloy
gearbox
steps:
craft nil cogwheel nil cogwheel andesite_casing cogwheel nil cogwheel
andesite_casing
base stripped_birch_log
steps:
deploy andesite_alloy
stripped_birch_log
base birch_log
steps:
deploy_tool flint_knife
stick
steps:
craft birch_planks nil nil birch_planks
iron_sheet
base iron_ingot
steps:
press
iron_ingot
steps:
craft iron_block
cogwheel
steps:
craft andesite_alloy bronze_sheet
flint_knife
steps:
craft flint nil nil stick
flint
base gravel
steps:
deploy_tool flint_knife
gravel
base cobblestone
steps:
mill

17
computer/13/sfx.lua Normal file
View file

@ -0,0 +1,17 @@
speaker = peripheral.wrap("left")
volume = 2
return {
success = function ()
speaker.playNote("pling",volume,4)
sleep(0.1)
speaker.playNote("pling",volume,8)
sleep(0.1)
speaker.playNote("pling",volume,16)
end,
fail = function ()
speaker.playNote("didgeridoo", volume, 6)
sleep(0.2)
speaker.playNote("didgeridoo", volume, 3)
end
}

View file

@ -0,0 +1,25 @@
function splitString(source, sep)
sep = sep or " "
elements = {}
for str in string.gmatch(source, "([^"..sep.."]+)") do
table.insert(elements, str)
end
return elements
end
function stripModname(name)
parts = splitString(name, ":")
if #parts ~= 2 then
printError("modname split failed")
printError(name)
end
return parts[2]
end
function len(table)
l = 0
for _, _ in pairs(table) do
l = l + 1
end
return l
end

3
computer/13/test.lua Normal file
View file

@ -0,0 +1,3 @@
s = require("sfx")
-- s.success()
s.fail()

154
computer/13/work.lua Normal file
View file

@ -0,0 +1,154 @@
pp = require("cc.pretty")
require("keep_stocked")
require("recipes")
sfx = require("sfx")
require("pathfinding")
use_machine = require("machines")
require("inventory")
go_to(vector.new(0,0,0), "south")
recipes = load_recipes()
print("known recipes:\n")
for k,_ in pairs(recipes) do
write(k)
write(", ")
end
write("\nchoose one: ")
function completion(partial)
list = {}
for k,_ in pairs(recipes) do
if string.sub(k, 1, #partial) == partial then
table.insert(list, string.sub(k, #partial + 1))
end
end
return list
end
input = splitString(read(nil, nil, completion))
target_product = input[1]
copies = input[2] or 1
if recipes[target_product] == nil then
print("I don't know how to make that, sorry")
return
end
-- pp.pretty_print(ingredientsOf(recipes[target_product]))
-- pp.pretty_print(recipes)
function doRecipe(recipe)
inited = false
for i = 1, recipe.repeats do
for _, step in pairs(recipe.steps) do
if inited then
selectItem(recipe.intermediate, true)
else
inited = true
selectItem(recipe.base, false)
end
use_machine[step.machine](step.extra_items)
-- read()
end
end
go_to(vector.new(0,0,0), "south")
for i = 1, 16 do
if turtle.getItemCount(i) ~= 0 then
turtle.select(i)
turtle.drop()
end
end
turtle.select(1)
end
todo = {}
for i = 1,copies do
table.insert(todo, recipes[target_product])
end
function listUncraftable(ingredients)
wait_for = {}
if len(ingredients) == 0 then
return wait_for
end
for name, count in pairs(ingredients) do
print("missing", count, name)
if recipes[name] == nil then
wait_for[name] = count
end
end
return wait_for
end
function tryCreating(recipe)
ingredients = ingredientsOf(recipe)
missing_ingredients = getMissing(ingredients)
if len(missing_ingredients) == 0 then
todo[#todo] = nil
turtle.select(1)
for item, count in pairs(ingredients) do
takeItems(item, count)
end
doRecipe(current_recipe)
-- for item, min_count in pairs(getMissing(keep_stocked)) do
-- table.insert(todo, recipes[item])
-- end
return nil
end
return missing_ingredients
end
while #todo > 0 do
-- for item, _count in pairs(getMissing(keep_stocked)) do
-- print("creating", item, "to keep stock up")
-- tryCreating(recipes[item])
-- end
current_recipe = todo[#todo]
-- ingredients = ingredientsOf(current_recipe)
pp.pretty_print(ingredients)
missing_ingredients = tryCreating(current_recipe)
if missing_ingredients then
-- missing_ingredients = getMissing(ingredients)
-- if len(missing_ingredients) == 0 then
-- todo[#todo] = nil
-- turtle.select(1)
-- for item, count in pairs(ingredients) do
-- takeItems(item, count)
-- end
-- doRecipe(current_recipe)
-- for item, min_count in pairs(getMissing(keep_stocked)) do
-- table.insert(todo, recipes[item])
-- end
-- else
wait_for = listUncraftable(missing_ingredients)
while len(wait_for) > 0 do
for name,count in pairs(wait_for) do
print("please supply", count, name, "manually")
end
print("press return to continue, q to quit")
sfx.fail()
if read() == "q" then
return
end
missing_ingredients = getMissing(ingredients)
wait_for = listUncraftable(missing_ingredients)
end
for name, count in pairs(missing_ingredients) do
if recipes[name] then
print("first making", count, name)
-- for i = 1,count do
table.insert(todo, recipes[name])
-- end
end
end
end
-- print("aaa")
-- read()
end
print("done!")
sfx.success()