rendered paste bodyIndex: 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;