Changeset 174
- Timestamp:
- 11/19/08 13:43:15 (17 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 38 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bindings/scripts/include/sc_creature.h
r153 r174 75 75 //Called at waypoint reached or PointMovement end 76 76 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) {} 77 80 78 81 //************* -
trunk/src/bindings/scripts/scripts/npc/npc_escortAI.cpp
r158 r174 257 257 } 258 258 259 void 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 259 278 void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs) 260 279 { -
trunk/src/bindings/scripts/scripts/npc/npc_escortAI.h
r90 r174 52 52 void MovementInform(uint32, uint32); 53 53 54 void OnPossess(bool apply); 55 54 56 // EscortAI functions 55 57 void AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs = 0); -
trunk/src/game/Chat.cpp
r169 r174 561 561 { "listfreeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListFreezeCommand, "", NULL }, 562 562 { "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL }, 563 { "possess", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePossessCommand, "", NULL }, 564 { "unpossess", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnPossessCommand, "", NULL }, 563 565 564 566 { NULL, 0, false, NULL, "", NULL } -
trunk/src/game/Chat.h
r168 r174 450 450 bool HandleDebugThreatList(const char * args); 451 451 bool HandleDebugHostilRefList(const char * args); 452 bool HandlePossessCommand(const char* args); 453 bool HandleUnPossessCommand(const char* args); 452 454 453 455 Player* getSelectedPlayer(); -
trunk/src/game/Creature.cpp
r173 r174 47 47 #include "OutdoorPvPMgr.h" 48 48 #include "GameEvent.h" 49 #include "PossessedAI.h" 49 50 // apply implementation of the singletons 50 51 #include "Policies/SingletonImp.h" … … 118 119 119 120 Creature::Creature() : 120 Unit(), i_AI(NULL), 121 Unit(), i_AI(NULL), i_AI_possessed(NULL), 121 122 lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), 122 123 m_lootMoney(0), m_lootRecipient(0), … … 146 147 delete i_AI; 147 148 i_AI = NULL; 149 150 DeletePossessedAI(); 148 151 } 149 152 … … 365 368 366 369 //Call AI respawn virtual function 367 i_AI->JustRespawned();370 AI()->JustRespawned(); 368 371 369 372 MapManager::Instance().GetMap(GetMapId(), this)->Add(this); … … 429 432 // do not allow the AI to be changed during update 430 433 m_AI_locked = true; 431 i_AI->UpdateAI(diff);434 AI()->UpdateAI(diff); 432 435 m_AI_locked = false; 433 436 } … … 526 529 } 527 530 531 // don't allow AI switch when possessed 532 if (isPossessed()) 533 return false; 534 528 535 CreatureAI * oldAI = i_AI; 529 536 i_motionMaster.Initialize(); … … 532 539 delete oldAI; 533 540 return true; 541 } 542 543 void 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 554 void 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); 534 563 } 535 564 -
trunk/src/game/Creature.h
r168 r174 396 396 { 397 397 CreatureAI *i_AI; 398 CreatureAI *i_AI_possessed; 398 399 399 400 public: … … 456 457 457 458 bool AIM_Initialize(); 459 void InitPossessedAI(); 460 void DeletePossessedAI(); 458 461 459 462 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; } 461 464 462 465 uint32 GetShieldBlockValue() const //dunno mob block value -
trunk/src/game/CreatureAI.h
r130 r174 122 122 // Called at waypoint reached or point movement finished 123 123 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) {} 124 127 }; 125 128 -
trunk/src/game/CreatureAIRegistry.cpp
r145 r174 25 25 #include "GuardAI.h" 26 26 #include "PetAI.h" 27 #include "PossessedAI.h" 27 28 #include "TotemAI.h" 28 29 #include "OutdoorPvPObjectiveAI.h" … … 45 46 (new CreatureAIFactory<TotemAI>("TotemAI"))->RegisterSelf(); 46 47 (new CreatureAIFactory<OutdoorPvPObjectiveAI>("OutdoorPvPObjectiveAI"))->RegisterSelf(); 48 (new CreatureAIFactory<PossessedAI>("PossessedAI"))->RegisterSelf(); 47 49 48 50 (new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf(); -
trunk/src/game/CreatureAISelector.cpp
r102 r174 57 57 if( creature->isGuard() ) 58 58 ai_factory = ai_registry.GetRegistryItem("GuardAI"); 59 else if(creature->isPet() || creature->isCharmed())59 else if(creature->isPet() || (creature->isCharmed() && !creature->isPossessed())) 60 60 ai_factory = ai_registry.GetRegistryItem("PetAI"); 61 61 else if(creature->isTotem()) … … 63 63 else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) 64 64 ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); 65 else if(creature->isPossessed()) 66 creature->InitPossessedAI(); 65 67 } 66 68 -
trunk/src/game/GridNotifiers.cpp
r102 r174 41 41 iter->getSource()->UpdateVisibilityOf(&i_player); 42 42 i_player.UpdateVisibilityOf(iter->getSource()); 43 if (i_player.isPossessedByPlayer()) 44 ((Player*)i_player.GetCharmer())->UpdateVisibilityOf(iter->getSource()); 43 45 } 44 46 } … … 140 142 } 141 143 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()) 144 void 145 Deliverer::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 159 void 160 Deliverer::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 173 void 174 Deliverer::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()) 161 185 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 190 void 191 MessageDeliverer::VisitObject(Player* plr) 192 { 193 if (i_toSelf || plr != &i_source) 194 SendPacket(plr); 195 } 196 197 void 198 MessageDistDeliverer::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); 190 204 } 191 205 } -
trunk/src/game/GridNotifiers.h
r102 r174 90 90 }; 91 91 92 struct TRINITY_DLL_DECL MessageDeliverer93 { 94 Player &i_player;92 struct TRINITY_DLL_DECL Deliverer 93 { 94 WorldObject &i_source; 95 95 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 { 96 109 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 { 114 122 bool i_toSelf; 115 123 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); } 130 132 }; 131 133 -
trunk/src/game/Level3.cpp
r173 r174 6545 6545 return true; 6546 6546 } 6547 6548 bool 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 6563 bool 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 218 218 $(srcdir)/PointMovementGenerator.cpp \ 219 219 $(srcdir)/PointMovementGenerator.h \ 220 $(srcdir)/PossessedAI.cpp \ 221 $(srcdir)/PossessedAI.h \ 220 222 $(srcdir)/QueryHandler.cpp \ 221 223 $(srcdir)/QuestDef.cpp \ -
trunk/src/game/Map.cpp
r173 r174 256 256 { 257 257 // add to world object registry in grid 258 if(obj->isPet() )258 if(obj->isPet() || obj->isPossessedByPlayer()) 259 259 { 260 260 (*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID()); … … 300 300 { 301 301 // remove from world object registry in grid 302 if(obj->isPet() )302 if(obj->isPet() || obj->isPossessedByPlayer()) 303 303 { 304 304 (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID()); … … 310 310 } 311 311 } 312 313 template<class T> 314 void 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 331 template void Map::SwitchGridContainers(Creature *, bool); 332 template void Map::SwitchGridContainers(Corpse *, bool); 312 333 313 334 template<class T> … … 468 489 } 469 490 470 void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self )491 void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self, bool to_possessor) 471 492 { 472 493 CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); … … 484 505 return; 485 506 486 Trinity::MessageDeliverer post_man(*player, msg, to_ self);507 Trinity::MessageDeliverer post_man(*player, msg, to_possessor, to_self); 487 508 TypeContainerVisitor<Trinity::MessageDeliverer, WorldTypeMapContainer > message(post_man); 488 509 CellLock<ReadGuard> cell_lock(cell, p); … … 490 511 } 491 512 492 void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg )513 void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg, bool to_possessor) 493 514 { 494 515 CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); … … 507 528 return; 508 529 509 Trinity::ObjectMessageDeliverer post_man( msg);530 Trinity::ObjectMessageDeliverer post_man(*obj, msg, to_possessor); 510 531 TypeContainerVisitor<Trinity::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man); 511 532 CellLock<ReadGuard> cell_lock(cell, p); … … 513 534 } 514 535 515 void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only )536 void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only, bool to_possessor) 516 537 { 517 538 CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); … … 529 550 return; 530 551 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); 532 553 TypeContainerVisitor<Trinity::MessageDistDeliverer , WorldTypeMapContainer > message(post_man); 533 554 CellLock<ReadGuard> cell_lock(cell, p); … … 535 556 } 536 557 537 void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist )558 void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist, bool to_possessor) 538 559 { 539 560 CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); … … 552 573 return; 553 574 554 Trinity::ObjectMessageDistDeliverer post_man(*obj, msg, dist);575 Trinity::ObjectMessageDistDeliverer post_man(*obj, msg, to_possessor, dist); 555 576 TypeContainerVisitor<Trinity::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man); 556 577 CellLock<ReadGuard> cell_lock(cell, p); … … 650 671 651 672 obj->RemoveFromWorld(); 673 652 674 RemoveFromGrid(obj,grid,cell); 653 675 … … 698 720 UpdatePlayerVisibility(player,new_cell,new_val); 699 721 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 700 727 PlayerRelocationNotify(player,new_cell,new_val); 701 728 NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY()); … … 726 753 AddCreatureToMoveList(creature,x,y,z,ang); 727 754 // 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); 728 757 } 729 758 else 730 759 { 731 760 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 732 765 CreatureRelocationNotify(creature,new_cell,new_val); 733 766 } -
trunk/src/game/Map.h
r102 r174 141 141 virtual void Update(const uint32&); 142 142 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); 147 147 148 148 void PlayerRelocation(Player *, float x, float y, float z, float angl); … … 237 237 Creature* GetCreatureInMap(uint64 guid); 238 238 GameObject* GetGameObjectInMap(uint64 guid); 239 240 template<class T> void SwitchGridContainers(T* obj, bool active); 239 241 private: 240 242 void LoadVMap(int pX, int pY); -
trunk/src/game/MovementHandler.cpp
r102 r174 190 190 CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4); 191 191 192 if(GetPlayer()->GetDontMove())193 return;194 195 192 /* extract packet */ 196 193 MovementInfo movementInfo; … … 205 202 recv_data >> movementInfo.o; 206 203 207 //Save movement flags208 _player->SetUnitMovementFlags(MovementFlags);209 210 204 if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT) 211 205 { … … 264 258 return; 265 259 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 266 274 /* handle special cases */ 267 275 if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT) … … 285 293 { 286 294 // unmount before boarding 287 _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);295 GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); 288 296 289 297 GetPlayer()->m_transport = (*iter); … … 305 313 } 306 314 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); 361 318 362 319 if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater()) … … 382 339 383 340 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 344 void 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); 408 401 } 409 402 } -
trunk/src/game/Object.cpp
r145 r174 1412 1412 } 1413 1413 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 );1414 void WorldObject::SendMessageToSet(WorldPacket *data, bool /*fake*/, bool bToPossessor) 1415 { 1416 MapManager::Instance().GetMap(m_mapId, this)->MessageBroadcast(this, data, bToPossessor); 1417 } 1418 1419 void WorldObject::SendMessageToSetInRange(WorldPacket *data, float dist, bool /*bToSelf*/, bool bToPossessor) 1420 { 1421 MapManager::Instance().GetMap(m_mapId, this)->MessageDistBroadcast(this, data, dist, bToPossessor); 1422 1422 } 1423 1423 -
trunk/src/game/Object.h
r141 r174 414 414 bool HasInArc( const float arcangle, const WorldObject* obj ) const; 415 415 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); 418 418 void BuildHeartBeatMsg( WorldPacket *data ) const; 419 419 void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const; -
trunk/src/game/ObjectAccessor.cpp
r126 r174 623 623 { 624 624 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 632 void 633 ObjectAccessor::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 640 void 641 ObjectAccessor::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 } 627 649 } 628 650 -
trunk/src/game/ObjectAccessor.h
r120 r174 209 209 UpdateDataMapType &i_updateDatas; 210 210 WorldObject &i_object; 211 std::set<uint64> plr_list; 211 212 WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {} 212 213 void Visit(PlayerMapType &); 214 void Visit(CreatureMapType &); 215 void BuildPacket(Player* plr); 213 216 template<class SKIP> void Visit(GridRefManager<SKIP> &) {} 214 217 }; -
trunk/src/game/Pet.cpp
r152 r174 549 549 // unsummon pet that lost owner 550 550 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()) 552 552 { 553 553 Remove(PET_SAVE_NOT_IN_SLOT, true); -
trunk/src/game/PetHandler.cpp
r152 r174 110 110 if(pet->GetTypeId() != TYPEID_PLAYER) 111 111 { 112 pet->GetMotionMaster()->Clear();113 112 if (((Creature*)pet)->AI()) 114 113 ((Creature*)pet)->AI()->AttackStart(TargetUnit); … … 140 139 p->setDeathState(CORPSE); 141 140 } 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 } 144 148 break; 145 149 default: … … 195 199 196 200 //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()) 198 202 { 199 203 pet->SetInFront(unit_target); … … 223 227 } 224 228 225 if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet-> HasAuraType(SPELL_AURA_MOD_POSSESS))229 if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed()) 226 230 { 227 231 pet->clearUnitState(UNIT_STAT_FOLLOW); … … 237 241 else 238 242 { 239 if(pet-> HasAuraType(SPELL_AURA_MOD_POSSESS))243 if(pet->isPossessed()) 240 244 { 241 245 WorldPacket data(SMSG_CAST_FAILED, (4+1+1)); … … 479 483 else if(pet->GetGUID() == _player->GetCharmGUID()) 480 484 { 481 _player->Uncharm(); 485 if (_player->isPossessing()) 486 _player->RemovePossess(true); 487 else 488 _player->Uncharm(); 482 489 } 483 490 } … … 602 609 recvPacket >> guid >> spellid; 603 610 611 // This opcode is also sent from charmed and possessed units (players and creatures) 604 612 if(!_player->GetPet() && !_player->GetCharm()) 605 613 return; 606 614 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())) 613 618 { 614 619 sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() ); … … 616 621 } 617 622 618 if ( pet->GetGlobalCooldown() > 0)623 if (caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->GetGlobalCooldown() > 0) 619 624 return; 620 625 … … 627 632 628 633 // do not cast not learned spells 629 if(! pet->HasSpell(spellid) || IsPassiveSpell(spellid))634 if(!caster->HasSpell(spellid) || IsPassiveSpell(spellid)) 630 635 return; 631 636 632 637 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); 639 644 spell->m_targets = targets; 640 645 … … 642 647 if(result == -1) 643 648 { 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 } 655 664 } 656 665 … … 659 668 else 660 669 { 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 } 664 681 665 682 spell->finish(false); -
trunk/src/game/Player.cpp
r168 r174 470 470 itr->second.save->RemovePlayer(this); 471 471 472 if (isPossessing()) 473 RemovePossess(false); 474 472 475 delete m_declinedname; 473 476 } … … 1254 1257 1255 1258 Pet* pet = GetPet(); 1256 if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) )1259 if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && !pet->isPossessed()) 1257 1260 { 1258 1261 RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); … … 1535 1538 SetSemaphoreTeleport(true); 1536 1539 1540 // Remove any possession on the player before teleporting 1541 if (isPossessedByPlayer()) 1542 ((Player*)GetCharmer())->RemovePossess(); 1543 1537 1544 // The player was ported to another map and looses the duel immediatly. 1538 1545 // We have to perform this check before the teleport, otherwise the … … 1748 1755 { 1749 1756 ///- Release charmed creatures, unsummon totems and remove pets/guardians 1757 RemovePossess(false); 1750 1758 Uncharm(); 1751 1759 UnsummonAllTotems(); … … 5267 5275 } 5268 5276 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);5277 void Player::SendMessageToSet(WorldPacket *data, bool self, bool to_possessor) 5278 { 5279 MapManager::Instance().GetMap(GetMapId(), this)->MessageBroadcast(this, data, self, to_possessor); 5280 } 5281 5282 void 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 5287 void 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); 5282 5290 } 5283 5291 … … 15974 15982 15975 15983 charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM); 15976 charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);15977 15984 } 15978 15985 … … 16007 16014 WorldPacket data(SMSG_MESSAGECHAT, 200); 16008 16015 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 ); 16010 16017 } 16011 16018 … … 18506 18513 } 18507 18514 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; 18515 void 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 18554 void 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 18580 void 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 18661 void 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 18755 void 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); 18515 18762 } 18516 18763 … … 18525 18772 ); 18526 18773 } 18774 18775 bool 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 906 906 void setActive(bool) {} 907 907 908 void SetViewport(uint64 guid, bool movable); 909 void Possess(Unit *target); 910 void RemovePossess(bool attack = true); 911 908 912 bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); 909 913 … … 1422 1426 PlayerSpellMap const& GetSpellMap() const { return m_spells; } 1423 1427 PlayerSpellMap & GetSpellMap() { return m_spells; } 1428 ActionButtonList const& GetActionButtonList() const { return m_actionButtons; } 1424 1429 1425 1430 void AddSpellMod(SpellModifier* mod, bool apply); … … 1620 1625 void UpdateUnderwaterState( Map * m, float x, float y, float z ); 1621 1626 1622 void SendMessageToSet(WorldPacket *data, bool self );// overwrite Object::SendMessageToSet1623 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); 1624 1629 // 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); 1626 1631 1627 1632 static void DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars = true); … … 1949 1954 1950 1955 void HandleDrowning(); 1956 void HandleFallDamage(MovementInfo& movementInfo); 1957 void HandleFallUnderMap(); 1951 1958 1952 1959 void SetClientControl(Unit* target, uint8 allowMove); -
trunk/src/game/Spell.cpp
r173 r174 4122 4122 duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER); 4123 4123 } 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) 4125 4126 { 4126 4127 return SPELL_FAILED_BAD_TARGETS; -
trunk/src/game/Spell.h
r173 r174 241 241 void EffectPickPocket(uint32 i); 242 242 void EffectAddFarsight(uint32 i); 243 void EffectSummonPossessed(uint32 i); 243 244 void EffectSummonWild(uint32 i); 244 245 void EffectSummonGuardian(uint32 i); -
trunk/src/game/SpellAuras.cpp
r173 r174 50 50 #include "GridNotifiersImpl.h" 51 51 #include "CellImpl.h" 52 #include "TemporarySummon.h" 52 53 53 54 #define NULL_AURA_SLOT 0xFF … … 528 529 } 529 530 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()) 532 533 { 533 534 Unit* caster = GetCaster(); … … 2004 2005 return; 2005 2006 } 2007 2006 2008 // Dark Fiend 2007 2009 if(GetId()==45934) … … 2017 2019 { 2018 2020 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(); 2019 2028 return; 2020 2029 } … … 2887 2896 if( apply ) 2888 2897 { 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); 2908 2900 } 2909 2901 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); 2939 2903 } 2940 2904 … … 2952 2916 if(apply) 2953 2917 { 2954 caster->SetUInt64Value(PLAYER_FARSIGHT, m_target->GetGUID()); 2955 m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); 2918 ((Player*)caster)->Possess(m_target); 2956 2919 } 2957 2920 else 2958 2921 { 2959 caster->SetUInt64Value(PLAYER_FARSIGHT, 0); 2960 m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); 2922 ((Player*)caster)->RemovePossess(false); 2961 2923 } 2962 2924 } -
trunk/src/game/SpellEffects.cpp
r168 r174 133 133 &Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET 134 134 &Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT 135 &Spell::EffectSummon Guardian,// 73 SPELL_EFFECT_SUMMON_POSSESSED135 &Spell::EffectSummonPossessed, // 73 SPELL_EFFECT_SUMMON_POSSESSED 136 136 &Spell::EffectSummonTotem, // 74 SPELL_EFFECT_SUMMON_TOTEM 137 137 &Spell::EffectHealMechanical, // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit … … 3128 3128 { 3129 3129 case SUMMON_TYPE_GUARDIAN: 3130 EffectSummonGuardian(i); 3131 break; 3130 3132 case SUMMON_TYPE_POSESSED: 3131 3133 case SUMMON_TYPE_POSESSED2: 3132 EffectSummon Guardian(i);3134 EffectSummonPossessed(i); 3133 3135 break; 3134 3136 case SUMMON_TYPE_WILD: … … 3676 3678 map->Add((Creature*)spawnCreature); 3677 3679 } 3680 } 3681 3682 void 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); 3678 3702 } 3679 3703 -
trunk/src/game/SpellHandler.cpp
r102 r174 303 303 } 304 304 305 // can't use our own spells when we're in possession of another unit, 306 if(_player->isPossessing()) 307 return; 308 305 309 // client provided targets 306 310 SpellCastTargets targets; … … 348 352 if (!spellInfo) 349 353 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 } 350 369 351 370 // not allow remove non positive spells and spells with attr SPELL_ATTR_CANT_CANCEL -
trunk/src/game/TemporarySummon.cpp
r107 r174 175 175 CombatStop(); 176 176 177 UnpossessSelf(false); 178 177 179 CleanupsBeforeDelete(); 178 180 AddObjectToRemoveList(); -
trunk/src/game/Unit.cpp
r173 r174 227 227 m_charmInfo = NULL; 228 228 m_unit_movement_flags = 0; 229 m_isPossessed = false; 229 230 230 231 // remove aurastates allowing special moves … … 702 703 ((Player*)pVictim)->SetPvPDeath(player!=NULL); 703 704 704 // Call KilledUnit for creatures705 if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())706 ((Creature*)this)->AI()->KilledUnit(pVictim);707 708 705 // 10% durability loss on death 709 706 // clean InHateListOf … … 719 716 ((Player*)pVictim)->GetSession()->SendPacket(&data); 720 717 } 718 // Call KilledUnit for creatures 719 if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI()) 720 ((Creature*)this)->AI()->KilledUnit(pVictim); 721 721 } 722 722 else // creature died … … 730 730 cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); 731 731 } 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 732 737 // Call creature just died function 733 738 if (cVictim->AI()) … … 773 778 he->DuelComplete(DUEL_INTERUPTED); 774 779 } 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); 775 787 776 788 // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill) … … 7170 7182 } 7171 7183 7184 void Unit::UncharmSelf() 7185 { 7186 if (!GetCharmer()) 7187 return; 7188 7189 RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM); 7190 } 7191 7192 void 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 7172 7207 void Unit::UnsummonAllTotems() 7173 7208 { … … 8589 8624 } 8590 8625 8626 // If the player is currently possessing, update visibility from the possessed unit's location 8627 const Unit* target = u->GetTypeId() == TYPEID_PLAYER && u->isPossessing() ? u->GetCharm() : u; 8628 8591 8629 // different visible distance checks 8592 8630 if(u->isInFlight()) // what see player in flight 8593 8631 { 8594 8632 // 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))) 8596 8634 return false; 8597 8635 } 8598 8636 else if(!isAlive()) // distance for show body 8599 8637 { 8600 if (!IsWithinDistInMap( u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)))8638 if (!IsWithinDistInMap(target,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f))) 8601 8639 return false; 8602 8640 } … … 8606 8644 { 8607 8645 // 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))) 8609 8647 return false; 8610 8648 } … … 8613 8651 // Units far than max visible distance for creature or not in our map are not visible too 8614 8652 // Active unit should always be visibile 8615 if (!IsWithinDistInMap( u, u->isActive()8653 if (!IsWithinDistInMap(target, target->isActive() 8616 8654 ? (MAX_VISIBILITY_DISTANCE - (inVisibleList ? 0.0f : World::GetVisibleUnitGreyDistance())) 8617 8655 : (World::GetMaxVisibleDistanceForCreature() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f)))) … … 8622 8660 { 8623 8661 // 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))) 8625 8663 return false; 8626 8664 } … … 8628 8666 { 8629 8667 // 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))) 8631 8669 return false; 8632 8670 } … … 9872 9910 RemoveAllDynObjects(); 9873 9911 GetMotionMaster()->Clear(false); // remove different non-standard movement generators. 9912 9913 UnpossessSelf(false); 9874 9914 } 9875 9915 RemoveFromWorld(); … … 9924 9964 void CharmInfo::InitPossessCreateSpells() 9925 9965 { 9926 if(m_unit->GetTypeId() == TYPEID_PLAYER)9927 return;9928 9929 InitEmptyActionBar(); //charm action bar9930 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 else9936 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 } 9937 9977 } 9938 9978 } -
trunk/src/game/Unit.h
r161 r174 990 990 void SetPet(Pet* pet); 991 991 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 992 1007 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()); } 993 1013 994 1014 CharmInfo* GetCharmInfo() { return m_charmInfo; } 995 1015 CharmInfo* InitCharmInfo(Unit* charm); 1016 void UncharmSelf(); 1017 void UnpossessSelf(bool attack); 996 1018 997 1019 Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); … … 1317 1339 1318 1340 CharmInfo *m_charmInfo; 1341 bool m_isPossessed; 1319 1342 1320 1343 virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; -
trunk/src/game/WorldSession.cpp
r173 r174 367 367 _player->RemoveFromGroup(); 368 368 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 369 376 ///- Remove the player from the world 370 377 // the player may not be in the world when logging out -
trunk/src/game/WorldSession.h
r173 r174 32 32 struct AuctionEntry; 33 33 struct DeclinedName; 34 struct MovementInfo; 34 35 35 36 class Creature; … … 318 319 319 320 void HandleMovementOpcodes(WorldPacket& recvPacket); 321 void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags); 320 322 void HandleSetActiveMoverOpcode(WorldPacket &recv_data); 321 323 void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data); -
trunk/win/VC71/game.vcproj
r86 r174 734 734 </File> 735 735 <File 736 RelativePath="..\..\src\game\PossessedAI.cpp" 737 > 738 </File> 739 <File 740 RelativePath="..\..\src\game\PossessedAI.h" 741 > 742 </File> 743 <File 736 744 RelativePath="..\..\src\game\RandomMovementGenerator.cpp"> 737 745 </File> -
trunk/win/VC80/game.vcproj
r86 r174 1128 1128 </File> 1129 1129 <File 1130 RelativePath="..\..\src\game\PossessedAI.cpp" 1131 > 1132 </File> 1133 <File 1134 RelativePath="..\..\src\game\PossessedAI.h" 1135 > 1136 </File> 1137 <File 1130 1138 RelativePath="..\..\src\game\PointMovementGenerator.h" 1131 1139 > -
trunk/win/VC90/game.vcproj
r86 r174 2 2 <VisualStudioProject 3 3 ProjectType="Visual C++" 4 Version="9 ,00"4 Version="9.00" 5 5 Name="game" 6 6 ProjectGUID="{1DC6C4DA-A028-41F3-877D-D5400C594F88}" … … 49 49 Optimization="0" 50 50 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;" 52 52 StringPooling="false" 53 53 MinimalRebuild="false" … … 102 102 </Configuration> 103 103 <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 <Tool114 Name="VCPreBuildEventTool"115 />116 <Tool117 Name="VCCustomBuildTool"118 />119 <Tool120 Name="VCXMLDataGeneratorTool"121 />122 <Tool123 Name="VCWebServiceProxyGeneratorTool"124 />125 <Tool126 Name="VCMIDLTool"127 TargetEnvironment="3"128 />129 <Tool130 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 <Tool154 Name="VCManagedResourceCompilerTool"155 />156 <Tool157 Name="VCResourceCompilerTool"158 PreprocessorDefinitions="_DEBUG"159 Culture="1033"160 />161 <Tool162 Name="VCPreLinkEventTool"163 />164 <Tool165 Name="VCLibrarianTool"166 AdditionalDependencies=".\shared__$(PlatformName)_$(ConfigurationName)\shared.lib"167 OutputFile=".\game__$(PlatformName)_$(ConfigurationName)\game.lib"168 SuppressStartupBanner="true"169 />170 <Tool171 Name="VCALinkTool"172 />173 <Tool174 Name="VCXDCMakeTool"175 />176 <Tool177 Name="VCBscMakeTool"178 />179 <Tool180 Name="VCFxCopTool"181 />182 <Tool183 Name="VCPostBuildEventTool"184 />185 </Configuration>186 <Configuration187 104 Name="Release|Win32" 188 105 OutputDirectory=".\game__$(PlatformName)_$(ConfigurationName)" … … 214 131 InlineFunctionExpansion="1" 215 132 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" 219 138 EnableFunctionLevelLinking="true" 220 139 EnableEnhancedInstructionSet="1" … … 239 158 Name="VCResourceCompilerTool" 240 159 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" 241 241 Culture="1033" 242 242 /> … … 1137 1137 </File> 1138 1138 <File 1139 RelativePath="..\..\src\game\PossessedAI.cpp" 1140 > 1141 </File> 1142 <File 1143 RelativePath="..\..\src\game\PossessedAI.h" 1144 > 1145 </File> 1146 <File 1139 1147 RelativePath="..\..\src\game\RandomMovementGenerator.cpp" 1140 1148 >