This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
dimsedut's profile picture

An automated attack turtle with GPS coordinates?

Started by dimsedut, 15 November 2014 - 11:13 AM
dimsedut #1
Posted 15 November 2014 - 12:13 PM
Hi,

I saw a video earlier with a guy who had a wireless melee turtle to hunt down monsters and attack them until dead. Unfortunately there were no links to any code,soo.. thats why I create this post now: have anyone been working with this?
I have build a GPS system, found a program that will tell a turtle to go to a specific coordinate i provide - so far so good. But, I would need a computer to realtime get the current coordinates of a monster and sending it to the turtle - updating it realtime - so that it will move towards the monster and keep hitting it until dead.
Anyone has some good ideas to continue forward in this process? Maybe someone already created something that works? :-)

The program that sends the turtle to a specific coordinate (then nothing else, does not attack or make sure that it faces front to the monster etc)
  • – this program is for a turtle and you give it coords and it will go there, just be sure to ahve a gps network set up
  • local tArgs = {}
  • local x = tonumber(tArgs[1])
  • local y = tonumber(tArgs[2])
  • local z = tonumber(tArgs[3])
  • local curx, cury, curz, dir
  • function getPos()
  • return gps.locate(3)
  • end
  • function getDir()
  • local dir, x, y, z
  • x, y, z = getPos()
  • while not turtle.forward() do
  • while not turtle.up() do
  • turtle.digUp()
  • end
  • end
  • nx, ny, nz = getPos()
  • –print ("New: "..nx..","..ny..","..nz)
  • if (x == nx) then
  • if (nz > z) then
  • dir = 2
  • else
  • dir = 0
  • end
  • else
  • if (nx > x) then
  • dir = 3
  • else
  • dir = 1
  • end
  • end
  • return dir
  • end
  • function setDir(toDir)
  • while toDir ~= dir do
  • turtle.turnLeft()
  • if dir == 3 then
  • dir = 0
  • else
  • dir = dir+1
  • end
  • end
  • end
  • function moveX()
  • distxx = x - curx
  • –print(distx)
  • if (x > curx) then
  • setDir(3)
  • else
  • setDir(1)
  • end
  • distx = math.abs(distx)
  • –print(distx)
  • for i = 1, distx do
  • while not turtle.forward() do
  • while not turtle.up() do
  • turtle.digUp()
  • end
  • end
  • end
  • end
  • function moveZ()
  • distz = z - curz
  • if (z < curz) then
  • setDir(0)
  • else
  • setDir(2)
  • end
  • distz = math.abs(distz)
  • – print(distz)
  • for i = 1, distz do
  • while not turtle.forward() do
  • while not turtle.up() do
  • turtle.digUp()
  • end
  • end
  • end
  • end
  • function moveY()
  • disty = y - cury
  • disty = math.abs(disty)
  • if (y < cury) then
  • for i = 1, disty do
  • while not turtle.down() do
  • turtle.digDown()
  • end
  • end
  • else
  • for i = 1, disty do
  • while not turtle.up() do
  • turtle.digUp()
  • end
  • end
  • end
  • end
  • if not x or not y or not z then
  • print("Must supply X Y Z")
  • exit()
  • end
  • rednet.open("right")
  • –print (x..","..y..","..z)
  • dir = getDir()
  • curx, cury, curz = getPos()
  • distx = x - curx
  • disty = y - cury
  • distz = z - curz
  • –print (" Current: "..curx..","..cury..","..curz)
  • –print ("Distance: ",, distx,,",".. disty..","..distz)
  • moveX()
  • curx, cury, curz = getPos()
  • moveZ()
  • curx, cury, curz = getPos()
  • moveY()
  • curx, cury, curz = getPos()
  • print("Current: "..curx..","..cury..","..curz)
KingofGamesYami #2
Posted 15 November 2014 - 10:40 PM
Ok, first: code tags. Use them. Or pastebin.
(without spaces)

Second: Without a third party mod, there is no way to detect where a player or mob is. The best you can get is if your turtle cant move forward and it does not detect a block, it is obstructed by either a player or a monster.
Bomb Bloke #3
Posted 15 November 2014 - 11:19 PM
I've got these scripts for a server and some turtles which basically beats up players who wandered into my base without "permission". They walk in, and about a dozen turtles rise up out of the ground to greet them…

I don't expect anyone to figure out exactly how to implement it all without documentation, but it should at least give you some ideas as to how to use a sensor for this task.
dimsedut #4
Posted 16 November 2014 - 11:09 AM
Hi Bomb Bloke!

those scripts looks awsome! I've installed it now and the turtle is now running arround, but can't get any commands from the computer, as I get an "attempt to call nill value" from line 19.. I have changed the values in your script to fit my little test setup - am I missing something in order for it to work ?

The setup:
I have one advanced computer with a sensor on the left and 3 advanced monitors on the top and a wireless modem on the right (the modem is active - it is glowing red). It seems like it is not detecting the monitors I guess?


local whiteList = {["Angrymouse666"] = true, ["Kimsni"] = true}

local sensorPos, mon, roomSensor, hunting = {-233,30,2876}, {}
local doorPos = {-227,30,2879}
local bounds = {{-227,-220},{30,35},{2871,2879}}

do
        local periphs = peripheral.getNames()

        for i=1,#periphs do if peripheral.getType(periphs[i]) == "monitor" then
                mon[#mon+1] = peripheral.wrap(periphs[i])
        elseif peripheral.getType(periphs[i]) == "openperipheral_sensor" then
                roomSensor = peripheral.wrap(periphs[i])
        elseif peripheral.getType(periphs[i]) == "modem" and peripheral.call(periphs[i],"isWireless") then
                rednet.open(periphs[i])
        end end
end

for i=1,3 do mon[i].setTextScale(2) end

local function clearMon(i)
        mon[i].setTextColour(colours.white)
        mon[i].setBackgroundColour(colours.black)
        mon[i].setTextScale(2)
        mon[i].clear()
        mon[i].setCursorPos(1,1)
end

local function monPrint(i,text)
        local xPos,yPos = mon[i].getCursorPos()
        mon[i].write(text)
        mon[i].setCursorPos(1,yPos+1)
end

whiteList["Angrymouse666"] = true
whiteList["Kimsni"] = true

rednet.broadcast({"basepatrol"})

while true do
        local players = roomSensor.getPlayerNames()
        table.sort(players)

        for i=1,#players do
                local pData = roomSensor.getPlayerData(players[i])

                if pData then
                        pData.position.x = math.floor(pData.position.x + sensorPos[1])
                        pData.position.y = math.floor(pData.position.y + sensorPos[2])
                        pData.position.z = math.floor(pData.position.z + sensorPos[3])
                        players[players[i]] = pData
                end
        end

        ----------------------------------------
        -- Open / close computer access door: --
        ----------------------------------------
        local doorClose = true
        for i=1,#players do if players[players[i]] and whiteList[players[i]] and math.abs(doorPos[1]-players[players[i]].position.x) < 5 andmath.abs(doorPos[2]-players[players[i]].position.y) < 5 and math.abs(doorPos[3]-players[players[i]].position.z) < 5 then doorClose = false endend
        rs.setOutput("left",doorClose)

        for i=1,#players do if players[players[i]] and (players[players[i]].position.x < bounds[1][1] or players[players[i]].position.x >bounds[1][2] or players[players[i]].position.y < bounds[2][1] or players[players[i]].position.y > bounds[2][2] orplayers[players[i]].position.z < bounds[3][1] or players[players[i]].position.z > bounds[3][2]) then players[players[i]] = nil end end

        ----------------------------------------
        --   Update basic monitor readouts:   --
        ----------------------------------------
        local counter = 1

        for i=1,#players do
                if players[players[i]] then
                        clearMon(counter)

                        mon[counter].setTextColour(whiteList[players[i]] and colours.green or colours.red)
                        monPrint(counter,players[i])
                        mon[counter].setTextColour(colours.white)

                        monPrint(counter,"X: "..players[players[i]].position.x.." Y: "..players[players[i]].position.y.." Z: "..players[players[i]].position.z)
                        monPrint(counter,players[players[i]].heldItem and ("Equipped: "..players[players[i]].heldItem.name) or "")
                        monPrint(counter,"")
                        monPrint(counter,"Health: "..players[players[i]].health.."/"..players[players[i]].maxHealth)
                        monPrint(counter,"Food:   "..players[players[i]].foodLevel)

                        counter = counter + 1
                        if counter > #mon then break end
                end
        end

        for i=counter,#mon do clearMon(i) end

        ----------------------------------------
        --              Turtles:              --
        ----------------------------------------
        local oldhunt = hunting
        hunting = nil

        for i=1,#players do if players[players[i]] and not whiteList[players[i]] then hunting = players[i] end end

        if hunting then rednet.broadcast({"basepatrol",hunting,{players[hunting].position.x,players[hunting].position.z,players[hunting].position.y}}) end

        if oldhunt and not hunting then rednet.broadcast({"basepatrol"}) end

        sleep(1)
end
dimsedut #5
Posted 16 November 2014 - 11:56 AM
Correction: the error code on the computer is: 19: attempt to index ? (a nil value)
Luca_S #6
Posted 16 November 2014 - 12:49 PM
Please post the code again in a code block, because idk what line 19 is, if i counted correclty, Line 19 is a comment and a comment cant error(if you mark it as comment)

Tried the code now, my turtle isnt moving at all( and it is fueled)
Edited on 16 November 2014 - 11:58 AM
Bomb Bloke #7
Posted 16 November 2014 - 01:32 PM
Assuming you mean line 19 of my server-controlling script reads:

for i=1,3 do mon[i].setTextScale(2) end

This attempts to change the text scale of the three monitors I attached to the system. If you don't have three monitors attached, then, well, it's gonna crash. :P/>

Though truth be told, I really should've used #mon instead of the number 3, I suppose. Even with that tweak it'll still want at least one monitor, though, due to requirements later on in the code.

Again, I didn't really expect you to use those scripts, especially since it's geared for attacking players (as opposed to mobs, which it'll ignore) - I more intended for you to take hints from them regarding how to use the sensor. But you've gone this far, so I guess I'll attempt to fill in the blanks for you:

The controller system needs at least three monitors, a wireless modem, and a sensor from OpenPeripherals. One monitor will do if you change line 19 as suggested.

The range of the sensor is rubbish. In my case, the server admin decided to change the OpenPeripheral config to extend it. In your case, the area you're tracking is so small it might not matter.

The turtles must be placed underground. Dig two blocks deep, then one to the side, and place the turtle in the tip of the hook. A side view would look something like this:

^ Up
|

***** ****
***** T***
**********

… where a * is a block, and the T is a turtle. Place as many (labeled and fueled) turtles as you like underground, but make sure none of their little chambers merge into each other. The turtles must be in this position before they first load their scripts - if they were misplaced at that time, delete the "config" file they generated, put them where they should be, and boot them again.

For bonus points, place a Tinker's Construct Drawbridge directly above each turtle, loaded with a single block and aimed at the gap leading to the surface. Each turtle will use its drawbridge to hide itself whenever it's underground.

I rig my GPS systems to use z for world height. Since you probably use y for this purpose, you may need to tweak lines 107 and 137 in the turtle code to switch those two variables around.
Luca_S #8
Posted 16 November 2014 - 05:56 PM
Sorry, i meant dimsedut.
Dragon53535 #9
Posted 16 November 2014 - 06:04 PM
Luca, that's the code he's using, he's using bomb bloke's code.