mirror of
https://github.com/Kiritow/OpenComputerScripts.git
synced 2024-03-22 13:10:46 +08:00
Smart Storage v0.6
Now support robot crafting.
This commit is contained in:
parent
15ee96e87e
commit
4b684885d4
241
SmartStorage.lua
241
SmartStorage.lua
|
@ -9,7 +9,7 @@ local serialization=require('serialization')
|
|||
|
||||
require('libevent')
|
||||
|
||||
local version_tag="Smart Storage v0.5.9"
|
||||
local version_tag="Smart Storage v0.6.1-dbg"
|
||||
|
||||
print(version_tag)
|
||||
print("Checking hardware...")
|
||||
|
@ -181,7 +181,7 @@ local function display(tb_data,tb_display,tb_craft,begin_at,filter)
|
|||
gpu.set(1,1,version_tag)
|
||||
gpu.fill(1,2,w,1,'-')
|
||||
gpu.fill(1,h-2,w,1,'-')
|
||||
gpu.set(1,h-1,"<Refresh> <Reform> <Set Filter> <Clear Filter> <Read recipe>")
|
||||
gpu.set(1,h-1,"<Refresh> <Reform> <Set Filter> <Clear Filter> <Read recipe> <Debug>")
|
||||
|
||||
local count_shown=0
|
||||
for i=begin_at,#tb_display,1 do
|
||||
|
@ -214,14 +214,58 @@ local function display(tb_data,tb_display,tb_craft,begin_at,filter)
|
|||
gpu.set(4,h-2," Space used: " .. math.floor(tb_data.slot_used/tb_data.slot_total*1000)/10 .. "% (" .. tb_data.slot_used .. "/" .. tb_data.slot_total ..") ")
|
||||
end
|
||||
|
||||
local function SystemGetItem(tb_data,request_key,request_amount)
|
||||
local fetched=0
|
||||
local this_table=tb_data[request_key]
|
||||
for idx,this_info in ipairs(this_table.position) do
|
||||
local this_trans=component.proxy(this_info.addr)
|
||||
local need=0
|
||||
if(this_info.size>request_amount-fetched) then
|
||||
need=request_amount-fetched
|
||||
else
|
||||
need=this_info.size
|
||||
end
|
||||
local done=this_trans.transferItem(this_info.side,sides.down,need,this_info.slot)
|
||||
fetched=fetched+done
|
||||
this_info.size=this_info.size-done
|
||||
this_table.total=this_table.total-done
|
||||
if(fetched>=request_amount) then break end
|
||||
status("[Working] " .. fetched .. " of " .. request_amount .. " items transferred.")
|
||||
end
|
||||
|
||||
-- Update storage info
|
||||
local idx=1
|
||||
while(idx<=#this_table.position) do
|
||||
if(this_table.position[idx].size<=0) then
|
||||
table.remove(this_table.position,idx)
|
||||
result.slot_used=result.slot_used-1
|
||||
else
|
||||
idx=idx+1
|
||||
end
|
||||
end
|
||||
if(this_table.total<1) then
|
||||
result[tb_display[begin_at+e.y-3]]=nil -- Remove this type
|
||||
table.remove(tb_display,begin_at+e.y-3)
|
||||
|
||||
if(begin_at>1) then
|
||||
begin_at=begin_at-1
|
||||
end
|
||||
end
|
||||
|
||||
status("[Done] " .. fetched .. " of " .. request_amount .. " items transferred") -- Sometimes (ex: output box is full) not all items can be transferred.
|
||||
|
||||
return fetched
|
||||
end
|
||||
|
||||
term.clear()
|
||||
print("Smart Storage System Starting...")
|
||||
status("Scanning...")
|
||||
local craft_table={}
|
||||
local result=full_scan()
|
||||
local tb_display=GetDisplayTable(result)
|
||||
local begin_at=1
|
||||
local item_filter=''
|
||||
-- These variable should be local. Here is just for debug purpose.
|
||||
craft_table={}
|
||||
result=full_scan()
|
||||
tb_display=GetDisplayTable(result)
|
||||
begin_at=1
|
||||
item_filter=''
|
||||
|
||||
local need_refresh=true
|
||||
|
||||
|
@ -343,18 +387,37 @@ while true do
|
|||
temp=io_trans.getStackInSlot(io_trans_buffer_side,from_slot)
|
||||
if(temp~=nil or temp.size~=nil) then
|
||||
newRecipe.from[idx]={
|
||||
id=getItemXID(temp.name,temp.label)
|
||||
id=getItemXID(temp.name,temp.label),
|
||||
size=temp.size
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if(not craft_table[newRecipe.to.id]) then
|
||||
craft_table[newRecipe.to.id]={}
|
||||
end
|
||||
table.insert(craft_table[newRecipe.to.id],{size=newRecipe.to.size,from=newRecipe.from})
|
||||
status("New recipe added")
|
||||
|
||||
need_refresh=true
|
||||
end
|
||||
elseif(e.x<=string.len("<Refresh> <Reform> <Set Filter> <Clear Filter> <Read recipe> <Debug>")) then
|
||||
term.setCursor(1,h-1)
|
||||
term.clearLine()
|
||||
io.write("Lua: ")
|
||||
local str=io.read()
|
||||
if(str) then
|
||||
local f,err=load(str,"UserChunk","t",_ENV)
|
||||
if(f==nil) then
|
||||
status("Invalid Debug: " .. err)
|
||||
else
|
||||
local ok,err=pcall(f)
|
||||
if(not ok) then
|
||||
status("Debug Failed: " .. err)
|
||||
end
|
||||
end
|
||||
need_refresh=true
|
||||
end
|
||||
end
|
||||
elseif(e.y>=3 and e.y<=h-3) then
|
||||
if(begin_at+e.y-3<=#tb_display) then
|
||||
|
@ -370,46 +433,134 @@ while true do
|
|||
status("Invalid input.")
|
||||
else
|
||||
status("Transfer begins.")
|
||||
local fetched=0
|
||||
for idx,this_info in ipairs(this_table.position) do
|
||||
local this_trans=component.proxy(this_info.addr)
|
||||
local need=0
|
||||
if(this_info.size>n-fetched) then
|
||||
need=n-fetched
|
||||
else
|
||||
need=this_info.size
|
||||
end
|
||||
local done=this_trans.transferItem(this_info.side,sides.down,need,this_info.slot)
|
||||
fetched=fetched+done
|
||||
this_info.size=this_info.size-done
|
||||
this_table.total=this_table.total-done
|
||||
if(fetched>=n) then break end
|
||||
status("[Working] " .. fetched .. " of " .. n .. " items transferred.")
|
||||
end
|
||||
|
||||
-- Update storage info
|
||||
local idx=1
|
||||
while(idx<=#this_table.position) do
|
||||
if(this_table.position[idx].size<=0) then
|
||||
table.remove(this_table.position,idx)
|
||||
result.slot_used=result.slot_used-1
|
||||
else
|
||||
idx=idx+1
|
||||
end
|
||||
end
|
||||
if(this_table.total<1) then
|
||||
result[tb_display[begin_at+e.y-3]]=nil -- Remove this type
|
||||
table.remove(tb_display,begin_at+e.y-3)
|
||||
|
||||
if(begin_at>1) then
|
||||
begin_at=begin_at-1
|
||||
end
|
||||
end
|
||||
|
||||
status("[Done] " .. fetched .. " of " .. n .. " items transferred") -- Sometimes (ex: output box is full) not all items can be transferred.
|
||||
SystemGetItem(result,tb_display[begin_at+e.y-3],n)
|
||||
end
|
||||
elseif(e.button==1) then -- Right click
|
||||
if(craft_table[tb_display[begin_at+e.y-3]]==nil) then
|
||||
status("This item can't be crafted.")
|
||||
else
|
||||
need_refresh=true
|
||||
local this_table=result[tb_display[begin_at+e.y-3]]
|
||||
local this_recipe_list=craft_table[tb_display[begin_at+e.y-3]]
|
||||
local resolved_recipe_id=nil
|
||||
|
||||
status("Calculating crafting need...")
|
||||
for idx,this_recipe in ipairs(this_recipe_list) do
|
||||
status("[Working] Checking recipe " .. idx .. "...")
|
||||
local temp_sum={}
|
||||
for idx,this_from in pairs(this_recipe.from) do
|
||||
if(not temp_sum[this_from.id]) then
|
||||
temp_sum[this_from.id]=0
|
||||
end
|
||||
temp_sum[this_from.id]=temp_sum[this_from.id]+this_from.size
|
||||
end
|
||||
local available=true
|
||||
for this_id,this_amount in pairs(temp_sum) do
|
||||
status("[Checking] ID=" .. this_id)
|
||||
if(result[this_id].total<this_amount) then
|
||||
available=false
|
||||
break
|
||||
end
|
||||
end
|
||||
if(available) then
|
||||
resolved_recipe_id=idx
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if(not resolved_recipe_id) then
|
||||
status("Unable to craft. Not enough ingredients.")
|
||||
else
|
||||
status("[Checked] Following recipe " .. resolved_recipe_id)
|
||||
local follow_recipe=this_recipe_list[resolved_recipe_id]
|
||||
|
||||
local target_slot={1,2,3,10,11,12,19,20,21}
|
||||
local flag_done=true
|
||||
|
||||
local io_trans=component.proxy(io_trans_addr)
|
||||
|
||||
for idx,this_slot in pairs(follow_recipe.from) do
|
||||
local ans=SystemGetItem(result,this_slot.id,this_slot.size)
|
||||
if(ans~=this_slot.size) then
|
||||
flag_done=false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if(not flag_done) then
|
||||
status("Unable to craft. Failed to fetch enough item.")
|
||||
else
|
||||
status("[Working] Clearing buffer chest...")
|
||||
while io_trans.transferItem(io_trans_buffer_side,io_trans_output_side)>0 do end
|
||||
status("[Working] Moving resource to buffer chest...")
|
||||
for i=1,9,1 do
|
||||
if(follow_recipe.from[i]) then
|
||||
status("[Working] Gathering item for slot " .. i .. "...")
|
||||
local which_slot=0
|
||||
while which_slot<1 do
|
||||
for j=1,io_trans.getInventorySize(io_trans_output_side),1 do
|
||||
local this_info=io_trans.getStackInSlot(io_trans_output_side,j)
|
||||
if(this_info~=nil and this_info.size~=nil and
|
||||
(getItemXID(this_info.name,this_info.label)==follow_recipe.from[i].id) and
|
||||
(this_info.size>=follow_recipe.from[i].size)
|
||||
) then
|
||||
which_slot=j
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
status("[Working] Waiting item for slot " .. i .. "...")
|
||||
end
|
||||
io_trans.transferItem(io_trans_output_side,io_trans_buffer_side,follow_recipe.from[i].size,which_slot,target_slot[i])
|
||||
end
|
||||
end
|
||||
|
||||
status("[Pending] Waiting for robot response...")
|
||||
modem.send(robotAddr,1000,"do_craft")
|
||||
local robot_ok=true
|
||||
while true do
|
||||
local e=WaitEvent(5,"modem_message")
|
||||
if(e==nil) then
|
||||
status("Unable to craft. Robot no response.")
|
||||
robot_ok=false
|
||||
break
|
||||
elseif(e.event=="modem_message" and e.port==1001 and e.data[1]=="craft_started") then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if(robot_ok) then
|
||||
status("[Pending] Robot is crafting... (Ctrl+C to stop)")
|
||||
local craft_done=false
|
||||
local craft_ok=false
|
||||
while true do
|
||||
local e=WaitMultipleEvent("modem_message","interrupted")
|
||||
if(e.event=="interrupted") then
|
||||
status("Craft process is cancelled by user.")
|
||||
break
|
||||
elseif(e.event=="modem_message" and e.port==1001 and e.data[1]=="craft_done") then
|
||||
status("[Working] Robot crafting finished.")
|
||||
craft_ok=e.data[2]
|
||||
|
||||
craft_done=true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if(craft_done) then
|
||||
status("[Working] Moving items to output chest...")
|
||||
while io_trans.transferItem(io_trans_buffer_side,io_trans_output_side)>0 do end
|
||||
if(craft_ok) then
|
||||
status("[Done] Item crafted successfully.")
|
||||
else
|
||||
status("[Done] Item failed to craft.")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
76
SmartStorageRobot.lua
Normal file
76
SmartStorageRobot.lua
Normal file
|
@ -0,0 +1,76 @@
|
|||
-- Smart Storage Robot
|
||||
-- Author: Kiritow
|
||||
|
||||
local component=require('component')
|
||||
local sides=require('sides')
|
||||
local serialization=require('serialization')
|
||||
local robot=require('robot')
|
||||
|
||||
require('libevent')
|
||||
|
||||
local version_tag="Smart Storage Robot v0.1"
|
||||
|
||||
print(version_tag)
|
||||
print("Checking hardware...")
|
||||
local modem=component.modem
|
||||
local crafting=component.crafting
|
||||
local controller=component.inventory_controller
|
||||
if(not modem or not crafting or not controller or robot.inventorySize()<16) then
|
||||
print("This program requires Modem, Crafting upgrade, Inventory Controller upgrade and at least a 16-slot inventory to run.")
|
||||
return
|
||||
end
|
||||
print("Reading config...")
|
||||
|
||||
print("Waiting for Smart Storage System... (Ctrl+C to stop)")
|
||||
local sysAddr=''
|
||||
modem.open(1000)
|
||||
while true do
|
||||
local e=WaitMultipleEvent("modem_message","interrupted")
|
||||
if(e.event=="interrupted") then
|
||||
print("Cancelled by user.")
|
||||
modem.close(1000)
|
||||
return
|
||||
elseif(e.event=="modem_message" and e.port==1000 and e.data[1]=="find_crafting_robot") then
|
||||
print("System request received.")
|
||||
sysAddr=e.senderAddress
|
||||
modem.send(sysAddr,1001,"crafting_robot_response")
|
||||
print("Response sent.")
|
||||
break
|
||||
end
|
||||
end
|
||||
print("Smart Storage System set to " .. sysAddr)
|
||||
while true do
|
||||
print("Waiting for requests... (Ctrl+C to stop)")
|
||||
local e=WaitMultipleEvent("modem_message","interrupted")
|
||||
if(e.event=="interrupted") then
|
||||
print("Receive stop signal")
|
||||
break
|
||||
elseif(e.event=="modem_message" and e.port==1000) then
|
||||
if(e.data[1]=="do_craft") then
|
||||
print("[Pending] Sending response...")
|
||||
modem.send(sysAddr,1001,"craft_started")
|
||||
print("[Working] Start craft task...")
|
||||
local from_slot={1,2,3,10,11,12,19,20,21}
|
||||
local to_slot={1,2,3,5,6,7,9,10,11}
|
||||
print("[Working] Moving resource...")
|
||||
for i=1,9,1 do
|
||||
robot.select(to_slot[i])
|
||||
controller.suckFromSlot(sides.front,from_slot[i])
|
||||
end
|
||||
print("[Working] Crafting...")
|
||||
robot.select(4)
|
||||
local result=crafting.craft()
|
||||
print("[Working] Craft result: ",result)
|
||||
print("[Working] Cleaning inventory...")
|
||||
for i=1,16,1 do
|
||||
robot.select(i)
|
||||
robot.drop()
|
||||
end
|
||||
modem.send(sysAddr,1001,"craft_done",result)
|
||||
print("[Done] Task craft finished.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
print("Closing ports...")
|
||||
modem.close(1000)
|
Loading…
Reference in New Issue
Block a user