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

📄 cbeyes.cpp

📁 这是一个游戏程序源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////
//	CBEyes.cpp		:	v0020
//	Written by		:	Liu Gang
//	Compiler		:	Microsoft Visual C++ 4.2
//	Copyright (C)	:	1996 WayAhead Corporation 
//	v0010			:	Feb.26.1997
//	v0020			:	Apr.29.1997, add so many functions
/////////////
// implementation file
// This file is to give thinking methods information they need.
// so call them Eyes.
#include "stdafx.h"
#include "Assert.h"

#include "CBGame.h"
#include "CBMAP.h"
#include "CBCTrl.h"
#include "CBEyes.h"
#include "CBData.h"
#include "CBRDelay.h"

//added by tian yue
#include <math.h>

/////////////
// externals
// declared in CBMap.cpp
extern POINT MAP_ptSenser[2][MAP_SENSER_MAX][8*MAP_SENSER_MAX];
extern POINT MAP_ptLocation[2][MAP_LOCATION_MAX];
extern int MAP_nLocationNum[4];
/////////////

// 本能策略
/////////////
// 取得本单元附近的(视野内)其它单元的ID
// bFriend	:	输入,0——取得所有单元,1——取得我方单元,2——取得敌方单元
// wThis	:	输入,本单元ID
// pwArray	:	输出,其它单元的ID数组
// nNum		:	输入,需要的其它单元的数量;输出,实际返回的单元数量
void EYE_GetUnitInSight( int bFriend, WORD wThis, WORD *pwArray, int *pnNum )
{
	struct UNIT_STRUCT *pUnit;
	int nSight;
	BOOL bOdd;
	int nX, nY, nNewX, nNewY;
	int nCounter=0;
	WORD codeUEx;
	WORD *pwCurrent;

	pUnit = MAP_GetUnit( wThis );
	Assert( pUnit );
	nSight = EYE_GetViewRange( &pUnit->Draw );
	bOdd = pUnit->Draw.nY%2;
	nX = pUnit->Draw.nX, nY = pUnit->Draw.nY;
	pwCurrent = pwArray;
	for( int i=0; i<nSight; i++ )
	for( int j=0; j<((i+1)<<3); j++ )
	{
		if( nCounter >= *pnNum )	break;
		nNewX = nX + MAP_ptSenser[bOdd][i][j].x;
		nNewY = nY + MAP_ptSenser[bOdd][i][j].y;
		if( EYE_IfOutOfRange( nNewX, nNewY ) )
			continue;
		codeUEx = MAP_GetUnitDataEx( nNewX, nNewY );
		if( codeUEx != MAP_DATA_NONE )
		{
			if( bFriend == 1 )
			{	// 只选择我方
				struct UNIT_STRUCT *p = MAP_GetUnit( codeUEx );
				Assert( p );
				if( pUnit->Draw.nPlayer != p->Draw.nPlayer )
				{	// 是敌方,略过
					continue;
				}
				if( EYE_IfUnitIsDead( p ) )	continue;
			}
			else if( bFriend == 2 )
			{	// 只选择敌人
				struct UNIT_STRUCT *p = MAP_GetUnit( codeUEx );
				Assert( p );
				if( EYE_PlayerIsAllied( pUnit->Draw.nPlayer, p->Draw.nPlayer )	)
				{// 是同盟者,略过
					continue;
				}
				if( pUnit->Status.nTaskID == MFU )
				{// 该部队正在埋伏
					continue;
				}

				//add by tian yue

				if( EYE_IfUnitIsDead( p ) )	continue;
			}
			*pwCurrent = codeUEx;
			nCounter++;
			pwCurrent++;
		}
	}
	*pnNum = nCounter;
}

// 取得本部队的其它单元的ID
// bFriend	:	输入,0——取得所有单元,1——取得我方单元,2——取得敌方单元
// wThis	:	输入,本单元ID
// pwArray	:	输出,其它单元的ID数组
// nNum		:	输入,需要的其它单元的数量;输出,实际返回的单元数量
void EYE_GetUnitInGroup( int bFriend, WORD wThis, WORD *pwArray, int *pnNum )
{
	struct UNIT_STRUCT *pUnit;
	int nPlayer;
	BOOL bOdd;
	int nX, nY;
	int nCounter=0;
	WORD codeUEx;
	WORD *pwCurrent;

	pUnit = MAP_GetUnit( wThis );
	Assert( pUnit );
	nPlayer = pUnit->Draw.nPlayer;
	if( EYE_IfUnitIsSoldier( pUnit ) )
	{
		if( pUnit->Soldier.nGenID == MAP_DATA_NONE )
		{
			*pnNum = 0;
			return;
		}
		wThis = pUnit->Soldier.nGenID;	// 把自己变成将领
		pUnit = MAP_GetUnit( wThis );
		Assert( pUnit );
		Assert( pUnit->nType == MAP_UNIT_TYPE_GEN
			|| pUnit->nType == MAP_UNIT_TYPE_WGEN
			|| pUnit->nType == MAP_UNIT_TYPE_SGEN );
	}

	bOdd = pUnit->Draw.nY%2;
	nX = pUnit->Draw.nX, nY = pUnit->Draw.nY;
	pwCurrent = pwArray;
	for( int i=0; i<GENERAL_TROOP_MAX; i++ )
	{
		if( nCounter >= *pnNum )	break;
		codeUEx = pUnit->Gen.wTroop[i];
		if( codeUEx != MAP_DATA_NONE )
		{
			if( bFriend == 1 )
			{	// 只选择我方
				struct UNIT_STRUCT *p = MAP_GetUnit( codeUEx );
				Assert( p );
				if( pUnit->Draw.nPlayer != p->Draw.nPlayer )
				{	// 是敌方,略过
					continue;
				}
				if( EYE_IfUnitIsDead( p ) )	continue;
			}
			else if( bFriend == 2 )
			{	// 只选择敌人
				struct UNIT_STRUCT *p = MAP_GetUnit( codeUEx );
				Assert( p );
				if( EYE_PlayerIsAllied( pUnit->Draw.nPlayer, p->Draw.nPlayer )	)
				{// 是同盟者,略过
					continue;
				}
				if( EYE_IfUnitIsDead( p ) )	continue;
			}
			*pwCurrent = codeUEx;
			nCounter++;
			pwCurrent++;
		}
	}
	*pnNum = nCounter;
}

// 检测目的单元是否在视野内
// wThis	:	本单元ID
// wThat	:	目的单元ID
// nRange	:	视野范围,缺省(-1)时为第一个单元的视野
// return	:	-1,不在视野以内,0-7是方向
int EYE_IfUnitIsInSight( WORD wThis, WORD wThat, int nRange/*= -1*/ )
{
	struct UNIT_STRUCT *pUnit, *pUnit2;
	int nSight;
	int nX, nY, bOdd, nXNext, nYNext;
	
	pUnit = MAP_GetUnit( wThis );
	Assert( pUnit );
	pUnit2 = MAP_GetUnit( wThat );
	Assert( pUnit2 );

	if( pUnit2->Status.bIRQ == TRUE 
		&& !EYE_IfUnitIsBuild( pUnit2 ) )	// 士兵在建筑之中,看不见
		return -1;

	if( nRange > 10 )
	{
		if( pUnit->Draw.nX > pUnit2->Draw.nX-nRange 
			&& pUnit->Draw.nY > pUnit2->Draw.nY-nRange 
			&& pUnit->Draw.nX < pUnit2->Draw.nX+nRange 
			&& pUnit->Draw.nY < pUnit2->Draw.nY+nRange )
		{
			return 1;
		}
		else
			return -1;
	}
	else if( nRange == - 1 )
		nSight = EYE_GetViewRange( &pUnit->Draw );
	else
		nSight = nRange;

	bOdd = pUnit->Draw.nY%2;
	nX = pUnit->Draw.nX, nY = pUnit->Draw.nY;
	
	for( int i=0; i<nSight; i++ )
	for( int j=0; j<((i+1)<<3); j++ )
	{
		nXNext = nX + MAP_ptSenser[bOdd][i][j].x,
		nYNext = nY + MAP_ptSenser[bOdd][i][j].y;
		if( EYE_IfOutOfRange( nXNext, nYNext ) )
			continue;
		WORD codeUEx = MAP_GetUnitDataEx( nXNext, nYNext );
		if( codeUEx == wThat )
			return (j>>i);
	}	
	return -1;
}

// 检测目的单元是否在攻击范围内
// wThis	:	本单元ID
// wThat	:	目的单元ID
// nRange	:	硬性规定的判定范围,缺省时为部队的攻击范围
// return	:	-1,不在射程以内,0-7是方向
int EYE_IfUnitIsInRange( WORD wThis, WORD wThat, int nRange/* = -1*/ )
{
	struct UNIT_STRUCT *pUnit, *pUnit2;
	int nX, nY, bOdd, nXNext, nYNext, bOdd2;
	
	pUnit = MAP_GetUnit( wThis );
	Assert( pUnit );
	pUnit2 = MAP_GetUnit( wThat );
	Assert( pUnit2 );
	
	if( pUnit2->nHasShadow == FALSE 
		&& !EYE_IfUnitIsBuild( pUnit2 ) )	// 士兵在建筑之中,看不见
		return -2;

	// 设置判定范围,为-1时为部队的攻击范围
	if( nRange == -1 )
	{
		nRange = DATA_Lib.Unit[pUnit->Draw.nFile].nFightRange;
		if( CTRL_GetSTG( &pUnit->Draw, GUNMU ) == TRUE 
			&& (pUnit->Draw.nFile == 32 || pUnit->Draw.nFile == 45) )
		{	// 使用滚木计谋,攻击范围是视野
			nRange = DATA_Lib.Unit[pUnit->Draw.nFile].nViewRange;
		}
	}

	bOdd = pUnit->Draw.nY&1;
	nX = pUnit->Draw.nX, nY = pUnit->Draw.nY;

	// 对于远程攻击部队,只判断实在点的位置,以加快判断速度
	if( nRange > 1 )
	{
		for( int i=0; i<nRange; i++ )
		for( int j=0; j<((i+1)<<3); j++ )
		{
			nXNext = nX + MAP_ptSenser[bOdd][i][j].x,
			nYNext = nY + MAP_ptSenser[bOdd][i][j].y;
			if( EYE_IfOutOfRange( nXNext, nYNext ) )
				continue;
			WORD codeUEx = MAP_GetUnitDataEx( nXNext, nYNext );
			if( codeUEx == wThat )
			{	// 得到方向
				j = j/(i+1);
				return j;
			}
		}
	}
	else
	{	// 对于近程攻击部队,要判断该部队所占据的所有点
		for( int x=0; x< MAP_nLocationNum[pUnit->Draw.nLocationSize]; x++ )
		{
			nX = pUnit->Draw.nX+MAP_ptLocation[bOdd][x].x, 
			nY = pUnit->Draw.nY+MAP_ptLocation[bOdd][x].y;
			if( EYE_IfOutOfRange( nX, nY ) )
				continue;
			bOdd2 = nY&1;
			for( int j=0; j<8; j++ )
			{
				nXNext = nX + MAP_ptSenser[bOdd2][0][j].x,
				nYNext = nY + MAP_ptSenser[bOdd2][0][j].y;
				if( EYE_IfOutOfRange( nXNext, nYNext ) )
					continue;
				WORD codeUEx = MAP_GetUnitDataEx( nXNext, nYNext );
				if( codeUEx == wThat )
					return j;
			}
		}
	}
	return -1;
}

// 检测目的位置是否在某单元位置一格范围内
// pUnit		:	被检测的单元
// nEndX, nEndY	:	被检测的目的地形位置
// return		:	-1,不在射程以内,0-7是方向
int EYE_IfShipYardIsInRange( struct UNIT_STRUCT *pUnit, int nEndX, int nEndY )
{
	BOOL bOdd = pUnit->Draw.nY&1;
	BOOL bOdd2 = nEndY&1;
	WORD codeG;
	struct MAP_GROUND_CODE_STRUCT stctG;
	int nX, nY, nX2, nY2;
	for( int i=0; i<8; i++ )
	{
		nX = pUnit->Draw.nX+MAP_ptSenser[bOdd][0][i].x, 
		nY = pUnit->Draw.nY+MAP_ptSenser[bOdd][0][i].y;
		for( int j=0; j<9; j++ )
		{
			nX2 = nEndX + MAP_ptLocation[bOdd2][j].x,
			nY2 = nEndY + MAP_ptLocation[bOdd2][j].y;
			if( nX == nX2 && nY == nY2 )
				return i;
		}

		codeG = MAP_GetGroundData( 0, nX, nY );
		Assert( codeG!= MAP_DATA_NONE );
		MAP_GroundDeCode( codeG, &stctG );
		if( stctG.nFile == 3 )// 岸边
			return i;
	}
	return -1;
}
/////////////


/////////////
// 检测该单元是否是有效
inline BOOL EYE_IfUnitIsUnit( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType != MAP_UNIT_TYPE_NONE )		// 无类型
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否是建筑
inline BOOL EYE_IfUnitIsBuild( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType == MAP_UNIT_TYPE_BUILDING		// 建筑
		|| pUnit->nType == MAP_UNIT_TYPE_RESOURCE	// 资源
		|| pUnit->nType == MAP_UNIT_TYPE_FLAG 		// 大旗
		|| pUnit->nType == MAP_UNIT_TYPE_SHIPYARD	// 船坞
		)
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否是将领
inline BOOL EYE_IfUnitIsGen( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType == MAP_UNIT_TYPE_GEN 
		|| pUnit->nType == MAP_UNIT_TYPE_WGEN 
		|| pUnit->nType == MAP_UNIT_TYPE_SGEN )		// 将领
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否是文将
inline BOOL EYE_IfUnitIsWorkerGen( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	//if( pUnit->Draw.nFile == 29 )		// 文将
	if( pUnit->nType == MAP_UNIT_TYPE_WGEN )		// 将领
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否是工人
inline BOOL EYE_IfUnitIsWorker( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType == MAP_UNIT_TYPE_WORKER )	// 工人
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否是平民
inline BOOL EYE_IfUnitIsMan( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType == MAP_UNIT_TYPE_MAN )		// 平民
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否是资源
inline BOOL EYE_IfUnitIsRes( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType == MAP_UNIT_TYPE_RESOURCE )// 资源
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否是特殊图素
inline BOOL EYE_IfUnitIsSpec( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType == MAP_UNIT_TYPE_SPECIAL )	// 特殊图素
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否有Soldier域,可以组建成部队
inline BOOL EYE_IfUnitIsSoldier( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType == MAP_UNIT_TYPE_SOLDIER		// 士兵
		|| pUnit->nType == MAP_UNIT_TYPE_SHIP 		// 战船
		|| pUnit->nType == MAP_UNIT_TYPE_LADDER 	// 云梯
		|| pUnit->nType == MAP_UNIT_TYPE_WORKER		// 工人
		|| pUnit->nType == MAP_UNIT_TYPE_MAN		// 平民
		)
	{
		return TRUE;
	}
	return FALSE;
}

// 检测该单元是否可以移动
inline BOOL EYE_IfUnitIsMovable( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->nType == MAP_UNIT_TYPE_SOLDIER		// 士兵
		|| pUnit->nType == MAP_UNIT_TYPE_SHIP 		// 战船
		|| pUnit->nType == MAP_UNIT_TYPE_LADDER 	// 云梯
		|| pUnit->nType == MAP_UNIT_TYPE_GEN 		// 将领
		|| pUnit->nType == MAP_UNIT_TYPE_SGEN 		// 水军将领
		|| pUnit->nType == MAP_UNIT_TYPE_WGEN 		// 文将
		|| pUnit->nType == MAP_UNIT_TYPE_MAN 		// 平民
		|| pUnit->nType == MAP_UNIT_TYPE_WORKER		// 工人
		)
	{
		return TRUE;
	}
	return FALSE;
}

// 查看该单元是否是弓箭手
inline BOOL EYE_IfUnitIsArcher( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->Draw.nFile == 33
		|| pUnit->Draw.nFile == 45
		|| pUnit->Draw.nFile == 39
		|| pUnit->Draw.nFile == 42
		|| pUnit->Draw.nFile == 44 )
	{
		return TRUE;
	}
	return FALSE;
}

// 查看该单元是否是箭楼
inline BOOL EYE_IfUnitIsTower( struct UNIT_STRUCT *pUnit )
{
	Assert( pUnit );
	if( pUnit->Draw.nFile == 18
		|| pUnit->Draw.nFile == 19 )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -