void OffsetRange(range& ioRange, cell inOffset, SplitType what, int split, int shift) { bool wasSpecial = false; if (shift < 0 && what != noSplit) if (what == hSplit) { if (abs(ioRange.left) >= split && abs(ioRange.right) <= split - shift) ioRange.Set(0, 0, 0, 0); else if (abs(ioRange.left) >= split && abs(ioRange.left) <= split - shift) { if (ioRange.left < 0) ioRange.left = -split; else ioRange.left = split; OffsetCell(ioRange.BotRight(), inOffset, what, split, shift); wasSpecial = true; } else if (abs(ioRange.right) >= split && abs(ioRange.right) <= split - shift) { if (ioRange.right < 0) ioRange.right = -split + 1; else ioRange.right = split - 1; OffsetCell(ioRange.TopLeft(), inOffset, what, split, shift); wasSpecial = true; } } else if (what == vSplit) { if (abs(ioRange.top) >= split && abs(ioRange.bottom) <= split - shift) ioRange.Set(0, 0, 0, 0); else if (abs(ioRange.top) >= split && abs(ioRange.top) <= split - shift) { if (ioRange.top < 0) ioRange.top = -split; else ioRange.top = split; OffsetCell(ioRange.BotRight(), inOffset, what, split, shift); wasSpecial = true; } else if (abs(ioRange.bottom) >= split && abs(ioRange.bottom) <= split - shift) { if (ioRange.bottom < 0) ioRange.bottom = -split + 1; else ioRange.bottom = split - 1; OffsetCell(ioRange.TopLeft(), inOffset, what, split, shift); wasSpecial = true; } } if (!wasSpecial) { OffsetCell(ioRange.TopLeft(), inOffset, what, split, shift); OffsetCell(ioRange.BotRight(), inOffset, what, split, shift); } } /* OffsetRange */
// AddHill // ---------------------------------------------------------------------------- static void AddHill( void ) { // make sure there is a terrain assert( m_pMap != NULL ); // pick a size for the hill float fRadius = RandomRange( m_fHillMin, m_fHillMax ); // pick a centerpoint for the hill float x, y; if( m_bIsland ) { // island code: float fTheta = RandomRange( 0.0f, 6.28f ); // this determines in which direction from the center of the map the // hill will be placed. #define min(a, b) (((a) < (b)) ? (a) : (b)) float fDistance = RandomRange( fRadius/2, min(m_uZSize,m_uXSize)/2 - fRadius ); // this is how far from the center of the map the hill be placed. note // that the radius of the hill is subtracted from the range to prevent // any part of a hill from reaching the very edge of the map. x = (float)(m_uXSize/2.0 + cos( fTheta ) * fDistance); y = (float)(m_uZSize/2.0 + sin( fTheta ) * fDistance); // converts theta and a distance into x and y coordinates. } else { // non-island code: x = RandomRange( -fRadius, m_uXSize + fRadius ); y = RandomRange( -fRadius, m_uZSize + fRadius ); // note that the range of the hill is used to determine the // centerpoint. this allows hills to have their centerpoint off the // edge of the terrain as long as part of the hill is in bounds. this // makes the terrains appear continuous all the way to the edge of the // map. } // square the hill radius so we don't have to square root the distance float fRadiusSq = fRadius * fRadius; float fDistSq; float fHeight; // find the range of cells affected by this hill int xMin = (int)(x - fRadius - 1); int xMax = (int)(x + fRadius + 1); // don't affect cell outside of bounds if( xMin < 0 ) xMin = 0; if( xMax >= m_uXSize ) xMax = m_uXSize - 1; int yMin = (int)(y - fRadius - 1); int yMax = (int)(y + fRadius + 1); // don't affect cell outside of bounds if( yMin < 0 ) yMin = 0; if( yMax >= m_uZSize ) yMax = m_uZSize - 1; // for each affected cell, determine the height of the hill at that point // and add it to that cell for( int h = xMin; h <= xMax; ++h ) { for( int v = yMin; v <= yMax; ++v ) { // determine how far from the center of the hill this point is fDistSq = ( x - h ) * ( x - h ) + ( y - v ) * ( y - v ); // determine the height of the hill at this point fHeight = fRadiusSq - fDistSq ; // don't add negative hill values (i.e. outside the hill's radius) if( fHeight > 0 ) { // add the height of this hill to the cell OffsetCell( h, v, fHeight ); } } } }