void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data ) { sLog.outDebug("WORLD: CMSG_PET_LEARN_TALENT"); recv_data.hexlike(); CHECK_PACKET_SIZE(recv_data, 8+4+4); uint64 guid; uint32 talent_id, requested_rank; recv_data >> guid >> talent_id >> requested_rank; Pet *pet = _player->GetPet(); if(!pet) return; if(guid != pet->GetGUID()) return; uint32 CurTalentPoints = pet->GetFreeTalentPoints(); if(CurTalentPoints == 0) return; if (requested_rank > 4) return; TalentEntry const *talentInfo = sTalentStore.LookupEntry(talent_id); 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; // prevent skip talent ranks (cheating) if(requested_rank > 0 && !pet->HasSpell(talentInfo->RankID[requested_rank-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[requested_rank]; if( spellid == 0 ) { sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank); 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", talent_id, requested_rank, spellid); }
static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* handler, char const* /*args*/) { Player* player = handler->GetSession()->GetPlayer(); Pet* pet = player->GetPet(); if (!pet) { handler->SendSysMessage(LANG_NO_PET_FOUND); handler->SetSentErrorMessage(true); return false; } CreatureTemplate const* creatureInfo = pet->GetCreatureInfo(); if (!creatureInfo) { handler->SendSysMessage(LANG_WRONG_PET_TYPE); handler->SetSentErrorMessage(true); return false; } CreatureFamilyEntry const* petFamily = sCreatureFamilyStore.LookupEntry(creatureInfo->family); if (!petFamily) { handler->SendSysMessage(LANG_WRONG_PET_TYPE); handler->SetSentErrorMessage(true); return false; } if (petFamily->petTalentType < 0) // not hunter pet { handler->SendSysMessage(LANG_WRONG_PET_TYPE); handler->SetSentErrorMessage(true); return false; } for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); if (!talentTabInfo) continue; // prevent learn talent for different family (cheating) if (((1 << petFamily->petTalentType) & talentTabInfo->petTalentMask) == 0) continue; // search highest talent rank uint32 spellId = 0; for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank) { if (talentInfo->RankID[rank] != 0) { spellId = talentInfo->RankID[rank]; break; } } if (!spellId) // ??? none spells in talent continue; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false)) continue; // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) pet->learnSpellHighRank(spellId); } pet->SetFreeTalentPoints(0); handler->SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS); return true; }