feat: add goo v1
This commit is contained in:
parent
23ac9e7778
commit
ffeaf79532
@ -23,6 +23,7 @@ stds.cc = {
|
|||||||
"vector",
|
"vector",
|
||||||
"commands",
|
"commands",
|
||||||
"disk",
|
"disk",
|
||||||
|
"turtle",
|
||||||
"periphemu", -- CraftOS-PC emulator only
|
"periphemu", -- CraftOS-PC emulator only
|
||||||
"read",
|
"read",
|
||||||
"sleep",
|
"sleep",
|
||||||
|
|||||||
@ -20,3 +20,4 @@ All servers are automatically started at boot
|
|||||||
- `router`: route messages (you need to setup a router to be able to use all `apis/net` based programs and libs)
|
- `router`: route messages (you need to setup a router to be able to use all `apis/net` based programs and libs)
|
||||||
- `ping` : ping machines (use `apis/net`)
|
- `ping` : ping machines (use `apis/net`)
|
||||||
- `cube`: cube client for deployment (use `cube help` command for more details)
|
- `cube`: cube client for deployment (use `cube help` command for more details)
|
||||||
|
- `goo`: turtle program for Just Dire Things goo block processing.
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
local _VERSION = '2.0.1'
|
local _VERSION = '2.0.2'
|
||||||
|
|
||||||
local LIST_FILES = {
|
local LIST_FILES = {
|
||||||
-- startup
|
-- startup
|
||||||
@ -11,6 +11,7 @@ local LIST_FILES = {
|
|||||||
'programs/router.lua', -- router is not in servers folder because he's not ran on every machines
|
'programs/router.lua', -- router is not in servers folder because he's not ran on every machines
|
||||||
'programs/ping.lua',
|
'programs/ping.lua',
|
||||||
'programs/cube.lua',
|
'programs/cube.lua',
|
||||||
|
'programs/goo.lua',
|
||||||
-- apis
|
-- apis
|
||||||
'apis/net.lua',
|
'apis/net.lua',
|
||||||
'apis/eventloop.lua',
|
'apis/eventloop.lua',
|
||||||
|
|||||||
399
programs/goo.lua
Normal file
399
programs/goo.lua
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
local _VERSION = '0.1.0';
|
||||||
|
|
||||||
|
local args = table.pack(...);
|
||||||
|
local command = args[1];
|
||||||
|
|
||||||
|
local GOO_BLOCK_PREFIX = 'justdirethings:gooblock_tier';
|
||||||
|
local WAIT_SECONDS = 2;
|
||||||
|
|
||||||
|
local PROCESS_ITEMS = {
|
||||||
|
['minecraft:iron_block'] = { tier = 1, label = 'iron' },
|
||||||
|
['minecraft:coal_block'] = { tier = 1, label = 'coal' },
|
||||||
|
['mekanism:block_charcoal'] = { tier = 1, label = 'charcoal' },
|
||||||
|
['minecraft:gold_block'] = { tier = 2, label = 'gold' },
|
||||||
|
['minecraft:diamond_block'] = { tier = 3, label = 'diamond' },
|
||||||
|
['minecraft:netherite_block'] = { tier = 4, label = 'netherite' },
|
||||||
|
};
|
||||||
|
|
||||||
|
local FEEDING_ITEMS_BY_TIER = {
|
||||||
|
[1] = { 'minecraft:sugar', 'minecraft:rotten_flesh' },
|
||||||
|
[2] = { 'minecraft:nether_wart' },
|
||||||
|
[3] = { 'minecraft:chorus_fruit' },
|
||||||
|
[4] = { 'minecraft:sculk' },
|
||||||
|
};
|
||||||
|
|
||||||
|
local loggedBlockedItems = {};
|
||||||
|
|
||||||
|
local function isFlag(name)
|
||||||
|
return function(arg)
|
||||||
|
return arg == '-' .. name or arg == '--' .. name;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local isHelpFlag = isFlag('help');
|
||||||
|
local isVersionFlag = isFlag('version');
|
||||||
|
|
||||||
|
local function printUsage()
|
||||||
|
print('goo usage:');
|
||||||
|
print();
|
||||||
|
print('\t\t\tgoo start');
|
||||||
|
print('\t\t\tgoo version');
|
||||||
|
print('\t\t\tgoo help');
|
||||||
|
end
|
||||||
|
|
||||||
|
if command == 'version' or isVersionFlag(command) then
|
||||||
|
print('goo v' .. _VERSION);
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
if command == nil or command == '' or command == 'help' or isHelpFlag(command) then
|
||||||
|
printUsage();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
if command ~= 'start' then
|
||||||
|
printUsage();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
if not turtle then
|
||||||
|
error('goo must be run on a turtle');
|
||||||
|
end
|
||||||
|
|
||||||
|
local function turnAround()
|
||||||
|
turtle.turnRight();
|
||||||
|
turtle.turnRight();
|
||||||
|
end
|
||||||
|
|
||||||
|
local function parseGooTier(blockName)
|
||||||
|
local tier = string.match(blockName or '', '^' .. GOO_BLOCK_PREFIX .. '(%d+)$');
|
||||||
|
|
||||||
|
return tonumber(tier);
|
||||||
|
end
|
||||||
|
|
||||||
|
local function isGooBlock(blockName)
|
||||||
|
return parseGooTier(blockName) ~= nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function isProcessBlock(blockName)
|
||||||
|
return PROCESS_ITEMS[blockName] ~= nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function inspectGoo()
|
||||||
|
local ok, inspected = turtle.inspectUp();
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
error('expected a Just Dire Things goo block above the turtle');
|
||||||
|
end
|
||||||
|
|
||||||
|
local tier = parseGooTier(inspected.name);
|
||||||
|
|
||||||
|
if not tier then
|
||||||
|
error('expected a Just Dire Things goo block above the turtle, got ' .. tostring(inspected.name));
|
||||||
|
end
|
||||||
|
|
||||||
|
return tier, inspected;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findItemSlot(itemName)
|
||||||
|
for slot = 1, 16 do
|
||||||
|
local item = turtle.getItemDetail(slot);
|
||||||
|
|
||||||
|
if item and item.name == itemName then
|
||||||
|
return slot, item;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findFeedingSlot(gooTier)
|
||||||
|
local feedingItems = FEEDING_ITEMS_BY_TIER[gooTier] or {};
|
||||||
|
|
||||||
|
for i = 1, #feedingItems do
|
||||||
|
local slot, item = findItemSlot(feedingItems[i]);
|
||||||
|
|
||||||
|
if slot then
|
||||||
|
return slot, item;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findEligibleProcessSlot(gooTier)
|
||||||
|
for slot = 1, 16 do
|
||||||
|
local item = turtle.getItemDetail(slot);
|
||||||
|
local processItem = item and PROCESS_ITEMS[item.name];
|
||||||
|
|
||||||
|
if processItem then
|
||||||
|
if processItem.tier <= gooTier then
|
||||||
|
return slot, item, processItem;
|
||||||
|
end
|
||||||
|
|
||||||
|
local logKey = item.name .. ':' .. tostring(gooTier);
|
||||||
|
|
||||||
|
if not loggedBlockedItems[logKey] then
|
||||||
|
print(item.name .. ' requires goo tier ' .. tostring(processItem.tier)
|
||||||
|
.. ', current tier is ' .. tostring(gooTier));
|
||||||
|
loggedBlockedItems[logKey] = true;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ensureGooAlive()
|
||||||
|
while true do
|
||||||
|
local gooTier, inspected = inspectGoo();
|
||||||
|
|
||||||
|
if inspected.state and inspected.state.alive == true then
|
||||||
|
return gooTier;
|
||||||
|
end
|
||||||
|
|
||||||
|
local slot, item = findFeedingSlot(gooTier);
|
||||||
|
|
||||||
|
if not slot then
|
||||||
|
print('Goo tier ' .. tostring(gooTier) .. ' is not alive. Waiting for feeding item...');
|
||||||
|
os.sleep(WAIT_SECONDS);
|
||||||
|
else
|
||||||
|
turtle.select(slot);
|
||||||
|
print('Goo tier ' .. tostring(gooTier) .. ' is not alive. Feeding with ' .. item.name .. '...');
|
||||||
|
|
||||||
|
if not turtle.placeUp() then
|
||||||
|
print('Could not feed the goo. Waiting before retry...');
|
||||||
|
os.sleep(WAIT_SECONDS);
|
||||||
|
else
|
||||||
|
os.sleep(1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function selectProcessItem(gooTier)
|
||||||
|
local slot, item, processItem = findEligibleProcessSlot(gooTier);
|
||||||
|
|
||||||
|
if not slot then
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
turtle.select(slot);
|
||||||
|
|
||||||
|
return item, processItem;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function workTarget(inspectFn, digFn, placeFn, gooTier, targetName)
|
||||||
|
local ok, inspected = inspectFn();
|
||||||
|
|
||||||
|
if ok then
|
||||||
|
if isGooBlock(inspected.name) then
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
if isProcessBlock(inspected.name) then
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Mining processed ' .. targetName .. ' block: ' .. tostring(inspected.name));
|
||||||
|
return digFn();
|
||||||
|
end
|
||||||
|
|
||||||
|
local item = selectProcessItem(gooTier);
|
||||||
|
|
||||||
|
if not item then
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Placing ' .. item.name .. ' on goo ' .. targetName);
|
||||||
|
return placeFn();
|
||||||
|
end
|
||||||
|
|
||||||
|
local function workHorizontalSide(gooTier, sideIndex)
|
||||||
|
if not turtle.forward() then
|
||||||
|
print('Cannot move to horizontal side ' .. tostring(sideIndex) .. '. Waiting...');
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
local changed = workTarget(turtle.inspectUp, turtle.digUp, turtle.placeUp, gooTier, 'side');
|
||||||
|
|
||||||
|
if not turtle.back() then
|
||||||
|
error('could not return below the goo');
|
||||||
|
end
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function workHorizontalSides(gooTier)
|
||||||
|
local changed = false;
|
||||||
|
|
||||||
|
for sideIndex = 1, 4 do
|
||||||
|
changed = workHorizontalSide(gooTier, sideIndex) or changed;
|
||||||
|
turtle.turnRight();
|
||||||
|
end
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function workTopFromCurrentSide(gooTier)
|
||||||
|
if not turtle.forward() then
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
local sideOccupied = turtle.inspectUp();
|
||||||
|
local changed = false;
|
||||||
|
|
||||||
|
if not sideOccupied then
|
||||||
|
if turtle.up() then
|
||||||
|
if turtle.up() then
|
||||||
|
turnAround();
|
||||||
|
changed = workTarget(turtle.inspect, turtle.dig, turtle.place, gooTier, 'top');
|
||||||
|
turnAround();
|
||||||
|
|
||||||
|
if not turtle.down() then
|
||||||
|
error('could not descend from top placement position');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print('Cannot climb high enough to work on the top side.');
|
||||||
|
end
|
||||||
|
|
||||||
|
if not turtle.down() then
|
||||||
|
error('could not return to side floor position');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print('Cannot climb to work on the top side.');
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not turtle.back() then
|
||||||
|
error('could not return below the goo after top side check');
|
||||||
|
end
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function workTop(gooTier)
|
||||||
|
local changed = false;
|
||||||
|
|
||||||
|
for _ = 1, 4 do
|
||||||
|
if not changed then
|
||||||
|
changed = workTopFromCurrentSide(gooTier);
|
||||||
|
end
|
||||||
|
|
||||||
|
turtle.turnRight();
|
||||||
|
end
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function turnLeft(times)
|
||||||
|
for _ = 1, times do
|
||||||
|
turtle.turnLeft();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function moveToSideFacingCenter()
|
||||||
|
for turns = 0, 3 do
|
||||||
|
if turtle.forward() then
|
||||||
|
turnAround();
|
||||||
|
return turns;
|
||||||
|
end
|
||||||
|
|
||||||
|
turtle.turnRight();
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function returnFromBottomSide(turns)
|
||||||
|
if not turtle.forward() then
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
turnAround();
|
||||||
|
turnLeft(turns);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
|
||||||
|
local function workBottom()
|
||||||
|
local gooTier = ensureGooAlive();
|
||||||
|
|
||||||
|
local turns = moveToSideFacingCenter();
|
||||||
|
|
||||||
|
if not turns then
|
||||||
|
print('Cannot move to a side position for bottom placement. Waiting...');
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
local changed = false;
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local ok, inspected = turtle.inspect();
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
if changed then
|
||||||
|
if returnFromBottomSide(turns) then
|
||||||
|
return changed;
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Center position is clear, but the turtle could not return. Waiting...');
|
||||||
|
os.sleep(WAIT_SECONDS);
|
||||||
|
else
|
||||||
|
local item = selectProcessItem(gooTier);
|
||||||
|
|
||||||
|
if item then
|
||||||
|
print('Placing ' .. item.name .. ' on goo bottom');
|
||||||
|
|
||||||
|
if turtle.place() then
|
||||||
|
changed = true;
|
||||||
|
else
|
||||||
|
print('Could not place bottom block.');
|
||||||
|
end
|
||||||
|
elseif returnFromBottomSide(turns) then
|
||||||
|
return changed;
|
||||||
|
else
|
||||||
|
print('Center position is blocked. Waiting...');
|
||||||
|
os.sleep(WAIT_SECONDS);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif isProcessBlock(inspected.name) then
|
||||||
|
print('Bottom block is still processing. Waiting outside...');
|
||||||
|
os.sleep(WAIT_SECONDS);
|
||||||
|
elseif isGooBlock(inspected.name) then
|
||||||
|
error('unexpected goo block in the turtle center position');
|
||||||
|
else
|
||||||
|
print('Mining processed bottom block: ' .. tostring(inspected.name));
|
||||||
|
|
||||||
|
if turtle.dig() then
|
||||||
|
changed = true;
|
||||||
|
else
|
||||||
|
print('Could not mine bottom block. Waiting...');
|
||||||
|
os.sleep(WAIT_SECONDS);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print('goo started. Place the turtle directly below the goo block.');
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local gooTier = ensureGooAlive();
|
||||||
|
local hasEligibleBlocks = findEligibleProcessSlot(gooTier) ~= nil;
|
||||||
|
|
||||||
|
local changed = false;
|
||||||
|
|
||||||
|
changed = workTop(gooTier) or changed;
|
||||||
|
changed = workHorizontalSides(gooTier) or changed;
|
||||||
|
changed = workBottom() or changed;
|
||||||
|
|
||||||
|
if not changed then
|
||||||
|
if hasEligibleBlocks then
|
||||||
|
print('No free goo side found. Waiting for processing...');
|
||||||
|
else
|
||||||
|
print('No eligible process block found. Waiting for inventory...');
|
||||||
|
end
|
||||||
|
|
||||||
|
os.sleep(WAIT_SECONDS);
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user