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

📄 npc_pattern.cpp

📁 国内著名网络游戏dragon的服务端完整源码 内附完整数据库结构
💻 CPP
📖 第 1 页 / 共 4 页
字号:

#include "..\stdafx.h"
#include <mmsystem.h>
#include "DefaultHeader.h"
#include "Path.h"

#include "NPC_Pattern.h"
#include "CItem.h"
#include "OP_Magic.h"
#include "dr_network.h"
#include "RajaSystem.h"
#include "Map.h"
#include "SealStoneGameServer.h" 
#include "AIDefine.h"
#include "LTSSupport.h"			// LTS NEW LOCALWAR
#include "AIManager.h"
#include "UserManager.h"
#include "AdventManager.h"
#include "ArenaManager.h"
#include "RegenManager.h"

#define	HOME_DIST_1AREA					245
#define HOME_DIST_2AREA					625

extern struct				CItem_List Item_Ref ;
extern cLocalWarfield*		g_pLocalWarfield;			// LTS NEW LOCALWAR

extern void SendAttackNPCArea( t_connection c[], int npc );
extern void SendViewTypeChange( int cn, int viewtype );

extern inline int IsNKNation( LPCHARLIST ch );
extern inline int	IsHeNK( LPCHARLIST ch, int nation );
extern void CalcResist(int tolerance, CHARLIST* target, int resist_Type);
extern int	CheckActivedGroup();						// LTS AI2
extern int CheckEventAttack();	 // CSD-031007

extern NPCName_by_Gender	NPC_Name_Ref[Num_Of_NPC_Name];
extern NPCLev_to_Exp		NPC_Lev_Ref[Num_Of_NPC_Lev] ;
extern NPC_Generation		NPC_Gen_Ref[Num_Of_NPC_Generation] ;


extern int NPC_FemaleName_Count;
extern int NPC_MaleName_Count; 
extern int NPC_LastName_Count; 

int NpcPatternTable[20] = 
{ 
	NPC_PATTERN_HOSTILE_,
	NPC_PATTERN_FIND_CLOSE_PC_,
	NPC_PATTERN_ACCESS_PC_,
	NPC_PATTERN_ATTACK_PC_,
	NPC_PATTERN_BACKDRAW_,
	NPC_PATTERN_RETURN_,		
};



#define	MAX_ANIMATION		   24
#define	MAX_PC_ANIMATION_FRAME 40

typedef struct	tagPCANIMATIONTABLE
{	
	int		nCount;
	BYTE	cFrame[ MAX_PC_ANIMATION_FRAME ];
	
	char  	dx[ MAX_PC_ANIMATION_FRAME ];
	char  	dy[ MAX_PC_ANIMATION_FRAME ];
	char    attackf[ MAX_PC_ANIMATION_FRAME ];
	short   wave[  MAX_PC_ANIMATION_FRAME ];
	short 	height[ MAX_PC_ANIMATION_FRAME ];
	short   effect[ MAX_PC_ANIMATION_FRAME ];
} PCANIMATIONTABLE, *LPPCANIMATIONTABLE;

PCANIMATIONTABLE AnimationTable[ MAX_ANIMATION ];

#define MAX_CHARACTER_SPRITE_ 200 // CSD-030417

int WalkDelayTimeTable[ MAX_CHARACTER_SPRITE_];
int RunDelayTimeTable[ MAX_CHARACTER_SPRITE_];
int HorseDelayTimeTable[ MAX_CHARACTER_SPRITE_];
int movep;

sNPCgeneratePosition NPCgeneratePosition[ MAX_GENERATE_POSITION_];
int NPCgeneratePositionMax;


bool CharMovingThreadStart0;
bool CharMovingThreadStart1;
bool CharMovingThreadStart2;

inline int ran( int r )
{	
	if( r == 0 ) return 0;
	return rand()%r;
}	

#define FRAME_PER_SEC		15

//	府畔 : 0捞 酒囱 蔼捞搁 档馒抗惑矫埃.
DWORD ReturnDestTime( LPCHARLIST ch )
{	
	int dist = ch->MoveLength - ch->MovePathCount;
	if( dist <= 0 ) {return 0;}
	
	const DWORD timepertile = ::Get_MoveDelayTime( ch );
	const DWORD desttime = global_time + timepertile * (DWORD )dist;
	
	ch->desttime = desttime;
	
	return desttime;
}	

void SaveMoveDelayTable()
{	//< CSD-030806 : 1鸥老 捞悼窍绰单 吧府绰 矫埃阑 绵仿
	FILE* pFile = fopen("./OutPut/Monster_WalkingTime_mSecPerTile.txt", "wt");
	Dbg_Assert(pFile != NULL);

	for (int i = 0; i < MAX_CHARACTER_SPRITE_; ++i)
	{
		fprintf(pFile, "[%03d]%s(%d msec/tile)\n", i, NPC_Gen_Ref[i].Name, WalkDelayTimeTable[i]);
	}
		
	fclose(pFile);
}	//> CSD-030806

void InitMoveDelayTable( void )
{	
	int i,j;
	double d = 0.;
	double framepertile;
	char temp[ FILENAME_MAX];
	FILE *fp;
	
	for( i = 0 ; i < MAX_CHARACTER_SPRITE_ ; i ++)
	{
		sprintf( temp, "%s/Char/%03dAniTable.bin", GameServerDataPath, i );
		fp = fopen( temp, "rb" );
		if( fp )
		{
			fseek( fp, 20, SEEK_SET );
			fseek( fp,  1, SEEK_CUR );
			fread( AnimationTable, sizeof( PCANIMATIONTABLE ), MAX_ANIMATION, fp );
			fclose(fp);
			
			for( d = 0, j = 0 ; j < AnimationTable[1].nCount ; j ++)
				d += (double)AnimationTable[1].dx[j];
			if( d )
			{
				framepertile = TILE_SIZE * (double)AnimationTable[1].nCount / d ;
				WalkDelayTimeTable[ i] = (int)(1000 * framepertile / FRAME_PER_SEC);
			}
			
			if( i == 0 || i == 1 ) 
			{
				for( d = 0, j = 0 ; j < AnimationTable[12].nCount ; j ++) // 崔府扁..
					d += (double)AnimationTable[12].dx[j];
				if( d )
				{
					framepertile = TILE_SIZE * (double)AnimationTable[12].nCount / d ;
					RunDelayTimeTable[ i] = (int)(1000 * framepertile / FRAME_PER_SEC);
				}
				
				
				for( d = 0, j = 0 ; j < AnimationTable[19].nCount ; j ++) // 富鸥扁....
					d += (double)AnimationTable[19].dx[j];
				if( d )
				{
					framepertile = TILE_SIZE * (double)AnimationTable[19].nCount / d ;
					HorseDelayTimeTable[ i] = (int)(1000 * framepertile / FRAME_PER_SEC);
				}
			}
		}
		else 
		{
			WalkDelayTimeTable[ i]	= 700;
			RunDelayTimeTable[ i]	= 300;
			HorseDelayTimeTable[i]	= 300;
		}
	}
}	

DWORD Get_MoveDelayTime( CHARLIST *ch )
{
	const int movp= ch->CalcMovePower();
	if(!movp){return 0;}
	
	DWORD ret = 0;
	switch( ch->SprNo )
	{
	case 0 :
	case 1 : 
		{
			switch( ch->MoveType )
			{
				// walking
			case 0 :	
				{
					if( ch->MoveLength <=4 ) 
					{
						ret = WalkDelayTimeTable[ ch->SprNo] * 50 / movp;
					}
					else 
					{
						ret = RunDelayTimeTable[ ch->SprNo] * 50 / movp;
					}
				}break;
				// running
			case 1 : 	
				{
					ret = RunDelayTimeTable[ ch->SprNo] * 50 / movp;
				}break;
				// Horsing..
			case 2 :	
				{
					ret = HorseDelayTimeTable[ ch->SprNo] * 50 / movp;
				}break;
			default :
				{
					ret = 500;
				}break;
			}
		}break;
	default :
		{
			ret = WalkDelayTimeTable[ ch->SprNo] * 50 / movp;
		}break;
	}
	return ret; 
}

int InDistance( CHARLIST *s, CHARLIST *d, int dis )
{	
	if( s->bAlive != ALIVE_ ) return 0;
	
	int sx = s->X;
	int sy = s->Y;
	int dx = d->X;
	int dy = d->Y;
	
	if( dis * dis > (dx-sx)*(dx-sx)+(dy-sy)*(dy-sy) ) return 1;
	
	return 0;
}	

bool NPC_CheckMustGoHome(CHARLIST *n,int tx,int ty)
{
	DWORD area1, area2;
	
	switch( n->patterntype )
	{
	case  NPC_PATTERN_ACCESS			:
	case  NPC_PATTERN_ATTACK			:
	case  NPC_PATTERN_ATTACKED			:
	case  NPC_PATTERN_BOSS_ACCESS		:
	case  NPC_PATTERN_BOSS_ATTACK		:
	case  NPC_PATTERN_BOSS_ATTACKED		:
		{
			area1 = (n->X/TILE_SIZE - n->homex)*(n->X/TILE_SIZE - n->homex) + (n->Y/TILE_SIZE - n->homey)*(n->Y/TILE_SIZE - n->homey);
			area2 = (tx - n->homex)*(tx - n->homex) + (ty - n->homey)*(ty - n->homey);
			if( area1 > HOME_DIST_1AREA )
			{	
				if( area2 > HOME_DIST_2AREA )
				{
					return true;
				}
			}	
			break;
		}
	}
	return false;
	
}

bool NPC_CanReach(CHARLIST *n,int tx,int ty,int *x,int *y)
{
	int d, i, j, tempdir;
	int ttx, tty;
	int dirt[ 5] = { 0,1,-1,-2,2 };
	
	*x = n->X / TILE_SIZE;  *y = n->Y / TILE_SIZE;
	tempdir = NPC_GetDir( tx, ty, n->X / TILE_SIZE, n->Y / TILE_SIZE );
	
	for( j = 1 ; j < 10 ; j ++)
	{		
		for( i = 0 ;  i < 5 ; i ++)
		{	
			ttx = tx;	tty = ty;
			d = ( tempdir + 8 + dirt[i] ) %8;
			switch( d )
			{
			case 0 :			tty +=j; break;
			case 1 : ttx -=j;	tty +=j; break;
			case 2 : ttx -=j;			 break;
			case 3 : ttx -=j;	tty -=j; break;
			case 4 :			tty -=j; break;
			case 5 : ttx +=j;	tty -=j; break;
			case 6 : ttx +=j;			 break;
			case 7 : ttx +=j;	tty +=j; break;
			}
			if(FreeTile( n, n->MoveSx, n->MoveSy, ttx, tty ))  
			{
				*x = ttx;  *y = tty;
				return true;
			}
		}	
	}	
	return false;
}

int NPC_NearCh( CHARLIST *n, CHARLIST *ch, int *x, int *y )			// LTS NPC MOVE
{
	int dirt[ 5] = { 0,1,-1,-2,2 };
	int tx = 0, ty  = 0;
	
	if( ch == NULL ){return 0;}
	
	tx = ch->MoveSx;
	ty = ch->MoveSy;
	
	if (ch->SprNo==0||ch->SprNo==1)
	{
		tx = ch->MoveGox/TILE_SIZE;
		ty = ch->MoveGoy/TILE_SIZE;
	}
	
	if (NPC_CheckMustGoHome(n,tx,ty))
	{
		if (!NPC_CanReach(n,n->homex,n->homey,x,y))
		{
			if (!NPC_CanReach(n,tx,ty,x,y))
			{
				return false;
			}
		}
	}
	else
	{
		if (!NPC_CanReach(n,tx,ty,x,y))
		{
			return false;
		}	
	}
	return true;
}

#define TILE_BLOCK_SIZE  11

BYTE TileBlock[ TILE_BLOCK_SIZE][ TILE_BLOCK_SIZE] = 
{
	{ 0,0,0,0,1,1,1,0,0,0,0 },
	{ 0,0,1,1,1,1,1,1,1,0,0 },
	{ 0,1,1,1,1,1,1,1,1,1,0 },
	{ 0,1,1,1,1,1,1,1,1,1,0 },
	{ 1,1,1,1,1,1,1,1,1,1,1 },
	{ 1,1,1,1,1,1,1,1,1,1,1 },
	{ 1,1,1,1,1,1,1,1,1,1,1 },
	{ 0,1,1,1,1,1,1,1,1,1,0 },
	{ 0,1,1,1,1,1,1,1,1,1,0 },
	{ 0,0,1,1,1,1,1,1,1,0,0 },
	{ 0,0,0,0,1,1,1,0,0,0,0 }
};

BYTE TileBlockBuf[ TILE_BLOCK_SIZE][ TILE_BLOCK_SIZE];

// 泅犁困摹俊辑 dist鸥老父怒  第肺 狐柳促. 
int NPC_NearBackCh( CHARLIST *n, CHARLIST *ch, int *x, int *y, int dist )
{	
	int dirt[ 5] = { 0,1,-1,-2,2 };
	int d, i, j, tempdir;
	int tx, ty;
	int ttx, tty;
	
	if( n->targetid == -1 ) 
	{
		//		n->targetid = NPC_IsWhoNearPC( n, 10  );
		//		if( n->targetid == -1 )  
		return 0;
	}
	
	// 傍拜 措惑捞 绝绢..
	if( !connections[n->targetid].dwAgentConnectionIndex || connections[n->targetid].state < CONNECT_JOIN ) return 0;
	if( connections[n->targetid].chrlst.bAlive >= DEAD_ ) return 0;
	
	tx = connections[ n->targetid].chrlst.MoveSx;
	ty = connections[ n->targetid].chrlst.MoveSy;
	*x = n->MoveSx;  *y = n->MoveSy;
	tempdir = NPC_GetDir( tx, ty, n->MoveSx, n->MoveSy );
	
	switch( tempdir )
	{
	case 0 :			ty +=dist;	break;
	case 1 : tx -=dist;	ty +=dist;	break;
	case 2 : tx -=dist;				break;
	case 3 : tx -=dist;	ty -=dist;	break;
	case 4 :			ty -=dist;	break;
	case 5 : tx +=dist;	ty -=dist;	break;
	case 6 : tx +=dist;				break;
	case 7 : tx +=dist;	ty +=dist;	break;
	}
	
	for( j = 0 ; j < 10 ; j ++)
	{
		for( i = 0 ;  i < 5 ; i ++)
		{
			ttx = tx;	tty = ty;
			d = ( tempdir + 8 + dirt[i] ) %8;
			switch( d )
			{
			case 0 :			tty +=j; break;
			case 1 : ttx -=j;	tty +=j; break;
			case 2 : ttx -=j;			 break;
			case 3 : ttx -=j;	tty -=j; break;
			case 4 :			tty -=j; break;
			case 5 : ttx +=j;	tty -=j; break;
			case 6 : ttx +=j;			 break;
			case 7 : ttx +=j;	tty +=j; break;
			}
			
			if( FreeTile( n, n->MoveSx, n->MoveSy, ttx, tty ) )  
			{
				*x = ttx;  *y = tty;
				return 1;
			}
		}
	}
	
	return 0;
}	

int NPC_GetDir( int sx, int sy, int ex, int ey )
{	
	if( sx > ex )  // 1/2/3
	{
		if( sy > ey )		return 3;
		else if( sy < ey )	return 1; 
		else				return 2;
	}
	else if( sx < ex ) // 5/6/7
	{
		if( sy > ey )		return 5;
		else if( sy < ey )	return 7; 
		else				return 6;
	}
	else 
	{
		if( sy > ey )		return 4;
		else if( sy < ey )	return 0;
	}
	
	return -1;
}		

int NPC_MakePath( CHARLIST *n, int tx, int ty, int how = 0 )
{		
	int dir;
	int c, i;
	int nx, ny, px, py;
	if( g_block_move )
	{
		return 0;
	}
	
	if (n->MoveP==0) return 0;		// LTS AI
	
	n->tx = tx;
	n->ty = ty;
	n->how = how;
	
	if( n->MovePathCount < 2 )
	{
		if( PathBuild( n, tx, ty ) == false ) { return 0; }
		
		int bOdd = 0;
		
		if( n->pathcount )
		{
			px = n->path[ n->pathcount -1][0];
			py = n->path[ n->pathcount -1][1];
			
			c = 0;
			for( i = n->pathcount -2 ; i >= 0 ; i -- )
			{		
				nx = n->path[i][0];
				ny = n->path[i][1];
				
				if( nx > px ) 
				{	
					if( ny > py )		{ dir = 7; }
					else if( ny < py )	{ dir = 5; }
					else				{ dir = 6; }
				}	
				else if( nx < px )
				{	
					if( ny > py )		{ dir = 1; }
					else if( ny < py )	{ dir = 3; }
					else				{ dir = 2; }
				}	
				else 
				{	
					if( ny > py )		{ dir = 0; }
					else				{ dir = 4; }
				}	
				
				
				if (  bOdd == 0){	n->MoveDirTbl[ (c/2) ] = dir << 4;	}
				else			{	n->MoveDirTbl[ (c/2) ] += dir;		}
				c++;
				bOdd = !bOdd;
				px = nx;
				py = ny;
			}
			
			n->MoveLength		= c;
			n->MovePathCount	= 0;
			n->MoveGox			= tx * TILE_SIZE + 16 -5 + ran(10);		// 捞悼困摹啊 函版
			n->MoveGoy			= ty * TILE_SIZE + 16 -5 + ran(10);		// 捞悼困摹啊 函版
			n->WalkTime			= global_time; // timeGetTime();
			n->MoveType			= 0;
			
			return 1;
		}
		
		return 0;
	}
	
	return 0;
}			

int NPC_MakePathBumn( CHARLIST *n, int tx, int ty, int how = 0 )
{
	int dir;
	int c, i;
	int nx, ny, px, py;
	
	n->tx = tx;
	n->ty = ty;
	n->how = how;
	
	if( g_block_move ) return 0;

⌨️ 快捷键说明

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