FAQ  •  Register  •  Login

RepairBot

<<

raptor

Posts: 1046

Joined: Mon Oct 11, 2010 9:03 pm

Post Fri May 18, 2012 12:16 pm

RepairBot

For Science! Or maybe Skybax...

I present to you: RepairBot!

Usage:
/addbot repair

Behavior:
  • Finds any friendly or neutral turret or forcefield projector and repairs the closest one. It will proceed until all possible are repaired
  • Shoots nearby targets (is slightly more accurate than s_bot)
  • Does not shield - this took too much energy away from its primary goal

Enjoy!

  Code:
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- RepairBot:  finally delegating base repair to a computer
--
-- RepairBot is a robot that will find any neutral or friendly turrets and
-- and forcefield projectors on the map and will proceed to repair them
--
-- RepairBot will also shoot nearby enemies if they come within range
--
-- Author:
--  - raptor
--
-- Version history
--
--   0.1    Initial release (for 017?)
--   0.2    Fix some crashes, remove ability to heal engineered items
--   0.3    Port to 018a, add optimizations, fixes
--   0.4    Only target a repairable you can actually navigate to
--   0.5    Don't use stupid waypoint finding, add back healing of engineered items
--   0.6    Update to 019 API
--

function getName()
    return( "RepairBot" )
end


function fireAtObject(obj, weapon)
    if(obj:getObjType() == ObjType.Turret or obj:getObjType() == ObjType.ForceFieldProjector) then
        if(obj:getHealth() < .1) then
            return(false)
        end
    end
   
    if(obj:getObjType() == ObjType.Ship or
        obj:getObjType() == ObjType.Robot or
        obj:getObjType() == ObjType.Turret or
        obj:getObjType() == ObjType.ForceFieldProjector or
        obj:getObjType() == ObjType.Core) then
            if obj:getTeamIndex() == bot:getTeamIndex() and game:isTeamGame() or obj:getTeamIndex() == Team.Neutral then
                return(false)
            end
    end

    local angle = getFiringSolution(obj)
    if angle ~= nil and bot:hasWeapon(weapon) then
        bot:setAngle(angle)
        bot:fireWeapon(Weapon.Phaser)
        return(true)
    end
    return(false)
end


function fireAtObjects()
    table.clear(items)
    bot:findVisibleObjects(items, ObjType.Robot, ObjType.Turret, ObjType.Ship, ObjType.Asteroid, ObjType.ForceFieldProjector, ObjType.SpyBug, ObjType.Core)
   
    for index,enemy in ipairs(items) do
        if(fireAtObject(enemy, Weapon.Phaser)) then
            break
        end
    end
end


-- Helper function to return the closest friendly or neutral item to the bot
-- Returns the closest item
function findClosestFriendly(items)
    if #items == 0 then
        return nil
    end

    local closestItem = nil
    local smallestDist = signedIntMax
    local distance
    for index, item in ipairs(items) do
        if (item:getTeamIndex() == bot:getTeamIndex() or item:getTeamIndex() == Team.Neutral) then
            distance = point.distSquared(bot:getPos(), item:getPos())  

            if( distance < smallestDist ) then
                closestItem = item
                smallestDist = distance
            end
        end
    end

    return closestItem
end


function findClosestLoadoutZone()
    return findClosestFriendly(possibleLoadoutZones)
end


function findClosestRepairTarget()
    if #possibleRepairTargets == 0 then
        return nil
    end

    local closestRepairTarget = nil
    local smallestDist = signedIntMax
    local distance
    for index, repairTarget in ipairs(possibleRepairTargets) do
        -- Must be able to repair it for the bot's team
        if (repairTarget:getTeamIndex() == bot:getTeamIndex() or repairTarget:getTeamIndex() == Team.Neutral) and
                -- Must need health
                repairTarget:getHealth() < repairHealthThreshold and
                -- Must be a path to get there
                bot:getWaypoint(adjustRepairTargetPoint(repairTarget)) ~= nil then
         
            distance = point.distSquared(bot:getPos(), repairTarget:getPos())  

            if( distance < smallestDist ) then
                closestRepairTarget = repairTarget
                smallestDist = distance
            end
        end
    end

    return closestRepairTarget
end


function findAllRepairTargets()
    -- Find all repairables
    table.clear(possibleRepairTargets)
    bf:findAllObjects(possibleRepairTargets, ObjType.ForceFieldProjector)
   
    table.clear(items)
    bf:findAllObjects(items, ObjType.Turret)

    -- Combine the tables into one
    for key, value in ipairs(items) do
        table.insert(possibleRepairTargets, items[key])
    end
end


-- We need to adjust the repair target point because sometimes the bot waypoint
-- search can't find it because it is against a wall; we offset only 10
function adjustRepairTargetPoint(repairTarget)
    return repairTarget:getPos() +
        point.new(10 * math.cos(repairTarget:getMountAngle()), 10 * math.sin(repairTarget:getMountAngle()))
end


function gotoClosestLoadoutZone()
    local zone = findClosestLoadoutZone()

    -- Go to nearest loadout zone to change
    if zone ~= nil then
        -- If we're close enough, just sit instead of fighting other bots for
        -- the zone center point
        if point.distSquared(zone:getPos(), bot:getPos()) > 1225 then  -- (35^2)
            bot:setThrustToPt(zone:getPos())
        end
    end
end


function hasRepairLoadout()
    return bot:hasModule(Module.Repair)
end


-- This function does most the logic for repair
function doObjective()
    -- This objective must be completed first at all costs (we need repair module)
    if needsRepairLoadout then
        gotoClosestLoadoutZone()

        -- See if we have repair
        if hasRepairLoadout() then
            needsRepairLoadout = false
        end

        return
    end

    -- Check some things with the timer
    if delayTimer < 0.01 then
   
        -- If no repair targets, search for them again
        if #possibleRepairTargets == 0 then
            findAllRepairTargets()
            return
        end
       
        -- Check our loadout in case we've been blowed up (loadout doesn't stick upon bots respawning??)
        if not hasRepairLoadout() then
            needsRepairLoadout = true
        end
    end

    -- Control logic based on current energy
    if (currentBotEnergy < 0.03) then
        onRepairTask = false
    elseif currentBotEnergy > 0.8 and not onRepairTask then
        onRepairTask = true
    end


    -- On repair duty!
    if onRepairTask then

        -- Do some tasks like pathfinding or target refreshing only every once in a while...
        if delayTimer < 0.01 then
            -- Find closest repair targets
            if currentRepairTarget == nil or currentRepairTarget:getHealth() >= repairHealthThreshold then
                currentRepairTarget = findClosestRepairTarget()
            end

            if currentRepairTarget ~= nil then
                goalPoint = bot:getWaypoint(adjustRepairTargetPoint(currentRepairTarget))

            -- Let's look for everything again if we still can't find a target.  This should find engineered
            -- items, too
            else
                findAllRepairTargets()
            end
        end

        -- No waypoint or repair target (probably everything has been repaired)
        if goalPoint == nil or currentRepairTarget == nil or currentRepairTarget:getPos() == nil then

            -- The :getPos() nil test here is to protect against engineered items disappearing
            if currentRepairTarget ~= nil and currentRepairTarget:getPos() == nil then
                currentRepairTarget = nil
            end
           
            return
        end

        -- Now go the repair target and heal it
        if point.distSquared(currentBotLocation, currentRepairTarget:getPos()) > 4900 then
            bot:setThrustToPt(goalPoint)
        else
            bot:fireModule(Module.Repair)
        end
    end
end


function onTick(deltaTime)
    currentBotLocation = bot:getPos()
    currentBotEnergy = bot:getEnergy()

    delayTimer = delayTimer - deltaTime

    -- Do something!
    doObjective()

    -- Fire!
    fireAtObjects()

    -- Now reset timer if needed
    if delayTimer < 0 then
        delayTimer = delayTime
    end
end


function main()
    -- General variables
    game = bf:getGameInfo()
    signedIntMax = 2147483647

    -- Current bot data
    currentBotLocation = nil
    currentBotEnergy = nil

    -- This timer slows some of the more CPU intesive actions like pathfinding
    delayTime = 500
    delayTimer = delayTime
    goalPoint = nil
   
    -- Table for various global searches
    items = {}

    -- Repair specific variables
    possibleRepairTargets = {}
    possibleLoadoutZones = {}
    bf:findAllObjects(possibleLoadoutZones, ObjType.LoadoutZone)
    onRepairTask = false
    currentRepairTarget = nil
    repairHealthThreshold = 0.99

    -- Do some starting tasks
    needsRepairLoadout = true
   
    -- Set up the loadout we want
    local loadout = {Weapon.Phaser, Weapon.Bouncer, Weapon.Triple, Module.Shield, Module.Repair}
 
    -- Set the loadout, will become active when bot hits loadout zone
    -- or spawns, depending on game
    bot:setLoadout(loadout)
   
    findAllRepairTargets()
end


Update: RepairBot optimizations and minor tweaks. Also fix a possible crash by disabling repair of engineered items - sorry
Update 2: Posted code here directly - still needs to be 018afied
Update 3: RepairBot has been updated for 018a; also with some more optimizations and AI improvements
Update 4: Slightly less dumb at finding a repair target
Update 5: Fix stupidness with waypoint finding and add back in ability to fix engineered items
Update 6: Update to 019 API
<<

Skybax

User avatar

Posts: 1035

Joined: Thu Mar 11, 2010 9:17 am

Location: Washington

Post Fri May 18, 2012 12:27 pm

Re: RepairBot

You're awesome!
raptor wrote:Sorry Skybax, I hijacked your signature so I could post lots of info.
Whittling While wrote:Does this mean I finally get quoted in someone's signature?
watusimoto wrote:Who are the devs around here?!?
<<

Heyub

Posts: 66

Joined: Thu Jul 22, 2010 2:57 pm

Post Fri May 18, 2012 2:28 pm

Re: RepairBot

I think I like it.
Honesty; I am not smart. Political; My vast knowledge is truly breathtaking.
Contract; I, herby, declare my knowledge unarguably* vast.
*In comparison to semi-intelligent life forms.
<<

Skybax

User avatar

Posts: 1035

Joined: Thu Mar 11, 2010 9:17 am

Location: Washington

Post Fri May 18, 2012 5:18 pm

Re: RepairBot

When I try to add one to the game, it kicks it.

This is what my log says

"unexpected symbol near '{' -- Aborting."

There aren't any { symbols in the bot code…
raptor wrote:Sorry Skybax, I hijacked your signature so I could post lots of info.
Whittling While wrote:Does this mean I finally get quoted in someone's signature?
watusimoto wrote:Who are the devs around here?!?
<<

raptor

Posts: 1046

Joined: Mon Oct 11, 2010 9:03 pm

Post Fri May 18, 2012 5:52 pm

Re: RepairBot

OK Skybax, I added it as a zip file, so you have the original code without having whitespace problems. Just extract and drop in your 'robots' folder.
<<

Skybax

User avatar

Posts: 1035

Joined: Thu Mar 11, 2010 9:17 am

Location: Washington

Post Sat May 19, 2012 12:47 pm

Re: RepairBot

This doesn't really have anything to do with RepairBot except for the fact that I'm using them, but how do I put them in the code so that multiple bots will spawn on one team?

I looked in past level codes I'd done, and it seems that the code was Robot team# bot
Ex.
  Code:
Robot 3 bot.bot

But when I tried to do that in the level I'm making, it distributed them all among all the teams. What am I doing wrong?
raptor wrote:Sorry Skybax, I hijacked your signature so I could post lots of info.
Whittling While wrote:Does this mean I finally get quoted in someone's signature?
watusimoto wrote:Who are the devs around here?!?
<<

sam686

User avatar

Posts: 468

Joined: Fri Oct 15, 2010 8:53 pm

Location: United States, South Dakota

Post Sat May 19, 2012 1:07 pm

Re: RepairBot

This line "Robot 3 bot.bot" only works if you have 4 or more teams.
The first team is "Robot 0 bot.bot"
Second team is "Robot 1 bot.bot" which need 2 or more teams in a level.
Out of range team number can get ignored.
<<

Skybax

User avatar

Posts: 1035

Joined: Thu Mar 11, 2010 9:17 am

Location: Washington

Post Sat May 19, 2012 8:25 pm

Re: RepairBot

Ohh I see what I did wrong now.
Thanks! :D
raptor wrote:Sorry Skybax, I hijacked your signature so I could post lots of info.
Whittling While wrote:Does this mean I finally get quoted in someone's signature?
watusimoto wrote:Who are the devs around here?!?
<<

raptor

Posts: 1046

Joined: Mon Oct 11, 2010 9:03 pm

Post Sun May 20, 2012 9:19 pm

Re: RepairBot

I updated RepairBot.

Changes:
- Disable repairing of engineered turrets/ffs because it was possible to crash the server by destroying one while being repaired.
- Multiple bots don't fight over the load-out zone center or repairables as much
<<

amgine

Posts: 1399

Joined: Thu Apr 19, 2012 2:57 pm

Post Wed Jan 30, 2013 10:16 pm

Re: RepairBot

rqaptor can you find a way to fix the FF turret bug so it can be added back thye dont seem as good now.
Bitfighter Forever.
<<

raptor

Posts: 1046

Joined: Mon Oct 11, 2010 9:03 pm

Post Mon Jul 01, 2013 1:49 pm

Re: RepairBot

Updated for 018a
<<

Fordcars

User avatar

Posts: 1016

Joined: Fri Apr 20, 2012 3:51 pm

Location: Some city, somewhere

Post Tue Jul 02, 2013 6:36 am

Re: RepairBot

*018afied
skybax: Why is this health pack following me?
bobdaduck: uh, it likes you.
<<

raptor

Posts: 1046

Joined: Mon Oct 11, 2010 9:03 pm

Post Tue Jul 02, 2013 7:10 am

Re: RepairBot

New version with enhancements and fixes
<<

Fordcars

User avatar

Posts: 1016

Joined: Fri Apr 20, 2012 3:51 pm

Location: Some city, somewhere

Post Tue Jul 02, 2013 9:30 am

Re: RepairBot

Ok ;)
skybax: Why is this health pack following me?
bobdaduck: uh, it likes you.
<<

raptor

Posts: 1046

Joined: Mon Oct 11, 2010 9:03 pm

Post Tue Dec 24, 2013 6:09 pm

Re: RepairBot

Updated to 019 API

Return to Bots

Who is online

Users browsing this forum: No registered users and 12 guests

cron