Changeset 178 for trunk/src/game
- Timestamp:
- 11/19/08 13:43:40 (17 years ago)
- Location:
- trunk/src/game
- Files:
-
- 10 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/Creature.cpp
r174 r178 319 319 m_spells[2] = GetCreatureInfo()->spell3; 320 320 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); 321 325 322 326 return true; … … 1488 1492 } 1489 1493 1494 bool 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 1490 1535 float Creature::GetAttackDistance(Unit const* pl) const 1491 1536 { … … 1699 1744 } 1700 1745 1701 bool Creature::IsVisibleInGridForPlayer(Player * pl) const1746 bool Creature::IsVisibleInGridForPlayer(Player const* pl) const 1702 1747 { 1703 1748 // gamemaster in GM mode see all, including ghosts -
trunk/src/game/Creature.h
r174 r178 548 548 uint32 m_GlobalCooldown; 549 549 550 bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; 550 551 float GetAttackDistance(Unit const* pl) const; 551 552 … … 561 562 void SetCurrentCell(Cell const& cell) { m_currentCell = cell; } 562 563 563 bool IsVisibleInGridForPlayer(Player * pl) const;564 bool IsVisibleInGridForPlayer(Player const* pl) const; 564 565 565 566 void RemoveCorpse(); -
trunk/src/game/Object.cpp
r174 r178 1487 1487 if(GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) 1488 1488 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()); 1490 1490 } 1491 1491 -
trunk/src/game/OutdoorPvPObjectiveAI.cpp
r102 r178 51 51 void OutdoorPvPObjectiveAI::AttackStart(Unit *) 52 52 { 53 EnterEvadeMode();53 //EnterEvadeMode(); 54 54 } 55 55 56 56 void OutdoorPvPObjectiveAI::EnterEvadeMode() 57 57 { 58 i_creature.DeleteThreatList();59 i_creature.CombatStop();58 // i_creature.DeleteThreatList(); 59 // i_creature.CombatStop(); 60 60 } 61 61 -
trunk/src/game/Player.cpp
r177 r178 2001 2001 if(HasAuraType(SPELL_AURA_MOD_STEALTH)) 2002 2002 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); 2005 2005 else 2006 2006 SetVisibility(VISIBILITY_ON); … … 16396 16396 if ((*i)->isVisibleForOrDetect(this,true)) 16397 16397 { 16398 16399 16398 (*i)->SendUpdateToPlayer(this); 16400 16399 m_clientGUIDs.insert((*i)->GetGUID()); … … 17189 17188 } 17190 17189 17191 bool Player::IsVisibleInGridForPlayer( Player* pl ) const 17190 bool 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 17291 bool Player::IsVisibleInGridForPlayer( Player const * pl ) const 17192 17292 { 17193 17293 // gamemaster in GM mode see all, including ghosts -
trunk/src/game/Player.h
r177 r178 1993 1993 ClientGUIDs m_clientGUIDs; 1994 1994 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; 1998 1999 bool IsVisibleGloballyFor(Player* pl) const; 1999 2000 -
trunk/src/game/SpellAuras.cpp
r174 r178 3231 3231 if(m_target->GetVisibility()!=VISIBILITY_OFF) 3232 3232 { 3233 m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); 3233 //m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); 3234 m_target->SetVisibility(VISIBILITY_OFF); 3234 3235 m_target->SetVisibility(VISIBILITY_GROUP_STEALTH); 3235 3236 } … … 3259 3260 if(m_target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) 3260 3261 { 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); 3263 3265 } 3264 3266 else … … 3315 3317 { 3316 3318 // 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); 3319 3322 } 3320 3323 } -
trunk/src/game/SpellEffects.cpp
r174 r178 3577 3577 } 3578 3578 3579 // trigger 3580 if(m_spellInfo->Id == 40276) 3581 { 3582 EffectSummonWild(i); 3583 return; 3584 } 3585 3579 3586 // set timer for unsummon 3580 3587 int32 duration = GetSpellDuration(m_spellInfo); -
trunk/src/game/Unit.cpp
r174 r178 8507 8507 return false; 8508 8508 8509 if(GetTypeId()==TYPEID_UNIT && (((Creature *)this)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER))8510 return false;8511 8512 8509 return isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; 8513 8510 } … … 8581 8578 if(!u) 8582 8579 return false; 8583 8584 // Always can see self 8585 if (u==this) 8580 return u->canSeeOrDetect(this, detect, inVisibleList); 8581 } 8582 8583 bool Unit::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const 8584 { 8585 return true; 8586 } 8587 8588 bool Unit::canDetectInvisibilityOf(Unit const* u) const 8589 { 8590 if(m_invisibilityMask & u->m_invisibilityMask) // same group 8586 8591 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()) 8682 8595 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 8836 8597 if(uint32 mask = (m_detectInvisibilityMask & u->m_invisibilityMask)) 8837 8598 { … … 8850 8611 // find invisibility detect level 8851 8612 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 8857 8613 if(i==6 && GetTypeId()==TYPEID_PLAYER) // special drunk detection case 8858 8614 { 8859 8615 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; 8860 8623 } 8861 8624 … … 8866 8629 8867 8630 return false; 8631 } 8632 8633 bool 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 8655 void 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 } 8868 8668 } 8869 8669 -
trunk/src/game/Unit.h
r174 r178 438 438 VISIBILITY_ON = 1, 439 439 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 break440 //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 442 442 VISIBILITY_RESPAWN = 5 // special totally not detectable visibility for force delete object at respawn command 443 443 }; … … 1136 1136 1137 1137 // common function for visibility checks for player/creatures with detection code 1138 virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; 1138 1139 bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false) const; 1139 1140 bool canDetectInvisibilityOf(Unit const* u) const; 1141 bool canDetectStealthOf(Unit const* u, float distance) const; 1140 1142 1141 1143 // virtual functions for all world objects types 1142 1144 bool isVisibleForInState(Player const* u, bool inVisibleList) const; 1143 1145 // 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; 1145 1147 1146 1148 bool waterbreath;