Changeset 174

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

[svn] Implemented player on player and player on creature possession:
* Implemented packet and vision forwarding through possessed units
* Added new OnPossess? script call alerting scripts on when possession is applied/removed
* Moved fall damage and fall under map calculations into the Player class
* Added new PossessedAI that is applied only while possession on creature is active
* Implemented summon possessed spell effect
* Fixed Eyes of the Beast

Original author: gvcoman
Date: 2008-11-05 20:51:05-06:00

Location:
trunk
Files:
3 added
38 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/bindings/scripts/include/sc_creature.h

    r153 r174  
    7575    //Called at waypoint reached or PointMovement end 
    7676    void MovementInform(uint32, uint32){} 
     77 
     78    // Called when AI is temporarily replaced or put back when possess is applied or removed 
     79    void OnPossess(bool apply) {} 
    7780 
    7881    //************* 
  • trunk/src/bindings/scripts/scripts/npc/npc_escortAI.cpp

    r158 r174  
    257257} 
    258258 
     259void npc_escortAI::OnPossess(bool apply) 
     260{ 
     261    // We got possessed in the middle of being escorted, store the point  
     262    // where we left off to come back to when possess is removed 
     263    if (IsBeingEscorted) 
     264    { 
     265        if (apply) 
     266            m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z); 
     267        else 
     268        { 
     269            Returning = true; 
     270            m_creature->GetMotionMaster()->MovementExpired(); 
     271            m_creature->GetMotionMaster()->MovePoint(WP_LAST_POINT, LastPos.x, LastPos.y, LastPos.z); 
     272        } 
     273    } 
     274} 
     275 
     276 
     277 
    259278void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs) 
    260279{ 
  • trunk/src/bindings/scripts/scripts/npc/npc_escortAI.h

    r90 r174  
    5252        void MovementInform(uint32, uint32); 
    5353 
     54        void OnPossess(bool apply); 
     55 
    5456        // EscortAI functions 
    5557        void AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs = 0); 
  • trunk/src/game/Chat.cpp

    r169 r174  
    561561                { "listfreeze",     SEC_ADMINISTRATOR,  false, &ChatHandler::HandleListFreezeCommand,          "", NULL },  
    562562                { "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand,   "", NULL },  
     563        { "possess",        SEC_ADMINISTRATOR,  false, &ChatHandler::HandlePossessCommand,             "", NULL }, 
     564        { "unpossess",      SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUnPossessCommand,           "", NULL }, 
    563565 
    564566                { NULL,             0,                  false, NULL,                                           "", NULL } 
  • trunk/src/game/Chat.h

    r168 r174  
    450450        bool HandleDebugThreatList(const char * args); 
    451451        bool HandleDebugHostilRefList(const char * args); 
     452        bool HandlePossessCommand(const char* args); 
     453        bool HandleUnPossessCommand(const char* args); 
    452454 
    453455        Player*   getSelectedPlayer(); 
  • trunk/src/game/Creature.cpp

    r173 r174  
    4747#include "OutdoorPvPMgr.h" 
    4848#include "GameEvent.h" 
     49#include "PossessedAI.h" 
    4950// apply implementation of the singletons 
    5051#include "Policies/SingletonImp.h" 
     
    118119 
    119120Creature::Creature() : 
    120 Unit(), i_AI(NULL), 
     121Unit(), i_AI(NULL), i_AI_possessed(NULL), 
    121122lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), 
    122123m_lootMoney(0), m_lootRecipient(0), 
     
    146147    delete i_AI; 
    147148    i_AI = NULL; 
     149 
     150    DeletePossessedAI(); 
    148151} 
    149152 
     
    365368 
    366369                //Call AI respawn virtual function 
    367                 i_AI->JustRespawned(); 
     370                AI()->JustRespawned(); 
    368371 
    369372                MapManager::Instance().GetMap(GetMapId(), this)->Add(this); 
     
    429432                // do not allow the AI to be changed during update 
    430433                m_AI_locked = true; 
    431                 i_AI->UpdateAI(diff); 
     434                AI()->UpdateAI(diff); 
    432435                m_AI_locked = false; 
    433436            } 
     
    526529    } 
    527530 
     531    // don't allow AI switch when possessed 
     532    if (isPossessed()) 
     533        return false; 
     534 
    528535    CreatureAI * oldAI = i_AI; 
    529536    i_motionMaster.Initialize(); 
     
    532539        delete oldAI; 
    533540    return true; 
     541} 
     542 
     543void Creature::InitPossessedAI() 
     544{ 
     545    if (!isPossessed()) return; 
     546 
     547    if (!i_AI_possessed) 
     548        i_AI_possessed = new PossessedAI(*this); 
     549 
     550    // Signal the old AI that it's been disabled 
     551    i_AI->OnPossess(true); 
     552} 
     553 
     554void Creature::DeletePossessedAI() 
     555{ 
     556    if (!i_AI_possessed) return; 
     557 
     558    delete i_AI_possessed; 
     559    i_AI_possessed = NULL; 
     560 
     561    // Signal the old AI that it's been re-enabled 
     562    i_AI->OnPossess(false); 
    534563} 
    535564 
  • trunk/src/game/Creature.h

    r168 r174  
    396396{ 
    397397    CreatureAI *i_AI; 
     398    CreatureAI *i_AI_possessed; 
    398399 
    399400    public: 
     
    456457 
    457458        bool AIM_Initialize(); 
     459        void InitPossessedAI(); 
     460        void DeletePossessedAI(); 
    458461 
    459462        void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type); 
    460         CreatureAI* AI() { return i_AI; } 
     463        CreatureAI* AI() { return isPossessed() && i_AI_possessed ? i_AI_possessed : i_AI; } 
    461464 
    462465        uint32 GetShieldBlockValue() const                  //dunno mob block value 
  • trunk/src/game/CreatureAI.h

    r130 r174  
    122122        // Called at waypoint reached or point movement finished 
    123123        virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {} 
     124 
     125        // Called when AI is temporarily replaced or put back when possess is applied or removed 
     126        virtual void OnPossess(bool apply) {} 
    124127}; 
    125128 
  • trunk/src/game/CreatureAIRegistry.cpp

    r145 r174  
    2525#include "GuardAI.h" 
    2626#include "PetAI.h" 
     27#include "PossessedAI.h" 
    2728#include "TotemAI.h" 
    2829#include "OutdoorPvPObjectiveAI.h" 
     
    4546        (new CreatureAIFactory<TotemAI>("TotemAI"))->RegisterSelf(); 
    4647        (new CreatureAIFactory<OutdoorPvPObjectiveAI>("OutdoorPvPObjectiveAI"))->RegisterSelf(); 
     48        (new CreatureAIFactory<PossessedAI>("PossessedAI"))->RegisterSelf(); 
    4749 
    4850        (new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf(); 
  • trunk/src/game/CreatureAISelector.cpp

    r102 r174  
    5757            if( creature->isGuard() ) 
    5858                ai_factory = ai_registry.GetRegistryItem("GuardAI");  
    59             else if(creature->isPet() || creature->isCharmed()) 
     59            else if(creature->isPet() || (creature->isCharmed() && !creature->isPossessed())) 
    6060                ai_factory = ai_registry.GetRegistryItem("PetAI"); 
    6161            else if(creature->isTotem()) 
     
    6363            else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) 
    6464                ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); 
     65            else if(creature->isPossessed()) 
     66                creature->InitPossessedAI(); 
    6567        } 
    6668 
  • trunk/src/game/GridNotifiers.cpp

    r102 r174  
    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()); 
    4345    } 
    4446} 
     
    140142} 
    141143 
    142 void 
    143 MessageDeliverer::Visit(PlayerMapType &m) 
    144 { 
    145     for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) 
    146     { 
    147         if( i_toSelf || iter->getSource() != &i_player) 
    148         { 
    149             if(WorldSession* session = iter->getSource()->GetSession()) 
    150                 session->SendPacket(i_message); 
    151         } 
    152     } 
    153 } 
    154  
    155 void 
    156 ObjectMessageDeliverer::Visit(PlayerMapType &m) 
    157 { 
    158     for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) 
    159     { 
    160         if(WorldSession* session = iter->getSource()->GetSession()) 
     144void  
     145Deliverer::Visit(PlayerMapType &m) 
     146{ 
     147    for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) 
     148    { 
     149        if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist) 
     150        { 
     151            // Send packet to possessor 
     152            if (iter->getSource()->isPossessedByPlayer()) 
     153                SendPacket((Player*)iter->getSource()->GetCharmer()); 
     154            VisitObject(iter->getSource()); 
     155        } 
     156    } 
     157} 
     158 
     159void  
     160Deliverer::Visit(CreatureMapType &m) 
     161{ 
     162    for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) 
     163    { 
     164        if (!i_dist || iter->getSource()->GetDistance(&i_source) <= i_dist) 
     165        { 
     166            // Send packet to possessor 
     167            if (iter->getSource()->isPossessedByPlayer()) 
     168                SendPacket((Player*)iter->getSource()->GetCharmer()); 
     169        } 
     170    } 
     171} 
     172 
     173void 
     174Deliverer::SendPacket(Player* plr) 
     175{ 
     176    if (!plr) 
     177        return; 
     178    // Don't send the packet to possesor if not supposed to 
     179    if (!i_toPossessor && plr->isPossessing() && plr->GetCharmGUID() == i_source.GetGUID()) 
     180        return; 
     181 
     182    if (plr_list.find(plr->GetGUID()) == plr_list.end()) 
     183    { 
     184        if (WorldSession* session = plr->GetSession()) 
    161185            session->SendPacket(i_message); 
    162     } 
    163 } 
    164  
    165 void 
    166 MessageDistDeliverer::Visit(PlayerMapType &m) 
    167 { 
    168     for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) 
    169     { 
    170         if( (i_toSelf || iter->getSource() != &i_player ) && 
    171             (!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) && 
    172             (!i_dist || iter->getSource()->GetDistance(&i_player) <= i_dist) ) 
    173         { 
    174             if(WorldSession* session = iter->getSource()->GetSession()) 
    175                 session->SendPacket(i_message); 
    176         } 
    177     } 
    178 } 
    179  
    180 void 
    181 ObjectMessageDistDeliverer::Visit(PlayerMapType &m) 
    182 { 
    183     for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) 
    184     { 
    185         if( !i_dist || iter->getSource()->GetDistance(&i_object) <= i_dist ) 
    186         { 
    187             if(WorldSession* session = iter->getSource()->GetSession()) 
    188                 session->SendPacket(i_message); 
    189         } 
     186        plr_list.insert(plr->GetGUID()); 
     187    } 
     188} 
     189 
     190void 
     191MessageDeliverer::VisitObject(Player* plr) 
     192{ 
     193    if (i_toSelf || plr != &i_source) 
     194        SendPacket(plr); 
     195} 
     196 
     197void 
     198MessageDistDeliverer::VisitObject(Player* plr) 
     199{ 
     200    if( (i_toSelf || plr != &i_source ) && 
     201        (!i_ownTeamOnly || (i_source.GetTypeId() == TYPEID_PLAYER && plr->GetTeam() == ((Player&)i_source).GetTeam())) ) 
     202    { 
     203        SendPacket(plr); 
    190204    } 
    191205} 
  • trunk/src/game/GridNotifiers.h

    r102 r174  
    9090    }; 
    9191 
    92     struct TRINITY_DLL_DECL MessageDeliverer 
    93     { 
    94         Player &i_player; 
     92    struct TRINITY_DLL_DECL Deliverer 
     93    { 
     94        WorldObject &i_source; 
    9595        WorldPacket *i_message; 
     96        std::set<uint64> plr_list; 
     97        bool i_toPossessor; 
     98        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        void Visit(PlayerMapType &m); 
     101        void Visit(CreatureMapType &m); 
     102        virtual void VisitObject(Player* plr) = 0; 
     103        void SendPacket(Player* plr); 
     104        template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 
     105    }; 
     106         
     107    struct TRINITY_DLL_DECL MessageDeliverer : public Deliverer 
     108    { 
    96109        bool i_toSelf; 
    97         MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {} 
    98         void Visit(PlayerMapType &m); 
    99         template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 
    100     }; 
    101  
    102     struct TRINITY_DLL_DECL ObjectMessageDeliverer 
    103     { 
    104         WorldPacket *i_message; 
    105         explicit ObjectMessageDeliverer(WorldPacket *msg) : i_message(msg) {} 
    106         void Visit(PlayerMapType &m); 
    107         template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 
    108     }; 
    109  
    110     struct TRINITY_DLL_DECL MessageDistDeliverer 
    111     { 
    112         Player &i_player; 
    113         WorldPacket *i_message; 
     110        MessageDeliverer(Player &pl, WorldPacket *msg, bool to_possessor, bool to_self) : Deliverer(pl, msg, to_possessor), i_toSelf(to_self) {} 
     111        void VisitObject(Player* plr); 
     112    }; 
     113 
     114    struct TRINITY_DLL_DECL ObjectMessageDeliverer : public Deliverer 
     115    { 
     116        explicit ObjectMessageDeliverer(WorldObject &src, WorldPacket *msg, bool to_possessor) : Deliverer(src, msg, to_possessor) {} 
     117        void VisitObject(Player* plr) { SendPacket(plr); } 
     118    }; 
     119 
     120    struct TRINITY_DLL_DECL MessageDistDeliverer : public Deliverer 
     121    { 
    114122        bool i_toSelf; 
    115123        bool i_ownTeamOnly; 
    116         float i_dist; 
    117         MessageDistDeliverer(Player &pl, WorldPacket *msg, float dist, bool to_self, bool ownTeamOnly) : i_player(pl), i_message(msg), i_dist(dist), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly) {} 
    118         void Visit(PlayerMapType &m); 
    119         template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 
    120     }; 
    121  
    122     struct TRINITY_DLL_DECL ObjectMessageDistDeliverer 
    123     { 
    124         WorldObject &i_object; 
    125         WorldPacket *i_message; 
    126         float i_dist; 
    127         ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {} 
    128         void Visit(PlayerMapType &m); 
    129         template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 
     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) {} 
     125        void VisitObject(Player* plr); 
     126    }; 
     127 
     128    struct TRINITY_DLL_DECL ObjectMessageDistDeliverer : public Deliverer 
     129    { 
     130        ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, bool to_possessor, float dist) : Deliverer(obj, msg, to_possessor, dist) {} 
     131        void VisitObject(Player* plr) { SendPacket(plr); } 
    130132    }; 
    131133 
  • trunk/src/game/Level3.cpp

    r173 r174  
    65456545    return true; 
    65466546} 
     6547 
     6548bool ChatHandler::HandlePossessCommand(const char* args) 
     6549{ 
     6550    Unit* pUnit = getSelectedUnit(); 
     6551    if(!pUnit) 
     6552        return false; 
     6553 
     6554    // Don't allow unlimited possession of players 
     6555    if (pUnit->GetTypeId() == TYPEID_PLAYER) 
     6556        return false; 
     6557 
     6558    m_session->GetPlayer()->Possess(pUnit); 
     6559 
     6560    return true; 
     6561} 
     6562 
     6563bool ChatHandler::HandleUnPossessCommand(const char* args) 
     6564{ 
     6565    // Use this command to also unpossess ourselves 
     6566    if (m_session->GetPlayer()->isPossessed()) 
     6567        m_session->GetPlayer()->UnpossessSelf(false); 
     6568    else 
     6569        m_session->GetPlayer()->RemovePossess(false); 
     6570 
     6571    return true; 
     6572} 
  • trunk/src/game/Makefile.am

    r102 r174  
    218218$(srcdir)/PointMovementGenerator.cpp \ 
    219219$(srcdir)/PointMovementGenerator.h \ 
     220$(srcdir)/PossessedAI.cpp \ 
     221$(srcdir)/PossessedAI.h \ 
    220222$(srcdir)/QueryHandler.cpp \ 
    221223$(srcdir)/QuestDef.cpp \ 
  • trunk/src/game/Map.cpp

    r173 r174  
    256256{ 
    257257    // add to world object registry in grid 
    258     if(obj->isPet()) 
     258    if(obj->isPet() || obj->isPossessedByPlayer()) 
    259259    { 
    260260        (*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID()); 
     
    300300{ 
    301301    // remove from world object registry in grid 
    302     if(obj->isPet()) 
     302    if(obj->isPet() || obj->isPossessedByPlayer()) 
    303303    { 
    304304        (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID()); 
     
    310310    } 
    311311} 
     312 
     313template<class T> 
     314void Map::SwitchGridContainers(T* obj, bool active) 
     315{ 
     316    CellPair pair = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); 
     317    Cell cell(pair); 
     318    NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); 
     319 
     320    if (active) 
     321    { 
     322        (*grid)(cell.CellX(), cell.CellY()).RemoveGridObject<T>(obj, obj->GetGUID()); 
     323        (*grid)(cell.CellX(), cell.CellY()).AddWorldObject<T>(obj, obj->GetGUID()); 
     324    } else 
     325    { 
     326        (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<T>(obj, obj->GetGUID()); 
     327        (*grid)(cell.CellX(), cell.CellY()).AddGridObject<T>(obj, obj->GetGUID()); 
     328    } 
     329} 
     330 
     331template void Map::SwitchGridContainers(Creature *, bool); 
     332template void Map::SwitchGridContainers(Corpse *, bool); 
    312333 
    313334template<class T> 
     
    468489} 
    469490 
    470 void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self) 
     491void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self, bool to_possessor) 
    471492{ 
    472493    CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); 
     
    484505        return; 
    485506 
    486     Trinity::MessageDeliverer post_man(*player, msg, to_self); 
     507    Trinity::MessageDeliverer post_man(*player, msg, to_possessor, to_self); 
    487508    TypeContainerVisitor<Trinity::MessageDeliverer, WorldTypeMapContainer > message(post_man); 
    488509    CellLock<ReadGuard> cell_lock(cell, p); 
     
    490511} 
    491512 
    492 void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg) 
     513void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg, bool to_possessor) 
    493514{ 
    494515    CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); 
     
    507528        return; 
    508529 
    509     Trinity::ObjectMessageDeliverer post_man(msg); 
     530    Trinity::ObjectMessageDeliverer post_man(*obj, msg, to_possessor); 
    510531    TypeContainerVisitor<Trinity::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man); 
    511532    CellLock<ReadGuard> cell_lock(cell, p); 
     
    513534} 
    514535 
    515 void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only) 
     536void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only, bool to_possessor) 
    516537{ 
    517538    CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); 
     
    529550        return; 
    530551 
    531     Trinity::MessageDistDeliverer post_man(*player, msg, dist, to_self, own_team_only); 
     552    Trinity::MessageDistDeliverer post_man(*player, msg, to_possessor, dist, to_self, own_team_only); 
    532553    TypeContainerVisitor<Trinity::MessageDistDeliverer , WorldTypeMapContainer > message(post_man); 
    533554    CellLock<ReadGuard> cell_lock(cell, p); 
     
    535556} 
    536557 
    537 void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist) 
     558void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist, bool to_possessor) 
    538559{ 
    539560    CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); 
     
    552573        return; 
    553574 
    554     Trinity::ObjectMessageDistDeliverer post_man(*obj, msg,dist); 
     575    Trinity::ObjectMessageDistDeliverer post_man(*obj, msg, to_possessor, dist); 
    555576    TypeContainerVisitor<Trinity::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man); 
    556577    CellLock<ReadGuard> cell_lock(cell, p); 
     
    650671 
    651672    obj->RemoveFromWorld(); 
     673 
    652674    RemoveFromGrid(obj,grid,cell); 
    653675 
     
    698720    UpdatePlayerVisibility(player,new_cell,new_val); 
    699721    UpdateObjectsVisibilityFor(player,new_cell,new_val); 
     722 
     723    // also update what possessing player sees 
     724    if(player->isPossessedByPlayer()) 
     725        UpdateObjectsVisibilityFor((Player*)player->GetCharmer(), new_cell, new_val); 
     726 
    700727    PlayerRelocationNotify(player,new_cell,new_val); 
    701728    NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY()); 
     
    726753        AddCreatureToMoveList(creature,x,y,z,ang); 
    727754        // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList 
     755        if(creature->isPossessedByPlayer()) 
     756            EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false); 
    728757    } 
    729758    else 
    730759    { 
    731760        creature->Relocate(x, y, z, ang); 
     761        // Update visibility back to player who is controlling the creature 
     762        if(creature->isPossessedByPlayer()) 
     763            UpdateObjectsVisibilityFor((Player*)creature->GetCharmer(), new_cell, new_val); 
     764 
    732765        CreatureRelocationNotify(creature,new_cell,new_val); 
    733766    } 
  • trunk/src/game/Map.h

    r102 r174  
    141141        virtual void Update(const uint32&); 
    142142 
    143         void MessageBroadcast(Player *, WorldPacket *, bool to_self); 
    144         void MessageBroadcast(WorldObject *, WorldPacket *); 
    145         void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool own_team_only = false); 
    146         void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist); 
     143        void MessageBroadcast(Player *, WorldPacket *, bool to_self, bool to_possessor); 
     144        void MessageBroadcast(WorldObject *, WorldPacket *, bool to_possessor); 
     145        void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool to_possessor, bool own_team_only = false); 
     146        void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist, bool to_possessor); 
    147147 
    148148        void PlayerRelocation(Player *, float x, float y, float z, float angl); 
     
    237237        Creature* GetCreatureInMap(uint64 guid); 
    238238        GameObject* GetGameObjectInMap(uint64 guid); 
     239 
     240        template<class T> void SwitchGridContainers(T* obj, bool active); 
    239241    private: 
    240242        void LoadVMap(int pX, int pY); 
  • trunk/src/game/MovementHandler.cpp

    r102 r174  
    190190    CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4); 
    191191 
    192     if(GetPlayer()->GetDontMove()) 
    193         return; 
    194  
    195192    /* extract packet */ 
    196193    MovementInfo movementInfo; 
     
    205202    recv_data >> movementInfo.o; 
    206203 
    207     //Save movement flags 
    208     _player->SetUnitMovementFlags(MovementFlags); 
    209  
    210204    if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT) 
    211205    { 
     
    264258        return; 
    265259 
     260    // Handle possessed unit movement separately 
     261    Unit* pos_unit = GetPlayer()->GetCharm(); 
     262    if (pos_unit && pos_unit->isPossessed()) // can be charmed but not possessed 
     263    { 
     264        HandlePossessedMovement(recv_data, movementInfo, MovementFlags); 
     265        return; 
     266    } 
     267 
     268    if (GetPlayer()->GetDontMove()) 
     269        return; 
     270 
     271    //Save movement flags 
     272    GetPlayer()->SetUnitMovementFlags(MovementFlags); 
     273 
    266274    /* handle special cases */ 
    267275    if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT) 
     
    285293                { 
    286294                    // unmount before boarding 
    287                     _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); 
     295                    GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); 
    288296 
    289297                    GetPlayer()->m_transport = (*iter); 
     
    305313    } 
    306314 
    307     // fall damage generation (ignore in flight case that can be triggred also at lags in moment teleportation to another map). 
    308     if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight()) 
    309     { 
    310         Player *target = GetPlayer(); 
    311  
    312         //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored 
    313         if (movementInfo.fallTime > 1100 && !target->isDead() && !target->isGameMaster() && 
    314             !target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL) && 
    315             !target->HasAuraType(SPELL_AURA_FLY) && !target->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) ) 
    316         { 
    317             //Safe fall, fall time reduction 
    318             int32 safe_fall = target->GetTotalAuraModifier(SPELL_AURA_SAFE_FALL); 
    319             uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0; 
    320  
    321             if(fall_time > 1100)                            //Prevent damage if fall time < 1100 
    322             { 
    323                 //Fall Damage calculation 
    324                 float fallperc = float(fall_time)/1100; 
    325                 uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * target->GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL)); 
    326  
    327                 float height = movementInfo.z; 
    328                 target->UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height); 
    329  
    330                 if (damage > 0) 
    331                 { 
    332                     //Prevent fall damage from being more than the player maximum health 
    333                     if (damage > target->GetMaxHealth()) 
    334                         damage = target->GetMaxHealth(); 
    335  
    336                     // Gust of Wind 
    337                     if (target->GetDummyAura(43621)) 
    338                         damage = target->GetMaxHealth()/2; 
    339  
    340                     target->EnvironmentalDamage(target->GetGUID(), DAMAGE_FALL, damage); 
    341                 } 
    342  
    343                 //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction 
    344                 DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, target->GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall); 
    345             } 
    346         } 
    347  
    348         //handle fall and logout at the same time (logout started before fall finished) 
    349         /* outdated and create problems with sit at stun sometime 
    350         if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE)) 
    351         { 
    352             target->SetStandState(PLAYER_STATE_SIT); 
    353             // Can't move 
    354             WorldPacket data( SMSG_FORCE_MOVE_ROOT, 12 ); 
    355             data.append(target->GetPackGUID()); 
    356             data << (uint32)2; 
    357             SendPacket( &data ); 
    358         } 
    359         */ 
    360     } 
     315    // handle fall damage 
     316    if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND) 
     317        GetPlayer()->HandleFallDamage(movementInfo); 
    361318 
    362319    if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater()) 
     
    382339 
    383340    if(movementInfo.z < -500.0f) 
    384     { 
    385         if(GetPlayer()->InBattleGround()  
    386             && GetPlayer()->GetBattleGround()  
    387             && GetPlayer()->GetBattleGround()->HandlePlayerUnderMap(_player)) 
    388         { 
    389             // do nothing, the handle already did if returned true 
    390         } 
    391         else 
    392         { 
    393             // NOTE: this is actually called many times while falling 
    394             // even after the player has been teleported away 
    395             // TODO: discard movement packets after the player is rooted 
    396             if(GetPlayer()->isAlive()) 
    397             { 
    398                 GetPlayer()->EnvironmentalDamage(GetPlayer()->GetGUID(),DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); 
    399                 // change the death state to CORPSE to prevent the death timer from 
    400                 // starting in the next player update 
    401                 GetPlayer()->KillPlayer(); 
    402                 GetPlayer()->BuildPlayerRepop(); 
    403             } 
    404  
    405             // cancel the death timer here if started 
    406             GetPlayer()->RepopAtGraveyard(); 
    407         } 
     341        GetPlayer()->HandleFallUnderMap(); 
     342} 
     343 
     344void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags) 
     345{ 
     346    // Whatever the client is controlling, it will send the GUID of the original player. 
     347    // If current player is controlling, it must be handled like the controlled player sent these opcodes 
     348 
     349    Unit* pos_unit = GetPlayer()->GetCharm(); 
     350 
     351    if (pos_unit->GetTypeId() == TYPEID_PLAYER && ((Player*)pos_unit)->GetDontMove()) 
     352        return; 
     353 
     354    //Save movement flags 
     355    pos_unit->SetUnitMovementFlags(MovementFlags); 
     356 
     357    // Remove possession if possessed unit enters a transport 
     358    if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT) 
     359    { 
     360        GetPlayer()->RemovePossess(true); 
     361        return; 
     362    } 
     363 
     364    recv_data.put<uint32>(5, getMSTime()); 
     365    WorldPacket data(recv_data.GetOpcode(), pos_unit->GetPackGUID().size()+recv_data.size()); 
     366    data.append(pos_unit->GetPackGUID()); 
     367    data.append(recv_data.contents(), recv_data.size()); 
     368    // Send the packet to self but not to the possessed player; for creatures the first bool is irrelevant 
     369    pos_unit->SendMessageToSet(&data, true, false); 
     370 
     371    // Possessed is a player 
     372    if (pos_unit->GetTypeId() == TYPEID_PLAYER) 
     373    { 
     374        Player* plr = (Player*)pos_unit; 
     375         
     376        if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND) 
     377            plr->HandleFallDamage(movementInfo); 
     378 
     379        if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != plr->IsInWater()) 
     380        { 
     381            // Now client not include swimming flag in case jumping under water 
     382            plr->SetInWater( !plr->IsInWater() || plr->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) ); 
     383        } 
     384         
     385        plr->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o, false); 
     386        plr->m_movementInfo = movementInfo; 
     387 
     388        if(plr->isMovingOrTurning()) 
     389            plr->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); 
     390 
     391        if(movementInfo.z < -500.0f) 
     392        { 
     393            GetPlayer()->RemovePossess(false); 
     394            plr->HandleFallUnderMap(); 
     395        } 
     396    }  
     397    else // Possessed unit is a creature 
     398    { 
     399        Map* map = MapManager::Instance().GetMap(pos_unit->GetMapId(), pos_unit); 
     400        map->CreatureRelocation((Creature*)pos_unit, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); 
    408401    } 
    409402} 
  • trunk/src/game/Object.cpp

    r145 r174  
    14121412} 
    14131413 
    1414 void WorldObject::SendMessageToSet(WorldPacket *data, bool /*bToSelf*/) 
    1415 { 
    1416     MapManager::Instance().GetMap(m_mapId, this)->MessageBroadcast(this, data); 
    1417 } 
    1418  
    1419 void WorldObject::SendMessageToSetInRange(WorldPacket *data, float dist, bool /*bToSelf*/) 
    1420 { 
    1421     MapManager::Instance().GetMap(m_mapId, this)->MessageDistBroadcast(this, data, dist); 
     1414void WorldObject::SendMessageToSet(WorldPacket *data, bool /*fake*/, bool bToPossessor) 
     1415{ 
     1416    MapManager::Instance().GetMap(m_mapId, this)->MessageBroadcast(this, data, bToPossessor); 
     1417} 
     1418 
     1419void WorldObject::SendMessageToSetInRange(WorldPacket *data, float dist, bool /*bToSelf*/, bool bToPossessor) 
     1420{ 
     1421    MapManager::Instance().GetMap(m_mapId, this)->MessageDistBroadcast(this, data, dist, bToPossessor); 
    14221422} 
    14231423 
  • trunk/src/game/Object.h

    r141 r174  
    414414        bool HasInArc( const float arcangle, const WorldObject* obj ) const; 
    415415 
    416         virtual void SendMessageToSet(WorldPacket *data, bool self); 
    417         virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self); 
     416        virtual void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true); 
     417        virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor = true); 
    418418        void BuildHeartBeatMsg( WorldPacket *data ) const; 
    419419        void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const; 
  • trunk/src/game/ObjectAccessor.cpp

    r126 r174  
    623623{ 
    624624    for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) 
    625         if(iter->getSource()->HaveAtClient(&i_object)) 
    626             ObjectAccessor::_buildPacket(iter->getSource(), &i_object, i_updateDatas); 
     625    { 
     626        BuildPacket(iter->getSource()); 
     627        if (iter->getSource()->isPossessedByPlayer()) 
     628            BuildPacket((Player*)iter->getSource()->GetCharmer()); 
     629    } 
     630} 
     631 
     632void 
     633ObjectAccessor::WorldObjectChangeAccumulator::Visit(CreatureMapType &m) 
     634{ 
     635    for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) 
     636        if (iter->getSource()->isPossessedByPlayer()) 
     637            BuildPacket((Player*)iter->getSource()->GetCharmer()); 
     638} 
     639 
     640void 
     641ObjectAccessor::WorldObjectChangeAccumulator::BuildPacket(Player* plr) 
     642{ 
     643    // Only send update once to a player 
     644    if (plr_list.find(plr->GetGUID()) == plr_list.end() && plr->HaveAtClient(&i_object)) 
     645    { 
     646        ObjectAccessor::_buildPacket(plr, &i_object, i_updateDatas); 
     647        plr_list.insert(plr->GetGUID()); 
     648    } 
    627649} 
    628650 
  • trunk/src/game/ObjectAccessor.h

    r120 r174  
    209209            UpdateDataMapType &i_updateDatas; 
    210210            WorldObject &i_object; 
     211            std::set<uint64> plr_list; 
    211212            WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {} 
    212213            void Visit(PlayerMapType &); 
     214            void Visit(CreatureMapType &); 
     215            void BuildPacket(Player* plr); 
    213216            template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 
    214217        }; 
  • trunk/src/game/Pet.cpp

    r152 r174  
    549549            // unsummon pet that lost owner 
    550550            Unit* owner = GetOwner(); 
    551             if(!owner || !IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) || isControlled() && !owner->GetPetGUID()) 
     551            if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && !isPossessed()) || isControlled() && !owner->GetPetGUID()) 
    552552            { 
    553553                Remove(PET_SAVE_NOT_IN_SLOT, true); 
  • trunk/src/game/PetHandler.cpp

    r152 r174  
    110110                    if(pet->GetTypeId() != TYPEID_PLAYER) 
    111111                    { 
    112                         pet->GetMotionMaster()->Clear(); 
    113112                        if (((Creature*)pet)->AI()) 
    114113                            ((Creature*)pet)->AI()->AttackStart(TargetUnit); 
     
    140139                            p->setDeathState(CORPSE); 
    141140                    } 
    142                     else                                    // charmed 
    143                         _player->Uncharm(); 
     141                    else                                    // charmed or possessed 
     142                    { 
     143                        if (_player->isPossessing()) 
     144                            _player->RemovePossess(true); 
     145                        else 
     146                            _player->Uncharm(); 
     147                    } 
    144148                    break; 
    145149                default: 
     
    195199 
    196200                                                            //auto turn to target unless possessed 
    197             if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) 
     201            if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed()) 
    198202            { 
    199203                pet->SetInFront(unit_target); 
     
    223227                } 
    224228 
    225                 if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) 
     229                if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed()) 
    226230                { 
    227231                    pet->clearUnitState(UNIT_STAT_FOLLOW); 
     
    237241            else 
    238242            { 
    239                 if(pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) 
     243                if(pet->isPossessed()) 
    240244                { 
    241245                    WorldPacket data(SMSG_CAST_FAILED, (4+1+1)); 
     
    479483        else if(pet->GetGUID() == _player->GetCharmGUID()) 
    480484        { 
    481             _player->Uncharm(); 
     485            if (_player->isPossessing()) 
     486                _player->RemovePossess(true); 
     487            else 
     488                _player->Uncharm(); 
    482489        } 
    483490    } 
     
    602609    recvPacket >> guid >> spellid; 
    603610 
     611    // This opcode is also sent from charmed and possessed units (players and creatures) 
    604612    if(!_player->GetPet() && !_player->GetCharm()) 
    605613        return; 
    606614 
    607     if(ObjectAccessor::FindPlayer(guid)) 
    608         return; 
    609  
    610     Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid); 
    611  
    612     if(!pet || (pet != _player->GetPet() && pet!= _player->GetCharm())) 
     615    Unit* caster = ObjectAccessor::GetUnit(*_player, guid); 
     616 
     617    if(!caster || (caster != _player->GetPet() && caster != _player->GetCharm())) 
    613618    { 
    614619        sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() ); 
     
    616621    } 
    617622 
    618     if (pet->GetGlobalCooldown() > 0) 
     623    if (caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->GetGlobalCooldown() > 0) 
    619624        return; 
    620625 
     
    627632 
    628633    // do not cast not learned spells 
    629     if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) 
     634    if(!caster->HasSpell(spellid) || IsPassiveSpell(spellid)) 
    630635        return; 
    631636 
    632637    SpellCastTargets targets; 
    633     if(!targets.read(&recvPacket,pet)) 
    634         return; 
    635  
    636     pet->clearUnitState(UNIT_STAT_FOLLOW); 
    637  
    638     Spell *spell = new Spell(pet, spellInfo, false); 
     638    if(!targets.read(&recvPacket,caster)) 
     639        return; 
     640 
     641    caster->clearUnitState(UNIT_STAT_FOLLOW); 
     642 
     643    Spell *spell = new Spell(caster, spellInfo, false); 
    639644    spell->m_targets = targets; 
    640645 
     
    642647    if(result == -1) 
    643648    { 
    644         pet->AddCreatureSpellCooldown(spellid); 
    645         if(pet->isPet()) 
    646         { 
    647             Pet* p = (Pet*)pet; 
    648             p->CheckLearning(spellid); 
    649             //10% chance to play special pet attack talk, else growl 
    650             //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell 
    651             if(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10)) 
    652                 pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); 
    653             else 
    654                 pet->SendPetAIReaction(guid); 
     649        if(caster->GetTypeId() == TYPEID_UNIT) 
     650        { 
     651            Creature* pet = (Creature*)caster; 
     652            pet->AddCreatureSpellCooldown(spellid); 
     653            if(pet->isPet()) 
     654            { 
     655                Pet* p = (Pet*)pet; 
     656                p->CheckLearning(spellid); 
     657                // 10% chance to play special pet attack talk, else growl 
     658                // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell 
     659                if(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10)) 
     660                    pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL); 
     661                else 
     662                    pet->SendPetAIReaction(guid); 
     663            } 
    655664        } 
    656665 
     
    659668    else 
    660669    { 
    661         pet->SendPetCastFail(spellid, result); 
    662         if(!pet->HasSpellCooldown(spellid)) 
    663             pet->SendPetClearCooldown(spellid); 
     670        caster->SendPetCastFail(spellid, result); 
     671        if(caster->GetTypeId() == TYPEID_PLAYER) 
     672        { 
     673            if(!((Player*)caster)->HasSpellCooldown(spellid)) 
     674                caster->SendPetClearCooldown(spellid); 
     675        } 
     676        else 
     677        { 
     678            if(!((Creature*)caster)->HasSpellCooldown(spellid)) 
     679                caster->SendPetClearCooldown(spellid); 
     680        } 
    664681 
    665682        spell->finish(false); 
  • trunk/src/game/Player.cpp

    r168 r174  
    470470            itr->second.save->RemovePlayer(this); 
    471471 
     472    if (isPossessing()) 
     473        RemovePossess(false); 
     474 
    472475    delete m_declinedname; 
    473476} 
     
    12541257 
    12551258    Pet* pet = GetPet(); 
    1256     if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE)) 
     1259    if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && !pet->isPossessed()) 
    12571260    { 
    12581261        RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); 
     
    15351538    SetSemaphoreTeleport(true); 
    15361539 
     1540    // Remove any possession on the player before teleporting 
     1541    if (isPossessedByPlayer()) 
     1542        ((Player*)GetCharmer())->RemovePossess(); 
     1543 
    15371544    // The player was ported to another map and looses the duel immediatly. 
    15381545    // We have to perform this check before the teleport, otherwise the 
     
    17481755    { 
    17491756        ///- Release charmed creatures, unsummon totems and remove pets/guardians 
     1757        RemovePossess(false); 
    17501758        Uncharm(); 
    17511759        UnsummonAllTotems(); 
     
    52675275} 
    52685276 
    5269 void Player::SendMessageToSet(WorldPacket *data, bool self) 
    5270 { 
    5271     MapManager::Instance().GetMap(GetMapId(), this)->MessageBroadcast(this, data, self); 
    5272 } 
    5273  
    5274 void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self) 
    5275 { 
    5276     MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self); 
    5277 } 
    5278  
    5279 void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only) 
    5280 { 
    5281     MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self,own_team_only); 
     5277void Player::SendMessageToSet(WorldPacket *data, bool self, bool to_possessor) 
     5278{ 
     5279    MapManager::Instance().GetMap(GetMapId(), this)->MessageBroadcast(this, data, self, to_possessor); 
     5280} 
     5281 
     5282void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor) 
     5283{ 
     5284    MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self, to_possessor); 
     5285} 
     5286 
     5287void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only, bool to_possessor) 
     5288{ 
     5289    MapManager::Instance().GetMap(GetMapId(), this)->MessageDistBroadcast(this, data, dist, self, to_possessor, own_team_only); 
    52825290} 
    52835291 
     
    1597415982 
    1597515983    charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM); 
    15976     charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS); 
    1597715984} 
    1597815985 
     
    1600716014    WorldPacket data(SMSG_MESSAGECHAT, 200); 
    1600816015    BuildPlayerChat(&data, CHAT_MSG_EMOTE, text, LANG_UNIVERSAL); 
    16009     SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true, !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) ); 
     16016    SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true, !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT), true ); 
    1601016017} 
    1601116018 
     
    1850618513} 
    1850718514 
    18508 bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const 
    18509 { 
    18510     for(ItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end();++itr) 
    18511         if(itr->pos == this->pos) 
    18512             return true; 
    18513  
    18514     return false; 
     18515void Player::HandleFallDamage(MovementInfo& movementInfo) 
     18516{ 
     18517    //Players with Feather Fall or low fall time, or physical immunity (charges used) are ignored 
     18518    if (!isInFlight() && movementInfo.fallTime > 1100 && !isDead() && !isGameMaster() && 
     18519        !HasAuraType(SPELL_AURA_HOVER) && !HasAuraType(SPELL_AURA_FEATHER_FALL) && 
     18520        !HasAuraType(SPELL_AURA_FLY) && !IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL,true) ) 
     18521    { 
     18522        //Safe fall, fall time reduction 
     18523        int32 safe_fall = GetTotalAuraModifier(SPELL_AURA_SAFE_FALL); 
     18524        uint32 fall_time = (movementInfo.fallTime > (safe_fall*10)) ? movementInfo.fallTime - (safe_fall*10) : 0; 
     18525 
     18526        if(fall_time > 1100)                            //Prevent damage if fall time < 1100 
     18527        { 
     18528            //Fall Damage calculation 
     18529            float fallperc = float(fall_time)/1100; 
     18530            uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL)); 
     18531 
     18532            float height = movementInfo.z; 
     18533            UpdateGroundPositionZ(movementInfo.x,movementInfo.y,height); 
     18534 
     18535            if (damage > 0) 
     18536            { 
     18537                //Prevent fall damage from being more than the player maximum health 
     18538                if (damage > GetMaxHealth()) 
     18539                    damage = GetMaxHealth(); 
     18540 
     18541                // Gust of Wind 
     18542                if (GetDummyAura(43621)) 
     18543                    damage = GetMaxHealth()/2; 
     18544 
     18545                EnvironmentalDamage(GetGUID(), DAMAGE_FALL, damage); 
     18546            } 
     18547 
     18548            //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction 
     18549            DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall); 
     18550        } 
     18551    } 
     18552} 
     18553 
     18554void Player::HandleFallUnderMap() 
     18555{ 
     18556    if(InBattleGround() && GetBattleGround()  
     18557        && GetBattleGround()->HandlePlayerUnderMap(this)) 
     18558    { 
     18559        // do nothing, the handle already did if returned true 
     18560    } 
     18561    else 
     18562    { 
     18563        // NOTE: this is actually called many times while falling 
     18564        // even after the player has been teleported away 
     18565        // TODO: discard movement packets after the player is rooted 
     18566        if(isAlive()) 
     18567        { 
     18568            EnvironmentalDamage(GetGUID(),DAMAGE_FALL_TO_VOID, GetMaxHealth()); 
     18569            // change the death state to CORPSE to prevent the death timer from 
     18570            // starting in the next player update 
     18571            KillPlayer(); 
     18572            BuildPlayerRepop(); 
     18573        } 
     18574 
     18575        // cancel the death timer here if started 
     18576        RepopAtGraveyard(); 
     18577    } 
     18578} 
     18579 
     18580void Player::Possess(Unit *target) 
     18581{ 
     18582    if(!target || target == this) 
     18583        return; 
     18584 
     18585    // Don't allow possession of someone else's pet 
     18586    if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && target != GetPet()) 
     18587        return; 
     18588 
     18589    // Don't allow possession on transports or when in flight; also remove possession from the now-to-be-possessed 
     18590    if (target->GetTypeId() == TYPEID_PLAYER) 
     18591    { 
     18592        if (((Player*)target)->m_transport || ((Player*)target)->isInFlight()) 
     18593            return; 
     18594        if (target->isPossessing()) 
     18595            ((Player*)target)->RemovePossess(true); 
     18596    } 
     18597 
     18598    // Remove any previous possession from the target 
     18599    if (target->isPossessedByPlayer()) 
     18600        ((Player*)target->GetCharmer())->RemovePossess(false); 
     18601    else if (target->isCharmed())  
     18602        target->UncharmSelf();  // Target isn't possessed, but charmed; uncharm before possessing 
     18603 
     18604    // Remove our previous possession 
     18605    if (isPossessing()) 
     18606        RemovePossess(true); 
     18607    else if (GetCharm()) // We are charming a creature, not possessing it; uncharm ourself first 
     18608        Uncharm(); 
     18609 
     18610    // Interrupt any current casting of the target 
     18611    if(target->IsNonMeleeSpellCasted(true)) 
     18612        target->InterruptNonMeleeSpells(true); 
     18613 
     18614    // Update the proper unit fields 
     18615    SetPossessedTarget(target); 
     18616 
     18617    target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction()); 
     18618    target->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); 
     18619    target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); 
     18620    target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); 
     18621    SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); 
     18622    SetUInt64Value(PLAYER_FARSIGHT, target->GetGUID()); 
     18623 
     18624    if(target->GetTypeId() == TYPEID_UNIT) 
     18625    { 
     18626        // Set target to active in the grid and place it in the world container to be picked up by all regular player cell visits 
     18627        Map* map = target->GetMap(); 
     18628        map->SwitchGridContainers((Creature*)target, true); 
     18629        target->setActive(true); 
     18630 
     18631        ((Creature*)target)->InitPossessedAI(); // Initialize the possessed AI 
     18632        target->StopMoving(); 
     18633        target->GetMotionMaster()->Clear(false); 
     18634        target->GetMotionMaster()->MoveIdle(); 
     18635    } 
     18636 
     18637    target->CombatStop(); 
     18638    target->DeleteThreatList(); 
     18639 
     18640    // Pets already have a properly initialized CharmInfo, don't overwrite it. 
     18641    if(target->GetTypeId() == TYPEID_PLAYER || (target->GetTypeId() == TYPEID_UNIT && !((Creature*)target)->isPet())) 
     18642    { 
     18643        CharmInfo* charmInfo = target->InitCharmInfo(target); 
     18644        charmInfo->InitPossessCreateSpells(); 
     18645    } 
     18646 
     18647    // Disable control for target player and remove AFK 
     18648    if(target->GetTypeId() == TYPEID_PLAYER) 
     18649    { 
     18650        if(((Player*)target)->isAFK()) 
     18651            ((Player*)target)->ToggleAFK(); 
     18652        ((Player*)target)->SetViewport(target->GetGUID(), false); 
     18653    } 
     18654 
     18655    // Set current viewport to target unit, controllable 
     18656    SetViewport(target->GetGUID(), true); 
     18657 
     18658    PossessSpellInitialize(); 
     18659} 
     18660 
     18661void Player::RemovePossess(bool attack) 
     18662{ 
     18663    Unit* target = GetCharm(); 
     18664    if(!target || !target->isPossessed()) 
     18665        return; 
     18666 
     18667    // Remove area auras from possessed 
     18668    Unit::AuraMap& tAuras = target->GetAuras(); 
     18669    for(Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();) 
     18670    { 
     18671        if(itr->second && itr->second->IsAreaAura()) 
     18672            target->RemoveAura(itr); 
     18673        else 
     18674            ++itr; 
     18675    } 
     18676 
     18677    RemovePossessedTarget(); 
     18678 
     18679    if(target->GetTypeId() == TYPEID_PLAYER) 
     18680        ((Player*)target)->setFactionForRace(target->getRace()); 
     18681    else if(target->GetTypeId() == TYPEID_UNIT) 
     18682    { 
     18683        // Set creature to inactive in grid and place it back into the grid container 
     18684        Map* map = target->GetMap(); 
     18685        target->setActive(false); 
     18686        map->SwitchGridContainers((Creature*)target, false); 
     18687 
     18688        if(((Creature*)target)->isPet()) 
     18689        { 
     18690            if(Unit* owner = target->GetOwner()) 
     18691                target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction()); 
     18692        } else 
     18693        { 
     18694            if(CreatureInfo const* cInfo = ((Creature*)target)->GetCreatureInfo()) 
     18695                target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, cInfo->faction_A); 
     18696        } 
     18697    } 
     18698 
     18699    target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); 
     18700    target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); 
     18701    RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); 
     18702    SetUInt64Value(PLAYER_FARSIGHT, 0); 
     18703 
     18704    // Remove pet spell action bar 
     18705    WorldPacket data(SMSG_PET_SPELLS, 8); 
     18706    data << uint64(0); 
     18707    m_session->SendPacket(&data); 
     18708 
     18709    // Restore original view 
     18710    SetViewport(GetGUID(), true); 
     18711    if(target->GetTypeId() == TYPEID_PLAYER) 
     18712        ((Player*)target)->SetViewport(target->GetGUID(), true); 
     18713    else 
     18714    { 
     18715        if(((Creature*)target)->isPet()) 
     18716        { 
     18717            ((Pet*)target)->InitPetCreateSpells(); 
     18718            PetSpellInitialize(); 
     18719        } 
     18720 
     18721        if (target->isAlive()) 
     18722        { 
     18723            // If we're still hostile to our target, continue attacking otherwise reset threat and go home 
     18724            if (target->getVictim()) 
     18725            { 
     18726                Unit* victim = target->getVictim(); 
     18727                FactionTemplateEntry const* t_faction = target->getFactionTemplateEntry(); 
     18728                FactionTemplateEntry const* v_faction = victim->getFactionTemplateEntry(); 
     18729                // Unit::IsHostileTo will always return true since the unit is always hostile to its victim 
     18730                if (t_faction && v_faction && !t_faction->IsHostileTo(*v_faction)) 
     18731                { 
     18732                    // Stop combat and remove the target from the threat lists of all its victims 
     18733                    target->CombatStop(); 
     18734                    target->getHostilRefManager().deleteReferences(); 
     18735                    target->DeleteThreatList(); 
     18736                    target->GetMotionMaster()->Clear(); 
     18737                    target->GetMotionMaster()->MoveTargetedHome(); 
     18738                } 
     18739            }  
     18740            else if (target->GetTypeId() == TYPEID_UNIT) 
     18741            { 
     18742                target->GetMotionMaster()->Clear(); 
     18743                target->GetMotionMaster()->MoveTargetedHome(); 
     18744            } 
     18745             
     18746            // Add high amount of threat on the player 
     18747            if(target != GetPet() && attack) 
     18748                target->AddThreat(this, 1000000.0f); 
     18749        } 
     18750        // Delete the assigned possessed AI 
     18751        ((Creature*)target)->DeletePossessedAI(); 
     18752    } 
     18753} 
     18754 
     18755void Player::SetViewport(uint64 guid, bool moveable) 
     18756{ 
     18757    WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, 8+1); 
     18758    data.appendPackGUID(guid); // Packed guid of object to set client's view to 
     18759    data << (moveable ? uint8(0x01) : uint8(0x00)); // 0 - can't move; 1 - can move 
     18760    m_session->SendPacket(&data); 
     18761    sLog.outDetail("Viewport for "I64FMT" (%s) changed to "I64FMT, GetGUID(), GetName(), guid); 
    1851518762} 
    1851618763 
     
    1852518772           ); 
    1852618773} 
     18774 
     18775bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const 
     18776{ 
     18777    for(ItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end();++itr) 
     18778        if(itr->pos == this->pos) 
     18779            return true; 
     18780 
     18781    return false; 
     18782} 
  • trunk/src/game/Player.h

    r136 r174  
    906906        void setActive(bool) {} 
    907907 
     908        void SetViewport(uint64 guid, bool movable); 
     909        void Possess(Unit *target); 
     910        void RemovePossess(bool attack = true);  
     911 
    908912        bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); 
    909913 
     
    14221426        PlayerSpellMap const& GetSpellMap() const { return m_spells; } 
    14231427        PlayerSpellMap      & GetSpellMap()       { return m_spells; } 
     1428        ActionButtonList const& GetActionButtonList() const { return m_actionButtons; } 
    14241429 
    14251430        void AddSpellMod(SpellModifier* mod, bool apply); 
     
    16201625        void UpdateUnderwaterState( Map * m, float x, float y, float z ); 
    16211626 
    1622         void SendMessageToSet(WorldPacket *data, bool self);// overwrite Object::SendMessageToSet 
    1623         void SendMessageToSetInRange(WorldPacket *data, float fist, bool self); 
     1627        void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true);// overwrite Object::SendMessageToSet 
     1628        void SendMessageToSetInRange(WorldPacket *data, float fist, bool self, bool to_possessor = true); 
    16241629                                                            // overwrite Object::SendMessageToSetInRange 
    1625         void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only); 
     1630        void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only, bool to_possessor); 
    16261631 
    16271632        static void DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars = true); 
     
    19491954 
    19501955        void HandleDrowning(); 
     1956        void HandleFallDamage(MovementInfo& movementInfo); 
     1957        void HandleFallUnderMap(); 
    19511958 
    19521959        void SetClientControl(Unit* target, uint8 allowMove); 
  • trunk/src/game/Spell.cpp

    r173 r174  
    41224122                    duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER); 
    41234123                } 
    4124                 if(m_caster->IsFriendlyTo(target) && !duelvsplayertar) 
     4124                // AoE spells have the caster as their target 
     4125                if(m_caster->IsFriendlyTo(target) && m_caster != target && !duelvsplayertar) 
    41254126                { 
    41264127                    return SPELL_FAILED_BAD_TARGETS; 
  • trunk/src/game/Spell.h

    r173 r174  
    241241        void EffectPickPocket(uint32 i); 
    242242        void EffectAddFarsight(uint32 i); 
     243        void EffectSummonPossessed(uint32 i); 
    243244        void EffectSummonWild(uint32 i); 
    244245        void EffectSummonGuardian(uint32 i); 
  • trunk/src/game/SpellAuras.cpp

    r173 r174  
    5050#include "GridNotifiersImpl.h" 
    5151#include "CellImpl.h" 
     52#include "TemporarySummon.h" 
    5253 
    5354#define NULL_AURA_SLOT 0xFF 
     
    528529    } 
    529530 
    530     // Channeled aura required check distance from caster 
    531     if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID()) 
     531    // Channeled aura required check distance from caster except in possessed cases 
     532    if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID() && !m_target->isPossessed()) 
    532533    { 
    533534        Unit* caster = GetCaster(); 
     
    20042005            return; 
    20052006        } 
     2007 
    20062008        // Dark Fiend 
    20072009        if(GetId()==45934) 
     
    20172019        { 
    20182020            m_target->CastSpell(m_target,47287,true,NULL,this); 
     2021            return; 
     2022        } 
     2023 
     2024        // Eye of Kilrogg, unsummon eye when aura is gone 
     2025        if(GetId() == 126 && caster->GetTypeId() == TYPEID_PLAYER && caster->GetCharm()) 
     2026        { 
     2027            ((TemporarySummon*)caster->GetCharm())->UnSummon(); 
    20192028            return; 
    20202029        } 
     
    28872896    if( apply ) 
    28882897    { 
    2889         m_target->SetCharmerGUID(GetCasterGUID()); 
    2890         m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction()); 
    2891         caster->SetCharm(m_target); 
    2892  
    2893         m_target->CombatStop(); 
    2894         m_target->DeleteThreatList(); 
    2895         if(m_target->GetTypeId() == TYPEID_UNIT) 
    2896         { 
    2897             m_target->StopMoving(); 
    2898             m_target->GetMotionMaster()->Clear(); 
    2899             m_target->GetMotionMaster()->MoveIdle(); 
    2900             CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target); 
    2901             charmInfo->InitPossessCreateSpells(); 
    2902         } 
    2903  
    2904         if(caster->GetTypeId() == TYPEID_PLAYER) 
    2905         { 
    2906             ((Player*)caster)->PossessSpellInitialize(); 
    2907         } 
     2898        if (caster->GetTypeId() == TYPEID_PLAYER) 
     2899            ((Player*)caster)->Possess(m_target); 
    29082900    } 
    29092901    else 
    2910     { 
    2911         m_target->SetCharmerGUID(0); 
    2912  
    2913         if(m_target->GetTypeId() == TYPEID_PLAYER) 
    2914             ((Player*)m_target)->setFactionForRace(m_target->getRace()); 
    2915         else if(m_target->GetTypeId() == TYPEID_UNIT) 
    2916         { 
    2917             CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); 
    2918             m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); 
    2919         } 
    2920  
    2921         caster->SetCharm(0); 
    2922  
    2923         if(caster->GetTypeId() == TYPEID_PLAYER) 
    2924         { 
    2925             WorldPacket data(SMSG_PET_SPELLS, 8); 
    2926             data << uint64(0); 
    2927             ((Player*)caster)->GetSession()->SendPacket(&data); 
    2928         } 
    2929         if(m_target->GetTypeId() == TYPEID_UNIT) 
    2930         { 
    2931             ((Creature*)m_target)->AIM_Initialize(); 
    2932  
    2933             if (((Creature*)m_target)->AI()) 
    2934                 ((Creature*)m_target)->AI()->AttackStart(caster); 
    2935         } 
    2936     } 
    2937     if(caster->GetTypeId() == TYPEID_PLAYER) 
    2938         caster->SetUInt64Value(PLAYER_FARSIGHT,apply ? m_target->GetGUID() : 0); 
     2902        m_target->UnpossessSelf(true); 
    29392903} 
    29402904 
     
    29522916    if(apply) 
    29532917    { 
    2954         caster->SetUInt64Value(PLAYER_FARSIGHT, m_target->GetGUID()); 
    2955         m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); 
     2918        ((Player*)caster)->Possess(m_target); 
    29562919    } 
    29572920    else 
    29582921    { 
    2959         caster->SetUInt64Value(PLAYER_FARSIGHT, 0); 
    2960         m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); 
     2922        ((Player*)caster)->RemovePossess(false); 
    29612923    } 
    29622924} 
  • trunk/src/game/SpellEffects.cpp

    r168 r174  
    133133    &Spell::EffectPickPocket,                               // 71 SPELL_EFFECT_PICKPOCKET 
    134134    &Spell::EffectAddFarsight,                              // 72 SPELL_EFFECT_ADD_FARSIGHT 
    135     &Spell::EffectSummonGuardian,                           // 73 SPELL_EFFECT_SUMMON_POSSESSED 
     135    &Spell::EffectSummonPossessed,                          // 73 SPELL_EFFECT_SUMMON_POSSESSED 
    136136    &Spell::EffectSummonTotem,                              // 74 SPELL_EFFECT_SUMMON_TOTEM 
    137137    &Spell::EffectHealMechanical,                           // 75 SPELL_EFFECT_HEAL_MECHANICAL          one spell: Mechanical Patch Kit 
     
    31283128    { 
    31293129        case SUMMON_TYPE_GUARDIAN: 
     3130            EffectSummonGuardian(i); 
     3131            break; 
    31303132        case SUMMON_TYPE_POSESSED: 
    31313133        case SUMMON_TYPE_POSESSED2: 
    3132             EffectSummonGuardian(i); 
     3134            EffectSummonPossessed(i); 
    31333135            break; 
    31343136        case SUMMON_TYPE_WILD: 
     
    36763678        map->Add((Creature*)spawnCreature); 
    36773679    } 
     3680} 
     3681 
     3682void Spell::EffectSummonPossessed(uint32 i) 
     3683{ 
     3684    uint32 creatureEntry = m_spellInfo->EffectMiscValue[i]; 
     3685    if(!creatureEntry) 
     3686        return; 
     3687 
     3688    if(m_caster->GetTypeId() != TYPEID_PLAYER) 
     3689        return; 
     3690 
     3691    uint32 level = m_caster->getLevel(); 
     3692 
     3693    float px, py, pz; 
     3694    m_caster->GetClosePoint(px, py, pz, DEFAULT_WORLD_OBJECT_SIZE); 
     3695 
     3696    int32 duration = GetSpellDuration(m_spellInfo); 
     3697 
     3698    TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN; 
     3699 
     3700    Creature* c = m_caster->SummonCreature(creatureEntry, px, py, pz, m_caster->GetOrientation(), summonType, duration); 
     3701    ((Player*)m_caster)->Possess(c); 
    36783702} 
    36793703 
  • trunk/src/game/SpellHandler.cpp

    r102 r174  
    303303    } 
    304304 
     305    // can't use our own spells when we're in possession of another unit, 
     306    if(_player->isPossessing()) 
     307        return; 
     308 
    305309    // client provided targets 
    306310    SpellCastTargets targets; 
     
    348352    if (!spellInfo) 
    349353        return; 
     354 
     355    // Remove possess aura from the possessed as well 
     356    if(_player->isPossessing()) 
     357    { 
     358        for (int i = 0; i < 3; ++i) 
     359        { 
     360            if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POSSESS || 
     361                spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POSSESS_PET) 
     362            { 
     363                _player->RemoveAurasDueToSpellByCancel(spellId); 
     364                _player->GetCharm()->RemoveAurasDueToSpellByCancel(spellId); 
     365                return; 
     366            } 
     367        } 
     368    } 
    350369 
    351370    // not allow remove non positive spells and spells with attr SPELL_ATTR_CANT_CANCEL 
  • trunk/src/game/TemporarySummon.cpp

    r107 r174  
    175175    CombatStop(); 
    176176 
     177    UnpossessSelf(false); 
     178 
    177179    CleanupsBeforeDelete(); 
    178180    AddObjectToRemoveList(); 
  • trunk/src/game/Unit.cpp

    r173 r174  
    227227    m_charmInfo = NULL; 
    228228    m_unit_movement_flags = 0; 
     229    m_isPossessed = false; 
    229230 
    230231    // remove aurastates allowing special moves 
     
    702703            ((Player*)pVictim)->SetPvPDeath(player!=NULL); 
    703704 
    704         // Call KilledUnit for creatures 
    705         if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI()) 
    706             ((Creature*)this)->AI()->KilledUnit(pVictim); 
    707  
    708705        // 10% durability loss on death 
    709706        // clean InHateListOf 
     
    719716                ((Player*)pVictim)->GetSession()->SendPacket(&data); 
    720717            } 
     718            // Call KilledUnit for creatures 
     719            if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI()) 
     720                ((Creature*)this)->AI()->KilledUnit(pVictim); 
    721721        } 
    722722        else                                                // creature died 
     
    730730                cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); 
    731731            } 
     732 
     733            // Call KilledUnit for creatures, this needs to be called after the lootable flag is set 
     734            if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI()) 
     735                ((Creature*)this)->AI()->KilledUnit(pVictim); 
     736 
    732737            // Call creature just died function 
    733738            if (cVictim->AI()) 
     
    773778            he->DuelComplete(DUEL_INTERUPTED); 
    774779        } 
     780 
     781        // Possessed unit died, restore control to possessor 
     782        pVictim->UnpossessSelf(false); 
     783 
     784        // Possessor died, remove possession 
     785        if(pVictim->GetTypeId() == TYPEID_PLAYER && pVictim->isPossessing()) 
     786            ((Player*)pVictim)->RemovePossess(false); 
    775787 
    776788        // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill) 
     
    71707182} 
    71717183 
     7184void Unit::UncharmSelf() 
     7185{ 
     7186    if (!GetCharmer()) 
     7187        return; 
     7188 
     7189    RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM); 
     7190} 
     7191 
     7192void Unit::UnpossessSelf(bool attack) 
     7193{ 
     7194    if (!isPossessed() || !GetCharmer()) 
     7195        return; 
     7196 
     7197    if (GetCharmer()->GetTypeId() == TYPEID_PLAYER) 
     7198        ((Player*)GetCharmer())->RemovePossess(attack); 
     7199    else 
     7200    { 
     7201        GetCharmer()->SetCharm(0); 
     7202        SetCharmerGUID(0); 
     7203        m_isPossessed = false; 
     7204    } 
     7205} 
     7206 
    71727207void Unit::UnsummonAllTotems() 
    71737208{ 
     
    85898624    } 
    85908625 
     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 
    85918629    // different visible distance checks 
    85928630    if(u->isInFlight())                                     // what see player in flight 
    85938631    { 
    85948632        // use object grey distance for all (only see objects any way) 
    8595         if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 
     8633        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceInFlight()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 
    85968634            return false; 
    85978635    } 
    85988636    else if(!isAlive())                                     // distance for show body 
    85998637    { 
    8600         if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 
     8638        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 
    86018639            return false; 
    86028640    } 
     
    86068644        { 
    86078645            // Players far than max visible distance for player or not in our map are not visible too 
    8608             if (!at_same_transport && !IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
     8646            if (!at_same_transport && !IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
    86098647                return false; 
    86108648        } 
     
    86138651            // Units far than max visible distance for creature or not in our map are not visible too 
    86148652            // Active unit should always be visibile 
    8615             if (!IsWithinDistInMap(u, u->isActive()  
     8653            if (!IsWithinDistInMap(target, target->isActive()  
    86168654                ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance())) 
    86178655                : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))) 
     
    86228660    { 
    86238661        // Pet/charmed far than max visible distance for player or not in our map are not visible too 
    8624         if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
     8662        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
    86258663            return false; 
    86268664    } 
     
    86288666    { 
    86298667        // Units far than max visible distance for creature or not in our map are not visible too 
    8630         if (!IsWithinDistInMap(u,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
     8668        if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f))) 
    86318669            return false; 
    86328670    } 
     
    98729910        RemoveAllDynObjects(); 
    98739911        GetMotionMaster()->Clear(false);                    // remove different non-standard movement generators. 
     9912 
     9913        UnpossessSelf(false); 
    98749914    } 
    98759915    RemoveFromWorld(); 
     
    99249964void CharmInfo::InitPossessCreateSpells() 
    99259965{ 
    9926     if(m_unit->GetTypeId() == TYPEID_PLAYER) 
    9927         return; 
    9928  
    9929     InitEmptyActionBar();                                   //charm action bar 
    9930  
    9931     for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) 
    9932     { 
    9933         if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x])) 
    9934             m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true); 
    9935         else 
    9936             AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_CAST); 
     9966    InitEmptyActionBar(); 
     9967    if(m_unit->GetTypeId() == TYPEID_UNIT) 
     9968    { 
     9969        for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) 
     9970        { 
     9971            uint32 spellid = ((Creature*)m_unit)->m_spells[i]; 
     9972            if(IsPassiveSpell(spellid)) 
     9973                m_unit->CastSpell(m_unit, spellid, true); 
     9974            else 
     9975                AddSpellToAB(0, spellid, ACT_CAST); 
     9976        } 
    99379977    } 
    99389978} 
  • trunk/src/game/Unit.h

    r161 r174  
    990990        void SetPet(Pet* pet); 
    991991        void SetCharm(Unit* pet); 
     992        void SetPossessedTarget(Unit* target) 
     993        { 
     994            if (!target) return; 
     995            SetCharm(target); 
     996            target->SetCharmerGUID(GetGUID()); 
     997            target->m_isPossessed = true; 
     998        } 
     999        void RemovePossessedTarget() 
     1000        { 
     1001            if (!GetCharm()) return; 
     1002            GetCharm()->SetCharmerGUID(0); 
     1003            GetCharm()->m_isPossessed = false; 
     1004            SetCharm(0); 
     1005        } 
     1006 
    9921007        bool isCharmed() const { return GetCharmerGUID() != 0; } 
     1008        bool isPossessed() const { return m_isPossessed; } 
     1009        bool isPossessedByPlayer() const { return m_isPossessed && IS_PLAYER_GUID(GetCharmerGUID()); } 
     1010        bool isPossessing() const { return GetCharm() && GetCharm()->isPossessed(); } 
     1011        bool isPossessing(Unit* u) const { return u->isPossessed() && GetCharmGUID() == u->GetGUID(); } 
     1012        bool isPossessingCreature() const { return isPossessing() && IS_CREATURE_GUID(GetCharmGUID()); } 
    9931013 
    9941014        CharmInfo* GetCharmInfo() { return m_charmInfo; } 
    9951015        CharmInfo* InitCharmInfo(Unit* charm); 
     1016        void UncharmSelf(); 
     1017        void UnpossessSelf(bool attack); 
    9961018 
    9971019        Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); 
     
    13171339 
    13181340        CharmInfo *m_charmInfo; 
     1341        bool m_isPossessed; 
    13191342 
    13201343        virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; 
  • trunk/src/game/WorldSession.cpp

    r173 r174  
    367367            _player->RemoveFromGroup(); 
    368368 
     369        // Unpossess the current possessed unit of player 
     370        if (_player->isPossessing()) 
     371            _player->RemovePossess(false); 
     372 
     373        // Remove any possession of this player on logout 
     374        _player->UnpossessSelf(false); 
     375 
    369376        ///- Remove the player from the world 
    370377        // the player may not be in the world when logging out 
  • trunk/src/game/WorldSession.h

    r173 r174  
    3232struct AuctionEntry; 
    3333struct DeclinedName; 
     34struct MovementInfo; 
    3435 
    3536class Creature; 
     
    318319 
    319320        void HandleMovementOpcodes(WorldPacket& recvPacket); 
     321        void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags); 
    320322        void HandleSetActiveMoverOpcode(WorldPacket &recv_data); 
    321323        void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data); 
  • trunk/win/VC71/game.vcproj

    r86 r174  
    734734                        </File> 
    735735                        <File 
     736                                RelativePath="..\..\src\game\PossessedAI.cpp" 
     737                                > 
     738                        </File> 
     739                        <File 
     740                                RelativePath="..\..\src\game\PossessedAI.h" 
     741                                > 
     742                        </File> 
     743                        <File 
    736744                                RelativePath="..\..\src\game\RandomMovementGenerator.cpp"> 
    737745                        </File> 
  • trunk/win/VC80/game.vcproj

    r86 r174  
    11281128                        </File> 
    11291129                        <File 
     1130                                RelativePath="..\..\src\game\PossessedAI.cpp" 
     1131                                > 
     1132                        </File> 
     1133                        <File 
     1134                                RelativePath="..\..\src\game\PossessedAI.h" 
     1135                                > 
     1136                        </File> 
     1137                        <File 
    11301138                                RelativePath="..\..\src\game\PointMovementGenerator.h" 
    11311139                                > 
  • trunk/win/VC90/game.vcproj

    r86 r174  
    22<VisualStudioProject 
    33        ProjectType="Visual C++" 
    4         Version="9,00" 
     4        Version="9.00" 
    55        Name="game" 
    66        ProjectGUID="{1DC6C4DA-A028-41F3-877D-D5400C594F88}" 
     
    4949                                Optimization="0" 
    5050                                AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers" 
    51                                 PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;" 
     51                                PreprocessorDefinitions="WIN32;_DEBUG;TRINITY_DEBUG;_LIB;" 
    5252                                StringPooling="false" 
    5353                                MinimalRebuild="false" 
     
    102102                </Configuration> 
    103103                <Configuration 
    104                         Name="Debug|x64" 
    105                         OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)" 
    106                         IntermediateDirectory=".\game__$(PlatformName)_$(ConfigurationName)" 
    107                         ConfigurationType="4" 
    108                         InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" 
    109                         UseOfMFC="0" 
    110                         ATLMinimizesCRunTimeLibraryUsage="false" 
    111                         CharacterSet="2" 
    112                         > 
    113                         <Tool 
    114                                 Name="VCPreBuildEventTool" 
    115                         /> 
    116                         <Tool 
    117                                 Name="VCCustomBuildTool" 
    118                         /> 
    119                         <Tool 
    120                                 Name="VCXMLDataGeneratorTool" 
    121                         /> 
    122                         <Tool 
    123                                 Name="VCWebServiceProxyGeneratorTool" 
    124                         /> 
    125                         <Tool 
    126                                 Name="VCMIDLTool" 
    127                                 TargetEnvironment="3" 
    128                         /> 
    129                         <Tool 
    130                                 Name="VCCLCompilerTool" 
    131                                 AdditionalOptions="/MP" 
    132                                 Optimization="0" 
    133                                 AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers" 
    134                                 PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;" 
    135                                 StringPooling="false" 
    136                                 MinimalRebuild="false" 
    137                                 BasicRuntimeChecks="3" 
    138                                 RuntimeLibrary="3" 
    139                                 EnableFunctionLevelLinking="true" 
    140                                 RuntimeTypeInfo="true" 
    141                                 UsePrecompiledHeader="0" 
    142                                 PrecompiledHeaderFile=".\game__$(PlatformName)_$(ConfigurationName)\game.pch" 
    143                                 AssemblerListingLocation=".\game__$(PlatformName)_$(ConfigurationName)\" 
    144                                 ObjectFile=".\game__$(PlatformName)_$(ConfigurationName)\" 
    145                                 ProgramDataBaseFileName=".\game__$(PlatformName)_$(ConfigurationName)\" 
    146                                 WarningLevel="3" 
    147                                 SuppressStartupBanner="true" 
    148                                 Detect64BitPortabilityProblems="false" 
    149                                 DebugInformationFormat="3" 
    150                                 CallingConvention="0" 
    151                                 CompileAs="0" 
    152                         /> 
    153                         <Tool 
    154                                 Name="VCManagedResourceCompilerTool" 
    155                         /> 
    156                         <Tool 
    157                                 Name="VCResourceCompilerTool" 
    158                                 PreprocessorDefinitions="_DEBUG" 
    159                                 Culture="1033" 
    160                         /> 
    161                         <Tool 
    162                                 Name="VCPreLinkEventTool" 
    163                         /> 
    164                         <Tool 
    165                                 Name="VCLibrarianTool" 
    166                                 AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib" 
    167                                 OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib" 
    168                                 SuppressStartupBanner="true" 
    169                         /> 
    170                         <Tool 
    171                                 Name="VCALinkTool" 
    172                         /> 
    173                         <Tool 
    174                                 Name="VCXDCMakeTool" 
    175                         /> 
    176                         <Tool 
    177                                 Name="VCBscMakeTool" 
    178                         /> 
    179                         <Tool 
    180                                 Name="VCFxCopTool" 
    181                         /> 
    182                         <Tool 
    183                                 Name="VCPostBuildEventTool" 
    184                         /> 
    185                 </Configuration> 
    186                 <Configuration 
    187104                        Name="Release|Win32" 
    188105                        OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)" 
     
    214131                                InlineFunctionExpansion="1" 
    215132                                AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers" 
    216                                 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;" 
    217                                 StringPooling="true" 
    218                                 RuntimeLibrary="2" 
     133                                PreprocessorDefinitions="WIN32;_DEBUG;MANGOS_DEBUG;_LIB;" 
     134                                StringPooling="false" 
     135                                MinimalRebuild="false" 
     136                                BasicRuntimeChecks="3" 
     137                                RuntimeLibrary="3" 
    219138                                EnableFunctionLevelLinking="true" 
    220139                                EnableEnhancedInstructionSet="1" 
     
    239158                                Name="VCResourceCompilerTool" 
    240159                                PreprocessorDefinitions="NDEBUG" 
     160                                Culture="1033" 
     161                        /> 
     162                        <Tool 
     163                                Name="VCPreLinkEventTool" 
     164                        /> 
     165                        <Tool 
     166                                Name="VCLibrarianTool" 
     167                                AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib" 
     168                                OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib" 
     169                                SuppressStartupBanner="true" 
     170                        /> 
     171                        <Tool 
     172                                Name="VCALinkTool" 
     173                        /> 
     174                        <Tool 
     175                                Name="VCXDCMakeTool" 
     176                        /> 
     177                        <Tool 
     178                                Name="VCBscMakeTool" 
     179                        /> 
     180                        <Tool 
     181                                Name="VCFxCopTool" 
     182                        /> 
     183                        <Tool 
     184                                Name="VCPostBuildEventTool" 
     185                        /> 
     186                </Configuration> 
     187                <Configuration 
     188                        Name="Debug|x64" 
     189                        OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)" 
     190                        IntermediateDirectory=".\game__$(PlatformName)_$(ConfigurationName)" 
     191                        ConfigurationType="4" 
     192                        InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" 
     193                        UseOfMFC="0" 
     194                        ATLMinimizesCRunTimeLibraryUsage="false" 
     195                        CharacterSet="2" 
     196                        > 
     197                        <Tool 
     198                                Name="VCPreBuildEventTool" 
     199                        /> 
     200                        <Tool 
     201                                Name="VCCustomBuildTool" 
     202                        /> 
     203                        <Tool 
     204                                Name="VCXMLDataGeneratorTool" 
     205                        /> 
     206                        <Tool 
     207                                Name="VCWebServiceProxyGeneratorTool" 
     208                        /> 
     209                        <Tool 
     210                                Name="VCMIDLTool" 
     211                                TargetEnvironment="3" 
     212                        /> 
     213                        <Tool 
     214                                Name="VCCLCompilerTool" 
     215                                AdditionalOptions="/MP" 
     216                                Optimization="0" 
     217                                AdditionalIncludeDirectories="..\..\dep\include;..\..\src\framework;..\..\src\shared;..\..\src\shared\vmap;..\..\dep\ACE_wrappers" 
     218                                PreprocessorDefinitions="WIN32;NDEBUG;_LIB;" 
     219                                StringPooling="true" 
     220                                RuntimeLibrary="2" 
     221                                EnableFunctionLevelLinking="true" 
     222                                RuntimeTypeInfo="true" 
     223                                UsePrecompiledHeader="0" 
     224                                PrecompiledHeaderFile=".\game__$(PlatformName)_$(ConfigurationName)\game.pch" 
     225                                AssemblerListingLocation=".\game__$(PlatformName)_$(ConfigurationName)\" 
     226                                ObjectFile=".\game__$(PlatformName)_$(ConfigurationName)\" 
     227                                ProgramDataBaseFileName=".\game__$(PlatformName)_$(ConfigurationName)\" 
     228                                WarningLevel="3" 
     229                                SuppressStartupBanner="true" 
     230                                Detect64BitPortabilityProblems="false" 
     231                                DebugInformationFormat="3" 
     232                                CallingConvention="0" 
     233                                CompileAs="0" 
     234                        /> 
     235                        <Tool 
     236                                Name="VCManagedResourceCompilerTool" 
     237                        /> 
     238                        <Tool 
     239                                Name="VCResourceCompilerTool" 
     240                                PreprocessorDefinitions="_DEBUG" 
    241241                                Culture="1033" 
    242242                        /> 
     
    11371137                        </File> 
    11381138                        <File 
     1139                                RelativePath="..\..\src\game\PossessedAI.cpp" 
     1140                                > 
     1141                        </File> 
     1142                        <File 
     1143                                RelativePath="..\..\src\game\PossessedAI.h" 
     1144                                > 
     1145                        </File> 
     1146                        <File 
    11391147                                RelativePath="..\..\src\game\RandomMovementGenerator.cpp" 
    11401148                                >