Hooks
static bool BeforeCvBuilderTaskingAI_AddChopDirectives(CvBuilderTaskingAI* self, CvUnit* pUnit, CvPlot* pPlot, int iMoveTurnsAway);static void AfterCvBuilderTaskingAI_AddChopDirectives(CvBuilderTaskingAI* self, CvUnit* pUnit, CvPlot* pPlot, int iMoveTurnsAway);static void ReplaceCvBuilderTaskingAI_AddChopDirectives(void (*original)(CvBuilderTaskingAI*, CvUnit*, CvPlot*, int), CvBuilderTaskingAI* self, CvUnit* pUnit, CvPlot* pPlot, int iMoveTurnsAway);CivRegisterBefore<CivHooks::CvBuilderTaskingAI_AddChopDirectives>(host, &BeforeCvBuilderTaskingAI_AddChopDirectives);CivRegisterAfter<CivHooks::CvBuilderTaskingAI_AddChopDirectives>(host, &AfterCvBuilderTaskingAI_AddChopDirectives);CivRegisterReplace<CivHooks::CvBuilderTaskingAI_AddChopDirectives>(host, &ReplaceCvBuilderTaskingAI_AddChopDirectives);
Code
1412/// Determines if the builder should "chop" the feature in the tile1413void CvBuilderTaskingAI::AddChopDirectives(CvUnit* pUnit, CvPlot* pPlot, int iMoveTurnsAway)1414{1415 // if it's not within a city radius1416 if(!pPlot->isWithinTeamCityRadius(pUnit->getTeam()))1417 {1418 return;1419 }14201421 if(pPlot->getImprovementType() != NO_IMPROVEMENT)1422 {1423 return;1424 }14251426 if(GET_PLAYER(pUnit->getOwner()).isOption(PLAYEROPTION_LEAVE_FORESTS))1427 {1428 return;1429 }14301431 // check to see if a resource is here. If so, bail out!1432 ResourceTypes eResource = pPlot->getResourceType(m_pPlayer->getTeam());1433 if(eResource != NO_RESOURCE)1434 {1435 return;1436 }14371438 CvCity* pCity = GetWorkingCity(pPlot);1439 if(!pCity)1440 {1441 return;1442 }14431444 if(pCity->GetCityCitizens()->IsWorkingPlot(pPlot))1445 {1446 return;1447 }14481449 FeatureTypes eFeature = pPlot->getFeatureType();1450 if(eFeature == NO_FEATURE)1451 {1452 // no feature in this tile, so bail1453 return;1454 }14551456 // celtic rule: if this is a forest tile next to a city, do not chop the trees1457 if (m_pPlayer->GetPlayerTraits()->IsFaithFromUnimprovedForest())1458 {1459 CvCity* pAdjacentCity = pPlot->GetAdjacentCity();1460 if (pAdjacentCity && pAdjacentCity->getOwner() == m_pPlayer->GetID())1461 {1462 if (eFeature == FEATURE_FOREST)1463 {1464 return;1465 }1466 }1467 }14681469 BuildTypes eChopBuild = NO_BUILD;1470 for(int iBuildIndex = 0; iBuildIndex < GC.getNumBuildInfos(); iBuildIndex++)1471 {1472 BuildTypes eBuild = (BuildTypes)iBuildIndex;1473 CvBuildInfo* pkBuild = GC.getBuildInfo(eBuild);1474 if(NULL != pkBuild && pkBuild->getImprovement() == NO_IMPROVEMENT && pkBuild->isFeatureRemove(eFeature) && pkBuild->getFeatureProduction(eFeature) > 0 && pUnit->canBuild(pPlot, eBuild))1475 {1476 eChopBuild = eBuild;1477 break;1478 }1479 }14801481 if(eChopBuild == NO_BUILD)1482 {1483 // we couldn't find a build that removed the feature without a production benefit1484 return;1485 }14861487 pCity = NULL;1488 int iProduction = pPlot->getFeatureProduction(eChopBuild, pUnit->getOwner(), &pCity);14891490 if(!DoesBuildHelpRush(pUnit, pPlot, eChopBuild))1491 {1492 return;1493 }14941495 int iWeight = GC.getBUILDER_TASKING_BASELINE_REPAIR();1496 //int iTurnsAway = FindTurnsAway(pUnit, pPlot);1497 iWeight = iWeight / (iMoveTurnsAway/*iTurnsAway*/ + 1);1498 iWeight = GetBuildCostWeight(iWeight, pPlot, eChopBuild);1499 int iBuildTimeWeight = GetBuildTimeWeight(pUnit, pPlot, eChopBuild, false, iMoveTurnsAway);1500 iWeight += iBuildTimeWeight;1501 iWeight *= iProduction; // times the amount that the plot produces from the chopping15021503 int iYieldDifferenceWeight = 0;1504 CvFlavorManager* pFlavorManager = m_pPlayer->GetFlavorManager();1505 for(uint ui = 0; ui < NUM_YIELD_TYPES; ui++)1506 {1507 // calculate natural yields1508 int iPreviousYield = pPlot->calculateNatureYield((YieldTypes)ui, m_pPlayer->getTeam());1509 int iNewYield = pPlot->calculateNatureYield((YieldTypes)ui, m_pPlayer->getTeam(), true /*bIgnoreFeature*/);1510 int iDeltaYield = iNewYield - iPreviousYield;15111512 if(iDeltaYield == 0)1513 {1514 continue;1515 }15161517 for(int iFlavorLoop = 0; iFlavorLoop < GC.getNumFlavorTypes(); iFlavorLoop++)1518 {1519 switch(ui)1520 {1521 case YIELD_FOOD:1522 if(GC.getFlavorTypes((FlavorTypes)iFlavorLoop) == "FLAVOR_GROWTH")1523 {1524 iYieldDifferenceWeight += iDeltaYield * pFlavorManager->GetPersonalityIndividualFlavor((FlavorTypes)iFlavorLoop) * GC.getBUILDER_TASKING_PLOT_EVAL_MULTIPLIER_FOOD();1525 }1526 break;1527 case YIELD_PRODUCTION:1528 if(GC.getFlavorTypes((FlavorTypes)iFlavorLoop) == "FLAVOR_PRODUCTION")1529 {1530 iYieldDifferenceWeight += iDeltaYield * pFlavorManager->GetPersonalityIndividualFlavor((FlavorTypes)iFlavorLoop) * GC.getBUILDER_TASKING_PLOT_EVAL_MULTIPLIER_PRODUCTION();1531 }1532 break;1533 case YIELD_GOLD:1534 if(GC.getFlavorTypes((FlavorTypes)iFlavorLoop) == "FLAVOR_GOLD")1535 {1536 iYieldDifferenceWeight += iDeltaYield * pFlavorManager->GetPersonalityIndividualFlavor((FlavorTypes)iFlavorLoop) * GC.getBUILDER_TASKING_PLOT_EVAL_MULTIPLIER_GOLD();1537 }1538 break;1539 case YIELD_SCIENCE:1540 if(GC.getFlavorTypes((FlavorTypes)iFlavorLoop) == "FLAVOR_SCIENCE")1541 {1542 iYieldDifferenceWeight += iDeltaYield * pFlavorManager->GetPersonalityIndividualFlavor((FlavorTypes)iFlavorLoop) * GC.getBUILDER_TASKING_PLOT_EVAL_MULTIPLIER_SCIENCE();1543 }1544 break;1545 case YIELD_CULTURE:1546 if(GC.getFlavorTypes((FlavorTypes)iFlavorLoop) == "FLAVOR_CULTURE")1547 {1548 iYieldDifferenceWeight += iDeltaYield * pFlavorManager->GetPersonalityIndividualFlavor((FlavorTypes)iFlavorLoop) * GC.getBUILDER_TASKING_PLOT_EVAL_MULTIPLIER_CULTURE();1549 }1550 break;1551 case YIELD_FAITH:1552 //if (GC.getFlavorTypes((FlavorTypes)iFlavorLoop) == "FLAVOR_SCIENCE")1553 //{1554 // iYieldDifferenceWeight += iDeltaYield * pFlavorManager->GetPersonalityIndividualFlavor((FlavorTypes)iFlavorLoop) * GC.getBUILDER_TASKING_PLOT_EVAL_MULTIPLIER_SCIENCE();1555 //}1556 break;1557#if defined(MOD_API_UNIFIED_YIELDS_TOURISM)1558 case YIELD_TOURISM:1559 break;1560#endif1561#if defined(MOD_API_UNIFIED_YIELDS_GOLDEN_AGE)1562 case YIELD_GOLDEN_AGE_POINTS:1563 break;1564#endif1565 }1566 }1567 }15681569 // if we are going backwards, bail1570 if(iYieldDifferenceWeight < 0)1571 {1572 return;1573 }15741575 iWeight += iYieldDifferenceWeight;15761577 if (m_pPlayer->GetPlayerTraits()->IsMoveFriendlyWoodsAsRoad() && (eFeature == FEATURE_FOREST || eFeature == FEATURE_JUNGLE))1578 {1579 iWeight = iWeight / 4;1580 }1581 if (m_pPlayer->GetPlayerTraits()->IsFaithFromUnimprovedForest() && eFeature == FEATURE_FOREST)1582 {1583 iWeight = iWeight / 4;1584 }1585 // this doesn't actually help them, but adds some historical flavor1586 if (m_pPlayer->GetPlayerTraits()->IsEmbarkedAllWater() && (eFeature == FEATURE_FOREST || eFeature == FEATURE_JUNGLE))1587 {1588 iWeight = iWeight * 2;1589 }15901591 iWeight = CorrectWeight(iWeight);15921593 if(iWeight > 0)1594 {1595 BuilderDirective directive;1596 directive.m_eDirective = BuilderDirective::CHOP;1597 directive.m_eBuild = eChopBuild;1598 directive.m_eResource = NO_RESOURCE;1599 directive.m_sX = pPlot->getX();1600 directive.m_sY = pPlot->getY();1601 //directive.m_iGoldCost = m_pPlayer->getBuildCost(pPlot, eChopBuild);1602 directive.m_sMoveTurnsAway = iMoveTurnsAway;16031604 if(m_bLogging)1605 {1606 CvString strTemp;1607 strTemp.Format("BuildTimeWeight, %d, Weight, %d", iBuildTimeWeight, iWeight);1608 LogInfo(strTemp, m_pPlayer);1609 }16101611 m_aDirectives.push_back(directive, iWeight);1612 }1613 else1614 {1615 if(m_bLogging)1616 {1617 LogInfo("Add chop directives, Weight is zero!", m_pPlayer);1618 }1619 }1620}