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

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • 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