All pastes #736937 Raw Edit

Stuff

public text v1 · immutable
·published 2007-10-14 23:04 UTC
rendered paste body
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp	(revision 4601)
+++ src/game/SpellAuras.cpp	(working copy)
@@ -2303,7 +2303,7 @@
 {
     if(Apply)
     {
-        m_target->m_invisibilityvalue = m_modifier.m_amount;
+        m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
 
         // drop flag at invisible in bg
         if(Real && m_target->GetTypeId()==TYPEID_PLAYER && ((Player*)m_target)->InBattleGround())
@@ -2325,11 +2325,20 @@
     }
     else
     {
-        m_target->m_invisibilityvalue = 0;
-        //m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_CREEP );
+        // recalculate value at modifier remove (current aura already removed)
+        m_target->m_invisibilityMask &= ~(1 << m_modifier.m_miscvalue);
+        Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
+        for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+        {
+            if((*itr)->GetModifier()->m_miscvalue==m_modifier.m_miscvalue)
+            {
+                m_target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue);
+                break;
+            }
+        }
 
-        // only at real aura remove
-        if(Real)
+        // only at real aura remove and if not have different invisibility auras.
+        if(Real && m_target->m_invisibilityMask==0)
         {
             // apply only if not in GM invisibility
             if(m_target->GetVisibility()!=VISIBILITY_OFF)
@@ -2346,11 +2355,21 @@
 {
     if(Apply)
     {
-        m_target->m_detectInvisibility = m_modifier.m_amount;
+        m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
     }
     else
     {
-        m_target->m_detectInvisibility = 0;
+        // recalculate value at modifier remove (current aura already removed)
+        m_target->m_detectInvisibilityMask &= ~(1 << m_modifier.m_miscvalue);
+        Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
+        for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+        {
+            if((*itr)->GetModifier()->m_miscvalue==m_modifier.m_miscvalue)
+            {
+                m_target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
+                break;
+            }
+        }
     }
 
     if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp	(revision 4601)
+++ src/game/SpellEffects.cpp	(working copy)
@@ -1087,6 +1087,7 @@
             case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
             case SPELL_AURA_EMPATHY:
             case SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS:
+            case SPELL_AURA_MOD_INVISIBILITY_DETECTION:
                 break;
             case SPELL_AURA_MOD_STUN:
                 //I'm not sure, if all STUN-Auras prevent attack, therefore the query
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp	(revision 4601)
+++ src/game/Unit.cpp	(working copy)
@@ -144,9 +144,9 @@
     m_Visibility = VISIBILITY_ON;
 
     m_detectStealth = 0;
-    m_detectInvisibility = 0;
+    m_detectInvisibilityMask = 0;
     m_stealthvalue = 0;
-    m_invisibilityvalue = 0;
+    m_invisibilityMask = 0;
     m_transform = 0;
     m_ShapeShiftForm = 0;
     m_canModifyStats = false;
@@ -5773,18 +5773,62 @@
     if (m_Visibility == VISIBILITY_OFF)
         return false;
 
-    // Invisible units, always are visible for units under invisibility or unit that can detect this invisibility
-    if (m_Visibility == VISIBILITY_GROUP_INVISIBILITY)
+    // Invisible units, always are visible for units under same invisibility type
+    if(m_invisibilityMask & u->m_invisibilityMask)
+        return true;
+        
+    // Invisible units, always are visible for unit that can detect this invisibility (have appropriate level for detect)
+    if(uint32 mask = (m_invisibilityMask & u->m_detectInvisibilityMask))
     {
-        if(u->GetVisibility()== VISIBILITY_GROUP_INVISIBILITY || m_invisibilityvalue <= u->m_detectInvisibility)
-            return true;
+        for(uint32 i = 0; i < 10; ++i)
+        {
+            if(((1 << i) & mask)==0)
+                continue;
+
+            // find invisibility level
+            uint32 invLevel = 0;
+            Unit::AuraList const& iAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
+            for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
+                if(((*itr)->GetModifier()->m_miscvalue)==i && invLevel < (*itr)->GetModifier()->m_amount)
+                    invLevel = (*itr)->GetModifier()->m_amount;
+
+            // find invisibility detect level
+            uint32 detectLevel = 0;
+            Unit::AuraList const& dAuras = u->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(invLevel <= detectLevel)
+                return true;
+        }
     }
 
     // Units that can detect invisibility always are visible for units that can be detected
-    if (u->GetVisibility()== VISIBILITY_GROUP_INVISIBILITY)
+    if(uint32 mask = (m_detectInvisibilityMask & u->m_invisibilityMask))
     {
-        if(m_detectInvisibility >= u->m_invisibilityvalue)
-            return true;
+        for(uint32 i = 0; i < 10; ++i)
+        {
+            if(((1 << i) & mask)==0)
+                continue;
+
+            // find invisibility level
+            uint32 invLevel = 0;
+            Unit::AuraList const& iAuras = u->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
+            for(Unit::AuraList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
+                if(((*itr)->GetModifier()->m_miscvalue)==i && invLevel < (*itr)->GetModifier()->m_amount)
+                    invLevel = (*itr)->GetModifier()->m_amount;
+
+            // 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(invLevel <= detectLevel)
+                return true;
+        }
     }
 
     // Stealth/invisible not hostile units, not visible (except Player-with-Player case)
Index: src/game/Unit.h
===================================================================
--- src/game/Unit.h	(revision 4601)
+++ src/game/Unit.h	(working copy)
@@ -1034,9 +1034,9 @@
         uint64 m_TotemSlot[4];
         uint64 m_ObjectSlot[4];
         uint32 m_detectStealth;
-        uint32 m_detectInvisibility;
+        uint32 m_detectInvisibilityMask;
         uint32 m_stealthvalue;
-        uint32 m_invisibilityvalue;
+        uint32 m_invisibilityMask;
         uint32 m_ShapeShiftForm;
         uint32 m_form;
         int32 m_modHitChance;