Page 1 of 1

SentinelBot

PostPosted: Fri Apr 27, 2012 2:07 am
by raptor
Bot development has been slow for a bit so I'd thought I contribute.

I give you: SentinelBot - the twisted offspring of s_bot, clonebot and orbitbot!

Usage:
/addbot sentinel [team index] [player name]

Example:
/addbot sentinel 0 raptor

Behavior:
SentinelBot does the following:
  • Find the designated player *anywhere* on the map (not just within sight) and will proceed to orbit that player
  • Shoot any hostile targets nearby while orbiting. It will shield itself, too.

Yes, this bot makes sure you know how to spell 'sentinel' correctly.

And yes, this bot can be transformed into a terror-bot: just specify your team with an opposing team's player :twisted:

Enjoy!

Update: SentinelBot now changes its name if used for evil
Update 2 : Updated to work with 018 scripting enginel
Update 3 : Really make it work with 018 this time
Update 4 : Really, really make it work with 018
Update 5 : Requires 019+ now

  Code:
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- SentinelBot:  when s_bot, orbitbot, and clonebot merge...
--
-- SentinelBot is a bot that orbits the designated player and shoots enemies
-- when they come within range
--
-- Authors:
--  - raptor
--  - s_bot, orbitbot, clonebot authors
--


function getName()
    if isTerror then
        return( "TerrorBot" )
    else
        return( "SentinelBot" )
    end
end


function onPlayerLeft(playerinfo_who_left)
    guardedShipInfo = nil
end


function fireAtObjects()
    local items = bf:findAllObjects(ObjType.Robot, ObjType.Turret, ObjType.Ship,
        ObjType.Asteroid, ObjType.ForceFieldProjector, ObjType.SpyBug, ObjType.Core)

    -- Cycle through list of potential items until we find one that we can attack
    for index, enemy in ipairs(items) do
        if(fireAtObject(enemy, Weapon.Phaser)) then
            break
        end
    end
end


-- Fires at the specified object with the specified weapon if the obj is a good target.
-- Does not fire if object is on the same team or if there is something in the way.
-- Returns whether it fired or not.
function fireAtObject(obj, weapon)
    local classId = obj:getObjType()

    if(classId == ObjType.Turret or classId == ObjType.ForceFieldProjector) then
    if(obj:getHealth() < .1) then
        --logprint("He's dead, Jim.")
        return(false)
        end
    end
   
    if(classId == ObjType.Ship    or   classId == ObjType.Robot   or   classId == ObjType.ForceFieldProjector   or
    classId == ObjType.Turret  or   classId == ObjType.Core) then
        if obj:getTeamIndex() == bot:getTeamIndex() and game:isTeamGame() or obj:getTeamIndex() == Team.Neutral then
                --logprint("It's an ally.")
                return(false)
        end
end

   
    local angle = getFiringSolution(obj)
    if angle ~= nil and bot:hasWeapon(weapon) then
        bot:setAngle(angle + math.rad((math.random()-0.5)*20*(1-difficulty)))
        bot:fireWeapon(Weapon.Phaser)
        --logprint("bot:fire() called!");
        return(true)
    end
    --logprint("Firing solution not found.");
    return(false)
end


function angleDifference(angleA, angleB)
    return (math.mod(math.mod(angleA - angleB, math.pi*2) + math.pi*3, math.pi*2) - math.pi)
end


function shieldSelf()
    items = bf:findAllObjects(ObjType.Bullet, ObjType.Seeker, ObjType.Asteroid, ObjType.Mine)

    local distToShieldAt = bot:getRad() * 2 + (1 - difficulty) * 100
    if (items ~= nil) then
        for i,bullet in ipairs(items) do
            local bulletLoc = bullet:getPos()
            local bulletVel = bullet:getVel()
            local angleDiff = math.abs(angleDifference(point.angleTo(reusableAngle, bulletVel), point.angleTo(bulletLoc, botLocation)))
            --logprint(angleDiff)
            if (point.distanceTo(bulletLoc, botLocation) < distToShieldAt + bullet:getRad() + point.distanceTo(reusableAngle, bulletVel) * 50 and angleDiff < math.pi / 4) then
                bot:fireModule(Module.Shield)
                return(true)
            end
        end
    end
end


function shield()
    averageArray[averageIndex] = shieldSelf()
    averageIndex = math.mod(averageIndex,averageMax) + 1
    local shieldPercent = 0
    for i = 1, averageMax do
        if(averageArray[averageIndex]) then
            shieldPercent = shieldPercent + 1
        end
    end
    shieldPercent = shieldPercent / averageMax
    if(shieldPercent > directionThreshold) then
        myOrbitalDirection = -myOrbitalDirection
        for i = 1, averageMax do
            averageArray[i] = false
        end
    end
end


function onTick(deltaTime)
    -- Make sure we have a ship to guard first
    if guardedShipInfo == nil then
        local items = bf:findAllObjects(ObjType.Ship, ObjType.Robot)

        for index, item in ipairs(items) do
            if item:getPlayerInfo():getName() == guardedShipName then
                guardedShipInfo = item:getPlayerInfo()
            end
        end
    end

    -- Wait until we actually get the guarded ship info to continue, the ship may have died
    if(guardedShipInfo == nil or guardedShipInfo:getShip() == nil) then
        return
    end

    botLocation = bot:getPos()
    guardedShipLocation = guardedShipInfo:getShip():getPos()
    local distanceSquared = point.distSquared(botLocation, guardedShipLocation)

    -- Change the angle according to the deltaTime;  factor of .0035 is an arbitrary value
    -- that tries to make angle adjustments seem smooth.  Note that a larger value is needed
    -- for a smaller orbit radius
    orbitAngle = orbitAngle + .0035 * deltaTime


    local destination

    -- Enter orbit when close enough
    if( distanceSquared <= orbitRadius * orbitRadius * 1.1 ) then
        destination = point.new(guardedShipLocation.x + orbitRadius * math.cos (orbitAngle),
        guardedShipLocation.y + orbitRadius * math.sin (orbitAngle))

        if( not isInOrbit ) then
            orbitAngle = point.angleTo(botLocation, destination) - math.pi / 2
        end   

        isInOrbit = true

    -- Not in orbit
    else
        isInOrbit = false

        destination = guardedShipLocation

        -- If it's time to calculate a new route, find the next point in the path
        pathTimer = pathTimer - deltaTime
        if pathTimer < .01 and not isInOrbit then
            waypoint = bot:getWaypoint(guardedShipLocation)
        end

        -- If we have a waypoint, change destination to that
        if(waypoint ~= nil) then
            destination = waypoint
        end
    end

   
    -- Go forth!
    bot:setThrustToPt(destination)

    -- Fire!
    fireAtObjects()

    -- Be safe!
    shield()

    -- Now reset path timer if needed
    if(pathTimer < 0)then
        pathTimer = pathTimerMax
    end
end


function isTerrorBot()
    local items = bf:findAllObjects(ObjType.Ship, ObjType.Robot)

    for index, item in ipairs(items) do
        if item:getPlayerInfo():getName() == guardedShipName then
            guardedShipInfo = item:getPlayerInfo()
        end
    end

    -- Ship not found, Abort!
    if(guardedShipInfo == nil or guardedShipInfo:getShip() == nil) then
        return
    end

    local guardedShip = guardedShipInfo:getShip()
    if guardedShip:getTeamIndex() ~= bot:getTeamIndex() or not game:isTeamGame() then
        isTerror = true
    end
end


function main()
    bf:subscribe(Event.PlayerLeft)
   
    game = bf:getGameInfo()
    gameType = game:getGameType()
    difficulty = 1
    directionThreshold = .25
    averageIndex = 1
    averageMax = 20
    averageArray = {}
    for i = 1, averageMax do
        averageArray[i] = false
    end
    myOrbitalDirection = 1
    reusableAngle = point.new(0,0)

    -- Only recalculate path every 500 ms or so
    pathTimerMax = 250
    pathTimer = pathTimerMax
    waypoint = nil

    botLocation = nil
    guardedShipLocation = nil
    orbitAngle = 0
    orbitRadius = 130
    isInOrbit = false
    guardedShipInfo = nil

    -- Who to guard?
    guardedShipName = arg[1]

    -- Test to see if we are TerrorBot
    isTerror = false
    isTerrorBot()
end

Re: SentinelBot

PostPosted: Fri Apr 27, 2012 6:54 am
by Heyub
Cool! I never thought sentinel was hard to spell, its spelled how it sounds. I'll have to try it out later :)

Re: SentinelBot

PostPosted: Fri Apr 27, 2012 6:57 am
by Little_Apple
Thank you so much!!

Re: SentinelBot

PostPosted: Fri Apr 27, 2012 8:17 am
by Heyub
**ROBOT ERROR*** in /Users/mycomputer/Library/Application Support/Bitfighter/robots/sentinelbot.bot ::: Script error: ...mycomputer/Library/Application Support/Bitfighter/robots/sentinelbot.bot:11: unexpected symbol near '�' -- Aborting.


EDIT: Restarted bitfighter, it worked... No clue why that error occurred.

A few comments; it uses shields if you shoot close enough to it, it should know your its friend! When you stop it should cease to circle you, in narrow passages it can be quite a nuisance, always bumping into you. Not to mention trying to destroy a mine.

Re: SentinelBot

PostPosted: Fri Apr 27, 2012 10:25 am
by raptor
When SentinelBot is used for evil:

screenshot_2.png

(Yes that is me in the middle)

Re: SentinelBot

PostPosted: Fri Apr 27, 2012 12:45 pm
by Skybax
That looks painful.

Re: SentinelBot

PostPosted: Fri Apr 27, 2012 12:46 pm
by Little_Apple
i have no regrets.

Re: SentinelBot

PostPosted: Fri Apr 27, 2012 3:06 pm
by raptor
Update:

Sentinel bot now changes its name if used for evil

Re: SentinelBot

PostPosted: Tue May 01, 2012 3:21 pm
by Santiago ZAP
Omfgz Epix BOt!

Re: SentinelBot

PostPosted: Wed Jan 30, 2013 10:17 pm
by amgine
raptor wrote:Update:

Sentinel bot now changes its name if used for evil


really what to??

Re: SentinelBot

PostPosted: Wed Jan 30, 2013 11:37 pm
by raptor
I have updated SentinelBot to run on 018

Re: SentinelBot

PostPosted: Thu Jan 31, 2013 6:09 pm
by Lamp
raptor wrote:I have updated SentinelBot to run on 018


YAY :D :zapdance:

Re: SentinelBot

PostPosted: Thu Jan 31, 2013 6:12 pm
by Lamp
IT STILL DOESNT WORK :o :shock:


***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: Variable 'findGlobalObjects' cannot be used if it is not first declared.. Aborting script.

Re: SentinelBot

PostPosted: Thu Jan 31, 2013 6:20 pm
by raptor
ok updated. I guess it was compatible with 018a not 018...

Re: SentinelBot

PostPosted: Fri Feb 01, 2013 5:45 pm
by amgine
ty. for fixing it.

Re: SentinelBot

PostPosted: Tue Feb 26, 2013 10:56 pm
by Lamp
IT STILL DOESN'T WORK

***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: attempt to call missing or unknown method 'findGlobalObjects' (a nil value). Aborting script.
***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: attempt to call missing or unknown method 'findGlobalObjects' (a nil value). Aborting script.

Re: SentinelBot

PostPosted: Sat Mar 02, 2013 9:13 pm
by Santiago ZAP
Lamp wrote:IT STILL DOESN'T WORK

***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: attempt to call missing or unknown method 'findGlobalObjects' (a nil value). Aborting script.
***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: attempt to call missing or unknown method 'findGlobalObjects' (a nil value). Aborting script.

+1
Same happens fer me

Re: SentinelBot

PostPosted: Sat Mar 02, 2013 9:55 pm
by amgine
Santiago ZAP wrote:
Lamp wrote:IT STILL DOESN'T WORK

***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: attempt to call missing or unknown method 'findGlobalObjects' (a nil value). Aborting script.
***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: attempt to call missing or unknown method 'findGlobalObjects' (a nil value). Aborting script.

+1
Same happens fer me


nope no problems here.

Re: SentinelBot

PostPosted: Fri Mar 15, 2013 3:46 pm
by Lamp
amgine wrote:
Santiago ZAP wrote:
Lamp wrote:IT STILL DOESN'T WORK

***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: attempt to call missing or unknown method 'findGlobalObjects' (a nil value). Aborting script.
***ROBOT ERROR*** Error encountered while attempting to run script's main() function: ...y/Application Support/Bitfighter/robots/sentinel.bot:199: attempt to call missing or unknown method 'findGlobalObjects' (a nil value). Aborting script.

+1
Same happens fer me


nope no problems here.


:(

Re: SentinelBot

PostPosted: Fri Mar 15, 2013 4:12 pm
by raptor
Lamp,

Are you trying to say that it doesn't work for you? If so, please say that.

Re: SentinelBot

PostPosted: Fri Mar 15, 2013 7:52 pm
by Lamp
raptor wrote:Lamp,

Are you trying to say that it doesn't work for you? If so, please say that.



I already did say that.

Re: SentinelBot

PostPosted: Tue Apr 02, 2013 3:35 pm
by raptor
Updated again to really work (again).

AND AGAIN!

Re: SentinelBot

PostPosted: Sun Jun 14, 2020 9:17 pm
by raptor
Updated for 019+

Re: SentinelBot

PostPosted: Mon Jun 22, 2020 6:15 am
by amgine
Cool!

A shame you put work into this but no one really uses it its interesting for 1 v 1s