God-Emperor
Deity
Another bug.
Quite some time ago I noticed that AI controlled starbases can attack units in places where it wouldn't be able to do so if it were controlled by me. Specifically, with an attack range of 3 they can attack units in tiles near the four corners of the 7x7 area that are actually 4 units away from the starabase (the actual target area should be the same as it is for a human player, select a starbase to see what it is) and they can attack units on the other side of asteroid fields. It would be even worse for omega starbases, attacking in more tiles that should be excluded due to the range calculation and even targets that it can not actually see since the attack range of an omega SB exceed's it's visual range, except I have never seen the AI use an omega starbase.
The attacking across asteroid fields would be a hard problem to solve in the Python (possible, but hard - and slow) - it is actually a bug in the DLL in the CvUnit::rangeStrike function. I have reported this bug in the Unofficial Patches forum here, it is bug "1.a" in that post that is causing this problem. Fixing it will also fix the ability to attack locations that ought to be out of range.
In addition to this, I'm pretty sure that every AI controlled starbase it trying to do a ranged attack every turn whether there are valid targets available or not. If there are no valid targets then the DLL will not actually to the attack, but time is wasted making the attempt.
So here is a fix for both the "attack even when there are no valid targets", the "attack things that are actually out of range", and the "attack targets out of visual range" (just in case the AI ever has an omega starabase) problems.
In CvAI.py, in the doStarbaseAI function:
Original code:
New code:
Quite some time ago I noticed that AI controlled starbases can attack units in places where it wouldn't be able to do so if it were controlled by me. Specifically, with an attack range of 3 they can attack units in tiles near the four corners of the 7x7 area that are actually 4 units away from the starabase (the actual target area should be the same as it is for a human player, select a starbase to see what it is) and they can attack units on the other side of asteroid fields. It would be even worse for omega starbases, attacking in more tiles that should be excluded due to the range calculation and even targets that it can not actually see since the attack range of an omega SB exceed's it's visual range, except I have never seen the AI use an omega starbase.
The attacking across asteroid fields would be a hard problem to solve in the Python (possible, but hard - and slow) - it is actually a bug in the DLL in the CvUnit::rangeStrike function. I have reported this bug in the Unofficial Patches forum here, it is bug "1.a" in that post that is causing this problem. Fixing it will also fix the ability to attack locations that ought to be out of range.
In addition to this, I'm pretty sure that every AI controlled starbase it trying to do a ranged attack every turn whether there are valid targets available or not. If there are no valid targets then the DLL will not actually to the attack, but time is wasted making the attempt.
So here is a fix for both the "attack even when there are no valid targets", the "attack things that are actually out of range", and the "attack targets out of visual range" (just in case the AI ever has an omega starabase) problems.
In CvAI.py, in the doStarbaseAI function:
Original code:
Code:
pLoopPlot = CyMap().plot(iActiveX, iActiveY)
iPlotValue = 0
# Look at all the units on this plot
for iUnitLoop in range(pLoopPlot.getNumUnits()):
pLoopUnit = pLoopPlot.getUnit(iUnitLoop)
# At war with this unit's owner?
if (pTeam.isAtWar(pLoopUnit.getTeam())):
# The greater the cost of the unit the more we want to kill it :)
iCost = gc.getUnitInfo(pLoopUnit.getUnitType()).getProductionCost()
if (iCost > 0):
iPlotValue += iCost
aiBombardPlotValues.append([iPlotValue, iActiveX, iActiveY])
# Any valid plots to hit?
Code:
pLoopPlot = CyMap().plot(iActiveX, iActiveY)
if pLoopPlot.isVisible(iTeam, false) and (plotDistance(pUnit.getX(),pUnit.getY(),iActiveX,iActiveY) <= pUnit.airRange()): # CP - bugfix for AI starbases attacking things they shouldn't be able to see or reach
iPlotValue = 0
# Look at all the units on this plot
for iUnitLoop in range(pLoopPlot.getNumUnits()):
pLoopUnit = pLoopPlot.getUnit(iUnitLoop)
# At war with this unit's owner?
if (pTeam.isAtWar(pLoopUnit.getTeam())):
# The greater the cost of the unit the more we want to kill it :)
iCost = gc.getUnitInfo(pLoopUnit.getUnitType()).getProductionCost()
if (iCost > 0):
iPlotValue += iCost
if iPlotValue > 0: # CP - bugfix for trying to attack when there are no valid targets
aiBombardPlotValues.append([iPlotValue, iActiveX, iActiveY])
# Any valid plots to hit?