Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local a="2.5.1b"local b="koro Worker"local c="bottom"local d="top"local e="front"local f={compact=true}local g=nil;local h=nil;local i=nil;local j=0;local k=os.computerID()local l={id=k,version=a,firmware=b}Chest={}function Chest.updateList(m)m.list={}for n,o in pairs(m.peripheral.list())do local item,count=o.name,tonumber(o.count)if m.list[item]==nil then m.list[item]={{n,count}}else table.insert(m.list[item],{n,count})end end end;function Chest.new(p,q)local r={}r.name=p;r.peripheral=peripheral.wrap(p)if q or false then Chest.updateList(r)end;return r end;local function s()local t=nil;local c=nil;turtle.equipRight()turtle.dropDown()for u,v in ipairs(peripheral.getNames())do if string.find(v,"chest")then local w=peripheral.wrap(v).list()if w[1]and w[1].name=="minecraft:crafting_table"then c=v else t=v end end end;turtle.suckDown()turtle.equipRight()return t,c end;local function x()local y=fs.open("cookbook.dat","r")local z=textutils.unserialize(y.readAll())y.close()return z end;local function A()local y=fs.open("cookbook.dat","w")y.write(textutils.serialize(h))y.close()end;local function B()turtle.select(1)local C,D=s()if C==nil or D==nil then return"init: missing chest inventory"end;g={["work"]=Chest.new(c,true),["temp"]=Chest.new(d),["portE"]=Chest.new(C),["workE"]=Chest.new(D)}h=x()end;local function E(item,count,F,G,H)Chest.updateList(F)local I=F.list[item]if not I then return"craft: could not pull desired item"end;local J=0;for K,L in ipairs(I)do local M,N=table.unpack(L)if N>=count then J=J+F.peripheral.pushItems(G,M,count,H)break else count=count-N;J=J+F.peripheral.pushItems(G,M,N,H)end end;return J end;Machine={machines={},sinks={}}local O={["ironfurnaces:netherite_furnace"]={archetype="factory",input={8,9,10,11,12,13},output={14,15,16,17,18,19}},["extendedae:crystal_assembler"]={archetype="assembler",output=10},["cookingforblockheads:sink"]={archetype="sink",fluid="water"},["extendedae:circuit_cutter"]={archetype="factory",input={1},output={2}}}function Machine.initialize()for u,P in ipairs(peripheral.getNames())do local Q,u=P:match("(.+)_(.+)")if O[Q]then if O[Q].archetype=="factory"then local R=peripheral.wrap(P)local S=#O[Q].input;Machine.machines[Q]={compose=function(T,item,count)local U=0;local V=0;local W,X;while U<count or V<count do if U<count then W=count-U;for K,n in pairs(O[Q].input)do X=E(T[1],math.floor(W/S)+(K<=W%S and 1 or 0),g["workE"],P,n)if type(X)=="string"then break end;U=U+X end end;for K,n in pairs(O[Q].output)do V=V+R.pushItems(g["workE"].name,n)end;sleep(1.5)end end}elseif O[Q].archetype=="assembler"then local R=peripheral.wrap(P)Machine.machines[Q]={compose=function(T,item,count)print(count)local Y={}local V=0;local X;local Z={}for K=1,#T do Z[K]=T.counts[K]*count end;local _=count*(T.yield or 1)while V<_ do for K=1,#T do if not Y[K]or Y[K]<Z[K]then if not Y[K]then Y[K]=0 end;Chest.updateList(g["workE"])local I=g["workE"].list[T[K]]Y[K]=Y[K]+g["workE"].peripheral.pushItems(P,I[1][1],Z[K]-Y[K],K)end end;if T.fluid then Machine.sinks[T.fluid.name].pushFluid(P,T.fluid.volume)end;V=V+g["workE"].peripheral.pullItems(P,O[Q].output)sleep(0.5)end end}elseif O[Q].archetype=="sink"then local R=peripheral.wrap(P)Machine.sinks[O[Q].fluid]=R end end end end;local function a0(F,a1)local a2=F.peripheral.list()while next(a2)~=nil do for n,u in pairs(a2)do F.peripheral.pushItems(peripheral.getName(a1.peripheral),n,64,n)a2=F.peripheral.list()end end end;local function a3(n)return math.floor(n+(n-1)/3)end;local function a4(T,count,a5)if count<1 then return end;for n=1,9 do if T[n]then err=E(T[n],count,g["work"],g["temp"].name)turtle.select(a3(n))turtle.suckUp()if type(err)=="string"then return err end;turtle.suck(count)end end;turtle.select(1)turtle.craft()j=j+1;local a6=a5;local n=1;local a7={}if T.remnants then for R,u in pairs(T.remnants)do turtle.select(a3(R))a7[a3(R)]=1;turtle.dropDown()end end;while a6>0 do if not a7[n]then turtle.select(n)turtle.dropDown()a6=a6-1 end end;turtle.select(1)end;local function a8(T,item,count)local a9=64;for n,aa in pairs(T)do if h.info[aa]and h.info[aa].stackSize and T.remnants[n]~=1 then a9=math.min(a9,h.info[aa].stackSize)end end;local ab=math.min(count,a9)local ac=nil;if h.info[item]and h.info[item].stackSize then ac=h.info[item].stackSize else ac=64 end;local a5=math.ceil(ab*(T.yield or 1)/ac)local ad=math.ceil(count%ab*(T.yield or 1)/ac)local ae=math.floor(count/ab)for u=1,ae do err=a4(T,ab,a5)if err then return err end end;if count>a9 then err=a4(T,count%a9,ad)if err then return err end end end;local function af(item,count)local T=h.recipes[item]if T==nil then return end;if T.type then Machine.machines[T.type].compose(T,item,count)else a8(T,item,count)end end;function makeTree(ag,item,ah,ai)ah=ah or 0;if ah==0 then ag={leaves={}}end;local aj={item=item,parent=ai}table.insert(ag,aj)local ak=#ag;local T=h.recipes[item]if T==nil then ag.leaves[#ag]=true;return end;local al={}for n=1,9 do if T[n]then al[T[n]]=true end end;aj.children={}for item,o in pairs(al)do local am=makeTree(ag,item,ah+1,ak)table.insert(aj.children,am)end;if ah==0 then return ag end;return ak end;function allIn(an,ao,ap)for K,v in ipairs(an)do if ao[v]==nil or ao[v]==ap then return false end end;return true end;function flatten(ag)local aq={}local ar={}for K,u in pairs(ag.leaves)do table.insert(ar,K)end;local as={}local at={}local au={}local ah=0;while#ar>0 do for u,K in ipairs(ar)do if ag[K].children and not allIn(ag[K].children,at,ah)then table.insert(as,K)else if not au[ag[K].item]then table.insert(aq,{item=ag[K].item,depth=ah})au[ag[K].item]=#aq end;table.insert(as,ag[K].parent)at[K]=ah end end;ar=as;as={}ah=ah+1 end;return aq end;function augment(aq)local av={}for K,v in ipairs(aq)do av[v.item]=K;if h.recipes[v.item]then local T=h.recipes[v.item]v.parents={}for n=1,9 do if T[n]then parentIndex=av[T[n]]if T.remnants and T.remnants[n]==1 then if not v.remnants then v.remnants={}end;v.remnants[parentIndex]=(v.remnants[parentIndex]or 0)+1 else v.parents[parentIndex]=(v.parents[parentIndex]or 0)+(T.counts and T.counts[n]or 1)end end end;v.yield=h.recipes[v.item].yield end end;return aq end;function plan(item,count)Chest.updateList(g["portE"])local thisTree=makeTree(thisTree,item)local aq=augment(flatten(thisTree))local aw={[#aq]={count,count}}for K=#aq,1,-1 do if g["portE"].list[aq[K].item]~=nil then local ax=0;for u,v in ipairs(g["portE"].list[aq[K].item])do local n,count=table.unpack(v)ax=ax+count end;aw[K][1]=math.max(0,aw[K][1]-ax)end;if aq[K].parents then for aa,ay in pairs(aq[K].parents)do if not aw[aa]then aw[aa]={0,0}end;aw[aa][1]=aw[aa][1]+math.ceil(aw[K][1]/(aq[K].yield or 1))*ay;aw[aa][2]=aw[aa][2]+math.ceil(aw[K][2]/(aq[K].yield or 1))*ay end end;if aq[K].remnants then for aa,ay in pairs(aq[K].remnants)do if not aw[aa]then aw[aa]={0,0}end;aw[aa][1]=math.max(aw[aa][1],ay)aw[aa][2]=math.max(aw[aa][2],ay)end end end;for K=1,#aq do aw[K]={aq[K].item,math.ceil(aw[K][1]/(aq[K].yield or 1)),math.ceil(aw[K][2]/(aq[K].yield or 1))}end;return aw end;function craft(aw,az,aA)for u,v in ipairs(aw)do item=v[1]count=v[2+az]if h.recipes[item]then aA(item,count*(h.recipes[item].yield or 1))err=af(item,count)if err then return err end end end end;function sortFunc(an,ao)return an[1]>ao[1]end;function endpointPlan(aB)local item,count=aB:match("([^%s]+)%s([^%s]+)")if item==nil or count==nil then return"plan: malformed request"end;if not h.recipes[item]then return"plan: no recipe for item"end;count=tonumber(count)i=plan(item,count)local aC={}local aD=false;for u,v in ipairs(i)do local aa,aE,ay=table.unpack(v)if aE~=ay then aD=true end;if not h.recipes[aa]then table.insert(aC,{aa,aE,ay})end end;table.sort(aC,sortFunc)return textutils.serialize({aC,aD},f)end;function endpointCraft(aB,id,protocol)local az=tonumber(aB)if i then startOpCount=j;a0(g["portE"],g["workE"])err=craft(i,az,function(item,count)rednet.send(id,textutils.serialize({item,count}),protocol.."Progress")end)a0(g["workE"],g["portE"])print(j-startOpCount.." operations performed.")else return"craft: no plan found"end;return err or"craft: success"end;function endpointUpdate(aB)local aF=textutils.unserialize(aB)if aF.recipes then for item,T in pairs(aF.recipes)do h.recipes[item]=T end end;if aF.info then for item,aG in pairs(aF.info)do h.info[item]=aG end end;A()return"update: success"end;function endpointCookbook(aB)return textutils.serialize(h)end;function endpointPing(aB)return k end;function endpointItemInfo(aB)return h.recipes[aB]~=nil end;function endpointWorkerInfo(aB)return textutils.serialize(l)end;local aH={["plan"]=endpointPlan,["craft"]=endpointCraft,["iteminfo"]=endpointItemInfo,["cookbook"]=endpointCookbook,["update"]=endpointUpdate,["ping"]=endpointPing}function main()term.clear()term.setCursorPos(1,1)print(b.." "..a)err=B()if err then print(err)return end;Machine.initialize()print("Ready")rednet.open(e)rednet.broadcast(k,"workerInit")local aI=true;local aJ=nil;while aI do id,message,protocol=rednet.receive()print(string.format("[%s/%s] %s",id,protocol,message))if id~=k and aH[protocol]then aJ=aH[protocol](message,id,protocol)else aJ="main: invalid endpoint"end;print("RESPONSE > "..tostring(aJ))rednet.send(id,aJ,protocol)end end;main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement