fix(Core/DungeonFinder): misc improvements (#7488)
- Players should be able to enter the same dungeon if just completed it - Properly define if the proposal is new - Set teleport point to the nearest graveyard if teleported to dungeon from other instance - Display completed encounters when joining LFG in progress (excluding random) - Closes #5914 - Closes #7388
This commit is contained in:
@@ -662,6 +662,14 @@ namespace lfg
|
||||
if (isRaid && grp && (grp->isLFGGroup() || guid != grp->GetLeaderGUID()))
|
||||
return;
|
||||
|
||||
// Do not allow to change dungeon in the middle of a current dungeon
|
||||
if (!isRaid && isContinue && grp->GetMembersCount() == 5)
|
||||
{
|
||||
dungeons.clear();
|
||||
dungeons.insert(GetDungeon(gguid));
|
||||
joinData.result = LFG_JOIN_PARTY_NOT_MEET_REQS;
|
||||
}
|
||||
|
||||
// Can't join. Send result
|
||||
if (joinData.result != LFG_JOIN_OK)
|
||||
{
|
||||
@@ -1603,6 +1611,18 @@ namespace lfg
|
||||
|
||||
_SaveToDB(gguid);
|
||||
|
||||
// Select a player inside to be teleported to
|
||||
WorldLocation const* teleportLocation = nullptr;
|
||||
for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
{
|
||||
Player* plr = itr->GetSource();
|
||||
if (plr && plr->GetMapId() == uint32(dungeon->map) && !proposal.isNew)
|
||||
{
|
||||
teleportLocation = plr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool randomDungeon = false;
|
||||
// Teleport Player
|
||||
for (LfgGuidList::const_iterator it = playersToTeleport.begin(); it != playersToTeleport.end(); ++it)
|
||||
@@ -1610,6 +1630,16 @@ namespace lfg
|
||||
{
|
||||
if (player->GetGroup() != grp) // pussywizard: could not add because group was full (some shitness happened)
|
||||
continue;
|
||||
|
||||
if (player->GetMapId() == uint32(dungeon->map))
|
||||
{
|
||||
// Remove bind to that map
|
||||
if (!sInstanceSaveMgr->PlayerIsPermBoundToInstance(player->GetGUID(), dungeon->map, player->GetDungeonDifficulty()))
|
||||
{
|
||||
sInstanceSaveMgr->PlayerUnbindInstance(player->GetGUID(), dungeon->map, player->GetDungeonDifficulty(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the cooldown spell if queued for a random dungeon
|
||||
// xinef: add aura
|
||||
if ((randomDungeon || selectedRandomLfgDungeon(player->GetGUID())) && !player->HasAura(LFG_SPELL_DUNGEON_COOLDOWN))
|
||||
@@ -1617,7 +1647,8 @@ namespace lfg
|
||||
randomDungeon = true;
|
||||
player->AddAura(LFG_SPELL_DUNGEON_COOLDOWN, player);
|
||||
}
|
||||
TeleportPlayer(player, false);
|
||||
|
||||
TeleportPlayer(player, false, teleportLocation);
|
||||
}
|
||||
|
||||
if (randomDungeon)
|
||||
@@ -1952,7 +1983,7 @@ namespace lfg
|
||||
@param[in] out Teleport out (true) or in (false)
|
||||
@param[in] fromOpcode Function called from opcode handlers? (Default false)
|
||||
*/
|
||||
void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*/)
|
||||
void LFGMgr::TeleportPlayer(Player* player, bool out, WorldLocation const* teleportLocation /*= nullptr*/)
|
||||
{
|
||||
LFGDungeonData const* dungeon = nullptr;
|
||||
Group* group = player->GetGroup();
|
||||
@@ -1986,7 +2017,7 @@ namespace lfg
|
||||
error = LFG_TELEPORTERROR_IN_VEHICLE;
|
||||
else if (player->GetCharmGUID())
|
||||
error = LFG_TELEPORTERROR_CHARMING;
|
||||
else if (player->GetMapId() != uint32(dungeon->map)) // Do not teleport players in dungeon to the entrance
|
||||
else
|
||||
{
|
||||
uint32 mapid = dungeon->map;
|
||||
float x = dungeon->x;
|
||||
@@ -1994,32 +2025,21 @@ namespace lfg
|
||||
float z = dungeon->z;
|
||||
float orientation = dungeon->o;
|
||||
|
||||
if (!fromOpcode)
|
||||
if (teleportLocation)
|
||||
{
|
||||
// Select a player inside to be teleported to
|
||||
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
|
||||
{
|
||||
Player* plrg = itr->GetSource();
|
||||
if (plrg && plrg != player && plrg->GetMapId() == uint32(dungeon->map))
|
||||
{
|
||||
mapid = plrg->GetMapId();
|
||||
x = plrg->GetPositionX();
|
||||
y = plrg->GetPositionY();
|
||||
z = plrg->GetPositionZ();
|
||||
orientation = plrg->GetOrientation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
teleportLocation->GetWorldLocation(mapid, x, y, z, orientation);
|
||||
}
|
||||
|
||||
if (!player->GetMap()->IsDungeon())
|
||||
if (!player->GetMap()->IsDungeon() || player->GetEntryPoint().GetMapId() == MAPID_INVALID)
|
||||
{
|
||||
player->SetEntryPoint();
|
||||
}
|
||||
|
||||
if (!player->TeleportTo(mapid, x, y, z, orientation))
|
||||
if (!player->TeleportTo(mapid, x, y, z, orientation, 0, nullptr, mapid == player->GetMapId()))
|
||||
{
|
||||
error = LFG_TELEPORTERROR_INVALID_LOCATION;
|
||||
}
|
||||
}
|
||||
else
|
||||
error = LFG_TELEPORTERROR_INVALID_LOCATION;
|
||||
|
||||
if (error != LFG_TELEPORTERROR_OK)
|
||||
player->GetSession()->SendLfgTeleportError(uint8(error));
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
class Group;
|
||||
class Player;
|
||||
class Quest;
|
||||
class WorldLocation;
|
||||
|
||||
namespace lfg
|
||||
{
|
||||
@@ -500,7 +501,7 @@ namespace lfg
|
||||
/// Returns all random and seasonal dungeons for given level and expansion
|
||||
LfgDungeonSet GetRandomAndSeasonalDungeons(uint8 level, uint8 expansion);
|
||||
/// Teleport a player to/from selected dungeon
|
||||
void TeleportPlayer(Player* player, bool out, bool fromOpcode = false);
|
||||
void TeleportPlayer(Player* player, bool out, WorldLocation const* teleportLocation = nullptr);
|
||||
/// Inits new proposal to boot a player
|
||||
void InitBoot(ObjectGuid gguid, ObjectGuid kicker, ObjectGuid victim, std::string const& reason);
|
||||
/// Updates player boot proposal with new player answer
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
|
||||
#include "Containers.h"
|
||||
#include "DBCStores.h"
|
||||
#include "Group.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "LFGMgr.h"
|
||||
#include "LFGQueue.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
|
||||
namespace lfg
|
||||
@@ -397,9 +400,8 @@ namespace lfg
|
||||
return LFG_COMPATIBLES_WITH_LESS_PLAYERS;
|
||||
}
|
||||
|
||||
ObjectGuid gguid = check.front();
|
||||
proposal.queues = strGuids;
|
||||
proposal.isNew = numLfgGroups != 1 || sLFGMgr->GetOldState(gguid) != LFG_STATE_DUNGEON;
|
||||
proposal.isNew = numLfgGroups != 1 || sLFGMgr->GetOldState(proposal.group) != LFG_STATE_DUNGEON;
|
||||
|
||||
if (!sLFGMgr->AllQueued(check)) // can't create proposal
|
||||
return LFG_COMPATIBILITY_PENDING;
|
||||
@@ -410,6 +412,7 @@ namespace lfg
|
||||
proposal.leader.Clear();
|
||||
proposal.dungeonId = Acore::Containers::SelectRandomContainerElement(proposalDungeons);
|
||||
|
||||
uint32 completedEncounters = 0;
|
||||
bool leader = false;
|
||||
for (LfgRolesMap::const_iterator itRoles = proposalRoles.begin(); itRoles != proposalRoles.end(); ++itRoles)
|
||||
{
|
||||
@@ -429,8 +432,27 @@ namespace lfg
|
||||
data.group = proposalGroups.find(itRoles->first)->second;
|
||||
if (!proposal.isNew && data.group && data.group == proposal.group) // Player from existing group, autoaccept
|
||||
data.accept = LFG_ANSWER_AGREE;
|
||||
|
||||
if (!completedEncounters && !proposal.isNew)
|
||||
{
|
||||
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(proposal.dungeonId))
|
||||
{
|
||||
if (Player* player = ObjectAccessor::FindConnectedPlayer(itRoles->first))
|
||||
{
|
||||
if (player->GetMapId() == static_cast<uint32>(dungeon->map))
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
{
|
||||
completedEncounters = instance->GetCompletedEncounterMask();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proposal.encounters = completedEncounters;
|
||||
|
||||
for (uint8 i = 0; i < 5 && proposal.queues.guids[i]; ++i)
|
||||
RemoveFromQueue(proposal.queues.guids[i], true);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user