Changeset 178 for trunk/src/game

Show
Ignore:
Timestamp:
11/19/08 13:43:40 (17 years ago)
Author:
yumileroy
Message:

[svn] Rewrite canSeeOrDetect function.
Minor change on trigger creatures.
Remove some unused hacks in scripts.

Original author: megamage
Date: 2008-11-06 10:27:58-06:00

Location:
trunk/src/game
Files:
10 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/game/Creature.cpp

    r174 r178  
    319319    m_spells[2] = GetCreatureInfo()->spell3; 
    320320    m_spells[3] = GetCreatureInfo()->spell4; 
     321 
     322    // HACK: trigger creature is always not selectable 
     323    if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) 
     324        SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    321325 
    322326    return true; 
     
    14881492} 
    14891493 
     1494bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const 
     1495{ 
     1496    // not in world 
     1497    if(!IsInWorld() || !u->IsInWorld()) 
     1498        return false; 
     1499 
     1500    // all dead creatures/players not visible for any creatures 
     1501    if(!u->isAlive() || !isAlive()) 
     1502        return false; 
     1503 
     1504    // Always can see self 
     1505    if (u == this) 
     1506        return true; 
     1507 
     1508    // always seen by owner 
     1509    if(GetGUID() == u->GetCharmerOrOwnerGUID()) 
     1510        return true; 
     1511 
     1512    if(u->GetVisibility() == VISIBILITY_OFF) //GM 
     1513        return false; 
     1514 
     1515    // invisible aura 
     1516    if((m_invisibilityMask || u->m_invisibilityMask) && !canDetectInvisibilityOf(u)) 
     1517        return false; 
     1518 
     1519    // unit got in stealth in this moment and must ignore old detected state 
     1520    //if (m_Visibility == VISIBILITY_GROUP_NO_DETECT) 
     1521    //    return false; 
     1522 
     1523    // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible 
     1524    if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH) 
     1525    { 
     1526        //do not know what is the use of this detect 
     1527        if(!detect || !canDetectStealthOf(u, GetDistance(u))) 
     1528            return false; 
     1529    } 
     1530 
     1531    // Now check is target visible with LoS 
     1532    return u->IsWithinLOS(GetPositionX(),GetPositionY(),GetPositionZ()); 
     1533} 
     1534 
    14901535float Creature::GetAttackDistance(Unit const* pl) const 
    14911536{ 
     
    16991744} 
    17001745 
    1701 bool Creature::IsVisibleInGridForPlayer(Player* pl) const 
     1746bool Creature::IsVisibleInGridForPlayer(Player const* pl) const 
    17021747{ 
    17031748    // gamemaster in GM mode see all, including ghosts 
  • trunk/src/game/Creature.h

    r174 r178  
    548548        uint32 m_GlobalCooldown; 
    549549 
     550        bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; 
    550551        float GetAttackDistance(Unit const* pl) const; 
    551552 
     
    561562        void SetCurrentCell(Cell const& cell) { m_currentCell = cell; } 
    562563 
    563         bool IsVisibleInGridForPlayer(Player* pl) const; 
     564        bool IsVisibleInGridForPlayer(Player const* pl) const; 
    564565 
    565566        void RemoveCorpse(); 
  • trunk/src/game/Object.cpp

    r174 r178  
    14871487        if(GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) 
    14881488            pCreature->setFaction(((Unit*)this)->getFaction()); 
    1489         pCreature->CastSpell(pCreature, pCreature->m_spells[0], true, 0, 0, GetGUID()); 
     1489        pCreature->CastSpell(pCreature, pCreature->m_spells[0], false, 0, 0, GetGUID()); 
    14901490    } 
    14911491 
  • trunk/src/game/OutdoorPvPObjectiveAI.cpp

    r102 r178  
    5151void OutdoorPvPObjectiveAI::AttackStart(Unit *) 
    5252{ 
    53     EnterEvadeMode(); 
     53    //EnterEvadeMode(); 
    5454} 
    5555 
    5656void OutdoorPvPObjectiveAI::EnterEvadeMode() 
    5757{ 
    58     i_creature.DeleteThreatList(); 
    59     i_creature.CombatStop(); 
     58//    i_creature.DeleteThreatList(); 
     59//    i_creature.CombatStop(); 
    6060} 
    6161 
  • trunk/src/game/Player.cpp

    r177 r178  
    20012001        if(HasAuraType(SPELL_AURA_MOD_STEALTH)) 
    20022002            SetVisibility(VISIBILITY_GROUP_STEALTH); 
    2003         else if(HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) 
    2004             SetVisibility(VISIBILITY_GROUP_INVISIBILITY); 
     2003        //else if(HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) 
     2004        //    SetVisibility(VISIBILITY_GROUP_INVISIBILITY); 
    20052005        else 
    20062006            SetVisibility(VISIBILITY_ON); 
     
    1639616396        if ((*i)->isVisibleForOrDetect(this,true)) 
    1639716397        { 
    16398  
    1639916398            (*i)->SendUpdateToPlayer(this); 
    1640016399            m_clientGUIDs.insert((*i)->GetGUID()); 
     
    1718917188} 
    1719017189 
    17191 bool Player::IsVisibleInGridForPlayer( Player* pl ) const 
     17190bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const 
     17191{ 
     17192    // Always can see self 
     17193    if (u == this) 
     17194        return true; 
     17195 
     17196    // player visible for other player if not logout and at same transport 
     17197    // including case when player is out of world 
     17198    bool at_same_transport = 
     17199        GetTransport() && u->GetTypeId() == TYPEID_PLAYER 
     17200        && !GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout() 
     17201        && !GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading() 
     17202        && GetTransport() == ((Player*)u)->GetTransport(); 
     17203 
     17204    // not in world 
     17205    if(!at_same_transport && (!IsInWorld() || !u->IsInWorld())) 
     17206        return false; 
     17207 
     17208    // forbidden to seen (at GM respawn command) 
     17209    if(u->GetVisibility() == VISIBILITY_RESPAWN) 
     17210        return false; 
     17211 
     17212    // always seen by owner 
     17213    if(GetGUID() == u->GetCharmerOrOwnerGUID()) 
     17214        return true; 
     17215 
     17216    // Grid dead/alive checks 
     17217    // non visible at grid for any stealth state 
     17218    if(!u->IsVisibleInGridForPlayer(this)) 
     17219        return false; 
     17220 
     17221    // If the player is currently possessing, update visibility from the possessed unit's location 
     17222    const Unit* target = isPossessing() ? GetCharm() : this; 
     17223 
     17224    // different visible distance checks 
     17225    if(isInFlight())                                     // what see player in flight 
     17226    { 
     17227        if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 
     17228            return false; 
     17229    } 
     17230    else if(!u->isAlive())                                     // distance for show body 
     17231    { 
     17232        if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 
     17233            return false; 
     17234    } 
     17235    else if(u->GetTypeId()==TYPEID_PLAYER)                     // distance for show player 
     17236    { 
     17237        // Players far than max visible distance for player or not in our map are not visible too 
     17238        if (!at_same_transport && !target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
     17239            return false; 
     17240    } 
     17241    else if(u->GetCharmerOrOwnerGUID())                        // distance for show pet/charmed 
     17242    { 
     17243        // Pet/charmed far than max visible distance for player or not in our map are not visible too 
     17244        if (!target->IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
     17245            return false; 
     17246    } 
     17247    else                                                    // distance for show creature 
     17248    { 
     17249        // Units far than max visible distance for creature or not in our map are not visible too 
     17250        if (!target->IsWithinDistInMap(u, target->isActive()  
     17251                ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance())) 
     17252                : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))) 
     17253            return false; 
     17254    } 
     17255 
     17256    // GMs see any players, not higher GMs and all units 
     17257    if(isGameMaster()) 
     17258    { 
     17259        if(u->GetTypeId() == TYPEID_PLAYER) 
     17260            return ((Player *)u)->GetSession()->GetSecurity() <= GetSession()->GetSecurity(); 
     17261        else 
     17262            return true; 
     17263    } 
     17264 
     17265    if(u->GetVisibility() == VISIBILITY_OFF) 
     17266        return false; 
     17267 
     17268    // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting) 
     17269    if((m_invisibilityMask || u->m_invisibilityMask) && !canDetectInvisibilityOf(u)) 
     17270        if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u)))) 
     17271            return false; 
     17272 
     17273    // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible 
     17274    if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH) 
     17275    { 
     17276        // if player is dead then he can't detect anyone in anycases 
     17277        //do not know what is the use of this detect 
     17278        // stealth and detected and visible for some seconds 
     17279        if(!isAlive()) 
     17280            detect = false; 
     17281        if(m_DetectInvTimer < 300 || !HaveAtClient(u)) 
     17282            if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u)))) 
     17283                if(!detect || !canDetectStealthOf(u, GetDistance(u))) 
     17284                    return false; 
     17285    } 
     17286 
     17287    // Now check is target visible with LoS 
     17288    return u->IsWithinLOS(GetPositionX(),GetPositionY(),GetPositionZ()); 
     17289} 
     17290 
     17291bool Player::IsVisibleInGridForPlayer( Player const * pl ) const 
    1719217292{ 
    1719317293    // gamemaster in GM mode see all, including ghosts 
  • trunk/src/game/Player.h

    r177 r178  
    19931993        ClientGUIDs m_clientGUIDs; 
    19941994 
    1995         bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); } 
    1996  
    1997         bool IsVisibleInGridForPlayer(Player* pl) const; 
     1995        bool HaveAtClient(WorldObject const* u) const { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); } 
     1996 
     1997        bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; 
     1998        bool IsVisibleInGridForPlayer(Player const* pl) const; 
    19981999        bool IsVisibleGloballyFor(Player* pl) const; 
    19992000 
  • trunk/src/game/SpellAuras.cpp

    r174 r178  
    32313231            if(m_target->GetVisibility()!=VISIBILITY_OFF) 
    32323232            { 
    3233                 m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); 
     3233                //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); 
     3234                m_target->SetVisibility(VISIBILITY_OFF); 
    32343235                m_target->SetVisibility(VISIBILITY_GROUP_STEALTH); 
    32353236            } 
     
    32593260                if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) 
    32603261                { 
    3261                     m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); 
    3262                     m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); 
     3262                    //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); 
     3263                    //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); 
     3264                    m_target->SetVisibility(VISIBILITY_ON); 
    32633265                } 
    32643266                else 
     
    33153317        { 
    33163318            // Aura not added yet but visibility code expect temporary add aura 
    3317             m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); 
    3318             m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); 
     3319            //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); 
     3320            //m_target->SetVisibility(VISIBILITY_GROUP_INVISIBILITY); 
     3321            m_target->SetVisibility(VISIBILITY_ON); 
    33193322        } 
    33203323    } 
  • trunk/src/game/SpellEffects.cpp

    r174 r178  
    35773577    } 
    35783578 
     3579    // trigger 
     3580    if(m_spellInfo->Id == 40276) 
     3581    { 
     3582        EffectSummonWild(i); 
     3583        return; 
     3584    } 
     3585 
    35793586    // set timer for unsummon 
    35803587    int32 duration = GetSpellDuration(m_spellInfo); 
  • trunk/src/game/Unit.cpp

    r174 r178  
    85078507        return false; 
    85088508 
    8509     if(GetTypeId()==TYPEID_UNIT && (((Creature *)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)) 
    8510         return false; 
    8511  
    85128509    return isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; 
    85138510} 
     
    85818578    if(!u) 
    85828579        return false; 
    8583  
    8584     // Always can see self 
    8585     if (u==this) 
     8580    return u->canSeeOrDetect(this, detect, inVisibleList); 
     8581} 
     8582 
     8583bool Unit::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const 
     8584{ 
     8585    return true; 
     8586} 
     8587 
     8588bool Unit::canDetectInvisibilityOf(Unit const* u) const 
     8589{ 
     8590    if(m_invisibilityMask & u->m_invisibilityMask) // same group 
    85868591        return true; 
    8587  
    8588     // player visible for other player if not logout and at same transport 
    8589     // including case when player is out of world 
    8590     bool at_same_transport = 
    8591         GetTypeId() == TYPEID_PLAYER &&  u->GetTypeId()==TYPEID_PLAYER && 
    8592         !((Player*)this)->GetSession()->PlayerLogout() && !((Player*)u)->GetSession()->PlayerLogout() && 
    8593         !((Player*)this)->GetSession()->PlayerLoading() && !((Player*)u)->GetSession()->PlayerLoading() && 
    8594         ((Player*)this)->GetTransport() && ((Player*)this)->GetTransport() == ((Player*)u)->GetTransport(); 
    8595  
    8596     // not in world 
    8597     if(!at_same_transport && (!IsInWorld() || !u->IsInWorld())) 
    8598         return false; 
    8599  
    8600     // forbidden to seen (at GM respawn command) 
    8601     if(m_Visibility==VISIBILITY_RESPAWN) 
    8602         return false; 
    8603  
    8604     // always seen by owner 
    8605     if(GetCharmerOrOwnerGUID()==u->GetGUID()) 
    8606         return true; 
    8607  
    8608     // Grid dead/alive checks 
    8609     if( u->GetTypeId()==TYPEID_PLAYER) 
    8610     { 
    8611         // non visible at grid for any stealth state 
    8612         if(!IsVisibleInGridForPlayer((Player *)u)) 
    8613             return false; 
    8614  
    8615         // if player is dead then he can't detect anyone in anycases 
    8616         if(!u->isAlive()) 
    8617             detect = false; 
    8618     } 
    8619     else 
    8620     { 
    8621         // all dead creatures/players not visible for any creatures 
    8622         if(!u->isAlive() || !isAlive()) 
    8623             return false; 
    8624     } 
    8625  
    8626     // If the player is currently possessing, update visibility from the possessed unit's location 
    8627     const Unit* target = u->GetTypeId() == TYPEID_PLAYER && u->isPossessing() ? u->GetCharm() : u; 
    8628  
    8629     // different visible distance checks 
    8630     if(u->isInFlight())                                     // what see player in flight 
    8631     { 
    8632         // use object grey distance for all (only see objects any way) 
    8633         if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 
    8634             return false; 
    8635     } 
    8636     else if(!isAlive())                                     // distance for show body 
    8637     { 
    8638         if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 
    8639             return false; 
    8640     } 
    8641     else if(GetTypeId()==TYPEID_PLAYER)                     // distance for show player 
    8642     { 
    8643         if(u->GetTypeId()==TYPEID_PLAYER) 
    8644         { 
    8645             // Players far than max visible distance for player or not in our map are not visible too 
    8646             if (!at_same_transport && !IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
    8647                 return false; 
    8648         } 
    8649         else 
    8650         { 
    8651             // Units far than max visible distance for creature or not in our map are not visible too 
    8652             // Active unit should always be visibile 
    8653             if (!IsWithinDistInMap(target, target->isActive()  
    8654                 ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance())) 
    8655                 : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))) 
    8656                 return false; 
    8657         } 
    8658     } 
    8659     else if(GetCharmerOrOwnerGUID())                        // distance for show pet/charmed 
    8660     { 
    8661         // Pet/charmed far than max visible distance for player or not in our map are not visible too 
    8662         if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
    8663             return false; 
    8664     } 
    8665     else                                                    // distance for show creature 
    8666     { 
    8667         // Units far than max visible distance for creature or not in our map are not visible too 
    8668         if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
    8669             return false; 
    8670     } 
    8671  
    8672     // Visible units, always are visible for all units, except for units under invisibility 
    8673     if (m_Visibility == VISIBILITY_ON && u->m_invisibilityMask==0) 
    8674         return true; 
    8675  
    8676     // GMs see any players, not higher GMs and all units 
    8677     if (u->GetTypeId() == TYPEID_PLAYER && ((Player *)u)->isGameMaster()) 
    8678     { 
    8679         if(GetTypeId() == TYPEID_PLAYER) 
    8680             return ((Player *)this)->GetSession()->GetSecurity() <= ((Player *)u)->GetSession()->GetSecurity(); 
    8681         else 
     8592    AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark 
     8593    for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) 
     8594        if((*iter)->GetCasterGUID()==u->GetGUID()) 
    86828595            return true; 
    8683     } 
    8684  
    8685     // non faction visibility non-breakable for non-GMs 
    8686     if (m_Visibility == VISIBILITY_OFF) 
    8687         return false; 
    8688  
    8689     // raw invisibility 
    8690     bool invisible = (m_invisibilityMask != 0 || u->m_invisibilityMask !=0); 
    8691  
    8692     // detectable invisibility case 
    8693     if( invisible && ( 
    8694         // Invisible units, always are visible for units under same invisibility type 
    8695         (m_invisibilityMask & u->m_invisibilityMask)!=0 || 
    8696         // Invisible units, always are visible for unit that can detect this invisibility (have appropriate level for detect) 
    8697         u->canDetectInvisibilityOf(this) || 
    8698         // Units that can detect invisibility always are visible for units that can be detected 
    8699         canDetectInvisibilityOf(u) )) 
    8700     { 
    8701         invisible = false; 
    8702     } 
    8703  
    8704     // special cases for always overwrite invisibility/stealth 
    8705     if(invisible || m_Visibility == VISIBILITY_GROUP_STEALTH) 
    8706     { 
    8707         // non-hostile case 
    8708         if (!u->IsHostileTo(this)) 
    8709         { 
    8710             // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting) 
    8711             if(GetTypeId()==TYPEID_PLAYER && u->GetTypeId()==TYPEID_PLAYER) 
    8712             { 
    8713                 if(((Player*)this)->IsGroupVisibleFor(((Player*)u))) 
    8714                     return true; 
    8715  
    8716                 // else apply same rules as for hostile case (detecting check for stealth) 
    8717             } 
    8718         } 
    8719         // hostile case 
    8720         else 
    8721         { 
    8722             // Hunter mark functionality 
    8723             AuraList const& auras = GetAurasByType(SPELL_AURA_MOD_STALKED); 
    8724             for(AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) 
    8725                 if((*iter)->GetCasterGUID()==u->GetGUID()) 
    8726                     return true; 
    8727  
    8728             // else apply detecting check for stealth 
    8729         } 
    8730  
    8731         // none other cases for detect invisibility, so invisible 
    8732         if(invisible) 
    8733             return false; 
    8734  
    8735         // else apply stealth detecting check 
    8736     } 
    8737  
    8738     // unit got in stealth in this moment and must ignore old detected state 
    8739     if (m_Visibility == VISIBILITY_GROUP_NO_DETECT) 
    8740         return false; 
    8741  
    8742     // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible 
    8743     if (m_Visibility != VISIBILITY_GROUP_STEALTH) 
    8744         return true; 
    8745  
    8746     // NOW ONLY STEALTH CASE 
    8747  
    8748     // stealth and detected and visible for some seconds 
    8749     if (u->GetTypeId() == TYPEID_PLAYER  && ((Player*)u)->m_DetectInvTimer > 300 && ((Player*)u)->HaveAtClient(this)) 
    8750         return true; 
    8751  
    8752     //if in non-detect mode then invisible for unit 
    8753     if (!detect) 
    8754         return false; 
    8755  
    8756     // Special cases 
    8757  
    8758     // If is attacked then stealth is lost, some creature can use stealth too 
    8759     if( !getAttackers().empty() ) 
    8760         return true; 
    8761  
    8762     // If there is collision rogue is seen regardless of level difference 
    8763     // TODO: check sizes in DB 
    8764     float distance = GetDistance(u); 
    8765     if (distance < 0.24f) 
    8766         return true; 
    8767  
    8768     //If a mob or player is stunned he will not be able to detect stealth 
    8769     if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this)) 
    8770         return false; 
    8771  
    8772     // Creature can detect target only in aggro radius 
    8773     if(u->GetTypeId() != TYPEID_PLAYER) 
    8774     { 
    8775         //Always invisible from back and out of aggro range 
    8776         bool isInFront = u->isInFront(this,((Creature const*)u)->GetAttackDistance(this)); 
    8777         if(!isInFront) 
    8778             return false; 
    8779     } 
    8780     else 
    8781     { 
    8782         //Always invisible from back 
    8783         bool isInFront = u->isInFront(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature()); 
    8784         if(!isInFront) 
    8785             return false; 
    8786     } 
    8787  
    8788     // if doesn't have stealth detection (Shadow Sight), then check how stealthy the unit is, otherwise just check los 
    8789     if(!u->HasAuraType(SPELL_AURA_DETECT_STEALTH)) 
    8790     { 
    8791         //Calculation if target is in front 
    8792  
    8793         //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5) 
    8794         float visibleDistance = 10.5f - (GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH)/100.0f); 
    8795  
    8796         //Visible distance is modified by 
    8797         //-Level Diff (every level diff = 1.0f in visible distance) 
    8798         visibleDistance += int32(u->getLevelForTarget(this)) - int32(this->getLevelForTarget(u)); 
    8799  
    8800         //This allows to check talent tree and will add addition stealth dependent on used points) 
    8801         int32 stealthMod = GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL); 
    8802         if(stealthMod < 0) 
    8803             stealthMod = 0; 
    8804  
    8805         //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia) 
    8806         //based on wowwiki every 5 mod we have 1 more level diff in calculation 
    8807         visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f; 
    8808  
    8809         if(distance > visibleDistance) 
    8810             return false; 
    8811     } 
    8812  
    8813     // Now check is target visible with LoS 
    8814     float ox,oy,oz; 
    8815     u->GetPosition(ox,oy,oz); 
    8816     return IsWithinLOS(ox,oy,oz); 
    8817 } 
    8818  
    8819 void Unit::SetVisibility(UnitVisibility x) 
    8820 { 
    8821     m_Visibility = x; 
    8822  
    8823     if(IsInWorld()) 
    8824     { 
    8825         Map *m = MapManager::Instance().GetMap(GetMapId(), this); 
    8826  
    8827         if(GetTypeId()==TYPEID_PLAYER) 
    8828             m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); 
    8829         else 
    8830             m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); 
    8831     } 
    8832 } 
    8833  
    8834 bool Unit::canDetectInvisibilityOf(Unit const* u) const 
    8835 { 
     8596 
    88368597    if(uint32 mask = (m_detectInvisibilityMask & u->m_invisibilityMask)) 
    88378598    { 
     
    88508611            // find invisibility detect level 
    88518612            uint32 detectLevel = 0; 
    8852             Unit::AuraList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION); 
    8853             for(Unit::AuraList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr) 
    8854                 if(((*itr)->GetModifier()->m_miscvalue)==i && detectLevel < (*itr)->GetModifier()->m_amount) 
    8855                     detectLevel = (*itr)->GetModifier()->m_amount; 
    8856  
    88578613            if(i==6 && GetTypeId()==TYPEID_PLAYER)          // special drunk detection case 
    88588614            { 
    88598615                detectLevel = ((Player*)this)->GetDrunkValue(); 
     8616            } 
     8617            else 
     8618            { 
     8619                Unit::AuraList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION); 
     8620                for(Unit::AuraList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr) 
     8621                    if(((*itr)->GetModifier()->m_miscvalue)==i && detectLevel < (*itr)->GetModifier()->m_amount) 
     8622                        detectLevel = (*itr)->GetModifier()->m_amount; 
    88608623            } 
    88618624 
     
    88668629 
    88678630    return false; 
     8631} 
     8632 
     8633bool Unit::canDetectStealthOf(Unit const* target, float distance) const 
     8634{ 
     8635    if(hasUnitState(UNIT_STAT_STUNNED)) 
     8636        return false; 
     8637    if(distance < 0.24f) //collision 
     8638        return true; 
     8639    if(!HasInArc(M_PI, target)) //behind 
     8640        return false; 
     8641    if(HasAuraType(SPELL_AURA_DETECT_STEALTH)) 
     8642        return true; 
     8643 
     8644    //Visible distance based on stealth value (stealth rank 4 300MOD, 10.5 - 3 = 7.5) 
     8645    float visibleDistance = 10.5f - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH) / 100.0f; 
     8646    //Visible distance is modified by -Level Diff (every level diff = 1.0f in visible distance) 
     8647    visibleDistance += int32(getLevelForTarget(target)) - int32(target->getLevelForTarget(this)); 
     8648    //-Stealth Mod(positive like Master of Deception) and Stealth Detection(negative like paranoia) 
     8649    //based on wowwiki every 5 mod we have 1 more level diff in calculation 
     8650    visibleDistance += (float)(GetTotalAuraModifier(SPELL_AURA_MOD_DETECT) - target->GetTotalAuraModifier(SPELL_AURA_MOD_STEALTH_LEVEL)) / 5.0f; 
     8651 
     8652    return distance < visibleDistance; 
     8653} 
     8654 
     8655void Unit::SetVisibility(UnitVisibility x) 
     8656{ 
     8657    m_Visibility = x; 
     8658 
     8659    if(IsInWorld()) 
     8660    { 
     8661        Map *m = MapManager::Instance().GetMap(GetMapId(), this); 
     8662 
     8663        if(GetTypeId()==TYPEID_PLAYER) 
     8664            m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); 
     8665        else 
     8666            m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); 
     8667    } 
    88688668} 
    88698669 
  • trunk/src/game/Unit.h

    r174 r178  
    438438    VISIBILITY_ON                 = 1, 
    439439    VISIBILITY_GROUP_STEALTH      = 2,                      // detect chance, seen and can see group members 
    440     VISIBILITY_GROUP_INVISIBILITY = 3,                      // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead) 
    441     VISIBILITY_GROUP_NO_DETECT    = 4,                      // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break 
     440    //VISIBILITY_GROUP_INVISIBILITY = 3,                      // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead) 
     441    //VISIBILITY_GROUP_NO_DETECT    = 4,                      // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break 
    442442    VISIBILITY_RESPAWN            = 5                       // special totally not detectable visibility for force delete object at respawn command 
    443443}; 
     
    11361136 
    11371137        // common function for visibility checks for player/creatures with detection code 
     1138        virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; 
    11381139        bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false) const; 
    11391140        bool canDetectInvisibilityOf(Unit const* u) const; 
     1141        bool canDetectStealthOf(Unit const* u, float distance) const; 
    11401142 
    11411143        // virtual functions for all world objects types 
    11421144        bool isVisibleForInState(Player const* u, bool inVisibleList) const; 
    11431145        // function for low level grid visibility checks in player/creature cases 
    1144         virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0; 
     1146        virtual bool IsVisibleInGridForPlayer(Player const* pl) const = 0; 
    11451147 
    11461148        bool waterbreath;