📄 cbmap.cpp
字号:
/////////////////
// 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 + -