?? cbeyes.cpp
字號:
/////////////
// 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 )
{
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 + -