Hooks
static bool BeforeCvFractal_ridgeBuilder(CvFractal* self, CvRandom& random, int iNumVoronoiSeeds, int iRidgeFlags, int iBlendRidge, int iBlendFract);static void AfterCvFractal_ridgeBuilder(CvFractal* self, CvRandom& random, int iNumVoronoiSeeds, int iRidgeFlags, int iBlendRidge, int iBlendFract);static void ReplaceCvFractal_ridgeBuilder(void (*original)(CvFractal*, CvRandom&, int, int, int, int), CvFractal* self, CvRandom& random, int iNumVoronoiSeeds, int iRidgeFlags, int iBlendRidge, int iBlendFract);// CivHooks.h gives this hook point no types, so nothing checks these hooks' parameters.host->RegisterHook(host->pluginIndex, CivHooks::CvFractal_ridgeBuilder::ID, CIV_HOOK_BEFORE, (void*)&BeforeCvFractal_ridgeBuilder);host->RegisterHook(host->pluginIndex, CivHooks::CvFractal_ridgeBuilder::ID, CIV_HOOK_AFTER, (void*)&AfterCvFractal_ridgeBuilder);host->RegisterHook(host->pluginIndex, CivHooks::CvFractal_ridgeBuilder::ID, CIV_HOOK_REPLACE, (void*)&ReplaceCvFractal_ridgeBuilder);
Code
433void CvFractal::ridgeBuilder(CvRandom& random, int iNumVoronoiSeeds, int iRidgeFlags, int iBlendRidge, int iBlendFract)434{435 // this will use a modified Voronoi system to give the appearance of mountain ranges436437 iNumVoronoiSeeds = std::max(iNumVoronoiSeeds,3); // make sure that we have at least 3438439 // randomly place the seed points of each region ??? do we want a way for an advanced script to pass this in ???440 FStaticVector<VoronoiSeed,256, true, c_eCiv5GameplayDLL, 0> vVoronoiSeeds;441 vVoronoiSeeds.reserve(iNumVoronoiSeeds);442443 for(int iThisVoronoiSeedIndex = 0; iThisVoronoiSeedIndex < iNumVoronoiSeeds; iThisVoronoiSeedIndex++)444 {445 VoronoiSeed thisVoronoiSeed;446 thisVoronoiSeed.m_iHexspaceY = random.get(m_iFracY, "Ridge Gen 1");447 thisVoronoiSeed.m_iHexspaceX = xToHexspaceX(random.get(m_iFracX, "Ridge Gen 2"), thisVoronoiSeed.m_iHexspaceY);448 thisVoronoiSeed.m_iWeakness = std::max(0,random.get(7, "Ridge Gen 3")-3); // ??? do we want to parameterize this???449 thisVoronoiSeed.m_eBiasDirection = random.get(NUM_DIRECTION_TYPES, "Ridge Gen 4");450 thisVoronoiSeed.m_iDirectionalBiasStrength = std::max(0,random.get(8, "Ridge Gen 5") - 4); // ??? do we want to parameterize this???451452 // check to see if we are too close to an existing seed453 bool bNeedToRecheck;454 do455 {456 bNeedToRecheck = false;457 for(int iThatVoronoiSeedIndex = 0; iThatVoronoiSeedIndex < iThisVoronoiSeedIndex; iThatVoronoiSeedIndex++)458 {459 int iDistanceBetweenVoronoiSeeds = hexDistance(thisVoronoiSeed.m_iHexspaceX-vVoronoiSeeds[iThatVoronoiSeedIndex].m_iHexspaceX,thisVoronoiSeed.m_iHexspaceY-vVoronoiSeeds[iThatVoronoiSeedIndex].m_iHexspaceY);460461 if(iDistanceBetweenVoronoiSeeds < 7) // ??? parameterize ???462 {463 thisVoronoiSeed.m_iHexspaceX = random.get(m_iFracX, "Ridge Gen 6");464 thisVoronoiSeed.m_iHexspaceY = random.get(m_iFracY, "Ridge Gen 7");465 bNeedToRecheck = true;466 break;467 }468 }469470 }471 while(bNeedToRecheck);472473 vVoronoiSeeds.push_back(thisVoronoiSeed);474 }475476 //std::vector<int> vDistances;477 //vDistances.reserve(iNumVoronoiSeeds);478479 for(int iX = 0; iX < m_iFracX; iX++)480 {481 for(int iY = 0; iY < m_iFracY; iY++)482 {483 // get the hexspace coordinate for this position484 int iThisHexX = xToHexspaceX(iX,iY);485 int iThisHexY = iY; // not really needed except for clarity486487 // find the distance to each of the seeds (with modifiers for strength of the seed, directional bias, and random factors)488 //vDistances.clear();489 int iClosestSeed = INT_MAX;490 int iNextClosestSeed = INT_MAX;491 for(int iThisVoronoiSeedIndex= 0; iThisVoronoiSeedIndex < iNumVoronoiSeeds; iThisVoronoiSeedIndex++)492 {493 int iModifiedHexspaceDistance = hexDistance(iThisHexX-vVoronoiSeeds[iThisVoronoiSeedIndex].m_iHexspaceX,iThisHexY-vVoronoiSeeds[iThisVoronoiSeedIndex].m_iHexspaceY);494 if(iRidgeFlags) // we may decide to add more control later495 {496 iModifiedHexspaceDistance += vVoronoiSeeds[iThisVoronoiSeedIndex].m_iWeakness;497 iModifiedHexspaceDistance += random.get(3, "Ridge Gen 8");498 DirectionTypes eRelativeDirection = estimateDirection(vVoronoiSeeds[iThisVoronoiSeedIndex].m_iHexspaceX-iThisHexX,vVoronoiSeeds[iThisVoronoiSeedIndex].m_iHexspaceY-iThisHexY);499 if(eRelativeDirection == vVoronoiSeeds[iThisVoronoiSeedIndex].m_eBiasDirection)500 {501 iModifiedHexspaceDistance -= vVoronoiSeeds[iThisVoronoiSeedIndex].m_iDirectionalBiasStrength;502 }503 else if(eRelativeDirection == (vVoronoiSeeds[iThisVoronoiSeedIndex].m_eBiasDirection + 3) % NUM_DIRECTION_TYPES)504 {505 iModifiedHexspaceDistance += vVoronoiSeeds[iThisVoronoiSeedIndex].m_iDirectionalBiasStrength;506 }507 iModifiedHexspaceDistance = std::max(1,iModifiedHexspaceDistance);508 }509 //vDistances.push_back(iModifiedHexspaceDistance);510 if(iModifiedHexspaceDistance < iClosestSeed)511 {512 iNextClosestSeed = iClosestSeed;513 iClosestSeed = iModifiedHexspaceDistance;514 }515 else if(iModifiedHexspaceDistance < iNextClosestSeed)516 {517 iNextClosestSeed = iModifiedHexspaceDistance;518 }519 }520521 // use the modified distance between the two closest seeds to determine the ridge height522 // ??? are there any other fudge factors I want to add in here???523 //std::sort(vDistances.begin(),vDistances.end());524525 int iRidgeHeight = (255 * iClosestSeed) / iNextClosestSeed;526527 // blend the new ridge height with the previous fractal height528 m_aaiFrac[iX][iY] = (iRidgeHeight * iBlendRidge + m_aaiFrac[iX][iY] * iBlendFract) / std::max(iBlendRidge + iBlendFract, 1);529 }530 }531}