Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- game = nil
- difficulty = nil
- speed = nil
- directionThreshold = nil
- averageIndex = nil
- averageMax = nil
- myOrbitalDirection = nil
- agression = nil
- defense = nil
- myNum = nil
- gameType = nil
- goalPt = vec.new(0,0)
- dirToGo = nil
- pathTimer = nil
- pathTimerMax = nil
- o = vec.new(0,0)
- botLoc = nil -- Bot's location, will be updated when onTick() is run
- botRadius = nil
- function main()
- botRadius = bot:getRad()
- pathTimerMax = 250
- pathTimer = pathTimerMax
- dirToGo = 0
- game = GameInfo()
- difficulty = tonumber(arg[1]) or .5
- agression = tonumber(arg[2]) or .5
- defense = tonumber(arg[3]) or .5
- speed = tonumber(arg[4]) or .75
- directionThreshold = tonumber(arg[5]) or .25
- gameType = game:getGameType()
- averageIndex = 1
- averageMax = 20
- averageArray = {}
- for i = 1, averageMax do
- averageArray[i] = false
- end
- myOrbitalDirection = 1
- myNum = math.random(0,10)
- end
- function vectorX(dir, dist)
- return(dist * math.cos(dir))
- end
- function vectorY(dir, dist)
- return(-dist * math.sin(dir))
- end
- function shieldSelf()
- local bullets = bot:findItems(BulletType,AsteroidType,MineType)
- local distToShieldAt = bot:getRad()*2 + (1-difficulty)*100
- if (bullets ~= nil) then
- for i,bullet in ipairs(bullets) do
- local bulletLoc = bullet:getLoc()
- local bulletVel = bullet:getVel()
- local angleDiff = math.abs(angleDifference(vec.angleTo(o, bulletVel), vec.angleTo(bulletLoc, botLoc)))
- --logprint(angleDiff)
- if (vec.distanceTo(bulletLoc, botLoc) < distToShieldAt + bullet:getRad() and angleDiff < math.pi/4) then
- bot:activateModule(ModuleShield)
- 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 fireAtObjects()
- local enemies = bot:findItems(RobotType, TurretType, ShipType, AsteroidType, ForceFieldProjectorType, SpyBugType)
- for index,enemy in ipairs(enemies) do
- if(fireAtObject(enemy, WeaponPhaser)) 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)
- if(obj:getClassID() == TurretType or obj:getClassID() == ForceFieldProjectorType) then
- if(obj:getHealth() < .1) then
- --logprint("It's dead.")
- return(false)
- end
- end
- if(obj:getClassID() == ShipType or
- obj:getClassID() == RobotType or
- obj:getClassID() == TurretType or
- obj:getClassID() == ForceFieldProjectorType) then
- if obj:getTeamIndx() == bot:getTeamIndx() and game:isTeamGame() 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()-1)*20*(1-difficulty)))
- bot:setWeapon(weapon)
- bot:fire()
- --logprint("bot:fire() called!");
- return(true)
- end
- --logprint("Firing solution not found.");
- return(false)
- end
- function getName()
- return("QuickBot")
- end
- function findEnemy()
- local enemies = bot:findItems(ShipType, RobotType)
- local target = nil
- local smallestDist = 999999
- for index,enemy in ipairs(enemies) do
- if (enemy:getTeamIndx() ~= bot:getTeamIndx() and game:isTeamGame()) then -- Put cheaper test first
- local d = vec.distSquared(botLoc, enemy:getLoc())
- if( d < smallestDist ) then
- target = enemy
- smallestDist = d
- end
- end
- end
- if(target ~= nil and bot:hasLosPt(target:getLoc())) then
- return(target)
- elseif(enemies[0] ~= nil) then
- return(enemies[0])
- end
- return(nil)
- 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)
- local distAway = bot:getRad()*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 = vec.distanceTo(pt, botLoc)
- 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 = vec.angleTo(pt, bot:getLoc())
- dirToGo = angleToPoint + (math.pi/2 + changeInAngle)*direction
- --bot:setThrust(speed,dirToGo)
- end
- end
- function gotoPosition(pt)
- if(pathTimer<.01)then
- goalPt=bot:getWaypoint(pt)
- dirToGo = vec.angleTo(botLoc,goalPt)
- end
- end
- function gotoAndOrbitPosition(pt)
- if not bot:hasLosPt(pt) then
- gotoPosition(pt)
- else
- orbitPoint(pt, myOrbitalDirection, botRadius * 5, 2)
- end
- end
- --returns if it found an enemy to fight
- function attackNearbyEnemies(agressionLevel)
- local target = findEnemy()
- if target ~= nil then
- local targetLoc = target:getLoc()
- local dist = vec.distanceTo(botLoc, targetLoc)
- local myPow = (bot:getEnergy() + bot:getHealth() )
- local enemies = bot:findItems(ShipType, RobotType)
- --for index, otherShip in ipairs(enemies) do
- -- otherPow = otherPow + target:getEnergy() + target:getHealth()
- --end
- -- Means this, right?
- local otherPow = target:getEnergy() + target:getHealth() * #enemies
- --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(targetLoc, myOrbitalDirection, botRadius * 9, 2)
- return(true)
- else
- end
- end
- return(false)
- end
- --Returns the objective for the bot based on myNum. This makes bots choose different defending locations.
- function getObjective(objType, team, onTeam)
- local items = bot:findGlobalItems(objType)
- local itemsOnMyTeam = {}
- local currentIndex = 1
- for ind, it in ipairs(items) do
- local itTeamIndex = it:getTeamIndx()
- if(objType == ShipType or objType == RobotType or objType == TurretType or objType == ForceFieldProjectorType or objType == FlagType or objType == GoalZoneType or objType == NexusType or objType == SpyBugType) then
- if (itTeamIndex == team and onTeam) or (itTeamIndex ~= team and not onTeam) then
- itemsOnMyTeam[currentIndex] = it
- currentIndex = currentIndex + 1
- end
- else
- itemsOnMyTeam[currentIndex] = it
- currentIndex = currentIndex + 1
- 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(myNum,listMax) + 1
- return(itemsOnMyTeam[targetNum])
- else
- return(nil)
- end
- end
- function doObjective()
- if(gameType == BitmatchGame or gameType == NexusGame or gameType == RabbitGame) then
- --Nothing to defend! Wander aimlessly
- elseif(gameType == HTFGame) then
- --defend the goals
- elseif(gameType == CTFGame) then
- --defend the flag
- local myFlag = getObjective(FlagType,bot:getTeamIndx(),true)
- local otherFlag = getObjective(FlagType,bot:getTeamIndx(),false)
- if(defense<.5) then
- if bot:hasFlag() then
- if not myFlag:isOnShip() then
- gotoPosition(myFlag:getLoc())
- else
- gotoAndOrbitPosition(myFlag:getLoc())
- end
- --gotoPosition(myFlag:getLoc())
- elseif(otherFlag ~= nil) then
- if not otherFlag:isOnShip() then
- gotoPosition(otherFlag:getLoc())
- else
- gotoAndOrbitPosition(otherFlag:getLoc())
- end
- end
- else
- if bot:hasFlag() then
- gotoPosition(myFlag:getLoc())
- elseif myFlag:isInInitLoc() then
- gotoAndOrbitPosition(myFlag:getLoc())
- else
- if myFlag:isOnShip() then
- gotoAndOrbitPosition(myFlag:getLoc())
- else
- gotoPosition(myFlag:getLoc())
- end
- end
- end
- elseif(gameType == SoccerGame) then
- --defend the goal
- elseif(gameType == RetrieveGame) then
- --defend the goals
- elseif(gameType == ZoneControlGame) then
- --defend the zones owned by bot's team
- end
- end
- function goInDirection()
- bot:setThrust(speed,dirToGo)
- end
- function onTick()
- botLoc = bot:getLoc()
- pathTimer=pathTimer-bot:getTime()
- assert(bot:getLoc() ~= nil)
- if not attackNearbyEnemies(1-agression) then
- doObjective()
- end
- goInDirection()
- fireAtObjects()
- shield()
- if(pathTimer<0)then
- pathTimer=pathTimerMax+math.random(0,pathTimerMax)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment