diff options
Diffstat (limited to 'src')
23 files changed, 935 insertions, 709 deletions
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 850c58bdf93..16595eb16dd 100755 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -118,7 +118,7 @@ DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomProp DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt); DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt); -DBCStorage <LFGDungeonEntry> sLFGDungeonStore(LFGDungeonEntryfmt); +DBCStorage <LFGDungeonEntryDbc> sLFGDungeonStore(LFGDungeonEntryfmt); DBCStorage <LiquidTypeEntry> sLiquidTypeStore(LiquidTypefmt); DBCStorage <LockEntry> sLockStore(LockEntryfmt); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index cd30ed587f8..f6fabb5a73d 100755 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -120,7 +120,7 @@ extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore; extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore; extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore; extern DBCStorage <ItemSetEntry> sItemSetStore; -extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore; +extern DBCStorage <LFGDungeonEntryDbc> sLFGDungeonStore; extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore; extern DBCStorage <LockEntry> sLockStore; extern DBCStorage <MailTemplateEntry> sMailTemplateStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 538a53344e8..2fc61e69fe2 100755 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1193,10 +1193,10 @@ struct ItemSetEntry uint32 required_skill_value; // 52 m_requiredSkillRank }; -struct LFGDungeonEntry +struct LFGDungeonEntryDbc { uint32 ID; // 0 - //char* name[16]; // 1-17 Name lang + char* name[16]; // 1-17 Name lang uint32 minlevel; // 18 uint32 maxlevel; // 19 uint32 reclevel; // 20 diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 39f9009419e..0c2cc565b22 100755 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -19,111 +19,111 @@ #ifndef TRINITY_DBCSFRM_H #define TRINITY_DBCSFRM_H -const char Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii"; +char const Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii"; const std::string CustomAchievementfmt="pppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapapaaaaaaaaaaaaaaaaaapp"; const std::string CustomAchievementIndex = "ID"; -const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiiiix"; -const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxiiiiixxx"; -const char AreaGroupEntryfmt[]="niiiiiii"; -const char AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix"; -const char AreaTriggerEntryfmt[]="niffffffff"; -const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx"; -const char BankBagSlotPricesEntryfmt[]="ni"; -const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii"; -const char BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx"; -const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi"; -const char ChatChannelsEntryfmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxx"; +char const AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiiiix"; +char const AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxiiiiixxx"; +char const AreaGroupEntryfmt[]="niiiiiii"; +char const AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix"; +char const AreaTriggerEntryfmt[]="niffffffff"; +char const AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx"; +char const BankBagSlotPricesEntryfmt[]="ni"; +char const BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii"; +char const BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx"; +char const CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +char const CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi"; +char const ChatChannelsEntryfmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxx"; // ChatChannelsEntryfmt, index not used (more compact store) -const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; -const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; -const char CinematicSequencesEntryfmt[]="nxxxxxxxxx"; -const char CreatureDisplayInfofmt[]="nixxfxxxxxxxxxxx"; -const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx"; -const char CreatureModelDatafmt[]="nxxxfxxxxxxxxxxffxxxxxxxxxxx"; -const char CreatureSpellDatafmt[]="niiiixxxx"; -const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx"; -const char CurrencyTypesfmt[]="xnxi"; -const char DestructibleModelDatafmt[]="nxxixxxixxxixxxixxx"; -const char DungeonEncounterfmt[]="niixissssssssssssssssxx"; -const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; -const char DurabilityQualityfmt[]="nf"; -const char EmotesEntryfmt[]="nxxiiix"; -const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx"; -const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx"; -const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii"; -const char GameObjectDisplayInfofmt[]="nsxxxxxxxxxxffffffx"; -const char GemPropertiesEntryfmt[]="nixxi"; -const char GlyphPropertiesfmt[]="niii"; -const char GlyphSlotfmt[]="nii"; -const char GtBarberShopCostBasefmt[]="f"; -const char GtCombatRatingsfmt[]="f"; -const char GtChanceToMeleeCritBasefmt[]="f"; -const char GtChanceToMeleeCritfmt[]="f"; -const char GtChanceToSpellCritBasefmt[]="f"; -const char GtChanceToSpellCritfmt[]="f"; -const char GtOCTClassCombatRatingScalarfmt[]="df"; -const char GtOCTRegenHPfmt[]="f"; -//const char GtOCTRegenMPfmt[]="f"; -const char GtRegenHPPerSptfmt[]="f"; -const char GtRegenMPPerSptfmt[]="f"; -const char Holidaysfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix"; -const char Itemfmt[]="niiiiiii"; -const char ItemBagFamilyfmt[]="nxxxxxxxxxxxxxxxxx"; -//const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; -//const char ItemCondExtCostsEntryfmt[]="xiii"; -const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiix"; -const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; -const char ItemRandomPropertiesfmt[]="nxiiixxssssssssssssssssx"; -const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiixxiiixx"; -const char ItemSetEntryfmt[]="dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii"; -const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiiiixxixixxxxxxxxxxxxxxxxx"; -const char LiquidTypefmt[]="nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; -const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx"; -const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix"; -const char MapDifficultyEntryfmt[]="diisxxxxxxxxxxxxxxxxiix"; -const char MovieEntryfmt[]="nxx"; -const char OverrideSpellDatafmt[]="niiiiiiiiiix"; -const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx"; -const char QuestXPfmt[]="niiiiiiiiii"; -const char QuestFactionRewardfmt[]="niiiiiiiiii"; -const char PvPDifficultyfmt[]="diiiii"; -const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; -const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii"; -const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiiii"; -const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi"; -const char SkillLineAbilityfmt[]="niiiixxiiiiixx"; -const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char SpellCastTimefmt[]="nixx"; -const char SpellDifficultyfmt[]="niiii"; +char const ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; +char const ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; +char const CinematicSequencesEntryfmt[]="nxxxxxxxxx"; +char const CreatureDisplayInfofmt[]="nixxfxxxxxxxxxxx"; +char const CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx"; +char const CreatureModelDatafmt[]="nxxxfxxxxxxxxxxffxxxxxxxxxxx"; +char const CreatureSpellDatafmt[]="niiiixxxx"; +char const CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx"; +char const CurrencyTypesfmt[]="xnxi"; +char const DestructibleModelDatafmt[]="nxxixxxixxxixxxixxx"; +char const DungeonEncounterfmt[]="niixissssssssssssssssxx"; +char const DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; +char const DurabilityQualityfmt[]="nf"; +char const EmotesEntryfmt[]="nxxiiix"; +char const EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx"; +char const FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx"; +char const FactionTemplateEntryfmt[]="niiiiiiiiiiiii"; +char const GameObjectDisplayInfofmt[]="nsxxxxxxxxxxffffffx"; +char const GemPropertiesEntryfmt[]="nixxi"; +char const GlyphPropertiesfmt[]="niii"; +char const GlyphSlotfmt[]="nii"; +char const GtBarberShopCostBasefmt[]="f"; +char const GtCombatRatingsfmt[]="f"; +char const GtChanceToMeleeCritBasefmt[]="f"; +char const GtChanceToMeleeCritfmt[]="f"; +char const GtChanceToSpellCritBasefmt[]="f"; +char const GtChanceToSpellCritfmt[]="f"; +char const GtOCTClassCombatRatingScalarfmt[]="df"; +char const GtOCTRegenHPfmt[]="f"; +//char const GtOCTRegenMPfmt[]="f"; +char const GtRegenHPPerSptfmt[]="f"; +char const GtRegenMPPerSptfmt[]="f"; +char const Holidaysfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix"; +char const Itemfmt[]="niiiiiii"; +char const ItemBagFamilyfmt[]="nxxxxxxxxxxxxxxxxx"; +//char const ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; +//char const ItemCondExtCostsEntryfmt[]="xiii"; +char const ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiix"; +char const ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; +char const ItemRandomPropertiesfmt[]="nxiiixxssssssssssssssssx"; +char const ItemRandomSuffixfmt[]="nssssssssssssssssxxiiixxiiixx"; +char const ItemSetEntryfmt[]="dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii"; +char const LFGDungeonEntryfmt[]="nssssssssssssssssiiiiiiiiixxixixxxxxxxxxxxxxxxxx"; +char const LiquidTypefmt[]="nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +char const LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; +char const MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx"; +char const MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix"; +char const MapDifficultyEntryfmt[]="diisxxxxxxxxxxxxxxxxiix"; +char const MovieEntryfmt[]="nxx"; +char const OverrideSpellDatafmt[]="niiiiiiiiiix"; +char const QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx"; +char const QuestXPfmt[]="niiiiiiiiii"; +char const QuestFactionRewardfmt[]="niiiiiiiiii"; +char const PvPDifficultyfmt[]="diiiii"; +char const RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; +char const ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii"; +char const ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiiii"; +char const SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi"; +char const SkillLineAbilityfmt[]="niiiixxiiiiixx"; +char const SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +char const SpellCastTimefmt[]="nixx"; +char const SpellDifficultyfmt[]="niiii"; const std::string CustomSpellDifficultyfmt="ppppp"; const std::string CustomSpellDifficultyIndex="id"; -const char SpellDurationfmt[]="niii"; -const char SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx"; +char const SpellDurationfmt[]="niii"; +char const SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx"; const std::string CustomSpellEntryfmt="papppppppppppapapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa"; const std::string CustomSpellEntryIndex = "Id"; -const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; -const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiiiii"; -const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; -const char SpellRadiusfmt[]="nfxf"; -const char SpellRangefmt[]="nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char SpellRuneCostfmt[]="niiii"; -const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixiiixxiiiiiiii"; -const char StableSlotPricesfmt[] = "ni"; -const char SummonPropertiesfmt[] = "niiiii"; -const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx"; -const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix"; -const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii"; -const char TaxiPathEntryfmt[]="niii"; -const char TaxiPathNodeEntryfmt[]="diiifffiiii"; -const char TeamContributionPointsfmt[]="df"; -const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; -const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx"; -const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx"; -const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx"; -const char WorldMapAreaEntryfmt[]="xinxffffixx"; -const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx"; -const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx"; +char const SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; +char const SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiiiii"; +char const SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; +char const SpellRadiusfmt[]="nfxf"; +char const SpellRangefmt[]="nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +char const SpellRuneCostfmt[]="niiii"; +char const SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixiiixxiiiiiiii"; +char const StableSlotPricesfmt[] = "ni"; +char const SummonPropertiesfmt[] = "niiiii"; +char const TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx"; +char const TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix"; +char const TaxiNodesEntryfmt[]="nifffssssssssssssssssxii"; +char const TaxiPathEntryfmt[]="niii"; +char const TaxiPathNodeEntryfmt[]="diiifffiiii"; +char const TeamContributionPointsfmt[]="df"; +char const TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; +char const VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx"; +char const VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx"; +char const WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx"; +char const WorldMapAreaEntryfmt[]="xinxffffixx"; +char const WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx"; +char const WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx"; #endif diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index 28498749af8..c00cc830ce8 100755 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -20,13 +20,20 @@ #include "Common.h" +enum LFGEnum +{ + LFG_TANKS_NEEDED = 1, + LFG_HEALERS_NEEDED = 1, + LFG_DPS_NEEDED = 3 +}; + enum LfgRoles { - ROLE_NONE = 0x00, - ROLE_LEADER = 0x01, - ROLE_TANK = 0x02, - ROLE_HEALER = 0x04, - ROLE_DAMAGE = 0x08 + PLAYER_ROLE_NONE = 0x00, + PLAYER_ROLE_LEADER = 0x01, + PLAYER_ROLE_TANK = 0x02, + PLAYER_ROLE_HEALER = 0x04, + PLAYER_ROLE_DAMAGE = 0x08 }; enum LfgUpdateType @@ -73,7 +80,16 @@ enum LfgLockStatusType LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL = 1002, LFG_LOCKSTATUS_QUEST_NOT_COMPLETED = 1022, LFG_LOCKSTATUS_MISSING_ITEM = 1025, - LFG_LOCKSTATUS_NOT_IN_SEASON = 1031 + LFG_LOCKSTATUS_NOT_IN_SEASON = 1031, + LFG_LOCKSTATUS_MISSING_ACHIEVEMENT = 1034 +}; + +/// Answer state (Also used to check compatibilites) +enum LfgAnswer +{ + LFG_ANSWER_PENDING = -1, + LFG_ANSWER_DENY = 0, + LFG_ANSWER_AGREE = 1 }; /// Dungeon and reason why player can't join @@ -84,7 +100,10 @@ struct LfgLockStatus }; typedef std::set<uint32> LfgDungeonSet; -typedef std::map<uint32, LfgLockStatusType> LfgLockMap; +typedef std::map<uint32, uint32> LfgLockMap; typedef std::map<uint64, LfgLockMap> LfgLockPartyMap; +typedef std::set<uint64> LfgGuidSet; +typedef std::list<uint64> LfgGuidList; +typedef std::map<uint64, uint8> LfgRolesMap; #endif diff --git a/src/server/game/DungeonFinding/LFGGroupData.cpp b/src/server/game/DungeonFinding/LFGGroupData.cpp index 607389c5dbf..cbcb1d130bb 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.cpp +++ b/src/server/game/DungeonFinding/LFGGroupData.cpp @@ -18,14 +18,16 @@ #include "LFG.h" #include "LFGGroupData.h" -LfgGroupData::LfgGroupData(): -m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), m_Dungeon(0), -m_VotesNeeded(LFG_GROUP_KICK_VOTES_NEEDED), m_KicksLeft(LFG_GROUP_MAX_KICKS) -{ -} +LfgGroupData::LfgGroupData(): m_State(LFG_STATE_NONE), m_OldState(LFG_STATE_NONE), + m_Dungeon(0), m_KicksLeft(LFG_GROUP_MAX_KICKS) +{ } LfgGroupData::~LfgGroupData() +{ } + +bool LfgGroupData::IsLfgGroup() { + return m_OldState != LFG_STATE_NONE; } void LfgGroupData::SetState(LfgState state) @@ -36,7 +38,7 @@ void LfgGroupData::SetState(LfgState state) case LFG_STATE_DUNGEON: case LFG_STATE_FINISHED_DUNGEON: m_OldState = state; - // No break on purpose + // No break on purpose default: m_State = state; } @@ -71,11 +73,6 @@ uint32 LfgGroupData::GetDungeon(bool asId /* = true */) const return m_Dungeon; } -uint8 LfgGroupData::GetVotesNeeded() const -{ - return m_VotesNeeded; -} - uint8 LfgGroupData::GetKicksLeft() const { return m_KicksLeft; diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h index 74570817698..359f7be7eee 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.h +++ b/src/server/game/DungeonFinding/LFGGroupData.h @@ -23,7 +23,6 @@ enum LfgGroupEnum { LFG_GROUP_MAX_KICKS = 3, - LFG_GROUP_KICK_VOTES_NEEDED = 3 }; /** @@ -35,13 +34,13 @@ class LfgGroupData LfgGroupData(); ~LfgGroupData(); + bool IsLfgGroup(); // General void SetState(LfgState state); void RestoreState(); // Dungeon void SetDungeon(uint32 dungeon); // VoteKick - void SetVotesNeeded(uint8 votes); void DecreaseKicksLeft(); // General @@ -49,7 +48,6 @@ class LfgGroupData // Dungeon uint32 GetDungeon(bool asId = true) const; // VoteKick - uint8 GetVotesNeeded() const; uint8 GetKicksLeft() const; private: @@ -59,7 +57,6 @@ class LfgGroupData // Dungeon uint32 m_Dungeon; ///< Dungeon entry // Vote Kick - uint8 m_VotesNeeded; ///< Votes need to kick success uint8 m_KicksLeft; ///< Number of kicks left }; diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 2b425dffff0..1b4a2fcdda3 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -32,46 +32,25 @@ #include "Group.h" #include "Player.h" -LFGMgr::LFGMgr(): m_update(true), m_QueueTimer(0), m_lfgProposalId(1), -m_WaitTimeAvg(-1), m_WaitTimeTank(-1), m_WaitTimeHealer(-1), m_WaitTimeDps(-1), -m_NumWaitTimeAvg(0), m_NumWaitTimeTank(0), m_NumWaitTimeHealer(0), m_NumWaitTimeDps(0) -{ - m_update = sWorld->getBoolConfig(CONFIG_DUNGEON_FINDER_ENABLE); - if (m_update) - { - new LFGPlayerScript(); - new LFGGroupScript(); - - // Initialize dungeon cache - for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) - { - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i); - if (dungeon && dungeon->type != LFG_TYPE_ZONE) - { - if (dungeon->type != LFG_TYPE_RANDOM) - m_CachedDungeonMap[dungeon->grouptype].insert(dungeon->ID); - m_CachedDungeonMap[0].insert(dungeon->ID); - } - } - } -} +LFGMgr::LFGMgr(): m_QueueTimer(0), m_lfgProposalId(1), + m_options(sWorld->getBoolConfig(CONFIG_DUNGEON_FINDER_ENABLE)), + m_WaitTimeAvg(-1), m_WaitTimeTank(-1), m_WaitTimeHealer(-1), m_WaitTimeDps(-1), + m_NumWaitTimeAvg(0), m_NumWaitTimeTank(0), m_NumWaitTimeHealer(0), m_NumWaitTimeDps(0), + m_lfgPlayerScript(new LFGPlayerScript()), m_lfgGroupScript(new LFGGroupScript()) +{ } LFGMgr::~LFGMgr() { for (LfgRewardMap::iterator itr = m_RewardMap.begin(); itr != m_RewardMap.end(); ++itr) delete itr->second; + delete m_lfgPlayerScript; + delete m_lfgGroupScript; for (LfgQueueInfoMap::iterator it = m_QueueInfoMap.begin(); it != m_QueueInfoMap.end(); ++it) delete it->second; for (LfgProposalMap::iterator it = m_Proposals.begin(); it != m_Proposals.end(); ++it) delete it->second; - - for (LfgPlayerBootMap::iterator it = m_Boots.begin(); it != m_Boots.end(); ++it) - delete it->second; - - for (LfgRoleCheckMap::iterator it = m_RoleChecks.begin(); it != m_RoleChecks.end(); ++it) - delete it->second; } void LFGMgr::_LoadFromDB(Field* fields, uint64 guid) @@ -122,6 +101,86 @@ void LFGMgr::_SaveToDB(uint64 guid, uint32 db_guid) CharacterDatabase.Execute(stmt); } +std::string LFGMgr::ConcatenateDungeons(LfgDungeonSet const& dungeons) +{ + std::string dungeonstr = ""; + if (!dungeons.empty()) + { + std::ostringstream o; + LfgDungeonSet::const_iterator it = dungeons.begin(); + o << (*it); + for (++it; it != dungeons.end(); ++it) + o << ", " << uint32(*it); + dungeonstr = o.str(); + } + return dungeonstr; +} + +std::string LFGMgr::GetRolesString(uint8 roles) +{ + std::string rolesstr = ""; + + if (roles & PLAYER_ROLE_TANK) + rolesstr.append("Tank"); + + if (roles & PLAYER_ROLE_HEALER) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append("Healer"); + } + + if (roles & PLAYER_ROLE_DAMAGE) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append("Dps"); + } + + if (roles & PLAYER_ROLE_LEADER) + { + if (!rolesstr.empty()) + rolesstr.append(", "); + rolesstr.append("Leader"); + } + + if (rolesstr.empty()) + rolesstr.append("None"); + + return rolesstr; +} + +char const * LFGMgr::GetStateString(LfgState state) +{ + switch (state) + { + case LFG_STATE_NONE: + return "None"; + break; + case LFG_STATE_ROLECHECK: + return "Rolecheck"; + break; + case LFG_STATE_QUEUED: + return "Queued"; + break; + case LFG_STATE_PROPOSAL: + return "Proposal"; + break; + case LFG_STATE_DUNGEON: + return "In Dungeon"; + break; + case LFG_STATE_BOOT: + return "Boot Player"; + break; + case LFG_STATE_FINISHED_DUNGEON: + return "Finished"; + break; + case LFG_STATE_RAIDBROWSER: + return "RaidBrowser"; + } + return "Error"; +} + /// Load rewards for completing dungeons void LFGMgr::LoadRewards() { @@ -155,7 +214,7 @@ void LFGMgr::LoadRewards() uint32 otherMoneyVar = fields[6].GetUInt32(); uint32 otherXPVar = fields[7].GetUInt32(); - if (!sLFGDungeonStore.LookupEntry(dungeonId)) + if (!GetLFGDungeon(dungeonId)) { sLog->outError(LOG_FILTER_SQL, "Dungeon %u specified in table `lfg_dungeon_rewards` does not exist!", dungeonId); continue; @@ -186,16 +245,50 @@ void LFGMgr::LoadRewards() sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u lfg dungeon rewards in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -void LFGMgr::LoadEntrancePositions() +LFGDungeonEntry const* LFGMgr::GetLFGDungeon(uint32 id) +{ + LFGDungeonMap::const_iterator itr = m_LfgDungeonMap.find(id); + if (itr != m_LfgDungeonMap.end()) + return &(itr->second); + + return NULL; +} + +LFGDungeonMap & LFGMgr::GetLFGDungeonMap() +{ + return m_LfgDungeonMap; +} + +void LFGMgr::LoadLFGDungeons(bool reload /* = false */) { uint32 oldMSTime = getMSTime(); - m_entrancePositions.clear(); + m_LfgDungeonMap.clear(); + + // Initialize Dungeon map with data from dbcs + for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) + { + LFGDungeonEntryDbc const* dungeon = sLFGDungeonStore.LookupEntry(i); + if (!dungeon) + continue; + + switch (dungeon->type) + { + case LFG_TYPE_DUNGEON: + case LFG_TYPE_HEROIC: + case LFG_TYPE_RAID: + case LFG_TYPE_RANDOM: + m_LfgDungeonMap[dungeon->ID] = LFGDungeonEntry(dungeon); + break; + } + } + + // Fill teleport locations from DB QueryResult result = WorldDatabase.Query("SELECT dungeonId, position_x, position_y, position_z, orientation FROM lfg_entrances"); if (!result) { - sLog->outError(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 lfg entrance positions. DB table `lfg_entrances` is empty!"); + sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 lfg entrance positions. DB table `lfg_entrances` is empty!"); return; } @@ -205,49 +298,85 @@ void LFGMgr::LoadEntrancePositions() { Field* fields = result->Fetch(); uint32 dungeonId = fields[0].GetUInt32(); - Position pos; - pos.m_positionX = fields[1].GetFloat(); - pos.m_positionY = fields[2].GetFloat(); - pos.m_positionZ = fields[3].GetFloat(); - pos.m_orientation = fields[4].GetFloat(); - m_entrancePositions[dungeonId] = pos; + LFGDungeonMap::iterator dungeonItr = m_LfgDungeonMap.find(dungeonId); + if (dungeonItr == m_LfgDungeonMap.end()) + { + sLog->outError(LOG_FILTER_SQL, "table `lfg_entrances` contains coordinates for wrong dungeon %u", dungeonId); + continue; + } + + LFGDungeonEntry& data = dungeonItr->second; + data.x = fields[1].GetFloat(); + data.y = fields[2].GetFloat(); + data.z = fields[3].GetFloat(); + data.o = fields[4].GetFloat(); + ++count; } while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u lfg entrance positions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + + // Fill all other teleport coords from areatriggers + for (LFGDungeonMap::iterator itr = m_LfgDungeonMap.begin(); itr != m_LfgDungeonMap.end(); ++itr) + { + LFGDungeonEntry& dungeon = itr->second; + // No teleport coords in database, load from areatriggers + if (dungeon.x == 0.0f && dungeon.y == 0.0f && dungeon.z == 0.0f) + { + AreaTrigger const* at = sObjectMgr->GetMapEntranceTrigger(dungeon.map); + if (!at) + { + sLog->outError(LOG_FILTER_LFG, "LFGMgr::LoadLFGDungeons: Failed to load dungeon %s, cant find areatrigger for map %u", dungeon.name.c_str(), dungeon.map); + continue; + } + + dungeon.map = at->target_mapId; + dungeon.x = at->target_X; + dungeon.y = at->target_Y; + dungeon.z = at->target_Z; + dungeon.o = at->target_Orientation; + } + + if (dungeon.type != LFG_TYPE_RANDOM) + m_CachedDungeonMap[dungeon.group].insert(dungeon.id); + m_CachedDungeonMap[0].insert(dungeon.id); + } + + if (reload) + { + m_CachedDungeonMap.clear(); + // Recalculate locked dungeons + for (LfgPlayerDataMap::const_iterator it = m_Players.begin(); it != m_Players.end(); ++it) + if (Player* player = ObjectAccessor::FindPlayer(it->first)) + InitializeLockedDungeons(player); + } } void LFGMgr::Update(uint32 diff) { - if (!m_update) + if (!m_options) return; - m_update = false; time_t currTime = time(NULL); // Remove obsolete role checks for (LfgRoleCheckMap::iterator it = m_RoleChecks.begin(); it != m_RoleChecks.end();) { LfgRoleCheckMap::iterator itRoleCheck = it++; - LfgRoleCheck* roleCheck = itRoleCheck->second; - if (currTime < roleCheck->cancelTime) + LfgRoleCheck& roleCheck = itRoleCheck->second; + if (currTime < roleCheck.cancelTime) continue; - roleCheck->state = LFG_ROLECHECK_MISSING_ROLE; + roleCheck.state = LFG_ROLECHECK_MISSING_ROLE; - for (LfgRolesMap::const_iterator itRoles = roleCheck->roles.begin(); itRoles != roleCheck->roles.end(); ++itRoles) + for (LfgRolesMap::const_iterator itRoles = roleCheck.roles.begin(); itRoles != roleCheck.roles.end(); ++itRoles) { uint64 guid = itRoles->first; - ClearState(guid); - if (Player* player = ObjectAccessor::FindPlayer(guid)) - { - player->GetSession()->SendLfgRoleCheckUpdate(roleCheck); - - if (itRoles->first == roleCheck->leader) - player->GetSession()->SendLfgJoinResult(LfgJoinResultData(LFG_JOIN_FAILED, LFG_ROLECHECK_MISSING_ROLE)); - } + ClearState(guid, "Remove Obsolete RoleCheck"); + SendLfgRoleCheckUpdate(guid, roleCheck); + if (guid == roleCheck.leader) + SendLfgJoinResult(guid, LfgJoinResultData(LFG_JOIN_FAILED, LFG_ROLECHECK_MISSING_ROLE)); } - delete roleCheck; m_RoleChecks.erase(itRoleCheck); } @@ -263,15 +392,16 @@ void LFGMgr::Update(uint32 diff) for (LfgPlayerBootMap::iterator it = m_Boots.begin(); it != m_Boots.end();) { LfgPlayerBootMap::iterator itBoot = it++; - LfgPlayerBoot* pBoot = itBoot->second; - if (pBoot->cancelTime < currTime) + LfgPlayerBoot& boot = itBoot->second; + if (boot.cancelTime < currTime) { - pBoot->inProgress = false; - for (LfgAnswerMap::const_iterator itVotes = pBoot->votes.begin(); itVotes != pBoot->votes.end(); ++itVotes) - if (Player* plrg = ObjectAccessor::FindPlayer(itVotes->first)) - if (plrg->GetGUID() != pBoot->victim) - plrg->GetSession()->SendLfgBootPlayer(pBoot); - delete pBoot; + boot.inProgress = false; + for (LfgAnswerMap::const_iterator itVotes = boot.votes.begin(); itVotes != boot.votes.end(); ++itVotes) + { + uint64 pguid = itVotes->first; + if (pguid != boot.victim) + SendLfgBootProposalUpdate(pguid, boot); + } m_Boots.erase(itBoot); } } @@ -317,7 +447,7 @@ void LFGMgr::Update(uint32 diff) } else player->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid))); - player->GetSession()->SendLfgUpdateProposal(m_lfgProposalId, pProposal); + player->GetSession()->SendLfgUpdateProposal(m_lfgProposalId, *pProposal); } } @@ -346,24 +476,24 @@ void LFGMgr::Update(uint32 diff) } uint32 dungeonId = (*queue->dungeons.begin()); uint32 queuedTime = uint32(currTime - queue->joinTime); - uint8 role = ROLE_NONE; + uint8 role = PLAYER_ROLE_NONE; for (LfgRolesMap::const_iterator itPlayer = queue->roles.begin(); itPlayer != queue->roles.end(); ++itPlayer) role |= itPlayer->second; - role &= ~ROLE_LEADER; + role &= ~PLAYER_ROLE_LEADER; int32 waitTime = -1; switch (role) { - case ROLE_NONE: // Should not happen - just in case + case PLAYER_ROLE_NONE: // Should not happen - just in case waitTime = -1; break; - case ROLE_TANK: + case PLAYER_ROLE_TANK: waitTime = m_WaitTimeTank; break; - case ROLE_HEALER: + case PLAYER_ROLE_HEALER: waitTime = m_WaitTimeHealer; break; - case ROLE_DAMAGE: + case PLAYER_ROLE_DAMAGE: waitTime = m_WaitTimeDps; break; default: @@ -371,14 +501,13 @@ void LFGMgr::Update(uint32 diff) break; } + LfgQueueStatusData queueData(dungeonId, waitTime, m_WaitTimeAvg, m_WaitTimeTank, m_WaitTimeHealer, m_WaitTimeDps, queuedTime, queue->tanks, queue->healers, queue->dps); for (LfgRolesMap::const_iterator itPlayer = queue->roles.begin(); itPlayer != queue->roles.end(); ++itPlayer) - if (Player* player = ObjectAccessor::FindPlayer(itPlayer->first)) - player->GetSession()->SendLfgQueueStatus(dungeonId, waitTime, m_WaitTimeAvg, m_WaitTimeTank, m_WaitTimeHealer, m_WaitTimeDps, queuedTime, queue->tanks, queue->healers, queue->dps); + SendLfgQueueStatus(itPlayer->first, queueData); } } else m_QueueTimer += diff; - m_update = true; } /** @@ -441,68 +570,61 @@ bool LFGMgr::RemoveFromQueue(uint64 guid) @param[in] player Player we need to initialize the lock status map */ -void LFGMgr::InitializeLockedDungeons(Player* player) +void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */) { uint64 guid = player->GetGUID(); - uint8 level = player->getLevel(); + if (!level) + level = player->getLevel(); uint8 expansion = player->GetSession()->Expansion(); - LfgDungeonSet dungeons = GetDungeonsByRandom(0); + LfgDungeonSet const& dungeons = GetDungeonsByRandom(0); LfgLockMap lock; for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end(); ++it) { - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(*it); + LFGDungeonEntry const* dungeon = GetLFGDungeon(*it); if (!dungeon) // should never happen - We provide a list from sLFGDungeonStore continue; - AccessRequirement const* ar = sObjectMgr->GetAccessRequirement(dungeon->map, Difficulty(dungeon->difficulty)); - - LfgLockStatusType locktype = LFG_LOCKSTATUS_OK; + uint32 lockData = 0; if (dungeon->expansion > expansion) - locktype = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION; + lockData = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION; else if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, dungeon->map, player)) - locktype = LFG_LOCKSTATUS_RAID_LOCKED; + lockData = LFG_LOCKSTATUS_RAID_LOCKED; else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty))) - { - //if (!player->GetGroup() || !player->GetGroup()->isLFGGroup() || GetDungeon(player->GetGroup()->GetGUID(), true) != dungeon->ID || GetState(player->GetGroup()->GetGUID()) != LFG_STATE_DUNGEON) - locktype = LFG_LOCKSTATUS_RAID_LOCKED; - } + lockData = LFG_LOCKSTATUS_RAID_LOCKED; else if (dungeon->minlevel > level) - locktype = LFG_LOCKSTATUS_TOO_LOW_LEVEL; + lockData = LFG_LOCKSTATUS_TOO_LOW_LEVEL; else if (dungeon->maxlevel < level) - locktype = LFG_LOCKSTATUS_TOO_HIGH_LEVEL; - else if (dungeon->flags & LFG_FLAG_SEASONAL) - { - if (HolidayIds holiday = sLFGMgr->GetDungeonSeason(dungeon->ID)) - if (!IsHolidayActive(holiday)) - locktype = LFG_LOCKSTATUS_NOT_IN_SEASON; - } - else if (locktype == LFG_LOCKSTATUS_OK && ar) + lockData = LFG_LOCKSTATUS_TOO_HIGH_LEVEL; + else if (dungeon->seasonal && !IsSeasonActive(dungeon->id)) + lockData = LFG_LOCKSTATUS_NOT_IN_SEASON; + else if (AccessRequirement const* ar = sObjectMgr->GetAccessRequirement(dungeon->map, Difficulty(dungeon->difficulty))) { if (ar->achievement && !player->HasAchieved(ar->achievement)) - locktype = LFG_LOCKSTATUS_RAID_LOCKED; // FIXME: Check the correct lock value + lockData = LFG_LOCKSTATUS_MISSING_ACHIEVEMENT; else if (player->GetTeam() == ALLIANCE && ar->quest_A && !player->GetQuestRewardStatus(ar->quest_A)) - locktype = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED; + lockData = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED; else if (player->GetTeam() == HORDE && ar->quest_H && !player->GetQuestRewardStatus(ar->quest_H)) - locktype = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED; + lockData = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED; else if (ar->item) { if (!player->HasItemCount(ar->item, 1) && (!ar->item2 || !player->HasItemCount(ar->item2, 1))) - locktype = LFG_LOCKSTATUS_MISSING_ITEM; + lockData = LFG_LOCKSTATUS_MISSING_ITEM; } else if (ar->item2 && !player->HasItemCount(ar->item2, 1)) - locktype = LFG_LOCKSTATUS_MISSING_ITEM; + lockData = LFG_LOCKSTATUS_MISSING_ITEM; } + /* TODO VoA closed if WG is not under team control (LFG_LOCKSTATUS_RAID_LOCKED) - locktype = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE; - locktype = LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE; - locktype = LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL; - locktype = LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL; + lockData = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE; + lockData = LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE; + lockData = LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL; + lockData = LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL; */ - if (locktype != LFG_LOCKSTATUS_OK) - lock[dungeon->Entry()] = locktype; + if (lockData) + lock[dungeon->Entry()] = lockData; } SetLockedDungeons(guid, lock); } @@ -517,10 +639,10 @@ void LFGMgr::InitializeLockedDungeons(Player* player) @param[in] dungeons Dungeons the player/group is applying for @param[in] comment Player selected comment */ -void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDungeons, const std::string& comment) +void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const std::string& comment) { - if (!player || !player->GetSession() || selectedDungeons.empty()) - return; + if (!player || !player->GetSession() || dungeons.empty()) + return; Group* grp = player->GetGroup(); uint64 guid = player->GetGUID(); @@ -529,7 +651,6 @@ void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDung PlayerSet players; uint32 rDungeonId = 0; bool isContinue = grp && grp->isLFGGroup() && GetState(gguid) != LFG_STATE_FINISHED_DUNGEON; - LfgDungeonSet dungeons = selectedDungeons; // Do not allow to change dungeon in the middle of a current dungeon if (isContinue) @@ -542,7 +663,7 @@ void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDung LfgQueueInfoMap::iterator itQueue = m_QueueInfoMap.find(gguid); if (itQueue != m_QueueInfoMap.end()) { - LfgDungeonSet playerDungeons = GetSelectedDungeons(guid); + LfgDungeonSet const& playerDungeons = GetSelectedDungeons(guid); if (playerDungeons == dungeons) // Joining the same dungeons -- Send OK { LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, comment); @@ -652,25 +773,24 @@ void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDung return; } - // FIXME - Raid browser not supported yet + SetComment(guid, comment); + if (isRaid) { sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::Join: [" UI64FMTD "] trying to join raid browser and it's disabled.", guid); return; } - SetComment(guid, comment); - + std::string debugNames = ""; if (grp) // Begin rolecheck { // Create new rolecheck - LfgRoleCheck* roleCheck = new LfgRoleCheck(); - roleCheck->cancelTime = time_t(time(NULL)) + LFG_TIME_ROLECHECK; - roleCheck->state = LFG_ROLECHECK_INITIALITING; - roleCheck->leader = guid; - roleCheck->dungeons = dungeons; - roleCheck->rDungeonId = rDungeonId; - m_RoleChecks[gguid] = roleCheck; + LfgRoleCheck& roleCheck = m_RoleChecks[gguid]; + roleCheck.cancelTime = time_t(time(NULL)) + LFG_TIME_ROLECHECK; + roleCheck.state = LFG_ROLECHECK_INITIALITING; + roleCheck.leader = guid; + roleCheck.dungeons = dungeons; + roleCheck.rDungeonId = rDungeonId; if (rDungeonId) { @@ -690,7 +810,10 @@ void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDung SetState(pguid, LFG_STATE_ROLECHECK); if (!isContinue) SetSelectedDungeons(pguid, dungeons); - roleCheck->roles[pguid] = 0; + roleCheck.roles[pguid] = 0; + if (!debugNames.empty()) + debugNames.append(", "); + debugNames.append(plrg->GetName()); } } // Update leader role @@ -703,19 +826,14 @@ void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDung pqInfo->joinTime = time_t(time(NULL)); pqInfo->roles[player->GetGUID()] = roles; pqInfo->dungeons = dungeons; - if (roles & ROLE_TANK) + if (roles & PLAYER_ROLE_TANK) --pqInfo->tanks; - else if (roles & ROLE_HEALER) + else if (roles & PLAYER_ROLE_HEALER) --pqInfo->healers; else --pqInfo->dps; m_QueueInfoMap[guid] = pqInfo; - // Send update to player - player->GetSession()->SendLfgJoinResult(joinData); - player->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, dungeons, comment)); - SetState(gguid, LFG_STATE_QUEUED); - SetRoles(guid, roles); if (!isContinue) { if (rDungeonId) @@ -725,9 +843,22 @@ void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDung } SetSelectedDungeons(guid, dungeons); } + // Send update to player + player->GetSession()->SendLfgJoinResult(joinData); + player->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, dungeons, comment)); + SetState(gguid, LFG_STATE_QUEUED); + SetRoles(guid, roles); + debugNames.append(player->GetName()); AddToQueue(guid, uint8(player->GetTeam())); } - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::Join: [" UI64FMTD "] joined with %u members. dungeons: %u", guid, grp ? grp->GetMembersCount() : 1, uint8(dungeons.size())); + + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + { + std::ostringstream o; + o << "LFGMgr::Join: [" << guid << "] joined (" << (grp ? "group" : "player") << ") Members: " << debugNames.c_str() + << ". Dungeons (" << uint32(dungeons.size()) << "): " << ConcatenateDungeons(dungeons); + sLog->outDebug(LOG_FILTER_LFG, "%s", o.str().c_str()); + } } /** @@ -737,7 +868,7 @@ void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDung @param[in] player Player trying to leave (can be NULL) @param[in] grp Group trying to leave (default NULL) */ -void LFGMgr::Leave(Player* player, Group* grp /* = NULL*/) +void LFGMgr::LeaveLfg(Player* player, Group* grp /* = NULL*/) { if (!player && !grp) return; @@ -754,19 +885,19 @@ void LFGMgr::Leave(Player* player, Group* grp /* = NULL*/) LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE); if (grp) { - RestoreState(guid); + RestoreState(guid, "Leave queue"); for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player* plrg = itr->getSource()) { plrg->GetSession()->SendLfgUpdateParty(updateData); uint64 pguid = plrg->GetGUID(); - ClearState(pguid); + ClearState(pguid, "Leave queue"); } } else { player->GetSession()->SendLfgUpdatePlayer(updateData); - ClearState(guid); + ClearState(guid, "Leave queue"); } } break; @@ -941,7 +1072,7 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal) for (LfgRolesMap::const_iterator itRoles = it->second->roles.begin(); itRoles != it->second->roles.end(); ++itRoles) { // Assign new leader - if (itRoles->second & ROLE_LEADER && (!leader || urand(0, 1))) + if (itRoles->second & PLAYER_ROLE_LEADER && (!leader || urand(0, 1))) leader = itRoles->first; rolesMap[itRoles->first] = itRoles->second; @@ -961,8 +1092,7 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal) { for (PlayerSet::const_iterator itPlayer = players.begin(); itPlayer != players.end() && player; ++itPlayer) { - // Do not form a group with ignoring candidates - if (player->GetSocial()->HasIgnore((*itPlayer)->GetGUIDLow()) || (*itPlayer)->GetSocial()->HasIgnore(player->GetGUIDLow())) + if (HasIgnore((*itPlayer)->GetGUID(), player->GetGUID())) { sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::CheckCompatibility: (%s) Players [" UI64FMTD "] and [" UI64FMTD "] ignoring", strGuids.c_str(), (*itPlayer)->GetGUID(), player->GetGUID()); player = NULL; @@ -1021,11 +1151,11 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal) for (LfgRolesMap::const_iterator itPlayer = queue->roles.begin(); itPlayer != queue->roles.end(); ++itPlayer) { uint8 roles = itPlayer->second; - if ((roles & ROLE_TANK) && Tanks_Needed > 0) + if ((roles & PLAYER_ROLE_TANK) && Tanks_Needed > 0) --Tanks_Needed; - else if ((roles & ROLE_HEALER) && Healers_Needed > 0) + else if ((roles & PLAYER_ROLE_HEALER) && Healers_Needed > 0) --Healers_Needed; - else if ((roles & ROLE_DAMAGE) && Dps_Needed > 0) + else if ((roles & PLAYER_ROLE_DAMAGE) && Dps_Needed > 0) --Dps_Needed; } } @@ -1106,7 +1236,7 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal) @param[in] guid Player guid (0 = rolecheck failed) @param[in] roles Player selected roles */ -void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* = ROLE_NONE */) +void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* = PLAYER_ROLE_NONE */) { if (!gguid) return; @@ -1116,87 +1246,88 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* if (itRoleCheck == m_RoleChecks.end()) return; - LfgRoleCheck* roleCheck = itRoleCheck->second; - bool sendRoleChosen = roleCheck->state != LFG_ROLECHECK_DEFAULT && guid; + LfgRoleCheck& roleCheck = itRoleCheck->second; + bool sendRoleChosen = roleCheck.state != LFG_ROLECHECK_DEFAULT && guid; if (!guid) - roleCheck->state = LFG_ROLECHECK_ABORTED; - else if (roles < ROLE_TANK) // Player selected no role. - roleCheck->state = LFG_ROLECHECK_NO_ROLE; + roleCheck.state = LFG_ROLECHECK_ABORTED; + else if (roles < PLAYER_ROLE_TANK) // Player selected no role. + roleCheck.state = LFG_ROLECHECK_NO_ROLE; else { - roleCheck->roles[guid] = roles; + roleCheck.roles[guid] = roles; // Check if all players have selected a role - LfgRolesMap::const_iterator itRoles = roleCheck->roles.begin(); - while (itRoles != roleCheck->roles.end() && itRoles->second != ROLE_NONE) + LfgRolesMap::const_iterator itRoles = roleCheck.roles.begin(); + while (itRoles != roleCheck.roles.end() && itRoles->second != PLAYER_ROLE_NONE) ++itRoles; - if (itRoles == roleCheck->roles.end()) + if (itRoles == roleCheck.roles.end()) { // 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; + check_roles = roleCheck.roles; + roleCheck.state = CheckGroupRoles(check_roles) ? LFG_ROLECHECK_FINISHED : LFG_ROLECHECK_WRONG_ROLES; } } uint8 team = 0; LfgDungeonSet dungeons; - if (roleCheck->rDungeonId) - dungeons.insert(roleCheck->rDungeonId); + if (roleCheck.rDungeonId) + dungeons.insert(roleCheck.rDungeonId); else - dungeons = roleCheck->dungeons; + dungeons = roleCheck.dungeons; - LfgJoinResultData joinData = LfgJoinResultData(LFG_JOIN_FAILED, roleCheck->state); - for (LfgRolesMap::const_iterator it = roleCheck->roles.begin(); it != roleCheck->roles.end(); ++it) + LfgJoinResultData joinData = LfgJoinResultData(LFG_JOIN_FAILED, roleCheck.state); + for (LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) { uint64 pguid = it->first; Player* plrg = ObjectAccessor::FindPlayer(pguid); if (!plrg) { - if (roleCheck->state == LFG_ROLECHECK_FINISHED) + if (roleCheck.state == LFG_ROLECHECK_FINISHED) SetState(pguid, LFG_STATE_QUEUED); - else if (roleCheck->state != LFG_ROLECHECK_INITIALITING) - ClearState(pguid); + else if (roleCheck.state != LFG_ROLECHECK_INITIALITING) + ClearState(pguid, "Offline while Rolecheck"); continue; } team = uint8(plrg->GetTeam()); if (!sendRoleChosen) - plrg->GetSession()->SendLfgRoleChosen(guid, roles); - plrg->GetSession()->SendLfgRoleCheckUpdate(roleCheck); - switch (roleCheck->state) + SendLfgRoleChosen(pguid, guid, roles); + + SendLfgRoleCheckUpdate(pguid, roleCheck); + switch (roleCheck.state) { case LFG_ROLECHECK_INITIALITING: continue; case LFG_ROLECHECK_FINISHED: SetState(pguid, LFG_STATE_QUEUED); - plrg->GetSession()->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, GetComment(pguid))); + SendLfgUpdateParty(pguid, LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, GetComment(pguid))); break; default: - if (roleCheck->leader == pguid) - plrg->GetSession()->SendLfgJoinResult(joinData); - plrg->GetSession()->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ROLECHECK_FAILED)); - ClearState(pguid); + if (roleCheck.leader == pguid) + SendLfgJoinResult(pguid, joinData); + SendLfgUpdateParty(pguid, LfgUpdateData(LFG_UPDATETYPE_ROLECHECK_FAILED)); + ClearState(pguid, "Role check Failed"); break; } } - if (roleCheck->state == LFG_ROLECHECK_FINISHED) + if (roleCheck.state == LFG_ROLECHECK_FINISHED) { SetState(gguid, LFG_STATE_QUEUED); LfgQueueInfo* pqInfo = new LfgQueueInfo(); pqInfo->joinTime = time_t(time(NULL)); - pqInfo->roles = roleCheck->roles; - pqInfo->dungeons = roleCheck->dungeons; + pqInfo->roles = roleCheck.roles; + pqInfo->dungeons = roleCheck.dungeons; // Set queue roles needed - As we are using check_roles will not have more that 1 tank, 1 healer, 3 dps for (LfgRolesMap::const_iterator it = check_roles.begin(); it != check_roles.end(); ++it) { uint8 roles2 = it->second; - if (roles2 & ROLE_TANK) + if (roles2 & PLAYER_ROLE_TANK) --pqInfo->tanks; - else if (roles2 & ROLE_HEALER) + else if (roles2 & PLAYER_ROLE_HEALER) --pqInfo->healers; else --pqInfo->dps; @@ -1210,12 +1341,9 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* } AddToQueue(gguid, team); } - - if (roleCheck->state != LFG_ROLECHECK_INITIALITING) + else if (roleCheck.state != LFG_ROLECHECK_INITIALITING) { - if (roleCheck->state != LFG_ROLECHECK_FINISHED) - RestoreState(gguid); - delete roleCheck; + RestoreState(gguid, "Rolecheck Failed"); m_RoleChecks.erase(itRoleCheck); } } @@ -1280,7 +1408,7 @@ void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, const PlayerSet& pla for (PlayerSet::const_iterator it = players.begin(); it != players.end() && !dungeons.empty(); ++it) { uint64 guid = (*it)->GetGUID(); - LfgLockMap cachedLockMap = GetLockedDungeons(guid); + LfgLockMap const& cachedLockMap = GetLockedDungeons(guid); for (LfgLockMap::const_iterator it2 = cachedLockMap.begin(); it2 != cachedLockMap.end() && !dungeons.empty(); ++it2) { uint32 dungeonId = (it2->first & 0x00FFFFFF); // Compare dungeon ids @@ -1314,21 +1442,21 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true if (removeLeaderFlag) for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it) - it->second &= ~ROLE_LEADER; + it->second &= ~PLAYER_ROLE_LEADER; for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it) { - if (it->second == ROLE_NONE) + if (it->second == PLAYER_ROLE_NONE) return false; - if (it->second & ROLE_TANK) + if (it->second & PLAYER_ROLE_TANK) { - if (it->second != ROLE_TANK) + if (it->second != PLAYER_ROLE_TANK) { - it->second -= ROLE_TANK; + it->second -= PLAYER_ROLE_TANK; if (CheckGroupRoles(groles, false)) return true; - it->second += ROLE_TANK; + it->second += PLAYER_ROLE_TANK; } else if (tank == LFG_TANKS_NEEDED) return false; @@ -1336,14 +1464,14 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true tank++; } - if (it->second & ROLE_HEALER) + if (it->second & PLAYER_ROLE_HEALER) { - if (it->second != ROLE_HEALER) + if (it->second != PLAYER_ROLE_HEALER) { - it->second -= ROLE_HEALER; + it->second -= PLAYER_ROLE_HEALER; if (CheckGroupRoles(groles, false)) return true; - it->second += ROLE_HEALER; + it->second += PLAYER_ROLE_HEALER; } else if (healer == LFG_HEALERS_NEEDED) return false; @@ -1351,14 +1479,14 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true healer++; } - if (it->second & ROLE_DAMAGE) + if (it->second & PLAYER_ROLE_DAMAGE) { - if (it->second != ROLE_DAMAGE) + if (it->second != PLAYER_ROLE_DAMAGE) { - it->second -= ROLE_DAMAGE; + it->second -= PLAYER_ROLE_DAMAGE; if (CheckGroupRoles(groles, false)) return true; - it->second += ROLE_DAMAGE; + it->second += PLAYER_ROLE_DAMAGE; } else if (damage == LFG_DPS_NEEDED) return false; @@ -1426,7 +1554,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) if (!allAnswered) { for (LfgPlayerList::const_iterator it = players.begin(); it != players.end(); ++it) - (*it)->GetSession()->SendLfgUpdateProposal(proposalId, pProposal); + (*it)->GetSession()->SendLfgUpdateProposal(proposalId, *pProposal); } else { @@ -1454,7 +1582,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) } // Set the dungeon difficulty - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId); + LFGDungeonEntry const* dungeon = GetLFGDungeon(pProposal->dungeonId); ASSERT(dungeon); // Create a new group (if needed) @@ -1466,7 +1594,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) uint64 pguid = player->GetGUID(); Group* group = player->GetGroup(); if (sendUpdate) - player->GetSession()->SendLfgUpdateProposal(proposalId, pProposal); + player->GetSession()->SendLfgUpdateProposal(proposalId, *pProposal); if (group) { @@ -1491,22 +1619,22 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) // Update timers uint8 role = GetRoles(pguid); - role &= ~ROLE_LEADER; + role &= ~PLAYER_ROLE_LEADER; switch (role) { - case ROLE_DAMAGE: + case PLAYER_ROLE_DAMAGE: { uint32 old_number = m_NumWaitTimeDps++; m_WaitTimeDps = int32((m_WaitTimeDps * old_number + waitTimesMap[player->GetGUID()]) / m_NumWaitTimeDps); break; } - case ROLE_HEALER: + case PLAYER_ROLE_HEALER: { uint32 old_number = m_NumWaitTimeHealer++; m_WaitTimeHealer = int32((m_WaitTimeHealer * old_number + waitTimesMap[player->GetGUID()]) / m_NumWaitTimeHealer); break; } - case ROLE_TANK: + case PLAYER_ROLE_TANK: { uint32 old_number = m_NumWaitTimeTank++; m_WaitTimeTank = int32((m_WaitTimeTank * old_number + waitTimesMap[player->GetGUID()]) / m_NumWaitTimeTank); @@ -1559,19 +1687,19 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) */ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType type) { - LfgProposal* pProposal = itProposal->second; - pProposal->state = LFG_PROPOSAL_FAILED; + LfgProposal& proposal = *(itProposal->second); + proposal.state = LFG_PROPOSAL_FAILED; sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RemoveProposal: Proposal %u, state FAILED, UpdateType %u", itProposal->first, type); // Mark all people that didn't answered as no accept if (type == LFG_UPDATETYPE_PROPOSAL_FAILED) - for (LfgProposalPlayerMap::const_iterator it = pProposal->players.begin(); it != pProposal->players.end(); ++it) + for (LfgProposalPlayerMap::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) if (it->second->accept == LFG_ANSWER_PENDING) it->second->accept = LFG_ANSWER_DENY; // Mark players/groups to be removed LfgGuidSet toRemove; - for (LfgProposalPlayerMap::const_iterator it = pProposal->players.begin(); it != pProposal->players.end(); ++it) + for (LfgProposalPlayerMap::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) { if (it->second->accept == LFG_ANSWER_AGREE) continue; @@ -1587,14 +1715,14 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t uint8 team = 0; // Notify players - for (LfgProposalPlayerMap::const_iterator it = pProposal->players.begin(); it != pProposal->players.end(); ++it) + for (LfgProposalPlayerMap::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) { Player* player = ObjectAccessor::FindPlayer(it->first); if (!player) continue; team = uint8(player->GetTeam()); - player->GetSession()->SendLfgUpdateProposal(itProposal->first, pProposal); + player->GetSession()->SendLfgUpdateProposal(itProposal->first, proposal); Group* grp = player->GetGroup(); uint64 guid = player->GetGUID(); @@ -1613,10 +1741,10 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t updateData.updateType = LFG_UPDATETYPE_REMOVED_FROM_QUEUE; sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RemoveProposal: [" UI64FMTD "] in same group that someone that didn't accept. Removing from queue and compatible cache", guid); } - ClearState(guid); + ClearState(guid, "Proposal Fail (didn't accepted or in group with someone that didn't accept"); if (grp) { - RestoreState(gguid); + RestoreState(gguid, "Proposal Fail (someone in group didn't accepted)"); player->GetSession()->SendLfgUpdateParty(updateData); } else @@ -1641,11 +1769,11 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t { uint64 guid = *it; RemoveFromQueue(guid); - pProposal->queues.remove(guid); + proposal.queues.remove(guid); } // Readd to queue - for (LfgGuidList::const_iterator it = pProposal->queues.begin(); it != pProposal->queues.end(); ++it) + for (LfgGuidList::const_iterator it = proposal.queues.begin(); it != proposal.queues.end(); ++it) { uint64 guid = *it; LfgGuidList& currentQueue = m_currentQueue[team]; @@ -1653,7 +1781,7 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t AddToQueue(guid, team); //We have to add each GUID in newQueue to check for a new groups } - delete pProposal; + delete &proposal; m_Proposals.erase(itProposal); } @@ -1665,41 +1793,39 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t @param[in] victim Victim guid @param[in] reason Kick reason */ -void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reason) +void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string const& reason) { if (!grp) return; - uint64 gguid = grp->GetGUID(); + uint32 gguid = grp->GetLowGUID(); SetState(gguid, LFG_STATE_BOOT); - LfgPlayerBoot* pBoot = new LfgPlayerBoot(); - pBoot->inProgress = true; - pBoot->cancelTime = time_t(time(NULL)) + LFG_TIME_BOOT; - pBoot->reason = reason; - pBoot->victim = victim; - pBoot->votedNeeded = GetVotesNeeded(gguid); + LfgPlayerBoot& boot = m_Boots[gguid]; + boot.inProgress = true; + boot.cancelTime = time_t(time(NULL)) + LFG_TIME_BOOT; + boot.reason = reason; + boot.victim = victim; - // Set votes + LfgGuidSet players; for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + if (Player* player = itr->getSource()) + players.insert(player->GetGUID()); + + // Set votes + for (LfgGuidSet::const_iterator itr = players.begin(); itr != players.end(); ++itr) { - if (Player* plrg = itr->getSource()) - { - uint64 guid = plrg->GetGUID(); - SetState(guid, LFG_STATE_BOOT); - if (guid == victim) - pBoot->votes[victim] = LFG_ANSWER_DENY; // Victim auto vote NO - else if (guid == kicker) - pBoot->votes[kicker] = LFG_ANSWER_AGREE; // Kicker auto vote YES - else - { - pBoot->votes[guid] = LFG_ANSWER_PENDING; // Other members need to vote - plrg->GetSession()->SendLfgBootPlayer(pBoot); - } - } + uint64 guid = (*itr); + SetState(guid, LFG_STATE_BOOT); + boot.votes[guid] = LFG_ANSWER_PENDING; } - m_Boots[grp->GetLowGUID()] = pBoot; + boot.votes[victim] = LFG_ANSWER_DENY; // Victim auto vote NO + boot.votes[kicker] = LFG_ANSWER_AGREE; // Kicker auto vote YES + + // Notify players + for (LfgGuidSet::const_iterator it = players.begin(); it != players.end(); ++it) + SendLfgBootProposalUpdate(*it, boot); } /** @@ -1714,25 +1840,23 @@ void LFGMgr::UpdateBoot(Player* player, bool accept) if (!grp) return; - uint32 bootId = grp->GetLowGUID(); + uint32 gguid = grp->GetLowGUID(); uint64 guid = player->GetGUID(); - LfgPlayerBootMap::iterator itBoot = m_Boots.find(bootId); + LfgPlayerBootMap::iterator itBoot = m_Boots.find(gguid); if (itBoot == m_Boots.end()) return; - LfgPlayerBoot* pBoot = itBoot->second; - if (!pBoot) - return; + LfgPlayerBoot& boot = itBoot->second; - if (pBoot->votes[guid] != LFG_ANSWER_PENDING) // Cheat check: Player can't vote twice + if (boot.votes[guid] != LFG_ANSWER_PENDING) // Cheat check: Player can't vote twice return; - pBoot->votes[guid] = LfgAnswer(accept); + boot.votes[guid] = LfgAnswer(accept); uint8 votesNum = 0; uint8 agreeNum = 0; - for (LfgAnswerMap::const_iterator itVotes = pBoot->votes.begin(); itVotes != pBoot->votes.end(); ++itVotes) + for (LfgAnswerMap::const_iterator itVotes = boot.votes.begin(); itVotes != boot.votes.end(); ++itVotes) { if (itVotes->second != LFG_ANSWER_PENDING) { @@ -1742,39 +1866,36 @@ void LFGMgr::UpdateBoot(Player* player, bool accept) } } - if (agreeNum == pBoot->votedNeeded || // Vote passed - votesNum == pBoot->votes.size() || // All voted but not passed - (pBoot->votes.size() - votesNum + agreeNum) < pBoot->votedNeeded) // Vote didnt passed + // 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) + return; + + // Send update info to all players + boot.inProgress = false; + for (LfgAnswerMap::const_iterator itVotes = boot.votes.begin(); itVotes != boot.votes.end(); ++itVotes) { - // Send update info to all players - pBoot->inProgress = false; - for (LfgAnswerMap::const_iterator itVotes = pBoot->votes.begin(); itVotes != pBoot->votes.end(); ++itVotes) + uint64 pguid = itVotes->first; + if (pguid != boot.victim) { - uint64 pguid = itVotes->first; - if (pguid != pBoot->victim) - { - SetState(pguid, LFG_STATE_DUNGEON); - if (Player* plrg = ObjectAccessor::FindPlayer(pguid)) - plrg->GetSession()->SendLfgBootPlayer(pBoot); - } + SetState(pguid, LFG_STATE_DUNGEON); + SendLfgBootProposalUpdate(pguid, boot); } + } - uint64 gguid = grp->GetGUID(); - SetState(gguid, LFG_STATE_DUNGEON); - if (agreeNum == pBoot->votedNeeded) // Vote passed - Kick player + gguid = grp->GetGUID(); + SetState(gguid, LFG_STATE_DUNGEON); + if (agreeNum == LFG_GROUP_KICK_VOTES_NEEDED) // Vote passed - Kick player + { + Player::RemoveFromGroup(grp, boot.victim); + if (Player* victim = ObjectAccessor::FindPlayer(boot.victim)) { - Player::RemoveFromGroup(grp, pBoot->victim); - if (Player* victim = ObjectAccessor::FindPlayer(pBoot->victim)) - { - TeleportPlayer(victim, true, false); - SetState(pBoot->victim, LFG_STATE_NONE); - } - OfferContinue(grp); - DecreaseKicksLeft(gguid); + TeleportPlayer(victim, true, false); + SetState(boot.victim, LFG_STATE_NONE); } - delete pBoot; - m_Boots.erase(itBoot); + OfferContinue(grp); + DecreaseKicksLeft(gguid); } + m_Boots.erase(itBoot); } /** @@ -1788,8 +1909,20 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* { sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::TeleportPlayer: [" UI64FMTD "] is being teleported %s", player->GetGUID(), out ? "out" : "in"); - LfgTeleportError error = LFG_TELEPORTERROR_OK; Group* grp = player->GetGroup(); + uint64 gguid = grp->GetGUID(); + LFGDungeonEntry const* dungeon = GetLFGDungeon(GetDungeon(gguid)); + if (!dungeon || (out && player->GetMapId() != uint32(dungeon->map))) + return; + + if (out) + { + player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); + player->TeleportToBGEntryPoint(); + return; + } + + LfgTeleportError error = LFG_TELEPORTERROR_OK; if (!grp || !grp->isLFGGroup()) // should never happen, but just in case... error = LFG_TELEPORTERROR_INVALID_LOCATION; @@ -1799,33 +1932,21 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* error = LFG_TELEPORTERROR_FALLING; else if (player->IsMirrorTimerActive(FATIGUE_TIMER)) error = LFG_TELEPORTERROR_FATIGUE; + else if (player->GetVehicle()) + error = LFG_TELEPORTERROR_IN_VEHICLE; + else if (player->GetCharmGUID()) + error = LFG_TELEPORTERROR_CHARMING; else { - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(grp->GetGUID())); - - if (out) - { - // Player needs to be inside the LFG dungeon to be able to teleport out - if (dungeon && player->GetMapId() == uint32(dungeon->map)) - { - player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); - player->TeleportToBGEntryPoint(); - } - else - player->GetSession()->SendLfgTeleportError(LFG_TELEPORTERROR_DONT_REPORT); // Not sure which error message to send - - return; - } - if (!dungeon) error = LFG_TELEPORTERROR_INVALID_LOCATION; else if (player->GetMapId() != uint32(dungeon->map)) // Do not teleport players in dungeon to the entrance { - uint32 mapid = 0; - float x = 0; - float y = 0; - float z = 0; - float orientation = 0; + uint32 mapid = dungeon->map; + float x = dungeon->x; + float y = dungeon->y; + float z = dungeon->z; + float orientation = dungeon->o; if (!fromOpcode) { @@ -1844,32 +1965,6 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* } } - if (!mapid) - { - LfgEntrancePositionMap::const_iterator itr = m_entrancePositions.find(dungeon->ID); - if (itr != m_entrancePositions.end()) - { - mapid = dungeon->map; - x = itr->second.GetPositionX(); - y = itr->second.GetPositionY(); - z = itr->second.GetPositionZ(); - orientation = itr->second.GetOrientation(); - } - else if (AreaTrigger const* at = sObjectMgr->GetMapEntranceTrigger(dungeon->map)) - { - mapid = at->target_mapId; - x = at->target_X; - y = at->target_Y; - z = at->target_Z; - orientation = at->target_Orientation; - } - else - { - sLog->outError(LOG_FILTER_LFG, "LfgMgr::TeleportPlayer: Failed to teleport [" UI64FMTD "]: No areatrigger found for map: %u difficulty: %u", player->GetGUID(), dungeon->map, dungeon->difficulty); - error = LFG_TELEPORTERROR_INVALID_LOCATION; - } - } - if (error == LFG_TELEPORTERROR_OK) { if (!player->GetMap()->IsDungeon()) @@ -1881,10 +1976,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* player->CleanupAfterTaxiFlight(); } - if (player->TeleportTo(mapid, x, y, z, orientation)) - // FIXME - HACK - this should be done by teleport, when teleporting far - player->RemoveAurasByType(SPELL_AURA_MOUNTED); - else + if (!player->TeleportTo(mapid, x, y, z, orientation)) { error = LFG_TELEPORTERROR_INVALID_LOCATION; sLog->outError(LOG_FILTER_LFG, "LfgMgr::TeleportPlayer: Failed to teleport [" UI64FMTD "] to map %u: ", player->GetGUID(), mapid); @@ -1932,12 +2024,12 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) // Clear player related lfg stuff uint32 rDungeonId = (*GetSelectedDungeons(guid).begin()); - ClearState(guid); + ClearState(guid, "Dungeon Finished"); SetState(guid, LFG_STATE_FINISHED_DUNGEON); // Give rewards only if its a random or seasonal dungeon - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(rDungeonId); - if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !(dungeon->flags & LFG_FLAG_SEASONAL))) + LFGDungeonEntry const* dungeon = GetLFGDungeon(rDungeonId); + if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal)) { sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] dungeon %u is not random nor seasonal", guid, rDungeonId); return; @@ -1986,9 +2078,9 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) */ const LfgDungeonSet& LFGMgr::GetDungeonsByRandom(uint32 randomdungeon) { - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(randomdungeon); - uint32 groupType = dungeon ? dungeon->grouptype : 0; - return m_CachedDungeonMap[groupType]; + LFGDungeonEntry const* dungeon = GetLFGDungeon(randomdungeon); + uint32 group = dungeon ? dungeon->group : 0; + return m_CachedDungeonMap[group]; } /** @@ -2021,7 +2113,7 @@ LfgReward const* LFGMgr::GetRandomDungeonReward(uint32 dungeon, uint8 level) */ LfgType LFGMgr::GetDungeonType(uint32 dungeonId) { - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId); + LFGDungeonEntry const* dungeon = GetLFGDungeon(dungeonId); if (!dungeon) return LFG_TYPE_NONE; @@ -2047,31 +2139,6 @@ std::string LFGMgr::ConcatenateGuids(LfgGuidList check) return o.str(); } -HolidayIds LFGMgr::GetDungeonSeason(uint32 dungeonId) -{ - HolidayIds holiday = HOLIDAY_NONE; - - switch (dungeonId) - { - case 285: - holiday = HOLIDAY_HALLOWS_END; - break; - case 286: - holiday = HOLIDAY_FIRE_FESTIVAL; - break; - case 287: - holiday = HOLIDAY_BREWFEST; - break; - case 288: - holiday = HOLIDAY_LOVE_IS_IN_THE_AIR; - break; - default: - break; - } - - return holiday; -} - LfgState LFGMgr::GetState(uint64 guid) { sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::GetState: [" UI64FMTD "]", guid); @@ -2123,35 +2190,45 @@ const LfgLockMap& LFGMgr::GetLockedDungeons(uint64 guid) uint8 LFGMgr::GetKicksLeft(uint64 guid) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::GetKicksLeft: [" UI64FMTD "]", guid); - return m_Groups[guid].GetKicksLeft(); + uint8 kicks = m_Groups[guid].GetKicksLeft(); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::GetKicksLeft: [" UI64FMTD "] = %u", guid, kicks); + return kicks; } -uint8 LFGMgr::GetVotesNeeded(uint64 guid) +void LFGMgr::RestoreState(uint64 guid, char const *debugMsg) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::GetVotesNeeded: [" UI64FMTD "]", guid); - return m_Groups[guid].GetVotesNeeded(); + LfgGroupData& data = m_Groups[guid]; + char const * const ps = GetStateString(data.GetState()); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RestoreState: Group: [" UI64FMTD "] (%s), State: %s", guid, debugMsg, ps); + data.RestoreState(); } -void LFGMgr::RestoreState(uint64 guid) +void LFGMgr::ClearState(uint64 guid, char const *debugMsg) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RestoreState: [" UI64FMTD "]", guid); - m_Groups[guid].RestoreState(); -} - -void LFGMgr::ClearState(uint64 guid) -{ - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::ClearState: [" UI64FMTD "]", guid); - m_Players[guid].ClearState(); + LfgPlayerData& data = m_Players[guid]; + char const * const ps = GetStateString(data.GetState()); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::ClearState: Player: [" UI64FMTD "] (%s) State: %s", guid, debugMsg, ps); + data.ClearState(); } void LFGMgr::SetState(uint64 guid, LfgState state) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::SetState: [" UI64FMTD "] state %u", guid, state); if (IS_GROUP(guid)) - m_Groups[guid].SetState(state); + { + LfgGroupData& data = m_Groups[guid]; + char const * const ns = GetStateString(state); + char const * const ps = GetStateString(data.GetState()); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::SetState: Group: [" UI64FMTD "] newState: %s, previous: %s", guid, ns, ps); + data.SetState(state); + } else - m_Players[guid].SetState(state); + { + LfgPlayerData& data = m_Players[guid]; + char const * const ns = GetStateString(state); + char const * const ps = GetStateString(data.GetState()); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::SetState: Player: [" UI64FMTD "] newState: %s, previous: %s", guid, ns, ps); + data.SetState(state); + } } void LFGMgr::SetDungeon(uint64 guid, uint32 dungeon) @@ -2205,3 +2282,81 @@ void LFGMgr::RemoveGroupData(uint64 guid) if (it != m_Groups.end()) m_Groups.erase(it); } + +bool LFGMgr::HasIgnore(uint64 guid1, uint64 guid2) +{ + Player* plr1 = ObjectAccessor::FindPlayer(guid1); + Player* plr2 = ObjectAccessor::FindPlayer(guid2); + uint32 low1 = GUID_LOPART(guid1); + uint32 low2 = GUID_LOPART(guid2); + return plr1 && plr2 && (plr1->GetSocial()->HasIgnore(low2) || plr2->GetSocial()->HasIgnore(low1)); +} + +void LFGMgr::SendLfgRoleChosen(uint64 guid, uint64 pguid, uint8 roles) +{ + if (Player* player = ObjectAccessor::FindPlayer(guid)) + player->GetSession()->SendLfgRoleChosen(pguid, roles); +} + +void LFGMgr::SendLfgRoleCheckUpdate(uint64 guid, const LfgRoleCheck& roleCheck) +{ + if (Player* player = ObjectAccessor::FindPlayer(guid)) + player->GetSession()->SendLfgRoleCheckUpdate(roleCheck); +} + +void LFGMgr::SendLfgUpdatePlayer(uint64 guid, const LfgUpdateData& data) +{ + if (Player* player = ObjectAccessor::FindPlayer(guid)) + player->GetSession()->SendLfgUpdatePlayer(data); +} + +void LFGMgr::SendLfgUpdateParty(uint64 guid, const LfgUpdateData& data) +{ + if (Player* player = ObjectAccessor::FindPlayer(guid)) + player->GetSession()->SendLfgUpdateParty(data); +} + +void LFGMgr::SendLfgJoinResult(uint64 guid, const LfgJoinResultData& data) +{ + if (Player* player = ObjectAccessor::FindPlayer(guid)) + player->GetSession()->SendLfgJoinResult(data); +} + +void LFGMgr::SendLfgBootProposalUpdate(uint64 guid, const LfgPlayerBoot& boot) +{ + if (Player* player = ObjectAccessor::FindPlayer(guid)) + player->GetSession()->SendLfgBootProposalUpdate(boot); +} + +void LFGMgr::SendLfgUpdateProposal(uint64 guid, uint32 proposalId, const LfgProposal& proposal) +{ + if (Player* player = ObjectAccessor::FindPlayer(guid)) + player->GetSession()->SendLfgUpdateProposal(proposalId, proposal); +} + +void LFGMgr::SendLfgQueueStatus(uint64 guid, const LfgQueueStatusData& data) +{ + if (Player* player = ObjectAccessor::FindPlayer(guid)) + player->GetSession()->SendLfgQueueStatus(data); +} + +bool LFGMgr::IsLfgGroup(uint64 guid) +{ + return guid && IS_GROUP(guid) && m_Groups[guid].IsLfgGroup(); +} + +bool LFGMgr::IsSeasonActive(uint32 dungeonId) +{ + switch (dungeonId) + { + case 285: // The Headless Horseman + return IsHolidayActive(HOLIDAY_HALLOWS_END); + case 286: // The Frost Lord Ahune + return IsHolidayActive(HOLIDAY_FIRE_FESTIVAL); + case 287: // Coren Direbrew + return IsHolidayActive(HOLIDAY_BREWFEST); + case 288: // The Crown Chemical Co. + return IsHolidayActive(HOLIDAY_LOVE_IS_IN_THE_AIR); + } + return false; +} diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 9937759741b..d4d35974604 100755 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -21,24 +21,24 @@ #include "Common.h" #include <ace/Singleton.h> #include "LFG.h" +#include "LFGGroupData.h" +#include "LFGPlayerData.h" -class LfgGroupData; -class LfgPlayerData; +class LFGPlayerScript; +class LFGGroupScript; class Group; class Player; -enum LFGenum +enum LFGMgrEnum { - LFG_TIME_ROLECHECK = 40*IN_MILLISECONDS, - LFG_TIME_BOOT = 2*MINUTE, - LFG_TIME_PROPOSAL = 2*MINUTE, - LFG_TANKS_NEEDED = 1, - LFG_HEALERS_NEEDED = 1, - LFG_DPS_NEEDED = 3, - LFG_QUEUEUPDATE_INTERVAL = 15*IN_MILLISECONDS, + LFG_TIME_ROLECHECK = 40 * IN_MILLISECONDS, + LFG_TIME_BOOT = 120, + LFG_TIME_PROPOSAL = 120, + LFG_QUEUEUPDATE_INTERVAL = 15 * IN_MILLISECONDS, LFG_SPELL_DUNGEON_COOLDOWN = 71328, LFG_SPELL_DUNGEON_DESERTER = 71041, - LFG_SPELL_LUCK_OF_THE_DRAW = 72221 + LFG_SPELL_LUCK_OF_THE_DRAW = 72221, + LFG_GROUP_KICK_VOTES_NEEDED = 3 }; enum LfgFlags @@ -52,11 +52,9 @@ enum LfgFlags /// Determines the type of instance enum LfgType { - LFG_TYPE_NONE = 0, // Internal use only + LFG_TYPE_NONE = 0, LFG_TYPE_DUNGEON = 1, LFG_TYPE_RAID = 2, - LFG_TYPE_QUEST = 3, - LFG_TYPE_ZONE = 4, LFG_TYPE_HEROIC = 5, LFG_TYPE_RANDOM = 6 }; @@ -72,13 +70,14 @@ enum LfgProposalState /// Teleport errors enum LfgTeleportError { - // 3, 7, 8 = "You can't do that right now" | 5 = No client reaction + // 7 = "You can't do that right now" | 5 = No client reaction LFG_TELEPORTERROR_OK = 0, // Internal use LFG_TELEPORTERROR_PLAYER_DEAD = 1, LFG_TELEPORTERROR_FALLING = 2, - LFG_TELEPORTERROR_DONT_REPORT = 3, + LFG_TELEPORTERROR_IN_VEHICLE = 3, LFG_TELEPORTERROR_FATIGUE = 4, - LFG_TELEPORTERROR_INVALID_LOCATION = 6 + LFG_TELEPORTERROR_INVALID_LOCATION = 6, + LFG_TELEPORTERROR_CHARMING = 8 // FIXME - It can be 7 or 8 (Need proper data) }; /// Queue join results @@ -116,42 +115,31 @@ enum LfgRoleCheckState LFG_ROLECHECK_NO_ROLE = 6 // Someone selected no role }; -/// Answer state (Also used to check compatibilites) -enum LfgAnswer -{ - LFG_ANSWER_PENDING = -1, - LFG_ANSWER_DENY = 0, - LFG_ANSWER_AGREE = 1 -}; - // Forward declaration (just to have all typedef together) +struct LFGDungeonEntry; struct LfgReward; -struct LfgLockStatus; struct LfgQueueInfo; struct LfgRoleCheck; struct LfgProposal; struct LfgProposalPlayer; struct LfgPlayerBoot; -typedef std::set<uint64> LfgGuidSet; -typedef std::list<uint64> LfgGuidList; typedef std::map<uint8, LfgGuidList> LfgGuidListMap; typedef std::set<Player*> PlayerSet; typedef std::list<Player*> LfgPlayerList; typedef std::multimap<uint32, LfgReward const*> LfgRewardMap; typedef std::pair<LfgRewardMap::const_iterator, LfgRewardMap::const_iterator> LfgRewardMapBounds; typedef std::map<std::string, LfgAnswer> LfgCompatibleMap; -typedef std::map<uint64, LfgDungeonSet> LfgDungeonMap; -typedef std::map<uint64, uint8> LfgRolesMap; +typedef std::map<uint8, LfgDungeonSet> LfgCachedDungeonMap; typedef std::map<uint64, LfgAnswer> LfgAnswerMap; -typedef std::map<uint64, LfgRoleCheck*> LfgRoleCheckMap; +typedef std::map<uint64, LfgRoleCheck> LfgRoleCheckMap; typedef std::map<uint64, LfgQueueInfo*> LfgQueueInfoMap; typedef std::map<uint32, LfgProposal*> LfgProposalMap; typedef std::map<uint64, LfgProposalPlayer*> LfgProposalPlayerMap; -typedef std::map<uint32, LfgPlayerBoot*> LfgPlayerBootMap; +typedef std::map<uint64, LfgPlayerBoot> LfgPlayerBootMap; typedef std::map<uint64, LfgGroupData> LfgGroupDataMap; typedef std::map<uint64, LfgPlayerData> LfgPlayerDataMap; -typedef std::map<uint32, Position> LfgEntrancePositionMap; +typedef UNORDERED_MAP<uint32, LFGDungeonEntry> LFGDungeonMap; // Data needed by SMSG_LFG_JOIN_RESULT struct LfgJoinResultData @@ -167,7 +155,7 @@ struct LfgJoinResultData struct LfgUpdateData { LfgUpdateData(LfgUpdateType _type = LFG_UPDATETYPE_DEFAULT): updateType(_type), comment("") {} - LfgUpdateData(LfgUpdateType _type, const LfgDungeonSet& _dungeons, std::string _comment): + LfgUpdateData(LfgUpdateType _type, LfgDungeonSet const& _dungeons, std::string _comment): updateType(_type), dungeons(_dungeons), comment(_comment) {} LfgUpdateType updateType; @@ -175,6 +163,26 @@ struct LfgUpdateData std::string comment; }; +// Data needed by SMSG_LFG_QUEUE_STATUS +struct LfgQueueStatusData +{ + LfgQueueStatusData(uint32 _dungeonId = 0, int32 _waitTime = -1, int32 _waitTimeAvg = -1, int32 _waitTimeTank = -1, int32 _waitTimeHealer = -1, + int32 _waitTimeDps = -1, uint32 _queuedTime = 0, uint8 _tanks = 0, uint8 _healers = 0, uint8 _dps = 0) : + dungeonId(_dungeonId), waitTime(_waitTime), waitTimeAvg(_waitTimeAvg), waitTimeTank(_waitTimeTank), waitTimeHealer(_waitTimeHealer), + waitTimeDps(_waitTimeDps), queuedTime(_queuedTime), tanks(_tanks), healers(_healers), dps(_dps) {} + + uint32 dungeonId; + int32 waitTime; + int32 waitTimeAvg; + int32 waitTimeTank; + int32 waitTimeHealer; + int32 waitTimeDps; + uint32 queuedTime; + uint8 tanks; + uint8 healers; + uint8 dps; +}; + /// Reward info struct LfgReward { @@ -236,7 +244,6 @@ struct LfgProposal time_t cancelTime; ///< Time when we will cancel this proposal LfgGuidList queues; ///< Queue Ids to remove/readd LfgProposalPlayerMap players; ///< Players data - }; /// Stores all rolecheck info of a group that wants to join @@ -261,6 +268,33 @@ struct LfgPlayerBoot std::string reason; ///< kick reason }; +struct LFGDungeonEntry +{ + LFGDungeonEntry(): 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) + { } + LFGDungeonEntry(LFGDungeonEntryDbc const* dbc): id(dbc->ID), name(dbc->name[0]), 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), x(0.0f), y(0.0f), z(0.0f), o(0.0f) + { } + + uint32 id; + std::string name; + uint16 map; + uint8 type; + uint8 expansion; + uint8 group; + uint8 minlevel; + uint8 maxlevel; + Difficulty difficulty; + bool seasonal; + float x, y, z, o; + + // Helpers + uint32 Entry() const { return id + (type << 24); } +}; + class LFGMgr { friend class ACE_Singleton<LFGMgr, ACE_Null_Mutex>; @@ -274,57 +308,70 @@ class LFGMgr // Reward void LoadRewards(); - void RewardDungeonDoneFor(const uint32 dungeonId, Player* player); + void RewardDungeonDoneFor(uint32 const dungeonId, Player* player); LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); // Queue - void Join(Player* player, uint8 roles, const LfgDungeonSet& dungeons, const std::string& comment); - void Leave(Player* player, Group* grp = NULL); + void JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, std::string const& comment); + void LeaveLfg(Player* player, Group* grp = NULL); // Role Check - void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = ROLE_NONE); + void UpdateRoleCheck(uint64 gguid, uint64 guid = 0, uint8 roles = PLAYER_ROLE_NONE); // Proposals void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); // Teleportation - void LoadEntrancePositions(); void TeleportPlayer(Player* player, bool out, bool fromOpcode = false); // Vote kick - void InitBoot(Group* grp, uint64 kguid, uint64 vguid, std::string reason); + void InitBoot(Group* grp, uint64 kguid, uint64 vguid, std::string const& reason); void UpdateBoot(Player* player, bool accept); void OfferContinue(Group* grp); - HolidayIds GetDungeonSeason(uint32 dungeonId); + void InitializeLockedDungeons(Player* player, uint8 level = 0); - void InitializeLockedDungeons(Player* player); + void SetRoles(uint64 guid, uint8 roles); + void SetComment(uint64 guid, std::string const& comment); + void SetState(uint64 guid, LfgState state); + void SetSelectedDungeons(uint64 guid, LfgDungeonSet const& dungeons); void _LoadFromDB(Field* fields, uint64 guid); void _SaveToDB(uint64 guid, uint32 db_guid); - void SetComment(uint64 guid, const std::string& comment); - const LfgLockMap& GetLockedDungeons(uint64 guid); - LfgState GetState(uint64 guid); - const LfgDungeonSet& GetSelectedDungeons(uint64 guid); - uint32 GetDungeon(uint64 guid, bool asId = true); - void SetState(uint64 guid, LfgState state); - void ClearState(uint64 guid); void RemovePlayerData(uint64 guid); void RemoveGroupData(uint64 guid); + + LfgLockMap const& GetLockedDungeons(uint64 guid); + LfgDungeonSet const& GetSelectedDungeons(uint64 guid); + uint32 GetDungeon(uint64 guid, bool asId = true); + LfgState GetState(uint64 guid); uint8 GetKicksLeft(uint64 gguid); - uint8 GetVotesNeeded(uint64 gguid); - bool IsTeleported(uint64 pguid); - void SetRoles(uint64 guid, uint8 roles); - void SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons); + bool IsLfgGroup(uint64 guid); + uint8 GetRoles(uint64 guid); + std::string const& GetComment(uint64 gguid); + bool IsTeleported(uint64 guid); + + static bool HasIgnore(uint64 guid1, uint64 guid2); + static void SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data); + bool IsSeasonActive(uint32 dungeonId); + + static std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); + static std::string GetRolesString(uint8 roles); + static char const * GetStateString(LfgState state); + + void LoadLFGDungeons(bool reload = false); + LFGDungeonEntry const* GetLFGDungeon(uint32 id); + LFGDungeonMap& GetLFGDungeonMap(); + + void ClearState(uint64 guid, char const *debugMsg); private: - uint8 GetRoles(uint64 guid); - const std::string& GetComment(uint64 gguid); - void RestoreState(uint64 guid); + void RestoreState(uint64 guid, char const *debugMsg); + void SetDungeon(uint64 guid, uint32 dungeon); - void SetLockedDungeons(uint64 guid, const LfgLockMap& lock); + void SetLockedDungeons(uint64 guid, LfgLockMap const& lock); void DecreaseKicksLeft(uint64 guid); // Queue @@ -338,20 +385,29 @@ class LFGMgr LfgProposal* FindNewGroups(LfgGuidList& check, LfgGuidList& all); bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); bool CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal); - void GetCompatibleDungeons(LfgDungeonSet& dungeons, const PlayerSet& players, LfgLockPartyMap& lockMap); + void GetCompatibleDungeons(LfgDungeonSet& dungeons, PlayerSet const& players, LfgLockPartyMap& lockMap); void SetCompatibles(std::string concatenatedGuids, bool compatibles); LfgAnswer GetCompatibles(std::string concatenatedGuids); void RemoveFromCompatibles(uint64 guid); // Generic - const LfgDungeonSet& GetDungeonsByRandom(uint32 randomdungeon); + LfgDungeonSet const& GetDungeonsByRandom(uint32 randomdungeon); LfgType GetDungeonType(uint32 dungeon); std::string ConcatenateGuids(LfgGuidList check); + void SendLfgBootProposalUpdate(uint64 guid, LfgPlayerBoot const& boot); + void SendLfgJoinResult(uint64 guid, LfgJoinResultData const& data); + void SendLfgRoleChosen(uint64 guid, uint64 pguid, uint8 roles); + void SendLfgRoleCheckUpdate(uint64 guid, LfgRoleCheck const& roleCheck); + void SendLfgUpdateParty(uint64 guid, LfgUpdateData const& data); + void SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data); + void SendLfgUpdateProposal(uint64 guid, uint32 proposalId, LfgProposal const& proposal); + // General variables - bool m_update; ///< Doing an update? uint32 m_QueueTimer; ///< used to check interval of update uint32 m_lfgProposalId; ///< used as internal counter for proposals + uint32 m_options; ///< Stores config options + int32 m_WaitTimeAvg; ///< Average wait time to find a group queuing as multiple roles int32 m_WaitTimeTank; ///< Average wait time to find a group queuing as tank int32 m_WaitTimeHealer; ///< Average wait time to find a group queuing as healer @@ -360,10 +416,10 @@ class LFGMgr uint32 m_NumWaitTimeTank; ///< Num of players used to calc tank wait time uint32 m_NumWaitTimeHealer; ///< Num of players used to calc healers wait time uint32 m_NumWaitTimeDps; ///< Num of players used to calc dps wait time - LfgDungeonMap m_CachedDungeonMap; ///< Stores all dungeons by groupType - LfgEntrancePositionMap m_entrancePositions; ///< Stores special entrance positions + LfgCachedDungeonMap m_CachedDungeonMap; ///< Stores all dungeons by groupType // Reward System LfgRewardMap m_RewardMap; ///< Stores rewards for random dungeons + LFGDungeonMap m_LfgDungeonMap; // Queue LfgQueueInfoMap m_QueueInfoMap; ///< Queued groups LfgGuidListMap m_currentQueue; ///< Ordered list. Used to find groups @@ -376,6 +432,9 @@ class LFGMgr LfgPlayerBootMap m_Boots; ///< Current player kicks LfgPlayerDataMap m_Players; ///< Player data LfgGroupDataMap m_Groups; ///< Group data + + LFGPlayerScript *m_lfgPlayerScript; + LFGGroupScript *m_lfgGroupScript; }; #define sLFGMgr ACE_Singleton<LFGMgr, ACE_Null_Mutex>::instance() diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 36f04b3020b..26686dbaa33 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -39,12 +39,12 @@ void LFGPlayerScript::OnLevelChanged(Player* player, uint8 /*oldLevel*/) void LFGPlayerScript::OnLogout(Player* player) { - sLFGMgr->Leave(player); + uint64 guid = player->GetGUID(); + sLFGMgr->LeaveLfg(player); LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE); player->GetSession()->SendLfgUpdateParty(updateData); player->GetSession()->SendLfgUpdatePlayer(updateData); - player->GetSession()->SendLfgUpdateSearch(false); - uint64 guid = player->GetGUID(); + player->GetSession()->SendLfgLfrList(false); // TODO - Do not remove, add timer before deleting sLFGMgr->RemovePlayerData(guid); } @@ -85,11 +85,11 @@ void LFGGroupScript::OnAddMember(Group* group, uint64 guid) // TODO - if group is queued and new player is added convert to rolecheck without notify the current players queued if (sLFGMgr->GetState(gguid) == LFG_STATE_QUEUED) - sLFGMgr->Leave(NULL, group); + sLFGMgr->LeaveLfg(NULL, group); if (sLFGMgr->GetState(guid) == LFG_STATE_QUEUED) if (Player* player = ObjectAccessor::FindPlayer(guid)) - sLFGMgr->Leave(player); + sLFGMgr->LeaveLfg(player); } void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, char const* reason) @@ -102,7 +102,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth if (sLFGMgr->GetState(gguid) == LFG_STATE_QUEUED) { // TODO - Do not remove, just remove the one leaving and rejoin queue with all other data - sLFGMgr->Leave(NULL, group); + sLFGMgr->LeaveLfg(NULL, group); } if (!group->isLFGGroup()) @@ -119,16 +119,14 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth } uint32 state = sLFGMgr->GetState(gguid); - sLFGMgr->ClearState(guid); + sLFGMgr->ClearState(guid, "OnRemoveMember"); sLFGMgr->SetState(guid, LFG_STATE_NONE); if (Player* player = ObjectAccessor::FindPlayer(guid)) { if (method == GROUP_REMOVEMETHOD_LEAVE && sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON && sLFGMgr->GetDungeon(gguid, false)) player->CastSpell(player, LFG_SPELL_DUNGEON_DESERTER, true); - /* - else if (group->isLfgKickActive()) + //else if (state == LFG_STATE_BOOT) // Update internal kick cooldown of kicked - */ LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_LEADER); player->GetSession()->SendLfgUpdateParty(updateData); @@ -176,5 +174,5 @@ void LFGGroupScript::OnInviteMember(Group* group, uint64 guid) return; sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnInviteMember [" UI64FMTD "]: invite [" UI64FMTD "] leader [" UI64FMTD "]", gguid, guid, group->GetLeaderGUID()); - sLFGMgr->Leave(NULL, group); + sLFGMgr->LeaveLfg(NULL, group); } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 161fdc2be1d..93a0580a866 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11901,7 +11901,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje bool lootedObjectInDungeon = false; Map const* map = lootedObject->GetMap(); if (uint32 dungeonId = sLFGMgr->GetDungeon(GetGroup()->GetGUID(), true)) - if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) + if (LFGDungeonEntry const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == uint32(map->GetDifficulty())) lootedObjectInDungeon = true; @@ -23261,7 +23261,7 @@ PartyResult Player::CanUninviteFromGroup() const if (state == LFG_STATE_BOOT) return ERR_PARTY_LFG_BOOT_IN_PROGRESS; - if (grp->GetMembersCount() <= sLFGMgr->GetVotesNeeded(gguid)) + if (grp->GetMembersCount() <= LFG_GROUP_KICK_VOTES_NEEDED) return ERR_PARTY_LFG_BOOT_TOO_FEW_PLAYERS; if (state == LFG_STATE_FINISHED_DUNGEON) @@ -23294,8 +23294,22 @@ PartyResult Player::CanUninviteFromGroup() const bool Player::isUsingLfg() { - uint64 guid = GetGUID(); - return sLFGMgr->GetState(guid) != LFG_STATE_NONE; + return sLFGMgr->GetState(GetGUID()) != LFG_STATE_NONE; +} + +bool Player::inRandomLfgDungeon() +{ + if (isUsingLfg()) + { + const LfgDungeonSet& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID()); + if (!dungeons.empty()) + { + LFGDungeonEntry const* dungeon = sLFGMgr->GetLFGDungeon(*dungeons.begin()); + if (dungeon && (dungeon->type == LFG_TYPE_RANDOM || dungeon->seasonal)) + return true; + } + } + return false; } void Player::SetBattlegroundOrBattlefieldRaid(Group* group, int8 subgroup) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index c417c73cdbc..9d80a17bc5e 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2356,6 +2356,7 @@ class Player : public Unit, public GridObject<Player> void RemoveAtLoginFlag(AtLoginFlags flags, bool persist = false); bool isUsingLfg(); + bool inRandomLfgDungeon(); typedef std::set<uint32> DFQuestsDoneList; DFQuestsDoneList m_DFQuests; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index b884a369eeb..17982a58061 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -45,6 +45,7 @@ #include "ScriptMgr.h" #include "SpellScript.h" #include "PoolMgr.h" +#include "LFGMgr.h" ScriptMapMap sQuestEndScripts; ScriptMapMap sQuestStartScripts; @@ -5028,7 +5029,7 @@ void ObjectMgr::LoadInstanceEncounters() continue; } - if (lastEncounterDungeon && !sLFGDungeonStore.LookupEntry(lastEncounterDungeon)) + if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeon(lastEncounterDungeon)) { sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon); continue; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 19ea3ff8174..f06225988d6 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -600,7 +600,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV if (isLFGGroup() && GetMembersCount() == 1) { Player* Leader = ObjectAccessor::FindPlayer(GetLeaderGUID()); - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(sLFGMgr->GetDungeon(GetGUID())); + LFGDungeonEntry const* dungeon = sLFGMgr->GetLFGDungeon(sLFGMgr->GetDungeon(GetGUID())); if ((Leader && dungeon && Leader->isAlive() && Leader->GetMapId() != uint32(dungeon->map)) || !dungeon) { Disband(); diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index f5d5a0b67e2..59631618757 100755 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -23,7 +23,6 @@ #include "LFGMgr.h" #include "ObjectMgr.h" #include "GroupMgr.h" -#include "GameEventMgr.h" #include "InstanceScript.h" void BuildPlayerLockDungeonBlock(WorldPacket& data, const LfgLockMap& lock) @@ -82,18 +81,19 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recv_data) std::string comment; recv_data >> comment; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_JOIN [" UI64FMTD "] roles: %u, Dungeons: %u, Comment: %s", GetPlayer()->GetGUID(), roles, uint8(newDungeons.size()), comment.c_str()); - sLFGMgr->Join(GetPlayer(), uint8(roles), newDungeons, comment); + sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment); } void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recv_data*/) { Group* grp = GetPlayer()->GetGroup(); + uint64 guid = GetPlayer()->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LEAVE [" UI64FMTD "] in group: %u", GetPlayer()->GetGUID(), grp ? 1 : 0); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LEAVE [" UI64FMTD "] in group: %u", guid, grp ? 1 : 0); // Check cheating - only leader can leave the queue if (!grp || grp->GetLeaderGUID() == GetPlayer()->GetGUID()) - sLFGMgr->Leave(GetPlayer(), grp); + sLFGMgr->LeaveLfg(GetPlayer(), grp); } void WorldSession::HandleLfgProposalResultOpcode(WorldPacket& recv_data) @@ -128,7 +128,7 @@ void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recv_data) std::string comment; recv_data >> comment; uint64 guid = GetPlayer()->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_LFG_COMMENT [" UI64FMTD "] comment: %s", guid, comment.c_str()); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_COMMENT [" UI64FMTD "] comment: %s", guid, comment.c_str()); sLFGMgr->SetComment(guid, comment); } @@ -138,7 +138,8 @@ void WorldSession::HandleLfgSetBootVoteOpcode(WorldPacket& recv_data) bool agree; // Agree to kick player recv_data >> agree; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_BOOT_VOTE [" UI64FMTD "] agree: %u", GetPlayer()->GetGUID(), agree ? 1 : 0); + uint64 guid = GetPlayer()->GetGUID(); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_BOOT_VOTE [" UI64FMTD "] agree: %u", guid, agree ? 1 : 0); sLFGMgr->UpdateBoot(GetPlayer(), agree); } @@ -154,32 +155,24 @@ void WorldSession::HandleLfgTeleportOpcode(WorldPacket& recv_data) void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data*/) { uint64 guid = GetPlayer()->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); // Get Random dungeons that can be done at a certain level and expansion LfgDungeonSet randomDungeons; uint8 level = GetPlayer()->getLevel(); uint8 expansion = GetPlayer()->GetSession()->Expansion(); - for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i) - { - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i); - if (dungeon && dungeon->expansion <= expansion && dungeon->minlevel <= level && level <= dungeon->maxlevel) - { - if (dungeon->flags & LFG_FLAG_SEASONAL) - { - if (HolidayIds holiday = sLFGMgr->GetDungeonSeason(dungeon->ID)) - if (!IsHolidayActive(holiday)) - continue; - } - else if (dungeon->type != LFG_TYPE_RANDOM) - continue; - randomDungeons.insert(dungeon->Entry()); - } + LFGDungeonMap& LfgDungeons = sLFGMgr->GetLFGDungeonMap(); + for (LFGDungeonMap::const_iterator itr = LfgDungeons.begin(); itr != LfgDungeons.end(); ++itr) + { + LFGDungeonEntry const& dungeon = itr->second; + if ((dungeon.type == LFG_TYPE_RANDOM || (dungeon.seasonal && sLFGMgr->IsSeasonActive(dungeon.id))) + && dungeon.expansion <= expansion && dungeon.minlevel <= level && level <= dungeon.maxlevel) + randomDungeons.insert(dungeon.Entry()); } // Get player locked Dungeons - LfgLockMap lock = sLFGMgr->GetLockedDungeons(guid); + LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid); uint32 rsize = uint32(randomDungeons.size()); uint32 lsize = uint32(lock.size()); @@ -191,40 +184,37 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data { data << uint32(*it); // Dungeon Entry (id + type) LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); - Quest const* qRew = NULL; + Quest const* quest = NULL; uint8 done = 0; if (reward) { - qRew = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); - if (qRew) + quest = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); + if (quest) { - done = !GetPlayer()->CanRewardQuest(qRew, false); + done = !GetPlayer()->CanRewardQuest(quest, false); if (done) - qRew = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); + quest = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); } } - if (qRew) + + if (quest) { data << uint8(done); - data << uint32(qRew->GetRewOrReqMoney()); - data << uint32(qRew->XPValue(GetPlayer())); + data << uint32(quest->GetRewOrReqMoney()); + data << uint32(quest->XPValue(GetPlayer())); data << uint32(reward->reward[done].variableMoney); data << uint32(reward->reward[done].variableXP); - data << uint8(qRew->GetRewItemsCount()); - if (qRew->GetRewItemsCount()) + data << uint8(quest->GetRewItemsCount()); + if (quest->GetRewItemsCount()) { - ItemTemplate const* iProto = NULL; for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) - { - if (!qRew->RewardItemId[i]) - continue; - - iProto = sObjectMgr->GetItemTemplate(qRew->RewardItemId[i]); - - data << uint32(qRew->RewardItemId[i]); - data << uint32(iProto ? iProto->DisplayInfoID : 0); - data << uint32(qRew->RewardItemIdCount[i]); - } + if (uint32 itemId = quest->RewardItemId[i]) + { + ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId); + data << uint32(itemId); + data << uint32(item ? item->DisplayInfoID : 0); + data << uint32(quest->RewardItemIdCount[i]); + } } } else @@ -244,7 +234,7 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data*/) { uint64 guid = GetPlayer()->GetGUID(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PARTY_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_PARTY_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); Group* grp = GetPlayer()->GetGroup(); if (!grp) @@ -275,11 +265,11 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data SendPacket(&data); } -void WorldSession::HandleLfrSearchOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfrJoinOpcode(WorldPacket& recv_data) { uint32 entry; // Raid id to search recv_data >> entry; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SEARCH_LFG_JOIN [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), entry); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LFR_JOIN [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), entry); //SendLfrUpdateListOpcode(entry); } @@ -287,7 +277,7 @@ void WorldSession::HandleLfrLeaveOpcode(WorldPacket& recv_data) { uint32 dungeonId; // Raid id queue to leave recv_data >> dungeonId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SEARCH_LFG_LEAVE [" UI64FMTD "] dungeonId: %u", GetPlayer()->GetGUID(), dungeonId); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_LFR_LEAVE [" UI64FMTD "] dungeonId: %u", GetPlayer()->GetGUID(), dungeonId); //sLFGMgr->LeaveLfr(GetPlayer(), dungeonId); } @@ -397,45 +387,44 @@ void WorldSession::SendLfgRoleChosen(uint64 guid, uint8 roles) SendPacket(&data); } -void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck* pRoleCheck) +void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) { - ASSERT(pRoleCheck); LfgDungeonSet dungeons; - if (pRoleCheck->rDungeonId) - dungeons.insert(pRoleCheck->rDungeonId); + if (roleCheck.rDungeonId) + dungeons.insert(roleCheck.rDungeonId); else - dungeons = pRoleCheck->dungeons; + dungeons = roleCheck.dungeons; sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_ROLE_CHECK_UPDATE [" UI64FMTD "]", GetPlayer()->GetGUID()); - WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + pRoleCheck->roles.size() * (8 + 1 + 4 + 1)); + WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1)); - data << uint32(pRoleCheck->state); // Check result - data << uint8(pRoleCheck->state == LFG_ROLECHECK_INITIALITING); + data << uint32(roleCheck.state); // Check result + data << uint8(roleCheck.state == LFG_ROLECHECK_INITIALITING); data << uint8(dungeons.size()); // Number of dungeons if (!dungeons.empty()) { for (LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it) { - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(*it); + LFGDungeonEntry const* dungeon = sLFGMgr->GetLFGDungeon(*it); data << uint32(dungeon ? dungeon->Entry() : 0); // Dungeon } } - data << uint8(pRoleCheck->roles.size()); // Players in group - if (!pRoleCheck->roles.empty()) + data << uint8(roleCheck.roles.size()); // Players in group + if (!roleCheck.roles.empty()) { // Leader info MUST be sent 1st :S - uint64 guid = pRoleCheck->leader; - uint8 roles = pRoleCheck->roles.find(guid)->second; + uint64 guid = roleCheck.leader; + uint8 roles = roleCheck.roles.find(guid)->second; data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles Player* player = ObjectAccessor::FindPlayer(guid); data << uint8(player ? player->getLevel() : 0); // Level - for (LfgRolesMap::const_iterator it = pRoleCheck->roles.begin(); it != pRoleCheck->roles.end(); ++it) + for (LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) { - if (it->first == pRoleCheck->leader) + if (it->first == roleCheck.leader) continue; guid = it->first; @@ -465,30 +454,31 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) SendPacket(&data); } -void WorldSession::SendLfgQueueStatus(uint32 dungeon, int32 waitTime, int32 avgWaitTime, int32 waitTimeTanks, int32 waitTimeHealer, int32 waitTimeDps, uint32 queuedTime, uint8 tanks, uint8 healers, uint8 dps) +void WorldSession::SendLfgQueueStatus(const LfgQueueStatusData& queueData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_QUEUE_STATUS [" UI64FMTD "] dungeon: %u - waitTime: %d - avgWaitTime: %d - waitTimeTanks: %d - waitTimeHealer: %d - waitTimeDps: %d - queuedTime: %u - tanks: %u - healers: %u - dps: %u", GetPlayer()->GetGUID(), dungeon, waitTime, avgWaitTime, waitTimeTanks, waitTimeHealer, waitTimeDps, queuedTime, tanks, healers, dps); + sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_QUEUE_STATUS [" UI64FMTD "] dungeon: %u - waitTime: %d - avgWaitTime: %d - waitTimeTanks: %d - waitTimeHealer: %d - waitTimeDps: %d - queuedTime: %u - tanks: %u - healers: %u - dps: %u", + GetPlayer()->GetGUID(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps); WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 +4 + 1 + 1 + 1 + 4); - data << uint32(dungeon); // Dungeon - data << int32(avgWaitTime); // Average Wait time - data << int32(waitTime); // Wait Time - data << int32(waitTimeTanks); // Wait Tanks - data << int32(waitTimeHealer); // Wait Healers - data << int32(waitTimeDps); // Wait Dps - data << uint8(tanks); // Tanks needed - data << uint8(healers); // Healers needed - data << uint8(dps); // Dps needed - data << uint32(queuedTime); // Player wait time in queue + data << uint32(queueData.dungeonId); // Dungeon + data << int32(queueData.waitTimeAvg); // Average Wait time + data << int32(queueData.waitTime); // Wait Time + data << int32(queueData.waitTimeTank); // Wait Tanks + data << int32(queueData.waitTimeHealer); // Wait Healers + data << int32(queueData.waitTimeDps); // Wait Dps + data << uint8(queueData.tanks); // Tanks needed + data << uint8(queueData.healers); // Healers needed + data << uint8(queueData.dps); // Dps needed + data << uint32(queueData.queuedTime); // Player wait time in queue SendPacket(&data); } -void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest* qRew) +void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest* quest) { - if (!rdungeonEntry || !sdungeonEntry || !qRew) + if (!rdungeonEntry || !sdungeonEntry || !quest) return; - uint8 itemNum = uint8(qRew ? qRew->GetRewItemsCount() : 0); + uint8 itemNum = uint8(quest ? quest->GetRewItemsCount() : 0); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PLAYER_REWARD [" UI64FMTD "] rdungeonEntry: %u - sdungeonEntry: %u - done: %u", GetPlayer()->GetGUID(), rdungeonEntry, sdungeonEntry, done); WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4)); @@ -496,37 +486,33 @@ void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntr data << uint32(sdungeonEntry); // Dungeon Finished data << uint8(done); data << uint32(1); - data << uint32(qRew->GetRewOrReqMoney()); - data << uint32(qRew->XPValue(GetPlayer())); + data << uint32(quest->GetRewOrReqMoney()); + data << uint32(quest->XPValue(GetPlayer())); data << uint32(reward->reward[done].variableMoney); data << uint32(reward->reward[done].variableXP); data << uint8(itemNum); if (itemNum) { - ItemTemplate const* iProto = NULL; for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) - { - if (!qRew->RewardItemId[i]) - continue; - - iProto = sObjectMgr->GetItemTemplate(qRew->RewardItemId[i]); - - data << uint32(qRew->RewardItemId[i]); - data << uint32(iProto ? iProto->DisplayInfoID : 0); - data << uint32(qRew->RewardItemIdCount[i]); - } + if (uint32 itemId = quest->RewardItemId[i]) + { + ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId); + data << uint32(itemId); + data << uint32(item ? item->DisplayInfoID : 0); + data << uint32(quest->RewardItemIdCount[i]); + } } SendPacket(&data); } -void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot) +void WorldSession::SendLfgBootProposalUpdate(const LfgPlayerBoot& boot) { uint64 guid = GetPlayer()->GetGUID(); - LfgAnswer playerVote = pBoot->votes.find(guid)->second; + LfgAnswer playerVote = boot.votes.find(guid)->second; uint8 votesNum = 0; uint8 agreeNum = 0; - uint32 secsleft = uint8((pBoot->cancelTime - time(NULL)) / 1000); - for (LfgAnswerMap::const_iterator it = pBoot->votes.begin(); it != pBoot->votes.end(); ++it) + uint32 secsleft = uint8((boot.cancelTime - time(NULL)) / 1000); + for (LfgAnswerMap::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it) { if (it->second != LFG_ANSWER_PENDING) { @@ -536,34 +522,31 @@ void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot) } } sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_BOOT_PROPOSAL_UPDATE [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s", - guid, uint8(pBoot->inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), pBoot->victim, votesNum, agreeNum, secsleft, pBoot->votedNeeded, pBoot->reason.c_str()); - WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length()); - data << uint8(pBoot->inProgress); // Vote in progress + guid, uint8(boot.inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), boot.victim, votesNum, agreeNum, secsleft, boot.votedNeeded, boot.reason.c_str()); + WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length()); + data << uint8(boot.inProgress); // Vote in progress data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree - data << uint64(pBoot->victim); // Victim GUID + data << uint64(boot.victim); // Victim GUID data << uint32(votesNum); // Total Votes data << uint32(agreeNum); // Agree Count data << uint32(secsleft); // Time Left - data << uint32(pBoot->votedNeeded); // Needed Votes - data << pBoot->reason.c_str(); // Kick reason + data << uint32(boot.votedNeeded); // Needed Votes + data << boot.reason.c_str(); // Kick reason SendPacket(&data); } -void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* pProp) +void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal& proposal) { - if (!pProp) - return; - uint64 guid = GetPlayer()->GetGUID(); - LfgProposalPlayerMap::const_iterator itPlayer = pProp->players.find(guid); - if (itPlayer == pProp->players.end()) // Player MUST be in the proposal + LfgProposalPlayerMap::const_iterator itPlayer = proposal.players.find(guid); + if (itPlayer == proposal.players.end()) // Player MUST be in the proposal return; LfgProposalPlayer* ppPlayer = itPlayer->second; uint32 pLowGroupGuid = ppPlayer->groupLowGuid; - uint32 dLowGuid = pProp->groupLowGuid; - uint32 dungeonId = pProp->dungeonId; + uint32 dLowGuid = proposal.groupLowGuid; + uint32 dungeonId = proposal.dungeonId; bool isSameDungeon = false; bool isContinue = false; Group* grp = dLowGuid ? sGroupMgr->GetGroupByGUID(dLowGuid) : NULL; @@ -575,8 +558,8 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* p isSameDungeon = GetPlayer()->GetGroup() == grp && isContinue; } - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", GetPlayer()->GetGUID(), pProp->state); - WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + pProp->players.size() * (4 + 1 + 1 + 1 + 1 +1)); + sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PROPOSAL_UPDATE [" UI64FMTD "] state: %u", GetPlayer()->GetGUID(), proposal.state); + WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); if (!isContinue) // Only show proposal dungeon if it's continue { @@ -585,7 +568,7 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* p dungeonId = (*playerDungeons.begin()); } - if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) + if (LFGDungeonEntry const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) { dungeonId = dungeon->Entry(); @@ -606,13 +589,13 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* p } data << uint32(dungeonId); // Dungeon - data << uint8(pProp->state); // Result state + data << uint8(proposal.state); // Result state data << uint32(proposalId); // Internal Proposal ID data << uint32(completedEncounters); // Bosses killed data << uint8(isSameDungeon); // Silent (show client window) - data << uint8(pProp->players.size()); // Group size + data << uint8(proposal.players.size()); // Group size - for (itPlayer = pProp->players.begin(); itPlayer != pProp->players.end(); ++itPlayer) + for (itPlayer = proposal.players.begin(); itPlayer != proposal.players.end(); ++itPlayer) { ppPlayer = itPlayer->second; data << uint32(ppPlayer->role); // Role @@ -633,9 +616,9 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, const LfgProposal* p SendPacket(&data); } -void WorldSession::SendLfgUpdateSearch(bool update) +void WorldSession::SendLfgLfrList(bool update) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_UPDATE_SEARCH [" UI64FMTD "] update: %u", GetPlayer()->GetGUID(), update ? 1 : 0); + sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_LFR_LIST [" UI64FMTD "] update: %u", GetPlayer()->GetGUID(), update ? 1 : 0); WorldPacket data(SMSG_LFG_UPDATE_SEARCH, 1); data << uint8(update); // In Lfg Queue? SendPacket(&data); @@ -667,8 +650,8 @@ void WorldSession::SendLfgTeleportError(uint8 err) /* void WorldSession::SendLfrUpdateListOpcode(uint32 dungeonEntry) { - sLog->outDebug(LOG_FILTER_PACKETIO, "SMSG_UPDATE_LFG_LIST [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), dungeonEntry); - WorldPacket data(SMSG_UPDATE_LFG_LIST); + sLog->outDebug(LOG_FILTER_PACKETIO, "SMSG_LFG_UPDATE_LIST [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), dungeonEntry); + WorldPacket data(SMSG_LFG_UPDATE_LIST); SendPacket(&data); } */ diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index bc524c720f7..c3c6befe2f9 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2468,8 +2468,8 @@ bool InstanceMap::AddPlayerToMap(Player* player) if (group && group->isLFGGroup()) if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) - if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) - if (LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin()))) + if (LFGDungeonEntry const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) + if (LFGDungeonEntry const* randomDungeon = sLFGMgr->GetLFGDungeon(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin()))) if (uint32(dungeon->map) == GetId() && dungeon->difficulty == uint32(GetDifficulty()) && randomDungeon->type == uint32(LFG_TYPE_RANDOM)) player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true); } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index a229d3ed536..af2ff2c6d86 100755 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -888,7 +888,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgJoinOpcode }, /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgLeaveOpcode }, - /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrSearchOpcode }, + /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrJoinOpcode }, /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrLeaveOpcode }, /*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x361*/ { "SMSG_LFG_PROPOSAL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index bc9e6ac4298..3ff45bff3b1 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -54,6 +54,7 @@ struct LfgJoinResultData; struct LfgLockStatus; struct LfgPlayerBoot; struct LfgProposal; +struct LfgQueueStatusData; struct LfgReward; struct LfgRoleCheck; struct LfgUpdateData; @@ -815,19 +816,19 @@ class WorldSession void HandleLfgProposalResultOpcode(WorldPacket& recv_data); void HandleLfgSetBootVoteOpcode(WorldPacket& recv_data); void HandleLfgTeleportOpcode(WorldPacket& recv_data); - void HandleLfrSearchOpcode(WorldPacket& recv_data); + void HandleLfrJoinOpcode(WorldPacket& recv_data); void HandleLfrLeaveOpcode(WorldPacket& recv_data); void SendLfgUpdatePlayer(const LfgUpdateData& updateData); void SendLfgUpdateParty(const LfgUpdateData& updateData); void SendLfgRoleChosen(uint64 guid, uint8 roles); - void SendLfgRoleCheckUpdate(const LfgRoleCheck* pRoleCheck); - void SendLfgUpdateSearch(bool update); + void SendLfgRoleCheckUpdate(const LfgRoleCheck& pRoleCheck); + void SendLfgLfrList(bool update); void SendLfgJoinResult(const LfgJoinResultData& joinData); - void SendLfgQueueStatus(uint32 dungeon, int32 waitTime, int32 avgWaitTime, int32 waitTimeTanks, int32 waitTimeHealer, int32 waitTimeDps, uint32 queuedTime, uint8 tanks, uint8 healers, uint8 dps); + void SendLfgQueueStatus(const LfgQueueStatusData& queueData); void SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest *qRew); - void SendLfgBootPlayer(const LfgPlayerBoot* pBoot); - void SendLfgUpdateProposal(uint32 proposalId, const LfgProposal *pProp); + void SendLfgBootProposalUpdate(const LfgPlayerBoot& boot); + void SendLfgUpdateProposal(uint32 proposalId, const LfgProposal& proposal); void SendLfgDisabled(); void SendLfgOfferContinue(uint32 dungeonEntry); void SendLfgTeleportError(uint8 err); diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index c8126f8aaf3..b1a2097a8f9 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -586,7 +586,7 @@ class AuraScript : public _SpellScript uint8 _currentScriptState; bool _defaultActionPrevented; ScriptStateStore(uint8 currentScriptState, AuraApplication const* auraApplication, bool defaultActionPrevented) - : _currentScriptState(currentScriptState), _auraApplication(auraApplication), _defaultActionPrevented(defaultActionPrevented) + : _auraApplication(auraApplication), _currentScriptState(currentScriptState), _defaultActionPrevented(defaultActionPrevented) {} }; typedef std::stack<ScriptStateStore> ScriptStateStack; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 06e8d3eccbe..35f991cd368 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1461,14 +1461,15 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Vehicle Accessories..."); sObjectMgr->LoadVehicleAccessories(); // must be after LoadCreatureTemplates() and LoadNPCSpellClickSpells() + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading LFG entrance positions..."); + sLFGMgr->LoadLFGDungeons(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Dungeon boss data..."); sObjectMgr->LoadInstanceEncounters(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading LFG rewards..."); sLFGMgr->LoadRewards(); - sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading LFG entrance positions..."); - sLFGMgr->LoadEntrancePositions(); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading SpellArea Data..."); // must be after quest load sSpellMgr->LoadSpellAreas(); diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp index 39fff139b52..28595571a2f 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp @@ -232,7 +232,7 @@ public: { npc_verdisa_beglaristrasz_eternosAI(Creature* creature) : ScriptedAI(creature) { } - void MovementInform(uint32 type, uint32 id) + void MovementInform(uint32 /*type*/, uint32 id) { // When Belgaristraz finish his moving say grateful text if (me->GetEntry() == NPC_BELGARISTRASZ) diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 5cc31ad54e8..547cb3dba51 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1581,12 +1581,12 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader } - LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*itr); + LFGDungeonEntry const* randomDungeon = sLFGMgr->GetLFGDungeon(*itr); if (Group* group = owner->GetGroup()) if (Map const* map = owner->GetMap()) if (group->isLFGGroup()) if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) - if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) + if (LFGDungeonEntry const* dungeon = sLFGMgr->GetLFGDungeon(dungeonId)) if (uint32(dungeon->map) == map->GetId() && dungeon->difficulty == uint32(map->GetDifficulty())) if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM) return; // in correct dungeon diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index b8df77d0346..b291b9751b4 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -2115,7 +2115,7 @@ class npc_shadowfiend : public CreatureScript { npc_shadowfiendAI(Creature* creature) : PetAI(creature) {} - void JustDied(Unit* killer) + void JustDied(Unit* /*killer*/) { if (me->isSummon()) if (Unit* owner = me->ToTempSummon()->GetSummoner()) |