aboutsummaryrefslogtreecommitdiff
path: root/src/game/Player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r--src/game/Player.cpp373
1 files changed, 261 insertions, 112 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 5683c55e04d..db7f0ad1ae9 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -3277,7 +3277,7 @@ void Player::RemoveArenaSpellCooldowns()
// notify player
WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8));
data << uint32(itr->first);
- data << GetGUID();
+ data << uint64(GetGUID());
GetSession()->SendPacket(&data);
// remove cooldown
m_spellCooldowns.erase(itr);
@@ -6111,12 +6111,9 @@ bool Player::SetOneFactionReputation(FactionEntry const* factionEntry, int32 sta
//Calculate total reputation percent player gain with quest/creature level
int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest)
{
- // always 100% (3.0.8)
- int32 percent = 100;
-
int32 repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN);
- percent += rep > 0 ? repMod : -repMod;
+ int32 percent = rep > 0 ? repMod : -repMod;
if(percent <=0)
return 0;
@@ -8628,10 +8625,10 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap
slots[0] = EQUIPMENT_SLOT_RANGED;
break;
case INVTYPE_BAG:
- slots[0] = INVENTORY_SLOT_BAG_1;
- slots[1] = INVENTORY_SLOT_BAG_2;
- slots[2] = INVENTORY_SLOT_BAG_3;
- slots[3] = INVENTORY_SLOT_BAG_4;
+ slots[0] = INVENTORY_SLOT_BAG_START + 0;
+ slots[1] = INVENTORY_SLOT_BAG_START + 1;
+ slots[2] = INVENTORY_SLOT_BAG_START + 2;
+ slots[3] = INVENTORY_SLOT_BAG_START + 3;
break;
case INVTYPE_RELIC:
{
@@ -9632,8 +9629,6 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
}
}
- // Vanity pet case skipped as not used
-
/* until proper implementation
else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
{
@@ -9656,28 +9651,6 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
}
}
*/
- /* until proper implementation
- else if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)
- {
- res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,false,pItem,bag,slot);
- if(res!=EQUIP_ERR_OK)
- {
- if(no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if(count==0)
- {
- if(no_similar_count==0)
- return EQUIP_ERR_OK;
-
- if(no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
- }
- */
res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot);
if(res!=EQUIP_ERR_OK)
@@ -9826,8 +9799,6 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
}
}
- // Vanity pet case skipped as not used
-
/* until proper implementation
else if(false pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
{
@@ -9850,28 +9821,6 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
}
}
*/
- /* until proper implementation
- else if(false pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)
- {
- res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,false,pItem,bag,slot);
- if(res!=EQUIP_ERR_OK)
- {
- if(no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if(count==0)
- {
- if(no_similar_count==0)
- return EQUIP_ERR_OK;
-
- if(no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
- }
- */
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
@@ -9943,13 +9892,11 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
int inv_bags[INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE];
int inv_keys[KEYRING_SLOT_END-KEYRING_SLOT_START];
int inv_tokens[CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START];
- int inv_quests[QUESTBAG_SLOT_END-QUESTBAG_SLOT_START];
memset(inv_slot_items,0,sizeof(int)*(INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START));
memset(inv_bags,0,sizeof(int)*(INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START)*MAX_BAG_SIZE);
memset(inv_keys,0,sizeof(int)*(KEYRING_SLOT_END-KEYRING_SLOT_START));
memset(inv_tokens,0,sizeof(int)*(CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START));
- memset(inv_quests,0,sizeof(int)*(QUESTBAG_SLOT_END-QUESTBAG_SLOT_START));
for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
{
@@ -9971,8 +9918,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
}
- // Vanity pet case skipped as not used
-
for(int i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
@@ -9983,16 +9928,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
}
- for(int i = QUESTBAG_SLOT_START; i < QUESTBAG_SLOT_END; i++)
- {
- pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i );
-
- if (pItem2 && !pItem2->IsInTrade())
- {
- inv_quests[i-QUESTBAG_SLOT_START] = pItem2->GetCount();
- }
- }
-
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
@@ -10052,8 +9987,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
if (b_found) continue;
- // Vanity pet case skipped as not used
-
for(int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; t++)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
@@ -10066,18 +9999,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
if (b_found) continue;
- for(int t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; t++)
- {
- pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
- if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_quests[t-QUESTBAG_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
- {
- inv_quests[t-QUESTBAG_SLOT_START] += pItem->GetCount();
- b_found = true;
- break;
- }
- }
- if (b_found) continue;
-
for(int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; t++)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
@@ -10130,8 +10051,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
if (b_found) continue;
- // Vanity pet case skipped as not used
-
/* until proper implementation
if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
{
@@ -10148,22 +10067,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
if (b_found) continue;
*/
- /* until proper implementation
- if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)
- {
- for(uint32 t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; ++t)
- {
- if( inv_quests[t-QUESTBAG_SLOT_START] == 0 )
- {
- inv_quests[t-QUESTBAG_SLOT_START] = 1;
- b_found = true;
- break;
- }
- }
- }
-
- if (b_found) continue;
- */
for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++)
{
@@ -11279,6 +11182,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
}
}
}
+
for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)
{
if (Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ))
@@ -15225,7 +15129,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
void Player::_LoadGlyphAuras()
{
- for (uint8 i = 0; i <= MAX_GLYPH_SLOT_INDEX; ++i)
+ for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
{
if (uint32 glyph = GetGlyph(i))
{
@@ -17076,7 +16980,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
if(pet->isControlled())
{
- WorldPacket data(SMSG_PET_SPELLS, 8);
+ WorldPacket data(SMSG_PET_SPELLS, 8+4);
data << uint64(0);
data << uint32(0);
GetSession()->SendPacket(&data);
@@ -17283,9 +17187,9 @@ void Player::PossessSpellInitialize()
//basic info 20
data << uint64(charm->GetGUID());
- data << uint32(0); //family
- data << uint32(0); //0
- data << uint8(0) << uint8(0) << uint16(0); //reactstate, commandstate, 0
+ data << uint32(0x00000000);
+ data << uint32(0);
+ data << uint32(0);
//action bar 40
for(uint32 i = 0; i < 10; i++)
@@ -18933,10 +18837,6 @@ void Player::SendInitialPacketsBeforeAddToMap()
data << (float)0.01666667f; // game speed
GetSession()->SendPacket( &data );
- data.Initialize(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
- data << uint32(0x00000000); // on blizz it increments periodically
- GetSession()->SendPacket(&data);
-
// set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment
if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight())
AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
@@ -20719,3 +20619,252 @@ void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 mi
{
GetAchievementMgr().UpdateAchievementCriteria(type, miscvalue1,miscvalue2,unit,time);
}
+
+void Player::LearnTalent(uint32 talentId, uint32 talentRank)
+{
+ uint32 CurTalentPoints = GetFreeTalentPoints();
+
+ if(CurTalentPoints == 0)
+ return;
+
+ if (talentRank > 4)
+ return;
+
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentId );
+
+ if(!talentInfo)
+ return;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
+
+ if(!talentTabInfo)
+ return;
+
+ // prevent learn talent for different class (cheating)
+ if( (getClassMask() & talentTabInfo->ClassMask) == 0 )
+ return;
+
+ // find current max talent rank
+ int32 curtalent_maxrank = 0;
+ for(int32 k = 4; k > -1; --k)
+ {
+ if(talentInfo->RankID[k] && HasSpell(talentInfo->RankID[k]))
+ {
+ curtalent_maxrank = k + 1;
+ break;
+ }
+ }
+
+ // we already have same or higher talent rank learned
+ if(curtalent_maxrank >= (talentRank + 1))
+ return;
+
+ // check if we have enough talent points
+ if(CurTalentPoints < (talentRank - curtalent_maxrank + 1))
+ return;
+
+ // Check if it requires another talent
+ if (talentInfo->DependsOn > 0)
+ {
+ if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
+ {
+ bool hasEnoughRank = false;
+ for (int i = talentInfo->DependsOnRank; i <= 4; i++)
+ {
+ if (depTalentInfo->RankID[i] != 0)
+ if (HasSpell(depTalentInfo->RankID[i]))
+ hasEnoughRank = true;
+ }
+ if (!hasEnoughRank)
+ return;
+ }
+ }
+
+ // Find out how many points we have in this field
+ uint32 spentPoints = 0;
+
+ uint32 tTab = talentInfo->TalentTab;
+ if (talentInfo->Row > 0)
+ {
+ unsigned int numRows = sTalentStore.GetNumRows();
+ for (unsigned int i = 0; i < numRows; i++) // Loop through all talents.
+ {
+ // Someday, someone needs to revamp
+ const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i);
+ if (tmpTalent) // the way talents are tracked
+ {
+ if (tmpTalent->TalentTab == tTab)
+ {
+ for (int j = 0; j <= 4; j++)
+ {
+ if (tmpTalent->RankID[j] != 0)
+ {
+ if (HasSpell(tmpTalent->RankID[j]))
+ {
+ spentPoints += j + 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // not have required min points spent in talent tree
+ if(spentPoints < (talentInfo->Row * 5))
+ return;
+
+ // spell not set in talent.dbc
+ uint32 spellid = talentInfo->RankID[talentRank];
+ if( spellid == 0 )
+ {
+ sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
+ return;
+ }
+
+ // already known
+ if(HasSpell(spellid))
+ return;
+
+ // learn! (other talent ranks will unlearned at learning)
+ learnSpell(spellid, false);
+ sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
+
+ // update free talent points
+ SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
+}
+
+void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
+{
+ Pet *pet = GetPet();
+
+ if(!pet)
+ return;
+
+ if(petGuid != pet->GetGUID())
+ return;
+
+ uint32 CurTalentPoints = pet->GetFreeTalentPoints();
+
+ if(CurTalentPoints == 0)
+ return;
+
+ if (talentRank > 2)
+ return;
+
+ TalentEntry const *talentInfo = sTalentStore.LookupEntry(talentId);
+
+ if(!talentInfo)
+ return;
+
+ TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
+
+ if(!talentTabInfo)
+ return;
+
+ CreatureInfo const *ci = pet->GetCreatureInfo();
+
+ if(!ci)
+ return;
+
+ CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
+
+ if(!pet_family)
+ return;
+
+ if(pet_family->petTalentType < 0) // not hunter pet
+ return;
+
+ // prevent learn talent for different family (cheating)
+ if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
+ return;
+
+ // find current max talent rank
+ int32 curtalent_maxrank = 0;
+ for(int32 k = 4; k > -1; --k)
+ {
+ if(talentInfo->RankID[k] && pet->HasSpell(talentInfo->RankID[k]))
+ {
+ curtalent_maxrank = k + 1;
+ break;
+ }
+ }
+
+ // we already have same or higher talent rank learned
+ if(curtalent_maxrank >= (talentRank + 1))
+ return;
+
+ // check if we have enough talent points
+ if(CurTalentPoints < (talentRank - curtalent_maxrank + 1))
+ return;
+
+ // Check if it requires another talent
+ if (talentInfo->DependsOn > 0)
+ {
+ if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
+ {
+ bool hasEnoughRank = false;
+ for (int i = talentInfo->DependsOnRank; i <= 4; i++)
+ {
+ if (depTalentInfo->RankID[i] != 0)
+ if (pet->HasSpell(depTalentInfo->RankID[i]))
+ hasEnoughRank = true;
+ }
+ if (!hasEnoughRank)
+ return;
+ }
+ }
+
+ // Find out how many points we have in this field
+ uint32 spentPoints = 0;
+
+ uint32 tTab = talentInfo->TalentTab;
+ if (talentInfo->Row > 0)
+ {
+ unsigned int numRows = sTalentStore.GetNumRows();
+ for (unsigned int i = 0; i < numRows; ++i) // Loop through all talents.
+ {
+ // Someday, someone needs to revamp
+ const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i);
+ if (tmpTalent) // the way talents are tracked
+ {
+ if (tmpTalent->TalentTab == tTab)
+ {
+ for (int j = 0; j <= 4; j++)
+ {
+ if (tmpTalent->RankID[j] != 0)
+ {
+ if (pet->HasSpell(tmpTalent->RankID[j]))
+ {
+ spentPoints += j + 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // not have required min points spent in talent tree
+ if(spentPoints < (talentInfo->Row * 3))
+ return;
+
+ // spell not set in talent.dbc
+ uint32 spellid = talentInfo->RankID[talentRank];
+ if( spellid == 0 )
+ {
+ sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
+ return;
+ }
+
+ // already known
+ if(pet->HasSpell(spellid))
+ return;
+
+ // learn! (other talent ranks will unlearned at learning)
+ pet->learnSpell(spellid);
+ sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
+
+ // update free talent points
+ pet->SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
+}