you can now reload creatures from creature_template table

NOTE: reload is limited to one creature at a time
Usage: .reload creature_template $entry
Warning: this is mainly for developers, reloading a creature can cause unexpected behaviors!!

--HG--
branch : trunk
This commit is contained in:
Rat@walamy
2010-05-16 17:45:45 +02:00
parent c26399a968
commit 9771757c4c
13 changed files with 478 additions and 297 deletions
+3
View File
@@ -0,0 +1,3 @@
DELETE FROM `command` WHERE `name` IN ('reload creature_template');
INSERT INTO `command` VALUES
('reload creature_template','3','Syntax: .reload creature_template $entry\r\nReload the specified creature\'s template.');
@@ -0,0 +1,4 @@
DELETE FROM `trinity_string` WHERE `entry` IN (817,818);
INSERT INTO `trinity_string` VALUES
(817,'Entry %u not found in creature_template table.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(818,'Entry %u not found in sCreatureStorage. Possible new line in creature_template, but you can not add new creatures without restarting. Only modifing is allowed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+3
View File
@@ -622,6 +622,7 @@ INSERT INTO `command` VALUES
('reload spell_script_target',3,'Syntax: .reload spell_script_target\nReload spell_script_target table.'), ('reload spell_script_target',3,'Syntax: .reload spell_script_target\nReload spell_script_target table.'),
('reload spell_target_position',3,'Syntax: .reload spell_target_position\nReload spell_target_position table.'), ('reload spell_target_position',3,'Syntax: .reload spell_target_position\nReload spell_target_position table.'),
('reload spell_threats',3,'Syntax: .reload spell_threats\nReload spell_threats table.'), ('reload spell_threats',3,'Syntax: .reload spell_threats\nReload spell_threats table.'),
('reload creature_template','3','Syntax: .reload creature_template $entry\r\nReload the specified creature\'s template.'),
('reload trinity_string',3,'Syntax: .reload trinity_string\nReload trinity_string table.'), ('reload trinity_string',3,'Syntax: .reload trinity_string\nReload trinity_string table.'),
('reload waypoint_scripts',3,'Syntax: .reload waypoint_scripts\nReload waypoint_scripts table.'), ('reload waypoint_scripts',3,'Syntax: .reload waypoint_scripts\nReload waypoint_scripts table.'),
('repairitems',2,'Syntax: .repairitems\r\n\r\nRepair all selected player''s items.'), ('repairitems',2,'Syntax: .repairitems\r\n\r\nRepair all selected player''s items.'),
@@ -15126,6 +15127,8 @@ INSERT INTO `trinity_string` (`entry`,`content_default`,`content_loc1`,`content_
(814, 'Member', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), (814, 'Member', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(815, 'Initiate', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), (815, 'Initiate', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(816, 'Warning: You''ve entered a no-fly zone and are about to be dismounted!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), (816, 'Warning: You''ve entered a no-fly zone and are about to be dismounted!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(817, 'Entry %u not found in creature_template table.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(818, 'Entry %u not found in sCreatureStorage. Possible new line in creature_template, but you can not add new creatures without restarting. Only modifing is allowed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1000, 'Exiting daemon...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), (1000, 'Exiting daemon...', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(1001, 'Account deleted: %s', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), (1001, 'Account deleted: %s', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
(1002, 'Account %s NOT deleted (probably sql file format was updated)', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL), (1002, 'Account %s NOT deleted (probably sql file format was updated)', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+1
View File
@@ -458,6 +458,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "creature_linked_respawn", SEC_GAMEMASTER, true, &ChatHandler::HandleReloadCreatureLinkedRespawnCommand, "", NULL }, { "creature_linked_respawn", SEC_GAMEMASTER, 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 },
{ "creature_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureTemplateCommand, "", NULL },
//{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL }, //{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL },
{ "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL }, { "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL },
{ "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL }, { "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
+1
View File
@@ -361,6 +361,7 @@ class ChatHandler
bool HandleReloadEventAISummonsCommand(const char* args); bool HandleReloadEventAISummonsCommand(const char* args);
bool HandleReloadEventAIScriptsCommand(const char* args); bool HandleReloadEventAIScriptsCommand(const char* args);
bool HandleReloadCommandCommand(const char* args); bool HandleReloadCommandCommand(const char* args);
bool HandleReloadCreatureTemplateCommand(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 HandleReloadCreatureLinkedRespawnCommand(const char* args);
+3
View File
@@ -803,6 +803,9 @@ bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry,
AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING); AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
} }
} }
LastUsedScriptID = m_creatureInfo->ScriptID;
return bResult; return bResult;
} }
+2
View File
@@ -216,6 +216,8 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
SetZoneScript(); SetZoneScript();
LastUsedScriptID = GetGOInfo()->ScriptId;
return true; return true;
} }
+4 -1
View File
@@ -725,7 +725,10 @@ enum TrinityStrings
LANG_GUILD_MEMBER = 814, LANG_GUILD_MEMBER = 814,
LANG_GUILD_INITIATE = 815, LANG_GUILD_INITIATE = 815,
LANG_ZONE_NOFLYZONE = 816, LANG_ZONE_NOFLYZONE = 816,
// Room for in-game strings 817-999 not used
LANG_COMMAND_CREATURETEMPLATE_NOTFOUND = 817,
LANG_COMMAND_CREATURESTORAGE_NOTFOUND = 818,
// Room for in-game strings 819-999 not used
// Level 4 (CLI only commands) // Level 4 (CLI only commands)
LANG_COMMAND_EXIT = 1000, LANG_COMMAND_EXIT = 1000,
+145
View File
@@ -749,6 +749,151 @@ bool ChatHandler::HandleReloadCommandCommand(const char*)
return true; return true;
} }
bool ChatHandler::HandleReloadCreatureTemplateCommand(const char* args)
{
if (!*args)
return false;
uint32 entry = (uint32) atoi((char*)args);
QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT difficulty_entry_1,difficulty_entry_2,difficulty_entry_3,KillCredit1,KillCredit2,modelid1,modelid2,modelid3,modelid4,name,subname,IconName,gossip_menu_id,minlevel,maxlevel,exp,faction_A,faction_H,npcflag,speed_walk,speed_run,scale,rank,mindmg,maxdmg,dmgschool,attackpower,dmg_multiplier,baseattacktime,rangeattacktime,unit_class,unit_flags,dynamicflags,family,trainer_type,trainer_spell,trainer_class,trainer_race,minrangedmg,maxrangedmg,rangedattackpower,type,type_flags,lootid,pickpocketloot,skinloot,resistance1,resistance2,resistance3,resistance4,resistance5,resistance6,spell1,spell2,spell3,spell4,spell5,spell6,spell7,spell8,PetSpellDataId,VehicleId,mingold,maxgold,AIName,MovementType,InhabitType,Health_mod,Mana_mod,Armor_mod,RacialLeader,questItem1,questItem2,questItem3,questItem4,questItem5,questItem6,movementId,RegenHealth,equipment_id,mechanic_immune_mask,flags_extra,ScriptName FROM creature_template WHERE entry = %u", entry);
if (!result)
{
PSendSysMessage(LANG_COMMAND_CREATURETEMPLATE_NOTFOUND, entry);
SetSentErrorMessage(true);
return false;
}
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry);
if (!cInfo)
{
PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry);
SetSentErrorMessage(true);
return false;
}
sLog.outString("Reloading creature template entry %u", entry);
Field *fields = result->Fetch();
const_cast<CreatureInfo*>(cInfo)->DifficultyEntry[0] = fields[0].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->DifficultyEntry[1] = fields[1].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->DifficultyEntry[2] = fields[2].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->KillCredit[0] = fields[3].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->KillCredit[1] = fields[4].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->Modelid1 = fields[5].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->Modelid2 = fields[6].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->Modelid3 = fields[7].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->Modelid4 = fields[8].GetUInt32();
size_t len = 0;
if (const char* temp = fields[9].GetString())
{
if (cInfo->Name)
delete cInfo->Name;
len = strlen(temp)+1;
const_cast<CreatureInfo*>(cInfo)->Name = new char[len];
strncpy(cInfo->Name, temp, len);
}
if (const char* temp = fields[10].GetString())
{
if (cInfo->SubName)
delete cInfo->SubName;
len = strlen(temp)+1;
const_cast<CreatureInfo*>(cInfo)->SubName = new char[len];
strncpy(cInfo->SubName, temp, len);
}
if (const char* temp = fields[11].GetString())
{
if (cInfo->IconName)
delete cInfo->IconName;
len = strlen(temp)+1;
const_cast<CreatureInfo*>(cInfo)->IconName = new char[len];
strncpy(cInfo->IconName, temp, len);
}
const_cast<CreatureInfo*>(cInfo)->GossipMenuId = fields[12].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->minlevel = fields[13].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->maxlevel = fields[14].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->expansion = fields[15].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->faction_A = fields[16].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->faction_H = fields[17].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->npcflag = fields[18].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->speed_walk = fields[19].GetFloat();
const_cast<CreatureInfo*>(cInfo)->speed_run = fields[20].GetFloat();
const_cast<CreatureInfo*>(cInfo)->scale = fields[21].GetFloat();
const_cast<CreatureInfo*>(cInfo)->rank = fields[22].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->mindmg = fields[23].GetFloat();
const_cast<CreatureInfo*>(cInfo)->maxdmg = fields[24].GetFloat();
const_cast<CreatureInfo*>(cInfo)->dmgschool = fields[25].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->attackpower = fields[26].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->dmg_multiplier = fields[27].GetFloat();
const_cast<CreatureInfo*>(cInfo)->baseattacktime = fields[28].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->rangeattacktime = fields[29].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->unit_class = fields[30].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->unit_flags = fields[31].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->dynamicflags = fields[32].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->family = fields[33].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->trainer_type = fields[34].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->trainer_spell = fields[35].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->trainer_class = fields[36].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->trainer_race = fields[37].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->minrangedmg = fields[38].GetFloat();
const_cast<CreatureInfo*>(cInfo)->maxrangedmg = fields[39].GetFloat();
const_cast<CreatureInfo*>(cInfo)->rangedattackpower = fields[40].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->type = fields[41].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->type_flags = fields[42].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->lootid = fields[43].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->pickpocketLootId = fields[44].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->SkinLootId = fields[45].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->resistance1 = fields[46].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->resistance2 = fields[47].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->resistance3 = fields[48].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->resistance4 = fields[49].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->resistance5 = fields[50].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->resistance6 = fields[51].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->spells[0] = fields[52].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->spells[1] = fields[53].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->spells[2] = fields[54].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->spells[3] = fields[55].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->spells[4] = fields[56].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->spells[5] = fields[57].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->spells[6] = fields[58].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->spells[7] = fields[59].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->PetSpellDataId = fields[60].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->VehicleId = fields[61].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->mingold = fields[62].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->maxgold = fields[63].GetUInt32();
if (const char* temp = fields[64].GetString())
{
if (cInfo->AIName)
delete cInfo->AIName;
len = strlen(temp)+1;
const_cast<CreatureInfo*>(cInfo)->AIName = new char[len];
strncpy(const_cast<char*>(cInfo->AIName), temp, len);
}
const_cast<CreatureInfo*>(cInfo)->MovementType = fields[65].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->InhabitType = fields[66].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->ModHealth = fields[67].GetFloat();
const_cast<CreatureInfo*>(cInfo)->ModMana = fields[68].GetFloat();
const_cast<CreatureInfo*>(cInfo)->ModArmor = fields[69].GetFloat();
const_cast<CreatureInfo*>(cInfo)->RacialLeader = fields[70].GetBool();
const_cast<CreatureInfo*>(cInfo)->questItems[0] = fields[71].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->questItems[1] = fields[72].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->questItems[2] = fields[73].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->questItems[3] = fields[74].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->questItems[4] = fields[75].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->questItems[5] = fields[76].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->movementId = fields[77].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->RegenHealth = fields[78].GetBool();
const_cast<CreatureInfo*>(cInfo)->equipmentId = fields[79].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->MechanicImmuneMask = fields[80].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->flags_extra = fields[81].GetUInt32();
const_cast<CreatureInfo*>(cInfo)->ScriptID = objmgr.GetScriptId(fields[82].GetString());
objmgr.CheckCreatureTemplate(cInfo);
SendGlobalGMSysMessage("Creature template reloaded.");
return true;
}
bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*) bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
{ {
sLog.outString("Loading Quests Relations... (`creature_questrelation`)"); sLog.outString("Loading Quests Relations... (`creature_questrelation`)");
+10
View File
@@ -126,6 +126,16 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data)
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if ((unit && unit->GetCreatureInfo()->ScriptID != unit->LastUsedScriptID) || (go && go->GetGOInfo()->ScriptId != go->LastUsedScriptID))
{
sLog.outDebug("WORLD: HandleGossipSelectOptionOpcode - Script reloaded while in use, ignoring and set new scipt id");
if (unit)
unit->LastUsedScriptID = unit->GetCreatureInfo()->ScriptID;
if (go)
go->LastUsedScriptID = go->GetGOInfo()->ScriptId;
_player->PlayerTalkClass->CloseGossip();
return;
}
if (!code.empty()) if (!code.empty())
{ {
if (unit) if (unit)
+1
View File
@@ -688,6 +688,7 @@ class WorldObject : public Object, public WorldLocation
#endif #endif
bool m_isWorldObject; bool m_isWorldObject;
uint32 LastUsedScriptID;
protected: protected:
explicit WorldObject(); explicit WorldObject();
std::string m_name; std::string m_name;
+20 -20
View File
@@ -497,15 +497,18 @@ void ObjectMgr::LoadCreatureTemplates()
sLog.outString(">> Loaded %u creature definitions", sCreatureStorage.RecordCount); sLog.outString(">> Loaded %u creature definitions", sCreatureStorage.RecordCount);
sLog.outString(); sLog.outString();
std::set<uint32> difficultyEntries[MAX_DIFFICULTY - 1]; // already loaded difficulty 1 value in creatures
std::set<uint32> hasDifficultyEntries[MAX_DIFFICULTY - 1]; // already loaded creatures with difficulty 1 values
// check data correctness // check data correctness
for (uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i) for (uint32 i = 1; i < sCreatureStorage.MaxEntry; ++i)
{ {
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(i);
CheckCreatureTemplate(cInfo);
}
}
void ObjectMgr::CheckCreatureTemplate(CreatureInfo const* cInfo)
{
if (!cInfo) if (!cInfo)
continue; return;
bool ok = true; // bool to allow continue outside this loop bool ok = true; // bool to allow continue outside this loop
for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff) for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
@@ -518,13 +521,13 @@ void ObjectMgr::LoadCreatureTemplates()
if (!difficultyInfo) if (!difficultyInfo)
{ {
sLog.outErrorDb("Creature (Entry: %u) have `difficulty_entry_%u`=%u but creature entry %u not exist.", sLog.outErrorDb("Creature (Entry: %u) have `difficulty_entry_%u`=%u but creature entry %u not exist.",
i, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff]); cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff]);
continue; continue;
} }
if (difficultyEntries[diff].find(i) != difficultyEntries[diff].end()) if (difficultyEntries[diff].find(cInfo->Entry) != difficultyEntries[diff].end())
{ {
sLog.outErrorDb("Creature (Entry: %u) listed as difficulty %u but have value in `difficulty_entry_1`.", i, diff + 1); sLog.outErrorDb("Creature (Entry: %u) listed as difficulty %u but have value in `difficulty_entry_1`.", cInfo->Entry, diff + 1);
continue; continue;
} }
@@ -541,7 +544,7 @@ void ObjectMgr::LoadCreatureTemplates()
if (hasDifficultyEntries[diff2].find(cInfo->DifficultyEntry[diff]) != hasDifficultyEntries[diff2].end()) if (hasDifficultyEntries[diff2].find(cInfo->DifficultyEntry[diff]) != hasDifficultyEntries[diff2].end())
{ {
sLog.outErrorDb("Creature (Entry: %u) have `difficulty_entry_%u`=%u but creature entry %u have difficulty %u entry also.", sLog.outErrorDb("Creature (Entry: %u) have `difficulty_entry_%u`=%u but creature entry %u have difficulty %u entry also.",
i, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff], diff2 + 1); cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff], cInfo->DifficultyEntry[diff], diff2 + 1);
continue; continue;
} }
ok2 = true; ok2 = true;
@@ -552,60 +555,58 @@ void ObjectMgr::LoadCreatureTemplates()
if (cInfo->unit_class != difficultyInfo->unit_class) if (cInfo->unit_class != difficultyInfo->unit_class)
{ {
sLog.outErrorDb("Creature (Entry: %u, class %u) has different `unit_class` in difficulty %u mode (Entry: %u, class %u).", sLog.outErrorDb("Creature (Entry: %u, class %u) has different `unit_class` in difficulty %u mode (Entry: %u, class %u).",
i, cInfo->unit_class, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->unit_class); cInfo->Entry, cInfo->unit_class, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->unit_class);
continue; continue;
} }
if (cInfo->npcflag != difficultyInfo->npcflag) if (cInfo->npcflag != difficultyInfo->npcflag)
{ {
sLog.outErrorDb("Creature (Entry: %u) has different `npcflag` in difficulty %u mode (Entry: %u).", i, diff + 1, cInfo->DifficultyEntry[diff]); sLog.outErrorDb("Creature (Entry: %u) has different `npcflag` in difficulty %u mode (Entry: %u).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
continue; continue;
} }
if (cInfo->trainer_class != difficultyInfo->trainer_class) if (cInfo->trainer_class != difficultyInfo->trainer_class)
{ {
sLog.outErrorDb("Creature (Entry: %u) has different `trainer_class` in difficulty %u mode (Entry: %u).", i, diff + 1, cInfo->DifficultyEntry[diff]); sLog.outErrorDb("Creature (Entry: %u) has different `trainer_class` in difficulty %u mode (Entry: %u).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
continue; continue;
} }
if (cInfo->trainer_race != difficultyInfo->trainer_race) if (cInfo->trainer_race != difficultyInfo->trainer_race)
{ {
sLog.outErrorDb("Creature (Entry: %u) has different `trainer_race` in difficulty %u mode (Entry: %u).", i, diff + 1, cInfo->DifficultyEntry[diff]); sLog.outErrorDb("Creature (Entry: %u) has different `trainer_race` in difficulty %u mode (Entry: %u).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
continue; continue;
} }
if (cInfo->trainer_type != difficultyInfo->trainer_type) if (cInfo->trainer_type != difficultyInfo->trainer_type)
{ {
sLog.outErrorDb("Creature (Entry: %u) has different `trainer_type` in difficulty %u mode (Entry: %u).", i, diff + 1, cInfo->DifficultyEntry[diff]); sLog.outErrorDb("Creature (Entry: %u) has different `trainer_type` in difficulty %u mode (Entry: %u).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
continue; continue;
} }
if (cInfo->trainer_spell != difficultyInfo->trainer_spell) if (cInfo->trainer_spell != difficultyInfo->trainer_spell)
{ {
sLog.outErrorDb("Creature (Entry: %u) has different `trainer_spell` in difficulty %u mode (Entry: %u).", i, diff + 1, cInfo->DifficultyEntry[diff]); sLog.outErrorDb("Creature (Entry: %u) has different `trainer_spell` in difficulty %u mode (Entry: %u).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
continue; continue;
} }
if (difficultyInfo->AIName && *difficultyInfo->AIName) if (difficultyInfo->AIName && *difficultyInfo->AIName)
{ {
sLog.outErrorDb("Difficulty %u mode creature (Entry: %u) has `AIName`, but in any case will used difficulty 0 mode creature (Entry: %u) AIName.", sLog.outErrorDb("Difficulty %u mode creature (Entry: %u) has `AIName`, but in any case will used difficulty 0 mode creature (Entry: %u) AIName.",
diff, cInfo->DifficultyEntry[diff], i); diff, cInfo->DifficultyEntry[diff], cInfo->Entry);
continue; continue;
} }
if (difficultyInfo->ScriptID) if (difficultyInfo->ScriptID)
{ {
sLog.outErrorDb("Difficulty %u mode creature (Entry: %u) has `ScriptName`, but in any case will used difficulty 0 mode creature (Entry: %u) ScriptName.", sLog.outErrorDb("Difficulty %u mode creature (Entry: %u) has `ScriptName`, but in any case will used difficulty 0 mode creature (Entry: %u) ScriptName.",
diff, cInfo->DifficultyEntry[diff], i); diff, cInfo->DifficultyEntry[diff], cInfo->Entry);
continue; continue;
} }
hasDifficultyEntries[diff].insert(i); hasDifficultyEntries[diff].insert(cInfo->Entry);
difficultyEntries[diff].insert(cInfo->DifficultyEntry[diff]); difficultyEntries[diff].insert(cInfo->DifficultyEntry[diff]);
ok = true; ok = true;
} }
if (!ok)
continue;
FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_A); FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_A);
if (!factionTemplate) if (!factionTemplate)
@@ -797,7 +798,6 @@ void ObjectMgr::LoadCreatureTemplates()
} }
const_cast<CreatureInfo*>(cInfo)->dmg_multiplier *= Creature::_GetDamageMod(cInfo->rank); const_cast<CreatureInfo*>(cInfo)->dmg_multiplier *= Creature::_GetDamageMod(cInfo->rank);
}
} }
void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr) void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr)
+5
View File
@@ -635,6 +635,7 @@ class ObjectMgr
void LoadCreatureClassLevelStats(); void LoadCreatureClassLevelStats();
void LoadCreatureLocales(); void LoadCreatureLocales();
void LoadCreatureTemplates(); void LoadCreatureTemplates();
void CheckCreatureTemplate(CreatureInfo const* cInfo);
void LoadCreatures(); void LoadCreatures();
void LoadCreatureLinkedRespawn(); void LoadCreatureLinkedRespawn();
bool CheckCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid) const; bool CheckCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid) const;
@@ -1115,6 +1116,10 @@ class ObjectMgr
CacheNpcTextIdMap m_mCacheNpcTextIdMap; CacheNpcTextIdMap m_mCacheNpcTextIdMap;
CacheVendorItemMap m_mCacheVendorItemMap; CacheVendorItemMap m_mCacheVendorItemMap;
CacheTrainerSpellMap m_mCacheTrainerSpellMap; CacheTrainerSpellMap m_mCacheTrainerSpellMap;
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
}; };
#define objmgr Trinity::Singleton<ObjectMgr>::Instance() #define objmgr Trinity::Singleton<ObjectMgr>::Instance()