diff options
-rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 21 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.h | 5 | ||||
-rwxr-xr-x | src/server/game/Instances/InstanceScript.h | 4 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/MiscHandler.cpp | 19 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Opcodes.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Server/WorldSession.cpp | 5 | ||||
-rwxr-xr-x | src/server/game/Server/WorldSession.h | 1 | ||||
-rwxr-xr-x | src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp | 10 |
8 files changed, 66 insertions, 1 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 81b3b6a2170..3bf78aad49c 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -616,6 +616,8 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_ConditionErrorMsgId = 0; isDebugAreaTriggers = false; + + SetPendingBind(NULL, 0); } Player::~Player () @@ -1498,6 +1500,17 @@ void Player::Update(uint32 p_time) HandleSobering(); } + if (HasPendingBind()) + { + if (_pendingBindTimer <= p_time) + { + BindToInstance(); + SetPendingBind(NULL, 0); + } + else + _pendingBindTimer -= p_time; + } + // not auto-free ghost from body in instances if (m_deathTimer > 0 && !GetBaseMap()->Instanceable()) { @@ -17688,6 +17701,14 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave *save, bool permanent, b return NULL; } +void Player::BindToInstance() +{ + WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); + data << uint32(0); + GetSession()->SendPacket(&data); + BindToInstance(_pendingBind, true); +} + void Player::SendRaidInfo() { uint32 counter = 0; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ac28ccf89d3..1e736fee32d 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2302,6 +2302,9 @@ class Player : public Unit, public GridObject<Player> void UnbindInstance(uint32 mapid, Difficulty difficulty, bool unload = false); void UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload = false); InstancePlayerBind* BindToInstance(InstanceSave *save, bool permanent, bool load = false); + void BindToInstance(); + void SetPendingBind(InstanceSave* save, uint32 bindTimer) { _pendingBind = save; _pendingBindTimer = bindTimer; } + bool HasPendingBind() const { return _pendingBind != NULL; } void SendRaidInfo(); void SendSavedInstances(); static void ConvertInstancesToGroup(Player *player, Group *group = NULL, uint64 player_guid = 0); @@ -2720,6 +2723,8 @@ class Player : public Unit, public GridObject<Player> uint32 m_timeSyncServer; InstanceTimeMap _instanceResetTimes; + InstanceSave* _pendingBind; + uint32 _pendingBindTimer; }; void AddItemsSetItem(Player*player,Item *item); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 652c29fbf2f..5e293eee0ca 100755 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -196,6 +196,10 @@ class InstanceScript : public ZoneScript // Checks boss requirements (one boss required to kill other) virtual bool CheckRequiredBosses(uint32 /*bossId*/, Player const* /*player*/ = NULL) const { return true; } + // Returns completed encounters mask for packets + // NOTE: MUST USE ENCOUNTER IDS FROM DungeonEncounter.dbc 4th column + virtual uint32 GetCompletedEncounterMask() const { return 0; } + void SendEncounterUnit(uint32 type, Unit* unit = NULL, uint8 param1 = 0, uint8 param2 = 0); protected: diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp index 218775e9512..8b659d82c02 100755 --- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp @@ -1741,3 +1741,22 @@ void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recv_data*/) _player->ResurrectPlayer(100); _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); } + +void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) +{ + uint8 accept; + recvPacket >> accept; + + if (!_player->HasPendingBind()) + { + sLog->outDetail("InstanceLockResponse: Player %s (guid %u) tried to bind himself/teleport to graveyard without a pending bind!", _player->GetName(), _player->GetGUIDLow()); + return; + } + + if (accept) + _player->BindToInstance(); + else + _player->RepopAtGraveyard(); + + _player->SetPendingBind(NULL, 0); +} diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 49ac60112c2..f73288feeb7 100755 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -345,7 +345,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSelectionOpcode }, /*0x13E*/ { "CMSG_EQUIPMENT_SET_DELETE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete }, - /*0x13F*/ { "CMSG_INSTANCE_LOCK_WARNING_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x13F*/ { "CMSG_INSTANCE_LOCK_WARNING_RESPONSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse }, /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackSwingOpcode }, /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackStopOpcode }, diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 88b6120d28d..a5ad60fc5ba 100755 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -402,6 +402,11 @@ void WorldSession::LogoutPlayer(bool Save) _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); } + else if (_player->HasPendingBind()) + { + _player->RepopAtGraveyard(); + _player->SetPendingBind(NULL, 0); + } //drop a flag if player is carrying it if (Battleground *bg = _player->GetBattleground()) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 4823d204a2b..926b0ac32e9 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -754,6 +754,7 @@ class WorldSession void HandleWhoisOpcode(WorldPacket& recv_data); void HandleResetInstancesOpcode(WorldPacket& recv_data); void HandleHearthAndResurrect(WorldPacket& recv_data); + void HandleInstanceLockResponse(WorldPacket& recvPacket); // Looking for Dungeon/Raid void HandleLfgSetCommentOpcode(WorldPacket & recv_data); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index c739364d23d..758bb92a1aa 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -395,6 +395,16 @@ class instance_icecrown_citadel : public InstanceMapScript return true; } + uint32 GetCompletedEncounterMask() const + { + uint32 mask = 0; + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (GetBossState(i) == DONE) + mask |= 1 << i; + + return mask; + } + void SetData(uint32 type, uint32 data) { switch (type) |