// -------------------------------------------------------------------------------- bool CvUnitMovement::IsSlowedByZOC(const CvUnit* pUnit, const CvPlot* pFromPlot, const CvPlot* pToPlot) { if (pUnit->IsIgnoreZOC()) return false; // Zone of Control if(GC.getZONE_OF_CONTROL_ENABLED() <= 0) return false; TeamTypes eUnitTeam = pUnit->getTeam(); DomainTypes eUnitDomain = pUnit->getDomainType(); CvTeam& kUnitTeam = GET_TEAM(eUnitTeam); //there are only two plots we need to check DirectionTypes moveDir = directionXY(pFromPlot,pToPlot); int eRight = (int(moveDir) + 1) % 6; int eLeft = (int(moveDir) + 5) % 6; CvPlot* aPlotsToCheck[2]; aPlotsToCheck[0] = plotDirection(pFromPlot->getX(),pFromPlot->getY(),(DirectionTypes)eRight); aPlotsToCheck[1] = plotDirection(pFromPlot->getX(),pFromPlot->getY(),(DirectionTypes)eLeft); for (int iCount=0; iCount<2; iCount++) { CvPlot* pAdjPlot = aPlotsToCheck[iCount]; if(!pAdjPlot) continue; // check city zone of control if(pAdjPlot->isEnemyCity(*pUnit)) return true; // Loop through all units to see if there's an enemy unit here IDInfo* pAdjUnitNode = pAdjPlot->headUnitNode(); while(pAdjUnitNode != NULL) { CvUnit* pLoopUnit = NULL; if((pAdjUnitNode->eOwner >= 0) && pAdjUnitNode->eOwner < MAX_PLAYERS) pLoopUnit = (GET_PLAYER(pAdjUnitNode->eOwner).getUnit(pAdjUnitNode->iID)); pAdjUnitNode = pAdjPlot->nextUnitNode(pAdjUnitNode); if(!pLoopUnit) continue; if(pLoopUnit->isInvisible(eUnitTeam,false)) continue; // Combat unit? if(!pLoopUnit->IsCombatUnit()) continue; // Embarked units don't have ZOC if(pLoopUnit->isEmbarked()) continue; // At war with this unit's team? TeamTypes eLoopUnitTeam = pLoopUnit->getTeam(); if(eLoopUnitTeam == BARBARIAN_TEAM || kUnitTeam.isAtWar(eLoopUnitTeam) || pLoopUnit->isAlwaysHostile(*pAdjPlot) ) { // Same Domain? DomainTypes eLoopUnitDomain = pLoopUnit->getDomainType(); if(eLoopUnitDomain != eUnitDomain) { // hovering units always exert a ZOC if (pLoopUnit->IsHoveringUnit() || eLoopUnitDomain==DOMAIN_HOVER) { // continue on } // water unit can ZoC embarked land unit else if(eLoopUnitDomain == DOMAIN_SEA && (pToPlot->needsEmbarkation(pUnit) || pFromPlot->needsEmbarkation(pUnit)) ) { // continue on } else { // ignore this unit continue; } } else { //land units don't ZoC embarked units (if they stay embarked) if(eLoopUnitDomain == DOMAIN_LAND && pToPlot->needsEmbarkation(pUnit) && pFromPlot->needsEmbarkation(pUnit)) { continue; } } //ok, all conditions fulfilled return true; } } } return false; }
// -------------------------------------------------------------------------------- bool CvUnitMovement::IsSlowedByZOC(const CvUnit* pUnit, const CvPlot* pFromPlot, const CvPlot* pToPlot) { if (pUnit->IsIgnoreZOC() || CostsOnlyOne(pUnit, pFromPlot, pToPlot)) { return false; } // Zone of Control if(GC.getZONE_OF_CONTROL_ENABLED() > 0) { IDInfo* pAdjUnitNode; CvUnit* pLoopUnit; int iFromPlotX = pFromPlot->getX(); int iFromPlotY = pFromPlot->getY(); int iToPlotX = pToPlot->getX(); int iToPlotY = pToPlot->getY(); TeamTypes unit_team_type = pUnit->getTeam(); DomainTypes unit_domain_type = pUnit->getDomainType(); bool bIsVisibleEnemyUnit = pToPlot->isVisibleEnemyUnit(pUnit); CvTeam& kUnitTeam = GET_TEAM(unit_team_type); for(int iDirection0 = 0; iDirection0 < NUM_DIRECTION_TYPES; iDirection0++) { CvPlot* pAdjPlot = plotDirection(iFromPlotX, iFromPlotY, ((DirectionTypes)iDirection0)); if(NULL != pAdjPlot) { // check city zone of control if(pAdjPlot->isEnemyCity(*pUnit)) { // Loop through plots adjacent to the enemy city and see if it's the same as our unit's Destination Plot for(int iDirection = 0; iDirection < NUM_DIRECTION_TYPES; iDirection++) { CvPlot* pEnemyAdjPlot = plotDirection(pAdjPlot->getX(), pAdjPlot->getY(), ((DirectionTypes)iDirection)); if(NULL != pEnemyAdjPlot) { // Destination adjacent to enemy city? if(pEnemyAdjPlot->getX() == iToPlotX && pEnemyAdjPlot->getY() == iToPlotY) { return true; } } } } pAdjUnitNode = pAdjPlot->headUnitNode(); // Loop through all units to see if there's an enemy unit here while(pAdjUnitNode != NULL) { if((pAdjUnitNode->eOwner >= 0) && pAdjUnitNode->eOwner < MAX_PLAYERS) { pLoopUnit = (GET_PLAYER(pAdjUnitNode->eOwner).getUnit(pAdjUnitNode->iID)); } else { pLoopUnit = NULL; } pAdjUnitNode = pAdjPlot->nextUnitNode(pAdjUnitNode); if(!pLoopUnit) continue; TeamTypes unit_loop_team_type = pLoopUnit->getTeam(); if(pLoopUnit->isInvisible(unit_team_type,false)) continue; // Combat unit? if(!pLoopUnit->IsCombatUnit()) { continue; } // At war with this unit's team? if(unit_loop_team_type == BARBARIAN_TEAM || kUnitTeam.isAtWar(unit_loop_team_type)) { // Same Domain? DomainTypes loop_unit_domain_type = pLoopUnit->getDomainType(); if(loop_unit_domain_type != unit_domain_type) { // this is valid if(loop_unit_domain_type == DOMAIN_SEA && unit_domain_type) { // continue on } else { continue; } } // Embarked? if(unit_domain_type == DOMAIN_LAND && pLoopUnit->isEmbarked()) { continue; } // Loop through plots adjacent to the enemy unit and see if it's the same as our unit's Destination Plot for(int iDirection2 = 0; iDirection2 < NUM_DIRECTION_TYPES; iDirection2++) { CvPlot* pEnemyAdjPlot = plotDirection(pAdjPlot->getX(), pAdjPlot->getY(), ((DirectionTypes)iDirection2)); if(!pEnemyAdjPlot) { continue; } // Don't check Enemy Unit's plot if(!bIsVisibleEnemyUnit) { // Destination adjacent to enemy unit? if(pEnemyAdjPlot->getX() == iToPlotX && pEnemyAdjPlot->getY() == iToPlotY) { return true; } } } } } } } } return false; }