diff options
Diffstat (limited to 'src/server/game/Groups')
| -rwxr-xr-x | src/server/game/Groups/Group.cpp | 121 | ||||
| -rwxr-xr-x | src/server/game/Groups/Group.h | 3 | ||||
| -rw-r--r-- | src/server/game/Groups/GroupMgr.cpp | 8 | ||||
| -rwxr-xr-x | src/server/game/Groups/GroupReference.cpp | 4 |
4 files changed, 97 insertions, 39 deletions
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 49472880edd..b2fb59ea993 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -190,6 +190,9 @@ void Group::LoadGroupFromDB(Field* fields) m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; else m_raidDifficulty = Difficulty(r_diff); + + if (m_groupType & GROUPTYPE_LFG) + sLFGMgr->_LoadFromDB(fields, GetGUID()); } void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles) @@ -211,6 +214,14 @@ void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, m_memberSlots.push_back(member); SubGroupCounterIncrease(subgroup); + + if (isLFGGroup()) + { + LfgDungeonSet Dungeons; + Dungeons.insert(sLFGMgr->GetDungeon(GetGUID())); + sLFGMgr->SetSelectedDungeons(member.guid, Dungeons); + sLFGMgr->SetState(member.guid, sLFGMgr->GetState(GetGUID())); + } } void Group::ConvertToLFG() @@ -441,7 +452,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV return m_memberSlots.size(); // remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG allow 1 member group) - if (GetMembersCount() > (isBGGroup() ? 1u : 2u)) + if (GetMembersCount() > ((isBGGroup() || isLFGGroup()) ? 1u : 2u)) { Player* player = ObjectAccessor::FindPlayer(guid); if (player) @@ -485,6 +496,8 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV CharacterDatabase.Execute(stmt); + DelinkMember(guid); + // Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline if ((player && player->GetSkillValue(SKILL_ENCHANTING)) || !player) ResetMaxEnchantingLevel(); @@ -534,6 +547,20 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV } SendUpdate(); + + if (isLFGGroup() && GetMembersCount() == 1) + { + Player* Leader = ObjectAccessor::FindPlayer(GetLeaderGUID()); + LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(sLFGMgr->GetDungeon(GetGUID())); + if ((Leader && dungeon && Leader->isAlive() && Leader->GetMapId() != dungeon->map) || !dungeon) + { + Disband(); + return false; + } + } + + if (m_memberMgr.getSize() < ((isLFGGroup() || isBGGroup()) ? 1u : 2u)) + Disband(); return true; } @@ -673,6 +700,10 @@ void Group::Disband(bool hideDestroy /* = false */) CharacterDatabase.CommitTransaction(trans); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA); + stmt->setUInt32(0, m_dbStoreId); + CharacterDatabase.Execute(stmt); sGroupMgr->FreeGroupDbStoreId(this); } @@ -709,6 +740,28 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r) } } +void Group::SendLootStartRollToPlayer(uint32 CountDown, uint32 mapid, Player* p, bool NeedBlocked, const Roll &r) +{ + if (!p || !p->GetSession()) + return; + + WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1 )); + data << uint64(r.itemGUID); // guid of rolled item + data << uint32(mapid); // 3.3.3 mapid + data << uint32(r.totalPlayersRolling); // maybe the number of players rolling for it??? + data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for + data << uint32(r.itemRandomSuffix); // randomSuffix + data << uint32(r.itemRandomPropId); // item random property ID + data << uint32(r.itemCount); // items in stack + data << uint32(CountDown); // the countdown time to choose "need" or "greed" + uint8 VoteMask = r.rollVoteMask; + if (NeedBlocked) + VoteMask &= ~ROLL_FLAG_TYPE_NEED; + data << uint8(VoteMask); // roll type mask + + p->GetSession()->SendPacket(&data); +} + void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) { WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1)); @@ -887,7 +940,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) } } -void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject) +void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) { ItemTemplate const* item; uint8 itemSlot = 0; @@ -902,7 +955,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject) if (item->Quality >= uint32(m_lootThreshold)) { uint64 newitemGUID = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), 0, HIGHGUID_ITEM); - Roll* r=new Roll(newitemGUID, *i); + Roll* r = new Roll(newitemGUID, *i); for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { @@ -911,21 +964,17 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject) continue; bool allowedForPlayer = i->AllowedForPlayer(playerToRoll); - if (playerToRoll->CanUseItem(item) == EQUIP_ERR_OK && allowedForPlayer) + if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false)) { - if (playerToRoll->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false)) + r->totalPlayersRolling++; + if (playerToRoll->GetPassOnGroupLoot()) { - r->totalPlayersRolling++; - - if (playerToRoll->GetPassOnGroupLoot()) - { - r->playerVote[playerToRoll->GetGUID()] = PASS; - r->totalPass++; - // can't broadcast the pass now. need to wait until all rolling players are known. - } - else - r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET; + r->playerVote[playerToRoll->GetGUID()] = PASS; + r->totalPass++; + // can't broadcast the pass now. need to wait until all rolling players are known. } + else + r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET; } } @@ -941,25 +990,24 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject) loot->items[itemSlot].is_blocked = true; - // If there is any "auto pass", broadcast the pass now. - if (r->totalPass) + //Broadcast Pass and Send Rollstart + for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr) { - for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr) - { - Player* p = ObjectAccessor::FindPlayer(itr->first); - if (!p || !p->GetSession()) - continue; - - if (itr->second == PASS) - SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r); - } + Player* p = ObjectAccessor::FindPlayer(itr->first); + if (!p || !p->GetSession()) + continue; + + if (itr->second == PASS) + SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r); + if (p->CanRollForItem(item) == EQUIP_ERR_OK) + SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, false, *r); + else + SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, true, *r); } - SendLootStartRoll(60000, pLootedObject->GetMapId(), *r); - RollId.push_back(r); - if (Creature* creature = pLootedObject->ToCreature()) + if (Creature* creature = lootedObject->ToCreature()) { creature->m_groupLootTimer = 60000; creature->lootingGroupLowGUID = GetLowGUID(); @@ -1242,9 +1290,7 @@ void Group::SendTargetIconList(WorldSession* session) void Group::SendUpdate() { for (member_witerator witr = m_memberSlots.begin(); witr != m_memberSlots.end(); ++witr) - { SendUpdateToPlayer(witr->guid, &(*witr)); - } } void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot) @@ -2118,8 +2164,19 @@ void Group::LinkMember(GroupReference* pRef) m_memberMgr.insertFirst(pRef); } -void Group::DelinkMember(GroupReference* /*pRef*/) const +void Group::DelinkMember(uint64 guid) { + GroupReference* ref = m_memberMgr.getFirst(); + while (ref) + { + GroupReference* nextRef = ref->next(); + if (ref->getSource()->GetGUID() == guid) + { + ref->unlink(); + break; + } + ref = nextRef; + } } Group::BoundInstancesMap& Group::GetBoundInstances(Difficulty difficulty) diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index bed112d5511..caa49125100 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -273,6 +273,7 @@ class Group bool isRollLootActive() const; void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r); + void SendLootStartRollToPlayer(uint32 CountDown, uint32 mapid, Player* p, bool NeedBlocked, const Roll &r); void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r); @@ -289,7 +290,7 @@ class Group void ResetMaxEnchantingLevel(); void LinkMember(GroupReference* pRef); - void DelinkMember(GroupReference* /*pRef*/) const; + void DelinkMember(uint64 guid); InstanceGroupBind* BindToInstance(InstanceSave* save, bool permanent, bool load = false); void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false); diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp index 412814a60d2..ae400852c73 100644 --- a/src/server/game/Groups/GroupMgr.cpp +++ b/src/server/game/Groups/GroupMgr.cpp @@ -119,10 +119,10 @@ void GroupMgr::LoadGroups() // Delete all groups with less than 2 members CharacterDatabase.DirectExecute("DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)"); - // 0 1 2 3 4 5 6 7 8 9 - QueryResult result = CharacterDatabase.PQuery("SELECT leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6" - // 10 11 12 13 14 15 - ", icon7, icon8, groupType, difficulty, raiddifficulty, guid FROM groups ORDER BY guid ASC"); + // 0 1 2 3 4 5 6 7 8 9 + QueryResult result = CharacterDatabase.PQuery("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6" + // 10 11 12 13 14 15 16 17 + ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC"); if (!result) { sLog->outString(">> Loaded 0 group definitions. DB table `groups` is empty!"); diff --git a/src/server/game/Groups/GroupReference.cpp b/src/server/game/Groups/GroupReference.cpp index 4d5890aa4e6..68d85c5bce9 100755 --- a/src/server/game/Groups/GroupReference.cpp +++ b/src/server/game/Groups/GroupReference.cpp @@ -28,12 +28,12 @@ void GroupReference::targetObjectBuildLink() void GroupReference::targetObjectDestroyLink() { // called from unlink() - getTarget()->DelinkMember(this); + //getTarget()->DelinkMember(this); } void GroupReference::sourceObjectDestroyLink() { // called from invalidate() - getTarget()->DelinkMember(this); + //getTarget()->DelinkMember(this); } |
