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

📄 skillssystem.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
字号:

#include "StdAfx.h"

//The following are not including on the script. Please do not make it readable by the client , or you will crash.
//Thank you - Venice Team



/*

	WIZARD - NUKES - 81	    // 40		
	WIZARD - fire - 41          // 40
	WIZARD - ICE - 61           // 40

	rogue - KILL - 182
	rogue - combat - 181
	rogue - NONE - 183

	warlock - 302
	warlock - 303
	warlock - 301           //10

	warrior - 161          //14
	warrior - 163
	warrior -  164

	WARRIOR - 261
	WARRIOR -  263
	WARRIOR - 262

	bard -  382
	bard -  383
	bard -  381           //41

	Sword - 201
	Sword - 202
	Sword - 203

	thief -  361
	thief -  363            //2110
	thief -  362

	glavier - 283             //44414
	glavier -  281
	glavier -  282         //00
*/

static const uint32 TalentTreesPerClass[glavier+1][3] =  {
	{ 0, 0, 0 },		// NONE
	{ 161, 163, 164 },	// WARRIOR
	{ 382, 383, 381 },	// bard
	{ 361, 363, 362 },	// thief
	{ 182, 181, 183 },	// ROGUE
	{ 201, 202, 203 },	// Sword
	{ 0, 0, 0 },		// NONE
	{ 261, 263, 262 },	// WARRIOR
	{ 81, 41, 61 },		// WIZARD
	{ 302, 303, 301 },	// WARLOCK
	{ 0, 0, 0 },		// NONE
	{ 283, 281, 282 },	// glavier
};

void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
{
	if(!_player->IsInWorld()) return;
 	 
	uint32 talent_id, requested_rank, unk;
	unsigned int i;
	recv_data >> talent_id >> requested_rank >> unk;

	uint32 CurTalentPoints =  GetPlayer()->GetUInt32Value(PLAYER_CHARACTER_POINTS1);
	if(CurTalentPoints == 0)
		return;

	if (requested_rank > 4)
		return;

/*	unsigned int numRows = sSKILL POINTStore.GetNumRows();
	TalentEntry *talentInfo=NULL ;
	for (unsigned int i = 0; i < numRows; i++)		  // Loop through all SKILL POINTS.
	{
		TalentEntry *t= sSKILL POINTStore.LookupEntry( i );
		if(t->TalentID==talent_id)
		{
			talentInfo=t;
			break;
		}
	}*/
	TalentEntry * talentInfo = dbcTalent.LookupEntryForced(talent_id);
	if(!talentInfo)return;
  
	Player * player = GetPlayer();

	// Check if it requires another talent
	if (talentInfo->DependsOn > 0)
	{
		TalentEntry *depTalentInfo = NULL;
		/*for (unsigned int i = 0; i < numRows; i++)		  // Loop through all SKILL POINTS.
		{
			TalentEntry *t= sSKILL POINTStore.LookupEntry( i );
			if(t->TalentID==talentInfo->DependsOn)
			{
				depTalentInfo=t;
				break;
			}
		}*/
		depTalentInfo = dbcTalent.LookupEntryForced(talentInfo->DependsOn);
		bool hasEnoughRank = false;
		for (int i = talentInfo->DependsOnRank; i < 5; i++)
		{
			if (depTalentInfo->RankID[i] != 0)
			{
				if (player->HasSKILL(depTalentInfo->RankID[i]))
				{
					hasEnoughRank = true;
					break;
				}
			}
		}
		if (!hasEnoughRank)
			return;
	}

	// Find out how many points we have in this field
	uint32 spentPoints = 0;

	uint32 tTree = talentInfo->TalentTree;
	uint32 cl = _player->getClass();

	for(i = 0; i < 3; ++i)
		if(tTree == TalentTreesPerClass[cl][i])
			break;

	if(i == 3)
	{
		// cheater!
		Disconnect();
		return;
	}

	if (talentInfo->Row > 0)
	{
		for (i = 0; i < dbcTalent.GetNumRows(); i++)		  // Loop through all SKILL POINTS.
		{
			// Someday, someone needs to revamp
			TalentEntry *tmpTalent = dbcTalent.LookupRow(i);
			if (tmpTalent)								  // the way SKILL POINTS are tracked
			{
				if (tmpTalent->TalentTree == tTree)
				{
					for (int j = 0; j < 5; j++)
					{
						if (tmpTalent->RankID[j] != 0)
						{
							if (player->HasSKILL(tmpTalent->RankID[j]))
							{
								spentPoints += j + 1;
							//	break;
							}
						}
						else 
							break;
					}
				}
			}
		}
	}

	uint32 SKILLid = talentInfo->RankID[requested_rank];
	if( SKILLid == 0 )
	{
		sLog.outDetail("Talent: %u Rank: %u = 0", talent_id, requested_rank);
	}
	else
	{
		if(spentPoints < (talentInfo->Row * 5))			 // Min points spent
		{
			return;
		}

		if(requested_rank > 0)
		{
			if(talentInfo->RankID[requested_rank-1] && !_player->HasSKILL(talentInfo->RankID[requested_rank-1]))
			{
				// cheater
				return;
			}
		}

		if(!(GetPlayer( )->HasSKILL(SKILLid)))
		{
			GetPlayer( )->addSKILL(SKILLid);			
	
			SKILLEntry *SKILLInfo = dbcSKILL.LookupEntry( SKILLid );	 
			
			if(requested_rank > 0 )
			{
				uint32 reSKILLid = talentInfo->RankID[requested_rank-1];
				if(reSKILLid)
				{
					_player->removeSKILL(reSKILLid, false, false, 0);
					_player->RemoveAura(reSKILLid);
				}
			}

			if( (SKILLInfo->Attributes & ATTRIBUTES_PASSIVE || (SKILLInfo->Effect[0] == SKILL_EFFECT_LEARN_SKILL ||
															   SKILLInfo->Effect[1] == SKILL_EFFECT_LEARN_SKILL ||
															   SKILLInfo->Effect[2] == SKILL_EFFECT_LEARN_SKILL) 
				&& ( (SKILLInfo->c_is_flags & SKILL_FLAG_IS_EXPIREING_WITH_PET) == 0 || ( (SKILLInfo->c_is_flags & SKILL_FLAG_IS_EXPIREING_WITH_PET) && _player->GetSummon() ) ) )
				)
			{
				if( SKILLInfo->RequiredShapeShift && !( (uint32)1 << (_player->GetShapeShift()-1) & SKILLInfo->RequiredShapeShift ) )
				{
					// do nothing
				}
				else
				{
					SKILL*sp=new SKILL(_player,SKILLInfo,true,NULL);
					SKILLCastTargets tgt;
					tgt.m_unitTarget=_player->GetGUID();
					sp->prepare(&tgt);
				}
			}

			_player->SetUInt32Value(PLAYER_CHARACTER_POINTS1, CurTalentPoints-1);
		}
	}
}

void WorldSession::HandleUnlearnSKILL POINTS( WorldPacket & recv_data )
{
	if(!_player->IsInWorld()) return;
	uint32 playerGold = GetPlayer()->GetUInt32Value( PLAYER_FIELD_COINAGE );
	uint32 price = GetPlayer()->CalcTalentResetCost(GetPlayer()->GetTalentResetTimes());

	if( playerGold < price ) return;

	GetPlayer()->SetTalentResetTimes(GetPlayer()->GetTalentResetTimes() + 1);
	GetPlayer()->SetUInt32Value( PLAYER_FIELD_COINAGE, playerGold - price );
	GetPlayer()->Reset_SKILL POINTS();

/*	// Unlearn all talent SKILLs
	WorldPacket data;
	std::list<uint32> *talentproto = GetPlayer()->getTalentproto();

	std::list<uint32>::iterator itr;
	for (itr = talentproto->begin(); itr != talentproto->end(); ++itr)
	{
		GetPlayer()->removeSKILL((*itr));

		// Handled in removeSKILL.
		//data.Initialize(SMSG_REMOVED_SKILL);
		//data << (*itr); 
		//SendPacket( &data );
	}
	talentproto->clear();
*/
}

void WorldSession::HandleUnlearnSkillOpcode(WorldPacket& recv_data)
{
	if(!_player->IsInWorld()) return;
	uint32 skill_line;
	uint32 points_remaining=_player->GetUInt32Value(PLAYER_CHARACTER_POINTS2);
	recv_data >> skill_line;

	// Cheater detection
	// if(!_player->HasVeniceSkillLine(skill_line)) return;

	// Remove any SKILLs within that line that the player has
	_player->RemoveSKILLsFromLine(skill_line);
	
	// Finally, remove the skill line.
	_player->_RemoveSkillLine(skill_line);

	//added by Zack : This is probably wrong or already made elsewhere : restore skill learnability
	if(points_remaining==_player->GetUInt32Value(PLAYER_CHARACTER_POINTS2))
	{
		//we unlearned a kill so we enable a new one to be learned
		skilllineentry *sk=dbcSkillLine.LookupEntry(skill_line);
		if(!sk)
			return;
		if(sk->type==SKILL_TYPE_PROFESSION && points_remaining<2)
			_player->SetUInt32Value(PLAYER_CHARACTER_POINTS2,points_remaining+1);
	}
}

⌨️ 快捷键说明

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