mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-25 14:46:24 +00:00
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);
|
||||
|
||||
|
||||
@@ -666,11 +666,49 @@ public:
|
||||
Relocate(x, y, z, o);
|
||||
}
|
||||
|
||||
void SetMapId(uint32 mapId)
|
||||
{
|
||||
m_mapId = mapId;
|
||||
}
|
||||
|
||||
[[nodiscard]] uint32 GetMapId() const
|
||||
{
|
||||
return m_mapId;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y, float& z) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y, float& z, float& o) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
o = m_orientation;
|
||||
}
|
||||
|
||||
void GetWorldLocation(WorldLocation* location) const
|
||||
{
|
||||
if (location)
|
||||
{
|
||||
location->Relocate(m_positionX, m_positionY, m_positionZ, m_orientation);
|
||||
location->SetMapId(m_mapId);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] WorldLocation GetWorldLocation() const
|
||||
{
|
||||
return *this;
|
||||
|
||||
@@ -1277,7 +1277,7 @@ void Player::SendTeleportAckPacket()
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Unit* target /*= nullptr*/)
|
||||
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Unit* target /*= nullptr*/, bool newInstance /*= false*/)
|
||||
{
|
||||
// for except kick by antispeedhack
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(this, true);
|
||||
@@ -1378,7 +1378,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
if (!sScriptMgr->OnBeforePlayerTeleport(this, mapid, x, y, z, orientation, options, target))
|
||||
return false;
|
||||
|
||||
if (GetMapId() == mapid)
|
||||
if (GetMapId() == mapid && !newInstance)
|
||||
{
|
||||
//lets reset far teleport flag if it wasn't reset during chained teleports
|
||||
SetSemaphoreTeleportFar(0);
|
||||
@@ -1547,9 +1547,15 @@ bool Player::TeleportToEntryPoint()
|
||||
ScheduleDelayedOperation(DELAYED_BG_TAXI_RESTORE);
|
||||
ScheduleDelayedOperation(DELAYED_BG_GROUP_RESTORE);
|
||||
|
||||
if (m_entryPointData.joinPos.m_mapId == MAPID_INVALID)
|
||||
WorldLocation loc = m_entryPointData.joinPos;
|
||||
m_entryPointData.joinPos.m_mapId = MAPID_INVALID;
|
||||
|
||||
if (loc.m_mapId == MAPID_INVALID)
|
||||
{
|
||||
return TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
|
||||
return TeleportTo(m_entryPointData.joinPos);
|
||||
}
|
||||
|
||||
return TeleportTo(loc);
|
||||
}
|
||||
|
||||
void Player::ProcessDelayedOperations()
|
||||
|
||||
@@ -992,7 +992,7 @@ public:
|
||||
return GetSession()->GetSessionDbLocaleIndex() == LOCALE_esES || GetSession()->GetSessionDbLocaleIndex() == LOCALE_esMX;
|
||||
}
|
||||
|
||||
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0, Unit* target = nullptr);
|
||||
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0, Unit* target = nullptr, bool newInstance = false);
|
||||
bool TeleportTo(WorldLocation const& loc, uint32 options = 0, Unit* target = nullptr)
|
||||
{
|
||||
return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options, target);
|
||||
|
||||
@@ -119,8 +119,19 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
Group* group = GetPlayer()->GetGroup();
|
||||
if (group && (group->isBGGroup() || group->isBFGroup()))
|
||||
group = GetPlayer()->GetOriginalGroup();
|
||||
if (group)
|
||||
{
|
||||
if (group->isLFGGroup() && group->IsLfgRandomInstance())
|
||||
{
|
||||
SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if (group->isBGGroup() || group->isBFGroup())
|
||||
{
|
||||
group = GetPlayer()->GetOriginalGroup();
|
||||
}
|
||||
}
|
||||
|
||||
Group* group2 = player->GetGroup();
|
||||
if (group2 && (group2->isBGGroup() || group2->isBFGroup()))
|
||||
|
||||
@@ -151,7 +151,7 @@ void WorldSession::HandleLfgTeleportOpcode(WorldPacket& recvData)
|
||||
recvData >> out;
|
||||
|
||||
LOG_DEBUG("network", "CMSG_LFG_TELEPORT [%s] out: %u", GetPlayer()->GetGUID().ToString().c_str(), out ? 1 : 0);
|
||||
sLFGMgr->TeleportPlayer(GetPlayer(), out, true);
|
||||
sLFGMgr->TeleportPlayer(GetPlayer(), out);
|
||||
}
|
||||
|
||||
void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData*/)
|
||||
|
||||
Reference in New Issue
Block a user