[8422] Implement far sight like spells work for long distance.

* Added basic infrastructure for visibility update in case difference player and current view point.
  Just for note: seletect additional arg way beacuse repeatable search object will slow but store pointer will not safe,
  so use middle case: get view point pointer early as possible at visibility updates.
* Implement dynamic object and creature activisation while it's target of far sight spell effect
* Use this for SPELL_AURA_BIND_SIGHT, SPELL_AURA_FAR_SIGHT and SPELL_EFFECT_ADD_FARSIGHT.
* Note2: some spyglass like spells let look _around_ at long distance, this hard implement in current grid loading system
  Without additional changes and not implemented (you will see empty area without creatures in likes case)

* Also fixed warning spam at CMSG_MOVE_SET_CAN_FLY_ACK receive by use proper packet sructure reading.
This commit is contained in:
VladimirMangos 2009-08-26 08:18:30 +04:00
parent db1c9924a9
commit 45dd7140b5
28 changed files with 228 additions and 144 deletions

View file

@ -3193,21 +3193,11 @@ Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
return NULL;
}
bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
{
return IsWithinDistInMap(target, distance) && HasInArc( arc, target );
}
void Unit::SetInFront(Unit const* target)
{
SetOrientation(GetAngle(target));
}
bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
{
return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target );
}
bool Unit::isInAccessablePlaceFor(Creature const* c) const
{
if(IsInWater())
@ -9272,7 +9262,7 @@ int32 Unit::ModifyPower(Powers power, int32 dVal)
return gain;
}
bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is3dDistance) const
bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, bool detect, bool inVisibleList, bool is3dDistance) const
{
if(!u)
return false;
@ -9319,16 +9309,20 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
if(GetCharmerOrOwnerGUID()==u->GetGUID())
return true;
// always seen by far sight caster
if( u->GetTypeId()==TYPEID_PLAYER && ((Player*)u)->GetFarSight()==GetGUID())
return true;
// 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(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
return false;
}
else if(!isAlive()) // distance for show body
{
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), is3dDistance))
return false;
}
else if(GetTypeId()==TYPEID_PLAYER) // distance for show player
@ -9336,26 +9330,26 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
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(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
if (!at_same_transport && !IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false;
}
else
{
// Units far than max visible distance for creature or not in our map are not visible too
if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
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(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
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(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false;
}
@ -9463,7 +9457,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
float visibleDistance = (u->GetTypeId() == TYPEID_PLAYER) ? MAX_PLAYER_STEALTH_DETECT_RANGE : ((Creature const*)u)->GetAttackDistance(this);
//Always invisible from back (when stealth detection is on), also filter max distance cases
bool isInFront = u->isInFrontInMap(this, visibleDistance);
bool isInFront = viewPoint->isInFrontInMap(this, visibleDistance);
if(!isInFront)
return false;
@ -9490,13 +9484,13 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
visibleDistance = visibleDistance > MAX_PLAYER_STEALTH_DETECT_RANGE ? MAX_PLAYER_STEALTH_DETECT_RANGE : visibleDistance;
// recheck new distance
if(visibleDistance <= 0 || !IsWithinDist(u,visibleDistance))
if(visibleDistance <= 0 || !IsWithinDist(viewPoint,visibleDistance))
return false;
}
// Now check is target visible with LoS
float ox,oy,oz;
u->GetPosition(ox,oy,oz);
viewPoint->GetPosition(ox,oy,oz);
return IsWithinLOS(ox,oy,oz);
}
@ -10203,9 +10197,9 @@ Unit* Unit::GetUnit(WorldObject& object, uint64 guid)
return ObjectAccessor::GetUnit(object,guid);
}
bool Unit::isVisibleForInState( Player const* u, bool inVisibleList ) const
bool Unit::isVisibleForInState( Player const* u, WorldObject const* viewPoint, bool inVisibleList ) const
{
return isVisibleForOrDetect(u, false, inVisibleList, false);
return isVisibleForOrDetect(u, viewPoint, false, inVisibleList, false);
}
uint32 Unit::GetCreatureType() const