aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Groups
diff options
context:
space:
mode:
authorSubv2112 <s.v.h.21@hotmail.com>2012-01-14 17:37:28 +0100
committerMachiavelli <machiavelli.trinity@gmail.com>2012-01-14 17:37:28 +0100
commitf4075f0f945c842fe2b1a08ea4a7fa253e8e2e53 (patch)
treebe27baca490ad8088774a2f7e7c20c319a766b01 /src/server/game/Groups
parentdbbac0bdaae4b6d8a0125999962c4a686092bd80 (diff)
Core/LFG:
Fix priority of the player when its added to the lfg group Better implementation of the Dungeon Deserter debuff Rewrite the NeedBeforeGreed loot Fixed players being shown as Unknown Entity when entering the lfg group Some incremental optimizations after original patch Thanks to Retriman and Paecman for base implementation Signed-off-by: Machiavelli <machiavelli.trinity@gmail.com>
Diffstat (limited to 'src/server/game/Groups')
-rwxr-xr-xsrc/server/game/Groups/Group.cpp121
-rwxr-xr-xsrc/server/game/Groups/Group.h3
-rw-r--r--src/server/game/Groups/GroupMgr.cpp8
-rwxr-xr-xsrc/server/game/Groups/GroupReference.cpp4
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);
}