Index: /trunk/src/game/Pet.h
===================================================================
--- /trunk/src/game/Pet.h (revision 206)
+++ /trunk/src/game/Pet.h (revision 250)
@@ -213,5 +213,5 @@
         void _SaveSpells();
 
-        bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL);
+        bool addSpell(uint16 spell_id, ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL);
         bool learnSpell(uint16 spell_id);
         void removeSpell(uint16 spell_id);
Index: /trunk/src/game/SharedDefines.h
===================================================================
--- /trunk/src/game/SharedDefines.h (revision 230)
+++ /trunk/src/game/SharedDefines.h (revision 250)
@@ -249,5 +249,5 @@
 #define SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY    0x00008000            // 15 remove auras on immunity
 #define SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE 0x00010000            // 16 unaffected by school immunity
-#define SPELL_ATTR_EX_UNK17                       0x00020000            // 17
+#define SPELL_ATTR_EX_PET_NOT_AUTOCAST            0x00020000            // 17
 #define SPELL_ATTR_EX_UNK18                       0x00040000            // 18
 #define SPELL_ATTR_EX_UNK19                       0x00080000            // 19
Index: /trunk/src/game/SpellMgr.h
===================================================================
--- /trunk/src/game/SpellMgr.h (revision 229)
+++ /trunk/src/game/SpellMgr.h (revision 250)
@@ -285,5 +285,5 @@
 }
 
-bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
+//bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
 
 inline bool IsSealSpell(SpellEntry const *spellInfo)
@@ -302,4 +302,5 @@
 int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
 bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1,uint32 spellSpec2);
+bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1,uint32 spellSpec2);
 bool IsPassiveSpell(uint32 spellId);
 
@@ -769,5 +770,5 @@
         bool IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const;
         static bool canStackSpellRanks(SpellEntry const *spellInfo);
-        bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const;
+        bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool isFromTheSameCaster ) const;
 
         SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const;
Index: /trunk/src/game/Unit.cpp
===================================================================
--- /trunk/src/game/Unit.cpp (revision 248)
+++ /trunk/src/game/Unit.cpp (revision 250)
@@ -3898,16 +3898,16 @@
         if(!is_triggered_by_spell)
         {
-            SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId);
-
-            bool is_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec);
-
-            if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() )
-            {
-                // cannot remove higher rank
-                if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
-                    if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)
+            bool isFromSameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID();
+            if( spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, isFromSameCaster) )
+            {
+                //some spells should be not removed by lower rank of them
+                if (!isFromSameCaster
+                    &&(spellProto->Effect[effIndex]==SPELL_AURA_MOD_INCREASE_ENERGY)
+                    &&(spellProto->DurationIndex==21)
+                    &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
+                    &&(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0))
                         return false;
 
-                // Its a parent aura (create this aura in ApplyModifier)
+                //Its a parent aura (create this aura in ApplyModifier)
                 if ((*i).second->IsInUse())
                 {
@@ -3921,37 +3921,4 @@
                 else
                     next =  m_Auras.begin();
-            }
-            else if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) )
-            {
-                // Its a parent aura (create this aura in ApplyModifier)
-                if ((*i).second->IsInUse())
-                {
-                    sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
-                    continue;
-                }
-                RemoveAurasDueToSpell(i_spellId);
-
-                if( m_Auras.empty() )
-                    break;
-                else
-                    next =  m_Auras.begin();
-            }
-            // Potions stack aura by aura (elixirs/flask already checked)
-            else if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION )
-            {
-                if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex))
-                {
-                    if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)
-                        return false;                       // cannot remove higher rank
-
-                    // Its a parent aura (create this aura in ApplyModifier)
-                    if ((*i).second->IsInUse())
-                    {
-                        sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
-                        continue;
-                    }
-                    RemoveAura(i);
-                    next = i;
-                }
             }
         }
Index: /trunk/src/game/Pet.cpp
===================================================================
--- /trunk/src/game/Pet.cpp (revision 218)
+++ /trunk/src/game/Pet.cpp (revision 250)
@@ -287,4 +287,9 @@
             ++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_PET_NOT_AUTOCAST)
+                m_charmInfo->GetActionBarEntry(index)->Type = ACT_CAST;
         }
 
@@ -1287,5 +1292,5 @@
             Field *fields = result->Fetch();
 
-            addSpell(fields[0].GetUInt16(), fields[2].GetUInt16(), PETSPELL_UNCHANGED, fields[1].GetUInt16());
+            addSpell(fields[0].GetUInt16(), (ActiveStates)fields[2].GetUInt16(), PETSPELL_UNCHANGED, fields[1].GetUInt16());
         }
         while( result->NextRow() );
@@ -1418,5 +1423,5 @@
 }
 
-bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 slot_id, PetSpellType type)
+bool Pet::addSpell(uint16 spell_id, ActiveStates active, PetSpellState state, uint16 slot_id, PetSpellType type)
 {
     SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
@@ -1434,4 +1439,7 @@
         return false;
     }
+    // same spells don't have autocast option
+    if (spellInfo->AttributesEx & SPELL_ATTR_EX_PET_NOT_AUTOCAST)
+        active = ACT_CAST;
 
     PetSpellMap::iterator itr = m_spells.find(spell_id);
@@ -1509,5 +1517,5 @@
         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)
@@ -1659,8 +1667,8 @@
         return;
 
-    if(const SpellEntry *tempSpell = GetSpellStore()->LookupEntry(spellid))
+    /*if(const SpellEntry *tempSpell = GetSpellStore()->LookupEntry(spellid))
         if(tempSpell->EffectImplicitTargetA[0] != TARGET_ALL_AROUND_CASTER
             && tempSpell->EffectImplicitTargetA[0] != TARGET_CHAIN_DAMAGE)
-            return;    
+            return;    */
 
     PetSpellMap::const_iterator itr = m_spells.find((uint16)spellid);
Index: /trunk/src/game/SpellMgr.cpp
===================================================================
--- /trunk/src/game/SpellMgr.cpp (revision 236)
+++ /trunk/src/game/SpellMgr.cpp (revision 250)
@@ -99,5 +99,5 @@
     return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0;
 }
-
+/*not used for now so commented out
 bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
 {
@@ -108,5 +108,4 @@
 
     if (spellInfo_1->Effect[effIndex_1] != spellInfo_2->Effect[effIndex_2] ||
-        spellInfo_1->EffectItemType[effIndex_1] != spellInfo_2->EffectItemType[effIndex_2] ||
         spellInfo_1->EffectMiscValue[effIndex_1] != spellInfo_2->EffectMiscValue[effIndex_2] ||
         spellInfo_1->EffectApplyAuraName[effIndex_1] != spellInfo_2->EffectApplyAuraName[effIndex_2])
@@ -114,5 +113,5 @@
 
     return true;
-}
+}*/
 
 int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
@@ -245,4 +244,17 @@
         case SPELL_CURSE:
         case SPELL_ASPECT:
+        case SPELL_POSITIVE_SHOUT:
+        case SPELL_JUDGEMENT:
+        case SPELL_WARLOCK_CORRUPTION:
+            return spellSpec1==spellSpec2;
+        default:
+            return false;
+    }
+}
+
+bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1,uint32 spellSpec2)
+{
+    switch(spellSpec1)
+    {
         case SPELL_TRACKER:
         case SPELL_WARLOCK_ARMOR:
@@ -250,7 +262,4 @@
         case SPELL_ELEMENTAL_SHIELD:
         case SPELL_MAGE_POLYMORPH:
-        case SPELL_POSITIVE_SHOUT:
-        case SPELL_JUDGEMENT:
-        case SPELL_WARLOCK_CORRUPTION:
             return spellSpec1==spellSpec2;
         case SPELL_BATTLE_ELIXIR:
@@ -1031,9 +1040,6 @@
 }
 
-bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const
-{
-    if(spellId_1 == spellId_2) // auras due to the same spell
-        return false;
-
+bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool isFromTheSameCaster ) const
+{
     SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
     SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
@@ -1041,4 +1047,11 @@
     if(!spellInfo_1 || !spellInfo_2)
         return false;
+
+    SpellSpecific spellId_spec_1 = GetSpellSpecific(spellId_1);
+    SpellSpecific spellId_spec_2 = GetSpellSpecific(spellId_2);
+    if (spellId_spec_1 && spellId_spec_2)
+        if (IsSingleFromSpellSpecificPerTarget(spellId_spec_1,spellId_spec_2)
+            || (IsSingleFromSpellSpecificPerCaster(spellId_spec_1,spellId_spec_2) && isFromTheSameCaster))
+            return true;
 
     if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
@@ -1051,12 +1064,42 @@
             return false;
     }
+
+    //if both elixirs are not battle/guardian/potions/flasks then always stack
+    else if ((spellInfo_1->SpellFamilyName == SPELLFAMILY_POTION)
+        &&(spellId_spec_1 || spellId_spec_2))
+        return false;
+
     else if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags)
         return false;
 
     for(uint32 i = 0; i < 3; ++i)
-        if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i]
-            || spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i])
+    {
+        if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i])
             return false;
-
+        if (spellInfo_1->EffectApplyAuraName[i] || spellInfo_2->EffectApplyAuraName[i])
+        {
+            if(spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]
+                || spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i])
+                    // need itemtype check? need to find an example
+                return false;
+            else if (!isFromTheSameCaster)
+                switch(spellInfo_1->EffectApplyAuraName[i])
+                    {
+                    //spells with these auras from different casters will stack
+                        case SPELL_AURA_PERIODIC_DAMAGE:
+                        case SPELL_AURA_PERIODIC_HEAL:
+                        case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+                        case SPELL_AURA_PERIODIC_ENERGIZE:
+                        case SPELL_AURA_PERIODIC_MANA_LEECH:
+                        case SPELL_AURA_PERIODIC_LEECH:
+                        //exception for shaman positive totems with these auras
+                        if ((spellInfo_1->SpellFamilyName != SPELLFAMILY_SHAMAN)
+                            ||(spellInfo_1->Effect[i]!=SPELL_AURA_MOD_INCREASE_ENERGY))
+                            return false;
+                        default:
+                            break;
+                    }
+        }
+    }
     return true;
 }
Index: /trunk/win/TrinityCore&Script VC80.sln
===================================================================
--- /trunk/win/TrinityCore&Script VC80.sln (revision 44)
+++ /trunk/win/TrinityCore&Script VC80.sln (revision 250)
Index: /trunk/win/TrinityCore&Script VC90.sln
===================================================================
--- /trunk/win/TrinityCore&Script VC90.sln (revision 37)
+++ /trunk/win/TrinityCore&Script VC90.sln (revision 250)
