Dungeon Finder: Initial setup and dungeon listing

--HG--
branch : trunk
This commit is contained in:
Spp
2010-05-20 23:35:27 +02:00
parent e6ba336f91
commit defd131970
18 changed files with 854 additions and 480 deletions
+3
View File
@@ -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
+1 -2
View File
@@ -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);
+1 -1
View File
@@ -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)
+3
View File
@@ -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");
+1
View File
@@ -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;
+23
View File
@@ -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
+1
View File
@@ -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";
+5 -1
View File
@@ -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);
}
}
+11
View File
@@ -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();
}
+72
View File
@@ -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
+91 -381
View File
@@ -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)
data << uint8(queued); // Join the queue
data << uint8(0); // unk - Always 0
data << uint8(0); // unk - Always 0
if (dungeonEntry)
{
string
data << uint8(1);
data << uint32(dungeonEntry);
}
if (flags & 0x10)
else
{
uint8
}
if (flags & 0x20)
{
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;
}
size_t count3_pos = data.wpos();
data << uint32(0); // count3
data << uint32(0); // unk
//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)
{
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
uint32 flags = 0x1FF;
data << uint32(flags); // flags
if (flags & 0x1)
{
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
}
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)
{
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));
}
}
}
data.put<uint32>(count3_pos, number); // fill count placeholder
SendPacket(&data);
*/
}
void WorldSession::HandleSetLfgOpcode(WorldPacket & recv_data)
void WorldSession::SendLfgUpdateParty(uint8 updateType, uint32 dungeonEntry /* = 0*/)
{
sLog.outDebug("CMSG_SET_LOOKING_FOR_GROUP");
recv_data.hexlike();
uint32 slot, temp, entry, type;
uint8 roles, unk1;
bool join = false;
bool extrainfo = false;
bool queued = false;
recv_data >> slot >> temp >> roles >> unk1;
switch(updateType)
{
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;
}
entry = (temp & 0x00FFFFFF);
type = ((temp >> 24) & 0x000000FF);
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 (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*/)
{
if (dungeonEntry)
{
data << uint8(1);
data << uint32(dungeonEntry);
}
else
{
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);
}
+440
View File
@@ -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);
}
+162
View File
@@ -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
+14 -14
View File
@@ -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 },
+1 -68
View File
@@ -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,
+5
View File
@@ -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();
+7 -12
View File
@@ -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);
+12
View File
@@ -646,10 +646,22 @@
RelativePath="..\..\src\game\ItemHandler.cpp"
>
</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"
>