*Cleanup, search through the talent map instead of spell chains for talent ranks during spec swaps.
Also properly set talent state upon talent reset, and only reset talents that exist in the active spec. Refs #367, #326 --HG-- branch : trunk
This commit is contained in:
+11
-6
@@ -1739,7 +1739,7 @@ Item* Guild::StoreItem(uint8 tabId, GuildItemPosCountVec const& dest, Item* pIte
|
|||||||
return lastItem;
|
return lastItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case.
|
// Return stored item (if stored to stack, it can diff. from pItem). And pItem can be deleted in this case.
|
||||||
Item* Guild::_StoreItem( uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone )
|
Item* Guild::_StoreItem( uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone )
|
||||||
{
|
{
|
||||||
if (!pItem)
|
if (!pItem)
|
||||||
@@ -1765,7 +1765,7 @@ Item* Guild::_StoreItem( uint8 tab, uint8 slot, Item *pItem, uint32 count, bool
|
|||||||
pItem->SetUInt64Value(ITEM_FIELD_OWNER, 0);
|
pItem->SetUInt64Value(ITEM_FIELD_OWNER, 0);
|
||||||
AddGBankItemToDB(GetId(), tab, slot, pItem->GetGUIDLow(), pItem->GetEntry());
|
AddGBankItemToDB(GetId(), tab, slot, pItem->GetGUIDLow(), pItem->GetEntry());
|
||||||
pItem->FSetState(ITEM_NEW);
|
pItem->FSetState(ITEM_NEW);
|
||||||
pItem->SaveToDB(); // not in onventory and can be save standalone
|
pItem->SaveToDB(); // not in inventory and can be save standalone
|
||||||
|
|
||||||
return pItem;
|
return pItem;
|
||||||
}
|
}
|
||||||
@@ -1773,7 +1773,7 @@ Item* Guild::_StoreItem( uint8 tab, uint8 slot, Item *pItem, uint32 count, bool
|
|||||||
{
|
{
|
||||||
pItem2->SetCount(pItem2->GetCount() + count);
|
pItem2->SetCount(pItem2->GetCount() + count);
|
||||||
pItem2->FSetState(ITEM_CHANGED);
|
pItem2->FSetState(ITEM_CHANGED);
|
||||||
pItem2->SaveToDB(); // not in onventory and can be save standalone
|
pItem2->SaveToDB(); // not in inventory and can be save standalone
|
||||||
|
|
||||||
if (!clone)
|
if (!clone)
|
||||||
{
|
{
|
||||||
@@ -1991,9 +1991,14 @@ void Guild::SwapItems(Player * pl, uint8 BankTab, uint8 BankTabSlot, uint8 BankT
|
|||||||
if (!pItemSrc) // may prevent crash
|
if (!pItemSrc) // may prevent crash
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (SplitedAmount > pItemSrc->GetCount())
|
if (pItemSrc->GetCount() == 0)
|
||||||
return; // cheating?
|
{
|
||||||
else if (SplitedAmount == pItemSrc->GetCount())
|
sLog.outCrash("Guild::SwapItems: Player %s(GUIDLow: %u) tried to move item %u from tab %u slot %u to tab %u slot %u, but item %u has a stack of zero!",
|
||||||
|
pl->GetName(), pl->GetGUIDLow(), pItemSrc->GetEntry(), BankTab, BankTabSlot, BankTabDst, BankTabSlotDst, pItemSrc->GetEntry());
|
||||||
|
//return; // Commented out for now, uncomment when it's verified that this causes a crash!!
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SplitedAmount >= pItemSrc->GetCount())
|
||||||
SplitedAmount = 0; // no split
|
SplitedAmount = 0; // no split
|
||||||
|
|
||||||
Item *pItemDst = GetItem(BankTabDst, BankTabSlotDst);
|
Item *pItemDst = GetItem(BankTabDst, BankTabSlotDst);
|
||||||
|
|||||||
+25
-23
@@ -2930,9 +2930,7 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
|
|||||||
|
|
||||||
PlayerTalentMap::iterator itr = m_talents[spec]->find(spell_id);
|
PlayerTalentMap::iterator itr = m_talents[spec]->find(spell_id);
|
||||||
if (itr != m_talents[spec]->end())
|
if (itr != m_talents[spec]->end())
|
||||||
{
|
|
||||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||||
}
|
|
||||||
else if (TalentSpellPos const *talentPos = GetTalentSpellPos(spell_id))
|
else if (TalentSpellPos const *talentPos = GetTalentSpellPos(spell_id))
|
||||||
{
|
{
|
||||||
if (TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
|
if (TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
|
||||||
@@ -2946,11 +2944,9 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
|
|||||||
|
|
||||||
PlayerTalentMap::iterator itr = m_talents[spec]->find(rankSpellId);
|
PlayerTalentMap::iterator itr = m_talents[spec]->find(rankSpellId);
|
||||||
if (itr != m_talents[spec]->end())
|
if (itr != m_talents[spec]->end())
|
||||||
{
|
|
||||||
itr->second->state = PLAYERSPELL_REMOVED;
|
itr->second->state = PLAYERSPELL_REMOVED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED;
|
PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED;
|
||||||
PlayerTalent *newtalent = new PlayerTalent();
|
PlayerTalent *newtalent = new PlayerTalent();
|
||||||
@@ -3787,7 +3783,14 @@ bool Player::resetTalents(bool no_cost)
|
|||||||
if ((getClassMask() & talentTabInfo->ClassMask) == 0)
|
if ((getClassMask() & talentTabInfo->ClassMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
PlayerTalentMap::const_iterator foundTalent = m_talents[m_activeSpec]->find(i);
|
||||||
|
if (foundTalent == m_talents[spec]->end() || foundTalent->second->state == PLAYERSPELL_REMOVED)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
foundTalent->second->state = PLAYERSPELL_REMOVED;
|
||||||
|
|
||||||
removeSpell(i, !IsPassiveSpell(i), false);
|
removeSpell(i, !IsPassiveSpell(i), false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for (PlayerTalentMap::iterator itr = m_talents[m_activeSpec]->begin(); itr != m_talents[m_activeSpec]->end(); ++itr)
|
for (PlayerTalentMap::iterator itr = m_talents[m_activeSpec]->begin(); itr != m_talents[m_activeSpec]->end(); ++itr)
|
||||||
{
|
{
|
||||||
@@ -3856,37 +3859,28 @@ bool Player::resetTalents(bool no_cost)
|
|||||||
Mail* Player::GetMail(uint32 id)
|
Mail* Player::GetMail(uint32 id)
|
||||||
{
|
{
|
||||||
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
|
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
|
||||||
{
|
|
||||||
if ((*itr)->messageID == id)
|
if ((*itr)->messageID == id)
|
||||||
{
|
|
||||||
return (*itr);
|
return (*itr);
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::_SetCreateBits(UpdateMask *updateMask, Player *target) const
|
void Player::_SetCreateBits(UpdateMask *updateMask, Player *target) const
|
||||||
{
|
{
|
||||||
if(target == this)
|
if(target == this)
|
||||||
{
|
|
||||||
Object::_SetCreateBits(updateMask, target);
|
Object::_SetCreateBits(updateMask, target);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (uint16 index = 0; index < m_valuesCount; index++)
|
for (uint16 index = 0; index < m_valuesCount; index++)
|
||||||
{
|
|
||||||
if (GetUInt32Value(index) != 0 && updateVisualBits.GetBit(index))
|
if (GetUInt32Value(index) != 0 && updateVisualBits.GetBit(index))
|
||||||
updateMask->SetBit(index);
|
updateMask->SetBit(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Player::_SetUpdateBits(UpdateMask *updateMask, Player *target) const
|
void Player::_SetUpdateBits(UpdateMask *updateMask, Player *target) const
|
||||||
{
|
{
|
||||||
if(target == this)
|
if(target == this)
|
||||||
{
|
|
||||||
Object::_SetUpdateBits(updateMask, target);
|
Object::_SetUpdateBits(updateMask, target);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Object::_SetUpdateBits(updateMask, target);
|
Object::_SetUpdateBits(updateMask, target);
|
||||||
@@ -3985,7 +3979,7 @@ void Player::InitVisibleBits()
|
|||||||
|
|
||||||
void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const
|
void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const
|
||||||
{
|
{
|
||||||
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; i++)
|
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
||||||
{
|
{
|
||||||
if(m_items[i] == NULL)
|
if(m_items[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -3995,7 +3989,7 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target )
|
|||||||
|
|
||||||
if(target == this)
|
if(target == this)
|
||||||
{
|
{
|
||||||
for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
|
for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
|
||||||
{
|
{
|
||||||
if(m_items[i] == NULL)
|
if(m_items[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -4018,7 +4012,7 @@ void Player::DestroyForPlayer( Player *target, bool anim ) const
|
|||||||
{
|
{
|
||||||
Unit::DestroyForPlayer( target, anim );
|
Unit::DestroyForPlayer( target, anim );
|
||||||
|
|
||||||
for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; i++)
|
for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i)
|
||||||
{
|
{
|
||||||
if(m_items[i] == NULL)
|
if(m_items[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -4028,7 +4022,7 @@ void Player::DestroyForPlayer( Player *target, bool anim ) const
|
|||||||
|
|
||||||
if(target == this)
|
if(target == this)
|
||||||
{
|
{
|
||||||
for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
|
for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
|
||||||
{
|
{
|
||||||
if(m_items[i] == NULL)
|
if(m_items[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -15174,7 +15168,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (m_specsCount > MAX_TALENT_SPECS || m_activeSpec > MAX_TALENT_SPEC ||
|
if (m_specsCount > MAX_TALENT_SPECS || m_activeSpec > MAX_TALENT_SPEC ||
|
||||||
m_specsCount < MIN_TALENT_SPECS || m_activeSpec < MIN_TALENT_SPEC ) // if (m_specsCount < 2) is not logical
|
m_specsCount < MIN_TALENT_SPECS || m_activeSpec < MIN_TALENT_SPEC)
|
||||||
{
|
{
|
||||||
m_activeSpec = 0;
|
m_activeSpec = 0;
|
||||||
sLog.outError("Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName(), GetGUIDLow(), m_specsCount, m_activeSpec);
|
sLog.outError("Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName(), GetGUIDLow(), m_specsCount, m_activeSpec);
|
||||||
@@ -22012,8 +22006,15 @@ void Player::ActivateSpec(uint8 spec)
|
|||||||
// Remove all talents and talent-learned spells under this spec.
|
// Remove all talents and talent-learned spells under this spec.
|
||||||
for (PlayerTalentMap::iterator itr = m_talents[m_activeSpec]->begin(); itr != m_talents[m_activeSpec]->end(); ++itr)
|
for (PlayerTalentMap::iterator itr = m_talents[m_activeSpec]->begin(); itr != m_talents[m_activeSpec]->end(); ++itr)
|
||||||
{
|
{
|
||||||
|
TalentEntry const *talentInfo = sTalentStore.LookupEntry(itr->first);
|
||||||
|
|
||||||
|
if (!talentInfo)
|
||||||
|
continue;
|
||||||
|
|
||||||
removeSpell(itr->first, !IsPassiveSpell(itr->first), false);
|
removeSpell(itr->first, !IsPassiveSpell(itr->first), false);
|
||||||
uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr->first);
|
|
||||||
|
for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
|
||||||
|
{
|
||||||
for (PlayerSpellMap::iterator itr2 = GetSpellMap().begin(); itr2 != GetSpellMap().end();)
|
for (PlayerSpellMap::iterator itr2 = GetSpellMap().begin(); itr2 != GetSpellMap().end();)
|
||||||
{
|
{
|
||||||
if (itr2->second->state == PLAYERSPELL_REMOVED || itr2->second->disabled)
|
if (itr2->second->state == PLAYERSPELL_REMOVED || itr2->second->disabled)
|
||||||
@@ -22023,16 +22024,16 @@ void Player::ActivateSpec(uint8 spec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove learned spells (all ranks)
|
// remove learned spells (all ranks)
|
||||||
uint32 itr2FirstId = spellmgr.GetFirstSpellInChain(itr2->first);
|
uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr2->first);
|
||||||
|
|
||||||
// unlearn if first rank is talent or learned by talent
|
// unlearn if first rank is talent or learned by talent
|
||||||
if (itrFirstId == itr2FirstId)
|
if (itrFirstId == talentInfo->RankID[rank])
|
||||||
{
|
{
|
||||||
removeSpell(itr2->first, !IsPassiveSpell(itr2->first), false);
|
removeSpell(itr2->first, !IsPassiveSpell(itr2->first), false);
|
||||||
itr2 = GetSpellMap().begin();
|
itr2 = GetSpellMap().begin();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (spellmgr.IsSpellLearnToSpell(itr->first, itrFirstId))
|
else if (spellmgr.IsSpellLearnToSpell(talentInfo->RankID[rank], itrFirstId))
|
||||||
{
|
{
|
||||||
removeSpell(itr2->first, !IsPassiveSpell(itr2->first));
|
removeSpell(itr2->first, !IsPassiveSpell(itr2->first));
|
||||||
itr2 = GetSpellMap().begin();
|
itr2 = GetSpellMap().begin();
|
||||||
@@ -22042,6 +22043,7 @@ void Player::ActivateSpec(uint8 spec)
|
|||||||
++itr2;
|
++itr2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set glyphs
|
// set glyphs
|
||||||
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
|
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
|
||||||
|
|||||||
Reference in New Issue
Block a user