diff options
Diffstat (limited to 'src/game/Pet.cpp')
-rw-r--r-- | src/game/Pet.cpp | 106 |
1 files changed, 70 insertions, 36 deletions
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 9bf67fae2c1..987a106a16d 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -286,6 +286,11 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str()); ++iter; m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str()); + + // patch for old data where some spells have ACT_DECIDE but should have ACT_CAST + // so overwrite old state + SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction); + if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_CAST; } //init teach spells @@ -1322,7 +1327,7 @@ void Pet::_LoadAuras(uint32 timediff) for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i) SetUInt32Value(i, 0); - QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); + QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); if(result) { @@ -1332,10 +1337,11 @@ void Pet::_LoadAuras(uint32 timediff) uint64 caster_guid = fields[0].GetUInt64(); uint32 spellid = fields[1].GetUInt32(); uint32 effindex = fields[2].GetUInt32(); - int32 damage = (int32)fields[3].GetUInt32(); - int32 maxduration = (int32)fields[4].GetUInt32(); - int32 remaintime = (int32)fields[5].GetUInt32(); - int32 remaincharges = (int32)fields[6].GetUInt32(); + uint32 stackcount= fields[3].GetUInt32(); + int32 damage = (int32)fields[4].GetUInt32(); + int32 maxduration = (int32)fields[5].GetUInt32(); + int32 remaintime = (int32)fields[6].GetUInt32(); + int32 remaincharges = (int32)fields[7].GetUInt32(); SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); if(!spellproto) @@ -1372,12 +1378,15 @@ void Pet::_LoadAuras(uint32 timediff) if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto)) continue; - Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL); + for(uint32 i=0; i<stackcount; i++) + { + Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL); - if(!damage) - damage = aura->GetModifier()->m_amount; - aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); - AddAura(aura); + if(!damage) + damage = aura->GetModifier()->m_amount; + aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); + AddAura(aura); + } } while( result->NextRow() ); @@ -1390,30 +1399,52 @@ void Pet::_SaveAuras() CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); AuraMap const& auras = GetAuras(); - for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) - { - // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras. - SpellEntry const *spellInfo = itr->second->GetSpellProto(); - uint8 i; - for (i = 0; i < 3; i++) - if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET ) - break; + if (auras.empty()) + return; - if (i != 3) - continue; - - if(itr->second->IsPassive()) - continue; + spellEffectPair lastEffectPair = auras.begin()->first; + uint32 stackCounter = 1; - /// do not save single target auras (unless they were cast by the player) - if (itr->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo)) - continue; + for(AuraMap::const_iterator itr = auras.begin(); ; ++itr) + { + if(itr == auras.end() || lastEffectPair != itr->first) + { + AuraMap::const_iterator itr2 = itr; + // save previous spellEffectPair to db + itr2--; + SpellEntry const *spellInfo = itr2->second->GetSpellProto(); + /// do not save single target auras (unless they were cast by the player) + if (!(itr2->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo))) + { + if(!itr2->second->IsPassive()) + { + // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras. + uint8 i; + for (i = 0; i < 3; i++) + if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH || + spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || + spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET ) + break; + + if (i == 3) + { + CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) " + "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d')", + m_charmInfo->GetPetNumber(), itr2->second->GetCasterGUID(),(uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->m_procCharges)); + } + } + } + if(itr == auras.end()) + break; + } - CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,amount,maxduration,remaintime,remaincharges) " - "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%d', '%d', '%d', '%d')", - m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(),(uint32)(*itr).second->GetId(), (uint32)(*itr).second->GetEffIndex(),(*itr).second->GetModifier()->m_amount,int((*itr).second->GetAuraMaxDuration()),int((*itr).second->GetAuraDuration()),int((*itr).second->m_procCharges)); + if (lastEffectPair == itr->first) + stackCounter++; + else + { + lastEffectPair = itr->first; + stackCounter = 1; + } } } @@ -1434,6 +1465,9 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s return false; } + // same spells don't have autocast option + if (spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) active = ACT_CAST; + PetSpellMap::iterator itr = m_spells.find(spell_id); if (itr != m_spells.end()) { @@ -1508,7 +1542,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s if (IsPassiveSpell(spell_id)) CastSpell(this, spell_id, true); else if(state == PETSPELL_NEW) - m_charmInfo->AddSpellToAB(oldspell_id, spell_id); + m_charmInfo->AddSpellToAB(oldspell_id, spell_id, active); if(newspell->active == ACT_ENABLED) ToggleAutocast(spell_id, true); @@ -1658,10 +1692,10 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply) if(IsPassiveSpell(spellid)) return; - if(const SpellEntry *tempSpell = GetSpellStore()->LookupEntry(spellid)) - if(tempSpell->EffectImplicitTargetA[0] != TARGET_ALL_AROUND_CASTER - && tempSpell->EffectImplicitTargetA[0] != TARGET_CHAIN_DAMAGE) - return; + //if(const SpellEntry *tempSpell = GetSpellStore()->LookupEntry(spellid)) + // if(tempSpell->EffectImplicitTargetA[0] != TARGET_ALL_AROUND_CASTER + // && tempSpell->EffectImplicitTargetA[0] != TARGET_CHAIN_DAMAGE) + // return; PetSpellMap::const_iterator itr = m_spells.find((uint16)spellid); |