AdvancedMiningController.lua

417 lines · 13.8 KB

Open raw

{program="AdvancedMiningController",version="2.0",date="2024-12-19"}

Copy & run

wget https://perlytiara.github.io/turtles.tips/raw/programs/perlytiara/tClear/AdvancedMiningController.lua
1--{program="AdvancedMiningController",version="2.0",date="2024-12-19"}
2---------------------------------------
3-- Advanced Mining Controller by AI Assistant
4-- 2024-12-19, v2.0 Advanced wireless mining system
5---------------------------------------
6
7---------------------------------------
8---- DESCRIPTION ----------------------
9---------------------------------------
10-- Master controller for advanced wireless mining operations
11-- Controls mining turtle and chunky turtle from a computer
12-- Features automatic pairing, real-time monitoring, and advanced coordination
13-- Supports single and multi-turtle operations with chunky pairing
14
15---------------------------------------
16---- ASSUMPTIONS ----------------------
17---------------------------------------
18-- Requires a computer with wireless modem
19-- Mining turtle placed at left corner of mining area
20-- Chunky turtle placed one block to the right of mining turtle
21-- Both turtles have wireless modems and required programs
22
23---------------------------------------
24---- VARIABLES ------------------------
25---------------------------------------
26local cVersion = "v2.0"
27local cPrgName = "AdvancedMiningController"
28local blnDebugPrint = true
29
30-- Communication settings
31local protocol = "advanced-mining"
32local discoveryTimeout = 5
33local responseTimeout = 3
34
35-- Turtle management
36local miningTurtleId = nil
37local chunkyTurtleId = nil
38local isOperationActive = false
39local operationStatus = "idle"
40
41-- Operation parameters
42local operationParams = {
43 depth = 0,
44 width = 0,
45 height = 0,
46 options = {}
47}
48
49---------------------------------------
50---- Utility Functions ----------------
51---------------------------------------
52local function debugPrint(str)
53 if blnDebugPrint then
54 print("[Controller] " .. str)
55 end
56end
57
58local function findModem()
59 for _, p in pairs(rs.getSides()) do
60 if peripheral.isPresent(p) and peripheral.getType(p) == "modem" then
61 return p
62 end
63 end
64 error("No modem attached to this computer.")
65end
66
67local function sendMessage(targetId, message, customProtocol)
68 local protocolToUse = customProtocol or protocol
69 rednet.send(targetId, message, protocolToUse)
70 debugPrint("Sent to " .. targetId .. ": " .. textutils.serialize(message))
71end
72
73local function broadcastMessage(message, customProtocol)
74 local protocolToUse = customProtocol or protocol
75 rednet.broadcast(message, protocolToUse)
76 debugPrint("Broadcasted: " .. textutils.serialize(message))
77end
78
79local function waitForResponse(targetId, expectedType, timeout)
80 timeout = timeout or responseTimeout
81 local startTime = os.time()
82
83 while (os.time() - startTime) < timeout do
84 local senderId, message, msgProtocol = rednet.receive(0.1)
85 if senderId == targetId and msgProtocol == protocol then
86 if message.type == expectedType then
87 return message
88 end
89 end
90 end
91 return nil
92end
93
94---------------------------------------
95---- Discovery Functions --------------
96---------------------------------------
97local function discoverTurtles()
98 print("Discovering available turtles...")
99
100 -- Send discovery broadcast
101 broadcastMessage({
102 type = "discover",
103 controllerId = os.getComputerID(),
104 timestamp = os.time()
105 })
106
107 local discoveredTurtles = {}
108 local discoveredChunkies = {}
109 local startTime = os.time()
110
111 -- Collect responses
112 while (os.time() - startTime) < discoveryTimeout do
113 local senderId, message, msgProtocol = rednet.receive(0.1)
114 if senderId and msgProtocol == protocol then
115 if message.type == "mining_turtle_available" then
116 table.insert(discoveredTurtles, {
117 id = senderId,
118 name = message.name or "Mining Turtle",
119 fuel = message.fuel or 0,
120 inventory = message.inventory or 0
121 })
122 print("Found mining turtle: " .. senderId .. " (Fuel: " .. (message.fuel or 0) .. ")")
123 elseif message.type == "chunky_turtle_available" then
124 table.insert(discoveredChunkies, {
125 id = senderId,
126 name = message.name or "Chunky Turtle",
127 fuel = message.fuel or 0
128 })
129 print("Found chunky turtle: " .. senderId .. " (Fuel: " .. (message.fuel or 0) .. ")")
130 end
131 end
132 end
133
134 return discoveredTurtles, discoveredChunkies
135end
136
137local function selectTurtles(discoveredTurtles, discoveredChunkies)
138 print("\n=== Turtle Selection ===")
139
140 -- Select mining turtle
141 if #discoveredTurtles == 0 then
142 error("No mining turtles found! Make sure mining turtle is running AdvancedMiningTurtle.lua")
143 end
144
145 if #discoveredTurtles == 1 then
146 miningTurtleId = discoveredTurtles[1].id
147 print("Auto-selected mining turtle: " .. miningTurtleId)
148 else
149 print("Multiple mining turtles found:")
150 for i, turtle in ipairs(discoveredTurtles) do
151 print(i .. ". ID: " .. turtle.id .. " - Fuel: " .. turtle.fuel .. " - Inventory: " .. turtle.inventory .. "%")
152 end
153 print("Select mining turtle (1-" .. #discoveredTurtles .. "):")
154 local choice = tonumber(read())
155 if choice and choice >= 1 and choice <= #discoveredTurtles then
156 miningTurtleId = discoveredTurtles[choice].id
157 else
158 error("Invalid selection")
159 end
160 end
161
162 -- Select chunky turtle
163 if #discoveredChunkies == 0 then
164 print("No chunky turtles found. Operation will continue without chunky pairing.")
165 chunkyTurtleId = nil
166 elseif #discoveredChunkies == 1 then
167 chunkyTurtleId = discoveredChunkies[1].id
168 print("Auto-selected chunky turtle: " .. chunkyTurtleId)
169 else
170 print("Multiple chunky turtles found:")
171 for i, chunky in ipairs(discoveredChunkies) do
172 print(i .. ". ID: " .. chunky.id .. " - Fuel: " .. chunky.fuel)
173 end
174 print("Select chunky turtle (1-" .. #discoveredChunkies .. ", or 0 to skip):")
175 local choice = tonumber(read())
176 if choice and choice >= 1 and choice <= #discoveredChunkies then
177 chunkyTurtleId = discoveredChunkies[choice].id
178 elseif choice == 0 then
179 chunkyTurtleId = nil
180 print("Skipping chunky turtle pairing")
181 else
182 error("Invalid selection")
183 end
184 end
185end
186
187---------------------------------------
188---- Operation Functions --------------
189---------------------------------------
190local function getOperationParameters()
191 print("\n=== Operation Parameters ===")
192
193 print("Enter mining depth (forward distance, >= 1):")
194 operationParams.depth = tonumber(read())
195 if not operationParams.depth or operationParams.depth < 1 then
196 error("Invalid depth. Must be >= 1")
197 end
198
199 print("Enter mining width (side distance, cannot be -1, 0, or 1):")
200 operationParams.width = tonumber(read())
201 if not operationParams.width or operationParams.width == -1 or operationParams.width == 0 or operationParams.width == 1 then
202 error("Invalid width. Cannot be -1, 0, or 1")
203 end
204
205 print("Enter mining height (up/down distance, cannot be 0):")
206 operationParams.height = tonumber(read())
207 if not operationParams.height or operationParams.height == 0 then
208 error("Invalid height. Cannot be 0")
209 end
210
211 print("Enter options (space-separated, or press Enter for none):")
212 print("Available options: layerbylayer, startwithin, stripmine")
213 local optionsInput = read()
214 operationParams.options = {}
215 if optionsInput and optionsInput ~= "" then
216 for option in string.gmatch(optionsInput, "%S+") do
217 table.insert(operationParams.options, string.lower(option))
218 end
219 end
220end
221
222local function startOperation()
223 print("\n=== Starting Operation ===")
224
225 -- Build command string
226 local command = tostring(operationParams.depth) .. " " ..
227 tostring(operationParams.width) .. " " ..
228 tostring(operationParams.height)
229
230 if #operationParams.options > 0 then
231 command = command .. " " .. table.concat(operationParams.options, " ")
232 end
233
234 print("Command: " .. command)
235
236 -- Start chunky turtle first if available
237 if chunkyTurtleId then
238 print("Starting chunky turtle...")
239 sendMessage(chunkyTurtleId, {
240 type = "start_chunky",
241 masterId = miningTurtleId,
242 timestamp = os.time()
243 })
244
245 -- Wait for chunky turtle to be ready
246 local response = waitForResponse(chunkyTurtleId, "chunky_ready", 5)
247 if response then
248 print("Chunky turtle ready!")
249 else
250 print("Warning: Chunky turtle did not respond, continuing anyway...")
251 end
252 end
253
254 -- Start mining turtle
255 print("Starting mining turtle...")
256 sendMessage(miningTurtleId, {
257 type = "start_mining",
258 command = command,
259 chunkyId = chunkyTurtleId,
260 timestamp = os.time()
261 })
262
263 -- Wait for mining turtle to start
264 local response = waitForResponse(miningTurtleId, "mining_started", 5)
265 if response then
266 print("Mining operation started!")
267 isOperationActive = true
268 operationStatus = "running"
269 else
270 error("Mining turtle failed to start operation")
271 end
272end
273
274---------------------------------------
275---- Monitoring Functions -------------
276---------------------------------------
277local function monitorOperation()
278 print("\n=== Operation Monitoring ===")
279 print("Press 's' for status, 'p' to pause, 'r' to resume, 'q' to quit monitoring")
280
281 while isOperationActive do
282 local event, key = os.pullEvent("key")
283
284 if key == keys.s then
285 -- Request status update
286 sendMessage(miningTurtleId, {
287 type = "status_request",
288 timestamp = os.time()
289 })
290
291 local statusResponse = waitForResponse(miningTurtleId, "status_update", 2)
292 if statusResponse then
293 print("=== Status Update ===")
294 print("Position: " .. (statusResponse.position or "unknown"))
295 print("Progress: " .. (statusResponse.progress or "unknown"))
296 print("Fuel: " .. (statusResponse.fuel or "unknown"))
297 print("Inventory: " .. (statusResponse.inventory or "unknown"))
298 if statusResponse.chunkyStatus then
299 print("Chunky Status: " .. statusResponse.chunkyStatus)
300 end
301 else
302 print("No status response received")
303 end
304
305 elseif key == keys.p then
306 -- Pause operation
307 sendMessage(miningTurtleId, {
308 type = "pause_operation",
309 timestamp = os.time()
310 })
311 print("Pause command sent")
312
313 elseif key == keys.r then
314 -- Resume operation
315 sendMessage(miningTurtleId, {
316 type = "resume_operation",
317 timestamp = os.time()
318 })
319 print("Resume command sent")
320
321 elseif key == keys.q then
322 -- Quit monitoring (but don't stop operation)
323 print("Stopping monitoring. Operation continues...")
324 break
325 end
326 end
327end
328
329local function stopOperation()
330 print("\n=== Stopping Operation ===")
331
332 if isOperationActive then
333 -- Stop mining turtle
334 sendMessage(miningTurtleId, {
335 type = "stop_operation",
336 timestamp = os.time()
337 })
338
339 -- Stop chunky turtle if active
340 if chunkyTurtleId then
341 sendMessage(chunkyTurtleId, {
342 type = "stop_operation",
343 timestamp = os.time()
344 })
345 end
346
347 isOperationActive = false
348 operationStatus = "stopped"
349 print("Stop commands sent to all turtles")
350 end
351end
352
353---------------------------------------
354---- Main Program ----------------------
355---------------------------------------
356local function main()
357 term.clear()
358 term.setCursorPos(1, 1)
359
360 print("==========================================")
361 print(" Advanced Mining Controller " .. cVersion)
362 print("==========================================")
363 print()
364
365 -- Initialize rednet
366 local modemSide = findModem()
367 rednet.open(modemSide)
368 print("Rednet initialized on " .. modemSide)
369
370 -- Discover turtles
371 local discoveredTurtles, discoveredChunkies = discoverTurtles()
372
373 if #discoveredTurtles == 0 then
374 error("No mining turtles found! Make sure at least one mining turtle is running AdvancedMiningTurtle.lua")
375 end
376
377 -- Select turtles
378 selectTurtles(discoveredTurtles, discoveredChunkies)
379
380 -- Get operation parameters
381 getOperationParameters()
382
383 -- Confirm operation
384 print("\n=== Operation Summary ===")
385 print("Mining Turtle: " .. miningTurtleId)
386 print("Chunky Turtle: " .. (chunkyTurtleId or "None"))
387 print("Parameters: " .. operationParams.depth .. " x " .. operationParams.width .. " x " .. operationParams.height)
388 if #operationParams.options > 0 then
389 print("Options: " .. table.concat(operationParams.options, ", "))
390 end
391 print()
392 print("Start operation? (y/n):")
393 local confirm = read()
394
395 if string.lower(confirm) == "y" or string.lower(confirm) == "yes" then
396 startOperation()
397
398 -- Monitor operation
399 monitorOperation()
400
401 -- Final stop
402 stopOperation()
403 else
404 print("Operation cancelled")
405 end
406
407 print("\nAdvanced Mining Controller finished.")
408end
409
410-- Run main program
411local ok, err = pcall(main)
412if not ok then
413 print("Error: " .. tostring(err))
414 print("Press any key to exit...")
415 os.pullEvent("key")
416end
417