void CvMapGenerator::addNonUniqueBonusType(BonusTypes eBonusType) { int iBonusCount = calculateNumBonusesToAdd(eBonusType); if (iBonusCount == 0) { return; } std::vector<int> aiShuffle(GC.getMapINLINE().numPlotsINLINE()); GC.getGameINLINE().getMapRand().shuffleSequence(aiShuffle, "addNonUniqueBonusType shuffle"); CvBonusInfo& pBonusInfo = GC.getBonusInfo(eBonusType); bool bIgnoreLatitude = false; gDLL->getPythonIFace()->pythonIsBonusIgnoreLatitudes(&bIgnoreLatitude); CvPlot* pPlot = NULL; for (int iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++) { pPlot = GC.getMapINLINE().plotByIndexINLINE(aiShuffle[iI]); if (canPlaceBonusAt(eBonusType, pPlot->getX_INLINE(), pPlot->getY_INLINE(), bIgnoreLatitude)) { pPlot->setBonusType(eBonusType); iBonusCount--; for (int iDX = -(pBonusInfo.getGroupRange()); iDX <= pBonusInfo.getGroupRange(); iDX++) { for (int iDY = -(pBonusInfo.getGroupRange()); iDY <= pBonusInfo.getGroupRange(); iDY++) { if (iBonusCount > 0) { CvPlot* pLoopPlot = plotXY(pPlot->getX_INLINE(), pPlot->getY_INLINE(), iDX, iDY); if (pLoopPlot != NULL) { if (canPlaceBonusAt(eBonusType, pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), bIgnoreLatitude)) { if (GC.getGameINLINE().getMapRandNum(100, "addNonUniqueBonusType") < pBonusInfo.getGroupRand()) { pLoopPlot->setBonusType(eBonusType); iBonusCount--; } } } } } } FAssertMsg(iBonusCount >= 0, "iBonusCount must be >= 0"); if (iBonusCount == 0) { break; } } } }
void CvMap::updateMinOriginalStartDist(CvArea* pArea) { PROFILE_FUNC(); CvPlot* pStartingPlot; CvPlot* pLoopPlot; int iDist; int iI, iJ; for (iI = 0; iI < numPlotsINLINE(); iI++) { pLoopPlot = plotByIndexINLINE(iI); if (pLoopPlot->area() == pArea) { pLoopPlot->setMinOriginalStartDist(-1); } } for (iI = 0; iI < MAX_PLAYERS; iI++) { pStartingPlot = GET_PLAYER((PlayerTypes)iI).getStartingPlot(); if (pStartingPlot != NULL) { if (pStartingPlot->area() == pArea) { for (iJ = 0; iJ < numPlotsINLINE(); iJ++) { pLoopPlot = plotByIndexINLINE(iJ); if (pLoopPlot->area() == pArea) { //iDist = GC.getMapINLINE().calculatePathDistance(pStartingPlot, pLoopPlot); iDist = stepDistance(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()); if (iDist != -1) { //int iCrowDistance = plotDistance(pStartingPlot->getX_INLINE(), pStartingPlot->getY_INLINE(), pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()); //iDist = std::min(iDist, iCrowDistance * 2); if ((pLoopPlot->getMinOriginalStartDist() == -1) || (iDist < pLoopPlot->getMinOriginalStartDist())) { pLoopPlot->setMinOriginalStartDist(iDist); } } } } } } } }
void CvMapGenerator::addGoodies() { PROFILE("CvMapGenerator::addGoodies"); if (gDLL->getPythonIFace()->callFunction(gDLL->getPythonIFace()->getMapScriptModule(), "addGoodies")) { if (!gDLL->getPythonIFace()->pythonUsingDefaultImpl()) { return; // Python override } } gDLL->NiTextOut("Adding Goodies..."); if (GC.getEraInfo(GC.getGameINLINE().getStartEra()).isNoGoodies()) { return; } int iNumPlots = GC.getMapINLINE().numPlotsINLINE(); int* piShuffle = shuffle(iNumPlots, GC.getGameINLINE().getMapRand()); 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(piShuffle[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); } } } } } } SAFE_DELETE_ARRAY(piShuffle); }
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); } } } } } } }
///TKs Med TradeScreens void CvMapGenerator::addEurope() { PROFILE_FUNC(); gDLL->NiTextOut("Adding Europe..."); for (int iEurope = 0; iEurope < GC.getNumEuropeInfos(); ++iEurope) { EuropeTypes eEurope = (EuropeTypes) iEurope; CvEuropeInfo& kEurope = GC.getEuropeInfo(eEurope); int iWidthPercent = kEurope.getWidthPercent(); gDLL->getPythonIFace()->pythonGetEuropeWidthPercent(eEurope, &iWidthPercent); int iMinLandDistance = kEurope.getMinLandDistance(); gDLL->getPythonIFace()->pythonGetEuropeMinLandDistance(eEurope, &iMinLandDistance); //try several times until at least one start europe is found //bool bWaterRoute = (kEurope.getDomainsValid(DOMAIN_SEA)); bool bAnyEuropeFound = false; bool bCheckDirection = true; //int iDomainCount = 0; int iGridWidth = GC.getMapINLINE().getGridWidthINLINE(); int iGridHeight = GC.getMapINLINE().getGridHeightINLINE(); for ( ; iMinLandDistance >= 0 && !bAnyEuropeFound; iMinLandDistance--) { for (int i = 0; i < GC.getMapINLINE().numPlotsINLINE(); ++i) { CvPlot* pPlot = GC.getMapINLINE().plotByIndexINLINE(i); bCheckDirection = true; if (!kEurope.getDomainsValid(DOMAIN_SEA) && pPlot->isWater()) { bCheckDirection = false; } //else if (kEurope.getDomainsValid(DOMAIN_SEA)) //{ //iDomainCount++; //} if (!kEurope.getDomainsValid(DOMAIN_LAND) && !pPlot->isWater()) { bCheckDirection = false; } //else if (kEurope.getDomainsValid(DOMAIN_LAND)) //{ //iDomainCount++; //} if (bCheckDirection && !pPlot->isTradeScreenAccessPlot(eEurope)) { for (int iDir = 0; iDir < NUM_DIRECTION_TYPES; ++iDir) { /*DIRECTION_NORTH, DIRECTION_NORTHEAST, DIRECTION_EAST, DIRECTION_SOUTHEAST, DIRECTION_SOUTH, DIRECTION_SOUTHWEST, DIRECTION_WEST, DIRECTION_NORTHWEST,*/ bool bEurope = false; if (kEurope.getDirectionValid(iDir)) { switch ((DirectionTypes)iDir) { case DIRECTION_EAST: bEurope = (pPlot->getX_INLINE() > (100 - iWidthPercent) * iGridWidth / 100 && pPlot->getY_INLINE() <= (100 - iWidthPercent) * iGridHeight / 100 && pPlot->getY_INLINE() >= iWidthPercent * iGridHeight / 100); break; case DIRECTION_NORTHEAST: bEurope = (pPlot->getX_INLINE() > (100 - iWidthPercent) * iGridWidth / 100 && pPlot->getY_INLINE() > (100 - iWidthPercent) * iGridHeight / 100); break; case DIRECTION_SOUTHEAST: bEurope = (pPlot->getX_INLINE() > (100 - iWidthPercent) * iGridWidth / 100 && pPlot->getY_INLINE() < iWidthPercent * iGridHeight / 100); break; case DIRECTION_WEST: bEurope = (pPlot->getX_INLINE() < iWidthPercent * iGridWidth / 100 && pPlot->getY_INLINE() <= (100 - iWidthPercent) * iGridHeight / 100 && pPlot->getY_INLINE() >= iWidthPercent * iGridHeight / 100); break; case DIRECTION_NORTHWEST: bEurope = (pPlot->getX_INLINE() < (100 - iWidthPercent) * iGridWidth / 100 && pPlot->getY_INLINE() > (100 - iWidthPercent) * iGridHeight / 100); break; case DIRECTION_SOUTHWEST: bEurope = (pPlot->getX_INLINE() < (100 - iWidthPercent) * iGridWidth / 100 && pPlot->getY_INLINE() < iWidthPercent * iGridHeight / 100); break; case DIRECTION_NORTH: bEurope = (pPlot->getY_INLINE() > (100 - iWidthPercent) * iGridHeight / 100 && pPlot->getX_INLINE() > iWidthPercent * iGridWidth / 100 && pPlot->getX_INLINE() < (100 - iWidthPercent) * iGridWidth / 100); break; case DIRECTION_SOUTH: bEurope = (pPlot->getY_INLINE() < iWidthPercent * iGridHeight / 100 && pPlot->getX_INLINE() > iWidthPercent * iGridWidth / 100 && pPlot->getX_INLINE() < (100 - iWidthPercent) * iGridWidth / 100); break; default: FAssertMsg(false, "Invalid direction"); break; } } if (bEurope) { if (kEurope.getDomainsValid(DOMAIN_SEA)) { for (int i = -iMinLandDistance; i <= iMinLandDistance && bEurope; i++) { for (int j = -iMinLandDistance; j <= iMinLandDistance && bEurope; j++) { CvPlot* pLoopPlot = ::plotXY(pPlot->getX_INLINE(), pPlot->getY_INLINE(), i, j); if (pLoopPlot != NULL) { if (!pLoopPlot->isWater()) { bEurope = false; } } } } if (bEurope) { if (pPlot->getFeatureType() != NO_FEATURE && GC.getFeatureInfo(pPlot->getFeatureType()).isImpassable()) { pPlot->setFeatureType(NO_FEATURE); } if (pPlot->isImpassable()) { bEurope = false; } } if (bEurope) { if (!pPlot->isEurope()) { pPlot->setEurope(eEurope); } pPlot->setTradeScreenAccess(eEurope); bAnyEuropeFound = true; } bEurope = true; } if (kEurope.getDomainsValid(DOMAIN_LAND)) { switch ((DirectionTypes)iDir) { case DIRECTION_EAST: if (pPlot->getX_INLINE() < (iGridWidth - kEurope.getMaxLandCoverage())) { bEurope = false; } break; case DIRECTION_NORTHEAST: if (pPlot->getX_INLINE() < (iGridWidth - kEurope.getMaxLandCoverage()) && pPlot->getY_INLINE() < (iGridHeight - kEurope.getMaxLandCoverage())) { bEurope = false; } break; case DIRECTION_SOUTHEAST: if (pPlot->getY_INLINE() > kEurope.getMaxLandCoverage() && pPlot->getX_INLINE() < (iGridWidth - kEurope.getMaxLandCoverage())) { bEurope = false; } break; case DIRECTION_WEST: if (pPlot->getX_INLINE() > kEurope.getMaxLandCoverage()) { bEurope = false; } break; case DIRECTION_NORTHWEST: if (pPlot->getX_INLINE() > kEurope.getMaxLandCoverage() && pPlot->getY_INLINE() < (iGridHeight - kEurope.getMaxLandCoverage())) { bEurope = false; } break; case DIRECTION_SOUTHWEST: if (pPlot->getY_INLINE() > kEurope.getMaxLandCoverage() && pPlot->getX_INLINE() > kEurope.getMaxLandCoverage()) { bEurope = false; } break; case DIRECTION_NORTH: if (pPlot->getY_INLINE() < (iGridHeight - kEurope.getMaxLandCoverage())) { bEurope = false; } break; case DIRECTION_SOUTH: if (pPlot->getY_INLINE() > kEurope.getMaxLandCoverage()) { bEurope = false; } break; default: FAssertMsg(false, "Invalid direction"); break; } if (bEurope) { if (pPlot->getFeatureType() != NO_FEATURE && GC.getFeatureInfo(pPlot->getFeatureType()).isImpassable()) { pPlot->setFeatureType(NO_FEATURE); } if (pPlot->isImpassable()) { bEurope = false; } } if (bEurope) { if (!pPlot->isEurope()) { pPlot->setEurope(eEurope); } pPlot->setTradeScreenAccess(eEurope); bAnyEuropeFound = true; } } } /*if (bEurope) { if (pPlot->getFeatureType() != NO_FEATURE && GC.getFeatureInfo(pPlot->getFeatureType()).isImpassable()) { pPlot->setFeatureType(NO_FEATURE); } if (pPlot->isImpassable()) { bEurope = false; } } if (bEurope) { if (!pPlot->isEurope()) { pPlot->setEurope(eEurope); } pPlot->setTradeScreenAccess(eEurope); bAnyEuropeFound = true; }*/ } } } } } }
void CvMapGenerator::addUniqueBonusType(BonusTypes eBonusType) { int* piAreaTried = new int[GC.getMapINLINE().getNumAreas()]; for (int iI = 0; iI < GC.getMapINLINE().getNumAreas(); iI++) { piAreaTried[iI] = FFreeList::INVALID_INDEX; } CvBonusInfo& pBonusInfo = GC.getBonusInfo(eBonusType); int iBonusCount = calculateNumBonusesToAdd(eBonusType); bool bIgnoreLatitude = false; gDLL->getPythonIFace()->pythonIsBonusIgnoreLatitudes(&bIgnoreLatitude); FAssertMsg(pBonusInfo.isOneArea(), "addUniqueBonusType called with non-unique bonus type"); while (true) { int iBestValue = 0; int iLoop = 0; CvArea *pBestArea = NULL; CvArea *pLoopArea = NULL; for(pLoopArea = GC.getMapINLINE().firstArea(&iLoop); pLoopArea != NULL; pLoopArea = GC.getMapINLINE().nextArea(&iLoop)) { bool bTried = false; for (int iI = 0; iI < GC.getMapINLINE().getNumAreas(); iI++) { if (pLoopArea->getID() == piAreaTried[iI]) { bTried = true; break; } } if (!bTried) { int iNumUniqueBonusesOnArea = pLoopArea->countNumUniqueBonusTypes() + 1; // number of unique bonuses starting on the area, plus this one int iNumTiles = pLoopArea->getNumTiles(); int iValue = iNumTiles / iNumUniqueBonusesOnArea; if (iValue > iBestValue) { iBestValue = iValue; pBestArea = pLoopArea; } } } if (pBestArea == NULL) { break; // can't place bonus on any area } for (int iI = 0; iI < GC.getMapINLINE().getNumAreas(); iI++) { if (piAreaTried[iI] == FFreeList::INVALID_INDEX) { piAreaTried[iI] = pBestArea->getID(); break; } } // Place the bonuses: std::vector<int> aiShuffle(GC.getMapINLINE().numPlotsINLINE()); GC.getGameINLINE().getMapRand().shuffleSequence(aiShuffle, "addUniqueBonusType shuffle"); for (int iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++) { CvPlot* pPlot = GC.getMapINLINE().plotByIndexINLINE(aiShuffle[iI]); FAssertMsg(pPlot != NULL, "addUniqueBonusType(): pPlot is null"); if (GC.getMapINLINE().getNumBonuses(eBonusType) >= iBonusCount) { break; // We already have enough } if (pBestArea == pPlot->area()) { if (canPlaceBonusAt(eBonusType, pPlot->getX_INLINE(), pPlot->getY_INLINE(), bIgnoreLatitude)) { pPlot->setBonusType(eBonusType); for (int iDX = -(pBonusInfo.getGroupRange()); iDX <= pBonusInfo.getGroupRange(); iDX++) { for (int iDY = -(pBonusInfo.getGroupRange()); iDY <= pBonusInfo.getGroupRange(); iDY++) { if (GC.getMapINLINE().getNumBonuses(eBonusType) < iBonusCount) { CvPlot* pLoopPlot = plotXY(pPlot->getX_INLINE(), pPlot->getY_INLINE(), iDX, iDY); if (pLoopPlot != NULL && (pLoopPlot->area() == pBestArea)) { if (canPlaceBonusAt(eBonusType, pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), bIgnoreLatitude)) { if (GC.getGameINLINE().getMapRandNum(100, "addUniqueBonusType") < pBonusInfo.getGroupRand()) { pLoopPlot->setBonusType(eBonusType); } } } } } } } } } } SAFE_DELETE_ARRAY(piAreaTried); }
bool CvMapGenerator::canPlaceBonusAt(BonusTypes eBonus, int iX, int iY, bool bIgnoreLatitude) { PROFILE_FUNC(); CvArea* pArea; CvPlot* pPlot; CvPlot* pLoopPlot; int iRange; int iDX, iDY; int iI; pPlot = GC.getMapINLINE().plotINLINE(iX, iY); pArea = pPlot->area(); if (!(pPlot->canHaveBonus(eBonus, bIgnoreLatitude))) { return false; } long result = 0; if (gDLL->getPythonIFace()->pythonCanPlaceBonusAt(pPlot, &result) && !gDLL->getPythonIFace()->pythonUsingDefaultImpl()) // Python override { if (result >= 0) { return result; } else { FAssertMsg(false, "canPlaceBonusAt() must return >= 0"); } } for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++) { pLoopPlot = plotDirection(iX, iY, ((DirectionTypes)iI)); if (pLoopPlot != NULL) { if ((pLoopPlot->getBonusType() != NO_BONUS) && (pLoopPlot->getBonusType() != eBonus)) { return false; } } } CvBonusInfo& pInfo = GC.getBonusInfo(eBonus); if (pPlot->isWater()) { if (((GC.getMapINLINE().getNumBonusesOnLand(eBonus) * 100) / (GC.getMapINLINE().getNumBonuses(eBonus) + 1)) < pInfo.getMinLandPercent()) { return false; } } // Make sure there are none of the same bonus nearby: iRange = pInfo.getUniqueRange(); for (iDX = -(iRange); iDX <= iRange; iDX++) { for (iDY = -(iRange); iDY <= iRange; iDY++) { pLoopPlot = plotXY(iX, iY, iDX, iDY); if (pLoopPlot != NULL) { if (pLoopPlot->area() == pArea) { if (plotDistance(iX, iY, pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()) <= iRange) { if (pLoopPlot->getBonusType() == eBonus) { return false; } } } } } } return true; }
// pStartPlot = the plot at whose SE corner the river is starting // void CvMapGenerator::doRiver(CvPlot *pStartPlot, CardinalDirectionTypes eLastCardinalDirection, CardinalDirectionTypes eOriginalCardinalDirection, int iThisRiverID) { if (iThisRiverID == -1) { iThisRiverID = GC.getMapINLINE().getNextRiverID(); GC.getMapINLINE().incrementNextRiverID(); } int iOtherRiverID = pStartPlot->getRiverID(); if (iOtherRiverID != -1 && iOtherRiverID != iThisRiverID) { return; // Another river already exists here; can't branch off of an existing river! } CvPlot *pRiverPlot = NULL; CvPlot *pAdjacentPlot = NULL; CardinalDirectionTypes eBestCardinalDirection = NO_CARDINALDIRECTION; if (eLastCardinalDirection==CARDINALDIRECTION_NORTH) { pRiverPlot = pStartPlot; if (pRiverPlot == NULL) { return; } pAdjacentPlot = plotCardinalDirection(pRiverPlot->getX_INLINE(), pRiverPlot->getY_INLINE(), CARDINALDIRECTION_EAST); if ((pAdjacentPlot == NULL) || pRiverPlot->isWOfRiver() || pRiverPlot->isWater() || pAdjacentPlot->isWater()) { return; } pStartPlot->setRiverID(iThisRiverID); pRiverPlot->setWOfRiver(true, eLastCardinalDirection); pRiverPlot = plotCardinalDirection(pRiverPlot->getX_INLINE(), pRiverPlot->getY_INLINE(), CARDINALDIRECTION_NORTH); } else if (eLastCardinalDirection==CARDINALDIRECTION_EAST) { pRiverPlot = plotCardinalDirection(pStartPlot->getX_INLINE(), pStartPlot->getY_INLINE(), CARDINALDIRECTION_EAST); if (pRiverPlot == NULL) { return; } pAdjacentPlot = plotCardinalDirection(pRiverPlot->getX_INLINE(), pRiverPlot->getY_INLINE(), CARDINALDIRECTION_SOUTH); if ((pAdjacentPlot == NULL) || pRiverPlot->isNOfRiver() || pRiverPlot->isWater() || pAdjacentPlot->isWater()) { return; } pStartPlot->setRiverID(iThisRiverID); pRiverPlot->setNOfRiver(true, eLastCardinalDirection); } else if (eLastCardinalDirection==CARDINALDIRECTION_SOUTH) { pRiverPlot = plotCardinalDirection(pStartPlot->getX_INLINE(), pStartPlot->getY_INLINE(), CARDINALDIRECTION_SOUTH); if (pRiverPlot == NULL) { return; } pAdjacentPlot = plotCardinalDirection(pRiverPlot->getX_INLINE(), pRiverPlot->getY_INLINE(), CARDINALDIRECTION_EAST); if ((pAdjacentPlot == NULL) || pRiverPlot->isWOfRiver() || pRiverPlot->isWater() || pAdjacentPlot->isWater()) { return; } pStartPlot->setRiverID(iThisRiverID); pRiverPlot->setWOfRiver(true, eLastCardinalDirection); } else if (eLastCardinalDirection==CARDINALDIRECTION_WEST) { pRiverPlot = pStartPlot; if (pRiverPlot == NULL) { return; } pAdjacentPlot = plotCardinalDirection(pRiverPlot->getX_INLINE(), pRiverPlot->getY_INLINE(), CARDINALDIRECTION_SOUTH); if ((pAdjacentPlot == NULL) || pRiverPlot->isNOfRiver() || pRiverPlot->isWater() || pAdjacentPlot->isWater()) { return; } pStartPlot->setRiverID(iThisRiverID); pRiverPlot->setNOfRiver(true, eLastCardinalDirection); pRiverPlot = plotCardinalDirection(pRiverPlot->getX_INLINE(), pRiverPlot->getY_INLINE(), CARDINALDIRECTION_WEST); } else { //FAssertMsg(false, "Illegal direction type"); // River is starting here, set the direction in the next step pRiverPlot = pStartPlot; long result = 0; if (gDLL->getPythonIFace()->pythonGetRiverStartCardinalDirection(pRiverPlot, &result) && !gDLL->getPythonIFace()->pythonUsingDefaultImpl()) // Python override { if (result >= 0) { eBestCardinalDirection = ((CardinalDirectionTypes)result); } else { FAssertMsg(false, "python pythonGetRiverStartCardinalDirection() must return >= 0"); } } } if (pRiverPlot == NULL) { return; // The river has flowed off the edge of the map. All is well. } else if (pRiverPlot->hasCoastAtSECorner()) { return; // The river has flowed into the ocean. All is well. } if (eBestCardinalDirection == NO_CARDINALDIRECTION) { int iBestValue = MAX_INT; for (int iI = 0; iI < NUM_CARDINALDIRECTION_TYPES; iI++) { if (getOppositeCardinalDirection((CardinalDirectionTypes)iI) != eOriginalCardinalDirection) { if (getOppositeCardinalDirection((CardinalDirectionTypes)iI) != eLastCardinalDirection) { CvPlot* pAdjacentPlot; pAdjacentPlot = plotCardinalDirection(pRiverPlot->getX_INLINE(), pRiverPlot->getY_INLINE(), ((CardinalDirectionTypes)iI)); if (pAdjacentPlot != NULL) { int iValue = getRiverValueAtPlot(pAdjacentPlot); if (iValue < iBestValue) { iBestValue = iValue; eBestCardinalDirection = (CardinalDirectionTypes)iI; } } } } } } if (eBestCardinalDirection != NO_CARDINALDIRECTION) { if (eOriginalCardinalDirection == NO_CARDINALDIRECTION) { eOriginalCardinalDirection = eBestCardinalDirection; } doRiver(pRiverPlot, eBestCardinalDirection, eOriginalCardinalDirection, iThisRiverID); } }
///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; }
void CvMap::calculateAreas() { PROFILE_FUNC(); CvPlot* pLoopPlot; CvArea* pArea; int iArea; int iI; for (iI = 0; iI < numPlotsINLINE(); iI++) { pLoopPlot = plotByIndexINLINE(iI); gDLL->callUpdater(); FAssertMsg(pLoopPlot != NULL, "LoopPlot is not assigned a valid value"); if (pLoopPlot->getArea() == FFreeList::INVALID_INDEX) { pArea = addArea(); pArea->init(pArea->getID(), pLoopPlot->isWater()); iArea = pArea->getID(); pLoopPlot->setArea(iArea); gDLL->getFAStarIFace()->GeneratePath(&GC.getAreaFinder(), pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), -1, -1, pLoopPlot->isWater(), iArea); } } }
void CvPlotGroup::recalculatePlots() { PROFILE_FUNC(); CLLNode<XYCoords>* pPlotNode; CvPlot* pPlot; CLinkList<XYCoords> oldPlotGroup; XYCoords xy; PlayerTypes eOwner; int iCount; eOwner = getOwnerINLINE(); pPlotNode = headPlotsNode(); if (pPlotNode != NULL) { pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY); iCount = 0; gDLL->getFAStarIFace()->SetData(&GC.getPlotGroupFinder(), &iCount); gDLL->getFAStarIFace()->GeneratePath(&GC.getPlotGroupFinder(), pPlot->getX_INLINE(), pPlot->getY_INLINE(), -1, -1, false, eOwner); if (iCount == getLengthPlots()) { return; } } oldPlotGroup.clear(); pPlotNode = headPlotsNode(); while (pPlotNode != NULL) { pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY); FAssertMsg(pPlot != NULL, "Plot is not assigned a valid value"); xy.iX = pPlot->getX_INLINE(); xy.iY = pPlot->getY_INLINE(); oldPlotGroup.insertAtEnd(xy); pPlot->setPlotGroup(eOwner, NULL); pPlotNode = deletePlotsNode(pPlotNode); // will delete this PlotGroup... } pPlotNode = oldPlotGroup.head(); while (pPlotNode != NULL) { pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY); FAssertMsg(pPlot != NULL, "Plot is not assigned a valid value"); pPlot->updatePlotGroup(eOwner, true); pPlotNode = oldPlotGroup.deleteNode(pPlotNode); } }
bool CvMapGenerator::canPlaceBonusAt(BonusTypes eBonus, int iX, int iY, bool bIgnoreLatitude) { PROFILE_FUNC(); CvArea* pArea; CvPlot* pPlot; CvPlot* pLoopPlot; int iRange; int iDX, iDY; int iI; pPlot = GC.getMapINLINE().plotINLINE(iX, iY); pArea = pPlot->area(); if (!(pPlot->canHaveBonus(eBonus, bIgnoreLatitude))) { return false; } long result = 0; CyPlot kPlot = CyPlot(pPlot); CyArgsList argsList; argsList.add(gDLL->getPythonIFace()->makePythonObject(&kPlot)); if (gDLL->getPythonIFace()->callFunction(gDLL->getPythonIFace()->getMapScriptModule(), "canPlaceBonusAt", argsList.makeFunctionArgs(), &result)) { if (!gDLL->getPythonIFace()->pythonUsingDefaultImpl()) { if (result >= 0) { return result; } else { FAssertMsg(false, "canPlaceBonusAt() must return >= 0"); } } } for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++) { pLoopPlot = plotDirection(iX, iY, ((DirectionTypes)iI)); if (pLoopPlot != NULL) { if ((pLoopPlot->getBonusType() != NO_BONUS) && (pLoopPlot->getBonusType() != eBonus)) { return false; } } } CvBonusInfo& pInfo = GC.getBonusInfo(eBonus); CvBonusClassInfo& pClassInfo = GC.getBonusClassInfo((BonusClassTypes) pInfo.getBonusClassType()); if (pPlot->isWater()) { if (((GC.getMapINLINE().getNumBonusesOnLand(eBonus) * 100) / (GC.getMapINLINE().getNumBonuses(eBonus) + 1)) < pInfo.getMinLandPercent()) { return false; } } // Make sure there are no bonuses of the same class (but a different type) nearby: iRange = pClassInfo.getUniqueRange(); for (iDX = -(iRange); iDX <= iRange; iDX++) { for (iDY = -(iRange); iDY <= iRange; iDY++) { pLoopPlot = plotXY(iX, iY, iDX, iDY); if (pLoopPlot != NULL) { if (pLoopPlot->area() == pArea) { if (plotDistance(iX, iY, pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()) <= iRange) { BonusTypes eOtherBonus = pLoopPlot->getBonusType(); if (eOtherBonus != NO_BONUS) { if (GC.getBonusInfo(eOtherBonus).getBonusClassType() == pInfo.getBonusClassType()) { return false; } } } } } } } // Make sure there are none of the same bonus nearby: iRange = pInfo.getUniqueRange(); for (iDX = -(iRange); iDX <= iRange; iDX++) { for (iDY = -(iRange); iDY <= iRange; iDY++) { pLoopPlot = plotXY(iX, iY, iDX, iDY); if (pLoopPlot != NULL) { if (pLoopPlot->area() == pArea) { if (plotDistance(iX, iY, pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()) <= iRange) { if (pLoopPlot->getBonusType() == eBonus) { return false; } } } } } } return true; }