aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpp <spp@jorge.gr>2010-05-20 23:35:27 +0200
committerSpp <spp@jorge.gr>2010-05-20 23:35:27 +0200
commitdefd13197071f4fe3975183ca67e4e8fabee8fad (patch)
treefffdbe39560b49fbc09355c98051e5d1908d95e5
parente6ba336f919e1e25e685964ad13992edf312d42b (diff)
Dungeon Finder: Initial setup and dungeon listing
--HG-- branch : trunk
-rw-r--r--src/game/CMakeLists.txt3
-rw-r--r--src/game/Channel.cpp3
-rw-r--r--src/game/CharacterHandler.cpp2
-rw-r--r--src/game/DBCStores.cpp3
-rw-r--r--src/game/DBCStores.h1
-rw-r--r--src/game/DBCStructure.h23
-rw-r--r--src/game/DBCfmt.h1
-rw-r--r--src/game/Group.cpp6
-rw-r--r--src/game/GroupHandler.cpp11
-rw-r--r--src/game/LFG.h72
-rw-r--r--src/game/LFGHandler.cpp468
-rw-r--r--src/game/LFGMgr.cpp440
-rw-r--r--src/game/LFGMgr.h162
-rw-r--r--src/game/Opcodes.cpp28
-rw-r--r--src/game/Player.h69
-rw-r--r--src/game/World.cpp5
-rw-r--r--src/game/WorldSession.h19
-rw-r--r--win/VC90/game.vcproj12
18 files changed, 851 insertions, 477 deletions
diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
index ab5ef6c2f56..3197185240d 100644
--- a/src/game/CMakeLists.txt
+++ b/src/game/CMakeLists.txt
@@ -146,7 +146,10 @@ SET(game_STAT_SRCS
Level1.cpp
Level2.cpp
Level3.cpp
+ LFG.h
LFGHandler.cpp
+ LFGMgr.cpp
+ LFGMgr.h
LootHandler.cpp
LootMgr.cpp
LootMgr.h
diff --git a/src/game/Channel.cpp b/src/game/Channel.cpp
index 68de32fd690..0047892972b 100644
--- a/src/game/Channel.cpp
+++ b/src/game/Channel.cpp
@@ -161,8 +161,7 @@ void Channel::Join(uint64 p, const char *pass)
if (plr)
{
if (HasFlag(CHANNEL_FLAG_LFG) &&
- sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER &&
- (plr->GetGroup() || plr->m_lookingForGroup.Empty()))
+ sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER && plr->GetGroup())
{
MakeNotInLfg(&data);
SendToOne(&data, p);
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index 066585175c4..d7f5d11cdfe 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -851,7 +851,7 @@ void WorldSession::HandleMeetingStoneInfo(WorldPacket & /*recv_data*/)
{
DEBUG_LOG("WORLD: Received CMSG_MEETING_STONE_INFO");
- SendLfgUpdate(0, 0, 0);
+ //SendLfgUpdate(0, 0, 0);
}
void WorldSession::HandleTutorialFlag(WorldPacket & recv_data)
diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp
index aeeb3f50e68..31848b26788 100644
--- a/src/game/DBCStores.cpp
+++ b/src/game/DBCStores.cpp
@@ -96,6 +96,8 @@ DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomProp
DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt);
+DBCStorage <LFGDungeonEntry> sLFGDungeonStore(LFGDungeonEntryfmt);
+
DBCStorage <LockEntry> sLockStore(LockEntryfmt);
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
@@ -319,6 +321,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc");
+ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLFGDungeonStore, dbcPath,"LFGDungeons.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc");
diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h
index e1d0c3e7721..acf5ac8ec41 100644
--- a/src/game/DBCStores.h
+++ b/src/game/DBCStores.h
@@ -113,6 +113,7 @@ extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore;
extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
extern DBCStorage <ItemSetEntry> sItemSetStore;
+extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore;
extern DBCStorage <LockEntry> sLockStore;
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
extern DBCStorage <MapEntry> sMapStore;
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 77393f2c4b4..f86eecc7644 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1092,6 +1092,29 @@ struct ItemSetEntry
uint32 required_skill_value; // 52 m_requiredSkillRank
};
+struct LFGDungeonEntry
+{
+ uint32 ID; // 0
+ //char* name[16]; // 1-17 Name lang
+ uint32 minlevel; // 18
+ uint32 maxlevel; // 19
+ uint32 reclevel; // 20
+ uint32 recminlevel; // 21
+ uint32 recmaxlevel; // 22
+ uint32 map; // 23
+ uint32 heroic; // 24
+ //uint32 unk; // 25
+ uint32 type; // 26
+ //uint32 unk2; // 27
+ //char* unk3; // 28
+ uint32 expansion; // 29
+ //uint32 unk4; // 30
+ uint32 grouptype; // 31
+ //char* desc[16]; // 32-47 Description
+ // Helpers
+ uint32 Entry() const { return ID + (type << 24); }
+};
+
#define MAX_LOCK_CASE 8
struct LockEntry
diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
index e192f3594b5..a5c1bc92d65 100644
--- a/src/game/DBCfmt.h
+++ b/src/game/DBCfmt.h
@@ -73,6 +73,7 @@ const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxix";
const char ItemRandomPropertiesfmt[]="nxiiiiissssssssssssssssx";
const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiiiiiiiii";
const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii";
+const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiixixxixixxxxxxxxxxxxxxxxx";
const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx";
const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix";
diff --git a/src/game/Group.cpp b/src/game/Group.cpp
index 91d6a263c85..ceec11fa94a 100644
--- a/src/game/Group.cpp
+++ b/src/game/Group.cpp
@@ -33,6 +33,7 @@
#include "InstanceSaveMgr.h"
#include "MapInstanced.h"
#include "Util.h"
+#include "LFG.h"
Group::Group()
{
@@ -384,7 +385,7 @@ uint32 Group::RemoveMember(const uint64 &guid, const uint8 &method)
}
// if group before remove <= 2 disband it
else
- Disband(true);
+ Disband();
return m_memberSlots.size();
}
@@ -425,6 +426,8 @@ void Group::Disband(bool hideDestroy)
player->SetOriginalGroup(NULL);
else
player->SetGroup(NULL);
+ player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_GROUP_DISBAND);
+ player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_LEADER);
}
// quest related GO state dependent from raid membership
@@ -1260,6 +1263,7 @@ bool Group::_removeMember(const uint64 &guid)
player->SetOriginalGroup(NULL);
else
player->SetGroup(NULL);
+ player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_LEADER);
}
}
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index cd58b30042c..f973bc24722 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -32,6 +32,7 @@
#include "Util.h"
#include "SpellAuras.h"
#include "Vehicle.h"
+#include "LFG.h"
class Aura;
@@ -176,6 +177,8 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data)
data << uint32(0); // unk
player->GetSession()->SendPacket(&data);
+ SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
+ SendLfgUpdateParty(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK);
}
@@ -218,6 +221,14 @@ void WorldSession::HandleGroupAcceptOpcode(WorldPacket & /*recv_data*/)
if (!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()))
return;
+ SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE);
+ for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ if (Player *plrg = itr->getSource())
+ {
+ plrg->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_CLEAR_LOCK_LIST);
+ plrg->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_CLEAR_LOCK_LIST);
+ }
+
group->BroadcastGroupUpdate();
}
diff --git a/src/game/LFG.h b/src/game/LFG.h
new file mode 100644
index 00000000000..d30d694f43e
--- /dev/null
+++ b/src/game/LFG.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LFG_H
+#define _LFG_H
+
+#include "Platform/Define.h"
+#include "Object.h"
+
+enum LfgRoles
+{
+ NONE = 0x00,
+ LEADER = 0x01,
+ TANK = 0x02,
+ HEALER = 0x04,
+ DAMAGE = 0x08,
+};
+
+enum LfgUpdateType
+{
+ LFG_UPDATETYPE_LEADER = 1,
+ LFG_UPDATETYPE_ROLECHECK_ABORTED = 4,
+ LFG_UPDATETYPE_JOIN_PROPOSAL = 5,
+ LFG_UPDATETYPE_ROLECHECK_FAILED = 6,
+ LFG_UPDATETYPE_REMOVED_FROM_QUEUE = 7,
+ LFG_UPDATETYPE_PROPOSAL_FAILED = 8,
+ LFG_UPDATETYPE_PROPOSAL_DECLINED = 9,
+ LFG_UPDATETYPE_GROUP_FOUND = 10,
+ LFG_UPDATETYPE_ADDED_TO_QUEUE = 12,
+ LFG_UPDATETYPE_PROPOSAL_FOUND = 13,
+ LFG_UPDATETYPE_CLEAR_LOCK_LIST = 14,
+ LFG_UPDATETYPE_GROUP_MEMBER_OFFLINE = 15,
+ LFG_UPDATETYPE_GROUP_DISBAND = 16,
+};
+
+typedef std::set<uint32> LfgDungeonSet;
+
+struct LookingForGroup
+{
+ LookingForGroup(): roles(0)
+ {
+ donerandomDungeons.clear();
+ applyDungeons.clear();
+ }
+ std::string comment;
+ int8 roles;
+
+ bool isDungeonDone(const uint32 entry)
+ {
+ return donerandomDungeons.find(entry) != donerandomDungeons.end();
+ }
+
+ LfgDungeonSet applyDungeons; // Dungeons the player have applied for
+ LfgDungeonSet donerandomDungeons; // Finished random Dungeons (to calculate the bonus);
+};
+
+#endif
diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp
index a98ec48e864..da9e32338cd 100644
--- a/src/game/LFGHandler.cpp
+++ b/src/game/LFGHandler.cpp
@@ -1,5 +1,4 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
@@ -18,417 +17,128 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "LFGMgr.h"
#include "WorldSession.h"
-#include "Log.h"
-#include "Database/DatabaseEnv.h"
-#include "Player.h"
#include "WorldPacket.h"
-#include "ObjectMgr.h"
-#include "World.h"
-
-static void AttemptJoin(Player* _player)
-{
- // skip not can autojoin cases and player group case
- if (!_player->m_lookingForGroup.canAutoJoin() || _player->GetGroup())
- return;
-
- ObjectAccessor::Guard guard(*HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& players = ObjectAccessor::Instance().GetPlayers();
- for (HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
- {
- Player *plr = iter->second;
-
- // skip enemies and self
- if (!plr || plr == _player || plr->GetTeam() != _player->GetTeam())
- continue;
-
- //skip players not in world
- if (!plr->IsInWorld())
- continue;
-
- // skip not auto add, not group leader cases
- if (!plr->GetSession()->LookingForGroup_auto_add || plr->GetGroup() && plr->GetGroup()->GetLeaderGUID() != plr->GetGUID())
- continue;
-
- // skip non auto-join or empty slots, or non compatible slots
- if (!plr->m_lookingForGroup.more.canAutoJoin() || !_player->m_lookingForGroup.HaveInSlot(plr->m_lookingForGroup.more))
- continue;
-
- // attempt create group, or skip
- if (!plr->GetGroup())
- {
- Group* group = new Group;
- if (!group->Create(plr->GetGUID(), plr->GetName()))
- {
- delete group;
- continue;
- }
-
- objmgr.AddGroup(group);
- }
-
- // stop at success join
- if (plr->GetGroup()->AddMember(_player->GetGUID(), _player->GetName()))
- {
- if (sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER)
- _player->LeaveLFGChannel();
- break;
- }
- // full
- else
- {
- if (sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER)
- plr->LeaveLFGChannel();
- }
- }
-}
-
-static void AttemptAddMore(Player* _player)
-{
- // skip not group leader case
- if (_player->GetGroup() && _player->GetGroup()->GetLeaderGUID() != _player->GetGUID())
- return;
-
- if (!_player->m_lookingForGroup.more.canAutoJoin())
- return;
-
- ObjectAccessor::Guard guard(*HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& players = ObjectAccessor::Instance().GetPlayers();
- for (HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
- {
- Player *plr = iter->second;
-
- // skip enemies and self
- if (!plr || plr == _player || plr->GetTeam() != _player->GetTeam())
- continue;
-
- if (!plr->IsInWorld())
- continue;
-
- // skip not auto join or in group
- if (!plr->GetSession()->LookingForGroup_auto_join || plr->GetGroup())
- continue;
-
- if (!plr->m_lookingForGroup.HaveInSlot(_player->m_lookingForGroup.more))
- continue;
-
- // attempt create group if need, or stop attempts
- if (!_player->GetGroup())
- {
- Group* group = new Group;
- if (!group->Create(_player->GetGUID(), _player->GetName()))
- {
- delete group;
- return; // can't create group (??)
- }
-
- objmgr.AddGroup(group);
- }
-
- // stop at join fail (full)
- if (!_player->GetGroup()->AddMember(plr->GetGUID(), plr->GetName()))
- {
- if (sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER)
- _player->LeaveLFGChannel();
-
- break;
- }
-
- // joined
- if (sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER)
- plr->LeaveLFGChannel();
-
- // and group full
- if (_player->GetGroup()->IsFull())
- {
- if (sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER)
- _player->LeaveLFGChannel();
-
- break;
- }
- }
-}
-
-void WorldSession::HandleLfgSetAutoJoinOpcode(WorldPacket & /*recv_data*/)
-{
- sLog.outDebug("CMSG_LFG_SET_AUTOJOIN");
- LookingForGroup_auto_join = true;
-
- if (!_player) // needed because STATUS_AUTHED
- return;
-
- AttemptJoin(_player);
-}
-
-void WorldSession::HandleLfgClearAutoJoinOpcode(WorldPacket & /*recv_data*/)
-{
- sLog.outDebug("CMSG_LFG_CLEAR_AUTOJOIN");
- LookingForGroup_auto_join = false;
-}
-
-void WorldSession::HandleLfmSetAutoFillOpcode(WorldPacket & /*recv_data*/)
-{
- sLog.outDebug("CMSG_LFM_SET_AUTOFILL");
- LookingForGroup_auto_add = true;
-
- if (!_player) // needed because STATUS_AUTHED
- return;
-
- AttemptAddMore(_player);
-}
-
-void WorldSession::HandleLfmClearAutoFillOpcode(WorldPacket & /*recv_data*/)
-{
- sLog.outDebug("CMSG_LFM_CLEAR_AUTOFILL");
- LookingForGroup_auto_add = false;
-}
-
-void WorldSession::HandleLfgClearOpcode(WorldPacket & /*recv_data */)
-{
- // empty packet
- sLog.outDebug("CMSG_CLEAR_LOOKING_FOR_GROUP");
-
- for (int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
- _player->m_lookingForGroup.slots[i].Clear();
-
- if (sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER)
- _player->LeaveLFGChannel();
-
- SendLfgUpdate(0, 0, 0);
-}
-
-void WorldSession::HandleLfmClearOpcode(WorldPacket & /*recv_data */)
-{
- // empty packet
- sLog.outDebug("CMSG_CLEAR_LOOKING_FOR_MORE");
-
- _player->m_lookingForGroup.more.Clear();
-}
-
-void WorldSession::HandleSetLfmOpcode(WorldPacket & recv_data)
-{
- sLog.outDebug("CMSG_SET_LOOKING_FOR_MORE");
- //recv_data.hexlike();
- uint32 temp, entry, type;
- uint8 unk1;
- uint8 unk2[3];
-
- recv_data >> temp >> unk1 >> unk2[0] >> unk2[1] >> unk2[2];
-
- entry = (temp & 0x00FFFFFF);
- type = ((temp >> 24) & 0x000000FF);
-
- _player->m_lookingForGroup.more.Set(entry,type);
- sLog.outDebug("LFM set: temp %u, zone %u, type %u", temp, entry, type);
-
- if (LookingForGroup_auto_add)
- AttemptAddMore(_player);
-
- SendLfgResult(type, entry, 1);
-}
void WorldSession::HandleSetLfgCommentOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_SET_LFG_COMMENT");
- //recv_data.hexlike();
std::string comment;
recv_data >> comment;
- sLog.outDebug("LFG comment %s", comment.c_str());
- _player->m_lookingForGroup.comment = comment;
+ GetPlayer()->m_lookingForGroup.comment = comment;
}
-void WorldSession::HandleLookingForGroup(WorldPacket& recv_data)
+void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket &/*recv_data*/)
{
- sLog.outDebug("MSG_LOOKING_FOR_GROUP");
- //recv_data.hexlike();
- uint32 type, entry, unk;
-
- recv_data >> type >> entry >> unk;
- sLog.outDebug("MSG_LOOKING_FOR_GROUP: type %u, entry %u, unk %u", type, entry, unk);
-
- if (LookingForGroup_auto_add)
- AttemptAddMore(_player);
-
- if (LookingForGroup_auto_join)
- AttemptJoin(_player);
-
- SendLfgResult(type, entry, 0);
- SendLfgUpdate(0, 1, 0);
+ sLog.outDebug("CMSG_LFD_PLAYER_LOCK_INFO_REQUEST");
+ sLFGMgr.SendLfgPlayerInfo(GetPlayer());
}
-void WorldSession::SendLfgResult(uint32 /*type*/, uint32 /*entry*/, uint8 /*lfg_type*/)
-{/*
- uint32 number = 0;
+void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket &/*recv_data*/)
+{
+ sLog.outDebug("CMSG_LFD_PARTY_LOCK_INFO_REQUEST");
+ sLFGMgr.SendLfgPartyInfo(GetPlayer());
+}
- WorldPacket data(MSG_LOOKING_FOR_GROUP);
- data << uint32(type); // type
- data << uint32(entry); // entry from LFGDungeons.dbc
+void WorldSession::SendLfgUpdatePlayer(uint8 updateType, uint32 dungeonEntry /* = 0*/)
+{
+ bool queued = false;
+ bool extrainfo = false;
- data << uint8(0);
- if (uint8)
+ switch(updateType)
{
- uint32 count1;
- for (count1)
- {
- uint64; // player guid
- }
+ case LFG_UPDATETYPE_JOIN_PROPOSAL:
+ case LFG_UPDATETYPE_ADDED_TO_QUEUE:
+ queued = true;
+ extrainfo = true;
+ break;
+ //case LFG_UPDATETYPE_CLEAR_LOCK_LIST: // TODO: Sometimes has extrainfo - Check ocurrences...
+ case LFG_UPDATETYPE_PROPOSAL_FOUND:
+ extrainfo = true;
+ break;
}
-
- data << uint32(0); // count2
- data << uint32(0);
- for (count2)
+ sLog.outDebug("SMSG_LFG_UPDATE_PLAYER");
+ WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + !dungeonEntry ? 4 : GetPlayer()->m_lookingForGroup.applyDungeons.size() * 4 + GetPlayer()->m_lookingForGroup.comment.length()));
+ data << uint8(updateType); // Lfg Update type
+ data << uint8(extrainfo); // Extra info
+ if (extrainfo)
{
- uint64 // not player guid
- uint32 flags;
- if (flags & 0x2)
- {
- string
- }
- if (flags & 0x10)
+ data << uint8(queued); // Join the queue
+ data << uint8(0); // unk - Always 0
+ data << uint8(0); // unk - Always 0
+
+ if (dungeonEntry)
{
- uint8
+ data << uint8(1);
+ data << uint32(dungeonEntry);
}
- if (flags & 0x20)
+ else
{
- for (3)
- {
- uint8
- }
+ uint8 size = GetPlayer()->m_lookingForGroup.applyDungeons.size();
+ data << uint8(size);
+
+ for (LfgDungeonSet::const_iterator it = GetPlayer()->m_lookingForGroup.applyDungeons.begin(); it != GetPlayer()->m_lookingForGroup.applyDungeons.end(); ++it)
+ data << uint32(*it);
}
+ data << GetPlayer()->m_lookingForGroup.comment;
}
+ SendPacket(&data);
+}
- size_t count3_pos = data.wpos();
- data << uint32(0); // count3
- data << uint32(0); // unk
+void WorldSession::SendLfgUpdateParty(uint8 updateType, uint32 dungeonEntry /* = 0*/)
+{
+ bool join = false;
+ bool extrainfo = false;
+ bool queued = false;
- //TODO: Guard Player map
- HashMapHolder<Player>::MapType const& players = ObjectAccessor::Instance().GetPlayers();
- for (HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
+ switch(updateType)
{
- Player *plr = iter->second;
-
- if (!plr || plr->GetTeam() != _player->GetTeam())
- continue;
-
- if (!plr->IsInWorld())
- continue;
-
- if (!plr->m_lookingForGroup.HaveInSlot(entry, type))
- continue;
-
- ++number;
-
- data << uint64(plr->GetGUID()); // guid
+ case LFG_UPDATETYPE_JOIN_PROPOSAL:
+ extrainfo = true;
+ break;
+ case LFG_UPDATETYPE_ADDED_TO_QUEUE:
+ extrainfo = true;
+ join = true;
+ queued = true;
+ break;
+ case LFG_UPDATETYPE_CLEAR_LOCK_LIST:
+ // join = true; // TODO: Sometimes queued and extrainfo - Check ocurrences...
+ queued = true;
+ break;
+ case LFG_UPDATETYPE_PROPOSAL_FOUND:
+ extrainfo = true;
+ join = true;
+ break;
+ }
- uint32 flags = 0x1FF;
- data << uint32(flags); // flags
+ sLog.outDebug("SMSG_LFG_UPDATE_PARTY");
+ WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + !dungeonEntry ? 4 : GetPlayer()->m_lookingForGroup.applyDungeons.size() * 4 + GetPlayer()->m_lookingForGroup.comment.length()));
+ data << uint8(updateType); // Lfg Update type
+ data << uint8(extrainfo); // Extra info
+ if (extrainfo)
+ {
+ data << uint8(join); // LFG Join
+ data << uint8(queued); // Join the queue
+ data << uint8(0); // unk - Always 0
+ data << uint8(0); // unk - Always 0
- if (flags & 0x1)
+ if (dungeonEntry)
{
- data << uint8(plr->getLevel());
- data << uint8(plr->getClass());
- data << uint8(plr->getRace());
-
- for (int i = 0; i < 3; ++i)
- data << uint8(0); // spent talents count in specific tab
-
- data << uint32(0); // resistances1
- data << uint32(0); // spd/heal
- data << uint32(0); // spd/heal
- data << uint32(0); // combat_rating9
- data << uint32(0); // combat_rating10
- data << uint32(0); // combat_rating11
- data << float(0); // mp5
- data << float(0); // unk
- data << uint32(0); // attack power
- data << uint32(0); // stat1
- data << uint32(0); // maxhealth
- data << uint32(0); // maxpower1
- data << uint32(0); // unk
- data << float(0); // unk
- data << uint32(0); // unk
- data << uint32(0); // unk
- data << uint32(0); // unk
- data << uint32(0); // unk
- data << uint32(0); // combat_rating20
- data << uint32(0); // unk
+ data << uint8(1);
+ data << uint32(dungeonEntry);
}
-
- if (flags & 0x2)
- data << plr->m_lookingForGroup.comment; // comment
-
- if (flags & 0x4)
- data << uint8(0); // unk
-
- if (flags & 0x8)
- data << uint64(0); // guid from count2 block, not player guid
-
- if (flags & 0x10)
- data << uint8(0); // unk
-
- if (flags & 0x20)
- data << uint8(plr->m_lookingForGroup.roles); // roles
-
- if (flags & 0x40)
- data << uint32(plr->GetZoneId()); // areaid
-
- if (flags & 0x100)
- data << uint8(0); // LFG/LFM flag?
-
- if (flags & 0x80)
+ else
{
- for (uint8 j = 0; j < MAX_LOOKING_FOR_GROUP_SLOT; ++j)
- {
- data << uint32(plr->m_lookingForGroup.slots[j].entry | (plr->m_lookingForGroup.slots[j].type << 24));
- }
+ uint8 size = GetPlayer()->m_lookingForGroup.applyDungeons.size();
+ data << uint8(size);
+
+ for (LfgDungeonSet::const_iterator it = GetPlayer()->m_lookingForGroup.applyDungeons.begin(); it != GetPlayer()->m_lookingForGroup.applyDungeons.end(); ++it)
+ data << uint32(*it);
}
+ data << GetPlayer()->m_lookingForGroup.comment;
}
-
- data.put<uint32>(count3_pos, number); // fill count placeholder
-
SendPacket(&data);
-*/
-}
-
-void WorldSession::HandleSetLfgOpcode(WorldPacket & recv_data)
-{
- sLog.outDebug("CMSG_SET_LOOKING_FOR_GROUP");
- recv_data.hexlike();
- uint32 slot, temp, entry, type;
- uint8 roles, unk1;
-
- recv_data >> slot >> temp >> roles >> unk1;
-
- entry = (temp & 0x00FFFFFF);
- type = ((temp >> 24) & 0x000000FF);
-
- if (slot >= MAX_LOOKING_FOR_GROUP_SLOT)
- return;
-
- _player->m_lookingForGroup.slots[slot].Set(entry, type);
- _player->m_lookingForGroup.roles = roles;
- sLog.outDebug("LFG set: looknumber %u, temp %X, type %u, entry %u", slot, temp, type, entry);
-
- if (LookingForGroup_auto_join)
- AttemptJoin(_player);
-
- //SendLfgResult(type, entry, 0);
- SendLfgUpdate(0, 1, 0);
-}
-
-void WorldSession::HandleLfgSetRoles(WorldPacket &recv_data)
-{
- sLog.outDebug("CMSG_LFG_SET_ROLES");
-
- uint8 roles;
- recv_data >> roles;
-
- _player->m_lookingForGroup.roles = roles;
-}
-
-void WorldSession::SendLfgUpdate(uint8 /*unk1*/, uint8 /*unk2*/, uint8 /*unk3*/)
-{
-
-}
+} \ No newline at end of file
diff --git a/src/game/LFGMgr.cpp b/src/game/LFGMgr.cpp
new file mode 100644
index 00000000000..474a34fe9d6
--- /dev/null
+++ b/src/game/LFGMgr.cpp
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "Policies/SingletonImp.h"
+#include "Common.h"
+#include "SharedDefines.h"
+#include "Group.h"
+#include "Player.h"
+#include "LFGMgr.h"
+#include "ObjectMgr.h"
+#include "WorldPacket.h"
+
+INSTANTIATE_SINGLETON_1(LFGMgr);
+
+LFGMgr::LFGMgr()
+{
+}
+
+LFGMgr::~LFGMgr()
+{
+ for (LfgRewardList::iterator it = m_RewardList.begin(); it != m_RewardList.end(); ++it)
+ delete *it;
+ m_RewardList.clear();
+
+ for (LfgRewardList::iterator it = m_RewardDoneList.begin(); it != m_RewardDoneList.end(); ++it)
+ delete *it;
+ m_RewardDoneList.clear();
+
+ for (LfgDungeonMap::iterator it = m_DungeonsMap.begin(); it != m_DungeonsMap.end(); ++it)
+ {
+ it->second->clear();
+ delete it->second;
+ }
+ m_DungeonsMap.clear();
+}
+
+/// <summary>
+/// Initialize Looking For Group
+/// </summary>
+void LFGMgr::InitLFG()
+{
+ // Fill reward data
+ LfgReward *reward;
+ for (uint8 i = 0; i <= LFG_REWARD_DATA_SIZE; ++i)
+ {
+ reward = new LfgReward();
+ reward->strangers = 0;
+ reward->baseXP = RewardDungeonData[i][0];
+ reward->baseMoney = RewardDungeonData[i][1];
+ reward->variableMoney = 0;
+ reward->variableXP = 0;
+ reward->itemId = RewardDungeonData[i][2];
+ reward->displayId = RewardDungeonData[i][3];
+ reward->stackCount = RewardDungeonData[i][4];
+ m_RewardList.push_back(reward);
+ }
+
+ for (uint8 i = 0; i < LFG_REWARD_DATA_SIZE; ++i)
+ {
+ reward = new LfgReward();
+ reward->strangers = 0;
+ reward->baseXP = RewardDungeonDoneData[i][0];
+ reward->baseMoney = RewardDungeonDoneData[i][1];
+ reward->variableMoney = 0;
+ reward->variableXP = 0;
+ reward->itemId = RewardDungeonDoneData[i][2];
+ reward->displayId = RewardDungeonDoneData[i][3];
+ reward->stackCount = RewardDungeonDoneData[i][4];
+ m_RewardDoneList.push_back(reward);
+ }
+ // Initialize dungeonMap
+ m_DungeonsMap[LFG_ALL_DUNGEONS] = GetAllDungeons();
+ /* This will be used later.
+ m_DungeonsMap[LFG_RANDOM_CLASSIC] = GetDungeonsByRandom(LFG_RANDOM_CLASSIC);
+ m_DungeonsMap[LFG_RANDOM_BC_NORMAL] = GetDungeonsByRandom(LFG_RANDOM_BC_NORMAL);
+ m_DungeonsMap[LFG_RANDOM_BC_HEROIC] = GetDungeonsByRandom(LFG_RANDOM_BC_HEROIC);
+ m_DungeonsMap[LFG_RANDOM_LK_NORMAL] = GetDungeonsByRandom(LFG_RANDOM_LK_NORMAL);
+ m_DungeonsMap[LFG_RANDOM_LK_HEROIC] = GetDungeonsByRandom(LFG_RANDOM_LK_HEROIC);
+ */
+}
+
+
+
+// --------------------------------------------------------------------------//
+// Packet Functions
+// --------------------------------------------------------------------------//
+
+/// <summary>
+/// Build and Send LFG lock player info and reward
+/// </summary>
+/// <param name="plr">Player</param>
+void LFGMgr::SendLfgPlayerInfo(Player *plr)
+{
+ uint32 rsize = 0;
+ uint32 lsize = 0;
+ LfgDungeonSet *randomlist = GetRandomDungeons(plr->getLevel(), plr->GetSession()->Expansion());
+ LfgLockStatusSet *lockSet = GetPlayerLockStatusDungeons(plr, m_DungeonsMap[LFG_ALL_DUNGEONS]);
+ if (randomlist)
+ rsize = randomlist->size();
+ if (lockSet)
+ lsize = lockSet->size();
+
+ sLog.outDebug("SMSG_LFG_PLAYER_INFO");
+ WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (4 + 4));
+ if (!randomlist)
+ {
+ data << uint8(0);
+ }
+ else
+ {
+ data << uint8(randomlist->size()); // Random Dungeon count
+ for (LfgDungeonSet::iterator it = randomlist->begin(); it != randomlist->end(); ++it)
+ {
+ data << uint32(*it); // Entry
+ BuildRewardBlock(data, *it, plr);
+ }
+ randomlist->clear();
+ delete randomlist;
+ }
+ BuildPlayerLockDungeonBlock(data, lockSet);
+ plr->GetSession()->SendPacket(&data);
+}
+
+/// <summary>
+/// Build and Send LFG lock party info and reward
+/// </summary>
+/// <param name="plr">Player</param>
+void LFGMgr::SendLfgPartyInfo(Player *plr)
+{
+ if (LfgLockStatusMap *lockMap = GetPartyLockStatusDungeons(plr, m_DungeonsMap[LFG_ALL_DUNGEONS]))
+ {
+ uint32 size = 0;
+ for (LfgLockStatusMap::const_iterator it = lockMap->begin(); it != lockMap->end(); ++it)
+ size += 8 + 4 + it->second->size() * (4 + 4);
+ sLog.outDebug("SMSG_LFG_PARTY_INFO");
+ WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size);
+ BuildPartyLockDungeonBlock(data, lockMap);
+ plr->GetSession()->SendPacket(&data);
+ }
+}
+
+/// <summary>
+/// Build Reward packet structure for a given dungeon
+/// </summary>
+/// <param name="data">WorldPacket</param>
+/// <param name="dungeon">Dungeon entry</param>
+/// <param name="plr">Player</param>
+void LFGMgr::BuildRewardBlock(WorldPacket &data, uint32 dungeon, Player *plr)
+{
+ bool done = plr->m_lookingForGroup.isDungeonDone(dungeon);
+ LfgReward *reward = GetRandomDungeonReward(dungeon, done, plr->getLevel());
+
+ if (!reward)
+ return;
+
+ data << uint8(done);
+ if (data.GetOpcode() == SMSG_LFG_PLAYER_REWARD)
+ data << uint32(reward->strangers);
+ data << uint32(reward->baseMoney);
+ data << uint32(reward->baseXP);
+ data << uint32(reward->variableMoney);
+ data << uint32(reward->variableXP);
+ data << uint8(reward->itemId != 0);
+ if (reward->itemId)
+ {
+ data << uint32(reward->itemId);
+ data << uint32(reward->displayId);
+ data << uint32(reward->stackCount);
+ }
+}
+
+/// <summary>
+/// Build Party Dungeon lock status packet
+/// </summary>
+/// <param name="data">WorldPacket</param>
+/// <param name="lock">lock status map</param>
+void LFGMgr::BuildPartyLockDungeonBlock(WorldPacket &data, LfgLockStatusMap *lockMap)
+{
+ assert(lockMap);
+
+ data << uint8(lockMap->size());
+
+ LfgLockStatusSet *lockSet;
+ uint64 guid;
+ for (LfgLockStatusMap::const_iterator it = lockMap->begin(); it != lockMap->end(); ++it)
+ {
+ guid = it->first;
+ lockSet = it->second;
+ if (!lockSet)
+ continue;
+
+ data << uint64(guid); // Player guid
+ BuildPlayerLockDungeonBlock(data, lockSet);
+ }
+ lockMap->clear();
+ delete lockMap;
+}
+
+/// <summary>
+/// Build Player Dungeon lock status packet
+/// </summary>
+/// <param name="data">WorldPacket</param>
+/// <param name="lock">lock status list</param>
+void LFGMgr::BuildPlayerLockDungeonBlock(WorldPacket &data, LfgLockStatusSet *lockSet)
+{
+ assert(lockSet);
+ data << uint32(lockSet->size()); // Size of lock dungeons
+ for (LfgLockStatusSet::iterator it = lockSet->begin(); it != lockSet->end(); ++it)
+ {
+ data << uint32((*it)->dungeon); // Dungeon entry + type
+ data << uint32((*it)->lockstatus); // Lock status
+ delete (*it);
+ }
+ lockSet->clear();
+ delete lockSet;
+}
+
+
+
+
+// --------------------------------------------------------------------------//
+// Auxiliar Functions
+// --------------------------------------------------------------------------//
+
+/// <summary>
+/// Get all Group members list of dungeons that can't be done and reason
+/// leader excluded as the list given is he list he can do
+/// </summary>
+/// <param name="grp">Group</param>
+/// <param name="dungeons">Dungeons to check</param>
+/// <returns>LfgLockStatusMap*</returns>
+LfgLockStatusMap* LFGMgr::GetPartyLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons)
+{
+ assert(plr);
+ assert(dungeons);
+ Group *grp = plr->GetGroup();
+ if (!grp)
+ return NULL;
+
+ Player *plrg;
+ LfgLockStatusMap *dungeonMap = new LfgLockStatusMap();
+ for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ plrg = itr->getSource();
+ if (!plrg || plrg == plr)
+ continue;
+ (*dungeonMap)[plrg->GetGUID()] = GetPlayerLockStatusDungeons(plrg, dungeons);
+ }
+ return dungeonMap;
+}
+
+/// <summary>
+/// Get list of dungeons player can't do and reasons
+/// </summary>
+/// <param name="plr">Player</param>
+/// <param name="dungeons">Dungeons to check</param>
+/// <returns>LfgLockStatusSet*</returns>
+LfgLockStatusSet* LFGMgr::GetPlayerLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons)
+{
+ LfgLockStatusSet *list = new LfgLockStatusSet();
+ LfgLockStatus *lockstatus = NULL;
+ LFGDungeonEntry const *dungeon;
+ LfgLockStatusType locktype;
+ uint8 level = plr->getLevel();
+ uint8 expansion = plr->GetSession()->Expansion();
+
+ for (LfgDungeonSet::const_iterator it = dungeons->begin(); it != dungeons->end(); ++it)
+ {
+ dungeon = sLFGDungeonStore.LookupEntry(*it);
+ assert(dungeon); // Will never happen - We provide a list from sLFGDungeonStore
+
+ locktype = LFG_LOCKSTATUS_OK;
+ if (dungeon->expansion > expansion)
+ locktype = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION;
+ else if (dungeon->minlevel > level)
+ locktype = LFG_LOCKSTATUS_TOO_LOW_LEVEL;
+ else if (dungeon->maxlevel < level)
+ locktype = LFG_LOCKSTATUS_TOO_HIGH_LEVEL;
+ /* TODO - Use these types when needed...
+ else if ()
+ locktype = LFG_LOCKSTATUS_TOO_LOG_GEAR_SCORE;
+ else if ()
+ locktype = LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE;
+ else if () // Locked due to WG, closed by GM, done daily, etc
+ locktype = LFG_LOCKSTATUS_RAID_LOCKED;
+ else if ()
+ locktype = LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL;
+ else if ()
+ locktype = LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL;
+ else if () // Need list of instances and needed quest to enter
+ locktype = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED;
+ else if () // Need list of instances and needed key to enter
+ locktype = LFG_LOCKSTATUS_MISSING_ITEM;
+ else if () // Need list of instances and needed season to open
+ locktype = LFG_LOCKSTATUS_NOT_IN_SEASON;
+ */
+
+ if (locktype != LFG_LOCKSTATUS_OK)
+ {
+ lockstatus = new LfgLockStatus();
+ lockstatus->dungeon = dungeon->Entry();
+ lockstatus->lockstatus = locktype;
+ list->insert(lockstatus);
+ }
+ }
+ return list;
+}
+
+/// <summary>
+/// Get the dungeon list that can be done.
+/// </summary>
+/// <returns>LfgDungeonSet*</returns>
+LfgDungeonSet* LFGMgr::GetAllDungeons()
+{
+ LfgDungeonSet *dungeons = new LfgDungeonSet();
+ LFGDungeonEntry const *dungeon;
+ for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
+ {
+ dungeon = sLFGDungeonStore.LookupEntry(i);
+ if (!dungeon || dungeon->type == LFG_TYPE_ZONE)
+ continue;
+ dungeons->insert(dungeon->ID);
+ }
+ if (!dungeons->size())
+ {
+ delete dungeons;
+ return NULL;
+ }
+ else
+ return dungeons;
+}
+
+/// <summary>
+/// Get the dungeon list that can be done given a random dungeon entry.
+/// </summary>
+/// <param name="randomdungeon">Random dungeon entry</param>
+/// <returns>LfgDungeonSet*</returns>
+LfgDungeonSet* LFGMgr::GetDungeonsByRandom(uint32 randomdungeon)
+{
+ LFGDungeonEntry const *dungeon = sLFGDungeonStore.LookupEntry(randomdungeon);
+ if (!dungeon)
+ return NULL;
+
+ uint32 grouptype = dungeon->grouptype;
+ LfgDungeonSet *random = new LfgDungeonSet();
+ for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
+ {
+ dungeon = sLFGDungeonStore.LookupEntry(i);
+ if (!dungeon || dungeon->type == LFG_TYPE_RANDOM || dungeon->grouptype != grouptype)
+ continue;
+ random->insert(dungeon->ID);
+ }
+ if (!random->size())
+ {
+ delete random;
+ return NULL;
+ }
+ else
+ return random;
+}
+
+/// <summary>
+/// Get the random dungeon list that can be done at a certain level and expansion.
+/// </summary>
+/// <param name="level">Player level</param>
+/// <param name="expansion">Player account expansion</param>
+/// <returns>LfgDungeonSet*</returns>
+LfgDungeonSet* LFGMgr::GetRandomDungeons(uint8 level, uint8 expansion)
+{
+ LfgDungeonSet *list = new LfgDungeonSet();
+ LFGDungeonEntry const *dungeon;
+ for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
+ {
+ dungeon = sLFGDungeonStore.LookupEntry(i);
+ if (dungeon && dungeon->expansion <= expansion && dungeon->type == LFG_TYPE_RANDOM &&
+ dungeon->minlevel <= level && level <= dungeon->maxlevel)
+ list->insert(dungeon->Entry());
+ }
+ return list;
+}
+
+/// <summary>
+/// Get the reward of a given random dungeon
+/// </summary>
+/// <param name="dungeon">random dungeon id</param>
+/// <param name="done">Dungeon previously done</param>
+/// <returns></returns>
+LfgReward* LFGMgr::GetRandomDungeonReward(uint32 dungeon, bool done, uint8 level)
+{
+ uint8 index = 0;
+ switch((dungeon & 0x00FFFFFF)) // Get dungeon id from dungeon entry
+ {
+ case LFG_RANDOM_CLASSIC:
+ if (level < 15)
+ index = LFG_REWARD_LEVEL0;
+ else if (level < 24)
+ index = LFG_REWARD_LEVEL1;
+ else if (level < 35)
+ index = LFG_REWARD_LEVEL2;
+ else if (level < 46)
+ index = LFG_REWARD_LEVEL3;
+ else if (level < 56)
+ index = LFG_REWARD_LEVEL4;
+ else
+ index = LFG_REWARD_LEVEL5;
+ break;
+ case LFG_RANDOM_BC_NORMAL:
+ index = LFG_REWARD_BC_NORMAL;
+ break;
+ case LFG_RANDOM_BC_HEROIC:
+ index = LFG_REWARD_BC_HEROIC;
+ break;
+ case LFG_RANDOM_LK_NORMAL:
+ index = level == 80 ? LFG_REWARD_LK_NORMAL80 : LFG_REWARD_LK_NORMAL;
+ break;
+ case LFG_RANDOM_LK_HEROIC:
+ index = LFG_REWARD_LK_HEROIC;
+ break;
+ default: // This should never happen!
+ done = false;
+ index = LFG_REWARD_LEVEL0;
+ sLog.outError("LFGMgr::GetRandomDungeonReward: Dungeon %u is not random dungeon!", dungeon);
+ break;
+ }
+ return done ? m_RewardDoneList.at(index) : m_RewardList.at(index);
+} \ No newline at end of file
diff --git a/src/game/LFGMgr.h b/src/game/LFGMgr.h
new file mode 100644
index 00000000000..ce58d468931
--- /dev/null
+++ b/src/game/LFGMgr.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LFGMGR_H
+#define _LFGMGR_H
+
+#include "Common.h"
+#include "Policies/Singleton.h"
+#include "Group.h"
+#include "LFG.h"
+
+
+enum LfgType
+{
+ LFG_TYPE_DUNGEON = 1,
+ LFG_TYPE_RAID = 2,
+ LFG_TYPE_QUEST = 3,
+ LFG_TYPE_ZONE = 4,
+ LFG_TYPE_HEROIC = 5,
+ LFG_TYPE_RANDOM = 6,
+};
+
+enum LfgLockStatusType
+{
+ LFG_LOCKSTATUS_OK = 0, // Internal use only
+ LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION = 1,
+ LFG_LOCKSTATUS_TOO_LOW_LEVEL = 2,
+ LFG_LOCKSTATUS_TOO_HIGH_LEVEL = 3,
+ LFG_LOCKSTATUS_TOO_LOG_GEAR_SCORE = 4,
+ LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE = 5,
+ LFG_LOCKSTATUS_RAID_LOCKED = 6,
+ LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL = 1001,
+ LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL = 1002,
+ LFG_LOCKSTATUS_QUEST_NOT_COMPLETED = 1022,
+ LFG_LOCKSTATUS_MISSING_ITEM = 1025,
+ LFG_LOCKSTATUS_NOT_IN_SEASON = 1031,
+};
+
+enum LfgRandomDungeonEntries
+{
+ LFG_ALL_DUNGEONS = 0,
+ LFG_RANDOM_CLASSIC = 258,
+ LFG_RANDOM_BC_NORMAL = 259,
+ LFG_RANDOM_BC_HEROIC = 260,
+ LFG_RANDOM_LK_NORMAL = 261,
+ LFG_RANDOM_LK_HEROIC = 262,
+};
+
+enum LfgRewardEnums
+{
+ LFG_REWARD_LEVEL0 = 10,
+ LFG_REWARD_LEVEL1 = 0,
+ LFG_REWARD_LEVEL2 = 1,
+ LFG_REWARD_LEVEL3 = 2,
+ LFG_REWARD_LEVEL4 = 3,
+ LFG_REWARD_LEVEL5 = 4,
+ LFG_REWARD_BC_NORMAL = 5,
+ LFG_REWARD_BC_HEROIC = 6,
+ LFG_REWARD_LK_NORMAL = 7,
+ LFG_REWARD_LK_NORMAL80 = 7,
+ LFG_REWARD_LK_HEROIC = 8,
+ LFG_REWARD_DATA_SIZE = 10,
+};
+
+const uint32 RewardDungeonData[LFG_REWARD_DATA_SIZE+1][5] =
+{ // XP, money, item, item display, count
+ {310, 3500, 51999, 56915, 1}, // Classic 15-23
+ {470, 7000, 52000, 56915, 1}, // Classic 24-34
+ {825, 13000, 52001, 56915, 1}, // Classic 35-45
+ {12250, 16500, 52002, 56915, 1}, // Classic 46-55
+ {14300, 18000, 52003, 56915, 1}, // Classic 56-60
+ {1600, 62000, 52004, 56915, 1}, // BC Normal
+ {1900, 88000, 52005, 56915, 1}, // BC Heroic
+ {33100, 148000, 47241, 62232, 2}, // LK Normal
+ {0, 198600, 47241, 62232, 2}, // LK Normal - Level 80
+ {0, 264600, 49426, 64062, 2}, // LK Heroic
+ {0, 0, 0, 0, 0}, // Classic - No level
+};
+
+const uint32 RewardDungeonDoneData[LFG_REWARD_DATA_SIZE][5] =
+{ // XP, money, item, item display, count
+ {200, 1800, 51999, 56915, 1}, // Classic 15-23
+ {310, 3500, 52000, 56915, 1}, // Classic 24-34
+ {550, 6500, 52001, 56915, 1}, // Classic 35-45
+ {8150, 8500, 52002, 56915, 1}, // Classic 46-55
+ {9550, 9000, 52003, 56915, 1}, // Classic 56-60
+ {1100, 31000, 52004, 56915, 1}, // BC Normal
+ {12650, 44000, 52005, 56915, 1}, // BC Heroic
+ {16550, 74000, 0, 0, 0}, // LK Normal
+ {0, 99300, 0, 0, 0}, // LK Normal - Level 80
+ {0, 132300, 47241, 62232, 2}, // LK Heroic
+};
+
+// Dungeon and reason why player can't join
+struct LfgLockStatus
+{
+ uint32 dungeon;
+ LfgLockStatusType lockstatus;
+};
+
+// Reward info
+struct LfgReward
+{
+ uint32 strangers;
+ uint32 baseMoney;
+ uint32 baseXP;
+ uint32 variableMoney;
+ uint32 variableXP;
+ uint32 itemId;
+ uint32 displayId;
+ uint32 stackCount;
+};
+
+typedef std::set<LfgLockStatus*> LfgLockStatusSet;
+typedef std::vector<LfgReward*> LfgRewardList;
+typedef std::map<uint64, LfgLockStatusSet*> LfgLockStatusMap;
+typedef std::map<uint32, LfgDungeonSet*> LfgDungeonMap;
+
+class LFGMgr
+{
+public:
+ LFGMgr();
+ ~LFGMgr();
+
+ void InitLFG();
+ void SendLfgPlayerInfo(Player *plr);
+ void SendLfgPartyInfo(Player *plr);
+
+private:
+ void BuildAvailableRandomDungeonList(WorldPacket &data, Player *plr);
+ void BuildRewardBlock(WorldPacket &data, uint32 dungeon, Player *plr);
+ void BuildPlayerLockDungeonBlock(WorldPacket &data, LfgLockStatusSet *lockSet);
+ void BuildPartyLockDungeonBlock(WorldPacket &data, LfgLockStatusMap *lockMap);
+ LfgLockStatusMap* GetPartyLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons);
+ LfgLockStatusSet* GetPlayerLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons);
+ LfgDungeonSet* GetRandomDungeons(uint8 level, uint8 expansion);
+ LfgDungeonSet* GetDungeonsByRandom(uint32 randomdungeon);
+ LfgDungeonSet* GetAllDungeons();
+ LfgReward* GetRandomDungeonReward(uint32 dungeon, bool done, uint8 level);
+
+ LfgRewardList m_RewardList;
+ LfgRewardList m_RewardDoneList;
+ LfgDungeonMap m_DungeonsMap;
+};
+
+#define sLFGMgr Trinity::Singleton<LFGMgr>::Instance()
+#endif
diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
index 2a69553abdf..d45e264cfd6 100644
--- a/src/game/Opcodes.cpp
+++ b/src/game/Opcodes.cpp
@@ -539,8 +539,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x1FD*/ { "CMSG_PLAYER_DIFFICULTY_CHANGE", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x1FF*/ { "SMSG_LFG_PLAYER_REWARD", STATUS_LOGGEDIN, &WorldSession::Handle_ServerSide },
- /*0x200*/ { "SMSG_LFG_TELEPORT_DENIED", STATUS_LOGGEDIN, &WorldSession::Handle_ServerSide },
+ /*0x1FF*/ { "SMSG_LFG_PLAYER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x200*/ { "SMSG_LFG_TELEPORT_DENIED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode },
/*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
@@ -888,10 +888,10 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
/*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
/*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetAutoJoinOpcode },
- /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearAutoJoinOpcode },
- /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetAutoFillOpcode },
- /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfmClearAutoFillOpcode },
+ /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
/*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x361*/ { "SMSG_LFG_PROPOSAL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x362*/ { "CMSG_LFG_PROPOSAL_RESULT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
@@ -902,15 +902,15 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x367*/ { "SMSG_LFG_UPDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x368*/ { "SMSG_LFG_UPDATE_PARTY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x369*/ { "SMSG_LFG_UPDATE_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36A*/ { "CMSG_LFG_SET_ROLES", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x36B*/ { "CMSG_LFG_SET_NEEDS", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x36C*/ { "CMSG_LFG_SET_BOOT_VOTE", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x36A*/ { "CMSG_LFG_SET_ROLES", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x36B*/ { "CMSG_LFG_SET_NEEDS", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x36C*/ { "CMSG_LFG_SET_BOOT_VOTE", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
/*0x36D*/ { "SMSG_LFG_BOOT_PROPOSAL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x36E*/ { "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x36E*/ { "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLfgPlayerLockInfoRequestOpcode},
/*0x36F*/ { "SMSG_LFG_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x370*/ { "CMSG_LFG_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x371*/ { "CMSG_LFD_PARTY_LOCK_INFO_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x372*/ { "SMSG_LFG_PARTY", STATUS_NEVER, &WorldSession::Handle_ServerSide },
+ /*0x370*/ { "CMSG_LFG_TELEPORT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
+ /*0x371*/ { "CMSG_LFD_PARTY_LOCK_INFO_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLfgPartyLockInfoRequestOpcode},
+ /*0x372*/ { "SMSG_LFG_PARTY_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleSetTitleOpcode },
/*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelMountAuraOpcode },
@@ -1236,7 +1236,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4B5*/ { "SMSG_ITEM_REFUND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4B6*/ { "CMSG_CORPSE_MAP_POSITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseMapPositionQuery },
/*0x4B7*/ { "SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x4B8*/ { "CMSG_LFG_SET_ROLES_2", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetRoles },
+ /*0x4B8*/ { "CMSG_LFG_SET_ROLES_2", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },
/*0x4B9*/ { "UMSG_UNKNOWN_1209", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4BA*/ { "CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4BB*/ { "SMSG_CALENDAR_ACTION_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide },
diff --git a/src/game/Player.h b/src/game/Player.h
index b1ab6a683aa..5ea6e22154f 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -39,6 +39,7 @@
#include "ReputationMgr.h"
#include "BattleGround.h"
#include "DBCEnums.h"
+#include "LFG.h"
#include<string>
#include<vector>
@@ -337,74 +338,6 @@ struct EnchantDuration
typedef std::list<EnchantDuration> EnchantDurationList;
typedef std::list<Item*> ItemDurationList;
-enum LfgType
-{
- LFG_TYPE_NONE = 0,
- LFG_TYPE_DUNGEON = 1,
- LFG_TYPE_RAID = 2,
- LFG_TYPE_QUEST = 3,
- LFG_TYPE_ZONE = 4,
- LFG_TYPE_HEROIC_DUNGEON = 5,
- LFG_TYPE_RANDOM_DUNGEON = 6
-};
-
-enum LfgRoles
-{
- LEADER = 0x01,
- TANK = 0x02,
- HEALER = 0x04,
- DAMAGE = 0x08
-};
-
-struct LookingForGroupSlot
-{
- LookingForGroupSlot() : entry(0), type(0) {}
- bool Empty() const { return !entry && !type; }
- void Clear() { entry = 0; type = 0; }
- void Set(uint32 _entry, uint32 _type) { entry = _entry; type = _type; }
- bool Is(uint32 _entry, uint32 _type) const { return entry == _entry && type == _type; }
- bool canAutoJoin() const { return entry && (type == LFG_TYPE_DUNGEON || type == LFG_TYPE_HEROIC_DUNGEON); }
-
- uint32 entry;
- uint32 type;
-};
-
-#define MAX_LOOKING_FOR_GROUP_SLOT 3
-
-struct LookingForGroup
-{
- LookingForGroup() {}
- bool HaveInSlot(LookingForGroupSlot const& slot) const { return HaveInSlot(slot.entry, slot.type); }
- bool HaveInSlot(uint32 _entry, uint32 _type) const
- {
- for (uint8 i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
- if (slots[i].Is(_entry, _type))
- return true;
- return false;
- }
-
- bool canAutoJoin() const
- {
- for (uint8 i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
- if (slots[i].canAutoJoin())
- return true;
- return false;
- }
-
- bool Empty() const
- {
- for (uint8 i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
- if (!slots[i].Empty())
- return false;
- return more.Empty();
- }
-
- LookingForGroupSlot slots[MAX_LOOKING_FOR_GROUP_SLOT];
- LookingForGroupSlot more;
- std::string comment;
- uint8 roles;
-};
-
enum PlayerMovementType
{
MOVE_ROOT = 1,
diff --git a/src/game/World.cpp b/src/game/World.cpp
index e6c3ebb974f..684ec7b970a 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -69,6 +69,7 @@
#include "ProgressBar.h"
#include "ScriptMgr.h"
#include "AddonMgr.h"
+#include "LFGMgr.h"
INSTANTIATE_SINGLETON_1(World);
@@ -1667,6 +1668,10 @@ void World::SetInitialWorldSettings()
sLog.outString("Loading World States..."); // must be loaded before battleground and outdoor PvP
LoadWorldStates();
+ ///- Initialize Looking For Group
+ sLog.outString("Starting Looking For Group System");
+ sLFGMgr.InitLFG();
+
///- Initialize Battlegrounds
sLog.outString("Starting BattleGround System");
sBattleGroundMgr.CreateInitialBattleGrounds();
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index a6cfae9c06d..a8abe9054d7 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -147,8 +147,6 @@ class WorldSession
void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
void SendNotification(int32 string_id,...);
void SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName);
- void SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type);
- void SendLfgUpdate(uint8 unk1, uint8 unk2, uint8 unk3);
void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res);
void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2,3);
void SendSetPhaseShift(uint32 phaseShift);
@@ -684,25 +682,22 @@ class WorldSession
void HandleMinimapPingOpcode(WorldPacket& recv_data);
void HandleRandomRollOpcode(WorldPacket& recv_data);
void HandleFarSightOpcode(WorldPacket& recv_data);
- void HandleSetLfgOpcode(WorldPacket& recv_data);
void HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data);
void HandleSetRaidDifficultyOpcode(WorldPacket& recv_data);
void HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data);
- void HandleLfgSetAutoJoinOpcode(WorldPacket& recv_data);
- void HandleLfgClearAutoJoinOpcode(WorldPacket& recv_data);
- void HandleLfmSetAutoFillOpcode(WorldPacket& recv_data);
- void HandleLfmClearAutoFillOpcode(WorldPacket& recv_data);
- void HandleLfgClearOpcode(WorldPacket& recv_data);
- void HandleLfmClearOpcode(WorldPacket& recv_data);
- void HandleSetLfmOpcode(WorldPacket& recv_data);
- void HandleSetLfgCommentOpcode(WorldPacket& recv_data);
- void HandleLfgSetRoles(WorldPacket& recv_data);
void HandleSetTitleOpcode(WorldPacket& recv_data);
void HandleRealmSplitOpcode(WorldPacket& recv_data);
void HandleTimeSyncResp(WorldPacket& recv_data);
void HandleWhoisOpcode(WorldPacket& recv_data);
void HandleResetInstancesOpcode(WorldPacket& recv_data);
+ // Looking for Dungeon/Raid
+ void HandleSetLfgCommentOpcode(WorldPacket & recv_data);
+ void HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& recv_data);
+ void HandleLfgPartyLockInfoRequestOpcode(WorldPacket& recv_data);
+ void SendLfgUpdatePlayer(uint8 updateType, uint32 dungeonEntry = 0);
+ void SendLfgUpdateParty(uint8 updateType, uint32 dungeonEntry = 0);
+
// Arena Team
void HandleInspectArenaTeamsOpcode(WorldPacket& recv_data);
void HandleArenaTeamQueryOpcode(WorldPacket& recv_data);
diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj
index 13e2d79f83f..8151b0b09a5 100644
--- a/win/VC90/game.vcproj
+++ b/win/VC90/game.vcproj
@@ -647,10 +647,22 @@
>
</File>
<File
+ RelativePath="..\..\src\game\LFG.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\game\LFGHandler.cpp"
>
</File>
<File
+ RelativePath="..\..\src\game\LFGMgr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\game\LFGMgr.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\game\LootHandler.cpp"
>
</File>