(...)
i have merged it with your bbai bug, saw no problem so far - have i overlooked something??
I have not gotten any reply to that though, afaik.(...)
If you already have a merge though, would you mind making the changed SDK files available to me? That might save me some effort.
border patrol does not work yet correctly for ships. this ship is stuck and when I add a modern ship like destroyer and set it to border patrol, the whole game gets slowed down - "laggy interface".
also, other people tell me, their ship is driving everywhere (around the sea, even outside the borders) when set to border patrol.
I've made a couple changes for a future version (which will be out in a few weeks, I'm afraid...) that will allow you to force Border Patrol units to stay inside their borders, and I changed the AI a bit. Anyway, you should be aware, Border Patrol units CAN leave the borders, and go up to 2 tiles away before they come back. I meant it to be that way so they could kill units on the outskirts of the borders.
I haven't tested much with late-game units, I'll do that when I'm back. Ciao.
//AI_patrolBorders relys heavily on the units current facing direction to determine where the next
//move should be. For example, units facing north should not turn around south, or any southerly
//direction (southwest, southeast) to patrol, since that would cause them to move back and forth
//in a nonsensical manner. Instead, they should appear to be intelligent, and move around
//the players borders in a circuit, without turning back or leaving the boundries of
//the cultural borders. This is not in fact the most optimal method of patroling, but it
//produces results that make sense to the average human, which is the actual goal, since
//the AI actually never use this function, only automated human units do.
bool CvUnitAI::AI_patrolBorders()
{
PROFILE_FUNC();
CvPlot* pBestPlot;
int iValue;
int iBestValue;
iBestValue = -1;
pBestPlot = NULL;
int iDX, iDY;
int iSearchRange = baseMoves();
for (iDX = -(iSearchRange); iDX <= iSearchRange; iDX++)
{
for (iDY = -(iSearchRange); iDY <= iSearchRange; iDY++)
{
CvPlot* pLoopPlot = plotXY(getX_INLINE(), getY_INLINE(), iDX, iDY);
if (pLoopPlot != NULL)
{
if (canMoveInto(pLoopPlot))
{
DirectionTypes eNewDirection = estimateDirection(plot(), pLoopPlot);
// offset of 250 to make sure to generate a result >= 1
iValue = 250 + GC.getGameINLINE().getSorenRandNum(1000, "AI Border Patrol");
if (pLoopPlot->isBorder(true))
{
// increased value to be sure to better than any non border plot!
// 1500 because: 1000 of max. random offset and 500 of max. random non border value addition
iValue += 1500;
iValue += GC.getGameINLINE().getSorenRandNum(1000, "AI Border Patrol");
}
else if (pLoopPlot->isBorder(false))
{
iValue += GC.getGameINLINE().getSorenRandNum(500, "AI Border Patrol");
}
//Avoid heading backwards, we want to circuit our borders, if possible.
if (eNewDirection == getOppositeDirection(getFacingDirection(false)))
{
iValue /= 25;
}
else if (isAdjacentDirection(getOppositeDirection(getFacingDirection(false)), eNewDirection))
{
iValue /= 10;
}
if (pLoopPlot->getOwnerINLINE() != getOwnerINLINE())
{
if (GET_PLAYER(getOwnerINLINE()).isOption(PLAYEROPTION_BORDER_STAY_IN_BORDERS))
{
iValue = -1;
}
else
{
iValue /= 10;
}
}
if (iValue > iBestValue)
{
iBestValue = iValue;
pBestPlot = pLoopPlot;
}
}
}
}
}
if (pBestPlot != NULL)
{
FAssert(!atPlot(pBestPlot));
getGroup()->pushMission(MISSION_MOVE_TO, pBestPlot->getX_INLINE(), pBestPlot->getY_INLINE());
return true;
}
return false;
}
if (iValue > iBestValue && getPathEndTurnPlot() != NULL)
{
iBestValue = iValue;
pBestPlot = getPathEndTurnPlot();
}
iBestValue = -1;
Okay; so I misunderstood how AI_searchRange worked. Thanks for alerting me to the issue.Okay, lets debug AUA together.
And Cybahs report is right. The ships will go everywhere. The reason is simple. You have set the searchrange to 2* BaseMove for DOMAIN_SEA. So destroyers will not go 2 plots away from the border they will go 10 plots and more from the border. And so they are out of control. And that is also the reason for the slowdown. The game has to check all plots in radius 14 sometimes instead of radius 2. A lot of plots.
And perhaps you like this code from CCV:
PHP://AI_patrolBorders relys heavily on the units current facing direction to determine where the next //move should be. For example, units facing north should not turn around south, or any southerly //direction (southwest, southeast) to patrol, since that would cause them to move back and forth //in a nonsensical manner. Instead, they should appear to be intelligent, and move around //the players borders in a circuit, without turning back or leaving the boundries of //the cultural borders. This is not in fact the most optimal method of patroling, but it //produces results that make sense to the average human, which is the actual goal, since //the AI actually never use this function, only automated human units do. bool CvUnitAI::AI_patrolBorders() { PROFILE_FUNC(); CvPlot* pBestPlot; int iValue; int iBestValue; iBestValue = -1; pBestPlot = NULL; int iDX, iDY; int iSearchRange = baseMoves(); for (iDX = -(iSearchRange); iDX <= iSearchRange; iDX++) { for (iDY = -(iSearchRange); iDY <= iSearchRange; iDY++) { CvPlot* pLoopPlot = plotXY(getX_INLINE(), getY_INLINE(), iDX, iDY); if (pLoopPlot != NULL) { if (canMoveInto(pLoopPlot)) { DirectionTypes eNewDirection = estimateDirection(plot(), pLoopPlot); // offset of 250 to make sure to generate a result >= 1 iValue = 250 + GC.getGameINLINE().getSorenRandNum(1000, "AI Border Patrol"); if (pLoopPlot->isBorder(true)) { // increased value to be sure to better than any non border plot! // 1500 because: 1000 of max. random offset and 500 of max. random non border value addition iValue += 1500; iValue += GC.getGameINLINE().getSorenRandNum(1000, "AI Border Patrol"); } else if (pLoopPlot->isBorder(false)) { iValue += GC.getGameINLINE().getSorenRandNum(500, "AI Border Patrol"); } //Avoid heading backwards, we want to circuit our borders, if possible. if (eNewDirection == getOppositeDirection(getFacingDirection(false))) { iValue /= 25; } else if (isAdjacentDirection(getOppositeDirection(getFacingDirection(false)), eNewDirection)) { iValue /= 10; } if (pLoopPlot->getOwnerINLINE() != getOwnerINLINE()) { if (GET_PLAYER(getOwnerINLINE()).isOption(PLAYEROPTION_BORDER_STAY_IN_BORDERS)) { iValue = -1; } else { iValue /= 10; } } if (iValue > iBestValue) { iBestValue = iValue; pBestPlot = pLoopPlot; } } } } } if (pBestPlot != NULL) { FAssert(!atPlot(pBestPlot)); getGroup()->pushMission(MISSION_MOVE_TO, pBestPlot->getX_INLINE(), pBestPlot->getY_INLINE()); return true; } return false; }
Unless I misunderstand how getPathEndTurnPlot is calculated; it should be returning NULL there, since I never tried to generate a path. NULL would cause the function to fail incorrectly, so units wouldn't be able to patrol. Try it and see; can units ever border patrol anymore?And it is useful to do some other changes. Just to be sure. Changes like this:
PHP:if (iValue > iBestValue && getPathEndTurnPlot() != NULL) { iBestValue = iValue; pBestPlot = getPathEndTurnPlot(); }
if (iValue > iBestValue)
{
iBestValue = iValue;
pBestPlot = pLoopPlot;
}
if (iValue > iBestValue && getPathEndTurnPlot() != NULL)
{
iBestValue = iValue;
pBestPlot = getPathEndTurnPlot();
}
And what I also should mention is a problem with your air missions. The airship can't be automated with your code. But a trick can help. Increase the collateral damage to a value > 0. So they are bombers for your code. But keep the related damagelimit at 0. So nothing will happen but the airship can be automated.
But the main problem is that your missions will not do what you describe in the help. Bombers will attack buildings as you say but they will attack units too. Same with fighters. They will do also both. But the description suggerates something else. And if you remove the lines that make the difference between fighters and bombers (modder option) it makes really no sence to have both missions at all. So you may notice that there is only one mission (airattack) for all air units.
I'm with Afforess there, getPathEndTurnPlot() should only return something useful if you did a generatePath() before. Which doesn't happen there.
If you really replace
Code:if (iValue > iBestValue) { iBestValue = iValue; pBestPlot = pLoopPlot; }
with
in AI_patrolBorders then patrolling should simply not happen, because no pathfinding means no LastNode means NULL is returned.Code:if (iValue > iBestValue && getPathEndTurnPlot() != NULL) { iBestValue = iValue; pBestPlot = getPathEndTurnPlot(); }
That is, unless you did some pathfinding with that same unit/selectiongroup in some other function before, but the only way this could happen is if anything was in huntrange but the decision was made not to hunt, which would mean that the unit will move towards that last-found enemy unit anyway. Or at least that's what I think would happen.
So what exactly is that code supposed to do? I don't get it.
I believe I made a comment to that effect in the code.
I've never suggested to use this lines in the patrol function from above. Have a look at my code. No, there are other code parts where the best plot is set to the getPathEndTurnPlot() but without a check if it is a valid plot and != NULL. The same with the offset I suggested. Not 0 in most cases. -1 will work better. I've posted my files.
About the airmissions. All I want to say is that the descriptions doesn't fit to the results.
I know exactly what you are talking about; but why shouldn't fighters be able to bomb? I just use different buttons so as not to confuse players; I realize they have the same effect.Exactly. So remove the line you commented and you will have a unit the gets both buttons. But while your description says that the first button will make the unit attack units it says that the other button will make the unit attack buildings. But that is not true. The unit will do both. Doesn't matter what button is pushed.
And the effect is also there without the modder modification. You push the attack unit button of a fighter and the fighter will also attack buildings.
More clearly now what I mean?
Ah, I see. That makes sense.
I know exactly what you are talking about; but why shouldn't fighters be able to bomb? I just use different buttons so as not to confuse players; I realize they have the same effect.
You can try german too, with me at leastYou never get my intention. My English must be terrible. Sorry.
I've never suggested to use this lines in the patrol function from above. Have a look at my code. No, there are other code parts where the best plot is set to the getPathEndTurnPlot() but without a check if it is a valid plot and != NULL. The same with the offset I suggested. Not 0 in most cases. -1 will work better. I've posted my files.
€: File attached