mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
Learn preview talents fix
This commit is contained in:
parent
49322fa20a
commit
329b06d1e3
6 changed files with 139 additions and 35 deletions
|
|
@ -1244,7 +1244,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||||
/*0x4BF*/ { "SMSG_UNKNOWN_1215", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4BF*/ { "SMSG_UNKNOWN_1215", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4C0*/ { "SMSG_TALENTS_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4C0*/ { "SMSG_TALENTS_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4C1*/ { "CMSG_LEARN_PREVIEW_TALENTS", STATUS_LOGGEDIN, &WorldSession::HandleLearnPreviewTalents },
|
/*0x4C1*/ { "CMSG_LEARN_PREVIEW_TALENTS", STATUS_LOGGEDIN, &WorldSession::HandleLearnPreviewTalents },
|
||||||
/*0x4C2*/ { "CMSG_LEARN_PREVIEW_TALENTS_PET", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4C2*/ { "CMSG_LEARN_PREVIEW_TALENTS_PET", STATUS_LOGGEDIN, &WorldSession::HandleLearnPreviewTalentsPet },
|
||||||
/*0x4C3*/ { "UMSG_UNKNOWN_1219", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4C3*/ { "UMSG_UNKNOWN_1219", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4C4*/ { "UMSG_UNKNOWN_1220", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4C4*/ { "UMSG_UNKNOWN_1220", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4C5*/ { "UMSG_UNKNOWN_1221", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4C5*/ { "UMSG_UNKNOWN_1221", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,7 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pet->resetTalents();
|
pet->resetTalents();
|
||||||
|
_player->SendTalentsInfoData(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
|
void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
|
||||||
|
|
@ -669,4 +670,31 @@ void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data )
|
||||||
recv_data >> guid >> talent_id >> requested_rank;
|
recv_data >> guid >> talent_id >> requested_rank;
|
||||||
|
|
||||||
_player->LearnPetTalent(guid, talent_id, requested_rank);
|
_player->LearnPetTalent(guid, talent_id, requested_rank);
|
||||||
|
_player->SendTalentsInfoData(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldSession::HandleLearnPreviewTalentsPet( WorldPacket & recv_data )
|
||||||
|
{
|
||||||
|
sLog.outDebug("CMSG_LEARN_PREVIEW_TALENTS_PET");
|
||||||
|
|
||||||
|
CHECK_PACKET_SIZE(recv_data, 8+4);
|
||||||
|
|
||||||
|
uint64 guid;
|
||||||
|
recv_data >> guid;
|
||||||
|
|
||||||
|
uint32 talentsCount;
|
||||||
|
recv_data >> talentsCount;
|
||||||
|
|
||||||
|
uint32 talentId, talentRank;
|
||||||
|
|
||||||
|
for(uint32 i = 0; i < talentsCount; ++i)
|
||||||
|
{
|
||||||
|
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4);
|
||||||
|
|
||||||
|
recv_data >> talentId >> talentRank;
|
||||||
|
|
||||||
|
_player->LearnPetTalent(guid, talentId, talentRank, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
_player->SendTalentsInfoData(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18080,25 +18080,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
|
||||||
m_achievementMgr.SendAllAchievementData();
|
m_achievementMgr.SendAllAchievementData();
|
||||||
UpdateZone(GetZoneId());
|
UpdateZone(GetZoneId());
|
||||||
|
|
||||||
uint32 count = 0;
|
SendEquipmentSetList();
|
||||||
data.Initialize(SMSG_EQUIPMENT_SET_LIST, 4);
|
|
||||||
size_t count_pos = data.wpos();
|
|
||||||
data << uint32(count); // count placeholder
|
|
||||||
for(EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr)
|
|
||||||
{
|
|
||||||
if(itr->second.state==EQUIPMENT_SET_DELETED)
|
|
||||||
continue;
|
|
||||||
data.appendPackGUID(itr->second.Guid);
|
|
||||||
data << uint32(itr->first);
|
|
||||||
data << itr->second.Name;
|
|
||||||
data << itr->second.IconName;
|
|
||||||
for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
|
||||||
data.appendPackGUID(MAKE_NEW_GUID(itr->second.Items[i], 0, HIGHGUID_ITEM));
|
|
||||||
|
|
||||||
++count; // client have limit but it checked at loading and set
|
|
||||||
}
|
|
||||||
data.put<uint32>(count_pos,count);
|
|
||||||
GetSession()->SendPacket(&data);
|
|
||||||
|
|
||||||
data.Initialize(SMSG_LOGIN_SETTIMESPEED, 8);
|
data.Initialize(SMSG_LOGIN_SETTIMESPEED, 8);
|
||||||
data << uint32(secsToTimeBitFields(sWorld.GetGameTime()));
|
data << uint32(secsToTimeBitFields(sWorld.GetGameTime()));
|
||||||
|
|
@ -19669,19 +19651,80 @@ void Player::BuildPlayerTalentsInfoData(WorldPacket *data)
|
||||||
|
|
||||||
void Player::BuildPetTalentsInfoData(WorldPacket *data)
|
void Player::BuildPetTalentsInfoData(WorldPacket *data)
|
||||||
{
|
{
|
||||||
*data << uint32(0); // unspentTalentPoints
|
uint32 unspentTalentPoints = 0;
|
||||||
*data << uint8(0); // talentCount
|
size_t pointsPos = data->wpos();
|
||||||
/*for(talentCount)
|
*data << uint32(unspentTalentPoints); // [PH], unspentTalentPoints
|
||||||
|
|
||||||
|
uint8 talentIdCount = 0;
|
||||||
|
size_t countPos = data->wpos();
|
||||||
|
*data << uint8(talentIdCount); // [PH], talentIdCount
|
||||||
|
|
||||||
|
Pet *pet = GetPet();
|
||||||
|
if(!pet)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unspentTalentPoints = pet->GetFreeTalentPoints();
|
||||||
|
|
||||||
|
data->put<uint32>(pointsPos, unspentTalentPoints); // put real points
|
||||||
|
|
||||||
|
CreatureInfo const *ci = pet->GetCreatureInfo();
|
||||||
|
if(!ci)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
|
||||||
|
if(!pet_family || pet_family->petTalentType < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId)
|
||||||
{
|
{
|
||||||
*data << uint32(0); // Talent.dbc
|
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentTabId );
|
||||||
*data << uint8(0); // maxRank
|
if(!talentTabInfo)
|
||||||
}*/
|
continue;
|
||||||
|
|
||||||
|
if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for(uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
|
||||||
|
{
|
||||||
|
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
|
||||||
|
if(!talentInfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// skip another tab talents
|
||||||
|
if(talentInfo->TalentTab != talentTabId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// find max talent rank
|
||||||
|
int32 curtalent_maxrank = -1;
|
||||||
|
for(int32 k = 4; k > -1; --k)
|
||||||
|
{
|
||||||
|
if(talentInfo->RankID[k] && pet->HasSpell(talentInfo->RankID[k]))
|
||||||
|
{
|
||||||
|
curtalent_maxrank = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not learned talent
|
||||||
|
if(curtalent_maxrank < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*data << uint32(talentInfo->TalentID); // Talent.dbc
|
||||||
|
*data << uint8(curtalent_maxrank); // talentMaxRank (0-4)
|
||||||
|
|
||||||
|
++talentIdCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->put<uint8>(countPos, talentIdCount); // put real count
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SendTalentsInfoData(bool pet)
|
void Player::SendTalentsInfoData(bool pet)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_TALENTS_INFO, 50);
|
WorldPacket data(SMSG_TALENTS_INFO, 50);
|
||||||
data << uint8(pet);
|
data << uint8(pet ? 1 : 0);
|
||||||
if(pet)
|
if(pet)
|
||||||
BuildPetTalentsInfoData(&data);
|
BuildPetTalentsInfoData(&data);
|
||||||
else
|
else
|
||||||
|
|
@ -19721,7 +19764,7 @@ void Player::BuildEnchantmentsInfoData(WorldPacket *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
void Player::LearnTalent(uint32 talentId, uint32 talentRank, bool skipPrevRanks)
|
||||||
{
|
{
|
||||||
uint32 CurTalentPoints = GetFreeTalentPoints();
|
uint32 CurTalentPoints = GetFreeTalentPoints();
|
||||||
|
|
||||||
|
|
@ -19745,8 +19788,12 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
||||||
if( (getClassMask() & talentTabInfo->ClassMask) == 0 )
|
if( (getClassMask() & talentTabInfo->ClassMask) == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// check for LearnPreviewTalents case
|
||||||
|
if(skipPrevRanks && (CurTalentPoints < (talentRank + 1)))
|
||||||
|
return;
|
||||||
|
|
||||||
// prevent skip talent ranks (cheating)
|
// prevent skip talent ranks (cheating)
|
||||||
if(talentRank > 0 && !HasSpell(talentInfo->RankID[talentRank-1]))
|
if(talentRank > 0 && !HasSpell(talentInfo->RankID[talentRank-1]) && !skipPrevRanks)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check if it requires another talent
|
// Check if it requires another talent
|
||||||
|
|
@ -19820,7 +19867,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
||||||
SetFreeTalentPoints(CurTalentPoints - 1);
|
SetFreeTalentPoints(CurTalentPoints - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
|
void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank, bool skipPrevRanks)
|
||||||
{
|
{
|
||||||
Pet *pet = GetPet();
|
Pet *pet = GetPet();
|
||||||
|
|
||||||
|
|
@ -19865,8 +19912,12 @@ void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
|
||||||
if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
|
if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// check for LearnPreviewTalents case
|
||||||
|
if(skipPrevRanks && (CurTalentPoints < (talentRank + 1)))
|
||||||
|
return;
|
||||||
|
|
||||||
// prevent skip talent ranks (cheating)
|
// prevent skip talent ranks (cheating)
|
||||||
if(talentRank > 0 && !pet->HasSpell(talentInfo->RankID[talentRank-1]))
|
if(talentRank > 0 && !pet->HasSpell(talentInfo->RankID[talentRank-1]) && !skipPrevRanks)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Check if it requires another talent
|
// Check if it requires another talent
|
||||||
|
|
@ -19937,6 +19988,29 @@ void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
|
||||||
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
|
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::SendEquipmentSetList()
|
||||||
|
{
|
||||||
|
uint32 count = 0;
|
||||||
|
WorldPacket data(SMSG_EQUIPMENT_SET_LIST, 4);
|
||||||
|
size_t count_pos = data.wpos();
|
||||||
|
data << uint32(count); // count placeholder
|
||||||
|
for(EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr)
|
||||||
|
{
|
||||||
|
if(itr->second.state==EQUIPMENT_SET_DELETED)
|
||||||
|
continue;
|
||||||
|
data.appendPackGUID(itr->second.Guid);
|
||||||
|
data << uint32(itr->first);
|
||||||
|
data << itr->second.Name;
|
||||||
|
data << itr->second.IconName;
|
||||||
|
for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
||||||
|
data.appendPackGUID(MAKE_NEW_GUID(itr->second.Items[i], 0, HIGHGUID_ITEM));
|
||||||
|
|
||||||
|
++count; // client have limit but it checked at loading and set
|
||||||
|
}
|
||||||
|
data.put<uint32>(count_pos,count);
|
||||||
|
GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
|
|
||||||
void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset)
|
void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset)
|
||||||
{
|
{
|
||||||
EquipmentSet& eqslot = m_EquipmentSets[index];
|
EquipmentSet& eqslot = m_EquipmentSets[index];
|
||||||
|
|
|
||||||
|
|
@ -1475,8 +1475,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void BuildPlayerTalentsInfoData(WorldPacket *data);
|
void BuildPlayerTalentsInfoData(WorldPacket *data);
|
||||||
void BuildPetTalentsInfoData(WorldPacket *data);
|
void BuildPetTalentsInfoData(WorldPacket *data);
|
||||||
void SendTalentsInfoData(bool pet);
|
void SendTalentsInfoData(bool pet);
|
||||||
void LearnTalent(uint32 talentId, uint32 talentRank);
|
void LearnTalent(uint32 talentId, uint32 talentRank, bool skipPrevRanks = false);
|
||||||
void LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank);
|
void LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank, bool skipPrevRanks = false);
|
||||||
|
|
||||||
uint32 CalculateTalentsPoints() const;
|
uint32 CalculateTalentsPoints() const;
|
||||||
|
|
||||||
|
|
@ -1867,6 +1867,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType);
|
void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType);
|
||||||
void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex);
|
void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex);
|
||||||
|
|
||||||
|
void SendEquipmentSetList();
|
||||||
void SetEquipmentSet(uint32 index, EquipmentSet eqset);
|
void SetEquipmentSet(uint32 index, EquipmentSet eqset);
|
||||||
void DeleteEquipmentSet(uint64 setGuid);
|
void DeleteEquipmentSet(uint64 setGuid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
|
||||||
|
|
||||||
void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
|
void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
sLog.outDebug("CMSG_UNKNOWN_1217");
|
sLog.outDebug("CMSG_LEARN_PREVIEW_TALENTS");
|
||||||
|
|
||||||
CHECK_PACKET_SIZE(recvPacket, 4);
|
CHECK_PACKET_SIZE(recvPacket, 4);
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
|
||||||
|
|
||||||
recvPacket >> talentId >> talentRank;
|
recvPacket >> talentId >> talentRank;
|
||||||
|
|
||||||
_player->LearnTalent(talentId, talentRank);
|
_player->LearnTalent(talentId, talentRank, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_player->SendTalentsInfoData(false);
|
_player->SendTalentsInfoData(false);
|
||||||
|
|
|
||||||
|
|
@ -579,6 +579,7 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
void HandlePetSpellAutocastOpcode( WorldPacket& recvPacket );
|
void HandlePetSpellAutocastOpcode( WorldPacket& recvPacket );
|
||||||
void HandlePetCastSpellOpcode( WorldPacket& recvPacket );
|
void HandlePetCastSpellOpcode( WorldPacket& recvPacket );
|
||||||
void HandlePetLearnTalent( WorldPacket& recvPacket );
|
void HandlePetLearnTalent( WorldPacket& recvPacket );
|
||||||
|
void HandleLearnPreviewTalentsPet( WorldPacket& recvPacket );
|
||||||
|
|
||||||
void HandleSetActionBar(WorldPacket& recv_data);
|
void HandleSetActionBar(WorldPacket& recv_data);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue