diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/AchievementMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/CharacterHandler.cpp | 4 | ||||
-rw-r--r-- | src/game/Language.h | 1 | ||||
-rw-r--r-- | src/game/Level3.cpp | 57 | ||||
-rw-r--r-- | src/game/Pet.cpp | 120 | ||||
-rw-r--r-- | src/game/Pet.h | 7 | ||||
-rw-r--r-- | src/game/Player.cpp | 20 | ||||
-rw-r--r-- | src/game/Player.h | 15 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 7 |
9 files changed, 148 insertions, 85 deletions
diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index e86fb543ed5..1a546a0d737 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -535,7 +535,7 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri if (!criteria) { // we will remove not existed criteria for all characters - sLog.outError("Not existed achievement creataria %u data removed from table `character_achievement_progress`.",id); + sLog.outError("Not existed achievement criteria %u data removed from table `character_achievement_progress`.",id); CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE criteria = %u",id); continue; } diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 84b830651e7..aca354750f0 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -815,6 +815,10 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) SendDoFlight( mountDisplayId, path, startNode ); } + // reset for all pets before pet loading + if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) + Pet::resetTalentsForAllPetsOf(pCurrChar); + // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) pCurrChar->LoadPet(); diff --git a/src/game/Language.h b/src/game/Language.h index c16393eba1c..33ad0421ea7 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -868,7 +868,6 @@ enum TrinityStrings LANG_GM_BROADCAST = 6613, LANG_GM_NOTIFY = 6614, LANG_GM_ANNOUNCE_COLOR = 6615, - LANG_RESETALL_PET_SPELLS = 6616, LANG_WORLD_CLOSED = 7523, LANG_WORLD_OPENED = 7524, diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index adb904dbbbe..a50b551398c 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -5374,42 +5374,51 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args) uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) + { + // Try reset talents as Hunter Pet + Creature* creature = getSelectedCreature(); + if (!*args && creature && creature->isPet()) + { + Unit *owner = creature->GetOwner(); + if(owner && owner->GetTypeId() == TYPEID_PLAYER && ((Pet *)creature)->IsPermanentPetFor((Player*)owner)) + { + ((Pet *)creature)->resetTalents(true); + ((Player*)owner)->SendTalentsInfoData(true); + + ChatHandler((Player*)owner).SendSysMessage(LANG_RESET_PET_TALENTS); + if(!m_session || m_session->GetPlayer()!=((Player*)owner)) + PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink((Player*)owner).c_str()); + } + return true; + } + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); return false; + } if (target) { target->resetTalents(true); - + target->SendTalentsInfoData(false); ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); if (!m_session || m_session->GetPlayer()!=target) PSendSysMessage(LANG_RESET_TALENTS_ONLINE,GetNameLink(target).c_str()); + Pet* pet = target->GetPet(); + Pet::resetTalentsForAllPetsOf(target,pet); + if(pet) + target->SendTalentsInfoData(true); return true; } else if (target_guid) { - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(target_guid) ); + uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS; + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",at_flags, GUID_LOPART(target_guid) ); std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,nameLink.c_str()); return true; } - // Try reset talents as Hunter Pet - Creature* creature = getSelectedCreature(); - if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET) - { - ((Pet *)creature)->resetTalents(true); - Unit *owner = creature->GetOwner(); - if (owner && owner->GetTypeId() == TYPEID_PLAYER) - { - Player* owner_player = (Player *)owner; - ChatHandler(owner_player).SendSysMessage(LANG_RESET_PET_TALENTS); - if(!m_session || m_session->GetPlayer()!=owner_player) - PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE,GetNameLink(owner_player).c_str()); - } - return true; - } - SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; @@ -5434,21 +5443,11 @@ bool ChatHandler::HandleResetAllCommand(const char * args) } else if(casename=="talents") { - atLogin = AT_LOGIN_RESET_TALENTS; + atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS); sWorld.SendWorldText(LANG_RESETALL_TALENTS); if(!m_session) SendSysMessage(LANG_RESETALL_TALENTS); } - else if(casename=="pet_spells") - { - CharacterDatabase.PExecute("UPDATE character_pet SET load_flags = load_flags | '%u' WHERE (load_flags & '%u') = '0'",uint32(AT_LOAD_RESET_SPELLS),uint32(AT_LOAD_RESET_SPELLS)); - HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers(); - for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) - if (itr->second->GetPet()) - itr->second->SetPetAtLoginFlag(AT_LOAD_RESET_SPELLS); - sWorld.SendWorldText(LANG_RESETALL_PET_SPELLS); - return true; - } else { PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE,args); diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 7448d6440ce..f45c0c1a2e0 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -51,8 +51,6 @@ m_declinedname(NULL), m_owner(owner) m_summonMask |= SUMMON_MASK_HUNTER_PET; m_name = "Pet"; m_regenTimer = 4000; - - owner->SetPetAtLoginFlag(0); } Pet::~Pet() @@ -93,24 +91,24 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool if (petnumber) // known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags " + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType" "FROM character_pet WHERE owner = '%u' AND id = '%u'", ownerid, petnumber); else if (current) // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags " + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType" "FROM character_pet WHERE owner = '%u' AND slot = '%u'", ownerid, PET_SAVE_AS_CURRENT ); else if (petentry) // known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets) // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags " + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType" "FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ", ownerid, petentry,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT); else // any current or other non-stabled pet (for hunter "call pet") // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags " + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType" "FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ", ownerid,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT); @@ -284,29 +282,16 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool uint32 timediff = (time(NULL) - fields[14].GetUInt32()); _LoadAuras(timediff); - uint8 loadFlags = fields[19].GetUInt8(); - owner->SetPetAtLoginFlag(loadFlags); - if (loadFlags & AT_LOAD_RESET_SPELLS) - { - CharacterDatabase.PExecute("UPDATE character_pet SET load_flags = load_flags & ~ %u WHERE id = '%u'",uint32(AT_LOAD_RESET_SPELLS),pet_number); - loadFlags &= ~uint8(AT_LOAD_RESET_SPELLS); - CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u'",pet_number); - InitPetCreateSpells(); - resetTalents(true); - } - else + // load action bar, if data broken will fill later by default spells. + if (!is_temporary_summoned) { - // load action bar, if data broken will fill later by default spells. - if (!is_temporary_summoned) - { - m_charmInfo->LoadPetActionBar(fields[13].GetCppString()); + m_charmInfo->LoadPetActionBar(fields[13].GetCppString()); - _LoadSpells(); - _LoadSpellCooldowns(); - LearnPetPassives(); - InitLevelupSpellsForLevel(); - CastPetAuras(current); - } + _LoadSpells(); + _LoadSpellCooldowns(); + LearnPetPassives(); + InitLevelupSpellsForLevel(); + CastPetAuras(current); } CleanupActionBar(); // remove unknown spells from action bar after load @@ -408,7 +393,7 @@ void Pet::SavePetToDB(PetSaveMode mode) owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT); // save pet std::ostringstream ss; - ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags) " + ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) " << "VALUES (" << m_charmInfo->GetPetNumber() << ", " << GetEntry() << ", " @@ -436,8 +421,7 @@ void Pet::SavePetToDB(PetSaveMode mode) << uint32(m_resetTalentsCost) << ", " << uint64(m_resetTalentsTime) << ", " << GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", " - << uint32(getPetType()) << ", " - << (pOwner->GetAtLoginFlag()>>AT_LOAD_PET_FLAGS) << ")"; + << uint32(getPetType()) << ")"; CharacterDatabase.Execute( ss.str().c_str() ); CharacterDatabase.CommitTransaction(); @@ -448,7 +432,6 @@ void Pet::SavePetToDB(PetSaveMode mode) RemoveAllAuras(); DeleteFromDB(m_charmInfo->GetPetNumber()); } - pOwner->SetPetAtLoginFlag(0); } void Pet::DeleteFromDB(uint32 guidlow) @@ -1490,6 +1473,10 @@ bool Pet::resetTalents(bool no_cost) if (!owner || owner->GetTypeId()!=TYPEID_PLAYER) return false; + // not need after this call + if(((Player*)owner)->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) + ((Player*)owner)->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS,true); + CreatureInfo const * ci = GetCreatureInfo(); if(!ci) return false; @@ -1576,6 +1563,77 @@ bool Pet::resetTalents(bool no_cost) return true; } +void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* online_pet /*= NULL*/) +{ + // not need after this call + if(((Player*)owner)->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) + ((Player*)owner)->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS,true); + + // reset for online + if(online_pet) + online_pet->resetTalents(true); + + // now need only reset for offline pets (all pets except online case) + uint32 except_petnumber = online_pet ? online_pet->GetCharmInfo()->GetPetNumber() : 0; + + QueryResult *resultPets = CharacterDatabase.PQuery( + "SELECT id FROM character_pet WHERE owner = '%u' AND id <> '%u'", + owner->GetGUIDLow(),except_petnumber); + + // no offline pets + if(!resultPets) + return; + + QueryResult *result = CharacterDatabase.PQuery( + "SELECT DISTINCT pet_spell.spell FROM pet_spell, character_pet " + "WHERE character_pet.owner = '%u' AND character_pet.id = pet_spell.guid AND character_pet.id <> %u", + owner->GetGUIDLow(),except_petnumber); + + if(!result) + { + delete resultPets; + return; + } + + bool need_comma = false; + std::ostringstream ss; + ss << "DELETE FROM pet_spell WHERE guid IN ("; + + do + { + Field *fields = resultPets->Fetch(); + uint32 id = fields[0].GetUInt32(); + if(need_comma) + ss << ","; + ss << id; + need_comma = true; + } + while( resultPets->NextRow() ); + delete resultPets; + + ss << ") AND spell IN ("; + + bool need_execute = false; + do + { + Field *fields = result->Fetch(); + uint32 spell = fields[0].GetUInt32(); + if(!GetTalentSpellCost(spell)) + continue; + if(need_execute) + ss << ","; + ss << spell; + need_execute = true; + } + while( result->NextRow() ); + delete result; + if(!need_execute) + return; + ss << ")"; + + CharacterDatabase.Execute(ss.str().c_str()); +} + void Pet::InitTalentForLevel() { uint32 level = getLevel(); diff --git a/src/game/Pet.h b/src/game/Pet.h index 49daad429ed..6ad47b63c6c 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -89,12 +89,6 @@ enum PetTalk PET_TALK_ATTACK = 1 }; -enum AtLoadFlags -{ - AT_LOAD_NONE = 0, - AT_LOAD_RESET_SPELLS = 1, -}; - enum PetNameInvalidReason { PET_NAME_INVALID = 1, @@ -212,6 +206,7 @@ class Pet : public Guardian void InitPetCreateSpells(); bool resetTalents(bool no_cost = false); + static void resetTalentsForAllPetsOf(Player* owner, Pet* online_pet = NULL); uint32 resetTalentsCost() const; void InitTalentForLevel(); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 17203faadde..160737ecfd8 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -3528,10 +3528,7 @@ bool Player::resetTalents(bool no_cost) { // not need after this call if(HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) - { - m_atLoginFlags = m_atLoginFlags & ~AT_LOGIN_RESET_TALENTS; - CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_TALENTS), GetGUIDLow()); - } + RemoveAtLoginFlag(AT_LOGIN_RESET_TALENTS,true); uint32 talentPointsForLevel = CalculateTalentsPoints(); @@ -16000,7 +15997,7 @@ void Player::SaveToDB() ss << uint32(m_stableSlots); // to prevent save uint8 as char ss << ", "; - ss << uint32(m_atLoginFlags & ((1<<AT_LOAD_PET_FLAGS) -1)); + ss << uint32(m_atLoginFlags); ss << ", "; ss << GetZoneId(); @@ -18883,10 +18880,7 @@ void Player::resetSpells() { // not need after this call if(HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) - { - m_atLoginFlags = m_atLoginFlags & ~AT_LOGIN_RESET_SPELLS; - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_SPELLS), GetGUIDLow()); - } + RemoveAtLoginFlag(AT_LOGIN_RESET_SPELLS,true); // make full copy of map (spells removed and marked as deleted at another spell remove // and we can't use original map for safe iterative with visit each spell at loop end @@ -21130,3 +21124,11 @@ void Player::ActivateSpec(uint32 specNum) resetTalents(true); } + +void Player::RemoveAtLoginFlag( AtLoginFlags f, bool in_db_also /*= false*/ ) +{ + m_atLoginFlags &= ~f; + + if(in_db_also) + CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(f), GetGUIDLow()); +} diff --git a/src/game/Player.h b/src/game/Player.h index 111e5def205..0fcdef48668 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -57,7 +57,6 @@ typedef std::deque<Mail*> PlayerMails; #define PLAYER_MAX_SKILLS 127 #define PLAYER_MAX_DAILY_QUESTS 25 -#define AT_LOAD_PET_FLAGS 16 // Note: SPELLMOD_* values is aura types in fact enum SpellModType @@ -510,11 +509,12 @@ enum PlayerExtraFlags // 2^n values enum AtLoginFlags { - AT_LOGIN_NONE = 0, - AT_LOGIN_RENAME = 1, - AT_LOGIN_RESET_SPELLS = 2, - AT_LOGIN_RESET_TALENTS = 4, - AT_LOGIN_CUSTOMIZE = 8, + AT_LOGIN_NONE = 0x00, + AT_LOGIN_RENAME = 0x01, + AT_LOGIN_RESET_SPELLS = 0x02, + AT_LOGIN_RESET_TALENTS = 0x04, + AT_LOGIN_CUSTOMIZE = 0x08, + AT_LOGIN_RESET_PET_TALENTS = 0x10, }; typedef std::map<uint32, QuestStatusData> QuestStatusMap; @@ -1996,8 +1996,7 @@ class TRINITY_DLL_SPEC Player : public Unit bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; } void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; } - uint32 GetAtLoginFlag() { return m_atLoginFlags; } - void SetPetAtLoginFlag(uint8 f) { m_atLoginFlags |= uint32(f<<AT_LOAD_PET_FLAGS); } + void RemoveAtLoginFlag(AtLoginFlags f, bool in_db_also = false); LookingForGroup m_lookingForGroup; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 9c54bf7e27b..1d19124a067 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2783,6 +2783,13 @@ void AuraEffect::HandleAuraDummy(bool apply, bool Real, bool changeAmount) if(m_target->IsInWorld()) m_target->CastCustomSpell(m_target,33778,&m_amount,NULL,NULL,true,NULL,this,GetCasterGUID()); + // restore mana + if (caster) + { + int32 returnmana = (GetSpellProto()->ManaCostPercentage * caster->GetCreateMana() / 100) * GetParentAura()->GetStackAmount() / 2; + caster->CastCustomSpell(caster, 64372, &returnmana, NULL, NULL, true, NULL, this, GetCasterGUID()); + } + /*// have a look if there is still some other Lifebloom dummy aura Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); ++itr) |