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:
UltraNix
2021-09-01 10:44:29 +02:00
committed by GitHub
parent a69be39fcb
commit 498faf380b
8 changed files with 131 additions and 33 deletions

View File

@@ -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));