Core/LFG:
* added missing dungeon ID to high priestess Azil's encounter credit * fixed the last encounter lfg reward. Cataclysm dungeons use a single entry for both difficulties so the instance needs to find the proper dungeon for the difficulty. Fixed. * increased amount of required votes to kick a player from a party * use the remaining teleport error messages for their according purpose * use a bgdata location as teleport location when teleporting out of a dungeon * fixed lfg state after group has been formed * the amount of required roles is now determined by dbc values (thanks to Onkelz28) * added some safety checks for reward data packets if no quest is found * fixed lfr queue and reward display * add the possibility to make lfg reward quests repeatable. This is getting used for dungeon quests with valor point rewards. Setting the alternative quest once the limit has been reached is handled corewise now. * implement valor points display in the lfg window. Note: to see it for the first time you need at least 1 valor point * implement Call to Arms system. Thanks to Tisk for the base code * added loot for the Call to Arms Satches of Exotic mysteries
This commit is contained in:
1 parent
f1c8505e9a
commit
7525fb165e
18 files changed
+512
-132
No files matched your search
@@ -0,0 +1,72 @@
|
||||
-- Make Cataclysm lfg quests repeatable. Their currency weekly cap is handled by the core
|
||||
UPDATE `quest_template_addon` SET `SpecialFlags`= 8 | 1 WHERE `ID` IN (29185, 28905, 28907);
|
||||
|
||||
-- Add loot to Satches of Exotic Mysteries
|
||||
DELETE FROM `item_loot_template` WHERE `entry`= 69903;
|
||||
INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `MinCount`, `MaxCount`) VALUES
|
||||
(69903, 0, 69903, 100, 2, 2);
|
||||
DELETE FROM `reference_loot_template` WHERE `entry`= 69903;
|
||||
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Chance`, `Lootmode`, `GroupId`, `MinCount`, `MaxCount`) VALUES
|
||||
(69903, 58085, 10, 1, 1, 1, 1),
|
||||
(69903, 58090, 7, 1, 1, 1, 3),
|
||||
(69903, 57191, 7, 1, 1, 1, 3),
|
||||
(69903, 58087, 6, 1, 1, 1, 1),
|
||||
(69903, 52195, 5, 1, 1, 1, 1),
|
||||
(69903, 52194, 5, 1, 1, 1, 1),
|
||||
(69903, 52192, 5, 1, 1, 1, 1),
|
||||
(69903, 52193, 5, 1, 1, 1, 1),
|
||||
(69903, 58086, 5, 1, 1, 1, 1),
|
||||
(69903, 52190, 5, 1, 1, 1, 1),
|
||||
(69903, 58145, 5, 1, 1, 1, 3),
|
||||
(69903, 52191, 4, 1, 1, 1, 1),
|
||||
(69903, 58088, 3, 1, 1, 1, 1),
|
||||
(69903, 57192, 3, 1, 1, 1, 3),
|
||||
(69903, 62251, 3, 1, 1, 1, 3),
|
||||
(69903, 57193, 1.7, 1, 1, 1, 3),
|
||||
(69903, 58091, 1.6, 1, 1, 1, 3),
|
||||
(69903, 58146, 1.5, 1, 1, 1, 3),
|
||||
(69903, 57194, 1.5, 1, 1, 1, 3),
|
||||
(69903, 67438, 1.4, 1, 1, 1, 1),
|
||||
(69903, 54436, 0.6, 1, 1, 1, 1),
|
||||
(69903, 8490, 0.6, 1, 1, 1, 1),
|
||||
(69903, 48120, 0.6, 1, 1, 1, 1),
|
||||
(69903, 8495, 0.6, 1, 1, 1, 1),
|
||||
(69903, 46398, 0.5, 1, 1, 1, 1),
|
||||
(69903, 8496, 0.5, 1, 1, 1, 1),
|
||||
(69903, 69991, 0.5, 1, 1, 1, 1),
|
||||
(69903, 43698, 0.4, 1, 1, 1, 1),
|
||||
(69903, 44980, 0.4, 1, 1, 1, 1),
|
||||
(69903, 44721, 0.4, 1, 1, 1, 1),
|
||||
(69903, 69992, 0.4, 1, 1, 1, 1),
|
||||
(69903, 44965, 0.4, 1, 1, 1, 1),
|
||||
(69903, 44971, 0.4, 1, 1, 1, 1),
|
||||
(69903, 44984, 0.3, 1, 1, 1, 1),
|
||||
(69903, 29901, 0.3, 1, 1, 1, 1),
|
||||
(69903, 8491, 0.3, 1, 1, 1, 1),
|
||||
(69903, 8485, 0.3, 1, 1, 1, 1),
|
||||
(69903, 8487, 0.3, 1, 1, 1, 1),
|
||||
(69903, 10392, 0.3, 1, 1, 1, 1),
|
||||
(69903, 44970, 0.3, 1, 1, 1, 1),
|
||||
(69903, 44973, 0.3, 1, 1, 1, 1),
|
||||
(69903, 44974, 0.3, 1, 1, 1, 1),
|
||||
(69903, 44982, 0.3, 1, 1, 1, 1),
|
||||
(69903, 29953, 0.3, 1, 1, 1, 1),
|
||||
(69903, 8500, 0.3, 1, 1, 1, 1),
|
||||
(69903, 45002, 0.3, 1, 1, 1, 1),
|
||||
(69903, 8492, 0.3, 1, 1, 1, 1),
|
||||
(69903, 10394, 0.3, 1, 1, 1, 1),
|
||||
(69903, 8497, 0.3, 1, 1, 1, 1),
|
||||
(69903, 44707, 0.3, 1, 1, 1, 1),
|
||||
(69903, 45606, 0.3, 1, 1, 1, 1),
|
||||
(69903, 10393, 0.3, 1, 1, 1, 1),
|
||||
(69903, 29904, 0.3, 1, 1, 1, 1),
|
||||
(69903, 35504, 0.2, 1, 1, 1, 1),
|
||||
(69903, 43953, 0.2, 1, 1, 1, 1),
|
||||
(69903, 43962, 0.2, 1, 1, 1, 1),
|
||||
(69903, 44151, 0.19, 1, 1, 1, 1),
|
||||
(69903, 13335, 0.07, 1, 1, 1, 1),
|
||||
(69903, 32768, 0.07, 1, 1, 1, 1),
|
||||
(69903, 8494, 0.06, 1, 1, 1, 1);
|
||||
|
||||
-- Add missing dungeon ID to High Priestess Azil
|
||||
UPDATE `instance_encounters` SET `lastEncounterDungeon`= 307 WHERE `entry`= 1057;
|
||||
@@ -1540,6 +1540,9 @@ struct LFGDungeonEntry
|
||||
uint32 grouptype; // 15
|
||||
//char* desc; // 16 Description
|
||||
uint32 randomCategoryId; // 17 RandomDungeonID assigned for this dungeon
|
||||
uint32 requiredTanks; // 18
|
||||
uint32 requiredHealers; // 19
|
||||
uint32 requiredDamageDealers; // 20
|
||||
// Helpers
|
||||
uint32 Entry() const { return ID + (type << 24); }
|
||||
};
|
||||
|
||||
@@ -101,7 +101,7 @@ char const ItemLimitCategoryEntryfmt[] = "nxii";
|
||||
char const ItemRandomPropertiesfmt[] = "nxiiixxs";
|
||||
char const ItemRandomSuffixfmt[] = "nsxiiiiiiiiii";
|
||||
char const ItemSetEntryfmt[] = "dsiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii";
|
||||
char const LFGDungeonEntryfmt[] = "nsiiiiiiiiixxixixixxx";
|
||||
char const LFGDungeonEntryfmt[] = "nsiiiiiiiiixxixixiiii";
|
||||
char const LightEntryfmt[] = "nifffxxxxxxxxxx";
|
||||
char const LiquidTypefmt[] = "nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
char const LockEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
|
||||
|
||||
@@ -24,13 +24,6 @@
|
||||
namespace lfg
|
||||
{
|
||||
|
||||
enum LFGEnum
|
||||
{
|
||||
LFG_TANKS_NEEDED = 1,
|
||||
LFG_HEALERS_NEEDED = 1,
|
||||
LFG_DPS_NEEDED = 3
|
||||
};
|
||||
|
||||
enum LfgRoles
|
||||
{
|
||||
PLAYER_ROLE_NONE = 0x00,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "LFGQueue.h"
|
||||
#include "Group.h"
|
||||
#include "Player.h"
|
||||
#include "Map.h"
|
||||
#include "RBAC.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "GameEventMgr.h"
|
||||
@@ -38,7 +39,9 @@ namespace lfg
|
||||
{
|
||||
|
||||
LFGMgr::LFGMgr(): m_QueueTimer(0), m_lfgProposalId(1),
|
||||
m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK))
|
||||
m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK)),
|
||||
_isCallToArmEligible(sWorld->getBoolConfig(CONFIG_LFG_CALL_TO_ARMS_ENABLED)),
|
||||
_callToArmsRoles(PLAYER_ROLE_TANK | PLAYER_ROLE_HEALER)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -167,6 +170,14 @@ LFGDungeonData const* LFGMgr::GetLFGDungeon(uint32 id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool LFGMgr::IsCallToArmEligible(uint32 level, uint32 dungeonId)
|
||||
{
|
||||
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
|
||||
return (level == DEFAULT_MAX_LEVEL && dungeon->type == LFG_TYPE_RANDOM && dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LFGMgr::LoadLFGDungeons(bool reload /* = false */)
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
@@ -186,7 +197,7 @@ void LFGMgr::LoadLFGDungeons(bool reload /* = false */)
|
||||
case LFG_TYPE_HEROIC:
|
||||
case LFG_TYPE_RAID:
|
||||
case LFG_TYPE_RANDOM:
|
||||
LfgDungeonStore[dungeon->ID] = LFGDungeonData(dungeon);
|
||||
LfgDungeonStore.insert(LFGDungeonContainer::value_type(dungeon->ID, LFGDungeonData(dungeon)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -356,8 +367,22 @@ void LFGMgr::Update(uint32 diff)
|
||||
if (m_QueueTimer > LFG_QUEUEUPDATE_INTERVAL)
|
||||
{
|
||||
m_QueueTimer = 0;
|
||||
uint32 tankCount = 0;
|
||||
uint32 healerCount = 0;
|
||||
uint32 dpsCount = 0;
|
||||
|
||||
for (LfgQueueContainer::iterator it = QueuesStore.begin(); it != QueuesStore.end(); ++it)
|
||||
it->second.UpdateQueueTimers(it->first, currTime);
|
||||
it->second.UpdateQueueTimers(it->first, currTime, tankCount, healerCount, dpsCount);
|
||||
|
||||
LFGMgr::RemoveCallToArmsRole(PLAYER_ROLE_HEALER);
|
||||
LFGMgr::RemoveCallToArmsRole(PLAYER_ROLE_TANK);
|
||||
LFGMgr::RemoveCallToArmsRole(PLAYER_ROLE_DAMAGE);
|
||||
if (!tankCount || tankCount < dpsCount)
|
||||
LFGMgr::AddCallToArmsRole(PLAYER_ROLE_TANK);
|
||||
if (!healerCount || healerCount < dpsCount)
|
||||
LFGMgr::AddCallToArmsRole(PLAYER_ROLE_HEALER);
|
||||
if (dpsCount && (dpsCount < tankCount || dpsCount < healerCount))
|
||||
AddCallToArmsRole(PLAYER_ROLE_DAMAGE);
|
||||
}
|
||||
else
|
||||
m_QueueTimer += diff;
|
||||
@@ -671,6 +696,16 @@ void LFGMgr::UpdateRoleCheck(ObjectGuid gguid, ObjectGuid guid /* = ObjectGuid::
|
||||
LfgRoleCheck& roleCheck = itRoleCheck->second;
|
||||
bool sendRoleChosen = roleCheck.state != LFG_ROLECHECK_DEFAULT && guid;
|
||||
|
||||
LfgDungeonSet dungeons;
|
||||
if (roleCheck.rDungeonId)
|
||||
dungeons.insert(roleCheck.rDungeonId);
|
||||
else
|
||||
dungeons = roleCheck.dungeons;
|
||||
|
||||
LFGDungeonData const* dungeon = nullptr;
|
||||
if (!dungeons.empty())
|
||||
dungeon = sLFGMgr->GetLFGDungeon(*dungeons.begin());
|
||||
|
||||
if (!guid)
|
||||
roleCheck.state = LFG_ROLECHECK_ABORTED;
|
||||
else if (roles < PLAYER_ROLE_TANK) // Player selected no role.
|
||||
@@ -688,16 +723,10 @@ void LFGMgr::UpdateRoleCheck(ObjectGuid gguid, ObjectGuid guid /* = ObjectGuid::
|
||||
{
|
||||
// use temporal var to check roles, CheckGroupRoles modifies the roles
|
||||
check_roles = roleCheck.roles;
|
||||
roleCheck.state = CheckGroupRoles(check_roles) ? LFG_ROLECHECK_FINISHED : LFG_ROLECHECK_WRONG_ROLES;
|
||||
roleCheck.state = (dungeon && CheckGroupRoles(check_roles, dungeon)) ? LFG_ROLECHECK_FINISHED : LFG_ROLECHECK_WRONG_ROLES;
|
||||
}
|
||||
}
|
||||
|
||||
LfgDungeonSet dungeons;
|
||||
if (roleCheck.rDungeonId)
|
||||
dungeons.insert(roleCheck.rDungeonId);
|
||||
else
|
||||
dungeons = roleCheck.dungeons;
|
||||
|
||||
LfgJoinResult joinResult = LFG_JOIN_FAILED;
|
||||
if (roleCheck.state == LFG_ROLECHECK_MISSING_ROLE || roleCheck.state == LFG_ROLECHECK_WRONG_ROLES)
|
||||
joinResult = LFG_JOIN_ROLE_CHECK_FAILED;
|
||||
@@ -806,8 +835,9 @@ void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, GuidSet const& playe
|
||||
@param[in] groles Map of roles to check
|
||||
@return True if roles are compatible
|
||||
*/
|
||||
bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles)
|
||||
bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, LFGDungeonData const* dungeon)
|
||||
{
|
||||
ASSERT(dungeon);
|
||||
if (groles.empty())
|
||||
return false;
|
||||
|
||||
@@ -826,11 +856,11 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles)
|
||||
if (role != PLAYER_ROLE_DAMAGE)
|
||||
{
|
||||
it->second -= PLAYER_ROLE_DAMAGE;
|
||||
if (CheckGroupRoles(groles))
|
||||
if (CheckGroupRoles(groles, dungeon))
|
||||
return true;
|
||||
it->second += PLAYER_ROLE_DAMAGE;
|
||||
}
|
||||
else if (damage == LFG_DPS_NEEDED)
|
||||
else if (damage == dungeon->requiredDamageDealers)
|
||||
return false;
|
||||
else
|
||||
damage++;
|
||||
@@ -841,11 +871,11 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles)
|
||||
if (role != PLAYER_ROLE_HEALER)
|
||||
{
|
||||
it->second -= PLAYER_ROLE_HEALER;
|
||||
if (CheckGroupRoles(groles))
|
||||
if (CheckGroupRoles(groles, dungeon))
|
||||
return true;
|
||||
it->second += PLAYER_ROLE_HEALER;
|
||||
}
|
||||
else if (healer == LFG_HEALERS_NEEDED)
|
||||
else if (healer == dungeon->requiredHealers)
|
||||
return false;
|
||||
else
|
||||
healer++;
|
||||
@@ -856,11 +886,11 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles)
|
||||
if (role != PLAYER_ROLE_TANK)
|
||||
{
|
||||
it->second -= PLAYER_ROLE_TANK;
|
||||
if (CheckGroupRoles(groles))
|
||||
if (CheckGroupRoles(groles, dungeon))
|
||||
return true;
|
||||
it->second += PLAYER_ROLE_TANK;
|
||||
}
|
||||
else if (tank == LFG_TANKS_NEEDED)
|
||||
else if (tank == dungeon->requiredTanks)
|
||||
return false;
|
||||
else
|
||||
tank++;
|
||||
@@ -909,7 +939,10 @@ void LFGMgr::MakeNewGroup(LfgProposal const& proposal)
|
||||
if (!grp)
|
||||
{
|
||||
grp = new Group();
|
||||
grp->ConvertToLFG();
|
||||
if (dungeon->IsRaid())
|
||||
grp->ConvertToLFR();
|
||||
else
|
||||
grp->ConvertToLFG();
|
||||
grp->Create(player);
|
||||
ObjectGuid gguid = grp->GetGUID();
|
||||
SetState(gguid, LFG_STATE_PROPOSAL);
|
||||
@@ -920,26 +953,35 @@ void LFGMgr::MakeNewGroup(LfgProposal const& proposal)
|
||||
|
||||
grp->SetLfgRoles(pguid, proposal.players.find(pguid)->second.role);
|
||||
|
||||
for (GuidList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
{
|
||||
ObjectGuid temppguid = (*itr);
|
||||
player->GetSession()->SendNameQueryOpcode(temppguid);
|
||||
}
|
||||
|
||||
// Add the cooldown spell if queued for a random dungeon
|
||||
if (dungeon->type == LFG_TYPE_RANDOM)
|
||||
player->CastSpell(player, LFG_SPELL_DUNGEON_COOLDOWN, false);
|
||||
}
|
||||
|
||||
ASSERT(grp);
|
||||
grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty));
|
||||
if (dungeon->IsRaid())
|
||||
grp->SetRaidDifficulty(Difficulty(dungeon->difficulty));
|
||||
else
|
||||
grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty));
|
||||
ObjectGuid gguid = grp->GetGUID();
|
||||
SetDungeon(gguid, dungeon->Entry());
|
||||
SetState(gguid, LFG_STATE_DUNGEON);
|
||||
|
||||
_SaveToDB(gguid, grp->GetDbStoreId());
|
||||
|
||||
// Update group info
|
||||
grp->SendUpdate();
|
||||
|
||||
// Teleport Player
|
||||
for (GuidList::const_iterator it = playersToTeleport.begin(); it != playersToTeleport.end(); ++it)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(*it))
|
||||
TeleportPlayer(player, false);
|
||||
|
||||
// Update group info
|
||||
grp->SendUpdate();
|
||||
}
|
||||
|
||||
uint32 LFGMgr::AddProposal(LfgProposal& proposal)
|
||||
@@ -1221,8 +1263,14 @@ void LFGMgr::UpdateBoot(ObjectGuid guid, bool accept)
|
||||
}
|
||||
}
|
||||
|
||||
bool raidFinderGroup = false;
|
||||
if (Group* group = sGroupMgr->GetGroupByGUID(gguid.GetCounter()))
|
||||
if (group->isLFRGroup())
|
||||
raidFinderGroup = true;
|
||||
|
||||
// if we don't have enough votes (agree or deny) do nothing
|
||||
if (agreeNum < LFG_GROUP_KICK_VOTES_NEEDED && (votesNum - agreeNum) < LFG_GROUP_KICK_VOTES_NEEDED)
|
||||
if (agreeNum < (raidFinderGroup ? LFR_GROUP_KICK_VOTES_NEEDED : LFG_GROUP_KICK_VOTES_NEEDED)
|
||||
&& (votesNum - agreeNum) < (raidFinderGroup ? LFR_GROUP_KICK_VOTES_NEEDED : LFG_GROUP_KICK_VOTES_NEEDED))
|
||||
return;
|
||||
|
||||
// Send update info to all players
|
||||
@@ -1235,7 +1283,7 @@ void LFGMgr::UpdateBoot(ObjectGuid guid, bool accept)
|
||||
}
|
||||
|
||||
SetVoteKick(gguid, false);
|
||||
if (agreeNum == LFG_GROUP_KICK_VOTES_NEEDED) // Vote passed - Kick player
|
||||
if (agreeNum == (raidFinderGroup ? LFR_GROUP_KICK_VOTES_NEEDED : LFG_GROUP_KICK_VOTES_NEEDED)) // Vote passed - Kick player
|
||||
{
|
||||
if (Group* group = sGroupMgr->GetGroupByGUID(gguid.GetCounter()))
|
||||
Player::RemoveFromGroup(group, boot.victim, GROUP_REMOVEMETHOD_KICK_LFG);
|
||||
@@ -1251,7 +1299,7 @@ void LFGMgr::UpdateBoot(ObjectGuid guid, bool accept)
|
||||
@param[in] out Teleport out (true) or in (false)
|
||||
@param[in] fromOpcode Function called from opcode handlers? (Default false)
|
||||
*/
|
||||
void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*/)
|
||||
void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*/, bool saveEntryPoint /*= true*/)
|
||||
{
|
||||
LFGDungeonData const* dungeon = NULL;
|
||||
Group* group = player->GetGroup();
|
||||
@@ -1299,7 +1347,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
|
||||
float z = dungeon->z;
|
||||
float orientation = dungeon->o;
|
||||
|
||||
if (!fromOpcode)
|
||||
if (!fromOpcode && saveEntryPoint)
|
||||
{
|
||||
// Select a player inside to be teleported to
|
||||
for (GroupReference* itr = group->GetFirstMember(); itr != NULL && !mapid; itr = itr->next())
|
||||
@@ -1316,8 +1364,17 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (player->HasValidLFGLeavePoint(mapid) && saveEntryPoint)
|
||||
{
|
||||
Position pos;
|
||||
player->GetLFGLeavePoint(&pos);
|
||||
x = pos.m_positionX;
|
||||
y = pos.m_positionY;
|
||||
z = pos.m_positionZ;
|
||||
orientation = pos.GetOrientation();
|
||||
}
|
||||
|
||||
if (!player->GetMap()->IsDungeon())
|
||||
if (!player->GetMap()->IsDungeon() && saveEntryPoint)
|
||||
player->SetBattlegroundEntryPoint();
|
||||
|
||||
if (player->IsInFlight())
|
||||
@@ -1330,7 +1387,15 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
|
||||
error = LFG_TELEPORTERROR_INVALID_LOCATION;
|
||||
}
|
||||
else
|
||||
error = LFG_TELEPORTERROR_INVALID_LOCATION;
|
||||
{
|
||||
if (player->IsInCombat())
|
||||
error = LFG_TELEPORTERROR_IN_COMBAT;
|
||||
else if (player->GetMapId() == uint32(dungeon->map))
|
||||
{
|
||||
player->SetLFGLeavePoint();
|
||||
player->TeleportToBGEntryPoint();
|
||||
}
|
||||
}
|
||||
|
||||
if (error != LFG_TELEPORTERROR_OK)
|
||||
player->GetSession()->SendLfgTeleportError(uint8(error));
|
||||
@@ -1430,6 +1495,17 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId, Map const*
|
||||
// we give reward without informing client (retail does this)
|
||||
player->RewardQuest(quest, 0, NULL, false);
|
||||
}
|
||||
uint8 tmpRole = 0;
|
||||
if (Group *group = player->GetGroup())
|
||||
tmpRole = group->GetLfgRoles(player->GetGUID());
|
||||
|
||||
if (IsCallToArmEligible(player->getLevel(), rDungeonId & 0x00FFFFFF))
|
||||
if (player->GetCallToArmsTempRoles() & tmpRole)
|
||||
{
|
||||
const Quest *q = sObjectMgr->GetQuestTemplate(LFG_CALL_TO_ARMS_QUEST);
|
||||
player->RewardQuest(q, 0, NULL, false);
|
||||
}
|
||||
player->SetTempCallToArmsRoles(0);
|
||||
|
||||
// Give rewards
|
||||
TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s done dungeon %u, %s previously done.", gguid.ToString().c_str(), guid.ToString().c_str(), GetDungeon(gguid), done ? " " : " not");
|
||||
@@ -1556,6 +1632,20 @@ uint32 LFGMgr::GetDungeonMapId(ObjectGuid guid)
|
||||
return mapId;
|
||||
}
|
||||
|
||||
uint32 LFGMgr::GetDungeonIdForDifficulty(uint32 dungeonId, Difficulty difficulty)
|
||||
{
|
||||
if (LFGDungeonData const* baseDungeon = GetLFGDungeon(dungeonId))
|
||||
{
|
||||
uint16 mapId = baseDungeon->map;
|
||||
LfgDungeonSet const& dungeons = GetDungeonsByRandom(0);
|
||||
for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end(); ++it)
|
||||
if (LFGDungeonData const* dungeon = GetLFGDungeon(*it))
|
||||
if (dungeon->map == mapId && Difficulty(dungeon->difficulty) == difficulty)
|
||||
return dungeon->id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 LFGMgr::GetRoles(ObjectGuid guid)
|
||||
{
|
||||
uint8 roles = PlayersStore[guid].GetRoles();
|
||||
@@ -1608,6 +1698,8 @@ LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid)
|
||||
lockStatus = LFG_LOCKSTATUS_RAID_LOCKED;
|
||||
else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))
|
||||
lockStatus = LFG_LOCKSTATUS_RAID_LOCKED;
|
||||
else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty), dungeon->type == LFG_TYPE_RAID))
|
||||
lockStatus = LFG_LOCKSTATUS_RAID_LOCKED;
|
||||
else if (dungeon->minlevel > level)
|
||||
lockStatus = LFG_LOCKSTATUS_TOO_LOW_LEVEL;
|
||||
else if (dungeon->maxlevel < level)
|
||||
@@ -2039,11 +2131,18 @@ LfgDungeonSet LFGMgr::GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion)
|
||||
for (lfg::LFGDungeonContainer::const_iterator itr = LfgDungeonStore.begin(); itr != LfgDungeonStore.end(); ++itr)
|
||||
{
|
||||
lfg::LFGDungeonData const& dungeon = itr->second;
|
||||
if ((dungeon.type == lfg::LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id)))
|
||||
if ((dungeon.type == lfg::LFG_TYPE_RANDOM || dungeon.IsRaid()|| (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id)))
|
||||
&& dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel)
|
||||
randomDungeons.insert(dungeon.Entry());
|
||||
}
|
||||
return randomDungeons;
|
||||
}
|
||||
|
||||
bool LFGDungeonData::IsRaid() const
|
||||
{
|
||||
if (MapEntry const* mapInfo = sMapStore.LookupEntry(map))
|
||||
return mapInfo->IsRaid();
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace lfg
|
||||
@@ -48,7 +48,8 @@ enum LFGMgrEnum
|
||||
LFG_SPELL_DUNGEON_COOLDOWN = 71328,
|
||||
LFG_SPELL_DUNGEON_DESERTER = 71041,
|
||||
LFG_SPELL_LUCK_OF_THE_DRAW = 72221,
|
||||
LFG_GROUP_KICK_VOTES_NEEDED = 3
|
||||
LFG_GROUP_KICK_VOTES_NEEDED = 4,
|
||||
LFR_GROUP_KICK_VOTES_NEEDED = 15
|
||||
};
|
||||
|
||||
enum LfgFlags
|
||||
@@ -56,7 +57,7 @@ enum LfgFlags
|
||||
LFG_FLAG_UNK1 = 0x1,
|
||||
LFG_FLAG_UNK2 = 0x2,
|
||||
LFG_FLAG_SEASONAL = 0x4,
|
||||
LFG_FLAG_UNK3 = 0x8
|
||||
LFG_FLAG_UNK3 = 0x8,
|
||||
};
|
||||
|
||||
/// Determines the type of instance
|
||||
@@ -87,7 +88,8 @@ enum LfgTeleportError
|
||||
LFG_TELEPORTERROR_IN_VEHICLE = 3,
|
||||
LFG_TELEPORTERROR_FATIGUE = 4,
|
||||
LFG_TELEPORTERROR_INVALID_LOCATION = 6,
|
||||
LFG_TELEPORTERROR_CHARMING = 8 // FIXME - It can be 7 or 8 (Need proper data)
|
||||
LFG_TELEPORTERROR_CHARMING = 7,
|
||||
LFG_TELEPORTERROR_IN_COMBAT = 8
|
||||
};
|
||||
|
||||
/// Queue join results
|
||||
@@ -126,6 +128,8 @@ enum LfgRoleCheckState
|
||||
LFG_ROLECHECK_NO_ROLE = 6 // Someone selected no role
|
||||
};
|
||||
|
||||
#define LFG_CALL_TO_ARMS_QUEST 29339
|
||||
|
||||
// Forward declaration (just to have all typedef together)
|
||||
struct LFGDungeonData;
|
||||
struct LfgReward;
|
||||
@@ -268,15 +272,14 @@ struct LfgPlayerBoot
|
||||
|
||||
struct LFGDungeonData
|
||||
{
|
||||
LFGDungeonData(): id(0), name(""), map(0), type(0), expansion(0), group(0), minlevel(0),
|
||||
maxlevel(0), difficulty(REGULAR_DIFFICULTY), seasonal(false), x(0.0f), y(0.0f), z(0.0f), o(0.0f),
|
||||
requiredItemLevel(0)
|
||||
{ }
|
||||
LFGDungeonData() = delete;
|
||||
|
||||
LFGDungeonData(LFGDungeonEntry const* dbc): id(dbc->ID), name(dbc->name), map(dbc->map),
|
||||
type(dbc->type), expansion(dbc->expansion), group(dbc->grouptype),
|
||||
minlevel(dbc->minlevel), maxlevel(dbc->maxlevel), difficulty(Difficulty(dbc->difficulty)),
|
||||
seasonal((dbc->flags & LFG_FLAG_SEASONAL) != 0), x(0.0f), y(0.0f), z(0.0f), o(0.0f),
|
||||
requiredItemLevel(0)
|
||||
requiredItemLevel(0), requiredTanks(dbc->requiredTanks), requiredHealers(dbc->requiredHealers),
|
||||
requiredDamageDealers(dbc->requiredDamageDealers)
|
||||
{ }
|
||||
|
||||
uint32 id;
|
||||
@@ -291,9 +294,14 @@ struct LFGDungeonData
|
||||
bool seasonal;
|
||||
float x, y, z, o;
|
||||
uint16 requiredItemLevel;
|
||||
uint32 requiredTanks;
|
||||
uint32 requiredHealers;
|
||||
uint32 requiredDamageDealers;
|
||||
|
||||
// Helpers
|
||||
uint32 Entry() const { return id + (type << 24); }
|
||||
uint32 GetMaxGroupSize() const { return requiredTanks + requiredHealers + requiredDamageDealers; }
|
||||
bool IsRaid() const;
|
||||
};
|
||||
|
||||
class TC_GAME_API LFGMgr
|
||||
@@ -331,6 +339,8 @@ class TC_GAME_API LFGMgr
|
||||
uint32 GetDungeon(ObjectGuid guid, bool asId = true);
|
||||
/// Get the map id of the current dungeon
|
||||
uint32 GetDungeonMapId(ObjectGuid guid);
|
||||
//// Get the heroic version of the current dungeon Id
|
||||
uint32 GetDungeonIdForDifficulty(uint32 dungeonId, Difficulty difficulty);
|
||||
/// Get kicks left in current group
|
||||
uint8 GetKicksLeft(ObjectGuid gguid);
|
||||
/// Load Lfg group info from DB
|
||||
@@ -339,6 +349,12 @@ class TC_GAME_API LFGMgr
|
||||
void SetupGroupMember(ObjectGuid guid, ObjectGuid gguid);
|
||||
/// Return Lfg dungeon entry for given dungeon id
|
||||
uint32 GetLFGDungeonEntry(uint32 id);
|
||||
/// Handles Call to Arms bonuses
|
||||
bool IsCallToArmEligible(uint32 level, uint32 dungeonId);
|
||||
uint8 GetRolesForCallToArms() { return _callToArmsRoles; }
|
||||
void AddCallToArmsRole(uint8 role) { _callToArmsRoles |= role; }
|
||||
void RemoveCallToArmsRole(uint8 role) { _callToArmsRoles = _callToArmsRoles & ~role; }
|
||||
void SetCallToArmEligible(bool val) { _isCallToArmEligible = val; }
|
||||
|
||||
// cs_lfg
|
||||
/// Get current player roles
|
||||
@@ -386,7 +402,7 @@ class TC_GAME_API LFGMgr
|
||||
/// Returns all random and seasonal dungeons for given level and expansion
|
||||
LfgDungeonSet GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion);
|
||||
/// Teleport a player to/from selected dungeon
|
||||
void TeleportPlayer(Player* player, bool out, bool fromOpcode = false);
|
||||
void TeleportPlayer(Player* player, bool out, bool fromOpcode = false, bool saveEntryPoint = true);
|
||||
/// Inits new proposal to boot a player
|
||||
void InitBoot(ObjectGuid gguid, ObjectGuid kguid, ObjectGuid vguid, std::string const& reason);
|
||||
/// Updates player boot proposal with new player answer
|
||||
@@ -420,11 +436,13 @@ class TC_GAME_API LFGMgr
|
||||
/// Gets queue join time
|
||||
time_t GetQueueJoinTime(ObjectGuid guid);
|
||||
/// Checks if given roles match, modifies given roles map with new roles
|
||||
static bool CheckGroupRoles(LfgRolesMap &groles);
|
||||
static bool CheckGroupRoles(LfgRolesMap& groles, LFGDungeonData const* dungeon);
|
||||
/// Checks if given players are ignoring each other
|
||||
static bool HasIgnore(ObjectGuid guid1, ObjectGuid guid2);
|
||||
/// Sends queue status to player
|
||||
static void SendLfgQueueStatus(ObjectGuid guid, LfgQueueStatusData const& data);
|
||||
/// Returns dungeon datas based on the dungeon ID
|
||||
LFGDungeonData const* GetLFGDungeon(uint32 id);
|
||||
|
||||
private:
|
||||
uint8 GetTeam(ObjectGuid guid);
|
||||
@@ -438,7 +456,6 @@ class TC_GAME_API LFGMgr
|
||||
void RemovePlayerData(ObjectGuid guid);
|
||||
void GetCompatibleDungeons(LfgDungeonSet& dungeons, GuidSet const& players, LfgLockPartyMap& lockMap, bool isContinue);
|
||||
void _SaveToDB(ObjectGuid guid, uint32 db_guid);
|
||||
LFGDungeonData const* GetLFGDungeon(uint32 id);
|
||||
|
||||
// Proposals
|
||||
void RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdateType type);
|
||||
@@ -475,6 +492,9 @@ class TC_GAME_API LFGMgr
|
||||
LfgPlayerBootContainer BootsStore; ///< Current player kicks
|
||||
LfgPlayerDataContainer PlayersStore; ///< Player data
|
||||
LfgGroupDataContainer GroupsStore; ///< Group data
|
||||
// Call to Arms System
|
||||
bool _isCallToArmEligible;
|
||||
uint8 _callToArmsRoles;
|
||||
};
|
||||
|
||||
} // namespace lfg
|
||||
|
||||
@@ -80,6 +80,23 @@ char const* GetCompatibleString(LfgCompatibility compatibles)
|
||||
}
|
||||
}
|
||||
|
||||
void LfgQueueData::InitializeGroupSetup()
|
||||
{
|
||||
tanks = -1;
|
||||
healers = -1;
|
||||
dps = -1;
|
||||
|
||||
if (!dungeons.empty())
|
||||
{
|
||||
if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(*dungeons.begin()))
|
||||
{
|
||||
tanks = dungeon->requiredTanks;
|
||||
healers = dungeon->requiredHealers;
|
||||
dps = dungeon->requiredDamageDealers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string LFGQueue::GetDetailedMatchRoles(GuidList const& check) const
|
||||
{
|
||||
if (check.empty())
|
||||
@@ -365,7 +382,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
LfgRolesMap proposalRoles;
|
||||
|
||||
// Check for correct size
|
||||
if (check.size() > MAXGROUPSIZE || check.empty())
|
||||
if (check.empty())
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s): Size wrong - Not compatibles", GetDetailedMatchRoles(check).c_str());
|
||||
return LFG_INCOMPATIBLES_WRONG_GROUP_SIZE;
|
||||
@@ -388,10 +405,54 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
check.push_front(frontGuid);
|
||||
}
|
||||
|
||||
std::ostringstream o;
|
||||
|
||||
// Find compatible dungeons
|
||||
if (check.size() > 1)
|
||||
{
|
||||
GuidList::iterator itguid = check.begin();
|
||||
proposalDungeons = QueueDataStore[*itguid].dungeons;
|
||||
|
||||
for (++itguid; itguid != check.end(); ++itguid)
|
||||
{
|
||||
LfgDungeonSet temporal;
|
||||
LfgDungeonSet& dungeons = QueueDataStore[*itguid].dungeons;
|
||||
|
||||
std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin()));
|
||||
proposalDungeons = temporal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
proposalDungeons = QueueDataStore[check.front()].dungeons;
|
||||
}
|
||||
|
||||
LFGDungeonData const* dungeon = nullptr;
|
||||
do
|
||||
{
|
||||
if (proposalDungeons.empty())
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "LFGQueue::CheckCompatibility: (%s) No compatible dungeons%s", strGuids.c_str(), o.str().c_str());
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_DUNGEONS);
|
||||
return LFG_INCOMPATIBLES_NO_DUNGEONS;
|
||||
}
|
||||
|
||||
proposal.dungeonId = Trinity::Containers::SelectRandomContainerElement(proposalDungeons);
|
||||
proposalDungeons.erase(proposal.dungeonId);
|
||||
dungeon = sLFGMgr->GetLFGDungeon(proposal.dungeonId);
|
||||
} while (!dungeon);
|
||||
|
||||
// Check for correct size
|
||||
if (check.size() > dungeon->GetMaxGroupSize())
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "LFGQueue::CheckCompatibility: (%s): Size wrong - Not compatibles", strGuids.c_str());
|
||||
return LFG_INCOMPATIBLES_WRONG_GROUP_SIZE;
|
||||
}
|
||||
|
||||
// Check if more than one LFG group and number of players joining
|
||||
uint8 numPlayers = 0;
|
||||
uint8 numLfgGroups = 0;
|
||||
for (GuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 2 && numPlayers <= MAXGROUPSIZE; ++it)
|
||||
for (GuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 1 && numPlayers <= dungeon->GetMaxGroupSize(); ++it)
|
||||
{
|
||||
ObjectGuid guid = *it;
|
||||
LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(guid);
|
||||
@@ -416,21 +477,6 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
}
|
||||
}
|
||||
|
||||
// Group with less that MAXGROUPSIZE members always compatible
|
||||
if (check.size() == 1 && numPlayers != MAXGROUPSIZE)
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) single group. Compatibles", GetDetailedMatchRoles(check).c_str());
|
||||
LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(check.front());
|
||||
|
||||
LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS);
|
||||
data.roles = itQueue->second.roles;
|
||||
LFGMgr::CheckGroupRoles(data.roles);
|
||||
|
||||
UpdateBestCompatibleInQueue(itQueue, strGuids, data.roles);
|
||||
SetCompatibilityData(strGuids, data);
|
||||
return LFG_COMPATIBLES_WITH_LESS_PLAYERS;
|
||||
}
|
||||
|
||||
if (numLfgGroups > 1)
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) More than one Lfggroup (%u)", GetDetailedMatchRoles(check).c_str(), numLfgGroups);
|
||||
@@ -438,7 +484,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
return LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS;
|
||||
}
|
||||
|
||||
if (numPlayers > MAXGROUPSIZE)
|
||||
if (numPlayers > dungeon->GetMaxGroupSize())
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Too many players (%u)", GetDetailedMatchRoles(check).c_str(), numPlayers);
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS);
|
||||
@@ -474,7 +520,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
}
|
||||
|
||||
LfgRolesMap debugRoles = proposalRoles;
|
||||
if (!LFGMgr::CheckGroupRoles(proposalRoles))
|
||||
if (!LFGMgr::CheckGroupRoles(proposalRoles, dungeon))
|
||||
{
|
||||
std::ostringstream o;
|
||||
for (LfgRolesMap::const_iterator it = debugRoles.begin(); it != debugRoles.end(); ++it)
|
||||
@@ -484,38 +530,15 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_ROLES);
|
||||
return LFG_INCOMPATIBLES_NO_ROLES;
|
||||
}
|
||||
|
||||
GuidList::iterator itguid = check.begin();
|
||||
proposalDungeons = QueueDataStore[*itguid].dungeons;
|
||||
std::ostringstream o;
|
||||
o << ", " << itguid->GetRawValue() << ": (" << ConcatenateDungeons(proposalDungeons) << ")";
|
||||
for (++itguid; itguid != check.end(); ++itguid)
|
||||
{
|
||||
LfgDungeonSet temporal;
|
||||
LfgDungeonSet& dungeons = QueueDataStore[*itguid].dungeons;
|
||||
o << ", " << itguid->GetRawValue() << ": (" << ConcatenateDungeons(dungeons) << ")";
|
||||
std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin()));
|
||||
proposalDungeons = temporal;
|
||||
}
|
||||
|
||||
if (proposalDungeons.empty())
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) No compatible dungeons%s", GetDetailedMatchRoles(check).c_str(), o.str().c_str());
|
||||
SetCompatibles(strGuids, LFG_INCOMPATIBLES_NO_DUNGEONS);
|
||||
return LFG_INCOMPATIBLES_NO_DUNGEONS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjectGuid gguid = *check.begin();
|
||||
const LfgQueueData &queue = QueueDataStore[gguid];
|
||||
proposalDungeons = queue.dungeons;
|
||||
proposalRoles = queue.roles;
|
||||
LFGMgr::CheckGroupRoles(proposalRoles); // assing new roles
|
||||
proposalRoles = QueueDataStore[check.front()].roles;
|
||||
LFGMgr::CheckGroupRoles(proposalRoles, dungeon); // assign new roles
|
||||
}
|
||||
|
||||
// Enough players?
|
||||
if (numPlayers != MAXGROUPSIZE)
|
||||
if (numPlayers != dungeon->GetMaxGroupSize())
|
||||
{
|
||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Compatibles but not enough players(%u)", GetDetailedMatchRoles(check).c_str(), numPlayers);
|
||||
LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS);
|
||||
@@ -528,7 +551,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
return LFG_COMPATIBLES_WITH_LESS_PLAYERS;
|
||||
}
|
||||
|
||||
ObjectGuid gguid = *check.begin();
|
||||
ObjectGuid gguid = check.front();
|
||||
proposal.queues = check;
|
||||
proposal.isNew = numLfgGroups != 1 || sLFGMgr->GetOldState(gguid) != LFG_STATE_DUNGEON;
|
||||
|
||||
@@ -543,7 +566,6 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
proposal.cancelTime = time(NULL) + LFG_TIME_PROPOSAL;
|
||||
proposal.state = LFG_PROPOSAL_INITIATING;
|
||||
proposal.leader.Clear();
|
||||
proposal.dungeonId = Trinity::Containers::SelectRandomContainerElement(proposalDungeons);
|
||||
|
||||
bool leader = false;
|
||||
for (LfgRolesMap::const_iterator itRoles = proposalRoles.begin(); itRoles != proposalRoles.end(); ++itRoles)
|
||||
@@ -581,7 +603,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
||||
return LFG_COMPATIBLES_MATCH;
|
||||
}
|
||||
|
||||
void LFGQueue::UpdateQueueTimers(uint8 queueId, time_t currTime)
|
||||
void LFGQueue::UpdateQueueTimers(uint8 queueId, time_t currTime, uint32 &tankCount, uint32 &healerCount, uint32 &dpsCount)
|
||||
{
|
||||
TC_LOG_TRACE("lfg.queue.timers.update", "Updating queue timers...");
|
||||
for (LfgQueueDataContainer::iterator itQueue = QueueDataStore.begin(); itQueue != QueueDataStore.end(); ++itQueue)
|
||||
@@ -600,6 +622,13 @@ void LFGQueue::UpdateQueueTimers(uint8 queueId, time_t currTime)
|
||||
role |= itPlayer->second;
|
||||
role &= ~PLAYER_ROLE_LEADER;
|
||||
|
||||
if (role & PLAYER_ROLE_TANK)
|
||||
tankCount++;
|
||||
if (role & PLAYER_ROLE_HEALER)
|
||||
healerCount++;
|
||||
if (role & PLAYER_ROLE_DAMAGE)
|
||||
dpsCount++;
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case PLAYER_ROLE_NONE: // Should not happen - just in case
|
||||
@@ -724,9 +753,8 @@ void LFGQueue::UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQu
|
||||
queueData.bestCompatible.c_str(), key.c_str(), itrQueue->first.ToString().c_str());
|
||||
|
||||
queueData.bestCompatible = key;
|
||||
queueData.tanks = LFG_TANKS_NEEDED;
|
||||
queueData.healers = LFG_HEALERS_NEEDED;
|
||||
queueData.dps = LFG_DPS_NEEDED;
|
||||
queueData.InitializeGroupSetup();
|
||||
|
||||
for (LfgRolesMap::const_iterator it = roles.begin(); it != roles.end(); ++it)
|
||||
{
|
||||
uint8 role = it->second;
|
||||
|
||||
@@ -51,14 +51,16 @@ struct LfgCompatibilityData
|
||||
/// Stores player or group queue info
|
||||
struct LfgQueueData
|
||||
{
|
||||
LfgQueueData(): joinTime(time_t(time(NULL))), tanks(LFG_TANKS_NEEDED),
|
||||
healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED)
|
||||
{ }
|
||||
LfgQueueData(): joinTime(time_t(time(NULL)))
|
||||
{
|
||||
InitializeGroupSetup();
|
||||
}
|
||||
|
||||
LfgQueueData(time_t _joinTime, LfgDungeonSet const& _dungeons, LfgRolesMap const& _roles):
|
||||
joinTime(_joinTime), tanks(LFG_TANKS_NEEDED), healers(LFG_HEALERS_NEEDED),
|
||||
dps(LFG_DPS_NEEDED), dungeons(_dungeons), roles(_roles)
|
||||
{ }
|
||||
LfgQueueData(time_t _joinTime, LfgDungeonSet const& _dungeons, LfgRolesMap const& _roles) :
|
||||
joinTime(_joinTime), dungeons(_dungeons), roles(_roles)
|
||||
{
|
||||
InitializeGroupSetup();
|
||||
}
|
||||
|
||||
time_t joinTime; ///< Player queue join time (to calculate wait times)
|
||||
uint8 tanks; ///< Tanks needed
|
||||
@@ -67,6 +69,8 @@ struct LfgQueueData
|
||||
LfgDungeonSet dungeons; ///< Selected Player/Group Dungeon/s
|
||||
LfgRolesMap roles; ///< Selected Player Role/s
|
||||
std::string bestCompatible; ///< Best compatible combination of people queued
|
||||
|
||||
void InitializeGroupSetup();
|
||||
};
|
||||
|
||||
struct LfgWaitTime
|
||||
@@ -101,7 +105,7 @@ class TC_GAME_API LFGQueue
|
||||
void UpdateWaitTimeDps(int32 waitTime, uint32 dungeonId);
|
||||
|
||||
// Update Queue timers
|
||||
void UpdateQueueTimers(uint8 queueId, time_t currTime);
|
||||
void UpdateQueueTimers(uint8 queueId, time_t currTime, uint32 &tankCount, uint32 &healerCount, uint32 &dpsCount);
|
||||
time_t GetJoinTime(ObjectGuid guid) const;
|
||||
|
||||
// Find new group
|
||||
|
||||
@@ -540,6 +540,8 @@ Player::Player(WorldSession* session): Unit(true), _archaeology(this)
|
||||
|
||||
m_achievementMgr = new AchievementMgr<Player>(this);
|
||||
m_reputationMgr = new ReputationMgr(this);
|
||||
|
||||
_hasValidLFGLeavePoint = false;
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
@@ -14865,6 +14867,13 @@ bool Player::CanRewardQuest(Quest const* quest, bool msg)
|
||||
if (quest->GetRewOrReqMoney() < 0 && !HasEnoughMoney(-int64(quest->GetRewOrReqMoney())))
|
||||
return false;
|
||||
|
||||
// dungeon finder quests cannot be rewarded when hit weekly currency limit
|
||||
if (quest->IsDFQuest())
|
||||
for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; i++)
|
||||
if (CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(quest->RewardCurrencyId[i]))
|
||||
if (GetCurrencyOnWeek(quest->RewardCurrencyId[i], false) == GetCurrencyWeekCap(currency))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15224,7 +15233,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
if (quest->IsDaily() || quest->IsDFQuest())
|
||||
if ((quest->IsDaily() || quest->IsDFQuest()) && !quest->IsRepeatable())
|
||||
{
|
||||
SetDailyQuestStatus(quest_id);
|
||||
if (quest->IsDaily())
|
||||
@@ -15779,7 +15788,7 @@ bool Player::SatisfyQuestDay(Quest const* qInfo, bool msg) const
|
||||
if (!qInfo->IsDaily() && !qInfo->IsDFQuest())
|
||||
return true;
|
||||
|
||||
if (qInfo->IsDFQuest())
|
||||
if (qInfo->IsDFQuest() && !qInfo->IsRepeatable())
|
||||
{
|
||||
if (m_DFQuests.find(qInfo->GetQuestId()) != m_DFQuests.end())
|
||||
return false;
|
||||
@@ -22575,6 +22584,28 @@ void Player::SetBattlegroundEntryPoint()
|
||||
m_bgData.joinPos = WorldLocation(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, 0.0f);
|
||||
}
|
||||
|
||||
void Player::GetLFGLeavePoint(Position* pos)
|
||||
{
|
||||
if (pos)
|
||||
{
|
||||
pos->Relocate(m_bgData.leavePos.m_positionX, m_bgData.leavePos.m_positionY,
|
||||
m_bgData.leavePos.m_positionZ, m_bgData.leavePos.GetOrientation());
|
||||
_hasValidLFGLeavePoint = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Player::HasValidLFGLeavePoint(uint32 mapid)
|
||||
{
|
||||
return _hasValidLFGLeavePoint && MapManager::IsValidMapCoord(mapid, m_bgData.leavePos.m_positionX, m_bgData.leavePos.m_positionY,
|
||||
m_bgData.leavePos.m_positionZ, m_bgData.leavePos.GetOrientation());
|
||||
}
|
||||
|
||||
void Player::SetLFGLeavePoint()
|
||||
{
|
||||
m_bgData.leavePos = WorldLocation(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
|
||||
_hasValidLFGLeavePoint = true;
|
||||
}
|
||||
|
||||
void Player::SetBGTeam(uint32 team)
|
||||
{
|
||||
m_bgData.bgTeam = team;
|
||||
|
||||
@@ -1115,6 +1115,7 @@ struct BGData
|
||||
uint32 taxiPath[2];
|
||||
|
||||
WorldLocation joinPos; ///< From where player entered BG
|
||||
WorldLocation leavePos;
|
||||
|
||||
void ClearTaxiPath() { taxiPath[0] = taxiPath[1] = 0; }
|
||||
bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; }
|
||||
@@ -2376,6 +2377,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
bool isUsingLfg() const;
|
||||
bool inRandomLfgDungeon() const;
|
||||
|
||||
void GetLFGLeavePoint(Position* pos);
|
||||
bool HasValidLFGLeavePoint(uint32 mapid);
|
||||
void SetLFGLeavePoint();
|
||||
|
||||
typedef std::set<uint32> DFQuestsDoneList;
|
||||
DFQuestsDoneList m_DFQuests;
|
||||
|
||||
@@ -2540,6 +2545,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
VoidStorageItem* GetVoidStorageItem(uint8 slot) const;
|
||||
VoidStorageItem* GetVoidStorageItem(uint64 id, uint8& slot) const;
|
||||
|
||||
void SetTempCallToArmsRoles(uint8 roles) { _tmpLfgRolesCheck = roles; }
|
||||
uint8 GetCallToArmsTempRoles() { return _tmpLfgRolesCheck; }
|
||||
|
||||
protected:
|
||||
// Gamemaster whisper whitelist
|
||||
GuidList WhisperList;
|
||||
@@ -2890,6 +2898,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
uint32 _activeCheats;
|
||||
uint32 _maxPersonalArenaRate;
|
||||
|
||||
bool _hasValidLFGLeavePoint;
|
||||
|
||||
// variables to save health and mana before duel and restore them after duel
|
||||
uint32 healthBeforeDuel;
|
||||
uint32 manaBeforeDuel;
|
||||
@@ -2897,6 +2907,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
WorldLocation _corpseLocation;
|
||||
|
||||
Archaeology _archaeology;
|
||||
|
||||
uint8 _tmpLfgRolesCheck;
|
||||
};
|
||||
|
||||
TC_GAME_API void AddItemsSetItem(Player* player, Item* item);
|
||||
|
||||
@@ -241,6 +241,26 @@ void Group::ConvertToLFG()
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void Group::ConvertToLFR()
|
||||
{
|
||||
m_groupType = GroupType(m_groupType | GROUPTYPE_LFG | GROUPTYPE_LFG_RESTRICTED | GROUPTYPE_RAID);
|
||||
m_lootMethod = NEED_BEFORE_GREED;
|
||||
|
||||
_initRaidSubGroupsCounter();
|
||||
|
||||
if (!isBGGroup() && !isBFGroup())
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
|
||||
|
||||
stmt->setUInt8(0, uint8(m_groupType));
|
||||
stmt->setUInt32(1, m_dbStoreId);
|
||||
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void Group::ConvertToRaid()
|
||||
{
|
||||
m_groupType = GroupType(m_groupType | GROUPTYPE_RAID);
|
||||
@@ -2374,6 +2394,15 @@ void Group::SetLfgRoles(ObjectGuid guid, uint8 roles)
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
uint8 Group::GetLfgRoles(ObjectGuid guid)
|
||||
{
|
||||
member_witerator slot = _getMemberWSlot(guid);
|
||||
if (slot == m_memberSlots.end())
|
||||
return 0;
|
||||
|
||||
return slot->roles;
|
||||
}
|
||||
|
||||
bool Group::IsFull() const
|
||||
{
|
||||
return isRaidGroup() ? (m_memberSlots.size() >= MAXRAIDSIZE) : (m_memberSlots.size() >= MAXGROUPSIZE);
|
||||
@@ -2384,6 +2413,11 @@ bool Group::isLFGGroup() const
|
||||
return (m_groupType & GROUPTYPE_LFG) != 0;
|
||||
}
|
||||
|
||||
bool Group::isLFRGroup() const
|
||||
{
|
||||
return (m_groupType & GROUPTYPE_LFG) && (m_groupType & GROUPTYPE_RAID);
|
||||
}
|
||||
|
||||
bool Group::isRaidGroup() const
|
||||
{
|
||||
return (m_groupType & GROUPTYPE_RAID) != 0;
|
||||
|
||||
@@ -206,6 +206,7 @@ class TC_GAME_API Group
|
||||
void SetLootThreshold(ItemQualities threshold);
|
||||
void Disband(bool hideDestroy = false);
|
||||
void SetLfgRoles(ObjectGuid guid, uint8 roles);
|
||||
uint8 GetLfgRoles(ObjectGuid guid);
|
||||
|
||||
void SetGroupMarkerMask(uint32 mask) { m_markerMask = mask; }
|
||||
void AddGroupMarkerMask(uint32 mask) { m_markerMask |= mask; }
|
||||
@@ -222,6 +223,7 @@ class TC_GAME_API Group
|
||||
// properties accessories
|
||||
bool IsFull() const;
|
||||
bool isLFGGroup() const;
|
||||
bool isLFRGroup() const;
|
||||
bool isRaidGroup() const;
|
||||
bool isBGGroup() const;
|
||||
bool isBFGroup() const;
|
||||
@@ -265,6 +267,7 @@ class TC_GAME_API Group
|
||||
uint8 GetMemberGroup(ObjectGuid guid) const;
|
||||
|
||||
void ConvertToLFG();
|
||||
void ConvertToLFR();
|
||||
void ConvertToRaid();
|
||||
void ConvertToGroup();
|
||||
|
||||
|
||||
@@ -794,7 +794,7 @@ void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& recvData)
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
if (_player->InBattleground())
|
||||
if (_player->InBattleground() || group->isLFGGroup())
|
||||
return;
|
||||
|
||||
// error handling
|
||||
|
||||
@@ -132,6 +132,8 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData)
|
||||
TC_LOG_DEBUG("lfg", "CMSG_LFG_JOIN %s roles: %u, Dungeons: %u, Comment: %s",
|
||||
GetPlayerInfo().c_str(), roles, uint8(newDungeons.size()), comment.c_str());
|
||||
|
||||
GetPlayer()->SetTempCallToArmsRoles(sLFGMgr->GetRolesForCallToArms());
|
||||
|
||||
sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment);
|
||||
}
|
||||
|
||||
@@ -170,7 +172,10 @@ void WorldSession::HandleLfgLeaveOpcode(WorldPacket& recvData)
|
||||
|
||||
// Check cheating - only leader can leave the queue
|
||||
if (!group || group->GetLeaderGUID() == guid)
|
||||
{
|
||||
GetPlayer()->SetTempCallToArmsRoles(0);
|
||||
sLFGMgr->LeaveLfg(gguid);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleLfgProposalResultOpcode(WorldPacket& recvData)
|
||||
@@ -309,8 +314,9 @@ void WorldSession::SendLfgPlayerLockInfo()
|
||||
data << uint8(randomDungeons.size()); // Random Dungeon count
|
||||
for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it)
|
||||
{
|
||||
data << uint32(*it); // Dungeon Entry (id + type)
|
||||
lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level);
|
||||
uint32 dungeonId = *it;
|
||||
data << uint32(dungeonId); // Dungeon Entry (id + type)
|
||||
lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(dungeonId, level);
|
||||
Quest const* quest = NULL;
|
||||
bool done = false;
|
||||
if (reward)
|
||||
@@ -325,26 +331,87 @@ void WorldSession::SendLfgPlayerLockInfo()
|
||||
}
|
||||
|
||||
data << uint8(done);
|
||||
data << uint32(0); // currencyQuantity
|
||||
data << uint32(0); // some sort of overall cap/weekly cap
|
||||
data << uint32(0); // currencyID
|
||||
data << uint32(0); // tier1Quantity
|
||||
data << uint32(0); // tier1Limit
|
||||
data << uint32(0); // overallQuantity
|
||||
data << uint32(0); // overallLimit
|
||||
data << uint32(0); // periodPurseQuantity
|
||||
data << uint32(0); // periodPurseLimit
|
||||
data << uint32(0); // purseQuantity
|
||||
data << uint32(0); // purseLimit
|
||||
data << uint32(0); // some sort of reward for completion
|
||||
data << uint32(0); // completedEncounters
|
||||
data << uint8(0); // Call to Arms eligible
|
||||
|
||||
for (uint32 i = 0; i < 3; ++i)
|
||||
CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(CURRENCY_TYPE_VALOR_POINTS);
|
||||
int8 valorPointsField = -1;
|
||||
|
||||
for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; i++)
|
||||
if (quest && quest->RewardCurrencyId[i] == CURRENCY_TYPE_VALOR_POINTS)
|
||||
valorPointsField = i;
|
||||
|
||||
if (currency && quest)
|
||||
{
|
||||
data << uint32(0); // Call to Arms Role
|
||||
//if (role)
|
||||
// BuildQuestReward(data, ctaRoleQuest, GetPlayer());
|
||||
data << uint32(valorPointsField >= 0 ? quest->RewardCurrencyCount[valorPointsField] : 0); // currencyQuantity
|
||||
data << uint32(GetPlayer()->GetCurrencyWeekCap(currency)); // some sort of overall cap/weekly cap
|
||||
data << uint32(quest->RewardCurrencyId[0]); // currencyID
|
||||
data << uint32(GetPlayer()->GetCurrencyOnWeek(CURRENCY_TYPE_VALOR_POINTS, false)); // tier1Quantity
|
||||
data << uint32(GetPlayer()->GetCurrencyWeekCap(currency)); // tier1Limit
|
||||
data << uint32(0); // overallQuantity
|
||||
data << uint32(GetPlayer()->GetCurrencyWeekCap(currency)); // overallLimit
|
||||
data << uint32(GetPlayer()->GetCurrencyOnWeek(CURRENCY_TYPE_VALOR_POINTS, false)); // periodPurseQuantity
|
||||
data << uint32(GetPlayer()->GetCurrencyWeekCap(currency)); // periodPurseLimit
|
||||
data << uint32(GetPlayer()->GetCurrencyTotalCap(currency)); // purseQuantity
|
||||
data << uint32(0); // purseLimit
|
||||
data << uint32(valorPointsField >= 0 ? quest->RewardCurrencyCount[valorPointsField] : 0); // some sort of reward for completion
|
||||
}
|
||||
else
|
||||
{
|
||||
data << uint32(0); // currencyQuantity
|
||||
data << uint32(0); // some sort of overall cap/weekly cap
|
||||
data << uint32(0); // currencyID
|
||||
data << uint32(0); // tier1Quantity
|
||||
data << uint32(0); // tier1Limit
|
||||
data << uint32(0); // overallQuantity
|
||||
data << uint32(0); // overallLimit
|
||||
data << uint32(0); // periodPurseQuantity
|
||||
data << uint32(0); // periodPurseLimit
|
||||
data << uint32(0); // purseQuantity
|
||||
data << uint32(0); // purseLimit
|
||||
data << uint32(0); // some sort of reward for completion
|
||||
}
|
||||
data << uint32(0); // completedEncounters
|
||||
|
||||
bool isCallToArmEligible = sLFGMgr->IsCallToArmEligible(level, dungeonId & 0x00FFFFFF);
|
||||
|
||||
data << uint8(isCallToArmEligible); // Call to Arms eligible
|
||||
|
||||
if (isCallToArmEligible)
|
||||
{
|
||||
uint8 roleTank = sLFGMgr->GetRolesForCallToArms() & lfg::PLAYER_ROLE_TANK ? lfg::PLAYER_ROLE_TANK : 0;
|
||||
uint8 roleHeal = sLFGMgr->GetRolesForCallToArms() & lfg::PLAYER_ROLE_HEALER ? lfg::PLAYER_ROLE_HEALER : 0;
|
||||
uint8 roleDPS = sLFGMgr->GetRolesForCallToArms() & lfg::PLAYER_ROLE_DAMAGE ? lfg::PLAYER_ROLE_DAMAGE : 0;
|
||||
|
||||
Quest const* ctaQuest = sObjectMgr->GetQuestTemplate(LFG_CALL_TO_ARMS_QUEST);
|
||||
if (roleTank)
|
||||
{
|
||||
data << uint32(roleTank);
|
||||
BuildQuestReward(data, ctaQuest, GetPlayer());
|
||||
}
|
||||
else
|
||||
data << uint32(0);
|
||||
if (roleHeal)
|
||||
{
|
||||
data << uint32(roleHeal);
|
||||
BuildQuestReward(data, ctaQuest, GetPlayer());
|
||||
}
|
||||
else
|
||||
data << uint32(0);
|
||||
if (roleDPS)
|
||||
{
|
||||
data << uint32(roleDPS);
|
||||
BuildQuestReward(data, ctaQuest, GetPlayer());
|
||||
}
|
||||
else
|
||||
data << uint32(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32 i = 0; i < 3; ++i)
|
||||
{
|
||||
data << uint32(0); // Call to Arms Role
|
||||
//if (role)
|
||||
// BuildQuestReward(data, ctaRoleQuest, GetPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
if (quest)
|
||||
@@ -473,7 +540,7 @@ void WorldSession::SendLfgUpdateStatus(lfg::LfgUpdateData const& updateData, boo
|
||||
data.WriteBit(party);
|
||||
data.WriteBits(size, 24);
|
||||
data.WriteBit(guid[6]);
|
||||
data.WriteBit(size > 0); // Extra info
|
||||
data.WriteBit(queued); // Extra info
|
||||
data.WriteBits(updateData.comment.length(), 9);
|
||||
data.WriteBit(guid[4]);
|
||||
data.WriteBit(guid[7]);
|
||||
|
||||
@@ -663,7 +663,11 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi
|
||||
completedEncounters |= 1 << encounter->dbcEntry->encounterIndex;
|
||||
if (encounter->lastEncounterDungeon)
|
||||
{
|
||||
dungeonId = encounter->lastEncounterDungeon;
|
||||
if (instance->GetDifficulty() != sLFGDungeonStore.LookupEntry(encounter->lastEncounterDungeon)->difficulty)
|
||||
dungeonId = sLFGMgr->GetDungeonIdForDifficulty(encounter->lastEncounterDungeon, instance->GetDifficulty());
|
||||
else
|
||||
dungeonId = encounter->lastEncounterDungeon;
|
||||
|
||||
TC_LOG_DEBUG("lfg", "UpdateEncounterState: Instance %s (instanceId %u) completed encounter %s. Credit Dungeon: %u", instance->GetMapName(), instance->GetInstanceId(), encounter->dbcEntry->encounterName, dungeonId);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1327,6 +1327,7 @@ void World::LoadConfigSettings(bool reload)
|
||||
|
||||
// Dungeon finder
|
||||
m_int_configs[CONFIG_LFG_OPTIONSMASK] = sConfigMgr->GetIntDefault("DungeonFinder.OptionsMask", 1);
|
||||
m_bool_configs[CONFIG_LFG_CALL_TO_ARMS_ENABLED] = sConfigMgr->GetBoolDefault("DungeonFinder.CallToArmsEnable", false);
|
||||
|
||||
// DBC_ItemAttributes
|
||||
m_bool_configs[CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES] = sConfigMgr->GetBoolDefault("DBC.EnforceItemAttributes", true);
|
||||
|
||||
@@ -188,6 +188,7 @@ enum WorldBoolConfigs
|
||||
CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED,
|
||||
CONFIG_CHECK_GOBJECT_LOS,
|
||||
CONFIG_RESPAWN_DYNAMIC_ESCORTNPC,
|
||||
CONFIG_LFG_CALL_TO_ARMS_ENABLED,
|
||||
BOOL_CONFIG_VALUE_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -1213,6 +1213,14 @@ DeletedCharacterTicketTrace = 0
|
||||
|
||||
DungeonFinder.OptionsMask = 1
|
||||
|
||||
#
|
||||
# DungeonFinder.CallToArmsEnable
|
||||
# Description: Enable Call to Arms bonus mechanism for random Cataclysm dungeons
|
||||
# Default: 0 - (Disabled)
|
||||
# 1 - (Enabled)
|
||||
|
||||
DungeonFinder.CallToArmsEnable = 0
|
||||
|
||||
#
|
||||
# DBC.EnforceItemAttributes
|
||||
# Description: Disallow overriding item attributes stored in DBC files with values from the
|
||||
|
||||
Reference in new issue
Block a user