Skip to content

Commit

Permalink
[9327] Replace leader based indexing groups by group ids.
Browse files Browse the repository at this point in the history
* This must repolve problem with loot.
  Before if some mob killed by group member and then leader changed
  then group members can't loot this mob body.
* Possible resolve crashes at loot. Now group storage content not dependent from leader changes.
  • Loading branch information
VladimirMangos committed Feb 8, 2010
1 parent 8fba9cc commit a01ddd4
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 42 deletions.
8 changes: 4 additions & 4 deletions src/game/Creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)

Creature::Creature(CreatureSubtype subtype) :
Unit(), i_AI(NULL),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), m_groupLootId(0),
m_lootMoney(0), m_lootRecipient(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0),
Expand Down Expand Up @@ -395,18 +395,18 @@ void Creature::Update(uint32 diff)
else
{
m_deathTimer -= diff;
if (m_groupLootTimer && lootingGroupLeaderGUID)
if (m_groupLootTimer && m_groupLootId)
{
if(diff <= m_groupLootTimer)
{
m_groupLootTimer -= diff;
}
else
{
if (Group* group = sObjectMgr.GetGroupByLeaderLowGUID(GUID_LOPART(lootingGroupLeaderGUID)))
if (Group* group = sObjectMgr.GetGroupById(m_groupLootId))
group->EndRoll();
m_groupLootTimer = 0;
lootingGroupLeaderGUID = 0;
m_groupLootId = 0;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/Creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
void SetRespawnRadius(float dist) { m_respawnradius = dist; }

uint32 m_groupLootTimer; // (msecs)timer used for group loot
uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse
uint32 m_groupLootId; // used to find group which is looting corpse

void SendZoneUnderAttackMessage(Player* attacker);

Expand Down
26 changes: 9 additions & 17 deletions src/game/Group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,11 @@
#include "MapInstanced.h"
#include "Util.h"

Group::Group()
Group::Group() : m_Id(0), m_leaderGuid(0), m_mainTank(0), m_mainAssistant(0), m_groupType(GROUPTYPE_NORMAL),
m_dungeonDifficulty(REGULAR_DIFFICULTY), m_raidDifficulty(REGULAR_DIFFICULTY),
m_bgGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_looterGuid(0), m_lootThreshold(ITEM_QUALITY_UNCOMMON),
m_subGroupsCounts(NULL)
{
m_leaderGuid = 0;
m_mainTank = 0;
m_mainAssistant = 0;
m_groupType = (GroupType)0;
m_bgGroup = NULL;
m_lootMethod = (LootMethod)0;
m_looterGuid = 0;
m_lootThreshold = ITEM_QUALITY_UNCOMMON;
m_subGroupsCounts = NULL;

for (int i = 0; i < TARGETICONCOUNT; ++i)
m_targetIcons[i] = 0;
}
Expand Down Expand Up @@ -123,7 +116,10 @@ bool Group::Create(const uint64 &guid, const char * name)
return false;

if(!isBGGroup())
{
CharacterDatabase.CommitTransaction();
m_Id = sObjectMgr.GenerateGroupId();
}

return true;
}
Expand Down Expand Up @@ -194,6 +190,7 @@ bool Group::LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result, bool
return false;
}

m_Id = sObjectMgr.GenerateGroupId();
return true;
}

Expand Down Expand Up @@ -616,7 +613,7 @@ void Group::GroupLoot(const uint64& playerGUID, Loot *loot, Creature *creature)

loot->items[itemSlot].is_blocked = true;
creature->m_groupLootTimer = 60000;
creature->lootingGroupLeaderGUID = GetLeaderGUID();
creature->m_groupLootId = GetId();

RollId.push_back(r);
}
Expand Down Expand Up @@ -1256,11 +1253,6 @@ void Group::_setLeader(const uint64 &guid)

m_leaderGuid = slot->guid;
m_leaderName = slot->name;

// Non-BG groups stored in sObjectMgr with leader low-guids as keys
if (IsCreated() && !isBGGroup())
sObjectMgr.UpdateGroup(old_guidlow,this);

}

void Group::_removeRolls(const uint64 &guid)
Expand Down
2 changes: 2 additions & 0 deletions src/game/Group.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class MANGOS_DLL_SPEC Group
void Disband(bool hideDestroy=false);

// properties accessories
uint32 GetId() const { return m_Id; }
bool IsFull() const { return (m_groupType==GROUPTYPE_NORMAL) ? (m_memberSlots.size()>=MAXGROUPSIZE) : (m_memberSlots.size()>=MAXRAIDSIZE); }
bool isRaidGroup() const { return m_groupType==GROUPTYPE_RAID; }
bool isBGGroup() const { return m_bgGroup != NULL; }
Expand Down Expand Up @@ -402,6 +403,7 @@ class MANGOS_DLL_SPEC Group
--m_subGroupsCounts[subgroup];
}

uint32 m_Id; // 0 for not created or BG groups
MemberSlotList m_memberSlots;
GroupRefManager m_memberMgr;
InvitesList m_invitees;
Expand Down
8 changes: 5 additions & 3 deletions src/game/GroupHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,12 @@ void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data )
// forming a new group, create it
if(!group->IsCreated())
{
if( leader )
if (leader)
group->RemoveInvite(leader);
group->Create(group->GetLeaderGUID(), group->GetLeaderName());
sObjectMgr.AddGroup(group);
if (group->Create(group->GetLeaderGUID(), group->GetLeaderName()))
sObjectMgr.AddGroup(group);
else
return;
}

// everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
Expand Down
52 changes: 39 additions & 13 deletions src/game/ObjectMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ ObjectMgr::ObjectMgr()
m_guildId = 1;
m_arenaTeamId = 1;
m_auctionid = 1;
m_groupId = 1;

// Only zero condition left, others will be added while loading DB tables
mConditions.resize(1);
Expand Down Expand Up @@ -180,16 +181,26 @@ ObjectMgr::~ObjectMgr()
itr->second.Clear();
}

Group * ObjectMgr::GetGroupByLeaderLowGUID(uint32 guid) const
Group* ObjectMgr::GetGroupById(uint32 id) const
{
GroupMap::const_iterator itr = mGroupMap.find(guid);
GroupMap::const_iterator itr = mGroupMap.find(id);
if (itr != mGroupMap.end())
return itr->second;

return NULL;
}

Guild * ObjectMgr::GetGuildById(uint32 GuildId) const
Group* ObjectMgr::GetGroupByLeaderLowGUID(uint32 guid) const
{
for(GroupMap::const_iterator itr = mGroupMap.begin(); itr != mGroupMap.end(); ++itr)
if (GUID_LOPART(itr->second->GetLeaderGUID())==guid)
return itr->second;

return NULL;
}


Guild* ObjectMgr::GetGuildById(uint32 GuildId) const
{
GuildMap::const_iterator itr = mGuildMap.find(GuildId);
if (itr != mGuildMap.end())
Expand Down Expand Up @@ -3124,6 +3135,8 @@ void ObjectMgr::LoadGroups()
return;
}

std::map<uint32,uint32> leader2groupMap;

barGoLink bar( result->GetRowCount() );

do
Expand All @@ -3140,6 +3153,7 @@ void ObjectMgr::LoadGroups()
continue;
}
AddGroup(group);
leader2groupMap[GUID_LOPART(leaderGuid)] = group->GetId();
}while( result->NextRow() );

delete result;
Expand Down Expand Up @@ -3173,7 +3187,11 @@ void ObjectMgr::LoadGroups()
uint32 leaderGuidLow = fields[3].GetUInt32();
if(!group || GUID_LOPART(group->GetLeaderGUID()) != leaderGuidLow)
{
group = GetGroupByLeaderLowGUID(leaderGuidLow);
// find group id in map by leader low guid
std::map<uint32,uint32>::const_iterator l2g_itr = leader2groupMap.find(leaderGuidLow);
if (l2g_itr != leader2groupMap.end())
group = GetGroupById(l2g_itr->second);

if(!group)
{
sLog.outErrorDb("Incorrect entry in group_member table : no group with leader %d for member %d!", leaderGuidLow, memberGuidlow);
Expand Down Expand Up @@ -3237,7 +3255,11 @@ void ObjectMgr::LoadGroups()

if(!group || GUID_LOPART(group->GetLeaderGUID()) != leaderGuidLow)
{
group = GetGroupByLeaderLowGUID(leaderGuidLow);
// find group id in map by leader low guid
std::map<uint32,uint32>::const_iterator l2g_itr = leader2groupMap.find(leaderGuidLow);
if (l2g_itr != leader2groupMap.end())
group = GetGroupById(l2g_itr->second);

if(!group)
{
sLog.outErrorDb("Incorrect entry in group_instance table : no group with leader %d", leaderGuidLow);
Expand Down Expand Up @@ -5706,6 +5728,16 @@ uint32 ObjectMgr::GenerateGuildId()
return m_guildId++;
}

uint32 ObjectMgr::GenerateGroupId()
{
if(m_groupId>=0xFFFFFFFE)
{
sLog.outError("Group ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_groupId++;
}

uint32 ObjectMgr::GenerateMailID()
{
if(m_mailid>=0xFFFFFFFE)
Expand Down Expand Up @@ -8426,18 +8458,12 @@ void ObjectMgr::RemoveGuild( uint32 Id )

void ObjectMgr::AddGroup( Group* group )
{
mGroupMap[GUID_LOPART(group->GetLeaderGUID())] = group ;
mGroupMap[group->GetId()] = group ;
}

void ObjectMgr::RemoveGroup( Group* group )
{
mGroupMap.erase(GUID_LOPART(group->GetLeaderGUID()));
}

void ObjectMgr::UpdateGroup( uint32 old_guidlow, Group* group )
{
mGroupMap.erase(old_guidlow);
AddGroup(group);
mGroupMap.erase(group->GetId());
}

void ObjectMgr::AddArenaTeam( ArenaTeam* arenaTeam )
Expand Down
8 changes: 5 additions & 3 deletions src/game/ObjectMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,10 @@ class ObjectMgr
void LoadGameobjectInfo();
void AddGameobjectInfo(GameObjectInfo *goinfo);

Group * GetGroupByLeaderLowGUID(uint32 lowguid) const;
Group* GetGroupById(uint32 id) const;
Group* GetGroupByLeaderLowGUID(uint32 guid) const; // slow way by leader guid
void AddGroup(Group* group);
void RemoveGroup(Group* group);
void UpdateGroup(uint32 old_guidlow, Group* group); // when need update leader guid as group key

Guild* GetGuildByLeader(uint64 const&guid) const;
Guild* GetGuildById(uint32 GuildId) const;
Expand Down Expand Up @@ -656,6 +656,7 @@ class ObjectMgr
uint32 GenerateAuctionID();
uint64 GenerateEquipmentSetGuid();
uint32 GenerateGuildId();
uint32 GenerateGroupId();
uint32 GenerateItemTextID();
uint32 GenerateMailID();
uint32 GeneratePetNumber();
Expand Down Expand Up @@ -894,8 +895,9 @@ class ObjectMgr
uint32 m_ItemTextId;
uint32 m_mailid;
uint32 m_hiPetNumber;
uint32 m_groupId;

// first free low guid for seelcted guid type
// first free low guid for selected guid type
uint32 m_hiCharGuid;
uint32 m_hiCreatureGuid;
uint32 m_hiItemGuid;
Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9326"
#define REVISION_NR "9327"
#endif // __REVISION_NR_H__

0 comments on commit a01ddd4

Please sign in to comment.