*Merge.
--HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `gm_tickets` ADD COLUMN `createtime` int(10) NOT NULL after `message`;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
DELETE FROM `trinity_string` WHERE `entry`=2025;
|
||||||
|
INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES
|
||||||
|
('2025','|cff00ff00Created|r:|cff00ccff %s ago|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
DROP TABLE IF EXISTS `creature_linked_respawn`;
|
||||||
|
CREATE TABLE `creature_linked_respawn` (
|
||||||
|
`guid` int(10) unsigned NOT NULL COMMENT 'dependent creature',
|
||||||
|
`linkedGuid` int(10) unsigned NOT NULL COMMENT 'master creature',
|
||||||
|
PRIMARY KEY (`guid`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Creature Respawn Link System';
|
||||||
|
|
||||||
|
DELETE FROM `trinity_string` WHERE `entry` = '750';
|
||||||
|
INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES
|
||||||
|
('750', 'linkGUID: %u, Entry: %u (%s)', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE `gm_tickets` ADD COLUMN `map` INT NOT NULL DEFAULT '0' AFTER `createtime`;
|
||||||
|
ALTER TABLE `gm_tickets` ADD COLUMN `posX` FLOAT NOT NULL DEFAULT '0' AFTER `map`;
|
||||||
|
ALTER TABLE `gm_tickets` ADD COLUMN `posY` FLOAT NOT NULL DEFAULT '0' AFTER `posX`;
|
||||||
|
ALTER TABLE `gm_tickets` ADD COLUMN `posZ` FLOAT NOT NULL DEFAULT '0' AFTER `posY`;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
insert into `command` (`name`, `security`, `help`) values('go ticket','1','Syntax: .go ticket #ticketid\r\nTeleports the user to the location where $ticketid was created.');
|
||||||
@@ -79,6 +79,7 @@ EndScriptData */
|
|||||||
|
|
||||||
#define ENSLAVED_SOUL_PASSIVE 41535
|
#define ENSLAVED_SOUL_PASSIVE 41535
|
||||||
#define SPELL_SOUL_RELEASE 41542
|
#define SPELL_SOUL_RELEASE 41542
|
||||||
|
#define SPELL_SUBMERGE 37550 //dropout 'head'
|
||||||
|
|
||||||
#define CREATURE_ENSLAVED_SOUL 23469
|
#define CREATURE_ENSLAVED_SOUL 23469
|
||||||
#define NUMBER_ENSLAVED_SOUL 8
|
#define NUMBER_ENSLAVED_SOUL 8
|
||||||
@@ -153,6 +154,7 @@ struct TRINITY_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI
|
|||||||
|
|
||||||
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||||
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
||||||
|
m_creature->RemoveAurasDueToSpell(SPELL_SUBMERGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aggro(Unit* who)
|
void Aggro(Unit* who)
|
||||||
@@ -231,13 +233,14 @@ struct TRINITY_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
Timer = 2800;
|
Timer = 2800;
|
||||||
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SUBMERGE); // Release the cube
|
//m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SUBMERGE); // Release the cube
|
||||||
|
DoCast(m_creature,SPELL_SUBMERGE);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
Timer = 5000;
|
Timer = 5000;
|
||||||
if(Creature* Summon = DoSpawnCreature(23417+Phase, 0, 0, 0, 0, TEMPSUMMON_DEAD_DESPAWN, 0))
|
if(Creature* Summon = DoSpawnCreature(23417+Phase, 0, 0, 0, 0, TEMPSUMMON_DEAD_DESPAWN, 0))
|
||||||
{
|
{
|
||||||
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); // Ribs: open
|
//m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); // Ribs: open
|
||||||
Summon->AI()->AttackStart(SelectUnit(SELECT_TARGET_TOPAGGRO, 0));
|
Summon->AI()->AttackStart(SelectUnit(SELECT_TARGET_TOPAGGRO, 0));
|
||||||
EssenceGUID = Summon->GetGUID();
|
EssenceGUID = Summon->GetGUID();
|
||||||
}else EnterEvadeMode();
|
}else EnterEvadeMode();
|
||||||
@@ -262,7 +265,8 @@ struct TRINITY_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI
|
|||||||
case 4:
|
case 4:
|
||||||
Timer = 1500;
|
Timer = 1500;
|
||||||
if(Essence->IsWithinDistInMap(m_creature, 10))
|
if(Essence->IsWithinDistInMap(m_creature, 10))
|
||||||
Essence->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SUBMERGE); //rotate and disappear
|
m_creature->RemoveAurasDueToSpell(SPELL_SUBMERGE);
|
||||||
|
//Essence->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_SUBMERGE); //rotate and disappear
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -408,6 +408,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||||||
{ "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
|
{ "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
|
||||||
{ "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL },
|
{ "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL },
|
||||||
{ "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL },
|
{ "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL },
|
||||||
|
{ "creature_linked_respawn", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureLinkedRespawnCommand, "", NULL },
|
||||||
{ "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL },
|
{ "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL },
|
||||||
{ "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL },
|
{ "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL },
|
||||||
//{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL },
|
//{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL },
|
||||||
@@ -518,6 +519,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||||||
{
|
{
|
||||||
{ "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
|
{ "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
|
||||||
{ "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL },
|
{ "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL },
|
||||||
|
{ "setlink", SEC_MODERATOR, false, &ChatHandler::HandleNpcSetLinkCommand, "", NULL },
|
||||||
{ NULL, 0, false, NULL, "", NULL }
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ class ChatHandler
|
|||||||
bool HandleNpcWhisperCommand(const char* args);
|
bool HandleNpcWhisperCommand(const char* args);
|
||||||
bool HandleNpcYellCommand(const char* args);
|
bool HandleNpcYellCommand(const char* args);
|
||||||
bool HandleNpcAddFormationCommand(const char* args);
|
bool HandleNpcAddFormationCommand(const char* args);
|
||||||
|
bool HandleNpcSetLinkCommand(const char* args);
|
||||||
|
|
||||||
//TODO: NpcCommands that needs to be fixed :
|
//TODO: NpcCommands that needs to be fixed :
|
||||||
bool HandleNpcAddWeaponCommand(const char* args);
|
bool HandleNpcAddWeaponCommand(const char* args);
|
||||||
@@ -312,6 +313,7 @@ class ChatHandler
|
|||||||
bool HandleReloadCommandCommand(const char* args);
|
bool HandleReloadCommandCommand(const char* args);
|
||||||
bool HandleReloadCreatureQuestRelationsCommand(const char* args);
|
bool HandleReloadCreatureQuestRelationsCommand(const char* args);
|
||||||
bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
|
bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
|
||||||
|
bool HandleReloadCreatureLinkedRespawnCommand(const char* args);
|
||||||
bool HandleReloadDbScriptStringCommand(const char* args);
|
bool HandleReloadDbScriptStringCommand(const char* args);
|
||||||
bool HandleReloadGameGraveyardZoneCommand(const char* args);
|
bool HandleReloadGameGraveyardZoneCommand(const char* args);
|
||||||
bool HandleReloadGameObjectScriptsCommand(const char* args);
|
bool HandleReloadGameObjectScriptsCommand(const char* args);
|
||||||
|
|||||||
+78
-34
@@ -404,36 +404,21 @@ void Creature::Update(uint32 diff)
|
|||||||
{
|
{
|
||||||
if( m_respawnTime <= time(NULL) )
|
if( m_respawnTime <= time(NULL) )
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Respawning...");
|
if(!GetLinkedCreatureRespawnTime()) // Can respawn
|
||||||
m_respawnTime = 0;
|
Respawn();
|
||||||
lootForPickPocketed = false;
|
else // the master is dead
|
||||||
lootForBody = false;
|
|
||||||
|
|
||||||
if(m_originalEntry != GetEntry())
|
|
||||||
UpdateEntry(m_originalEntry);
|
|
||||||
|
|
||||||
CreatureInfo const *cinfo = GetCreatureInfo();
|
|
||||||
SelectLevel(cinfo);
|
|
||||||
|
|
||||||
if (m_isDeadByDefault)
|
|
||||||
{
|
{
|
||||||
setDeathState(JUST_DIED);
|
if(uint32 targetGuid = objmgr.GetLinkedRespawnGuid(m_DBTableGuid))
|
||||||
SetHealth(0);
|
{
|
||||||
i_motionMaster.Clear();
|
if(targetGuid == m_DBTableGuid) // if linking self, never respawn (check delayed to next day)
|
||||||
clearUnitState(UNIT_STAT_ALL_STATE);
|
SetRespawnTime(DAY);
|
||||||
LoadCreaturesAddon(true);
|
else
|
||||||
|
m_respawnTime = (time(NULL)>GetLinkedCreatureRespawnTime()? time(NULL):GetLinkedCreatureRespawnTime())+urand(5,MINUTE); // else copy time from master and add a little
|
||||||
|
SaveRespawnTime(); // also save to DB immediately
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
setDeathState( JUST_ALIVED );
|
Respawn();
|
||||||
|
}
|
||||||
//Call AI respawn virtual function
|
|
||||||
AI()->JustRespawned();
|
|
||||||
|
|
||||||
uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId());
|
|
||||||
if (poolid)
|
|
||||||
poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId());
|
|
||||||
else
|
|
||||||
GetMap()->Add(this);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1444,7 +1429,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
|
|||||||
m_deathState = m_isDeadByDefault ? DEAD : ALIVE;
|
m_deathState = m_isDeadByDefault ? DEAD : ALIVE;
|
||||||
|
|
||||||
m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId());
|
m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId());
|
||||||
if(m_respawnTime > time(NULL)) // not ready to respawn
|
if(m_respawnTime) // respawn on Update
|
||||||
{
|
{
|
||||||
m_deathState = DEAD;
|
m_deathState = DEAD;
|
||||||
if(canFly())
|
if(canFly())
|
||||||
@@ -1454,11 +1439,6 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
|
|||||||
Relocate(data->posX,data->posY,tz);
|
Relocate(data->posX,data->posY,tz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(m_respawnTime) // respawn time set but expired
|
|
||||||
{
|
|
||||||
m_respawnTime = 0;
|
|
||||||
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 curhealth = data->curhealth;
|
uint32 curhealth = data->curhealth;
|
||||||
if(curhealth)
|
if(curhealth)
|
||||||
@@ -1728,7 +1708,37 @@ void Creature::Respawn()
|
|||||||
{
|
{
|
||||||
if (m_DBTableGuid)
|
if (m_DBTableGuid)
|
||||||
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
|
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
|
||||||
m_respawnTime = time(NULL); // respawn at next tick
|
|
||||||
|
DEBUG_LOG("Respawning...");
|
||||||
|
m_respawnTime = 0;
|
||||||
|
lootForPickPocketed = false;
|
||||||
|
lootForBody = false;
|
||||||
|
|
||||||
|
if(m_originalEntry != GetEntry())
|
||||||
|
UpdateEntry(m_originalEntry);
|
||||||
|
|
||||||
|
CreatureInfo const *cinfo = GetCreatureInfo();
|
||||||
|
SelectLevel(cinfo);
|
||||||
|
|
||||||
|
if (m_isDeadByDefault)
|
||||||
|
{
|
||||||
|
setDeathState(JUST_DIED);
|
||||||
|
SetHealth(0);
|
||||||
|
i_motionMaster.Clear();
|
||||||
|
clearUnitState(UNIT_STAT_ALL_STATE);
|
||||||
|
LoadCreaturesAddon(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
setDeathState( JUST_ALIVED );
|
||||||
|
|
||||||
|
//Call AI respawn virtual function
|
||||||
|
AI()->JustRespawned();
|
||||||
|
|
||||||
|
uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId());
|
||||||
|
if (poolid)
|
||||||
|
poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId());
|
||||||
|
else
|
||||||
|
GetMap()->Add(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2349,3 +2359,37 @@ const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const
|
|||||||
|
|
||||||
return GetName();
|
return GetName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CreatureData* Creature::GetLinkedRespawnCreatureData() const
|
||||||
|
{
|
||||||
|
if(!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(uint32 targetGuid = objmgr.GetLinkedRespawnGuid(m_DBTableGuid))
|
||||||
|
return objmgr.GetCreatureData(targetGuid);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns master's remaining respawn time if any
|
||||||
|
time_t Creature::GetLinkedCreatureRespawnTime() const
|
||||||
|
{
|
||||||
|
if(!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(uint32 targetGuid = objmgr.GetLinkedRespawnGuid(m_DBTableGuid))
|
||||||
|
{
|
||||||
|
Map* targetMap = NULL;
|
||||||
|
if(const CreatureData* data = objmgr.GetCreatureData(targetGuid))
|
||||||
|
{
|
||||||
|
if(data->mapid == GetMapId()) // look up on the same map
|
||||||
|
targetMap = GetMap();
|
||||||
|
else // it shouldn't be instanceable map here
|
||||||
|
targetMap = MapManager::Instance().FindMap(data->mapid);
|
||||||
|
}
|
||||||
|
if(targetMap)
|
||||||
|
return objmgr.GetCreatureRespawnTime(targetGuid,targetMap->GetInstanceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -645,6 +645,10 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
|||||||
float GetRespawnRadius() const { return m_respawnradius; }
|
float GetRespawnRadius() const { return m_respawnradius; }
|
||||||
void SetRespawnRadius(float dist) { m_respawnradius = dist; }
|
void SetRespawnRadius(float dist) { m_respawnradius = dist; }
|
||||||
|
|
||||||
|
// Linked Creature Respawning System
|
||||||
|
time_t GetLinkedCreatureRespawnTime() const;
|
||||||
|
const CreatureData* GetLinkedRespawnCreatureData() const;
|
||||||
|
|
||||||
uint32 m_groupLootTimer; // (msecs)timer used for group loot
|
uint32 m_groupLootTimer; // (msecs)timer used for group loot
|
||||||
uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse
|
uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -694,7 +694,9 @@ enum TrinityStrings
|
|||||||
// LANG_BG_EY_START_TWO_MINUTES = 755, - defined above
|
// LANG_BG_EY_START_TWO_MINUTES = 755, - defined above
|
||||||
// Room for batleground/arena strings 756-799 not used
|
// Room for batleground/arena strings 756-799 not used
|
||||||
|
|
||||||
// Room for BG/ARENA 750-769 not used
|
// Room for BG/ARENA 751-769 not used
|
||||||
|
|
||||||
|
LANG_NPCINFO_LINKGUID = 750,
|
||||||
|
|
||||||
LANG_ARENA_TESTING = 785,
|
LANG_ARENA_TESTING = 785,
|
||||||
LANG_AUTO_ANN = 786,
|
LANG_AUTO_ANN = 786,
|
||||||
|
|||||||
@@ -282,6 +282,7 @@ std::string ChatHandler::PGetParseString(int32 entry, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
return (std::string)str;
|
return (std::string)str;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleGMTicketListCommand(const char* args)
|
bool ChatHandler::HandleGMTicketListCommand(const char* args)
|
||||||
{
|
{
|
||||||
SendSysMessage(LANG_COMMAND_TICKETSHOWLIST);
|
SendSysMessage(LANG_COMMAND_TICKETSHOWLIST);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "GlobalEvents.h"
|
#include "GlobalEvents.h"
|
||||||
|
#include "TicketMgr.h"
|
||||||
|
|
||||||
#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
|
#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
|
||||||
#include "CreatureGroups.h"
|
#include "CreatureGroups.h"
|
||||||
@@ -4640,3 +4641,37 @@ bool ChatHandler::HandleNpcAddFormationCommand(const char* args)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleNpcSetLinkCommand(const char* args)
|
||||||
|
{
|
||||||
|
if (!*args)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 linkguid = (uint32) atoi((char*)args);
|
||||||
|
|
||||||
|
Creature* pCreature = getSelectedCreature();
|
||||||
|
|
||||||
|
if(!pCreature)
|
||||||
|
{
|
||||||
|
SendSysMessage(LANG_SELECT_CREATURE);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!pCreature->GetDBTableGUIDLow())
|
||||||
|
{
|
||||||
|
PSendSysMessage("Selected creature isn't in `creature` table", pCreature->GetGUIDLow());
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!objmgr.SetCreatureLinkedRespawn(pCreature->GetDBTableGUIDLow(), linkguid))
|
||||||
|
{
|
||||||
|
PSendSysMessage("Selected creature can't link with guid '%u'", linkguid);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSendSysMessage("LinkGUID '%u' added to creature with DBTableGUID: '%u'", linkguid, pCreature->GetDBTableGUIDLow());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -714,6 +714,14 @@ bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleReloadCreatureLinkedRespawnCommand(const char* args)
|
||||||
|
{
|
||||||
|
sLog.outString( "Loading Linked Respawns... (`creature_linked_respawn`)" );
|
||||||
|
objmgr.LoadCreatureLinkedRespawn();
|
||||||
|
SendGlobalGMSysMessage("DB table `creature_linked_respawn` (creature linked respawns) reloaded.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
|
bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
|
||||||
{
|
{
|
||||||
sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
|
sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
|
||||||
@@ -4300,6 +4308,9 @@ bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
|
|||||||
PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
|
PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
|
||||||
PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
|
PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
|
||||||
PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
|
PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
|
||||||
|
if(const CreatureData* const linked = target->GetLinkedRespawnCreatureData())
|
||||||
|
if(CreatureInfo const *master = GetCreatureInfo(linked->id))
|
||||||
|
PSendSysMessage(LANG_NPCINFO_LINKGUID, objmgr.GetLinkedRespawnGuid(target->GetDBTableGUIDLow()), linked->id, master->Name);
|
||||||
|
|
||||||
if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
|
if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
|
||||||
{
|
{
|
||||||
|
|||||||
+88
-3
@@ -940,6 +940,94 @@ void ObjectMgr::LoadCreatureModelInfo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.outError("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.outError("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.outError("LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask",guid,linkedGuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectMgr::LoadCreatureLinkedRespawn()
|
||||||
|
{
|
||||||
|
mCreatureLinkedRespawnMap.clear();
|
||||||
|
QueryResult *result = WorldDatabase.Query("SELECT guid, linkedGuid FROM creature_linked_respawn ORDER BY guid ASC");
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
{
|
||||||
|
barGoLink bar(1);
|
||||||
|
|
||||||
|
bar.step();
|
||||||
|
|
||||||
|
sLog.outString("");
|
||||||
|
sLog.outErrorDb(">> Loaded 0 linked respawns. DB table `creature_linked_respawn` is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
barGoLink bar(result->GetRowCount());
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Field *fields = result->Fetch();
|
||||||
|
bar.step();
|
||||||
|
|
||||||
|
uint32 guid = fields[0].GetUInt32();
|
||||||
|
uint32 linkedGuid = fields[1].GetUInt32();
|
||||||
|
|
||||||
|
if(CheckCreatureLinkedRespawn(guid,linkedGuid))
|
||||||
|
mCreatureLinkedRespawnMap[guid] = linkedGuid;
|
||||||
|
|
||||||
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
|
||||||
|
sLog.outString();
|
||||||
|
sLog.outString( ">> Loaded %u linked respawns", mCreatureLinkedRespawnMap.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid)
|
||||||
|
{
|
||||||
|
if(!guid)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!linkedGuid) // we're removing the linking
|
||||||
|
{
|
||||||
|
mCreatureLinkedRespawnMap.erase(guid);
|
||||||
|
WorldDatabase.DirectPExecute("DELETE FROM `creature_linked_respawn` WHERE `guid` = '%u'",guid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CheckCreatureLinkedRespawn(guid,linkedGuid)) // we add/change linking
|
||||||
|
{
|
||||||
|
mCreatureLinkedRespawnMap[guid] = linkedGuid;
|
||||||
|
WorldDatabase.DirectPExecute("REPLACE INTO `creature_linked_respawn`(`guid`,`linkedGuid`) VALUES ('%u','%u')",guid,linkedGuid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectMgr::LoadCreatures()
|
void ObjectMgr::LoadCreatures()
|
||||||
{
|
{
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
@@ -1246,9 +1334,6 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data
|
|||||||
|
|
||||||
void ObjectMgr::LoadCreatureRespawnTimes()
|
void ObjectMgr::LoadCreatureRespawnTimes()
|
||||||
{
|
{
|
||||||
// remove outdated data
|
|
||||||
WorldDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");
|
|
||||||
|
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
|
|
||||||
QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM creature_respawn");
|
QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM creature_respawn");
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ struct TrinityStringLocale
|
|||||||
std::vector<std::string> Content; // 0 -> default, i -> i-1 locale index
|
std::vector<std::string> Content; // 0 -> default, i -> i-1 locale index
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::map<uint32,uint32> CreatureLinkedRespawnMap;
|
||||||
typedef UNORDERED_MAP<uint32,CreatureData> CreatureDataMap;
|
typedef UNORDERED_MAP<uint32,CreatureData> CreatureDataMap;
|
||||||
typedef UNORDERED_MAP<uint32,GameObjectData> GameObjectDataMap;
|
typedef UNORDERED_MAP<uint32,GameObjectData> GameObjectDataMap;
|
||||||
typedef UNORDERED_MAP<uint32,CreatureLocale> CreatureLocaleMap;
|
typedef UNORDERED_MAP<uint32,CreatureLocale> CreatureLocaleMap;
|
||||||
@@ -528,6 +529,9 @@ class ObjectMgr
|
|||||||
void LoadCreatureLocales();
|
void LoadCreatureLocales();
|
||||||
void LoadCreatureTemplates();
|
void LoadCreatureTemplates();
|
||||||
void LoadCreatures();
|
void LoadCreatures();
|
||||||
|
void LoadCreatureLinkedRespawn();
|
||||||
|
bool CheckCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid) const;
|
||||||
|
bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid);
|
||||||
void LoadCreatureRespawnTimes();
|
void LoadCreatureRespawnTimes();
|
||||||
void LoadCreatureAddons();
|
void LoadCreatureAddons();
|
||||||
void LoadCreatureModelInfo();
|
void LoadCreatureModelInfo();
|
||||||
@@ -635,6 +639,12 @@ class ObjectMgr
|
|||||||
}
|
}
|
||||||
CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }
|
CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }
|
||||||
void DeleteCreatureData(uint32 guid);
|
void DeleteCreatureData(uint32 guid);
|
||||||
|
uint32 GetLinkedRespawnGuid(uint32 guid) const
|
||||||
|
{
|
||||||
|
CreatureLinkedRespawnMap::const_iterator itr = mCreatureLinkedRespawnMap.find(guid);
|
||||||
|
if(itr == mCreatureLinkedRespawnMap.end()) return 0;
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
CreatureLocale const* GetCreatureLocale(uint32 entry) const
|
CreatureLocale const* GetCreatureLocale(uint32 entry) const
|
||||||
{
|
{
|
||||||
CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);
|
CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);
|
||||||
@@ -897,6 +907,7 @@ class ObjectMgr
|
|||||||
|
|
||||||
MapObjectGuids mMapObjectGuids;
|
MapObjectGuids mMapObjectGuids;
|
||||||
CreatureDataMap mCreatureDataMap;
|
CreatureDataMap mCreatureDataMap;
|
||||||
|
CreatureLinkedRespawnMap mCreatureLinkedRespawnMap;
|
||||||
CreatureLocaleMap mCreatureLocaleMap;
|
CreatureLocaleMap mCreatureLocaleMap;
|
||||||
GameObjectDataMap mGameObjectDataMap;
|
GameObjectDataMap mGameObjectDataMap;
|
||||||
GameObjectLocaleMap mGameObjectLocaleMap;
|
GameObjectLocaleMap mGameObjectLocaleMap;
|
||||||
|
|||||||
@@ -1254,6 +1254,9 @@ void World::SetInitialWorldSettings()
|
|||||||
sLog.outString( "Loading Creature Data..." );
|
sLog.outString( "Loading Creature Data..." );
|
||||||
objmgr.LoadCreatures();
|
objmgr.LoadCreatures();
|
||||||
|
|
||||||
|
sLog.outString( "Loading Creature Linked Respawn..." );
|
||||||
|
objmgr.LoadCreatureLinkedRespawn(); // must be after LoadCreatures()
|
||||||
|
|
||||||
sLog.outString( "Loading Creature Addon Data..." );
|
sLog.outString( "Loading Creature Addon Data..." );
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
|
objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
|
||||||
|
|||||||
Reference in New Issue
Block a user