Пример #1
0
void CvMapGenerator::addGoodies()
{
	PROFILE_FUNC();

	if (gDLL->getPythonIFace()->pythonAddGoodies() && !gDLL->getPythonIFace()->pythonUsingDefaultImpl())
	{
		return; // Python override
	}

	gDLL->NiTextOut("Adding Goodies...");

	if (GC.getEraInfo(GC.getGameINLINE().getStartEra()).isNoGoodies())
	{
		return;
	}

	int iNumPlots = GC.getMapINLINE().numPlotsINLINE();
	std::vector<int> aiShuffle(iNumPlots);
	GC.getGameINLINE().getMapRand().shuffleSequence(aiShuffle, "addNonUniqueBonusType shuffle");

	for (int iI = 0; iI < GC.getNumImprovementInfos(); iI++)
	{
		if (GC.getImprovementInfo((ImprovementTypes)iI).isGoody() && GC.getImprovementInfo((ImprovementTypes)iI).getTilesPerGoody() > 0)
		{
			for (int iJ = 0; iJ < iNumPlots; iJ++)
			{
				gDLL->callUpdater();
				CvPlot *pPlot = GC.getMapINLINE().plotByIndexINLINE(aiShuffle[iJ]);
				FAssertMsg(pPlot, "pPlot is expected not to be NULL");
				if (!(pPlot->isWater()))
				{
					CvArea *pArea = GC.getMapINLINE().getArea(pPlot->getArea());
					FAssertMsg(pArea, "pArea is expected not to be NULL");
					if (pArea->getNumImprovements((ImprovementTypes)iI) < ((pArea->getNumTiles() + (GC.getImprovementInfo((ImprovementTypes)iI).getTilesPerGoody() / 2)) / GC.getImprovementInfo((ImprovementTypes) iI).getTilesPerGoody()))
					{
						if (canPlaceGoodyAt(((ImprovementTypes)iI), pPlot->getX_INLINE(), pPlot->getY_INLINE()))
						{
							pPlot->setImprovementType((ImprovementTypes)iI);
						}
					}
				}
			}
		}
	}
}
Пример #2
0
void CvPlayerAI::AI_updateFoundValues(bool bStartingLoc)
{
	int iLoop;
	const int iNumPlots = GC.getMap().numPlots();
	for(CvArea *pLoopArea = GC.getMap().firstArea(&iLoop); pLoopArea != NULL; pLoopArea = GC.getMap().nextArea(&iLoop))
	{
		pLoopArea->setTotalFoundValue(0);
	}

	const PlayerTypes eID = GetID();
	if (bStartingLoc)
	{
		for (int iI = 0; iI < iNumPlots; iI++)
		{
			GC.getMap().plotByIndexUnchecked(iI)->setFoundValue(eID, -1);
		}
	}
	else
	{
		const TeamTypes eTeam = getTeam();
		for (int iI = 0; iI < iNumPlots; iI++)
		{
			CvPlot* pLoopPlot = GC.getMap().plotByIndexUnchecked(iI);

			if (pLoopPlot->isRevealed(eTeam))
			{
				const int iValue = AI_foundValue(pLoopPlot->getX(), pLoopPlot->getY());
				pLoopPlot->setFoundValue(eID, iValue);
				CvArea *pLoopArea = GC.getMap().getArea(pLoopPlot->getArea());
				if (pLoopArea && !pLoopArea->isWater())
				{
					pLoopArea->setTotalFoundValue(pLoopArea->getTotalFoundValue() + iValue);
				}
			}
			else
			{
				pLoopPlot->setFoundValue(eID, -1);
			}
		}
	}
}
int CvArea::countCoastalLand() const
{
	if (isWater())
	{
		return 0;
	}

	int iCount = 0;

	for (int iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++)
	{
		CvPlot* pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);

		if (pLoopPlot->getArea() == getID())
		{
			if (pLoopPlot->isCoastalLand())
			{
				iCount++;
			}
		}
	}

	return iCount;
}
/// Add data for this cell into dominance zone information
void CvTacticalAnalysisMap::AddToDominanceZones(int iIndex, CvTacticalAnalysisCell* pCell)
{
	TeamTypes ourTeam = GET_PLAYER(m_ePlayer).getTeam();
	CvPlot* pPlot = GC.getMap().plotByIndex(iIndex);

	// Compute zone data for this cell
	CvTacticalDominanceZone newZone;
	newZone.SetAreaID(pPlot->getArea());
	newZone.SetWater(pPlot->isWater());

	int iCityDistance = GC.getGame().GetClosestCityDistanceInTurns(pPlot);
	CvCity* pCity = GC.getGame().GetClosestCityByEstimatedTurns(pPlot);
	PlayerTypes eOwnerPlayer = NO_PLAYER;
	TeamTypes eOwnerTeam = NO_TEAM;

	//for plots far away from a city, check the owner
	if (iCityDistance>2)
	{
		eOwnerTeam = pPlot->getTeam();
		eOwnerPlayer = pPlot->getOwner();

		//there is almost always a closest city, but we're not always interested
		if (pCity && eOwnerPlayer!=pCity->getOwner())
			pCity = NULL;
	}
	else if (pCity) //look at the city
	{
		eOwnerTeam = pCity->getTeam();
		eOwnerPlayer = pCity->getOwner();
	}

	newZone.SetOwner(eOwnerPlayer);
	newZone.SetZoneCity(pCity);
	newZone.Extend(pPlot);

	if(eOwnerTeam==NO_TEAM)
	{
		newZone.SetTerritoryType(TACTICAL_TERRITORY_NO_OWNER);
	}
	else if(eOwnerTeam == ourTeam)
	{
		newZone.SetTerritoryType(TACTICAL_TERRITORY_FRIENDLY);
	}
	else if(GET_TEAM(ourTeam).isAtWar(eOwnerTeam))
	{
		newZone.SetTerritoryType(TACTICAL_TERRITORY_ENEMY);
	}
	else
	{
		newZone.SetTerritoryType(TACTICAL_TERRITORY_NEUTRAL);
	}

	// Now see if we already have a matching zone
	CvTacticalDominanceZone* pZone = MergeWithExistingZone(&newZone);
	if(!pZone)
	{
		// Data populated, now add to vector
		newZone.SetDominanceZoneID(m_DominanceZones.size());
		m_DominanceZones.push_back(newZone);
		pZone = &m_DominanceZones[m_DominanceZones.size() - 1];
	}

	// Set zone for this cell
	pCell->SetDominanceZone(pZone->GetDominanceZoneID());
	pZone->Extend(pPlot);
}
Пример #5
0
///Tks Med
CvPlot* CvMap::syncRandPlot(int iFlags, int iArea, int iMinUnitDistance, int iTimeout, bool bIgnoreNativeTeams)
{
///TKe
	CvPlot* pPlot = NULL;
	int iCount = 0;

	while (iCount < iTimeout)
	{
		CvPlot* pTestPlot = plotSorenINLINE(GC.getGameINLINE().getSorenRandNum(getGridWidthINLINE(), "Rand Plot Width"), GC.getGameINLINE().getSorenRandNum(getGridHeightINLINE(), "Rand Plot Height"));

		FAssertMsg(pTestPlot != NULL, "TestPlot is not assigned a valid value");

		if ((iArea == -1) || (pTestPlot->getArea() == iArea))
		{
			bool bValid = true;

			if (bValid)
			{
				if (iMinUnitDistance != -1)
				{
					for (int iDX = -(iMinUnitDistance); iDX <= iMinUnitDistance; iDX++)
					{
						for (int iDY = -(iMinUnitDistance); iDY <= iMinUnitDistance; iDY++)
						{
							CvPlot* pLoopPlot = plotXY(pTestPlot->getX_INLINE(), pTestPlot->getY_INLINE(), iDX, iDY);

							if (pLoopPlot != NULL)
							{
								if (pLoopPlot->isUnit())
								{
									bValid = false;
								}
							}
						}
					}
				}
			}

			if (bValid)
			{
				if (iFlags & RANDPLOT_LAND)
				{
					if (pTestPlot->isWater())
					{
						bValid = false;
					}
				}
			}

			if (bValid)
			{
				if (iFlags & RANDPLOT_UNOWNED)
				{
					if (pTestPlot->isOwned())
					{
						///Tks Med
						if (bIgnoreNativeTeams)
						{
							if (!GET_PLAYER(pTestPlot->getOwnerINLINE()).isNative())
							{
								bValid = false;
							}
						}
						else
						{
							bValid = false;
						}
						///TKe
					}
				}
			}

			if (bValid)
			{
				if (iFlags & RANDPLOT_ADJACENT_UNOWNED)
				{
					if (pTestPlot->isAdjacentOwned())
					{
						bValid = false;
					}
				}
			}

			if (bValid)
			{
				if (iFlags & RANDPLOT_ADJACENT_LAND)
				{
					if (!(pTestPlot->isAdjacentToLand()))
					{
						bValid = false;
					}
				}
			}

			if (bValid)
			{
				if (iFlags & RANDPLOT_PASSIBLE)
				{
					if (pTestPlot->isImpassable())
					{
						bValid = false;
					}
				}
			}

			if (bValid)
			{
				if (iFlags & RANDPLOT_NOT_VISIBLE_TO_CIV)
				{
				    ///TKs Med
					if (pTestPlot->isVisibleToCivTeam(bIgnoreNativeTeams))
					{
						bValid = false;
					}
					///TKe
				}
			}
            ///TKs Med
            if (bValid)
			{
				if (bIgnoreNativeTeams)
				{

					if (pTestPlot->isVisibleToWatchingHuman())
					{
						bValid = false;
					}

				}
			}
            ///TKe
			if (bValid)
			{
				if (iFlags & RANDPLOT_NOT_CITY)
				{
					if (pTestPlot->isCity())
					{
						bValid = false;
					}
				}
			}

			if (bValid)
			{
				pPlot = pTestPlot;
				break;
			}
		}

		iCount++;
	}

	return pPlot;
}
/// Add data for this cell into dominance zone information
void CvTacticalAnalysisMap::AddToDominanceZones(int iIndex, CvTacticalAnalysisCell* pCell)
{
	CvPlot* pPlot = GC.getMap().plotByIndex(iIndex);

	// Compute zone data for this cell
	m_TempZone.SetAreaID(pPlot->getArea());
	m_TempZone.SetOwner(pPlot->getOwner());
	m_TempZone.SetWater(pPlot->isWater());
	if(!pPlot->isOwned())
	{
		m_TempZone.SetTerritoryType(TACTICAL_TERRITORY_NO_OWNER);
	}
	else if(pPlot->getTeam() == m_pPlayer->getTeam())
	{
		m_TempZone.SetTerritoryType(TACTICAL_TERRITORY_FRIENDLY);
	}
	else if(GET_TEAM(m_pPlayer->getTeam()).isAtWar(pPlot->getTeam()))
	{
		m_TempZone.SetTerritoryType(TACTICAL_TERRITORY_ENEMY);
	}
	else
	{
		m_TempZone.SetTerritoryType(TACTICAL_TERRITORY_NEUTRAL);
	}
	m_TempZone.SetClosestCity(NULL);
	if(m_TempZone.GetTerritoryType() == TACTICAL_TERRITORY_ENEMY ||
	        m_TempZone.GetTerritoryType() == TACTICAL_TERRITORY_NEUTRAL ||
	        m_TempZone.GetTerritoryType() == TACTICAL_TERRITORY_FRIENDLY)
	{
		int iLoop;
		int iBestDistance = MAX_INT;
		CvCity* pBestCity = NULL;

		for(CvCity* pLoopCity = GET_PLAYER(m_TempZone.GetOwner()).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER(m_TempZone.GetOwner()).nextCity(&iLoop))
		{
			int iDistance = plotDistance(pLoopCity->getX(), pLoopCity->getY(), pPlot->getX(), pPlot->getY());
			if(iDistance < iBestDistance)
			{
				iBestDistance = iDistance;
				pBestCity = pLoopCity;
			}
		}

		if(pBestCity != NULL)
		{
			m_TempZone.SetClosestCity(pBestCity);
		}
	}

	// Now see if we already have a matching zone
	CvTacticalDominanceZone* pZone = FindExistingZone(pPlot);
	if(!pZone)
	{
		// Data populated, now add to vector
		m_TempZone.SetDominanceZoneID(m_DominanceZones.size());
		m_DominanceZones.push_back(m_TempZone);
		pZone = &m_DominanceZones[m_DominanceZones.size() - 1];
	}

	// If this isn't owned territory, update zone with military strength info
	if(pZone->GetTerritoryType() == TACTICAL_TERRITORY_NO_OWNER ||
	        pZone->GetTerritoryType() == TACTICAL_TERRITORY_TEMP_ZONE)
	{
		CvUnit* pFriendlyUnit = pCell->GetFriendlyMilitaryUnit();
		if(pFriendlyUnit)
		{
			if(pFriendlyUnit->getDomainType() == DOMAIN_AIR ||
			        (pFriendlyUnit->getDomainType() == DOMAIN_LAND && !pZone->IsWater()) ||
			        (pFriendlyUnit->getDomainType() == DOMAIN_SEA && pZone->IsWater()))
			{
				int iStrength = pFriendlyUnit->GetBaseCombatStrengthConsideringDamage();
				if(iStrength == 0 && pFriendlyUnit->isEmbarked() && !pZone->IsWater())
				{
					iStrength = pFriendlyUnit->GetBaseCombatStrength(true);
				}
				pZone->AddFriendlyStrength(iStrength * m_iUnitStrengthMultiplier);
				pZone->AddFriendlyRangedStrength(pFriendlyUnit->GetMaxRangedCombatStrength(NULL, /*pCity*/ NULL, true, true));
				if(pFriendlyUnit->GetRange() > GetBestFriendlyRange())
				{
					SetBestFriendlyRange(pFriendlyUnit->GetRange());
				}
				if(pFriendlyUnit->IsRangeAttackIgnoreLOS())
				{
					SetIgnoreLOS(true);
				}
				pZone->AddFriendlyUnitCount(1);
				if(pFriendlyUnit->isRanged())
				{
					pZone->AddFriendlyRangedUnitCount(1);
				}
			}
		}

		CvUnit* pEnemyUnit = pCell->GetEnemyMilitaryUnit();
		if(pEnemyUnit)
		{
			if(pEnemyUnit->getDomainType() == DOMAIN_AIR ||
			        (pEnemyUnit->getDomainType() == DOMAIN_LAND && !pZone->IsWater()) ||
			        (pEnemyUnit->getDomainType() == DOMAIN_SEA && pZone->IsWater()))
			{
				int iStrength = pEnemyUnit->GetBaseCombatStrengthConsideringDamage();
				if(iStrength == 0 && pEnemyUnit->isEmbarked() && !pZone->IsWater())
				{
					iStrength = pEnemyUnit->GetBaseCombatStrength(true);
				}
#if defined(MOD_AI_SMART_V3)
				int iEnemyRangedStrength = pEnemyUnit->GetMaxRangedCombatStrength(NULL, /*pCity*/ NULL, true, true);

				if (MOD_AI_SMART_V3)
				{
					if (!pCell->IsVisible())
					{
						iStrength /= 2;
						iEnemyRangedStrength /= 2;
					}
					
					iEnemyRangedStrength = iEnemyRangedStrength * m_iUnitStrengthMultiplier;
				}
#endif				

				pZone->AddEnemyStrength(iStrength * m_iUnitStrengthMultiplier);
#if defined(MOD_AI_SMART_V3)
				pZone->AddEnemyRangedStrength(iEnemyRangedStrength);
#else
				pZone->AddEnemyRangedStrength(pEnemyUnit->GetMaxRangedCombatStrength(NULL, /*pCity*/ NULL, true, true));
#endif				
				pZone->AddEnemyUnitCount(1);
				if(pEnemyUnit->isRanged())
				{
					pZone->AddEnemyRangedUnitCount(1);
				}
				if (pEnemyUnit->getDomainType() == DOMAIN_SEA)
				{
					pZone->AddEnemyNavalUnitCount(1);
				}
			}
		}
	}

	// Set zone for this cell
	pCell->SetDominanceZone(pZone->GetDominanceZoneID());
}
// Indicate the plots we might want to move to that the enemy can attack
void CvTacticalAnalysisMap::MarkCellsNearEnemy()
{
	int iDistance;

	// Look at every cell on the map
	for(int iI = 0; iI < GC.getMap().numPlots(); iI++)
	{
		bool bMarkedIt = false;   // Set true once we've found one that enemy can move past (worst case)

		CvPlot* pPlot = GC.getMap().plotByIndexUnchecked(iI);
		if(m_pPlots[iI].IsRevealed() && !m_pPlots[iI].IsImpassableTerrain() && !m_pPlots[iI].IsImpassableTerritory())
		{
			// Friendly cities always safe
			if(!m_pPlots[iI].IsFriendlyCity())
			{
				if(!pPlot->isVisibleToEnemyTeam(m_pPlayer->getTeam()))
				{
					m_pPlots[iI].SetNotVisibleToEnemy(true);
				}
				else
				{
					for(unsigned int iUnitIndex = 0;  iUnitIndex < m_EnemyUnits.size() && !bMarkedIt; iUnitIndex++)
					{
						CvUnit* pUnit = m_EnemyUnits[iUnitIndex];
						if(pUnit->getArea() == pPlot->getArea())
						{
							// Distance check before hitting pathfinder
							iDistance = plotDistance(pUnit->getX(), pUnit->getY(), pPlot->getX(), pPlot->getY());
							if(iDistance == 0)
							{
								m_pPlots[iI].SetSubjectToAttack(true);
								m_pPlots[iI].SetEnemyCanMovePast(true);
								bMarkedIt = true;
							}

							// TEMPORARY OPTIMIZATION: Assumes can't use roads or RR
							else if(iDistance <= pUnit->baseMoves())
							{
								int iTurnsToReach;
								iTurnsToReach = TurnsToReachTarget(pUnit, pPlot, true /*bReusePaths*/, true /*bIgnoreUnits*/);	// Its ok to reuse paths because when ignoring units, we don't use the tactical analysis map (which we are building)
								if(iTurnsToReach <= 1)
								{
									m_pPlots[iI].SetSubjectToAttack(true);
								}
								if(iTurnsToReach == 0)
								{
									m_pPlots[iI].SetEnemyCanMovePast(true);
									bMarkedIt = true;
								}
							}
						}
					}

					// Check adjacent plots for enemy citadels
					if(!m_pPlots[iI].IsSubjectToAttack())
					{
						CvPlot* pAdjacentPlot;
						for(int jJ = 0; jJ < NUM_DIRECTION_TYPES; jJ++)
						{
							pAdjacentPlot = plotDirection(pPlot->getX(), pPlot->getY(), ((DirectionTypes)jJ));
							if(pAdjacentPlot != NULL && pAdjacentPlot->getOwner() != NO_PLAYER)
							{
								if(atWar(m_pPlayer->getTeam(), GET_PLAYER(pAdjacentPlot->getOwner()).getTeam()))
								{
									ImprovementTypes eImprovement = pAdjacentPlot->getImprovementType();
									if(eImprovement != NO_IMPROVEMENT && GC.getImprovementInfo(eImprovement)->GetNearbyEnemyDamage() > 0)
									{
										m_pPlots[iI].SetSubjectToAttack(true);
										break;
									}
								}
							}
						}
					}
				}
			}
		}
	}
}