📄 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 + -