Changeset 233 for trunk

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

[svn] * Reimplemented packet/update forwarding in more generic way
* Implemented far sight spells (Far Sight, Eagle Eye, etc) at unlimited range and properly forward packets
* Implemented bind vision spells (Mind Vision, etc) to forward packets at unlimited distance
* Implemented Sentry Totem (both vision switching/forwarding and alerting)
* Other misc possession fixes
* Added .bindsight and .unbindsight commands

Please test out the above spells (including Mind Control) and report any issues on the forums.

Original author: gvcoman
Date: 2008-11-14 20:40:35-06:00

Location:
trunk
Files:
1 added
20 modified

Legend:

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

    r232 r233  
    566566        { "possess",        SEC_ADMINISTRATOR,  false, &ChatHandler::HandlePossessCommand,             "", NULL }, 
    567567        { "unpossess",      SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnPossessCommand,           "", NULL }, 
     568        { "bindsight",      SEC_ADMINISTRATOR,  false, &ChatHandler::HandleBindSightCommand,           "", NULL }, 
     569        { "unbindsight",    SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnbindSightCommand,         "", NULL }, 
    568570 
    569571        { NULL,             0,                  false, NULL,                                           "", NULL } 
  • trunk/src/game/Chat.h

    r232 r233  
    454454        bool HandlePossessCommand(const char* args); 
    455455        bool HandleUnPossessCommand(const char* args); 
     456        bool HandleBindSightCommand(const char* args); 
     457        bool HandleUnbindSightCommand(const char* args); 
    456458 
    457459        Player*   getSelectedPlayer(); 
  • trunk/src/game/DynamicObject.cpp

    r120 r233  
    137137void DynamicObject::Delete() 
    138138{ 
     139    // Make sure the object is back to grid container for removal as farsight targets 
     140    // are switched to world container on creation 
     141    GetMap()->SwitchGridContainers(this, false); 
    139142    SendObjectDeSpawnAnim(GetGUID()); 
    140143    AddObjectToRemoveList(); 
     
    151154bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const 
    152155{ 
    153     return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); 
     156    return IsInWorld() && u->IsInWorld() /*&& IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))*/; 
    154157} 
  • trunk/src/game/GridDefines.h

    r102 r233  
    5858 
    5959// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case) 
    60 typedef TYPELIST_3(Player, Creature/*pets*/, Corpse/*resurrectable*/)                  AllWorldObjectTypes; 
     60typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes; 
    6161typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes; 
    6262 
  • trunk/src/game/GridNotifiers.cpp

    r221 r233  
    4141        iter->getSource()->UpdateVisibilityOf(&i_player); 
    4242        i_player.UpdateVisibilityOf(iter->getSource()); 
    43         if (i_player.isPossessedByPlayer()) 
    44             ((Player*)i_player.GetCharmer())->UpdateVisibilityOf(iter->getSource()); 
     43 
     44        if (!i_player.GetSharedVisionList().empty()) 
     45            for (SharedVisionList::const_iterator it = i_player.GetSharedVisionList().begin(); it != i_player.GetSharedVisionList().end(); ++it) 
     46                (*it)->UpdateVisibilityOf(iter->getSource()); 
    4547    } 
    4648} 
     
    149151        if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist) 
    150152        { 
    151             // Send packet to possessor 
    152             if (iter->getSource()->isPossessedByPlayer()) 
    153                 SendPacket((Player*)iter->getSource()->GetCharmer()); 
     153            // Send packet to all who are sharing the player's vision 
     154            if (!iter->getSource()->GetSharedVisionList().empty()) 
     155            { 
     156                SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin(); 
     157                for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it) 
     158                    SendPacket(*it); 
     159            } 
     160 
    154161            VisitObject(iter->getSource()); 
    155162        } 
     
    164171        if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist) 
    165172        { 
    166             // Send packet to possessor 
    167             if (iter->getSource()->isPossessedByPlayer()) 
    168                 SendPacket((Player*)iter->getSource()->GetCharmer()); 
     173            // Send packet to all who are sharing the creature's vision 
     174            if (!iter->getSource()->GetSharedVisionList().empty()) 
     175            { 
     176                SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin(); 
     177                for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it) 
     178                    SendPacket(*it); 
     179            } 
     180        } 
     181    } 
     182} 
     183 
     184void 
     185Deliverer::Visit(DynamicObjectMapType &m) 
     186{ 
     187    for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter) 
     188    { 
     189        if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID())) 
     190        { 
     191            // Send packet back to the caster if the caster has vision of dynamic object 
     192            Player* caster = (Player*)iter->getSource()->GetCaster(); 
     193            if (caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID() && 
     194                (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist)) 
     195                SendPacket(caster); 
    169196        } 
    170197    } 
     
    176203    if (!plr) 
    177204        return; 
     205 
     206    // Don't send the packet to self if not supposed to 
     207    if (!i_toSelf && plr == &i_source) 
     208        return; 
     209 
    178210    // Don't send the packet to possesor if not supposed to 
    179211    if (!i_toPossessor && plr->isPossessing() && plr->GetCharmGUID() == i_source.GetGUID()) 
     
    191223MessageDeliverer::VisitObject(Player* plr) 
    192224{ 
    193     if (i_toSelf || plr != &i_source) 
    194         SendPacket(plr); 
     225    SendPacket(plr); 
    195226} 
    196227 
     
    198229MessageDistDeliverer::VisitObject(Player* plr) 
    199230{ 
    200     if( (i_toSelf || plr != &i_source ) && 
    201         (!i_ownTeamOnly || (i_source.GetTypeId() == TYPEID_PLAYER && plr->GetTeam() == ((Player&)i_source).GetTeam())) ) 
     231    if( !i_ownTeamOnly || (i_source.GetTypeId() == TYPEID_PLAYER && plr->GetTeam() == ((Player&)i_source).GetTeam()) ) 
    202232    { 
    203233        SendPacket(plr); 
  • trunk/src/game/GridNotifiers.h

    r174 r233  
    9696        std::set<uint64> plr_list; 
    9797        bool i_toPossessor; 
     98        bool i_toSelf; 
    9899        float i_dist; 
    99         Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, float dist = 0.0f) : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_dist(dist) {} 
     100        Deliverer(WorldObject &src, WorldPacket *msg, bool to_possessor, bool to_self, float dist = 0.0f) : i_source(src), i_message(msg), i_toPossessor(to_possessor), i_toSelf(to_self), i_dist(dist) {} 
    100101        void Visit(PlayerMapType &m); 
    101102        void Visit(CreatureMapType &m); 
     103        void Visit(DynamicObjectMapType &m); 
    102104        virtual void VisitObject(Player* plr) = 0; 
    103105        void SendPacket(Player* plr); 
     
    107109    struct TRINITY_DLL_DECL MessageDeliverer : public Deliverer 
    108110    { 
    109         bool i_toSelf; 
    110         MessageDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, bool to_self) : Deliverer(pl, msg, to_possessor), i_toSelf(to_self) {} 
     111        MessageDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, bool to_self) : Deliverer(pl, msg, to_possessor, to_self) {} 
    111112        void VisitObject(Player* plr); 
    112113    }; 
     
    114115    struct TRINITY_DLL_DECL ObjectMessageDeliverer : public Deliverer 
    115116    { 
    116         explicit ObjectMessageDeliverer(WorldObject &src, WorldPacket *msg, bool to_possessor) : Deliverer(src, msg, to_possessor) {} 
     117        explicit ObjectMessageDeliverer(WorldObject &src, WorldPacket *msg, bool to_possessor) : Deliverer(src, msg, to_possessor, false) {} 
    117118        void VisitObject(Player* plr) { SendPacket(plr); } 
    118119    }; 
     
    120121    struct TRINITY_DLL_DECL MessageDistDeliverer : public Deliverer 
    121122    { 
    122         bool i_toSelf; 
    123123        bool i_ownTeamOnly; 
    124         MessageDistDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, float dist, bool to_self, bool ownTeamOnly) : Deliverer(pl, msg, to_possessor, dist), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly) {} 
     124        MessageDistDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, float dist, bool to_self, bool ownTeamOnly) : Deliverer(pl, msg, to_possessor, to_self, dist), i_ownTeamOnly(ownTeamOnly) {} 
    125125        void VisitObject(Player* plr); 
    126126    }; 
     
    128128    struct TRINITY_DLL_DECL ObjectMessageDistDeliverer : public Deliverer 
    129129    { 
    130         ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, bool to_possessor, float dist) : Deliverer(obj, msg, to_possessor, dist) {} 
     130        ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, bool to_possessor, float dist) : Deliverer(obj, msg, to_possessor, false, dist) {} 
    131131        void VisitObject(Player* plr) { SendPacket(plr); } 
    132132    }; 
  • trunk/src/game/Level3.cpp

    r232 r233  
    68166816    return true; 
    68176817} 
     6818 
     6819bool ChatHandler::HandleBindSightCommand(const char* args) 
     6820{ 
     6821    Unit* pUnit = getSelectedUnit(); 
     6822    if (!pUnit) 
     6823        return false; 
     6824         
     6825    if (m_session->GetPlayer()->isPossessing()) 
     6826        return false; 
     6827 
     6828    pUnit->AddPlayerToVision(m_session->GetPlayer()); 
     6829 
     6830    return true; 
     6831} 
     6832 
     6833bool ChatHandler::HandleUnbindSightCommand(const char* args) 
     6834{ 
     6835    if (m_session->GetPlayer()->isPossessing()) 
     6836        return false; 
     6837         
     6838    m_session->GetPlayer()->RemoveFarsightTarget(); 
     6839    return true; 
     6840} 
  • trunk/src/game/Map.cpp

    r229 r233  
    316316    CellPair pair = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); 
    317317    Cell cell(pair); 
    318     NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); 
     318    NGridType *ngrid = getNGrid(cell.GridX(), cell.GridY()); 
     319    GridType &grid = (*ngrid)(cell.CellX(), cell.CellY()); 
    319320 
    320321    if (active) 
    321322    { 
    322         (*grid)(cell.CellX(), cell.CellY()).RemoveGridObject<T>(obj, obj->GetGUID()); 
    323         (*grid)(cell.CellX(), cell.CellY()).AddWorldObject<T>(obj, obj->GetGUID()); 
     323        if (!grid.GetWorldObject(obj->GetGUID(), obj)) 
     324        { 
     325            grid.RemoveGridObject<T>(obj, obj->GetGUID()); 
     326            grid.AddWorldObject<T>(obj, obj->GetGUID()); 
     327        } 
    324328    } else 
    325329    { 
    326         (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<T>(obj, obj->GetGUID()); 
    327         (*grid)(cell.CellX(), cell.CellY()).AddGridObject<T>(obj, obj->GetGUID()); 
     330        if (!grid.GetGridObject(obj->GetGUID(), obj)) 
     331        { 
     332            grid.RemoveWorldObject<T>(obj, obj->GetGUID()); 
     333            grid.AddGridObject<T>(obj, obj->GetGUID()); 
     334        } 
    328335    } 
    329336} 
     
    331338template void Map::SwitchGridContainers(Creature *, bool); 
    332339template void Map::SwitchGridContainers(Corpse *, bool); 
     340template void Map::SwitchGridContainers(DynamicObject *, bool); 
    333341 
    334342template<class T> 
  • trunk/src/game/MiscHandler.cpp

    r232 r233  
    13921392    //recv_data.hexlike(); 
    13931393 
    1394     uint8 unk; 
    1395     recv_data >> unk; 
    1396  
    1397     switch(unk) 
     1394    uint8 apply; 
     1395    recv_data >> apply; 
     1396 
     1397    CellPair pair; 
     1398 
     1399    switch(apply) 
    13981400    { 
    13991401        case 0: 
    1400             //WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0) 
    1401             //SendPacket(&data); 
    1402             //_player->SetUInt64Value(PLAYER_FARSIGHT, 0); 
    1403             sLog.outDebug("Removed FarSight from player %u", _player->GetGUIDLow()); 
     1402            _player->SetFarsightVision(false); 
     1403            pair = Trinity::ComputeCellPair(_player->GetPositionX(), _player->GetPositionY()); 
     1404            sLog.outDebug("Player %u set vision to himself", _player->GetGUIDLow()); 
    14041405            break; 
    14051406        case 1: 
    1406             sLog.outDebug("Added FarSight " I64FMTD " to player %u", _player->GetUInt64Value(PLAYER_FARSIGHT), _player->GetGUIDLow()); 
     1407            _player->SetFarsightVision(true); 
     1408            if (WorldObject* obj = _player->GetFarsightTarget()) 
     1409                pair = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); 
     1410            else 
     1411                return; 
     1412            sLog.outDebug("Player %u set vision to farsight target " I64FMTD ".", _player->GetGUIDLow(), _player->GetUInt64Value(PLAYER_FARSIGHT)); 
    14071413            break; 
    1408     } 
     1414        default: 
     1415            sLog.outDebug("Unhandled mode in CMSG_FAR_SIGHT: %u", apply); 
     1416            return; 
     1417    } 
     1418    // Update visibility after vision change 
     1419    Cell cell(pair); 
     1420    GetPlayer()->GetMap()->UpdateObjectsVisibilityFor(_player, cell, pair); 
    14091421} 
    14101422 
  • trunk/src/game/ObjectAccessor.cpp

    r206 r233  
    625625    { 
    626626        BuildPacket(iter->getSource()); 
    627         if (iter->getSource()->isPossessedByPlayer()) 
    628             BuildPacket((Player*)iter->getSource()->GetCharmer()); 
     627        if (!iter->getSource()->GetSharedVisionList().empty()) 
     628        { 
     629            SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin(); 
     630            for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it) 
     631                BuildPacket(*it); 
     632        } 
    629633    } 
    630634} 
     
    634638{ 
    635639    for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) 
    636         if (iter->getSource()->isPossessedByPlayer()) 
    637             BuildPacket((Player*)iter->getSource()->GetCharmer()); 
     640    { 
     641        if (!iter->getSource()->GetSharedVisionList().empty()) 
     642        { 
     643            SharedVisionList::const_iterator it = iter->getSource()->GetSharedVisionList().begin(); 
     644            for ( ; it != iter->getSource()->GetSharedVisionList().end(); ++it) 
     645                BuildPacket(*it); 
     646        } 
     647    } 
     648} 
     649 
     650void 
     651ObjectAccessor::WorldObjectChangeAccumulator::Visit(DynamicObjectMapType &m) 
     652{ 
     653    for(DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter) 
     654    { 
     655        if (IS_PLAYER_GUID(iter->getSource()->GetCasterGUID())) 
     656        { 
     657            Player* caster = (Player*)iter->getSource()->GetCaster(); 
     658            if (caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->getSource()->GetGUID()) 
     659                BuildPacket(caster); 
     660        } 
     661    } 
    638662} 
    639663 
  • trunk/src/game/ObjectAccessor.h

    r206 r233  
    213213            void Visit(PlayerMapType &); 
    214214            void Visit(CreatureMapType &); 
     215            void Visit(DynamicObjectMapType &); 
    215216            void BuildPacket(Player* plr); 
    216217            template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 
  • trunk/src/game/Player.cpp

    r230 r233  
    428428 
    429429    m_isActive = true; 
     430 
     431    m_farsightVision = false; 
    430432} 
    431433 
     
    12921294        RemoveGuardians(); 
    12931295 
     1296        // remove possession 
     1297        if(isPossessing()) 
     1298            RemovePossess(false); 
     1299        else 
     1300            RemoveFarsightTarget(); 
     1301 
    12941302        // save value before aura remove in Unit::setDeathState 
    12951303        ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL); 
     
    15451553        ((Player*)GetCharmer())->RemovePossess(); 
    15461554 
    1547     // The player was ported to another map and looses the duel immediately. 
     1555    // Remove player's possession before teleporting 
     1556    if (isPossessing()) 
     1557        RemovePossess(false); 
     1558 
     1559    // Empty vision list and clear farsight (if it hasn't already been cleared by RemovePossess) before teleporting 
     1560    RemoveAllFromVision(); 
     1561    RemoveFarsightTarget(); 
     1562 
     1563    // The player was ported to another map and looses the duel immediatly. 
    15481564    // We have to perform this check before the teleport, otherwise the 
    15491565    // ObjectAccessor won't find the flag. 
     
    17631779        RemoveMiniPet(); 
    17641780        RemoveGuardians(); 
     1781        RemoveFarsightTarget(); 
    17651782    } 
    17661783 
     
    1729417311        return false; 
    1729517312 
    17296     // If the player is currently possessing, update visibility from the possessed unit's location 
    17297     const Unit* target = isPossessing() ? GetCharm() : this; 
     17313    // If the player is currently channeling vision, update visibility from the target unit's location 
     17314    const WorldObject* target = GetFarsightTarget(); 
     17315    if (!target || !HasFarsightVision()) // Vision needs to be on the farsight target 
     17316        target = this; 
    1729817317 
    1729917318    // different visible distance checks 
     
    1874418763    SetPossessedTarget(target); 
    1874518764 
     18765    // Start channeling packets to possessor 
     18766    target->AddPlayerToVision(this); 
     18767 
    1874618768    target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction()); 
    1874718769    target->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); 
     
    1874918771    target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); 
    1875018772    SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); 
    18751     SetUInt64Value(PLAYER_FARSIGHT, target->GetGUID()); 
    1875218773 
    1875318774    if(target->GetTypeId() == TYPEID_UNIT) 
    1875418775    { 
    18755         // Set target to active in the grid and place it in the world container to be picked up by all regular player cell visits 
    18756         Map* map = target->GetMap(); 
    18757         map->SwitchGridContainers((Creature*)target, true); 
    18758         target->setActive(true); 
    18759  
    1876018776        ((Creature*)target)->InitPossessedAI(); // Initialize the possessed AI 
    1876118777        target->StopMoving(); 
     
    1881018826    RemovePossessedTarget(); 
    1881118827 
     18828    // Stop channeling packets back to possessor 
     18829    target->RemovePlayerFromVision(this); 
     18830 
    1881218831    if(target->GetTypeId() == TYPEID_PLAYER) 
    1881318832        ((Player*)target)->setFactionForRace(target->getRace()); 
    1881418833    else if(target->GetTypeId() == TYPEID_UNIT) 
    1881518834    { 
    18816         // Set creature to inactive in grid and place it back into the grid container 
    18817         Map* map = target->GetMap(); 
    18818         target->setActive(false); 
    18819         map->SwitchGridContainers((Creature*)target, false); 
    18820  
    1882118835        if(((Creature*)target)->isPet()) 
    1882218836        { 
     
    1883218846    target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); 
    1883318847    RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); 
    18834     SetUInt64Value(PLAYER_FARSIGHT, 0); 
    1883518848 
    1883618849    // Remove pet spell action bar 
     
    1889818911} 
    1889918912 
     18913WorldObject* Player::GetFarsightTarget() const 
     18914{ 
     18915    // Players can have in farsight field another player's guid, a creature's guid, or a dynamic object's guid 
     18916    if (uint64 guid = GetUInt64Value(PLAYER_FARSIGHT)) 
     18917        return (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*this, guid, TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT); 
     18918    return NULL; 
     18919} 
     18920 
     18921void Player::RemoveFarsightTarget() 
     18922{ 
     18923    if (WorldObject* fTarget = GetFarsightTarget()) 
     18924    { 
     18925        if (fTarget->isType(TYPEMASK_PLAYER | TYPEMASK_UNIT)) 
     18926            ((Unit*)fTarget)->RemovePlayerFromVision(this); 
     18927    } 
     18928    ClearFarsight(); 
     18929} 
     18930 
     18931void Player::ClearFarsight() 
     18932{ 
     18933    if (GetUInt64Value(PLAYER_FARSIGHT)) 
     18934    { 
     18935        SetUInt64Value(PLAYER_FARSIGHT, 0); 
     18936        WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0); 
     18937        GetSession()->SendPacket(&data); 
     18938    } 
     18939} 
     18940 
     18941void Player::SetFarsightTarget(WorldObject* obj) 
     18942{ 
     18943    if (!obj || !obj->isType(TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT)) 
     18944        return; 
     18945 
     18946    // Remove the current target if there is one 
     18947    RemoveFarsightTarget(); 
     18948 
     18949    SetUInt64Value(PLAYER_FARSIGHT, obj->GetGUID()); 
     18950} 
     18951 
    1890018952bool Player::isAllowUseBattleGroundObject() 
    1890118953{ 
  • trunk/src/game/Player.h

    r230 r233  
    903903        void Possess(Unit *target); 
    904904        void RemovePossess(bool attack = true);  
     905        WorldObject* GetFarsightTarget() const; 
     906        void ClearFarsight(); 
     907        void RemoveFarsightTarget(); 
     908        void SetFarsightTarget(WorldObject* target); 
     909        // Controls if vision is currently on farsight object, updated in FAR_SIGHT opcode 
     910        void SetFarsightVision(bool apply) { m_farsightVision = apply; } 
     911        bool HasFarsightVision() const { return m_farsightVision; } 
    905912 
    906913        bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); 
     
    22902297        WorldLocation m_teleport_dest; 
    22912298 
     2299        bool m_farsightVision; 
     2300 
    22922301        DeclinedName *m_declinedname; 
    22932302    private: 
  • trunk/src/game/SpellAuras.cpp

    r229 r233  
    19651965    else 
    19661966    { 
    1967         if( m_target->GetTypeId() == TYPEID_PLAYER && 
    1968             ( GetSpellProto()->Effect[0]==72 || GetSpellProto()->Effect[0]==6 && 
    1969             ( GetSpellProto()->EffectApplyAuraName[0]==1 || GetSpellProto()->EffectApplyAuraName[0]==128 ) ) ) 
     1967        if( m_target->GetTypeId() == TYPEID_PLAYER && GetSpellProto()->Effect[0]==72 ) 
    19701968        { 
    19711969            // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425 
    1972             m_target->SetUInt64Value(PLAYER_FARSIGHT, 0); 
    1973             WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0); 
    1974             ((Player*)m_target)->GetSession()->SendPacket(&data); 
     1970            ((Player*)m_target)->ClearFarsight(); 
    19751971            return; 
    19761972        } 
     
    22282224 
    22292225                ((Player*)m_target)->AddSpellMod(m_spellmod, apply); 
     2226                return; 
     2227            } 
     2228 
     2229            // Sentry Totem 
     2230            if (GetId() == 6495 && caster->GetTypeId() == TYPEID_PLAYER) 
     2231            { 
     2232                if (apply) 
     2233                { 
     2234                    uint64 guid = caster->m_TotemSlot[3]; 
     2235                    if (guid) 
     2236                    { 
     2237                        Creature *totem = ObjectAccessor::GetCreature(*caster, guid); 
     2238                        if (totem && totem->isTotem()) 
     2239                            totem->AddPlayerToVision((Player*)caster); 
     2240                    } 
     2241                }  
     2242                else 
     2243                    ((Player*)caster)->RemoveFarsightTarget(); 
    22302244                return; 
    22312245            } 
     
    28312845        return; 
    28322846 
    2833     caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0); 
     2847    if (apply) 
     2848        m_target->AddPlayerToVision((Player*)caster); 
     2849    else 
     2850        m_target->RemovePlayerFromVision((Player*)caster); 
    28342851} 
    28352852 
  • trunk/src/game/SpellEffects.cpp

    r229 r233  
    34913491void Spell::EffectAddFarsight(uint32 i) 
    34923492{ 
     3493    if (m_caster->GetTypeId() != TYPEID_PLAYER) 
     3494        return; 
     3495 
    34933496    float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); 
    34943497    int32 duration = GetSpellDuration(m_spellInfo); 
     
    35023505    dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002); 
    35033506    m_caster->AddDynObject(dynObj); 
    3504     MapManager::Instance().GetMap(dynObj->GetMapId(), dynObj)->Add(dynObj); 
    3505     m_caster->SetUInt64Value(PLAYER_FARSIGHT, dynObj->GetGUID()); 
     3507 
     3508    CellPair pair = Trinity::ComputeCellPair(dynObj->GetPositionX(), dynObj->GetPositionY()); 
     3509    Cell cell(pair); 
     3510    Map* map = MapManager::Instance().GetMap(dynObj->GetMapId(), dynObj); 
     3511    map->LoadGrid(cell);                        // In case the spell is casted into a different grid by player 
     3512    map->Add(dynObj); 
     3513    map->SwitchGridContainers(dynObj, true);    // Needed for forwarding player packets 
     3514    dynObj->setActive(true);                    // Keep the grid updated even if there are no players in it 
     3515       
     3516    // Need to update visibility of object for client to accept farsight guid 
     3517    ((Player*)m_caster)->UpdateVisibilityOf(dynObj); 
     3518    ((Player*)m_caster)->SetFarsightTarget(dynObj); 
    35063519} 
    35073520 
  • trunk/src/game/SpellHandler.cpp

    r207 r233  
    353353        return; 
    354354 
    355     // Remove possess/charm aura from the possessed/charmed as well 
     355    // Remove possess/charm/sight aura from the possessed/charmed as well 
    356356    // TODO: Remove this once the ability to cancel aura sets at once is implemented 
    357     if(_player->GetCharm()) 
     357    if(_player->GetCharm() || _player->GetFarsightTarget()) 
    358358    { 
    359359        for (int i = 0; i < 3; ++i) 
     
    361361            if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POSSESS || 
    362362                spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POSSESS_PET || 
    363                 spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_CHARM) 
     363                spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_CHARM || 
     364                spellInfo->EffectApplyAuraName[i] == SPELL_AURA_BIND_SIGHT) 
    364365            { 
    365366                _player->RemoveAurasDueToSpellByCancel(spellId); 
    366                 _player->GetCharm()->RemoveAurasDueToSpellByCancel(spellId); 
     367                if (_player->GetCharm()) 
     368                    _player->GetCharm()->RemoveAurasDueToSpellByCancel(spellId); 
     369                else if (_player->GetFarsightTarget()->GetTypeId() != TYPEID_DYNAMICOBJECT) 
     370                    ((Unit*)_player->GetFarsightTarget())->RemoveAurasDueToSpellByCancel(spellId); 
    367371                return; 
    368372            } 
     
    465469 
    466470    Creature* totem = ObjectAccessor::GetCreature(*_player,_player->m_TotemSlot[slotId]); 
    467     if(totem && totem->isTotem()) 
     471    // Don't unsummon sentry totem 
     472    if(totem && totem->isTotem() && totem->GetEntry() != SENTRY_TOTEM_ENTRY) 
    468473        ((Totem*)totem)->UnSummon(); 
    469474} 
  • trunk/src/game/Totem.h

    r102 r233  
    3030    TOTEM_STATUE     = 2 
    3131}; 
     32 
     33#define SENTRY_TOTEM_ENTRY  3968 
    3234 
    3335class Totem : public Creature 
  • trunk/src/game/TotemAI.cpp

    r102 r233  
    123123TotemAI::AttackStart(Unit *) 
    124124{ 
     125    // Sentry totem sends ping on attack 
     126    if (i_totem.GetEntry() == SENTRY_TOTEM_ENTRY && i_totem.GetOwner()->GetTypeId() == TYPEID_PLAYER) 
     127    { 
     128        WorldPacket data(MSG_MINIMAP_PING, (8+4+4)); 
     129        data << i_totem.GetGUID(); 
     130        data << i_totem.GetPositionX(); 
     131        data << i_totem.GetPositionY(); 
     132        ((Player*)i_totem.GetOwner())->GetSession()->SendPacket(&data); 
     133    } 
    125134} 
  • trunk/src/game/Unit.cpp

    r232 r233  
    828828            he->DuelComplete(DUEL_INTERUPTED); 
    829829        } 
    830  
    831         // Possessed unit died, restore control to possessor 
    832         pVictim->UnpossessSelf(false); 
    833  
    834         // Possessor died, remove possession 
    835         if(pVictim->GetTypeId() == TYPEID_PLAYER && pVictim->isPossessing()) 
    836             ((Player*)pVictim)->RemovePossess(false); 
    837830 
    838831        // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill) 
     
    71847177} 
    71857178 
     7179void Unit::AddPlayerToVision(Player* plr)  
     7180{  
     7181    if (m_sharedVision.empty() && GetTypeId() == TYPEID_UNIT) 
     7182    { 
     7183        setActive(true); 
     7184        GetMap()->SwitchGridContainers((Creature*)this, true); 
     7185    } 
     7186    m_sharedVision.push_back(plr); 
     7187    plr->SetFarsightTarget(this); 
     7188} 
     7189 
     7190void Unit::RemovePlayerFromVision(Player* plr)  
     7191{  
     7192    m_sharedVision.remove(plr);  
     7193    if (m_sharedVision.empty() && GetTypeId() == TYPEID_UNIT) 
     7194    { 
     7195        setActive(false); 
     7196        GetMap()->SwitchGridContainers((Creature*)this, false); 
     7197    } 
     7198    plr->ClearFarsight(); 
     7199} 
     7200 
     7201void Unit::RemoveAllFromVision() 
     7202{ 
     7203    while (!m_sharedVision.empty()) 
     7204    { 
     7205        Player* plr = *m_sharedVision.begin(); 
     7206        m_sharedVision.erase(m_sharedVision.begin()); 
     7207        plr->ClearFarsight(); 
     7208    } 
     7209} 
     7210 
    71867211void Unit::UncharmSelf() 
    71877212{ 
     
    89368961        UnsummonAllTotems(); 
    89378962 
     8963        // Possessed unit died, restore control to possessor 
     8964        UnpossessSelf(false); 
     8965        RemoveAllFromVision(); 
     8966 
    89388967        ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false); 
    89398968        ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false); 
     
    97579786 
    97589787        UnpossessSelf(false); 
     9788        RemoveAllFromVision(); 
    97599789    } 
    97609790    RemoveFromWorld(); 
    97619791} 
     9792 
     9793 
    97629794 
    97639795CharmInfo* Unit::InitCharmInfo(Unit *charm) 
  • trunk/src/game/Unit.h

    r231 r233  
    639639}; 
    640640 
     641typedef std::list<Player*> SharedVisionList; 
     642 
    641643struct CharmInfo 
    642644{ 
     
    10191021        CharmInfo* GetCharmInfo() { return m_charmInfo; } 
    10201022        CharmInfo* InitCharmInfo(Unit* charm); 
     1023        SharedVisionList const& GetSharedVisionList() { return m_sharedVision; } 
     1024        void AddPlayerToVision(Player* plr); 
     1025        void RemovePlayerFromVision(Player* plr); 
     1026        void RemoveAllFromVision(); 
    10211027        void UncharmSelf(); 
    10221028        void UnpossessSelf(bool attack); 
     
    13511357        CharmInfo *m_charmInfo; 
    13521358        bool m_isPossessed; 
     1359        SharedVisionList m_sharedVision; 
    13531360 
    13541361        virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;