Enabling solo-dungeon queue and implementing first dungeonhelper prototyp
This commit is contained in:
1 parent
fcedaf23b9
commit
f35c3c4ae9
5 files changed
+168
-3
No files matched your search
@@ -23,6 +23,7 @@
|
|||||||
#include "Group.h"
|
#include "Group.h"
|
||||||
#include "LFGQueue.h"
|
#include "LFGQueue.h"
|
||||||
#include "LFGMgr.h"
|
#include "LFGMgr.h"
|
||||||
|
#include "World.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
namespace lfg
|
namespace lfg
|
||||||
@@ -331,6 +332,105 @@ uint8 LFGQueue::FindGroups()
|
|||||||
else
|
else
|
||||||
AddToCurrentQueue(frontguid); // Lfg group not found, add this group to the queue.
|
AddToCurrentQueue(frontguid); // Lfg group not found, add this group to the queue.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep normal TrinityCore matchmaking authoritative. Only after normal
|
||||||
|
// matching has failed do we permit an underfilled low-population group.
|
||||||
|
if (sWorld->getBoolConfig(CONFIG_DUNGEON_FINDER_LOW_POPULATION_ENABLE))
|
||||||
|
proposals += FindLowPopulationGroups();
|
||||||
|
|
||||||
|
return proposals;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuidList LFGQueue::GetQueueGuidsFromKey(std::string const& key) const
|
||||||
|
{
|
||||||
|
GuidList result;
|
||||||
|
|
||||||
|
for (GuidList::const_iterator itr = currentQueueStore.begin(); itr != currentQueueStore.end(); ++itr)
|
||||||
|
{
|
||||||
|
std::ostringstream o;
|
||||||
|
o << itr->GetRawValue();
|
||||||
|
std::string token = o.str();
|
||||||
|
|
||||||
|
size_t pos = key.find(token);
|
||||||
|
while (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
size_t end = pos + token.length();
|
||||||
|
bool leftBoundary = pos == 0 || key[pos - 1] == '|';
|
||||||
|
bool rightBoundary = end == key.length() || key[end] == '|';
|
||||||
|
|
||||||
|
if (leftBoundary && rightBoundary)
|
||||||
|
{
|
||||||
|
result.push_back(*itr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = key.find(token, pos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 LFGQueue::FindLowPopulationGroups()
|
||||||
|
{
|
||||||
|
uint8 proposals = 0;
|
||||||
|
uint32 const fallbackDelay =
|
||||||
|
sWorld->getIntConfig(CONFIG_DUNGEON_FINDER_LOW_POPULATION_FALLBACK_DELAY);
|
||||||
|
uint32 const minPlayers =
|
||||||
|
sWorld->getIntConfig(CONFIG_DUNGEON_FINDER_LOW_POPULATION_MIN_PLAYERS);
|
||||||
|
time_t const now = GameTime::GetGameTime();
|
||||||
|
|
||||||
|
bool createdProposal = true;
|
||||||
|
while (createdProposal)
|
||||||
|
{
|
||||||
|
createdProposal = false;
|
||||||
|
GuidList queueSnapshot = currentQueueStore;
|
||||||
|
|
||||||
|
for (GuidList::const_iterator itrGuid = queueSnapshot.begin(); itrGuid != queueSnapshot.end(); ++itrGuid)
|
||||||
|
{
|
||||||
|
LfgQueueDataContainer::iterator itrQueue = QueueDataStore.find(*itrGuid);
|
||||||
|
if (itrQueue == QueueDataStore.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LfgQueueData& queueData = itrQueue->second;
|
||||||
|
|
||||||
|
if (now < queueData.joinTime || uint32(now - queueData.joinTime) < fallbackDelay)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (queueData.bestCompatible.empty())
|
||||||
|
FindBestCompatibleInQueue(itrQueue);
|
||||||
|
|
||||||
|
if (queueData.bestCompatible.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
GuidList check = GetQueueGuidsFromKey(queueData.bestCompatible);
|
||||||
|
if (check.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32 playerCount = 0;
|
||||||
|
for (GuidList::const_iterator itrCheck = check.begin(); itrCheck != check.end(); ++itrCheck)
|
||||||
|
{
|
||||||
|
LfgQueueDataContainer::const_iterator itrData = QueueDataStore.find(*itrCheck);
|
||||||
|
if (itrData != QueueDataStore.end())
|
||||||
|
playerCount += uint32(itrData->second.roles.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playerCount < minPlayers)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TC_LOG_DEBUG("lfg.queue.lowpopulation",
|
||||||
|
"Low population fallback after %u seconds: trying partial group (%s) with %u player(s)",
|
||||||
|
fallbackDelay, ConcatenateGuids(check).c_str(), playerCount);
|
||||||
|
|
||||||
|
if (CheckCompatibility(check, true) == LFG_COMPATIBLES_MATCH)
|
||||||
|
{
|
||||||
|
++proposals;
|
||||||
|
createdProposal = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return proposals;
|
return proposals;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +479,7 @@ LfgCompatibility LFGQueue::FindNewGroups(GuidList& check, GuidList& all)
|
|||||||
@param[in] check List of guids to check compatibilities
|
@param[in] check List of guids to check compatibilities
|
||||||
@return LfgCompatibility type of compatibility
|
@return LfgCompatibility type of compatibility
|
||||||
*/
|
*/
|
||||||
LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
LfgCompatibility LFGQueue::CheckCompatibility(GuidList check, bool allowIncomplete)
|
||||||
{
|
{
|
||||||
std::string strGuids = ConcatenateGuids(check);
|
std::string strGuids = ConcatenateGuids(check);
|
||||||
LfgProposal proposal;
|
LfgProposal proposal;
|
||||||
@@ -544,7 +644,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enough players?
|
// Enough players?
|
||||||
if (numPlayers != dungeon->GetMaxGroupSize())
|
if (numPlayers != dungeon->GetMaxGroupSize() && !allowIncomplete)
|
||||||
{
|
{
|
||||||
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Compatibles but not enough players(%u)", GetDetailedMatchRoles(check).c_str(), numPlayers);
|
TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Compatibles but not enough players(%u)", GetDetailedMatchRoles(check).c_str(), numPlayers);
|
||||||
LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS);
|
LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS);
|
||||||
|
|||||||
@@ -138,9 +138,11 @@ class TC_GAME_API LFGQueue
|
|||||||
LfgCompatibilityData* GetCompatibilityData(std::string const& key);
|
LfgCompatibilityData* GetCompatibilityData(std::string const& key);
|
||||||
void FindBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue);
|
void FindBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue);
|
||||||
void UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue, std::string const& key, LfgRolesMap const& roles);
|
void UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue, std::string const& key, LfgRolesMap const& roles);
|
||||||
|
uint8 FindLowPopulationGroups();
|
||||||
|
GuidList GetQueueGuidsFromKey(std::string const& key) const;
|
||||||
|
|
||||||
LfgCompatibility FindNewGroups(GuidList& check, GuidList& all);
|
LfgCompatibility FindNewGroups(GuidList& check, GuidList& all);
|
||||||
LfgCompatibility CheckCompatibility(GuidList check);
|
LfgCompatibility CheckCompatibility(GuidList check, bool allowIncomplete = false);
|
||||||
|
|
||||||
// Queue
|
// Queue
|
||||||
LfgQueueDataContainer QueueDataStore; ///< Queued groups
|
LfgQueueDataContainer QueueDataStore; ///< Queued groups
|
||||||
|
|||||||
@@ -1521,6 +1521,20 @@ void World::LoadConfigSettings(bool reload)
|
|||||||
|
|
||||||
// Dungeon finder
|
// Dungeon finder
|
||||||
m_int_configs[CONFIG_LFG_OPTIONSMASK] = sConfigMgr->GetIntDefault("DungeonFinder.OptionsMask", 1);
|
m_int_configs[CONFIG_LFG_OPTIONSMASK] = sConfigMgr->GetIntDefault("DungeonFinder.OptionsMask", 1);
|
||||||
|
m_bool_configs[CONFIG_DUNGEON_FINDER_LOW_POPULATION_ENABLE] =
|
||||||
|
sConfigMgr->GetBoolDefault("DungeonFinder.LowPopulation.Enable", false);
|
||||||
|
m_int_configs[CONFIG_DUNGEON_FINDER_LOW_POPULATION_FALLBACK_DELAY] =
|
||||||
|
sConfigMgr->GetIntDefault("DungeonFinder.LowPopulation.FallbackDelay", 60);
|
||||||
|
m_int_configs[CONFIG_DUNGEON_FINDER_LOW_POPULATION_MIN_PLAYERS] =
|
||||||
|
sConfigMgr->GetIntDefault("DungeonFinder.LowPopulation.MinPlayers", 1);
|
||||||
|
|
||||||
|
if (m_int_configs[CONFIG_DUNGEON_FINDER_LOW_POPULATION_MIN_PLAYERS] < 1)
|
||||||
|
{
|
||||||
|
TC_LOG_ERROR("server.loading",
|
||||||
|
"DungeonFinder.LowPopulation.MinPlayers (%u) must be at least 1. Using 1 instead.",
|
||||||
|
m_int_configs[CONFIG_DUNGEON_FINDER_LOW_POPULATION_MIN_PLAYERS]);
|
||||||
|
m_int_configs[CONFIG_DUNGEON_FINDER_LOW_POPULATION_MIN_PLAYERS] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// DBC_ItemAttributes
|
// DBC_ItemAttributes
|
||||||
m_bool_configs[CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES] = sConfigMgr->GetBoolDefault("DBC.EnforceItemAttributes", true);
|
m_bool_configs[CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES] = sConfigMgr->GetBoolDefault("DBC.EnforceItemAttributes", true);
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ enum WorldBoolConfigs : uint8
|
|||||||
CONFIG_CHAT_PARTY_RAID_WARNINGS,
|
CONFIG_CHAT_PARTY_RAID_WARNINGS,
|
||||||
CONFIG_DETECT_POS_COLLISION,
|
CONFIG_DETECT_POS_COLLISION,
|
||||||
CONFIG_RESTRICTED_LFG_CHANNEL,
|
CONFIG_RESTRICTED_LFG_CHANNEL,
|
||||||
|
CONFIG_DUNGEON_FINDER_LOW_POPULATION_ENABLE,
|
||||||
CONFIG_CHAT_FAKE_MESSAGE_PREVENTING,
|
CONFIG_CHAT_FAKE_MESSAGE_PREVENTING,
|
||||||
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP,
|
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP,
|
||||||
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE,
|
CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE,
|
||||||
@@ -364,6 +365,8 @@ enum WorldIntConfigs : uint8
|
|||||||
CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION,
|
CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION,
|
||||||
CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS,
|
CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS,
|
||||||
CONFIG_LFG_OPTIONSMASK,
|
CONFIG_LFG_OPTIONSMASK,
|
||||||
|
CONFIG_DUNGEON_FINDER_LOW_POPULATION_FALLBACK_DELAY,
|
||||||
|
CONFIG_DUNGEON_FINDER_LOW_POPULATION_MIN_PLAYERS,
|
||||||
CONFIG_MAX_INSTANCES_PER_HOUR,
|
CONFIG_MAX_INSTANCES_PER_HOUR,
|
||||||
CONFIG_WARDEN_CLIENT_RESPONSE_DELAY,
|
CONFIG_WARDEN_CLIENT_RESPONSE_DELAY,
|
||||||
CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF,
|
CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ EndContentData */
|
|||||||
#include "Spell.h"
|
#include "Spell.h"
|
||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
#include "TemporarySummon.h"
|
#include "TemporarySummon.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
namespace ItemScripts
|
namespace ItemScripts
|
||||||
{
|
{
|
||||||
@@ -412,6 +413,50 @@ class item_generic_limit_chance_above_60 : public ItemScript
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/*#####
|
||||||
|
# item_horde_adventurer_horn
|
||||||
|
#####*/
|
||||||
|
|
||||||
|
enum HordeAdventurerHorn
|
||||||
|
{
|
||||||
|
NPC_ORGRIMMAR_GRUNT = 3296
|
||||||
|
};
|
||||||
|
|
||||||
|
class item_horde_adventurer_horn : public ItemScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
item_horde_adventurer_horn() : ItemScript("item_horde_adventurer_horn") { }
|
||||||
|
|
||||||
|
bool OnUse(Player* player, Item* item, SpellCastTargets const& /*targets*/) override
|
||||||
|
{
|
||||||
|
TC_LOG_INFO("scripts", "Horde adventureer horn OnUse triggered by player %s (item %u)", player->GetName().c_str(), item->GetEntry());
|
||||||
|
// The horn may not be used during combat.
|
||||||
|
if (player->IsInCombat())
|
||||||
|
{
|
||||||
|
player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The horn may only be used inside a dungeon instance.
|
||||||
|
if (!player->GetMap()->IsDungeon())
|
||||||
|
{
|
||||||
|
player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
player->SummonCreature(
|
||||||
|
NPC_ORGRIMMAR_GRUNT,
|
||||||
|
player->GetPositionX() + 2.0f,
|
||||||
|
player->GetPositionY(),
|
||||||
|
player->GetPositionZ(),
|
||||||
|
player->GetOrientation(),
|
||||||
|
TEMPSUMMON_MANUAL_DESPAWN,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddSC_item_scripts()
|
void AddSC_item_scripts()
|
||||||
@@ -428,4 +473,5 @@ void AddSC_item_scripts()
|
|||||||
new item_dehta_trap_smasher();
|
new item_dehta_trap_smasher();
|
||||||
new item_captured_frog();
|
new item_captured_frog();
|
||||||
new item_generic_limit_chance_above_60();
|
new item_generic_limit_chance_above_60();
|
||||||
|
new item_horde_adventurer_horn();
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user