- Redesigned stealth and invisibility handling
  - Implemented the handling of multiple stealth types
- Implemented fake inebriation
- The message deliverer no longer sends packets from a non-visible source
  - The server won't send that much garbage which just takes bandwith
  - It won't be possible to use cheats to detect invisible objects
- Removed a lot of checks for the Z-coord
  - Fixes visibility problems happening while flying
- Limited the grid activation range of creatures to use less resources
- Implemented Shroud of Death
- Implemented increased visibility range for active objects
- Removed visibility check at spellhit (only sanctuary effects should prevent it)
(And a lot of other changes...)

Closes issue 4208
Closes issue 3049
Closes issue 2097
Closes issue 2198
Closes issue 2384
Closes issue 2197
Closes issue 2319

--HG--
branch : trunk
This commit is contained in:
linencloth
2010-11-13 17:18:09 +01:00
parent 995408f0a9
commit bf888285aa
36 changed files with 780 additions and 791 deletions
+140 -45
View File
@@ -69,9 +69,9 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&AuraEffect::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
&AuraEffect::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
&AuraEffect::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_DETECT implement in GameObject::canDetectTrap and Unit::canDetectStealthOf
&AuraEffect::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
&AuraEffect::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
&AuraEffect::HandleModStealthDetect, // 17 SPELL_AURA_MOD_DETECT
&AuraEffect::HandleModInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
&AuraEffect::HandleModInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
&AuraEffect::HandleNoImmediateEffect, // 20 SPELL_AURA_OBS_MOD_HEALTH implemented in AuraEffect::PeriodicTick
&AuraEffect::HandleNoImmediateEffect, // 21 SPELL_AURA_OBS_MOD_POWER implemented in AuraEffect::PeriodicTick
&AuraEffect::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
@@ -206,7 +206,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
&AuraEffect::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
&AuraEffect::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
&AuraEffect::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
&AuraEffect::HandleModStealthLevel, //154 SPELL_AURA_MOD_STEALTH_LEVEL
&AuraEffect::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
&AuraEffect::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
&AuraEffect::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
@@ -356,7 +356,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoImmediateEffect, //301 SPELL_AURA_SCHOOL_HEAL_ABSORB implemented in Unit::CalcHealAbsorb
&AuraEffect::HandleNULL, //302 0 spells in 3.3.5
&AuraEffect::HandleNoImmediateEffect, //303 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
&AuraEffect::HandleUnused, //304 clientside
&AuraEffect::HandleAuraModFakeInebriation, //304 SPELL_AURA_MOD_DRUNK
&AuraEffect::HandleAuraModIncreaseSpeed, //305 SPELL_AURA_MOD_MINIMUM_SPEED
&AuraEffect::HandleNULL, //306 0 spells in 3.3.5
&AuraEffect::HandleNULL, //307 0 spells in 3.3.5
@@ -2685,40 +2685,40 @@ void AuraEffect::HandleShapeshiftBoosts(Unit * target, bool apply) const
/*** VISIBILITY & PHASES ***/
/**************************************/
void AuraEffect::HandleInvisibilityDetect(AuraApplication const * aurApp, uint8 mode, bool apply) const
void AuraEffect::HandleModInvisibilityDetect(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
if (!(mode & AURA_EFFECT_HANDLE_REAL))
return;
Unit * target = aurApp->GetTarget();
InvisibilityType type = InvisibilityType(GetMiscValue());
if (apply)
{
target->m_detectInvisibilityMask |= (1 << GetMiscValue());
target->m_invisibilityDetect.AddFlag(type);
target->m_invisibilityDetect.AddValue(type, GetAmount());
}
else
{
// recalculate value at modifier remove (current aura already removed)
target->m_detectInvisibilityMask = 0;
Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
target->m_detectInvisibilityMask |= (1 << GetMiscValue());
if (!target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY_DETECT))
target->m_invisibilityDetect.DelFlag(type);
target->m_invisibilityDetect.AddValue(type, -GetAmount());
}
if (target->GetTypeId() == TYPEID_PLAYER)
target->UpdateObjectVisibility();
target->UpdateObjectVisibility();
}
void AuraEffect::HandleInvisibility(AuraApplication const * aurApp, uint8 mode, bool apply) const
void AuraEffect::HandleModInvisibility(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
if (!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
return;
Unit * target = aurApp->GetTarget();
InvisibilityType type = InvisibilityType(GetMiscValue());
if (apply)
{
target->m_invisibilityMask |= (1 << GetMiscValue());
if (mode & AURA_EFFECT_HANDLE_REAL)
{
// drop flag at invisibiliy in bg
@@ -2729,23 +2729,49 @@ void AuraEffect::HandleInvisibility(AuraApplication const * aurApp, uint8 mode,
if (target->GetTypeId() == TYPEID_PLAYER)
target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
target->UpdateObjectVisibility();
target->m_invisibility.AddFlag(type);
target->m_invisibility.AddValue(type, GetAmount());
}
else
{
// recalculate value at modifier remove (current aura already removed)
target->m_invisibilityMask = 0;
Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(SPELL_AURA_MOD_INVISIBILITY);
for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
target->m_invisibilityMask |= (1 << GetMiscValue());
if (!target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY))
{
// if not have different invisibility auras.
// remove glow vision
if (target->GetTypeId() == TYPEID_PLAYER)
target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
// if not have different invisibility auras.
// remove glow vision
if (!target->m_invisibilityMask && target->GetTypeId() == TYPEID_PLAYER)
target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
target->m_invisibility.DelFlag(type);
}
target->UpdateObjectVisibility();
target->m_invisibility.AddValue(type, -GetAmount());
}
target->UpdateObjectVisibility();
}
void AuraEffect::HandleModStealthDetect(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
if (!(mode & AURA_EFFECT_HANDLE_REAL))
return;
Unit * target = aurApp->GetTarget();
StealthType type = StealthType(GetMiscValue());
if (apply)
{
target->m_stealthDetect.AddFlag(type);
target->m_stealthDetect.AddValue(type, GetAmount());
}
else
{
if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH_DETECT))
target->m_stealthDetect.DelFlag(type);
target->m_stealthDetect.AddValue(type, -GetAmount());
}
target->UpdateObjectVisibility();
}
void AuraEffect::HandleModStealth(AuraApplication const * aurApp, uint8 mode, bool apply) const
@@ -2754,6 +2780,7 @@ void AuraEffect::HandleModStealth(AuraApplication const * aurApp, uint8 mode, bo
return;
Unit * target = aurApp->GetTarget();
StealthType type = StealthType(GetMiscValue());
if (apply)
{
@@ -2763,23 +2790,44 @@ void AuraEffect::HandleModStealth(AuraApplication const * aurApp, uint8 mode, bo
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
}
target->m_stealth.AddFlag( type);
target->m_stealth.AddValue(type, GetAmount());
target->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
if (target->GetTypeId() == TYPEID_PLAYER)
target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
// apply only if not in GM invisibility (and overwrite invisibility state)
if (target->GetVisibility() != VISIBILITY_OFF)
target->SetVisibility(VISIBILITY_GROUP_STEALTH);
}
else if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH
else
{
target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
if (target->GetTypeId() == TYPEID_PLAYER)
target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
target->m_stealth.AddValue(type, -GetAmount());
if (target->GetVisibility() != VISIBILITY_OFF)
target->SetVisibility(VISIBILITY_ON);
if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH
{
target->m_stealth.DelFlag(type);
target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
if (target->GetTypeId() == TYPEID_PLAYER)
target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
}
}
target->UpdateObjectVisibility();
}
void AuraEffect::HandleModStealthLevel(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
if (!(mode & AURA_EFFECT_HANDLE_REAL))
return;
Unit * target = aurApp->GetTarget();
StealthType type = StealthType(GetMiscValue());
if (apply)
target->m_stealth.AddValue(type, GetAmount());
else
target->m_stealth.AddValue(type, -GetAmount());
target->UpdateObjectVisibility();
}
void AuraEffect::HandleSpiritOfRedemption(AuraApplication const * aurApp, uint8 mode, bool apply) const
@@ -2823,12 +2871,19 @@ void AuraEffect::HandleAuraGhost(AuraApplication const * aurApp, uint8 mode, boo
return;
if (apply)
{
target->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
target->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
target->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
}
else
{
if (target->HasAuraType(SPELL_AURA_GHOST))
return;
target->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
target->m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
target->m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
}
}
@@ -3315,9 +3370,9 @@ void AuraEffect::HandleFeignDeath(AuraApplication const * aurApp, uint8 mode, bo
*/
UnitList targets;
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(target, target, target->GetMap()->GetVisibilityDistance());
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(target, target, target->GetMap()->GetVisibilityRange());
Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(target, targets, u_check);
target->VisitNearbyObject(target->GetMap()->GetVisibilityDistance(), searcher);
target->VisitNearbyObject(target->GetMap()->GetVisibilityRange(), searcher);
for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
if (!(*iter)->hasUnitState(UNIT_STAT_CASTING))
@@ -3601,11 +3656,11 @@ void AuraEffect::HandleAuraModStalked(AuraApplication const * aurApp, uint8 mode
else
{
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if (target->HasAuraType(GetAuraType()))
return;
target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
if (!target->HasAuraType(GetAuraType()))
target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
}
target->UpdateObjectVisibility();
}
void AuraEffect::HandleAuraUntrackable(AuraApplication const * aurApp, uint8 mode, bool apply) const
@@ -4022,7 +4077,7 @@ void AuraEffect::HandleModPossessPet(AuraApplication const * aurApp, uint8 mode,
{
pet->RemoveCharmedBy(caster);
if (!pet->IsWithinDistInMap(caster, pet->GetMap()->GetVisibilityDistance()))
if (!pet->IsWithinDistInMap(caster, pet->GetMap()->GetVisibilityRange()))
pet->Remove(PET_SAVE_NOT_IN_SLOT, true);
else
{
@@ -6349,6 +6404,46 @@ void AuraEffect::HandleAuraOpenStable(AuraApplication const * aurApp, uint8 mode
// client auto close stable dialog at !apply aura
}
void AuraEffect::HandleAuraModFakeInebriation(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
if (!(mode & AURA_EFFECT_HANDLE_REAL))
return;
Unit* target = aurApp->GetTarget();
if (apply)
{
target->m_invisibilityDetect.AddFlag( INVISIBILITY_DRUNK);
target->m_invisibilityDetect.AddValue(INVISIBILITY_DRUNK, GetAmount());
if (target->GetTypeId() == TYPEID_PLAYER)
{
int32 oldval = target->ToPlayer()->GetInt32Value(PLAYER_FAKE_INEBRIATION);
target->ToPlayer()->SetInt32Value(PLAYER_FAKE_INEBRIATION, oldval + GetAmount());
}
}
else
{
bool removeDetect = !target->HasAuraType(SPELL_AURA_MOD_FAKE_INEBRIATE);
target->m_invisibilityDetect.AddValue(INVISIBILITY_DRUNK, -GetAmount());
if (target->GetTypeId() == TYPEID_PLAYER)
{
int32 oldval = target->ToPlayer()->GetInt32Value(PLAYER_FAKE_INEBRIATION);
target->ToPlayer()->SetInt32Value(PLAYER_FAKE_INEBRIATION, oldval - GetAmount());
if (removeDetect)
removeDetect = !target->ToPlayer()->GetDrunkValue();
}
if (removeDetect)
target->m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK);
}
target->UpdateObjectVisibility();
}
void AuraEffect::HandleAuraSetVehicle(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
if (!(mode & AURA_EFFECT_HANDLE_REAL))