📄 cbctrls.cpp
字号:
//////////////////////
// local functions
// 在刚刚创建单元后,使用此函数对该单元赋给属性值
void CTRL_SetUnitAttribute( struct UNIT_STRUCT *pUnit )
{
//switch( pUnit->nType
}
//////////////////////
// 部队
//////////////////////
// 根据将领的编号产生部队
// nZ, nX, nY : position to locate,产生的位置
// nGenNum : general index number in DATA_Lib
// nPlayer : player to be added to
// nType : troop type
// return : general ID extended code if successful,
// MAP_DATA_NONE if failed
WORD CTRL_GROUP_Create( int nZ, int nX, int nY, DWORD nGenNum, int nPlayer, int nType )
{
// 从将领的类型得到单元种类编号
int nGenFile[4]={35,31,33,29};
if( nGenNum <= 0 || nGenNum > 118 ) return MAP_DATA_NONE; // 超过范围
DWORD codeU = MAP_Lib.Unit[nGenFile[DATA_Lib.Gen[nGenNum].nType-1]].nItems[0];
// 设置游戏者
struct MAP_UNIT_CODE_STRUCT stctU;
MAP_UnitDeCode( codeU, &stctU );
stctU.nPlayer = nPlayer;
if( nType == MAP_UNIT_TYPE_SGEN )
stctU.nFile = 52; // 如果是水军将领,则变为大战船
codeU = MAP_UnitEnCode( stctU );
// 创建单元
WORD codeUEx = CTRL_UNIT_Create( nZ, nX, nY, codeU );
if( codeUEx == MAP_DATA_NONE )
{
OutputDebugString( "CTRL_GROUP_Create Error(1): Cannot create unit!\n" );
return codeUEx;
}
struct UNIT_STRUCT *pUnit = MAP_GetUnit( codeUEx );
Assert( pUnit );
// 把该将领添加在将领数组中
BOOL bSuccess = FALSE;
for( int i=0; i< PLAYER_GROUP_MAX; i++ )
{
if( GAME.Players[nPlayer].wGroup[i] == MAP_DATA_NONE )
{
GAME.Players[nPlayer].wGroup[i] = codeUEx;
GAME.Players[nPlayer].wGroupCounter++;
bSuccess = TRUE;
break;
}
}
if( !bSuccess )
{
CTRL_UNIT_Destroy( pUnit );
//部队数不能超过20个,无法组建部队
FACE_ShowPromptInfor( 19 ) ;
return MAP_DATA_NONE;
}
// 设置其它属性
//pUnit->nType = MAP_UNIT_TYPE_GEN;
pUnit->nType = nType;
pUnit->Gen.nID = (WORD)nGenNum;
pUnit->Gen.nType = DATA_Lib.Gen[nGenNum].nType; // 将领的类型
DATA_Lib.Gen[nGenNum].bOnBattle = TRUE; // 在战场上了
// 生命值
pUnit->nLife = DATA_Lib.Gen[nGenNum].dwLife; // 重设置生命值
// 个人属性
// pUnit->Gen.nHealth = DATA_Lib.Gen[nGenNum].nHealth; // 将领的体力
pUnit->Gen.nMorale = 70; // 将领的初始士气
pUnit->Gen.nLineUp = 0; //阵型
// pUnit->Gen.nTactic = 0; // 谋略
// pUnit->Gen.nLevel = DATA_Lib.Gen[nGenNum].nLevel; // 将领的级别
// 如果是自己人,设置焦点状态
// if( EYE_IfSheIsMine( pUnit ) )
// pUnit->Draw.bUpdate = TRUE;
// 手下士兵数组,在CTRL_UNIT_Create()中做过了
// memset( pUnit->Gen.wTroop, MAP_DATA_NONE, sizeof( WORD )*GENERAL_TROOP_MAX );
if( GAME.nMe == nPlayer )
{
// 设置部队按钮,打开
// LHJ
FACE_SetNumberButtonState( i, BUTTON_UP, TRUE );
// LHJ
}
return codeUEx;
}
// 删除部队:解散部队,并删除将领单元
// pUnit : unit pointer to be destroyed
// return : TRUE if successful
BOOL CTRL_GROUP_Destroy( struct UNIT_STRUCT *pUnit )
{
int nPlayer;
WORD codeUEx;
#ifdef _DEBUG
{
Assert( pUnit );
Assert( EYE_IfUnitIsGen( pUnit ) );
for( int i=0; i<GENERAL_TROOP_MAX; i++ )
{
if( pUnit->Gen.wTroop[i] != MAP_DATA_NONE )
{
OutputDebugString( "CTRL_DestroyGrup Warning: Destroy general before release troops!\n" );
}
}
}
#endif
// 把将领从将领数据数组里永远删除
if( pUnit->nLife <= 0 )
DATA_Lib.Gen[pUnit->Gen.nID].nID = 0;
DATA_Lib.Gen[pUnit->Gen.nID].bOnBattle = FALSE; // 设置返回后台的标志
if( pUnit->nLife < 0 ) pUnit->nLife = 0;
// 生命值
DATA_Lib.Gen[pUnit->Gen.nID].dwLife = pUnit->nLife; // 保存生命值
nPlayer = pUnit->Draw.nPlayer;
codeUEx = pUnit->nID;
// changed on July 31, 1997
// 从将领数组中删除该将领
BOOL bSuccess = FALSE;
for( int i=0; i< PLAYER_GROUP_MAX; i++ )
{
if( GAME.Players[nPlayer].wGroup[i] == codeUEx )
{
GAME.Players[nPlayer].wGroup[i] = MAP_DATA_NONE;
GAME.Players[nPlayer].wGroupCounter--;
bSuccess = TRUE;
break;
}
}
if( !bSuccess )
{
OutputDebugString( "Cannot find general in general list!\n" );
}
else if( GAME.nMe == nPlayer )
{
// 设置部队按钮,关闭
// LHJ
FACE_SetNumberButtonState( i, BUTTON_DISABLE, TRUE );
// LHJ
}
// 直接删除
if( !CTRL_UNIT_Destroy( pUnit ) )
return FALSE;
return TRUE;
}
// 通过将领的编号寻找将领的ID
// nPlayer : player to search in
// nGenNum : Index number of general in DATA_Lib,将领的编号
// return : general ID extended code if successful,
// MAP_DATA_NONE if failed
WORD CTRL_GROUP_Find( int nPlayer, WORD nGenNum )
{
for( int i=0; i<PLAYER_GROUP_MAX; i++ )
{
WORD codeUEx = GAME.Players[nPlayer].wGroup[i];
if( codeUEx != MAP_DATA_NONE )
{
struct UNIT_STRUCT *pUnit = MAP_GetUnit( codeUEx );
Assert( pUnit );
if( pUnit->Gen.nID == nGenNum )
{
return codeUEx;
}
}
}
return MAP_DATA_NONE;
}
// 把单元直接加入到部队中
// pUnitG : pointer of the general to be added to
// pUnit : unit pointer to be added
// return : TRUE if successful
BOOL CTRL_GROUP_Add( struct UNIT_STRUCT *pUnitG, struct UNIT_STRUCT *pUnit )
{
for( int i=0; i<GENERAL_TROOP_MAX; i++ )
{
if( pUnitG->Gen.wTroop[i] == MAP_DATA_NONE )
{ // set relationship
// 把将领标识加到士兵里
pUnit->Soldier.nGenID = pUnitG->nID;
// 把士兵ID加到将领的士兵数组里
pUnitG->Gen.wTroop[i] = pUnit->nID;
return TRUE;
}
}
OutputDebugString( "CTRL_GROUP_Add Warning(10): Troop list is full!\n" );
return FALSE;
}
// 从部队中直接解散单元
// pUnit : unit pointer to be subed,将要被解散的部队
// return : TRUE if successful
BOOL CTRL_GROUP_Sub( struct UNIT_STRUCT *pUnit )
{
struct UNIT_STRUCT *pUnitG;
BOOL bDone = FALSE;
// 从将领的士兵数组中删除该士兵的标识
Assert( pUnit->Soldier.nGenID != MAP_DATA_NONE );
pUnitG = MAP_GetUnit( pUnit->Soldier.nGenID );
Assert( pUnitG );
Assert( EYE_IfUnitIsGen( pUnitG ) );
for( int i=0; i<GENERAL_TROOP_MAX; i++ )
{
if( pUnitG->Gen.wTroop[i] == pUnit->nID )
{
// 从士兵中删除将领的标识
pUnit->Soldier.nGenID = MAP_DATA_NONE;
// 将领的士兵数组中删除该士兵
pUnitG->Gen.wTroop[i] = MAP_DATA_NONE;
bDone = TRUE;
break;
}
}
if( !bDone )
{
OutputDebugString( "CTRL_GROUP_Sub Error(10): Not found itself in its general list!\n" );
return FALSE;// 删除失败,在自己的部队中没有找到自己
}
return TRUE;
}
// 从部队中解散手下的所有士兵
// pUnit : general pointer to sub soldiers from
// return : TRUE if successful
void CTRL_GROUP_ToSubAll( struct UNIT_STRUCT *pUnit )
{
struct UNIT_STRUCT *pU;
Assert( pUnit );
Assert( EYE_IfUnitIsGen( pUnit ) );
// 把将领是否在战场上的标志设置回来
DATA_Lib.Gen[pUnit->Gen.nID].bOnBattle = FALSE;
for( int i=0; i<GENERAL_TROOP_MAX; i++ )
{
if( pUnit->Gen.wTroop[i] != MAP_DATA_NONE )
{
pU = MAP_GetUnit( pUnit->Gen.wTroop[i] );
Assert( pU );
Assert( EYE_IfUnitIsSoldier( pU ) );
pU->Soldier.nGenID = MAP_DATA_NONE;
pUnit->Gen.wTroop[i] = MAP_DATA_NONE;
}
}
}
//////////////////////
// 其它
//////////////////////
// 一个单元走进建筑或上船
// bCheck : 为真时,要检测地面上是否有自己,如果是,把自己从地面清干净
void CTRL_UNIT_InUnit( struct UNIT_STRUCT *pUnit, BOOL bCheck/* = FALSE*/ )
{
Assert( pUnit->Status.bIRQ == FALSE );
Assert( pUnit->nHasShadow == 1 );
Assert( pUnit->Draw.ptOff.x == 0 && pUnit->Draw.ptOff.y == 0 );
// 把是谁攻击我去掉
pUnit->nIDAttackMe = MAP_DATA_NONE;
int bOdd = pUnit->Draw.nY&1;
int nXNext, nYNext;
if( bCheck )
{
for( int i=0; i<MAP_nLocationNum[pUnit->Draw.nLocationSize]; i++ )
{
nXNext = pUnit->Draw.nX + MAP_ptLocation[bOdd][i].x;
nYNext = pUnit->Draw.nY + MAP_ptLocation[bOdd][i].y;
if( MAP_GetUnitDataEx( nXNext, nYNext ) == pUnit->nID )
MAP_SetUnitDataEx( nXNext, nYNext, MAP_DATA_NONE );
}
}
else
{
for( int i=0; i<MAP_nLocationNum[pUnit->Draw.nLocationSize]; i++ )
{
nXNext = pUnit->Draw.nX + MAP_ptLocation[bOdd][i].x;
nYNext = pUnit->Draw.nY + MAP_ptLocation[bOdd][i].y;
Assert( MAP_GetUnitDataEx( nXNext, nYNext ) == pUnit->nID );
MAP_SetUnitDataEx( nXNext, nYNext, MAP_DATA_NONE );
}
}
// 擦掉阴影
if( GAME.nMe == pUnit->Draw.nPlayer )
{
int nSight = EYE_GetViewRange( &pUnit->Draw );
Assert( pUnit->nHasShadow == 1 );
SHADOW_death( pUnit->Draw.nX, pUnit->Draw.nY, nSight );
}
pUnit->nHasShadow--;
// erase from minimap
MINI_SetGroundData( pUnit->Draw.nXLast, pUnit->Draw.nYLast, pUnit->Draw.nLocationSize ); // for minimap
}
// 一个单元从建筑或船中走出来
// return : TRUE if successful
BOOL CTRL_UNIT_OutUnit( struct UNIT_STRUCT *pUnit )
{
Assert( pUnit->Status.bIRQ == TRUE );
Assert( pUnit->nHasShadow == 0 );
Assert( pUnit->Draw.ptOff.x == 0 && pUnit->Draw.ptOff.y == 0 );
#ifdef _DEBUG_OFFSET_
if( !(pUnit->Draw.ptOff.x == 0 && pUnit->Draw.ptOff.y == 0) )
{
pUnit->Draw.ptOff.x = pUnit->Draw.ptOff.y = 0;
// WriteLogFile( "off.log", "outunit\n" );
}
#endif //_DEBUG_OFFSET_
POINT ptNew = MAP_FindRegion( 0, pUnit->Draw.nX, pUnit->Draw.nY, MAP_Lib.Unit[pUnit->Draw.nFile].nItems[0] );
Assert( MAP_GetUnitDataEx( ptNew.x, ptNew.y ) == MAP_DATA_NONE );
// Assert( ptNew.x != -1 && ptNew.y != -1 );
if( ptNew.x==-1 || ptNew.y==-1 )
return FALSE;
pUnit->Draw.nXLast = pUnit->Draw.nX,
pUnit->Draw.nYLast = pUnit->Draw.nY;
pUnit->Draw.nX = (WORD)ptNew.x, pUnit->Draw.nY = (WORD)ptNew.y;
// set display position
int bOdd = pUnit->Draw.nY&1;
pUnit->Draw.nDrawX = pUnit->Draw.nX + (WORD)MAP_ptLocation[bOdd][MAP_nDrawNum[pUnit->Draw.nLocationSize]].x;
pUnit->Draw.nDrawY = pUnit->Draw.nY + (WORD)MAP_ptLocation[bOdd][MAP_nDrawNum[pUnit->Draw.nLocationSize]].y;
int nXNext, nYNext;
for( int i=0; i<MAP_nLocationNum[pUnit->Draw.nLocationSize]; i++ )
{
nXNext = pUnit->Draw.nX + MAP_ptLocation[bOdd][i].x;
nYNext = pUnit->Draw.nY + MAP_ptLocation[bOdd][i].y;
Assert( MAP_GetUnitDataEx( nXNext, nYNext ) == MAP_DATA_NONE );
MAP_SetUnitDataEx( nXNext, nYNext, pUnit->nID );
}
// 重现阴影
if( GAME.nMe == pUnit->Draw.nPlayer )
{
int nSight = EYE_GetViewRange( &pUnit->Draw );
Assert( pUnit->nHasShadow == 0 );
SHADOW_existent( pUnit->Draw.nX, pUnit->Draw.nY, nSight );
}
pUnit->nHasShadow++;
// draw to minimap
MINI_SetUnitData( pUnit->Draw.nX, pUnit->Draw.nY, pUnit->Draw.nPlayer, pUnit->Draw.nLocationSize ); // for minimap
return TRUE;
}
//////////////////////
//////////////////////
// 计谋用
// 对某个单元设置计谋值,使该单元中计
// pDraw : 单元的控制结构
// JiMou : 计谋ID
inline void CTRL_SetSTG( CTRL_FRAME_STRUCT *pDraw, CTRL_JIMOU JiMou, BOOL bSet/*=TRUE*/ )
{
Assert( pDraw );
pDraw->nSTG[JiMou] = bSet;
pDraw->wSTGCounter[JiMou] = 0;
}
// 取得某个单元是否中某个计谋
// pDraw : 单元的控制结构
// JiMou : 计谋ID
inline BOOL CTRL_GetSTG( CTRL_FRAME_STRUCT *pDraw, CTRL_JIMOU JiMou )
{
Assert( pDraw );
return pDraw->nSTG[JiMou];
}
//////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -