aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/AchievementMgr.cpp2
-rw-r--r--src/game/CharacterHandler.cpp4
-rw-r--r--src/game/Language.h1
-rw-r--r--src/game/Level3.cpp57
-rw-r--r--src/game/Pet.cpp120
-rw-r--r--src/game/Pet.h7
-rw-r--r--src/game/Player.cpp20
-rw-r--r--src/game/Player.h15
-rw-r--r--src/game/SpellAuras.cpp7
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)