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

📄 cbrunot.cpp

📁 赤壁之战(游戏原码)
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 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 + -