176 lines
No EOL
5.5 KiB
C++
176 lines
No EOL
5.5 KiB
C++
#include "StdAfx.h"
|
|
#include "EtMazeMask.h"
|
|
#include "EtRandomDungeon.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
#endif
|
|
|
|
CEtMazeMask::CEtMazeMask( int nWidth, int nHeight, int nLevel )
|
|
{
|
|
m_pMask = new int **[nWidth];
|
|
for( int i=0; i<nWidth; i++ ) {
|
|
m_pMask[i] = new int *[nHeight];
|
|
for( int j=0; j<nHeight; j++ ) {
|
|
m_pMask[i][j] = new int[nLevel];
|
|
memset( m_pMask[i][j], 0, nLevel * sizeof(int) );
|
|
}
|
|
}
|
|
|
|
m_nWidth = nWidth;
|
|
m_nHeight = nHeight;
|
|
m_nLevel = nLevel;
|
|
}
|
|
|
|
CEtMazeMask::~CEtMazeMask()
|
|
{
|
|
for( int i=0; i<m_nWidth; i++ ) {
|
|
for( int j=0; j<m_nHeight; j++ ) {
|
|
SAFE_DELETEA( m_pMask[i][j] );
|
|
}
|
|
SAFE_DELETEA( m_pMask[i] );
|
|
}
|
|
SAFE_DELETEA( m_pMask );
|
|
}
|
|
|
|
int CEtMazeMask::GetMaskAt( int nX, int nY, int nZ )
|
|
{
|
|
return m_pMask[nX][nY][nZ];
|
|
}
|
|
|
|
bool CEtMazeMask::IsCheckMask( int nX, int nY, int nZ )
|
|
{
|
|
if( m_pMask[nX][nY][nZ] == CEtRandomDungeon::BA_NONE ) return false;
|
|
if( m_pMask[nX][nY][nZ] & CEtRandomDungeon::BA_PASSAGE ) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void CEtMazeMask::AddBlock( int nX, int nY, int nZ, int nWidth, int nHeight )
|
|
{
|
|
if( nZ == -1 ) {
|
|
for( int i=0; i<m_nLevel; i++ ) AddBlock( nX, nY, i, nWidth, nHeight );
|
|
}
|
|
else {
|
|
bool bFlag = true;
|
|
for( int i=0; i<nWidth; i++ ) {
|
|
for( int j=0; j<nHeight; j++ ) {
|
|
if( m_pMask[nX+i][nY+j][nZ] != CEtRandomDungeon::BA_NONE ) {
|
|
bFlag = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if( bFlag == false ) return;
|
|
|
|
for( int i=0; i<nWidth; i++ ) {
|
|
for( int j=0; j<nHeight; j++ ) {
|
|
m_pMask[nX+i][nY+j][nZ] = CEtRandomDungeon::BA_BLOCK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CEtMazeMask::AddRoad( int nX, int nY, int nZ, CEtMaze::Maze_Direction Dir )
|
|
{
|
|
if( nZ == -1 ) {
|
|
for( int i=0; i<m_nLevel; i++ ) AddRoad( nX, nY, i, Dir );
|
|
}
|
|
else {
|
|
if( m_pMask[nX][nY][nZ] != CEtRandomDungeon::BA_NONE ) return;
|
|
|
|
m_pMask[nX][nY][nZ] = CEtRandomDungeon::BA_PASSAGE;
|
|
if( Dir & CEtMaze::MD_WEST ) m_pMask[nX][nY][nZ] |= CEtRandomDungeon::BA_WEST;
|
|
if( Dir & CEtMaze::MD_EAST ) m_pMask[nX][nY][nZ] |= CEtRandomDungeon::BA_EAST;
|
|
if( Dir & CEtMaze::MD_NORTH ) m_pMask[nX][nY][nZ] |= CEtRandomDungeon::BA_NORTH;
|
|
if( Dir & CEtMaze::MD_SOUTH ) m_pMask[nX][nY][nZ] |= CEtRandomDungeon::BA_SOUTH;
|
|
if( Dir & CEtMaze::MD_UP ) m_pMask[nX][nY][nZ] |= CEtRandomDungeon::BA_UP;
|
|
if( Dir & CEtMaze::MD_DOWN ) m_pMask[nX][nY][nZ] |= CEtRandomDungeon::BA_DOWN;
|
|
}
|
|
}
|
|
|
|
void CEtMazeMask::AddRoom( int nX, int nY, int nZ, int nWidth, int nHeight, std::vector<CEtRandomDungeonRoom::DoorStruct> *pVecDoorList )
|
|
{
|
|
if( nZ == -1 ) {
|
|
for( int i=0; i<m_nLevel; i++ ) AddRoom( nX, nY, i, nWidth, nHeight, pVecDoorList );
|
|
}
|
|
else {
|
|
bool bFlag = true;
|
|
for( int i=0; i<nWidth; i++ ) {
|
|
for( int j=0; j<nHeight; j++ ) {
|
|
if( m_pMask[nX+i][nY+j][nZ] != CEtRandomDungeon::BA_NONE ) {
|
|
bFlag = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if( bFlag == false ) return;
|
|
|
|
for( int i=0; i<nWidth; i++ ) {
|
|
for( int j=0; j<nHeight; j++ ) {
|
|
m_pMask[nX+i][nY+j][nZ] = CEtRandomDungeon::BA_ROOM;
|
|
}
|
|
}
|
|
int *pMask;
|
|
for( DWORD i=0; i<pVecDoorList->size(); i++ ) {
|
|
pMask = &m_pMask[nX + (*pVecDoorList)[i].nX][nY + (*pVecDoorList)[i].nY][nZ];
|
|
if( (*pVecDoorList)[i].Direction & CEtRandomDungeonRoom::DD_WEST ) {
|
|
*pMask |= CEtRandomDungeon::BA_DOOR | CEtRandomDungeon::BA_WEST;
|
|
m_pMask[nX + (*pVecDoorList)[i].nX - 1][nY + (*pVecDoorList)[i].nY][nZ] |= CEtRandomDungeon::BA_PASSAGE | CEtRandomDungeon::BA_EAST;
|
|
}
|
|
if( (*pVecDoorList)[i].Direction & CEtRandomDungeonRoom::DD_EAST ) {
|
|
*pMask |= CEtRandomDungeon::BA_DOOR | CEtRandomDungeon::BA_EAST;
|
|
m_pMask[nX + (*pVecDoorList)[i].nX + 1][nY + (*pVecDoorList)[i].nY][nZ] |= CEtRandomDungeon::BA_PASSAGE | CEtRandomDungeon::BA_WEST;
|
|
}
|
|
if( (*pVecDoorList)[i].Direction & CEtRandomDungeonRoom::DD_NORTH ) {
|
|
*pMask |= CEtRandomDungeon::BA_DOOR | CEtRandomDungeon::BA_NORTH;
|
|
m_pMask[nX + (*pVecDoorList)[i].nX][nY + (*pVecDoorList)[i].nY - 1][nZ] |= CEtRandomDungeon::BA_PASSAGE | CEtRandomDungeon::BA_SOUTH;
|
|
}
|
|
if( (*pVecDoorList)[i].Direction & CEtRandomDungeonRoom::DD_SOUTH ) {
|
|
*pMask |= CEtRandomDungeon::BA_DOOR | CEtRandomDungeon::BA_SOUTH;
|
|
m_pMask[nX + (*pVecDoorList)[i].nX][nY + (*pVecDoorList)[i].nY + 1][nZ] |= CEtRandomDungeon::BA_PASSAGE | CEtRandomDungeon::BA_NORTH;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CEtMazeMask::AddStartBlock( int nX, int nY, int nZ )
|
|
{
|
|
int nDir = CEtMaze::MD_EAST | CEtMaze::MD_WEST | CEtMaze::MD_NORTH | CEtMaze::MD_SOUTH;
|
|
if( nX == 0 ) nDir &= ~CEtMaze::MD_WEST;
|
|
if( nX == m_nWidth - 1 ) nDir &= ~CEtMaze::MD_EAST;
|
|
if( nY == 0 ) nDir &= ~CEtMaze::MD_NORTH;
|
|
if( nY == m_nHeight - 1 ) nDir &= ~CEtMaze::MD_SOUTH;
|
|
|
|
std::vector<int> nVecList;
|
|
if( nDir & CEtMaze::MD_EAST ) nVecList.push_back( CEtMaze::MD_EAST );
|
|
if( nDir & CEtMaze::MD_WEST ) nVecList.push_back( CEtMaze::MD_WEST );
|
|
if( nDir & CEtMaze::MD_NORTH ) nVecList.push_back( CEtMaze::MD_NORTH );
|
|
if( nDir & CEtMaze::MD_SOUTH ) nVecList.push_back( CEtMaze::MD_SOUTH );
|
|
if( nVecList.size() > 1 ) {
|
|
int nResult = rand()%(int)nVecList.size() + 1;
|
|
while( nResult != (int)nVecList.size() ) {
|
|
int nIndex = rand()%(int)nVecList.size();
|
|
nDir &= ~nVecList[nIndex];
|
|
nVecList.erase( nVecList.begin() + nIndex );
|
|
}
|
|
}
|
|
for( DWORD i=0; i<nVecList.size(); i++ ) {
|
|
switch( nVecList[i] ) {
|
|
case CEtMaze::MD_EAST:
|
|
AddRoad( nX + 1, nY, nZ, CEtMaze::MD_WEST );
|
|
break;
|
|
case CEtMaze::MD_WEST:
|
|
AddRoad( nX - 1, nY, nZ, CEtMaze::MD_EAST );
|
|
break;
|
|
case CEtMaze::MD_NORTH:
|
|
AddRoad( nX, nY - 1, nZ, CEtMaze::MD_SOUTH );
|
|
break;
|
|
case CEtMaze::MD_SOUTH:
|
|
AddRoad( nX, nY + 1, nZ, CEtMaze::MD_NORTH );
|
|
break;
|
|
}
|
|
}
|
|
|
|
AddRoad( nX, nY, nZ, CEtMaze::Maze_Direction( nDir ) );
|
|
} |