Skip to content

Commit

Permalink
fix citadel logic in tactsim
Browse files Browse the repository at this point in the history
fix city state resurrection logic
  • Loading branch information
ilteroi authored and RecursiveVision committed Jun 22, 2024
1 parent eb3d5c0 commit b488e3d
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 19 deletions.
6 changes: 3 additions & 3 deletions CvGameCoreDLL_Expansion2/CvAStar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,24 +418,23 @@ bool CvAStar::FindPathWithCurrentConfiguration(int iXstart, int iYstart, int iXd
saiRuntimeHistogram[iBin]++;

CvUnit* pUnit = m_sData.iUnitID > 0 ? GET_PLAYER(m_sData.ePlayer).getUnit(m_sData.iUnitID) : NULL;
#if defined(VPDEBUG)
if ( timer.GetDeltaInSeconds()>0.2 && data.ePath==PT_UNIT_MOVEMENT )
{
//debug hook
int iStartIndex = GC.getMap().plotNum(m_iXstart, m_iYstart);
#if defined(VPDEBUG)
if (iStartIndex==giLastStartIndex && iStartIndex>0)
{
OutputDebugString("Repeated pathfinding start\n");
gStackWalker.ShowCallstack(5);
}
#endif
giLastStartIndex = iStartIndex;

int iNumPlots = GC.getMap().numPlots();

//in some cases we have no destination plot, so exhaustion is not always a "fail"
CvString msg = CvString::format("Run %d: Path type %d %s (%s from %d,%d to %d,%d - flags %d), tested %d, processed %d nodes in %d rounds (%d%% of map) in %.2f ms\n",
m_iCurrentGenerationID, m_sData.ePath, bSuccess ? "found" : "not found", pUnit ? pUnit->getName().c_str() : "unknown",
m_iCurrentGenerationID, m_sData.ePath, bSuccess||!HasValidDestination() ? "found" : "not found", pUnit ? pUnit->getName().c_str() : "unknown",
m_iXstart, m_iYstart, m_iXdest, m_iYdest, m_sData.iFlags, m_iTestedNodes, m_iProcessedNodes, m_iRounds,
(100 * m_iProcessedNodes) / iNumPlots, timer.GetDeltaInSeconds() * 1000);
OutputDebugString( msg.c_str() );
Expand All @@ -448,6 +447,7 @@ bool CvAStar::FindPathWithCurrentConfiguration(int iXstart, int iYstart, int iXd
//gStackWalker.SetLog(NULL);
#endif
}
#endif

if (g_bPathFinderLogging)
{
Expand Down
2 changes: 1 addition & 1 deletion CvGameCoreDLL_Expansion2/CvGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1577,7 +1577,7 @@ void CvGame::update()
doTurn();
}

if(!isPaused()) // Check for paused again, the doTurn call might have called something that paused the game and we don't want an update to sneak through
if(!isPaused() && !bExternalPause) // Check for paused again, the doTurn call might have called something that paused the game and we don't want an update to sneak through
{
updateScore();

Expand Down
9 changes: 9 additions & 0 deletions CvGameCoreDLL_Expansion2/CvMinorCivAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4877,11 +4877,19 @@ void CvMinorCivAI::DoChangeAliveStatus(bool bAlive)
for(int iPlayerLoop = 0; iPlayerLoop < MAX_MAJOR_CIVS; iPlayerLoop++)
{
PlayerTypes ePlayer = (PlayerTypes) iPlayerLoop;
if (!GET_PLAYER(ePlayer).isAlive())
continue;

bool bFriends = false;
bool bAllies = false;
if (IsFriendshipAboveFriendsThreshold(ePlayer, GetEffectiveFriendshipWithMajor(ePlayer)))
{
//make sure we are consistent
if (bAlive && !IsFriends(ePlayer))
{
CUSTOMLOG("inconsistent friendship state after resurrection!");
SetFriends(ePlayer, true);
}
bFriends = true;
}
if(GetAlly() == ePlayer)
Expand All @@ -4891,6 +4899,7 @@ void CvMinorCivAI::DoChangeAliveStatus(bool bAlive)
}
if(bFriends || bAllies)
{
GET_PLAYER(ePlayer).GetDiplomacyAI()->LogMinorStatusChange(m_pPlayer->GetID(), bAlive ? "restore bonus yields after resurrection" : "remove bonus yields after elimination");
DoSetBonus(ePlayer, bAlive, bFriends, bAllies);
}
}
Expand Down
6 changes: 3 additions & 3 deletions CvGameCoreDLL_Expansion2/CvPlayerAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3104,7 +3104,7 @@ std::priority_queue<SPlotWithScore> CvPlayerAI::GetBestCultureBombPlots(BuildTyp

const vector<CvPlot*>& CvPlayerAI::GetTopCitadelPlotsCached()
{
const int MAX_CANDIDATES = 13;
const int MAX_CANDIDATES = 5;

if (m_iCurrentCitadelTargetsTurn == GC.getGame().getGameTurn())
return m_vCurrentCitadelTargets;
Expand All @@ -3120,8 +3120,8 @@ const vector<CvPlot*>& CvPlayerAI::GetTopCitadelPlotsCached()
m_vCurrentCitadelTargets.push_back(candidate.pPlot);
goodPlots.pop();

//give up if the rest is much worse than what we have
if (goodPlots.top().score < candidate.score / 2)
//give up if the rest is much worse than what we just had
if (goodPlots.top().score < candidate.score * 0.7f)
break;
}

Expand Down
37 changes: 25 additions & 12 deletions CvGameCoreDLL_Expansion2/CvTacticalAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8064,12 +8064,6 @@ STacticalAssignment ScorePlotForNonFightingUnitMove(const SUnitStats& unit, cons
return result;
}
}
else if (testPlot.isNicePlotForCitadel() && pUnit->IsGreatGeneral() && movePlot.iMovesLeft > 0)
{
result.eAssignmentType = A_USE_POWER;
result.iRemainingMoves = 0;
iScore += 100;
}
else if (!pTestPlot->isFriendlyCity(*pUnit)) //cities are considered safe
return result;

Expand All @@ -8086,6 +8080,10 @@ STacticalAssignment ScorePlotForNonFightingUnitMove(const SUnitStats& unit, cons
iScore -= 3;
}

//place to be!
if (testPlot.isNicePlotForCitadel() && pUnit->IsGreatGeneral())
iScore += 23;

//points for supported units (count only the first ring for performance ...)
int iFriends = testPlot.getNumAdjacentFriendlies(CvTacticalPlot::TD_BOTH, -1);
if (testPlot.hasFriendlyCombatUnit())
Expand Down Expand Up @@ -8788,10 +8786,23 @@ void CvTacticalPosition::getPreferredAssignmentsForUnit(const SUnitStats& unit,
}
else if (unit.iPlotIndex == it->iPlotIndex)
{
STacticalAssignment newAssignment = ScorePlotForPillageMove(unit, testPlot, *it, *this);
//pillaging must have a positive score
if (newAssignment.iScore > 0 && (newAssignment.iRemainingMoves>0 || couldEndTurnAfterThisAssignment(newAssignment)))
STacticalAssignment newAssignment(unit.iPlotIndex, unit.iPlotIndex, unit.iUnitID, it->iMovesLeft,unit.eMoveStrategy,0,A_BLOCKED);

//maybe we can do something special here?
if (testPlot.isNicePlotForCitadel() && pUnit->IsGreatGeneral())
{
newAssignment.eAssignmentType = A_USE_POWER;
newAssignment.iScore = 1000;
}
else
newAssignment = ScorePlotForPillageMove(unit, testPlot, *it, *this);

//special action must have a positive score
if (newAssignment.iScore > 0 && (newAssignment.iRemainingMoves > 0 || couldEndTurnAfterThisAssignment(newAssignment)))
{
gPossibleMoves.push_back(newAssignment);
}
//stay in plot but do nothing special
else if (refAssignment.iScore > TACTICAL_COMBAT_IMPOSSIBLE_SCORE)
{
int iBonus = 0;
Expand Down Expand Up @@ -10366,7 +10377,7 @@ bool CvTacticalPosition::addTacticalPlot(const CvPlot* pPlot, const vector<CvUni

bool CvTacticalPosition::addAvailableUnit(const CvUnit* pUnit)
{
if (!pUnit || !pUnit->canMove() || !pUnit->canEndTurnAtPlot(pUnit->plot()))
if (!pUnit || !pUnit->canMove())
return false;

eUnitMovementStrategy eStrategy = MS_NONE;
Expand Down Expand Up @@ -10780,6 +10791,8 @@ vector<STacticalAssignment> TacticalAIHelpers::FindBestUnitAssignments(
for(vector<CvUnit*>::iterator it=ourUnits.begin(); it!=ourUnits.end(); ++it)
{
CvUnit* pUnit = *it;
//if the add fails we might have marked a tactical plot as available but now suddenly it's occupied by a non-sim unit
//but should not happen with the pre-checks above and it's not a big problem anyway
if (initialPosition->addAvailableUnit(pUnit))
{
//make sure we know the immediate surroundings of every unit
Expand Down Expand Up @@ -10981,7 +10994,7 @@ bool TacticalAIHelpers::ExecuteUnitAssignments(PlayerTypes ePlayer, const std::v
//see if we can indeed reach the target plot this turn ...
pUnit->ClearPathCache();
if (!pUnit->GeneratePath(pToPlot, iMoveflags) || pUnit->GetPathEndFirstTurnPlot() != pToPlot)
OutputDebugString("ouch, pathfinding problem\n");
CUSTOMLOG("ouch, pathfinding problem for u%d at (%d:%d)\n", pUnit->GetID(), pToPlot->getX(), pToPlot->getY());
}
#endif
if (bPrecondition)
Expand All @@ -10991,7 +11004,7 @@ bool TacticalAIHelpers::ExecuteUnitAssignments(PlayerTypes ePlayer, const std::v
#ifdef TACTDEBUG
//check this only for moves, eg melee kills can fail this check because the pathfinder assumes attacks end the turn!
if (vAssignments[i].iRemainingMoves != pUnit->getMoves() && bPostcondition)
OutputDebugString("ouch, inconsistent movement points\n");
CUSTOMLOG("ouch, inconsistent movement points for u%d at (%d:%d)\n", pUnit->GetID(), pToPlot->getX(), pToPlot->getY());
#endif
break;
case A_MOVE_SWAP:
Expand Down

0 comments on commit b488e3d

Please sign in to comment.