Hooks
static bool BeforeCvPlayerCulture_ThemeBuilding(CvPlayerCulture* self, vector<CvGreatWorkBuildingInMyEmpire>::const_iterator buildingIt, vector<CvGreatWorkInMyEmpire> & works1, vector<CvGreatWorkInMyEmpire> & works2, bool bConsiderOtherPlayers, bool& result);static void AfterCvPlayerCulture_ThemeBuilding(CvPlayerCulture* self, vector<CvGreatWorkBuildingInMyEmpire>::const_iterator buildingIt, vector<CvGreatWorkInMyEmpire> & works1, vector<CvGreatWorkInMyEmpire> & works2, bool bConsiderOtherPlayers, bool& result);static bool ReplaceCvPlayerCulture_ThemeBuilding(bool (*original)(CvPlayerCulture*, vector<CvGreatWorkBuildingInMyEmpire>::const_iterator, vector<CvGreatWorkInMyEmpire> &, vector<CvGreatWorkInMyEmpire> &, bool), CvPlayerCulture* self, vector<CvGreatWorkBuildingInMyEmpire>::const_iterator buildingIt, vector<CvGreatWorkInMyEmpire> & works1, vector<CvGreatWorkInMyEmpire> & works2, bool bConsiderOtherPlayers);CivRegisterBefore<CivHooks::CvPlayerCulture_ThemeBuilding>(host, &BeforeCvPlayerCulture_ThemeBuilding);CivRegisterAfter<CivHooks::CvPlayerCulture_ThemeBuilding>(host, &AfterCvPlayerCulture_ThemeBuilding);CivRegisterReplace<CivHooks::CvPlayerCulture_ThemeBuilding>(host, &ReplaceCvPlayerCulture_ThemeBuilding);
Code
1347/// Uses the available Great Works to fill a building with those works that provide the best Theming Bonus1348bool CvPlayerCulture::ThemeBuilding(vector<CvGreatWorkBuildingInMyEmpire>::const_iterator buildingIt, vector<CvGreatWorkInMyEmpire> &works1, vector<CvGreatWorkInMyEmpire> &works2, bool bConsiderOtherPlayers)1349{1350 CvGameCulture *pkGameCulture = GC.getGame().GetGameCulture();13511352 vector<CvGreatWorkInMyEmpire> worksToConsider;1353 vector<CvGreatWorkInMyEmpire>::const_iterator it;1354 vector<CvGreatWorkInMyEmpire>::const_iterator it2;1355 vector<CvGreatWorkInMyEmpire>::iterator it3;1356 vector<CvGreatWorkInMyEmpire> tempWorks;13571358 vector<int> aWorksChosen;1359 vector<PlayerTypes> aPlayersSeen;1360 vector<EraTypes> aErasSeen;13611362 CvBuildingEntry *pkEntry = GC.getBuildingInfo(buildingIt->m_eBuilding);1363 if (!pkEntry || pkEntry->GetGreatWorkCount() < 2)1364 {1365 return false;1366 }13671368 // Try each of the theming bonuses for this building1369 for (int iI = 0; iI < pkEntry->GetNumThemingBonuses(); iI++)1370 {1371 CvThemingBonusInfo *pkBonusInfo = pkEntry->GetThemingBonusInfo(iI);1372 if (pkBonusInfo->IsMustBeArt())1373 {1374 worksToConsider = works1;1375 }1376 else if (pkBonusInfo->IsMustBeArtifact())1377 {1378 worksToConsider = works2;1379 }1380 // Dedicated routine to handle the equal art/artifact case1381 else if (pkBonusInfo->IsMustBeEqualArtArtifact())1382 {1383 if (ThemeEqualArtArtifact(*buildingIt, iI, pkEntry->GetGreatWorkCount(), works1, works2, bConsiderOtherPlayers))1384 {1385 return true;1386 }1387 }1388 else1389 {1390 worksToConsider = works1;1391 for (it = works2.begin(); it != works2.end(); it++)1392 {1393 worksToConsider.push_back(*it);1394 }1395 }13961397 // If not enough works, try other theming bonuses1398 int iCountSlots = pkEntry->GetGreatWorkCount();1399 if (worksToConsider.size() < (unsigned int)iCountSlots)1400 {1401 continue;1402 }14031404 // Try each of the works as the starter1405 for (it = worksToConsider.begin(); it != worksToConsider.end(); it++)1406 {1407 // First, make sure this "starter" is valid1408 if (pkBonusInfo->IsRequiresOwner() && it->m_ePlayer != m_pPlayer->GetID())1409 {1410 continue;1411 }1412 if (pkBonusInfo->IsRequiresAnyButOwner() && it->m_ePlayer == m_pPlayer->GetID())1413 {1414 continue;1415 }14161417 aWorksChosen.clear();1418 aPlayersSeen.clear();1419 aErasSeen.clear();14201421 aWorksChosen.push_back(it->m_iGreatWorkIndex);1422 aPlayersSeen.push_back(it->m_ePlayer);1423 aErasSeen.push_back(it->m_eEra);14241425 // Loop through the rest looking for works that will match up1426 it2 = it;1427 for (it2++; it2 != worksToConsider.end() && aWorksChosen.size() < (unsigned int)iCountSlots; it2++)1428 {1429 if (CultureHelpers::IsValidForThemingBonus(pkBonusInfo, it2->m_eEra, aErasSeen, it2->m_ePlayer, aPlayersSeen, m_pPlayer->GetID()))1430 {1431 aWorksChosen.push_back(it2->m_iGreatWorkIndex);1432 aPlayersSeen.push_back(it2->m_ePlayer);1433 aErasSeen.push_back(it2->m_eEra);1434 }1435 }14361437 // Did we theme it properly?1438 bool bThemedProperly = false;1439 if (aWorksChosen.size() == iCountSlots && CultureHelpers::GetThemingBonusIndex(m_pPlayer->GetID(), pkEntry, aWorksChosen) == iI)1440 {1441 bThemedProperly = true;1442 }14431444 // If we are one work short, let's look to other players1445 else if (bConsiderOtherPlayers && aWorksChosen.size() == (iCountSlots - 1) && (pkEntry->GetGreatWorkSlotType() != CvTypes::getGREAT_WORK_SLOT_MUSIC()))1446 {1447 for (int iLoopPlayer = 0; iLoopPlayer < MAX_MAJOR_CIVS; iLoopPlayer++)1448 {1449 CvPlayer& kPlayer = GET_PLAYER((PlayerTypes)iLoopPlayer);1450 if (kPlayer.isAlive() && m_pPlayer->GetDiplomacyAI()->IsPlayerValid((PlayerTypes)iLoopPlayer))1451 {1452 int iToBeAcquiredWorkIndex = NO_GREAT_WORK;1453 int iToBeDiscardedWorkIndex = NO_GREAT_WORK;14541455 if (pkEntry->GetGreatWorkSlotType() == CvTypes::getGREAT_WORK_SLOT_ART_ARTIFACT())1456 {1457 if (pkBonusInfo->IsMustBeArt())1458 {1459 iToBeAcquiredWorkIndex = kPlayer.GetCulture()->GetSwappableArtIndex();1460 iToBeDiscardedWorkIndex = CultureHelpers::FindWorkNotChosen(works1, aWorksChosen);1461 }1462 else if (pkBonusInfo->IsMustBeArtifact())1463 {1464 iToBeAcquiredWorkIndex = kPlayer.GetCulture()->GetSwappableArtifactIndex();1465 iToBeDiscardedWorkIndex = CultureHelpers::FindWorkNotChosen(works2, aWorksChosen);1466 }1467 }1468 else1469 {1470 iToBeAcquiredWorkIndex = kPlayer.GetCulture()->GetSwappableWritingIndex();1471 iToBeDiscardedWorkIndex = CultureHelpers::FindWorkNotChosen(works1, aWorksChosen);1472 }14731474 // Does this work fit?1475 if (iToBeAcquiredWorkIndex != NO_GREAT_WORK && iToBeDiscardedWorkIndex != NO_GREAT_WORK)1476 {1477 EraTypes eEra = pkGameCulture->m_CurrentGreatWorks[iToBeAcquiredWorkIndex].m_eEra;1478 PlayerTypes ePlayer = pkGameCulture->GetGreatWorkCreator(iToBeAcquiredWorkIndex);1479 if (CultureHelpers::IsValidForThemingBonus(pkBonusInfo, eEra, aErasSeen, ePlayer, aPlayersSeen, m_pPlayer->GetID()))1480 {1481 aWorksChosen.push_back(iToBeAcquiredWorkIndex);1482 if (CultureHelpers::GetThemingBonusIndex(m_pPlayer->GetID(), pkEntry, aWorksChosen) == iI)1483 {1484 bool bSwapSuccess = pkGameCulture->SwapGreatWorks(m_pPlayer->GetID(), iToBeDiscardedWorkIndex, ePlayer, iToBeAcquiredWorkIndex);1485 if (bSwapSuccess)1486 {1487 bThemedProperly = true;14881489 LogSwapWorks(ePlayer, iToBeDiscardedWorkIndex, iToBeAcquiredWorkIndex);14901491 // Update works list1492 tempWorks.clear();1493 if (!pkBonusInfo->IsMustBeArtifact())1494 {1495 for (it3 = works1.begin(); it3 != works1.end(); it3++)1496 {1497 if (it3->m_iGreatWorkIndex == iToBeDiscardedWorkIndex)1498 {1499 it3->m_iGreatWorkIndex = iToBeAcquiredWorkIndex;1500 GetGreatWorkLocation(it3->m_iGreatWorkIndex, it3->m_iCityID, it3->m_eBuilding, it3->m_iSlot);1501 }1502 tempWorks.push_back(*it3);1503 }1504 works1 = tempWorks;1505 }1506 else1507 {1508 for (it3 = works2.begin(); it3 != works2.end(); it3++)1509 {1510 if (it3->m_iGreatWorkIndex == iToBeDiscardedWorkIndex)1511 {1512 it3->m_iGreatWorkIndex = iToBeAcquiredWorkIndex;1513 GetGreatWorkLocation(it3->m_iGreatWorkIndex, it3->m_iCityID, it3->m_eBuilding, it3->m_iSlot);1514 }1515 tempWorks.push_back(*it3);1516 }1517 works2 = tempWorks;1518 }15191520 CultureHelpers::SendArtSwapNotification(pkEntry->GetGreatWorkSlotType(), pkBonusInfo->IsMustBeArt(), m_pPlayer->GetID(), ePlayer, iToBeDiscardedWorkIndex, iToBeAcquiredWorkIndex);1521 break; // Themed it through acquisition1522 }1523 }1524 }1525 }1526 }1527 }1528 }15291530 if (bThemedProperly)1531 {1532 for (int jJ = 0; jJ < (int)aWorksChosen.size(); jJ++)1533 {1534 for (int kK = 0; kK < (int)worksToConsider.size(); kK++)1535 {1536 if (worksToConsider[kK].m_iGreatWorkIndex == aWorksChosen[jJ])1537 {1538 MoveWorkIntoSlot(worksToConsider[kK], buildingIt->m_iCityID, buildingIt->m_eBuilding, jJ);1539 break;1540 }1541 }1542 }15431544 // Remove these works from those to consider later1545 tempWorks.clear();1546 for (it3 = works1.begin(); it3 != works1.end(); it3++)1547 {1548 // Copy it over if not chosen, updating its location1549 if (find(aWorksChosen.begin(), aWorksChosen.end(), it3->m_iGreatWorkIndex) == aWorksChosen.end())1550 {1551 GetGreatWorkLocation(it3->m_iGreatWorkIndex, it3->m_iCityID, it3->m_eBuilding, it3->m_iSlot);1552 tempWorks.push_back(*it3);1553 }1554 }1555 works1 = tempWorks;15561557 tempWorks.clear();1558 for (it3 = works2.begin(); it3 != works2.end(); it3++)1559 {1560 // Copy it over if not chosen, updating its location1561 if (find(aWorksChosen.begin(), aWorksChosen.end(), it3->m_iGreatWorkIndex) == aWorksChosen.end())1562 {1563 GetGreatWorkLocation(it3->m_iGreatWorkIndex, it3->m_iCityID, it3->m_eBuilding, it3->m_iSlot);1564 tempWorks.push_back(*it3);1565 }1566 }1567 works2 = tempWorks;15681569 // All done1570 LogThemedBuilding(buildingIt->m_iCityID, buildingIt->m_eBuilding, pkBonusInfo->GetBonus());1571 return true;1572 }1573 }1574 }1575 return false;1576}