mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 10:37:03 +00:00
[11206] Move visibility self/around to new function and use it.
* Fixed wrong visibility changes in some cases at .mod phase uses. * Apply phase change to any owned units (not only pets as before). It also will applied in more safe way for avoid unexpected lost owner at update. * Check view point setting auras targets accessability not only at visibility change but also at phase change. * Replace SetVisibility(GetVisibility()) hack like calls.
This commit is contained in:
parent
bef47ce126
commit
f1899e3b27
6 changed files with 64 additions and 50 deletions
|
|
@ -8057,45 +8057,44 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
|
|||
return IsWithinLOS(ox,oy,oz);
|
||||
}
|
||||
|
||||
void Unit::UpdateVisibilityAndView()
|
||||
{
|
||||
|
||||
static const AuraType auratypes[] = {SPELL_AURA_BIND_SIGHT, SPELL_AURA_FAR_SIGHT, SPELL_AURA_NONE};
|
||||
for (AuraType const* type = &auratypes[0]; *type != SPELL_AURA_NONE; ++type)
|
||||
{
|
||||
AuraList& alist = m_modAuras[*type];
|
||||
if(alist.empty())
|
||||
continue;
|
||||
|
||||
for (AuraList::iterator it = alist.begin(); it != alist.end();)
|
||||
{
|
||||
Aura* aura = (*it);
|
||||
Unit* owner = aura->GetCaster();
|
||||
|
||||
if (!owner || !isVisibleForOrDetect(owner,this,false))
|
||||
{
|
||||
alist.erase(it);
|
||||
RemoveAura(aura);
|
||||
it = alist.begin();
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
GetViewPoint().Call_UpdateVisibilityForOwner();
|
||||
UpdateObjectVisibility();
|
||||
ScheduleAINotify(0);
|
||||
GetViewPoint().Event_ViewPointVisibilityChanged();
|
||||
}
|
||||
|
||||
void Unit::SetVisibility(UnitVisibility x)
|
||||
{
|
||||
m_Visibility = x;
|
||||
|
||||
if(IsInWorld())
|
||||
{
|
||||
// some auras requires visible target
|
||||
if(m_Visibility == VISIBILITY_GROUP_NO_DETECT || m_Visibility == VISIBILITY_OFF)
|
||||
{
|
||||
static const AuraType auratypes[] = {SPELL_AURA_BIND_SIGHT, SPELL_AURA_FAR_SIGHT, SPELL_AURA_NONE};
|
||||
for (AuraType const* type = &auratypes[0]; *type != SPELL_AURA_NONE; ++type)
|
||||
{
|
||||
AuraList& alist = m_modAuras[*type];
|
||||
if(alist.empty())
|
||||
continue;
|
||||
|
||||
for (AuraList::iterator it = alist.begin(); it != alist.end();)
|
||||
{
|
||||
Aura* aura = (*it);
|
||||
Unit* owner = aura->GetCaster();
|
||||
|
||||
if (!owner || !isVisibleForOrDetect(owner,this,false))
|
||||
{
|
||||
alist.erase(it);
|
||||
RemoveAura(aura);
|
||||
it = alist.begin();
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetViewPoint().Call_UpdateVisibilityForOwner();
|
||||
UpdateObjectVisibility();
|
||||
ScheduleAINotify(0);
|
||||
|
||||
GetViewPoint().Event_ViewPointVisibilityChanged();
|
||||
}
|
||||
UpdateVisibilityAndView();
|
||||
}
|
||||
|
||||
bool Unit::canDetectInvisibilityOf(Unit const* u) const
|
||||
|
|
@ -10373,14 +10372,14 @@ void Unit::SetContestedPvP(Player *attackedPlayer)
|
|||
player->addUnitState(UNIT_STAT_ATTACK_PLAYER);
|
||||
player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP);
|
||||
// call MoveInLineOfSight for nearby contested guards
|
||||
SetVisibility(GetVisibility());
|
||||
UpdateVisibilityAndView();
|
||||
}
|
||||
|
||||
if (!hasUnitState(UNIT_STAT_ATTACK_PLAYER))
|
||||
{
|
||||
addUnitState(UNIT_STAT_ATTACK_PLAYER);
|
||||
// call MoveInLineOfSight for nearby contested guards
|
||||
SetVisibility(GetVisibility());
|
||||
UpdateVisibilityAndView();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -10469,19 +10468,30 @@ void Unit::RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId,
|
|||
}
|
||||
}
|
||||
|
||||
struct SetPhaseMaskHelper
|
||||
{
|
||||
explicit SetPhaseMaskHelper(uint32 _phaseMask) : phaseMask(_phaseMask) {}
|
||||
void operator()(Unit* unit) const { unit->SetPhaseMask(phaseMask, true); }
|
||||
uint32 phaseMask;
|
||||
};
|
||||
|
||||
void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||
{
|
||||
if(newPhaseMask==GetPhaseMask())
|
||||
if (newPhaseMask==GetPhaseMask())
|
||||
return;
|
||||
|
||||
if(IsInWorld())
|
||||
// first move to both phase for proper update controlled units
|
||||
WorldObject::SetPhaseMask(GetPhaseMask() | newPhaseMask, false);
|
||||
|
||||
if (IsInWorld())
|
||||
{
|
||||
RemoveNotOwnSingleTargetAuras(newPhaseMask); // we can lost access to caster or target
|
||||
|
||||
WorldObject::SetPhaseMask(newPhaseMask,update);
|
||||
// all controlled except not owned charmed units
|
||||
CallForAllControlledUnits(SetPhaseMaskHelper(newPhaseMask), CONTROLLED_PET|CONTROLLED_GUARDIANS|CONTROLLED_MINIPET|CONTROLLED_TOTEMS);
|
||||
}
|
||||
|
||||
if(IsInWorld())
|
||||
if(Pet* pet = GetPet())
|
||||
pet->SetPhaseMask(newPhaseMask,true);
|
||||
WorldObject::SetPhaseMask(newPhaseMask, update);
|
||||
}
|
||||
|
||||
void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool casting /*= false*/ )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue