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

📄 cbmap.cpp

📁 经典游戏赤壁的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////
// CBMap.cpp	:	《赤壁》地图图素全局数据结构
// CBMap.cpp	:	<< chibi >> global map data structure
//
// v0010		:	Sep.18.1996
// v0011		:	Oct.16.1996
// v0012		:	Nov.7.1996
// v0013		:	Nov.22.1996
// v0014		:	Feb.5.1997
// v0020		:	Feb.28.1997
// v0030		:	May.14.1997, changed so many things, especialy for testregion
//
// 编写			:	刘刚
// written by	:	Liu Gang
//
// 编译器		:	Visual C++ 4.2
// Compiler		:	Visual C++ 4.2
//
// 版权			:	北京前导软件有限公司		1996-1997
// Copyright	:	WayAhead Software Co.Ltd.	1996-1997
/////////////////
// 此文件包所有对地形和单元图素的操作

#include "stdafx.h"
#include "Assert.h"	// Error message

#include "CBMap.h"
#include "CBEyes.h"	// EYE_IfOutOfRange()
#include "CBGame.h"

///////////
// 全局量,mostly used in this file
///////////
// 地形图素数据数组
WORD MAP_wGroundData[MAP_DATA_THICK][MAP_DATA_WIDTH][MAP_DATA_HEIGHT];
// 单元图素数据数组
WORD MAP_wUnitData[MAP_DATA_WIDTH][MAP_DATA_HEIGHT];
// 区域数据数组,内部使用
// 但是不要直接访问,而是使用MAP_GetRegionData(),除非特别需要速度的地方(频繁调用的地方)。
WORD MAP_wRegionData[MAP_DATA_WIDTH][MAP_DATA_HEIGHT];
// 地形图素总库
struct MAP_LIB_STRUCT	MAP_Lib;
///////////

///////////
//    0
//  7   1
//6       2
//  5   3
//    4
// 以某点为中心,周围MAP_SENSER_MAX点远的所有点的相对坐标
// First Dimension:		Even or Odd
// Second Dimension:	Distance from center
// Third Dimension:		max senser items
POINT MAP_ptSenser[2][MAP_SENSER_MAX][8*MAP_SENSER_MAX];
int MAP_nLocationNum[4] = { 1, 4, 9, 16 };
int MAP_nDrawNum[4] = { 0, 1, 3, 5 };
///////////

///////////
//      F
//    B   E
//  A   8   D
//9   5   7   C
//  4   3   6
//    1   2
//      0
//
// 单元所占位置的相对坐标
// first dimension:		Even or Odd
POINT MAP_ptLocation[2][MAP_LOCATION_MAX]=
{	{{0,0},{-1,-1},{0,-1},
	{0,-2},{-1,-2},{-1,-3},
	{1,-2},{0,-3},{0,-4},
	{-2,-3},{-1,-4},{-1,-5},
	{1,-3},{1,-4},{0,-5},{0,-6}},
	{{0,0},{0,-1},{1,-1},
	{0,-2},{-1,-2},{0,-3},
	{1,-2},{1,-3},{0,-4},
	{-1,-3},{-1,-4},{0,-5},
	{2,-3},{1,-4},{1,-5},{0,-6}}
};	// 单元所占地图位置数组(偶数)
///////////

// Local functions
///////////
// only called by MAP_TestRegion()
// 检测是否可以在点上修建建筑,return 10 if successful
// nLayer		:	层号
// pt			:	测试点,格子为单位
// codeU		:	建筑代码(压缩)
// codeUEx		:	出发点的单元,检测时可以取得此点,MAP_DATA_NONE时无效
// return value	:	错误代码,见上
int MAP_testPointRegion( int nLayer, POINT pt, DWORD codeU, WORD codeUEx = MAP_DATA_NONE );

// 移动显示图素
// nColFrom	:	出发点行
// nRowFrom	:	出发点列
// nColTo	:	目的点行
// nRowTo	:	目的点列
void MAP_MoveUnitData( int nColFrom, int nRowFrom, int nColTo, int nRowTo );
///////////

// 初始化
///////////
// 初始化图素数据(Unit, Ground, Region)
// initialize ground, unit, region data and map library
void MAP_InitMap()
{
	MAP_ResetGround();
	MAP_ResetUnit();
	MAP_ResetRegion();
	MAP_InitMapLib();
}

// initialize ground, unit, region data
void MAP_InitGUR()
{
	MAP_ResetGround();
	MAP_ResetUnit();
	MAP_ResetRegion();
}

// initialize map library
void MAP_InitMapLib()
{
	memset( &MAP_Lib, 0, sizeof(struct MAP_LIB_STRUCT ) );
}

// 初始化地形图素数据
void MAP_ResetGround()
{
	memset( MAP_wGroundData, MAP_DATA_NONE, sizeof(WORD)*MAP_DATA_THICK*MAP_DATA_WIDTH*MAP_DATA_HEIGHT );
}

// 初始化单元图素数据
void MAP_ResetUnit()
{
	memset( MAP_wUnitData, MAP_DATA_NONE, sizeof(WORD)*MAP_DATA_WIDTH*MAP_DATA_HEIGHT );
}

// 初始化区域图素数据
void MAP_ResetRegion()
{
	memset( MAP_wRegionData, 0xFF, sizeof(WORD)*MAP_DATA_WIDTH*MAP_DATA_HEIGHT );
}
///////////

// 地形图素
///////////
// 对地形图素解码
// 在调用此函数之前应该判断code值是否为MAP_DATA_NONE
// codeG	:	地形图素代码(压缩)(入口)
// pstctG	:	地形图素代码(展开)(出口)
inline void MAP_GroundDeCode(WORD codeG, struct MAP_GROUND_CODE_STRUCT * pstctG)
{
	memset( pstctG, 0, sizeof( MAP_GROUND_CODE_STRUCT ) );

	pstctG->nRow=codeG&0x0F;
	codeG=codeG>>4;
	pstctG->nCol=codeG&0x0F;
	codeG=codeG>>4;
	pstctG->nFile=codeG&0x0F;
	codeG=codeG>>4;
	pstctG->nAttr=codeG&0x0F;
}

// 对地形图素加码
// stctG		:	地形图素代码(展开)(入口)
// return value	:	地形图素代码(压缩)(出口)
inline WORD MAP_GroundEnCode(struct MAP_GROUND_CODE_STRUCT stctG)
{
	WORD codeG=0;
	codeG=stctG.nAttr&0x0F;
	codeG=codeG<<4;
	codeG|=stctG.nFile&0x0F;
	codeG=codeG<<4;
	codeG|=stctG.nCol&0x0F;
	codeG=codeG<<4;
	codeG|=stctG.nRow&0x0F;
	return codeG;
}

// 取得地形图素数据
// nLayer		:	层号
// nCol			:	列号
// nRow			:	行号
// return value	:	地形图素代码(压缩)
inline WORD MAP_GetGroundData( int nLayer, int nCol, int nRow )
{
	return MAP_wGroundData[nLayer][nCol][nRow];
}

// 设置地形图素数据
// nLayer	:	层号
// nCol		:	列号
// nRow		:	行号
// codeG	:	地形图素代码(压缩)
inline void MAP_SetGroundData( int nLayer, int nCol, int nRow, WORD codeG )
{
	MAP_wGroundData[nLayer][nCol][nRow] = codeG;
}

// 得到地形图素在屏幕的相对位置和大小(点)
// lprcS		:	屏幕内格子的相对坐标指针(入口)
// nLayer		:	层号
// nCol			:	列号
// nRow			:	行号
// nFile		:	文件号
// return value	:	地形图素在屏幕的相对位置和大小(点)
RECT MAP_GetGroundRect( CONST POINT ptOff, int nLayer, int nCol, int nRow, int nFile )
{
	int left, top;
	int width = MAP_Lib.Ground[nFile].szItem.cx;
	int height = MAP_Lib.Ground[nFile].szItem.cy;
	RECT rect;

	// calc top-left position on screen
	top = nRow*MAP_Lib.szItem.cy>>1;
	top -= MAP_Lib.nHeight[nLayer];
	top -= MAP_Lib.Ground[nFile].nHeight;
	if( (nRow&1) == 0 )
	{
		left = nCol*MAP_Lib.szItem.cx;
	}
	else
	{
		left = nCol*MAP_Lib.szItem.cx+(MAP_Lib.szItem.cx>>1);
	}

	// re-adjust coords
	left -= ptOff.x;
	top -= ptOff.y;
	
	rect.left = left, rect.top = top, 
	rect.right = left+width, rect.bottom = top + height;
	return rect;
}
///////////

// 单元图素
///////////
// 对单元图素解码
// 在调用此函数之前应该判断code值是否为MAP_DATA_NONE
// codeU	:	单元图素代码(压缩)(入口)
// pstctU	:	单元图素代码(展开)(出口)
inline void MAP_UnitDeCode(DWORD codeU, struct MAP_UNIT_CODE_STRUCT * pstctU)
{
	memset( pstctU, 0, sizeof( MAP_UNIT_CODE_STRUCT ) );

	pstctU->nRow=codeU&0x0F;
	codeU=codeU>>4;
	pstctU->nCol=codeU&0x3F;
	codeU=codeU>>6;
	pstctU->nFile=codeU&0x3F;
	codeU=codeU>>6;
	pstctU->nPlayer=codeU&0x0F;
	codeU=codeU>>4;
	pstctU->nLayer=codeU&0x03;

	Assert( pstctU->nLayer < 3 );
}

// 对单元图素加码
// stctU		:	单元图素代码(展开)(入口)
// return value	:	单元图素代码(压缩)(出口)
inline DWORD MAP_UnitEnCode(struct MAP_UNIT_CODE_STRUCT stctU)
{
	DWORD codeU=0;
	codeU|=stctU.nLayer&0x03;
	codeU=codeU<<4;
	codeU|=stctU.nPlayer&0x0F;
	codeU=codeU<<6;
	codeU|=stctU.nFile&0x3F;
	codeU=codeU<<6;
	codeU|=stctU.nCol&0x3F;
	codeU=codeU<<4;
	codeU|=stctU.nRow&0x0F;
	return codeU;
}

// 对单元图素数据进行操作
// 得到单元数据(压缩)
// nCol			:	列号
// nRow			:	行号
// return value	:	单元数据(压缩)
DWORD MAP_GetUnitData( int nCol, int nRow )
{
	// get data
	WORD code = MAP_wUnitData[nCol][nRow];
	if( code == MAP_DATA_NONE ) return MAP_DATA_NONE;

	WORD counter = code&0x0FFF;
	code = code>>12;
	struct UNIT_STRUCT *pUnit = &GAME.Players[code].Unit[counter];
	
	// set data 
	struct MAP_UNIT_CODE_STRUCT stct;
	stct.nPlayer = code;
	stct.nFile = pUnit->Draw.nFile;
	stct.nCol = pUnit->Draw.nCol;
	stct.nRow = pUnit->Draw.nRow;
	stct.nLayer = pUnit->Draw.nLayer;

	Assert( stct.nLayer < 3 );
	// encode to lib data
	return MAP_UnitEnCode( stct );
}

// 得到显示/设置数据(压缩)
// 产生单元数据和删除单元数据,都在这一个函数里
// 但是只被CTRL_UNIT_Create()和CTRL_UNIT_Destroy()调用
// 外部函数在产生或删除单元时不直接使用这个函数
// nCol			:	列号,目的位置
// nRow			:	行号,目的位置
// codeU		:	单元数据(压缩)
// return value	:	产生的单元压缩代码Ex(codeUEx)
WORD MAP_SetUnitData( int nLayer, int nX, int nY, DWORD dcodeU )
{
	// if should erase
	if( dcodeU == MAP_DATA_NONE )
	{
		WORD code = MAP_wUnitData[nX][nY];
		Assert( code != MAP_DATA_NONE );
		if( code != MAP_DATA_NONE )
		{
			WORD counter = code&0x0FFF;
			code = code>>12;
			struct UNIT_STRUCT *pUnit = &GAME.Players[code].Unit[counter];
			POINT pt;
			int bOdd = pUnit->Draw.nY&1;	// TRUE if Odd
			for( int i=0; i<MAP_nLocationNum[pUnit->Draw.nLocationSize]; i++ )
			{
				pt.x = pUnit->Draw.nX + MAP_ptLocation[bOdd][i].x;
				pt.y = pUnit->Draw.nY + MAP_ptLocation[bOdd][i].y;
				MAP_wUnitData[pt.x][pt.y] = MAP_DATA_NONE;
			}
			if( pUnit->nType == MAP_UNIT_TYPE_NONE )
				OutputDebugString( " CBMap Warning(0): the unit has been deleted! " );
			else
				GAME.Players[code].wUnitCounter--;
			pUnit->nType = MAP_UNIT_TYPE_NONE;
		}
		return MAP_DATA_NONE;
	}

	// decode from lib data
	struct MAP_UNIT_CODE_STRUCT stct;
	MAP_UnitDeCode( dcodeU, &stct );
#ifdef	_DEBUG
	if( stct.nPlayer >= GAME_PLAYER_MAX )
	{
		OutputDebugString( "MAP_SetUnitData Error(0): Error in Decode! Player ID is too large!\n" );
		return MAP_DATA_NONE;
	}
#endif // _DEBUG
	// try to find next room to fit the unit
	WORD	wUnitID = GAME.Players[stct.nPlayer].wLastUnit;
	WORD	wCount = 0;

	// Dec.1.1997
	do
	{
		wCount++;
		wUnitID++;
		if( wUnitID >= PLAYER_UNIT_MAX )	
		{
			wUnitID = 0;
			OutputDebugString( "MAP_SetUnitData Message(0): back to the head\n" );
			//return MAP_DATA_NONE;	// no room to store the unit
		}
		if( wCount >= PLAYER_UNIT_MAX-1 )
		{	// 队列满了
			return MAP_DATA_NONE;
		}
	}
	while( GAME.Players[stct.nPlayer].Unit[wUnitID].nType != MAP_UNIT_TYPE_NONE );

	GAME.Players[stct.nPlayer].wLastUnit = wUnitID;
	GAME.Players[stct.nPlayer].wUnitCounter++;

	// get data
	WORD code=0;
	code = stct.nPlayer<<12;
	code |= wUnitID;
	struct UNIT_STRUCT *pUnit = &GAME.Players[stct.nPlayer].Unit[wUnitID];

	// initialize
	memset( pUnit, 0, sizeof( struct UNIT_STRUCT ) );

	// 设置内容到结构中
	pUnit->nID = code;	// 将压缩代码置到结构中
	pUnit->nType = MAP_Lib.Unit[stct.nFile].nType;

#ifdef	_DEBUG
	if( pUnit->nType == MAP_UNIT_TYPE_NONE )
	{
		OutputDebugString( "MAP_SetUnitData Error(2): Error in decode! The type of new unit is NONE!\n" );
		return MAP_DATA_NONE;
	}
#endif // _DEBUG

	// 设置显示内容
	pUnit->Draw.bUpdate = FALSE;
	pUnit->Draw.nPlayer = stct.nPlayer;
	pUnit->Draw.nFile = stct.nFile;
	pUnit->Draw.nLayer = nLayer;
	Assert( nLayer < 3 );
	//pUnit->Draw.nFrame = 0;

	int nLocationSize = MAP_Lib.Unit[stct.nFile].nLocationSize;
	pUnit->Draw.nX = nX;
	pUnit->Draw.nY = nY;
	{
		// set display position
		int bOdd = nY&1;
		pUnit->Draw.nDrawX = nX + (WORD)MAP_ptLocation[bOdd][MAP_nDrawNum[nLocationSize]].x;
		pUnit->Draw.nDrawY = nY + (WORD)MAP_ptLocation[bOdd][MAP_nDrawNum[nLocationSize]].y;
	}
	pUnit->Draw.nLocationSize = nLocationSize;
#ifdef	_MAP_COMPRESS_
	pUnit->Draw.nCol = MAP_Lib.AniSeq[pUnit->Draw.nFile].nAniSeq[pUnit->Draw.nState][pUnit->Draw.nFrame]+MAP_Lib.AniSeq[pUnit->Draw.nFile].nOffset;
	pUnit->Draw.nRow = 0;
#else
	pUnit->Draw.nRow = stct.nRow;
	pUnit->Draw.nCol = stct.nCol;
#endif

	//pUnit->Draw.ptOff.x = 0;
	//pUnit->Draw.ptOff.y = 0;

	pUnit->Draw.nXLast = nX;
	pUnit->Draw.nYLast = nY;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -