View difference between Paste ID: saVGtpYB and CYeudwFd
SHOW: | | - or go back to the newest paste.
1-
local sendChannel=666
1+
local sendChannel=1
2
local pingLimit=5
3
4-
if fs.exists("event")==false then shell.run("pastebin get UKPy4iiE event") end
4+
if fs.exists("event")==false then shell.run("pastebin get CGn8AsPe event") end
5
if os.loadAPI("event")==false then error("Failed to load event API") end
6
 
7-
if fs.exists("data")==false then shell.run("pastebin get LnvzL7ur data") end
7+
if fs.exists("data")==false then shell.run("pastebin get zn5jECxd data") end
8
if os.loadAPI("data")==false then error("Failed to load data API") end
9
10-
if fs.exists("utils")==false then shell.run("pastebin get dyvydHtK utils") end
10+
if fs.exists("utils")==false then shell.run("pastebin get a5HpUVYL utils") end
11
if os.loadAPI("utils")==false then error("Failed to load utils API") end
12
13
local self={
14
	facing="north",
15
	pos={x=0,y=0,z=0},
16
}
17
18
19
local pingtimer
20
local pongtimer
21
local failedPings=0
22
local dropoffTimer
23
local failedDrops=0
24
local localChannel
25
local task={}
26
27
function self.updatePos()
28
	print(textutils.serialise(self.pos))
29
	data.set("position",self.pos.x..","..self.pos.y..","..self.pos.z,"db/position")
30
end
31
32
function self.getFilePos()
33
	local pos=data.get("position","db/position")
34
	if pos==nil then return end
35
	local x=utils.split(pos,",",1)
36
	local y=utils.split(pos,",",2)
37
	local z=utils.split(pos,",",3)
38
	return x,y,z
39
end
40
41
function self.move(direction,ammount,digging)
42
	if ammount==nil then ammount=1 end
43
	local moveFunction=nil
44
	local digFunction=nil
45
	local directionalAxis=""
46
	if direction=="up" then
47
		moveFunction=turtle.up
48
		digFunction=turtle.digUp
49
		directionalAxis="y|+1"
50
	elseif direction=="down" then
51
		moveFunction=turtle.down
52
		digFunction=turtle.digDown
53
		directionalAxis="y|-1"
54
	else
55
		if direction=="back" then
56
			self.turn("right",2)
57
		elseif direction=="right" then
58
			self.turn("right")
59
		elseif direction=="left" then
60
			self.turn("left")
61
		end
62
		moveFunction=turtle.forward
63
		digFunction=turtle.dig
64
		if self.facing=="north" then
65
			directionalAxis="z|-1"
66
		elseif self.facing=="east" then
67
			directionalAxis="x|1"
68
		elseif self.facing=="south" then
69
			directionalAxis="z|1"
70
		elseif self.facing=="west" then
71
			directionalAxis="x|-1"
72
		end
73
	end
74
	for i=1,ammount do
75
		if digging==true then
76
			digFunction()
77
		end
78
		local axis=utils.split(directionalAxis,"|",1)
79
		local delta=tonumber(utils.split(directionalAxis,"|",2))
80
		local returned=moveFunction()
81
		if returned==true then
82
			self.pos[axis]=self.pos[axis]+delta
83
			self.updatePos()
84
		end
85
		if returned==false then return returned end
86
	end
87
end
88
89
local facing={
90
	[0]="west","north","east","south","west","north",
91
	north=1,east=2,south=3,west=4,
92
}
93
94
function self.turn(direction,ammount)
95
	for i=1,ammount do
96
		if direction=="right" then
97
			turtle.turnRight()
98
			self.facing=facing[ facing[self.facing]+1 ]
99
		else
100
			turtle.turnLeft()
101
			self.facing=facing[ facing[self.facing]-1 ]
102
		end
103
	end
104
	data.set("facing",self.facing,"db/position")
105
end
106
107
function self.setFacing(targetFacing)
108
	local targetFacing=string.lower(targetFacing)
109
	local currentFacing=string.lower(self.facing)
110
	if targetFacing==currentFacing then
111
		return
112
	else
113
		local currentFacingIndex=facing[currentFacing]
114
		local facingIndex=facing[targetFacing]
115
		local turns=facingIndex-currentFacingIndex
116
		if turns<0 then
117
			turns=turns+4
118
		end	
119
		if turns==3 then
120
			self.turn("left",1)
121
		else
122
			for i=1,turns do
123
				self.turn("right",1)
124
			end
125
		end
126
	end
127
end
128
129
function self.goto(x,y,z,fails)
130
	if turtle.getFuelLevel() == 0 then
131
		wireless.transmit(replyChannel,localChannel,"status|Out of fuel")
132
		print("Awaiting fuel in slot 16")
133
		turtle.select(16)
134
		while turtle.getFuelLevel() == 0 do
135
			turtle.refuel()
136
		end
137
	end
138
	local fails=fails
139
	if fails==nil then
140
		fails=0
141
	end
142
	--print("going from "..tostring(self.pos.x)..","..tostring(self.pos.y)..","..tostring(self.pos.z).."\n to "..tostring(x)..","..tostring(y)..","..tostring(z))
143
	local yDistance=(self.pos.y-y)*-1
144
	--print("Y axis travel distance : "..yDistance)
145
	local yTravel=true
146
	if yDistance>0 then
147
		yTravel=self.move("up",yDistance)
148
	elseif yDistance<0 then
149
		yTravel=self.move("down",yDistance*-1)
150
	end
151
	local xDistance=(self.pos.x-x)*-1
152
	--print("X axis travel distance : "..xDistance)
153
	local xTravel=true
154
	if xDistance>0 then
155
		self.setFacing("east")
156
	elseif xDistance<0 then
157
		self.setFacing("west")
158
		xDistance=xDistance*-1
159
	end
160
	xTravel=self.move("forward",xDistance)
161
	local zDistance=(self.pos.z-z)*-1
162
	--print("Z axis travel distance : "..zDistance)
163
	local zTravel=true
164
	if zDistance>0 then
165
		self.setFacing("south")
166
	elseif zDistance<0 then
167
		self.setFacing("north")
168
		zDistance=zDistance*-1
169
	end
170
	zTravel=self.move("forward",zDistance)
171
	if xTravel==false or zTravel==false or yTravel==false then
172
		if fails==6 or fails == 8 or fails == 10 then
173
			self.move("up",1)
174
			self.move("forward",2)
175
			self.move("down",1)
176
		elseif fails == 5 or fails == 7 or fails == 9 then
177
			local originalFacing = self.facing
178
			if originalFacing == "north" then
179
				self.setFacing("west")
180
				self.move("forward",1)
181
				self.setFacing(originalFacing)
182
				self.move("forward",2)
183
				self.setFacing("east")
184
				self.move("forward",1)
185
				self.setFacing(originalFacing)
186
			elseif originalFacing == "south" then
187
				self.setFacing("east")
188
				self.move("forward",1)
189
				self.setFacing(originalFacing)
190
				self.move("forward",2)
191
				self.setFacing("west")
192
				self.move("forward",1)
193
				self.setFacing(originalFacing)
194
			elseif originalFacing == "west" then
195
				self.setFacing("north")
196
				self.move("forward",1)
197
				self.setFacing(originalFacing)
198
				self.move("forward",2)
199
				self.setFacing("south")
200
				self.move("forward",1)
201
				self.setFacing(originalFacing)
202
			else
203
				self.setFacing("south")
204
				self.move("forward",1)
205
				self.setFacing(originalFacing)
206
				self.move("forward",2)
207
				self.setFacing("north")
208
				self.move("forward",1)
209
				self.setFacing(originalFacing)
210
			end
211
		end
212
		fails=fails+1
213
		if fails>=11 then
214
			return false
215
		end
216
		sleep(1)
217
		return self.goto(x,y,z,fails)
218
	end
219
	return true
220
end
221
222
local slotTable = {
223
	1,2,3,5,6,7,9,10,11
224
}
225
226
function self.pickup(itemname,count,targetSlot)
227
	local chest=peripheral.wrap("bottom")
228
	local items=chest.getAllStacks()
229
	local count=tonumber(count)
230
	local remainder=count
231
	local targetSlot = slotTable[tonumber(targetSlot)]
232
	print(itemname .. " : " .. count .. " : " .. tostring(targetSlot) )
233
	for slot,item in pairs(items) do
234
		--print(item.all().display_name)
235
		if string.lower(item.all().display_name)==itemname then
236
			local count=item.all().qty
237
			if count>remainder then
238
				chest.pushItem("up",slot,remainder,targetSlot)
239
				remainder=0
240
			else
241
				chest.pushItem("up",slot,count,targetSlot)
242
				remainder=remainder-count
243
			end
244
		end
245
		if remainder<=0 then
246
			break
247
		end
248
	end
249
end
250
251
function self.dropoff(x,y,z)
252
	if self.goto(x,y,z) then
253
		for i=1,16 do
254
			if turtle.getItemCount(i)>0 then
255
				turtle.select(i)
256
				turtle.dropDown()
257
			end
258
		end	
259
	end
260
end
261
262
function initPos()
263
	local x,y,z=self.getFilePos()
264
	if x==nil or y==nil or z==nil then
265
		print("Please input coordinates:")
266
		io.write("x: ")
267
		x=tonumber(read())
268
		io.write("y: ")
269
		y=tonumber(read())
270
		io.write("z: ")
271
		z=tonumber(read())
272
	end
273
	self.pos.x,self.pos.y,self.pos.z=tonumber(x),tonumber(y),tonumber(z)
274
	self.updatePos()
275
	local facing=data.get("facing","db/position")
276
	if facing==nil then
277
		print("Please input facing:")
278
		io.write("facing: ")
279
		facing=read()
280
		data.set("facing",facing,"db/position")
281
	end
282
	self.facing=facing
283
end
284
285
function initConnection()
286
	if localChannel~=nil then
287
		wireless.close(localChannel)
288
	end
289
	wireless=peripheral.wrap("left")
290
	localChannel=math.random(1000,5000)
291
	wireless.open(localChannel)
292
	repeat
293
		wireless.transmit(sendChannel,localChannel,"assign")
294
		local timer=os.startTimer(5)
295
		repeat
296
			tEvent,var,sender,receiver,message=os.pullEvent()
297
			--print(localChannel.." | "..event.." : "..tostring(message))
298
		until tEvent=="modem_message" or tEvent=="timer"
299
		if message=="denied" then
300
			wireless.close(localChannel)
301
			localChannel=math.random(1000,5000)
302
			wireless.open(localChannel)
303
		end
304
	until message=="confirmed"
305
	failedPings=0
306
end
307
308
function init()
309
	initPos()
310
	initConnection()
311
end
312
init()
313
314
function craft(replyChannel,message,isFinal)
315
	local count=tonumber(utils.split(message,"|",2))
316
	local allSubs=utils.getSplits(message,"|")
317
	local itemSubs = {}
318
	for i = 3, #allSubs do
319
		itemSubs[#itemSubs+1]=allSubs[i]
320
	end
321
	for i,itemSub in pairs(itemSubs) do
322
		local item=utils.split(itemSub,";",1)
323
		local pos=utils.split(itemSub,";",2)
324
		local slot = utils.split(itemSub,";",3)
325
		if pos~=nil then
326
			local x=utils.split(pos,",",1)
327
			local y=utils.split(pos,",",2)
328
			local z=utils.split(pos,",",3)
329
			self.goto(x,y,z)
330
			self.pickup(item,count,slot)
331
		end
332
	end
333
	
334
	turtle.craft(count)
335
	
336
	if isFinal == true then
337
		dropoffTimer=os.startTimer(5)
338
		wireless.transmit(replyChannel,localChannel,"requestDropoff")
339
	else
340
		self.dropoff(self.pos.x,self.pos.y,self.pos.z)
341
		wireless.transmit(sendChannel,localChannel,"requestRestPos")
342
	end
343
end
344
345
local messageHandles={
346
	["ping"]=function(replyChannel,message)
347
		return "pong"
348
	end,
349
	
350
	["get"]=function(replyChannel,message)
351
		wireless.transmit(replyChannel,localChannel,"status|working")
352
		local item=utils.split(message,"|",2)
353
		local count=tonumber(utils.split(message,"|",3))
354
		local pos=utils.split(message,"|",4)
355
		if pos==nil then return end
356
		local x=utils.split(pos,",",1)
357
		local y=utils.split(pos,",",2)
358
		local z=utils.split(pos,",",3)
359
		self.goto(x,y,z)
360
		self.pickup(item,count)
361
		dropoffTimer=os.startTimer(5)
362
		wireless.transmit(replyChannel,localChannel,"requestDropoff")
363
	end,
364
	
365
	["craft"]=function(replyChannel,message)
366
		wireless.transmit(replyChannel,localChannel,"status|working")
367
		craft(replyChannel,message,true)
368
	end,
369
	
370
	["innerCraft"]=function(replyChannel,message)
371
		craft(replyChannel,message,false)
372
		wireless.transmit(sendChannel,localChannel,"requestRestPos")
373
	end,
374
	
375
	["goto"]=function(replyChannel,message)
376
		wireless.transmit(replyChannel,localChannel,"status|working")
377
		local pos=utils.split(message,"|",2)
378
		local x=tonumber(utils.split(pos,",",1))
379
		local y=tonumber(utils.split(pos,",",2))
380
		local z=tonumber(utils.split(pos,",",3))
381
		self.goto(x,y,z)
382
		pingtimer=os.startTimer(10)
383
		return("status|idle")
384
	end,
385
	
386
	["pong"]=function()
387
		pongtimer=nil
388
		failedPings=failedPings-1
389
		if failedPings<0 then failedPings=0 end
390
	end,
391
	
392
	["loadstring"]=function(_,message)
393
		local func = loadstring(utils.split(message,"|",2))
394
		setfenv(func, getfenv())
395
		func()
396
	end,
397
	
398
	["run"]=function(_,message)
399
		wireless.transmit(replyChannel,localChannel,"status|working")
400
		shell.run(utils.split(message,"|",2))
401
		pingtimer=os.startTimer(10)
402
		return("status|idle")
403
	end,
404
	
405
	["returnDropoff"]=function(_,message)
406
		failedDrops=0
407
		local pos=utils.split(message,"|",2)
408
		local x=tonumber(utils.split(pos,",",1))
409
		local y=tonumber(utils.split(pos,",",2))
410
		local z=tonumber(utils.split(pos,",",3))
411
		self.dropoff(x,y,z)
412
		wireless.transmit(sendChannel,localChannel,"requestRestPos")
413
	end,
414
	
415
	["returnHomePos"]=function(_,message)
416
		local pos=utils.split(message,"|",2)
417
		local x=tonumber(utils.split(pos,",",1))
418
		local y=tonumber(utils.split(pos,",",2))
419
		local z=tonumber(utils.split(pos,",",3))
420
		self.goto(x,y,z)
421
		pingtimer=os.startTimer(10)
422
		wireless.transmit(sendChannel,localChannel,"status|idle")	
423
	end,
424
}
425
426
function handleMessages(side,channel,replyChannel,message)
427
	--print(tostring(replyChannel).." : "..tostring(message))
428
	if replyChannel==nil then return end
429
	local messageType=utils.split(message,"|",1)
430
	if messageHandles[messageType]==nil then return end
431
	local returnMessage=messageHandles[messageType](replyChannel,message)
432
	if returnMessage==nil then return end
433
	wireless.transmit(replyChannel,localChannel,returnMessage)
434
end
435
event.addHandler("modem_message",handleMessages)
436
437
function timerExpired(id)
438
	--print("Timer: "..tostring(id).." | Pingtimer:"..tostring(pingtimer))
439
	if id==pingtimer then
440
		wireless.transmit(sendChannel,localChannel,"ping")
441
		pongtimer=os.startTimer(1)
442
		pingtimer=nil
443
	elseif id==pongtimer then
444
		failedPings=failedPings+1
445
		print("Ping was not answered. Rep: "..failedPings)
446
		if failedPings>pingLimit then
447
			initConnection()
448
		end
449
	elseif id==dropoffTimer then
450
		failedDrops=failedDrops+1
451
		if failedDrops>5 then
452
			wireless.transmit(sendChannel,localChannel,"status|idle")
453
			return
454
		end
455
		wireless.transmit(sendChannel,localChannel,"requestDropoff")
456
		dropoffTimer=os.startTimer(5)
457
	end
458
end
459
event.addHandler("timer",timerExpired)
460
461
while true do
462
	pingtimer=os.startTimer(10)
463
	repeat
464
		event.handleCCEvents()
465
	until pingtimer==nil
466
end