Skybot
Skybot turned out to be extremely awesome. He hunts players, and says Skybaxy stuff. It's Fast, Fun, and Skybax
By the way, you can add or remove as many phrases as you want in the beginning of the code
- Code:
-- Skybot 1.2
-- by fordcars, for Skybax
-- Based on s_bot
function main()
-------------------------------------------------------------------------------------------------------
-- Enter as many phrases as you want
-- Randomly during the game
randomPhrases = {"Soccer is the worst gamemode evvar.. let's have basketball instead!",
"Man, I really wish I could make floating turrets right about now...",
"Quartz will never mow his lawn again!",
"Anyone wanna play on BitTown?",
"Fordcars is the greatest robot coder in the history of robot coding!",
"Anyone in the mood for pancakes? I hear sky_lark is running a special...",
"Root beer is the most bestest beverage"}
-- When zapping people
killedPeople = {"Booyah!",
"Niiiiice",
"Thanks for the points!",
"NINJA-SHIP JUTSU!"}
-- When saying something with your name in it
skybotReplies = {"Yes?",
"NO U",
"Cool story bro",
"Hehehuhueheuhuehuh maybe",
"Your mom",
"Oh, okay"}
-- Say the phrases when somebody says (case insensitive)
skybotNames = {"sky"}
-- When Skybax is killed by Skybot
skyKilledSky = {"Did I just win, or did I commit suicide?"}
-- When Skybot is killed by somebody else
skybotDead = {"DAMMIT"}
-- When the game ends
gameEnded = {"GG"}
-- When somebody says something over 50 characters long
longText = {"Indeed."}
-- When killing FoOtloOse
killedFootloose = {"I'z a sozzies :( want a brownie?"}
-- When killing sky_lark
killedSkylark = {"Cloak is soooo way better than shield!"}
-------------------------------------------------------------------------------------------------------
skybotRaptorKills = 0;
raptorSkybotKills = 0;
botRadius = bot:getRad()
pathTimerMax = 250
pathTimer = pathTimerMax
dirToGo = 0
game = bf:getGameInfo()
talk = nil
if(arg[1]~=nil and arg[1]~="")then
talk = toBoolean(arg[1])
else
talk = true
end
difficulty = tonumber(arg[2]) or .5
agression = tonumber(arg[3]) or 0.5
defense = tonumber(arg[4]) or 0
speed = tonumber(arg[5]) or 1
directionThreshold = tonumber(arg[6]) or .25
gameType = game:getGameType()
averageIndex = 1
averageMax = 20
averageArray = { }
for i = 1, averageMax do
averageArray[i] = false
end
myOrbitalDirection = 1
myObjective = getRandomNumber(0, 10)
-- Skybot stuff
if(talk==true) then
subscribe(Event.ShipKilled)
subscribe(Event.MsgReceived)
subscribe(Event.GameOver)
end
-- 1 2 3 4 5 6 7 8 9
phrasesLength = {getLength(randomPhrases), getLength(killedPeople), getLength(skybotReplies), getLength(skyKilledSky), getLength(skybotDead), getLength(gameEnded), getLength(longText), getLength(killedFootloose), getLength(killedSkylark)}
skybotNamesCI = {}
for i,v in ipairs(skybotNames) do
table.insert(skybotNamesCI,noCase(skybotNames[i]))
end
if(talk==true) then
Timer:scheduleOnce(randomPhrase, getRandomNumber(6000,30000))
end
signedIntMax = 2147483647
runawayMode = false
firstPhase = true
chargingPlayer = false
loadoutWanted = {Weapon.Phaser, Weapon.Burst, Weapon.Triple, Module.Cloak, Module.Shield}
end
goalPt = point.new(0,0)
prevtarget = nil
gotoPositionWasNil = true
o = point.new(0,0)
botPos = nil -- Bot's location, will be updated when onTick() is run
items = { } -- Global variable, reusable container for bf:findAllObjects. Reusing this table avoids costs of
-- constructing and destructing it every time we call bf:findAllObjects(). Be sure to clear the
-- table before reusing it!
function toBoolean(booleanString)
if(boolean==true or booleanString=="True" or booleanString=="true" or booleanString==1)then
return true
else
return false
end
end
function getLength(arr)
local arrLength = 0
for i,v in ipairs(arr) do
arrLength = arrLength + 1
end
return arrLength
end
function onShipKilled(shipKilled,damagingObject,shooter)
local shipKilledName = shipKilled:getPlayerInfo():getName()
local botName = bot:getPlayerInfo():getName()
if(shipKilledName==botName) then
if(shooter~=nil and (shooter:getObjType()==ObjType.Ship or shooter:getObjType()==ObjType.Robot)) then
local shooterName = shooter:getPlayerInfo():getName()
if(shooterName=="raptor") then
raptorSkybotKills = raptorSkybotKills + 1
local tempRaptorString = "Skybot - " .. skybotRaptorKills .. "; raptor - " .. raptorSkybotKills
globalMsg(tempRaptorString)
else
local randomInt = getRandomNumber(1,phrasesLength[5])
globalMsg(skybotDead[randomInt])
end
end
else
if(shooter~=nil and (shooter:getObjType()==ObjType.Ship or shooter:getObjType()==ObjType.Robot)) then
local shooterName = shooter:getPlayerInfo():getName()
if(shooterName==botName) then
if(shipKilledName=="FoOtloOse") then -- Hard coded
local randomInt = getRandomNumber(1,phrasesLength[8])
globalMsg(killedFootloose[randomInt])
elseif(shipKilledName=="sky_lark") then -- Hard coded
local randomInt = getRandomNumber(1,phrasesLength[9])
globalMsg(killedSkylark[randomInt])
elseif(shipKilledName=="raptor") then -- Hard coded
skybotRaptorKills = skybotRaptorKills + 1
local tempRaptorString = "Skybot - " .. skybotRaptorKills .. "; raptor - " .. raptorSkybotKills
globalMsg(tempRaptorString)
elseif(shipKilledName=="Skybax") then -- Hard coded
local randomInt = getRandomNumber(1,phrasesLength[4])
globalMsg(skyKilledSky[randomInt])
else
local randomInt = getRandomNumber(1,phrasesLength[2])
globalMsg(killedPeople[randomInt])
end
end
end
end
end
function onGameOver()
local randomInt = getRandomNumber(1,phrasesLength[6])
globalMsg(gameEnded[randomInt])
end
function onMsgReceived(message,messageSender,isGlobalMessage)
if(isGlobalMessage==true and messageSender:isRobot()==false) then
if(string.len(message)>=50) then
local randomInt = getRandomNumber(1,phrasesLength[7])
globalMsg(longText[randomInt])
return
end
local foundString = nil
for i,v in ipairs(skybotNamesCI) do
foundString = string.find(message,skybotNamesCI[i])
if(foundString ~= nil) then
local randomInt = getRandomNumber(1,phrasesLength[3])
globalMsg(skybotReplies[randomInt])
break
end
end
end
end
function noCase(s)
s = string.gsub(s, "%a", function (c)
return string.format("[%s%s]", string.lower(c),
string.upper(c))
end)
return s
end
function randomPhrase()
local randomInt = getRandomNumber(1,phrasesLength[1])
globalMsg(randomPhrases[randomInt])
Timer:scheduleOnce(randomPhrase, getRandomNumber(50000,80000))
end
function shieldSelf()
table.clear(items)
bot:findVisibleObjects(items, ObjType.Bullet, ObjType.Seeker, ObjType.Asteroid, ObjType.Mine)
local distToShieldAt = botRadius * 2 + (1 - difficulty) * 100
if (items ~= nil) then
for i,bullet in ipairs(items) do
local bulletPos = bullet:getPos()
local bulletVel = bullet:getVel()
local angleDiff = math.abs(angleDifference(point.angleTo(o, bulletVel), point.angleTo(bulletPos, botPos)))
--logprint(angleDiff)
local bulletFromTeam = false
if (game:isTeamGame() == true) and (bullet:getTeamIndex() == bot:getTeamIndex()) then -- If bullet is from team
bulletFromTeam = true -- bullet from team is true
end
if (bulletFromTeam == false) and (point.distanceTo(bulletPos, botPos) < distToShieldAt + bullet:getRad() + point.distanceTo(o, bulletVel) * 50 and angleDiff < math.pi / 4) then
bot:fireModule(Module.Shield)
return(true)
end
end
end
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 copyArray(arrToCopy)
if(arrToCopy~=nil) then
local copiedArray = {}
for i,v in ipairs(arrToCopy) do
table.insert(copiedArray,v)
end
return copiedArray
end
return nil
end
function orderArrayByDistance(arrToOrder)
if(arrToOrder~=nil) then
local tempArray = copyArray(arrToOrder)
local finalArray = {}
local closestItem = nil
local closestItemIndex = nil
for i,v in ipairs(arrToOrder) do
local smallestDist = signedIntMax
local distance = nil
for j,k in ipairs(tempArray) do
distance = point.distSquared(botPos, k:getPos())
if( distance < smallestDist ) then
closestItemIndex = j
closestItem = k
smallestDist = distance
end
end
table.insert(finalArray,closestItem)
table.remove(tempArray,closestItemIndex)
end
return finalArray
end
return {}
end
function fireWeaponsAndModules()
local itemsToShootAt = {}
if(runawayMode==false) then
local tempArr = {}
local itemPos = nil
bf:findAllObjects(items, ObjType.Robot, ObjType.Ship)
for i,v in ipairs(items) do
itemPos = v:getPos()
if(itemPos~=nil and (point.distSquared(botPos, v:getPos()) < 800 * 800)) then
table.insert(tempArr,v)
end
end
itemsToShootAt = orderArrayByDistance(tempArr)
table.remove(itemsToShootAt,1)
else
local tempArr = {}
chargingPlayer = false
bot:findVisibleObjects(tempArr, ObjType.Robot, ObjType.Turret, ObjType.Ship, ObjType.Asteroid,
ObjType.ForceFieldProjector, ObjType.SpyBug, ObjType.Core)
itemsToShootAt = orderArrayByDistance(tempArr)
end
if(getLength(itemsToShootAt)>0) then
if(runawayMode==false) then
local enemyObjType = nil
local enemyShipPresence = false
for i,v in ipairs(itemsToShootAt) do
if((bf:getGameInfo():isTeamGame()==true and v:getTeamIndex()~=bot:getTeamIndex()) or (bf:getGameInfo():isTeamGame()==false and v:getTeamIndex()==bot:getTeamIndex()) or (v:getTeamIndex()==Team.Neutral)) then
enemyObjType = v:getObjType()
if(point.distSquared(botPos,v:getPos()) <= 150 * 150) then
if(enemyObjType==ObjType.Turret) then
if(v:getHealth() > 0.1) then
bot:fireModule(Module.Cloak)
end
else
shield()
enemyShipPresence = true
chargingPlayer = true
gotoAndOrbitItem(v:getPos())
fireAtObject(v,Weapon.Triple, true)
break
end
else
if(enemyObjType==ObjType.Ship or enemyObjType==ObjType.Robot) then
enemyShipPresence = true
chargingPlayer = true
gotoAndOrbitItem(v:getPos())
bot:fireModule(Module.Cloak)
break
end
if(enemyObjType==ObjType.Turret and v:getHealth() > .1) then
bot:fireModule(Module.Cloak)
end
end
end
end
if(enemyShipPresence==false) then
chargingPlayer = false
end
else
shield()
fireAtObject(itemsToShootAt[1], Weapon.Phaser)
end
else
chargingPlayer = false
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, isTriple)
local classId = obj:getObjType()
if(classId == ObjType.Turret or classId == ObjType.ForceFieldProjector) then
-- Ignore all same-team engineered objects... even in single-team games
if obj:getTeamIndex() == bot:getTeamIndex() then
return false -- Cancel fireAtObject function
end
if obj:getHealth() < .1 then -- If item is essentially dead
return false
end
end
-- No shooting various team related objects
if (obj:getTeamIndex() == bot:getTeamIndex() and game:isTeamGame()) or -- Same team
obj:getTeamIndex() == Team.Neutral then -- Neutral team
if (classId == ObjType.Ship or classId == ObjType.Robot or -- Turrets and FFs handled above
classId == ObjType.Core or classId == ObjType.SpyBug) then
return false
end
end
-- No shooting non-flag carriers in single player rabbit
if gameType == GameType.Rabbit and not game:isTeamGame() and
(classId == ObjType.Ship or classId == ObjType.Robot) and
not bot:hasFlag() and not obj:hasFlag() then
return false
end
-- We made it here! We have a valid target..
local angle = 0
if(isTriple==nil or isTriple==false) then
angle = getFiringSolution(obj)
else
angle = bot:getAnglePt(obj:getPos())
end
if angle ~= nil and bot:hasWeapon(weapon) then
bot:setAngle(angle)
bot:fireWeapon(weapon)
--logprint("bot:fireWeapon() called!");
return(true)
end
--logprint("Firing solution not found.");
return(false)
end
function getName()
return("Skybot")
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 orbitPoint(pt, dir, inputDist, inputStrictness, noDirToGo)
local distAway = botRadius * 7
local strictness = 2
local direction = 1
if(dir ~= nil) then
direction = dir
end
if(inputDist ~= nil) then
distAway = inputDist
end
if(inputStrictness ~= nil) then
strictness = inputStrictness
end
if(pt ~= nil) then
local dist = point.distanceTo(pt, botPos)
local deltaDistance = (dist - distAway) * strictness / distAway
local sign = 1
if(deltaDistance > 0) then
sign = 1
elseif(deltaDistance < 0) then
sign = -1
end
local changeInAngle = (math.abs(deltaDistance)/(deltaDistance + sign)) * math.pi/2
local angleToPoint = point.angleTo(pt, bot:getPos())
if(noDirToGo~=true) then
dirToGo = angleToPoint + (math.pi/2 + changeInAngle)*direction
else
bot:setThrust(speed, angleToPoint + (math.pi/2 + changeInAngle)*direction)
end
end
end
function gotoPosition(pt)
if pt ~= nil then
gotoPositionWasNil = false
if pathTimer < .01 then
goalPt = bot:getWaypoint(pt)
if(goalPt ~= nil) then
dirToGo = point.angleTo(botPos, goalPt)
end
end
end
end
function moveToItem(pt)
if pt ~= nil then
local itemWayPt = bot:getWaypoint(pt)
if(itemWayPt ~= nil) then
bot:setThrust(speed, point.angleTo(botPos, itemWayPt))
end
end
end
function gotoAndOrbitPosition(pt)
if pt ~= nil then
gotoPositionWasNil = false
if not bot:canSeePoint(pt) then
gotoPositionWasNil = false
gotoPosition(pt)
else
gotoPositionWasNil = false
orbitPoint(pt, myOrbitalDirection, botRadius * 5, 2)
end
end
end
function gotoAndOrbitItem(pt)
if pt ~= nil then
if not bot:canSeePoint(pt) then
moveToItem(pt)
else
orbitPoint(pt, myOrbitalDirection, botRadius * 5, 2, true)
end
end
end
-- Returns true if it found an enemy to fight
function attackNearbyEnemies(target, agressionLevel)
if target ~= nil then
local targetPos = target:getPos()
-- local dist = point.distanceTo(botPos, targetPos)
local myPow = bot:getEnergy() + bot:getHealth()
table.clear(items)
bot:findVisibleObjects(items, ObjType.Ship, ObjType.Robot)
local otherPow = target:getEnergy() + target:getHealth() * #items
--advantage is between -1 and 1, -1 meaning an extreme disadvantage and 1 meaning an extreme advantage
local advantage = (myPow - otherPow) / math.max(myPow, otherPow)
if(advantage / 2 + .5 >agressionLevel) then
--orbitPoint(targetPos, myOrbitalDirection, botRadius * 9, 2)
prevtarget = targetPos
return(false) -- was true
else
end
end
return(false)
end
-- Returns the objective for the bot, in the form of an object the bot can navigate towards. This makes bots choose different defending locations.
-- If onTeam is true, will only return items on specified team. If onTeam is false, will return items *not* on
-- specified team. If called with fewer than three args, will ignore team altogether.
function getObjective(objType, team, onTeam)
table.clear(items)
bf:findAllObjects(items, objType) -- Returns a list of all items of type objType in the game
local itemsOnMyTeam = {}
local currentIndex = 1
for index, item in ipairs(items) do -- Iterate through all found items
local itemTeamIndex = item:getTeamIndex()
if (objType == ObjType.Flag) and (gameType == GameType.Nexus) then
if not item:isOnShip() then
itemsOnMyTeam[currentIndex] = item
currentIndex = currentIndex + 1
end
elseif (objType == ObjType.Flag) and
((gameType == GameType.HTF) or (gameType == GameType.Retrieve)) and
item:isInCaptureZone() then
--logprint(item:getCaptureZone():getTeamIndex());
if item:getCaptureZone():getTeamIndex() ~= bot:getTeamIndex() then
itemsOnMyTeam[currentIndex] = item
currentIndex = currentIndex + 1
end
elseif (objType == ObjType.GoalZone) and (gameType == GameType.HTF or gameType == GameType.Retrieve) then
if onTeam == nil or ((itemTeamIndex == team) == onTeam) then
if not item:hasFlag() then
itemsOnMyTeam[currentIndex] = item
currentIndex = currentIndex + 1
end
end
else
if (itemTeamIndex == Team.Neutral ) and (objType ~= ObjType.GoalZone or gameType ~= GameType.ZC) then
itemTeamIndex = team -- anything Neutral is on our team (except zone control neutral goal zone)
end
if onTeam == nil or ((itemTeamIndex == team) == onTeam) then
itemsOnMyTeam[currentIndex] = item
currentIndex = currentIndex + 1
end
end
end
local listMax = 0
--find max
if itemsOnMyTeam[1] ~= nil then
for index,item in ipairs(itemsOnMyTeam) do
if(item ~= nil) then
listMax = listMax + 1
end
end
local targetNum = math.mod(myObjective, listMax) + 1
return(itemsOnMyTeam[targetNum])
else
return(nil)
end
-- local closestitem = 0 --itemsOnMyTeam[1]
-- local cur = 1
-- local closestdist = 99999999
-- while itemsOnMyTeam[cur] ~= nil do
-- local item1 = itemsOnMyTeam[cur]
-- if item1 ~= nil then
-- local loc = item1.getPos()
-- if loc ~= nil then
-- local dist = point.distanceTo(botPos, loc)
-- if dist < closestdist then
-- closestdist = dist
-- closesetitem = item1
-- end
-- end
-- end
-- cur=cur+1
-- end
-- return(closestitem)
end
function doObjective(closestEnemy)
gotoPositionWasNil = true
if(gameType == GameType.Bitmatch) then
--Nothing to do here.
elseif(gameType == GameType.Nexus) then
-- Grab any flags that are found, and go to nexus when it opens
local otherFlag = getObjective(ObjType.Flag) -- Find any flags
if otherFlag ~= nil then -- If there is a flag avalible
gotoPosition(otherFlag:getPos())
end
-- If bot has more than 4 flags and the nexus is open or we're within 10 seconds of opening
if bot:getFlagCount() > 4 and (game:isNexusOpen() or game:getNexusTimeLeft() < 10) then -- Need to know if nexus is open
local nexusOrFlag = getObjective(ObjType.Nexus) -- unimplemented push function error.
if nexusOrFlag ~= nil then
gotoPosition(nexusOrFlag:getPos())
end
end
elseif(gameType == GameType.Rabbit) then
--Grab a flag, or go after the flag.
if not bot:hasFlag() then
runawayMode = false
local otherFlag = getObjective(ObjType.Flag, bot:getTeamIndex(), true) -- Find flags on our team
gotoPosition(otherFlag:getPos())
else
runawayMode = true
end
elseif(gameType == GameType.HTF or gameType == GameType.Retrieve) then
-- Grab the flag and put it into goal zones
-- Robot keeps trying to pick up the flags that is already in the goalZones
if bot:hasFlag() then -- If the bot has the flag
runawayMode = true
local otherFlag = getObjective(ObjType.GoalZone, bot:getTeamIndex(), true) -- Find an avalible GoalZone on our team
if otherFlag ~= nil then -- If there is an avalible GoalZone
gotoPosition(otherFlag:getPos()) -- Go to it
end
else -- If the bot doesn't have the flag
runawayMode = false
local otherFlag = getObjective(ObjType.Flag, bot:getTeamIndex(), true) -- Find flags on our team
if otherFlag ~= nil then -- If there is a flag avalible
gotoPosition(otherFlag:getPos()) -- Go to it
end
end
elseif(gameType == GameType.CTF) then
--defend the flag
local myFlag = getObjective(ObjType.Flag, bot:getTeamIndex(), true) -- Find flags on our team
local otherFlag = getObjective(ObjType.Flag, bot:getTeamIndex(), false) -- Find flags not on our team
if(defense < .5) then -- If bot doesn't defend allot (default is 0)
if bot:hasFlag() then -- If the bot has a flag
runawayMode = true
if not myFlag:isOnShip() then -- If my flag is not on a ship
gotoPosition(myFlag:getPos()) -- Go to position of my flag
else
gotoAndOrbitPosition(myFlag:getPos()) -- Otherwise, go and orbit the flag on enemy
end
--gotoPosition(myFlag:getPos())
else -- If the bot doesn't have the flag
runawayMode = false
local retrievingFlag = false
if myFlag ~= nil then
if not myFlag:isInInitLoc() and not myFlag:isOnShip() and -- If my flag is not in its initial location and my flag is not on a ship
point.distSquared(myFlag:getPos(), botPos) <= 2000 * 2000 then -- .. and we're within some sane range of the flag
gotoPosition(myFlag:getPos()) -- Go to and return my flag
retrievingFlag = true
end
end
if otherFlag ~= nil then -- If there is an enemy flag
if not retrievingFlag then -- .. and this bot isn't already retrieving a flag
if myFlag:isOnShip() then -- If my flag is on a ship
gotoPosition(myFlag:getPos()) -- Go to position of my flag
elseif not otherFlag:isOnShip() then -- If enemy flag is not on a ship
gotoPosition(otherFlag:getPos()) -- Go to that flag
else
gotoAndOrbitPosition(otherFlag:getPos()) -- Go and orbit our team flag's carrier
end
end
end
end
else
if bot:hasFlag() then -- If the bot has a flag and has more than .5 defense
runawayMode = true
gotoPosition(myFlag:getPos()) -- Go to team flag
elseif myFlag:isInInitLoc() then -- If the bot doesn't have a flag and the team flag is in intial location
runawayMode = false
gotoAndOrbitPosition(myFlag:getPos()) -- Go and orbit team flag
else
runawayMode = false
if myFlag:isOnShip() then -- If team flag is on a ship
gotoAndOrbitPosition(myFlag:getPos()) -- Go and orbit team flag
else
gotoPosition(myFlag:getPos()) -- If team flag is not on a ship, go to team flag
end
end
end
elseif(gameType == GameType.Soccer) then
--grab soccer and put into enemy goal
-- How do we know if we are holding soccer ? (not supported when cannot pickup soccer (016)
if bot:getMountedItems(ObjType.SoccerBallItem)[1] ~= nil then
local otherFlag = getObjective(ObjType.GoalZone, bot:getTeamIndex(), false) -- Find GoalZones not on our team
if otherFlag ~= nil then
gotoPosition(otherFlag:getPos())
end
else
local otherFlag = getObjective(ObjType.SoccerBallItem) -- Find SoccerBall
if otherFlag ~= nil then
gotoPosition(otherFlag:getPos())
end
end
elseif(gameType == GameType.ZC) then
-- Grab flag, then go after zones that is not ours.
if not bot:hasFlag() then
runawayMode = false
local otherFlag = getObjective(ObjType.Flag, bot:getTeamIndex(), true) -- Find flags on our team
if otherFlag ~= nil then
if otherFlag:isOnShip() then
gotoAndOrbitPosition(otherFlag:getPos())
else
gotoPosition(otherFlag:getPos())
end
end
else
runawayMode = true
local otherFlag = getObjective(ObjType.GoalZone, bot:getTeamIndex(), false) -- Find GoalZones on our team
if otherFlag then
gotoPosition(otherFlag:getPos())
end
end
elseif(gameType == GameType.Core) then
local obj = getObjective(ObjType.Core, bot:getTeamIndex(), false) -- Find enemy Core
if obj ~= nil then
gotoAndOrbitPosition(obj:getPos())
end
end
-- If we have no where to go, go to nearest enemy.
if gotoPositionWasNil then
if(closestEnemy ~= nil) then
prevtarget = closestEnemy:getPos()
end
if(prevtarget ~= nil) then
gotoAndOrbitPosition(prevtarget)
end
end
end
function goInDirection()
bot:setThrust(speed, dirToGo)
end
function searchForEnergyItems()
local closestItem = nil
table.clear(items)
bot:findVisibleObjects(items, ObjType.Ship, ObjType.Robot)
if(runawayMode==false and getLength(items)==0) then
table.clear(items)
bot:findVisibleObjects(items, ObjType.EnergyItem)
if(getLength(items)>0) then
local smallestDist = signedIntMax
local distance = nil
for i,v in ipairs(items) do
distance = point.distSquared(botPos, v:getPos())
if( distance < smallestDist ) then
closestItem = v
smallestDist = distance
end
end
moveToItem(closestItem:getPos())
return true
end
return false
end
end
function basicAI()
local closestEnemy = bot:findClosestEnemy()
-- attackNearbyEnemies returns true if there is an enemy to fight, false if the bot can do something else
attackNearbyEnemies(closestEnemy, 1 - agression)
doObjective(closestEnemy) -- Set bot's objective
goInDirection() -- Move the ship
updatePathTimer()
end
function updatePathTimer()
if(pathTimer < 0) then
pathTimer = pathTimerMax + math.random(0, pathTimerMax)
end
end
-- This function gets called every game tick; deltaTime is the time that has elapsed since it was last called
function onTick(deltaTime)
botPos = bot:getPos()
pathTimer = pathTimer - deltaTime
assert(botPos ~= nil)
if(firstPhase==true) then
bot:setLoadoutNow(loadoutWanted)
if(bot:hasModule(Module.Cloak)) then -- I don't know if this is necessary, but it's to make sure it's all good
firstPhase = false
end
end
fireWeaponsAndModules()
if(bot:getEnergy()<0.25 and searchForEnergyItems()==true) then
updatePathTimer()
return
end
if(firstPhase==false and chargingPlayer==false) then
basicAI()
end
end
skybax: Why is this health pack following me?
bobdaduck: uh, it likes you.