def tryProduce(factory, type): prod = BoScript.productionTypes(factory) for p in prod: if p == type: BoScript.produceUnit(factory, p) return 1 return 0
def place(): units = BoScript.allPlayerUnits(ai.player) for u in units: # AB; unitAdvanceWork(u) == 9 means "WorkPlugin", which is e.g. produce if BoScript.canUnitProduce(u) and BoScript.unitAdvanceWork(u) == 9 and BoScript.hasUnitCompletedProduction(u): boprint("debug", "start placement algorithm for unit %d" % u) placeUnit(u, BoScript.completedProductionType(u))
def findExplorerUnit(self): units = BoScript.allPlayerUnits(self.mPlayer) for u in units: if BoScript.isUnitMobile(u): if BoScript.canUnitMineMinerals(u) or BoScript.canUnitMineOil( u): continue pos = BoScript.unitPosition(u) if pos[0] != -1: return unit.Unit(self.mPlayer, u) return 0
def findTarget(): boprint("debug", "%s: findTarget()" % module) target = -1 units = BoScript.allEnemyUnitsVisibleFor(ai.player) for u in units: # FIXME: command center id is hardcoded if BoScript.unitType(u) == 5: return u if target == -1: target = u # if cmdcenter wasn't found, return any other unit return target
def advanceAttack(): global aiunit, aitarget boprint("debug", "%s: advanceAttack()" % module) # check if target is still alive if aitarget == -1 or not BoScript.isUnitAlive(aitarget): boprint("debug", "searching for new target...") aitarget = findTarget() if aitarget == -1: boprint("debug", "... no target found. nothing to do.") return boprint("debug", "... target is now %s" % aitarget) # find attacker attacker = -1 units = BoScript.allPlayerUnits(ai.player) while attacker == -1: aiunit = aiunit + 1 if aiunit >= len(units): aiunit = -1 boprint("info", "No attacker found, returning") return u = units[aiunit] if BoScript.isUnitMobile(u): if BoScript.canUnitShoot( u) and not explorerObject.isIdExploring(u): attacker = u targetpos = BoScript.unitPosition(aitarget) boprint( "debug", "ordering unit %s to attack targetpos %s containing target %s" % (attacker, targetpos, aitarget)) BoScript.moveUnitWithAttacking(attacker, targetpos[0], targetpos[1])
def produce(): units = BoScript.allPlayerUnits(ai.player) for u in units: # AB: unitAdvanceWork(u) == 0 means that the unit is idle if BoScript.canUnitProduce(u) and BoScript.unitAdvanceWork(u) == 0: boprint("debug", "start production algorithm for unit %d" % u) prod = BoScript.productionTypes(u) canProduceFacilities = 0 canProduceMobiles = 0 for p in prod: isMobile = BoScript.isUnitTypeMobile(ai.player, p) if isMobile: canProduceMobiles = 1 else: canProduceFacilities = 1 if canProduceFacilities: produceFacilities(u) if canProduceMobiles: produceMobiles(u)
def placeUnit(factory, unitType): if(BoScript.isUnitTypeMobile(ai.player, int(unitType)) == False): boprint("debug", "Ok , building") pos = BoScript.unitPosition(int(factory)) x = int(pos[0]) y = int(pos[1]) tmpx = x tmpy = y # AB: don't make unlimitied tries (avoid infinite loop) tries = 0 while BoScript.canPlaceProductionAt(factory, unitType, int(tmpx), int(tmpy)) != 1 and tries < 30: distance = randint(0, 20) tmpx = randint(x-distance, x+distance) tmpy = randint(y-distance, y+distance) if(tmpx < 0): tmpx = x if(tmpy < 0): tmpy = y tries = tries + 1 boprint("debug","placed tmpx %d,tmpy %d " % (tmpx,tmpy)) BoScript.placeProduction(int(factory), tmpx, tmpy)
def updateLighting(): global sun ### Light position: # Calculate position of the light on xy plane lightpos2d = pointByRotation(degrees(sun.az), 5000) # Calculate height of the light. height = 5000 * tan(sun.alt) # Compose final position for the light and set it pos = lightpos2d[0], -lightpos2d[1], height, 1 BoScript.setLightPos(0, pos) # Sunfactor should be an approximate of how much of Sun's light will reach # the ground (some of it will be dispersed in the atmosphere) sunfactor = 0.0 if sun.alt >= 90: sunfactor = 1.0 elif sun.alt > 0.0: adist = 1.0 / sin(sun.alt) #sunfactor = 1.0 / sqrt(adist) sunfactor = 1.0 / adist ### Light colors: # Base intensities for ambient and diffuse colors baseambientday = 0.4 # Ambient color at day baseambientnight = 0.3 # Ambient color at night basediffuseday = 0.9 # Diffuse color at day basediffusenight = 0.0 # Diffuse color at night # Calculate base ambient intensity # If the sun is shining bright, ambient intensity is quite big (in real world, # it's because of radiosity). Increase it # Note that we don't want it to get too high either, because we'd have no # shading then baseambient = baseambientnight + sunfactor * (baseambientday - baseambientnight) # Calculate base diffuse intensity # Diffuse color is based on the angle of the sun. Note that here, we set # diffuse color to max when sun angle is 60 degrees (max here), not 90. basediffuse = basediffusenight + sunfactor * (basediffuseday - basediffusenight) # Set light colors ambient = baseambient, baseambient, baseambient, 1.0 diffuse = basediffuse, basediffuse, basediffuse, 1.0 BoScript.setLightAmbient(0, ambient) BoScript.setLightDiffuse(0, diffuse) BoScript.setLightSpecular(0, diffuse) # not used yet, same as diffuse
def position( self ): """@return The unit position.""" return BoScript.unitPosition( self.mID )
def moveWithAttacking( self, x, y ): """ The same as in @ref moveUnit, but the unit will attack enemy units on its way.""" BoScript.moveUnitWithAttacking( self.mID, x, y )
def mine( self, x, y ): """Sends the unit to the mine at (x,y).""" BoScript.mineUnit( self.mID, x, y )
def isAlive( self ): """@return @c true if the unit is alive, otherwise @c false.""" return BoScript.isUnitAlive( self.mID )
def dropBomb( self, weapon, x, y ): """Drops a bomb by using the specified weapon at the given position.""" BoScript.dropBomb( self.mID, weapon, x, y )
def canProduce( self ): """ @return @c true if the unit can produce something (units or upgrades), otherwise @c false.""" return BoScript.canUnitProduce( self.mID )
def produceFacilities(factory): boprint("debug", "produceFacilities()") prod = BoScript.productionTypes(factory) # at first we make sure that we always have at least 1000 more than we need. boprint("debug", " rule 1: power!") powerGenerated = BoScript.powerGeneratedAfterConstructions(ai.player) powerConsumed = BoScript.powerConsumedAfterConstructions(ai.player) if powerGenerated < powerConsumed + 1000: boprint("debug", " rule 1: not fullfilled - powerGenerated=%d, powerConsumed=%d" % (powerGenerated, powerConsumed)) # try to build a powerplant (ID=2) for p in prod: if p == 2: # powerplant BoScript.produceUnit(factory, p) return boprint("debug", " rule 1: cannot fullfill rule") # build weapon factory (ID=3) if necessary boprint("debug", " rule 2: weaponsfactory!") haveWeaponsFactory = BoScript.playerUnitsOfTypeCount(ai.player, 3) if haveWeaponsFactory < 1: boprint("debug", " rule 2: not fullfilled") for p in prod: if p == 3: BoScript.produceUnit(factory, p) return boprint("debug", " rule 2: cannot fullfill rule") # buld mineral/oil refineries boprint("debug", " rule 3: refineries!") haveMineralRefinery = BoScript.playerUnitsOfTypeCount(ai.player, 13) haveOilRefinery = BoScript.playerUnitsOfTypeCount(ai.player, 8) if haveMineralRefinery < 1 or haveOilRefinery < 1: boprint("debug", " rule 3: not fullfilled") # AB: we use 2 different loops - we prefer mineral refinieries over oil # refineries (we need more minerals to build them) for p in prod: if p == 13 and haveMineralRefinery < 1: BoScript.produceUnit(factory, p) return for p in prod: if p == 8 and haveOilRefinery < 1: BoScript.produceUnit(factory, p) return boprint("debug", " rule 3: cannot fullfill rule") minerals = BoScript.minerals(ai.player) oil = BoScript.minerals(ai.player) haveMineralHarvesters = BoScript.playerUnitsOfTypeCount(ai.player, 10003) haveOilHarvesters = BoScript.playerUnitsOfTypeCount(ai.player, 10002) if (minerals < 1500 and haveMineralHarvesters < 1) or (oil < 1500 and haveOilHarvesters < 1): boprint("debug", "unsufficient resources - delay facility production (need to build harvesters first") return # build at least a minimum amount of defense facilities (turrets, samsites) # TODO boprint("debug", " rule 4: defenses! (TODO)") haveDefenses = 0 # TODO defensesMinimum = 0 # TODO if haveDefenses < defensesMinimum: boprint("debug", " rule 4: not fullfilled") wantMoreTurrets = 0 # TODO wantMoreSamsites = 0 # TODO wantMoreAirTurrets = 0 # TODO for p in prod: if p == 10 and wantMoreTurrets > 0: # turret BoScript.produceUnit(factory, p) return if p == 6 and wantMoreSamsites > 0: # samsite BoScript.produceUnit(factory, p) return if p == 18 and wantMoreAirTurrets > 0: # airturret BoScript.produceUnit(factory, p) return boprint("debug", " rule 4: cannot fullfill rule") # only build the expensive stuff if we have enough resources or at least # potential to gain new resources if (minerals < 3000 and haveMineralHarvesters < 1) or (oil < 3000 and haveOilHarvesters < 1): boprint("debug", "unsufficient resources - delay facility production (need to build harvesters first") return # build secondary production facilities and comsat boprint("debug", " rule 5: secondary productions!") haveComsat = BoScript.playerUnitsOfTypeCount(ai.player, 14) haveHelipad = BoScript.playerUnitsOfTypeCount(ai.player, 1) haveTechcenter = BoScript.playerUnitsOfTypeCount(ai.player, 12) if haveComsat < 1 or haveHelipad < 1 or haveTechcenter < 1: boprint("debug", " rule 5: not fullfilled") for p in prod: if p == 14 and haveComsat < 1: BoScript.produceUnit(factory, p) return if p == 1 and haveHelipad < 1: BoScript.produceUnit(factory, p) return if p == 12 and haveTechcenter < 1: BoScript.produceUnit(factory, p) return boprint("debug", " rule 5: cannot fullfill rule") # now make sure that we have some power reserves boprint("debug", " rule 6: power reserves!") if powerGenerated < powerConsumed * 1.25: boprint("debug", " rule 6: not fullfilled") for p in prod: if p == 2: # powerplant BoScript.produceUnit(factory, p) return boprint("debug", " rule 6: cannot fullfill rule") # finally build additional defenses defensesMaximum = 0 # TODO boprint("debug", " rule 7: additional defenses! (TODO)") if haveDefenses < defensesMaximum: boprint("debug", " rule 7: not fullfilled") wantMoreTurrets = 0 # TODO wantMoreSamsites = 0 # TODO wantMoreAirTurrets = 0 # TODO for p in prod: if p == 10 and wantMoreTurrets > 0: # turret BoScript.produceUnit(factory, p) return if p == 6 and wantMoreSamsites > 0: # samsite BoScript.produceUnit(factory, p) return if p == 18 and wantMoreAirTurrets > 0: # airturret BoScript.produceUnit(factory, p) return boprint("debug", " rule 7: cannot fullfill rule") boprint("debug", " no rules left. nothing to produce.")
def canMineMinerals( self ): """@return @c true if the unit can mine minerals, otherwise @c false.""" return BoScript.canUnitMineMinerals( self.mID )
def canMineOil( self ): """@return @c true if the unit can mine oil, otherwise @c false.""" return BoScript.canUnitMineOil( self.mID )
def setRotation( self, rotation ): """Sets the unit's rotation to the given value.""" BoScript.setUnitRotation( self.mID, rotation )
def canShoot( self ): """@return @c true if the unit can shoot, otherwise @c false.""" return BoScript.canUnitShoot( self.mID )
def stop( self ): """Stops unit from doing anything and becomes idle. Note that even idle units shoot at any enemy units in range. If stop was called while the unit was attacking, then after calling stop() it may start to shoot at another unit.""" BoScript.stopUnit( self.mID )
def isAircraft( self ): """@return @c true if the unit is an aircraft, otherwise @c false.""" return BoScript.isUnitAircraft( self.mID )
def type( self ): """@return The type of the unit.""" return BoScript.unitType( self.mID )
def isMobile( self ): """@return @c true if the unit is mobile, otherwise @c false.""" return BoScript.isUnitMobile( self.mID )
def teleport( self, x, y ): """Immediately moves the unit to position (x,y).""" BoScript.teleportUnit( self.mID, x, y )
def move( self, x, y ): """ Move unit to position x, y. The unit will go to the given poistion without attacking other units on its way.""" BoScript.moveUnit( self.mID, x, y )
def work( self ): """ Current work the unit is involved in, e.g., attacking, moving, ... For a complete list of possible return values see unitbase.h . @return the ID of the current work.""" return BoScript.unitAdvanceWork( self.mID )
def owner( self ): """@return The owner of the unit.""" return BoScript.unitOwner( self.mID )
def sightRange( self ): """ @return how many cells away the unit can see.""" return BoScript.unitSightRange( self.mID )
def produceUnit( self, productID ): """Produces a unit of the given product ID.""" BoScript.produceUnit( self.mID, productID )
def attack( self, targetID ): """ Unit will attack the unit with the given target ID. In case the target is not in weapon range, the unit will move until the target is close enough to be attacked.""" BoScript.attack( self.mID, targetID )