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.cpp106
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);