⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cbmap.cpp

📁 经典游戏赤壁的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	//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 + -