diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 277e7a879..64d7c349c 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1568,7 +1568,28 @@ namespace lfg LFGDungeonData const* dungeon = GetLFGDungeon(proposal.dungeonId); ASSERT(dungeon); + bool isPremadeGroup = false; Group* grp = proposal.group ? sGroupMgr->GetGroupByGUID(proposal.group.GetCounter()) : nullptr; + if (!grp) + { + ObjectGuid groupGUID; + for (ObjectGuid const& guid : players) + { + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) + { + Group* group = player->GetGroup(); + if (!group || (groupGUID && groupGUID != group->GetGUID())) + { + isPremadeGroup = false; + break; + } + + groupGUID = group->GetGUID(); + isPremadeGroup = true; + } + } + } + ObjectGuid oldGroupGUID; for (LfgGuidList::const_iterator it = players.begin(); it != players.end(); ++it) { @@ -1578,6 +1599,13 @@ namespace lfg continue; Group* group = player->GetGroup(); + if (isPremadeGroup && !grp) + { + oldGroupGUID = group->GetGUID(); + grp = group; + grp->ConvertToLFG(false); + SetState(grp->GetGUID(), LFG_STATE_PROPOSAL); + } // Xinef: Apply Random Buff if (grp && !grp->IsLfgWithBuff()) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0881c1b1d..713a4dfc3 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -12157,7 +12157,7 @@ PartyResult Player::CanUninviteFromGroup(ObjectGuid targetPlayerGUID) const if (!grp) return ERR_NOT_IN_GROUP; - if (grp->isLFGGroup()) + if (grp->isLFGGroup(true)) { ObjectGuid gguid = grp->GetGUID(); if (!sLFGMgr->GetKicksLeft(gguid)) diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index dbd80071e..b2aa83289 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -2370,7 +2370,7 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const { - if (!GetGroup() || !GetGroup()->isLFGGroup()) + if (!GetGroup() || !GetGroup()->isLFGGroup(true)) return EQUIP_ERR_OK; // not in LFG group // check if looted object is inside the lfg dungeon diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 9b58cf9be..097e7f1da 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -252,10 +252,15 @@ void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uin sLFGMgr->SetupGroupMember(member.guid, GetGUID()); } -void Group::ConvertToLFG() +void Group::ConvertToLFG(bool restricted /*= true*/) { - m_groupType = GroupType(m_groupType | GROUPTYPE_LFG | GROUPTYPE_LFG_RESTRICTED); - m_lootMethod = NEED_BEFORE_GREED; + m_groupType = GroupType(m_groupType | GROUPTYPE_LFG); + if (restricted) + { + m_groupType = GroupType(m_groupType | GROUPTYPE_LFG_RESTRICTED); + m_lootMethod = NEED_BEFORE_GREED; + } + if (!isBGGroup() && !isBFGroup()) { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE); @@ -525,14 +530,14 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R BroadcastGroupUpdate(); // LFG group vote kick handled in scripts - if (isLFGGroup() && method == GROUP_REMOVEMETHOD_KICK) + if (isLFGGroup(true) && method == GROUP_REMOVEMETHOD_KICK) { sLFGMgr->InitBoot(GetGUID(), kicker, guid, std::string(reason ? reason : "")); return m_memberSlots.size() > 0; } // remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group) - if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u)) + if (GetMembersCount() > ((isBGGroup() || isLFGGroup(true) || isBFGroup()) ? 1u : 2u)) { Player* player = ObjectAccessor::FindConnectedPlayer(guid); if (player) @@ -654,7 +659,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R //return false; } - if (isLFGGroup() && GetMembersCount() == 1) + if (isLFGGroup(true) && GetMembersCount() == 1) { Player* leader = ObjectAccessor::FindConnectedPlayer(GetLeaderGUID()); uint32 mapId = sLFGMgr->GetDungeonMapId(GetGUID()); @@ -666,7 +671,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R } } - if (m_memberMgr.getSize() < ((isLFGGroup() || isBGGroup() || isBFGroup()) ? 1u : 2u)) + if (m_memberMgr.getSize() < ((isLFGGroup(true) || isBGGroup() || isBFGroup()) ? 1u : 2u)) { Disband(); return false; @@ -2118,9 +2123,10 @@ bool Group::IsFull() const return isRaidGroup() ? (m_memberSlots.size() >= MAXRAIDSIZE) : (m_memberSlots.size() >= MAXGROUPSIZE); } -bool Group::isLFGGroup() const +bool Group::isLFGGroup(bool restricted /*= false*/) const { - return m_groupType & GROUPTYPE_LFG; + bool isLFG = m_groupType & GROUPTYPE_LFG; + return isLFG && (!restricted || (m_groupType & GROUPTYPE_LFG_RESTRICTED) != 0); } bool Group::isRaidGroup() const diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 7d88f1192..37f827852 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -208,7 +208,7 @@ public: // properties accessories bool IsFull() const; - bool isLFGGroup() const; + bool isLFGGroup(bool restricted = false) const; bool isRaidGroup() const; bool isBFGroup() const; bool isBGGroup() const; @@ -242,7 +242,7 @@ public: uint8 GetMemberGroup(ObjectGuid guid) const; - void ConvertToLFG(); + void ConvertToLFG(bool restricted = true); void ConvertToRaid(); void SetBattlegroundGroup(Battleground* bg); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 976556203..56bcaf028 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -356,13 +356,13 @@ void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket& recvData) return; // Xinef: do not allow to kick with empty reason, this will resend packet with given reason - if (grp->isLFGGroup() && reason.empty()) + if (grp->isLFGGroup(true) && reason.empty()) { SendPartyResult(PARTY_OP_UNINVITE, name, ERR_VOTE_KICK_REASON_NEEDED); return; } - if (grp->IsLeader(guid) && !grp->isLFGGroup()) + if (grp->IsLeader(guid) && !grp->isLFGGroup(true)) { SendPartyResult(PARTY_OP_UNINVITE, name, ERR_NOT_LEADER); return; @@ -489,7 +489,7 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket& recvData) /** error handling **/ // Xinef: Check if group is LFG - if (!group->IsLeader(GetPlayer()->GetGUID()) || group->isLFGGroup()) + if (!group->IsLeader(GetPlayer()->GetGUID()) || group->isLFGGroup(true)) return; if (lootMethod > NEED_BEFORE_GREED)