Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Wrap peripherals
- local scanner = peripheral.wrap("back")
- local monitor = peripheral.wrap("top")
- local modem = peripheral.find("modem") or error("No modem attached", 0)
- local comp_x, comp_y, comp_z = gps.locate()
- local direction = "south" -- Options: north, south, east, west
- if not scanner then
- print("Universal Scanner not found!")
- return
- end
- if not monitor then
- print("Monitor not found!")
- return
- end
- -- Monitor setup
- monitor.setTextScale(0.5)
- monitor.setBackgroundColor(colors.black)
- monitor.setTextColor(colors.white)
- -- Parameters
- local monWidth, monHeight = monitor.getSize()
- local centerX, centerY = math.floor(monWidth / 2), math.floor(monHeight / 2)
- local iconMap = {}
- local infoEntityUUID = nil
- local currentEntity = nil
- local infoBoxLines = 6
- local infoBoxXBtn = { x = monWidth - 2, y = 1 }
- local fireButton = { label = "[FIRE]", x = 1, y = 6 }
- local radiusOptions = { 10, 16, 20 }
- local radiusIndex = 3
- local maxRange = radiusOptions[radiusIndex]
- local radiusButton = { label = "", x = 1, y = monHeight }
- local firingContinuously = false
- local flashState = false
- -- Helpers
- local function getRelativeTargetCoords(entity)
- local dy = entity.y + comp_y
- local dx = comp_x - entity.x
- local dz = comp_z - entity.z
- if direction == "north" then
- local dx = comp_x + entity.x
- local dz = comp_z + entity.z
- elseif direction == "south" then
- return dx, dy, dz
- elseif direction == "east" then
- local dz = comp_z + entity.z
- elseif direction == "west" then
- local dx = comp_x + entity.x
- end
- return dx, dy, dz
- end
- local function toScreen(x, z)
- local scale = maxRange
- local screenX = centerX + math.floor(x / scale * centerX)
- local screenY = centerY + math.floor(z / scale * centerY)
- return screenX, screenY
- end
- local function drawInfo(entity)
- monitor.setBackgroundColor(firingContinuously and (flashState and colors.red or colors.gray) or colors.gray)
- monitor.setTextColor(colors.white)
- for i = 1, infoBoxLines do
- monitor.setCursorPos(1, i)
- monitor.write(string.rep(" ", monWidth))
- end
- monitor.setCursorPos(infoBoxXBtn.x, infoBoxXBtn.y)
- monitor.setTextColor(colors.red)
- monitor.write("[X]")
- monitor.setCursorPos(1, 1)
- monitor.setTextColor(colors.white)
- monitor.write("Name: " .. (entity.displayName or "unknown"))
- monitor.setCursorPos(1, 2)
- monitor.write("Type: " .. (entity.type or "unknown"))
- monitor.setCursorPos(1, 3)
- monitor.write("Health: " .. (entity.health or "?"))
- monitor.setCursorPos(1, 4)
- monitor.write(string.format("REL Pos: %.1f, %.1f, %.1f", entity.x, entity.y, entity.z))
- local tx, ty, tz = getRelativeTargetCoords(entity)
- monitor.setCursorPos(1, 5)
- monitor.write(string.format("ABS Pos: %.1f, %.1f, %.1f", tx, ty, tz))
- monitor.setCursorPos(fireButton.x, fireButton.y)
- monitor.setTextColor(colors.orange)
- if firingContinuously then
- monitor.write("[STOP]")
- else
- monitor.write(fireButton.label)
- end
- monitor.setBackgroundColor(colors.black)
- end
- local function drawEntityCount(count)
- monitor.setCursorPos(1, 1)
- monitor.setTextColor(colors.yellow)
- monitor.write("Entities: " .. tostring(count))
- monitor.setTextColor(colors.white)
- end
- local function drawRadiusButton()
- radiusButton.label = "Radius: [" .. tostring(maxRange) .. "]"
- radiusButton.x = monWidth - #radiusButton.label + 1
- monitor.setCursorPos(radiusButton.x, radiusButton.y)
- monitor.setTextColor(colors.cyan)
- monitor.write(radiusButton.label)
- monitor.setTextColor(colors.white)
- end
- local function drawRadar(entities)
- iconMap = {}
- monitor.setBackgroundColor(colors.black)
- monitor.clear()
- monitor.setCursorPos(centerX, centerY)
- monitor.setTextColor(colors.white)
- monitor.write("+")
- local displayedCount = 0
- local found = false
- for _, entity in ipairs(entities) do
- if entity.displayName ~= "Armor Stand" and entity.displayName ~= "Hat Stand" then
- local screenX, screenY = toScreen(entity.x, entity.z)
- if screenX >= 1 and screenX <= monWidth and screenY >= 1 and screenY <= monHeight then
- local key = screenX .. "," .. screenY
- iconMap[key] = entity
- monitor.setCursorPos(screenX, screenY)
- if entity.uuid == infoEntityUUID and firingContinuously then
- monitor.setTextColor(flashState and colors.orange or colors.red)
- elseif entity.displayName == "Player" then
- monitor.setTextColor(colors.lime)
- else
- monitor.setTextColor(colors.red)
- end
- local displayChar = entity.displayName and entity.displayName:sub(1, 1) or "?"
- monitor.write(displayChar)
- displayedCount = displayedCount + 1
- end
- if infoEntityUUID and entity.uuid == infoEntityUUID then
- currentEntity = entity
- found = true
- end
- end
- end
- if not found then
- currentEntity = nil
- infoEntityUUID = nil
- firingContinuously = false
- end
- if currentEntity then
- drawInfo(currentEntity)
- else
- drawEntityCount(displayedCount)
- end
- drawRadiusButton()
- monitor.setTextColor(colors.white)
- end
- local function sendFireCommand(entity)
- local tx, ty, tz = getRelativeTargetCoords(entity)
- local messages = {"Artillery", "Arrows", "Scatter", "1", tostring(tx), tostring(ty), tostring(tz)}
- for _, msg in ipairs(messages) do
- modem.transmit(15, 43, msg)
- sleep(0.1)
- end
- end
- -- Main loop
- while true do
- flashState = not flashState
- local status, entities = pcall(function()
- return scanner.scan("entity", maxRange)
- end)
- if not status or not entities then
- print("Scan failed or returned nil.")
- end
- drawRadar(entities)
- local timer = os.startTimer(2)
- if firingContinuously and currentEntity then
- sendFireCommand(currentEntity)
- end
- while true do
- local event, side, x, y = os.pullEvent()
- if event == "monitor_touch" then
- if x >= infoBoxXBtn.x and x <= infoBoxXBtn.x + 2 and y == infoBoxXBtn.y then
- infoEntityUUID, currentEntity = nil, nil
- firingContinuously = false
- drawRadar(entities)
- elseif y == radiusButton.y and x >= radiusButton.x and x <= radiusButton.x + #radiusButton.label - 1 then
- radiusIndex = radiusIndex % #radiusOptions + 1
- maxRange = radiusOptions[radiusIndex]
- infoEntityUUID, currentEntity = nil, nil
- firingContinuously = false
- break
- elseif currentEntity and y == fireButton.y and x >= fireButton.x and x <= fireButton.x + #fireButton.label - 1 then
- firingContinuously = not firingContinuously
- drawRadar(entities)
- else
- local key = x .. "," .. y
- if iconMap[key] then
- infoEntityUUID = iconMap[key].uuid
- currentEntity = iconMap[key]
- drawRadar(entities)
- end
- end
- elseif event == "timer" and side == timer then
- break
- end
- end
- ::continue::
- end
Advertisement
Add Comment
Please, Sign In to add comment