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

📄 npc_pattern.cpp

📁 国内著名网络游戏dragon的服务端完整源码 内附完整数据库结构
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	
	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;
}

inline int NPC_IsMoving( CHARLIST *n )
{			
	if( n->desttime > global_time ) return 1;
	return 0;
}			

int NPC_IsWhoNearPC( CHARLIST *npc, int tilerange  )
{
	int i;
	CHARLIST *ch;
	int x = npc->X;
	int y = npc->Y;
	int tx, ty;
	DWORD t, min = 0xFFFFFFFF;
	int findch;
	
	for( i = DRAGON_CONNECTIONS_START ; i < DRAGON_MAX_CONNECTIONS ; i ++)
	{
		if(connections[i].dwAgentConnectionIndex && connections[i].state >= CONNECT_JOIN )
		{
			ch = &connections[i].chrlst;
			if( ch->bAlive >= DEAD_ || ch->GetState() == CON_STONE) continue;
			
			tx = ch->X;
			ty = ch->Y;
			t = (tx-x)*(tx-x) + (ty-y)*(ty-y);
			if( t < min ) 
			{
				min = t;
				findch = i;
			}
		}
	}
	
	if( min > (DWORD)(TILE_SIZE * tilerange) * (DWORD)( TILE_SIZE *tilerange) ) 
	{
		
		return -1;
	}
	
	
	return findch;
}

CHARLIST* NPC_ReturnCharListPoint( const int id )
{//021030 lsw////叼厚单阁(1)捞搁 巩力啊 积辨 荐档 乐绢辑 绊闷嚼聪促.
	if( id < 0 ) return NULL;
	
	if( id >= 10000 )
	{	
		if( NPCList[ id-10000 ].bAlive >= DEAD_ ) return NULL;
		else return &NPCList[ id-10000];
	}	
	else 
	{	
		CHARLIST *pTempCh = ::CheckServerId( id );
		if(pTempCh)
		{
			if(pTempCh->bAlive < DEAD_)//磷篮 惑怕搁 棵赋聪促.
			{
				return pTempCh;
			}
		}
	}
	return NULL;
}		



CHARLIST* ReturnCharListPoint( char *name )
{	//< CSD-030415	
	if (name != NULL)
	{	
		for (int i = NPC_LIST_START ; i < MAX_NPC_LIST; ++i)
		{	
			if (NPCList[i].bAlive == ALIVE_)
			{
				if (strcmp(NPCList[i].Name, name) == 0)
				{
					return &NPCList[i];
				}
			}
		}	

		CHARLIST* pUser = g_pUserManager->GetCharList(name);

		if (pUser != NULL && pUser->bAlive == ALIVE_)
		{
			return pUser;
		}
	}

	return NULL;
}	//> CSD-030415

#define MAGIC_TEST_NO	30

bool SetTileOccupied(short int &iX, short int &iY, const bool bOccupiedState)
{
	if(	VILLAGE_SIZE <= iX
		||	VILLAGE_SIZE <= iY
		||	0 > iX
		||  0 > iY)
	{
		::MyLog(1,"Critical Warning!! SetTileOccupied(%d, %d) Call Developer",iX,iY);
		if(0 > iX)	{iX = 0;}
		if(0 > iY)	{iY = 0;}
		
		if(VILLAGE_SIZE > iX){iX = VILLAGE_SIZE-1;}
		if(VILLAGE_SIZE > iY){iY = VILLAGE_SIZE-1;}
		
		return false;
	}
	
	TileMap[iX][iY].occupied = bOccupiedState;
	return true;
}

void CharacterMovingSub( CHARLIST *ch, int spritetype )
{
	if( ch->MovePathCount >= ch->MoveLength ) 
	{
		ch->MovePathCount = ch->MoveLength = 0;
		ch->X = ch->MoveGox;
		ch->Y = ch->MoveGoy;
		return;
	}
	
	int dir = ch->MoveDirTbl[ ch->MovePathCount >> 1];
	
	if( ch->MovePathCount % 2 )
	{	
		dir &= 0x0f;
	}	
	else 
	{	
		dir >>= 4;
	}	
	
	::SetTileOccupied(ch->MoveSx,ch->MoveSy,false);
	
	ch->OldMoveSx = ch->MoveSx;
	ch->OldMoveSy = ch->MoveSy;
	
	switch( dir )
	{	
	case 0 : 					ch->MoveSy++;	break;
	case 1 : 	ch->MoveSx--; 	ch->MoveSy++;	break;
	case 2 : 	ch->MoveSx--;					break;
	case 3 : 	ch->MoveSx--; 	ch->MoveSy--;	break;
	case 4 : 					ch->MoveSy--; 	break;
	case 5 : 	ch->MoveSx++;	ch->MoveSy--;	break;
	case 6 : 	ch->MoveSx++; 					break;
	case 7 : 	ch->MoveSx++;	ch->MoveSy++;	break;
	}	
	
	::SetTileOccupied(ch->MoveSx,ch->MoveSy,true);
	
	ch->MovePathCount++;
	if( ch->MovePathCount >= ch->MoveLength )
	{
		ch->X = ch->MoveGox;
		ch->Y = ch->MoveGoy;
		ch->MovePathCount = ch->MoveLength = 0;
		
		if( spritetype == SPRITETYPE_NPC )
		{
			::SendModifyPositionNPC( connections, ch->GetServerID()); 
		}
	}	
	else 
	{	
		ch->X = (ch->MoveSx * TILE_SIZE ) + 16;
		ch->Y = (ch->MoveSy * TILE_SIZE ) + 16;
	}
}

void MovingNPC()
{
	const DWORD curtime = ::timeGetTime();
	
	for( int i = NPC_LIST_START ; i < MAX_NPC_LIST ; i++ ) 
	{
		CHARLIST* npc = ::CheckNpcId(i);
		if(!npc){continue;}
		
		if(	ALIVE_ != npc->bAlive	
			||	CON_STONE == npc->GetState() )
		{
			continue;
		}
		
		if( npc->MoveLength <= npc->MovePathCount )
		{
			if (npc->ChairNum)
			{
				g_pAIManager->ProcessNPCAI(npc);
			}
			
			continue;
		}
		
		const DWORD dwDelayTime = ::Get_MoveDelayTime( npc );
		if(dwDelayTime <= 0){continue;}
		
		const DWORD dwElapsedTime = curtime - npc->WalkTime;
		if( dwElapsedTime >= dwDelayTime ) 
		{
			const DWORD oldt =  dwElapsedTime / dwDelayTime;
			DWORD t = oldt;
			npc->WalkTime += t * dwDelayTime;
			for( ; t ; t-- )
			{
				::CharacterMovingSub( npc, SPRITETYPE_NPC );
			}
			if( oldt )
			{
				::SetArea(MOVE_NPC_AREA, i );
			}
		}
		
		switch (NPC_Gen_Ref[npc->npc_index].nAttr)
		{	//< CSD-031027
		case AT_PIERCING:
		case AT_ANTIMAGIC:
		case AT_BOSS:
		case AT_SEMIBOSS:
			{
				if (npc->ChairNum)
				{
					g_pAIManager->ProcessNPCAI(npc);
				}

				break;
			}
		}	//> CSD-031027
	}
}

void MovingCharacter()
{
	const DWORD dwCurtime = ::timeGetTime();
	
	for(int i = DRAGON_CONNECTIONS_START ; i < DRAGON_MAX_CONNECTIONS; i ++ )
	{
		CHARLIST *pc = ::CheckServerId(i);
		if(!pc){continue;}
		if(pc->MoveLength <= pc->MovePathCount ){continue;}
		
		const DWORD dwElapsedTime = dwCurtime - pc->WalkTime;
		const DWORD dwDelayTime = ::Get_MoveDelayTime( pc );
		if( dwDelayTime <= 0  )
		{
			pc->MoveLength = pc->MovePathCount = 0;
			continue;
		}
		
		if( dwElapsedTime >= dwDelayTime ) 
		{
			const DWORD oldt =  dwElapsedTime / dwDelayTime;
			DWORD t = oldt;
			
			pc->WalkTime += t * dwDelayTime;
			for( ; t ; t-- )
			{
				::CharacterMovingSub( pc, SPRITETYPE_CHARACTER );
				
				if( !pc->Peacests)
				{
					::HungryMuchAdd( pc, ((!pc->MoveType)?HT_WALK:HT_RUN) ); // 硅绊悄荐摹 皑家.
				}
				else 
				{
					::HungryMuchAdd( pc, ((!pc->MoveType)?HT_BATTLE_WALK :HT_BATTLE_RUN) ); // 硅绊悄荐摹 皑家.
				}
			}
			if( oldt ) 
			{
				::SetArea(MOVE_PC_AREA, i );
			}
		}
	}
}

void NPCAddBasicData(int i, t_server_npc_add* p)
{	//< CSD-030419
	CHARLIST* pNpc = &NPCList[i];
	p->idNpc = i + 10000;
	p->nStatus = pNpc->bAlive;
	p->nSprNo = pNpc->SprNo;
	p->nMutant = pNpc->mutant;
	p->nX = pNpc->X;
	p->nY = pNpc->Y;
	p->nHomeX = pNpc->homex;
	p->nHomeY = pNpc->homey;
	p->nNameNo = pNpc->namenumber;
	p->nEventNpc	= (pNpc->eventno > 0) ? 1:0;
	p->nAttr = NPC_Gen_Ref[pNpc->npc_index].nAttr;
	p->nViewType = pNpc->viewtype;
	p->nRace = pNpc->Race;
	
	if (pNpc->patterntype >= NPC_PATTERN_WANDER && pNpc->patterntype <= NPC_PATTERN_ATTACKED) // LTS AI
	{
		p->nAIType	= pNpc->ChairNum;	// LTS AI
	}
	else
	{
		p->nAIType = 0;
	}
	
	switch (pNpc->generationtype)
	{	//< CSD-031013
	case GT_SKILL_SUMMON:
		{
			p->nAttr = AT_SUMMON;
			break;
		}
	case GT_HUNT_MONSTER:
		{
			p->nRecall = 0;
			break;
		}
	default:
		{
			p->nRecall = (pNpc->GetMaster() == 0) ? 0:1;
			break;
		}
	}	//> CSD-031013
}	//> CSD-030419

// 弥家 1付府绰 惯积阑 窍霸 茄促. 
void NPCGeneratePosition( int npcindex, int x, int y, int eventno, int maxno )
{	
	if( NPCgeneratePositionMax >= MAX_GENERATE_POSITION_ ) return;
	
	NPCgeneratePosition[ NPCgeneratePositionMax].curnpc		= 0;
	
	NPCgeneratePosition[ NPCgeneratePositionMax].npcindex	= npcindex;
	NPCgeneratePosition[ NPCgeneratePositionMax].x			= x;
	NPCgeneratePosition[ NPCgeneratePositionMax].y			= y;
	
	// Event锅龋啊 0锅捞搁 Event锅龋甫 啊龙荐 乐绰 NPC父 0锅阑 啊瘤绊 唱赣瘤绰 
	// -1蔼阑 爱绰促. 
	if( eventno == 0 )
	{	
		switch (npcindex)
		{
		case 21 :
		case 22 :
		case 23 :
		case 24 :
		case 71 :
		case 72 :
		case 73 :
		case 74 :
		case 75 :
		case 76 :
		case 77 :
		case 78 :
		case 79 :
		case 80 :	NPCgeneratePosition[ NPCgeneratePositionMax].eventno	= eventno;
			break;
			
		default : 	NPCgeneratePosition[ NPCgeneratePositionMax].eventno	= -1;
		}
	}
	else
	{
		NPCgeneratePosition[NPCgeneratePositionMax].eventno = eventno;
	}
	
	
	// 版厚绰 Event锅龋啊 绝绢具 茄促. 
	// 010613 KHS
	switch( npcindex )
	{
	case 18 :
	case 19 :
	case 20 : NPCgeneratePosition[ NPCgeneratePositionMax].eventno	= -1;
		break;
	}
	
	if( maxno <= 0 ) maxno = 1;
	NPCgeneratePosition[ NPCgeneratePositionMax].maxno						= maxno;
	
	NPCgeneratePositionMax ++;
}	

int  GetDeleteAbleNPC()//030211 lsw
{//酒林 老馆利栏肺 攫力 磷咯档 惑包绝绰 NPC甫 惶澜
	int i = NPC_LIST_START;
	int iTypeId = -1;
	for(; i < MAX_NPC_LIST; i ++)
	{
		const int iGenerateType = NPCList[i].generationtype;
		const int iAliveFlag =  NPCList[i].bAlive;
		if(	iGenerateType == GT_SKB_FILE 
			||	iGenerateType == GT_SKILL_SUMMON )
		{
			iTypeId = i;
		}
		if( iAliveFlag == REMOVE_)
		{
			return i;
		}
	}
	
	if(iTypeId >= 0)
	{
		return iTypeId;
	}
	
	::MyLog( LOG_NORMAL, "Can't Get Normal NpcList" );
	return(-1);
}

int NPC_Create(int Num, int npcindex, int x, int y, int eventno, int generationpos, int generationtype,int GroupNo, int isBoss)	// LTS AI2
{	//< CSD-030408
	if (Num < 0) 
	{
		MyLog(LOG_NORMAL, "NPC_CREATE Failed!!! Argument is Lower than Zero, Num : %d",Num);
		return 0;
	}
	
	if (npcindex < 0) 
	{
		MyLog(LOG_NORMAL, "NPC_CREATE Failed!!! Argument is Lower than Zero, Index : %d",npcindex);
		return 0;
	}
	if (npcindex >= Num_Of_NPC_Generation)
	{
		MyLog(LOG_NORMAL, "NPC_CREATE Failed!!! Argument is Higher than Max Generation, Index : %d",npcindex);
		return 0;
	}
	
	NPC_Generation* pNpcTable = &NPC_Gen_Ref[npcindex];	
	CHARLIST* n = &NPCList[Num];
	memset(n, 0, sizeof(CHARLIST));
	n->SprType = SPRITETYPE_NPC;
	n->npc_index = npcindex;
	n->SetServerID(Num);
	n->GenerateNpcName(); // 捞抚 汲沥
	n->eventno = eventno;
	n->generationpos = generationpos;
	n->generationtype = generationtype;
	n->SprNo = pNpcTable->SprNO;
	n->mutant = pNpcTable->mutant;
	n->homemap = MapNumber;
	n->homex = x; // 积己等 困摹
	n->homey = y;
	n->Class = CREATURE; // 努贰胶 汲沥
	n->Race = pNpcTable->nNpcRace; // 辆练 汲沥
	n->SetLevel(pNpcTable->nLvMin + ran(pNpcTable->nLvMax - pNpcTable->nLvMin)); // CSD-030806 : 饭骇 汲沥
	n->Exp = pNpcTable->nEpMax; // 版氰摹 汲沥
	n->SetClassStep(pNpcTable->nStep);
	n->SetAttribute(pNpcTable->nNpcRace); // 加己 汲沥
	n->Face = 0;
	n->Sight = 12;
	n->ResetAbility(0);
	n->Hp = n->HpMax ;
	n->Mana = n->ManaMax;
	n->Hungry = n->HungryMax;
	n->name_status.nation = (pNpcTable->nNpcNK == 0) ? 2:MapInfo[MapNumber].nation;
	n->Money = pNpcTable->Money_min + ran(pNpcTable->Money_Max - pNpcTable->Money_min);
	n->SetState(CON_NORMAL);
	// 历亲仿(窜困 %)
	n->SetBasicResist(RT_POISON, 0);                // 刀拌凯 付过俊 措茄 历亲仿
	n->SetBasicResist(RT_CURSE, 0);	                // 历林拌凯 付过俊 措茄 历亲仿
	n->SetBasicResist(RT_HOLY, pNpcTable->nHoly);   // 脚仿拌凯 傍拜 付过俊 措茄 历亲仿
	n->SetBasicResist(RT_FIRE, pNpcTable->nFire);   // 阂拌凯 傍拜 付过俊 措茄 历亲仿
	n->SetBasicResist(RT_ICE, pNpcTable->nIce);	    // 倔澜拌凯 傍拜 付过俊 措茄 历亲仿
	n->SetBasicResist(RT_ELECT, pNpcTable->nElect); // 傈拜拌凯 傍拜 付过俊 措茄 历亲仿
	
	switch (pNpcTable->Sel_gender)
	{
	case 1:
	case 2: 
		{

⌨️ 快捷键说明

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