Code
8992void CvGame::testVictory()8993{8994 bool bEndScore = false;89958996 // Send a game event to allow a Lua script to set the victory state8997 ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();8998 if(pkScriptSystem)8999 {9000 CvLuaArgsHandle args;9001 bool bResult;9002 LuaSupport::CallHook(pkScriptSystem, "GameCoreTestVictory", args.get(), bResult);9003 }90049005 if(getVictory() != NO_VICTORY)9006 {9007 return;9008 }90099010 if(getGameState() == GAMESTATE_EXTENDED)9011 {9012 return;9013 }90149015 updateScore();90169017 bool bEndGame = false;90189019 std::vector<std::vector<int> > aaiGameWinners;9020 int iTeamLoop = 0;9021 int iVictoryLoop = 0;90229023 int iNumCompetitionWinners = 0;9024 for(iTeamLoop = 0; iTeamLoop < MAX_CIV_TEAMS; iTeamLoop++)9025 {9026 m_aiTeamCompetitionWinnersScratchPad[iTeamLoop] = 0;9027 }90289029 // Look at each Victory Competition9030 for(iVictoryLoop = 0; iVictoryLoop < GC.getNumVictoryInfos(); iVictoryLoop++)9031 {9032 const VictoryTypes eVictory = static_cast<VictoryTypes>(iVictoryLoop);9033 CvVictoryInfo* pkVictoryInfo = GC.getVictoryInfo(eVictory);9034 if(pkVictoryInfo == NULL)9035 continue;90369037 for(iTeamLoop = 0; iTeamLoop < MAX_CIV_TEAMS; iTeamLoop++)9038 {9039 CvTeam& kLoopTeam = GET_TEAM((TeamTypes)iTeamLoop);9040 if(kLoopTeam.isAlive())9041 {9042 if(!(kLoopTeam.isMinorCiv()))9043 {9044 if(testVictory(eVictory, (TeamTypes)iTeamLoop, &bEndScore))9045 {9046 // Some Victories win the game for the player who accomplishes it. If this happens for multiple teams in the same turn we have to break the tie9047 if(pkVictoryInfo->IsWinsGame())9048 {9049 std::vector<int> aWinner;9050 aWinner.push_back(iTeamLoop);9051 aWinner.push_back(iVictoryLoop);9052 aaiGameWinners.push_back(aWinner);90539054 bEndGame = true;9055 }9056 // Non game-ending Competition winner placement9057 else9058 {9059 m_aiTeamCompetitionWinnersScratchPad[iNumCompetitionWinners] = iTeamLoop;9060 iNumCompetitionWinners++;9061 }9062 }9063 }9064 }9065 }90669067 // Any (non game-ending) Competition placers?9068 if(iNumCompetitionWinners > 0)9069 {9070 int iRand;90719072 do9073 {9074 if(isVictoryAvailable(eVictory))9075 {9076 iRand = GC.getGame().getJonRandNum(iNumCompetitionWinners, "Victory Competition tiebreaker");9077 iTeamLoop = m_aiTeamCompetitionWinnersScratchPad[iRand];90789079 DoPlaceTeamInVictoryCompetition(eVictory, (TeamTypes) iTeamLoop);90809081 iNumCompetitionWinners--;9082 }9083 else9084 {9085 iNumCompetitionWinners = 0;9086 }9087 }9088 while(iNumCompetitionWinners > 0);9089 }9090 }90919092 // Game could have been set to ending already by an insta-win victory, or we might have hit the end of time manually9093 if(!bEndGame)9094 {9095 bEndGame = IsEndGameTechResearched();90969097 if(bEndGame)9098 {9099 VictoryTypes eScoreVictory = NO_VICTORY;9100 for(iVictoryLoop = 0; iVictoryLoop < GC.getNumVictoryInfos(); iVictoryLoop++)9101 {9102 VictoryTypes eVictory = static_cast<VictoryTypes>(iVictoryLoop);9103 CvVictoryInfo* pkVictoryInfo = GC.getVictoryInfo(eVictory);9104 if(pkVictoryInfo)9105 {9106 if(pkVictoryInfo->isTargetScore())9107 {9108 eScoreVictory = eVictory;9109 break;9110 }9111 }9112 }91139114 aaiGameWinners.clear();91159116 // Find out who is in the lead with VPs9117 int iBestVPNum = 0;9118 int iVPs;9119 for(iTeamLoop = 0; iTeamLoop < MAX_CIV_TEAMS; iTeamLoop++)9120 {9121 iVPs = GET_TEAM((TeamTypes) iTeamLoop).getVictoryPoints();91229123 if(iVPs > iBestVPNum)9124 {9125 iBestVPNum = iVPs;9126 }9127 }91289129 // Now that we know what the highest is, see if any players are tied9130 for(iTeamLoop = 0; iTeamLoop < MAX_CIV_TEAMS; iTeamLoop++)9131 {9132 iVPs = GET_TEAM((TeamTypes) iTeamLoop).getVictoryPoints();91339134 if(iVPs == iBestVPNum)9135 {9136 std::vector<int> aWinner;9137 aWinner.push_back(iTeamLoop);9138 aWinner.push_back(eScoreVictory);9139 aaiGameWinners.push_back(aWinner);9140 }9141 }9142 }9143 }91449145 if(!bEndGame)9146 {9147 bEndGame = (getMaxTurns() > 0 && getElapsedGameTurns() >= getMaxTurns());91489149 if(bEndGame)9150 {9151 VictoryTypes eScoreVictory = NO_VICTORY;9152 for(iVictoryLoop = 0; iVictoryLoop < GC.getNumVictoryInfos(); iVictoryLoop++)9153 {9154 VictoryTypes eVictory = static_cast<VictoryTypes>(iVictoryLoop);9155 CvVictoryInfo* pkVictoryInfo = GC.getVictoryInfo(eVictory);9156 if(pkVictoryInfo)9157 {9158 if(pkVictoryInfo->isEndScore())9159 {9160 eScoreVictory = eVictory;9161 break;9162 }9163 }9164 }91659166 aaiGameWinners.clear();91679168 // Find out who is in the lead with VPs9169 int iBestVPNum = 0;9170 int iVPs;9171 for(iTeamLoop = 0; iTeamLoop < MAX_CIV_TEAMS; iTeamLoop++)9172 {9173 iVPs = GET_TEAM((TeamTypes) iTeamLoop).GetScore();91749175 if(iVPs > iBestVPNum)9176 {9177 iBestVPNum = iVPs;9178 }9179 }91809181 // Now that we know what the highest is, see if any players are tied9182 for(iTeamLoop = 0; iTeamLoop < MAX_CIV_TEAMS; iTeamLoop++)9183 {9184 iVPs = GET_TEAM((TeamTypes) iTeamLoop).GetScore();91859186 if(iVPs == iBestVPNum)9187 {9188 std::vector<int> aWinner;9189 aWinner.push_back(iTeamLoop);9190 aWinner.push_back(eScoreVictory);9191 aaiGameWinners.push_back(aWinner);9192 }9193 }9194 }9195 }919691979198 // Two things can set this to true: either someone has finished an insta-win victory, or the game-ending tech has been researched and we're now tallying VPs9199 if(bEndGame && !aaiGameWinners.empty())9200 {9201 int iWinner = getJonRandNum(aaiGameWinners.size(), "Victory tie breaker");9202 CUSTOMLOG("Calling setWinner from testVictory: %i, %i", aaiGameWinners[iWinner][0], aaiGameWinners[iWinner][1]);9203 setWinner(((TeamTypes)aaiGameWinners[iWinner][0]), ((VictoryTypes)aaiGameWinners[iWinner][1]));9204 }92059206 if(getVictory() == NO_VICTORY)9207 {9208 if(getMaxTurns() > 0)9209 {9210 if(getElapsedGameTurns() >= getMaxTurns())9211 {9212 if(!bEndScore)9213 {9214 if((getAIAutoPlay() > 0) || gDLL->GetAutorun())9215 {9216 setGameState(GAMESTATE_EXTENDED);9217 }9218 else9219 {9220 setGameState(GAMESTATE_OVER);9221 }9222 }9223 }9224 }9225 }9226}