mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 08:28:32 +01:00
*Make CreatureGroupHolder map-based to prevent crash when using multi-thread map.
--HG-- branch : trunk
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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 ¬ifier);
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user