mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
[11827] Implement Creature Linking via database
Thanks to Silverice for feedback! This system interprets the content of the table `creature_linking_template`. To trigger different actions on different events of the npcs that are linked together. Possible event/ action combinations can be taken form the flags in CreatureLinkingMgr.h::CreatureLinkingFlags
This commit is contained in:
parent
6edfcea7f0
commit
fbdd79141c
16 changed files with 783 additions and 7 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_11813_01_mangos_mangos_string` bit(1) default NULL
|
||||
`required_11827_01_mangos_creature_linking_template` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -945,6 +945,28 @@ LOCK TABLES `creature_involvedrelation` WRITE;
|
|||
/*!40000 ALTER TABLE `creature_involvedrelation` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `creature_linking_template`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS creature_linking_template;
|
||||
CREATE TABLE creature_linking_template (
|
||||
entry INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'creature_template.entry of the slave mob that is linked',
|
||||
map MEDIUMINT(8) UNSIGNED NOT NULL COMMENT 'Id of map of the mobs',
|
||||
master_entry 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 (entry, map)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature Linking System';
|
||||
|
||||
--
|
||||
-- Dumping data for table `creature_linking_template`
|
||||
--
|
||||
|
||||
LOCK TABLES `creature_linking_template` WRITE;
|
||||
/*!40000 ALTER TABLE `creature_linking_template` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `creature_linking_template` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `creature_loot_template`
|
||||
--
|
||||
|
|
|
|||
10
sql/updates/11827_01_mangos_creature_linking_template.sql
Normal file
10
sql/updates/11827_01_mangos_creature_linking_template.sql
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_11813_01_mangos_mangos_string required_11827_01_mangos_creature_linking_template bit;
|
||||
|
||||
DROP TABLE IF EXISTS creature_linking_template;
|
||||
CREATE TABLE creature_linking_template (
|
||||
entry INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'creature_template.entry of the slave mob that is linked',
|
||||
map MEDIUMINT(8) UNSIGNED NOT NULL COMMENT 'Id of map of the mobs',
|
||||
master_entry 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 (entry, map)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature Linking System';
|
||||
|
|
@ -46,6 +46,7 @@
|
|||
#include "GridNotifiersImpl.h"
|
||||
#include "CellImpl.h"
|
||||
#include "movement/MoveSplineInit.h"
|
||||
#include "CreatureLinkingMgr.h"
|
||||
|
||||
// apply implementation of the singletons
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
|
@ -469,7 +470,7 @@ void Creature::Update(uint32 update_diff, uint32 diff)
|
|||
break;
|
||||
case DEAD:
|
||||
{
|
||||
if( m_respawnTime <= time(NULL) )
|
||||
if (m_respawnTime <= time(NULL) && (!m_isSpawningLinked || GetMap()->GetCreatureLinkingHolder()->CanSpawn(this)))
|
||||
{
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Respawning...");
|
||||
m_respawnTime = 0;
|
||||
|
|
@ -506,6 +507,9 @@ void Creature::Update(uint32 update_diff, uint32 diff)
|
|||
if (AI())
|
||||
AI()->JustRespawned();
|
||||
|
||||
if (m_isCreatureLinkingTrigger)
|
||||
GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_RESPAWN, this);
|
||||
|
||||
GetMap()->Add(this);
|
||||
}
|
||||
break;
|
||||
|
|
@ -771,6 +775,15 @@ bool Creature::Create(uint32 guidlow, CreatureCreatePos& cPos, CreatureInfo cons
|
|||
break;
|
||||
}
|
||||
|
||||
// Add to CreatureLinkingHolder if needed
|
||||
if (sCreatureLinkingMgr.GetLinkedTriggerInformation(this))
|
||||
cPos.GetMap()->GetCreatureLinkingHolder()->AddSlaveToHolder(this);
|
||||
if (sCreatureLinkingMgr.IsLinkedEventTrigger(this))
|
||||
{
|
||||
m_isCreatureLinkingTrigger = true;
|
||||
cPos.GetMap()->GetCreatureLinkingHolder()->AddMasterToHolder(this);
|
||||
}
|
||||
|
||||
LoadCreatureAddon();
|
||||
|
||||
return true;
|
||||
|
|
@ -1315,6 +1328,23 @@ bool Creature::LoadFromDB(uint32 guidlow, Map *map)
|
|||
curhealth = 1;
|
||||
}
|
||||
|
||||
if (sCreatureLinkingMgr.IsSpawnedByLinkedMob(this))
|
||||
{
|
||||
m_isSpawningLinked = true;
|
||||
if (m_deathState == ALIVE && !GetMap()->GetCreatureLinkingHolder()->CanSpawn(this))
|
||||
{
|
||||
m_deathState = DEAD;
|
||||
|
||||
// Just set to dead, so need to relocate like above
|
||||
if (CanFly())
|
||||
{
|
||||
float tz = GetTerrain()->GetHeight(data->posX, data->posY, data->posZ, false);
|
||||
if (data->posZ - tz > 0.1)
|
||||
Relocate(data->posX, data->posY, tz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetHealth(m_deathState == ALIVE ? curhealth : 0);
|
||||
SetPower(POWER_MANA, data->curmana);
|
||||
|
||||
|
|
@ -1324,6 +1354,11 @@ bool Creature::LoadFromDB(uint32 guidlow, Map *map)
|
|||
m_defaultMovementType = MovementGeneratorType(data->movementType);
|
||||
|
||||
AIM_Initialize();
|
||||
|
||||
// Creature Linking, Initial load is handled like respawn
|
||||
if (m_isCreatureLinkingTrigger && isAlive())
|
||||
GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_RESPAWN, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class MANGOS_DLL_SPEC CreatureAI
|
|||
virtual void EnterEvadeMode() {}
|
||||
|
||||
/**
|
||||
* Called at reaching home after MoveTargetHome
|
||||
* Called at reaching home after MoveTargetedHome
|
||||
*/
|
||||
virtual void JustReachedHome() {}
|
||||
|
||||
|
|
|
|||
468
src/game/CreatureLinkingMgr.cpp
Normal file
468
src/game/CreatureLinkingMgr.cpp
Normal file
|
|
@ -0,0 +1,468 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup npc_linking
|
||||
* @{
|
||||
*
|
||||
* @file CreatureLinkingMgr.cpp
|
||||
* This file contains the code needed for MaNGOS to link npcs together
|
||||
* Currently implemented
|
||||
* - Aggro on boss aggro, also reversed
|
||||
* - Despawning/ Selfkill on death of mob if the NPC it is linked to dies
|
||||
* - Respawning on leaving combat if the linked to NPC evades, also reversed
|
||||
* - Respawning on death of the linked to NPC
|
||||
* - (Re)Spawning dependend on boss Alive/ Dead
|
||||
* - Following NPCs
|
||||
*
|
||||
*/
|
||||
|
||||
#include "CreatureLinkingMgr.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(CreatureLinkingMgr);
|
||||
|
||||
/* *********************************************************
|
||||
* Method to Load From DB
|
||||
* DB Format: entry, map, master_entry, flag
|
||||
* 0 1 2 3
|
||||
* **************************************
|
||||
* 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
|
||||
*
|
||||
* ***************************************************** */
|
||||
|
||||
void CreatureLinkingMgr::LoadFromDB()
|
||||
{
|
||||
// Clear maps
|
||||
m_creatureLinkingMap.clear();
|
||||
m_eventTriggers.clear(); // master
|
||||
|
||||
QueryResult* result = WorldDatabase.Query("SELECT entry, map, master_entry, flag FROM creature_linking_template");
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
if (!result)
|
||||
{
|
||||
BarGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString(">> Table creature_linking_template is empty.");
|
||||
sLog.outString();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BarGoLink bar((int)result->GetRowCount());
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
CreatureLinkingInfo tmp;
|
||||
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
tmp.mapId = fields[1].GetUInt32();
|
||||
tmp.masterId = fields[2].GetUInt32();
|
||||
tmp.linkingFlag = fields[3].GetUInt16();
|
||||
tmp.masterDBGuid = 0; // Will be initialized for unique mobs later (only for spawning dependend)
|
||||
|
||||
if (!IsLinkingEntryValid(entry, &tmp))
|
||||
continue;
|
||||
|
||||
// Store db-guid for master of whom pTmp is spawn dependend
|
||||
if (tmp.linkingFlag & (FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE))
|
||||
{
|
||||
if (QueryResult* guid_result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id=%u AND map=%u LIMIT 1", tmp.masterId, tmp.mapId))
|
||||
{
|
||||
tmp.masterDBGuid = (*guid_result)[0].GetUInt32();
|
||||
|
||||
delete guid_result;
|
||||
}
|
||||
}
|
||||
|
||||
++count;
|
||||
|
||||
// Add it to the map
|
||||
m_creatureLinkingMap.insert(CreatureLinkingMap::value_type(entry, tmp));
|
||||
|
||||
// Store master_entry
|
||||
m_eventTriggers.insert(tmp.masterId);
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded creature linking for %u creature-IDs", count);
|
||||
delete result;
|
||||
}
|
||||
|
||||
// This function is used to check if a DB-Entry is valid
|
||||
bool CreatureLinkingMgr::IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingInfo* pTmp)
|
||||
{
|
||||
// Basic checks first
|
||||
CreatureInfo const* pInfo = ObjectMgr::GetCreatureTemplate(slaveEntry);
|
||||
if (!pInfo)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has a non existing slave_entry (ID: %u), skipped.", slaveEntry);
|
||||
return false;
|
||||
}
|
||||
|
||||
pInfo = ObjectMgr::GetCreatureTemplate(pTmp->masterId);
|
||||
if (!pInfo)
|
||||
{
|
||||
sLog.outErrorDb("`creature_linking_template` has a non existing master_entry (ID: %u), skipped", 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);
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for uniqueness of mob whom is followed, on whom spawning is dependend
|
||||
if (pTmp->linkingFlag & (FLAG_FOLLOW | FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE))
|
||||
{
|
||||
// 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
|
||||
return true;
|
||||
}
|
||||
|
||||
// Linked actions and corresponding flags
|
||||
enum EventMask
|
||||
{
|
||||
EVENT_MASK_ON_AGGRO = FLAG_AGGRO_ON_AGGRO,
|
||||
EVENT_MASK_ON_EVADE = FLAG_RESPAWN_ON_EVADE,
|
||||
EVENT_MASK_ON_DIE = FLAG_DESPAWN_ON_DEATH | FLAG_SELFKILL_ON_DEATH | FLAG_RESPAWN_ON_DEATH | FLAG_FOLLOW,
|
||||
EVENT_MASK_ON_RESPAWN = FLAG_RESPAWN_ON_RESPAWN | FLAG_DESPAWN_ON_RESPAWN | FLAG_FOLLOW,
|
||||
EVENT_MASK_TRIGGER_TO = FLAG_TO_AGGRO_ON_AGGRO | FLAG_TO_RESPAWN_ON_EVADE | FLAG_FOLLOW,
|
||||
};
|
||||
|
||||
// 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
|
||||
if (m_eventTriggers.find(pCreature->GetEntry()) != m_eventTriggers.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;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function check if the NPC is a master to other NPCs
|
||||
bool CreatureLinkingMgr::IsLinkedMaster(Creature* pCreature)
|
||||
{
|
||||
return m_eventTriggers.find(pCreature->GetEntry()) != m_eventTriggers.end();
|
||||
}
|
||||
|
||||
// This function checks if the spawning of this NPC is dependend on other NPCs
|
||||
bool CreatureLinkingMgr::IsSpawnedByLinkedMob(Creature* pCreature)
|
||||
{
|
||||
CreatureLinkingInfo const* pInfo = CreatureLinkingMgr::GetLinkedTriggerInformation(pCreature);
|
||||
|
||||
return pInfo && pInfo->linkingFlag & (FLAG_CANT_SPAWN_IF_BOSS_DEAD | FLAG_CANT_SPAWN_IF_BOSS_ALIVE) && pInfo->masterDBGuid;
|
||||
}
|
||||
|
||||
// This gives the information of a linked NPC (describes action when its ActionTrigger triggers)
|
||||
// Depends of the map
|
||||
CreatureLinkingInfo const* CreatureLinkingMgr::GetLinkedTriggerInformation(Creature* pCreature)
|
||||
{
|
||||
CreatureLinkingMapBounds bounds = m_creatureLinkingMap.equal_range(pCreature->GetEntry());
|
||||
for (CreatureLinkingMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter)
|
||||
{
|
||||
if (iter->second.mapId == pCreature->GetMapId())
|
||||
return &(iter->second);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Function to add slave-NPCs to the holder
|
||||
void CreatureLinkingHolder::AddSlaveToHolder(Creature* pCreature)
|
||||
{
|
||||
CreatureLinkingInfo const* pInfo = sCreatureLinkingMgr.GetLinkedTriggerInformation(pCreature);
|
||||
if (!pInfo)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
FlagAndGuids tmp;
|
||||
tmp.linkedGuids.push_back(pCreature->GetObjectGuid());
|
||||
tmp.linkingFlag = pInfo->linkingFlag;
|
||||
m_holderMap.insert(HolderMap::value_type(pInfo->masterId, tmp));
|
||||
}
|
||||
}
|
||||
|
||||
// Function to add master-NPCs to the holder
|
||||
void CreatureLinkingHolder::AddMasterToHolder(Creature* pCreature)
|
||||
{
|
||||
if (pCreature->IsPet())
|
||||
return;
|
||||
|
||||
// Only add master NPCs
|
||||
if (!sCreatureLinkingMgr.IsLinkedMaster(pCreature))
|
||||
return;
|
||||
|
||||
m_masterGuid[pCreature->GetEntry()] = pCreature->GetObjectGuid();
|
||||
}
|
||||
|
||||
// Function to process actions for linked NPCs
|
||||
void CreatureLinkingHolder::DoCreatureLinkingEvent(CreatureLinkingEvent eventType, Creature* pSource, Unit* pEnemy /* = NULL*/)
|
||||
{
|
||||
// This check will be needed in reload case
|
||||
if (!sCreatureLinkingMgr.IsLinkedEventTrigger(pSource))
|
||||
return;
|
||||
|
||||
// Ignore atypic behaviour
|
||||
if (pSource->IsControlledByPlayer())
|
||||
return;
|
||||
|
||||
if (eventType == LINKING_EVENT_AGGRO && !pEnemy)
|
||||
return;
|
||||
|
||||
uint32 eventFlagFilter = 0;
|
||||
uint32 reverseEventFlagFilter = 0;
|
||||
|
||||
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_RESPAWN: eventFlagFilter = EVENT_MASK_ON_RESPAWN; reverseEventFlagFilter = FLAG_FOLLOW; break;
|
||||
}
|
||||
|
||||
// Process Slaves
|
||||
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.linkedGuids, pEnemy);
|
||||
|
||||
// Process Master
|
||||
if (CreatureLinkingInfo const* pInfo = sCreatureLinkingMgr.GetLinkedTriggerInformation(pSource))
|
||||
{
|
||||
if (pInfo->linkingFlag & reverseEventFlagFilter)
|
||||
{
|
||||
BossGuidMap::const_iterator find = m_masterGuid.find(pInfo->masterId);
|
||||
if (find != m_masterGuid.end())
|
||||
{
|
||||
if (Creature* pMaster = pSource->GetMap()->GetCreature(find->second))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function, to process a slave list
|
||||
void CreatureLinkingHolder::ProcessSlaveGuidList(CreatureLinkingEvent eventType, Creature* pSource, uint32 flag, GuidList& slaveGuidList, Unit* pEnemy)
|
||||
{
|
||||
if (!flag)
|
||||
return;
|
||||
|
||||
for (GuidList::iterator slave_itr = slaveGuidList.begin(); slave_itr != slaveGuidList.end();)
|
||||
{
|
||||
Creature* pSlave = pSource->GetMap()->GetCreature(*slave_itr);
|
||||
if (!pSlave)
|
||||
{
|
||||
// Remove old guid first
|
||||
slaveGuidList.erase(slave_itr++);
|
||||
continue;
|
||||
}
|
||||
|
||||
++slave_itr;
|
||||
|
||||
// Ignore Pets
|
||||
if (pSlave->IsPet())
|
||||
continue;
|
||||
|
||||
// Handle single slave
|
||||
ProcessSlave(eventType, pSource, flag, pSlave, pEnemy);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function, to process a single slave
|
||||
void CreatureLinkingHolder::ProcessSlave(CreatureLinkingEvent eventType, Creature* pSource, uint32 flag, Creature* pSlave, Unit* pEnemy)
|
||||
{
|
||||
switch (eventType)
|
||||
{
|
||||
case LINKING_EVENT_AGGRO:
|
||||
if (flag & FLAG_AGGRO_ON_AGGRO)
|
||||
{
|
||||
if (pSlave->IsControlledByPlayer())
|
||||
return;
|
||||
|
||||
if (pSlave->isInCombat())
|
||||
pSlave->SetInCombatWith(pEnemy);
|
||||
else
|
||||
pSlave->AI()->AttackStart(pEnemy);
|
||||
}
|
||||
break;
|
||||
case LINKING_EVENT_EVADE:
|
||||
if (flag & FLAG_RESPAWN_ON_EVADE && !pSlave->isAlive())
|
||||
pSlave->Respawn();
|
||||
break;
|
||||
case LINKING_EVENT_DIE:
|
||||
if (flag & FLAG_SELFKILL_ON_DEATH && pSlave->isAlive())
|
||||
pSlave->DealDamage(pSlave, pSlave->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
if (flag & FLAG_DESPAWN_ON_DEATH && pSlave->isAlive())
|
||||
pSlave->ForcedDespawn();
|
||||
if (flag & FLAG_RESPAWN_ON_DEATH && !pSlave->isAlive())
|
||||
pSlave->Respawn();
|
||||
break;
|
||||
case LINKING_EVENT_RESPAWN:
|
||||
if (flag & FLAG_RESPAWN_ON_RESPAWN)
|
||||
{
|
||||
// Additional check to prevent endless loops (in case whole group respawns on first respawn)
|
||||
if (!pSlave->isAlive() && pSlave->GetRespawnTime() > time(NULL))
|
||||
pSlave->Respawn();
|
||||
}
|
||||
else if (flag & FLAG_DESPAWN_ON_RESPAWN && pSlave->isAlive())
|
||||
pSlave->ForcedDespawn();
|
||||
|
||||
if (flag & FLAG_FOLLOW && pSlave->isAlive() && !pSlave->isInCombat())
|
||||
SetFollowing(pSlave, pSource);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to set following
|
||||
void CreatureLinkingHolder::SetFollowing(Creature* pWho, Creature* pWhom)
|
||||
{
|
||||
// Do some calculations
|
||||
float sX, sY, sZ, mX, mY, mZ, mO;
|
||||
pWho->GetRespawnCoord(sX, sY, sZ);
|
||||
pWhom->GetRespawnCoord(mX, mY, mZ, &mO);
|
||||
|
||||
float dx, dy, dz;
|
||||
dx = sX - mX;
|
||||
dy = sY - mY;
|
||||
dz = sZ - mZ;
|
||||
|
||||
float dist = sqrt(dx*dx + dy*dy + dz*dz);
|
||||
// REMARK: This code needs the same distance calculation that is used for following
|
||||
// Atm this means we have to subtract the bounding radiuses
|
||||
dist = dist - pWho->GetObjectBoundingRadius() - pWhom->GetObjectBoundingRadius();
|
||||
if (dist < 0.0f)
|
||||
dist = 0.0f;
|
||||
|
||||
// Need to pass the relative angle to following
|
||||
float angle = atan2(dy, dx) - mO;
|
||||
angle = (angle >= 0) ? angle : 2 * M_PI_F + angle;
|
||||
|
||||
pWho->GetMotionMaster()->MoveFollow(pWhom, dist, angle);
|
||||
}
|
||||
|
||||
// Function to check if a passive spawning condition is met
|
||||
bool CreatureLinkingHolder::CanSpawn(Creature* pCreature)
|
||||
{
|
||||
CreatureLinkingInfo const* pInfo = sCreatureLinkingMgr.GetLinkedTriggerInformation(pCreature);
|
||||
if (!pInfo || !pInfo->masterDBGuid)
|
||||
return true;
|
||||
|
||||
if (pInfo->linkingFlag & FLAG_CANT_SPAWN_IF_BOSS_DEAD)
|
||||
return pCreature->GetMap()->GetPersistentState()->GetCreatureRespawnTime(pInfo->masterDBGuid) == 0;
|
||||
else if (pInfo->linkingFlag & FLAG_CANT_SPAWN_IF_BOSS_ALIVE)
|
||||
return pCreature->GetMap()->GetPersistentState()->GetCreatureRespawnTime(pInfo->masterDBGuid) > 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function lets a slave refollow his master
|
||||
bool CreatureLinkingHolder::TryFollowMaster(Creature* pCreature)
|
||||
{
|
||||
CreatureLinkingInfo const* pInfo = sCreatureLinkingMgr.GetLinkedTriggerInformation(pCreature);
|
||||
if (!pInfo || !(pInfo->linkingFlag & FLAG_FOLLOW))
|
||||
return false;
|
||||
|
||||
BossGuidMap::const_iterator find = m_masterGuid.find(pInfo->masterId);
|
||||
if (find != m_masterGuid.end())
|
||||
{
|
||||
Creature* pMaster = pCreature->GetMap()->GetCreature(find->second);
|
||||
if (pMaster && pMaster->isAlive())
|
||||
{
|
||||
SetFollowing(pCreature, pMaster);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! @} */
|
||||
185
src/game/CreatureLinkingMgr.h
Normal file
185
src/game/CreatureLinkingMgr.h
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup npc_linking System to link groups of NPCs together
|
||||
* This NPC-linking system in MaNGOS consists of 2 files:
|
||||
* - CreatureLinkingMgr.h
|
||||
* - CreatureLinkingMgr.cpp
|
||||
* as well of
|
||||
* - hooks in Creature.cpp, to trigger actions
|
||||
* - holder of the linked npcs for every map
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file CreatureLinkingMgr.h
|
||||
* This file contains the the headers needed for MaNGOS to link NPCs together
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CREATURE_LINKING_MGR_H
|
||||
#define CREATURE_LINKING_MGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
class ObjectGuid;
|
||||
class Unit;
|
||||
class Creature;
|
||||
|
||||
// enum on which Events an action for linked NPCs can trigger
|
||||
enum CreatureLinkingEvent
|
||||
{
|
||||
LINKING_EVENT_AGGRO = 0,
|
||||
LINKING_EVENT_EVADE = 1,
|
||||
LINKING_EVENT_DIE = 2,
|
||||
LINKING_EVENT_RESPAWN = 3,
|
||||
};
|
||||
|
||||
// enum describing possible flags action flags for NPCs linked to other NPCs
|
||||
// These flags are actually put into the database
|
||||
// FLAG_TO_ means, that in this case the linked NPC will also trigger an action for the NPC it is linked to
|
||||
enum CreatureLinkingFlags
|
||||
{
|
||||
// Dynamic behaviour, in combat
|
||||
FLAG_AGGRO_ON_AGGRO = 0x0001,
|
||||
FLAG_TO_AGGRO_ON_AGGRO = 0x0002,
|
||||
FLAG_RESPAWN_ON_EVADE = 0x0004,
|
||||
FLAG_TO_RESPAWN_ON_EVADE = 0x0008,
|
||||
FLAG_DESPAWN_ON_DEATH = 0x0010,
|
||||
FLAG_SELFKILL_ON_DEATH = 0x0020,
|
||||
FLAG_RESPAWN_ON_DEATH = 0x0040,
|
||||
FLAG_RESPAWN_ON_RESPAWN = 0x0080,
|
||||
FLAG_DESPAWN_ON_RESPAWN = 0x0100,
|
||||
|
||||
// Dynamic behaviour, out of combat
|
||||
FLAG_FOLLOW = 0x0200,
|
||||
|
||||
// Passive behaviour
|
||||
FLAG_CANT_SPAWN_IF_BOSS_DEAD = 0x0400,
|
||||
FLAG_CANT_SPAWN_IF_BOSS_ALIVE = 0x0800,
|
||||
|
||||
LINKING_FLAG_INVALID = 0x1000, // TODO adjust when other flags are implemented
|
||||
};
|
||||
|
||||
// Structure holding the information for an entry
|
||||
struct CreatureLinkingInfo
|
||||
{
|
||||
uint32 mapId;
|
||||
uint32 masterId;
|
||||
uint16 linkingFlag;
|
||||
uint32 masterDBGuid;
|
||||
};
|
||||
|
||||
/**
|
||||
* A class to represent the static information of linking NPCs together
|
||||
*/
|
||||
|
||||
class CreatureLinkingMgr
|
||||
{
|
||||
public: // Constructors
|
||||
CreatureLinkingMgr() {}
|
||||
|
||||
public: // Initialisation
|
||||
void LoadFromDB();
|
||||
|
||||
public: // Accessors
|
||||
// This functions checks if the NPC triggers actions for other NPCs
|
||||
bool IsLinkedEventTrigger(Creature* pCreature);
|
||||
|
||||
// This function checks if the NPC is a master NPC.
|
||||
bool IsLinkedMaster(Creature* pCreature);
|
||||
|
||||
// This function checks if the spawning of this NPC is dependend on other NPCs
|
||||
bool IsSpawnedByLinkedMob(Creature* pCreature);
|
||||
|
||||
// This gives the information of a linked NPC (describes action when its ActionTrigger triggers)
|
||||
// Depends of the map
|
||||
CreatureLinkingInfo const* GetLinkedTriggerInformation(Creature* pCreature);
|
||||
|
||||
private:
|
||||
typedef std::multimap<uint32 /*slaveEntry*/, CreatureLinkingInfo> CreatureLinkingMap;
|
||||
typedef std::pair<CreatureLinkingMap::const_iterator, CreatureLinkingMap::const_iterator> CreatureLinkingMapBounds;
|
||||
|
||||
// Storage of Data: npc_entry_slave, (map, npc_entry_master, flag, master_db_guid[If Unique])
|
||||
CreatureLinkingMap m_creatureLinkingMap;
|
||||
|
||||
// Lookup Storage for fast access:
|
||||
UNORDERED_SET<uint32> m_eventTriggers; // master
|
||||
|
||||
// Check-routine
|
||||
bool IsLinkingEntryValid(uint32 slaveEntry, CreatureLinkingInfo* pInfo);
|
||||
};
|
||||
|
||||
/**
|
||||
* A class to represent the dynamic information of linking NPCs together
|
||||
*
|
||||
* Every map has an instance of this class as member, in which the dynamic information (GUIDs) are stored
|
||||
*/
|
||||
|
||||
class CreatureLinkingHolder
|
||||
{
|
||||
public: // Constructors
|
||||
CreatureLinkingHolder() {}
|
||||
|
||||
public: // Accessors
|
||||
// Function to add slave-NPCs to the holder
|
||||
void AddSlaveToHolder(Creature* pCreature);
|
||||
|
||||
// Function to add master-NPCs to the holder
|
||||
void AddMasterToHolder(Creature* pCreature);
|
||||
|
||||
// Function to process actions for linked NPCs
|
||||
void DoCreatureLinkingEvent(CreatureLinkingEvent eventType, Creature* pSource, Unit* pEnemy = NULL);
|
||||
|
||||
// Function to check if a passive spawning condition is met
|
||||
bool CanSpawn(Creature* pCreature);
|
||||
|
||||
// This function lets a slave refollow his master
|
||||
bool TryFollowMaster(Creature* pCreature);
|
||||
|
||||
private:
|
||||
typedef std::list<ObjectGuid> GuidList;
|
||||
// Structure associated to a master
|
||||
struct FlagAndGuids
|
||||
{
|
||||
uint16 linkingFlag;
|
||||
GuidList linkedGuids;
|
||||
};
|
||||
|
||||
typedef std::multimap<uint32 /*masterEntry*/, FlagAndGuids> HolderMap;
|
||||
typedef std::pair<HolderMap::iterator, HolderMap::iterator> HolderMapBounds;
|
||||
typedef UNORDERED_MAP<uint32 /*Entry*/, ObjectGuid> BossGuidMap;
|
||||
|
||||
// Helper function, to process a slave list
|
||||
void ProcessSlaveGuidList(CreatureLinkingEvent eventType, Creature* pSource, uint32 flag, GuidList& slaveGuidList, Unit* pEnemy);
|
||||
// Helper function, to process a single slave
|
||||
void ProcessSlave(CreatureLinkingEvent eventType, Creature* pSource, uint32 flag, Creature* pSlave, Unit* pEnemy);
|
||||
// Helper function to set following
|
||||
void SetFollowing(Creature* pWho, Creature* pWhom);
|
||||
|
||||
// Storage of Data (boss, flag) GuidList for action triggering
|
||||
HolderMap m_holderMap;
|
||||
// boss_entry, guid for reverse action triggering and check alive
|
||||
BossGuidMap m_masterGuid;
|
||||
};
|
||||
|
||||
#define sCreatureLinkingMgr MaNGOS::Singleton<CreatureLinkingMgr>::Instance()
|
||||
|
||||
#endif
|
||||
/*! @} */
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
#include "MapRefManager.h"
|
||||
#include "Utilities/TypeList.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "CreatureLinkingMgr.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <list>
|
||||
|
|
@ -259,6 +260,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
|
|||
void MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid = 0);
|
||||
void PlayDirectSoundToMap(uint32 soundId, uint32 zoneId = 0);
|
||||
|
||||
|
||||
// Get Holder for Creature Linking
|
||||
CreatureLinkingHolder* GetCreatureLinkingHolder() { return &m_creatureLinkingHolder; }
|
||||
|
||||
private:
|
||||
void LoadMapAndVMap(int gx, int gy);
|
||||
|
||||
|
|
@ -346,6 +351,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
|
|||
|
||||
template<class T>
|
||||
void RemoveFromGrid(T*, NGridType *, Cell const&);
|
||||
|
||||
// Holder for information about linked mobs
|
||||
CreatureLinkingHolder m_creatureLinkingHolder;
|
||||
};
|
||||
|
||||
class MANGOS_DLL_SPEC WorldMap : public Map
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "RandomMovementGenerator.h"
|
||||
#include "movement/MoveSpline.h"
|
||||
#include "movement/MoveSplineInit.h"
|
||||
#include "CreatureLinkingMgr.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
|
@ -243,8 +244,14 @@ void MotionMaster::MoveTargetedHome()
|
|||
|
||||
if (m_owner->GetTypeId() == TYPEID_UNIT && !((Creature*)m_owner)->GetCharmerOrOwnerGuid())
|
||||
{
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "%s targeted home", m_owner->GetGuidStr().c_str());
|
||||
Mutate(new HomeMovementGenerator<Creature>());
|
||||
// Manual exception for linked mobs
|
||||
if (m_owner->IsLinkingEventTrigger() && m_owner->GetMap()->GetCreatureLinkingHolder()->TryFollowMaster((Creature*)m_owner))
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "%s refollowed linked master", m_owner->GetGuidStr().c_str());
|
||||
else
|
||||
{
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "%s targeted home", m_owner->GetGuidStr().c_str());
|
||||
Mutate(new HomeMovementGenerator<Creature>());
|
||||
}
|
||||
}
|
||||
else if (m_owner->GetTypeId() == TYPEID_UNIT && ((Creature*)m_owner)->GetCharmerOrOwnerGuid())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "MovementGenerator.h"
|
||||
#include "movement/MoveSplineInit.h"
|
||||
#include "movement/MoveSpline.h"
|
||||
#include "CreatureLinkingMgr.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
|
@ -263,6 +264,9 @@ Unit::Unit() :
|
|||
// remove aurastates allowing special moves
|
||||
for(int i=0; i < MAX_REACTIVE; ++i)
|
||||
m_reactiveTimer[i] = 0;
|
||||
|
||||
m_isCreatureLinkingTrigger = false;
|
||||
m_isSpawningLinked = false;
|
||||
}
|
||||
|
||||
Unit::~Unit()
|
||||
|
|
@ -843,6 +847,9 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
if (InstanceData* mapInstance = cVictim->GetInstanceData())
|
||||
mapInstance->OnCreatureDeath(cVictim);
|
||||
|
||||
if (cVictim->IsLinkingEventTrigger())
|
||||
cVictim->GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_DIE, cVictim);
|
||||
|
||||
// Dungeon specific stuff, only applies to players killing creatures
|
||||
if(cVictim->GetInstanceId())
|
||||
{
|
||||
|
|
@ -7798,6 +7805,9 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
|
|||
|
||||
if (InstanceData* mapInstance = GetInstanceData())
|
||||
mapInstance->OnCreatureEnterCombat(pCreature);
|
||||
|
||||
if (m_isCreatureLinkingTrigger)
|
||||
GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_AGGRO, pCreature, enemy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8562,6 +8572,9 @@ void Unit::TauntFadeOut(Unit *taunter)
|
|||
if (InstanceData* mapInstance = GetInstanceData())
|
||||
mapInstance->OnCreatureEvade((Creature*)this);
|
||||
|
||||
if (m_isCreatureLinkingTrigger)
|
||||
GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_EVADE, (Creature*)this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -8662,6 +8675,9 @@ bool Unit::SelectHostileTarget()
|
|||
if (InstanceData* mapInstance = GetInstanceData())
|
||||
mapInstance->OnCreatureEvade((Creature*)this);
|
||||
|
||||
if (m_isCreatureLinkingTrigger)
|
||||
GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_EVADE, (Creature*)this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1903,6 +1903,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
void _SetAINotifyScheduled(bool on) { m_AINotifyScheduled = on;} // only for call from RelocationNotifyEvent code
|
||||
void OnRelocated();
|
||||
|
||||
bool IsLinkingEventTrigger() { return m_isCreatureLinkingTrigger; }
|
||||
|
||||
protected:
|
||||
explicit Unit ();
|
||||
|
||||
|
|
@ -1954,6 +1956,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
|
||||
VehicleInfo* m_vehicleInfo;
|
||||
void DisableSpline();
|
||||
bool m_isCreatureLinkingTrigger;
|
||||
bool m_isSpawningLinked;
|
||||
|
||||
private:
|
||||
void CleanupDeletedAuras();
|
||||
void UpdateSplineMovement(uint32 t_diff);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include "Util.h"
|
||||
#include "AuctionHouseBot/AuctionHouseBot.h"
|
||||
#include "CharacterDatabaseCleaner.h"
|
||||
#include "CreatureLinkingMgr.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1( World );
|
||||
|
||||
|
|
@ -1067,6 +1068,9 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Loading Gameobject Addon Data..." );
|
||||
sObjectMgr.LoadGameObjectAddon();
|
||||
|
||||
sLog.outString( "Loading CreatureLinking Data..." ); // must be after Creatures
|
||||
sCreatureLinkingMgr.LoadFromDB();
|
||||
|
||||
sLog.outString( "Loading Objects Pooling Data...");
|
||||
sPoolMgr.LoadFromDB();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11826"
|
||||
#define REVISION_NR "11827"
|
||||
#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_11813_01_mangos_mangos_string"
|
||||
#define REVISION_DB_MANGOS "required_11827_01_mangos_creature_linking_template"
|
||||
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
|
|
@ -387,6 +387,7 @@
|
|||
<ClCompile Include="..\..\src\game\CreatureAISelector.cpp" />
|
||||
<ClCompile Include="..\..\src\game\CreatureEventAI.cpp" />
|
||||
<ClCompile Include="..\..\src\game\CreatureEventAIMgr.cpp" />
|
||||
<ClCompile Include="..\..\src\game\CreatureLinkingMgr.cpp" />
|
||||
<ClCompile Include="..\..\src\game\DBCStores.cpp" />
|
||||
<ClCompile Include="..\..\src\game\debugcmds.cpp" />
|
||||
<ClCompile Include="..\..\src\game\DuelHandler.cpp" />
|
||||
|
|
@ -550,6 +551,7 @@
|
|||
<ClInclude Include="..\..\src\game\CreatureAISelector.h" />
|
||||
<ClInclude Include="..\..\src\game\CreatureEventAI.h" />
|
||||
<ClInclude Include="..\..\src\game\CreatureEventAIMgr.h" />
|
||||
<ClInclude Include="..\..\src\game\CreatureLinkingMgr.h" />
|
||||
<ClInclude Include="..\..\src\game\DBCEnums.h" />
|
||||
<ClInclude Include="..\..\src\game\DBCfmt.h" />
|
||||
<ClInclude Include="..\..\src\game\DBCStores.h" />
|
||||
|
|
|
|||
|
|
@ -502,6 +502,9 @@
|
|||
<ClCompile Include="..\..\src\game\movement\MoveSpline.cpp">
|
||||
<Filter>Movement</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\game\CreatureLinkingMgr.cpp">
|
||||
<Filter>World/Handlers</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\game\AccountMgr.h">
|
||||
|
|
@ -949,5 +952,8 @@
|
|||
<ClInclude Include="..\..\src\game\movement\typedefs.h">
|
||||
<Filter>Movement</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\game\CreatureLinkingMgr.h">
|
||||
<Filter>World/Handlers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -718,6 +718,14 @@
|
|||
RelativePath="..\..\src\game\CombatHandler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\CreatureLinkingMgr.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\CreatureLinkingMgr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\DuelHandler.cpp"
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue