Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Kino Drone Script for OpenComputers (Optimized for Memory)
- local component = component
- local computer = computer
- local modem = component.list("modem")()
- local drone = component.list("drone")()
- local geolyzer = component.list("geolyzer")()
- local radar = component.list("radar")()
- local chunkloader = component.list("chunkloader")()
- modem = modem and component.proxy(modem)
- drone = drone and component.proxy(drone)
- geolyzer = geolyzer and component.proxy(geolyzer)
- radar = radar and component.proxy(radar)
- chunkloader = chunkloader and component.proxy(chunkloader)
- confirmed_move = false
- got_address = false
- local Version = "1.0.0"
- local base_address = ""
- local tablet_address = ""
- local scan_mode = "normal"
- local SCAN_HEIGHT = 10
- local scan_step = 1
- local scan_x, scan_y, scan_z = 0, -3, 0 -- Start at Kino's position
- local step_size = 4 -- Scan size (4x4x4)
- local max_radius = 10 -- Maximum scan range
- local layer = 0 -- Current expansion layer
- local direction = 1 -- 1 = right, 2 = down, 3 = left, 4 = up
- local moves_per_layer = 1
- local move_count = 0
- local no_geo = false
- local batch_scan_data = {} -- Buffer to store multiple scan results
- local batch_threshold = 5 -- Number of scans before sending
- local low_energy = false
- local fine_motor_control = false
- local kino_x, kino_y, kino_z = 0, 0, 0
- local scanned_positions = {}
- local function debug(msg)
- modem.send(base_address, 123, "debug", msg)
- end
- modem.open(123)
- local function sleep(time)
- local start = computer.uptime()
- while computer.uptime() - start < time do
- computer.pullSignal(0) -- ✅ Allows OpenComputers to process events
- end
- end
- local function can_move(direction)
- local blocked, blockType = drone.detect(direction)
- if not blocked then
- return true -- ✅ Path is clear, movement allowed
- elseif blockType == "passable" or blockType == "air" or blockType == "replaceable" then
- return true -- ✅ Movement allowed through these block types
- else
- return false -- ❌ Movement blocked
- end
- end
- -- **Optimized Movement Function with Position Tracking**
- local function move(dx, dy, dz)
- drone.move(dx, dy, dz)
- sleep(0.5) -- ✅ **Wait for movement to complete**
- kino_x = kino_x + dx
- kino_y = kino_y + dy
- kino_z = kino_z + dz
- end
- -- Function to send all accumulated data
- function send_scan_data()
- if #batch_scan_data == 0 then return end
- -- ✅ Check energy level
- local energy_level = computer.energy() / computer.maxEnergy()
- if energy_level < 0.07 then
- low_energy = true -- ⚡ Mark for shutdown
- end
- for i = 1, #batch_scan_data, 20 do
- modem.send(base_address, 123, "scan_data", table.concat(batch_scan_data, ",", i, math.min(i + 19, #batch_scan_data)))
- sleep(0.1)
- end
- batch_scan_data = {} -- Clear buffer after sending
- end
- local function perform_scan(x, y, z)
- -- Avoid scanning the same position twice
- local scan_key = x .. "," .. y .. "," .. z
- if scanned_positions[scan_key] then
- return
- end
- scanned_positions[scan_key] = true
- local success, result = pcall(geolyzer.scan, x, z, y, 4, 4, 4)
- if success and type(result) == "table" then
- for i, density in ipairs(result) do
- local sx = ((i - 1) % 4) + x
- local sz = (((i - 1) // 4) % 4) + z
- local sy = (((i - 1) // 16) % 4) + y
- if density > 0 then
- table.insert(batch_scan_data, sx)
- table.insert(batch_scan_data, sy)
- table.insert(batch_scan_data, sz)
- table.insert(batch_scan_data, density)
- end
- end
- else
- debug("❌ Scan failed at X=" .. x .. " Y=" .. y .. " Z=" .. z)
- end
- -- Send data if batch threshold is reached
- if #batch_scan_data >= batch_threshold * 20 then
- send_scan_data()
- end
- end
- local function calculate_scan_coords()
- if low_energy then
- debug("[⚠️] Low energy detected! Sending last scan data and shutting down.")
- send_scan_data() -- Ensure all data is sent before shutdown
- modem.send(tablet_address, 123, "shutdownenergy")
- computer.shutdown()
- end
- -- Scan the Kino’s position first
- perform_scan(scan_x, scan_y, scan_z)
- -- Adjust X scanning (Alternate Positive/Negative)
- if scan_x == 0 and scan_z == 0 then
- scan_x = -step_size -- Start negative first
- elseif scan_x < 0 then
- scan_x = -scan_x -- Flip to positive side
- else
- scan_x = -(scan_x + step_size) -- Move further negative
- end
- -- Ensure Z alternates properly
- if math.abs(scan_x) > max_radius then
- scan_x = 0
- if scan_z >= 0 then
- scan_z = -scan_z - step_size -- Move to negative Z if not already
- else
- scan_z = -scan_z -- Flip to positive
- end
- end
- -- Move upwards if we've fully scanned the X-Z plane
- if math.abs(scan_z) > max_radius then
- scan_x, scan_z = 0, 0
- scan_y = scan_y + step_size
- end
- -- Stop if max height is reached
- if scan_y > SCAN_HEIGHT then
- debug("[✔] Full area scan completed.")
- return false
- end
- return true
- end
- local function scan_entire_area()
- debug("[🔄] Starting full area scan...")
- drone.setStatusText("Scanning")
- drone.setLightColor(008000)
- while calculate_scan_coords() do
- sleep(0.2) -- Small delay to prevent CPU overload
- end
- send_scan_data()
- debug("[✔] Full area scan completed.")
- scan_x, scan_y, scan_z = 0, -4, 0 -- Start at Kino's position
- step_size = 4 -- Scan size (4x4x4)
- scanned_positions = {}
- modem.send(tablet_address, 123, "finish")
- drone.setStatusText("Ready")
- drone.setLightColor(32768)
- end
- -- Confirm script upload to sender
- modem.broadcast(123, "kino_update_success")
- drone.setStatusText("Waiting")
- while not got_address do
- local _, _, sender, _, _, cmd, value, value2 = computer.pullSignal(5)
- if cmd == "adresses" and value then
- tablet_address = value
- base_address = value2
- got_address = true
- debug("[✔] Tablet address updated: " .. tablet_address)
- debug("[✔] Base address updated: " .. base_address)
- end
- end
- if not modem or not drone then
- debug("[❌] Missing modem or drone component!")
- end
- if not geolyzer then
- debug("[❌] No Geolyzer found, stopping.")
- no_geo = true
- end
- if not chunkloader then
- debug("[❌] No Chunkloader found, Kino wont scan correctly.")
- elseif chunkloader then
- chunkloader.setActive(true)
- end
- drone.setStatusText("Ready")
- drone.setLightColor(32768)
- -- **Main Loop: Handles movement + scan mode**
- while got_address and not no_geo do
- local _, _, sender, _, _, cmd, value = computer.pullSignal(5)
- if sender == tablet_address then
- if cmd == "move" then
- if value == "forward" and not confirmed_move then
- move(scan_step, 0, 0)
- elseif value == "forward" and confirmed_move then
- drone.move(scan_step, 0, 0)
- sleep(0.2)
- computer.shutdown()
- elseif value == "backward" and not confirmed_move then
- move(-scan_step, 0, 0)
- elseif value == "backward" and confirmed_move then
- drone.move(-scan_step, 0, 0)
- sleep(0.2)
- computer.shutdown()
- elseif value == "left" and not confirmed_move then
- move(0, 0, -scan_step)
- elseif value == "left" and confirmed_move then
- drone.move(0, 0, -scan_step)
- sleep(0.2)
- computer.shutdown()
- elseif value == "right" and not confirmed_move then
- move(0, 0, scan_step)
- elseif value == "right" and confirmed_move then
- drone.move(0, 0, scan_step)
- sleep(0.2)
- computer.shutdown()
- elseif value == "up" and not confirmed_move then
- move(0, scan_step, 0)
- elseif value == "down" and not confirmed_move then
- move(0, -scan_step, 0)
- end
- elseif cmd == "set_scan_mode" then scan_mode = value
- elseif cmd == "scanconfirm" then
- modem.send(base_address, 123, "newscan")
- modem.send(tablet_address, 123, "newscan")
- elseif cmd == "scan" then
- if scan_mode == "normal" and not confirmed_move then
- modem.send(tablet_address, 123, "moveme")
- elseif scan_mode == "normal" and confirmed_move then
- -- why are we here, just to suffer
- elseif scan_mode == "manual" then
- scan_entire_area()
- end
- elseif cmd == "fine_control" then
- if value == "on" then
- fine_motor_control = true
- scan_step = 4
- debug("[🔧] Fine Motor Control ENABLED")
- elseif value == "off" then
- fine_motor_control = false
- scan_step = 1
- debug("[🔧] Fine Motor Control DISABLED")
- end
- elseif cmd == "confirmed_move" then
- confirmed_move = true
- elseif cmd == "autoscan" then
- modem.send(tablet_address, 123, "autoscanning")
- scan_entire_area()
- elseif cmd == "shutdown" then
- debug("Shutting Down")
- modem.send(tablet_address, 123, "shutok")
- sleep(1)
- computer.shutdown()
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement