📄 mapinfo.cpp
字号:
#include "global.h"
#include "mapinfo.h"
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
CMapInfo::CMapInfo() {
m_bReversed = false;
m_nBlocks = 0;
m_cxBlocks = 0;
m_cyBlocks = 0;
m_szFileName = NULL;
m_ptBase = NULL;
m_pBlocks = NULL;
m_pTankInfo = NULL;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
CMapInfo::~CMapInfo() {
DestroyMap();
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
void CMapInfo::DestroyMap() {
//DELETE_PTR( m_szFileName ); // Undefined error here
//DELETE_ARRAY( m_ptBase );
//DELETE_ARRAY( m_pBlocks );
//DELETE_ARRAY( m_pTankInfo );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
bool CMapInfo::LoadMap( const char *filename ) {
if ( !filename )
return false;
DestroyMap();
m_szFileName = new char[strlen(filename)+1];
strcpy( m_szFileName, filename );
HANDLE hfile;
DWORD read, ret;
FILEHEADER header;
// Open exist file
hfile = CreateFile( m_szFileName, GENERIC_READ,
0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL );
if ( hfile == INVALID_HANDLE_VALUE )
goto err_quit_loadmap;
// Read file header and test if the file format is legal
read = sizeof(FILEHEADER);
if ( !ReadFile( hfile, (LPVOID)&header, read, &ret, NULL ) )
goto err_quit_loadmap;
if ( header.dwFileID != GAME_MAP_FILE_IDENTITY ||
header.dwVersion != GAME_MAP_VER_1_2_0 )
goto err_quit_loadmap;
// Read base possitions
m_ptBase = new POINT[2];
read = sizeof(POINT) * 2;
if ( !ReadFile( hfile, (LPVOID)m_ptBase, read, &ret , NULL ) )
goto err_quit_loadmap;
// Read tanks' original infomation settings
m_pTankInfo = new TANKINFO[20];
if ( !m_pTankInfo )
goto err_quit_loadmap;
read = sizeof(TANKINFO)*20;
if( !ReadFile( hfile, (LPVOID)m_pTankInfo, read, &ret, NULL ) )
goto err_quit_loadmap;
// Read block infomations
m_nBlocks = header.nBlocks;
m_cxBlocks = DEFAULT_CX_BLOCKS;
m_cyBlocks = DEFAULT_CY_BLOCKS;
m_pBlocks = new BLOCK[m_nBlocks];
if ( !m_pBlocks )
goto err_quit_loadmap;
read = sizeof(BLOCK) * m_nBlocks;
ZeroMemory( m_pBlocks, read );
if( !ReadFile( hfile, (LPVOID)m_pBlocks, read, &ret, NULL ) )
goto err_quit_loadmap;
// Close file handle
CloseHandle(hfile);
// Need to be added in further version of map
m_uiTankNum = 20;
return true;
// False return
err_quit_loadmap:
CloseHandle(hfile);
DestroyMap();
m_nBlocks = 0;
m_cxBlocks = 0;
m_cyBlocks = 0;
return false;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
void CMapInfo::SetReversed( bool flag ) {
if ( m_bReversed != flag && CenterRotate180() )
m_bReversed = flag;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
void CMapInfo::ConvertCoord( CObject * pobj ) {
pobj->SetPos( g_FrameLeft - pobj->GetLeft(), g_FrameLeft - pobj->GetTop() );
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
void CMapInfo::Protect( RECT rt, bool flag, POINT *ppts, int &changed ) {
int x, y;
int xend = rt.left/32+1, yend = rt.top/32+1;
int total = 0;
for ( y = yend-2; y <= yend; y++ ) {
if ( y < 0 || y > m_cyBlocks-2)
continue;
for ( x = xend-2; x <= xend; x++ ) {
if ( x < 0 || x > m_cxBlocks-2)
continue;
if ( total < changed ) {
if ( flag )
(m_pBlocks+y*m_cyBlocks+x)->byClass = LAND_IRON;
else
(m_pBlocks+y*m_cyBlocks+x)->byClass = LAND_BRICK;
ppts[total].x = x;
ppts[total].y = y;
total++;
}
}
}
changed = total;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
bool CMapInfo::CenterRotate180() {
if ( !(HorReverseMap() && VerReverseMap()) )
return false;
// Reverse base position too
if ( m_ptBase ) {
m_ptBase[0].x = (m_cxBlocks-2)*32-m_ptBase[0].x;
m_ptBase[0].y = (m_cyBlocks-2)*32-m_ptBase[0].y;
m_ptBase[1].x = (m_cxBlocks-2)*32-m_ptBase[1].x;
m_ptBase[1].y = (m_cyBlocks-2)*32-m_ptBase[1].y;
}
return true;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
bool CMapInfo::HorReverseMap() {
if ( !m_pBlocks || m_cxBlocks == 0)
return false;
int i,j,half,opp;
BLOCK block;
half = (m_cxBlocks-1)/2; // Divide to two pars, left and right
for(j=0; j<m_cyBlocks-1; j++) {
for(i=0; i<half; i++) {
// exchange b[j][i] and b[j][19-i]
opp = m_cxBlocks-2-i;
HorReverseBlock(i,j);
HorReverseBlock(opp,j);
block = *(m_pBlocks+j*m_cyBlocks+i);
*(m_pBlocks+j*m_cyBlocks+i) = *(m_pBlocks+j*m_cyBlocks+opp);
*(m_pBlocks+j*m_cyBlocks+opp) = block;
}
}
return true;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
bool CMapInfo::VerReverseMap() {
if ( !m_pBlocks || m_cyBlocks == 0)
return false;
int i,j,half,opp;
BLOCK block;
half = (m_cyBlocks-1)/2; // Divide to two parts, up and down
for(i=0; i<m_cxBlocks-1; i++) {
for(j=0; j<half; j++) {
// exchange b[j][i] and b[19-j][i]
opp = m_cyBlocks-2-j;
VerReverseBlock( i, j );
VerReverseBlock( i, opp );
block = *( m_pBlocks + j*m_cyBlocks + i);
*( m_pBlocks + j*m_cyBlocks+i ) = *( m_pBlocks + opp*m_cyBlocks+i );
*( m_pBlocks+ opp*m_cyBlocks+i ) = block;
}
}
return true;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
void CMapInfo::HorReverseBlock( int x, int y ) {
BYTE b1,b2,b3,b4,obs;
obs = (m_pBlocks+y*m_cyBlocks+x)->byObstacle;
if(obs != 0 && obs != 0x0f) {
b1 = obs & 0x01;
b2 = obs & 0x02;
b3 = obs & 0x04;
b4 = obs & 0x08;
(m_pBlocks+y*m_cyBlocks+x)->byObstacle = (b1<<3) +
(b2<<1) + (b3>>1) + (b4>>3);
}
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
void CMapInfo::VerReverseBlock( int x, int y ) {
BYTE b1,b2,b3,b4,obs;
obs = (m_pBlocks+y*m_cyBlocks+x)->byObstacle;
if(obs != 0 && obs != 0x0f) {
b1 = obs & 0x01;
b2 = obs & 0x02;
b3 = obs & 0x04;
b4 = obs & 0x08;
(m_pBlocks+y*m_cyBlocks+x)->byObstacle = (b1<<1) +
(b2>>1) + (b3<<1) + (b4>>1);
}
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
int CMapInfo::BlockCounter( DWORD land, CObjBlock *pobb ) {
int counter = 0;
BLOCK *pblk;
for ( int i=0; i<m_cyBlocks-1; i++ )
for ( int j=0; j<m_cxBlocks-1; j++ ) {
pblk = m_pBlocks+i*m_cxBlocks+j;
if ( pblk->byClass == land ) {
if ( pobb ) {
pobb[counter].CreateObjBlock( j, i, land );
pobb[counter].SetTotalFrame( 3 );
}
counter++;
}
}
return counter;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
bool CMapInfo::BlockLocator( int x, int y, RECT *prc, int &level ) {
BLOCK *pblock = m_pBlocks + x + y*m_cxBlocks;
DWORD dwLocType;
level = LAYER_GROUND;
switch(pblock->byClass)
{
case LAND_BRICK:
dwLocType = LOC_BLOCK_BRICK0;
break;
case LAND_IRON:
dwLocType = LOC_BLOCK_IRON0;
break;
case LAND_RIVER:
dwLocType = LOC_BLOCK_RIVER0;
break;
case LAND_GRASS:
dwLocType = LOC_BLOCK_GRASS0;
level = LAYER_TREE;
break;
case LAND_ICE:
dwLocType = LOC_BLOCK_ICE0;
break;
case LAND_NONE:
default:
dwLocType = LOC_BLOCK_NONE;
}
int *pres = &ResArray[dwLocType][0];
prc->left = pblock->byObstacle * (*(pres+RESSIZE_WIDTH)) + (*(pres+RESPOS_LEFT));
prc->top = *(pres+RESPOS_TOP);
prc->right = prc->left + (*(pres+RESSIZE_WIDTH));
prc->bottom = prc->top + (*(pres+RESSIZE_HEIGHT));
return true;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
bool CMapInfo::ObjectLocator( CObject *pobj, RECT *prc, int &level ) {
DWORD type = pobj->GetType();
if ( type == OBJTYPE_TANK ) {
prc->top = RES_POST_TANK;
prc->left = RES_POSL_TANK;
prc->left += ((CObjTank *)pobj)->m_uiDirection - 1;
prc->left *= g_FrameSmall;
prc->top *= g_FrameSmall;
level = LAYER_TANK;
} else if ( type == OBJTYPE_BULLET ) {
prc->top = 128;
prc->left = pobj->GetFrameCurrent() * g_FrameSmall;
level = LAYER_BULLET;
} else if ( type == OBJTYPE_BASE ) {
prc->top = RES_POST_BASE;
prc->left = RES_POSL_BASE;
}
prc->right = prc->left + pobj->GetWidth();
prc->bottom = prc->top + pobj->GetHeight();
return true;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
bool CMapInfo::ObjBlockLocator( CObjBlock *poblk, RECT *prc, int &level ) {
if ( poblk->GetLand() == LAND_RIVER ) {
BLOCK *pblock = m_pBlocks + poblk->GetBx() +
poblk->GetBy()*m_cxBlocks;
prc->left = pblock->byObstacle + RES_POSL_LAND;
prc->top = RES_POST_LAND_RIVER + poblk->GetFrameCurrent();
prc->left *= g_FrameSmall;
prc->top *= g_FrameSmall;
prc->right = prc->left + g_FrameSmall;
prc->bottom = prc->top + g_FrameSmall;
level = LAYER_GROUND;
}
return true;
}
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
bool CMapInfo::ColR2R( RECT &rt_move, RECT rt_stable, POINT step ) {
bool intersect = false;
SetRect( &rt_move, rt_move.left - rt_stable.right, rt_move.top - rt_stable.bottom,
rt_move.right - rt_stable.left, rt_move.bottom - rt_stable.top );
while ( rt_move.left * rt_move.right < 0 && rt_move.top * rt_move.bottom < 0 ) {
intersect = true;
if ( step.x != 0 ) {
rt_move.left -= step.x;
rt_move.right -= step.x;
} else if ( step.y != 0 ) {
rt_move.top -= step.y;
rt_move.bottom -= step.y;
} else
break;
}
rt_move.left += rt_stable.right;
rt_move.top += rt_stable.bottom;
rt_move.right += rt_stable.left;
rt_move.bottom += rt_stable.top;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -