aboutsummaryrefslogtreecommitdiff
path: root/src/game/Pet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Pet.cpp')
-rw-r--r--src/game/Pet.cpp187
1 files changed, 136 insertions, 51 deletions
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 7448d6440ce..05764beec11 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -49,10 +49,15 @@ m_declinedname(NULL), m_owner(owner)
m_summonMask |= SUMMON_MASK_PET;
if(type == HUNTER_PET)
m_summonMask |= SUMMON_MASK_HUNTER_PET;
+
+ if (!(m_summonMask & SUMMON_MASK_CONTROLABLE_GUARDIAN))
+ {
+ m_summonMask |= SUMMON_MASK_CONTROLABLE_GUARDIAN;
+ InitCharmInfo();
+ }
+
m_name = "Pet";
m_regenTimer = 4000;
-
- owner->SetPetAtLoginFlag(0);
}
Pet::~Pet()
@@ -93,24 +98,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);
@@ -151,7 +156,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
}
uint32 pet_number = fields[0].GetUInt32();
-
+
if (current && owner->IsPetNeedBeTemporaryUnsummoned())
{
owner->SetTemporaryUnsummonedPetNumber(pet_number);
@@ -168,7 +173,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
}
float px, py, pz;
- owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle());
Relocate(px, py, pz, owner->GetOrientation());
if (!IsPositionValid())
@@ -284,29 +289,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 +400,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() << ", "
@@ -427,8 +419,8 @@ void Pet::SavePetToDB(PetSaveMode mode)
// save only spell slots from action bar
for(uint32 i = ACTION_BAR_INDEX_PET_SPELL_START; i < ACTION_BAR_INDEX_PET_SPELL_END; ++i)
{
- ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " "
- << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " ";
+ ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << " "
+ << uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << " ";
};
ss << "', "
@@ -436,8 +428,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 +439,6 @@ void Pet::SavePetToDB(PetSaveMode mode)
RemoveAllAuras();
DeleteFromDB(m_charmInfo->GetPetNumber());
}
- pOwner->SetPetAtLoginFlag(0);
}
void Pet::DeleteFromDB(uint32 guidlow)
@@ -732,9 +722,6 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
}
uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET);
- sLog.outDebug("SetInstanceID()");
- SetInstanceId(creature->GetInstanceId());
-
sLog.outDebug("Create pet");
uint32 pet_number = objmgr.GeneratePetNumber();
if(!Create(guid, creature->GetMap(), creature->GetPhaseMask(), creature->GetEntry(), pet_number))
@@ -941,6 +928,16 @@ bool Guardian::InitStatsForLevel(uint32 petlevel)
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
break;
}
+ case 31216: // Mirror Image
+ {
+ SetBonusDamage( int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f));
+ if(!pInfo)
+ {
+ SetCreateMana(28 + 30*petlevel);
+ SetCreateHealth(28 + 10*petlevel);
+ }
+ break;
+ }
default:
{
if(!pInfo)
@@ -1081,7 +1078,7 @@ void Pet::_LoadSpells()
{
Field *fields = result->Fetch();
- addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED);
+ addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt8()), PETSPELL_UNCHANGED);
}
while( result->NextRow() );
@@ -1346,8 +1343,8 @@ bool Pet::learnSpell(uint32 spell_id)
if(!m_loading)
{
- WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
- data << uint16(spell_id);
+ WorldPacket data(SMSG_PET_LEARNED_SPELL, 4);
+ data << uint32(spell_id);
m_owner->GetSession()->SendPacket(&data);
m_owner->PetSpellInitialize();
}
@@ -1399,8 +1396,8 @@ bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
{
if(!m_loading)
{
- WorldPacket data(SMSG_PET_REMOVED_SPELL, 2);
- data << uint16(spell_id);
+ WorldPacket data(SMSG_PET_REMOVED_SPELL, 4);
+ data << uint32(spell_id);
m_owner->GetSession()->SendPacket(&data);
}
return true;
@@ -1464,12 +1461,12 @@ void Pet::CleanupActionBar()
{
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
if(UnitActionBarEntry const* ab = m_charmInfo->GetActionBarEntry(i))
- if(ab->SpellOrAction && ab->IsActionBarForSpell())
+ if(ab->GetAction() && ab->IsActionBarForSpell())
{
- if(!HasSpell(ab->SpellOrAction))
+ if(!HasSpell(ab->GetAction()))
m_charmInfo->SetActionBar(i, 0, ACT_PASSIVE);
- else if(ab->Type == ACT_ENABLED)
- ToggleAutocast(ab->SpellOrAction, true);
+ else if(ab->GetType() == ACT_ENABLED)
+ ToggleAutocast(ab->GetAction(), true);
}
}
@@ -1490,6 +1487,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 +1577,90 @@ 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();
@@ -1693,10 +1778,10 @@ bool Pet::IsPermanentPetFor(Player* owner)
bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
{
- SetMapId(map->GetId());
- SetInstanceId(map->GetInstanceId());
- SetPhaseMask(phaseMask,false);
+ assert(map);
+ SetMap(map);
+ SetPhaseMask(phaseMask,false);
Object::_Create(guidlow, pet_number, HIGHGUID_PET);
m_DBTableGuid = guidlow;
@@ -1761,7 +1846,7 @@ void Pet::CastPetAuras(bool current)
void Pet::CastPetAura(PetAura const* aura)
{
- uint16 auraId = aura->GetAura(GetEntry());
+ uint32 auraId = aura->GetAura(GetEntry());
if(!auraId)
return;