mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[11994] Implement creature_linking by guid
This commit is contained in:
parent
74e3e55668
commit
d41974b38b
6 changed files with 258 additions and 73 deletions
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
|||
`version` varchar(120) default NULL,
|
||||
`creature_ai_version` varchar(120) default NULL,
|
||||
`cache_id` int(10) default '0',
|
||||
`required_11985_01_mangos_gameobject_template_scripts` bit(1) default NULL
|
||||
`required_11994_01_mangos_creature_linking` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -966,6 +966,28 @@ LOCK TABLES `creature_involvedrelation` WRITE;
|
|||
/*!40000 ALTER TABLE `creature_involvedrelation` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `creature_linking`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS creature_linking;
|
||||
CREATE TABLE `creature_linking` (
|
||||
`guid` int(10) UNSIGNED NOT NULL COMMENT 'creature.guid of the slave mob that is linked',
|
||||
`master_guid` int(10) UNSIGNED NOT NULL COMMENT 'master to trigger events',
|
||||
`flag` mediumint(8) UNSIGNED NOT NULL COMMENT 'flag - describing what should happen when',
|
||||
PRIMARY KEY (`guid`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature Linking System';
|
||||
|
||||
|
||||
--
|
||||
-- Dumping data for table `creature_linking`
|
||||
--
|
||||
|
||||
LOCK TABLES `creature_linking` WRITE;
|
||||
/*!40000 ALTER TABLE `creature_linking` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `creature_linking` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `creature_linking_template`
|
||||
--
|
||||
|
|
|
|||
13
sql/updates/11994_01_mangos_creature_linking.sql
Normal file
13
sql/updates/11994_01_mangos_creature_linking.sql
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_11985_01_mangos_gameobject_template_scripts required_11994_01_mangos_creature_linking bit;
|
||||
|
||||
--
|
||||
-- Table structure for table `creature_linking`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS creature_linking;
|
||||
CREATE TABLE `creature_linking` (
|
||||
`guid` int(10) UNSIGNED NOT NULL COMMENT 'creature.guid of the slave mob that is linked',
|
||||
`master_guid` int(10) UNSIGNED NOT NULL COMMENT 'master to trigger events',
|
||||
`flag` mediumint(8) UNSIGNED NOT NULL COMMENT 'flag - describing what should happen when',
|
||||
PRIMARY KEY (`guid`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature Linking System';
|
||||
|
|
@ -43,15 +43,20 @@
|
|||
|
||||
INSTANTIATE_SINGLETON_1(CreatureLinkingMgr);
|
||||
|
||||
#define INVALID_MAP_ID 0xFFFFFFFF
|
||||
|
||||
/* *********************************************************
|
||||
* Method to Load From DB
|
||||
* DB Format: entry, map, master_entry, flag
|
||||
* 0 1 2 3
|
||||
* DB Format: entry, map, master_entry, flag, search_radius for `creature_linking_template` (by entry)
|
||||
* 0 1 2 3 4
|
||||
* DB Format: guid, master_guid, flag for `creature_linking` (by guid)
|
||||
* 0 1 2
|
||||
* **************************************
|
||||
* entry: creature_template.entry
|
||||
* map: Map on which the NPC has to be
|
||||
* master_entry creature_template.entry of the npc, that shall trigger the actions
|
||||
* flag: flag value, of type CreatureLinkingFlags
|
||||
* entry/guid: creature_template.entry/guid
|
||||
* map: Map on which the NPC has to be
|
||||
* master_entry/master_guid creature_template.entry of the npc, that shall trigger the actions
|
||||
* flag: flag value, of type CreatureLinkingFlags
|
||||
* search_radius: radius, in which master and slave must be spawned so that they are linked together
|
||||
*
|
||||
* ***************************************************** */
|
||||
|
||||
|
|
@ -59,7 +64,9 @@ void CreatureLinkingMgr::LoadFromDB()
|
|||
{
|
||||
// Clear maps
|
||||
m_creatureLinkingMap.clear();
|
||||
m_creatureLinkingGuidMap.clear();
|
||||
m_eventTriggers.clear(); // master
|
||||
m_eventGuidTriggers.clear();
|
||||
|
||||
QueryResult* result = WorldDatabase.Query("SELECT entry, map, master_entry, flag, search_range FROM creature_linking_template");
|
||||
|
||||
|
|
@ -77,7 +84,6 @@ void CreatureLinkingMgr::LoadFromDB()
|
|||
}
|
||||
|
||||
BarGoLink bar((int)result->GetRowCount());
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
|
|
@ -92,7 +98,7 @@ void CreatureLinkingMgr::LoadFromDB()
|
|||
tmp.searchRange = fields[4].GetUInt16();
|
||||
tmp.masterDBGuid = 0; // Will be initialized for unique mobs later (only for spawning dependend)
|
||||
|
||||
if (!IsLinkingEntryValid(entry, &tmp))
|
||||
if (!IsLinkingEntryValid(entry, &tmp, true))
|
||||
continue;
|
||||
|
||||
// Store db-guid for master of whom pTmp is spawn dependend (only non-local bosses)
|
||||
|
|
@ -117,55 +123,136 @@ void CreatureLinkingMgr::LoadFromDB()
|
|||
while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded creature linking for %u creature-IDs", count);
|
||||
sLog.outString(">> Loaded creature linking for %u creature-entries", count);
|
||||
|
||||
delete result;
|
||||
|
||||
result = WorldDatabase.Query("SELECT guid, master_guid, flag FROM creature_linking");
|
||||
|
||||
count = 0;
|
||||
|
||||
if (!result)
|
||||
{
|
||||
BarGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString(">> Table creature_linking is empty.");
|
||||
sLog.outString();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BarGoLink guidBar((int)result->GetRowCount());
|
||||
do
|
||||
{
|
||||
guidBar.step();
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
CreatureLinkingInfo tmp;
|
||||
|
||||
uint32 guid = fields[0].GetUInt32();
|
||||
tmp.mapId = INVALID_MAP_ID; // some invalid value, this marks the guid-linking
|
||||
tmp.masterId = fields[1].GetUInt32();
|
||||
tmp.linkingFlag = fields[2].GetUInt16();
|
||||
tmp.masterDBGuid = tmp.masterId;
|
||||
tmp.searchRange = 0;
|
||||
|
||||
if (!IsLinkingEntryValid(guid, &tmp, false))
|
||||
continue;
|
||||
|
||||
++count;
|
||||
|
||||
// Add it to the map
|
||||
m_creatureLinkingGuidMap.insert(CreatureLinkingMap::value_type(guid, tmp));
|
||||
|
||||
// Store master_guid
|
||||
m_eventGuidTriggers.insert(tmp.masterId);
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded creature linking for %u creature-Guids", count);
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
// This function is used to check if a DB-Entry is valid
|
||||
bool CreatureLinkingMgr::IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingInfo* pTmp)
|
||||
bool CreatureLinkingMgr::IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingInfo* pTmp, bool byEntry)
|
||||
{
|
||||
// Basic checks first
|
||||
CreatureInfo const* pInfo = ObjectMgr::GetCreatureTemplate(slaveEntry);
|
||||
if (!pInfo)
|
||||
if (byEntry) // Entry given
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has a non existing slave_entry (ID: %u), skipped.", slaveEntry);
|
||||
return false;
|
||||
}
|
||||
CreatureInfo const* pInfo = ObjectMgr::GetCreatureTemplate(slaveEntry);
|
||||
CreatureInfo const* pMasterInfo = ObjectMgr::GetCreatureTemplate(pTmp->masterId);
|
||||
|
||||
pInfo = ObjectMgr::GetCreatureTemplate(pTmp->masterId);
|
||||
if (!pInfo)
|
||||
if (!pInfo)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has a non existing slave_entry (slave: %u, master %u), skipped.", slaveEntry, pTmp->masterId);
|
||||
return false;
|
||||
}
|
||||
if (!pMasterInfo)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has a non existing master_entry (slave: %u, master %u), skipped", slaveEntry, pTmp->masterId);
|
||||
return false;
|
||||
}
|
||||
if (pTmp->mapId && !sMapStore.LookupEntry(pTmp->mapId))
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has a non existing map %u (slave %u, master %u), skipped", pTmp->mapId, slaveEntry, pTmp->masterId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // guid given
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has a non existing master_entry (ID: %u), skipped", pTmp->masterId);
|
||||
return false;
|
||||
CreatureData const* slaveData = sObjectMgr.GetCreatureData(slaveEntry);
|
||||
CreatureData const* masterData = sObjectMgr.GetCreatureData(pTmp->masterId);
|
||||
|
||||
if (!slaveData)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking` has a non existing slave (guid: %u, master_guid %u), skipped", slaveEntry, pTmp->masterId);
|
||||
return false;
|
||||
}
|
||||
if (!masterData)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking` has a non existing master (guid: %u,, master_guid: %u), skipped", slaveEntry, pTmp->masterId);
|
||||
return false;
|
||||
}
|
||||
if (slaveData->mapid != masterData->mapid)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking` has a slave and master on different maps (guid: %u, master_guid: %u), skipped", slaveEntry, pTmp->masterId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pTmp->linkingFlag & ~(LINKING_FLAG_INVALID - 1) || pTmp->linkingFlag == 0)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has invalid flag, (entry: %u, map: %u, flags: %u), skipped", slaveEntry, pTmp->mapId, pTmp->linkingFlag);
|
||||
sLog.outErrorDb("`creature_linking%s` has invalid flag, (entry: %u, map: %u, flags: %u), skipped", byEntry ? "_template" : "", slaveEntry, pTmp->mapId, pTmp->linkingFlag);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Additional checks, depending on flags
|
||||
if (pTmp->linkingFlag & FLAG_DESPAWN_ON_RESPAWN && slaveEntry == pTmp->masterId)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has pointless FLAG_DESPAWN_ON_RESPAWN for self, (entry: %u, map: %u), skipped", slaveEntry, pTmp->mapId);
|
||||
sLog.outErrorDb("`creature_linking%s` has pointless FLAG_DESPAWN_ON_RESPAWN for self, (entry: %u, map: %u), skipped", byEntry ? "_template" : "", slaveEntry, pTmp->mapId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for uniqueness of mob whom is followed, on whom spawning is dependend
|
||||
if (pTmp->searchRange == 0 && pTmp->linkingFlag & (FLAG_FOLLOW | FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE))
|
||||
if (byEntry)
|
||||
{
|
||||
// Painfully slow, needs better idea
|
||||
QueryResult *result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id=%u AND map=%u", pTmp->masterId, pTmp->mapId);
|
||||
if (result)
|
||||
// Check for uniqueness of mob whom is followed, on whom spawning is dependend
|
||||
if (pTmp->searchRange == 0 && pTmp->linkingFlag & (FLAG_FOLLOW | FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE))
|
||||
{
|
||||
if ((*result)[0].GetUInt32() > 1)
|
||||
sLog.outErrorDb("`creature_linking_template` has FLAG_FOLLOW, but non unique master, (entry: %u, map: %u, master: %u)", slaveEntry, pTmp->mapId, pTmp->masterId);
|
||||
delete result;
|
||||
// Painfully slow, needs better idea
|
||||
QueryResult *result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id=%u AND map=%u", pTmp->masterId, pTmp->mapId);
|
||||
if (result)
|
||||
{
|
||||
if ((*result)[0].GetUInt32() > 1)
|
||||
sLog.outErrorDb("`creature_linking_template` has FLAG_FOLLOW, but non unique master, (entry: %u, map: %u, master: %u)", slaveEntry, pTmp->mapId, pTmp->masterId);
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All checks are passed, entry is valid
|
||||
// All checks are passed, entry/guid is valid
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -182,11 +269,14 @@ enum EventMask
|
|||
// This functions checks if the NPC has linked NPCs for dynamic action
|
||||
bool CreatureLinkingMgr::IsLinkedEventTrigger(Creature* pCreature)
|
||||
{
|
||||
// TODO could actually be improved to also check for the map
|
||||
// Depends if we want to cache this bool into Creature or not
|
||||
// Entry case
|
||||
if (m_eventTriggers.find(pCreature->GetEntry()) != m_eventTriggers.end())
|
||||
return true;
|
||||
|
||||
// Guid case
|
||||
if (m_eventGuidTriggers.find(pCreature->GetGUIDLow()) != m_eventGuidTriggers.end())
|
||||
return true;
|
||||
|
||||
// Also return true for npcs that trigger reverse actions, or for followers(needed in respawn)
|
||||
if (CreatureLinkingInfo const* pInfo = GetLinkedTriggerInformation(pCreature))
|
||||
return pInfo->linkingFlag & EVENT_MASK_TRIGGER_TO;
|
||||
|
|
@ -195,6 +285,7 @@ bool CreatureLinkingMgr::IsLinkedEventTrigger(Creature* pCreature)
|
|||
}
|
||||
|
||||
// This function check if the NPC is a master to other NPCs
|
||||
// return true only for masters stored by entry - this prevents adding them to master-holder maps
|
||||
bool CreatureLinkingMgr::IsLinkedMaster(Creature* pCreature)
|
||||
{
|
||||
return m_eventTriggers.find(pCreature->GetEntry()) != m_eventTriggers.end();
|
||||
|
|
@ -212,7 +303,13 @@ bool CreatureLinkingMgr::IsSpawnedByLinkedMob(Creature* pCreature)
|
|||
// Depends of the map
|
||||
CreatureLinkingInfo const* CreatureLinkingMgr::GetLinkedTriggerInformation(Creature* pCreature)
|
||||
{
|
||||
CreatureLinkingMapBounds bounds = m_creatureLinkingMap.equal_range(pCreature->GetEntry());
|
||||
// guid case
|
||||
CreatureLinkingMapBounds bounds = m_creatureLinkingGuidMap.equal_range(pCreature->GetGUIDLow());
|
||||
for (CreatureLinkingMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter)
|
||||
return &(iter->second);
|
||||
|
||||
// entry case
|
||||
bounds = m_creatureLinkingMap.equal_range(pCreature->GetEntry());
|
||||
for (CreatureLinkingMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter)
|
||||
{
|
||||
if (iter->second.mapId == pCreature->GetMapId())
|
||||
|
|
@ -229,6 +326,31 @@ void CreatureLinkingHolder::AddSlaveToHolder(Creature* pCreature)
|
|||
if (!pInfo)
|
||||
return;
|
||||
|
||||
if (pInfo->mapId == INVALID_MAP_ID) // Guid case, store master->slaves for fast access
|
||||
{
|
||||
HolderMapBounds bounds = m_holderGuidMap.equal_range(pInfo->masterId);
|
||||
for (HolderMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
{
|
||||
if (itr->second.linkingFlag == pInfo->linkingFlag)
|
||||
{
|
||||
itr->second.linkedGuids.push_back(pCreature->GetObjectGuid());
|
||||
pCreature = NULL; // Store that is was handled
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a new flag, insert new entry
|
||||
if (pCreature)
|
||||
{
|
||||
InfoAndGuids tmp;
|
||||
tmp.linkedGuids.push_back(pCreature->GetObjectGuid());
|
||||
tmp.linkingFlag = pInfo->linkingFlag;
|
||||
tmp.searchRange = 0;
|
||||
m_holderGuidMap.insert(HolderMap::value_type(pInfo->masterId, tmp));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// First try to find holder with same flag
|
||||
HolderMapBounds bounds = m_holderMap.equal_range(pInfo->masterId);
|
||||
for (HolderMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
|
|
@ -258,7 +380,7 @@ void CreatureLinkingHolder::AddMasterToHolder(Creature* pCreature)
|
|||
if (pCreature->IsPet())
|
||||
return;
|
||||
|
||||
// Only add master NPCs
|
||||
// Only add master NPCs (by entry)
|
||||
if (!sCreatureLinkingMgr.IsLinkedMaster(pCreature))
|
||||
return;
|
||||
|
||||
|
|
@ -290,15 +412,19 @@ void CreatureLinkingHolder::DoCreatureLinkingEvent(CreatureLinkingEvent eventTyp
|
|||
|
||||
switch (eventType)
|
||||
{
|
||||
case LINKING_EVENT_AGGRO: eventFlagFilter = EVENT_MASK_ON_AGGRO; reverseEventFlagFilter = FLAG_TO_AGGRO_ON_AGGRO; break;
|
||||
case LINKING_EVENT_EVADE: eventFlagFilter = EVENT_MASK_ON_EVADE; reverseEventFlagFilter = FLAG_TO_RESPAWN_ON_EVADE; break;
|
||||
case LINKING_EVENT_DIE: eventFlagFilter = EVENT_MASK_ON_DIE; reverseEventFlagFilter = 0; break;
|
||||
case LINKING_EVENT_AGGRO: eventFlagFilter = EVENT_MASK_ON_AGGRO; reverseEventFlagFilter = FLAG_TO_AGGRO_ON_AGGRO; break;
|
||||
case LINKING_EVENT_EVADE: eventFlagFilter = EVENT_MASK_ON_EVADE; reverseEventFlagFilter = FLAG_TO_RESPAWN_ON_EVADE; break;
|
||||
case LINKING_EVENT_DIE: eventFlagFilter = EVENT_MASK_ON_DIE; reverseEventFlagFilter = 0; break;
|
||||
case LINKING_EVENT_RESPAWN: eventFlagFilter = EVENT_MASK_ON_RESPAWN; reverseEventFlagFilter = FLAG_FOLLOW; break;
|
||||
}
|
||||
|
||||
// Process Slaves
|
||||
// Process Slaves (by entry)
|
||||
HolderMapBounds bounds = m_holderMap.equal_range(pSource->GetEntry());
|
||||
// Get all holders for this boss
|
||||
for (HolderMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
ProcessSlaveGuidList(eventType, pSource, itr->second.linkingFlag & eventFlagFilter, itr->second.searchRange, itr->second.linkedGuids, pEnemy);
|
||||
|
||||
// Process Slaves (by guid)
|
||||
bounds = m_holderGuidMap.equal_range(pSource->GetGUIDLow());
|
||||
for (HolderMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
|
||||
ProcessSlaveGuidList(eventType, pSource, itr->second.linkingFlag & eventFlagFilter, itr->second.searchRange, itr->second.linkedGuids, pEnemy);
|
||||
|
||||
|
|
@ -307,31 +433,44 @@ void CreatureLinkingHolder::DoCreatureLinkingEvent(CreatureLinkingEvent eventTyp
|
|||
{
|
||||
if (pInfo->linkingFlag & reverseEventFlagFilter)
|
||||
{
|
||||
BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId);
|
||||
for (BossGuidMap::iterator itr = finds.first; itr != finds.second; ++itr)
|
||||
Creature* pMaster = NULL;
|
||||
if (pInfo->mapId != INVALID_MAP_ID) // entry case
|
||||
{
|
||||
Creature* pMaster = pSource->GetMap()->GetCreature(itr->second);
|
||||
if (pMaster && IsSlaveInRangeOfBoss(pSource, pMaster, pInfo->searchRange))
|
||||
BossGuidMapBounds finds = m_masterGuid.equal_range(pInfo->masterId);
|
||||
for (BossGuidMap::iterator itr = finds.first; itr != finds.second; ++itr)
|
||||
{
|
||||
switch (eventType)
|
||||
{
|
||||
case LINKING_EVENT_AGGRO:
|
||||
if (pMaster->IsControlledByPlayer())
|
||||
return;
|
||||
pMaster = pSource->GetMap()->GetCreature(itr->second);
|
||||
if (pMaster && IsSlaveInRangeOfBoss(pSource, pMaster, pInfo->searchRange))
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // guid case
|
||||
{
|
||||
CreatureData const* masterData = sObjectMgr.GetCreatureData(pInfo->masterDBGuid);
|
||||
CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(masterData->id);
|
||||
pMaster = pSource->GetMap()->GetCreature(ObjectGuid(cInfo->GetHighGuid(), cInfo->Entry, pInfo->masterDBGuid));
|
||||
}
|
||||
|
||||
if (pMaster->isInCombat())
|
||||
pMaster->SetInCombatWith(pEnemy);
|
||||
else
|
||||
pMaster->AI()->AttackStart(pEnemy);
|
||||
break;
|
||||
case LINKING_EVENT_EVADE:
|
||||
if (!pMaster->isAlive())
|
||||
pMaster->Respawn();
|
||||
break;
|
||||
case LINKING_EVENT_RESPAWN:
|
||||
if (pMaster->isAlive())
|
||||
SetFollowing(pSource, pMaster);
|
||||
}
|
||||
if (pMaster)
|
||||
{
|
||||
switch (eventType)
|
||||
{
|
||||
case LINKING_EVENT_AGGRO:
|
||||
if (pMaster->IsControlledByPlayer())
|
||||
return;
|
||||
|
||||
if (pMaster->isInCombat())
|
||||
pMaster->SetInCombatWith(pEnemy);
|
||||
else
|
||||
pMaster->AI()->AttackStart(pEnemy);
|
||||
break;
|
||||
case LINKING_EVENT_EVADE:
|
||||
if (!pMaster->isAlive())
|
||||
pMaster->Respawn();
|
||||
break;
|
||||
case LINKING_EVENT_RESPAWN:
|
||||
if (pMaster->isAlive())
|
||||
SetFollowing(pSource, pMaster);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ struct CreatureLinkingInfo
|
|||
uint32 mapId;
|
||||
uint32 masterId;
|
||||
uint32 masterDBGuid;
|
||||
uint16 linkingFlag;
|
||||
uint16 searchRange;
|
||||
uint16 linkingFlag:16;
|
||||
uint16 searchRange:16;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -121,12 +121,15 @@ class CreatureLinkingMgr
|
|||
|
||||
// Storage of Data: npc_entry_slave, (map, npc_entry_master, flag, master_db_guid[If Unique], search_range)
|
||||
CreatureLinkingMap m_creatureLinkingMap;
|
||||
// Storage of Data: npc_guid_slave, (map, npc_guid_master, flag, master_db_guid, search_range)
|
||||
CreatureLinkingMap m_creatureLinkingGuidMap;
|
||||
|
||||
// Lookup Storage for fast access:
|
||||
UNORDERED_SET<uint32> m_eventTriggers; // master
|
||||
UNORDERED_SET<uint32> m_eventTriggers; // master by entry
|
||||
UNORDERED_SET<uint32> m_eventGuidTriggers; // master by guid
|
||||
|
||||
// Check-routine
|
||||
bool IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingInfo* pInfo);
|
||||
bool IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingInfo* pInfo, bool byEntry);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -158,15 +161,21 @@ class CreatureLinkingHolder
|
|||
|
||||
private:
|
||||
typedef std::list<ObjectGuid> GuidList;
|
||||
// Structure associated to a master
|
||||
// Structure associated to a master (entry case)
|
||||
struct InfoAndGuids
|
||||
{
|
||||
uint16 linkingFlag;
|
||||
uint16 searchRange;
|
||||
uint16 linkingFlag:16;
|
||||
uint16 searchRange:16;
|
||||
GuidList linkedGuids;
|
||||
};
|
||||
// Structure associated to a master (guid case)
|
||||
struct InfoAndGuid
|
||||
{
|
||||
uint16 linkingFlag;
|
||||
ObjectGuid linkedGuid;
|
||||
};
|
||||
|
||||
typedef std::multimap<uint32 /*masterEntry*/, InfoAndGuids> HolderMap;
|
||||
typedef std::multimap<uint32 /*masterEntryOrGuid*/, InfoAndGuids> HolderMap;
|
||||
typedef std::pair<HolderMap::iterator, HolderMap::iterator> HolderMapBounds;
|
||||
typedef std::multimap<uint32 /*Entry*/, ObjectGuid> BossGuidMap;
|
||||
typedef std::pair<BossGuidMap::iterator, BossGuidMap::iterator> BossGuidMapBounds;
|
||||
|
|
@ -180,8 +189,10 @@ class CreatureLinkingHolder
|
|||
// Helper function to return if a slave is in range of a boss
|
||||
bool IsSlaveInRangeOfBoss(Creature* pSlave, Creature* pBoss, uint16 searchRange);
|
||||
|
||||
// Storage of Data (boss, flag) GuidList for action triggering
|
||||
// Storage of Data (boss, flag, searchRange, GuidList) for action triggering
|
||||
HolderMap m_holderMap;
|
||||
// Storage of Data (boss, flag, slave-guid)
|
||||
HolderMap m_holderGuidMap;
|
||||
// boss_entry, guid for reverse action triggering and check alive
|
||||
BossGuidMap m_masterGuid;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11993"
|
||||
#define REVISION_NR "11994"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_11785_02_characters_instance"
|
||||
#define REVISION_DB_MANGOS "required_11985_01_mangos_gameobject_template_scripts"
|
||||
#define REVISION_DB_MANGOS "required_11994_01_mangos_creature_linking"
|
||||
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue