*Make CreatureGroupHolder map-based to prevent crash when using multi-thread map.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-04-10 12:46:40 -05:00
parent d6f792d307
commit 0ce060ddd7
3 changed files with 40 additions and 49 deletions

View File

@@ -29,57 +29,46 @@
INSTANTIATE_SINGLETON_1(CreatureGroupManager);
CreatureGroupHolderType CreatureGroupHolder;
CreatureGroupInfoType CreatureGroupMap;
void CreatureGroupManager::AddCreatureToGroup(uint32 group_id, Creature *member)
void CreatureGroupManager::AddCreatureToGroup(uint32 groupId, Creature *member)
{
CreatureGroupHolderType::iterator cgroup_data = CreatureGroupHolder.find(group_id);
Map *map = member->FindMap();
if(!map)
return;
CreatureGroupHolderType::iterator itr = map->CreatureGroupHolder.find(groupId);
//Add member to an existing group
if(cgroup_data != CreatureGroupHolder.end())
if(itr != map->CreatureGroupHolder.end())
{
typedef std::multimap<uint32, CreatureGroup *>::iterator multiplegroup;
std::pair<multiplegroup, multiplegroup> range = CreatureGroupHolder.equal_range(group_id);
for(multiplegroup i = range.first; i != range.second; ++i)
{
if(i->second->getInstanceID() == member->GetInstanceId())
{
sLog.outDebug("Group found: %u, inserting creature GUID: %u, Group InstanceID %u", group_id, member->GetGUIDLow(), i->second->getInstanceID());
i->second->AddMember(member);
return;
}
}
sLog.outDebug("Group found: %u, inserting creature GUID: %u, Group InstanceID %u", groupId, member->GetGUIDLow(), member->GetInstanceId());
itr->second->AddMember(member);
}
//Create new group
sLog.outDebug("Group not found: %u. Creating new group.", group_id);
CreatureGroup* cgroup = new CreatureGroup(group_id, member->GetInstanceId());
CreatureGroupHolder.insert(std::make_pair(group_id, cgroup));
cgroup->AddMember(member);
else
{
sLog.outDebug("Group not found: %u. Creating new group.", groupId);
CreatureGroup* group = new CreatureGroup(groupId);
map->CreatureGroupHolder[groupId] = group;
group->AddMember(member);
}
}
void CreatureGroupManager::RemoveCreatureFromGroup(CreatureGroup *formation, Creature *member)
void CreatureGroupManager::RemoveCreatureFromGroup(CreatureGroup *group, Creature *member)
{
sLog.outDebug("Deleting member pointer to GUID: %u from group %u", formation->GetId(), member->GetDBTableGUIDLow());
formation->RemoveMember(member);
sLog.outDebug("Deleting member pointer to GUID: %u from group %u", group->GetId(), member->GetDBTableGUIDLow());
group->RemoveMember(member);
if(formation->isEmpty())
if(group->isEmpty())
{
uint32 id = formation->GetId();
typedef std::multimap<uint32, CreatureGroup *>::iterator multiplegroup;
std::pair<multiplegroup, multiplegroup> range = CreatureGroupHolder.equal_range(id);
Map *map = member->FindMap();
if(!map)
return;
for(multiplegroup i = range.first; i != range.second; ++i)
{
if(i->second == formation)
{
sLog.outDebug("Deleting group with InstanceID %u", i->second->getInstanceID());
CreatureGroupHolder.erase(i);
delete formation;
}
}
sLog.outDebug("Deleting group with InstanceID %u", member->GetInstanceId());
map->CreatureGroupHolder.erase(group->GetId());
delete group;
}
}
@@ -245,13 +234,12 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z)
float dx = x + cos(angle + pathangle) * dist;
float dy = y + sin(angle + pathangle) * dist;
Trinity::NormalizeMapCoord(dx);
Trinity::NormalizeMapCoord(dy);
float dz = z;
float dz = member->GetMap()->GetHeight(dx,dy,z,false);
member->UpdateGroundPositionZ(dx, dy, dz);
Trinity::NormalizeMapCoord(dx);
Trinity::NormalizeMapCoord(dy);
member->UpdateGroundPositionZ(dx, dy, dz);
if(member->GetDistance(m_leader) < dist + MAX_DESYNC)
member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());

View File

@@ -41,10 +41,8 @@ class CreatureGroupManager
void LoadCreatureFormations();
};
typedef std::multimap<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
typedef UNORDERED_MAP<uint32/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType;
extern CreatureGroupHolderType CreatureGroupHolder;
extern CreatureGroupInfoType CreatureGroupMap;
class CreatureGroup
@@ -54,17 +52,16 @@ class CreatureGroup
typedef std::map<Creature*, FormationInfo*> CreatureGroupMemberType;
CreatureGroupMemberType m_members;
uint32 m_groupID, mInstanceID;
uint32 m_groupID;
bool m_Formed;
public:
//Group cannot be created empty
explicit CreatureGroup(uint32 id, uint32 InstanceID) : m_groupID(id), m_leader(NULL), mInstanceID(InstanceID), m_Formed(false) {}
~CreatureGroup(){sLog.outDebug("Destroying group");}
explicit CreatureGroup(uint32 id) : m_groupID(id), m_leader(NULL), m_Formed(false) {}
~CreatureGroup() { sLog.outDebug("Destroying group"); }
Creature* getLeader() const { return m_leader; }
uint32 GetId() const { return m_groupID; }
uint32 getInstanceID() const { return mInstanceID; }
bool isEmpty() const { return m_members.empty(); }
bool isFormed() const { return m_Formed; }

View File

@@ -44,6 +44,7 @@ class Group;
class InstanceSave;
class WorldObject;
class TempSummon;
class CreatureGroup;
namespace ZThread
{
@@ -248,6 +249,8 @@ typedef UNORDERED_MAP<Creature*, CreatureMover> CreatureMoveList;
#define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE
#define MIN_UNLOAD_DELAY 1 // immediate unload
typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockable<Map, ZThread::Mutex>
{
friend class MapReference;
@@ -416,6 +419,9 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER &notifier);
TempSummon *SummonCreature(uint32 entry, float x, float y, float z, float angle, SummonPropertiesEntry const *properties = NULL, uint32 duration = 0, Unit *summoner = NULL);
CreatureGroupHolderType CreatureGroupHolder;
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);