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:
Machiavelli
2010-12-24 18:55:50 +01:00
parent e57866ac9a
commit c05ed659cb
8 changed files with 271 additions and 135 deletions
+194 -54
View File
@@ -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()
+27 -6
View File
@@ -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()