Advertisement
samuelask

Kino Script

Mar 8th, 2025 (edited)
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.87 KB | None | 0 0
  1. -- Kino Drone Script for OpenComputers (Optimized for Memory)
  2. local component = component
  3. local computer = computer
  4.  
  5. local modem = component.list("modem")()
  6. local drone = component.list("drone")()
  7. local geolyzer = component.list("geolyzer")()
  8. local radar = component.list("radar")()
  9. local chunkloader = component.list("chunkloader")()
  10.  
  11. modem = modem and component.proxy(modem)
  12. drone = drone and component.proxy(drone)
  13. geolyzer = geolyzer and component.proxy(geolyzer)
  14. radar = radar and component.proxy(radar)
  15. chunkloader = chunkloader and component.proxy(chunkloader)
  16.  
  17. got_address = false
  18. local base_address = "a676e3d0-282e-401b-8848-bd6ee3b3fa98"
  19. local tablet_address = ""
  20. local scan_mode = "normal"
  21.  
  22. local SCAN_HEIGHT = 10
  23.  
  24. local scan_x, scan_y, scan_z = 0, -4, 0  -- Start at Kino's position
  25. local step_size = 4  -- Scan size (4x4x4)
  26. local max_radius = 12  -- Maximum scan range
  27. local layer = 0  -- Current expansion layer
  28. local direction = 1  -- 1 = right, 2 = down, 3 = left, 4 = up
  29. local moves_per_layer = 1
  30. local move_count = 0
  31. local no_geo = false
  32. local no_chunk = false
  33. local batch_scan_data = {}  -- Buffer to store multiple scan results
  34. local batch_threshold = 5    -- Number of scans before sending
  35. local low_energy = false
  36. local fine_motor_control = false
  37.  
  38. local kino_x, kino_y, kino_z = 0, 0, 0
  39.  
  40. local scanned_positions = {}
  41.  
  42. local function debug(msg)
  43.     modem.send(base_address, 123, "debug", msg)
  44. end
  45.  
  46. modem.open(123)
  47.  
  48. local function sleep(time)
  49.     local start = computer.uptime()
  50.     while computer.uptime() - start < time do
  51.         computer.pullSignal(0)  -- ✅ Allows OpenComputers to process events
  52.     end
  53. end
  54. local function can_move(direction)
  55.     local blocked, blockType = drone.detect(direction)
  56.  
  57.     if not blocked then
  58.         return true  -- ✅ Path is clear, movement allowed
  59.     elseif blockType == "passable" or blockType == "air" or blockType == "replaceable" then
  60.         return true  -- ✅ Movement allowed through these block types
  61.     else
  62.         return false -- ❌ Movement blocked
  63.     end
  64. end
  65. -- **Optimized Movement Function with Position Tracking**
  66. local function move(dx, dy, dz)
  67.     drone.move(dx, dy, dz)
  68.     sleep(0.5)  -- ✅ **Wait for movement to complete**
  69.     kino_x = kino_x + dx
  70.     kino_y = kino_y + dy
  71.     kino_z = kino_z + dz
  72. end
  73. -- Function to send all accumulated data
  74. function send_scan_data()
  75.     if #batch_scan_data == 0 then return end
  76.    
  77.         -- ✅ Check energy level
  78.     local energy_level = computer.energy() / computer.maxEnergy()
  79.     if energy_level < 0.05 then
  80.         low_energy = true -- ⚡ Mark for shutdown
  81.     end
  82.    
  83.     for i = 1, #batch_scan_data, 20 do
  84.         modem.send(base_address, 123, "scan_data", table.concat(batch_scan_data, ",", i, math.min(i + 19, #batch_scan_data)))
  85.         sleep(0.1)
  86.     end
  87.     batch_scan_data = {} -- Clear buffer after sending
  88. end
  89. local function perform_scan(x, y, z)
  90.  
  91.     -- Avoid scanning the same position twice
  92.     local scan_key = x .. "," .. y .. "," .. z
  93.     if scanned_positions[scan_key] then
  94.         return
  95.     end
  96.     scanned_positions[scan_key] = true
  97.  
  98.     local success, result = pcall(geolyzer.scan, x, z, y, 4, 4, 4)
  99.  
  100.     if success and type(result) == "table" then
  101.         for i, density in ipairs(result) do
  102.             local sx = ((i - 1) % 4) + x
  103.             local sz = (((i - 1) // 4) % 4) + z
  104.             local sy = (((i - 1) // 16) % 4) + y
  105.             if density > 0 then
  106.                 table.insert(batch_scan_data, sx)
  107.                 table.insert(batch_scan_data, sy)
  108.                 table.insert(batch_scan_data, sz)
  109.                 table.insert(batch_scan_data, density)
  110.             end
  111.         end
  112.     else
  113.         debug("❌ Scan failed at X=" .. x .. " Y=" .. y .. " Z=" .. z)
  114.     end
  115.    
  116.     -- Send data if batch threshold is reached
  117.     if #batch_scan_data >= batch_threshold * 20 then
  118.         send_scan_data()
  119.     end
  120. end
  121. local function calculate_scan_coords()
  122.     if low_energy then
  123.         debug("⚠️ Low energy detected! Sending last scan data and shutting down.")
  124.         send_scan_data() -- Ensure all data is sent before shutdown
  125.         modem.send(tablet_address, 123, "shutdownenergy")
  126.         computer.shutdown()
  127.         return
  128.     end
  129.    
  130.     -- Scan the Kino’s position first
  131.     perform_scan(scan_x, scan_y, scan_z)
  132.  
  133.     -- Adjust X scanning (Alternate Positive/Negative)
  134.     if scan_x == 0 and scan_z == 0 then
  135.         scan_x = -step_size  -- Start negative first
  136.     elseif scan_x < 0 then
  137.         scan_x = -scan_x     -- Flip to positive side
  138.     else
  139.         scan_x = -(scan_x + step_size) -- Move further negative
  140.     end
  141.  
  142.     -- Ensure Z alternates properly
  143.     if math.abs(scan_x) > max_radius then
  144.         scan_x = 0
  145.         if scan_z >= 0 then
  146.             scan_z = -scan_z - step_size -- Move to negative Z if not already
  147.         else
  148.             scan_z = -scan_z  -- Flip to positive
  149.         end
  150.     end
  151.  
  152.     -- Move upwards if we've fully scanned the X-Z plane
  153.     if math.abs(scan_z) > max_radius then
  154.         scan_x, scan_z = 0, 0
  155.         scan_y = scan_y + step_size
  156.     end
  157.  
  158.     -- Stop if max height is reached
  159.     if scan_y > SCAN_HEIGHT then
  160.         debug("✅ Full area scan completed.")
  161.         return false
  162.     end
  163.  
  164.     return true
  165. end
  166. local function scan_entire_area()
  167.     debug("🔄 Starting full area scan...")
  168.     drone.setStatusText("Scanning")
  169.     drone.setLightColor(008000)
  170.  
  171.     while calculate_scan_coords() do
  172.         sleep(0.2)  -- Small delay to prevent CPU overload
  173.     end
  174.    
  175.     send_scan_data()
  176.     debug("✅ Full area scan completed.")
  177.     scan_x, scan_y, scan_z = 0, -4, 0  -- Start at Kino's position
  178.     step_size = 4  -- Scan size (4x4x4)
  179.     scanned_positions = {}
  180.     modem.send(tablet_address, 123, "finish")
  181.     drone.setStatusText("Ready")
  182.     drone.setLightColor(32768)
  183. end
  184. -- Confirm script upload to sender
  185. modem.broadcast(123, "kino_update_success")
  186. drone.setStatusText("Waiting")
  187. while not got_address do
  188.     local _, _, sender, _, _, cmd, value = computer.pullSignal(5)  
  189.     if cmd == "adresses" and value then
  190.         tablet_address = value
  191.         got_address = true
  192.         debug("[✔] Tablet address updated: " .. tablet_address)
  193.     end
  194. end
  195.  
  196. if not modem or not drone then
  197.     debug("Missing modem or drone component!")
  198. end
  199. if not geolyzer then
  200.     debug("❌ No Geolyzer found, stopping.")
  201.     no_geo = true
  202. end
  203. if not chunkloader then
  204.     debug("❌ No Chunkloader found, Kino wont scan correctly.")
  205.     no_chunk = true
  206. end
  207. if not no_chunk then
  208.     chunkloader.setActive(true)
  209. end
  210. drone.setStatusText("Ready")
  211. drone.setLightColor(32768)
  212. -- **Main Loop: Handles movement + scan mode**
  213. while got_address and not no_geo do
  214.     local _, _, sender, _, _, cmd, value = computer.pullSignal(5)
  215.  
  216.     if sender == tablet_address then
  217.         if cmd == "move" then
  218.             if value == "forward" then move(scan_step, 0, 0)
  219.             elseif value == "backward" then move(-scan_step, 0, 0)
  220.             elseif value == "left" then move(0, 0, -scan_step)
  221.             elseif value == "right" then move(0, 0, scan_step)
  222.             elseif value == "up" then move(0, scan_step, 0)
  223.             elseif value == "down" then move(0, -scan_step, 0)
  224.             end
  225.         elseif cmd == "set_scan_mode" then scan_mode = value
  226.         elseif cmd == "scanconfirm" then
  227.             modem.send(base_address, 123, "newscan")
  228.             modem.send(tablet_address, 123, "newscan")
  229.         elseif cmd == "scan" then
  230.             scan_entire_area()
  231.         elseif cmd == "fine_control" then
  232.                 if value == "on" then
  233.                     fine_motor_control = true
  234.                     scan_step = 1
  235.                     debug("🔧 Fine Motor Control ENABLED")
  236.                 elseif value == "off" then
  237.                     fine_motor_control = false
  238.                     scan_step = 4
  239.                     debug("🔧 Fine Motor Control DISABLED")
  240.                 end
  241.         elseif cmd == "shutdown" then
  242.             debug("Shutting Down")
  243.             modem.send(tablet_address, 123, "shutok")
  244.             sleep(1)
  245.             computer.shutdown()
  246.         end
  247.     end
  248. end
  249.  
  250. debug("No Geolyzer Installed!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement