Core/Entities:
- Rename creature_linked_respawn to linked_respawn - Update functionality: add field ´linkType´. ** 0 = creature respawn dependant on creature (default) ** 1 = creature respawn dependant on gameobject ** 2 = gameobject respawn dependant on gameobject ** 3 = gameobject respawn dependant on creature --HG-- branch : trunk
This commit is contained in:
@@ -1179,92 +1179,232 @@ void ObjectMgr::LoadCreatureModelInfo()
|
||||
sLog->outString();
|
||||
}
|
||||
|
||||
bool ObjectMgr::CheckCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid) const
|
||||
{
|
||||
const CreatureData* const slave = GetCreatureData(guid);
|
||||
const CreatureData* const master = GetCreatureData(linkedGuid);
|
||||
|
||||
if (!slave || !master) // they must have a corresponding entry in db
|
||||
{
|
||||
sLog->outErrorDb("LinkedRespawn: Creature '%u' linking to '%u' which doesn't exist",guid,linkedGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
const MapEntry* const map = sMapStore.LookupEntry(master->mapid);
|
||||
|
||||
if (master->mapid != slave->mapid // link only to same map
|
||||
&& (!map || map->Instanceable())) // or to unistanced world
|
||||
{
|
||||
sLog->outErrorDb("LinkedRespawn: Creature '%u' linking to '%u' on an unpermitted map",guid,linkedGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(master->spawnMask & slave->spawnMask) // they must have a possibility to meet (normal/heroic difficulty)
|
||||
&& (!map || map->Instanceable()))
|
||||
{
|
||||
sLog->outErrorDb("LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask",guid,linkedGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureLinkedRespawn()
|
||||
void ObjectMgr::LoadLinkedRespawn()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
mCreatureLinkedRespawnMap.clear();
|
||||
QueryResult result = WorldDatabase.Query("SELECT guid, linkedGuid FROM creature_linked_respawn ORDER BY guid ASC");
|
||||
mLinkedRespawnMap.clear();
|
||||
QueryResult result = WorldDatabase.Query("SELECT guid, linkedGuid, linkType FROM linked_respawn ORDER BY guid ASC");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog->outErrorDb(">> Loaded 0 linked respawns. DB table `creature_linked_respawn` is empty.");
|
||||
sLog->outErrorDb(">> Loaded 0 linked respawns. DB table `linked_respawn` is empty.");
|
||||
sLog->outString();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
uint32 guid = fields[0].GetUInt32();
|
||||
uint32 linkedGuid = fields[1].GetUInt32();
|
||||
uint32 guidLow = fields[0].GetUInt32();
|
||||
uint32 linkedGuidLow = fields[1].GetUInt32();
|
||||
uint8 linkType = fields[2].GetUInt8();
|
||||
|
||||
if (CheckCreatureLinkedRespawn(guid,linkedGuid))
|
||||
mCreatureLinkedRespawnMap[guid] = linkedGuid;
|
||||
uint64 guid, linkedGuid;
|
||||
bool error = false;
|
||||
switch (linkType)
|
||||
{
|
||||
case CREATURE_TO_CREATURE:
|
||||
{
|
||||
const CreatureData* slave = GetCreatureData(guidLow);
|
||||
if (!slave)
|
||||
{
|
||||
sLog->outErrorDb("Couldn't get creature data for GUIDLow %u", guidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
} while (result->NextRow());
|
||||
const CreatureData* master = GetCreatureData(linkedGuidLow);
|
||||
if (!master)
|
||||
{
|
||||
sLog->outErrorDb("Couldn't get creature data for GUIDLow %u", linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
sLog->outString(">> Loaded " UI64FMTD " linked respawns in %u ms", uint64(mCreatureLinkedRespawnMap.size()), GetMSTimeDiffToNow(oldMSTime));
|
||||
const MapEntry* const map = sMapStore.LookupEntry(master->mapid);
|
||||
if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
|
||||
{
|
||||
sLog->outErrorDb("Creature '%u' linking to '%u' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
|
||||
{
|
||||
sLog->outErrorDb("LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
guid = MAKE_NEW_GUID(guidLow, slave->id, HIGHGUID_UNIT);
|
||||
linkedGuid = MAKE_NEW_GUID(linkedGuidLow, master->id, HIGHGUID_UNIT);
|
||||
break;
|
||||
}
|
||||
case CREATURE_TO_GO:
|
||||
{
|
||||
const CreatureData* slave = GetCreatureData(guidLow);
|
||||
if (!slave)
|
||||
{
|
||||
sLog->outErrorDb("Couldn't get creature data for GUIDLow %u", guidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const GameObjectData* master = GetGOData(linkedGuidLow);
|
||||
if (!master)
|
||||
{
|
||||
sLog->outErrorDb("Couldn't get gameobject data for GUIDLow %u", linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const MapEntry* const map = sMapStore.LookupEntry(master->mapid);
|
||||
if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
|
||||
{
|
||||
sLog->outErrorDb("Creature '%u' linking to '%u' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
|
||||
{
|
||||
sLog->outErrorDb("LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
guid = MAKE_NEW_GUID(guidLow, slave->id, HIGHGUID_UNIT);
|
||||
linkedGuid = MAKE_NEW_GUID(linkedGuidLow, master->id, HIGHGUID_GAMEOBJECT);
|
||||
break;
|
||||
}
|
||||
case GO_TO_GO:
|
||||
{
|
||||
const GameObjectData* slave = GetGOData(guidLow);
|
||||
if (!slave)
|
||||
{
|
||||
sLog->outErrorDb("Couldn't get gameobject data for GUIDLow %u", guidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const GameObjectData* master = GetGOData(linkedGuidLow);
|
||||
if (!master)
|
||||
{
|
||||
sLog->outErrorDb("Couldn't get gameobject data for GUIDLow %u", linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const MapEntry* const map = sMapStore.LookupEntry(master->mapid);
|
||||
if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
|
||||
{
|
||||
sLog->outErrorDb("Creature '%u' linking to '%u' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
|
||||
{
|
||||
sLog->outErrorDb("LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
guid = MAKE_NEW_GUID(guidLow, slave->id, HIGHGUID_GAMEOBJECT);
|
||||
linkedGuid = MAKE_NEW_GUID(linkedGuidLow, master->id, HIGHGUID_GAMEOBJECT);
|
||||
break;
|
||||
}
|
||||
case GO_TO_CREATURE:
|
||||
{
|
||||
const GameObjectData* slave = GetGOData(guidLow);
|
||||
if (!slave)
|
||||
{
|
||||
sLog->outErrorDb("Couldn't get gameobject data for GUIDLow %u", guidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const CreatureData* master = GetCreatureData(linkedGuidLow);
|
||||
if (!master)
|
||||
{
|
||||
sLog->outErrorDb("Couldn't get creature data for GUIDLow %u", linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const MapEntry* const map = sMapStore.LookupEntry(master->mapid);
|
||||
if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
|
||||
{
|
||||
sLog->outErrorDb("Creature '%u' linking to '%u' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
|
||||
{
|
||||
sLog->outErrorDb("LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
guid = MAKE_NEW_GUID(guidLow, slave->id, HIGHGUID_GAMEOBJECT);
|
||||
linkedGuid = MAKE_NEW_GUID(linkedGuidLow, master->id, HIGHGUID_UNIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!error)
|
||||
mLinkedRespawnMap[guid] = linkedGuid;
|
||||
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog->outString(">> Loaded " UI64FMTD " linked respawns in %u ms", uint64(mLinkedRespawnMap.size()), GetMSTimeDiffToNow(oldMSTime));
|
||||
sLog->outString();
|
||||
}
|
||||
|
||||
bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid)
|
||||
bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guidLow, uint32 linkedGuidLow)
|
||||
{
|
||||
if (!guid)
|
||||
if (!guidLow)
|
||||
return false;
|
||||
|
||||
if (!linkedGuid) // we're removing the linking
|
||||
const CreatureData* master = GetCreatureData(guidLow);
|
||||
uint64 guid = MAKE_NEW_GUID(guidLow, master->id, HIGHGUID_UNIT);
|
||||
|
||||
if (!linkedGuidLow) // we're removing the linking
|
||||
{
|
||||
mCreatureLinkedRespawnMap.erase(guid);
|
||||
mLinkedRespawnMap.erase(guid);
|
||||
PreparedStatement *stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CRELINKED_RESPAWN);
|
||||
stmt->setUInt32(0, guid);
|
||||
stmt->setUInt32(0, guidLow);
|
||||
WorldDatabase.Execute(stmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CheckCreatureLinkedRespawn(guid,linkedGuid)) // we add/change linking
|
||||
const CreatureData* slave = GetCreatureData(linkedGuidLow);
|
||||
|
||||
const MapEntry* const map = sMapStore.LookupEntry(master->mapid);
|
||||
if (!map || !map->Instanceable() || (master->mapid != slave->mapid))
|
||||
{
|
||||
mCreatureLinkedRespawnMap[guid] = linkedGuid;
|
||||
PreparedStatement *stmt = WorldDatabase.GetPreparedStatement(WORLD_REP_CRELINKED_RESPAWN);
|
||||
stmt->setUInt32(0, guid);
|
||||
stmt->setUInt32(1, linkedGuid);
|
||||
WorldDatabase.Execute(stmt);
|
||||
return true;
|
||||
sLog->outErrorDb("Creature '%u' linking to '%u' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty)
|
||||
{
|
||||
sLog->outErrorDb("LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64 linkedGuid = MAKE_NEW_GUID(linkedGuidLow, slave->id, HIGHGUID_UNIT);
|
||||
|
||||
mLinkedRespawnMap[guid] = linkedGuid;
|
||||
PreparedStatement *stmt = WorldDatabase.GetPreparedStatement(WORLD_REP_CRELINKED_RESPAWN);
|
||||
stmt->setUInt32(0, guidLow);
|
||||
stmt->setUInt32(1, linkedGuidLow);
|
||||
WorldDatabase.Execute(stmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatures()
|
||||
|
||||
@@ -379,7 +379,7 @@ struct TrinityStringLocale
|
||||
StringVector Content;
|
||||
};
|
||||
|
||||
typedef std::map<uint32,uint32> CreatureLinkedRespawnMap;
|
||||
typedef std::map<uint64,uint64> LinkedRespawnMap;
|
||||
typedef UNORDERED_MAP<uint32,CreatureData> CreatureDataMap;
|
||||
typedef UNORDERED_MAP<uint32,GameObjectData> GameObjectDataMap;
|
||||
typedef UNORDERED_MAP<uint32,CreatureLocale> CreatureLocaleMap;
|
||||
@@ -866,7 +866,6 @@ class ObjectMgr
|
||||
void CheckCreatureTemplate(CreatureInfo const* cInfo);
|
||||
void LoadCreatures();
|
||||
void LoadCreatureLinkedRespawn();
|
||||
bool CheckCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid) const;
|
||||
bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid);
|
||||
void LoadCreatureRespawnTimes();
|
||||
void LoadCreatureAddons();
|
||||
@@ -980,10 +979,10 @@ class ObjectMgr
|
||||
}
|
||||
CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }
|
||||
void DeleteCreatureData(uint32 guid);
|
||||
uint32 GetLinkedRespawnGuid(uint32 guid) const
|
||||
uint64 GetLinkedRespawnGuid(uint64 guid) const
|
||||
{
|
||||
CreatureLinkedRespawnMap::const_iterator itr = mCreatureLinkedRespawnMap.find(guid);
|
||||
if (itr == mCreatureLinkedRespawnMap.end()) return 0;
|
||||
LinkedRespawnMap::const_iterator itr = mLinkedRespawnMap.find(guid);
|
||||
if (itr == mLinkedRespawnMap.end()) return 0;
|
||||
return itr->second;
|
||||
}
|
||||
CreatureLocale const* GetCreatureLocale(uint32 entry) const
|
||||
@@ -1073,6 +1072,20 @@ class ObjectMgr
|
||||
void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance);
|
||||
void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid);
|
||||
|
||||
time_t GetLinkedRespawnTime(uint64 guid, uint32 instance)
|
||||
{
|
||||
uint64 linkedGuid = GetLinkedRespawnGuid(guid);
|
||||
switch (GUID_HIPART(linkedGuid))
|
||||
{
|
||||
case HIGHGUID_UNIT:
|
||||
return GetCreatureRespawnTime(GUID_LOPART(linkedGuid), instance);
|
||||
case HIGHGUID_GAMEOBJECT:
|
||||
return GetGORespawnTime(GUID_LOPART(linkedGuid), instance);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance)
|
||||
{
|
||||
ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, m_CreatureRespawnTimesMtx, 0);
|
||||
@@ -1319,7 +1332,7 @@ class ObjectMgr
|
||||
|
||||
MapObjectGuids mMapObjectGuids;
|
||||
CreatureDataMap mCreatureDataMap;
|
||||
CreatureLinkedRespawnMap mCreatureLinkedRespawnMap;
|
||||
LinkedRespawnMap mLinkedRespawnMap;
|
||||
CreatureLocaleMap mCreatureLocaleMap;
|
||||
GameObjectDataMap mGameObjectDataMap;
|
||||
GameObjectLocaleMap mGameObjectLocaleMap;
|
||||
@@ -1343,6 +1356,14 @@ class ObjectMgr
|
||||
std::set<uint32> difficultyEntries[MAX_DIFFICULTY - 1]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate
|
||||
std::set<uint32> hasDifficultyEntries[MAX_DIFFICULTY - 1]; // already loaded creatures with difficulty 1 values, used in CheckCreatureTemplate
|
||||
|
||||
enum CreatureLinkedRespawnType
|
||||
{
|
||||
CREATURE_TO_CREATURE,
|
||||
CREATURE_TO_GO, // Creature is dependant on GO
|
||||
GO_TO_GO,
|
||||
GO_TO_CREATURE, // GO is dependant on creature
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#define sObjectMgr ACE_Singleton<ObjectMgr, ACE_Null_Mutex>::instance()
|
||||
|
||||
Reference in New Issue
Block a user