diff options
Diffstat (limited to 'src/game/Pet.cpp')
-rw-r--r-- | src/game/Pet.cpp | 187 |
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; |