mirror of
https://github.com/mangosfour/server.git
synced 2025-12-20 07:37:02 +00:00
Fixed talents display and inspect
This commit is contained in:
parent
8c489f80dc
commit
9e1e845e54
5 changed files with 131 additions and 133 deletions
|
|
@ -1184,76 +1184,20 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)
|
||||||
if(!plr) // wrong player
|
if(!plr) // wrong player
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32 talent_points = 0x3D;
|
WorldPacket data(SMSG_INSPECT_TALENT, 50);
|
||||||
uint32 guid_size = plr->GetPackGUID().size();
|
|
||||||
WorldPacket data(SMSG_INSPECT_TALENT, 4+talent_points);
|
|
||||||
data.append(plr->GetPackGUID());
|
data.append(plr->GetPackGUID());
|
||||||
data << uint32(talent_points);
|
|
||||||
|
|
||||||
// fill by 0 talents array
|
|
||||||
for(uint32 i = 0; i < talent_points; ++i)
|
|
||||||
data << uint8(0);
|
|
||||||
|
|
||||||
if(sWorld.getConfig(CONFIG_TALENTS_INSPECTING) || _player->isGameMaster())
|
if(sWorld.getConfig(CONFIG_TALENTS_INSPECTING) || _player->isGameMaster())
|
||||||
{
|
{
|
||||||
// find class talent tabs (all players have 3 talent tabs)
|
plr->BuildPlayerTalentsInfoData(&data);
|
||||||
uint32 const* talentTabIds = GetTalentTabPages(plr->getClass());
|
plr->BuildEnchantmentsInfoData(&data);
|
||||||
|
}
|
||||||
uint32 talentTabPos = 0; // pos of first talent rank in tab including all prev tabs
|
else
|
||||||
for(uint32 i = 0; i < 3; ++i)
|
{
|
||||||
{
|
data << uint32(0); // unspentTalentPoints
|
||||||
uint32 talentTabId = talentTabIds[i];
|
data << uint8(0); // talentGroupCount
|
||||||
|
data << uint8(0); // talentGroupIndex
|
||||||
// fill by real data
|
data << uint32(0); // slotUsedMask
|
||||||
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 talent rank
|
|
||||||
uint32 curtalent_maxrank = 0;
|
|
||||||
for(uint32 k = 5; k > 0; --k)
|
|
||||||
{
|
|
||||||
if(talentInfo->RankID[k-1] && plr->HasSpell(talentInfo->RankID[k-1]))
|
|
||||||
{
|
|
||||||
curtalent_maxrank = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// not learned talent
|
|
||||||
if(!curtalent_maxrank)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// 1 rank talent bit index
|
|
||||||
uint32 curtalent_index = talentTabPos + GetTalentInspectBitPosInTab(talentId);
|
|
||||||
|
|
||||||
uint32 curtalent_rank_index = curtalent_index+curtalent_maxrank-1;
|
|
||||||
|
|
||||||
// slot/offset in 7-bit bytes
|
|
||||||
uint32 curtalent_rank_slot7 = curtalent_rank_index / 7;
|
|
||||||
uint32 curtalent_rank_offset7 = curtalent_rank_index % 7;
|
|
||||||
|
|
||||||
// rank pos with skipped 8 bit
|
|
||||||
uint32 curtalent_rank_index2 = curtalent_rank_slot7 * 8 + curtalent_rank_offset7;
|
|
||||||
|
|
||||||
// slot/offset in 8-bit bytes with skipped high bit
|
|
||||||
uint32 curtalent_rank_slot = curtalent_rank_index2 / 8;
|
|
||||||
uint32 curtalent_rank_offset = curtalent_rank_index2 % 8;
|
|
||||||
|
|
||||||
// apply mask
|
|
||||||
uint32 val = data.read<uint8>(guid_size + 4 + curtalent_rank_slot);
|
|
||||||
val |= (1 << curtalent_rank_offset);
|
|
||||||
data.put<uint8>(guid_size + 4 + curtalent_rank_slot, val & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
talentTabPos += GetTalentTabInspectBitSize(talentTabId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
|
|
|
||||||
|
|
@ -18089,6 +18089,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
|
||||||
data << uint32( GetTutorialInt(i) );
|
data << uint32( GetTutorialInt(i) );
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
|
|
||||||
|
SendTalentInfoData(false);
|
||||||
SendInitialSpells();
|
SendInitialSpells();
|
||||||
|
|
||||||
data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4);
|
data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4);
|
||||||
|
|
@ -19611,3 +19612,119 @@ uint8 Player::CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_s
|
||||||
|
|
||||||
return EQUIP_ERR_OK;
|
return EQUIP_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::BuildPlayerTalentsInfoData(WorldPacket *data)
|
||||||
|
{
|
||||||
|
*data << uint32(GetFreeTalentPoints()); // unspentTalentPoints
|
||||||
|
uint8 talentGroupCount = 1;
|
||||||
|
*data << uint8(talentGroupCount); // talent group count (1 or 2)
|
||||||
|
*data << uint8(0); // talent group index (0 or 1)
|
||||||
|
|
||||||
|
if(talentGroupCount)
|
||||||
|
{
|
||||||
|
uint8 talentIdCount = 0;
|
||||||
|
size_t pos = data->wpos();
|
||||||
|
*data << uint8(talentIdCount); // [PH], talentIdCount
|
||||||
|
|
||||||
|
// find class talent tabs (all players have 3 talent tabs)
|
||||||
|
uint32 const* talentTabIds = GetTalentTabPages(getClass());
|
||||||
|
|
||||||
|
for(uint32 i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
uint32 talentTabId = talentTabIds[i];
|
||||||
|
|
||||||
|
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] && 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>(pos, talentIdCount); // put real count
|
||||||
|
|
||||||
|
uint8 glyphsCount = 6;
|
||||||
|
*data << uint8(glyphsCount); // glyphs count
|
||||||
|
|
||||||
|
for(uint8 i = 0; i < glyphsCount; ++i)
|
||||||
|
*data << uint16(GetGlyph(i)); // GlyphProperties.dbc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::BuildPetTalentsInfoData(WorldPacket *data)
|
||||||
|
{
|
||||||
|
*data << uint32(0); // unspentTalentPoints
|
||||||
|
*data << uint8(0); // talentCount
|
||||||
|
/*for(talentCount)
|
||||||
|
{
|
||||||
|
*data << uint32(0); // Talent.dbc
|
||||||
|
*data << uint8(0); // maxRank
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::SendTalentInfoData(bool pet)
|
||||||
|
{
|
||||||
|
WorldPacket data(SMSG_UNKNOWN_1216, 50);
|
||||||
|
data << uint8(pet);
|
||||||
|
if(pet)
|
||||||
|
BuildPetTalentsInfoData(&data);
|
||||||
|
else
|
||||||
|
BuildPlayerTalentsInfoData(&data);
|
||||||
|
GetSession()->SendPacket(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::BuildEnchantmentsInfoData(WorldPacket *data)
|
||||||
|
{
|
||||||
|
uint32 slotUsedMask = 0;
|
||||||
|
*data << uint32(slotUsedMask); // > 0x80000
|
||||||
|
|
||||||
|
for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
||||||
|
{
|
||||||
|
if(slotUsedMask & 1)
|
||||||
|
{
|
||||||
|
*data << uint32(0); // item entry
|
||||||
|
uint16 enchantmentMask = 0;
|
||||||
|
*data << uint16(enchantmentMask); // > 0x1000
|
||||||
|
|
||||||
|
for(uint32 j = 0; j < MAX_ENCHANTMENT_SLOT; ++j)
|
||||||
|
{
|
||||||
|
if(enchantmentMask & 1)
|
||||||
|
{
|
||||||
|
*data << uint16(0); // enchantmentId?
|
||||||
|
}
|
||||||
|
|
||||||
|
enchantmentMask >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data << uint16(0);
|
||||||
|
*data << uint8(0); // PGUID!
|
||||||
|
*data << uint32(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
slotUsedMask >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1187,6 +1187,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool apply_dur = true, bool ignore_condition = false);
|
void ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool apply_dur = true, bool ignore_condition = false);
|
||||||
void ApplyEnchantment(Item *item,bool apply);
|
void ApplyEnchantment(Item *item,bool apply);
|
||||||
void SendEnchantmentDurations();
|
void SendEnchantmentDurations();
|
||||||
|
void BuildEnchantmentsInfoData(WorldPacket *data);
|
||||||
void AddItemDurations(Item *item);
|
void AddItemDurations(Item *item);
|
||||||
void RemoveItemDurations(Item *item);
|
void RemoveItemDurations(Item *item);
|
||||||
void SendItemDurations();
|
void SendItemDurations();
|
||||||
|
|
@ -1459,6 +1460,9 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
bool resetTalents(bool no_cost = false);
|
bool resetTalents(bool no_cost = false);
|
||||||
uint32 resetTalentsCost() const;
|
uint32 resetTalentsCost() const;
|
||||||
void InitTalentForLevel();
|
void InitTalentForLevel();
|
||||||
|
void BuildPlayerTalentsInfoData(WorldPacket *data);
|
||||||
|
void BuildPetTalentsInfoData(WorldPacket *data);
|
||||||
|
void SendTalentInfoData(bool pet);
|
||||||
|
|
||||||
uint32 CalculateTalentsPoints() const;
|
uint32 CalculateTalentsPoints() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,9 +120,6 @@ TalentSpellPosMap sTalentSpellPosMap;
|
||||||
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
|
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
|
||||||
|
|
||||||
// store absolute bit position for first rank for talent inspect
|
// store absolute bit position for first rank for talent inspect
|
||||||
typedef std::map<uint32,uint32> TalentInspectMap;
|
|
||||||
static TalentInspectMap sTalentPosInInspect;
|
|
||||||
static TalentInspectMap sTalentTabSizeInInspect;
|
|
||||||
static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3];
|
static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3];
|
||||||
|
|
||||||
DBCStorage <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
|
DBCStorage <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
|
||||||
|
|
@ -350,34 +347,6 @@ void LoadDBCStores(const std::string& dataPath)
|
||||||
|
|
||||||
// prepare fast data access to bit pos of talent ranks for use at inspecting
|
// prepare fast data access to bit pos of talent ranks for use at inspecting
|
||||||
{
|
{
|
||||||
// fill table by amount of talent ranks and fill sTalentTabBitSizeInInspect
|
|
||||||
// store in with (row,col,talent)->size key for correct sorting by (row,col)
|
|
||||||
typedef std::map<uint32,uint32> TalentBitSize;
|
|
||||||
TalentBitSize sTalentBitSize;
|
|
||||||
for(uint32 i = 1; i < sTalentStore.GetNumRows(); ++i)
|
|
||||||
{
|
|
||||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
|
||||||
if (!talentInfo) continue;
|
|
||||||
|
|
||||||
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
|
|
||||||
if(!talentTabInfo)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// find talent rank
|
|
||||||
uint32 curtalent_maxrank = 0;
|
|
||||||
for(uint32 k = 5; k > 0; --k)
|
|
||||||
{
|
|
||||||
if(talentInfo->RankID[k-1])
|
|
||||||
{
|
|
||||||
curtalent_maxrank = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sTalentBitSize[(talentInfo->Row<<24) + (talentInfo->Col<<16)+talentInfo->TalentID] = curtalent_maxrank;
|
|
||||||
sTalentTabSizeInInspect[talentInfo->TalentTab] += curtalent_maxrank;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now have all max ranks (and then bit amount used for store talent ranks in inspect)
|
// now have all max ranks (and then bit amount used for store talent ranks in inspect)
|
||||||
for(uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId)
|
for(uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId)
|
||||||
{
|
{
|
||||||
|
|
@ -390,22 +359,6 @@ void LoadDBCStores(const std::string& dataPath)
|
||||||
for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < 12 /*MAX_CLASSES*/;m <<=1, ++cls) {}
|
for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < 12 /*MAX_CLASSES*/;m <<=1, ++cls) {}
|
||||||
|
|
||||||
sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId;
|
sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId;
|
||||||
|
|
||||||
// add total amount bits for first rank starting from talent tab first talent rank pos.
|
|
||||||
uint32 pos = 0;
|
|
||||||
for(TalentBitSize::iterator itr = sTalentBitSize.begin(); itr != sTalentBitSize.end(); ++itr)
|
|
||||||
{
|
|
||||||
uint32 talentId = itr->first & 0xFFFF;
|
|
||||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentId );
|
|
||||||
if(!talentInfo)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(talentInfo->TalentTab != talentTabId)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sTalentPosInInspect[talentId] = pos;
|
|
||||||
pos+= itr->second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -679,24 +632,6 @@ void Map2ZoneCoordinates(float& x,float& y,uint32 zone)
|
||||||
std::swap(x,y); // client have map coords swapped
|
std::swap(x,y); // client have map coords swapped
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetTalentInspectBitPosInTab(uint32 talentId)
|
|
||||||
{
|
|
||||||
TalentInspectMap::const_iterator itr = sTalentPosInInspect.find(talentId);
|
|
||||||
if(itr == sTalentPosInInspect.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return itr->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 GetTalentTabInspectBitSize(uint32 talentTabId)
|
|
||||||
{
|
|
||||||
TalentInspectMap::const_iterator itr = sTalentTabSizeInInspect.find(talentTabId);
|
|
||||||
if(itr == sTalentTabSizeInInspect.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return itr->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 const* GetTalentTabPages(uint32 cls)
|
uint32 const* GetTalentTabPages(uint32 cls)
|
||||||
{
|
{
|
||||||
return sTalentTabPages[cls];
|
return sTalentTabPages[cls];
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,6 @@ bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredT
|
||||||
void Zone2MapCoordinates(float& x,float& y,uint32 zone);
|
void Zone2MapCoordinates(float& x,float& y,uint32 zone);
|
||||||
void Map2ZoneCoordinates(float& x,float& y,uint32 zone);
|
void Map2ZoneCoordinates(float& x,float& y,uint32 zone);
|
||||||
|
|
||||||
uint32 GetTalentInspectBitPosInTab(uint32 talentId);
|
|
||||||
uint32 GetTalentTabInspectBitSize(uint32 talentTabId);
|
|
||||||
uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
|
uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue