예제 #1
0
파일: RM_Path.cpp 프로젝트: emileb/JK3
/************************************************************************************************
 * CRMPathManager::GenerateRivers
 *	Creates a river which intersects the main path
 *
 * inputs:
 *  none
 *
 * return:
 *	none
 *
 ************************************************************************************************/
void CRMPathManager::GenerateRivers ()
{
	if (mRiverBedDepth == 1)
		// no rivers
		return;

	mMaxDepth = mRiverDepth;
	mDepth = 0;

	int cell_x = 0;
	int cell_y = 0;

	// choose starting cell along an edge
	int edge = TheRandomMissionManager->GetLandScape()->irand(0, 7);
	switch ( edge )
	{
		case 0:
			cell_x = mXNodes / 2; cell_y = 0;
			break;
		case 1:
			cell_x = mXNodes; cell_y = 0;
			break;
		case 2:
			cell_x = mXNodes; cell_y = mYNodes / 2;
			break;
		case 3:
			cell_x = mXNodes; cell_y = mYNodes;
			break;
		case 4:
			cell_x = mXNodes / 2; cell_y = mYNodes;
			break;
		case 5:
			cell_x = 0; cell_y = mYNodes;
			break;
		case 6:
			cell_x = 0; cell_y = mYNodes / 2;
			break;
		case 7:
			cell_x = 0; cell_y = 0;
			break;
	}

	ClearCells(mXNodes+1, mYNodes+1);

	mRiverCount = mPathCount;

	// visit the first cell
	RiverVisit(cell_x,cell_y);

	mRiverCount = mPathCount - mRiverCount;

	return;
}
예제 #2
0
파일: RM_Path.cpp 프로젝트: klusark/OpenJK
void CRMPathManager::RiverVisit(const int c_x, const int c_y)
{
    // does this cell have any neighbors with all walls intact?
    int i,off;

    // look at neighbors in random order
    off = TheRandomMissionManager->GetLandScape()->irand(DIR_FIRST, DIR_MAX-1);

    ++mDepth;	// track our depth of recursion

    for (i = DIR_FIRST; i<DIR_MAX && mDepth <= mMaxDepth; i+=2)
    {
        int d = (i + off) % DIR_MAX;
        if ( !Cell(c_x, c_y).Border(d) )
        {   // we can move this way, since no border
            int new_c_x = c_x + neighbor_x[d];
            int new_c_y = c_y + neighbor_y[d];
            if (RiverCell(new_c_x,new_c_y).Wall() == DIR_ALL)
            {   // we have a new cell that has not been visited!

                int new_dir;
                // d is the direction relative to the current cell
                // new_dir is the direction relative to the next cell (N becomes S, NE becomes SW, etc...)
                if( d < HALF_DIR_MAX )
                {
                    new_dir = d + HALF_DIR_MAX;
                }
                else
                {
                    new_dir = d - HALF_DIR_MAX;
                }
                // knock down walls
                RiverCell(c_x,c_y).RemoveWall(d);
                RiverCell(new_c_x,new_c_y).RemoveWall(new_dir); //DIR_MAX - d);

                // create river between cells
                mTerrain->CreatePath ( mPathCount++,
                                       -1,
                                       0,
                                       mRiverPoints,
                                       GetRiverPos(c_x,c_y)[0],
                                       GetRiverPos(c_x,c_y)[1],
                                       GetRiverPos(new_c_x,new_c_y)[0],
                                       GetRiverPos(new_c_x,new_c_y)[1],
                                       mRiverMinWidth,
                                       mRiverMaxWidth,
                                       mRiverBedDepth,
                                       mRiverDeviation,
                                       mRiverBreadth );

                // flatten a small spot
                CArea		area;
                float flat_radius = mRiverMinWidth *
                                    fabs(TheRandomMissionManager->GetLandScape()->GetBounds()[1][0] - TheRandomMissionManager->GetLandScape()->GetBounds()[0][0]);
                area.Init( GetRiverPos(c_x,c_y), flat_radius, 0.0f, AT_NONE, 0, 0 );
                TheRandomMissionManager->GetLandScape()->FlattenArea (&area, 255 * mRiverBedDepth, false, true, true );

                // recurse
                RiverVisit(new_c_x, new_c_y);
            }
        }
    }

//	--mDepth;
}