mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[8229] Improve stealth detection code for player case.
Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
parent
c4ceafcf56
commit
fc7871f0a2
5 changed files with 44 additions and 45 deletions
|
|
@ -1274,8 +1274,8 @@ void Player::Update( uint32 p_time )
|
||||||
{
|
{
|
||||||
if (p_time >= m_DetectInvTimer)
|
if (p_time >= m_DetectInvTimer)
|
||||||
{
|
{
|
||||||
m_DetectInvTimer = 3000;
|
|
||||||
HandleStealthedUnitsDetection();
|
HandleStealthedUnitsDetection();
|
||||||
|
m_DetectInvTimer = 3000;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_DetectInvTimer -= p_time;
|
m_DetectInvTimer -= p_time;
|
||||||
|
|
@ -16876,35 +16876,40 @@ void Player::HandleStealthedUnitsDetection()
|
||||||
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
|
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
|
||||||
cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap());
|
cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap());
|
||||||
|
|
||||||
for (std::list<Unit*>::iterator i = stealthedUnits.begin(); i != stealthedUnits.end();)
|
for (std::list<Unit*>::const_iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i)
|
||||||
{
|
{
|
||||||
if((*i)==this)
|
if((*i)==this)
|
||||||
{
|
|
||||||
i = stealthedUnits.erase(i);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if ((*i)->isVisibleForOrDetect(this,true))
|
bool hasAtClient = HaveAtClient((*i));
|
||||||
|
bool hasDetected = (*i)->isVisibleForOrDetect(this, true);
|
||||||
|
|
||||||
|
if (hasDetected)
|
||||||
{
|
{
|
||||||
|
if(!hasAtClient)
|
||||||
|
{
|
||||||
|
(*i)->SendUpdateToPlayer(this);
|
||||||
|
m_clientGUIDs.insert((*i)->GetGUID());
|
||||||
|
|
||||||
(*i)->SendUpdateToPlayer(this);
|
#ifdef MANGOS_DEBUG
|
||||||
m_clientGUIDs.insert((*i)->GetGUID());
|
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
|
||||||
|
sLog.outDebug("Object %u (Type: %u) is detected in stealth by player %u. Distance = %f",(*i)->GetGUIDLow(),(*i)->GetTypeId(),GetGUIDLow(),GetDistance(*i));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MANGOS_DEBUG
|
// target aura duration for caster show only if target exist at caster client
|
||||||
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
|
// send data at target visibility change (adding to client)
|
||||||
sLog.outDebug("Object %u (Type: %u) is detected in stealth by player %u. Distance = %f",(*i)->GetGUIDLow(),(*i)->GetTypeId(),GetGUIDLow(),GetDistance(*i));
|
if((*i)!=this && (*i)->isType(TYPEMASK_UNIT))
|
||||||
#endif
|
SendAurasForTarget(*i);
|
||||||
|
}
|
||||||
// target aura duration for caster show only if target exist at caster client
|
}
|
||||||
// send data at target visibility change (adding to client)
|
else
|
||||||
if((*i)!=this && (*i)->isType(TYPEMASK_UNIT))
|
{
|
||||||
SendAurasForTarget(*i);
|
if(hasAtClient)
|
||||||
|
{
|
||||||
i = stealthedUnits.erase(i);
|
(*i)->DestroyForPlayer(this);
|
||||||
continue;
|
m_clientGUIDs.erase((*i)->GetGUID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2101,7 +2101,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
|
void UpdateVisibilityOf(T* target, UpdateData& data, UpdateDataMapType& data_updates, std::set<WorldObject*>& visibleNow);
|
||||||
|
|
||||||
// Stealth detection system
|
// Stealth detection system
|
||||||
uint32 m_DetectInvTimer;
|
|
||||||
void HandleStealthedUnitsDetection();
|
void HandleStealthedUnitsDetection();
|
||||||
|
|
||||||
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
|
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
|
||||||
|
|
@ -2455,6 +2454,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
bool m_bCanDelayTeleport;
|
bool m_bCanDelayTeleport;
|
||||||
bool m_bHasDelayedTeleport;
|
bool m_bHasDelayedTeleport;
|
||||||
|
|
||||||
|
uint32 m_DetectInvTimer;
|
||||||
|
|
||||||
// Temporary removed pet cache
|
// Temporary removed pet cache
|
||||||
uint32 m_temporaryUnsummonedPetNumber;
|
uint32 m_temporaryUnsummonedPetNumber;
|
||||||
uint32 m_oldpetspell;
|
uint32 m_oldpetspell;
|
||||||
|
|
|
||||||
|
|
@ -9232,13 +9232,11 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
|
||||||
|
|
||||||
// NOW ONLY STEALTH CASE
|
// NOW ONLY STEALTH CASE
|
||||||
|
|
||||||
// stealth and detected and visible for some seconds
|
|
||||||
if (u->GetTypeId() == TYPEID_PLAYER && ((Player*)u)->m_DetectInvTimer > 300 && ((Player*)u)->HaveAtClient(this))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
//if in non-detect mode then invisible for unit
|
//if in non-detect mode then invisible for unit
|
||||||
|
//mobs always detect players (detect == true)... return 'false' for those mobs which have (detect == false)
|
||||||
|
//players detect players only in Player::HandleStealthedUnitsDetection()
|
||||||
if (!detect)
|
if (!detect)
|
||||||
return false;
|
return (u->GetTypeId() == TYPEID_PLAYER) ? ((Player*)u)->HaveAtClient(this) : false;
|
||||||
|
|
||||||
// Special cases
|
// Special cases
|
||||||
|
|
||||||
|
|
@ -9254,21 +9252,13 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
|
||||||
if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this))
|
if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Creature can detect target only in aggro radius
|
// set max ditance
|
||||||
if(u->GetTypeId() != TYPEID_PLAYER)
|
float visibleDistance = (u->GetTypeId() == TYPEID_PLAYER) ? MAX_PLAYER_STEALTH_DETECT_RANGE : ((Creature const*)u)->GetAttackDistance(this);
|
||||||
{
|
|
||||||
//Always invisible from back and out of aggro range
|
//Always invisible from back (when stealth detection is on), also filter max distance cases
|
||||||
bool isInFront = u->isInFrontInMap(this,((Creature const*)u)->GetAttackDistance(this));
|
bool isInFront = u->isInFrontInMap(this, visibleDistance);
|
||||||
if(!isInFront)
|
if(!isInFront)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Always invisible from back
|
|
||||||
bool isInFront = u->isInFrontInMap(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature());
|
|
||||||
if(!isInFront)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if doesn't have stealth detection (Shadow Sight), then check how stealthy the unit is, otherwise just check los
|
// if doesn't have stealth detection (Shadow Sight), then check how stealthy the unit is, otherwise just check los
|
||||||
if(!u->HasAuraType(SPELL_AURA_DETECT_STEALTH))
|
if(!u->HasAuraType(SPELL_AURA_DETECT_STEALTH))
|
||||||
|
|
@ -9276,7 +9266,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
|
||||||
//Calculation if target is in front
|
//Calculation if target is in front
|
||||||
|
|
||||||
//Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5)
|
//Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5)
|
||||||
float visibleDistance = 10.5f - (GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/100.0f);
|
visibleDistance = 10.5f - (GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/100.0f);
|
||||||
|
|
||||||
//Visible distance is modified by
|
//Visible distance is modified by
|
||||||
//-Level Diff (every level diff = 1.0f in visible distance)
|
//-Level Diff (every level diff = 1.0f in visible distance)
|
||||||
|
|
@ -9290,7 +9280,9 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
|
||||||
//-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia)
|
//-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia)
|
||||||
//based on wowwiki every 5 mod we have 1 more level diff in calculation
|
//based on wowwiki every 5 mod we have 1 more level diff in calculation
|
||||||
visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f;
|
visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f;
|
||||||
|
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(u,visibleDistance))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -851,6 +851,7 @@ typedef std::set<uint64> GuardianPetList;
|
||||||
|
|
||||||
// delay time next attack to prevent client attack animation problems
|
// delay time next attack to prevent client attack animation problems
|
||||||
#define ATTACK_DISPLAY_DELAY 200
|
#define ATTACK_DISPLAY_DELAY 200
|
||||||
|
#define MAX_PLAYER_STEALTH_DETECT_RANGE 45.0f // max distance for detection targets by player
|
||||||
|
|
||||||
struct SpellProcEventEntry; // used only privately
|
struct SpellProcEventEntry; // used only privately
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8228"
|
#define REVISION_NR "8229"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue