Hooks
static bool BeforeCvTeam_DoDeclareWar(CvTeam* self, PlayerTypes eOriginatingPlayer, bool bAggressor, TeamTypes eTeam, bool bDefensivePact, bool bMinorAllyPact);static void AfterCvTeam_DoDeclareWar(CvTeam* self, PlayerTypes eOriginatingPlayer, bool bAggressor, TeamTypes eTeam, bool bDefensivePact, bool bMinorAllyPact);static void ReplaceCvTeam_DoDeclareWar(void (*original)(CvTeam*, PlayerTypes, bool, TeamTypes, bool, bool), CvTeam* self, PlayerTypes eOriginatingPlayer, bool bAggressor, TeamTypes eTeam, bool bDefensivePact, bool bMinorAllyPact);CivRegisterBefore<CivHooks::CvTeam_DoDeclareWar>(host, &BeforeCvTeam_DoDeclareWar);CivRegisterAfter<CivHooks::CvTeam_DoDeclareWar>(host, &AfterCvTeam_DoDeclareWar);CivRegisterReplace<CivHooks::CvTeam_DoDeclareWar>(host, &ReplaceCvTeam_DoDeclareWar);
Code
1119#if defined(MOD_EVENTS_WAR_AND_PEACE)1120void CvTeam::DoDeclareWar(PlayerTypes eOriginatingPlayer, bool bAggressor, TeamTypes eTeam, bool bDefensivePact, bool bMinorAllyPact)1121#else1122void CvTeam::DoDeclareWar(TeamTypes eTeam, bool bDefensivePact, bool bMinorAllyPact)1123#endif1124{1125 Localization::String locString;1126 int iI;11271128 CvAssertMsg(eTeam != NO_TEAM, "eTeam is not assigned a valid value");1129 CvAssertMsg(eTeam != GetID(), "eTeam is not expected to be equal with GetID()");11301131 if(isAtWar(eTeam))1132 {1133 return;1134 }11351136 CvAssertMsg(eTeam != GetID(), "eTeam is not expected to be equal with GetID()");1137 if(!isBarbarian())1138 {1139 // Since we declared war, all of OUR Defensive Pacts are nullified1140 cancelDefensivePacts();1141 GC.getGame().GetGameTrade()->DoAutoWarPlundering(m_eID, eTeam);1142 GC.getGame().GetGameTrade()->CancelTradeBetweenTeams(m_eID, eTeam);11431144 if (!bDefensivePact)1145 {1146 for(int iAttackingPlayer = 0; iAttackingPlayer < MAX_MAJOR_CIVS; iAttackingPlayer++)1147 {1148 PlayerTypes eAttackingPlayer = (PlayerTypes)iAttackingPlayer;1149 CvPlayerAI& kAttackingPlayer = GET_PLAYER(eAttackingPlayer);1150 if(kAttackingPlayer.isAlive() && kAttackingPlayer.getTeam() == GetID())1151 {1152 for (int iDefendingPlayer = 0; iDefendingPlayer < MAX_MAJOR_CIVS; iDefendingPlayer++)1153 {1154 PlayerTypes eDefendingPlayer = (PlayerTypes)iDefendingPlayer;1155 CvPlayerAI& kDefendingPlayer = GET_PLAYER(eDefendingPlayer);1156 if(kDefendingPlayer.isAlive() && kDefendingPlayer.getTeam() == eTeam)1157 {1158 // Forget any of that liberation crud!1159 int iNumCitiesLiberated = kDefendingPlayer.GetDiplomacyAI()->GetNumCitiesLiberated(eAttackingPlayer);1160 kDefendingPlayer.GetDiplomacyAI()->ChangeNumCitiesLiberated(eAttackingPlayer, -iNumCitiesLiberated);11611162#if defined(MOD_DIPLOMACY_AUTO_DENOUNCE)1163 if (MOD_DIPLOMACY_AUTO_DENOUNCE && kAttackingPlayer.isHuman() && !kDefendingPlayer.isHuman())1164 {1165 CvDiplomacyAI* pDiplomacy = kAttackingPlayer.GetDiplomacyAI();11661167 if (!pDiplomacy->IsDenouncedPlayer(eDefendingPlayer)) {1168 pDiplomacy->DoDenouncePlayer(eDefendingPlayer);1169 }1170 }1171#endif1172 }1173 }1174 }1175 }1176 }11771178 // Auto War for Defensive Pacts1179 for(iI = 0; iI < MAX_TEAMS; iI++)1180 {1181 if(GET_TEAM((TeamTypes)iI).isAlive())1182 {1183 if(GET_TEAM((TeamTypes)iI).IsHasDefensivePact(eTeam))1184 {1185#if defined(MOD_EVENTS_WAR_AND_PEACE)1186 GET_TEAM((TeamTypes)iI).DoDeclareWar(eOriginatingPlayer, !bAggressor, GetID(), /*bDefensivePact*/ true);1187#else1188 GET_TEAM((TeamTypes)iI).DoDeclareWar(GetID(), /*bDefensivePact*/ true);1189#endif1190 }1191 }1192 }1193 }11941195 // Cancel Trade Deals, RAs, diplomats1196 if(!isBarbarian())1197 {1198 GC.getGame().GetGameDeals()->DoCancelDealsBetweenTeams(GetID(), eTeam);1199 CloseEmbassyAtTeam(eTeam);1200 GET_TEAM(eTeam).CloseEmbassyAtTeam(m_eID);1201 CancelResearchAgreement(eTeam);1202 GET_TEAM(eTeam).CancelResearchAgreement(m_eID);1203 EvacuateDiplomatsAtTeam(eTeam);1204 GET_TEAM(eTeam).EvacuateDiplomatsAtTeam(m_eID);1205 }12061207#if !defined(MOD_GLOBAL_STACKING_RULES)1208 // Bump Units out of places they shouldn't be1209 GC.getMap().verifyUnitValidPlot();1210#endif12111212#if defined(MOD_EVENTS_WAR_AND_PEACE)1213 setAtWar(eTeam, true, bAggressor);1214 GET_TEAM(eTeam).setAtWar(GetID(), true, !bAggressor);1215#else1216 setAtWar(eTeam, true);1217 GET_TEAM(eTeam).setAtWar(GetID(), true);1218#endif12191220#if defined(MOD_GLOBAL_STACKING_RULES)1221 // Bump Units out of places they shouldn't be1222 GC.getMap().verifyUnitValidPlot();1223#endif12241225#if defined(MOD_GLOBAL_EARLY_COOP_WAR_LOCK)1226 /*1227 * There is an interesting edge case. If player A agrees to a co-op war in X turns with B against C,1228 * and then immediately declares war on C, A can make peace with C before the X turn limit.1229 * When B shows up after X turns to start the war, A can agree and, despite having a peace treaty with C, will immediately declare war!1230 *1231 * The simple fix for this is to lock player A into war for at least X turns, if any co-op war agreements include A warring against C1232 */1233 if (MOD_GLOBAL_EARLY_COOP_WAR_LOCK)1234 {1235 for (int iCoopPlayer = 0; iCoopPlayer < MAX_MAJOR_CIVS; iCoopPlayer++)1236 {1237 CvPlayer& kCoopPlayer = GET_PLAYER((PlayerTypes)iCoopPlayer);1238 TeamTypes eCoopTeam = kCoopPlayer.getTeam();12391240 if (kCoopPlayer.isAlive() && eCoopTeam != m_eID && eCoopTeam != eTeam)1241 {1242 for (int iTheirPlayer = 0; iTheirPlayer < MAX_MAJOR_CIVS; iTheirPlayer++)1243 {1244 if (GET_PLAYER((PlayerTypes)iTheirPlayer).getTeam() == eTeam)1245 {1246 for (int iMyPlayer = 0; iMyPlayer < MAX_MAJOR_CIVS; iMyPlayer++)1247 {1248 if (GET_PLAYER((PlayerTypes)iMyPlayer).getTeam() == m_eID)1249 {1250 if (kCoopPlayer.GetDiplomacyAI()->GetCoopWarAcceptedState((PlayerTypes)iMyPlayer, (PlayerTypes)iTheirPlayer) == COOP_WAR_STATE_SOON)1251 {1252 CUSTOMLOG("Locking team %i into a co-op war against team %i - early start to agreement between player %i with player %i", m_eID, eTeam, iMyPlayer, iCoopPlayer);1253 ChangeNumTurnsLockedIntoWar(eTeam, GC.getCOOP_WAR_LOCKED_LENGTH());1254 goto done; // Cannot use break here, as we need to exit from three loops1255 }1256 }1257 }1258 }1259 }1260 }1261 }1262 1263 done: __noop;1264 }1265#endif12661267#if defined(MOD_EVENTS_WAR_AND_PEACE)1268 if (MOD_EVENTS_WAR_AND_PEACE) {1269 GAMEEVENTINVOKE_HOOK(GAMEEVENT_DeclareWar, eOriginatingPlayer, eTeam, bAggressor);1270 } else {1271#endif1272 ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();1273 if (pkScriptSystem)1274 {1275 CvLuaArgsHandle args;1276 args->Push(GetID());1277 args->Push(eTeam);12781279 bool bResult;1280 LuaSupport::CallHook(pkScriptSystem, "DeclareWar", args.get(), bResult);1281 }1282#if defined(MOD_EVENTS_WAR_AND_PEACE)1283 }1284#endif12851286 // One shot things1287 DoNowAtWarOrPeace(eTeam, true);1288 GET_TEAM(eTeam).DoNowAtWarOrPeace(GetID(), true);12891290 // Meet the team if we haven't already1291 meet(eTeam, false);12921293 // Update the ATTACKED players' Diplo AI1294 if(!isBarbarian())1295 {1296 for(iI = 0; iI < MAX_CIV_PLAYERS; iI++)1297 {1298 CvPlayerAI& kPlayer = GET_PLAYER((PlayerTypes)iI);1299 if(kPlayer.isAlive() && kPlayer.getTeam() == eTeam)1300 kPlayer.GetDiplomacyAI()->DoSomeoneDeclaredWarOnMe(GetID());1301 }13021303 // If we've made a peace treaty before, this is bad news (no minors though)1304 if(!GET_TEAM(eTeam).isMinorCiv())1305 {1306 int iPeaceTreatyTurn = GetTurnMadePeaceTreatyWithTeam(eTeam);1307 if(iPeaceTreatyTurn != -1)1308 {1309 int iTurnsSincePeace = GC.getGame().getElapsedGameTurns() - iPeaceTreatyTurn;1310 if (iTurnsSincePeace < GC.getPEACE_TREATY_LENGTH())1311 {1312 SetHasBrokenPeaceTreaty(true);1313 }1314 }1315 }1316 }13171318 // Update interface stuff1319 if((GetID() == GC.getGame().getActiveTeam()) || (eTeam == GC.getGame().getActiveTeam()))1320 {1321 DLLUI->setDirty(Score_DIRTY_BIT, true);1322 DLLUI->setDirty(CityInfo_DIRTY_BIT, true);1323 }13241325 if(GC.getGame().isFinalInitialized())1326 {1327 // Message everyone about what happened1328 if(!isBarbarian() && !(GET_TEAM(eTeam).isBarbarian()))1329 {1330 {1331 PlayerTypes ePlayer;1332 for(iI = 0; iI < MAX_PLAYERS; iI++)1333 {1334 ePlayer = (PlayerTypes) iI;13351336 if(GET_PLAYER(ePlayer).isAlive() && GET_PLAYER(ePlayer).GetNotifications())1337 {1338 // If this declaration is a minor following a major's declaration, don't send out these individual notifications1339 if(!bMinorAllyPact)1340 {1341 // Players on team that declared1342 if(GET_PLAYER(ePlayer).getTeam() == GetID())1343 {1344 if(ePlayer == GC.getGame().getActivePlayer())1345 {1346 locString = Localization::Lookup("TXT_KEY_MISC_YOU_DECLARED_WAR_ON");1347 locString << GET_TEAM(eTeam).getName().GetCString();1348 DLLUI->AddMessage(0, (ePlayer), true, GC.getEVENT_MESSAGE_TIME(), locString.toUTF8()/*, "AS2D_DECLAREWAR", MESSAGE_TYPE_MAJOR_EVENT, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_WARNING_TEXT")*/);1349 }1350 }1351 // Players on team that got declared on1352 else if(GET_PLAYER(ePlayer).getTeam() == eTeam)1353 {1354 locString = Localization::Lookup("TXT_KEY_MISC_DECLARED_WAR_ON_YOU");1355 locString << getName().GetCString();1356 GET_PLAYER(ePlayer).GetNotifications()->Add(NOTIFICATION_WAR_ACTIVE_PLAYER, locString.toUTF8(), locString.toUTF8(), -1, -1, this->getLeaderID());1357 }1358 // Players that are on neither team, but know both parties1359 else if(GET_TEAM(GET_PLAYER(ePlayer).getTeam()).isHasMet(GetID()) && GET_TEAM(GET_PLAYER(ePlayer).getTeam()).isHasMet(eTeam))1360 {1361 locString = Localization::Lookup("TXT_KEY_MISC_SOMEONE_DECLARED_WAR");1362 locString << getName().GetCString() << GET_TEAM(eTeam).getName().GetCString();1363 GET_PLAYER(ePlayer).GetNotifications()->Add(NOTIFICATION_WAR, locString.toUTF8(), locString.toUTF8(), -1, -1, this->getLeaderID(), eTeam);1364 }1365 }1366 }1367 }1368 }13691370 locString = Localization::Lookup("TXT_KEY_MISC_SOMEONE_DECLARES_WAR");1371 locString << getName().GetCString() << GET_TEAM(eTeam).getName().GetCString();1372 GC.getGame().addReplayMessage(REPLAY_MESSAGE_MAJOR_EVENT, getLeaderID(), locString.toUTF8(), -1, -1);1373 }1374 }13751376 int iMinorCivLoop;1377 int iMajorCivLoop;13781379 // Minor Civs declaring war1380 if(isMinorCiv())1381 {13821383 }1384 // Major is declaring War1385 else1386 {1387 int iMajorCivLoop2;13881389 // Update what every Major Civ sees1390 for(iMajorCivLoop = 0; iMajorCivLoop < MAX_MAJOR_CIVS; iMajorCivLoop++)1391 {1392 if(GET_PLAYER((PlayerTypes) iMajorCivLoop).getTeam() == GetID())1393 {1394 if(GET_PLAYER((PlayerTypes) iMajorCivLoop).isAlive())1395 {1396 // Alter Grand Strategy stats for all Majors in the game whove met this declaring war Major1397 for(iMajorCivLoop2 = 0; iMajorCivLoop2 < MAX_MAJOR_CIVS; iMajorCivLoop2++)1398 {1399 // I don't care if it's me1400 if(iMajorCivLoop != iMajorCivLoop2)1401 {1402 // Have I actually met this player declaring war?1403 if(GET_TEAM(GET_PLAYER((PlayerTypes) iMajorCivLoop2).getTeam()).isHasMet(GET_PLAYER((PlayerTypes) iMajorCivLoop).getTeam()))1404 {1405 GET_PLAYER((PlayerTypes) iMajorCivLoop2).GetDiplomacyAI()->DoPlayerDeclaredWarOnSomeone((PlayerTypes) iMajorCivLoop, eTeam);14061407 if(!bDefensivePact)1408 {1409 // Major declaring war on Minor1410 if(GET_TEAM(eTeam).isMinorCiv())1411 {1412 GET_PLAYER((PlayerTypes) iMajorCivLoop2).GetDiplomacyAI()->ChangeOtherPlayerNumMinorsAttacked((PlayerTypes) iMajorCivLoop, 1);1413 }1414 // Major declaring war on Major1415 else1416 {1417 GET_PLAYER((PlayerTypes) iMajorCivLoop2).GetDiplomacyAI()->ChangeOtherPlayerNumMajorsAttacked((PlayerTypes) iMajorCivLoop, 1, eTeam);1418 }1419 }1420 }1421 }1422 }14231424 // Declaring war on Minor1425 for(iMinorCivLoop = MAX_MAJOR_CIVS; iMinorCivLoop < MAX_CIV_PLAYERS; iMinorCivLoop++)1426 {1427 // Now loop through all players on this team to nullify Quests for them1428 if(GET_PLAYER((PlayerTypes) iMinorCivLoop).getTeam() == eTeam)1429 {1430 if(GET_PLAYER((PlayerTypes) iMinorCivLoop).isAlive())1431 {1432 // Increment # of Minors this player has attacked - note that this will be called EACH time a team declares war on a Minor,1433 // even the same Minor multiple times. The current design assumes that once a player is at war with a Minor it's forever, so this is fine1434 //antonjs: consider: this statement is no longer valid, since current design allows peace to be made; update the implementation1435 if(!isMinorCiv() && !bDefensivePact)1436 {1437 ChangeNumMinorCivsAttacked(1);14381439 GET_PLAYER((PlayerTypes) iMinorCivLoop).GetMinorCivAI()->DoTeamDeclaredWarOnMe(GetID());1440 }1441 }1442 }1443 }1444 }1445 }1446 }1447 }1448}