aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp21
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h5
-rwxr-xr-xsrc/server/game/Instances/InstanceScript.h4
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/MiscHandler.cpp19
-rwxr-xr-xsrc/server/game/Server/Protocol/Opcodes.cpp2
-rwxr-xr-xsrc/server/game/Server/WorldSession.cpp5
-rwxr-xr-xsrc/server/game/Server/WorldSession.h1
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp10
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)