*Make CreatureGroupHolder map-based to prevent crash when using multi-thread map.
--HG-- branch : trunk
This commit is contained in:
+30
-42
@@ -29,57 +29,46 @@
|
|||||||
|
|
||||||
INSTANTIATE_SINGLETON_1(CreatureGroupManager);
|
INSTANTIATE_SINGLETON_1(CreatureGroupManager);
|
||||||
|
|
||||||
CreatureGroupHolderType CreatureGroupHolder;
|
|
||||||
CreatureGroupInfoType CreatureGroupMap;
|
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
|
//Add member to an existing group
|
||||||
if(cgroup_data != CreatureGroupHolder.end())
|
if(itr != map->CreatureGroupHolder.end())
|
||||||
{
|
{
|
||||||
typedef std::multimap<uint32, CreatureGroup *>::iterator multiplegroup;
|
sLog.outDebug("Group found: %u, inserting creature GUID: %u, Group InstanceID %u", groupId, member->GetGUIDLow(), member->GetInstanceId());
|
||||||
std::pair<multiplegroup, multiplegroup> range = CreatureGroupHolder.equal_range(group_id);
|
itr->second->AddMember(member);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create new group
|
//Create new group
|
||||||
sLog.outDebug("Group not found: %u. Creating new group.", group_id);
|
else
|
||||||
CreatureGroup* cgroup = new CreatureGroup(group_id, member->GetInstanceId());
|
{
|
||||||
CreatureGroupHolder.insert(std::make_pair(group_id, cgroup));
|
sLog.outDebug("Group not found: %u. Creating new group.", groupId);
|
||||||
cgroup->AddMember(member);
|
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());
|
sLog.outDebug("Deleting member pointer to GUID: %u from group %u", group->GetId(), member->GetDBTableGUIDLow());
|
||||||
formation->RemoveMember(member);
|
group->RemoveMember(member);
|
||||||
|
|
||||||
if(formation->isEmpty())
|
if(group->isEmpty())
|
||||||
{
|
{
|
||||||
uint32 id = formation->GetId();
|
Map *map = member->FindMap();
|
||||||
typedef std::multimap<uint32, CreatureGroup *>::iterator multiplegroup;
|
if(!map)
|
||||||
std::pair<multiplegroup, multiplegroup> range = CreatureGroupHolder.equal_range(id);
|
return;
|
||||||
|
|
||||||
for(multiplegroup i = range.first; i != range.second; ++i)
|
sLog.outDebug("Deleting group with InstanceID %u", member->GetInstanceId());
|
||||||
{
|
map->CreatureGroupHolder.erase(group->GetId());
|
||||||
if(i->second == formation)
|
delete group;
|
||||||
{
|
|
||||||
sLog.outDebug("Deleting group with InstanceID %u", i->second->getInstanceID());
|
|
||||||
CreatureGroupHolder.erase(i);
|
|
||||||
delete formation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,13 +234,12 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z)
|
|||||||
|
|
||||||
float dx = x + cos(angle + pathangle) * dist;
|
float dx = x + cos(angle + pathangle) * dist;
|
||||||
float dy = y + sin(angle + pathangle) * dist;
|
float dy = y + sin(angle + pathangle) * dist;
|
||||||
|
float dz = z;
|
||||||
|
|
||||||
Trinity::NormalizeMapCoord(dx);
|
Trinity::NormalizeMapCoord(dx);
|
||||||
Trinity::NormalizeMapCoord(dy);
|
Trinity::NormalizeMapCoord(dy);
|
||||||
|
|
||||||
float dz = member->GetMap()->GetHeight(dx,dy,z,false);
|
member->UpdateGroundPositionZ(dx, dy, dz);
|
||||||
|
|
||||||
member->UpdateGroundPositionZ(dx, dy, dz);
|
|
||||||
|
|
||||||
if(member->GetDistance(m_leader) < dist + MAX_DESYNC)
|
if(member->GetDistance(m_leader) < dist + MAX_DESYNC)
|
||||||
member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
|
member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
|
||||||
|
|||||||
@@ -41,10 +41,8 @@ class CreatureGroupManager
|
|||||||
void LoadCreatureFormations();
|
void LoadCreatureFormations();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::multimap<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
|
|
||||||
typedef UNORDERED_MAP<uint32/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType;
|
typedef UNORDERED_MAP<uint32/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType;
|
||||||
|
|
||||||
extern CreatureGroupHolderType CreatureGroupHolder;
|
|
||||||
extern CreatureGroupInfoType CreatureGroupMap;
|
extern CreatureGroupInfoType CreatureGroupMap;
|
||||||
|
|
||||||
class CreatureGroup
|
class CreatureGroup
|
||||||
@@ -54,17 +52,16 @@ class CreatureGroup
|
|||||||
typedef std::map<Creature*, FormationInfo*> CreatureGroupMemberType;
|
typedef std::map<Creature*, FormationInfo*> CreatureGroupMemberType;
|
||||||
CreatureGroupMemberType m_members;
|
CreatureGroupMemberType m_members;
|
||||||
|
|
||||||
uint32 m_groupID, mInstanceID;
|
uint32 m_groupID;
|
||||||
bool m_Formed;
|
bool m_Formed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//Group cannot be created empty
|
//Group cannot be created empty
|
||||||
explicit CreatureGroup(uint32 id, uint32 InstanceID) : m_groupID(id), m_leader(NULL), mInstanceID(InstanceID), m_Formed(false) {}
|
explicit CreatureGroup(uint32 id) : m_groupID(id), m_leader(NULL), m_Formed(false) {}
|
||||||
~CreatureGroup(){sLog.outDebug("Destroying group");}
|
~CreatureGroup() { sLog.outDebug("Destroying group"); }
|
||||||
|
|
||||||
Creature* getLeader() const { return m_leader; }
|
Creature* getLeader() const { return m_leader; }
|
||||||
uint32 GetId() const { return m_groupID; }
|
uint32 GetId() const { return m_groupID; }
|
||||||
uint32 getInstanceID() const { return mInstanceID; }
|
|
||||||
bool isEmpty() const { return m_members.empty(); }
|
bool isEmpty() const { return m_members.empty(); }
|
||||||
bool isFormed() const { return m_Formed; }
|
bool isFormed() const { return m_Formed; }
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class Group;
|
|||||||
class InstanceSave;
|
class InstanceSave;
|
||||||
class WorldObject;
|
class WorldObject;
|
||||||
class TempSummon;
|
class TempSummon;
|
||||||
|
class CreatureGroup;
|
||||||
|
|
||||||
namespace ZThread
|
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 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
|
#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>
|
class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockable<Map, ZThread::Mutex>
|
||||||
{
|
{
|
||||||
friend class MapReference;
|
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 ¬ifier);
|
template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
||||||
|
|
||||||
TempSummon *SummonCreature(uint32 entry, float x, float y, float z, float angle, SummonPropertiesEntry const *properties = NULL, uint32 duration = 0, Unit *summoner = NULL);
|
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:
|
private:
|
||||||
void LoadMapAndVMap(int gx, int gy);
|
void LoadMapAndVMap(int gx, int gy);
|
||||||
void LoadVMap(int gx, int gy);
|
void LoadVMap(int gx, int gy);
|
||||||
|
|||||||
Reference in New Issue
Block a user