aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorDehravor <dehravor@gmail.com>2014-03-16 19:12:01 +0100
committerDehravor <dehravor@gmail.com>2014-03-16 19:12:01 +0100
commit6a5c43b0d819fc43a3d46aa63fa7576a11e5761c (patch)
tree7d0a26d1ff26e68906c62d3545e6c9687d99cd96 /src/server/game
parent892d9eac79e94796e3b22e5be368063d59b20efc (diff)
Core/Loot: Implement round robin for under threshold items in case of master loot
Thanks @Shauren for pointing out
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp10
-rw-r--r--src/server/game/Groups/Group.cpp62
-rw-r--r--src/server/game/Groups/Group.h3
-rw-r--r--src/server/game/Groups/GroupMgr.cpp4
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp1
-rw-r--r--src/server/game/Handlers/LootHandler.cpp30
-rw-r--r--src/server/game/Loot/LootMgr.cpp16
8 files changed, 69 insertions, 61 deletions
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 822ae904ef1..d9df2057b54 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -60,8 +60,8 @@ void LFGMgr::_LoadFromDB(Field* fields, uint64 guid)
SetLeader(guid, MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER));
- uint32 dungeon = fields[16].GetUInt32();
- uint8 state = fields[17].GetUInt8();
+ uint32 dungeon = fields[17].GetUInt32();
+ uint8 state = fields[18].GetUInt8();
if (!dungeon || !state)
return;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index e78392e917f..2f7b37a2254 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -8835,7 +8835,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
switch (group->GetLootMethod())
{
case MASTER_LOOT:
- permission = group->GetLooterGuid() == GetGUID() ? MASTER_PERMISSION : RESTRICTED_PERMISSION;
+ permission = group->GetMasterLooterGuid() == GetGUID() ? MASTER_PERMISSION : RESTRICTED_PERMISSION;
break;
case FREE_FOR_ALL:
permission = ALL_PERMISSION;
@@ -9013,7 +9013,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
switch (group->GetLootMethod())
{
case MASTER_LOOT:
- permission = group->GetLooterGuid() == GetGUID() ? MASTER_PERMISSION : RESTRICTED_PERMISSION;
+ permission = group->GetMasterLooterGuid() == GetGUID() ? MASTER_PERMISSION : RESTRICTED_PERMISSION;
break;
case FREE_FOR_ALL:
permission = ALL_PERMISSION;
@@ -17794,7 +17794,6 @@ bool Player::isAllowedToLoot(const Creature* creature)
switch (thisGroup->GetLootMethod())
{
case FREE_FOR_ALL:
- case MASTER_LOOT:
return true;
case ROUND_ROBIN:
// may only loot if the player is the loot roundrobin player
@@ -17803,6 +17802,11 @@ bool Player::isAllowedToLoot(const Creature* creature)
return true;
return loot->hasItemFor(this);
+ case MASTER_LOOT:
+ // may loot if the player is the master looter
+ if (thisGroup->GetMasterLooterGuid() == GetGUID())
+ return true;
+ // fall-through
case GROUP_LOOT:
case NEED_BEFORE_GREED:
// may only loot if the player is the loot roundrobin player
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index abc4b19f3f2..699a67b5340 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -56,7 +56,7 @@ Loot* Roll::getLoot()
Group::Group() : m_leaderGuid(0), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL),
m_dungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL), m_raidDifficulty(RAID_DIFFICULTY_10MAN_NORMAL),
m_bgGroup(NULL), m_bfGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(0),
-m_subGroupsCounts(NULL), m_guid(0), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0)
+m_masterLooterGuid(0), m_subGroupsCounts(NULL), m_guid(0), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0)
{
for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
m_targetIcons[i] = 0;
@@ -112,6 +112,7 @@ bool Group::Create(Player* leader)
m_lootThreshold = ITEM_QUALITY_UNCOMMON;
m_looterGuid = leaderGuid;
+ m_masterLooterGuid = 0;
m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL;
m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
@@ -146,6 +147,7 @@ bool Group::Create(Player* leader)
stmt->setUInt8(index++, uint8(m_groupType));
stmt->setUInt32(index++, uint8(m_dungeonDifficulty));
stmt->setUInt32(index++, uint8(m_raidDifficulty));
+ stmt->setUInt32(index++, GUID_LOPART(m_masterLooterGuid));
CharacterDatabase.Execute(stmt);
@@ -162,7 +164,7 @@ bool Group::Create(Player* leader)
void Group::LoadGroupFromDB(Field* fields)
{
- m_dbStoreId = fields[15].GetUInt32();
+ m_dbStoreId = fields[16].GetUInt32();
m_guid = MAKE_NEW_GUID(sGroupMgr->GenerateGroupId(), 0, HIGHGUID_GROUP);
m_leaderGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
@@ -193,6 +195,8 @@ void Group::LoadGroupFromDB(Field* fields)
else
m_raidDifficulty = Difficulty(r_diff);
+ m_masterLooterGuid = MAKE_NEW_GUID(fields[15].GetUInt32(), 0, HIGHGUID_PLAYER);
+
if (m_groupType & GROUPTYPE_LFG)
sLFGMgr->_LoadFromDB(fields, GetGUID());
}
@@ -891,24 +895,15 @@ void Group::SendLooter(Creature* creature, Player* groupLooter)
WorldPacket data(SMSG_LOOT_LIST, (8+8));
data << uint64(creature->GetGUID());
- if (groupLooter)
- {
- if (GetLootMethod() == MASTER_LOOT)
- {
- data.append(groupLooter->GetPackGUID());
- data << uint8(0);
- }
- else
- {
- data << uint8(0);
- data.append(groupLooter->GetPackGUID());
- }
- }
+ if (GetLootMethod() == MASTER_LOOT)
+ data.appendPackGUID(GetMasterLooterGuid());
else
- {
data << uint8(0);
+
+ if (groupLooter)
+ data.append(groupLooter->GetPackGUID());
+ else
data << uint8(0);
- }
BroadcastPacket(&data, false);
}
@@ -1550,7 +1545,12 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot)
if (GetMembersCount() - 1)
{
data << uint8(m_lootMethod); // loot method
- data << uint64(m_looterGuid); // looter guid
+
+ if (m_lootMethod == MASTER_LOOT)
+ data << uint64(m_masterLooterGuid); // master looter guid
+ else
+ data << uint64(m_looterGuid); // looter guid
+
data << uint8(m_lootThreshold); // loot threshold
data << uint8(m_dungeonDifficulty); // Dungeon Difficulty
data << uint8(m_raidDifficulty); // Raid Difficulty
@@ -1706,7 +1706,7 @@ void Group::ChangeMembersGroup(uint64 guid, uint8 group)
// Retrieve the next Round-Roubin player for the group
//
-// No update done if loot method is Master or FFA.
+// No update done if loot method is FFA.
//
// If the RR player is not yet set for the group, the first group member becomes the round-robin player.
// If the RR player is set, the next player in group becomes the round-robin player.
@@ -1717,16 +1717,10 @@ void Group::ChangeMembersGroup(uint64 guid, uint8 group)
// if not, he loses his turn.
void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed)
{
- switch (GetLootMethod())
- {
- case MASTER_LOOT:
- case FREE_FOR_ALL:
- return;
- default:
- // round robin style looting applies for all low
- // quality items in each loot method except free for all and master loot
- break;
- }
+ // round robin style looting applies for all low
+ // quality items in each loot method except free for all
+ if (GetLootMethod() == FREE_FOR_ALL)
+ return;
uint64 oldLooterGUID = GetLooterGuid();
member_citerator guid_itr = _getMemberCSlot(oldLooterGUID);
@@ -2150,6 +2144,11 @@ void Group::SetLooterGuid(uint64 guid)
m_looterGuid = guid;
}
+void Group::SetMasterLooterGuid(uint64 guid)
+{
+ m_masterLooterGuid = guid;
+}
+
void Group::SetLootThreshold(ItemQualities threshold)
{
m_lootThreshold = threshold;
@@ -2225,6 +2224,11 @@ uint64 Group::GetLooterGuid() const
return m_looterGuid;
}
+uint64 Group::GetMasterLooterGuid() const
+{
+ return m_masterLooterGuid;
+}
+
ItemQualities Group::GetLootThreshold() const
{
return m_lootThreshold;
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 6336a1bb30c..64122b0cb4d 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -195,6 +195,7 @@ class Group
void ChangeLeader(uint64 guid);
void SetLootMethod(LootMethod method);
void SetLooterGuid(uint64 guid);
+ void SetMasterLooterGuid(uint64 guid);
void UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed = false);
void SetLootThreshold(ItemQualities threshold);
void Disband(bool hideDestroy=false);
@@ -213,6 +214,7 @@ class Group
const char * GetLeaderName() const;
LootMethod GetLootMethod() const;
uint64 GetLooterGuid() const;
+ uint64 GetMasterLooterGuid() const;
ItemQualities GetLootThreshold() const;
uint32 GetDbStoreId() const { return m_dbStoreId; };
@@ -332,6 +334,7 @@ class Group
LootMethod m_lootMethod;
ItemQualities m_lootThreshold;
uint64 m_looterGuid;
+ uint64 m_masterLooterGuid;
Rolls RollId;
BoundInstancesMap m_boundInstances[MAX_DIFFICULTY];
uint8* m_subGroupsCounts;
diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp
index 20e6a0671a5..39735f5dce3 100644
--- a/src/server/game/Groups/GroupMgr.cpp
+++ b/src/server/game/Groups/GroupMgr.cpp
@@ -123,8 +123,8 @@ void GroupMgr::LoadGroups()
// 0 1 2 3 4 5 6 7 8 9
QueryResult result = CharacterDatabase.Query("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");
+ // 10 11 12 13 14 15 16 17 18
+ ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.masterLooterGuid, 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)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 group definitions. DB table `groups` is empty!");
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index fd7d0602265..7e8f662df4c 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -438,6 +438,7 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket& recvData)
// everything's fine, do it
group->SetLootMethod((LootMethod)lootMethod);
+ group->SetMasterLooterGuid(lootMaster);
group->SetLooterGuid(lootMaster);
group->SetLootThreshold((ItemQualities)lootThreshold);
group->SendUpdate();
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index d1b60ed07fa..f92c6e08e31 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -297,17 +297,7 @@ void WorldSession::DoLootRelease(uint64 lguid)
// if the round robin player release, reset it.
if (player->GetGUID() == loot->roundRobinPlayer)
- {
- if (Group* group = player->GetGroup())
- {
- if (group->GetLootMethod() != MASTER_LOOT)
- {
- loot->roundRobinPlayer = 0;
- }
- }
- else
- loot->roundRobinPlayer = 0;
- }
+ loot->roundRobinPlayer = 0;
}
}
else if (IS_CORPSE_GUID(lguid)) // ONLY remove insignia at BG
@@ -376,19 +366,15 @@ void WorldSession::DoLootRelease(uint64 lguid)
// if the round robin player release, reset it.
if (player->GetGUID() == loot->roundRobinPlayer)
{
+ loot->roundRobinPlayer = 0;
+
if (Group* group = player->GetGroup())
{
- if (group->GetLootMethod() != MASTER_LOOT)
- {
- loot->roundRobinPlayer = 0;
- group->SendLooter(creature, NULL);
-
- // force update of dynamic flags, otherwise other group's players still not able to loot.
- creature->ForceValuesUpdateAtIndex(UNIT_DYNAMIC_FLAGS);
- }
+ group->SendLooter(creature, NULL);
+
+ // force update of dynamic flags, otherwise other group's players still not able to loot.
+ creature->ForceValuesUpdateAtIndex(UNIT_DYNAMIC_FLAGS);
}
- else
- loot->roundRobinPlayer = 0;
}
}
}
@@ -404,7 +390,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
recvData >> lootguid >> slotid >> target_playerguid;
- if (!_player->GetGroup() || _player->GetGroup()->GetLooterGuid() != _player->GetGUID() || _player->GetGroup()->GetLootMethod() != MASTER_LOOT)
+ if (!_player->GetGroup() || _player->GetGroup()->GetMasterLooterGuid() != _player->GetGUID() || _player->GetGroup()->GetLootMethod() != MASTER_LOOT)
{
_player->SendLootRelease(GetPlayer()->GetLootGUID());
return;
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 79056bcd750..cbb7036538c 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -555,7 +555,7 @@ QuestItemList* Loot::FillQuestLoot(Player* player)
{
LootItem &item = quest_items[i];
- if (!item.is_looted && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT ))))
+ if (!item.is_looted && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT))))
{
ql->push_back(QuestItem(i));
@@ -589,7 +589,7 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player, bool pres
for (uint8 i = 0; i < items.size(); ++i)
{
LootItem &item = items[i];
- if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT ))))
+ if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT))))
{
if (presentAtLooting)
item.AddAllowedLooter(player);
@@ -959,7 +959,17 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer))
{
- uint8 slot_type = l.items[i].is_blocked ? LOOT_SLOT_TYPE_LOCKED : LOOT_SLOT_TYPE_ALLOW_LOOT;
+ uint8 slot_type;
+
+ if (l.items[i].is_blocked)
+ slot_type = LOOT_SLOT_TYPE_LOCKED;
+ else
+ {
+ if (l.roundRobinPlayer == 0 || lv.viewer->GetGUID() == l.roundRobinPlayer)
+ slot_type = LOOT_SLOT_TYPE_ALLOW_LOOT;
+ else
+ continue; // item shall not be displayed
+ }
b << uint8(i) << l.items[i];
b << uint8(slot_type);