📄 cbmap.cpp
字号:
//pUnit->Draw.ptOffLast.x = 0;
//pUnit->Draw.ptOffLast.y = 0;
POINT pt;
int bOdd = nY&1; // TRUE if Odd
for( int i=0; i<MAP_nLocationNum[pUnit->Draw.nLocationSize]; i++ )
{
pt.x = nX + MAP_ptLocation[bOdd][i].x;
pt.y = nY + MAP_ptLocation[bOdd][i].y;
WORD codeUEx = MAP_wUnitData[pt.x][pt.y];
Assert( codeUEx == MAP_DATA_NONE );
#ifdef _DEBUG
if( codeUEx != MAP_DATA_NONE )
OutputDebugString( ";" );
#endif
MAP_wUnitData[pt.x][pt.y] = code;
}
return code;
}
// 直接得到数组内数据
// nCol : 列号
// nRow : 行号
// return value : 单元数据(但不是压缩码)
inline WORD MAP_GetUnitDataEx( int nCol, int nRow )
{
return MAP_wUnitData[nCol][nRow];
}
// 直接设置数组内数据
// nCol : 列号
// nRow : 行号
// wCode : 单元数据(但不是压缩码)
inline void MAP_SetUnitDataEx( int nCol, int nRow, WORD wCode )
{
MAP_wUnitData[nCol][nRow] = wCode;
}
// 得到显示图素数据,此函数专门用于显示
// 当输入的行列号不在该单元的显示位置时,则返回失败
// nCol : 列号
// nRow : 行号
// pstctCF : 帧数据结构(出口)
// reutrn value : TRUE if succeeded
BOOL MAP_GetUnitFrameData( int nCol, int nRow, struct CTRL_FRAME_STRUCT *pstctCF, BOOL bDone/*=TRUE*/ )
{
// get data
WORD code = MAP_wUnitData[nCol][nRow];
if( code == MAP_DATA_NONE ) return FALSE;
WORD counter = code&0x0FFF;
code = code>>12;
struct UNIT_STRUCT *pUnit = &GAME.Players[code].Unit[counter];
struct CTRL_FRAME_STRUCT *pDraw = &pUnit->Draw;
Assert( pDraw->nLayer < 3 );
// if should display in the right position
if( pDraw->nDrawX != nCol || pDraw->nDrawY != nRow )
return FALSE;
// set data
memcpy( pstctCF, pDraw, sizeof(struct CTRL_FRAME_STRUCT) );
/*
pstctCF->bUpdate = pDraw->bUpdate;
pstctCF->nPlayer = pDraw->nPlayer;
pstctCF->nFile = pDraw->nFile;
pstctCF->nLayer = pDraw->nLayer;
pstctCF->nFrame = pDraw->nFrame;
pstctCF->nX = pDraw->nX;
pstctCF->nY = pDraw->nY;
pstctCF->nDrawX = pDraw->nDrawX;
pstctCF->nDrawY = pDraw->nDrawY;
pstctCF->nCol = pDraw->nCol;
pstctCF->nRow = pDraw->nRow;
pstctCF->nState = pDraw->nState;
pstctCF->nDir = pDraw->nDir;
pstctCF->nLocationSize = pDraw->nLocationSize;
pstctCF->ptOff.x = pDraw->ptOff.x,
pstctCF->ptOff.y = pDraw->ptOff.y;
pstctCF->nXLast = pDraw->nXLast;
pstctCF->nYLast = pDraw->nYLast;
pstctCF->ptOffLast.x = pDraw->ptOffLast.x;
pstctCF->ptOffLast.y = pDraw->ptOffLast.y;
*/
// set update to FALSE
// if( bDone )
// pDraw->bUpdate = FALSE;
return TRUE;
}
// 移动显示图素
// nColFrom : 出发点行
// nRowFrom : 出发点列
// nColTo : 目的点行
// nRowTo : 目的点列
void MAP_MoveUnitData( int nColFrom, int nRowFrom, int nColTo, int nRowTo )
{
WORD code = MAP_wUnitData[nColFrom][nRowFrom];
MAP_wUnitData[nColTo][nRowTo] = code;
MAP_wUnitData[nColFrom][nRowFrom] = MAP_DATA_NONE;
}
// 移动整个单元
// 当目的位置被其它单元占据时返回失败
// 只被CTRL_UNIT_Move()调用,其他人不直接调用此函数
// only used by CTRL_UNIT_Move()
// pDraw : unit control frame struct 单元帧控制结构
// nType : type of unit
// return value : TRUE if succeeded
BOOL MAP_MoveUnit( struct CTRL_FRAME_STRUCT *pDraw, int nType )
{
int i;
WORD codeUEx, codeUExLast;
int nX[16], nY[16], nXLast[16], nYLast[16];
int nNum = MAP_nLocationNum[pDraw->nLocationSize];
codeUExLast = MAP_wUnitData[pDraw->nXLast][pDraw->nYLast];
int bOdd = pDraw->nY&1;
int bOddLast = pDraw->nYLast&1;
for( i=0; i<nNum; i++ )
{
nXLast[i] = pDraw->nXLast+MAP_ptLocation[bOddLast][i].x;
nYLast[i] = pDraw->nYLast+MAP_ptLocation[bOddLast][i].y;
nX[i] = pDraw->nX+MAP_ptLocation[bOdd][i].x;
nY[i] = pDraw->nY+MAP_ptLocation[bOdd][i].y;
if( nX[i] < 2 ) return FALSE;
if( nY[i] < 5 ) return FALSE;
if( nX[i] > MAP_Lib.szNum.cx-3 ) return FALSE;
if( nY[i] > MAP_Lib.szNum.cy-2 ) return FALSE;
#ifdef _DEBUG
// check footprint
codeUEx = MAP_wUnitData[nXLast[i]][nYLast[i]];
if( codeUEx != codeUExLast )
OutputDebugString( "MAP_MoveUnit Warning(0): :\n" );
#endif
codeUEx = MAP_wUnitData[nX[i]][nY[i]];
// test if there is some one (not me) in front of me
if( codeUEx != MAP_DATA_NONE &&
codeUEx != codeUExLast )
return FALSE; // someone blocked him
// test if there is a hill here
if( pDraw->nLayer < 2 )
if( MAP_GetGroundData( pDraw->nLayer+1, nX[i], nY[i] ) != MAP_DATA_NONE )
return FALSE;
// test if cannot move there
WORD codeG = MAP_GetGroundData( pDraw->nLayer, nX[i], nY[i] );
if( codeG == MAP_DATA_NONE ) return FALSE;
struct MAP_GROUND_CODE_STRUCT stctG;
MAP_GroundDeCode( codeG, &stctG );
if( stctG.nAttr != MAP_SPECIAL_NONE
&& stctG.nAttr != MAP_SPECIAL_CUT_WOOD
&& stctG.nAttr != MAP_SPECIAL_CUT_WHEAT ) // cannot move in Forest and Field
// && GroundDeCode.nAttr != MAP_SPECIAL_CUT_WOOD
// && GroundDeCode.nAttr != MAP_SPECIAL_CUT_WHEAT ) // cannot move in Forest and Field
{
return FALSE;
}
if( nType == MAP_UNIT_TYPE_SHIP
|| nType == MAP_UNIT_TYPE_SGEN )
{ // ship cannot move out of water
if( stctG.nFile != 3 || stctG.nCol != 12 ) // 水
{
return FALSE;
}
}
else if( nType == MAP_UNIT_TYPE_SOLDIER
|| nType == MAP_UNIT_TYPE_LADDER
|| nType == MAP_UNIT_TYPE_WORKER
|| nType == MAP_UNIT_TYPE_MAN
|| nType == MAP_UNIT_TYPE_WGEN
|| nType == MAP_UNIT_TYPE_GEN )
{ // others cannot move in water
if( stctG.nFile == 3 && stctG.nCol == 12 ) // 水
{
return FALSE;
}
}
}
// set display position
pDraw->nDrawX = pDraw->nX + (WORD)MAP_ptLocation[bOdd][MAP_nDrawNum[pDraw->nLocationSize]].x;
pDraw->nDrawY = pDraw->nY + (WORD)MAP_ptLocation[bOdd][MAP_nDrawNum[pDraw->nLocationSize]].y;
// Erase old footprint
for( i=0; i<nNum; i++ )
{
#ifdef _DEBUG
// check footprint
codeUEx = MAP_wUnitData[nXLast[i]][nYLast[i]];
if( codeUEx != codeUExLast )
OutputDebugString( "MAP_MoveUnit Warning(1): ,\n" );
#endif // _DEBUG
MAP_wUnitData[nXLast[i]][nYLast[i]] = MAP_DATA_NONE;
}
// draw new footprint
for( i=0; i<nNum; i++ )
{
#ifdef _DEBUG
// check footprint
codeUEx = MAP_wUnitData[nX[i]][nY[i]];
if( codeUEx != MAP_DATA_NONE )
OutputDebugString( "MAP_MoveUnit Warning(2): .\n" );
#endif // _DEBUG
MAP_wUnitData[nX[i]][nY[i]] = codeUExLast;
}
return TRUE;
}
// 得到单元结构
// nCol : 列号
// nRow : 行号
// return value : 单元结构指针
inline struct UNIT_STRUCT *MAP_GetUnit( int nCol, int nRow )
{
// get data
WORD code = MAP_wUnitData[nCol][nRow];
if( code == MAP_DATA_NONE )
{
// WriteLogFile( "Test.log","MAP_GetUnit()\n" );
// OutputDebugString( "MAP_GetUnit0 Warning: unit is NULL!\n" );
return NULL;
}
WORD counter = code&0x0FFF;
code = code>>12;
struct UNIT_STRUCT *pUnit = &GAME.Players[code].Unit[counter];
return pUnit;
}
// 得到单元结构
// dwCode : 单元的压缩代码
// return value : 单元结构指针
inline struct UNIT_STRUCT *MAP_GetUnit( WORD wCode )
{
struct UNIT_STRUCT *pUnit=NULL;
WORD counter;
if( wCode == MAP_DATA_NONE )
{
// WriteLogFile( "Test.log","MAP_GetUnit()AAA\n" );
OutputDebugString( "MAP_GetUnit Warning: unit is NULL!\n" );
return NULL;
}
counter = wCode&0x0FFF;
wCode = wCode>>12;
pUnit = &GAME.Players[wCode].Unit[counter];
return pUnit;
}
// 得到单元图素在屏幕的相对位置和大小(点)
// lprcS : 屏幕内格子的相对坐标指针(入口)
// pstctCF : 帧结构指针(入口)
// return value : 单元图素在屏幕的相对位置和大小(点)
RECT MAP_GetUnitRect( CONST POINT ptOff, CONST struct CTRL_FRAME_STRUCT *lpstctCF )
{
int top, left;
int width = MAP_Lib.Unit[lpstctCF->nFile].szItem.cx;
int height = MAP_Lib.Unit[lpstctCF->nFile].szItem.cy;
RECT rect;
// calc top-left position on screen
top = (lpstctCF->nY*MAP_Lib.szItem.cy>>1)+MAP_Lib.szItem.cy;
top -= MAP_Lib.nHeight[lpstctCF->nLayer+1];
top -= lpstctCF->nOff_Z;
top -= height;
if( (lpstctCF->nY&1) == 0 )
{
left = lpstctCF->nX*MAP_Lib.szItem.cx;
}
else
{
left = lpstctCF->nX*MAP_Lib.szItem.cx+(MAP_Lib.szItem.cx>>1);
}
// if( lpstctCF->nLocationSize == 2 )
// left = left - MAP_Lib.szItem.cx;
// else
left = left + (MAP_Lib.szItem.cx>>1) - (width>>1);
// re-adjust coords to relative
left = left - ptOff.x + lpstctCF->ptOff.x;
top = top - ptOff.y + lpstctCF->ptOff.y;
rect.left = left, rect.top = top,
rect.right = left + width, rect.bottom = top + height;
return rect;
}
// 得到单元的旧相对位置和大小,用于在旧位置上擦除该单元
// lprcS : 屏幕内格子的相对坐标指针
// pstctCF : 帧结构指针(入口)
// return value : 单元图素在屏幕的上一个位置的相对位置和大小(点)
RECT MAP_GetUnitRectLast( CONST POINT ptOff, CONST struct CTRL_FRAME_STRUCT *lpstctCF )
{
int top, left;
int width = MAP_Lib.Unit[lpstctCF->nFile].szItem.cx;
int height = MAP_Lib.Unit[lpstctCF->nFile].szItem.cy;
RECT rect;
// calc top-left position on screen
top = (lpstctCF->nYLast*MAP_Lib.szItem.cy>>1)+MAP_Lib.szItem.cy;
top -= MAP_Lib.nHeight[lpstctCF->nLayer+1];
top -= height;
if( (lpstctCF->nYLast&1) == 0 )
{
left = lpstctCF->nXLast*MAP_Lib.szItem.cx;
}
else
{
left = lpstctCF->nXLast*MAP_Lib.szItem.cx+(MAP_Lib.szItem.cx>>1);
}
// if( lpstctCF->nLocationSize == 2 )
// left = left - MAP_Lib.szItem.cx;
// else
left = left + (MAP_Lib.szItem.cx>>1) - (width>>1);
// re-adjust coords to relative
left = left - ptOff.x + lpstctCF->ptOffLast.x;
top = top - ptOff.y + lpstctCF->ptOffLast.y;
rect.left = left, rect.top = top,
rect.right = left+width, rect.bottom = top + height;
return rect;
}
///////////
// 特殊图素
///////////
// 得到显示图素数据,return not null for pstct is valid
// nLayer : 层号
// nCol : 列号
// nRow : 行号
// nAttr : 属性
// pstctCF : 帧结构指针(出口)
// reutrn value : TRUE if succeeded
BOOL MAP_GetSpecFrameData( int nLayer, int nCol, int nRow, int nAttr, struct CTRL_FRAME_STRUCT *pstctCF )
{
// decode
int nA = nAttr%4;
int nB = nAttr/4;
DWORD codeU = MAP_Lib.Special[nA];
if( codeU == MAP_DATA_NONE ) return FALSE;
struct MAP_UNIT_CODE_STRUCT stctU;
MAP_UnitDeCode( codeU, &stctU );
// set data
pstctCF->bUpdate = FALSE;
pstctCF->nPlayer = stctU.nPlayer;
pstctCF->nFile = stctU.nFile;
pstctCF->nLayer = nLayer;
Assert( nLayer < 3 );
pstctCF->nFrame = 0;
pstctCF->nX = nCol;
pstctCF->nY = nRow;
pstctCF->nDrawX = nCol;
pstctCF->nDrawY = nRow;
#ifdef _MAP_COMPRESS_
pstctCF->nCol = stctU.nRow*2 + stctU.nCol+MAP_Lib.AniSeq[stctU.nFile].nOffset;
if( nB == 2 ) pstctCF->nCol += 1; // 被砍伐掉了
pstctCF->nRow = 0; //stctU.nRow;
#else
pstctCF->nCol = stctU.nCol;
pstctCF->nRow = stctU.nRow;
#endif
pstctCF->nState = 0;
pstctCF->nDir = 0;
// pstctCF->nMaxFrame = 1;
pstctCF->nLocationSize = 0;
pstctCF->ptOff.x = 0;
pstctCF->ptOff.y = 0;
pstctCF->nXLast = pstctCF->nX;
pstctCF->nYLast = pstctCF->nY;
pstctCF->ptOffLast.x = 0;
pstctCF->ptOffLast.y = 0;
return TRUE;
}
///////////
// 区域图素
///////////
// 对区域图素解码
// 在调用此函数之前应该判断code值是否为MAP_DATA_NONE
// codeR : 区域图素(压缩)(入口)
// pstctR : 区域图素(展开)(出口)
inline void MAP_RegionDeCode(WORD codeR, struct MAP_REGION_CODE_STRUCT * pstctR)
{
memset( pstctR, 0, sizeof( MAP_REGION_CODE_STRUCT ) );
pstctR->nPlayer=codeR&0x0F;
codeR=codeR>>4;
pstctR->nShadow=codeR&0x0F;
codeR=codeR>>4;
pstctR->nShadowEx=codeR&0x0F;
}
// 对区域图素加码
// stctR : 区域图素(展开)(入口)
// return value : 区域图素(压缩)(出口)
inline WORD MAP_RegionEnCode(struct MAP_REGION_CODE_STRUCT stctR)
{
WORD codeR=0;
codeR|=0x0F;
codeR=codeR<<4;
codeR|=stctR.nShadowEx&0x0F;
codeR=codeR<<4;
codeR|=stctR.nShadow&0x0F;
codeR=codeR<<4;
codeR|=stctR.nPlayer&0x0F;
return codeR;
}
// 对区域数据进行操作
// 对区域数据的操作
// 填充区域, 递归函数
// pt : 填充点种子,格子为单位
// nPlayer : 填充内容,游戏者编号
int MAP_nRegionStack=0;
#define MAP_REGION_STACK_MAX 1024
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -