Index: trunk/src/game/SpellEffects.cpp
===================================================================
--- trunk/src/game/SpellEffects.cpp (revision 174)
+++ trunk/src/game/SpellEffects.cpp (revision 178)
@@ -3577,4 +3577,11 @@
     }
 
+    // trigger
+    if(m_spellInfo->Id == 40276)
+    {
+        EffectSummonWild(i);
+        return;
+    }
+
     // set timer for unsummon
     int32 duration = GetSpellDuration(m_spellInfo);
Index: trunk/src/game/Unit.h
===================================================================
--- trunk/src/game/Unit.h (revision 174)
+++ trunk/src/game/Unit.h (revision 178)
@@ -438,6 +438,6 @@
     VISIBILITY_ON                 = 1,
     VISIBILITY_GROUP_STEALTH      = 2,                      // detect chance, seen and can see group members
-    VISIBILITY_GROUP_INVISIBILITY = 3,                      // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead)
-    VISIBILITY_GROUP_NO_DETECT    = 4,                      // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break
+    //VISIBILITY_GROUP_INVISIBILITY = 3,                      // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead)
+    //VISIBILITY_GROUP_NO_DETECT    = 4,                      // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break
     VISIBILITY_RESPAWN            = 5                       // special totally not detectable visibility for force delete object at respawn command
 };
@@ -1136,11 +1136,13 @@
 
         // common function for visibility checks for player/creatures with detection code
+        virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const;
         bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false) const;
         bool canDetectInvisibilityOf(Unit const* u) const;
+        bool canDetectStealthOf(Unit const* u, float distance) const;
 
         // virtual functions for all world objects types
         bool isVisibleForInState(Player const* u, bool inVisibleList) const;
         // function for low level grid visibility checks in player/creature cases
-        virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0;
+        virtual bool IsVisibleInGridForPlayer(Player const* pl) const = 0;
 
         bool waterbreath;
Index: trunk/src/game/SpellAuras.cpp
===================================================================
--- trunk/src/game/SpellAuras.cpp (revision 174)
+++ trunk/src/game/SpellAuras.cpp (revision 178)
@@ -3231,5 +3231,6 @@
             if(m_target->GetVisibility()!=VISIBILITY_OFF)
             {
-                m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
+                //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
+                m_target->SetVisibility(VISIBILITY_OFF);
                 m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
             }
@@ -3259,6 +3260,7 @@
                 if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
                 {
-                    m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
-                    m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
+                    //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
+                    //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
+                    m_target->SetVisibility(VISIBILITY_ON);
                 }
                 else
@@ -3315,6 +3317,7 @@
         {
             // Aura not added yet but visibility code expect temporary add aura
-            m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
-            m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
+            //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT);
+            //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
+            m_target->SetVisibility(VISIBILITY_ON);
         }
     }
Index: trunk/src/game/OutdoorPvPObjectiveAI.cpp
===================================================================
--- trunk/src/game/OutdoorPvPObjectiveAI.cpp (revision 102)
+++ trunk/src/game/OutdoorPvPObjectiveAI.cpp (revision 178)
@@ -51,11 +51,11 @@
 void OutdoorPvPObjectiveAI::AttackStart(Unit *)
 {
-    EnterEvadeMode();
+    //EnterEvadeMode();
 }
 
 void OutdoorPvPObjectiveAI::EnterEvadeMode()
 {
-    i_creature.DeleteThreatList();
-    i_creature.CombatStop();
+//    i_creature.DeleteThreatList();
+//    i_creature.CombatStop();
 }
 
Index: trunk/src/game/Creature.cpp
===================================================================
--- trunk/src/game/Creature.cpp (revision 174)
+++ trunk/src/game/Creature.cpp (revision 178)
@@ -319,4 +319,8 @@
     m_spells[2] = GetCreatureInfo()->spell3;
     m_spells[3] = GetCreatureInfo()->spell4;
+
+    // HACK: trigger creature is always not selectable
+    if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
+        SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
 
     return true;
@@ -1488,4 +1492,45 @@
 }
 
+bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const
+{
+    // not in world
+    if(!IsInWorld() || !u->IsInWorld())
+        return false;
+
+    // all dead creatures/players not visible for any creatures
+    if(!u->isAlive() || !isAlive())
+        return false;
+
+    // Always can see self
+    if (u == this)
+        return true;
+
+    // always seen by owner
+    if(GetGUID() == u->GetCharmerOrOwnerGUID())
+        return true;
+
+    if(u->GetVisibility() == VISIBILITY_OFF) //GM
+        return false;
+
+    // invisible aura
+    if((m_invisibilityMask || u->m_invisibilityMask) && !canDetectInvisibilityOf(u))
+        return false;
+
+    // unit got in stealth in this moment and must ignore old detected state
+    //if (m_Visibility == VISIBILITY_GROUP_NO_DETECT)
+    //    return false;
+
+    // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible
+    if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH)
+    {
+        //do not know what is the use of this detect
+        if(!detect || !canDetectStealthOf(u, GetDistance(u)))
+            return false;
+    }
+
+    // Now check is target visible with LoS
+    return u->IsWithinLOS(GetPositionX(),GetPositionY(),GetPositionZ());
+}
+
 float Creature::GetAttackDistance(Unit const* pl) const
 {
@@ -1699,5 +1744,5 @@
 }
 
-bool Creature::IsVisibleInGridForPlayer(Player* pl) const
+bool Creature::IsVisibleInGridForPlayer(Player const* pl) const
 {
     // gamemaster in GM mode see all, including ghosts
Index: trunk/src/game/Object.cpp
===================================================================
--- trunk/src/game/Object.cpp (revision 174)
+++ trunk/src/game/Object.cpp (revision 178)
@@ -1487,5 +1487,5 @@
         if(GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER)
             pCreature->setFaction(((Unit*)this)->getFaction());
-        pCreature->CastSpell(pCreature, pCreature->m_spells[0], true, 0, 0, GetGUID());
+        pCreature->CastSpell(pCreature, pCreature->m_spells[0], false, 0, 0, GetGUID());
     }
 
Index: trunk/src/game/Creature.h
===================================================================
--- trunk/src/game/Creature.h (revision 174)
+++ trunk/src/game/Creature.h (revision 178)
@@ -548,4 +548,5 @@
         uint32 m_GlobalCooldown;
 
+        bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const;
         float GetAttackDistance(Unit const* pl) const;
 
@@ -561,5 +562,5 @@
         void SetCurrentCell(Cell const& cell) { m_currentCell = cell; }
 
-        bool IsVisibleInGridForPlayer(Player* pl) const;
+        bool IsVisibleInGridForPlayer(Player const* pl) const;
 
         void RemoveCorpse();
Index: trunk/src/game/Player.h
===================================================================
--- trunk/src/game/Player.h (revision 177)
+++ trunk/src/game/Player.h (revision 178)
@@ -1993,7 +1993,8 @@
         ClientGUIDs m_clientGUIDs;
 
-        bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); }
-
-        bool IsVisibleInGridForPlayer(Player* pl) const;
+        bool HaveAtClient(WorldObject const* u) const { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); }
+
+        bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const;
+        bool IsVisibleInGridForPlayer(Player const* pl) const;
         bool IsVisibleGloballyFor(Player* pl) const;
 
Index: trunk/src/game/Unit.cpp
===================================================================
--- trunk/src/game/Unit.cpp (revision 174)
+++ trunk/src/game/Unit.cpp (revision 178)
@@ -8507,7 +8507,4 @@
         return false;
 
-    if(GetTypeId()==TYPEID_UNIT && (((Creature *)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER))
-        return false;
-
     return isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/;
 }
@@ -8581,257 +8578,21 @@
     if(!u)
         return false;
-
-    // Always can see self
-    if (u==this)
+    return u->canSeeOrDetect(this, detect, inVisibleList);
+}
+
+bool Unit::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const
+{
+    return true;
+}
+
+bool Unit::canDetectInvisibilityOf(Unit const* u) const
+{
+    if(m_invisibilityMask & u->m_invisibilityMask) // same group
         return true;
-
-    // player visible for other player if not logout and at same transport
-    // including case when player is out of world
-    bool at_same_transport =
-        GetTypeId() == TYPEID_PLAYER &&  u->GetTypeId()==TYPEID_PLAYER &&
-        !((Player*)this)->GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout() &&
-        !((Player*)this)->GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading() &&
-        ((Player*)this)->GetTransport() && ((Player*)this)->GetTransport() == ((Player*)u)->GetTransport();
-
-    // not in world
-    if(!at_same_transport && (!IsInWorld() || !u->IsInWorld()))
-        return false;
-
-    // forbidden to seen (at GM respawn command)
-    if(m_Visibility==VISIBILITY_RESPAWN)
-        return false;
-
-    // always seen by owner
-    if(GetCharmerOrOwnerGUID()==u->GetGUID())
-        return true;
-
-    // Grid dead/alive checks
-    if( u->GetTypeId()==TYPEID_PLAYER)
-    {
-        // non visible at grid for any stealth state
-        if(!IsVisibleInGridForPlayer((Player *)u))
-            return false;
-
-        // if player is dead then he can't detect anyone in anycases
-        if(!u->isAlive())
-            detect = false;
-    }
-    else
-    {
-        // all dead creatures/players not visible for any creatures
-        if(!u->isAlive() || !isAlive())
-            return false;
-    }
-
-    // If the player is currently possessing, update visibility from the possessed unit's location
-    const Unit* target = u->GetTypeId() == TYPEID_PLAYER && u->isPossessing() ? u->GetCharm() : u;
-
-    // different visible distance checks
-    if(u->isInFlight())                                     // what see player in flight
-    {
-        // use object grey distance for all (only see objects any way)
-        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
-            return false;
-    }
-    else if(!isAlive())                                     // distance for show body
-    {
-        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
-            return false;
-    }
-    else if(GetTypeId()==TYPEID_PLAYER)                     // distance for show player
-    {
-        if(u->GetTypeId()==TYPEID_PLAYER)
-        {
-            // Players far than max visible distance for player or not in our map are not visible too
-            if (!at_same_transport && !IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
-                return false;
-        }
-        else
-        {
-            // Units far than max visible distance for creature or not in our map are not visible too
-            // Active unit should always be visibile
-            if (!IsWithinDistInMap(target, target->isActive() 
-                ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance()))
-                : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))))
-                return false;
-        }
-    }
-    else if(GetCharmerOrOwnerGUID())                        // distance for show pet/charmed
-    {
-        // Pet/charmed far than max visible distance for player or not in our map are not visible too
-        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
-            return false;
-    }
-    else                                                    // distance for show creature
-    {
-        // Units far than max visible distance for creature or not in our map are not visible too
-        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
-            return false;
-    }
-
-    // Visible units, always are visible for all units, except for units under invisibility
-    if (m_Visibility == VISIBILITY_ON && u->m_invisibilityMask==0)
-        return true;
-
-    // GMs see any players, not higher GMs and all units
-    if (u->GetTypeId() == TYPEID_PLAYER && ((Player *)u)->isGameMaster())
-    {
-        if(GetTypeId() == TYPEID_PLAYER)
-            return ((Player *)this)->GetSession()->GetSecurity() <= ((Player *)u)->GetSession()->GetSecurity();
-        else
+    AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
+    for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+        if((*iter)->GetCasterGUID()==u->GetGUID())
             return true;
-    }
-
-    // non faction visibility non-breakable for non-GMs
-    if (m_Visibility == VISIBILITY_OFF)
-        return false;
-
-    // raw invisibility
-    bool invisible = (m_invisibilityMask != 0 || u->m_invisibilityMask !=0);
-
-    // detectable invisibility case
-    if( invisible && (
-        // Invisible units, always are visible for units under same invisibility type
-        (m_invisibilityMask & u->m_invisibilityMask)!=0 ||
-        // Invisible units, always are visible for unit that can detect this invisibility (have appropriate level for detect)
-        u->canDetectInvisibilityOf(this) ||
-        // Units that can detect invisibility always are visible for units that can be detected
-        canDetectInvisibilityOf(u) ))
-    {
-        invisible = false;
-    }
-
-    // special cases for always overwrite invisibility/stealth
-    if(invisible || m_Visibility == VISIBILITY_GROUP_STEALTH)
-    {
-        // non-hostile case
-        if (!u->IsHostileTo(this))
-        {
-            // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting)
-            if(GetTypeId()==TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER)
-            {
-                if(((Player*)this)->IsGroupVisibleFor(((Player*)u)))
-                    return true;
-
-                // else apply same rules as for hostile case (detecting check for stealth)
-            }
-        }
-        // hostile case
-        else
-        {
-            // Hunter mark functionality
-            AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED);
-            for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
-                if((*iter)->GetCasterGUID()==u->GetGUID())
-                    return true;
-
-            // else apply detecting check for stealth
-        }
-
-        // none other cases for detect invisibility, so invisible
-        if(invisible)
-            return false;
-
-        // else apply stealth detecting check
-    }
-
-    // unit got in stealth in this moment and must ignore old detected state
-    if (m_Visibility == VISIBILITY_GROUP_NO_DETECT)
-        return false;
-
-    // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible
-    if (m_Visibility != VISIBILITY_GROUP_STEALTH)
-        return true;
-
-    // NOW ONLY STEALTH CASE
-
-    // stealth and detected and visible for some seconds
-    if (u->GetTypeId() == TYPEID_PLAYER  && ((Player*)u)->m_DetectInvTimer > 300 && ((Player*)u)->HaveAtClient(this))
-        return true;
-
-    //if in non-detect mode then invisible for unit
-    if (!detect)
-        return false;
-
-    // Special cases
-
-    // If is attacked then stealth is lost, some creature can use stealth too
-    if( !getAttackers().empty() )
-        return true;
-
-    // If there is collision rogue is seen regardless of level difference
-    // TODO: check sizes in DB
-    float distance = GetDistance(u);
-    if (distance < 0.24f)
-        return true;
-
-    //If a mob or player is stunned he will not be able to detect stealth
-    if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this))
-        return false;
-
-    // Creature can detect target only in aggro radius
-    if(u->GetTypeId() != TYPEID_PLAYER)
-    {
-        //Always invisible from back and out of aggro range
-        bool isInFront = u->isInFront(this,((Creature const*)u)->GetAttackDistance(this));
-        if(!isInFront)
-            return false;
-    }
-    else
-    {
-        //Always invisible from back
-        bool isInFront = u->isInFront(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature());
-        if(!isInFront)
-            return false;
-    }
-
-    // if doesn't have stealth detection (Shadow Sight), then check how stealthy the unit is, otherwise just check los
-    if(!u->HasAuraType(SPELL_AURA_DETECT_STEALTH))
-    {
-        //Calculation if target is in front
-
-        //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5)
-        float visibleDistance = 10.5f - (GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/100.0f);
-
-        //Visible distance is modified by
-        //-Level Diff (every level diff = 1.0f in visible distance)
-        visibleDistance += int32(u->getLevelForTarget(this)) - int32(this->getLevelForTarget(u));
-
-        //This allows to check talent tree and will add addition stealth dependent on used points)
-        int32 stealthMod = GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL);
-        if(stealthMod < 0)
-            stealthMod = 0;
-
-        //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia)
-        //based on wowwiki every 5 mod we have 1 more level diff in calculation
-        visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f;
-
-        if(distance > visibleDistance)
-            return false;
-    }
-
-    // Now check is target visible with LoS
-    float ox,oy,oz;
-    u->GetPosition(ox,oy,oz);
-    return IsWithinLOS(ox,oy,oz);
-}
-
-void Unit::SetVisibility(UnitVisibility x)
-{
-    m_Visibility = x;
-
-    if(IsInWorld())
-    {
-        Map *m = MapManager::Instance().GetMap(GetMapId(), this);
-
-        if(GetTypeId()==TYPEID_PLAYER)
-            m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
-        else
-            m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
-    }
-}
-
-bool Unit::canDetectInvisibilityOf(Unit const* u) const
-{
+
     if(uint32 mask = (m_detectInvisibilityMask & u->m_invisibilityMask))
     {
@@ -8850,12 +8611,14 @@
             // find invisibility detect level
             uint32 detectLevel = 0;
-            Unit::AuraList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
-            for(Unit::AuraList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr)
-                if(((*itr)->GetModifier()->m_miscvalue)==i && detectLevel < (*itr)->GetModifier()->m_amount)
-                    detectLevel = (*itr)->GetModifier()->m_amount;
-
             if(i==6 && GetTypeId()==TYPEID_PLAYER)          // special drunk detection case
             {
                 detectLevel = ((Player*)this)->GetDrunkValue();
+            }
+            else
+            {
+                Unit::AuraList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
+                for(Unit::AuraList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr)
+                    if(((*itr)->GetModifier()->m_miscvalue)==i && detectLevel < (*itr)->GetModifier()->m_amount)
+                        detectLevel = (*itr)->GetModifier()->m_amount;
             }
 
@@ -8866,4 +8629,41 @@
 
     return false;
+}
+
+bool Unit::canDetectStealthOf(Unit const* target, float distance) const
+{
+    if(hasUnitState(UNIT_STAT_STUNNED))
+        return false;
+    if(distance < 0.24f) //collision
+        return true;
+    if(!HasInArc(M_PI, target)) //behind
+        return false;
+    if(HasAuraType(SPELL_AURA_DETECT_STEALTH))
+        return true;
+
+    //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5)
+    float visibleDistance = 10.5f - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH) / 100.0f;
+    //Visible distance is modified by -Level Diff (every level diff = 1.0f in visible distance)
+    visibleDistance += int32(getLevelForTarget(target)) - int32(target->getLevelForTarget(this));
+    //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia)
+    //based on wowwiki every 5 mod we have 1 more level diff in calculation
+    visibleDistance += (float)(GetTotalAuraModifier(SPELL_AURA_MOD_DETECT) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL)) / 5.0f;
+
+    return distance < visibleDistance;
+}
+
+void Unit::SetVisibility(UnitVisibility x)
+{
+    m_Visibility = x;
+
+    if(IsInWorld())
+    {
+        Map *m = MapManager::Instance().GetMap(GetMapId(), this);
+
+        if(GetTypeId()==TYPEID_PLAYER)
+            m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+        else
+            m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
+    }
 }
 
Index: trunk/src/game/Player.cpp
===================================================================
--- trunk/src/game/Player.cpp (revision 177)
+++ trunk/src/game/Player.cpp (revision 178)
@@ -2001,6 +2001,6 @@
         if(HasAuraType(SPELL_AURA_MOD_STEALTH))
             SetVisibility(VISIBILITY_GROUP_STEALTH);
-        else if(HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
-            SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
+        //else if(HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
+        //    SetVisibility(VISIBILITY_GROUP_INVISIBILITY);
         else
             SetVisibility(VISIBILITY_ON);
@@ -16396,5 +16396,4 @@
         if ((*i)->isVisibleForOrDetect(this,true))
         {
-
             (*i)->SendUpdateToPlayer(this);
             m_clientGUIDs.insert((*i)->GetGUID());
@@ -17189,5 +17188,106 @@
 }
 
-bool Player::IsVisibleInGridForPlayer( Player* pl ) const
+bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const
+{
+    // Always can see self
+    if (u == this)
+        return true;
+
+    // player visible for other player if not logout and at same transport
+    // including case when player is out of world
+    bool at_same_transport =
+        GetTransport() && u->GetTypeId() == TYPEID_PLAYER
+        && !GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout()
+        && !GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading()
+        && GetTransport() == ((Player*)u)->GetTransport();
+
+    // not in world
+    if(!at_same_transport && (!IsInWorld() || !u->IsInWorld()))
+        return false;
+
+    // forbidden to seen (at GM respawn command)
+    if(u->GetVisibility() == VISIBILITY_RESPAWN)
+        return false;
+
+    // always seen by owner
+    if(GetGUID() == u->GetCharmerOrOwnerGUID())
+        return true;
+
+    // Grid dead/alive checks
+    // non visible at grid for any stealth state
+    if(!u->IsVisibleInGridForPlayer(this))
+        return false;
+
+    // If the player is currently possessing, update visibility from the possessed unit's location
+    const Unit* target = isPossessing() ? GetCharm() : this;
+
+    // different visible distance checks
+    if(isInFlight())                                     // what see player in flight
+    {
+        if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
+            return false;
+    }
+    else if(!u->isAlive())                                     // distance for show body
+    {
+        if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))
+            return false;
+    }
+    else if(u->GetTypeId()==TYPEID_PLAYER)                     // distance for show player
+    {
+        // Players far than max visible distance for player or not in our map are not visible too
+        if (!at_same_transport && !target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
+            return false;
+    }
+    else if(u->GetCharmerOrOwnerGUID())                        // distance for show pet/charmed
+    {
+        // Pet/charmed far than max visible distance for player or not in our map are not visible too
+        if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))
+            return false;
+    }
+    else                                                    // distance for show creature
+    {
+        // Units far than max visible distance for creature or not in our map are not visible too
+        if (!target->IsWithinDistInMap(u, target->isActive() 
+                ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance()))
+                : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))))
+            return false;
+    }
+
+    // GMs see any players, not higher GMs and all units
+    if(isGameMaster())
+    {
+        if(u->GetTypeId() == TYPEID_PLAYER)
+            return ((Player *)u)->GetSession()->GetSecurity() <= GetSession()->GetSecurity();
+        else
+            return true;
+    }
+
+    if(u->GetVisibility() == VISIBILITY_OFF)
+        return false;
+
+    // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting)
+    if((m_invisibilityMask || u->m_invisibilityMask) && !canDetectInvisibilityOf(u))
+        if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u))))
+            return false;
+
+    // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible
+    if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH)
+    {
+        // if player is dead then he can't detect anyone in anycases
+        //do not know what is the use of this detect
+        // stealth and detected and visible for some seconds
+        if(!isAlive())
+            detect = false;
+        if(m_DetectInvTimer < 300 || !HaveAtClient(u))
+            if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u))))
+                if(!detect || !canDetectStealthOf(u, GetDistance(u)))
+                    return false;
+    }
+
+    // Now check is target visible with LoS
+    return u->IsWithinLOS(GetPositionX(),GetPositionY(),GetPositionZ());
+}
+
+bool Player::IsVisibleInGridForPlayer( Player const * pl ) const
 {
     // gamemaster in GM mode see all, including ghosts
