CvPlot* CvArmyAI::CheckTargetReached(PlayerTypes eEnemy, bool bNavalOp, int iMaxDistance)
{
	//check if we're at the target
	CvPlot *pTargetPlot = GetGoalPlot();
	CvPlot *pCenterOfMass = GetCenterOfMass(NO_DOMAIN);
	if(pCenterOfMass && pTargetPlot && plotDistance(*pCenterOfMass,*pTargetPlot) <= iMaxDistance)
		return pTargetPlot;

	//check early termination if we ran into the enemy
	if(GetArmyAIState() == ARMYAISTATE_MOVING_TO_DESTINATION)
	{
		CvPlot*	pEnemyPlot = DetectNearbyEnemy(eEnemy, bNavalOp);
		if(pEnemyPlot != NULL)
		{
			CvCity* pCity = pEnemyPlot->getWorkingCity();
			if(pCity != NULL)
			{
				if (bNavalOp && pCity->isCoastal() && pCity->waterArea()==pTargetPlot->area())
					pEnemyPlot = pCity->plot();

				if (!bNavalOp && pCity->area()==pTargetPlot->area())
					pEnemyPlot = pCity->plot();

				if (pEnemyPlot!=GetGoalPlot())
				{
					if(GC.getLogging() && GC.getAILogging())
					{
						CvString strMsg;
						strMsg.Format("Switching target from %d,%d to closest city at %d,%d", GetGoalX(), GetGoalY(), pEnemyPlot->getX(), pEnemyPlot->getY() );
						GET_PLAYER(m_eOwner).getAIOperation(m_iOperationID)->LogOperationSpecialMessage(strMsg);
					}
				}

				return pEnemyPlot;
			}
		}
	}

	return NULL;
}
示例#2
0
CvCity* CvMap::findTraderCity(int iX, int iY, PlayerTypes eOwner, TeamTypes eTeam, bool bSameArea, bool bCoastalOnly, bool bNative, YieldTypes eNativeYield, int iMinAttitude, CvUnit* pUnit, bool bRandom)
{
	int iBestValue = MAX_INT;
	CvCity* pBestCity = NULL;
	CvCity* pHomeCity = NULL;
	if (pUnit != NULL)
    {
        pHomeCity = pUnit->getHomeCity();
        if (pHomeCity == NULL)
        {
            return NULL;
        }
    }
    std::vector<CvCity*> aCitys;
	for (int iI = 0; iI < MAX_PLAYERS; iI++)
	{
		if (GET_PLAYER((PlayerTypes)iI).isAlive() && (!bNative || GET_PLAYER((PlayerTypes)iI).isNative()))
		{
			if ((eOwner == NO_PLAYER) || (eOwner != NO_PLAYER && (GET_PLAYER(eOwner).isNative() != GET_PLAYER((PlayerTypes)iI).isNative())))
			{
				if ((eTeam == NO_TEAM) || GET_TEAM(GET_PLAYER((PlayerTypes)iI).getTeam()).isOpenBorders(eTeam))
				{
					int iLoop;
					for (CvCity* pLoopCity = GET_PLAYER((PlayerTypes)iI).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER((PlayerTypes)iI).nextCity(&iLoop))
					{
					    int iNativeCityPathTurns;
					    if (pUnit == NULL || pUnit->generatePath(pLoopCity->plot(), 0, true, &iNativeCityPathTurns))
					    {
                            if (!bSameArea || (pLoopCity->area() == plotINLINE(iX, iY)->area()) || (bCoastalOnly && (pLoopCity->waterArea() == plotINLINE(iX, iY)->area())))
                            {
                                if (!bCoastalOnly || pLoopCity->isCoastal(GC.getMIN_WATER_SIZE_FOR_OCEAN()))
                                {
                                    //if(!bNative || pLoopCity->isNative())
                                   //{
                                        if (eNativeYield == NO_YIELD || (iMinAttitude <= 0 && pLoopCity->AI_getDesiredYield() == eNativeYield) || (pLoopCity->isHuman() && pLoopCity->isImport(eNativeYield)))
                                        {
                                            int iValue = plotDistance(iX, iY, pLoopCity->getX_INLINE(), pLoopCity->getY_INLINE());
                                            if ((iValue <= iMinAttitude) || iMinAttitude <= 0)
                                            {

                                                if (!bRandom)
                                                {

                                                    if (iValue < iBestValue)
                                                    {
                                                        iBestValue = iValue;
                                                        pBestCity = pLoopCity;
                                                    }
                                                }
                                                else
                                                {
                                                    aCitys.push_back(pLoopCity);
                                                }
                                            }
                                        }
                                    //}
                                }
                            }
					    }
					}
				}
			}
		}
	}
    if (bRandom)
    {
        int iRandom = aCitys.size();

        if (iRandom >= 1)
        {
            iRandom = GC.getGameINLINE().getSorenRandNum(iRandom, "Random Find City");
            return aCitys[iRandom];
        }
        else
        {
            return NULL;
        }

    }

    return pBestCity;
}
示例#3
0
///TKs Med
CvCity* CvMap::findCity(int iX, int iY, PlayerTypes eOwner, TeamTypes eTeam, bool bSameArea, bool bCoastalOnly, TeamTypes eTeamAtWarWith, DirectionTypes eDirection, CvCity* pSkipCity, bool bRandom)
{
	int iBestValue = MAX_INT;
	CvCity* pBestCity = NULL;
    std::vector<CvCity*> aCitys;
	for (int iI = 0; iI < MAX_PLAYERS; iI++)
	{
		if (GET_PLAYER((PlayerTypes)iI).isAlive())
		{
			if ((eOwner == NO_PLAYER) || (iI == eOwner))
			{
				if ((eTeam == NO_TEAM) || (GET_PLAYER((PlayerTypes)iI).getTeam() == eTeam))
				{
					int iLoop;
					for (CvCity* pLoopCity = GET_PLAYER((PlayerTypes)iI).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER((PlayerTypes)iI).nextCity(&iLoop))
					{
						if (!bSameArea || (pLoopCity->area() == plotINLINE(iX, iY)->area()) || (bCoastalOnly && (pLoopCity->waterArea() == plotINLINE(iX, iY)->area())))
						{
							if (!bCoastalOnly || pLoopCity->isCoastal(GC.getMIN_WATER_SIZE_FOR_OCEAN()))
							{
								if ((eTeamAtWarWith == NO_TEAM) || atWar(GET_PLAYER((PlayerTypes)iI).getTeam(), eTeamAtWarWith))
								{
									if ((eDirection == NO_DIRECTION) || (estimateDirection(dxWrap(pLoopCity->getX_INLINE() - iX), dyWrap(pLoopCity->getY_INLINE() - iY)) == eDirection))
									{
										if ((pSkipCity == NULL) || (pLoopCity != pSkipCity))
										{
										    if (!bRandom)
										    {
                                                int iValue = plotDistance(iX, iY, pLoopCity->getX_INLINE(), pLoopCity->getY_INLINE());

                                                if (iValue < iBestValue)
                                                {
                                                    iBestValue = iValue;
                                                    pBestCity = pLoopCity;
                                                }
										    }
										    else
										    {
										        aCitys.push_back(pLoopCity);
										    }
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
    if (bRandom)
    {
        int iRandom = aCitys.size();

        if (iRandom >= 1)
        {
            iRandom = GC.getGameINLINE().getSorenRandNum(iRandom, "Random Find City");
            return aCitys[iRandom];
        }
        else
        {
            return NULL;
        }

    }

    return pBestCity;
}
示例#4
0
        bool operator() (const UnitInfo::BaseNode& node) const
        {
#ifdef ALTAI_DEBUG
            //std::ostream& os = CivLog::getLog(*player_.getCvPlayer())->getStream();
#endif
            // includes great people
            if (node.cost < 0)
            {
                // do great people if city can produce the right type of great people points from specialists
                return false;
            }

            for (size_t i = 0, count = node.techTypes.size(); i < count; ++i)
            {
                // if we don't we have the tech and its depth is deeper than our lookaheadDepth, return false
                if (!civHelper_->hasTech(node.techTypes[i]) &&
                    (lookaheadDepth_ == 0 || pAnalysis_->getTechResearchDepth(node.techTypes[i]) > lookaheadDepth_))
                {
                    return false;
                }
            }

            for (size_t i = 0, count = node.nodes.size(); i < count; ++i)
            {
                if (!boost::apply_visitor(*this, node.nodes[i]))
                {
                    return false;
                }
            }

            if (node.specialUnitType != NO_SPECIALUNIT)
            {
                if (!gGlobals.getGame().isSpecialUnitValid(node.specialUnitType))
                {
                    return false;
                }
            }

            // todo - add religion and any other checks
            bool passedAreaCheck = node.minAreaSize < 0, passedBonusCheck = ignoreRequiredResources_ || (node.andBonusTypes.empty() && node.orBonusTypes.empty());
            bool passedBuildingCheck = node.prereqBuildingType == NO_BUILDING;

            if (!passedBuildingCheck)
            {
                SpecialBuildingTypes specialBuildingType = (SpecialBuildingTypes)gGlobals.getBuildingInfo(node.prereqBuildingType).getSpecialBuildingType();
                if (specialBuildingType != NO_SPECIALBUILDING)
                {
                    passedBuildingCheck = player_.getCivHelper()->getSpecialBuildingNotRequiredCount(specialBuildingType) > 0;
                }
            }
#ifdef ALTAI_DEBUG
            //os << "\narea check = " << passedAreaCheck << ", bonus check = " << passedBonusCheck << ", building check = " << passedBuildingCheck;
#endif

            CityIter cityIter(*player_.getCvPlayer());
            CvCity* pCity;

            while (pCity = cityIter())
            {
                if (!passedAreaCheck)
                {
                    if (node.domainType == DOMAIN_SEA)
                    {
                        if (pCity->isCoastal(node.minAreaSize))
                        {
                            passedAreaCheck = true;
                        }
                    }
                    else if (node.domainType == DOMAIN_LAND)
                    {
                        if (pCity->area()->getNumTiles() >= node.minAreaSize)
                        {
                            passedAreaCheck = true;
                        }
                    }
                }

                if (!passedBonusCheck)
                {
                    bool foundAllAndBonuses = true, foundOrBonus = node.orBonusTypes.empty();
                    for (size_t i = 0, count = node.andBonusTypes.size(); i < count; ++i)
                    {
                        if (!pCity->hasBonus(node.andBonusTypes[i]))
                        {
                            foundAllAndBonuses = false;
                            break;
                        }
                    }

                    if (foundAllAndBonuses)
                    {
                        for (size_t i = 0, count = node.orBonusTypes.size(); i < count; ++i)
                        {
                            if (pCity->hasBonus(node.orBonusTypes[i]))
                            {
                                foundOrBonus = true;
                                break;
                            }
                        }

                        if (foundOrBonus)
                        {
                            passedBonusCheck = true;
                        }
                    }
                }

                if (!passedBuildingCheck)
                {
                    passedBuildingCheck = pCity->getNumBuilding(node.prereqBuildingType) > 0;
                }
            }
            return passedAreaCheck && passedBonusCheck && passedBuildingCheck;
        }