?? cbrunot.cpp
字號:
// pUnit : 投石車
// pU : 敵人
void RUN_FIGHT_SetStone( struct UNIT_STRUCT *pUnit , struct UNIT_STRUCT *pU )
{
Assert( EYE_IfUnitIsCatapult( pUnit ) );
struct OTHER_STRUCT other;
OTHER_ClearData( &other );
// 類型,大小和顯示
other.nType = OTHER_TYPE_STONE;
other.nFile = 4;
// 得到打擊點數
//--------------------攻擊計算--------------------
int nAttack;
Assert( EYE_IfUnitIsCatapult( pUnit ) );
nAttack = EYE_GetFarAttack( pUnit );
//other.nHit = RUN_FIGHT_calcHitPoint( pUnit, pU );
//--------------------攻擊計算--------------------
other.nHit = nAttack;
other.nSpeed = 8;
other.nMaxFrame = 1;
other.szItem.cx = MAP_Lib.Other[other.nFile].szItem.cx; // size
other.szItem.cy = MAP_Lib.Other[other.nFile].szItem.cy;
other.nOwnerID = pUnit->nID; // 設置自己的標識,為攻擊敵人后給敵人的nIDAttackMe賦值
// 開始和結束坐標
// 這里所進行校正據要與CBOther.cpp文件里的OTHER_Hit()的校正相同
POINT ptEnd;
RECT rect = MAP_GetUnitRect( DRAW_ptScreenOffset, &pUnit->Draw );
other.ptBegin.x = ((rect.left+rect.right)>>1) + DRAW_ptScreenOffset.x;// begin position
other.ptBegin.y = ((rect.top+rect.bottom)>>1) + DRAW_ptScreenOffset.y-10;
rect = MAP_GetUnitRect( DRAW_ptScreenOffset, &pU->Draw );
ptEnd.x = ((rect.left+rect.right)>>1) + DRAW_ptScreenOffset.x;// end position
// 注意:此處與弓箭手不一樣
Assert( ptEnd.y >=0 );
Assert( ptEnd.x >=0 );
ptEnd.y = ((rect.top+rect.bottom)>>1) + DRAW_ptScreenOffset.y;
other.ptEnd.x = pU->Draw.nX; // 目的地坐標是敵人現在所在位置坐標
other.ptEnd.y = pU->Draw.nY;
// 為移動做準備
int nDistX, nDistY;
nDistX = ptEnd.x - other.ptBegin.x;
nDistY = ptEnd.y - other.ptBegin.y;
other.nDelay = (int)sqrt( float(nDistX*nDistX+nDistY*nDistY) ); // 求斜邊的長
other.fSin = nDistY/(float)other.nDelay;// Sin()
other.fCos = nDistX/(float)other.nDelay;// Cos()
// 設置方向
int nDir = -1;
float fSin = other.fSin;
float fCos = other.fCos;
if( fSin >= 0.866 ) nDir = 4; // 60-120
else if( fSin<0.866 && fSin>=0.5 )
{
if( fCos<0.866 && fCos>=0.5 )
nDir = 3; // 30-60
else nDir = 5; // 120-150
}
else if( fSin<0.5 && fSin>=-0.5 )
{
if( fCos>0.866 )
nDir = 2; // 330-30
else nDir = 6; // 150-210
}
else if( fSin<-0.5 && fSin>=-0.866 )
{
if( fCos<-0.5 && fCos>=-0.866 )
nDir = 7; // 210-240
else nDir = 1; // 300-330
}
else if( fSin<-0.866 ) nDir = 0; // 240-300
// other.nCol[0] = nDir;
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", "Setstone\n" );
}
#endif //_DEBUG_OFFSET_
pUnit->Draw.nDir = nDir; // 順便也給弓箭手設上
OTHER_CreateData( &other );
//---- 音效
// 投石車
POINT pt;
pt.x = pUnit->Draw.nX, pt.y = pUnit->Draw.nY;
if( PtInRect( &DRAW_rcScreen, pt ) )
{
// throw.wav
DATA_WAVE_EffectPlay( 105 );
}
//---- 音效
}
// 是100人的步兵和弓兵,而且正使用的計謀是滾木
// pUnit : 投滾木的人
// pU : 敵人
void RUN_FIGHT_SetGunMu( struct UNIT_STRUCT *pUnit , struct UNIT_STRUCT *pU )
{
// 必須是100人的步兵或弓兵
Assert( pUnit->Draw.nFile == 32 || pUnit->Draw.nFile == 45 );
struct OTHER_STRUCT other;
OTHER_ClearData( &other );
// 類型,大小和顯示
other.nType = OTHER_TYPE_GUNMU;
if( pUnit->Draw.nFile == 32 )
other.nFile = 9; // 石頭
else
other.nFile = 10; // 木頭
// 得到打擊點數
//--------------------攻擊計算--------------------
int nAttack;
// Assert( EYE_IfUnitIsCatapult( pUnit ) );
// nAttack = EYE_GetFarAttack( pUnit );
nAttack = 30;
//other.nHit = RUN_FIGHT_calcHitPoint( pUnit, pU );
//--------------------攻擊計算--------------------
other.nHit = nAttack;
other.nSpeed = 8;
other.nMaxFrame = 1;
other.szItem.cx = MAP_Lib.Other[other.nFile].szItem.cx; // size
other.szItem.cy = MAP_Lib.Other[other.nFile].szItem.cy;
other.nOwnerID = pUnit->nID; // 設置自己的標識,為攻擊敵人后給敵人的nIDAttackMe賦值
// 開始和結束坐標
// 這里所進行校正據要與CBOther.cpp文件里的OTHER_Hit()的校正相同
POINT ptEnd;
RECT rect = MAP_GetUnitRect( DRAW_ptScreenOffset, &pUnit->Draw );
other.ptBegin.x = ((rect.left+rect.right)>>1) + DRAW_ptScreenOffset.x;// begin position
other.ptBegin.y = ((rect.top+rect.bottom)>>1) + DRAW_ptScreenOffset.y-10;
rect = MAP_GetUnitRect( DRAW_ptScreenOffset, &pU->Draw );
ptEnd.x = ((rect.left+rect.right)>>1) + DRAW_ptScreenOffset.x;// end position
// 注意:此處與弓箭手不一樣
Assert( ptEnd.y >=0 );
Assert( ptEnd.x >=0 );
ptEnd.y = ((rect.top+rect.bottom)>>1) + DRAW_ptScreenOffset.y;
other.ptEnd.x = pU->Draw.nX; // 目的地坐標是敵人現在所在位置坐標
other.ptEnd.y = pU->Draw.nY;
// 為移動做準備
int nDistX, nDistY;
nDistX = ptEnd.x - other.ptBegin.x;
nDistY = ptEnd.y - other.ptBegin.y;
other.nDelay = (int)sqrt( float(nDistX*nDistX+nDistY*nDistY) ); // 求斜邊的長
other.fSin = nDistY/(float)other.nDelay;// Sin()
other.fCos = nDistX/(float)other.nDelay;// Cos()
// 設置方向
int nDir = -1;
float fSin = other.fSin;
float fCos = other.fCos;
if( fSin >= 0.866 ) nDir = 4; // 60-120
else if( fSin<0.866 && fSin>=0.5 )
{
if( fCos<0.866 && fCos>=0.5 )
nDir = 3; // 30-60
else nDir = 5; // 120-150
}
else if( fSin<0.5 && fSin>=-0.5 )
{
if( fCos>0.866 )
nDir = 2; // 330-30
else nDir = 6; // 150-210
}
else if( fSin<-0.5 && fSin>=-0.866 )
{
if( fCos<-0.5 && fCos>=-0.866 )
nDir = 7; // 210-240
else nDir = 1; // 300-330
}
else if( fSin<-0.866 ) nDir = 0; // 240-300
other.nCol[0] = nDir;
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", "Setstone\n" );
}
#endif //_DEBUG_OFFSET_
pUnit->Draw.nDir = nDir; // 順便也給弓箭手設上
OTHER_CreateData( &other );
//---- 音效
// 投石車
POINT pt;
pt.x = pUnit->Draw.nX, pt.y = pUnit->Draw.nY;
if( PtInRect( &DRAW_rcScreen, pt ) )
{
// throw.wav
DATA_WAVE_EffectPlay( 105 );
}
//---- 音效
}
// 對于弓箭手,箭樓,戰船,要射箭,必然命中
// pUnit : 弓箭手
// pU : 敵人
void RUN_FIGHT_SetArrow( struct UNIT_STRUCT *pUnit , struct UNIT_STRUCT *pU )
{
Assert( EYE_IfUnitIsArcher( pUnit )
|| EYE_IfUnitIsTower( pUnit )
|| EYE_IfUnitIsBattleShip( pUnit ) );
/*
if( pUnit->bHasStone == TRUE )
{ // 已經投出石頭了,不能再投
return;
}
// 設置投出的標志
pUnit->bHasStone = TRUE;
*/
struct OTHER_STRUCT other;
OTHER_ClearData( &other );
// 類型,大小和顯示
other.nType = OTHER_TYPE_ARROW;
other.nFile = 0;
// 得到遠程打擊點數
other.nHit = RUN_FIGHT_calcHitPointF( pUnit, pU );
other.nSpeed = 16;
other.nMaxFrame = 1;
other.szItem.cx = MAP_Lib.Other[other.nFile].szItem.cx; // size
other.szItem.cy = MAP_Lib.Other[other.nFile].szItem.cy;
other.nOwnerID = pUnit->nID; // 設置自己的標識,為攻擊敵人后給敵人的nIDAttackMe賦值
other.nTargetID = pU->nID; // 敵人的標識,必然命中
// 開始和結束坐標
// 這里所進行校正據要與CBOther.cpp文件里的OTHER_Hit()的校正相同
RECT rect = MAP_GetUnitRect( DRAW_ptScreenOffset, &pUnit->Draw );
other.ptBegin.x = ((rect.left+rect.right)>>1) + DRAW_ptScreenOffset.x;// begin position
other.ptBegin.y = ((rect.top+rect.bottom)>>1) + DRAW_ptScreenOffset.y-10;
rect = MAP_GetUnitRect( DRAW_ptScreenOffset, &pU->Draw );
other.ptEnd.x = ((rect.left+rect.right)>>1) + DRAW_ptScreenOffset.x;// end position
other.ptEnd.y = ((rect.top+rect.bottom)>>1) + DRAW_ptScreenOffset.y-10;
// 為移動做準備
int nDistX, nDistY;
nDistX = other.ptEnd.x - other.ptBegin.x;
nDistY = other.ptEnd.y - other.ptBegin.y;
other.nDelay = (int)sqrt( float(nDistX*nDistX+nDistY*nDistY) ); // 求斜邊的長
other.fSin = nDistY/(float)other.nDelay;// Sin()
other.fCos = nDistX/(float)other.nDelay;// Cos()
// 設置方向
int nDir = -1;
float fSin = other.fSin;
float fCos = other.fCos;
if( fSin >= 0.866 ) nDir = 4; // 60-120
else if( fSin<0.866 && fSin>=0.5 )
{
if( fCos<0.866 && fCos>=0.5 )
nDir = 3; // 30-60
else nDir = 5; // 120-150
}
else if( fSin<0.5 && fSin>=-0.5 )
{
if( fCos>0.866 )
nDir = 2; // 330-30
else nDir = 6; // 150-210
}
else if( fSin<-0.5 && fSin>=-0.866 )
{
if( fCos<-0.5 && fCos>=-0.866 )
nDir = 7; // 210-240
else nDir = 1; // 300-330
}
else if( fSin<-0.866 ) nDir = 0; // 240-300
other.nCol[0] = nDir;
pUnit->Draw.nDir = nDir; // 順便也給弓箭手設上
OTHER_CreateData( &other );
// 弓箭攻擊音效
RUN_SOUND_HitF( pUnit->Draw.nX, pUnit->Draw.nY, pUnit->Draw.nFile );
// 弓箭攻擊音效
}
// mouse hit result
// 命令的主體的計數器
extern int CTRL_nHitCounter;
// 計算戰斗效果,死傷人數
// pUnit : 攻擊方
// pU : 被攻擊方
// return : TRUE if 被攻擊的一方死了
BOOL RUN_FIGHT_CalcResult( struct UNIT_STRUCT *pUnit, struct UNIT_STRUCT *pU )
{
// July 31. 1997, Liu Gang
if( EYE_IfUnitIsDead( pU ) )
return FALSE; //
// 給被攻擊的人置標志
if( pUnit->Draw.nPlayer != pU->Draw.nPlayer )
{
pU->nIDAttackMe = pUnit->nID;
if( pU->Draw.nPlayer == GAME.nMe ) // 被攻擊方是游戲者
{
MINI_SetBlink( pU->Draw.nDrawX, pU->Draw.nDrawY );
RUN_SOUND_UnderAttack( pU->Draw.nX, pU->Draw.nY, pU->Draw.nFile );
}
}
// 如果被攻擊方的血格在被攻擊前多于滿值一半,而被攻擊后少于滿值一半,
// 則發出受傷聲音。
BOOL bWounded = FALSE;
if( pU->nLife>=(EYE_GetFullLife( pU->Draw.nPlayer, pU->Draw.nFile )>>1) )
bWounded = TRUE;
// 被攻擊方生命減少
pU->nLife -= RUN_FIGHT_calcHitPoint( pUnit, pU );
if( pU->nLife>=(EYE_GetFullLife( pU->Draw.nPlayer, pU->Draw.nFile )>>1)
|| bWounded == FALSE )
bWounded = FALSE;
if( bWounded == TRUE )
// 受傷音效
RUN_SOUND_Wounded( pU->Draw.nX, pU->Draw.nY, pU->Draw.nFile );
// 受傷音效
// 攻擊音效
RUN_SOUND_Hit( pUnit->Draw.nX, pUnit->Draw.nY, pUnit->Draw.nFile );
// 攻擊音效
// 查看是否該死了
if( pU->nLife <= 0 )
{
RUN_UNIT_ToDie( pU );
return TRUE;
}
if( EYE_IfFocusOnUnit( pU ) )
//&& EYE_IfSheIsMine( pU )
{
// 更新血格條
if( EYE_IfUnitIsGen( pU ) )
{
FACE_ShowProcessBar( PROCESSBAR_BLOOD, pU->nLife*100/EYE_GetFullLife( pU->Draw.nPlayer, pU->Draw.nFile) );
}
else if( CTRL_nHitCounter == 1 )
FACE_ShowProcessBar( PROCESSBAR_STONE, pU->nLife*100/EYE_GetFullLife( pU->Draw.nPlayer, pU->Draw.nFile) );
}
return FALSE;
}
// 檢測是否到達目的地了
// pUnit : 被檢測的單元
// return : 應該轉變的方向,0-1,為-1時未到達
int RUN_MOVE_IfArrived( struct UNIT_STRUCT *pUnit )
{
// 對于運送(采集)命令,nTaskIDEx所指定的目的地類型是地形(麥田,樹林)
// 有部隊歸屬的工人士兵和文將,目標類型是地形
if( (pUnit->Task.nTaskID == YUNSONG
&& pUnit->Status.nTaskID == YIDONG
&& pUnit->Status.nTaskIDEx == 1 ) )
{
if( EYE_IfUnitIsWorker( pUnit )
&& pUnit->Soldier.nGenID == MAP_DATA_NONE )
;
else
{
Assert( (EYE_IfUnitIsWorker( pUnit )
&& pUnit->Soldier.nGenID != MAP_DATA_NONE)
|| EYE_IfUnitIsWorkerGen( pUnit ) );
Assert( pUnit->Task.nTaskIDEx2 < 2
&& pUnit->Task.nTaskIDEx2 >= 0 );
int nDir;
nDir = EYE_IfResIsInRange( pUnit, pUnit->Task.nTaskIDEx2 );
if( nDir != -1 )
{
pUnit->Status.nParam4 = 0; // 取消預堵塞
return nDir;
}
}
}
// 檢測是否接近目的地,目的地是單元
if( pUnit->Status.nTaskIDEx == 2 )
{
int nDir, nRange;
// 只判定相臨的格子
if( pUnit->Task.nTaskID == GONGJI )
nRange = -1;
else nRange = 1; // 如果任務不是攻擊,強制判定范圍是1
if( (nDir = EYE_IfUnitIsInRange( pUnit->nID, pUnit->Task.nParam1, nRange )) >= 0 )
{ // 到達目的地了
pUnit->Status.nParam4 = 0; // 取消預堵塞
return nDir;
}
// 檢測是否目標單元已經被刪除,或在建筑內部
struct UNIT_STRUCT *pU = MAP_GetUnit( pUnit->Task.nParam1 );
Assert( pU );
if( EYE_IfUnitIsDead( pU )
|| nDir == -2 )
{ // 到達目的地了
pUnit->Status.nParam4 = 0; // 取消預堵塞
return pUnit->Draw.nDir;
}
}
if( pUnit->MarchTrack[pUnit->StepNum] == 255 )
{ // 到達目的地
if( pUnit->Task.nTaskID == JIANZAO
&& pUnit->Task.nTaskIDEx2 == 20// 任務是造船塢
&& pUnit->Task.nTaskIDEx == 1
&& pUnit->Status.nParam4 != 255 )
//&& MAP_GetUnitDataEx( pUnit->Status.nParam2, pUnit->Status.nParam3 ) == MAP_DATA_NONE
//&& EYE_IfShipYardIsInRange( pUnit, pUnit->Status.nParam2, pUnit->Status.nParam3 ) ) // 船塢
{ // 到達水邊
// 把坐標變換到建造建筑(船塢)的位置上去,不能省略
pUnit->Draw.nXLast = pUnit->Draw.nX;
pUnit->Draw.nYLast = pUnit->Draw.nY;
pUnit->Draw.nX = pUnit->Task.nParam2,
pUnit->Draw.nY = pUnit->Task.nParam3;
MAP_SetUnitDataEx( pUnit->Draw.nXLast, pUnit->Draw.nYLast, MAP_DATA_NONE );
MAP_SetUnitDataEx( pUnit->Draw.nX, pUnit->Draw.nY, pUnit->nID );
pUnit->Status.nParam4 = 0; // 取消預堵塞
// 移動陰影
CTRL_UNIT_MoveShadow( &pUnit->Draw );
}
return pUnit->Draw.nDir;
}
// 路徑出界了
if( pUnit->StepNum >= GAME_MARCH_MAX )
{
return pUnit->Draw.nDir;
}
return -1;
}
// 計算收取建筑資源的多少
// pUnit : 工人部隊
// pU : 資源建筑
// return : 如果尚在獲取為0,資源獲取完畢為1,資源枯竭為2
int RUN_HARVEST_Build( struct UNIT_STRUCT *pUnit, struct UNIT_STRUCT *pU )
{
if( EYE_IfUnitIsDead( pU ) )
return 2; // 該資源已經枯竭了
if( pUnit->nCounter < RUN_TIMEDELAY_HARVEST )
return 0; // 繼續在建筑里呆著
Assert( EYE_IfUnitIsRes( pU )
|| pU->Draw.nFile == 10
|| pU->Draw.nFile == 11 );
Assert( EYE_IfUnitIsWorker( pUnit ) || EYE_IfUnitIsWorkerGen( pUnit ) );
int *pSource = NULL;
if( pU->Draw.nFile == 10 || pU->Draw.nFile == 11 )
{ // 敵人的糧倉
pSource = &GAME.Players[pU->Draw.nPlayer].nFood;
}
else
{ // 一般資源
pSource = &pU->Build.nResource;
}
if( *pSource > 0 )
{
if( EYE_IfUnitIsWorker( pUnit ) )
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -