2010-10-07 15:35:36 +02:00
/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 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, see <http://www.gnu.org/licenses/>.
2008-10-11 14:16:25 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
#include "Common.h"
2010-06-08 16:13:55 -06:00
#include "DatabaseEnv.h"
2008-10-11 14:16:25 -05:00
#include "Log.h"
#include "MapManager.h"
#include "ObjectMgr.h"
2011-05-03 15:01:10 +02:00
#include "ArenaTeamMgr.h"
2011-05-04 10:08:09 +02:00
#include "GuildMgr.h"
2011-05-05 10:23:00 +02:00
#include "GroupMgr.h"
2008-10-11 14:16:25 -05:00
#include "SpellMgr.h"
#include "UpdateMask.h"
#include "World.h"
#include "ArenaTeam.h"
2010-06-07 23:40:17 +02:00
#include "Transport.h"
2008-10-11 14:16:25 -05:00
#include "Language.h"
2009-03-06 19:36:47 -06:00
#include "GameEventMgr.h"
2008-10-11 14:16:25 -05:00
#include "Spell.h"
#include "Chat.h"
2008-10-20 12:59:45 -05:00
#include "AccountMgr.h"
2008-10-11 14:16:25 -05:00
#include "InstanceSaveMgr.h"
#include "SpellAuras.h"
#include "Util.h"
2008-11-22 09:51:35 -06:00
#include "WaypointManager.h"
2009-12-20 13:35:08 +02:00
#include "GossipDef.h"
2010-03-12 18:19:50 +01:00
#include "Vehicle.h"
2010-03-15 04:37:28 +01:00
#include "AchievementMgr.h"
2010-07-21 12:14:23 +02:00
#include "DisableMgr.h"
2010-07-24 22:41:42 +02:00
#include "ScriptMgr.h"
#include "SpellScript.h"
2010-09-14 13:56:27 +02:00
#include "PoolMgr.h"
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ScriptMapMap sQuestEndScripts ;
ScriptMapMap sQuestStartScripts ;
ScriptMapMap sSpellScripts ;
ScriptMapMap sGameObjectScripts ;
ScriptMapMap sEventScripts ;
2008-12-10 06:34:35 +02:00
ScriptMapMap sWaypointScripts ;
2009-10-17 15:51:44 -07:00
2010-08-20 12:19:14 +06:00
std :: string GetScriptsTableNameByType ( ScriptsType type )
{
std :: string res = "" ;
switch ( type )
{
case SCRIPTS_QUEST_END : res = "quest_end_scripts" ; break ;
case SCRIPTS_QUEST_START : res = "quest_start_scripts" ; break ;
case SCRIPTS_SPELL : res = "spell_scripts" ; break ;
case SCRIPTS_GAMEOBJECT : res = "gameobject_scripts" ; break ;
case SCRIPTS_EVENT : res = "event_scripts" ; break ;
case SCRIPTS_WAYPOINT : res = "waypoint_scripts" ; break ;
2010-08-21 20:55:31 +02:00
default : break ;
2010-08-20 12:19:14 +06:00
}
return res ;
}
ScriptMapMap * GetScriptsMapByType ( ScriptsType type )
{
ScriptMapMap * res = NULL ;
switch ( type )
{
case SCRIPTS_QUEST_END : res = & sQuestEndScripts ; break ;
case SCRIPTS_QUEST_START : res = & sQuestStartScripts ; break ;
case SCRIPTS_SPELL : res = & sSpellScripts ; break ;
case SCRIPTS_GAMEOBJECT : res = & sGameObjectScripts ; break ;
case SCRIPTS_EVENT : res = & sEventScripts ; break ;
case SCRIPTS_WAYPOINT : res = & sWaypointScripts ; break ;
2010-08-21 20:55:31 +02:00
default : break ;
2010-08-20 12:19:14 +06:00
}
return res ;
}
2010-08-20 14:57:05 +06:00
std :: string GetScriptCommandName ( ScriptCommands command )
{
std :: string res = "" ;
switch ( command )
{
case SCRIPT_COMMAND_TALK : res = "SCRIPT_COMMAND_TALK" ; break ;
case SCRIPT_COMMAND_EMOTE : res = "SCRIPT_COMMAND_EMOTE" ; break ;
case SCRIPT_COMMAND_FIELD_SET : res = "SCRIPT_COMMAND_FIELD_SET" ; break ;
case SCRIPT_COMMAND_MOVE_TO : res = "SCRIPT_COMMAND_MOVE_TO" ; break ;
case SCRIPT_COMMAND_FLAG_SET : res = "SCRIPT_COMMAND_FLAG_SET" ; break ;
case SCRIPT_COMMAND_FLAG_REMOVE : res = "SCRIPT_COMMAND_FLAG_REMOVE" ; break ;
case SCRIPT_COMMAND_TELEPORT_TO : res = "SCRIPT_COMMAND_TELEPORT_TO" ; break ;
case SCRIPT_COMMAND_QUEST_EXPLORED : res = "SCRIPT_COMMAND_QUEST_EXPLORED" ; break ;
case SCRIPT_COMMAND_KILL_CREDIT : res = "SCRIPT_COMMAND_KILL_CREDIT" ; break ;
case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT : res = "SCRIPT_COMMAND_RESPAWN_GAMEOBJECT" ; break ;
case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE : res = "SCRIPT_COMMAND_TEMP_SUMMON_CREATURE" ; break ;
case SCRIPT_COMMAND_OPEN_DOOR : res = "SCRIPT_COMMAND_OPEN_DOOR" ; break ;
case SCRIPT_COMMAND_CLOSE_DOOR : res = "SCRIPT_COMMAND_CLOSE_DOOR" ; break ;
case SCRIPT_COMMAND_ACTIVATE_OBJECT : res = "SCRIPT_COMMAND_ACTIVATE_OBJECT" ; break ;
case SCRIPT_COMMAND_REMOVE_AURA : res = "SCRIPT_COMMAND_REMOVE_AURA" ; break ;
case SCRIPT_COMMAND_CAST_SPELL : res = "SCRIPT_COMMAND_CAST_SPELL" ; break ;
case SCRIPT_COMMAND_PLAY_SOUND : res = "SCRIPT_COMMAND_PLAY_SOUND" ; break ;
case SCRIPT_COMMAND_CREATE_ITEM : res = "SCRIPT_COMMAND_CREATE_ITEM" ; break ;
case SCRIPT_COMMAND_DESPAWN_SELF : res = "SCRIPT_COMMAND_DESPAWN_SELF" ; break ;
case SCRIPT_COMMAND_LOAD_PATH : res = "SCRIPT_COMMAND_LOAD_PATH" ; break ;
case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT : res = "SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT" ; break ;
case SCRIPT_COMMAND_KILL : res = "SCRIPT_COMMAND_KILL" ; break ;
// TrinityCore only
case SCRIPT_COMMAND_ORIENTATION : res = "SCRIPT_COMMAND_ORIENTATION" ; break ;
case SCRIPT_COMMAND_EQUIP : res = "SCRIPT_COMMAND_EQUIP" ; break ;
case SCRIPT_COMMAND_MODEL : res = "SCRIPT_COMMAND_MODEL" ; break ;
case SCRIPT_COMMAND_CLOSE_GOSSIP : res = "SCRIPT_COMMAND_CLOSE_GOSSIP" ; break ;
case SCRIPT_COMMAND_PLAYMOVIE : res = "SCRIPT_COMMAND_PLAYMOVIE" ; break ;
2010-09-12 01:40:27 +02:00
default :
2010-08-20 14:57:05 +06:00
{
char sz [ 32 ];
sprintf ( sz , "Unknown command: %u" , command );
res = sz ;
break ;
}
}
return res ;
}
std :: string ScriptInfo :: GetDebugInfo () const
{
char sz [ 256 ];
sprintf ( sz , "%s ('%s' script id: %u)" , GetScriptCommandName ( command ). c_str (), GetScriptsTableNameByType ( type ). c_str (), id );
return std :: string ( sz );
}
2008-10-11 14:16:25 -05:00
bool normalizePlayerName ( std :: string & name )
{
2010-04-07 19:14:10 +02:00
if ( name . empty ())
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
wchar_t wstr_buf [ MAX_INTERNAL_PLAYER_NAME + 1 ];
size_t wstr_len = MAX_INTERNAL_PLAYER_NAME ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( name , & wstr_buf [ 0 ], wstr_len ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
wstr_buf [ 0 ] = wcharToUpper ( wstr_buf [ 0 ]);
2009-10-17 16:20:24 -07:00
for ( size_t i = 1 ; i < wstr_len ; ++ i )
2008-10-11 14:16:25 -05:00
wstr_buf [ i ] = wcharToLower ( wstr_buf [ i ]);
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( ! WStrToUtf8 ( wstr_buf , wstr_len , name ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
LanguageDesc lang_description [ LANGUAGES_COUNT ] =
{
{ LANG_ADDON , 0 , 0 },
{ LANG_UNIVERSAL , 0 , 0 },
{ LANG_ORCISH , 669 , SKILL_LANG_ORCISH },
{ LANG_DARNASSIAN , 671 , SKILL_LANG_DARNASSIAN },
{ LANG_TAURAHE , 670 , SKILL_LANG_TAURAHE },
{ LANG_DWARVISH , 672 , SKILL_LANG_DWARVEN },
{ LANG_COMMON , 668 , SKILL_LANG_COMMON },
{ LANG_DEMONIC , 815 , SKILL_LANG_DEMON_TONGUE },
{ LANG_TITAN , 816 , SKILL_LANG_TITAN },
{ LANG_THALASSIAN , 813 , SKILL_LANG_THALASSIAN },
{ LANG_DRACONIC , 814 , SKILL_LANG_DRACONIC },
{ LANG_KALIMAG , 817 , SKILL_LANG_OLD_TONGUE },
{ LANG_GNOMISH , 7340 , SKILL_LANG_GNOMISH },
{ LANG_TROLL , 7341 , SKILL_LANG_TROLL },
{ LANG_GUTTERSPEAK , 17737 , SKILL_LANG_GUTTERSPEAK },
{ LANG_DRAENEI , 29932 , SKILL_LANG_DRAENEI },
{ LANG_ZOMBIE , 0 , 0 },
{ LANG_GNOMISH_BINARY , 0 , 0 },
{ LANG_GOBLIN_BINARY , 0 , 0 }
};
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
LanguageDesc const * GetLanguageDescByID ( uint32 lang )
{
2009-10-17 16:20:24 -07:00
for ( uint8 i = 0 ; i < LANGUAGES_COUNT ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( uint32 ( lang_description [ i ]. lang_id ) == lang )
2008-10-11 14:16:25 -05:00
return & lang_description [ i ];
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return NULL ;
}
2009-10-17 15:51:44 -07:00
2011-02-26 23:00:09 +01:00
bool SpellClickInfo :: IsFitToRequirements ( Unit const * clicker , Unit const * clickee ) const
2009-06-15 23:07:43 -05:00
{
2011-03-08 19:11:02 +01:00
Player const * playerClicker = clicker -> ToPlayer ();
if ( playerClicker )
2009-06-15 23:07:43 -05:00
{
2011-02-26 23:00:09 +01:00
if ( questStart )
{
// not in expected required quest state
if ((( ! questStartCanActive || ! playerClicker -> IsActiveQuest ( questStart )) && ! playerClicker -> GetQuestRewardStatus ( questStart )))
return false ;
}
2009-10-17 15:51:44 -07:00
2011-02-26 23:00:09 +01:00
if ( questEnd )
{
// not in expected forbidden quest state
if ( playerClicker -> GetQuestRewardStatus ( questEnd ))
return false ;
}
2009-06-15 23:07:43 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-17 02:53:39 +02:00
if ( auraRequired )
2011-02-26 23:00:09 +01:00
if ( ! clicker -> HasAura ( auraRequired ))
2009-08-17 02:53:39 +02:00
return false ;
2009-10-17 15:51:44 -07:00
2009-08-17 02:53:39 +02:00
if ( auraForbidden )
2011-02-26 23:00:09 +01:00
if ( clicker -> HasAura ( auraForbidden ))
2009-08-17 02:53:39 +02:00
return false ;
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
Unit const * summoner = NULL ;
2009-08-17 02:53:39 +02:00
// Check summoners for party
2011-02-26 23:00:09 +01:00
if ( clickee -> isSummon ())
summoner = clickee -> ToTempSummon () -> GetSummoner ();
2009-08-17 02:53:39 +02:00
if ( ! summoner )
2011-02-26 23:00:09 +01:00
summoner = clickee ;
2009-10-17 15:51:44 -07:00
2011-02-26 23:00:09 +01:00
if ( ! playerClicker )
return true ;
// This only applies to players
2009-08-17 02:53:39 +02:00
switch ( userType )
{
case SPELL_CLICK_USER_FRIEND :
2011-02-26 23:00:09 +01:00
if ( ! playerClicker -> IsFriendlyTo ( summoner ))
2009-08-17 02:53:39 +02:00
return false ;
break ;
case SPELL_CLICK_USER_RAID :
2011-02-26 23:00:09 +01:00
if ( ! playerClicker -> IsInRaidWith ( summoner ))
2009-08-17 02:53:39 +02:00
return false ;
break ;
case SPELL_CLICK_USER_PARTY :
2011-02-26 23:00:09 +01:00
if ( ! playerClicker -> IsInPartyWith ( summoner ))
2009-08-17 02:53:39 +02:00
return false ;
break ;
2010-08-21 20:55:31 +02:00
default :
break ;
2009-08-17 02:53:39 +02:00
}
2009-10-17 15:51:44 -07:00
2009-06-15 23:07:43 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2011-08-04 15:14:15 +02:00
ObjectMgr :: ObjectMgr () : m_auctionid ( 1 ), m_equipmentSetGuid ( 1 ),
m_ItemTextId ( 1 ), m_mailid ( 1 ), m_hiPetNumber ( 1 ), m_hiCharGuid ( 1 ),
m_hiCreatureGuid ( 1 ), m_hiPetGuid ( 1 ), m_hiVehicleGuid ( 1 ), m_hiItemGuid ( 1 ),
m_hiGoGuid ( 1 ), m_hiDoGuid ( 1 ), m_hiCorpseGuid ( 1 ), m_hiMoTransGuid ( 1 )
{}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ObjectMgr ::~ ObjectMgr ()
{
2010-04-07 22:59:46 +02:00
for ( QuestMap :: iterator i = mQuestTemplates . begin (); i != mQuestTemplates . end (); ++ i )
2008-10-11 14:16:25 -05:00
delete i -> second ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( PetLevelInfoMap :: iterator i = petInfo . begin (); i != petInfo . end (); ++ i )
2008-10-11 14:16:25 -05:00
delete [] i -> second ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// free only if loaded
for ( int class_ = 0 ; class_ < MAX_CLASSES ; ++ class_ )
delete [] playerClassInfo [ class_ ]. levelInfo ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
for ( int race = 0 ; race < MAX_RACES ; ++ race )
for ( int class_ = 0 ; class_ < MAX_CLASSES ; ++ class_ )
delete [] playerInfo [ race ][ class_ ]. levelInfo ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
for ( CacheVendorItemMap :: iterator itr = m_mCacheVendorItemMap . begin (); itr != m_mCacheVendorItemMap . end (); ++ itr )
itr -> second . Clear ();
2009-10-17 15:51:44 -07:00
2010-12-21 20:26:59 +01:00
m_mCacheTrainerSpellMap . clear ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-08-04 15:14:15 +02:00
void ObjectMgr :: AddLocaleString ( std :: string const & s , LocaleConstant locale , StringVector & data )
2010-08-26 15:54:56 +06:00
{
if ( ! s . empty ())
{
2010-09-17 19:55:54 +02:00
if ( data . size () <= size_t ( locale ))
data . resize ( locale + 1 );
2010-08-26 15:54:56 +06:00
2010-09-17 19:55:54 +02:00
data [ locale ] = s ;
2010-08-26 15:54:56 +06:00
}
}
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadCreatureLocales ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
mCreatureLocaleMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, name_loc1, subname_loc1, name_loc2, subname_loc2, name_loc3, subname_loc3, name_loc4, subname_loc4, name_loc5, subname_loc5, name_loc6, subname_loc6, name_loc7, subname_loc7, name_loc8, subname_loc8 FROM locales_creature" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CreatureLocale & data = mCreatureLocaleMap [ entry ];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-08-26 15:54:56 +06:00
LocaleConstant locale = ( LocaleConstant ) i ;
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ 1 + 2 * ( i - 1 )]. GetString (), locale , data . Name );
AddLocaleString ( fields [ 1 + 2 * ( i - 1 ) + 1 ]. GetString (), locale , data . SubName );
2008-10-11 14:16:25 -05:00
}
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu creature locale strings in %u ms" , ( unsigned long ) mCreatureLocaleMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 00:58:24 +02:00
void ObjectMgr :: LoadGossipMenuItemsLocales ()
2008-11-05 09:22:56 -06:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-12-20 13:35:08 +02:00
mGossipMenuItemsLocaleMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT menu_id, id, "
"option_text_loc1, box_text_loc1, option_text_loc2, box_text_loc2, "
"option_text_loc3, box_text_loc3, option_text_loc4, box_text_loc4, "
"option_text_loc5, box_text_loc5, option_text_loc6, box_text_loc6, "
"option_text_loc7, box_text_loc7, option_text_loc8, box_text_loc8 "
2009-12-20 13:35:08 +02:00
"FROM locales_gossip_menu_option" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-11-05 09:22:56 -06:00
return ;
2009-10-17 15:51:44 -07:00
2008-11-05 09:22:56 -06:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-12-20 13:35:08 +02:00
uint16 menuId = fields [ 0 ]. GetUInt16 ();
uint16 id = fields [ 1 ]. GetUInt16 ();
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
GossipMenuItemsLocale & data = mGossipMenuItemsLocaleMap [ MAKE_PAIR32 ( menuId , id )];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2008-11-05 09:22:56 -06:00
{
2010-08-26 15:54:56 +06:00
LocaleConstant locale = ( LocaleConstant ) i ;
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ 2 + 2 * ( i - 1 )]. GetString (), locale , data . OptionText );
AddLocaleString ( fields [ 2 + 2 * ( i - 1 ) + 1 ]. GetString (), locale , data . BoxText );
2008-11-05 09:22:56 -06:00
}
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu gossip_menu_option locale strings in %u ms" , ( unsigned long ) mGossipMenuItemsLocaleMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-11-05 09:22:56 -06:00
}
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
void ObjectMgr :: LoadPointOfInterestLocales ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-02-17 17:40:03 -06:00
mPointOfInterestLocaleMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, icon_name_loc1, icon_name_loc2, icon_name_loc3, icon_name_loc4, icon_name_loc5, icon_name_loc6, icon_name_loc7, icon_name_loc8 FROM locales_points_of_interest" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2009-02-17 17:40:03 -06:00
return ;
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
PointOfInterestLocale & data = mPointOfInterestLocaleMap [ entry ];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ i ]. GetString (), LocaleConstant ( i ), data . IconName );
2009-02-17 17:40:03 -06:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu points_of_interest locale strings in %u ms" , ( unsigned long ) mPointOfInterestLocaleMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2009-02-17 17:40:03 -06:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadCreatureTemplates ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-28 22:57:08 +02:00
// 0 1 2 3 4 5 6 7 8
QueryResult result = WorldDatabase . Query ( "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, "
// 9 10 11 12 13 14 15 16 17 18 19 20 21
"modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, "
// 22 23 24 25 26 27 28 29 30 31 32
"scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, "
// 33 34 35 36 37 38 39 40 41 42
"dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, "
// 43 44 45 46 47 48 49 50 51 52 53
"type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, "
// 54 55 56 57 58 59 60 61 62 63 64 65 66
"spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
// 67 68 69 70 71 72 73 74 75 76 77
"InhabitType, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, "
// 78 79 80 81 82 83
"movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName "
"FROM creature_template;" );
2009-10-17 15:51:44 -07:00
2011-04-28 22:57:08 +02:00
if ( ! result )
{
sLog -> outString ( ">> Loaded 0 creature template definitions. DB table `creature_template` is empty." );
sLog -> outString ();
return ;
}
uint32 count = 0 ;
do
{
Field * fields = result -> Fetch ();
uint32 entry = fields [ 0 ]. GetUInt32 ();
2011-04-29 19:59:40 +02:00
CreatureTemplate & creatureTemplate = CreatureTemplateStore [ entry ];
2011-04-28 22:57:08 +02:00
creatureTemplate . Entry = entry ;
for ( uint8 i = 0 ; i < MAX_DIFFICULTY - 1 ; ++ i )
{
creatureTemplate . DifficultyEntry [ i ] = fields [ 1 + i ]. GetUInt32 ();
}
for ( uint8 i = 0 ; i < MAX_KILL_CREDIT ; ++ i )
{
creatureTemplate . KillCredit [ i ] = fields [ 4 + i ]. GetUInt32 ();
}
creatureTemplate . Modelid1 = fields [ 6 ]. GetUInt32 ();
creatureTemplate . Modelid2 = fields [ 7 ]. GetUInt32 ();
creatureTemplate . Modelid3 = fields [ 8 ]. GetUInt32 ();
creatureTemplate . Modelid4 = fields [ 9 ]. GetUInt32 ();
creatureTemplate . Name = fields [ 10 ]. GetString ();
creatureTemplate . SubName = fields [ 11 ]. GetString ();
creatureTemplate . IconName = fields [ 12 ]. GetString ();
creatureTemplate . GossipMenuId = fields [ 13 ]. GetUInt32 ();
creatureTemplate . minlevel = fields [ 14 ]. GetUInt8 ();
creatureTemplate . maxlevel = fields [ 15 ]. GetUInt8 ();
creatureTemplate . expansion = uint32 ( fields [ 16 ]. GetUInt16 ());
creatureTemplate . faction_A = uint32 ( fields [ 17 ]. GetUInt16 ());
creatureTemplate . faction_H = uint32 ( fields [ 18 ]. GetUInt16 ());
creatureTemplate . npcflag = fields [ 19 ]. GetUInt32 ();
creatureTemplate . speed_walk = fields [ 20 ]. GetFloat ();
creatureTemplate . speed_run = fields [ 21 ]. GetFloat ();
creatureTemplate . scale = fields [ 22 ]. GetFloat ();
creatureTemplate . rank = uint32 ( fields [ 23 ]. GetUInt8 ());
creatureTemplate . mindmg = fields [ 24 ]. GetFloat ();
creatureTemplate . maxdmg = fields [ 25 ]. GetFloat ();
creatureTemplate . dmgschool = uint32 ( fields [ 26 ]. GetInt8 ());
creatureTemplate . attackpower = fields [ 27 ]. GetUInt32 ();
creatureTemplate . dmg_multiplier = fields [ 28 ]. GetFloat ();
creatureTemplate . baseattacktime = fields [ 29 ]. GetUInt32 ();
creatureTemplate . rangeattacktime = fields [ 30 ]. GetUInt32 ();
creatureTemplate . unit_class = uint32 ( fields [ 31 ]. GetUInt8 ());
creatureTemplate . unit_flags = fields [ 32 ]. GetUInt32 ();
creatureTemplate . dynamicflags = fields [ 33 ]. GetUInt32 ();
creatureTemplate . family = uint32 ( fields [ 34 ]. GetUInt8 ());
creatureTemplate . trainer_type = uint32 ( fields [ 35 ]. GetUInt8 ());
creatureTemplate . trainer_spell = fields [ 36 ]. GetUInt32 ();
creatureTemplate . trainer_class = uint32 ( fields [ 37 ]. GetUInt8 ());
creatureTemplate . trainer_race = uint32 ( fields [ 38 ]. GetUInt8 ());
creatureTemplate . minrangedmg = fields [ 39 ]. GetFloat ();
creatureTemplate . maxrangedmg = fields [ 40 ]. GetFloat ();
creatureTemplate . rangedattackpower = uint32 ( fields [ 41 ]. GetUInt16 ());
creatureTemplate . type = uint32 ( fields [ 42 ]. GetUInt8 ());
creatureTemplate . type_flags = fields [ 43 ]. GetUInt32 ();
creatureTemplate . lootid = fields [ 44 ]. GetUInt32 ();
creatureTemplate . pickpocketLootId = fields [ 45 ]. GetUInt32 ();
creatureTemplate . SkinLootId = fields [ 46 ]. GetUInt32 ();
for ( uint8 i = SPELL_SCHOOL_HOLY ; i < MAX_SPELL_SCHOOL ; ++ i )
{
creatureTemplate . resistance [ i ] = fields [ 47 + i - 1 ]. GetInt32 ();
}
for ( uint8 i = 0 ; i < CREATURE_MAX_SPELLS ; ++ i )
{
creatureTemplate . spells [ i ] = fields [ 53 + i ]. GetUInt32 ();
}
creatureTemplate . PetSpellDataId = fields [ 61 ]. GetUInt32 ();
creatureTemplate . VehicleId = fields [ 62 ]. GetUInt32 ();
creatureTemplate . mingold = fields [ 63 ]. GetUInt32 ();
creatureTemplate . maxgold = fields [ 64 ]. GetUInt32 ();
creatureTemplate . AIName = fields [ 65 ]. GetString ();
creatureTemplate . MovementType = uint32 ( fields [ 66 ]. GetUInt8 ());
creatureTemplate . InhabitType = uint32 ( fields [ 67 ]. GetUInt8 ());
creatureTemplate . ModHealth = fields [ 68 ]. GetFloat ();
creatureTemplate . ModMana = fields [ 69 ]. GetFloat ();
creatureTemplate . ModArmor = fields [ 70 ]. GetFloat ();
creatureTemplate . RacialLeader = fields [ 71 ]. GetBool ();
for ( uint8 i = 0 ; i < MAX_CREATURE_QUEST_ITEMS ; ++ i )
{
creatureTemplate . questItems [ i ] = fields [ 72 + i ]. GetUInt32 ();
}
creatureTemplate . movementId = fields [ 78 ]. GetUInt32 ();
creatureTemplate . RegenHealth = fields [ 79 ]. GetBool ();
creatureTemplate . equipmentId = fields [ 80 ]. GetUInt32 ();
creatureTemplate . MechanicImmuneMask = fields [ 81 ]. GetUInt32 ();
creatureTemplate . flags_extra = fields [ 82 ]. GetUInt32 ();
creatureTemplate . ScriptID = GetScriptId ( fields [ 83 ]. GetCString ());
++ count ;
}
while ( result -> NextRow ());
// Checking needs to be done after loading because of the difficulty self referencing
for ( CreatureTemplateContainer :: const_iterator itr = CreatureTemplateStore . begin (); itr != CreatureTemplateStore . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:57:08 +02:00
CheckCreatureTemplate ( & itr -> second );
2010-05-16 17:45:45 +02:00
}
2010-12-19 17:06:33 +01:00
2011-04-28 22:57:08 +02:00
sLog -> outString ( ">> Loaded %u creature definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2010-05-16 17:45:45 +02:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:50:06 +02:00
void ObjectMgr :: LoadCreatureTemplateAddons ()
{
uint32 oldMSTime = getMSTime ();
// 0 1 2 3 4 5 6
QueryResult result = WorldDatabase . Query ( "SELECT entry, path_id, mount, bytes1, bytes2, emote, auras FROM creature_template_addon" );
if ( ! result )
{
sLog -> outString ( ">> Loaded 0 creature template addon definitions. DB table `creature_addon` is empty." );
sLog -> outString ();
return ;
}
uint32 count = 0 ;
do
{
Field * fields = result -> Fetch ();
uint32 entry = fields [ 0 ]. GetUInt32 ();
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate ( entry ))
2011-04-28 22:50:06 +02:00
{
sLog -> outErrorDb ( "Creature template (Entry: %u) does not exist but has a record in `creature_template_addon`" , entry );
continue ;
}
2011-04-29 19:59:40 +02:00
CreatureAddon & creatureAddon = CreatureTemplateAddonStore [ entry ];
2011-04-28 22:50:06 +02:00
creatureAddon . path_id = fields [ 1 ]. GetUInt32 ();
creatureAddon . mount = fields [ 2 ]. GetUInt32 ();
creatureAddon . bytes1 = fields [ 3 ]. GetUInt32 ();
creatureAddon . bytes2 = fields [ 4 ]. GetUInt32 ();
creatureAddon . emote = fields [ 5 ]. GetUInt32 ();
Tokens tokens ( fields [ 6 ]. GetString (), ' ' );
uint8 i = 0 ;
creatureAddon . auras . resize ( tokens . size ());
for ( Tokens :: iterator itr = tokens . begin (); itr != tokens . end (); ++ itr )
{
2011-07-26 23:09:28 +02:00
SpellInfo const * AdditionalSpellInfo = sSpellMgr -> GetSpellInfo ( uint32 ( atol ( * itr )));
2011-04-28 22:50:06 +02:00
if ( ! AdditionalSpellInfo )
{
sLog -> outErrorDb ( "Creature (GUID: %u) has wrong spell %u defined in `auras` field in `creature_addon`." , entry , uint32 ( atol ( * itr )));
continue ;
}
creatureAddon . auras [ i ++ ] = uint32 ( atol ( * itr ));
}
if ( creatureAddon . mount )
{
if ( ! sCreatureDisplayInfoStore . LookupEntry ( creatureAddon . mount ))
{
sLog -> outErrorDb ( "Creature (GUID: %u) has invalid displayInfoId (%u) for mount defined in `creature_addon`" , entry , creatureAddon . mount );
creatureAddon . mount = 0 ;
}
}
if ( ! sEmotesStore . LookupEntry ( creatureAddon . emote ))
sLog -> outErrorDb ( "Creature (GUID: %u) has invalid emote (%u) defined in `creature_addon`." , entry , creatureAddon . emote );
++ count ;
}
while ( result -> NextRow ());
sLog -> outString ( ">> Loaded %u creature template addons in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
}
2011-04-28 22:57:08 +02:00
void ObjectMgr :: CheckCreatureTemplate ( CreatureTemplate const * cInfo )
2010-05-16 17:45:45 +02:00
{
if ( ! cInfo )
return ;
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
bool ok = true ; // bool to allow continue outside this loop
for ( uint32 diff = 0 ; diff < MAX_DIFFICULTY - 1 && ok ; ++ diff )
{
if ( ! cInfo -> DifficultyEntry [ diff ])
continue ;
ok = false ; // will be set to true at the end of this loop again
2009-10-17 15:51:44 -07:00
2011-04-28 22:57:08 +02:00
CreatureTemplate const * difficultyInfo = GetCreatureTemplate ( cInfo -> DifficultyEntry [ diff ]);
2010-05-16 17:45:45 +02:00
if ( ! difficultyInfo )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has `difficulty_entry_%u`=%u but creature entry %u does not exist." ,
2010-05-16 17:45:45 +02:00
cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ], cInfo -> DifficultyEntry [ diff ]);
continue ;
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
bool ok2 = true ;
for ( uint32 diff2 = 0 ; diff2 < MAX_DIFFICULTY - 1 && ok2 ; ++ diff2 )
{
ok2 = false ;
2010-07-30 06:47:35 +02:00
if ( difficultyEntries [ diff2 ]. find ( cInfo -> Entry ) != difficultyEntries [ diff2 ]. end ())
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) is listed as `difficulty_entry_%u` of another creature, but itself lists %u in `difficulty_entry_%u`." ,
2010-07-30 06:47:35 +02:00
cInfo -> Entry , diff2 + 1 , cInfo -> DifficultyEntry [ diff ], diff + 1 );
continue ;
}
2010-05-16 17:45:45 +02:00
if ( difficultyEntries [ diff2 ]. find ( cInfo -> DifficultyEntry [ diff ]) != difficultyEntries [ diff2 ]. end ())
2009-04-14 18:31:31 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) already listed as `difficulty_entry_%u` for another entry." , cInfo -> DifficultyEntry [ diff ], diff2 + 1 );
2009-04-14 18:31:31 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( hasDifficultyEntries [ diff2 ]. find ( cInfo -> DifficultyEntry [ diff ]) != hasDifficultyEntries [ diff2 ]. end ())
2009-04-14 18:31:31 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has `difficulty_entry_%u`=%u but creature entry %u has itself a value in `difficulty_entry_%u`." ,
2010-05-16 17:45:45 +02:00
cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ], cInfo -> DifficultyEntry [ diff ], diff2 + 1 );
2009-04-14 18:31:31 -05:00
continue ;
}
2010-05-16 17:45:45 +02:00
ok2 = true ;
2008-10-11 14:16:25 -05:00
}
2010-05-16 17:45:45 +02:00
if ( ! ok2 )
2009-12-17 14:06:20 +01:00
continue ;
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> unit_class != difficultyInfo -> unit_class )
2008-10-27 11:48:45 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u, class %u) has different `unit_class` in difficulty %u mode (Entry: %u, class %u)." ,
2010-05-16 17:45:45 +02:00
cInfo -> Entry , cInfo -> unit_class , diff + 1 , cInfo -> DifficultyEntry [ diff ], difficultyInfo -> unit_class );
continue ;
2009-06-15 18:02:12 -05:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> npcflag != difficultyInfo -> npcflag )
2008-10-27 11:48:45 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has different `npcflag` in difficulty %u mode (Entry: %u)." , cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ]);
2010-05-16 17:45:45 +02:00
continue ;
2009-06-15 18:02:12 -05:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> trainer_class != difficultyInfo -> trainer_class )
2009-06-14 10:01:44 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has different `trainer_class` in difficulty %u mode (Entry: %u)." , cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ]);
2010-05-16 17:45:45 +02:00
continue ;
2009-06-14 10:01:44 -05:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> trainer_race != difficultyInfo -> trainer_race )
2009-06-14 10:01:44 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has different `trainer_race` in difficulty %u mode (Entry: %u)." , cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ]);
2010-05-16 17:45:45 +02:00
continue ;
2009-06-14 10:01:44 -05:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> trainer_type != difficultyInfo -> trainer_type )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has different `trainer_type` in difficulty %u mode (Entry: %u)." , cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ]);
2010-05-16 17:45:45 +02:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> trainer_spell != difficultyInfo -> trainer_spell )
2009-07-20 12:30:37 +08:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has different `trainer_spell` in difficulty %u mode (Entry: %u)." , cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ]);
2010-05-16 17:45:45 +02:00
continue ;
2009-07-20 12:30:37 +08:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:57:08 +02:00
if ( ! difficultyInfo -> AIName . empty ())
2010-01-14 19:20:11 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) lists difficulty %u mode entry %u with `AIName` filled in. `AIName` of difficulty 0 mode creature is always used instead." ,
2010-07-30 06:47:35 +02:00
cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ]);
2010-05-16 17:45:45 +02:00
continue ;
2010-01-14 19:20:11 +01:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( difficultyInfo -> ScriptID )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) lists difficulty %u mode entry %u with `ScriptName` filled in. `ScriptName` of difficulty 0 mode creature is always used instead." ,
2010-07-30 06:47:35 +02:00
cInfo -> Entry , diff + 1 , cInfo -> DifficultyEntry [ diff ]);
2010-05-16 17:45:45 +02:00
continue ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
hasDifficultyEntries [ diff ]. insert ( cInfo -> Entry );
difficultyEntries [ diff ]. insert ( cInfo -> DifficultyEntry [ diff ]);
ok = true ;
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
FactionTemplateEntry const * factionTemplate = sFactionTemplateStore . LookupEntry ( cInfo -> faction_A );
if ( ! factionTemplate )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has non-existing faction_A template (%u)." , cInfo -> Entry , cInfo -> faction_A );
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
factionTemplate = sFactionTemplateStore . LookupEntry ( cInfo -> faction_H );
if ( ! factionTemplate )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has non-existing faction_H template (%u)." , cInfo -> Entry , cInfo -> faction_H );
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
// used later for scale
CreatureDisplayInfoEntry const * displayScaleEntry = NULL ;
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> Modelid1 )
{
CreatureDisplayInfoEntry const * displayEntry = sCreatureDisplayInfoStore . LookupEntry ( cInfo -> Modelid1 );
if ( ! displayEntry )
2009-01-22 22:44:27 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) lists non-existing Modelid1 id (%u), this can crash the client." , cInfo -> Entry , cInfo -> Modelid1 );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> Modelid1 = 0 ;
2009-01-22 22:44:27 -06:00
}
2010-05-16 17:45:45 +02:00
else if ( ! displayScaleEntry )
displayScaleEntry = displayEntry ;
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
CreatureModelInfo const * modelInfo = GetCreatureModelInfo ( cInfo -> Modelid1 );
if ( ! modelInfo )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "No model data exist for `Modelid1` = %u listed by creature (Entry: %u)." , cInfo -> Modelid1 , cInfo -> Entry );
2010-05-16 17:45:45 +02:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> Modelid2 )
{
CreatureDisplayInfoEntry const * displayEntry = sCreatureDisplayInfoStore . LookupEntry ( cInfo -> Modelid2 );
if ( ! displayEntry )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) lists non-existing Modelid2 id (%u), this can crash the client." , cInfo -> Entry , cInfo -> Modelid2 );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> Modelid2 = 0 ;
2008-10-11 14:16:25 -05:00
}
2010-05-16 17:45:45 +02:00
else if ( ! displayScaleEntry )
displayScaleEntry = displayEntry ;
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
CreatureModelInfo const * modelInfo = GetCreatureModelInfo ( cInfo -> Modelid2 );;
if ( ! modelInfo )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "No model data exist for `Modelid2` = %u listed by creature (Entry: %u)." , cInfo -> Modelid2 , cInfo -> Entry );
2010-05-16 17:45:45 +02:00
}
2010-02-17 00:51:19 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> Modelid3 )
{
CreatureDisplayInfoEntry const * displayEntry = sCreatureDisplayInfoStore . LookupEntry ( cInfo -> Modelid3 );
if ( ! displayEntry )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) lists non-existing Modelid3 id (%u), this can crash the client." , cInfo -> Entry , cInfo -> Modelid3 );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> Modelid3 = 0 ;
2008-10-11 14:16:25 -05:00
}
2010-05-16 17:45:45 +02:00
else if ( ! displayScaleEntry )
displayScaleEntry = displayEntry ;
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
CreatureModelInfo const * modelInfo = GetCreatureModelInfo ( cInfo -> Modelid3 );
if ( ! modelInfo )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "No model data exist for `Modelid3` = %u listed by creature (Entry: %u)." , cInfo -> Modelid3 , cInfo -> Entry );
2010-05-16 17:45:45 +02:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> Modelid4 )
{
CreatureDisplayInfoEntry const * displayEntry = sCreatureDisplayInfoStore . LookupEntry ( cInfo -> Modelid4 );
if ( ! displayEntry )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) lists non-existing Modelid4 id (%u), this can crash the client." , cInfo -> Entry , cInfo -> Modelid4 );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> Modelid4 = 0 ;
2008-10-11 14:16:25 -05:00
}
2010-05-16 17:45:45 +02:00
else if ( ! displayScaleEntry )
displayScaleEntry = displayEntry ;
2011-04-28 22:11:45 +02:00
CreatureModelInfo const * modelInfo = GetCreatureModelInfo ( cInfo -> Modelid4 );;
if ( ! modelInfo )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "No model data exist for `Modelid4` = %u listed by creature (Entry: %u)." , cInfo -> Modelid4 , cInfo -> Entry );
2010-05-16 17:45:45 +02:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( ! displayScaleEntry )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) does not have any existing display id in Modelid1/Modelid2/Modelid3/Modelid4." , cInfo -> Entry );
2010-05-16 17:45:45 +02:00
for ( int k = 0 ; k < MAX_KILL_CREDIT ; ++ k )
{
if ( cInfo -> KillCredit [ k ])
2008-10-11 14:16:25 -05:00
{
2010-05-16 17:45:45 +02:00
if ( ! GetCreatureTemplate ( cInfo -> KillCredit [ k ]))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) lists non-existing creature entry %u in `KillCredit%d`." , cInfo -> Entry , cInfo -> KillCredit [ k ], k + 1 );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> KillCredit [ k ] = 0 ;
2008-10-11 14:16:25 -05:00
}
}
2010-05-16 17:45:45 +02:00
}
if ( ! cInfo -> unit_class || (( 1 << ( cInfo -> unit_class - 1 )) & CLASSMASK_ALL_CREATURES ) == 0 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has invalid unit_class (%u) in creature_template. Set to 1 (UNIT_CLASS_WARRIOR)." , cInfo -> Entry , cInfo -> unit_class );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> unit_class = UNIT_CLASS_WARRIOR ;
2010-05-16 17:45:45 +02:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> dmgschool >= MAX_SPELL_SCHOOL )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has invalid spell school value (%u) in `dmgschool`." , cInfo -> Entry , cInfo -> dmgschool );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> dmgschool = SPELL_SCHOOL_NORMAL ;
2010-05-16 17:45:45 +02:00
}
if ( cInfo -> baseattacktime == 0 )
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> baseattacktime = BASE_ATTACK_TIME ;
2010-05-16 17:45:45 +02:00
if ( cInfo -> rangeattacktime == 0 )
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> rangeattacktime = BASE_ATTACK_TIME ;
2010-05-16 17:45:45 +02:00
if (( cInfo -> npcflag & UNIT_NPC_FLAG_TRAINER ) && cInfo -> trainer_type >= MAX_TRAINER_TYPE )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has wrong trainer type %u." , cInfo -> Entry , cInfo -> trainer_type );
2010-05-16 17:45:45 +02:00
if ( cInfo -> type && ! sCreatureTypeStore . LookupEntry ( cInfo -> type ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has invalid creature type (%u) in `type`." , cInfo -> Entry , cInfo -> type );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> type = CREATURE_TYPE_HUMANOID ;
2010-05-16 17:45:45 +02:00
}
// must exist or used hidden but used in data horse case
if ( cInfo -> family && ! sCreatureFamilyStore . LookupEntry ( cInfo -> family ) && cInfo -> family != CREATURE_FAMILY_HORSE_CUSTOM )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has invalid creature family (%u) in `family`." , cInfo -> Entry , cInfo -> family );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> family = 0 ;
2010-05-16 17:45:45 +02:00
}
if ( cInfo -> InhabitType <= 0 || cInfo -> InhabitType > INHABIT_ANYWHERE )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has wrong value (%u) in `InhabitType`, creature will not correctly walk/swim/fly." , cInfo -> Entry , cInfo -> InhabitType );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> InhabitType = INHABIT_ANYWHERE ;
2010-05-16 17:45:45 +02:00
}
if ( cInfo -> VehicleId )
{
VehicleEntry const * vehId = sVehicleStore . LookupEntry ( cInfo -> VehicleId );
if ( ! vehId )
2010-08-18 15:49:51 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has a non-existing VehicleId (%u). This *WILL* cause the client to freeze!" , cInfo -> Entry , cInfo -> VehicleId );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> VehicleId = 0 ;
2010-08-18 15:49:51 +01:00
}
2010-05-16 17:45:45 +02:00
}
if ( cInfo -> PetSpellDataId )
{
CreatureSpellDataEntry const * spellDataId = sCreatureSpellDataStore . LookupEntry ( cInfo -> PetSpellDataId );
if ( ! spellDataId )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has non-existing PetSpellDataId (%u)." , cInfo -> Entry , cInfo -> PetSpellDataId );
2010-05-16 17:45:45 +02:00
}
for ( uint8 j = 0 ; j < CREATURE_MAX_SPELLS ; ++ j )
{
2011-07-26 23:09:28 +02:00
if ( cInfo -> spells [ j ] && ! sSpellMgr -> GetSpellInfo ( cInfo -> spells [ j ]))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has non-existing Spell%d (%u), set to 0." , cInfo -> Entry , j + 1 , cInfo -> spells [ j ]);
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> spells [ j ] = 0 ;
2008-10-11 14:16:25 -05:00
}
2010-05-16 17:45:45 +02:00
}
if ( cInfo -> MovementType >= MAX_DB_MOTION_TYPE )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Creature (Entry: %u) has wrong movement generator type (%u), ignored and set to IDLE." , cInfo -> Entry , cInfo -> MovementType );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> MovementType = IDLE_MOTION_TYPE ;
2010-05-16 17:45:45 +02:00
}
2009-10-17 15:51:44 -07:00
2010-05-16 17:45:45 +02:00
if ( cInfo -> equipmentId > 0 ) // 0 no equipment
{
if ( ! GetEquipmentInfo ( cInfo -> equipmentId ))
2010-03-03 03:29:03 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature_template` lists creature (Entry: %u) with `equipment_id` %u not found in table `creature_equip_template`, set to no equipment." , cInfo -> Entry , cInfo -> equipmentId );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> equipmentId = 0 ;
2010-03-03 03:29:03 +02:00
}
2010-05-16 17:45:45 +02:00
}
2010-03-03 03:29:03 +02:00
2010-05-16 17:45:45 +02:00
/// if not set custom creature scale then load scale from CreatureDisplayInfo.dbc
if ( cInfo -> scale <= 0.0f )
{
if ( displayScaleEntry )
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> scale = displayScaleEntry -> scale ;
2010-05-16 17:45:45 +02:00
else
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> scale = 1.0f ;
2008-10-11 14:16:25 -05:00
}
2010-05-16 17:45:45 +02:00
if ( cInfo -> expansion > ( MAX_CREATURE_BASE_HP - 1 ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature_template` lists creature (Entry: %u) with expansion %u. Ignored and set to 0." , cInfo -> Entry , cInfo -> expansion );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> expansion = 0 ;
2010-05-16 17:45:45 +02:00
}
2011-02-09 16:28:56 +01:00
if ( uint32 badFlags = ( cInfo -> flags_extra & ~ CREATURE_FLAG_EXTRA_DB_ALLOWED ))
{
sLog -> outErrorDb ( "Table `creature_template` lists creature (Entry: %u) with disallowed `flags_extra` %u, removing incorrect flag." , cInfo -> Entry , badFlags );
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> flags_extra &= CREATURE_FLAG_EXTRA_DB_ALLOWED ;
2011-02-09 16:28:56 +01:00
}
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( cInfo ) -> dmg_multiplier *= Creature :: _GetDamageMod ( cInfo -> rank );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
void ObjectMgr :: LoadCreatureAddons ()
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:46:40 +02:00
uint32 oldMSTime = getMSTime ();
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
// 0 1 2 3 4 5 6
QueryResult result = WorldDatabase . Query ( "SELECT guid, path_id, mount, bytes1, bytes2, emote, auras FROM creature_addon" );
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:46:40 +02:00
sLog -> outString ( ">> Loaded 0 creature addon definitions. DB table `creature_addon` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
uint32 count = 0 ;
do
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:46:40 +02:00
Field * fields = result -> Fetch ();
uint32 guid = fields [ 0 ]. GetUInt32 ();
if ( mCreatureDataMap . find ( guid ) == mCreatureDataMap . end ())
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:46:40 +02:00
sLog -> outErrorDb ( "Creature (GUID: %u) does not exist but has a record in `creature_addon`" , guid );
2008-10-11 14:16:25 -05:00
continue ;
}
2011-04-28 22:46:40 +02:00
2011-04-29 19:59:40 +02:00
CreatureAddon & creatureAddon = CreatureAddonStore [ guid ];
2011-04-28 22:46:40 +02:00
creatureAddon . path_id = fields [ 1 ]. GetUInt32 ();
creatureAddon . mount = fields [ 2 ]. GetUInt32 ();
creatureAddon . bytes1 = fields [ 3 ]. GetUInt32 ();
creatureAddon . bytes2 = fields [ 4 ]. GetUInt32 ();
creatureAddon . emote = fields [ 5 ]. GetUInt32 ();
Tokens tokens ( fields [ 6 ]. GetString (), ' ' );
uint8 i = 0 ;
creatureAddon . auras . resize ( tokens . size ());
for ( Tokens :: iterator itr = tokens . begin (); itr != tokens . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * AdditionalSpellInfo = sSpellMgr -> GetSpellInfo ( uint32 ( atol ( * itr )));
2011-04-28 22:46:40 +02:00
if ( ! AdditionalSpellInfo )
2010-01-10 01:23:15 +01:00
{
2011-04-28 22:46:40 +02:00
sLog -> outErrorDb ( "Creature (GUID: %u) has wrong spell %u defined in `auras` field in `creature_addon`." , guid , uint32 ( atol ( * itr )));
continue ;
2010-01-10 01:23:15 +01:00
}
2011-04-28 22:46:40 +02:00
creatureAddon . auras [ i ++ ] = uint32 ( atol ( * itr ));
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
if ( creatureAddon . mount )
2009-05-31 15:58:58 -05:00
{
2011-04-28 22:46:40 +02:00
if ( ! sCreatureDisplayInfoStore . LookupEntry ( creatureAddon . mount ))
2009-06-13 09:40:44 -05:00
{
2011-04-28 22:46:40 +02:00
sLog -> outErrorDb ( "Creature (GUID: %u) has invalid displayInfoId (%u) for mount defined in `creature_addon`" , guid , creatureAddon . mount );
creatureAddon . mount = 0 ;
2009-06-13 09:40:44 -05:00
}
2009-05-31 15:58:58 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
if ( ! sEmotesStore . LookupEntry ( creatureAddon . emote ))
sLog -> outErrorDb ( "Creature (GUID: %u) has invalid emote (%u) defined in `creature_addon`." , guid , creatureAddon . emote );
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
++ count ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:46:40 +02:00
while ( result -> NextRow ());
2010-12-19 17:06:33 +01:00
2011-04-28 22:46:40 +02:00
sLog -> outString ( ">> Loaded %u creature addons in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2009-07-16 10:47:44 +08:00
}
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
CreatureAddon const * ObjectMgr :: GetCreatureAddon ( uint32 lowguid )
2009-07-16 10:47:44 +08:00
{
2011-04-28 22:46:40 +02:00
CreatureAddonContainer :: const_iterator itr = CreatureAddonStore . find ( lowguid );
if ( itr != CreatureAddonStore . end ())
return & ( itr -> second );
2010-12-19 17:06:33 +01:00
2011-04-28 22:46:40 +02:00
return NULL ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
CreatureAddon const * ObjectMgr :: GetCreatureTemplateAddon ( uint32 entry )
2011-04-28 22:50:06 +02:00
{
CreatureAddonContainer :: const_iterator itr = CreatureTemplateAddonStore . find ( entry );
if ( itr != CreatureTemplateAddonStore . end ())
return & ( itr -> second );
return NULL ;
}
2008-10-11 14:16:25 -05:00
EquipmentInfo const * ObjectMgr :: GetEquipmentInfo ( uint32 entry )
{
2011-04-28 22:34:40 +02:00
EquipmentInfoContainer :: const_iterator itr = EquipmentInfoStore . find ( entry );
if ( itr != EquipmentInfoStore . end ())
return & ( itr -> second );
return NULL ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadEquipmentTemplates ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-28 22:34:40 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, itemEntry1, itemEntry2, itemEntry3 FROM creature_equip_template" );
2009-10-17 15:51:44 -07:00
2011-04-28 22:34:40 +02:00
if ( ! result )
2008-12-24 09:58:26 -06:00
{
2011-04-28 22:34:40 +02:00
sLog -> outString ( ">> Loaded 0 creature equipment templates. DB table `creature_equip_template` is empty!" );
sLog -> outString ();
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:34:40 +02:00
uint32 count = 0 ;
do
{
Field * fields = result -> Fetch ();
uint16 entry = fields [ 0 ]. GetUInt16 ();
2011-04-29 19:59:40 +02:00
EquipmentInfo & equipmentInfo = EquipmentInfoStore [ entry ];
2011-04-28 22:34:40 +02:00
equipmentInfo . ItemEntry [ 0 ] = fields [ 1 ]. GetUInt32 ();
equipmentInfo . ItemEntry [ 1 ] = fields [ 2 ]. GetUInt32 ();
equipmentInfo . ItemEntry [ 2 ] = fields [ 3 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2011-04-29 09:28:10 +02:00
for ( uint8 i = 0 ; i < MAX_EQUIPMENT_ITEMS ; ++ i )
2008-12-24 09:58:26 -06:00
{
2011-04-28 22:34:40 +02:00
if ( ! equipmentInfo . ItemEntry [ i ])
continue ;
2009-10-17 15:51:44 -07:00
2011-04-28 22:34:40 +02:00
ItemEntry const * dbcItem = sItemStore . LookupEntry ( equipmentInfo . ItemEntry [ i ]);
2009-10-17 15:51:44 -07:00
2011-04-28 22:34:40 +02:00
if ( ! dbcItem )
2008-12-24 09:58:26 -06:00
{
2011-04-28 22:34:40 +02:00
sLog -> outErrorDb ( "Unknown item (entry=%u) in creature_equip_template.itemEntry%u for entry = %u, forced to 0." ,
equipmentInfo . ItemEntry [ i ], i + 1 , entry );
equipmentInfo . ItemEntry [ i ] = 0 ;
2008-12-24 09:58:26 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:34:40 +02:00
if ( dbcItem -> InventoryType != INVTYPE_WEAPON &&
dbcItem -> InventoryType != INVTYPE_SHIELD &&
dbcItem -> InventoryType != INVTYPE_RANGED &&
dbcItem -> InventoryType != INVTYPE_2HWEAPON &&
dbcItem -> InventoryType != INVTYPE_WEAPONMAINHAND &&
dbcItem -> InventoryType != INVTYPE_WEAPONOFFHAND &&
dbcItem -> InventoryType != INVTYPE_HOLDABLE &&
dbcItem -> InventoryType != INVTYPE_THROWN &&
dbcItem -> InventoryType != INVTYPE_RANGEDRIGHT )
2008-12-24 09:58:26 -06:00
{
2011-04-28 22:34:40 +02:00
sLog -> outErrorDb ( "Item (entry=%u) in creature_equip_template.itemEntry%u for entry = %u is not equipable in a hand, forced to 0." ,
equipmentInfo . ItemEntry [ i ], i + 1 , entry );
equipmentInfo . ItemEntry [ i ] = 0 ;
2008-12-24 09:58:26 -06:00
}
}
2011-04-28 22:34:40 +02:00
++ count ;
2008-12-24 09:58:26 -06:00
}
2011-04-28 22:34:40 +02:00
while ( result -> NextRow ());
2010-12-19 17:06:33 +01:00
2011-04-28 22:34:40 +02:00
sLog -> outString ( ">> Loaded %u equipment templates in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
CreatureModelInfo const * ObjectMgr :: GetCreatureModelInfo ( uint32 modelId )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:11:45 +02:00
CreatureModelContainer :: const_iterator itr = CreatureModelStore . find ( modelId );
if ( itr != CreatureModelStore . end ())
return & ( itr -> second );
return NULL ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:57:08 +02:00
uint32 ObjectMgr :: ChooseDisplayId ( uint32 /*team*/ , const CreatureTemplate * cinfo , const CreatureData * data /*= NULL*/ )
2008-10-11 14:16:25 -05:00
{
// Load creature model (display id)
2009-09-21 07:52:16 +02:00
uint32 display_id = 0 ;
2009-10-17 15:51:44 -07:00
2009-09-21 07:52:16 +02:00
if ( ! data || data -> displayid == 0 )
{
display_id = cinfo -> GetRandomValidModelId ();
}
else
2009-06-15 18:02:12 -05:00
return data -> displayid ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return display_id ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:57:08 +02:00
void ObjectMgr :: ChooseCreatureFlags ( const CreatureTemplate * cinfo , uint32 & npcflag , uint32 & unit_flags , uint32 & dynamicflags , const CreatureData * data /*= NULL*/ )
2010-10-09 17:52:00 +02:00
{
npcflag = cinfo -> npcflag ;
unit_flags = cinfo -> unit_flags ;
dynamicflags = cinfo -> dynamicflags ;
if ( data )
{
if ( data -> npcflag )
npcflag = data -> npcflag ;
if ( data -> unit_flags )
unit_flags = data -> unit_flags ;
if ( data -> dynamicflags )
dynamicflags = data -> dynamicflags ;
}
}
2011-05-07 20:09:45 +02:00
CreatureModelInfo const * ObjectMgr :: GetCreatureModelRandomGender ( uint32 * displayID )
2008-10-11 14:16:25 -05:00
{
2011-05-07 20:09:45 +02:00
CreatureModelInfo const * minfo = GetCreatureModelInfo ( * displayID );
2010-04-07 19:14:10 +02:00
if ( ! minfo )
2008-10-11 14:16:25 -05:00
return NULL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// If a model for another gender exists, 50% chance to use it
2011-04-29 20:47:02 +02:00
if ( minfo -> modelid_other_gender != 0 && urand ( 0 , 1 ) == 0 )
2008-10-11 14:16:25 -05:00
{
CreatureModelInfo const * minfo_tmp = GetCreatureModelInfo ( minfo -> modelid_other_gender );
2010-04-07 19:14:10 +02:00
if ( ! minfo_tmp )
2011-05-11 11:12:26 +06:00
sLog -> outErrorDb ( "Model (Entry: %u) has modelid_other_gender %u not found in table `creature_model_info`. " , * displayID , minfo -> modelid_other_gender );
2008-10-11 14:16:25 -05:00
else
2011-04-28 22:11:45 +02:00
{
// Model ID changed
2011-05-07 20:09:45 +02:00
* displayID = minfo -> modelid_other_gender ;
2008-10-11 14:16:25 -05:00
return minfo_tmp ;
2011-04-28 22:11:45 +02:00
}
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:11:45 +02:00
return minfo ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadCreatureModelInfo ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-28 22:11:45 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT modelid, bounding_radius, combat_reach, gender, modelid_other_gender FROM creature_model_info" );
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
if ( ! result )
2009-06-15 18:02:12 -05:00
{
2011-04-28 22:11:45 +02:00
sLog -> outString ( ">> Loaded 0 creature model definitions. DB table `creature_model_info` is empty." );
sLog -> outString ();
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
do
{
Field * fields = result -> Fetch ();
uint32 modelId = fields [ 0 ]. GetUInt32 ();
2011-04-29 19:59:40 +02:00
CreatureModelInfo & modelInfo = CreatureModelStore [ modelId ];
2011-04-28 22:11:45 +02:00
modelInfo . bounding_radius = fields [ 1 ]. GetFloat ();
modelInfo . combat_reach = fields [ 2 ]. GetFloat ();
modelInfo . gender = fields [ 3 ]. GetUInt8 ();
modelInfo . modelid_other_gender = fields [ 4 ]. GetUInt32 ();
// Checks
if ( ! sCreatureDisplayInfoStore . LookupEntry ( modelId ))
sLog -> outErrorDb ( "Table `creature_model_info` has model for not existed display id (%u)." , modelId );
if ( modelInfo . gender > GENDER_NONE )
2009-06-15 18:02:12 -05:00
{
2011-04-28 22:11:45 +02:00
sLog -> outErrorDb ( "Table `creature_model_info` has wrong gender (%u) for display id (%u)." , uint32 ( modelInfo . gender ), modelId );
modelInfo . gender = GENDER_MALE ;
2009-06-15 18:02:12 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
if ( modelInfo . modelid_other_gender && ! sCreatureDisplayInfoStore . LookupEntry ( modelInfo . modelid_other_gender ))
2009-06-15 18:02:12 -05:00
{
2011-04-28 22:11:45 +02:00
sLog -> outErrorDb ( "Table `creature_model_info` has not existed alt.gender model (%u) for existed display id (%u)." , modelInfo . modelid_other_gender , modelId );
modelInfo . modelid_other_gender = 0 ;
2009-06-15 18:02:12 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
if ( modelInfo . combat_reach < 0.1f )
2008-11-01 16:53:16 -05:00
{
2011-04-28 22:11:45 +02:00
modelInfo . combat_reach = DEFAULT_COMBAT_REACH ;
2008-11-01 16:53:16 -05:00
}
2011-04-28 22:11:45 +02:00
++ count ;
2008-11-01 16:53:16 -05:00
}
2011-04-28 22:11:45 +02:00
while ( result -> NextRow ());
2010-12-19 17:06:33 +01:00
2011-04-28 22:11:45 +02:00
sLog -> outString ( ">> Loaded %u creature model based info in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-12-24 18:55:50 +01:00
void ObjectMgr :: LoadLinkedRespawn ()
2009-04-14 14:33:48 +02:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-12-24 18:55:50 +01:00
mLinkedRespawnMap . clear ();
QueryResult result = WorldDatabase . Query ( "SELECT guid, linkedGuid, linkType FROM linked_respawn ORDER BY guid ASC" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2009-04-14 14:33:48 +02:00
{
2010-12-24 18:55:50 +01:00
sLog -> outErrorDb ( ">> Loaded 0 linked respawns. DB table `linked_respawn` is empty." );
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2009-04-14 14:33:48 +02:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-04-14 14:33:48 +02:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2010-12-24 18:55:50 +01:00
uint32 guidLow = fields [ 0 ]. GetUInt32 ();
uint32 linkedGuidLow = fields [ 1 ]. GetUInt32 ();
uint8 linkType = fields [ 2 ]. GetUInt8 ();
2009-10-17 15:51:44 -07:00
2011-01-11 11:18:00 +01:00
uint64 guid = 0 , linkedGuid = 0 ;
2010-12-24 18:55:50 +01:00
bool error = false ;
switch ( linkType )
{
case CREATURE_TO_CREATURE :
{
const CreatureData * slave = GetCreatureData ( guidLow );
if ( ! slave )
{
sLog -> outErrorDb ( "Couldn't get creature data for GUIDLow %u" , guidLow );
error = true ;
break ;
}
2009-10-17 15:51:44 -07:00
2010-12-24 18:55:50 +01:00
const CreatureData * master = GetCreatureData ( linkedGuidLow );
if ( ! master )
{
sLog -> outErrorDb ( "Couldn't get creature data for GUIDLow %u" , linkedGuidLow );
error = true ;
break ;
}
const MapEntry * const map = sMapStore . LookupEntry ( master -> mapid );
if ( ! map || ! map -> Instanceable () || ( master -> mapid != slave -> mapid ))
{
sLog -> outErrorDb ( "Creature '%u' linking to '%u' on an unpermitted map." , guidLow , linkedGuidLow );
error = true ;
break ;
}
if ( ! ( master -> spawnMask & slave -> spawnMask )) // they must have a possibility to meet (normal/heroic difficulty)
{
sLog -> outErrorDb ( "LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask" , guidLow , linkedGuidLow );
error = true ;
break ;
}
2011-01-26 01:03:35 +01:00
2010-12-24 18:55:50 +01:00
guid = MAKE_NEW_GUID ( guidLow , slave -> id , HIGHGUID_UNIT );
linkedGuid = MAKE_NEW_GUID ( linkedGuidLow , master -> id , HIGHGUID_UNIT );
break ;
}
case CREATURE_TO_GO :
{
const CreatureData * slave = GetCreatureData ( guidLow );
if ( ! slave )
{
sLog -> outErrorDb ( "Couldn't get creature data for GUIDLow %u" , guidLow );
error = true ;
break ;
}
const GameObjectData * master = GetGOData ( linkedGuidLow );
if ( ! master )
{
sLog -> outErrorDb ( "Couldn't get gameobject data for GUIDLow %u" , linkedGuidLow );
error = true ;
break ;
}
const MapEntry * const map = sMapStore . LookupEntry ( master -> mapid );
if ( ! map || ! map -> Instanceable () || ( master -> mapid != slave -> mapid ))
{
sLog -> outErrorDb ( "Creature '%u' linking to '%u' on an unpermitted map." , guidLow , linkedGuidLow );
error = true ;
break ;
}
if ( ! ( master -> spawnMask & slave -> spawnMask )) // they must have a possibility to meet (normal/heroic difficulty)
{
sLog -> outErrorDb ( "LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask" , guidLow , linkedGuidLow );
error = true ;
break ;
}
guid = MAKE_NEW_GUID ( guidLow , slave -> id , HIGHGUID_UNIT );
linkedGuid = MAKE_NEW_GUID ( linkedGuidLow , master -> id , HIGHGUID_GAMEOBJECT );
break ;
}
case GO_TO_GO :
{
const GameObjectData * slave = GetGOData ( guidLow );
if ( ! slave )
{
sLog -> outErrorDb ( "Couldn't get gameobject data for GUIDLow %u" , guidLow );
error = true ;
break ;
}
const GameObjectData * master = GetGOData ( linkedGuidLow );
if ( ! master )
{
sLog -> outErrorDb ( "Couldn't get gameobject data for GUIDLow %u" , linkedGuidLow );
error = true ;
break ;
}
const MapEntry * const map = sMapStore . LookupEntry ( master -> mapid );
if ( ! map || ! map -> Instanceable () || ( master -> mapid != slave -> mapid ))
{
sLog -> outErrorDb ( "Creature '%u' linking to '%u' on an unpermitted map." , guidLow , linkedGuidLow );
error = true ;
break ;
}
if ( ! ( master -> spawnMask & slave -> spawnMask )) // they must have a possibility to meet (normal/heroic difficulty)
{
sLog -> outErrorDb ( "LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask" , guidLow , linkedGuidLow );
error = true ;
break ;
}
guid = MAKE_NEW_GUID ( guidLow , slave -> id , HIGHGUID_GAMEOBJECT );
linkedGuid = MAKE_NEW_GUID ( linkedGuidLow , master -> id , HIGHGUID_GAMEOBJECT );
break ;
}
case GO_TO_CREATURE :
{
const GameObjectData * slave = GetGOData ( guidLow );
if ( ! slave )
{
sLog -> outErrorDb ( "Couldn't get gameobject data for GUIDLow %u" , guidLow );
error = true ;
break ;
}
2009-10-17 15:51:44 -07:00
2010-12-24 18:55:50 +01:00
const CreatureData * master = GetCreatureData ( linkedGuidLow );
if ( ! master )
{
sLog -> outErrorDb ( "Couldn't get creature data for GUIDLow %u" , linkedGuidLow );
error = true ;
break ;
2011-01-26 01:03:35 +01:00
}
2010-12-24 18:55:50 +01:00
const MapEntry * const map = sMapStore . LookupEntry ( master -> mapid );
if ( ! map || ! map -> Instanceable () || ( master -> mapid != slave -> mapid ))
{
sLog -> outErrorDb ( "Creature '%u' linking to '%u' on an unpermitted map." , guidLow , linkedGuidLow );
error = true ;
break ;
}
if ( ! ( master -> spawnMask & slave -> spawnMask )) // they must have a possibility to meet (normal/heroic difficulty)
{
sLog -> outErrorDb ( "LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask" , guidLow , linkedGuidLow );
error = true ;
break ;
}
guid = MAKE_NEW_GUID ( guidLow , slave -> id , HIGHGUID_GAMEOBJECT );
linkedGuid = MAKE_NEW_GUID ( linkedGuidLow , master -> id , HIGHGUID_UNIT );
break ;
}
}
if ( ! error )
mLinkedRespawnMap [ guid ] = linkedGuid ;
}
while ( result -> NextRow ());
sLog -> outString ( ">> Loaded " UI64FMTD " linked respawns in %u ms" , uint64 ( mLinkedRespawnMap . size ()), GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2009-04-14 14:33:48 +02:00
}
2009-10-17 15:51:44 -07:00
2010-12-24 18:55:50 +01:00
bool ObjectMgr :: SetCreatureLinkedRespawn ( uint32 guidLow , uint32 linkedGuidLow )
2009-04-14 14:33:48 +02:00
{
2010-12-24 18:55:50 +01:00
if ( ! guidLow )
2009-04-14 14:33:48 +02:00
return false ;
2009-10-17 15:51:44 -07:00
2010-12-24 18:55:50 +01:00
const CreatureData * master = GetCreatureData ( guidLow );
uint64 guid = MAKE_NEW_GUID ( guidLow , master -> id , HIGHGUID_UNIT );
if ( ! linkedGuidLow ) // we're removing the linking
2009-04-14 14:33:48 +02:00
{
2010-12-24 18:55:50 +01:00
mLinkedRespawnMap . erase ( guid );
2010-09-18 19:21:03 -07:00
PreparedStatement * stmt = WorldDatabase . GetPreparedStatement ( WORLD_DEL_CRELINKED_RESPAWN );
2010-12-24 18:55:50 +01:00
stmt -> setUInt32 ( 0 , guidLow );
2010-09-18 19:21:03 -07:00
WorldDatabase . Execute ( stmt );
2009-04-14 14:33:48 +02:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-12-24 18:55:50 +01:00
const CreatureData * slave = GetCreatureData ( linkedGuidLow );
const MapEntry * const map = sMapStore . LookupEntry ( master -> mapid );
if ( ! map || ! map -> Instanceable () || ( master -> mapid != slave -> mapid ))
2009-04-14 14:33:48 +02:00
{
2010-12-24 18:55:50 +01:00
sLog -> outErrorDb ( "Creature '%u' linking to '%u' on an unpermitted map." , guidLow , linkedGuidLow );
return false ;
2009-04-14 14:33:48 +02:00
}
2010-09-18 19:21:03 -07:00
2010-12-24 18:55:50 +01:00
if ( ! ( master -> spawnMask & slave -> spawnMask )) // they must have a possibility to meet (normal/heroic difficulty)
{
sLog -> outErrorDb ( "LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask" , guidLow , linkedGuidLow );
return false ;
}
2011-01-26 01:03:35 +01:00
2010-12-24 18:55:50 +01:00
uint64 linkedGuid = MAKE_NEW_GUID ( linkedGuidLow , slave -> id , HIGHGUID_UNIT );
mLinkedRespawnMap [ guid ] = linkedGuid ;
PreparedStatement * stmt = WorldDatabase . GetPreparedStatement ( WORLD_REP_CRELINKED_RESPAWN );
stmt -> setUInt32 ( 0 , guidLow );
stmt -> setUInt32 ( 1 , linkedGuidLow );
WorldDatabase . Execute ( stmt );
return true ;
2009-04-14 14:33:48 +02:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadCreatures ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-28 22:46:40 +02:00
// 0 1 2 3 4 5 6 7 8 9 10
QueryResult result = WorldDatabase . Query ( "SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, "
2011-06-27 20:22:53 +02:00
// 11 12 13 14 15 16 17 18 19 20 21
"currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags "
2011-04-28 22:46:40 +02:00
"FROM creature "
"LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
2009-02-19 18:44:20 -06:00
"LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 creatures. DB table `creature` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
// Build single time for check creature data
2009-12-17 14:06:20 +01:00
std :: set < uint32 > difficultyCreatures [ MAX_DIFFICULTY - 1 ];
2011-04-28 22:57:08 +02:00
CreatureTemplateContainer const * ctc = sObjectMgr -> GetCreatureTemplates ();
for ( CreatureTemplateContainer :: const_iterator itr = ctc -> begin (); itr != ctc -> end (); ++ itr )
2009-12-17 14:06:20 +01:00
for ( uint32 diff = 0 ; diff < MAX_DIFFICULTY - 1 ; ++ diff )
2011-04-28 22:57:08 +02:00
if ( itr -> second . DifficultyEntry [ diff ])
difficultyCreatures [ diff ]. insert ( itr -> second . DifficultyEntry [ diff ]);
2009-12-17 14:06:20 +01:00
2011-04-28 22:46:40 +02:00
// Build single time for check spawnmask
2011-04-29 20:47:02 +02:00
std :: map < uint32 , uint32 > spawnMasks ;
2010-04-07 19:12:44 +02:00
for ( uint32 i = 0 ; i < sMapStore . GetNumRows (); ++ i )
2010-04-07 19:14:10 +02:00
if ( sMapStore . LookupEntry ( i ))
2010-04-07 19:12:44 +02:00
for ( int k = 0 ; k < MAX_DIFFICULTY ; ++ k )
2011-04-29 20:47:02 +02:00
if ( GetMapDifficultyData ( i , Difficulty ( k )))
2009-12-17 14:06:20 +01:00
spawnMasks [ i ] |= ( 1 << k );
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
uint32 count = 0 ;
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-02-19 18:44:20 -06:00
uint32 guid = fields [ 0 ]. GetUInt32 ();
uint32 entry = fields [ 1 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2011-04-28 22:57:08 +02:00
CreatureTemplate const * cInfo = GetCreatureTemplate ( entry );
2010-04-07 19:14:10 +02:00
if ( ! cInfo )
2009-02-19 18:44:20 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature` has creature (GUID: %u) with non existing creature entry %u, skipped." , guid , entry );
2009-02-19 18:44:20 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CreatureData & data = mCreatureDataMap [ guid ];
2009-10-17 15:51:44 -07:00
2009-02-19 18:44:20 -06:00
data . id = entry ;
2008-10-11 14:16:25 -05:00
data . mapid = fields [ 2 ]. GetUInt32 ();
data . displayid = fields [ 3 ]. GetUInt32 ();
data . equipmentId = fields [ 4 ]. GetUInt32 ();
data . posX = fields [ 5 ]. GetFloat ();
data . posY = fields [ 6 ]. GetFloat ();
data . posZ = fields [ 7 ]. GetFloat ();
data . orientation = fields [ 8 ]. GetFloat ();
data . spawntimesecs = fields [ 9 ]. GetUInt32 ();
data . spawndist = fields [ 10 ]. GetFloat ();
data . currentwaypoint = fields [ 11 ]. GetUInt32 ();
data . curhealth = fields [ 12 ]. GetUInt32 ();
data . curmana = fields [ 13 ]. GetUInt32 ();
2011-06-27 20:22:53 +02:00
data . movementType = fields [ 14 ]. GetUInt8 ();
data . spawnMask = fields [ 15 ]. GetUInt8 ();
data . phaseMask = fields [ 16 ]. GetUInt16 ();
int16 gameEvent = fields [ 17 ]. GetInt16 ();
uint32 PoolId = fields [ 18 ]. GetUInt32 ();
data . npcflag = fields [ 19 ]. GetUInt32 ();
data . unit_flags = fields [ 20 ]. GetUInt32 ();
data . dynamicflags = fields [ 21 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-12-17 14:06:20 +01:00
MapEntry const * mapEntry = sMapStore . LookupEntry ( data . mapid );
2010-04-07 19:14:10 +02:00
if ( ! mapEntry )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `creature` have creature (GUID: %u) that spawned at not existed map (Id: %u), skipped." , guid , data . mapid );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-12-17 14:06:20 +01:00
if ( data . spawnMask & ~ spawnMasks [ data . mapid ])
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `creature` have creature (GUID: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u)." , guid , data . spawnMask , data . mapid );
2009-12-17 14:06:20 +01:00
bool ok = true ;
for ( uint32 diff = 0 ; diff < MAX_DIFFICULTY - 1 && ok ; ++ diff )
{
if ( difficultyCreatures [ diff ]. find ( data . id ) != difficultyCreatures [ diff ]. end ())
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature` have creature (GUID: %u) that listed as difficulty %u template (entry: %u) in `creature_template`, skipped." ,
2010-04-07 22:59:46 +02:00
guid , diff + 1 , data . id );
2009-12-17 14:06:20 +01:00
ok = false ;
}
}
if ( ! ok )
continue ;
2011-04-28 22:46:40 +02:00
// -1 no equipment, 0 use default
if ( data . equipmentId > 0 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! GetEquipmentInfo ( data . equipmentId ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment." , data . id , data . equipmentId );
2008-10-11 14:16:25 -05:00
data . equipmentId = - 1 ;
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( cInfo -> flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND )
2009-02-27 12:21:28 -06:00
{
2010-04-07 19:14:10 +02:00
if ( ! mapEntry || ! mapEntry -> IsDungeon ())
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature` have creature (GUID: %u Entry: %u) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance." , guid , data . id );
2009-02-27 12:21:28 -06:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( data . spawndist < 0.0f )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature` have creature (GUID: %u Entry: %u) with `spawndist`< 0, set to 0." , guid , data . id );
2008-10-11 14:16:25 -05:00
data . spawndist = 0.0f ;
}
2010-04-07 19:14:10 +02:00
else if ( data . movementType == RANDOM_MOTION_TYPE )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( data . spawndist == 0.0f )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature` have creature (GUID: %u Entry: %u) with `MovementType`=1 (random movement) but with `spawndist`=0, replace by idle movement type (0)." , guid , data . id );
2008-10-11 14:16:25 -05:00
data . movementType = IDLE_MOTION_TYPE ;
}
}
2010-04-07 19:14:10 +02:00
else if ( data . movementType == IDLE_MOTION_TYPE )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( data . spawndist != 0.0f )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature` have creature (GUID: %u Entry: %u) with `MovementType`=0 (idle) have `spawndist`<>0, set to 0." , guid , data . id );
2008-10-11 14:16:25 -05:00
data . spawndist = 0.0f ;
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( data . phaseMask == 0 )
2009-01-31 16:38:50 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature` have creature (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1." , guid , data . id );
2009-01-31 16:38:50 -06:00
data . phaseMask = 1 ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
// Add to grid if not managed by the game event or pool system
if ( gameEvent == 0 && PoolId == 0 )
2008-10-11 14:16:25 -05:00
AddCreatureToGrid ( guid , & data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2011-04-28 22:46:40 +02:00
sLog -> outString ( ">> Loaded %u creatures in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: AddCreatureToGrid ( uint32 guid , CreatureData const * data )
{
uint8 mask = data -> spawnMask ;
2009-10-17 16:20:24 -07:00
for ( uint8 i = 0 ; mask != 0 ; i ++ , mask >>= 1 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( mask & 1 )
2008-10-11 14:16:25 -05:00
{
2008-10-14 11:57:03 -05:00
CellPair cell_pair = Trinity :: ComputeCellPair ( data -> posX , data -> posY );
2008-10-11 14:16:25 -05:00
uint32 cell_id = ( cell_pair . y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP ) + cell_pair . x_coord ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
CellObjectGuids & cell_guids = mMapObjectGuids [ MAKE_PAIR32 ( data -> mapid , i )][ cell_id ];
2008-10-11 14:16:25 -05:00
cell_guids . creatures . insert ( guid );
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: RemoveCreatureFromGrid ( uint32 guid , CreatureData const * data )
{
uint8 mask = data -> spawnMask ;
2009-10-17 16:20:24 -07:00
for ( uint8 i = 0 ; mask != 0 ; i ++ , mask >>= 1 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( mask & 1 )
2008-10-11 14:16:25 -05:00
{
2008-10-14 11:57:03 -05:00
CellPair cell_pair = Trinity :: ComputeCellPair ( data -> posX , data -> posY );
2008-10-11 14:16:25 -05:00
uint32 cell_id = ( cell_pair . y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP ) + cell_pair . x_coord ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
CellObjectGuids & cell_guids = mMapObjectGuids [ MAKE_PAIR32 ( data -> mapid , i )][ cell_id ];
2008-10-11 14:16:25 -05:00
cell_guids . creatures . erase ( guid );
}
}
}
2009-10-17 15:51:44 -07:00
2009-08-10 23:38:51 -05:00
uint32 ObjectMgr :: AddGOData ( uint32 entry , uint32 mapId , float x , float y , float z , float o , uint32 spawntimedelay , float rotation0 , float rotation1 , float rotation2 , float rotation3 )
2009-05-31 14:26:57 -05:00
{
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * goinfo = GetGameObjectTemplate ( entry );
2009-05-31 14:26:57 -05:00
if ( ! goinfo )
return 0 ;
2009-10-17 15:51:44 -07:00
2010-12-22 21:25:23 +01:00
Map * map = const_cast < Map *> ( sMapMgr -> CreateBaseMap ( mapId ));
2010-04-07 19:14:10 +02:00
if ( ! map )
2009-08-12 08:51:51 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2009-05-31 14:26:57 -05:00
uint32 guid = GenerateLowGuid ( HIGHGUID_GAMEOBJECT );
GameObjectData & data = NewGOData ( guid );
data . id = entry ;
data . mapid = mapId ;
data . posX = x ;
data . posY = y ;
data . posZ = z ;
data . orientation = o ;
data . rotation0 = rotation0 ;
data . rotation1 = rotation1 ;
data . rotation2 = rotation2 ;
data . rotation3 = rotation3 ;
data . spawntimesecs = spawntimedelay ;
data . animprogress = 100 ;
data . spawnMask = 1 ;
data . go_state = GO_STATE_READY ;
data . phaseMask = PHASEMASK_NORMAL ;
2009-08-21 12:31:52 -05:00
data . artKit = goinfo -> type == GAMEOBJECT_TYPE_CAPTURE_POINT ? 21 : 0 ;
2009-05-31 14:26:57 -05:00
data . dbData = false ;
2009-10-17 15:51:44 -07:00
2009-05-31 14:26:57 -05:00
AddGameobjectToGrid ( guid , & data );
2009-10-17 15:51:44 -07:00
2009-05-31 14:26:57 -05:00
// Spawn if necessary (loaded grids only)
2009-08-12 08:51:51 -05:00
// We use spawn coords to spawn
2010-04-07 19:14:10 +02:00
if ( ! map -> Instanceable () && map -> IsLoaded ( x , y ))
2009-05-31 14:26:57 -05:00
{
2009-08-12 08:51:51 -05:00
GameObject * go = new GameObject ;
2009-10-31 17:34:35 -07:00
if ( ! go -> LoadFromDB ( guid , map ))
2009-05-31 14:26:57 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "AddGOData: cannot add gameobject entry %u to map" , entry );
2009-08-12 08:51:51 -05:00
delete go ;
return 0 ;
2009-05-31 14:26:57 -05:00
}
2009-08-12 08:51:51 -05:00
map -> Add ( go );
2009-05-31 14:26:57 -05:00
}
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_MAPS , "AddGOData: dbguid %u entry %u map %u x %f y %f z %f o %f" , guid , entry , mapId , x , y , z , o );
2009-10-17 15:51:44 -07:00
2009-05-31 14:26:57 -05:00
return guid ;
}
2009-10-17 15:51:44 -07:00
2009-11-07 15:54:33 +01:00
bool ObjectMgr :: MoveCreData ( uint32 guid , uint32 mapId , Position pos )
{
CreatureData & data = NewOrExistCreatureData ( guid );
if ( ! data . id )
return false ;
RemoveCreatureFromGrid ( guid , & data );
if ( data . posX == pos . GetPositionX () && data . posY == pos . GetPositionY () && data . posZ == pos . GetPositionZ ())
return true ;
data . posX = pos . GetPositionX ();
data . posY = pos . GetPositionY ();
data . posZ = pos . GetPositionZ ();
data . orientation = pos . GetOrientation ();
AddCreatureToGrid ( guid , & data );
// Spawn if necessary (loaded grids only)
2010-12-22 21:25:23 +01:00
if ( Map * map = const_cast < Map *> ( sMapMgr -> CreateBaseMap ( mapId )))
2009-11-07 15:54:33 +01:00
{
// We use spawn coords to spawn
2010-04-07 19:14:10 +02:00
if ( ! map -> Instanceable () && map -> IsLoaded ( data . posX , data . posY ))
2009-11-07 15:54:33 +01:00
{
Creature * creature = new Creature ;
2010-04-07 19:14:10 +02:00
if ( ! creature -> LoadFromDB ( guid , map ))
2009-11-07 15:54:33 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "AddCreature: cannot add creature entry %u to map" , guid );
2009-11-07 15:54:33 +01:00
delete creature ;
return false ;
}
map -> Add ( creature );
}
}
return true ;
}
2010-04-19 09:26:37 +02:00
uint32 ObjectMgr :: AddCreData ( uint32 entry , uint32 /*team*/ , uint32 mapId , float x , float y , float z , float o , uint32 spawntimedelay )
2009-05-31 14:26:57 -05:00
{
2011-04-28 22:57:08 +02:00
CreatureTemplate const * cInfo = GetCreatureTemplate ( entry );
2010-04-07 19:14:10 +02:00
if ( ! cInfo )
2009-05-31 14:26:57 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2009-12-20 20:23:18 -07:00
uint32 level = cInfo -> minlevel == cInfo -> maxlevel ? cInfo -> minlevel : urand ( cInfo -> minlevel , cInfo -> maxlevel ); // Only used for extracting creature base stats
2011-08-04 15:14:15 +02:00
CreatureBaseStats const * stats = GetCreatureBaseStats ( level , cInfo -> unit_class );
2009-12-20 20:23:18 -07:00
2009-05-31 14:26:57 -05:00
uint32 guid = GenerateLowGuid ( HIGHGUID_UNIT );
CreatureData & data = NewOrExistCreatureData ( guid );
data . id = entry ;
data . mapid = mapId ;
data . displayid = 0 ;
data . equipmentId = cInfo -> equipmentId ;
data . posX = x ;
data . posY = y ;
data . posZ = z ;
data . orientation = o ;
data . spawntimesecs = spawntimedelay ;
data . spawndist = 0 ;
data . currentwaypoint = 0 ;
2010-01-10 22:02:03 +01:00
data . curhealth = stats -> GenerateHealth ( cInfo );
data . curmana = stats -> GenerateMana ( cInfo );
2009-05-31 14:26:57 -05:00
data . movementType = cInfo -> MovementType ;
data . spawnMask = 1 ;
data . phaseMask = PHASEMASK_NORMAL ;
data . dbData = false ;
2010-10-09 17:52:00 +02:00
data . npcflag = cInfo -> npcflag ;
data . unit_flags = cInfo -> unit_flags ;
data . dynamicflags = cInfo -> dynamicflags ;
2009-05-31 14:26:57 -05:00
AddCreatureToGrid ( guid , & data );
2009-10-17 15:51:44 -07:00
2009-05-31 14:26:57 -05:00
// Spawn if necessary (loaded grids only)
2010-12-22 21:25:23 +01:00
if ( Map * map = const_cast < Map *> ( sMapMgr -> CreateBaseMap ( mapId )))
2009-05-31 14:26:57 -05:00
{
// We use spawn coords to spawn
2010-04-07 19:14:10 +02:00
if ( ! map -> Instanceable () && ! map -> IsRemovalGrid ( x , y ))
2009-05-31 14:26:57 -05:00
{
Creature * creature = new Creature ;
2010-04-07 19:14:10 +02:00
if ( ! creature -> LoadFromDB ( guid , map ))
2009-05-31 14:26:57 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "AddCreature: cannot add creature entry %u to map" , entry );
2009-05-31 14:26:57 -05:00
delete creature ;
return 0 ;
}
map -> Add ( creature );
}
}
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
return guid ;
2009-05-31 14:26:57 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGameobjects ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-01-26 01:03:35 +01:00
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// 0 1 2 3 4 5 6
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
2011-03-18 00:11:12 +01:00
// 7 8 9 10 11 12 13 14 15 16 17
"rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry "
2009-02-19 18:44:20 -06:00
"FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
"LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 gameobjects. DB table `gameobject` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-12-17 14:55:19 +01:00
// build single time for check spawnmask
2011-04-29 20:47:02 +02:00
std :: map < uint32 , uint32 > spawnMasks ;
2010-04-07 19:12:44 +02:00
for ( uint32 i = 0 ; i < sMapStore . GetNumRows (); ++ i )
2010-04-07 19:14:10 +02:00
if ( sMapStore . LookupEntry ( i ))
2010-04-07 19:12:44 +02:00
for ( int k = 0 ; k < MAX_DIFFICULTY ; ++ k )
2011-04-29 20:47:02 +02:00
if ( GetMapDifficultyData ( i , Difficulty ( k )))
2009-12-17 14:55:19 +01:00
spawnMasks [ i ] |= ( 1 << k );
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-02-19 18:44:20 -06:00
uint32 guid = fields [ 0 ]. GetUInt32 ();
uint32 entry = fields [ 1 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * gInfo = GetGameObjectTemplate ( entry );
2010-04-07 19:14:10 +02:00
if ( ! gInfo )
2009-02-19 18:44:20 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u) with non existing gameobject entry %u, skipped." , guid , entry );
2009-02-19 18:44:20 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-12-22 00:36:02 +01:00
if ( ! gInfo -> displayId )
2009-12-17 14:55:19 +01:00
{
2009-12-22 00:36:02 +01:00
switch ( gInfo -> type )
{
case GAMEOBJECT_TYPE_TRAP :
case GAMEOBJECT_TYPE_SPELL_FOCUS :
break ;
default :
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Gameobject (GUID: %u Entry %u GoType: %u) doesn't have a displayId (%u), not loaded." , guid , entry , gInfo -> type , gInfo -> displayId );
2009-12-22 02:39:39 +01:00
break ;
2009-12-22 00:36:02 +01:00
}
2009-12-17 14:55:19 +01:00
}
2009-09-02 15:42:40 -05:00
if ( gInfo -> displayId && ! sGameObjectDisplayInfoStore . LookupEntry ( gInfo -> displayId ))
2009-06-13 09:40:44 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Gameobject (GUID: %u Entry %u GoType: %u) has an invalid displayId (%u), not loaded." , guid , entry , gInfo -> type , gInfo -> displayId );
2009-06-13 09:40:44 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GameObjectData & data = mGameObjectDataMap [ guid ];
2009-10-17 15:51:44 -07:00
2009-02-19 18:44:20 -06:00
data . id = entry ;
2008-10-11 14:16:25 -05:00
data . mapid = fields [ 2 ]. GetUInt32 ();
data . posX = fields [ 3 ]. GetFloat ();
data . posY = fields [ 4 ]. GetFloat ();
data . posZ = fields [ 5 ]. GetFloat ();
data . orientation = fields [ 6 ]. GetFloat ();
data . rotation0 = fields [ 7 ]. GetFloat ();
data . rotation1 = fields [ 8 ]. GetFloat ();
data . rotation2 = fields [ 9 ]. GetFloat ();
data . rotation3 = fields [ 10 ]. GetFloat ();
data . spawntimesecs = fields [ 11 ]. GetInt32 ();
2009-10-17 15:51:44 -07:00
2009-12-17 14:55:19 +01:00
MapEntry const * mapEntry = sMapStore . LookupEntry ( data . mapid );
2010-04-07 19:14:10 +02:00
if ( ! mapEntry )
2009-12-17 14:55:19 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u Entry: %u) spawned on a non-existed map (Id: %u), skip" , guid , data . id , data . mapid );
2009-12-17 14:55:19 +01:00
continue ;
}
2010-04-07 23:25:02 +02:00
if ( data . spawntimesecs == 0 && gInfo -> IsDespawnAtAction ())
2009-07-16 12:06:07 +08:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u Entry: %u) with `spawntimesecs` (0) value, but the gameobejct is marked as despawnable at action." , guid , data . id );
2009-07-16 12:06:07 +08:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data . animprogress = fields [ 12 ]. GetUInt32 ();
2009-08-21 12:31:52 -05:00
data . artKit = 0 ;
2009-10-17 15:51:44 -07:00
2009-04-27 18:36:10 -05:00
uint32 go_state = fields [ 13 ]. GetUInt32 ();
if ( go_state >= MAX_GO_STATE )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u Entry: %u) with invalid `state` (%u) value, skip" , guid , data . id , go_state );
2009-04-27 18:36:10 -05:00
continue ;
}
data . go_state = GOState ( go_state );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data . spawnMask = fields [ 14 ]. GetUInt8 ();
2009-12-17 14:55:19 +01:00
if ( data . spawnMask & ~ spawnMasks [ data . mapid ])
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u Entry: %u) that has wrong spawn mask %u including not supported difficulty modes for map (Id: %u), skip" , guid , data . id , data . spawnMask , data . mapid );
2009-12-17 14:55:19 +01:00
2009-01-31 16:38:50 -06:00
data . phaseMask = fields [ 15 ]. GetUInt16 ();
int16 gameEvent = fields [ 16 ]. GetInt16 ();
2010-08-26 06:57:50 +03:00
uint32 PoolId = fields [ 17 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-09-02 15:42:40 -05:00
if ( data . rotation2 < - 1.0f || data . rotation2 > 1.0f )
2009-03-18 20:46:21 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u Entry: %u) with invalid rotation2 (%f) value, skip" , guid , data . id , data . rotation2 );
2009-03-18 20:46:21 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-09-02 15:42:40 -05:00
if ( data . rotation3 < - 1.0f || data . rotation3 > 1.0f )
2009-03-18 20:46:21 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u Entry: %u) with invalid rotation3 (%f) value, skip" , guid , data . id , data . rotation3 );
2009-03-18 20:46:21 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( ! MapManager :: IsValidMapCoord ( data . mapid , data . posX , data . posY , data . posZ , data . orientation ))
2009-03-18 20:46:21 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u Entry: %u) with invalid coordinates, skip" , guid , data . id );
2009-03-18 20:46:21 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( data . phaseMask == 0 )
2009-01-31 16:38:50 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject` has gameobject (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1." , guid , data . id );
2009-01-31 16:38:50 -06:00
data . phaseMask = 1 ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( gameEvent == 0 && PoolId == 0 ) // if not this is to be managed by GameEvent System or Pool system
2008-10-11 14:16:25 -05:00
AddGameobjectToGrid ( guid , & data );
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu gameobjects in %u ms" , ( unsigned long ) mGameObjectDataMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: AddGameobjectToGrid ( uint32 guid , GameObjectData const * data )
{
uint8 mask = data -> spawnMask ;
2009-10-17 16:20:24 -07:00
for ( uint8 i = 0 ; mask != 0 ; i ++ , mask >>= 1 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( mask & 1 )
2008-10-11 14:16:25 -05:00
{
2008-10-14 11:57:03 -05:00
CellPair cell_pair = Trinity :: ComputeCellPair ( data -> posX , data -> posY );
2008-10-11 14:16:25 -05:00
uint32 cell_id = ( cell_pair . y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP ) + cell_pair . x_coord ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
CellObjectGuids & cell_guids = mMapObjectGuids [ MAKE_PAIR32 ( data -> mapid , i )][ cell_id ];
2008-10-11 14:16:25 -05:00
cell_guids . gameobjects . insert ( guid );
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: RemoveGameobjectFromGrid ( uint32 guid , GameObjectData const * data )
{
uint8 mask = data -> spawnMask ;
2009-10-17 16:20:24 -07:00
for ( uint8 i = 0 ; mask != 0 ; i ++ , mask >>= 1 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( mask & 1 )
2008-10-11 14:16:25 -05:00
{
2008-10-14 11:57:03 -05:00
CellPair cell_pair = Trinity :: ComputeCellPair ( data -> posX , data -> posY );
2008-10-11 14:16:25 -05:00
uint32 cell_id = ( cell_pair . y_coord * TOTAL_NUMBER_OF_CELLS_PER_MAP ) + cell_pair . x_coord ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
CellObjectGuids & cell_guids = mMapObjectGuids [ MAKE_PAIR32 ( data -> mapid , i )][ cell_id ];
2008-10-11 14:16:25 -05:00
cell_guids . gameobjects . erase ( guid );
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadCreatureRespawnTimes ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2011-04-13 17:02:06 +06:00
PreparedQueryResult result = CharacterDatabase . Query ( CharacterDatabase . GetPreparedStatement ( CHAR_LOAD_CREATURE_RESPAWNS ));
2010-01-01 14:19:29 -06:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 creature respawn time." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 loguid = fields [ 0 ]. GetUInt32 ();
2011-01-19 22:46:21 +01:00
uint32 respawn_time = fields [ 1 ]. GetUInt32 ();
2008-10-11 14:16:25 -05:00
uint32 instance = fields [ 2 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
mCreatureRespawnTimes [ MAKE_PAIR64 ( loguid , instance )] = time_t ( respawn_time );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu creature respawn times in %u ms" , ( unsigned long ) mCreatureRespawnTimes . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGameobjectRespawnTimes ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-12-23 05:49:23 +01:00
// Remove outdated data
2011-04-13 17:02:06 +06:00
CharacterDatabase . DirectExecute ( CharacterDatabase . GetPreparedStatement ( CHAR_DEL_EXPIRED_GO_RESPAWNS ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2011-04-13 17:02:06 +06:00
PreparedQueryResult result = CharacterDatabase . Query ( CharacterDatabase . GetPreparedStatement ( CHAR_LOAD_GO_RESPAWNS ));
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 gameobject respawn times. DB table `gameobject_respawn` is empty!" );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 loguid = fields [ 0 ]. GetUInt32 ();
2011-01-20 00:08:45 +01:00
uint32 respawn_time = fields [ 1 ]. GetUInt32 ();
2008-10-11 14:16:25 -05:00
uint32 instance = fields [ 2 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
mGORespawnTimes [ MAKE_PAIR64 ( loguid , instance )] = time_t ( respawn_time );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ();
sLog -> outString ( ">> Loaded %lu gameobject respawn times in %u ms" , ( unsigned long ) mGORespawnTimes . size (), GetMSTimeDiffToNow ( oldMSTime ));
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-09-13 09:16:57 +02:00
Player * ObjectMgr :: GetPlayerByLowGUID ( uint32 lowguid ) const
{
2010-09-13 09:51:40 +02:00
uint64 guid = MAKE_NEW_GUID ( lowguid , 0 , HIGHGUID_PLAYER );
return ObjectAccessor :: FindPlayer ( guid );
2010-09-13 09:16:57 +02:00
}
2008-10-11 14:16:25 -05:00
// name must be checked to correctness (if received) before call this function
uint64 ObjectMgr :: GetPlayerGUIDByName ( std :: string name ) const
{
uint64 guid = 0 ;
2009-10-17 15:51:44 -07:00
2011-06-30 14:52:44 +02:00
CharacterDatabase . EscapeString ( name );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Player name safe to sending to DB (checked at login) and this function using
2010-09-11 21:10:54 +02:00
QueryResult result = CharacterDatabase . PQuery ( "SELECT guid FROM characters WHERE name = '%s'" , name . c_str ());
2010-04-07 19:14:10 +02:00
if ( result )
2008-10-11 14:16:25 -05:00
guid = MAKE_NEW_GUID (( * result )[ 0 ]. GetUInt32 (), 0 , HIGHGUID_PLAYER );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return guid ;
}
2009-10-17 15:51:44 -07:00
2011-08-04 15:14:15 +02:00
bool ObjectMgr :: GetPlayerNameByGUID ( uint64 guid , std :: string & name ) const
2008-10-11 14:16:25 -05:00
{
// prevent DB access for online player
2011-07-27 12:14:27 +02:00
if ( Player * player = ObjectAccessor :: FindPlayer ( guid ))
2008-10-11 14:16:25 -05:00
{
name = player -> GetName ();
return true ;
}
2009-10-17 15:51:44 -07:00
2010-09-11 21:10:54 +02:00
QueryResult result = CharacterDatabase . PQuery ( "SELECT name FROM characters WHERE guid = '%u'" , GUID_LOPART ( guid ));
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( result )
2008-10-11 14:16:25 -05:00
{
2010-09-24 22:16:21 +02:00
name = ( * result )[ 0 ]. GetString ();
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2011-08-04 15:14:15 +02:00
uint32 ObjectMgr :: GetPlayerTeamByGUID ( uint64 guid ) const
2008-10-11 14:16:25 -05:00
{
2009-12-17 14:55:19 +01:00
// prevent DB access for online player
2011-07-27 12:14:27 +02:00
if ( Player * player = ObjectAccessor :: FindPlayer ( guid ))
2009-12-17 14:55:19 +01:00
{
return Player :: TeamForRace ( player -> getRace ());
}
2010-09-11 21:10:54 +02:00
QueryResult result = CharacterDatabase . PQuery ( "SELECT race FROM characters WHERE guid = '%u'" , GUID_LOPART ( guid ));
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( result )
2008-10-11 14:16:25 -05:00
{
uint8 race = ( * result )[ 0 ]. GetUInt8 ();
return Player :: TeamForRace ( race );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2011-08-04 15:14:15 +02:00
uint32 ObjectMgr :: GetPlayerAccountIdByGUID ( uint64 guid ) const
2008-10-11 14:16:25 -05:00
{
2009-12-17 14:55:19 +01:00
// prevent DB access for online player
2011-07-27 12:14:27 +02:00
if ( Player * player = ObjectAccessor :: FindPlayer ( guid ))
2009-12-17 14:55:19 +01:00
{
return player -> GetSession () -> GetAccountId ();
}
2010-09-11 21:10:54 +02:00
QueryResult result = CharacterDatabase . PQuery ( "SELECT account FROM characters WHERE guid = '%u'" , GUID_LOPART ( guid ));
2010-04-07 19:14:10 +02:00
if ( result )
2008-10-11 14:16:25 -05:00
{
uint32 acc = ( * result )[ 0 ]. GetUInt32 ();
return acc ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
uint32 ObjectMgr :: GetPlayerAccountIdByPlayerName ( const std :: string & name ) const
2008-10-21 19:07:16 -05:00
{
2010-09-11 21:10:54 +02:00
QueryResult result = CharacterDatabase . PQuery ( "SELECT account FROM characters WHERE name = '%s'" , name . c_str ());
2010-04-07 19:14:10 +02:00
if ( result )
2008-10-21 19:07:16 -05:00
{
uint32 acc = ( * result )[ 0 ]. GetUInt32 ();
return acc ;
}
2009-10-17 15:51:44 -07:00
2008-10-21 19:07:16 -05:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadItemLocales ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
mItemLocaleMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, name_loc1, description_loc1, name_loc2, description_loc2, name_loc3, description_loc3, name_loc4, description_loc4, name_loc5, description_loc5, name_loc6, description_loc6, name_loc7, description_loc7, name_loc8, description_loc8 FROM locales_item" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ItemLocale & data = mItemLocaleMap [ entry ];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-08-26 15:54:56 +06:00
LocaleConstant locale = ( LocaleConstant ) i ;
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ 1 + 2 * ( i - 1 )]. GetString (), locale , data . Name );
AddLocaleString ( fields [ 1 + 2 * ( i - 1 ) + 1 ]. GetString (), locale , data . Description );
2008-10-11 14:16:25 -05:00
}
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu Item locale strings in %u ms" , ( unsigned long ) mItemLocaleMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
void ObjectMgr :: LoadItemTemplates ()
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-28 22:42:33 +02:00
// 0 1 2 3 4 5 6 7 8 9 10 11 12
QueryResult result = WorldDatabase . Query ( "SELECT entry, class, subclass, unk0, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, "
// 13 14 15 16 17 18 19 20
"AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, "
// 21 22 23 24 25 26 27 28
"RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, StatsCount, stat_type1, "
// 29 30 31 32 33 34 35 36 37 38
"stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4, stat_type5, stat_value5, stat_type6, "
// 39 40 41 42 43 44 45 46 47
"stat_value6, stat_type7, stat_value7, stat_type8, stat_value8, stat_type9, stat_value9, stat_type10, stat_value10, "
// 48 49 50 51 52 53 54 55 56 57 58
"ScalingStatDistribution, ScalingStatValue, dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, "
// 59 60 61 62 63 64 65 66 67 68
"nature_res, frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1, spellcharges_1, "
// 69 70 71 72 73 74 75
"spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2, spelltrigger_2, spellcharges_2, "
// 76 77 78 79 80 81 82
"spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, spellid_3, spelltrigger_3, spellcharges_3, "
// 83 84 85 86 87 88 89
"spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, "
// 90 91 92 93 94 95 96
"spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, "
// 97 98 99 100 101 102 103 104 105
"spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID, PageMaterial, "
// 106 107 108 109 110 111 112 113 114 115 116 117
"startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset, MaxDurability, area, Map, BagFamily, "
// 118 119 120 121 122 123 124 125
"TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, "
// 126 127 128 129 130 131 132 133
"GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, Duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
// 134 135 136
"FoodType, minMoneyLoot, maxMoneyLoot FROM item_template" );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( ! result )
{
sLog -> outString ( ">> Loaded 0 item templates. DB table `item_template` is empty." );
sLog -> outString ();
return ;
}
uint32 count = 0 ;
2010-12-23 23:25:44 +01:00
bool enforceDBCAttributes = sWorld -> getBoolConfig ( CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES );
2011-04-28 22:42:33 +02:00
do
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
Field * fields = result -> Fetch ();
uint32 entry = fields [ 0 ]. GetUInt32 ();
2011-04-29 19:59:40 +02:00
ItemTemplate & itemTemplate = ItemTemplateStore [ entry ];
2011-04-28 22:42:33 +02:00
itemTemplate . ItemId = entry ;
itemTemplate . Class = uint32 ( fields [ 1 ]. GetUInt8 ());
itemTemplate . SubClass = uint32 ( fields [ 2 ]. GetUInt8 ());
itemTemplate . Unk0 = fields [ 3 ]. GetInt32 ();
2011-04-29 19:59:40 +02:00
itemTemplate . Name1 = fields [ 4 ]. GetString ();
2011-04-28 22:42:33 +02:00
itemTemplate . DisplayInfoID = fields [ 5 ]. GetUInt32 ();
itemTemplate . Quality = uint32 ( fields [ 6 ]. GetUInt8 ());
itemTemplate . Flags = uint32 ( fields [ 7 ]. GetInt64 ());
itemTemplate . Flags2 = fields [ 8 ]. GetUInt32 ();
itemTemplate . BuyCount = uint32 ( fields [ 9 ]. GetUInt8 ());
itemTemplate . BuyPrice = int32 ( fields [ 10 ]. GetInt64 ());
itemTemplate . SellPrice = fields [ 11 ]. GetUInt32 ();
itemTemplate . InventoryType = uint32 ( fields [ 12 ]. GetUInt8 ());
itemTemplate . AllowableClass = fields [ 13 ]. GetInt32 ();
itemTemplate . AllowableRace = fields [ 14 ]. GetInt32 ();
itemTemplate . ItemLevel = uint32 ( fields [ 15 ]. GetUInt16 ());
itemTemplate . RequiredLevel = uint32 ( fields [ 16 ]. GetUInt8 ());
itemTemplate . RequiredSkill = uint32 ( fields [ 17 ]. GetUInt16 ());
itemTemplate . RequiredSkillRank = uint32 ( fields [ 18 ]. GetUInt16 ());
itemTemplate . RequiredSpell = fields [ 19 ]. GetUInt32 ();
itemTemplate . RequiredHonorRank = fields [ 20 ]. GetUInt32 ();
itemTemplate . RequiredCityRank = fields [ 21 ]. GetUInt32 ();
itemTemplate . RequiredReputationFaction = uint32 ( fields [ 22 ]. GetUInt16 ());
itemTemplate . RequiredReputationRank = uint32 ( fields [ 23 ]. GetUInt16 ());
itemTemplate . MaxCount = fields [ 24 ]. GetInt32 ();
itemTemplate . Stackable = fields [ 25 ]. GetInt32 ();
itemTemplate . ContainerSlots = uint32 ( fields [ 26 ]. GetUInt8 ());
itemTemplate . StatsCount = uint32 ( fields [ 27 ]. GetUInt8 ());
for ( uint8 i = 0 ; i < itemTemplate . StatsCount ; ++ i )
{
itemTemplate . ItemStat [ i ]. ItemStatType = uint32 ( fields [ 28 + i * 2 ]. GetUInt8 ());
2011-04-29 22:52:06 +02:00
itemTemplate . ItemStat [ i ]. ItemStatValue = int32 ( fields [ 29 + i * 2 ]. GetInt16 ());
2011-04-28 22:42:33 +02:00
}
itemTemplate . ScalingStatDistribution = uint32 ( fields [ 48 ]. GetUInt16 ());
itemTemplate . ScalingStatValue = fields [ 49 ]. GetInt32 ();
for ( uint8 i = 0 ; i < MAX_ITEM_PROTO_DAMAGES ; ++ i )
{
2011-04-29 21:00:56 +02:00
itemTemplate . Damage [ i ]. DamageMin = fields [ 50 + i * 3 ]. GetFloat ();
itemTemplate . Damage [ i ]. DamageMax = fields [ 51 + i * 3 ]. GetFloat ();
2011-04-28 22:42:33 +02:00
itemTemplate . Damage [ i ]. DamageType = uint32 ( fields [ 52 + i * 3 ]. GetUInt8 ());
}
itemTemplate . Armor = uint32 ( fields [ 56 ]. GetUInt16 ());
itemTemplate . HolyRes = uint32 ( fields [ 57 ]. GetUInt8 ());
itemTemplate . FireRes = uint32 ( fields [ 58 ]. GetUInt8 ());
itemTemplate . NatureRes = uint32 ( fields [ 59 ]. GetUInt8 ());
itemTemplate . FrostRes = uint32 ( fields [ 60 ]. GetUInt8 ());
itemTemplate . ShadowRes = uint32 ( fields [ 61 ]. GetUInt8 ());
itemTemplate . ArcaneRes = uint32 ( fields [ 62 ]. GetUInt8 ());
itemTemplate . Delay = uint32 ( fields [ 63 ]. GetUInt16 ());
itemTemplate . AmmoType = uint32 ( fields [ 64 ]. GetUInt8 ());
itemTemplate . RangedModRange = fields [ 65 ]. GetFloat ();
for ( uint8 i = 0 ; i < MAX_ITEM_PROTO_SPELLS ; ++ i )
{
itemTemplate . Spells [ i ]. SpellId = fields [ 66 + i * 7 ]. GetInt32 ();
itemTemplate . Spells [ i ]. SpellTrigger = uint32 ( fields [ 67 + i * 7 ]. GetUInt8 ());
2011-04-29 23:17:20 +02:00
itemTemplate . Spells [ i ]. SpellCharges = int32 ( fields [ 68 + i * 7 ]. GetInt16 ());
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ i ]. SpellPPMRate = fields [ 69 + i * 7 ]. GetFloat ();
itemTemplate . Spells [ i ]. SpellCooldown = fields [ 70 + i * 7 ]. GetInt32 ();
itemTemplate . Spells [ i ]. SpellCategory = uint32 ( fields [ 71 + i * 7 ]. GetUInt16 ());
itemTemplate . Spells [ i ]. SpellCategoryCooldown = fields [ 72 + i * 7 ]. GetInt32 ();
}
itemTemplate . Bonding = uint32 ( fields [ 101 ]. GetUInt8 ());
2011-04-29 19:59:40 +02:00
itemTemplate . Description = fields [ 102 ]. GetString ();
2011-04-28 22:42:33 +02:00
itemTemplate . PageText = fields [ 103 ]. GetUInt32 ();
itemTemplate . LanguageID = uint32 ( fields [ 104 ]. GetUInt8 ());
itemTemplate . PageMaterial = uint32 ( fields [ 105 ]. GetUInt8 ());
itemTemplate . StartQuest = fields [ 106 ]. GetUInt32 ();
itemTemplate . LockID = fields [ 107 ]. GetUInt32 ();
2011-04-29 23:17:20 +02:00
itemTemplate . Material = int32 ( fields [ 108 ]. GetInt8 ());
2011-04-28 22:42:33 +02:00
itemTemplate . Sheath = uint32 ( fields [ 109 ]. GetUInt8 ());
itemTemplate . RandomProperty = fields [ 110 ]. GetUInt32 ();
2011-04-29 23:17:20 +02:00
itemTemplate . RandomSuffix = fields [ 111 ]. GetInt32 ();
2011-04-28 22:42:33 +02:00
itemTemplate . Block = fields [ 112 ]. GetUInt32 ();
itemTemplate . ItemSet = fields [ 113 ]. GetUInt32 ();
itemTemplate . MaxDurability = uint32 ( fields [ 114 ]. GetUInt16 ());
itemTemplate . Area = fields [ 115 ]. GetUInt32 ();
itemTemplate . Map = uint32 ( fields [ 116 ]. GetUInt16 ());
itemTemplate . BagFamily = fields [ 117 ]. GetUInt32 ();
itemTemplate . TotemCategory = fields [ 118 ]. GetUInt32 ();
for ( uint8 i = 0 ; i < MAX_ITEM_PROTO_SOCKETS ; ++ i )
{
itemTemplate . Socket [ i ]. Color = uint32 ( fields [ 119 + i * 2 ]. GetUInt8 ());
itemTemplate . Socket [ i ]. Content = fields [ 120 + i * 2 ]. GetUInt32 ();
}
itemTemplate . socketBonus = fields [ 125 ]. GetUInt32 ();
itemTemplate . GemProperties = fields [ 126 ]. GetUInt32 ();
itemTemplate . RequiredDisenchantSkill = uint32 ( fields [ 127 ]. GetInt16 ());
itemTemplate . ArmorDamageModifier = fields [ 128 ]. GetFloat ();
itemTemplate . Duration = fields [ 129 ]. GetInt32 ();
itemTemplate . ItemLimitCategory = uint32 ( fields [ 130 ]. GetInt16 ());
itemTemplate . HolidayId = fields [ 131 ]. GetUInt32 ();
itemTemplate . ScriptId = sObjectMgr -> GetScriptId ( fields [ 132 ]. GetCString ());
itemTemplate . DisenchantID = fields [ 133 ]. GetUInt32 ();
itemTemplate . FoodType = uint32 ( fields [ 134 ]. GetUInt8 ());
itemTemplate . MinMoneyLoot = fields [ 135 ]. GetUInt32 ();
itemTemplate . MaxMoneyLoot = fields [ 136 ]. GetUInt32 ();
// Checks
ItemEntry const * dbcitem = sItemStore . LookupEntry ( entry );
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( dbcitem )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Class != dbcitem -> Class )
2009-01-14 18:42:53 -06:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have a correct class %u, must be %u ." , entry , itemTemplate . Class , dbcitem -> Class );
2010-12-01 21:20:28 +02:00
if ( enforceDBCAttributes )
2011-04-28 22:42:33 +02:00
itemTemplate . Class = dbcitem -> Class ;
2009-01-14 18:42:53 -06:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Unk0 != dbcitem -> Unk0 )
2009-01-14 00:35:13 -06:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have a correct Unk0 (%i) , must be %i ." , entry , itemTemplate . Unk0 , dbcitem -> Unk0 );
2010-12-01 21:20:28 +02:00
if ( enforceDBCAttributes )
2011-04-28 22:42:33 +02:00
itemTemplate . Unk0 = dbcitem -> Unk0 ;
2009-01-14 00:35:13 -06:00
}
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Material != dbcitem -> Material )
2009-01-14 00:35:13 -06:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have a correct material (%i), must be %i ." , entry , itemTemplate . Material , dbcitem -> Material );
2010-12-01 21:20:28 +02:00
if ( enforceDBCAttributes )
2011-04-28 22:42:33 +02:00
itemTemplate . Material = dbcitem -> Material ;
2009-01-14 00:35:13 -06:00
}
2011-04-28 22:42:33 +02:00
if ( itemTemplate . InventoryType != dbcitem -> InventoryType )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have a correct inventory type (%u), must be %u ." , entry , itemTemplate . InventoryType , dbcitem -> InventoryType );
2010-12-13 22:37:56 +01:00
if ( enforceDBCAttributes )
2011-04-28 22:42:33 +02:00
itemTemplate . InventoryType = dbcitem -> InventoryType ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:42:33 +02:00
if ( itemTemplate . DisplayInfoID != dbcitem -> DisplayId )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have a correct display id (%u), must be %u ." , entry , itemTemplate . DisplayInfoID , dbcitem -> DisplayId );
2010-12-01 21:20:28 +02:00
if ( enforceDBCAttributes )
2011-04-28 22:42:33 +02:00
itemTemplate . DisplayInfoID = dbcitem -> DisplayId ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Sheath != dbcitem -> Sheath )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have a correct sheathid (%u), must be %u ." , entry , itemTemplate . Sheath , dbcitem -> Sheath );
2010-12-01 21:20:28 +02:00
if ( enforceDBCAttributes )
2011-04-28 22:42:33 +02:00
itemTemplate . Sheath = dbcitem -> Sheath ;
2008-10-11 14:16:25 -05:00
}
2010-12-01 21:20:28 +02:00
2008-10-11 14:16:25 -05:00
}
else
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not exist in item.dbc! (not correct id?)." , entry );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Class >= MAX_ITEM_CLASS )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong Class value (%u)" , entry , itemTemplate . Class );
itemTemplate . Class = ITEM_CLASS_MISC ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . SubClass >= MaxItemSubclassValues [ itemTemplate . Class ])
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong Subclass value (%u) for class %u" , entry , itemTemplate . SubClass , itemTemplate . Class );
2011-04-28 22:42:33 +02:00
itemTemplate . SubClass = 0 ; // exist for all item classes
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Quality >= MAX_ITEM_QUALITY )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong Quality value (%u)" , entry , itemTemplate . Quality );
2011-04-28 22:42:33 +02:00
itemTemplate . Quality = ITEM_QUALITY_NORMAL ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY )
2010-07-18 04:37:08 -06:00
{
if ( FactionEntry const * faction = sFactionStore . LookupEntry ( HORDE ))
2011-04-28 22:42:33 +02:00
if (( itemTemplate . AllowableRace & faction -> BaseRepRaceMask [ 0 ]) == 0 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item (Entry: %u) has value (%u) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_HORDE_ONLY (%u) in Flags field, item cannot be equipped or used by these races." ,
2011-04-28 22:42:33 +02:00
entry , itemTemplate . AllowableRace , ITEM_FLAGS_EXTRA_HORDE_ONLY );
2010-07-18 04:37:08 -06:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item (Entry: %u) has value (%u) in `Flags2` flags (ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) and ITEM_FLAGS_EXTRA_HORDE_ONLY (%u) in Flags field, this is a wrong combination." ,
2011-04-28 22:42:33 +02:00
entry , ITEM_FLAGS_EXTRA_ALLIANCE_ONLY , ITEM_FLAGS_EXTRA_HORDE_ONLY );
2010-07-18 04:37:08 -06:00
}
2011-04-28 22:42:33 +02:00
else if ( itemTemplate . Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY )
2010-07-18 04:37:08 -06:00
{
if ( FactionEntry const * faction = sFactionStore . LookupEntry ( ALLIANCE ))
2011-04-28 22:42:33 +02:00
if (( itemTemplate . AllowableRace & faction -> BaseRepRaceMask [ 0 ]) == 0 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item (Entry: %u) has value (%u) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_ALLIANCE_ONLY (%u) in Flags field, item cannot be equipped or used by these races." ,
2011-04-28 22:42:33 +02:00
entry , itemTemplate . AllowableRace , ITEM_FLAGS_EXTRA_ALLIANCE_ONLY );
2010-07-18 04:37:08 -06:00
}
2011-04-28 22:42:33 +02:00
if ( itemTemplate . BuyCount <= 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong BuyCount value (%u), set to default(1)." , entry , itemTemplate . BuyCount );
2011-04-28 22:42:33 +02:00
itemTemplate . BuyCount = 1 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . InventoryType >= MAX_INVTYPE )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong InventoryType value (%u)" , entry , itemTemplate . InventoryType );
2011-04-28 22:42:33 +02:00
itemTemplate . InventoryType = INVTYPE_NON_EQUIP ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . RequiredSkill >= MAX_SKILL_TYPE )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong RequiredSkill value (%u)" , entry , itemTemplate . RequiredSkill );
2011-04-28 22:42:33 +02:00
itemTemplate . RequiredSkill = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
{
2009-01-04 16:37:14 -06:00
// can be used in equip slot, as page read use in inventory, or spell casting at use
2011-04-28 22:42:33 +02:00
bool req = itemTemplate . InventoryType != INVTYPE_NON_EQUIP || itemTemplate . PageText ;
2009-11-01 17:53:07 -08:00
if ( ! req )
for ( uint8 j = 0 ; j < MAX_ITEM_PROTO_SPELLS ; ++ j )
2009-01-04 16:37:14 -06:00
{
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Spells [ j ]. SpellId )
2009-01-04 16:37:14 -06:00
{
req = true ;
break ;
}
}
2009-12-18 13:41:30 -08:00
2009-11-01 17:53:07 -08:00
if ( req )
2009-01-04 16:37:14 -06:00
{
2011-04-28 22:42:33 +02:00
if ( ! ( itemTemplate . AllowableClass & CLASSMASK_ALL_PLAYABLE ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have any playable classes (%u) in `AllowableClass` and can't be equipped or used." , entry , itemTemplate . AllowableClass );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( ! ( itemTemplate . AllowableRace & RACEMASK_ALL_PLAYABLE ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have any playable races (%u) in `AllowableRace` and can't be equipped or used." , entry , itemTemplate . AllowableRace );
2009-01-04 16:37:14 -06:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-07-26 23:09:28 +02:00
if ( itemTemplate . RequiredSpell && ! sSpellMgr -> GetSpellInfo ( itemTemplate . RequiredSpell ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has a wrong (non-existing) spell in RequiredSpell (%u)" , entry , itemTemplate . RequiredSpell );
2011-04-28 22:42:33 +02:00
itemTemplate . RequiredSpell = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . RequiredReputationRank >= MAX_REPUTATION_RANK )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong reputation rank in RequiredReputationRank (%u), item can't be used." , entry , itemTemplate . RequiredReputationRank );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . RequiredReputationFaction )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( ! sFactionStore . LookupEntry ( itemTemplate . RequiredReputationFaction ))
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong (not existing) faction in RequiredReputationFaction (%u)" , entry , itemTemplate . RequiredReputationFaction );
itemTemplate . RequiredReputationFaction = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . RequiredReputationRank == MIN_REPUTATION_RANK )
sLog -> outErrorDb ( "Item (Entry: %u) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless." , entry );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . MaxCount < - 1 )
2009-01-03 11:06:51 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has too large negative in maxcount (%i), replace by value (-1) no storing limits." , entry , itemTemplate . MaxCount );
2011-04-28 22:42:33 +02:00
itemTemplate . MaxCount = - 1 ;
2009-01-03 11:06:51 -06:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Stackable == 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong value in stackable (%i), replace by default 1." , entry , itemTemplate . Stackable );
2011-04-28 22:42:33 +02:00
itemTemplate . Stackable = 1 ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:42:33 +02:00
else if ( itemTemplate . Stackable < - 1 )
2009-01-03 11:06:51 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has too large negative in stackable (%i), replace by value (-1) no stacking limits." , entry , itemTemplate . Stackable );
2011-04-28 22:42:33 +02:00
itemTemplate . Stackable = - 1 ;
2009-01-03 11:06:51 -06:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . ContainerSlots > MAX_BAG_SIZE )
2009-07-01 17:38:38 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has too large value in ContainerSlots (%u), replace by hardcoded limit (%u)." , entry , itemTemplate . ContainerSlots , MAX_BAG_SIZE );
2011-04-28 22:42:33 +02:00
itemTemplate . ContainerSlots = MAX_BAG_SIZE ;
2009-07-01 17:38:38 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . StatsCount > MAX_ITEM_PROTO_STATS )
2009-03-02 16:47:20 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u)." , entry , itemTemplate . StatsCount , MAX_ITEM_PROTO_STATS );
2011-04-28 22:42:33 +02:00
itemTemplate . StatsCount = MAX_ITEM_PROTO_STATS ;
2009-03-02 16:47:20 -06:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
for ( uint8 j = 0 ; j < itemTemplate . StatsCount ; ++ j )
2008-10-11 14:16:25 -05:00
{
// for ItemStatValue != 0
2011-04-28 22:42:33 +02:00
if ( itemTemplate . ItemStat [ j ]. ItemStatValue && itemTemplate . ItemStat [ j ]. ItemStatType >= MAX_ITEM_MOD )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong (non-existing?) stat_type%d (%u)" , entry , j + 1 , itemTemplate . ItemStat [ j ]. ItemStatType );
2011-04-28 22:42:33 +02:00
itemTemplate . ItemStat [ j ]. ItemStatType = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
switch ( itemTemplate . ItemStat [ j ]. ItemStatType )
2009-09-02 18:11:11 -05:00
{
case ITEM_MOD_SPELL_HEALING_DONE :
case ITEM_MOD_SPELL_DAMAGE_DONE :
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has deprecated stat_type%d (%u)" , entry , j + 1 , itemTemplate . ItemStat [ j ]. ItemStatType );
2009-09-02 18:11:11 -05:00
break ;
default :
break ;
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
for ( uint8 j = 0 ; j < MAX_ITEM_PROTO_DAMAGES ; ++ j )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Damage [ j ]. DamageType >= MAX_SPELL_SCHOOL )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong dmg_type%d (%u)" , entry , j + 1 , itemTemplate . Damage [ j ]. DamageType );
2011-04-28 22:42:33 +02:00
itemTemplate . Damage [ j ]. DamageType = 0 ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// special format
2011-04-28 22:42:33 +02:00
if (( itemTemplate . Spells [ 0 ]. SpellId == 483 ) || ( itemTemplate . Spells [ 0 ]. SpellId == 55884 ))
2008-10-11 14:16:25 -05:00
{
// spell_1
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Spells [ 0 ]. SpellTrigger != ITEM_SPELLTRIGGER_ON_USE )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format" , entry , 0 + 1 , itemTemplate . Spells [ 0 ]. SpellTrigger );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ 0 ]. SpellId = 0 ;
itemTemplate . Spells [ 0 ]. SpellTrigger = ITEM_SPELLTRIGGER_ON_USE ;
itemTemplate . Spells [ 1 ]. SpellId = 0 ;
itemTemplate . Spells [ 1 ]. SpellTrigger = ITEM_SPELLTRIGGER_ON_USE ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// spell_2 have learning spell
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Spells [ 1 ]. SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format." , entry , 1 + 1 , itemTemplate . Spells [ 1 ]. SpellTrigger );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ 0 ]. SpellId = 0 ;
itemTemplate . Spells [ 1 ]. SpellId = 0 ;
itemTemplate . Spells [ 1 ]. SpellTrigger = ITEM_SPELLTRIGGER_ON_USE ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:42:33 +02:00
else if ( ! itemTemplate . Spells [ 1 ]. SpellId )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) does not have an expected spell in spellid_%d in special learning format." , entry , 1 + 1 );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ 0 ]. SpellId = 0 ;
itemTemplate . Spells [ 1 ]. SpellTrigger = ITEM_SPELLTRIGGER_ON_USE ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:42:33 +02:00
else if ( itemTemplate . Spells [ 1 ]. SpellId != - 1 )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( itemTemplate . Spells [ 1 ]. SpellId );
2011-04-28 22:42:33 +02:00
if ( ! spellInfo && ! sDisableMgr -> IsDisabledFor ( DISABLE_TYPE_SPELL , itemTemplate . Spells [ 1 ]. SpellId , NULL ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%d)" , entry , 1 + 1 , itemTemplate . Spells [ 1 ]. SpellId );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ 0 ]. SpellId = 0 ;
itemTemplate . Spells [ 1 ]. SpellId = 0 ;
itemTemplate . Spells [ 1 ]. SpellTrigger = ITEM_SPELLTRIGGER_ON_USE ;
2008-10-11 14:16:25 -05:00
}
// allowed only in special format
2011-04-28 22:42:33 +02:00
else if (( itemTemplate . Spells [ 1 ]. SpellId == 483 ) || ( itemTemplate . Spells [ 1 ]. SpellId == 55884 ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has broken spell in spellid_%d (%d)" , entry , 1 + 1 , itemTemplate . Spells [ 1 ]. SpellId );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ 0 ]. SpellId = 0 ;
itemTemplate . Spells [ 1 ]. SpellId = 0 ;
itemTemplate . Spells [ 1 ]. SpellTrigger = ITEM_SPELLTRIGGER_ON_USE ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
// spell_3*, spell_4*, spell_5* is empty
2009-11-01 17:53:07 -08:00
for ( uint8 j = 2 ; j < MAX_ITEM_PROTO_SPELLS ; ++ j )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Spells [ j ]. SpellTrigger != ITEM_SPELLTRIGGER_ON_USE )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)" , entry , j + 1 , itemTemplate . Spells [ j ]. SpellTrigger );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ j ]. SpellId = 0 ;
itemTemplate . Spells [ j ]. SpellTrigger = ITEM_SPELLTRIGGER_ON_USE ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:42:33 +02:00
else if ( itemTemplate . Spells [ j ]. SpellId != 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong spell in spellid_%d (%d) for learning special format" , entry , j + 1 , itemTemplate . Spells [ j ]. SpellId );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ j ]. SpellId = 0 ;
2008-10-11 14:16:25 -05:00
}
}
}
// normal spell list
else
{
2009-11-01 17:53:07 -08:00
for ( uint8 j = 0 ; j < MAX_ITEM_PROTO_SPELLS ; ++ j )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Spells [ j ]. SpellTrigger >= MAX_ITEM_SPELLTRIGGER || itemTemplate . Spells [ j ]. SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)" , entry , j + 1 , itemTemplate . Spells [ j ]. SpellTrigger );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ j ]. SpellId = 0 ;
itemTemplate . Spells [ j ]. SpellTrigger = ITEM_SPELLTRIGGER_ON_USE ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Spells [ j ]. SpellId && itemTemplate . Spells [ j ]. SpellId != - 1 )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( itemTemplate . Spells [ j ]. SpellId );
2011-04-28 22:42:33 +02:00
if ( ! spellInfo && ! sDisableMgr -> IsDisabledFor ( DISABLE_TYPE_SPELL , itemTemplate . Spells [ j ]. SpellId , NULL ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%d)" , entry , j + 1 , itemTemplate . Spells [ j ]. SpellId );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ j ]. SpellId = 0 ;
2008-10-11 14:16:25 -05:00
}
// allowed only in special format
2011-04-28 22:42:33 +02:00
else if (( itemTemplate . Spells [ j ]. SpellId == 483 ) || ( itemTemplate . Spells [ j ]. SpellId == 55884 ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has broken spell in spellid_%d (%d)" , entry , j + 1 , itemTemplate . Spells [ j ]. SpellId );
2011-04-28 22:42:33 +02:00
itemTemplate . Spells [ j ]. SpellId = 0 ;
2008-10-11 14:16:25 -05:00
}
}
}
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Bonding >= MAX_BIND_TYPE )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong Bonding value (%u)" , entry , itemTemplate . Bonding );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . PageText && ! GetPageText ( itemTemplate . PageText ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has non existing first page (Id:%u)" , entry , itemTemplate . PageText );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . LockID && ! sLockStore . LookupEntry ( itemTemplate . LockID ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong LockID (%u)" , entry , itemTemplate . LockID );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Sheath >= MAX_SHEATHETYPE )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong Sheath (%u)" , entry , itemTemplate . Sheath );
2011-04-28 22:42:33 +02:00
itemTemplate . Sheath = SHEATHETYPE_NONE ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . RandomProperty )
2008-10-11 14:16:25 -05:00
{
2010-06-27 19:46:25 +02:00
// To be implemented later
2011-04-28 22:42:33 +02:00
if ( itemTemplate . RandomProperty == - 1 )
itemTemplate . RandomProperty = 0 ;
2010-08-08 19:45:53 +02:00
2011-04-28 22:42:33 +02:00
else if ( ! sItemRandomPropertiesStore . LookupEntry ( GetItemEnchantMod ( itemTemplate . RandomProperty )))
2010-06-27 19:46:25 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)" , entry , itemTemplate . RandomProperty );
2011-04-28 22:42:33 +02:00
itemTemplate . RandomProperty = 0 ;
2010-08-08 19:45:53 +02:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . RandomSuffix && ! sItemRandomSuffixStore . LookupEntry ( GetItemEnchantMod ( itemTemplate . RandomSuffix )))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong RandomSuffix (%u)" , entry , itemTemplate . RandomSuffix );
2011-04-28 22:42:33 +02:00
itemTemplate . RandomSuffix = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . ItemSet && ! sItemSetStore . LookupEntry ( itemTemplate . ItemSet ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) have wrong ItemSet (%u)" , entry , itemTemplate . ItemSet );
2011-04-28 22:42:33 +02:00
itemTemplate . ItemSet = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Area && ! GetAreaEntryByAreaID ( itemTemplate . Area ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong Area (%u)" , entry , itemTemplate . Area );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Map && ! sMapStore . LookupEntry ( itemTemplate . Map ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong Map (%u)" , entry , itemTemplate . Map );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . BagFamily )
2009-03-21 22:43:47 -06:00
{
// check bits
2011-04-28 22:42:33 +02:00
for ( uint32 j = 0 ; j < sizeof ( itemTemplate . BagFamily ) * 8 ; ++ j )
2009-03-21 22:43:47 -06:00
{
2009-03-24 09:45:03 -06:00
uint32 mask = 1 << j ;
2011-04-28 22:42:33 +02:00
if (( itemTemplate . BagFamily & mask ) == 0 )
2009-03-21 22:43:47 -06:00
continue ;
2009-10-17 15:51:44 -07:00
2009-03-24 09:45:03 -06:00
ItemBagFamilyEntry const * bf = sItemBagFamilyStore . LookupEntry ( j + 1 );
2009-11-01 17:53:07 -08:00
if ( ! bf )
2009-03-21 22:43:47 -06:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has bag family bit set not listed in ItemBagFamily.dbc, remove bit" , entry );
itemTemplate . BagFamily &= ~ mask ;
2009-03-21 22:44:59 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( BAG_FAMILY_MASK_CURRENCY_TOKENS & mask )
2009-03-21 22:44:59 -06:00
{
2011-04-28 22:42:33 +02:00
CurrencyTypesEntry const * ctEntry = sCurrencyTypesStore . LookupEntry ( itemTemplate . ItemId );
2009-11-01 17:53:07 -08:00
if ( ! ctEntry )
2009-03-21 22:44:59 -06:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit" , entry );
itemTemplate . BagFamily &= ~ mask ;
2009-03-21 22:44:59 -06:00
}
2009-03-21 22:43:47 -06:00
}
}
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . TotemCategory && ! sTotemCategoryStore . LookupEntry ( itemTemplate . TotemCategory ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong TotemCategory (%u)" , entry , itemTemplate . TotemCategory );
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
for ( uint8 j = 0 ; j < MAX_ITEM_PROTO_SOCKETS ; ++ j )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( itemTemplate . Socket [ j ]. Color && ( itemTemplate . Socket [ j ]. Color & SOCKET_COLOR_ALL ) != itemTemplate . Socket [ j ]. Color )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong socketColor_%d (%u)" , entry , j + 1 , itemTemplate . Socket [ j ]. Color );
2011-04-28 22:42:33 +02:00
itemTemplate . Socket [ j ]. Color = 0 ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . GemProperties && ! sGemPropertiesStore . LookupEntry ( itemTemplate . GemProperties ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong GemProperties (%u)" , entry , itemTemplate . GemProperties );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . FoodType >= MAX_PET_DIET )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong FoodType value (%u)" , entry , itemTemplate . FoodType );
2011-04-28 22:42:33 +02:00
itemTemplate . FoodType = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . ItemLimitCategory && ! sItemLimitCategoryStore . LookupEntry ( itemTemplate . ItemLimitCategory ))
2009-02-15 11:58:27 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong LimitCategory value (%u)" , entry , itemTemplate . ItemLimitCategory );
2011-04-28 22:42:33 +02:00
itemTemplate . ItemLimitCategory = 0 ;
2009-02-15 11:58:27 -06:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( itemTemplate . HolidayId && ! sHolidaysStore . LookupEntry ( itemTemplate . HolidayId ))
2009-06-13 09:42:46 -05:00
{
2011-04-28 22:42:33 +02:00
sLog -> outErrorDb ( "Item (Entry: %u) has wrong HolidayId value (%u)" , entry , itemTemplate . HolidayId );
itemTemplate . HolidayId = 0 ;
2009-06-13 09:42:46 -05:00
}
2011-04-28 22:42:33 +02:00
++ count ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:42:33 +02:00
while ( result -> NextRow ());
2010-02-14 19:13:14 -07:00
2011-04-28 22:42:33 +02:00
// Check if item templates for DBC referenced character start outfit are present
2010-02-14 19:13:14 -07:00
std :: set < uint32 > notFoundOutfit ;
for ( uint32 i = 1 ; i < sCharStartOutfitStore . GetNumRows (); ++ i )
{
CharStartOutfitEntry const * entry = sCharStartOutfitStore . LookupEntry ( i );
if ( ! entry )
continue ;
2010-04-07 19:12:44 +02:00
for ( int j = 0 ; j < MAX_OUTFIT_ITEMS ; ++ j )
2010-02-14 19:13:14 -07:00
{
2010-04-07 19:14:10 +02:00
if ( entry -> ItemId [ j ] <= 0 )
2010-02-14 19:13:14 -07:00
continue ;
uint32 item_id = entry -> ItemId [ j ];
2011-04-28 22:42:33 +02:00
if ( ! sObjectMgr -> GetItemTemplate ( item_id ))
2010-02-14 19:13:14 -07:00
notFoundOutfit . insert ( item_id );
}
}
2010-04-07 19:12:44 +02:00
for ( std :: set < uint32 >:: const_iterator itr = notFoundOutfit . begin (); itr != notFoundOutfit . end (); ++ itr )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item (Entry: %u) does not exist in `item_template` but is referenced in `CharStartOutfit.dbc`" , * itr );
2010-12-19 17:06:33 +01:00
2011-04-28 22:42:33 +02:00
sLog -> outString ( ">> Loaded %u item templates in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2010-06-11 20:02:46 +02:00
}
2011-04-28 22:42:33 +02:00
ItemTemplate const * ObjectMgr :: GetItemTemplate ( uint32 entry )
{
ItemTemplateContainer :: const_iterator itr = ItemTemplateStore . find ( entry );
if ( itr != ItemTemplateStore . end ())
return & ( itr -> second );
return NULL ;
}
2010-06-11 20:02:46 +02:00
void ObjectMgr :: LoadItemSetNameLocales ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-06-11 20:02:46 +02:00
mItemSetNameLocaleMap . clear (); // need for reload case
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT `entry`, `name_loc1`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc5`, `name_loc6`, `name_loc7`, `name_loc8` FROM `locales_item_set_names`" );
2010-06-11 20:02:46 +02:00
if ( ! result )
return ;
do
{
Field * fields = result -> Fetch ();
uint32 entry = fields [ 0 ]. GetUInt32 ();
ItemSetNameLocale & data = mItemSetNameLocaleMap [ entry ];
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ i ]. GetString (), LocaleConstant ( i ), data . Name );
2010-06-11 20:02:46 +02:00
} while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded " UI64FMTD " Item set name locale strings in %u ms" , uint64 ( mItemSetNameLocaleMap . size ()), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-06-11 20:02:46 +02:00
}
void ObjectMgr :: LoadItemSetNames ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-06-11 20:02:46 +02:00
2010-12-19 17:06:33 +01:00
mItemSetNameMap . clear (); // needed for reload case
2010-06-11 20:02:46 +02:00
std :: set < uint32 > itemSetItems ;
// fill item set member ids
for ( uint32 entryId = 0 ; entryId < sItemSetStore . GetNumRows (); ++ entryId )
{
ItemSetEntry const * setEntry = sItemSetStore . LookupEntry ( entryId );
if ( ! setEntry )
continue ;
for ( uint32 i = 0 ; i < MAX_ITEM_SET_ITEMS ; ++ i )
if ( setEntry -> itemId [ i ])
itemSetItems . insert ( setEntry -> itemId [ i ]);
}
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`" );
2010-06-11 20:02:46 +02:00
2010-12-19 17:06:33 +01:00
if ( ! result )
2010-06-11 20:02:46 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 item set names. DB table `item_set_names` is empty." );
sLog -> outString ();
2010-12-19 17:06:33 +01:00
return ;
2010-06-11 20:02:46 +02:00
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
do
{
Field * fields = result -> Fetch ();
uint32 entry = fields [ 0 ]. GetUInt32 ();
if ( itemSetItems . find ( entry ) == itemSetItems . end ())
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item set name (Entry: %u) not found in ItemSet.dbc, data useless." , entry );
2010-12-19 17:06:33 +01:00
continue ;
}
ItemSetNameEntry & data = mItemSetNameMap [ entry ];
data . name = fields [ 1 ]. GetString ();
uint32 invType = fields [ 2 ]. GetUInt32 ();
if ( invType >= MAX_INVTYPE )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item set name (Entry: %u) has wrong InventoryType value (%u)" , entry , invType );
2010-12-19 17:06:33 +01:00
invType = INVTYPE_NON_EQUIP ;
}
data . InventoryType = invType ;
itemSetItems . erase ( entry );
++ count ;
} while ( result -> NextRow ());
2011-01-26 01:03:35 +01:00
2010-06-11 20:02:46 +02:00
if ( ! itemSetItems . empty ())
{
2011-04-28 22:42:33 +02:00
ItemTemplate const * pProto ;
2010-06-11 20:02:46 +02:00
for ( std :: set < uint32 >:: iterator itr = itemSetItems . begin (); itr != itemSetItems . end (); ++ itr )
{
uint32 entry = * itr ;
// add data from item_template if available
2011-04-28 22:42:33 +02:00
pProto = sObjectMgr -> GetItemTemplate ( entry );
2010-08-21 21:54:41 +02:00
if ( pProto )
2010-06-11 20:02:46 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item set part (Entry: %u) does not have entry in `item_set_names`, adding data from `item_template`." , entry );
2010-06-11 20:02:46 +02:00
ItemSetNameEntry & data = mItemSetNameMap [ entry ];
data . name = pProto -> Name1 ;
data . InventoryType = pProto -> InventoryType ;
++ count ;
}
else
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item set part (Entry: %u) does not have entry in `item_set_names`, set will not display properly." , entry );
2010-06-11 20:02:46 +02:00
}
}
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u item set names in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-03-06 23:45:22 +01:00
void ObjectMgr :: LoadVehicleTemplateAccessories ()
{
uint32 oldMSTime = getMSTime ();
m_VehicleTemplateAccessoryMap . clear (); // needed for reload case
uint32 count = 0 ;
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT `entry`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_template_accessory`" );
2011-03-06 23:45:22 +01:00
if ( ! result )
{
sLog -> outErrorDb ( ">> Loaded 0 vehicle template accessories. DB table `vehicle_template_accessory` is empty." );
sLog -> outString ();
return ;
}
do
{
Field * fields = result -> Fetch ();
uint32 uiEntry = fields [ 0 ]. GetUInt32 ();
uint32 uiAccessory = fields [ 1 ]. GetUInt32 ();
int8 uiSeat = int8 ( fields [ 2 ]. GetInt16 ());
bool bMinion = fields [ 3 ]. GetBool ();
uint8 uiSummonType = fields [ 4 ]. GetUInt8 ();
uint32 uiSummonTimer = fields [ 5 ]. GetUInt32 ();
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate ( uiEntry ))
2011-03-06 23:45:22 +01:00
{
sLog -> outErrorDb ( "Table `vehicle_template_accessory`: creature template entry %u does not exist." , uiEntry );
continue ;
}
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate ( uiAccessory ))
2011-03-06 23:45:22 +01:00
{
sLog -> outErrorDb ( "Table `vehicle_template_accessory`: Accessory %u does not exist." , uiAccessory );
continue ;
}
if ( mSpellClickInfoMap . find ( uiEntry ) == mSpellClickInfoMap . end ())
{
sLog -> outErrorDb ( "Table `vehicle_template_accessory`: creature template entry %u has no data in npc_spellclick_spells" , uiEntry );
continue ;
}
m_VehicleTemplateAccessoryMap [ uiEntry ]. push_back ( VehicleAccessory ( uiAccessory , uiSeat , bMinion , uiSummonType , uiSummonTimer ));
++ count ;
}
while ( result -> NextRow ());
2011-03-07 19:05:18 +01:00
sLog -> outString ( ">> Loaded %u Vehicle Template Accessories in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2011-03-06 23:45:22 +01:00
sLog -> outString ();
}
2010-03-12 18:19:50 +01:00
void ObjectMgr :: LoadVehicleAccessories ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-03-12 18:19:50 +01:00
m_VehicleAccessoryMap . clear (); // needed for reload case
uint32 count = 0 ;
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT `guid`, `accessory_entry`, `seat_id`, `minion`, `summontype`, `summontimer` FROM `vehicle_accessory`" );
2010-03-12 18:19:50 +01:00
if ( ! result )
{
2011-03-21 10:44:58 +01:00
sLog -> outString ( ">> Loaded 0 Vehicle Accessories in %u ms" , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2010-03-12 18:19:50 +01:00
return ;
}
do
{
Field * fields = result -> Fetch ();
2011-03-07 19:05:18 +01:00
uint32 uiGUID = fields [ 0 ]. GetUInt32 ();
2011-02-26 23:00:09 +01:00
uint32 uiAccessory = fields [ 1 ]. GetUInt32 ();
int8 uiSeat = int8 ( fields [ 2 ]. GetInt16 ());
bool bMinion = fields [ 3 ]. GetBool ();
uint8 uiSummonType = fields [ 4 ]. GetUInt8 ();
uint32 uiSummonTimer = fields [ 5 ]. GetUInt32 ();
2010-03-12 18:19:50 +01:00
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate ( uiAccessory ))
2010-03-12 18:19:50 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `vehicle_accessory`: Accessory %u does not exist." , uiAccessory );
2010-03-12 18:19:50 +01:00
continue ;
}
2011-03-07 19:05:18 +01:00
m_VehicleAccessoryMap [ uiGUID ]. push_back ( VehicleAccessory ( uiAccessory , uiSeat , bMinion , uiSummonType , uiSummonTimer ));
2010-03-12 18:19:50 +01:00
++ count ;
2011-02-22 23:47:28 +01:00
}
while ( result -> NextRow ());
2010-03-12 18:19:50 +01:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u Vehicle Accessories in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-03-12 18:19:50 +01:00
}
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadPetLevelInfo ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// 0 1 2 3 4 5 6 7 8 9
QueryResult result = WorldDatabase . Query ( "SELECT creature_entry, level, hp, mana, str, agi, sta, inte, spi, armor FROM pet_levelstats" );
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 level pet stats definitions. DB table `pet_levelstats` is empty." );
sLog -> outString ();
2010-12-19 17:06:33 +01:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 creature_id = fields [ 0 ]. GetUInt32 ();
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate ( creature_id ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong creature id %u in `pet_levelstats` table, ignoring." , creature_id );
2010-12-19 17:06:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 current_level = fields [ 1 ]. GetUInt32 ();
2010-12-23 23:25:44 +01:00
if ( current_level > sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ))
2010-12-19 17:06:33 +01:00
{
if ( current_level > STRONG_MAX_LEVEL ) // hardcoded level maximum
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong (> %u) level %u in `pet_levelstats` table, ignoring." , STRONG_MAX_LEVEL , current_level );
2010-12-19 17:06:33 +01:00
else
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outDetail ( "Unused (> MaxPlayerLevel in worldserver.conf) level %u in `pet_levelstats` table, ignoring." , current_level );
2010-12-19 17:06:33 +01:00
++ count ; // make result loading percent "expected" correct in case disabled detail mode for example.
2008-10-11 14:16:25 -05:00
}
2010-12-19 17:06:33 +01:00
continue ;
}
else if ( current_level < 1 )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong (<1) level %u in `pet_levelstats` table, ignoring." , current_level );
2010-12-19 17:06:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
PetLevelInfo *& pInfoMapEntry = petInfo [ creature_id ];
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
if ( pInfoMapEntry == NULL )
2010-12-23 23:25:44 +01:00
pInfoMapEntry = new PetLevelInfo [ sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL )];
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// data for level 1 stored in [0] array element, ...
PetLevelInfo * pLevelInfo = & pInfoMapEntry [ current_level - 1 ];
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
pLevelInfo -> health = fields [ 2 ]. GetUInt16 ();
pLevelInfo -> mana = fields [ 3 ]. GetUInt16 ();
pLevelInfo -> armor = fields [ 9 ]. GetUInt16 ();
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
for ( int i = 0 ; i < MAX_STATS ; i ++ )
{
pLevelInfo -> stats [ i ] = fields [ i + 4 ]. GetUInt16 ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
++ count ;
2008-10-11 14:16:25 -05:00
}
2010-12-19 17:06:33 +01:00
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Fill gaps and check integrity
for ( PetLevelInfoMap :: iterator itr = petInfo . begin (); itr != petInfo . end (); ++ itr )
{
PetLevelInfo * pInfo = itr -> second ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// fatal error if no level 1 data
2010-04-07 22:59:46 +02:00
if ( ! pInfo || pInfo [ 0 ]. health == 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Creature %u does not have pet stats data for Level 1!" , itr -> first );
2008-10-11 14:16:25 -05:00
exit ( 1 );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// fill level gaps
2010-12-23 23:25:44 +01:00
for ( uint8 level = 1 ; level < sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ); ++ level )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pInfo [ level ]. health == 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Creature %u has no data for Level %i pet stats data, using data of Level %i." , itr -> first , level + 1 , level );
2008-10-11 14:16:25 -05:00
pInfo [ level ] = pInfo [ level - 1 ];
}
}
}
2010-12-19 17:06:33 +01:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u level pet stats definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
PetLevelInfo const * ObjectMgr :: GetPetLevelInfo ( uint32 creature_id , uint8 level ) const
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
if ( level > sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ))
level = sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PetLevelInfoMap :: const_iterator itr = petInfo . find ( creature_id );
2010-04-07 19:14:10 +02:00
if ( itr == petInfo . end ())
2008-10-11 14:16:25 -05:00
return NULL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return & itr -> second [ level - 1 ]; // data for level 1 stored in [0] array element, ...
}
2009-10-17 15:51:44 -07:00
2010-06-14 21:03:05 +02:00
void ObjectMgr :: PlayerCreateInfoAddItemHelper ( uint32 race_ , uint32 class_ , uint32 itemId , int32 count )
{
if ( count > 0 )
playerInfo [ race_ ][ class_ ]. item . push_back ( PlayerCreateInfoItem ( itemId , count ));
else
{
if ( count < - 1 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Invalid count %i specified on item %u be removed from original player create info (use -1)!" , count , itemId );
2010-06-14 21:03:05 +02:00
uint32 RaceClass = ( race_ ) | ( class_ << 8 );
bool doneOne = false ;
for ( uint32 i = 1 ; i < sCharStartOutfitStore . GetNumRows (); ++ i )
{
if ( CharStartOutfitEntry const * entry = sCharStartOutfitStore . LookupEntry ( i ))
{
if ( entry -> RaceClassGender == RaceClass || entry -> RaceClassGender == ( RaceClass | ( 1 << 16 )))
{
bool found = false ;
for ( uint8 x = 0 ; x < MAX_OUTFIT_ITEMS ; ++ x )
{
2010-08-30 15:25:15 +02:00
if ( entry -> ItemId [ x ] > 0 && uint32 ( entry -> ItemId [ x ]) == itemId )
2010-06-14 21:03:05 +02:00
{
found = true ;
const_cast < CharStartOutfitEntry *> ( entry ) -> ItemId [ x ] = 0 ;
break ;
}
}
if ( ! found )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item %u specified to be removed from original create info not found in dbc!" , itemId );
2010-08-08 19:45:53 +02:00
2010-06-14 21:03:05 +02:00
if ( ! doneOne )
doneOne = true ;
else
break ;
}
}
}
}
}
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadPlayerInfo ()
{
// Load playercreate
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
// 0 1 2 3 4 5 6
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT race, class, map, zone, position_x, position_y, position_z, orientation FROM playercreateinfo" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outString ();
sLog -> outErrorDb ( ">> Loaded 0 player create definitions. DB table `playercreateinfo` is empty." );
2008-10-11 14:16:25 -05:00
exit ( 1 );
}
2010-12-19 17:06:33 +01:00
else
{
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 current_race = fields [ 0 ]. GetUInt32 ();
uint32 current_class = fields [ 1 ]. GetUInt32 ();
uint32 mapId = fields [ 2 ]. GetUInt32 ();
uint32 areaId = fields [ 3 ]. GetUInt32 ();
float positionX = fields [ 4 ]. GetFloat ();
float positionY = fields [ 5 ]. GetFloat ();
float positionZ = fields [ 6 ]. GetFloat ();
float orientation = fields [ 7 ]. GetFloat ();
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
if ( current_race >= MAX_RACES )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong race %u in `playercreateinfo` table, ignoring." , current_race );
2010-12-19 17:06:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
ChrRacesEntry const * rEntry = sChrRacesStore . LookupEntry ( current_race );
if ( ! rEntry )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong race %u in `playercreateinfo` table, ignoring." , current_race );
2010-12-19 17:06:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
if ( current_class >= MAX_CLASSES )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong class %u in `playercreateinfo` table, ignoring." , current_class );
2010-12-19 17:06:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
if ( ! sChrClassesStore . LookupEntry ( current_class ))
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong class %u in `playercreateinfo` table, ignoring." , current_class );
2010-12-19 17:06:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// accept DB data only for valid position (and non instanceable)
2011-04-29 20:47:02 +02:00
if ( ! MapManager :: IsValidMapCoord ( mapId , positionX , positionY , positionZ , orientation ))
2010-12-19 17:06:33 +01:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong home position for class %u race %u pair in `playercreateinfo` table, ignoring." , current_class , current_race );
2010-12-19 17:06:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
if ( sMapStore . LookupEntry ( mapId ) -> Instanceable ())
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Home position in instanceable map for class %u race %u pair in `playercreateinfo` table, ignoring." , current_class , current_race );
2010-12-19 17:06:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
PlayerInfo * pInfo = & playerInfo [ current_race ][ current_class ];
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
pInfo -> mapId = mapId ;
pInfo -> areaId = areaId ;
pInfo -> positionX = positionX ;
pInfo -> positionY = positionY ;
pInfo -> positionZ = positionZ ;
pInfo -> orientation = orientation ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
pInfo -> displayId_m = rEntry -> model_m ;
pInfo -> displayId_f = rEntry -> model_f ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u player create definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Load playercreate items
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Loading Player Create Items Data..." );
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
// 0 1 2 3
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT race, class, itemid, amount FROM playercreateinfo_item" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 custom player create items. DB table `playercreateinfo_item` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
else
{
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_race = fields [ 0 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_race >= MAX_RACES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong race %u in `playercreateinfo_item` table, ignoring." , current_race );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_class = fields [ 1 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_class >= MAX_CLASSES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong class %u in `playercreateinfo_item` table, ignoring." , current_class );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 item_id = fields [ 2 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( ! sObjectMgr -> GetItemTemplate ( item_id ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item id %u (race %u class %u) in `playercreateinfo_item` table but not listed in `item_template`, ignoring." , item_id , current_race , current_class );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-06-14 21:03:05 +02:00
int32 amount = fields [ 3 ]. GetInt32 ();
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! amount )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Item id %u (class %u race %u) have amount == 0 in `playercreateinfo_item` table, ignoring." , item_id , current_race , current_class );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-06-14 21:03:05 +02:00
if ( ! current_race || ! current_class )
{
uint32 min_race = current_race ? current_race : 1 ;
uint32 max_race = current_race ? current_race + 1 : MAX_RACES ;
uint32 min_class = current_class ? current_class : 1 ;
uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES ;
for ( uint32 r = min_race ; r < max_race ; ++ r )
for ( uint32 c = min_class ; c < max_class ; ++ c )
PlayerCreateInfoAddItemHelper ( r , c , item_id , amount );
}
else
PlayerCreateInfoAddItemHelper ( current_race , current_class , item_id , amount );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
}
2010-04-07 19:13:19 +02:00
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u custom player create items in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Load playercreate spells
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Loading Player Create Spell Data..." );
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-10-17 15:51:44 -07:00
2010-09-11 21:10:54 +02:00
QueryResult result = QueryResult ( NULL );
2010-12-23 23:25:44 +01:00
if ( sWorld -> getBoolConfig ( CONFIG_START_ALL_SPELLS ))
2008-10-14 11:57:03 -05:00
result = WorldDatabase . Query ( "SELECT race, class, Spell, Active FROM playercreateinfo_spell_custom" );
else
2009-01-12 10:53:53 -06:00
result = WorldDatabase . Query ( "SELECT race, class, Spell FROM playercreateinfo_spell" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 player create spells. DB table `%s` is empty." , sWorld -> getBoolConfig ( CONFIG_START_ALL_SPELLS ) ? "playercreateinfo_spell_custom" : "playercreateinfo_spell" );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
else
{
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_race = fields [ 0 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_race >= MAX_RACES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong race %u in `playercreateinfo_spell` table, ignoring." , current_race );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_class = fields [ 1 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_class >= MAX_CLASSES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong class %u in `playercreateinfo_spell` table, ignoring." , current_class );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! current_race || ! current_class )
2009-05-30 00:09:50 -05:00
{
uint32 min_race = current_race ? current_race : 1 ;
uint32 max_race = current_race ? current_race + 1 : MAX_RACES ;
uint32 min_class = current_class ? current_class : 1 ;
uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES ;
2009-10-17 16:20:24 -07:00
for ( uint32 r = min_race ; r < max_race ; ++ r )
for ( uint32 c = min_class ; c < max_class ; ++ c )
2009-05-30 00:09:50 -05:00
playerInfo [ r ][ c ]. spell . push_back ( fields [ 2 ]. GetUInt32 ());
}
else
playerInfo [ current_race ][ current_class ]. spell . push_back ( fields [ 2 ]. GetUInt32 ());
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
}
2010-04-07 22:59:46 +02:00
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u player create spells in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Load playercreate actions
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Loading Player Create Action Data..." );
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-07-01 18:07:20 -05:00
// 0 1 2 3 4
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT race, class, button, action, type FROM playercreateinfo_action" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 player create actions. DB table `playercreateinfo_action` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
else
{
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_race = fields [ 0 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_race >= MAX_RACES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong race %u in `playercreateinfo_action` table, ignoring." , current_race );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_class = fields [ 1 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_class >= MAX_CLASSES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong class %u in `playercreateinfo_action` table, ignoring." , current_class );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PlayerInfo * pInfo = & playerInfo [ current_race ][ current_class ];
2011-04-29 20:47:02 +02:00
pInfo -> action . push_back ( PlayerCreateInfoAction ( fields [ 2 ]. GetUInt8 (), fields [ 3 ]. GetUInt32 (), fields [ 4 ]. GetUInt8 ()));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
}
2010-04-07 22:59:46 +02:00
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u player create actions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Loading levels data (class only dependent)
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Loading Player Create Level HP/Mana Data..." );
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
// 0 1 2 3
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT class, level, basehp, basemana FROM player_classlevelstats" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 level health/mana definitions. DB table `game_event_condition` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
exit ( 1 );
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_class = fields [ 0 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_class >= MAX_CLASSES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong class %u in `player_classlevelstats` table, ignoring." , current_class );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-08-30 15:25:15 +02:00
uint8 current_level = fields [ 1 ]. GetUInt8 (); // Can't be > than STRONG_MAX_LEVEL (hardcoded level maximum) due to var type
2010-12-23 23:25:44 +01:00
if ( current_level > sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outDetail ( "Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_classlevelstats` table, ignoring." , current_level );
2010-08-30 15:25:15 +02:00
++ count ; // make result loading percent "expected" correct in case disabled detail mode for example.
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PlayerClassInfo * pClassInfo = & playerClassInfo [ current_class ];
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! pClassInfo -> levelInfo )
2010-12-23 23:25:44 +01:00
pClassInfo -> levelInfo = new PlayerClassLevelInfo [ sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL )];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PlayerClassLevelInfo * pClassLevelInfo = & pClassInfo -> levelInfo [ current_level - 1 ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
pClassLevelInfo -> basehealth = fields [ 2 ]. GetUInt16 ();
pClassLevelInfo -> basemana = fields [ 3 ]. GetUInt16 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// Fill gaps and check integrity
for ( int class_ = 0 ; class_ < MAX_CLASSES ; ++ class_ )
{
// skip non existed classes
if ( ! sChrClassesStore . LookupEntry ( class_ ))
continue ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
PlayerClassInfo * pClassInfo = & playerClassInfo [ class_ ];
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// fatal error if no level 1 data
if ( ! pClassInfo -> levelInfo || pClassInfo -> levelInfo [ 0 ]. basehealth == 0 )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Class %i Level 1 does not have health/mana data!" , class_ );
2010-12-19 17:06:33 +01:00
exit ( 1 );
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// fill level gaps
2010-12-23 23:25:44 +01:00
for ( uint8 level = 1 ; level < sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ); ++ level )
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
if ( pClassInfo -> levelInfo [ level ]. basehealth == 0 )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Class %i Level %i does not have health/mana data. Using stats data of level %i." , class_ , level + 1 , level );
2010-12-19 17:06:33 +01:00
pClassInfo -> levelInfo [ level ] = pClassInfo -> levelInfo [ level - 1 ];
}
2008-10-11 14:16:25 -05:00
}
}
2010-12-19 17:06:33 +01:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u level health/mana definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Loading levels data (class/race dependent)
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Loading Player Create Level Stats Data..." );
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
// 0 1 2 3 4 5 6 7
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT race, class, level, str, agi, sta, inte, spi FROM player_levelstats" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 level stats definitions. DB table `player_levelstats` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
exit ( 1 );
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_race = fields [ 0 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_race >= MAX_RACES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong race %u in `player_levelstats` table, ignoring." , current_race );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_class = fields [ 1 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( current_class >= MAX_CLASSES )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong class %u in `player_levelstats` table, ignoring." , current_class );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 current_level = fields [ 2 ]. GetUInt32 ();
2010-12-23 23:25:44 +01:00
if ( current_level > sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( current_level > STRONG_MAX_LEVEL ) // hardcoded level maximum
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong (> %u) level %u in `player_levelstats` table, ignoring." , STRONG_MAX_LEVEL , current_level );
2008-10-11 14:16:25 -05:00
else
2009-03-09 16:38:53 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outDetail ( "Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_levelstats` table, ignoring." , current_level );
2009-03-09 16:38:53 -06:00
++ count ; // make result loading percent "expected" correct in case disabled detail mode for example.
}
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PlayerInfo * pInfo = & playerInfo [ current_race ][ current_class ];
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! pInfo -> levelInfo )
2010-12-23 23:25:44 +01:00
pInfo -> levelInfo = new PlayerLevelInfo [ sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL )];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PlayerLevelInfo * pLevelInfo = & pInfo -> levelInfo [ current_level - 1 ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
for ( int i = 0 ; i < MAX_STATS ; i ++ )
{
pLevelInfo -> stats [ i ] = fields [ i + 3 ]. GetUInt8 ();
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// Fill gaps and check integrity
for ( int race = 0 ; race < MAX_RACES ; ++ race )
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
// skip non existed races
if ( ! sChrRacesStore . LookupEntry ( race ))
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
for ( int class_ = 0 ; class_ < MAX_CLASSES ; ++ class_ )
{
// skip non existed classes
if ( ! sChrClassesStore . LookupEntry ( class_ ))
continue ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
PlayerInfo * pInfo = & playerInfo [ race ][ class_ ];
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// skip non loaded combinations
if ( ! pInfo -> displayId_m || ! pInfo -> displayId_f )
continue ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// skip expansion races if not playing with expansion
2010-12-23 23:25:44 +01:00
if ( sWorld -> getIntConfig ( CONFIG_EXPANSION ) < 1 && ( race == RACE_BLOODELF || race == RACE_DRAENEI ))
2010-12-19 17:06:33 +01:00
continue ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// skip expansion classes if not playing with expansion
2010-12-23 23:25:44 +01:00
if ( sWorld -> getIntConfig ( CONFIG_EXPANSION ) < 2 && class_ == CLASS_DEATH_KNIGHT )
2010-12-19 17:06:33 +01:00
continue ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// fatal error if no level 1 data
if ( ! pInfo -> levelInfo || pInfo -> levelInfo [ 0 ]. stats [ 0 ] == 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Race %i Class %i Level 1 does not have stats data!" , race , class_ );
2010-12-19 17:06:33 +01:00
exit ( 1 );
}
// fill level gaps
2010-12-23 23:25:44 +01:00
for ( uint8 level = 1 ; level < sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ); ++ level )
2010-12-19 17:06:33 +01:00
{
if ( pInfo -> levelInfo [ level ]. stats [ 0 ] == 0 )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Race %i Class %i Level %i does not have stats data. Using stats data of level %i." , race , class_ , level + 1 , level );
2010-12-19 17:06:33 +01:00
pInfo -> levelInfo [ level ] = pInfo -> levelInfo [ level - 1 ];
}
2008-10-11 14:16:25 -05:00
}
}
}
2010-12-19 17:06:33 +01:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u level stats definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-01-16 14:17:24 -06:00
// Loading xp per level data
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Loading Player Create XP Data..." );
2009-01-16 14:17:24 -06:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-12-23 23:25:44 +01:00
mPlayerXPperLevel . resize ( sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ));
for ( uint8 level = 0 ; level < sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ); ++ level )
2009-01-16 14:17:24 -06:00
mPlayerXPperLevel [ level ] = 0 ;
2009-10-17 15:51:44 -07:00
2009-01-16 14:17:24 -06:00
// 0 1
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT lvl, xp_for_next_level FROM player_xp_for_level" );
2009-10-17 15:51:44 -07:00
2009-01-16 14:17:24 -06:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 xp for level definitions. DB table `player_xp_for_level` is empty." );
sLog -> outString ();
2009-01-16 14:17:24 -06:00
exit ( 1 );
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2009-01-16 14:17:24 -06:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-01-16 14:17:24 -06:00
uint32 current_level = fields [ 0 ]. GetUInt32 ();
uint32 current_xp = fields [ 1 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( current_level >= sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ))
2009-01-16 14:17:24 -06:00
{
2010-04-07 19:14:10 +02:00
if ( current_level > STRONG_MAX_LEVEL ) // hardcoded level maximum
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong (> %u) level %u in `player_xp_for_level` table, ignoring." , STRONG_MAX_LEVEL , current_level );
2009-01-16 14:17:24 -06:00
else
2009-03-09 16:38:53 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outDetail ( "Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_xp_for_levels` table, ignoring." , current_level );
2009-03-09 16:38:53 -06:00
++ count ; // make result loading percent "expected" correct in case disabled detail mode for example.
}
2009-01-16 14:17:24 -06:00
continue ;
}
//PlayerXPperLevel
mPlayerXPperLevel [ current_level ] = current_xp ;
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
// fill level gaps
2010-12-23 23:25:44 +01:00
for ( uint8 level = 1 ; level < sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ); ++ level )
2009-01-16 14:17:24 -06:00
{
2010-12-19 17:06:33 +01:00
if ( mPlayerXPperLevel [ level ] == 0 )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Level %i does not have XP for level data. Using data of level [%i] + 100." , level + 1 , level );
2010-12-19 17:06:33 +01:00
mPlayerXPperLevel [ level ] = mPlayerXPperLevel [ level - 1 ] + 100 ;
}
2009-01-16 14:17:24 -06:00
}
2010-12-19 17:06:33 +01:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u xp for level definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2009-01-16 14:17:24 -06:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
void ObjectMgr :: GetPlayerClassLevelInfo ( uint32 class_ , uint8 level , PlayerClassLevelInfo * info ) const
2008-10-11 14:16:25 -05:00
{
2009-11-01 17:53:07 -08:00
if ( level < 1 || class_ >= MAX_CLASSES )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PlayerClassInfo const * pInfo = & playerClassInfo [ class_ ];
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( level > sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ))
level = sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
* info = pInfo -> levelInfo [ level - 1 ];
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
void ObjectMgr :: GetPlayerLevelInfo ( uint32 race , uint32 class_ , uint8 level , PlayerLevelInfo * info ) const
2008-10-11 14:16:25 -05:00
{
2010-04-07 23:56:35 +02:00
if ( level < 1 || race >= MAX_RACES || class_ >= MAX_CLASSES )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PlayerInfo const * pInfo = & playerInfo [ race ][ class_ ];
2010-04-07 23:25:02 +02:00
if ( pInfo -> displayId_m == 0 || pInfo -> displayId_f == 0 )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
if ( level <= sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ))
2008-10-11 14:16:25 -05:00
* info = pInfo -> levelInfo [ level - 1 ];
else
2011-04-29 20:47:02 +02:00
BuildPlayerLevelInfo ( race , class_ , level , info );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: BuildPlayerLevelInfo ( uint8 race , uint8 _class , uint8 level , PlayerLevelInfo * info ) const
{
// base data (last known level)
2010-12-23 23:25:44 +01:00
* info = playerInfo [ race ][ _class ]. levelInfo [ sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ) - 1 ];
2009-10-17 15:51:44 -07:00
2009-06-18 18:29:28 +02:00
// if conversion from uint32 to uint8 causes unexpected behaviour, change lvl to uint32
2010-12-23 23:25:44 +01:00
for ( uint8 lvl = sWorld -> getIntConfig ( CONFIG_MAX_PLAYER_LEVEL ) - 1 ; lvl < level ; ++ lvl )
2008-10-11 14:16:25 -05:00
{
switch ( _class )
{
case CLASS_WARRIOR :
info -> stats [ STAT_STRENGTH ] += ( lvl > 23 ? 2 : ( lvl > 1 ? 1 : 0 ));
info -> stats [ STAT_STAMINA ] += ( lvl > 23 ? 2 : ( lvl > 1 ? 1 : 0 ));
info -> stats [ STAT_AGILITY ] += ( lvl > 36 ? 1 : ( lvl > 6 && ( lvl % 2 ) ? 1 : 0 ));
info -> stats [ STAT_INTELLECT ] += ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_SPIRIT ] += ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 );
break ;
case CLASS_PALADIN :
info -> stats [ STAT_STRENGTH ] += ( lvl > 3 ? 1 : 0 );
info -> stats [ STAT_STAMINA ] += ( lvl > 33 ? 2 : ( lvl > 1 ? 1 : 0 ));
info -> stats [ STAT_AGILITY ] += ( lvl > 38 ? 1 : ( lvl > 7 && ! ( lvl % 2 ) ? 1 : 0 ));
info -> stats [ STAT_INTELLECT ] += ( lvl > 6 && ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_SPIRIT ] += ( lvl > 7 ? 1 : 0 );
break ;
case CLASS_HUNTER :
info -> stats [ STAT_STRENGTH ] += ( lvl > 4 ? 1 : 0 );
info -> stats [ STAT_STAMINA ] += ( lvl > 4 ? 1 : 0 );
info -> stats [ STAT_AGILITY ] += ( lvl > 33 ? 2 : ( lvl > 1 ? 1 : 0 ));
info -> stats [ STAT_INTELLECT ] += ( lvl > 8 && ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_SPIRIT ] += ( lvl > 38 ? 1 : ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 ));
break ;
case CLASS_ROGUE :
info -> stats [ STAT_STRENGTH ] += ( lvl > 5 ? 1 : 0 );
info -> stats [ STAT_STAMINA ] += ( lvl > 4 ? 1 : 0 );
info -> stats [ STAT_AGILITY ] += ( lvl > 16 ? 2 : ( lvl > 1 ? 1 : 0 ));
info -> stats [ STAT_INTELLECT ] += ( lvl > 8 && ! ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_SPIRIT ] += ( lvl > 38 ? 1 : ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 ));
break ;
case CLASS_PRIEST :
info -> stats [ STAT_STRENGTH ] += ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_STAMINA ] += ( lvl > 5 ? 1 : 0 );
info -> stats [ STAT_AGILITY ] += ( lvl > 38 ? 1 : ( lvl > 8 && ( lvl % 2 ) ? 1 : 0 ));
info -> stats [ STAT_INTELLECT ] += ( lvl > 22 ? 2 : ( lvl > 1 ? 1 : 0 ));
info -> stats [ STAT_SPIRIT ] += ( lvl > 3 ? 1 : 0 );
break ;
case CLASS_SHAMAN :
info -> stats [ STAT_STRENGTH ] += ( lvl > 34 ? 1 : ( lvl > 6 && ( lvl % 2 ) ? 1 : 0 ));
info -> stats [ STAT_STAMINA ] += ( lvl > 4 ? 1 : 0 );
info -> stats [ STAT_AGILITY ] += ( lvl > 7 && ! ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_INTELLECT ] += ( lvl > 5 ? 1 : 0 );
info -> stats [ STAT_SPIRIT ] += ( lvl > 4 ? 1 : 0 );
break ;
case CLASS_MAGE :
info -> stats [ STAT_STRENGTH ] += ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_STAMINA ] += ( lvl > 5 ? 1 : 0 );
info -> stats [ STAT_AGILITY ] += ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_INTELLECT ] += ( lvl > 24 ? 2 : ( lvl > 1 ? 1 : 0 ));
info -> stats [ STAT_SPIRIT ] += ( lvl > 33 ? 2 : ( lvl > 2 ? 1 : 0 ));
break ;
case CLASS_WARLOCK :
info -> stats [ STAT_STRENGTH ] += ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_STAMINA ] += ( lvl > 38 ? 2 : ( lvl > 3 ? 1 : 0 ));
info -> stats [ STAT_AGILITY ] += ( lvl > 9 && ! ( lvl % 2 ) ? 1 : 0 );
info -> stats [ STAT_INTELLECT ] += ( lvl > 33 ? 2 : ( lvl > 2 ? 1 : 0 ));
info -> stats [ STAT_SPIRIT ] += ( lvl > 38 ? 2 : ( lvl > 3 ? 1 : 0 ));
break ;
case CLASS_DRUID :
info -> stats [ STAT_STRENGTH ] += ( lvl > 38 ? 2 : ( lvl > 6 && ( lvl % 2 ) ? 1 : 0 ));
info -> stats [ STAT_STAMINA ] += ( lvl > 32 ? 2 : ( lvl > 4 ? 1 : 0 ));
info -> stats [ STAT_AGILITY ] += ( lvl > 38 ? 2 : ( lvl > 8 && ( lvl % 2 ) ? 1 : 0 ));
info -> stats [ STAT_INTELLECT ] += ( lvl > 38 ? 3 : ( lvl > 4 ? 1 : 0 ));
info -> stats [ STAT_SPIRIT ] += ( lvl > 38 ? 3 : ( lvl > 5 ? 1 : 0 ));
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadQuests ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
// For reload case
2009-10-17 16:20:24 -07:00
for ( QuestMap :: const_iterator itr = mQuestTemplates . begin (); itr != mQuestTemplates . end (); ++ itr )
2008-10-11 14:16:25 -05:00
delete itr -> second ;
mQuestTemplates . clear ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
mExclusiveQuestGroups . clear ();
2009-10-17 15:51:44 -07:00
2010-05-14 23:43:42 +02:00
// 0 1 2 3 4 5 6 7 8 9
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, Method, ZoneOrSort, SkillOrClassMask, MinLevel, MaxLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue, "
2010-03-23 16:10:18 +01:00
// 10 11 12 13 14 15 16 17 18 19
2011-04-29 20:47:02 +02:00
"RepObjectiveFaction, RepObjectiveValue, RepObjectiveFaction2, RepObjectiveValue2, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime, "
2010-03-27 15:10:26 +01:00
// 20 21 22 23 24 25 26 27 28 29 30 31 32 33
2011-04-29 20:47:02 +02:00
"QuestFlags, SpecialFlags, CharTitleId, PlayersSlain, BonusTalents, RewardArenaPoints, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, RewXPId, SrcItemId, SrcItemCount, SrcSpell, "
2010-03-27 15:10:26 +01:00
// 34 35 36 37 38 39 40 41 42 43 44
2011-04-29 20:47:02 +02:00
"Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, CompletedText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4, "
2010-03-27 15:10:26 +01:00
// 45 46 47 48 49 50 51 52 53 54 55 56
2011-04-29 20:47:02 +02:00
"ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemId5, ReqItemId6, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4, ReqItemCount5, ReqItemCount6, "
2010-03-27 15:10:26 +01:00
// 57 58 59 60 61 62 63 64
2011-04-29 20:47:02 +02:00
"ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, "
2010-03-27 15:10:26 +01:00
// 65 66 67 68 69 70 71 72
2011-04-29 20:47:02 +02:00
"ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4, "
2010-03-27 15:10:26 +01:00
// 73 74 75 76
2011-04-29 20:47:02 +02:00
"ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4, "
2010-03-27 15:10:26 +01:00
// 77 78 79 80 81 82
2011-04-29 20:47:02 +02:00
"RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6, "
2010-03-27 15:10:26 +01:00
// 83 84 85 86 87 88
2011-04-29 20:47:02 +02:00
"RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6, "
2010-03-27 15:10:26 +01:00
// 89 90 91 92 93 94 95 96
2011-04-29 20:47:02 +02:00
"RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4, "
2010-03-27 15:10:26 +01:00
// 97 98 99 100 101 102 103 104 105 106
2011-04-29 20:47:02 +02:00
"RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValueId1, RewRepValueId2, RewRepValueId3, RewRepValueId4, RewRepValueId5, "
2010-03-27 15:10:26 +01:00
// 107 108 109 110 111
2011-04-29 20:47:02 +02:00
"RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5, "
2010-03-27 15:10:26 +01:00
// 112 113 114 115 116 117 118 119 120 121 122 123
2011-04-29 20:47:02 +02:00
"RewHonorAddition, RewHonorMultiplier, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt, "
2010-03-27 15:10:26 +01:00
// 124 125 126 127 128 129 130 131
2011-04-29 20:47:02 +02:00
"DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, DetailsEmoteDelay1, DetailsEmoteDelay2, DetailsEmoteDelay3, DetailsEmoteDelay4, "
2010-03-27 15:10:26 +01:00
// 132 133 134 135 136 137
2011-04-29 20:47:02 +02:00
"IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4, "
2010-03-27 15:10:26 +01:00
// 138 139 140 141
2011-04-29 20:47:02 +02:00
"OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4, "
2010-03-27 15:10:26 +01:00
// 142 143
2008-10-11 14:16:25 -05:00
"StartScript, CompleteScript"
" FROM quest_template" );
2011-04-23 15:53:48 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 quests definitions. DB table `quest_template` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// create multimap previous quest for each existed quest
// some quests can have many previous maps set by NextQuestId in previous quest
// for example set of race quests can lead to single not race specific quest
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Quest * newQuest = new Quest ( fields );
mQuestTemplates [ newQuest -> GetQuestId ()] = newQuest ;
2010-04-07 22:59:46 +02:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
std :: map < uint32 , uint32 > usedMailTemplates ;
2009-12-16 18:58:36 +02:00
2008-10-11 14:16:25 -05:00
// Post processing
2008-12-08 16:34:03 -06:00
for ( QuestMap :: iterator iter = mQuestTemplates . begin (); iter != mQuestTemplates . end (); ++ iter )
2008-10-11 14:16:25 -05:00
{
2010-07-21 12:14:23 +02:00
// skip post-loading checks for disabled quests
2010-12-22 21:25:23 +01:00
if ( sDisableMgr -> IsDisabledFor ( DISABLE_TYPE_QUEST , iter -> first , NULL ))
2010-07-21 12:14:23 +02:00
continue ;
2008-10-11 14:16:25 -05:00
Quest * qinfo = iter -> second ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// additional quest integrity checks (GO, creature_template and item_template must be loaded already)
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( qinfo -> GetQuestMethod () >= 3 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Quest %u has `Method` = %u, expected values are 0, 1 or 2." , qinfo -> GetQuestId (), qinfo -> GetQuestMethod ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-15 08:26:30 +04:00
if ( qinfo -> QuestFlags & ~ QUEST_TRINITY_FLAGS_DB_ALLOWED )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `SpecialFlags` = %u > max allowed value. Correct `SpecialFlags` to value <= %u" ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> QuestFlags >> 20 , QUEST_TRINITY_FLAGS_DB_ALLOWED >> 20 );
2008-10-14 11:57:03 -05:00
qinfo -> QuestFlags &= QUEST_TRINITY_FLAGS_DB_ALLOWED ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-15 08:26:30 +04:00
if ( qinfo -> QuestFlags & QUEST_FLAGS_DAILY && qinfo -> QuestFlags & QUEST_FLAGS_WEEKLY )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Weekly Quest %u is marked as daily quest in `QuestFlags`, removed daily flag." , qinfo -> GetQuestId ());
2010-04-15 08:26:30 +04:00
qinfo -> QuestFlags &= ~ QUEST_FLAGS_DAILY ;
}
if ( qinfo -> QuestFlags & QUEST_FLAGS_DAILY )
{
if ( ! ( qinfo -> QuestFlags & QUEST_TRINITY_FLAGS_REPEATABLE ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Daily Quest %u not marked as repeatable in `SpecialFlags`, added." , qinfo -> GetQuestId ());
2010-04-15 08:26:30 +04:00
qinfo -> QuestFlags |= QUEST_TRINITY_FLAGS_REPEATABLE ;
}
}
if ( qinfo -> QuestFlags & QUEST_FLAGS_WEEKLY )
{
if ( ! ( qinfo -> QuestFlags & QUEST_TRINITY_FLAGS_REPEATABLE ))
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Weekly Quest %u not marked as repeatable in `SpecialFlags`, added." , qinfo -> GetQuestId ());
2010-04-15 08:26:30 +04:00
qinfo -> QuestFlags |= QUEST_TRINITY_FLAGS_REPEATABLE ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-04-15 08:26:30 +04:00
if ( qinfo -> QuestFlags & QUEST_FLAGS_AUTO_REWARDED )
2008-10-11 14:16:25 -05:00
{
// at auto-reward can be rewarded only RewChoiceItemId[0]
2010-04-24 17:48:52 +02:00
for ( int j = 1 ; j < QUEST_REWARD_CHOICES_COUNT ; ++ j )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( uint32 id = qinfo -> RewChoiceItemId [ j ])
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewChoiceItemId%d` = %u but item from `RewChoiceItemId%d` can't be rewarded with quest flag QUEST_FLAGS_AUTO_REWARDED." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , j + 1 );
2008-10-11 14:16:25 -05:00
// no changes, quest ignore this data
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// client quest log visual (area case)
2010-04-07 22:59:46 +02:00
if ( qinfo -> ZoneOrSort > 0 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! GetAreaEntryByAreaID ( qinfo -> ZoneOrSort ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ZoneOrSort` = %u (zone case) but zone with this id does not exist." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> ZoneOrSort );
2008-10-11 14:16:25 -05:00
// no changes, quest not dependent from this value but can have problems at client
}
}
// client quest log visual (sort case)
2010-04-07 22:59:46 +02:00
if ( qinfo -> ZoneOrSort < 0 )
2008-10-11 14:16:25 -05:00
{
QuestSortEntry const * qSort = sQuestSortStore . LookupEntry ( - int32 ( qinfo -> ZoneOrSort ));
2010-04-07 22:59:46 +02:00
if ( ! qSort )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ZoneOrSort` = %i (sort case) but quest sort with this id does not exist." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> ZoneOrSort );
2008-10-11 14:16:25 -05:00
// no changes, quest not dependent from this value but can have problems at client (note some may be 0, we must allow this so no check)
}
//check SkillOrClass value (class case).
2010-04-07 22:59:46 +02:00
if ( ClassByQuestSort ( - int32 ( qinfo -> ZoneOrSort )))
2008-10-11 14:16:25 -05:00
{
// SkillOrClass should not have class case when class case already set in ZoneOrSort.
2010-05-14 23:43:42 +02:00
if ( qinfo -> SkillOrClassMask < 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ZoneOrSort` = %i (class sort case) and `SkillOrClassMask` = %i (class case), redundant." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> ZoneOrSort , qinfo -> SkillOrClassMask );
2008-10-11 14:16:25 -05:00
}
}
//check for proper SkillOrClass value (skill case)
2010-04-07 19:14:10 +02:00
if ( int32 skill_id = SkillByQuestSort ( - int32 ( qinfo -> ZoneOrSort )))
2008-10-11 14:16:25 -05:00
{
// skill is positive value in SkillOrClass
2010-05-14 23:43:42 +02:00
if ( qinfo -> SkillOrClassMask != skill_id )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ZoneOrSort` = %i (skill sort case) but `SkillOrClassMask` does not have a corresponding value (%i)." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> ZoneOrSort , skill_id );
2008-10-11 14:16:25 -05:00
//override, and force proper value here?
}
}
}
2009-10-17 15:51:44 -07:00
2010-05-14 23:43:42 +02:00
// SkillOrClassMask (class case)
if ( qinfo -> SkillOrClassMask < 0 )
2008-10-11 14:16:25 -05:00
{
2010-05-14 23:43:42 +02:00
if ( ! ( - int32 ( qinfo -> SkillOrClassMask ) & CLASSMASK_ALL_PLAYABLE ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `SkillOrClassMask` = %i (class case) but classmask does not have valid class" ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> SkillOrClassMask );
2008-10-11 14:16:25 -05:00
}
}
2010-05-14 23:43:42 +02:00
// SkillOrClassMask (skill case)
if ( qinfo -> SkillOrClassMask > 0 )
2008-10-11 14:16:25 -05:00
{
2010-05-14 23:43:42 +02:00
if ( ! sSkillLineStore . LookupEntry ( qinfo -> SkillOrClassMask ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `SkillOrClass` = %u (skill case) but skill (%i) does not exist" ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> SkillOrClassMask , qinfo -> SkillOrClassMask );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( qinfo -> RequiredSkillValue )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
if ( qinfo -> RequiredSkillValue > sWorld -> GetConfigMaxSkillValue ())
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RequiredSkillValue` = %u but max possible skill is %u, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RequiredSkillValue , sWorld -> GetConfigMaxSkillValue ());
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2010-05-14 23:43:42 +02:00
if ( qinfo -> SkillOrClassMask <= 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RequiredSkillValue` = %u but `SkillOrClass` = %i (class case), value ignored." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RequiredSkillValue , qinfo -> SkillOrClassMask );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement (fail at wrong skill id)
}
}
// else Skill quests can have 0 skill level, this is ok
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> RepObjectiveFaction2 && ! sFactionStore . LookupEntry ( qinfo -> RepObjectiveFaction2 ))
2009-12-20 16:51:41 -07:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RepObjectiveFaction2` = %u but faction template %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RepObjectiveFaction2 , qinfo -> RepObjectiveFaction2 );
2009-12-20 16:51:41 -07:00
// no changes, quest can't be done for this requirement
}
2010-04-07 19:14:10 +02:00
if ( qinfo -> RepObjectiveFaction && ! sFactionStore . LookupEntry ( qinfo -> RepObjectiveFaction ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RepObjectiveFaction` = %u but faction template %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RepObjectiveFaction , qinfo -> RepObjectiveFaction );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> RequiredMinRepFaction && ! sFactionStore . LookupEntry ( qinfo -> RequiredMinRepFaction ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RequiredMinRepFaction` = %u but faction template %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RequiredMinRepFaction , qinfo -> RequiredMinRepFaction );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> RequiredMaxRepFaction && ! sFactionStore . LookupEntry ( qinfo -> RequiredMaxRepFaction ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RequiredMaxRepFaction` = %u but faction template %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RequiredMaxRepFaction , qinfo -> RequiredMaxRepFaction );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> RequiredMinRepValue && qinfo -> RequiredMinRepValue > ReputationMgr :: Reputation_Cap )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RequiredMinRepValue` = %d but max reputation is %u, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RequiredMinRepValue , ReputationMgr :: Reputation_Cap );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> RequiredMinRepValue && qinfo -> RequiredMaxRepValue && qinfo -> RequiredMaxRepValue <= qinfo -> RequiredMinRepValue )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RequiredMaxRepValue` = %d and `RequiredMinRepValue` = %d, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RequiredMaxRepValue , qinfo -> RequiredMinRepValue );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2011-09-04 23:44:01 +01:00
if ( ! qinfo -> RepObjectiveFaction && qinfo -> RepObjectiveValue != 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RepObjectiveValue` = %d but `RepObjectiveFaction` is 0, value has no effect" ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RepObjectiveValue );
2008-10-11 14:16:25 -05:00
// warning
}
2009-10-17 15:51:44 -07:00
2011-09-04 23:44:01 +01:00
if ( ! qinfo -> RepObjectiveFaction2 && qinfo -> RepObjectiveValue2 != 0 )
2009-12-20 16:51:41 -07:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RepObjectiveValue2` = %d but `RepObjectiveFaction2` is 0, value has no effect" ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RepObjectiveValue2 );
2009-12-20 16:51:41 -07:00
// warning
}
2011-09-04 23:44:01 +01:00
if ( ! qinfo -> RequiredMinRepFaction && qinfo -> RequiredMinRepValue != 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RequiredMinRepValue` = %d but `RequiredMinRepFaction` is 0, value has no effect" ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RequiredMinRepValue );
2008-10-11 14:16:25 -05:00
// warning
}
2009-10-17 15:51:44 -07:00
2011-09-04 23:44:01 +01:00
if ( ! qinfo -> RequiredMaxRepFaction && qinfo -> RequiredMaxRepValue != 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RequiredMaxRepValue` = %d but `RequiredMaxRepFaction` is 0, value has no effect" ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RequiredMaxRepValue );
2008-10-11 14:16:25 -05:00
// warning
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> CharTitleId && ! sCharTitlesStore . LookupEntry ( qinfo -> CharTitleId ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `CharTitleId` = %u but CharTitle Id %u does not exist, quest can't be rewarded with title." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> GetCharTitleId (), qinfo -> GetCharTitleId ());
2008-10-11 14:16:25 -05:00
qinfo -> CharTitleId = 0 ;
// quest can't reward this title
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> SrcItemId )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( ! sObjectMgr -> GetItemTemplate ( qinfo -> SrcItemId ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `SrcItemId` = %u but item with entry %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> SrcItemId , qinfo -> SrcItemId );
2008-10-11 14:16:25 -05:00
qinfo -> SrcItemId = 0 ; // quest can't be done for this requirement
}
2010-04-07 23:25:02 +02:00
else if ( qinfo -> SrcItemCount == 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `SrcItemId` = %u but `SrcItemCount` = 0, set to 1 but need fix in DB." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> SrcItemId );
2008-11-14 16:28:45 -06:00
qinfo -> SrcItemCount = 1 ; // update to 1 for allow quest work for backward compatibility with DB
2008-10-11 14:16:25 -05:00
}
}
2010-04-07 19:14:10 +02:00
else if ( qinfo -> SrcItemCount > 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `SrcItemId` = 0 but `SrcItemCount` = %u, useless value." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> SrcItemCount );
2008-10-11 14:16:25 -05:00
qinfo -> SrcItemCount = 0 ; // no quest work changes in fact
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> SrcSpell )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( qinfo -> SrcSpell );
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `SrcSpell` = %u but spell %u doesn't exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> SrcSpell , qinfo -> SrcSpell );
2008-10-11 14:16:25 -05:00
qinfo -> SrcSpell = 0 ; // quest can't be done for this requirement
}
2010-04-07 19:14:10 +02:00
else if ( ! SpellMgr :: IsSpellValid ( spellInfo ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `SrcSpell` = %u but spell %u is broken, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> SrcSpell , qinfo -> SrcSpell );
2008-10-11 14:16:25 -05:00
qinfo -> SrcSpell = 0 ; // quest can't be done for this requirement
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint8 j = 0 ; j < QUEST_ITEM_OBJECTIVES_COUNT ; ++ j )
2008-10-11 14:16:25 -05:00
{
uint32 id = qinfo -> ReqItemId [ j ];
2010-04-07 19:14:10 +02:00
if ( id )
2008-10-11 14:16:25 -05:00
{
2010-04-07 23:25:02 +02:00
if ( qinfo -> ReqItemCount [ j ] == 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqItemId%d` = %u but `ReqItemCount%d` = 0, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , j + 1 );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
qinfo -> SetFlag ( QUEST_TRINITY_FLAGS_DELIVER );
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( ! sObjectMgr -> GetItemTemplate ( id ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqItemId%d` = %u but item with entry %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , id );
2008-10-11 14:16:25 -05:00
qinfo -> ReqItemCount [ j ] = 0 ; // prevent incorrect work of quest
}
}
2010-04-07 19:14:10 +02:00
else if ( qinfo -> ReqItemCount [ j ] > 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqItemId%d` = 0 but `ReqItemCount%d` = %u, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , j + 1 , qinfo -> ReqItemCount [ j ]);
2008-10-11 14:16:25 -05:00
qinfo -> ReqItemCount [ j ] = 0 ; // prevent incorrect work of quest
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint8 j = 0 ; j < QUEST_SOURCE_ITEM_IDS_COUNT ; ++ j )
2008-10-11 14:16:25 -05:00
{
uint32 id = qinfo -> ReqSourceId [ j ];
2010-04-07 19:14:10 +02:00
if ( id )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( ! sObjectMgr -> GetItemTemplate ( id ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqSourceId%d` = %u but item with entry %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , id );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
}
else
{
2010-04-07 19:14:10 +02:00
if ( qinfo -> ReqSourceCount [ j ] > 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqSourceId%d` = 0 but `ReqSourceCount%d` = %u." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , j + 1 , qinfo -> ReqSourceCount [ j ]);
2008-10-11 14:16:25 -05:00
// no changes, quest ignore this data
}
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint8 j = 0 ; j < QUEST_OBJECTIVES_COUNT ; ++ j )
2008-10-11 14:16:25 -05:00
{
uint32 id = qinfo -> ReqSpell [ j ];
2010-04-07 19:14:10 +02:00
if ( id )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( id );
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqSpellCast%d` = %u but spell %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , id );
2009-04-27 18:42:35 -05:00
continue ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! qinfo -> ReqCreatureOrGOId [ j ])
2008-10-11 14:16:25 -05:00
{
bool found = false ;
2010-09-28 08:21:51 +03:00
for ( uint8 k = 0 ; k < MAX_SPELL_EFFECTS ; ++ k )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
if (( spellInfo -> Effects [ k ]. Effect == SPELL_EFFECT_QUEST_COMPLETE && uint32 ( spellInfo -> Effects [ k ]. MiscValue ) == qinfo -> QuestId ) ||
spellInfo -> Effects [ k ]. Effect == SPELL_EFFECT_SEND_EVENT )
2008-10-11 14:16:25 -05:00
{
found = true ;
break ;
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( found )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! qinfo -> HasFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Spell (id: %u) have SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT for quest %u and ReqCreatureOrGOId%d = 0, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Quest flags or ReqCreatureOrGOId%d must be fixed, quest modified to enable objective." , spellInfo -> Id , qinfo -> QuestId , j + 1 , j + 1 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// this will prevent quest completing without objective
2008-10-14 11:57:03 -05:00
const_cast < Quest *> ( qinfo ) -> SetFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT );
2008-10-11 14:16:25 -05:00
}
}
else
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqSpellCast%d` = %u and ReqCreatureOrGOId%d = 0 but spell %u does not have SPELL_EFFECT_QUEST_COMPLETE or SPELL_EFFECT_SEND_EVENT effect for this quest, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , j + 1 , id );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done for this requirement
}
}
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint8 j = 0 ; j < QUEST_OBJECTIVES_COUNT ; ++ j )
2008-10-11 14:16:25 -05:00
{
int32 id = qinfo -> ReqCreatureOrGOId [ j ];
2011-04-28 22:54:30 +02:00
if ( id < 0 && ! sObjectMgr -> GetGameObjectTemplate ( - id ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqCreatureOrGOId%d` = %i but gameobject %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , uint32 ( - id ));
2008-10-11 14:16:25 -05:00
qinfo -> ReqCreatureOrGOId [ j ] = 0 ; // quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:57:08 +02:00
if ( id > 0 && ! sObjectMgr -> GetCreatureTemplate ( id ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqCreatureOrGOId%d` = %i but creature with entry %u does not exist, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , uint32 ( id ));
2008-10-11 14:16:25 -05:00
qinfo -> ReqCreatureOrGOId [ j ] = 0 ; // quest can't be done for this requirement
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( id )
2008-10-11 14:16:25 -05:00
{
// In fact SpeakTo and Kill are quite same: either you can speak to mob:SpeakTo or you can't:Kill/Cast
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
qinfo -> SetFlag ( QUEST_TRINITY_FLAGS_KILL_OR_CAST | QUEST_TRINITY_FLAGS_SPEAKTO );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! qinfo -> ReqCreatureOrGOCount [ j ])
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqCreatureOrGOId%d` = %u but `ReqCreatureOrGOCount%d` = 0, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , j + 1 );
2008-10-11 14:16:25 -05:00
// no changes, quest can be incorrectly done, but we already report this
}
}
2010-04-07 19:14:10 +02:00
else if ( qinfo -> ReqCreatureOrGOCount [ j ] > 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `ReqCreatureOrGOId%d` = 0 but `ReqCreatureOrGOCount%d` = %u." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , j + 1 , qinfo -> ReqCreatureOrGOCount [ j ]);
2008-10-11 14:16:25 -05:00
// no changes, quest ignore this data
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint8 j = 0 ; j < QUEST_REWARD_CHOICES_COUNT ; ++ j )
2008-10-11 14:16:25 -05:00
{
uint32 id = qinfo -> RewChoiceItemId [ j ];
2010-04-07 19:14:10 +02:00
if ( id )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( ! sObjectMgr -> GetItemTemplate ( id ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewChoiceItemId%d` = %u but item with entry %u does not exist, quest will not reward this item." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , id );
2008-10-11 14:16:25 -05:00
qinfo -> RewChoiceItemId [ j ] = 0 ; // no changes, quest will not reward this
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! qinfo -> RewChoiceItemCount [ j ])
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewChoiceItemId%d` = %u but `RewChoiceItemCount%d` = 0, quest can't be done." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , j + 1 );
2008-10-11 14:16:25 -05:00
// no changes, quest can't be done
}
}
2010-04-07 19:14:10 +02:00
else if ( qinfo -> RewChoiceItemCount [ j ] > 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewChoiceItemId%d` = 0 but `RewChoiceItemCount%d` = %u." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , j + 1 , qinfo -> RewChoiceItemCount [ j ]);
2008-10-11 14:16:25 -05:00
// no changes, quest ignore this data
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
for ( uint8 j = 0 ; j < QUEST_REWARDS_COUNT ; ++ j )
2008-10-11 14:16:25 -05:00
{
uint32 id = qinfo -> RewItemId [ j ];
2010-04-07 19:14:10 +02:00
if ( id )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
if ( ! sObjectMgr -> GetItemTemplate ( id ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewItemId%d` = %u but item with entry %u does not exist, quest will not reward this item." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , id );
2008-10-11 14:16:25 -05:00
qinfo -> RewItemId [ j ] = 0 ; // no changes, quest will not reward this item
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! qinfo -> RewItemCount [ j ])
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewItemId%d` = %u but `RewItemCount%d` = 0, quest will not reward this item." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , id , j + 1 );
2008-10-11 14:16:25 -05:00
// no changes
}
}
2010-04-07 19:14:10 +02:00
else if ( qinfo -> RewItemCount [ j ] > 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewItemId%d` = 0 but `RewItemCount%d` = %u." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , j + 1 , qinfo -> RewItemCount [ j ]);
2008-10-11 14:16:25 -05:00
// no changes, quest ignore this data
}
}
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( uint8 j = 0 ; j < QUEST_REPUTATIONS_COUNT ; ++ j )
2008-10-11 14:16:25 -05:00
{
2010-02-14 19:13:14 -07:00
if ( qinfo -> RewRepFaction [ j ])
2008-10-11 14:16:25 -05:00
{
2010-02-14 19:13:14 -07:00
if ( abs ( qinfo -> RewRepValueId [ j ]) > 9 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has RewRepValueId%d = %i. That is outside the range of valid values (-9 to 9)." , qinfo -> GetQuestId (), j + 1 , qinfo -> RewRepValueId [ j ]);
2008-10-11 14:16:25 -05:00
}
2010-04-07 19:14:10 +02:00
if ( ! sFactionStore . LookupEntry ( qinfo -> RewRepFaction [ j ]))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Quest %u has `RewRepFaction%d` = %u but raw faction (faction.dbc) %u does not exist, quest will not reward reputation for this faction." , qinfo -> GetQuestId (), j + 1 , qinfo -> RewRepFaction [ j ] , qinfo -> RewRepFaction [ j ]);
2008-10-11 14:16:25 -05:00
qinfo -> RewRepFaction [ j ] = 0 ; // quest will not reward this
}
2010-04-07 18:09:10 +02:00
}
2010-04-08 08:20:08 +02:00
else if ( qinfo -> RewRepValue [ j ] != 0 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewRepFaction%d` = 0 but `RewRepValue%d` = %i." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), j + 1 , j + 1 , qinfo -> RewRepValue [ j ]);
2008-10-11 14:16:25 -05:00
// no changes, quest ignore this data
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> RewSpell )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( qinfo -> RewSpell );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewSpell` = %u but spell %u does not exist, spell removed as display reward." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RewSpell , qinfo -> RewSpell );
2008-10-11 14:16:25 -05:00
qinfo -> RewSpell = 0 ; // no spell reward will display for this quest
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
else if ( ! SpellMgr :: IsSpellValid ( spellInfo ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewSpell` = %u but spell %u is broken, quest will not have a spell reward." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RewSpell , qinfo -> RewSpell );
2008-10-11 14:16:25 -05:00
qinfo -> RewSpell = 0 ; // no spell reward will display for this quest
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
else if ( GetTalentSpellCost ( qinfo -> RewSpell ))
2009-07-01 18:07:57 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewSpell` = %u but spell %u is talent, quest will not have a spell reward." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RewSpell , qinfo -> RewSpell );
2009-07-01 18:07:57 -05:00
qinfo -> RewSpell = 0 ; // no spell reward will display for this quest
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> RewSpellCast > 0 )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( qinfo -> RewSpellCast );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewSpellCast` = %u but spell %u does not exist, quest will not have a spell reward." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RewSpellCast , qinfo -> RewSpellCast );
2008-10-11 14:16:25 -05:00
qinfo -> RewSpellCast = 0 ; // no spell will be casted on player
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
else if ( ! SpellMgr :: IsSpellValid ( spellInfo ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewSpellCast` = %u but spell %u is broken, quest will not have a spell reward." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RewSpellCast , qinfo -> RewSpellCast );
2008-10-11 14:16:25 -05:00
qinfo -> RewSpellCast = 0 ; // no spell will be casted on player
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
else if ( GetTalentSpellCost ( qinfo -> RewSpellCast ))
2009-07-01 18:07:57 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewSpell` = %u but spell %u is talent, quest will not have a spell reward." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RewSpellCast , qinfo -> RewSpellCast );
2009-07-01 18:07:57 -05:00
qinfo -> RewSpellCast = 0 ; // no spell will be casted on player
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
if ( qinfo -> RewMailTemplateId )
2008-10-11 14:16:25 -05:00
{
2009-12-16 18:58:36 +02:00
if ( ! sMailTemplateStore . LookupEntry ( qinfo -> RewMailTemplateId ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewMailTemplateId` = %u but mail template %u does not exist, quest will not have a mail reward." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RewMailTemplateId , qinfo -> RewMailTemplateId );
2008-10-11 14:16:25 -05:00
qinfo -> RewMailTemplateId = 0 ; // no mail will send to player
qinfo -> RewMailDelaySecs = 0 ; // no mail will send to player
}
2009-12-16 18:58:36 +02:00
else if ( usedMailTemplates . find ( qinfo -> RewMailTemplateId ) != usedMailTemplates . end ())
{
2011-04-29 20:47:02 +02:00
std :: map < uint32 , uint32 >:: const_iterator used_mt_itr = usedMailTemplates . find ( qinfo -> RewMailTemplateId );
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `RewMailTemplateId` = %u but mail template %u already used for quest %u, quest will not have a mail reward." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> RewMailTemplateId , qinfo -> RewMailTemplateId , used_mt_itr -> second );
2009-12-16 18:58:36 +02:00
qinfo -> RewMailTemplateId = 0 ; // no mail will send to player
qinfo -> RewMailDelaySecs = 0 ; // no mail will send to player
}
else
usedMailTemplates [ qinfo -> RewMailTemplateId ] = qinfo -> GetQuestId ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
if ( qinfo -> NextQuestInChain )
2008-10-11 14:16:25 -05:00
{
2009-03-09 17:40:40 -06:00
QuestMap :: iterator qNextItr = mQuestTemplates . find ( qinfo -> NextQuestInChain );
2010-04-07 19:14:10 +02:00
if ( qNextItr == mQuestTemplates . end ())
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %u has `NextQuestInChain` = %u but quest %u does not exist, quest chain will not work." ,
2011-04-29 20:47:02 +02:00
qinfo -> GetQuestId (), qinfo -> NextQuestInChain , qinfo -> NextQuestInChain );
2008-10-11 14:16:25 -05:00
qinfo -> NextQuestInChain = 0 ;
}
else
2009-03-09 17:40:40 -06:00
qNextItr -> second -> prevChainQuests . push_back ( qinfo -> GetQuestId ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// fill additional data stores
2010-04-07 19:14:10 +02:00
if ( qinfo -> PrevQuestId )
2008-10-11 14:16:25 -05:00
{
if ( mQuestTemplates . find ( abs ( qinfo -> GetPrevQuestId ())) == mQuestTemplates . end ())
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %d has PrevQuestId %i, but no such quest" , qinfo -> GetQuestId (), qinfo -> GetPrevQuestId ());
2008-10-11 14:16:25 -05:00
}
else
{
qinfo -> prevQuests . push_back ( qinfo -> PrevQuestId );
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> NextQuestId )
2008-10-11 14:16:25 -05:00
{
2009-03-09 17:40:40 -06:00
QuestMap :: iterator qNextItr = mQuestTemplates . find ( abs ( qinfo -> GetNextQuestId ()));
if ( qNextItr == mQuestTemplates . end ())
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest %d has NextQuestId %i, but no such quest" , qinfo -> GetQuestId (), qinfo -> GetNextQuestId ());
2008-10-11 14:16:25 -05:00
}
else
{
int32 signedQuestId = qinfo -> NextQuestId < 0 ? - int32 ( qinfo -> GetQuestId ()) : int32 ( qinfo -> GetQuestId ());
2009-03-09 17:40:40 -06:00
qNextItr -> second -> prevQuests . push_back ( signedQuestId );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( qinfo -> ExclusiveGroup )
2008-10-11 14:16:25 -05:00
mExclusiveQuestGroups . insert ( std :: pair < int32 , uint32 > ( qinfo -> ExclusiveGroup , qinfo -> GetQuestId ()));
2010-04-07 19:14:10 +02:00
if ( qinfo -> LimitTime )
2008-10-14 11:57:03 -05:00
qinfo -> SetFlag ( QUEST_TRINITY_FLAGS_TIMED );
2011-09-05 15:18:12 +01:00
if ( qinfo -> PlayersSlain )
qinfo -> SetFlag ( QUEST_TRINITY_FLAGS_PLAYER_KILL );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
// check QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
2011-07-26 23:09:28 +02:00
for ( uint32 i = 0 ; i < sSpellMgr -> GetSpellInfoStoreSize (); ++ i )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( i );
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 j = 0 ; j < MAX_SPELL_EFFECTS ; ++ j )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
if ( spellInfo -> Effects [ j ]. Effect != SPELL_EFFECT_QUEST_COMPLETE )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2011-07-26 23:09:28 +02:00
uint32 quest_id = spellInfo -> Effects [ j ]. MiscValue ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Quest const * quest = GetQuestTemplate ( quest_id );
2009-10-17 15:51:44 -07:00
2008-11-14 16:28:45 -06:00
// some quest referenced in spells not exist (outdated spells)
2010-04-07 19:14:10 +02:00
if ( ! quest )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! quest -> HasFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Spell (id: %u) have SPELL_EFFECT_QUEST_COMPLETE for quest %u , but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Quest flags must be fixed, quest modified to enable objective." , spellInfo -> Id , quest_id );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// this will prevent quest completing without objective
2008-10-14 11:57:03 -05:00
const_cast < Quest *> ( quest ) -> SetFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT );
2008-10-11 14:16:25 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu quests definitions in %u ms" , ( unsigned long ) mQuestTemplates . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadQuestLocales ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
mQuestLocaleMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, "
"Title_loc1, Details_loc1, Objectives_loc1, OfferRewardText_loc1, RequestItemsText_loc1, EndText_loc1, CompletedText_loc1, ObjectiveText1_loc1, ObjectiveText2_loc1, ObjectiveText3_loc1, ObjectiveText4_loc1, "
"Title_loc2, Details_loc2, Objectives_loc2, OfferRewardText_loc2, RequestItemsText_loc2, EndText_loc2, CompletedText_loc2, ObjectiveText1_loc2, ObjectiveText2_loc2, ObjectiveText3_loc2, ObjectiveText4_loc2, "
"Title_loc3, Details_loc3, Objectives_loc3, OfferRewardText_loc3, RequestItemsText_loc3, EndText_loc3, CompletedText_loc3, ObjectiveText1_loc3, ObjectiveText2_loc3, ObjectiveText3_loc3, ObjectiveText4_loc3, "
"Title_loc4, Details_loc4, Objectives_loc4, OfferRewardText_loc4, RequestItemsText_loc4, EndText_loc4, CompletedText_loc4, ObjectiveText1_loc4, ObjectiveText2_loc4, ObjectiveText3_loc4, ObjectiveText4_loc4, "
"Title_loc5, Details_loc5, Objectives_loc5, OfferRewardText_loc5, RequestItemsText_loc5, EndText_loc5, CompletedText_loc5, ObjectiveText1_loc5, ObjectiveText2_loc5, ObjectiveText3_loc5, ObjectiveText4_loc5, "
"Title_loc6, Details_loc6, Objectives_loc6, OfferRewardText_loc6, RequestItemsText_loc6, EndText_loc6, CompletedText_loc6, ObjectiveText1_loc6, ObjectiveText2_loc6, ObjectiveText3_loc6, ObjectiveText4_loc6, "
"Title_loc7, Details_loc7, Objectives_loc7, OfferRewardText_loc7, RequestItemsText_loc7, EndText_loc7, CompletedText_loc7, ObjectiveText1_loc7, ObjectiveText2_loc7, ObjectiveText3_loc7, ObjectiveText4_loc7, "
"Title_loc8, Details_loc8, Objectives_loc8, OfferRewardText_loc8, RequestItemsText_loc8, EndText_loc8, CompletedText_loc8, ObjectiveText1_loc8, ObjectiveText2_loc8, ObjectiveText3_loc8, ObjectiveText4_loc8"
2010-12-19 17:06:33 +01:00
" FROM locales_quest" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
QuestLocale & data = mQuestLocaleMap [ entry ];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-08-26 15:54:56 +06:00
LocaleConstant locale = ( LocaleConstant ) i ;
2009-10-17 15:51:44 -07:00
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ 1 + 11 * ( i - 1 )]. GetString (), locale , data . Title );
AddLocaleString ( fields [ 1 + 11 * ( i - 1 ) + 1 ]. GetString (), locale , data . Details );
AddLocaleString ( fields [ 1 + 11 * ( i - 1 ) + 2 ]. GetString (), locale , data . Objectives );
AddLocaleString ( fields [ 1 + 11 * ( i - 1 ) + 3 ]. GetString (), locale , data . OfferRewardText );
AddLocaleString ( fields [ 1 + 11 * ( i - 1 ) + 4 ]. GetString (), locale , data . RequestItemsText );
AddLocaleString ( fields [ 1 + 11 * ( i - 1 ) + 5 ]. GetString (), locale , data . EndText );
AddLocaleString ( fields [ 1 + 11 * ( i - 1 ) + 6 ]. GetString (), locale , data . CompletedText );
2010-03-02 09:59:59 -07:00
2009-10-17 16:20:24 -07:00
for ( uint8 k = 0 ; k < 4 ; ++ k )
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ 1 + 11 * ( i - 1 ) + 7 + k ]. GetString (), locale , data . ObjectiveText [ k ]);
2008-10-11 14:16:25 -05:00
}
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu Quest locale strings in %u ms" , ( unsigned long ) mQuestLocaleMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-20 12:19:14 +06:00
void ObjectMgr :: LoadScripts ( ScriptsType type )
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-08-20 12:19:14 +06:00
ScriptMapMap * scripts = GetScriptsMapByType ( type );
if ( ! scripts )
return ;
std :: string tableName = GetScriptsTableNameByType ( type );
if ( tableName . empty ())
return ;
2011-04-13 12:07:20 +06:00
if ( sScriptMgr -> IsScriptScheduled ()) // function cannot be called when scripts are in use.
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Loading %s..." , tableName . c_str ());
2009-10-17 15:51:44 -07:00
2011-04-13 12:07:20 +06:00
scripts -> clear (); // need for reload support
2009-10-17 15:51:44 -07:00
2010-08-20 12:19:14 +06:00
bool isSpellScriptTable = ( type == SCRIPTS_SPELL );
2010-07-24 21:51:25 +02:00
char buff [ 125 ];
2011-04-29 20:47:02 +02:00
sprintf ( buff , "SELECT id, delay, command, datalong, datalong2, dataint, x, y, z, o%s FROM %s" , isSpellScriptTable ? ", effIndex" : "" , tableName . c_str ());
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( buff );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 script definitions. DB table `%s` is empty!" , tableName . c_str ());
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
ScriptInfo tmp ;
2010-08-20 14:57:05 +06:00
tmp . type = type ;
2010-09-22 18:13:57 +06:00
tmp . id = fields [ 0 ]. GetUInt32 ();
if ( isSpellScriptTable )
tmp . id |= fields [ 10 ]. GetUInt8 () << 24 ;
tmp . delay = fields [ 1 ]. GetUInt32 ();
tmp . command = ScriptCommands ( fields [ 2 ]. GetUInt32 ());
tmp . Raw . nData [ 0 ] = fields [ 3 ]. GetUInt32 ();
tmp . Raw . nData [ 1 ] = fields [ 4 ]. GetUInt32 ();
tmp . Raw . nData [ 2 ] = fields [ 5 ]. GetInt32 ();
tmp . Raw . fData [ 0 ] = fields [ 6 ]. GetFloat ();
tmp . Raw . fData [ 1 ] = fields [ 7 ]. GetFloat ();
tmp . Raw . fData [ 2 ] = fields [ 8 ]. GetFloat ();
tmp . Raw . fData [ 3 ] = fields [ 9 ]. GetFloat ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// generic command args check
2010-06-02 18:43:11 +02:00
switch ( tmp . command )
2008-10-11 14:16:25 -05:00
{
case SCRIPT_COMMAND_TALK :
{
2010-09-22 18:13:57 +06:00
if ( tmp . Talk . ChatType > CHAT_TYPE_WHISPER && tmp . Talk . ChatType != CHAT_MSG_RAID_BOSS_WHISPER )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid talk type (datalong = %u) in SCRIPT_COMMAND_TALK for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . Talk . ChatType , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2010-09-22 18:13:57 +06:00
if ( ! tmp . Talk . TextID )
2008-11-20 16:16:57 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid talk text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . Talk . TextID , tmp . id );
2008-11-20 16:16:57 -06:00
continue ;
}
2010-09-22 18:13:57 +06:00
if ( tmp . Talk . TextID < MIN_DB_SCRIPT_STRING_ID || tmp . Talk . TextID >= MAX_DB_SCRIPT_STRING_ID )
2008-11-20 16:16:57 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has out of range text id (dataint = %i expected %u-%u) in SCRIPT_COMMAND_TALK for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . Talk . TextID , MIN_DB_SCRIPT_STRING_ID , MAX_DB_SCRIPT_STRING_ID , tmp . id );
2008-11-20 16:16:57 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
break ;
}
2009-10-17 15:51:44 -07:00
2009-04-19 18:24:40 -05:00
case SCRIPT_COMMAND_EMOTE :
{
2010-09-22 18:13:57 +06:00
if ( ! sEmotesStore . LookupEntry ( tmp . Emote . EmoteID ))
2009-04-19 18:24:40 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid emote id (datalong = %u) in SCRIPT_COMMAND_EMOTE for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . Emote . EmoteID , tmp . id );
2009-04-19 18:24:40 -05:00
continue ;
}
break ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
case SCRIPT_COMMAND_TELEPORT_TO :
{
2010-09-22 18:13:57 +06:00
if ( ! sMapStore . LookupEntry ( tmp . TeleportTo . MapID ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid map (Id: %u) in SCRIPT_COMMAND_TELEPORT_TO for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . TeleportTo . MapID , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-09-22 18:13:57 +06:00
if ( ! Trinity :: IsValidMapCoord ( tmp . TeleportTo . DestX , tmp . TeleportTo . DestY , tmp . TeleportTo . DestZ , tmp . TeleportTo . Orientation ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid coordinates (X: %f Y: %f Z: %f O: %f) in SCRIPT_COMMAND_TELEPORT_TO for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . TeleportTo . DestX , tmp . TeleportTo . DestY , tmp . TeleportTo . DestZ , tmp . TeleportTo . Orientation , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
break ;
}
2009-10-17 15:51:44 -07:00
2010-09-22 18:13:57 +06:00
case SCRIPT_COMMAND_QUEST_EXPLORED :
2009-12-19 18:53:27 +01:00
{
2010-09-22 18:13:57 +06:00
Quest const * quest = GetQuestTemplate ( tmp . QuestExplored . QuestID );
if ( ! quest )
2009-12-19 18:53:27 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid quest (ID: %u) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . QuestExplored . QuestID , tmp . id );
2009-12-19 18:53:27 +01:00
continue ;
}
2010-09-22 18:13:57 +06:00
if ( ! quest -> HasFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has quest (ID: %u) in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT in quest flags. Script command or quest flags wrong. Quest modified to require objective." ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . QuestExplored . QuestID , tmp . id );
// this will prevent quest completing without objective
const_cast < Quest *> ( quest ) -> SetFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT );
// continue; - quest objective requirement set and command can be allowed
}
if ( float ( tmp . QuestExplored . Distance ) > DEFAULT_VISIBILITY_DISTANCE )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . QuestExplored . Distance , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-09-22 18:13:57 +06:00
if ( tmp . QuestExplored . Distance && float ( tmp . QuestExplored . Distance ) > DEFAULT_VISIBILITY_DISTANCE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has too large distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, max distance is %f or 0 for disable distance check" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . QuestExplored . Distance , tmp . id , DEFAULT_VISIBILITY_DISTANCE );
continue ;
}
if ( tmp . QuestExplored . Distance && float ( tmp . QuestExplored . Distance ) < INTERACTION_DISTANCE )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has too small distance (%u) for exploring objective complete in `datalong2` in SCRIPT_COMMAND_QUEST_EXPLORED in `datalong` for script id %u, min distance is %f or 0 for disable distance check" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . QuestExplored . Distance , tmp . id , INTERACTION_DISTANCE );
continue ;
}
break ;
}
case SCRIPT_COMMAND_KILL_CREDIT :
{
if ( ! GetCreatureTemplate ( tmp . KillCredit . CreatureEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid creature (Entry: %u) in SCRIPT_COMMAND_KILL_CREDIT for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . KillCredit . CreatureEntry , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
break ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT :
{
2010-09-22 18:13:57 +06:00
GameObjectData const * data = GetGOData ( tmp . RespawnGameobject . GOGuid );
2010-04-07 19:14:10 +02:00
if ( ! data )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid gameobject (GUID: %u) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . RespawnGameobject . GOGuid , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * info = GetGameObjectTemplate ( data -> id );
2010-04-07 19:14:10 +02:00
if ( ! info )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has gameobject with invalid entry (GUID: %u Entry: %u) in SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . RespawnGameobject . GOGuid , data -> id , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( info -> type == GAMEOBJECT_TYPE_FISHINGNODE ||
info -> type == GAMEOBJECT_TYPE_FISHINGHOLE ||
info -> type == GAMEOBJECT_TYPE_DOOR ||
info -> type == GAMEOBJECT_TYPE_BUTTON ||
info -> type == GAMEOBJECT_TYPE_TRAP )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` have gameobject type (%u) unsupported by command SCRIPT_COMMAND_RESPAWN_GAMEOBJECT for script id %u" ,
2011-04-28 22:54:30 +02:00
tableName . c_str (), info -> entry , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
break ;
}
2009-10-17 15:51:44 -07:00
2010-09-22 18:13:57 +06:00
case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE :
{
if ( ! Trinity :: IsValidMapCoord ( tmp . TempSummonCreature . PosX , tmp . TempSummonCreature . PosY , tmp . TempSummonCreature . PosZ , tmp . TempSummonCreature . Orientation ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid coordinates (X: %f Y: %f Z: %f O: %f) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . TempSummonCreature . PosX , tmp . TempSummonCreature . PosY , tmp . TempSummonCreature . PosZ , tmp . TempSummonCreature . Orientation , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-09-22 18:13:57 +06:00
if ( ! GetCreatureTemplate ( tmp . TempSummonCreature . CreatureEntry ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid creature (Entry: %u) in SCRIPT_COMMAND_TEMP_SUMMON_CREATURE for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . TempSummonCreature . CreatureEntry , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
break ;
}
2009-10-17 15:51:44 -07:00
2010-09-22 18:13:57 +06:00
case SCRIPT_COMMAND_OPEN_DOOR :
case SCRIPT_COMMAND_CLOSE_DOOR :
{
GameObjectData const * data = GetGOData ( tmp . ToggleDoor . GOGuid );
if ( ! data )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has invalid gameobject (GUID: %u) in %s for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . ToggleDoor . GOGuid , GetScriptCommandName ( tmp . command ). c_str (), tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * info = GetGameObjectTemplate ( data -> id );
2010-09-22 18:13:57 +06:00
if ( ! info )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has gameobject with invalid entry (GUID: %u Entry: %u) in %s for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . ToggleDoor . GOGuid , data -> id , GetScriptCommandName ( tmp . command ). c_str (), tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-09-22 18:13:57 +06:00
if ( info -> type != GAMEOBJECT_TYPE_DOOR )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has gameobject type (%u) non supported by command %s for script id %u" ,
2011-04-28 22:54:30 +02:00
tableName . c_str (), info -> entry , GetScriptCommandName ( tmp . command ). c_str (), tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
break ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
case SCRIPT_COMMAND_REMOVE_AURA :
2009-02-19 18:56:50 -06:00
{
2011-07-26 23:09:28 +02:00
if ( ! sSpellMgr -> GetSpellInfo ( tmp . RemoveAura . SpellID ))
2009-02-19 18:56:50 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` using non-existent spell (id: %u) in SCRIPT_COMMAND_REMOVE_AURA for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . RemoveAura . SpellID , tmp . id );
2009-02-19 18:56:50 -06:00
continue ;
}
2011-04-29 20:47:02 +02:00
if ( tmp . RemoveAura . Flags & ~ 0x1 ) // 1 bits (0, 1)
2009-02-19 18:56:50 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` using unknown flags in datalong2 (%u) in SCRIPT_COMMAND_REMOVE_AURA for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . RemoveAura . Flags , tmp . id );
2009-02-19 18:56:50 -06:00
continue ;
}
break ;
}
2010-09-22 18:13:57 +06:00
2008-10-11 14:16:25 -05:00
case SCRIPT_COMMAND_CAST_SPELL :
{
2011-07-26 23:09:28 +02:00
if ( ! sSpellMgr -> GetSpellInfo ( tmp . CastSpell . SpellID ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` using non-existent spell (id: %u) in SCRIPT_COMMAND_CAST_SPELL for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . CastSpell . SpellID , tmp . id );
2008-10-11 14:16:25 -05:00
continue ;
}
2010-09-22 18:13:57 +06:00
if ( tmp . CastSpell . Flags > 4 ) // targeting type
2009-02-19 18:56:50 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` using unknown target in datalong2 (%u) in SCRIPT_COMMAND_CAST_SPELL for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . CastSpell . Flags , tmp . id );
2009-02-19 18:56:50 -06:00
continue ;
}
2011-04-29 20:47:02 +02:00
if ( tmp . CastSpell . Flags != 4 && tmp . CastSpell . CreatureEntry & ~ 0x1 ) // 1 bit (0, 1)
2010-07-27 19:18:44 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` using unknown flags in dataint (%u) in SCRIPT_COMMAND_CAST_SPELL for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . CastSpell . CreatureEntry , tmp . id );
2010-07-27 19:18:44 +02:00
continue ;
}
2010-09-22 18:13:57 +06:00
else if ( tmp . CastSpell . Flags == 4 && ! GetCreatureTemplate ( tmp . CastSpell . CreatureEntry ))
2010-07-28 10:33:14 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` using invalid creature entry in dataint (%u) in SCRIPT_COMMAND_CAST_SPELL for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . CastSpell . CreatureEntry , tmp . id );
2010-07-28 10:33:14 +02:00
continue ;
}
2008-10-11 14:16:25 -05:00
break ;
}
2010-06-02 18:43:11 +02:00
case SCRIPT_COMMAND_CREATE_ITEM :
{
2011-08-04 15:14:15 +02:00
if ( ! GetItemTemplate ( tmp . CreateItem . ItemEntry ))
2010-06-02 18:43:11 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` has nonexistent item (entry: %u) in SCRIPT_COMMAND_CREATE_ITEM for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . CreateItem . ItemEntry , tmp . id );
2010-06-02 18:43:11 +02:00
continue ;
}
2010-09-22 18:13:57 +06:00
if ( ! tmp . CreateItem . Amount )
2010-06-02 18:43:11 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `%s` SCRIPT_COMMAND_CREATE_ITEM but amount is %u for script id %u" ,
2010-09-22 18:13:57 +06:00
tableName . c_str (), tmp . CreateItem . Amount , tmp . id );
2010-06-02 18:43:11 +02:00
continue ;
}
2010-08-08 19:45:53 +02:00
break ;
2010-06-02 18:43:11 +02:00
}
2010-08-21 20:55:31 +02:00
default :
break ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-20 12:19:14 +06:00
if ( scripts -> find ( tmp . id ) == scripts -> end ())
2008-10-11 14:16:25 -05:00
{
ScriptMap emptyMap ;
2010-08-20 12:19:14 +06:00
( * scripts )[ tmp . id ] = emptyMap ;
2008-10-11 14:16:25 -05:00
}
2010-08-20 12:19:14 +06:00
( * scripts )[ tmp . id ]. insert ( std :: pair < uint32 , ScriptInfo > ( tmp . delay , tmp ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
2010-12-19 17:06:33 +01:00
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u script definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGameObjectScripts ()
{
2010-08-20 12:19:14 +06:00
LoadScripts ( SCRIPTS_GAMEOBJECT );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check ids
2009-10-17 16:20:24 -07:00
for ( ScriptMapMap :: const_iterator itr = sGameObjectScripts . begin (); itr != sGameObjectScripts . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! GetGOData ( itr -> first ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject_scripts` has not existing gameobject (GUID: %u) as script id" , itr -> first );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadQuestEndScripts ()
{
2010-08-20 12:19:14 +06:00
LoadScripts ( SCRIPTS_QUEST_END );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check ids
2009-10-17 16:20:24 -07:00
for ( ScriptMapMap :: const_iterator itr = sQuestEndScripts . begin (); itr != sQuestEndScripts . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! GetQuestTemplate ( itr -> first ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `quest_end_scripts` has not existing quest (Id: %u) as script id" , itr -> first );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadQuestStartScripts ()
{
2010-08-20 12:19:14 +06:00
LoadScripts ( SCRIPTS_QUEST_START );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check ids
2009-10-17 16:20:24 -07:00
for ( ScriptMapMap :: const_iterator itr = sQuestStartScripts . begin (); itr != sQuestStartScripts . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! GetQuestTemplate ( itr -> first ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `quest_start_scripts` has not existing quest (Id: %u) as script id" , itr -> first );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadSpellScripts ()
{
2010-08-20 12:19:14 +06:00
LoadScripts ( SCRIPTS_SPELL );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check ids
2009-10-17 16:20:24 -07:00
for ( ScriptMapMap :: const_iterator itr = sSpellScripts . begin (); itr != sSpellScripts . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-08-20 12:19:14 +06:00
uint32 spellId = uint32 ( itr -> first ) & 0x00FFFFFF ;
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( spellId );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! spellInfo )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `spell_scripts` has not existing spell (Id: %u) as script id" , spellId );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-08-20 12:19:14 +06:00
uint8 i = ( uint8 )(( uint32 ( itr -> first ) >> 24 ) & 0x000000FF );
2008-10-11 14:16:25 -05:00
//check for correct spellEffect
2011-07-26 23:09:28 +02:00
if ( ! spellInfo -> Effects [ i ]. Effect || ( spellInfo -> Effects [ i ]. Effect != SPELL_EFFECT_SCRIPT_EFFECT && spellInfo -> Effects [ i ]. Effect != SPELL_EFFECT_DUMMY ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `spell_scripts` - spell %u effect %u is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY" , spellId , i );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadEventScripts ()
{
2010-08-20 12:19:14 +06:00
LoadScripts ( SCRIPTS_EVENT );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
std :: set < uint32 > evt_scripts ;
// Load all possible script entries from gameobjects
2011-04-28 22:54:30 +02:00
GameObjectTemplateContainer const * gotc = sObjectMgr -> GetGameObjectTemplates ();
for ( GameObjectTemplateContainer :: const_iterator itr = gotc -> begin (); itr != gotc -> end (); ++ itr )
if ( uint32 eventId = itr -> second . GetEventScriptId ())
evt_scripts . insert ( eventId );
2008-10-11 14:16:25 -05:00
// Load all possible script entries from spells
2011-07-26 23:09:28 +02:00
for ( uint32 i = 1 ; i < sSpellMgr -> GetSpellInfoStoreSize (); ++ i )
2011-08-04 15:14:15 +02:00
if ( SpellInfo const * spell = sSpellMgr -> GetSpellInfo ( i ))
2010-09-28 08:21:51 +03:00
for ( uint8 j = 0 ; j < MAX_SPELL_EFFECTS ; ++ j )
2011-07-26 23:09:28 +02:00
if ( spell -> Effects [ j ]. Effect == SPELL_EFFECT_SEND_EVENT )
if ( spell -> Effects [ j ]. MiscValue )
evt_scripts . insert ( spell -> Effects [ j ]. MiscValue );
2010-06-02 18:43:11 +02:00
2011-06-12 02:30:32 +02:00
for ( size_t path_idx = 0 ; path_idx < sTaxiPathNodesByPath . size (); ++ path_idx )
2010-06-23 01:59:32 +02:00
{
2011-06-12 02:30:32 +02:00
for ( size_t node_idx = 0 ; node_idx < sTaxiPathNodesByPath [ path_idx ]. size (); ++ node_idx )
2010-06-23 01:59:32 +02:00
{
TaxiPathNodeEntry const & node = sTaxiPathNodesByPath [ path_idx ][ node_idx ];
if ( node . arrivalEventID )
evt_scripts . insert ( node . arrivalEventID );
if ( node . departureEventID )
evt_scripts . insert ( node . departureEventID );
}
}
2008-10-11 14:16:25 -05:00
// Then check if all scripts are in above list of possible script entries
2009-10-17 16:20:24 -07:00
for ( ScriptMapMap :: const_iterator itr = sEventScripts . begin (); itr != sEventScripts . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
std :: set < uint32 >:: const_iterator itr2 = evt_scripts . find ( itr -> first );
if ( itr2 == evt_scripts . end ())
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `event_scripts` has script (Id: %u) not referring to any gameobject_template type 10 data2 field, type 3 data6 field, type 13 data 2 field or any spell effect %u" ,
2009-06-01 14:56:54 -05:00
itr -> first , SPELL_EFFECT_SEND_EVENT );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-12-09 23:06:16 -06:00
//Load WP Scripts
void ObjectMgr :: LoadWaypointScripts ()
{
2010-08-20 12:19:14 +06:00
LoadScripts ( SCRIPTS_WAYPOINT );
2009-10-17 15:51:44 -07:00
2010-10-25 02:31:19 +02:00
std :: set < uint32 > actionSet ;
2009-10-17 16:20:24 -07:00
for ( ScriptMapMap :: const_iterator itr = sWaypointScripts . begin (); itr != sWaypointScripts . end (); ++ itr )
2010-10-25 02:31:19 +02:00
actionSet . insert ( itr -> first );
QueryResult result = WorldDatabase . PQuery ( "SELECT DISTINCT(`action`) FROM waypoint_data" );
if ( result )
2008-12-09 23:06:16 -06:00
{
2010-12-13 22:37:56 +01:00
do
2010-10-25 02:31:19 +02:00
{
Field * fields = result -> Fetch ();
uint32 action = fields [ 0 ]. GetUInt32 ();
actionSet . erase ( action );
} while ( result -> NextRow ());
2008-12-09 23:06:16 -06:00
}
2010-10-25 02:31:19 +02:00
for ( std :: set < uint32 >:: iterator itr = actionSet . begin (); itr != actionSet . end (); ++ itr )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "There is no waypoint which links to the waypoint script %u" , * itr );
2008-12-09 23:06:16 -06:00
}
2009-10-17 15:51:44 -07:00
2010-07-24 22:41:42 +02:00
void ObjectMgr :: LoadSpellScriptNames ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-07-24 22:41:42 +02:00
mSpellScripts . clear (); // need for reload case
2010-12-19 17:06:33 +01:00
QueryResult result = WorldDatabase . Query ( "SELECT spell_id, ScriptName FROM spell_script_names" );
2010-07-24 22:41:42 +02:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 spell script names. DB table `spell_script_names` is empty!" );
sLog -> outString ();
2010-07-24 22:41:42 +02:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2010-07-24 22:41:42 +02:00
do
{
Field * fields = result -> Fetch ();
int32 spellId = fields [ 0 ]. GetInt32 ();
2010-09-24 22:16:21 +02:00
const char * scriptName = fields [ 1 ]. GetCString ();
2010-07-24 22:41:42 +02:00
bool allRanks = false ;
if ( spellId <= 0 )
{
allRanks = true ;
spellId = - spellId ;
}
2011-07-26 23:09:28 +02:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( spellId );
if ( ! spellInfo )
2010-07-24 22:41:42 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Scriptname:`%s` spell (spell_id:%d) does not exist in `Spell.dbc`." , scriptName , fields [ 0 ]. GetInt32 ());
2010-07-24 22:41:42 +02:00
continue ;
}
if ( allRanks )
{
2010-12-22 21:25:23 +01:00
if ( sSpellMgr -> GetFirstSpellInChain ( spellId ) != uint32 ( spellId ))
2010-07-24 22:41:42 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Scriptname:`%s` spell (spell_id:%d) is not first rank of spell." , scriptName , fields [ 0 ]. GetInt32 ());
2010-07-24 22:41:42 +02:00
continue ;
}
2011-07-26 23:09:28 +02:00
while ( spellInfo )
2010-07-24 22:41:42 +02:00
{
2011-07-26 23:09:28 +02:00
mSpellScripts . insert ( SpellScriptsMap :: value_type ( spellInfo -> Id , GetScriptId ( scriptName )));
spellInfo = sSpellMgr -> GetSpellInfo ( spellInfo -> Id ) -> GetNextRankSpell ();
2010-07-24 22:41:42 +02:00
}
}
else
2011-07-26 23:09:28 +02:00
mSpellScripts . insert ( SpellScriptsMap :: value_type ( spellInfo -> Id , GetScriptId ( scriptName )));
2010-12-19 17:06:33 +01:00
++ count ;
}
while ( result -> NextRow ());
2010-07-24 22:41:42 +02:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u spell script names in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-07-24 22:41:42 +02:00
}
void ObjectMgr :: ValidateSpellScripts ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-07-24 22:41:42 +02:00
if ( mSpellScripts . empty ())
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Validated 0 scripts." );
sLog -> outString ();
2010-07-24 22:41:42 +02:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2010-07-24 22:41:42 +02:00
for ( SpellScriptsMap :: iterator itr = mSpellScripts . begin (); itr != mSpellScripts . end ();)
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellEntry = sSpellMgr -> GetSpellInfo ( itr -> first );
2010-08-24 00:10:49 +02:00
std :: vector < std :: pair < SpellScriptLoader * , SpellScriptsMap :: iterator > > SpellScriptLoaders ;
2010-12-22 21:25:23 +01:00
sScriptMgr -> CreateSpellScriptLoaders ( itr -> first , SpellScriptLoaders );
2010-07-24 22:41:42 +02:00
itr = mSpellScripts . upper_bound ( itr -> first );
2010-08-24 00:10:49 +02:00
for ( std :: vector < std :: pair < SpellScriptLoader * , SpellScriptsMap :: iterator > >:: iterator sitr = SpellScriptLoaders . begin (); sitr != SpellScriptLoaders . end (); ++ sitr )
2010-07-24 22:41:42 +02:00
{
2010-08-24 00:10:49 +02:00
SpellScript * spellScript = sitr -> first -> GetSpellScript ();
AuraScript * auraScript = sitr -> first -> GetAuraScript ();
bool valid = true ;
if ( ! spellScript && ! auraScript )
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "TSCR: Functions GetSpellScript() and GetAuraScript() of script `%s` do not return objects - script skipped" , GetScriptName ( sitr -> second -> second ));
2010-08-24 00:10:49 +02:00
valid = false ;
}
if ( spellScript )
{
2010-10-04 17:44:49 +02:00
spellScript -> _Init ( & sitr -> first -> GetName (), spellEntry -> Id );
spellScript -> _Register ();
if ( ! spellScript -> _Validate ( spellEntry ))
2010-08-24 00:10:49 +02:00
valid = false ;
delete spellScript ;
}
if ( auraScript )
{
2010-10-04 17:44:49 +02:00
auraScript -> _Init ( & sitr -> first -> GetName (), spellEntry -> Id );
auraScript -> _Register ();
if ( ! auraScript -> _Validate ( spellEntry ))
2010-08-24 00:10:49 +02:00
valid = false ;
delete auraScript ;
}
if ( ! valid )
2010-12-19 17:06:33 +01:00
{
2010-07-24 22:41:42 +02:00
mSpellScripts . erase ( sitr -> second );
2010-12-19 17:06:33 +01:00
}
2010-07-24 22:41:42 +02:00
}
2010-12-19 17:06:33 +01:00
++ count ;
2010-07-24 22:41:42 +02:00
}
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Validated %u scripts in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-07-24 22:41:42 +02:00
}
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadPageTexts ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-28 22:13:09 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, text, next_page FROM page_text" );
2009-10-17 15:51:44 -07:00
2011-04-28 22:13:09 +02:00
if ( ! result )
{
sLog -> outString ( ">> Loaded 0 page texts. DB table `page_text` is empty!" );
sLog -> outString ();
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:13:09 +02:00
uint32 count = 0 ;
do
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:13:09 +02:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2011-04-29 19:59:40 +02:00
PageText & pageText = PageTextStore [ fields [ 0 ]. GetUInt32 ()];
2011-04-28 22:13:09 +02:00
pageText . Text = fields [ 1 ]. GetString ();
pageText . NextPage = fields [ 2 ]. GetInt16 ();
++ count ;
}
while ( result -> NextRow ());
for ( PageTextContainer :: const_iterator itr = PageTextStore . begin (); itr != PageTextStore . end (); ++ itr )
{
if ( itr -> second . NextPage )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:13:09 +02:00
PageTextContainer :: const_iterator itr2 = PageTextStore . find ( itr -> second . NextPage );
if ( itr2 == PageTextStore . end ())
sLog -> outErrorDb ( "Page text (Id: %u) has not existing next page (Id: %u)" , itr -> first , itr -> second . NextPage );
2008-10-11 14:16:25 -05:00
}
}
2010-12-19 17:06:33 +01:00
2011-04-28 22:13:09 +02:00
sLog -> outString ( ">> Loaded %u page texts in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:13:09 +02:00
PageText const * ObjectMgr :: GetPageText ( uint32 pageEntry )
{
PageTextContainer :: const_iterator itr = PageTextStore . find ( pageEntry );
if ( itr != PageTextStore . end ())
return & ( itr -> second );
return NULL ;
}
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadPageTextLocales ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
mPageTextLocaleMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8 FROM locales_page_text" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
PageTextLocale & data = mPageTextLocaleMap [ entry ];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ i ]. GetString (), LocaleConstant ( i ), data . Text );
2008-10-11 14:16:25 -05:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu PageText locale strings in %u ms" , ( unsigned long ) mPageTextLocaleMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadInstanceTemplate ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-28 22:16:13 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT map, parent, script, allowMount FROM instance_template" );
2009-10-17 15:51:44 -07:00
2011-04-28 22:16:13 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:16:13 +02:00
sLog -> outString ( ">> Loaded 0 instance templates. DB table `page_text` is empty!" );
sLog -> outString ();
return ;
}
uint32 count = 0 ;
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2011-04-28 22:16:13 +02:00
uint16 mapID = fields [ 0 ]. GetUInt16 ();
2009-12-17 14:06:20 +01:00
2011-04-28 22:16:13 +02:00
if ( ! MapManager :: IsValidMAP ( mapID , true ))
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:16:13 +02:00
sLog -> outErrorDb ( "ObjectMgr::LoadInstanceTemplate: bad mapid %d for template!" , mapID );
continue ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:16:13 +02:00
InstanceTemplate instanceTemplate ;
instanceTemplate . AllowMount = fields [ 3 ]. GetBool ();
2011-04-29 09:28:10 +02:00
instanceTemplate . Parent = uint32 ( fields [ 1 ]. GetUInt16 ());
instanceTemplate . ScriptId = sObjectMgr -> GetScriptId ( fields [ 2 ]. GetCString ());
2011-04-28 22:16:13 +02:00
InstanceTemplateStore [ mapID ] = instanceTemplate ;
++ count ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:16:13 +02:00
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2011-04-28 22:16:13 +02:00
sLog -> outString ( ">> Loaded %u instance templates in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:16:13 +02:00
InstanceTemplate const * ObjectMgr :: GetInstanceTemplate ( uint32 mapID )
{
InstanceTemplateContainer :: const_iterator itr = InstanceTemplateStore . find ( uint16 ( mapID ));
if ( itr != InstanceTemplateStore . end ())
return & ( itr -> second );
return NULL ;
}
2011-02-03 22:20:40 +01:00
void ObjectMgr :: LoadInstanceEncounters ()
{
uint32 oldMSTime = getMSTime ();
QueryResult result = WorldDatabase . Query ( "SELECT entry, creditType, creditEntry, lastEncounterDungeon FROM instance_encounters" );
if ( ! result )
{
sLog -> outErrorDb ( ">> Loaded 0 instance encounters, table is empty!" );
sLog -> outString ();
return ;
}
uint32 count = 0 ;
std :: map < uint32 , DungeonEncounterEntry const *> dungeonLastBosses ;
do
{
Field * fields = result -> Fetch ();
uint32 entry = fields [ 0 ]. GetUInt32 ();
2011-02-09 16:28:56 +01:00
uint8 creditType = fields [ 1 ]. GetUInt8 ();
uint32 creditEntry = fields [ 2 ]. GetUInt32 ();
uint32 lastEncounterDungeon = fields [ 3 ]. GetUInt32 ();
2011-02-03 22:20:40 +01:00
DungeonEncounterEntry const * dungeonEncounter = sDungeonEncounterStore . LookupEntry ( entry );
if ( ! dungeonEncounter )
{
sLog -> outErrorDb ( "Table `instance_encounters` has an invalid encounter id %u, skipped!" , entry );
continue ;
}
2011-02-09 16:28:56 +01:00
if ( lastEncounterDungeon && ! sLFGDungeonStore . LookupEntry ( lastEncounterDungeon ))
{
sLog -> outErrorDb ( "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!" , entry , dungeonEncounter -> encounterName [ 0 ], lastEncounterDungeon );
continue ;
}
std :: map < uint32 , DungeonEncounterEntry const *>:: const_iterator itr = dungeonLastBosses . find ( lastEncounterDungeon );
if ( lastEncounterDungeon )
{
if ( itr != dungeonLastBosses . end ())
{
sLog -> outErrorDb ( "Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!" , entry , dungeonEncounter -> encounterName [ 0 ], itr -> second -> id , itr -> second -> encounterName [ 0 ]);
continue ;
}
dungeonLastBosses [ lastEncounterDungeon ] = dungeonEncounter ;
}
2011-02-03 22:20:40 +01:00
switch ( creditType )
{
case ENCOUNTER_CREDIT_KILL_CREATURE :
2011-02-09 16:28:56 +01:00
{
2011-04-28 22:57:08 +02:00
CreatureTemplate const * creatureInfo = GetCreatureTemplate ( creditEntry );
2011-02-09 16:28:56 +01:00
if ( ! creatureInfo )
2011-02-03 22:20:40 +01:00
{
sLog -> outErrorDb ( "Table `instance_encounters` has an invalid creature (entry %u) linked to the encounter %u (%s), skipped!" , creditEntry , entry , dungeonEncounter -> encounterName [ 0 ]);
continue ;
}
2011-04-28 22:57:08 +02:00
const_cast < CreatureTemplate *> ( creatureInfo ) -> flags_extra |= CREATURE_FLAG_EXTRA_DUNGEON_BOSS ;
2011-02-12 10:40:07 +01:00
break ;
2011-02-09 16:28:56 +01:00
}
2011-02-03 22:20:40 +01:00
case ENCOUNTER_CREDIT_CAST_SPELL :
2011-07-26 23:09:28 +02:00
if ( ! sSpellMgr -> GetSpellInfo ( creditEntry ))
2011-02-03 22:20:40 +01:00
{
sLog -> outErrorDb ( "Table `instance_encounters` has an invalid spell (entry %u) linked to the encounter %u (%s), skipped!" , creditEntry , entry , dungeonEncounter -> encounterName [ 0 ]);
continue ;
}
break ;
default :
sLog -> outErrorDb ( "Table `instance_encounters` has an invalid credit type (%u) for encounter %u (%s), skipped!" , creditType , entry , dungeonEncounter -> encounterName [ 0 ]);
continue ;
}
DungeonEncounterList & encounters = mDungeonEncounters [ MAKE_PAIR32 ( dungeonEncounter -> mapId , dungeonEncounter -> difficulty )];
encounters . push_back ( new DungeonEncounter ( dungeonEncounter , EncounterCreditType ( creditType ), creditEntry , lastEncounterDungeon ));
++ count ;
} while ( result -> NextRow ());
sLog -> outString ( ">> Loaded %u instance encounters in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
}
2009-02-16 20:12:55 -06:00
GossipText const * ObjectMgr :: GetGossipText ( uint32 Text_ID ) const
2008-10-11 14:16:25 -05:00
{
2009-02-16 20:12:55 -06:00
GossipTextMap :: const_iterator itr = mGossipText . find ( Text_ID );
2010-04-07 19:14:10 +02:00
if ( itr != mGossipText . end ())
2009-02-16 20:12:55 -06:00
return & itr -> second ;
2008-10-11 14:16:25 -05:00
return NULL ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGossipText ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT * FROM npc_text" );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int count = 0 ;
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u npc texts" , count );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int cic ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
++ count ;
cic = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-02-16 20:12:55 -06:00
uint32 Text_ID = fields [ cic ++ ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( ! Text_ID )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `npc_text` has record wit reserved id 0, ignore." );
2009-02-16 20:12:55 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-02-16 20:12:55 -06:00
GossipText & gText = mGossipText [ Text_ID ];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( int i = 0 ; i < MAX_GOSSIP_TEXT_OPTIONS ; i ++ )
2009-02-16 20:12:55 -06:00
{
2010-09-24 22:16:21 +02:00
gText . Options [ i ]. Text_0 = fields [ cic ++ ]. GetString ();
gText . Options [ i ]. Text_1 = fields [ cic ++ ]. GetString ();
2009-10-17 15:51:44 -07:00
2009-02-16 20:12:55 -06:00
gText . Options [ i ]. Language = fields [ cic ++ ]. GetUInt32 ();
gText . Options [ i ]. Probability = fields [ cic ++ ]. GetFloat ();
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 j = 0 ; j < MAX_GOSSIP_TEXT_EMOTES ; ++ j )
2009-02-16 20:12:55 -06:00
{
gText . Options [ i ]. Emotes [ j ]. _Delay = fields [ cic ++ ]. GetUInt32 ();
gText . Options [ i ]. Emotes [ j ]. _Emote = fields [ cic ++ ]. GetUInt32 ();
}
2008-10-11 14:16:25 -05:00
}
2010-04-07 22:59:46 +02:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u npc texts in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadNpcTextLocales ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
mNpcTextLocaleMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, "
"Text0_0_loc1, Text0_1_loc1, Text1_0_loc1, Text1_1_loc1, Text2_0_loc1, Text2_1_loc1, Text3_0_loc1, Text3_1_loc1, Text4_0_loc1, Text4_1_loc1, Text5_0_loc1, Text5_1_loc1, Text6_0_loc1, Text6_1_loc1, Text7_0_loc1, Text7_1_loc1, "
"Text0_0_loc2, Text0_1_loc2, Text1_0_loc2, Text1_1_loc2, Text2_0_loc2, Text2_1_loc2, Text3_0_loc2, Text3_1_loc1, Text4_0_loc2, Text4_1_loc2, Text5_0_loc2, Text5_1_loc2, Text6_0_loc2, Text6_1_loc2, Text7_0_loc2, Text7_1_loc2, "
"Text0_0_loc3, Text0_1_loc3, Text1_0_loc3, Text1_1_loc3, Text2_0_loc3, Text2_1_loc3, Text3_0_loc3, Text3_1_loc1, Text4_0_loc3, Text4_1_loc3, Text5_0_loc3, Text5_1_loc3, Text6_0_loc3, Text6_1_loc3, Text7_0_loc3, Text7_1_loc3, "
"Text0_0_loc4, Text0_1_loc4, Text1_0_loc4, Text1_1_loc4, Text2_0_loc4, Text2_1_loc4, Text3_0_loc4, Text3_1_loc1, Text4_0_loc4, Text4_1_loc4, Text5_0_loc4, Text5_1_loc4, Text6_0_loc4, Text6_1_loc4, Text7_0_loc4, Text7_1_loc4, "
"Text0_0_loc5, Text0_1_loc5, Text1_0_loc5, Text1_1_loc5, Text2_0_loc5, Text2_1_loc5, Text3_0_loc5, Text3_1_loc1, Text4_0_loc5, Text4_1_loc5, Text5_0_loc5, Text5_1_loc5, Text6_0_loc5, Text6_1_loc5, Text7_0_loc5, Text7_1_loc5, "
"Text0_0_loc6, Text0_1_loc6, Text1_0_loc6, Text1_1_loc6, Text2_0_loc6, Text2_1_loc6, Text3_0_loc6, Text3_1_loc1, Text4_0_loc6, Text4_1_loc6, Text5_0_loc6, Text5_1_loc6, Text6_0_loc6, Text6_1_loc6, Text7_0_loc6, Text7_1_loc6, "
"Text0_0_loc7, Text0_1_loc7, Text1_0_loc7, Text1_1_loc7, Text2_0_loc7, Text2_1_loc7, Text3_0_loc7, Text3_1_loc1, Text4_0_loc7, Text4_1_loc7, Text5_0_loc7, Text5_1_loc7, Text6_0_loc7, Text6_1_loc7, Text7_0_loc7, Text7_1_loc7, "
"Text0_0_loc8, Text0_1_loc8, Text1_0_loc8, Text1_1_loc8, Text2_0_loc8, Text2_1_loc8, Text3_0_loc8, Text3_1_loc1, Text4_0_loc8, Text4_1_loc8, Text5_0_loc8, Text5_1_loc8, Text6_0_loc8, Text6_1_loc8, Text7_0_loc8, Text7_1_loc8 "
2008-10-11 14:16:25 -05:00
" FROM locales_npc_text" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
NpcTextLocale & data = mNpcTextLocaleMap [ entry ];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-08-26 15:54:56 +06:00
LocaleConstant locale = ( LocaleConstant ) i ;
2010-09-28 08:21:51 +03:00
for ( uint8 j = 0 ; j < MAX_LOCALES ; ++ j )
2008-10-11 14:16:25 -05:00
{
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ 1 + 8 * 2 * ( i - 1 ) + 2 * j ]. GetString (), locale , data . Text_0 [ j ]);
AddLocaleString ( fields [ 1 + 8 * 2 * ( i - 1 ) + 2 * j + 1 ]. GetString (), locale , data . Text_1 [ j ]);
2008-10-11 14:16:25 -05:00
}
}
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu NpcText locale strings in %u ms" , ( unsigned long ) mNpcTextLocaleMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
//not very fast function but it is called only once a day, or on starting-up
void ObjectMgr :: ReturnOrDeleteOldMails ( bool serverUp )
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-12-15 14:08:12 +06:00
time_t curTime = time ( NULL );
tm * lt = localtime ( & curTime );
uint64 basetime ( curTime );
2011-02-20 20:16:34 +01:00
sLog -> outDetail ( "Returning mails current time: hour: %d, minute: %d, second: %d " , lt -> tm_hour , lt -> tm_min , lt -> tm_sec );
2010-12-15 14:08:12 +06:00
// Delete all old mails without item and without body immediately, if starting server
2008-10-11 14:16:25 -05:00
if ( ! serverUp )
2010-12-15 14:08:12 +06:00
{
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_EMPTY_EXPIRED_MAIL );
stmt -> setUInt64 ( 0 , basetime );
CharacterDatabase . Execute ( stmt );
}
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_GET_EXPIRED_MAIL );
stmt -> setUInt64 ( 0 , basetime );
PreparedQueryResult result = CharacterDatabase . Query ( stmt );
2010-04-07 22:59:46 +02:00
if ( ! result )
2009-01-22 22:44:27 -06:00
{
2011-06-08 18:55:21 +02:00
sLog -> outString ( ">> No expired mails found." );
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ; // any mails need to be returned or deleted
2009-01-22 22:44:27 -06:00
}
2009-10-17 15:51:44 -07:00
2011-06-08 18:55:21 +02:00
std :: map < uint32 /*messageId*/ , MailItemInfoVec > itemsCache ;
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_GET_EXPIRED_MAIL_ITEMS );
stmt -> setUInt64 ( 0 , basetime );
if ( PreparedQueryResult items = CharacterDatabase . Query ( stmt ))
{
MailItemInfo item ;
do
{
Field * fields = items -> Fetch ();
item . item_guid = fields [ 0 ]. GetUInt32 ();
item . item_template = fields [ 1 ]. GetUInt32 ();
uint32 mailId = fields [ 2 ]. GetUInt32 ();
itemsCache [ mailId ]. push_back ( item );
} while ( items -> NextRow ());
}
uint32 deletedCount = 0 ;
uint32 returnedCount = 0 ;
2008-10-11 14:16:25 -05:00
do
{
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
Field * fields = result -> Fetch ();
2008-10-11 14:16:25 -05:00
Mail * m = new Mail ;
m -> messageID = fields [ 0 ]. GetUInt32 ();
m -> messageType = fields [ 1 ]. GetUInt8 ();
m -> sender = fields [ 2 ]. GetUInt32 ();
m -> receiver = fields [ 3 ]. GetUInt32 ();
2010-04-11 11:16:42 +04:00
bool has_items = fields [ 4 ]. GetBool ();
2011-01-20 02:11:49 +01:00
m -> expire_time = time_t ( fields [ 5 ]. GetUInt32 ());
2008-10-11 14:16:25 -05:00
m -> deliver_time = 0 ;
2010-04-11 11:16:42 +04:00
m -> COD = fields [ 6 ]. GetUInt32 ();
m -> checked = fields [ 7 ]. GetUInt32 ();
m -> mailTemplateId = fields [ 8 ]. GetInt16 ();
2009-10-17 15:51:44 -07:00
2010-09-18 19:49:17 -07:00
Player * pl = NULL ;
2008-10-11 14:16:25 -05:00
if ( serverUp )
2011-07-27 12:14:27 +02:00
pl = ObjectAccessor :: FindPlayer (( uint64 ) m -> receiver );
2010-09-18 19:49:17 -07:00
2008-10-11 14:16:25 -05:00
if ( pl && pl -> m_mailsLoaded )
2010-12-15 14:08:12 +06:00
{ // this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail
// his in mailbox and he has already listed his mails)
2008-10-11 14:16:25 -05:00
delete m ;
continue ;
}
2010-09-18 19:49:17 -07:00
2010-12-15 14:08:12 +06:00
// Delete or return mail
2008-10-11 14:16:25 -05:00
if ( has_items )
{
2011-06-08 18:55:21 +02:00
// read items from cache
m -> items . swap ( itemsCache [ m -> messageID ]);
2009-10-17 15:51:44 -07:00
2010-12-15 14:08:12 +06:00
// if it is mail from non-player, or if it's already return mail, it shouldn't be returned, but deleted
if ( m -> messageType != MAIL_NORMAL || ( m -> checked & ( MAIL_CHECK_MASK_COD_PAYMENT | MAIL_CHECK_MASK_RETURNED )))
2008-10-11 14:16:25 -05:00
{
// mail open and then not returned
2010-12-15 14:08:12 +06:00
for ( MailItemInfoVec :: iterator itr2 = m -> items . begin (); itr2 != m -> items . end (); ++ itr2 )
2010-09-21 21:55:16 +02:00
{
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_ITEM_INSTANCE );
stmt -> setUInt32 ( 0 , itr2 -> item_guid );
CharacterDatabase . Execute ( stmt );
}
2008-10-11 14:16:25 -05:00
}
else
{
2010-12-15 14:08:12 +06:00
// Mail will be returned
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_SET_MAIL_RETURNED );
stmt -> setUInt32 ( 0 , m -> receiver );
stmt -> setUInt32 ( 1 , m -> sender );
stmt -> setUInt64 ( 2 , basetime + 30 * DAY );
stmt -> setUInt64 ( 3 , basetime );
stmt -> setUInt8 ( 4 , uint8 ( MAIL_CHECK_MASK_RETURNED ));
stmt -> setUInt32 ( 5 , m -> messageID );
CharacterDatabase . Execute ( stmt );
for ( MailItemInfoVec :: iterator itr2 = m -> items . begin (); itr2 != m -> items . end (); ++ itr2 )
{
// Update receiver in mail items for its proper delivery, and in instance_item for avoid lost item at sender delete
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_SET_MAIL_ITEM_RECEIVER );
stmt -> setUInt32 ( 0 , m -> sender );
stmt -> setUInt32 ( 1 , itr2 -> item_guid );
CharacterDatabase . Execute ( stmt );
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_SET_ITEM_OWNER );
stmt -> setUInt32 ( 0 , m -> sender );
stmt -> setUInt32 ( 1 , itr2 -> item_guid );
CharacterDatabase . Execute ( stmt );
}
2008-10-11 14:16:25 -05:00
delete m ;
2011-06-08 18:55:21 +02:00
++ returnedCount ;
2008-10-11 14:16:25 -05:00
continue ;
}
}
2009-10-17 15:51:44 -07:00
2010-12-15 14:08:12 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_MAIL );
stmt -> setUInt32 ( 0 , m -> messageID );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
delete m ;
2011-06-08 18:55:21 +02:00
++ deletedCount ;
2010-12-19 17:06:33 +01:00
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2011-06-08 18:55:21 +02:00
sLog -> outString ( ">> Processed %u expired mails: %u deleted and %u returned in %u ms" , deletedCount + returnedCount , deletedCount , returnedCount , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadQuestAreaTriggers ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
mQuestAreaTriggerMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT id, quest FROM areatrigger_involvedrelation" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 quest trigger points. DB table `areatrigger_involvedrelation` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 trigger_ID = fields [ 0 ]. GetUInt32 ();
uint32 quest_ID = fields [ 1 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTriggerEntry const * atEntry = sAreaTriggerStore . LookupEntry ( trigger_ID );
2010-04-07 19:14:10 +02:00
if ( ! atEntry )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`." , trigger_ID );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Quest const * quest = GetQuestTemplate ( quest_ID );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! quest )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `areatrigger_involvedrelation` has record (id: %u) for not existing quest %u" , trigger_ID , quest_ID );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! quest -> HasFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `areatrigger_involvedrelation` has record (id: %u) for not quest %u, but quest not have flag QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT. Trigger or quest flags must be fixed, quest modified to require objective." , trigger_ID , quest_ID );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// this will prevent quest completing without objective
2008-10-14 11:57:03 -05:00
const_cast < Quest *> ( quest ) -> SetFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT );
2009-10-17 15:51:44 -07:00
2008-11-14 16:28:45 -06:00
// continue; - quest modified to required objective and trigger can be allowed.
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
mQuestAreaTriggerMap [ trigger_ID ] = quest_ID ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u quest trigger points in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadTavernAreaTriggers ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
mTavernAreaTriggerSet . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT id FROM areatrigger_tavern" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 tavern triggers. DB table `areatrigger_tavern` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Trigger_ID = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTriggerEntry const * atEntry = sAreaTriggerStore . LookupEntry ( Trigger_ID );
2010-04-07 19:14:10 +02:00
if ( ! atEntry )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`." , Trigger_ID );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
mTavernAreaTriggerSet . insert ( Trigger_ID );
2010-04-07 22:59:46 +02:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u tavern triggers in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadAreaTriggerScripts ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
mAreaTriggerScripts . clear (); // need for reload case
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, ScriptName FROM areatrigger_scripts" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 areatrigger scripts. DB table `areatrigger_scripts` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Trigger_ID = fields [ 0 ]. GetUInt32 ();
2010-09-24 22:16:21 +02:00
const char * scriptName = fields [ 1 ]. GetCString ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTriggerEntry const * atEntry = sAreaTriggerStore . LookupEntry ( Trigger_ID );
2010-04-07 19:14:10 +02:00
if ( ! atEntry )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`." , Trigger_ID );
2008-10-11 14:16:25 -05:00
continue ;
}
2008-11-20 16:16:57 -06:00
mAreaTriggerScripts [ Trigger_ID ] = GetScriptId ( scriptName );
2010-04-07 22:59:46 +02:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u areatrigger scripts in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint32 ObjectMgr :: GetNearestTaxiNode ( float x , float y , float z , uint32 mapid , uint32 team )
2008-10-11 14:16:25 -05:00
{
bool found = false ;
2010-04-19 17:03:10 +02:00
float dist = 10000 ;
2008-10-11 14:16:25 -05:00
uint32 id = 0 ;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( uint32 i = 1 ; i < sTaxiNodesStore . GetNumRows (); ++ i )
2008-10-11 14:16:25 -05:00
{
TaxiNodesEntry const * node = sTaxiNodesStore . LookupEntry ( i );
2009-12-17 14:55:19 +01:00
2010-08-21 21:54:41 +02:00
if ( ! node || node -> map_id != mapid || ( ! node -> MountCreatureID [ team == ALLIANCE ? 1 : 0 ] && node -> MountCreatureID [ 0 ] != 32981 )) // dk flight
2009-01-22 22:44:27 -06:00
continue ;
2009-10-17 15:51:44 -07:00
2009-01-22 22:44:27 -06:00
uint8 field = ( uint8 )(( i - 1 ) / 32 );
uint32 submask = 1 << (( i - 1 ) % 32 );
2009-10-17 15:51:44 -07:00
2009-01-22 22:44:27 -06:00
// skip not taxi network nodes
2010-04-07 23:25:02 +02:00
if (( sTaxiNodesMask [ field ] & submask ) == 0 )
2009-01-22 22:44:27 -06:00
continue ;
2009-10-17 15:51:44 -07:00
2009-12-18 13:41:30 -08:00
float dist2 = ( node -> x - x ) * ( node -> x - x ) + ( node -> y - y ) * ( node -> y - y ) + ( node -> z - z ) * ( node -> z - z );
2010-04-07 19:14:10 +02:00
if ( found )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( dist2 < dist )
2008-10-11 14:16:25 -05:00
{
dist = dist2 ;
id = i ;
}
}
2009-01-22 22:44:27 -06:00
else
{
found = true ;
dist = dist2 ;
id = i ;
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return id ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
void ObjectMgr :: GetTaxiPath ( uint32 source , uint32 destination , uint32 & path , uint32 & cost )
2008-10-11 14:16:25 -05:00
{
TaxiPathSetBySource :: iterator src_i = sTaxiPathSetBySource . find ( source );
2010-04-07 23:25:02 +02:00
if ( src_i == sTaxiPathSetBySource . end ())
2008-10-11 14:16:25 -05:00
{
path = 0 ;
cost = 0 ;
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
TaxiPathSetForSource & pathSet = src_i -> second ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
TaxiPathSetForSource :: iterator dest_i = pathSet . find ( destination );
2010-04-07 23:25:02 +02:00
if ( dest_i == pathSet . end ())
2008-10-11 14:16:25 -05:00
{
path = 0 ;
cost = 0 ;
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
cost = dest_i -> second . price ;
path = dest_i -> second . ID ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint32 ObjectMgr :: GetTaxiMountDisplayId ( uint32 id , uint32 team , bool allowed_alt_team /* = false */ )
2008-10-11 14:16:25 -05:00
{
2009-09-21 07:52:16 +02:00
uint32 mount_id = 0 ;
2009-10-17 15:51:44 -07:00
2009-06-15 18:02:12 -05:00
// select mount creature id
2008-10-11 14:16:25 -05:00
TaxiNodesEntry const * node = sTaxiNodesStore . LookupEntry ( id );
2010-04-07 19:14:10 +02:00
if ( node )
2008-10-11 14:16:25 -05:00
{
2010-12-06 02:07:53 +01:00
uint32 mount_entry = 0 ;
2008-12-24 09:58:26 -06:00
if ( team == ALLIANCE )
mount_entry = node -> MountCreatureID [ 1 ];
2009-09-21 07:52:16 +02:00
else
2008-12-24 09:58:26 -06:00
mount_entry = node -> MountCreatureID [ 0 ];
2009-10-17 15:51:44 -07:00
2009-11-17 20:26:35 -08:00
// Fix for Alliance not being able to use Acherus taxi
// only one mount type for both sides
if ( mount_entry == 0 && allowed_alt_team )
{
// Simply reverse the selection. At least one team in theory should have a valid mount ID to choose.
mount_entry = team == ALLIANCE ? node -> MountCreatureID [ 0 ] : node -> MountCreatureID [ 1 ];
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:57:08 +02:00
CreatureTemplate const * mount_info = GetCreatureTemplate ( mount_entry );
2009-09-21 07:52:16 +02:00
if ( mount_info )
{
2010-04-19 17:03:10 +02:00
mount_id = mount_info -> GetRandomValidModelId ();
if ( ! mount_id )
2009-09-21 07:52:16 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "No displayid found for the taxi mount with the entry %u! Can't load it!" , mount_entry );
2009-09-21 07:52:16 +02:00
return false ;
}
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:11:45 +02:00
// minfo is not actually used but the mount_id was updated
2011-05-07 20:09:45 +02:00
sObjectMgr -> GetCreatureModelRandomGender ( & mount_id );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return mount_id ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGraveyardZones ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
mGraveYardMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT id, ghost_zone, faction FROM game_graveyard_zone" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 graveyard-zone links. DB table `game_graveyard_zone` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 safeLocId = fields [ 0 ]. GetUInt32 ();
uint32 zoneId = fields [ 1 ]. GetUInt32 ();
uint32 team = fields [ 2 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldSafeLocsEntry const * entry = sWorldSafeLocsStore . LookupEntry ( safeLocId );
2010-04-07 19:14:10 +02:00
if ( ! entry )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `game_graveyard_zone` has a record for not existing graveyard (WorldSafeLocs.dbc id) %u, skipped." , safeLocId );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTableEntry const * areaEntry = GetAreaEntryByAreaID ( zoneId );
2010-04-07 19:14:10 +02:00
if ( ! areaEntry )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `game_graveyard_zone` has a record for not existing zone id (%u), skipped." , zoneId );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( areaEntry -> zone != 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `game_graveyard_zone` has a record for subzone id (%u) instead of zone, skipped." , zoneId );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-04-08 08:20:08 +02:00
if ( team != 0 && team != HORDE && team != ALLIANCE )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `game_graveyard_zone` has a record for non player faction (%u), skipped." , team );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( ! AddGraveYardLink ( safeLocId , zoneId , team , false ))
sLog -> outErrorDb ( "Table `game_graveyard_zone` has a duplicate record for Graveyard (ID: %u) and Zone (ID: %u), skipped." , safeLocId , zoneId );
2010-04-07 22:59:46 +02:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u graveyard-zone links in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-08-06 17:23:33 +01:00
WorldSafeLocsEntry const * ObjectMgr :: GetDefaultGraveYard ( uint32 team )
{
enum DefaultGraveyard
{
HORDE_GRAVEYARD = 10 , // Crossroads
ALLIANCE_GRAVEYARD = 4 , // Westfall
};
if ( team == HORDE )
return sWorldSafeLocsStore . LookupEntry ( HORDE_GRAVEYARD );
else if ( team == ALLIANCE )
return sWorldSafeLocsStore . LookupEntry ( ALLIANCE_GRAVEYARD );
else return NULL ;
}
2008-10-11 14:16:25 -05:00
WorldSafeLocsEntry const * ObjectMgr :: GetClosestGraveYard ( float x , float y , float z , uint32 MapId , uint32 team )
{
// search for zone associated closest graveyard
2011-04-29 20:47:02 +02:00
uint32 zoneId = sMapMgr -> GetZoneId ( MapId , x , y , z );
2009-10-17 15:51:44 -07:00
2010-10-25 11:47:23 +02:00
if ( ! zoneId )
{
if ( z > - 500 )
2011-08-06 17:23:33 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "ZoneId not found for map %u coords (%f, %f, %f)" , MapId , x , y , z );
2011-08-06 17:23:33 +01:00
return GetDefaultGraveYard ( team );
}
2010-10-25 11:47:23 +02:00
}
2010-10-25 11:28:42 +02:00
2008-10-11 14:16:25 -05:00
// Simulate std. algorithm:
2011-04-29 20:47:02 +02:00
// found some graveyard associated to (ghost_zone, ghost_map)
2008-10-11 14:16:25 -05:00
//
// if mapId == graveyard.mapId (ghost in plain zone or city or battleground) and search graveyard at same map
// then check faction
// if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated
2008-11-14 17:03:03 -06:00
// then check faction
2008-10-11 14:16:25 -05:00
GraveYardMap :: const_iterator graveLow = mGraveYardMap . lower_bound ( zoneId );
GraveYardMap :: const_iterator graveUp = mGraveYardMap . upper_bound ( zoneId );
2009-03-18 21:18:45 +01:00
MapEntry const * map = sMapStore . LookupEntry ( MapId );
// not need to check validity of map object; MapId _MUST_ be valid here
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( graveLow == graveUp && ! map -> IsBattleArena ())
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard." , zoneId , team );
2011-08-06 17:23:33 +01:00
return GetDefaultGraveYard ( team );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-14 17:03:03 -06:00
// at corpse map
2008-10-11 14:16:25 -05:00
bool foundNear = false ;
2010-04-19 17:03:10 +02:00
float distNear = 10000 ;
2008-10-11 14:16:25 -05:00
WorldSafeLocsEntry const * entryNear = NULL ;
2009-10-17 15:51:44 -07:00
2008-11-14 17:03:03 -06:00
// at entrance map for corpse map
bool foundEntr = false ;
2010-04-19 17:03:10 +02:00
float distEntr = 10000 ;
2008-11-14 17:03:03 -06:00
WorldSafeLocsEntry const * entryEntr = NULL ;
2009-10-17 15:51:44 -07:00
2008-11-14 17:03:03 -06:00
// some where other
2008-10-11 14:16:25 -05:00
WorldSafeLocsEntry const * entryFar = NULL ;
2009-10-17 15:51:44 -07:00
2008-11-14 17:03:03 -06:00
MapEntry const * mapEntry = sMapStore . LookupEntry ( MapId );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( GraveYardMap :: const_iterator itr = graveLow ; itr != graveUp ; ++ itr )
2008-10-11 14:16:25 -05:00
{
GraveYardData const & data = itr -> second ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldSafeLocsEntry const * entry = sWorldSafeLocsStore . LookupEntry ( data . safeLocId );
2010-04-07 19:14:10 +02:00
if ( ! entry )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `game_graveyard_zone` has record for not existing graveyard (WorldSafeLocs.dbc id) %u, skipped." , data . safeLocId );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-11-14 17:03:03 -06:00
// skip enemy faction graveyard
2008-10-11 14:16:25 -05:00
// team == 0 case can be at call from .neargrave
2010-04-07 19:14:10 +02:00
if ( data . team != 0 && team != 0 && data . team != team )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2008-11-14 17:03:03 -06:00
// find now nearest graveyard at other map
2010-04-07 19:14:10 +02:00
if ( MapId != entry -> map_id )
2008-10-11 14:16:25 -05:00
{
2008-11-14 17:03:03 -06:00
// if find graveyard at different map from where entrance placed (or no entrance data), use any first
2009-05-03 22:21:46 -05:00
if ( ! mapEntry ||
mapEntry -> entrance_map < 0 ||
2010-05-01 22:25:14 +02:00
uint32 ( mapEntry -> entrance_map ) != entry -> map_id ||
2009-05-03 22:21:46 -05:00
( mapEntry -> entrance_x == 0 && mapEntry -> entrance_y == 0 ))
2008-10-11 14:16:25 -05:00
{
2008-11-14 17:03:03 -06:00
// not have any corrdinates for check distance anyway
entryFar = entry ;
continue ;
}
2009-10-17 15:51:44 -07:00
2008-11-14 17:03:03 -06:00
// at entrance map calculate distance (2D);
float dist2 = ( entry -> x - mapEntry -> entrance_x ) * ( entry -> x - mapEntry -> entrance_x )
+ ( entry -> y - mapEntry -> entrance_y ) * ( entry -> y - mapEntry -> entrance_y );
2010-04-07 19:14:10 +02:00
if ( foundEntr )
2008-11-14 17:03:03 -06:00
{
2010-04-07 19:14:10 +02:00
if ( dist2 < distEntr )
2008-11-14 17:03:03 -06:00
{
distEntr = dist2 ;
entryEntr = entry ;
}
}
else
{
foundEntr = true ;
distEntr = dist2 ;
entryEntr = entry ;
2008-10-11 14:16:25 -05:00
}
}
2008-11-14 17:03:03 -06:00
// find now nearest graveyard at same map
2008-10-11 14:16:25 -05:00
else
{
2008-11-14 17:03:03 -06:00
float dist2 = ( entry -> x - x ) * ( entry -> x - x ) + ( entry -> y - y ) * ( entry -> y - y ) + ( entry -> z - z ) * ( entry -> z - z );
2010-04-07 19:14:10 +02:00
if ( foundNear )
2008-11-14 17:03:03 -06:00
{
2010-04-07 19:14:10 +02:00
if ( dist2 < distNear )
2008-11-14 17:03:03 -06:00
{
distNear = dist2 ;
entryNear = entry ;
}
}
else
{
foundNear = true ;
distNear = dist2 ;
entryNear = entry ;
}
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( entryNear )
2008-10-11 14:16:25 -05:00
return entryNear ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( entryEntr )
2008-11-14 17:03:03 -06:00
return entryEntr ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return entryFar ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GraveYardData const * ObjectMgr :: FindGraveYardData ( uint32 id , uint32 zoneId )
{
GraveYardMap :: const_iterator graveLow = mGraveYardMap . lower_bound ( zoneId );
GraveYardMap :: const_iterator graveUp = mGraveYardMap . upper_bound ( zoneId );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( GraveYardMap :: const_iterator itr = graveLow ; itr != graveUp ; ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-04-07 23:25:02 +02:00
if ( itr -> second . safeLocId == id )
2008-10-11 14:16:25 -05:00
return & itr -> second ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return NULL ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool ObjectMgr :: AddGraveYardLink ( uint32 id , uint32 zoneId , uint32 team , bool inDB )
{
2011-04-29 20:47:02 +02:00
if ( FindGraveYardData ( id , zoneId ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// add link to loaded data
GraveYardData data ;
data . safeLocId = id ;
data . team = team ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
mGraveYardMap . insert ( GraveYardMap :: value_type ( zoneId , data ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// add link to DB
2010-04-07 19:14:10 +02:00
if ( inDB )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
WorldDatabase . PExecute ( "INSERT INTO game_graveyard_zone (id, ghost_zone, faction) "
"VALUES ('%u', '%u', '%u')" , id , zoneId , team );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
void ObjectMgr :: RemoveGraveYardLink ( uint32 id , uint32 zoneId , uint32 team , bool inDB )
{
GraveYardMap :: iterator graveLow = mGraveYardMap . lower_bound ( zoneId );
GraveYardMap :: iterator graveUp = mGraveYardMap . upper_bound ( zoneId );
2010-04-07 23:25:02 +02:00
if ( graveLow == graveUp )
2008-10-14 11:57:03 -05:00
{
2011-04-29 20:47:02 +02:00
//sLog->outErrorDb("Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.", zoneId, team);
2008-10-14 11:57:03 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
bool found = false ;
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
GraveYardMap :: iterator itr ;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( itr = graveLow ; itr != graveUp ; ++ itr )
2008-10-14 11:57:03 -05:00
{
GraveYardData & data = itr -> second ;
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
// skip not matching safezone id
2010-04-07 19:14:10 +02:00
if ( data . safeLocId != id )
2008-10-14 11:57:03 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
// skip enemy faction graveyard at same map (normal area, city, or battleground)
// team == 0 case can be at call from .neargrave
2010-04-07 19:14:10 +02:00
if ( data . team != 0 && team != 0 && data . team != team )
2008-10-14 11:57:03 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
found = true ;
break ;
}
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
// no match, return
2010-04-07 19:14:10 +02:00
if ( ! found )
2008-10-14 11:57:03 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
// remove from links
mGraveYardMap . erase ( itr );
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
// remove link from DB
2010-04-07 19:14:10 +02:00
if ( inDB )
2008-10-14 11:57:03 -05:00
{
2011-04-29 20:47:02 +02:00
WorldDatabase . PExecute ( "DELETE FROM game_graveyard_zone WHERE id = '%u' AND ghost_zone = '%u' AND faction = '%u'" , id , zoneId , team );
2008-10-14 11:57:03 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
return ;
}
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadAreaTriggerTeleports ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
mAreaTriggers . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
// 0 1 2 3 4 5
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT id, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM areatrigger_teleport" );
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 area trigger teleport definitions. DB table `areatrigger_teleport` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Trigger_ID = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTrigger at ;
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
at . target_mapId = fields [ 1 ]. GetUInt32 ();
at . target_X = fields [ 2 ]. GetFloat ();
at . target_Y = fields [ 3 ]. GetFloat ();
at . target_Z = fields [ 4 ]. GetFloat ();
at . target_Orientation = fields [ 5 ]. GetFloat ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTriggerEntry const * atEntry = sAreaTriggerStore . LookupEntry ( Trigger_ID );
2010-04-07 19:14:10 +02:00
if ( ! atEntry )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`." , Trigger_ID );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-03-05 21:02:33 +01:00
MapEntry const * mapEntry = sMapStore . LookupEntry ( at . target_mapId );
2010-04-07 19:14:10 +02:00
if ( ! mapEntry )
2009-03-05 21:02:33 +01:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Area trigger (ID:%u) target map (ID: %u) does not exist in `Map.dbc`." , Trigger_ID , at . target_mapId );
2009-03-05 21:02:33 +01:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( at . target_X == 0 && at . target_Y == 0 && at . target_Z == 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Area trigger (ID:%u) target coordinates not provided." , Trigger_ID );
2009-03-05 21:02:33 +01:00
continue ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-03-05 21:02:33 +01:00
mAreaTriggers [ Trigger_ID ] = at ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u area trigger teleport definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2009-03-05 21:02:33 +01:00
}
2009-10-17 15:51:44 -07:00
2009-03-05 21:02:33 +01:00
void ObjectMgr :: LoadAccessRequirements ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
mAccessRequirements . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
// 0 1 2 3 4 5 6 7 8 9
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT mapid, difficulty, level_min, level_max, item, item2, quest_done_A, quest_done_H, completed_achievement, quest_failed_text FROM access_requirement" );
2010-04-07 22:59:46 +02:00
if ( ! result )
2009-03-05 21:02:33 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 access requirement definitions. DB table `access_requirement` is empty." );
sLog -> outString ();
2009-03-05 21:02:33 +01:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2009-03-05 21:02:33 +01:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-03-05 21:02:33 +01:00
++ count ;
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
uint32 mapid = fields [ 0 ]. GetUInt32 ();
uint8 difficulty = fields [ 1 ]. GetUInt8 ();
2011-04-29 20:47:02 +02:00
uint32 requirement_ID = MAKE_PAIR32 ( mapid , difficulty );
2009-10-17 15:51:44 -07:00
2009-03-05 21:02:33 +01:00
AccessRequirement ar ;
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
ar . levelMin = fields [ 2 ]. GetUInt8 ();
ar . levelMax = fields [ 3 ]. GetUInt8 ();
ar . item = fields [ 4 ]. GetUInt32 ();
ar . item2 = fields [ 5 ]. GetUInt32 ();
ar . quest_A = fields [ 6 ]. GetUInt32 ();
ar . quest_H = fields [ 7 ]. GetUInt32 ();
ar . achievement = fields [ 8 ]. GetUInt32 ();
2010-09-24 22:16:21 +02:00
ar . questFailedText = fields [ 9 ]. GetString ();
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ar . item )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
ItemTemplate const * pProto = sObjectMgr -> GetItemTemplate ( ar . item );
2010-04-07 19:14:10 +02:00
if ( ! pProto )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Key item %u does not exist for map %u difficulty %u, removing key requirement." , ar . item , mapid , difficulty );
2009-03-05 21:02:33 +01:00
ar . item = 0 ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ar . item2 )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:42:33 +02:00
ItemTemplate const * pProto = sObjectMgr -> GetItemTemplate ( ar . item2 );
2010-04-07 19:14:10 +02:00
if ( ! pProto )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Second item %u does not exist for map %u difficulty %u, removing key requirement." , ar . item2 , mapid , difficulty );
2009-03-05 21:02:33 +01:00
ar . item2 = 0 ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
if ( ar . quest_A )
2008-10-11 14:16:25 -05:00
{
2010-07-29 18:11:41 +02:00
if ( ! GetQuestTemplate ( ar . quest_A ))
2009-02-09 08:16:34 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Required Alliance Quest %u not exist for map %u difficulty %u, remove quest done requirement." , ar . quest_A , mapid , difficulty );
2010-07-29 18:11:41 +02:00
ar . quest_A = 0 ;
2009-02-09 08:16:34 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
if ( ar . quest_H )
2009-04-20 18:11:55 -05:00
{
2010-07-29 18:11:41 +02:00
if ( ! GetQuestTemplate ( ar . quest_H ))
2009-04-07 10:51:45 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Required Horde Quest %u not exist for map %u difficulty %u, remove quest done requirement." , ar . quest_H , mapid , difficulty );
2010-07-29 18:11:41 +02:00
ar . quest_H = 0 ;
2009-04-20 18:11:55 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
if ( ar . achievement )
2008-10-11 14:16:25 -05:00
{
2010-07-29 18:11:41 +02:00
if ( ! sAchievementStore . LookupEntry ( ar . achievement ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Required Achievement %u not exist for map %u difficulty %u, remove quest done requirement." , ar . achievement , mapid , difficulty );
2010-07-29 18:11:41 +02:00
ar . achievement = 0 ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-07-29 18:11:41 +02:00
mAccessRequirements [ requirement_ID ] = ar ;
2010-04-07 22:59:46 +02:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u access requirement definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-01-03 10:54:51 -06:00
/*
2010-05-04 18:25:30 +02:00
* Searches for the areatrigger which teleports players out of the given map with instance_template.parent field support
2009-01-03 10:54:51 -06:00
*/
2008-10-11 14:16:25 -05:00
AreaTrigger const * ObjectMgr :: GetGoBackTrigger ( uint32 Map ) const
{
2010-05-04 18:25:30 +02:00
bool useParentDbValue = false ;
uint32 parentId = 0 ;
2008-10-11 14:16:25 -05:00
const MapEntry * mapEntry = sMapStore . LookupEntry ( Map );
2010-05-04 18:25:30 +02:00
if ( ! mapEntry || mapEntry -> entrance_map < 0 )
return NULL ;
if ( mapEntry -> IsDungeon ())
{
2011-04-28 22:16:13 +02:00
const InstanceTemplate * iTemplate = sObjectMgr -> GetInstanceTemplate ( Map );
2010-05-04 18:25:30 +02:00
if ( ! iTemplate )
return NULL ;
2011-04-28 22:16:13 +02:00
parentId = iTemplate -> Parent ;
2010-05-04 18:25:30 +02:00
useParentDbValue = true ;
}
2010-05-01 22:25:14 +02:00
uint32 entrance_map = uint32 ( mapEntry -> entrance_map );
2008-12-08 16:34:03 -06:00
for ( AreaTriggerMap :: const_iterator itr = mAreaTriggers . begin (); itr != mAreaTriggers . end (); ++ itr )
2010-05-04 18:25:30 +02:00
if (( ! useParentDbValue && itr -> second . target_mapId == entrance_map ) || ( useParentDbValue && itr -> second . target_mapId == parentId ))
2008-10-11 14:16:25 -05:00
{
AreaTriggerEntry const * atEntry = sAreaTriggerStore . LookupEntry ( itr -> first );
2010-04-07 19:14:10 +02:00
if ( atEntry && atEntry -> mapid == Map )
2008-10-11 14:16:25 -05:00
return & itr -> second ;
}
return NULL ;
}
2009-10-17 15:51:44 -07:00
2009-01-03 10:54:51 -06:00
/**
* Searches for the areatrigger which teleports players to the given map
*/
AreaTrigger const * ObjectMgr :: GetMapEntranceTrigger ( uint32 Map ) const
{
for ( AreaTriggerMap :: const_iterator itr = mAreaTriggers . begin (); itr != mAreaTriggers . end (); ++ itr )
{
2010-04-07 19:14:10 +02:00
if ( itr -> second . target_mapId == Map )
2009-01-03 10:54:51 -06:00
{
AreaTriggerEntry const * atEntry = sAreaTriggerStore . LookupEntry ( itr -> first );
2010-04-07 19:14:10 +02:00
if ( atEntry )
2009-01-03 10:54:51 -06:00
return & itr -> second ;
}
}
return NULL ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: SetHighestGuids ()
{
2010-09-11 21:10:54 +02:00
QueryResult result = CharacterDatabase . Query ( "SELECT MAX(guid) FROM characters" );
2010-04-07 22:59:46 +02:00
if ( result )
2008-10-11 14:16:25 -05:00
m_hiCharGuid = ( * result )[ 0 ]. GetUInt32 () + 1 ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
result = WorldDatabase . Query ( "SELECT MAX(guid) FROM creature" );
if ( result )
2008-10-11 14:16:25 -05:00
m_hiCreatureGuid = ( * result )[ 0 ]. GetUInt32 () + 1 ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
result = CharacterDatabase . Query ( "SELECT MAX(guid) FROM item_instance" );
if ( result )
2008-10-11 14:16:25 -05:00
m_hiItemGuid = ( * result )[ 0 ]. GetUInt32 () + 1 ;
2009-10-17 15:51:44 -07:00
2010-04-07 23:56:35 +02:00
// Cleanup other tables from not existed guids ( >= m_hiItemGuid)
2008-10-11 14:16:25 -05:00
CharacterDatabase . PExecute ( "DELETE FROM character_inventory WHERE item >= '%u'" , m_hiItemGuid );
CharacterDatabase . PExecute ( "DELETE FROM mail_items WHERE item_guid >= '%u'" , m_hiItemGuid );
CharacterDatabase . PExecute ( "DELETE FROM auctionhouse WHERE itemguid >= '%u'" , m_hiItemGuid );
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_item WHERE item_guid >= '%u'" , m_hiItemGuid );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
result = WorldDatabase . Query ( "SELECT MAX(guid) FROM gameobject" );
if ( result )
2008-10-11 14:16:25 -05:00
m_hiGoGuid = ( * result )[ 0 ]. GetUInt32 () + 1 ;
2009-10-17 15:51:44 -07:00
2010-09-02 10:40:32 +02:00
result = WorldDatabase . Query ( "SELECT MAX(guid) FROM transports" );
if ( result )
m_hiMoTransGuid = ( * result )[ 0 ]. GetUInt32 () + 1 ;
2010-04-07 22:59:46 +02:00
result = CharacterDatabase . Query ( "SELECT MAX(id) FROM auctionhouse" );
if ( result )
2008-10-11 14:16:25 -05:00
m_auctionid = ( * result )[ 0 ]. GetUInt32 () + 1 ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
result = CharacterDatabase . Query ( "SELECT MAX(id) FROM mail" );
if ( result )
2008-10-11 14:16:25 -05:00
m_mailid = ( * result )[ 0 ]. GetUInt32 () + 1 ;
2009-10-17 15:51:44 -07:00
2011-04-11 14:39:00 +06:00
result = CharacterDatabase . Query ( "SELECT MAX(corpseGuid) FROM corpse" );
2010-04-07 22:59:46 +02:00
if ( result )
2008-10-11 14:16:25 -05:00
m_hiCorpseGuid = ( * result )[ 0 ]. GetUInt32 () + 1 ;
2009-10-17 15:51:44 -07:00
2008-11-20 16:16:57 -06:00
result = CharacterDatabase . Query ( "SELECT MAX(arenateamid) FROM arena_team" );
if ( result )
2011-05-03 15:01:10 +02:00
sArenaTeamMgr -> SetNextArenaTeamId (( * result )[ 0 ]. GetUInt32 () + 1 );
2009-10-17 15:51:44 -07:00
2009-06-11 00:45:59 -05:00
result = CharacterDatabase . Query ( "SELECT MAX(setguid) FROM character_equipmentsets" );
if ( result )
m_equipmentSetGuid = ( * result )[ 0 ]. GetUInt64 () + 1 ;
2009-10-17 15:51:44 -07:00
2011-04-11 14:39:00 +06:00
result = CharacterDatabase . Query ( "SELECT MAX(guildId) FROM guild" );
2008-11-20 16:16:57 -06:00
if ( result )
2011-05-04 10:08:09 +02:00
sGuildMgr -> SetNextGuildId (( * result )[ 0 ]. GetUInt32 () + 1 );
2010-05-08 01:58:47 +02:00
result = CharacterDatabase . Query ( "SELECT MAX(guid) FROM groups" );
if ( result )
2011-05-05 10:23:00 +02:00
sGroupMgr -> SetGroupDbStoreSize (( * result )[ 0 ]. GetUInt32 () + 1 );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-02-13 19:50:20 -06:00
uint32 ObjectMgr :: GenerateAuctionID ()
2008-11-20 16:16:57 -06:00
{
2010-04-07 23:56:35 +02:00
if ( m_auctionid >= 0xFFFFFFFE )
2008-11-20 16:16:57 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Auctions ids overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
}
2009-02-13 19:50:20 -06:00
return m_auctionid ++ ;
2008-11-20 16:16:57 -06:00
}
2009-10-17 15:51:44 -07:00
2009-06-11 00:45:59 -05:00
uint64 ObjectMgr :: GenerateEquipmentSetGuid ()
{
2011-03-08 19:11:02 +01:00
if ( m_equipmentSetGuid >= uint64 ( 0xFFFFFFFFFFFFFFFELL ))
2009-06-11 00:45:59 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "EquipmentSet guid overflow!! Can't continue, shutting down server. " );
2009-06-11 00:45:59 -05:00
World :: StopNow ( ERROR_EXIT_CODE );
}
return m_equipmentSetGuid ++ ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 ObjectMgr :: GenerateMailID ()
{
2010-04-07 23:56:35 +02:00
if ( m_mailid >= 0xFFFFFFFE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Mail ids overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
2008-10-11 14:16:25 -05:00
}
2008-11-20 16:16:57 -06:00
return m_mailid ++ ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 ObjectMgr :: GenerateLowGuid ( HighGuid guidhigh )
{
switch ( guidhigh )
{
case HIGHGUID_ITEM :
2010-04-07 23:56:35 +02:00
if ( m_hiItemGuid >= 0xFFFFFFFE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Item guid overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
2008-10-11 14:16:25 -05:00
}
2008-11-20 16:16:57 -06:00
return m_hiItemGuid ++ ;
2008-10-11 14:16:25 -05:00
case HIGHGUID_UNIT :
2010-04-07 23:56:35 +02:00
if ( m_hiCreatureGuid >= 0x00FFFFFE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Creature guid overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
2008-10-11 14:16:25 -05:00
}
2008-11-20 16:16:57 -06:00
return m_hiCreatureGuid ++ ;
2008-10-11 14:16:25 -05:00
case HIGHGUID_PET :
2010-04-07 23:56:35 +02:00
if ( m_hiPetGuid >= 0x00FFFFFE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Pet guid overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
2008-10-11 14:16:25 -05:00
}
2008-11-20 16:16:57 -06:00
return m_hiPetGuid ++ ;
2008-12-24 09:58:26 -06:00
case HIGHGUID_VEHICLE :
2010-04-07 23:56:35 +02:00
if ( m_hiVehicleGuid >= 0x00FFFFFF )
2008-12-24 09:58:26 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Vehicle guid overflow!! Can't continue, shutting down server. " );
2008-12-24 09:58:26 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
}
return m_hiVehicleGuid ++ ;
2008-10-11 14:16:25 -05:00
case HIGHGUID_PLAYER :
2010-04-07 23:56:35 +02:00
if ( m_hiCharGuid >= 0xFFFFFFFE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Players guid overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
2008-10-11 14:16:25 -05:00
}
2008-11-20 16:16:57 -06:00
return m_hiCharGuid ++ ;
2008-10-11 14:16:25 -05:00
case HIGHGUID_GAMEOBJECT :
2010-04-07 23:56:35 +02:00
if ( m_hiGoGuid >= 0x00FFFFFE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Gameobject guid overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
2008-10-11 14:16:25 -05:00
}
2008-11-20 16:16:57 -06:00
return m_hiGoGuid ++ ;
2008-10-11 14:16:25 -05:00
case HIGHGUID_CORPSE :
2010-04-07 23:56:35 +02:00
if ( m_hiCorpseGuid >= 0xFFFFFFFE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Corpse guid overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
2008-10-11 14:16:25 -05:00
}
2008-11-20 16:16:57 -06:00
return m_hiCorpseGuid ++ ;
2008-10-11 14:16:25 -05:00
case HIGHGUID_DYNAMICOBJECT :
2010-04-07 23:56:35 +02:00
if ( m_hiDoGuid >= 0xFFFFFFFE )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "DynamicObject guid overflow!! Can't continue, shutting down server. " );
2008-11-20 16:16:57 -06:00
World :: StopNow ( ERROR_EXIT_CODE );
2008-10-11 14:16:25 -05:00
}
2008-11-20 16:16:57 -06:00
return m_hiDoGuid ++ ;
2010-09-02 10:40:32 +02:00
case HIGHGUID_MO_TRANSPORT :
if ( m_hiMoTransGuid >= 0xFFFFFFFE )
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "MO Transport guid overflow!! Can't continue, shutting down server. " );
2010-09-02 10:40:32 +02:00
World :: StopNow ( ERROR_EXIT_CODE );
}
return m_hiMoTransGuid ++ ;
2008-10-11 14:16:25 -05:00
default :
ASSERT ( 0 );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ASSERT ( 0 );
return 0 ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGameObjectLocales ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
mGameObjectLocaleMap . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, "
"name_loc1, name_loc2, name_loc3, name_loc4, name_loc5, name_loc6, name_loc7, name_loc8, "
"castbarcaption_loc1, castbarcaption_loc2, castbarcaption_loc3, castbarcaption_loc4, "
"castbarcaption_loc5, castbarcaption_loc6, castbarcaption_loc7, castbarcaption_loc8 FROM locales_gameobject" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GameObjectLocale & data = mGameObjectLocaleMap [ entry ];
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ i ]. GetString (), LocaleConstant ( i ), data . Name );
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 1 ; i < TOTAL_LOCALES ; ++ i )
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ i + ( TOTAL_LOCALES - 1 )]. GetString (), LocaleConstant ( i ), data . CastBarCaption );
2008-10-11 14:16:25 -05:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %lu gameobject locale strings in %u ms" , ( unsigned long ) mGameObjectLocaleMap . size (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-08-04 15:14:15 +02:00
inline void CheckGOLockId ( GameObjectTemplate const * goInfo , uint32 dataN , uint32 N )
2009-04-08 16:38:07 -05:00
{
2009-04-08 16:39:49 -05:00
if ( sLockStore . LookupEntry ( dataN ))
2009-04-08 16:38:07 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Gameobject (Entry: %u GoType: %u) have data%d=%u but lock (Id: %u) not found." ,
2011-04-29 20:47:02 +02:00
goInfo -> entry , goInfo -> type , N , goInfo -> door . lockId , goInfo -> door . lockId );
2009-04-08 16:38:07 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
inline void CheckGOLinkedTrapId ( GameObjectTemplate const * goInfo , uint32 dataN , uint32 N )
2009-04-08 16:38:58 -05:00
{
2011-04-28 22:54:30 +02:00
if ( GameObjectTemplate const * trapInfo = sObjectMgr -> GetGameObjectTemplate ( dataN ))
2009-04-08 16:38:58 -05:00
{
2010-04-08 08:20:08 +02:00
if ( trapInfo -> type != GAMEOBJECT_TYPE_TRAP )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Gameobject (Entry: %u GoType: %u) have data%d=%u but GO (Entry %u) have not GAMEOBJECT_TYPE_TRAP (%u) type." ,
2011-04-29 20:47:02 +02:00
goInfo -> entry , goInfo -> type , N , dataN , dataN , GAMEOBJECT_TYPE_TRAP );
2009-04-08 16:38:58 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
inline void CheckGOSpellId ( GameObjectTemplate const * goInfo , uint32 dataN , uint32 N )
2009-04-08 16:39:49 -05:00
{
2011-07-26 23:09:28 +02:00
if ( sSpellMgr -> GetSpellInfo ( dataN ))
2009-04-08 16:39:49 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Gameobject (Entry: %u GoType: %u) have data%d=%u but Spell (Entry %u) not exist." ,
2011-04-29 20:47:02 +02:00
goInfo -> entry , goInfo -> type , N , dataN , dataN );
2009-04-08 16:39:49 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
inline void CheckAndFixGOChairHeightId ( GameObjectTemplate const * goInfo , uint32 const & dataN , uint32 N )
2009-04-08 16:39:49 -05:00
{
2010-04-07 22:59:46 +02:00
if ( dataN <= ( UNIT_STAND_STATE_SIT_HIGH_CHAIR - UNIT_STAND_STATE_SIT_LOW_CHAIR ))
2009-04-08 16:39:49 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Gameobject (Entry: %u GoType: %u) have data%d=%u but correct chair height in range 0..%i." ,
2011-04-29 20:47:02 +02:00
goInfo -> entry , goInfo -> type , N , dataN , UNIT_STAND_STATE_SIT_HIGH_CHAIR - UNIT_STAND_STATE_SIT_LOW_CHAIR );
2009-10-17 15:51:44 -07:00
2009-04-08 16:39:49 -05:00
// prevent client and server unexpected work
const_cast < uint32 &> ( dataN ) = 0 ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
inline void CheckGONoDamageImmuneId ( GameObjectTemplate * goTemplate , uint32 dataN , uint32 N )
2009-04-08 16:40:26 -05:00
{
// 0/1 correct values
if ( dataN <= 1 )
return ;
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
sLog -> outErrorDb ( "Gameobject (Entry: %u GoType: %u) have data%d=%u but expected boolean (0/1) noDamageImmune field value." , goTemplate -> entry , goTemplate -> type , N , dataN );
2009-04-08 16:40:26 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
inline void CheckGOConsumable ( GameObjectTemplate const * goInfo , uint32 dataN , uint32 N )
2009-07-16 12:06:07 +08:00
{
// 0/1 correct values
if ( dataN <= 1 )
return ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Gameobject (Entry: %u GoType: %u) have data%d=%u but expected boolean (0/1) consumable field value." ,
2011-04-29 20:47:02 +02:00
goInfo -> entry , goInfo -> type , N , dataN );
2009-07-16 12:06:07 +08:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
void ObjectMgr :: LoadGameObjectTemplate ()
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-28 22:54:30 +02:00
// 0 1 2 3 4 5 6 7 8 9 10 11 12
QueryResult result = WorldDatabase . Query ( "SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, faction, flags, size, questItem1, questItem2, questItem3, "
// 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
"questItem4, questItem5, questItem6, data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12, "
// 29 30 31 32 33 34 35 36 37 38 39 40 41
"data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, AIName, ScriptName "
"FROM gameobject_template" );
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
sLog -> outString ( ">> Loaded 0 gameobject definitions. DB table `gameobject_template` is empty." );
sLog -> outString ();
return ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
uint32 count = 0 ;
do
{
Field * fields = result -> Fetch ();
uint32 entry = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2011-04-29 19:59:40 +02:00
GameObjectTemplate & got = GameObjectTemplateStore [ entry ];
2011-04-28 22:54:30 +02:00
got . entry = entry ;
got . type = uint32 ( fields [ 1 ]. GetUInt8 ());
got . displayId = fields [ 2 ]. GetUInt32 ();
2011-04-29 19:59:40 +02:00
got . name = fields [ 3 ]. GetString ();
got . IconName = fields [ 4 ]. GetString ();
got . castBarCaption = fields [ 5 ]. GetString ();
got . unk1 = fields [ 6 ]. GetString ();
2011-04-28 22:54:30 +02:00
got . faction = uint32 ( fields [ 7 ]. GetUInt16 ());
got . flags = fields [ 8 ]. GetUInt32 ();
got . size = fields [ 9 ]. GetFloat ();
for ( uint8 i = 0 ; i < MAX_GAMEOBJECT_QUEST_ITEMS ; ++ i )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
got . questItems [ i ] = fields [ 10 + i ]. GetUInt32 ();
}
for ( uint8 i = 0 ; i < MAX_GAMEOBJECT_DATA ; ++ i )
{
got . raw . data [ i ] = fields [ 16 + i ]. GetUInt32 ();
}
2011-04-29 19:59:40 +02:00
got . AIName = fields [ 40 ]. GetString ();
2011-04-28 22:54:30 +02:00
got . ScriptId = GetScriptId ( fields [ 41 ]. GetCString ());
// Checks
switch ( got . type )
{
case GAMEOBJECT_TYPE_DOOR : //0
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . door . lockId )
CheckGOLockId ( & got , got . door . lockId , 1 );
CheckGONoDamageImmuneId ( & got , got . door . noDamageImmune , 3 );
2008-10-11 14:16:25 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_BUTTON : //1
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . button . lockId )
CheckGOLockId ( & got , got . button . lockId , 1 );
CheckGONoDamageImmuneId ( & got , got . button . noDamageImmune , 4 );
2009-04-08 16:38:07 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_QUESTGIVER : //2
2009-04-08 16:38:07 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . questgiver . lockId )
CheckGOLockId ( & got , got . questgiver . lockId , 0 );
CheckGONoDamageImmuneId ( & got , got . questgiver . noDamageImmune , 5 );
2008-10-11 14:16:25 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_CHEST : //3
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . chest . lockId )
CheckGOLockId ( & got , got . chest . lockId , 0 );
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
CheckGOConsumable ( & got , got . chest . consumable , 3 );
2009-10-17 15:51:44 -07:00
2011-05-03 10:57:59 +02:00
if ( got . chest . linkedTrapId ) // linked trap
2011-04-28 22:54:30 +02:00
CheckGOLinkedTrapId ( & got , got . chest . linkedTrapId , 7 );
2008-10-11 14:16:25 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_TRAP : //6
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . trap . lockId )
CheckGOLockId ( & got , got . trap . lockId , 0 );
2008-10-11 14:16:25 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_CHAIR : //7
CheckAndFixGOChairHeightId ( & got , got . chair . height , 1 );
break ;
case GAMEOBJECT_TYPE_SPELL_FOCUS : //8
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . spellFocus . focusId )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( ! sSpellFocusObjectStore . LookupEntry ( got . spellFocus . focusId ))
sLog -> outErrorDb ( "GameObject (Entry: %u GoType: %u) have data0=%u but SpellFocus (Id: %u) not exist." ,
entry , got . type , got . spellFocus . focusId , got . spellFocus . focusId );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
if ( got . spellFocus . linkedTrapId ) // linked trap
CheckGOLinkedTrapId ( & got , got . spellFocus . linkedTrapId , 2 );
2008-10-11 14:16:25 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_GOOBER : //10
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . goober . lockId )
CheckGOLockId ( & got , got . goober . lockId , 0 );
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
CheckGOConsumable ( & got , got . goober . consumable , 3 );
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
if ( got . goober . pageId ) // pageId
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( ! GetPageText ( got . goober . pageId ))
sLog -> outErrorDb ( "GameObject (Entry: %u GoType: %u) have data7=%u but PageText (Entry %u) not exist." ,
entry , got . type , got . goober . pageId , got . goober . pageId );
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:54:30 +02:00
CheckGONoDamageImmuneId ( & got , got . goober . noDamageImmune , 11 );
if ( got . goober . linkedTrapId ) // linked trap
CheckGOLinkedTrapId ( & got , got . goober . linkedTrapId , 12 );
2008-10-11 14:16:25 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_AREADAMAGE : //12
2009-04-08 16:38:07 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . areadamage . lockId )
CheckGOLockId ( & got , got . areadamage . lockId , 0 );
2009-04-08 16:38:07 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_CAMERA : //13
2009-04-08 16:38:07 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . camera . lockId )
CheckGOLockId ( & got , got . camera . lockId , 0 );
2009-04-08 16:38:07 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_MO_TRANSPORT : //15
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . moTransport . taxiPathId )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . moTransport . taxiPathId >= sTaxiPathNodesByPath . size () || sTaxiPathNodesByPath [ got . moTransport . taxiPathId ]. empty ())
sLog -> outErrorDb ( "GameObject (Entry: %u GoType: %u) have data0=%u but TaxiPath (Id: %u) not exist." ,
entry , got . type , got . moTransport . taxiPathId , got . moTransport . taxiPathId );
2008-10-11 14:16:25 -05:00
}
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_SUMMONING_RITUAL : //18
break ;
case GAMEOBJECT_TYPE_SPELLCASTER : //22
2008-10-11 14:16:25 -05:00
{
2009-04-08 16:39:49 -05:00
// always must have spell
2011-04-28 22:54:30 +02:00
CheckGOSpellId ( & got , got . spellcaster . spellId , 0 );
2008-10-11 14:16:25 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_FLAGSTAND : //24
2009-04-08 16:38:07 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . flagstand . lockId )
CheckGOLockId ( & got , got . flagstand . lockId , 0 );
CheckGONoDamageImmuneId ( & got , got . flagstand . noDamageImmune , 5 );
2009-04-08 16:38:07 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_FISHINGHOLE : //25
2009-04-08 16:38:07 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . fishinghole . lockId )
CheckGOLockId ( & got , got . fishinghole . lockId , 4 );
2009-04-08 16:38:07 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_FLAGDROP : //26
2009-04-08 16:38:07 -05:00
{
2011-04-28 22:54:30 +02:00
if ( got . flagdrop . lockId )
CheckGOLockId ( & got , got . flagdrop . lockId , 0 );
CheckGONoDamageImmuneId ( & got , got . flagdrop . noDamageImmune , 3 );
2009-04-08 16:38:07 -05:00
break ;
}
2011-04-28 22:54:30 +02:00
case GAMEOBJECT_TYPE_BARBER_CHAIR : //32
CheckAndFixGOChairHeightId ( & got , got . barberChair . chairheight , 0 );
break ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:54:30 +02:00
2011-04-29 19:59:40 +02:00
++ count ;
2008-10-11 14:16:25 -05:00
}
2011-04-28 22:54:30 +02:00
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2011-04-28 22:54:30 +02:00
sLog -> outString ( ">> Loaded %u game object templates in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadExplorationBaseXP ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-12-25 05:22:37 +01:00
QueryResult result = WorldDatabase . Query ( "SELECT level, basexp FROM exploration_basexp" );
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-25 05:22:37 +01:00
sLog -> outErrorDb ( ">> Loaded 0 BaseXP definitions. DB table `exploration_basexp` is empty." );
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-11-01 17:53:07 -08:00
uint8 level = fields [ 0 ]. GetUInt8 ();
2008-10-11 14:16:25 -05:00
uint32 basexp = fields [ 1 ]. GetUInt32 ();
mBaseXPTable [ level ] = basexp ;
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u BaseXP definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
uint32 ObjectMgr :: GetBaseXP ( uint8 level )
2008-10-11 14:16:25 -05:00
{
return mBaseXPTable [ level ] ? mBaseXPTable [ level ] : 0 ;
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
uint32 ObjectMgr :: GetXPForLevel ( uint8 level )
2009-01-16 14:17:24 -06:00
{
if ( level < mPlayerXPperLevel . size ())
return mPlayerXPperLevel [ level ];
return 0 ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadPetNames ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT word, entry, half FROM pet_name_generation" );
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 pet name parts. DB table `pet_name_generation` is empty!" );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
std :: string word = fields [ 0 ]. GetString ();
uint32 entry = fields [ 1 ]. GetUInt32 ();
bool half = fields [ 2 ]. GetBool ();
2009-11-01 17:53:07 -08:00
if ( half )
2008-10-11 14:16:25 -05:00
PetHalfName1 [ entry ]. push_back ( word );
else
PetHalfName0 [ entry ]. push_back ( word );
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u pet name parts in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadPetNumber ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-09-11 21:10:54 +02:00
QueryResult result = CharacterDatabase . Query ( "SELECT MAX(id) FROM character_pet" );
2009-11-01 17:53:07 -08:00
if ( result )
2008-10-11 14:16:25 -05:00
{
Field * fields = result -> Fetch ();
m_hiPetNumber = fields [ 0 ]. GetUInt32 () + 1 ;
}
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded the max pet number: %d in %u ms" , m_hiPetNumber - 1 , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
std :: string ObjectMgr :: GeneratePetName ( uint32 entry )
{
2010-08-26 15:54:56 +06:00
StringVector & list0 = PetHalfName0 [ entry ];
StringVector & list1 = PetHalfName1 [ entry ];
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( list0 . empty () || list1 . empty ())
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:57:08 +02:00
CreatureTemplate const * cinfo = GetCreatureTemplate ( entry );
2010-12-23 23:25:44 +01:00
char * petname = GetPetName ( cinfo -> family , sWorld -> GetDefaultDbcLocale ());
2009-11-01 17:53:07 -08:00
if ( ! petname )
2011-04-28 22:57:08 +02:00
return cinfo -> Name ;
2008-10-11 14:16:25 -05:00
return std :: string ( petname );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return * ( list0 . begin () + urand ( 0 , list0 . size () - 1 )) + * ( list1 . begin () + urand ( 0 , list1 . size () - 1 ));
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 ObjectMgr :: GeneratePetNumber ()
{
return ++ m_hiPetNumber ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadCorpses ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2011-01-26 01:03:35 +01:00
2011-04-11 14:39:00 +06:00
PreparedQueryResult result = CharacterDatabase . Query ( CharacterDatabase . GetPreparedStatement ( CHAR_LOAD_CORPSES ));
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 corpses. DB table `pet_name_generation` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2010-07-30 15:15:07 +02:00
uint32 guid = fields [ 16 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2011-04-11 14:39:00 +06:00
Corpse * corpse = new Corpse ();
2010-07-30 15:15:07 +02:00
if ( ! corpse -> LoadFromDB ( guid , fields ))
2008-10-11 14:16:25 -05:00
{
delete corpse ;
continue ;
}
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sObjectAccessor -> AddCorpse ( corpse );
2008-10-11 14:16:25 -05:00
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u corpses in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-07-26 16:21:10 -06:00
void ObjectMgr :: LoadReputationRewardRate ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-07-26 16:21:10 -06:00
m_RepRewardRateMap . clear (); // for reload case
uint32 count = 0 ;
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT faction, quest_rate, creature_rate, spell_rate FROM reputation_reward_rate" );
2010-07-26 16:21:10 -06:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded `reputation_reward_rate`, table is empty!" );
sLog -> outString ();
2010-07-26 16:21:10 -06:00
return ;
}
do
{
Field * fields = result -> Fetch ();
uint32 factionId = fields [ 0 ]. GetUInt32 ();
RepRewardRate repRate ;
repRate . quest_rate = fields [ 1 ]. GetFloat ();
repRate . creature_rate = fields [ 2 ]. GetFloat ();
repRate . spell_rate = fields [ 3 ]. GetFloat ();
FactionEntry const * factionEntry = sFactionStore . LookupEntry ( factionId );
if ( ! factionEntry )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u does not exist but is used in `reputation_reward_rate`" , factionId );
2010-07-26 16:21:10 -06:00
continue ;
}
if ( repRate . quest_rate < 0.0f )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table reputation_reward_rate has quest_rate with invalid rate %f, skipping data for faction %u" , repRate . quest_rate , factionId );
2010-07-26 16:21:10 -06:00
continue ;
}
if ( repRate . creature_rate < 0.0f )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table reputation_reward_rate has creature_rate with invalid rate %f, skipping data for faction %u" , repRate . creature_rate , factionId );
2010-07-26 16:21:10 -06:00
continue ;
}
if ( repRate . spell_rate < 0.0f )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table reputation_reward_rate has spell_rate with invalid rate %f, skipping data for faction %u" , repRate . spell_rate , factionId );
2010-07-26 16:21:10 -06:00
continue ;
}
m_RepRewardRateMap [ factionId ] = repRate ;
++ count ;
}
while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u reputation_reward_rate in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-07-26 16:21:10 -06:00
}
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadReputationOnKill ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-06-08 17:19:36 +02:00
// For reload case
mRepOnKill . clear ();
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// 0 1 2
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT creature_id, RewOnKillRepFaction1, RewOnKillRepFaction2, "
2008-10-11 14:16:25 -05:00
// 3 4 5 6 7 8 9
"IsTeamAward1, MaxStanding1, RewOnKillRepValue1, IsTeamAward2, MaxStanding2, RewOnKillRepValue2, TeamDependent "
"FROM creature_onkill_reputation" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 creature award reputation definitions. DB table `creature_onkill_reputation` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 creature_id = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ReputationOnKillEntry repOnKill ;
repOnKill . repfaction1 = fields [ 1 ]. GetUInt32 ();
repOnKill . repfaction2 = fields [ 2 ]. GetUInt32 ();
repOnKill . is_teamaward1 = fields [ 3 ]. GetBool ();
repOnKill . reputation_max_cap1 = fields [ 4 ]. GetUInt32 ();
repOnKill . repvalue1 = fields [ 5 ]. GetInt32 ();
repOnKill . is_teamaward2 = fields [ 6 ]. GetBool ();
repOnKill . reputation_max_cap2 = fields [ 7 ]. GetUInt32 ();
repOnKill . repvalue2 = fields [ 8 ]. GetInt32 ();
repOnKill . team_dependent = fields [ 9 ]. GetUInt8 ();
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( ! GetCreatureTemplate ( creature_id ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `creature_onkill_reputation` have data for not existed creature entry (%u), skipped" , creature_id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( repOnKill . repfaction1 )
2008-10-11 14:16:25 -05:00
{
FactionEntry const * factionEntry1 = sFactionStore . LookupEntry ( repOnKill . repfaction1 );
2009-11-01 17:53:07 -08:00
if ( ! factionEntry1 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`" , repOnKill . repfaction1 );
2008-10-11 14:16:25 -05:00
continue ;
}
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( repOnKill . repfaction2 )
2008-10-11 14:16:25 -05:00
{
FactionEntry const * factionEntry2 = sFactionStore . LookupEntry ( repOnKill . repfaction2 );
2009-11-01 17:53:07 -08:00
if ( ! factionEntry2 )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`" , repOnKill . repfaction2 );
2008-10-11 14:16:25 -05:00
continue ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
mRepOnKill [ creature_id ] = repOnKill ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u creature award reputation definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-07-26 17:58:25 -06:00
void ObjectMgr :: LoadReputationSpilloverTemplate ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-07-26 17:58:25 -06:00
m_RepSpilloverTemplateMap . clear (); // for reload case
uint32 count = 0 ;
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT faction, faction1, rate_1, rank_1, faction2, rate_2, rank_2, faction3, rate_3, rank_3, faction4, rate_4, rank_4 FROM reputation_spillover_template" );
2010-07-26 17:58:25 -06:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded `reputation_spillover_template`, table is empty." );
sLog -> outString ();
2010-07-26 17:58:25 -06:00
return ;
}
do
{
Field * fields = result -> Fetch ();
uint32 factionId = fields [ 0 ]. GetUInt32 ();
RepSpilloverTemplate repTemplate ;
repTemplate . faction [ 0 ] = fields [ 1 ]. GetUInt32 ();
repTemplate . faction_rate [ 0 ] = fields [ 2 ]. GetFloat ();
repTemplate . faction_rank [ 0 ] = fields [ 3 ]. GetUInt32 ();
repTemplate . faction [ 1 ] = fields [ 4 ]. GetUInt32 ();
repTemplate . faction_rate [ 1 ] = fields [ 5 ]. GetFloat ();
repTemplate . faction_rank [ 1 ] = fields [ 6 ]. GetUInt32 ();
repTemplate . faction [ 2 ] = fields [ 7 ]. GetUInt32 ();
repTemplate . faction_rate [ 2 ] = fields [ 8 ]. GetFloat ();
repTemplate . faction_rank [ 2 ] = fields [ 9 ]. GetUInt32 ();
repTemplate . faction [ 3 ] = fields [ 10 ]. GetUInt32 ();
repTemplate . faction_rate [ 3 ] = fields [ 11 ]. GetFloat ();
repTemplate . faction_rank [ 3 ] = fields [ 12 ]. GetUInt32 ();
FactionEntry const * factionEntry = sFactionStore . LookupEntry ( factionId );
if ( ! factionEntry )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u does not exist but is used in `reputation_spillover_template`" , factionId );
2010-07-26 17:58:25 -06:00
continue ;
}
if ( factionEntry -> team == 0 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u in `reputation_spillover_template` does not belong to any team, skipping" , factionId );
2010-07-26 17:58:25 -06:00
continue ;
}
for ( uint32 i = 0 ; i < MAX_SPILLOVER_FACTIONS ; ++ i )
{
if ( repTemplate . faction [ i ])
{
FactionEntry const * factionSpillover = sFactionStore . LookupEntry ( repTemplate . faction [ i ]);
if ( ! factionSpillover )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Spillover faction (faction.dbc) %u does not exist but is used in `reputation_spillover_template` for faction %u, skipping" , repTemplate . faction [ i ], factionId );
2010-07-26 17:58:25 -06:00
continue ;
}
if ( factionSpillover -> reputationListID < 0 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Spillover faction (faction.dbc) %u for faction %u in `reputation_spillover_template` can not be listed for client, and then useless, skipping" , repTemplate . faction [ i ], factionId );
2010-07-26 17:58:25 -06:00
continue ;
}
if ( repTemplate . faction_rank [ i ] >= MAX_REPUTATION_RANK )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Rank %u used in `reputation_spillover_template` for spillover faction %u is not valid, skipping" , repTemplate . faction_rank [ i ], repTemplate . faction [ i ]);
2010-07-26 17:58:25 -06:00
continue ;
}
}
}
FactionEntry const * factionEntry0 = sFactionStore . LookupEntry ( repTemplate . faction [ 0 ]);
if ( repTemplate . faction [ 0 ] && ! factionEntry0 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u does not exist but is used in `reputation_spillover_template`" , repTemplate . faction [ 0 ]);
2010-07-26 17:58:25 -06:00
continue ;
}
FactionEntry const * factionEntry1 = sFactionStore . LookupEntry ( repTemplate . faction [ 1 ]);
if ( repTemplate . faction [ 1 ] && ! factionEntry1 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u does not exist but is used in `reputation_spillover_template`" , repTemplate . faction [ 1 ]);
2010-07-26 17:58:25 -06:00
continue ;
}
FactionEntry const * factionEntry2 = sFactionStore . LookupEntry ( repTemplate . faction [ 2 ]);
if ( repTemplate . faction [ 2 ] && ! factionEntry2 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u does not exist but is used in `reputation_spillover_template`" , repTemplate . faction [ 2 ]);
2010-07-26 17:58:25 -06:00
continue ;
}
FactionEntry const * factionEntry3 = sFactionStore . LookupEntry ( repTemplate . faction [ 3 ]);
if ( repTemplate . faction [ 3 ] && ! factionEntry3 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Faction (faction.dbc) %u does not exist but is used in `reputation_spillover_template`" , repTemplate . faction [ 3 ]);
2010-07-26 17:58:25 -06:00
continue ;
}
m_RepSpilloverTemplateMap [ factionId ] = repTemplate ;
++ count ;
}
while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u reputation_spillover_template in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-07-26 17:58:25 -06:00
}
2009-02-17 17:40:03 -06:00
void ObjectMgr :: LoadPointsOfInterest ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-08-28 01:44:35 +03:00
mPointsOfInterest . clear (); // need for reload case
2010-09-12 01:40:27 +02:00
2009-02-17 17:40:03 -06:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
// 0 1 2 3 4 5 6
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, x, y, icon, flags, data, icon_name FROM points_of_interest" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2009-02-17 17:40:03 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 Points of Interest definitions. DB table `points_of_interest` is empty." );
sLog -> outString ();
2009-02-17 17:40:03 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
uint32 point_id = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
PointOfInterest POI ;
POI . x = fields [ 1 ]. GetFloat ();
POI . y = fields [ 2 ]. GetFloat ();
POI . icon = fields [ 3 ]. GetUInt32 ();
POI . flags = fields [ 4 ]. GetUInt32 ();
POI . data = fields [ 5 ]. GetUInt32 ();
2010-09-24 22:16:21 +02:00
POI . icon_name = fields [ 6 ]. GetString ();
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( ! Trinity :: IsValidMapCoord ( POI . x , POI . y ))
2009-02-17 17:40:03 -06:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `points_of_interest` (Entry: %u) have invalid coordinates (X: %f Y: %f), ignored." , point_id , POI . x , POI . y );
2009-02-17 17:40:03 -06:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
mPointsOfInterest [ point_id ] = POI ;
2009-10-17 15:51:44 -07:00
2009-02-17 17:40:03 -06:00
++ count ;
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u Points of Interest definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2009-02-17 17:40:03 -06:00
}
2009-10-17 15:51:44 -07:00
2010-02-14 19:13:14 -07:00
void ObjectMgr :: LoadQuestPOI ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-08-28 01:44:35 +03:00
mQuestPOIMap . clear (); // need for reload case
2010-09-12 01:40:27 +02:00
2010-02-14 19:13:14 -07:00
uint32 count = 0 ;
2010-04-07 18:09:10 +02:00
2010-09-17 04:25:00 +02:00
// 0 1 2 3 4 5 6 7
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT questId, id, objIndex, mapid, WorldMapAreaId, FloorId, unk3, unk4 FROM quest_poi order by questId" );
2010-04-07 18:09:10 +02:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2010-02-14 19:13:14 -07:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty." );
sLog -> outString ();
2010-02-14 19:13:14 -07:00
return ;
}
2010-04-07 18:09:10 +02:00
2010-09-17 04:25:00 +02:00
// 0 1 2 3
QueryResult points = WorldDatabase . PQuery ( "SELECT questId, id, x, y FROM quest_poi_points ORDER BY questId DESC, idx" );
2010-09-17 14:58:30 +02:00
std :: vector < std :: vector < std :: vector < QuestPOIPoint > > > POIs ;
2010-09-17 04:25:00 +02:00
if ( points )
{
// The first result should have the highest questId
Field * fields = points -> Fetch ();
uint32 questId = fields [ 0 ]. GetUInt32 ();
POIs . resize ( questId + 1 );
do
{
2010-09-17 14:58:30 +02:00
2010-09-17 04:25:00 +02:00
Field * fields = points -> Fetch ();
uint32 questId = fields [ 0 ]. GetUInt32 ();
uint32 id = fields [ 1 ]. GetUInt32 ();
int32 x = fields [ 2 ]. GetInt32 ();
int32 y = fields [ 3 ]. GetInt32 ();
2011-06-12 02:30:32 +02:00
if ( POIs [ questId ]. size () <= id + 1 )
2010-09-17 04:25:00 +02:00
POIs [ questId ]. resize ( id + 10 );
QuestPOIPoint point ( x , y );
POIs [ questId ][ id ]. push_back ( point );
} while ( points -> NextRow ());
}
2010-02-14 19:13:14 -07:00
do
{
Field * fields = result -> Fetch ();
2010-04-07 18:09:10 +02:00
2010-02-14 19:13:14 -07:00
uint32 questId = fields [ 0 ]. GetUInt32 ();
uint32 id = fields [ 1 ]. GetUInt32 ();
int32 objIndex = fields [ 2 ]. GetInt32 ();
uint32 mapId = fields [ 3 ]. GetUInt32 ();
uint32 WorldMapAreaId = fields [ 4 ]. GetUInt32 ();
uint32 FloorId = fields [ 5 ]. GetUInt32 ();
uint32 unk3 = fields [ 6 ]. GetUInt32 ();
uint32 unk4 = fields [ 7 ]. GetUInt32 ();
2010-03-20 21:26:29 +01:00
QuestPOI POI ( id , objIndex , mapId , WorldMapAreaId , FloorId , unk3 , unk4 );
2010-09-17 04:25:00 +02:00
POI . points = POIs [ questId ][ id ];
2010-04-07 18:09:10 +02:00
2010-02-14 19:13:14 -07:00
mQuestPOIMap [ questId ]. push_back ( POI );
2010-04-07 18:09:10 +02:00
2010-02-14 19:13:14 -07:00
++ count ;
} while ( result -> NextRow ());
2010-04-07 18:09:10 +02:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u quest POI definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-02-14 19:13:14 -07:00
}
2009-05-05 16:56:15 -05:00
void ObjectMgr :: LoadNPCSpellClickSpells ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-10-17 15:51:44 -07:00
2009-05-05 16:56:15 -05:00
mSpellClickInfoMap . clear ();
2009-08-17 02:53:39 +02:00
// 0 1 2 3 4 5 6 7 8
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT npc_entry, spell_id, quest_start, quest_start_active, quest_end, cast_flags, aura_required, aura_forbidden, user_type FROM npc_spellclick_spells" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2009-05-05 16:56:15 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 spellclick spells. DB table `npc_spellclick_spells` is empty." );
sLog -> outString ();
2009-05-05 16:56:15 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2009-05-05 16:56:15 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-05-05 16:56:15 -05:00
uint32 npc_entry = fields [ 0 ]. GetUInt32 ();
2011-04-28 22:57:08 +02:00
CreatureTemplate const * cInfo = GetCreatureTemplate ( npc_entry );
2009-05-05 16:56:15 -05:00
if ( ! cInfo )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table npc_spellclick_spells references unknown creature_template %u. Skipping entry." , npc_entry );
2009-05-05 16:56:15 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-05-05 16:56:15 -05:00
uint32 spellid = fields [ 1 ]. GetUInt32 ();
2011-07-26 23:09:28 +02:00
SpellInfo const * spellinfo = sSpellMgr -> GetSpellInfo ( spellid );
2009-05-05 16:56:15 -05:00
if ( ! spellinfo )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table npc_spellclick_spells references unknown spellid %u. Skipping entry." , spellid );
2009-05-05 16:56:15 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2009-08-17 02:53:39 +02:00
uint32 auraRequired = fields [ 6 ]. GetUInt32 ();
if ( auraRequired )
{
2011-07-26 23:09:28 +02:00
SpellInfo const * aurReqInfo = sSpellMgr -> GetSpellInfo ( auraRequired );
2009-08-17 02:53:39 +02:00
if ( ! aurReqInfo )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table npc_spellclick_spells references unknown aura required %u. Skipping entry." , auraRequired );
2009-08-17 02:53:39 +02:00
continue ;
}
}
2009-10-17 15:51:44 -07:00
2009-08-17 02:53:39 +02:00
uint32 auraForbidden = fields [ 7 ]. GetUInt32 ();
if ( auraForbidden )
{
2011-07-26 23:09:28 +02:00
SpellInfo const * aurForInfo = sSpellMgr -> GetSpellInfo ( auraForbidden );
2009-08-17 02:53:39 +02:00
if ( ! aurForInfo )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table npc_spellclick_spells references unknown aura forbidden %u. Skipping entry." , auraForbidden );
2009-08-17 02:53:39 +02:00
continue ;
}
}
2009-10-17 15:51:44 -07:00
2009-06-15 23:07:43 -05:00
uint32 quest_start = fields [ 2 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-05-05 16:56:15 -05:00
// quest might be 0 to enable spellclick independent of any quest
2009-06-15 23:07:43 -05:00
if ( quest_start )
2009-05-05 16:56:15 -05:00
{
2010-04-07 19:14:10 +02:00
if ( mQuestTemplates . find ( quest_start ) == mQuestTemplates . end ())
2009-05-05 16:56:15 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table npc_spellclick_spells references unknown start quest %u. Skipping entry." , quest_start );
2009-05-05 16:56:15 -05:00
continue ;
}
}
2009-10-17 15:51:44 -07:00
2009-06-15 23:07:43 -05:00
bool quest_start_active = fields [ 3 ]. GetBool ();
2009-10-17 15:51:44 -07:00
2009-06-15 23:07:43 -05:00
uint32 quest_end = fields [ 4 ]. GetUInt32 ();
// quest might be 0 to enable spellclick active infinity after start quest
if ( quest_end )
{
2010-04-07 19:14:10 +02:00
if ( mQuestTemplates . find ( quest_end ) == mQuestTemplates . end ())
2009-06-15 23:07:43 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table npc_spellclick_spells references unknown end quest %u. Skipping entry." , quest_end );
2009-06-15 23:07:43 -05:00
continue ;
}
}
2009-10-17 15:51:44 -07:00
2009-08-17 02:53:39 +02:00
uint8 userType = fields [ 8 ]. GetUInt8 ();
if ( userType >= SPELL_CLICK_USER_MAX )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table npc_spellclick_spells references unknown user type %u. Skipping entry." , uint32 ( userType ));
2009-10-17 15:51:44 -07:00
2009-06-15 23:07:43 -05:00
uint8 castFlags = fields [ 5 ]. GetUInt8 ();
2009-05-05 16:56:15 -05:00
SpellClickInfo info ;
info . spellId = spellid ;
2009-06-15 23:07:43 -05:00
info . questStart = quest_start ;
info . questStartCanActive = quest_start_active ;
info . questEnd = quest_end ;
2009-05-05 16:56:15 -05:00
info . castFlags = castFlags ;
2009-08-17 02:53:39 +02:00
info . auraRequired = auraRequired ;
info . auraForbidden = auraForbidden ;
2009-08-17 19:29:33 +02:00
info . userType = SpellClickUserTypes ( userType );
2009-05-05 16:56:15 -05:00
mSpellClickInfoMap . insert ( SpellClickInfoMap :: value_type ( npc_entry , info ));
2009-10-17 15:51:44 -07:00
2009-05-05 16:56:15 -05:00
++ count ;
2010-12-19 17:06:33 +01:00
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2011-03-06 11:12:19 +01:00
// all spellclick data loaded, now we check if there are creatures with NPC_FLAG_SPELLCLICK but with no data
// NOTE: It *CAN* be the other way around: no spellclick flag but with spellclick data, in case of creature-only vehicle accessories
2011-04-28 22:57:08 +02:00
CreatureTemplateContainer const * ctc = sObjectMgr -> GetCreatureTemplates ();
for ( CreatureTemplateContainer :: const_iterator itr = ctc -> begin (); itr != ctc -> end (); ++ itr )
2011-03-06 11:12:19 +01:00
{
2011-04-28 22:57:08 +02:00
if (( itr -> second . npcflag & UNIT_NPC_FLAG_SPELLCLICK ) && mSpellClickInfoMap . find ( itr -> second . Entry ) == mSpellClickInfoMap . end ())
2011-03-06 11:12:19 +01:00
{
2011-04-28 22:57:08 +02:00
sLog -> outErrorDb ( "npc_spellclick_spells: Creature template %u has UNIT_NPC_FLAG_SPELLCLICK but no data in spellclick table! Removing flag" , itr -> second . Entry );
const_cast < CreatureTemplate *> ( & itr -> second ) -> npcflag &= ~ UNIT_NPC_FLAG_SPELLCLICK ;
2011-03-06 11:12:19 +01:00
}
}
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u spellclick definitions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2009-05-05 16:56:15 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: SaveCreatureRespawnTime ( uint32 loguid , uint32 instance , time_t t )
{
2010-12-23 05:49:23 +01:00
if ( ! t )
{
// Delete only
RemoveCreatureRespawnTime ( loguid , instance );
return ;
}
2011-01-26 01:03:35 +01:00
2010-12-23 05:49:23 +01:00
// This function can be called from various map threads concurrently
2010-08-13 01:16:50 +02:00
{
2010-11-10 21:57:33 +01:00
m_CreatureRespawnTimesMtx . acquire ();
2010-12-23 05:49:23 +01:00
mCreatureRespawnTimes [ MAKE_PAIR64 ( loguid , instance )] = t ;
2010-11-10 21:57:33 +01:00
m_CreatureRespawnTimesMtx . release ();
2010-08-13 01:16:50 +02:00
}
2011-04-13 17:02:06 +06:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_ADD_CREATURE_RESPAWN );
2010-09-03 00:44:27 +02:00
stmt -> setUInt32 ( 0 , loguid );
2010-12-23 05:49:23 +01:00
stmt -> setUInt64 ( 1 , uint64 ( t ));
stmt -> setUInt32 ( 2 , instance );
2010-11-19 15:53:14 +01:00
CharacterDatabase . Execute ( stmt );
2010-12-23 05:49:23 +01:00
}
2010-09-03 00:44:27 +02:00
2010-12-23 05:49:23 +01:00
void ObjectMgr :: RemoveCreatureRespawnTime ( uint32 loguid , uint32 instance )
{
// This function can be called from various map threads concurrently
2010-09-03 00:44:27 +02:00
{
2010-12-23 05:49:23 +01:00
m_CreatureRespawnTimesMtx . acquire ();
mCreatureRespawnTimes [ MAKE_PAIR64 ( loguid , instance )] = 0 ;
m_CreatureRespawnTimesMtx . release ();
2010-09-03 00:44:27 +02:00
}
2010-12-23 05:49:23 +01:00
2011-04-13 17:02:06 +06:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_CREATURE_RESPAWN );
2010-12-23 05:49:23 +01:00
stmt -> setUInt32 ( 0 , loguid );
stmt -> setUInt32 ( 1 , instance );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: DeleteCreatureData ( uint32 guid )
{
// remove mapid*cellid -> guid_set map
CreatureData const * data = GetCreatureData ( guid );
2010-04-07 19:14:10 +02:00
if ( data )
2008-10-11 14:16:25 -05:00
RemoveCreatureFromGrid ( guid , data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
mCreatureDataMap . erase ( guid );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: SaveGORespawnTime ( uint32 loguid , uint32 instance , time_t t )
2010-12-23 05:49:23 +01:00
{
if ( ! t )
{
// Delete only
RemoveGORespawnTime ( loguid , instance );
return ;
}
2011-01-26 01:03:35 +01:00
2010-12-23 05:49:23 +01:00
// This function can be called from different map threads concurrently
{
m_GORespawnTimesMtx . acquire ();
mGORespawnTimes [ MAKE_PAIR64 ( loguid , instance )] = t ;
m_GORespawnTimesMtx . release ();
}
2011-04-13 17:02:06 +06:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_ADD_GO_RESPAWN );
2010-12-23 05:49:23 +01:00
stmt -> setUInt32 ( 0 , loguid );
stmt -> setUInt64 ( 1 , uint64 ( t ));
stmt -> setUInt32 ( 2 , instance );
CharacterDatabase . Execute ( stmt );
}
void ObjectMgr :: RemoveGORespawnTime ( uint32 loguid , uint32 instance )
2008-10-11 14:16:25 -05:00
{
2010-08-13 01:16:50 +02:00
// This function can be called from different map threads concurrently
{
2010-11-10 21:57:33 +01:00
m_GORespawnTimesMtx . acquire ();
2010-12-23 05:49:23 +01:00
mGORespawnTimes [ MAKE_PAIR64 ( loguid , instance )] = 0 ;
2010-11-10 21:57:33 +01:00
m_GORespawnTimesMtx . release ();
2010-08-13 01:16:50 +02:00
}
2011-04-13 17:02:06 +06:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GO_RESPAWN );
2010-12-23 05:49:23 +01:00
stmt -> setUInt32 ( 0 , loguid );
stmt -> setUInt32 ( 1 , instance );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: DeleteRespawnTimeForInstance ( uint32 instance )
{
2010-08-13 01:16:50 +02:00
// This function can be called from different map threads concurrently
2008-10-11 14:16:25 -05:00
RespawnTimes :: iterator next ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
{
2010-11-10 21:57:33 +01:00
m_GORespawnTimesMtx . acquire ();
2010-08-13 01:16:50 +02:00
for ( RespawnTimes :: iterator itr = mGORespawnTimes . begin (); itr != mGORespawnTimes . end (); itr = next )
{
next = itr ;
++ next ;
2009-10-17 15:51:44 -07:00
2010-08-13 01:16:50 +02:00
if ( GUID_HIPART ( itr -> first ) == instance )
mGORespawnTimes . erase ( itr );
}
2010-11-10 21:57:33 +01:00
m_GORespawnTimesMtx . release ();
2008-10-11 14:16:25 -05:00
}
{
2010-11-10 21:57:33 +01:00
m_CreatureRespawnTimesMtx . acquire ();
2010-08-13 01:16:50 +02:00
for ( RespawnTimes :: iterator itr = mCreatureRespawnTimes . begin (); itr != mCreatureRespawnTimes . end (); itr = next )
{
next = itr ;
++ next ;
2009-10-17 15:51:44 -07:00
2010-08-13 01:16:50 +02:00
if ( GUID_HIPART ( itr -> first ) == instance )
mCreatureRespawnTimes . erase ( itr );
}
2010-11-10 21:57:33 +01:00
m_CreatureRespawnTimesMtx . release ();
2008-10-11 14:16:25 -05:00
}
2011-04-13 17:02:06 +06:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE );
stmt -> setUInt32 ( 0 , instance );
CharacterDatabase . Execute ( stmt );
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GO_RESPAWN_BY_INSTANCE );
stmt -> setUInt32 ( 0 , instance );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: DeleteGOData ( uint32 guid )
{
// remove mapid*cellid -> guid_set map
GameObjectData const * data = GetGOData ( guid );
2010-04-07 19:14:10 +02:00
if ( data )
2008-10-11 14:16:25 -05:00
RemoveGameobjectFromGrid ( guid , data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
mGameObjectDataMap . erase ( guid );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: AddCorpseCellData ( uint32 mapid , uint32 cellid , uint32 player_guid , uint32 instance )
{
// corpses are always added to spawn mode 0 and they are spawned by their instance id
2011-04-29 20:47:02 +02:00
CellObjectGuids & cell_guids = mMapObjectGuids [ MAKE_PAIR32 ( mapid , 0 )][ cellid ];
2008-10-11 14:16:25 -05:00
cell_guids . corpses [ player_guid ] = instance ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: DeleteCorpseCellData ( uint32 mapid , uint32 cellid , uint32 player_guid )
{
// corpses are always added to spawn mode 0 and they are spawned by their instance id
2011-04-29 20:47:02 +02:00
CellObjectGuids & cell_guids = mMapObjectGuids [ MAKE_PAIR32 ( mapid , 0 )][ cellid ];
2008-10-11 14:16:25 -05:00
cell_guids . corpses . erase ( player_guid );
}
2009-10-17 15:51:44 -07:00
2010-09-14 13:56:27 +02:00
void ObjectMgr :: LoadQuestRelationsHelper ( QuestRelations & map , std :: string table , bool starter , bool go )
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
map . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2010-09-14 13:56:27 +02:00
QueryResult result = WorldDatabase . PQuery ( "SELECT id, quest, pool_entry FROM %s qr LEFT JOIN pool_quest pq ON qr.quest = pq.entry" , table . c_str ());
2009-10-17 15:51:44 -07:00
2010-01-01 14:19:29 -06:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 quest relations from `%s`, table is empty." , table . c_str ());
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-22 21:25:23 +01:00
PooledQuestRelation * poolRelationMap = go ? & sPoolMgr -> mQuestGORelation : & sPoolMgr -> mQuestCreatureRelation ;
2010-09-14 13:56:27 +02:00
if ( starter )
poolRelationMap -> clear ();
2008-10-11 14:16:25 -05:00
do
{
2009-10-17 15:51:44 -07:00
2010-09-14 13:56:27 +02:00
uint32 id = result -> Fetch ()[ 0 ]. GetUInt32 ();
uint32 quest = result -> Fetch ()[ 1 ]. GetUInt32 ();
uint32 poolId = result -> Fetch ()[ 2 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( mQuestTemplates . find ( quest ) == mQuestTemplates . end ())
2008-10-11 14:16:25 -05:00
{
2011-02-19 14:43:36 +01:00
sLog -> outErrorDb ( "Table `%s`: Quest %u listed for entry %u does not exist." , table . c_str (), quest , id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-09-14 13:56:27 +02:00
if ( ! poolId || ! starter )
map . insert ( QuestRelations :: value_type ( id , quest ));
else if ( starter )
poolRelationMap -> insert ( PooledQuestRelation :: value_type ( quest , id ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u quest relations from %s in %u ms" , count , table . c_str (), GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGameobjectQuestRelations ()
{
2010-09-14 13:56:27 +02:00
LoadQuestRelationsHelper ( mGOQuestRelations , "gameobject_questrelation" , true , true );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( QuestRelations :: iterator itr = mGOQuestRelations . begin (); itr != mGOQuestRelations . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * goInfo = GetGameObjectTemplate ( itr -> first );
2010-04-07 19:14:10 +02:00
if ( ! goInfo )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject_questrelation` have data for not existed gameobject entry (%u) and existed quest %u" , itr -> first , itr -> second );
2010-04-07 19:14:10 +02:00
else if ( goInfo -> type != GAMEOBJECT_TYPE_QUESTGIVER )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject_questrelation` have data gameobject entry (%u) for quest %u, but GO is not GAMEOBJECT_TYPE_QUESTGIVER" , itr -> first , itr -> second );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGameobjectInvolvedRelations ()
{
2010-09-14 13:56:27 +02:00
LoadQuestRelationsHelper ( mGOQuestInvolvedRelations , "gameobject_involvedrelation" , false , true );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( QuestRelations :: iterator itr = mGOQuestInvolvedRelations . begin (); itr != mGOQuestInvolvedRelations . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * goInfo = GetGameObjectTemplate ( itr -> first );
2010-04-07 19:14:10 +02:00
if ( ! goInfo )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject_involvedrelation` have data for not existed gameobject entry (%u) and existed quest %u" , itr -> first , itr -> second );
2010-04-07 19:14:10 +02:00
else if ( goInfo -> type != GAMEOBJECT_TYPE_QUESTGIVER )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `gameobject_involvedrelation` have data gameobject entry (%u) for quest %u, but GO is not GAMEOBJECT_TYPE_QUESTGIVER" , itr -> first , itr -> second );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadCreatureQuestRelations ()
{
2010-09-14 13:56:27 +02:00
LoadQuestRelationsHelper ( mCreatureQuestRelations , "creature_questrelation" , true , false );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( QuestRelations :: iterator itr = mCreatureQuestRelations . begin (); itr != mCreatureQuestRelations . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:57:08 +02:00
CreatureTemplate const * cInfo = GetCreatureTemplate ( itr -> first );
2010-04-07 19:14:10 +02:00
if ( ! cInfo )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `creature_questrelation` have data for not existed creature entry (%u) and existed quest %u" , itr -> first , itr -> second );
2010-04-07 19:14:10 +02:00
else if ( ! ( cInfo -> npcflag & UNIT_NPC_FLAG_QUESTGIVER ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `creature_questrelation` has creature entry (%u) for quest %u, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER" , itr -> first , itr -> second );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadCreatureInvolvedRelations ()
{
2010-09-14 13:56:27 +02:00
LoadQuestRelationsHelper ( mCreatureQuestInvolvedRelations , "creature_involvedrelation" , false , false );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( QuestRelations :: iterator itr = mCreatureQuestInvolvedRelations . begin (); itr != mCreatureQuestInvolvedRelations . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:57:08 +02:00
CreatureTemplate const * cInfo = GetCreatureTemplate ( itr -> first );
2010-04-07 19:14:10 +02:00
if ( ! cInfo )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `creature_involvedrelation` have data for not existed creature entry (%u) and existed quest %u" , itr -> first , itr -> second );
2010-04-07 19:14:10 +02:00
else if ( ! ( cInfo -> npcflag & UNIT_NPC_FLAG_QUESTGIVER ))
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `creature_involvedrelation` has creature entry (%u) for quest %u, but npcflag does not include UNIT_NPC_FLAG_QUESTGIVER" , itr -> first , itr -> second );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadReservedPlayersNames ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
m_ReservedNames . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2010-11-19 15:53:14 +01:00
QueryResult result = CharacterDatabase . Query ( "SELECT name FROM reserved_name" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 reserved player names. DB table `reserved_name` is empty!" );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields ;
do
{
fields = result -> Fetch ();
2010-09-24 22:16:21 +02:00
std :: string name = fields [ 0 ]. GetString ();
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
std :: wstring wstr ;
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( name , wstr ))
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Table `reserved_name` have invalid name: %s" , name . c_str ());
2009-01-25 16:35:14 -06:00
continue ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
wstrToLower ( wstr );
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
m_ReservedNames . insert ( wstr );
++ count ;
2010-12-19 17:06:33 +01:00
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u reserved player names in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
bool ObjectMgr :: IsReservedName ( const std :: string & name ) const
2009-01-25 16:35:14 -06:00
{
std :: wstring wstr ;
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( name , wstr ))
2009-01-25 16:35:14 -06:00
return false ;
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
wstrToLower ( wstr );
2009-10-17 15:51:44 -07:00
2009-01-25 16:35:14 -06:00
return m_ReservedNames . find ( wstr ) != m_ReservedNames . end ();
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
enum LanguageType
{
LT_BASIC_LATIN = 0x0000 ,
LT_EXTENDEN_LATIN = 0x0001 ,
LT_CYRILLIC = 0x0002 ,
LT_EAST_ASIA = 0x0004 ,
LT_ANY = 0xFFFF
};
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
static LanguageType GetRealmLanguageType ( bool create )
{
2010-12-23 23:25:44 +01:00
switch ( sWorld -> getIntConfig ( CONFIG_REALM_ZONE ))
2008-10-11 14:16:25 -05:00
{
case REALM_ZONE_UNKNOWN : // any language
case REALM_ZONE_DEVELOPMENT :
case REALM_ZONE_TEST_SERVER :
case REALM_ZONE_QA_SERVER :
return LT_ANY ;
case REALM_ZONE_UNITED_STATES : // extended-Latin
case REALM_ZONE_OCEANIC :
case REALM_ZONE_LATIN_AMERICA :
case REALM_ZONE_ENGLISH :
case REALM_ZONE_GERMAN :
case REALM_ZONE_FRENCH :
case REALM_ZONE_SPANISH :
return LT_EXTENDEN_LATIN ;
case REALM_ZONE_KOREA : // East-Asian
case REALM_ZONE_TAIWAN :
case REALM_ZONE_CHINA :
return LT_EAST_ASIA ;
case REALM_ZONE_RUSSIAN : // Cyrillic
return LT_CYRILLIC ;
default :
return create ? LT_BASIC_LATIN : LT_ANY ; // basic-Latin at create, any at login
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool isValidString ( std :: wstring wstr , uint32 strictMask , bool numericOrSpace , bool create = false )
{
2010-04-07 23:25:02 +02:00
if ( strictMask == 0 ) // any language, ignore realm
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
if ( isExtendedLatinString ( wstr , numericOrSpace ))
2008-10-11 14:16:25 -05:00
return true ;
2011-04-29 20:47:02 +02:00
if ( isCyrillicString ( wstr , numericOrSpace ))
2008-10-11 14:16:25 -05:00
return true ;
2011-04-29 20:47:02 +02:00
if ( isEastAsianString ( wstr , numericOrSpace ))
2008-10-11 14:16:25 -05:00
return true ;
return false ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( strictMask & 0x2 ) // realm zone specific
2008-10-11 14:16:25 -05:00
{
LanguageType lt = GetRealmLanguageType ( create );
2010-04-07 19:14:10 +02:00
if ( lt & LT_EXTENDEN_LATIN )
2011-04-29 20:47:02 +02:00
if ( isExtendedLatinString ( wstr , numericOrSpace ))
2008-10-11 14:16:25 -05:00
return true ;
2010-04-07 19:14:10 +02:00
if ( lt & LT_CYRILLIC )
2011-04-29 20:47:02 +02:00
if ( isCyrillicString ( wstr , numericOrSpace ))
2008-10-11 14:16:25 -05:00
return true ;
2010-04-07 19:14:10 +02:00
if ( lt & LT_EAST_ASIA )
2011-04-29 20:47:02 +02:00
if ( isEastAsianString ( wstr , numericOrSpace ))
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( strictMask & 0x1 ) // basic Latin
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
if ( isBasicLatinString ( wstr , numericOrSpace ))
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
uint8 ObjectMgr :: CheckPlayerName ( const std :: string & name , bool create )
2008-10-11 14:16:25 -05:00
{
std :: wstring wname ;
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( name , wname ))
2009-07-10 08:25:33 +08:00
return CHAR_NAME_INVALID_CHARACTER ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( wname . size () > MAX_PLAYER_NAME )
2009-07-10 08:25:33 +08:00
return CHAR_NAME_TOO_LONG ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
uint32 minName = sWorld -> getIntConfig ( CONFIG_MIN_PLAYER_NAME );
2010-04-07 19:14:10 +02:00
if ( wname . size () < minName )
2009-07-10 08:25:33 +08:00
return CHAR_NAME_TOO_SHORT ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
uint32 strictMask = sWorld -> getIntConfig ( CONFIG_STRICT_PLAYER_NAMES );
2011-04-29 20:47:02 +02:00
if ( ! isValidString ( wname , strictMask , false , create ))
2009-07-10 08:25:33 +08:00
return CHAR_NAME_MIXED_LANGUAGES ;
2009-10-17 15:51:44 -07:00
2009-07-10 08:25:33 +08:00
return CHAR_NAME_SUCCESS ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
bool ObjectMgr :: IsValidCharterName ( const std :: string & name )
2008-10-11 14:16:25 -05:00
{
std :: wstring wname ;
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( name , wname ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( wname . size () > MAX_CHARTER_NAME )
2009-07-10 08:25:33 +08:00
return false ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
uint32 minName = sWorld -> getIntConfig ( CONFIG_MIN_CHARTER_NAME );
2010-04-07 19:14:10 +02:00
if ( wname . size () < minName )
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
uint32 strictMask = sWorld -> getIntConfig ( CONFIG_STRICT_CHARTER_NAMES );
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
return isValidString ( wname , strictMask , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
PetNameInvalidReason ObjectMgr :: CheckPetName ( const std :: string & name )
2008-10-11 14:16:25 -05:00
{
std :: wstring wname ;
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( name , wname ))
2009-07-10 08:25:33 +08:00
return PET_NAME_INVALID ;
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( wname . size () > MAX_PET_NAME )
2009-07-10 08:25:33 +08:00
return PET_NAME_TOO_LONG ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
uint32 minName = sWorld -> getIntConfig ( CONFIG_MIN_PET_NAME );
2010-04-07 19:14:10 +02:00
if ( wname . size () < minName )
2009-07-10 08:25:33 +08:00
return PET_NAME_TOO_SHORT ;
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
uint32 strictMask = sWorld -> getIntConfig ( CONFIG_STRICT_PET_NAMES );
2011-04-29 20:47:02 +02:00
if ( ! isValidString ( wname , strictMask , false ))
2009-07-10 08:25:33 +08:00
return PET_NAME_MIXED_LANGUAGES ;
2009-10-17 15:51:44 -07:00
2009-07-10 08:25:33 +08:00
return PET_NAME_SUCCESS ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGameObjectForQuests ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-10-11 14:16:25 -05:00
mGameObjectForQuestSet . clear (); // need for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 19:59:40 +02:00
if ( sObjectMgr -> GetGameObjectTemplates () -> empty ())
2009-01-22 22:44:27 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 GameObjects for quests" );
sLog -> outString ();
2009-01-22 22:44:27 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// collect GO entries for GO that must activated
2011-04-28 22:54:30 +02:00
GameObjectTemplateContainer const * gotc = sObjectMgr -> GetGameObjectTemplates ();
for ( GameObjectTemplateContainer :: const_iterator itr = gotc -> begin (); itr != gotc -> end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
switch ( itr -> second . type )
2008-10-11 14:16:25 -05:00
{
// scan GO chest with loot including quest items
case GAMEOBJECT_TYPE_CHEST :
{
2011-04-28 22:54:30 +02:00
uint32 loot_id = ( itr -> second . GetLootId ());
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// find quest loot for GO
2011-04-28 22:54:30 +02:00
if ( itr -> second . chest . questId || LootTemplates_Gameobject . HaveQuestLootFor ( loot_id ))
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
mGameObjectForQuestSet . insert ( itr -> second . entry );
2008-10-11 14:16:25 -05:00
++ count ;
}
break ;
}
2010-10-06 16:36:50 -06:00
case GAMEOBJECT_TYPE_GENERIC :
{
2011-04-28 22:54:30 +02:00
if ( itr -> second . _generic . questID > 0 ) //quests objects
2010-10-06 16:36:50 -06:00
{
2011-04-28 22:54:30 +02:00
mGameObjectForQuestSet . insert ( itr -> second . entry );
2010-10-06 16:36:50 -06:00
count ++ ;
}
break ;
}
2008-10-11 14:16:25 -05:00
case GAMEOBJECT_TYPE_GOOBER :
{
2011-04-28 22:54:30 +02:00
if ( itr -> second . goober . questId > 0 ) //quests objects
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:54:30 +02:00
mGameObjectForQuestSet . insert ( itr -> second . entry );
2008-10-11 14:16:25 -05:00
count ++ ;
}
break ;
}
default :
break ;
}
}
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u GameObjects for quests in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-09-02 17:47:50 +02:00
bool ObjectMgr :: LoadTrinityStrings ( char const * table , int32 min_value , int32 max_value )
2008-10-11 14:16:25 -05:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-05-15 16:41:36 -05:00
int32 start_value = min_value ;
int32 end_value = max_value ;
// some string can have negative indexes range
if ( start_value < 0 )
{
if ( end_value >= start_value )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table '%s' attempt loaded with invalid range (%d - %d), strings not loaded." , table , min_value , max_value );
2009-05-15 16:41:36 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
// real range (max+1, min+1) exaple: (-10, -1000) -> -999...-10+1
std :: swap ( start_value , end_value );
2009-05-15 16:41:36 -05:00
++ start_value ;
++ end_value ;
}
else
{
if ( start_value >= end_value )
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table '%s' attempt loaded with invalid range (%d - %d), strings not loaded." , table , min_value , max_value );
2009-05-15 16:41:36 -05:00
return false ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// cleanup affected map part for reloading case
2009-11-20 19:11:28 -08:00
for ( TrinityStringLocaleMap :: iterator itr = mTrinityStringLocaleMap . begin (); itr != mTrinityStringLocaleMap . end ();)
2008-10-11 14:16:25 -05:00
{
2009-05-15 16:41:36 -05:00
if ( itr -> first >= start_value && itr -> first < end_value )
2009-05-18 15:07:14 -05:00
mTrinityStringLocaleMap . erase ( itr ++ );
2008-10-11 14:16:25 -05:00
else
++ itr ;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . PQuery ( "SELECT entry, content_default, content_loc1, content_loc2, content_loc3, content_loc4, content_loc5, content_loc6, content_loc7, content_loc8 FROM %s" , table );
2009-10-17 15:51:44 -07:00
2009-05-15 16:41:36 -05:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2009-10-17 15:51:44 -07:00
2009-05-15 16:41:36 -05:00
if ( min_value == MIN_TRINITY_STRING_ID ) // error only in case internal strings
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( ">> Loaded 0 trinity strings. DB table `%s` is empty. Cannot continue." , table );
2008-10-11 14:16:25 -05:00
else
2011-04-29 20:47:02 +02:00
sLog -> outString ( ">> Loaded 0 string templates. DB table `%s` is empty." , table );
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
int32 entry = fields [ 0 ]. GetInt32 ();
2009-10-17 15:51:44 -07:00
2010-04-07 23:25:02 +02:00
if ( entry == 0 )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `%s` contain reserved entry 0, ignored." , table );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-05-15 16:41:36 -05:00
else if ( entry < start_value || entry >= end_value )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `%s` contain entry %i out of allowed range (%d - %d), ignored." , table , entry , min_value , max_value );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-14 11:57:03 -05:00
TrinityStringLocale & data = mTrinityStringLocaleMap [ entry ];
2009-10-17 15:51:44 -07:00
2011-07-01 14:58:44 +02:00
if ( ! data . Content . empty ())
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `%s` contain data for already loaded entry %i (from another table?), ignored." , table , entry );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data . Content . resize ( 1 );
++ count ;
2009-10-17 15:51:44 -07:00
2010-09-28 08:21:51 +03:00
for ( uint8 i = 0 ; i < TOTAL_LOCALES ; ++ i )
2011-08-04 15:14:15 +02:00
AddLocaleString ( fields [ i + 1 ]. GetString (), LocaleConstant ( i ), data . Content );
2008-10-11 14:16:25 -05:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2009-05-15 16:41:36 -05:00
if ( min_value == MIN_TRINITY_STRING_ID )
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u Trinity strings from table %s in %u ms" , count , table , GetMSTimeDiffToNow ( oldMSTime ));
2008-10-11 14:16:25 -05:00
else
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u string templates from %s in %u ms" , count , table , GetMSTimeDiffToNow ( oldMSTime ));
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-09-17 07:04:29 +02:00
const char * ObjectMgr :: GetTrinityString ( int32 entry , LocaleConstant locale_idx ) const
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( TrinityStringLocale const * msl = GetTrinityStringLocale ( entry ))
2008-10-11 14:16:25 -05:00
{
2010-09-17 07:04:29 +02:00
if ( msl -> Content . size () > size_t ( locale_idx ) && ! msl -> Content [ locale_idx ]. empty ())
return msl -> Content [ locale_idx ]. c_str ();
return msl -> Content [ DEFAULT_LOCALE ]. c_str ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( entry > 0 )
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Entry %i not found in `trinity_string` table." , entry );
2008-10-11 14:16:25 -05:00
else
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Trinity string entry %i not found in DB." , entry );
2008-10-11 14:16:25 -05:00
return "<error>" ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadFishingBaseSkillLevel ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-14 16:28:45 -06:00
mFishingBaseForArea . clear (); // for reload case
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, skill FROM skill_fishing_base_level" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 areas for fishing base skill level. DB table `skill_fishing_base_level` is empty." );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
uint32 entry = fields [ 0 ]. GetUInt32 ();
int32 skill = fields [ 1 ]. GetInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AreaTableEntry const * fArea = GetAreaEntryByAreaID ( entry );
2010-04-07 19:14:10 +02:00
if ( ! fArea )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "AreaId %u defined in `skill_fishing_base_level` does not exist" , entry );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
mFishingBaseForArea [ entry ] = skill ;
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u areas for fishing base skill level in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-05-10 18:52:28 +07:00
bool ObjectMgr :: CheckDeclinedNames ( std :: wstring w_ownname , DeclinedName const & names )
2008-10-11 14:16:25 -05:00
{
2011-05-10 18:52:28 +07:00
// get main part of the name
std :: wstring mainpart = GetMainPartOfName ( w_ownname , 0 );
// prepare flags
bool x = true ;
bool y = true ;
// check declined names
2009-10-17 16:20:24 -07:00
for ( uint8 i = 0 ; i < MAX_DECLINED_NAME_CASES ; ++ i )
2008-10-11 14:16:25 -05:00
{
std :: wstring wname ;
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( names . name [ i ], wname ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( mainpart != GetMainPartOfName ( wname , i + 1 ))
2011-05-10 18:52:28 +07:00
x = false ;
2011-05-17 13:17:42 +02:00
2011-05-10 18:52:28 +07:00
if ( w_ownname != wname )
y = false ;
2008-10-11 14:16:25 -05:00
}
2011-05-10 18:52:28 +07:00
return ( x || y );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-20 16:16:57 -06:00
uint32 ObjectMgr :: GetAreaTriggerScriptId ( uint32 trigger_id )
2008-10-11 14:16:25 -05:00
{
2008-11-20 16:16:57 -06:00
AreaTriggerScriptMap :: const_iterator i = mAreaTriggerScripts . find ( trigger_id );
2010-04-07 19:14:10 +02:00
if ( i != mAreaTriggerScripts . end ())
2008-11-20 16:16:57 -06:00
return i -> second ;
return 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-07-24 22:41:42 +02:00
SpellScriptsBounds ObjectMgr :: GetSpellScriptsBounds ( uint32 spell_id )
{
2011-04-29 20:47:02 +02:00
return SpellScriptsBounds ( mSpellScripts . lower_bound ( spell_id ), mSpellScripts . upper_bound ( spell_id ));
2010-07-24 22:41:42 +02:00
}
2008-10-11 14:16:25 -05:00
SkillRangeType GetSkillRangeType ( SkillLineEntry const * pSkill , bool racial )
{
switch ( pSkill -> categoryId )
{
case SKILL_CATEGORY_LANGUAGES : return SKILL_RANGE_LANGUAGE ;
case SKILL_CATEGORY_WEAPON :
2010-04-08 08:20:08 +02:00
if ( pSkill -> id != SKILL_FIST_WEAPONS )
2008-10-11 14:16:25 -05:00
return SKILL_RANGE_LEVEL ;
else
return SKILL_RANGE_MONO ;
case SKILL_CATEGORY_ARMOR :
case SKILL_CATEGORY_CLASS :
2010-04-07 19:14:10 +02:00
if ( pSkill -> id != SKILL_LOCKPICKING )
2008-10-11 14:16:25 -05:00
return SKILL_RANGE_MONO ;
else
return SKILL_RANGE_LEVEL ;
case SKILL_CATEGORY_SECONDARY :
case SKILL_CATEGORY_PROFESSION :
// not set skills for professions and racial abilities
2010-04-07 19:14:10 +02:00
if ( IsProfessionSkill ( pSkill -> id ))
2008-10-11 14:16:25 -05:00
return SKILL_RANGE_RANK ;
2010-04-07 19:14:10 +02:00
else if ( racial )
2008-10-11 14:16:25 -05:00
return SKILL_RANGE_NONE ;
else
return SKILL_RANGE_MONO ;
default :
case SKILL_CATEGORY_ATTRIBUTES : //not found in dbc
2008-12-24 09:58:26 -06:00
case SKILL_CATEGORY_GENERIC : //only GENERIC(DND)
2008-10-11 14:16:25 -05:00
return SKILL_RANGE_NONE ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadGameTele ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-14 16:28:45 -06:00
m_GameTeleMap . clear (); // for reload case
2009-10-17 15:51:44 -07:00
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT id, position_x, position_y, position_z, orientation, map, name FROM game_tele" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 GameTeleports. DB table `game_tele` is empty!" );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 id = fields [ 0 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GameTele gt ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
gt . position_x = fields [ 1 ]. GetFloat ();
gt . position_y = fields [ 2 ]. GetFloat ();
gt . position_z = fields [ 3 ]. GetFloat ();
gt . orientation = fields [ 4 ]. GetFloat ();
gt . mapId = fields [ 5 ]. GetUInt32 ();
2010-09-24 22:16:21 +02:00
gt . name = fields [ 6 ]. GetString ();
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( ! MapManager :: IsValidMapCoord ( gt . mapId , gt . position_x , gt . position_y , gt . position_z , gt . orientation ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong position for id %u (name: %s) in `game_tele` table, ignoring." , id , gt . name . c_str ());
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( gt . name , gt . wnameLow ))
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Wrong UTF8 name for id %u in `game_tele` table, ignoring." , id );
2008-10-11 14:16:25 -05:00
continue ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
wstrToLower ( gt . wnameLow );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_GameTeleMap [ id ] = gt ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ count ;
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u GameTeleports in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
GameTele const * ObjectMgr :: GetGameTele ( const std :: string & name ) const
2008-10-11 14:16:25 -05:00
{
// explicit name case
std :: wstring wname ;
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( name , wname ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// converting string that we try to find to lower case
2010-04-07 22:59:46 +02:00
wstrToLower ( wname );
2009-10-17 15:51:44 -07:00
2008-10-29 18:06:01 -05:00
// Alternative first GameTele what contains wnameLow as substring in case no GameTele location found
const GameTele * alt = NULL ;
2009-10-17 16:20:24 -07:00
for ( GameTeleMap :: const_iterator itr = m_GameTeleMap . begin (); itr != m_GameTeleMap . end (); ++ itr )
2008-10-29 18:06:01 -05:00
{
2010-04-07 19:14:10 +02:00
if ( itr -> second . wnameLow == wname )
2008-10-11 14:16:25 -05:00
return & itr -> second ;
2008-10-29 18:06:01 -05:00
else if ( alt == NULL && itr -> second . wnameLow . find ( wname ) != std :: wstring :: npos )
alt = & itr -> second ;
}
2009-10-17 15:51:44 -07:00
2008-10-29 18:06:01 -05:00
return alt ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool ObjectMgr :: AddGameTele ( GameTele & tele )
{
// find max id
uint32 new_id = 0 ;
2009-10-17 16:20:24 -07:00
for ( GameTeleMap :: const_iterator itr = m_GameTeleMap . begin (); itr != m_GameTeleMap . end (); ++ itr )
2010-04-07 19:14:10 +02:00
if ( itr -> first > new_id )
2008-10-11 14:16:25 -05:00
new_id = itr -> first ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// use next
++ new_id ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( tele . name , tele . wnameLow ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
wstrToLower ( tele . wnameLow );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_GameTeleMap [ new_id ] = tele ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
WorldDatabase . PExecute ( "INSERT INTO game_tele (id, position_x, position_y, position_z, orientation, map, name) VALUES (%u, %f, %f, %f, %f, %d, '%s')" ,
new_id , tele . position_x , tele . position_y , tele . position_z , tele . orientation , tele . mapId , tele . name . c_str ());
2010-08-18 02:25:52 +02:00
return true ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
bool ObjectMgr :: DeleteGameTele ( const std :: string & name )
2008-10-11 14:16:25 -05:00
{
// explicit name case
std :: wstring wname ;
2011-04-29 20:47:02 +02:00
if ( ! Utf8toWStr ( name , wname ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// converting string that we try to find to lower case
2010-04-07 22:59:46 +02:00
wstrToLower ( wname );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( GameTeleMap :: iterator itr = m_GameTeleMap . begin (); itr != m_GameTeleMap . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( itr -> second . wnameLow == wname )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
WorldDatabase . PExecute ( "DELETE FROM game_tele WHERE name = '%s'" , itr -> second . name . c_str ());
2008-10-11 14:16:25 -05:00
m_GameTeleMap . erase ( itr );
return true ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2009-12-16 18:58:36 +02:00
void ObjectMgr :: LoadMailLevelRewards ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-12-16 18:58:36 +02:00
m_mailLevelRewardMap . clear (); // for reload case
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT level, raceMask, mailTemplateId, senderEntry FROM mail_level_reward" );
2009-12-16 18:58:36 +02:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2009-12-16 18:58:36 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 level dependent mail rewards. DB table `mail_level_reward` is empty." );
sLog -> outString ();
2009-12-16 18:58:36 +02:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2009-12-16 18:58:36 +02:00
do
{
Field * fields = result -> Fetch ();
uint8 level = fields [ 0 ]. GetUInt8 ();
uint32 raceMask = fields [ 1 ]. GetUInt32 ();
uint32 mailTemplateId = fields [ 2 ]. GetUInt32 ();
uint32 senderEntry = fields [ 3 ]. GetUInt32 ();
2010-04-07 19:14:10 +02:00
if ( level > MAX_LEVEL )
2009-12-16 18:58:36 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `mail_level_reward` have data for level %u that more supported by client (%u), ignoring." , level , MAX_LEVEL );
2009-12-16 18:58:36 +02:00
continue ;
}
2010-04-07 19:14:10 +02:00
if ( ! ( raceMask & RACEMASK_ALL_PLAYABLE ))
2009-12-16 18:58:36 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `mail_level_reward` have raceMask (%u) for level %u that not include any player races, ignoring." , raceMask , level );
2009-12-16 18:58:36 +02:00
continue ;
}
2010-04-07 19:14:10 +02:00
if ( ! sMailTemplateStore . LookupEntry ( mailTemplateId ))
2009-12-16 18:58:36 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `mail_level_reward` have invalid mailTemplateId (%u) for level %u that invalid not include any player races, ignoring." , mailTemplateId , level );
2009-12-16 18:58:36 +02:00
continue ;
}
2011-04-01 20:31:15 +02:00
if ( ! GetCreatureTemplate ( senderEntry ))
2009-12-16 18:58:36 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table `mail_level_reward` have not existed sender creature entry (%u) for level %u that invalid not include any player races, ignoring." , senderEntry , level );
2009-12-16 18:58:36 +02:00
continue ;
}
2011-04-29 20:47:02 +02:00
m_mailLevelRewardMap [ level ]. push_back ( MailLevelReward ( raceMask , mailTemplateId , senderEntry ));
2009-12-16 18:58:36 +02:00
++ count ;
}
while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u level dependent mail rewards in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2009-12-16 18:58:36 +02:00
}
2011-06-12 02:30:32 +02:00
void ObjectMgr :: AddSpellToTrainer ( uint32 entry , uint32 spell , uint32 spellCost , uint32 reqSkill , uint32 reqSkillValue , uint32 reqLevel )
2010-03-24 18:27:09 -06:00
{
2010-04-13 11:49:09 +02:00
if ( entry >= TRINITY_TRAINER_START_REF )
2010-12-21 20:26:59 +01:00
return ;
2010-04-13 11:49:09 +02:00
2011-04-28 22:57:08 +02:00
CreatureTemplate const * cInfo = GetCreatureTemplate ( entry );
2010-04-12 07:26:22 -06:00
if ( ! cInfo )
2010-03-24 18:27:09 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `npc_trainer` contains an entry for a non-existing creature template (Entry: %u), ignoring" , entry );
2010-12-21 20:26:59 +01:00
return ;
2010-03-24 18:27:09 -06:00
}
2010-04-07 19:14:10 +02:00
if ( ! ( cInfo -> npcflag & UNIT_NPC_FLAG_TRAINER ))
2010-03-24 18:27:09 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `npc_trainer` contains an entry for a creature template (Entry: %u) without trainer flag, ignoring" , entry );
2010-12-21 20:26:59 +01:00
return ;
2010-03-24 18:27:09 -06:00
}
2011-07-26 23:09:28 +02:00
SpellInfo const * spellinfo = sSpellMgr -> GetSpellInfo ( spell );
2010-04-07 19:14:10 +02:00
if ( ! spellinfo )
2010-03-24 18:27:09 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `npc_trainer` contains an entry (Entry: %u) for a non-existing spell (Spell: %u), ignoring" , entry , spell );
2010-12-21 20:26:59 +01:00
return ;
2010-03-24 18:27:09 -06:00
}
2010-04-07 19:14:10 +02:00
if ( ! SpellMgr :: IsSpellValid ( spellinfo ))
2010-03-24 18:27:09 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `npc_trainer` contains an entry (Entry: %u) for a broken spell (Spell: %u), ignoring" , entry , spell );
2010-12-21 20:26:59 +01:00
return ;
2010-03-24 18:27:09 -06:00
}
2010-04-07 19:14:10 +02:00
if ( GetTalentSpellCost ( spell ))
2010-03-24 18:27:09 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `npc_trainer` contains an entry (Entry: %u) for a non-existing spell (Spell: %u) which is a talent, ignoring" , entry , spell );
2010-12-21 20:26:59 +01:00
return ;
2010-03-24 18:27:09 -06:00
}
TrainerSpellData & data = m_mCacheTrainerSpellMap [ entry ];
TrainerSpell & trainerSpell = data . spellList [ spell ];
trainerSpell . spell = spell ;
2010-12-21 20:26:59 +01:00
trainerSpell . spellCost = spellCost ;
trainerSpell . reqSkill = reqSkill ;
trainerSpell . reqSkillValue = reqSkillValue ;
trainerSpell . reqLevel = reqLevel ;
2010-03-24 18:27:09 -06:00
2010-04-07 19:14:10 +02:00
if ( ! trainerSpell . reqLevel )
2011-07-26 23:09:28 +02:00
trainerSpell . reqLevel = spellinfo -> SpellLevel ;
2010-03-24 18:27:09 -06:00
// calculate learned spell for profession case when stored cast-spell
trainerSpell . learnedSpell [ 0 ] = spell ;
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
2011-07-26 23:09:28 +02:00
if ( spellinfo -> Effects [ i ]. Effect != SPELL_EFFECT_LEARN_SPELL )
2010-03-24 18:27:09 -06:00
continue ;
if ( trainerSpell . learnedSpell [ 0 ] == spell )
trainerSpell . learnedSpell [ 0 ] = 0 ;
// player must be able to cast spell on himself
2011-07-27 12:35:59 +02:00
if ( spellinfo -> Effects [ i ]. TargetA . GetTarget () != 0 && spellinfo -> Effects [ i ]. TargetA . GetTarget () != TARGET_UNIT_TARGET_ALLY
&& spellinfo -> Effects [ i ]. TargetA . GetTarget () != TARGET_UNIT_TARGET_ANY && spellinfo -> Effects [ i ]. TargetA . GetTarget () != TARGET_UNIT_CASTER )
2010-03-24 18:27:09 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `npc_trainer` has spell %u for trainer entry %u with learn effect which has incorrect target type, ignoring learn effect!" , spell , entry );
2010-03-24 18:27:09 -06:00
continue ;
}
2011-07-26 23:09:28 +02:00
trainerSpell . learnedSpell [ i ] = spellinfo -> Effects [ i ]. TriggerSpell ;
2010-03-24 18:27:09 -06:00
2011-07-26 23:09:28 +02:00
if ( trainerSpell . learnedSpell [ i ])
{
SpellInfo const * learnedSpellInfo = sSpellMgr -> GetSpellInfo ( trainerSpell . learnedSpell [ i ]);
if ( learnedSpellInfo && learnedSpellInfo -> IsProfession ())
data . trainerType = 2 ;
}
2010-03-24 18:27:09 -06:00
}
2010-12-21 20:26:59 +01:00
return ;
2010-03-24 18:27:09 -06:00
}
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadTrainerSpell ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
// For reload case
2008-10-11 14:16:25 -05:00
m_mCacheTrainerSpellMap . clear ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
std :: set < uint32 > skip_trainers ;
2009-10-17 15:51:44 -07:00
2010-12-21 20:26:59 +01:00
QueryResult result = WorldDatabase . Query ( "SELECT b.entry, a.spell, a.spellcost, a.reqskill, a.reqskillvalue, a.reqlevel FROM npc_trainer AS a "
"INNER JOIN npc_trainer AS b ON a.entry = -(b.spell) "
"UNION SELECT * FROM npc_trainer WHERE spell > 0" );
2009-10-17 15:51:44 -07:00
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 Trainers. DB table `npc_trainer` is empty!" );
sLog -> outString ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2011-01-26 01:03:35 +01:00
2008-10-11 14:16:25 -05:00
do
{
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2010-12-21 20:26:59 +01:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
uint32 spell = fields [ 1 ]. GetUInt32 ();
uint32 spellCost = fields [ 2 ]. GetUInt32 ();
uint32 reqSkill = fields [ 3 ]. GetUInt32 ();
uint32 reqSkillValue = fields [ 4 ]. GetUInt32 ();
uint32 reqLevel = fields [ 5 ]. GetUInt32 ();
AddSpellToTrainer ( entry , spell , spellCost , reqSkill , reqSkillValue , reqLevel );
count ++ ;
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %d Trainers in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-03-24 18:27:09 -06:00
}
2009-10-17 15:51:44 -07:00
2010-03-24 18:27:09 -06:00
int ObjectMgr :: LoadReferenceVendor ( int32 vendor , int32 item , std :: set < uint32 > * skip_vendors )
{
// find all items from the reference vendor
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . PQuery ( "SELECT item, maxcount, incrtime, ExtendedCost FROM npc_vendor WHERE entry='%d' ORDER BY slot ASC" , item );
2010-04-07 22:59:46 +02:00
if ( ! result )
2010-03-24 18:27:09 -06:00
return 0 ;
2009-10-17 15:51:44 -07:00
2010-03-24 18:27:09 -06:00
uint32 count = 0 ;
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2010-04-19 17:08:08 +02:00
int32 item_id = fields [ 0 ]. GetInt32 ();
2009-10-17 15:51:44 -07:00
2010-03-24 18:27:09 -06:00
// if item is a negative, its a reference
2010-04-07 22:59:46 +02:00
if ( item_id < 0 )
2010-03-24 18:27:09 -06:00
count += LoadReferenceVendor ( vendor , - item_id , skip_vendors );
else
2009-01-14 00:35:13 -06:00
{
2010-04-19 17:08:08 +02:00
int32 maxcount = fields [ 1 ]. GetInt32 ();
uint32 incrtime = fields [ 2 ]. GetUInt32 ();
2010-07-15 10:12:51 +02:00
uint32 ExtendedCost = fields [ 3 ]. GetUInt32 ();
2010-03-24 18:27:09 -06:00
2010-07-15 10:12:51 +02:00
if ( ! IsVendorItemValid ( vendor , item_id , maxcount , incrtime , ExtendedCost , NULL , skip_vendors ))
2010-01-31 17:24:13 +01:00
continue ;
2010-03-24 18:27:09 -06:00
VendorItemData & vList = m_mCacheVendorItemMap [ vendor ];
2009-10-17 15:51:44 -07:00
2010-07-15 10:12:51 +02:00
vList . AddItem ( item_id , maxcount , incrtime , ExtendedCost );
2010-03-24 18:27:09 -06:00
++ count ;
2010-01-31 17:24:13 +01:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-03-24 18:27:09 -06:00
return count ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void ObjectMgr :: LoadVendors ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
// For reload case
2008-10-11 14:16:25 -05:00
for ( CacheVendorItemMap :: iterator itr = m_mCacheVendorItemMap . begin (); itr != m_mCacheVendorItemMap . end (); ++ itr )
itr -> second . Clear ();
m_mCacheVendorItemMap . clear ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
std :: set < uint32 > skip_vendors ;
2009-10-17 15:51:44 -07:00
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor ORDER BY entry, slot ASC" );
2010-04-07 22:59:46 +02:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ();
sLog -> outErrorDb ( ">> Loaded 0 Vendors. DB table `npc_vendor` is empty!" );
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 count = 0 ;
2010-12-19 17:06:33 +01:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
2010-03-24 18:27:09 -06:00
int32 item_id = fields [ 1 ]. GetInt32 ();
2009-10-17 15:51:44 -07:00
2010-03-24 18:27:09 -06:00
// if item is a negative, its a reference
2010-04-07 22:59:46 +02:00
if ( item_id < 0 )
2010-03-24 18:27:09 -06:00
count += LoadReferenceVendor ( entry , - item_id , & skip_vendors );
else
{
int32 maxcount = fields [ 2 ]. GetInt32 ();
uint32 incrtime = fields [ 3 ]. GetUInt32 ();
2010-07-15 10:12:51 +02:00
uint32 ExtendedCost = fields [ 4 ]. GetUInt32 ();
2010-03-24 18:27:09 -06:00
2010-07-15 10:12:51 +02:00
if ( ! IsVendorItemValid ( entry , item_id , maxcount , incrtime , ExtendedCost , NULL , & skip_vendors ))
2010-03-24 18:27:09 -06:00
continue ;
2009-10-17 15:51:44 -07:00
2010-03-24 18:27:09 -06:00
VendorItemData & vList = m_mCacheVendorItemMap [ entry ];
2009-10-17 15:51:44 -07:00
2010-07-15 10:12:51 +02:00
vList . AddItem ( item_id , maxcount , incrtime , ExtendedCost );
2010-03-24 18:27:09 -06:00
++ count ;
}
2009-10-17 15:51:44 -07:00
2010-12-19 17:06:33 +01:00
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %d Vendors in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-12-20 13:35:08 +02:00
void ObjectMgr :: LoadGossipMenu ()
2008-11-05 09:22:56 -06:00
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-12-20 13:35:08 +02:00
m_mGossipMenusMap . clear ();
2009-10-17 15:51:44 -07:00
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT entry, text_id FROM gossip_menu" );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! result )
2008-11-05 09:22:56 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 gossip_menu entries. DB table `gossip_menu` is empty!" );
sLog -> outString ();
2008-11-05 09:22:56 -06:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-11-05 09:22:56 -06:00
uint32 count = 0 ;
2009-10-17 15:51:44 -07:00
2008-11-05 09:22:56 -06:00
do
{
2009-10-17 15:51:44 -07:00
2008-11-05 09:22:56 -06:00
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-12-20 13:35:08 +02:00
GossipMenus gMenu ;
gMenu . entry = fields [ 0 ]. GetUInt32 ();
2010-08-08 19:45:53 +02:00
gMenu . text_id = fields [ 1 ]. GetUInt32 ();
2009-12-20 13:35:08 +02:00
if ( ! GetGossipText ( gMenu . text_id ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table gossip_menu entry %u are using non-existing text_id %u" , gMenu . entry , gMenu . text_id );
2009-12-20 13:35:08 +02:00
continue ;
}
m_mGossipMenusMap . insert ( GossipMenusMap :: value_type ( gMenu . entry , gMenu ));
2009-10-17 15:51:44 -07:00
2008-11-05 09:22:56 -06:00
++ count ;
2009-12-20 13:35:08 +02:00
}
2010-04-07 19:13:19 +02:00
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u gossip_menu entries in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2009-12-20 13:35:08 +02:00
}
void ObjectMgr :: LoadGossipMenuItems ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2009-12-20 13:35:08 +02:00
m_mGossipMenuItemsMap . clear ();
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query (
2009-12-20 13:35:08 +02:00
"SELECT menu_id, id, option_icon, option_text, option_id, npc_option_npcflag, "
2011-06-18 23:40:14 +01:00
"action_menu_id, action_poi_id, box_coded, box_money, box_text "
2010-07-01 09:20:09 -06:00
"FROM gossip_menu_option ORDER BY menu_id, id" );
2009-12-20 13:35:08 +02:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 gossip_menu_option entries. DB table `gossip_menu_option` is empty!" );
sLog -> outString ();
2009-12-20 13:35:08 +02:00
return ;
}
uint32 count = 0 ;
do
{
Field * fields = result -> Fetch ();
GossipMenuItems gMenuItem ;
2011-05-26 23:57:17 +02:00
gMenuItem . MenuId = fields [ 0 ]. GetUInt32 ();
gMenuItem . OptionIndex = fields [ 1 ]. GetUInt32 ();
gMenuItem . OptionIcon = fields [ 2 ]. GetUInt8 ();
gMenuItem . OptionText = fields [ 3 ]. GetString ();
gMenuItem . OptionType = fields [ 4 ]. GetUInt32 ();
gMenuItem . OptionNpcflag = fields [ 5 ]. GetUInt32 ();
gMenuItem . ActionMenuId = fields [ 6 ]. GetUInt32 ();
gMenuItem . ActionPoiId = fields [ 7 ]. GetUInt32 ();
2011-06-18 23:40:14 +01:00
gMenuItem . BoxCoded = fields [ 8 ]. GetBool ();
gMenuItem . BoxMoney = fields [ 9 ]. GetUInt32 ();
gMenuItem . BoxText = fields [ 10 ]. GetString ();
2009-12-20 13:35:08 +02:00
2011-05-26 23:57:17 +02:00
if ( gMenuItem . OptionIcon >= GOSSIP_ICON_MAX )
2009-12-20 13:35:08 +02:00
{
2011-05-26 23:57:17 +02:00
sLog -> outErrorDb ( "Table gossip_menu_option for menu %u, id %u has unknown icon id %u. Replacing with GOSSIP_ICON_CHAT" , gMenuItem . MenuId , gMenuItem . OptionIndex , gMenuItem . OptionIcon );
gMenuItem . OptionIcon = GOSSIP_ICON_CHAT ;
2009-12-20 13:35:08 +02:00
}
2011-05-26 23:57:17 +02:00
if ( gMenuItem . OptionType >= GOSSIP_OPTION_MAX )
sLog -> outErrorDb ( "Table gossip_menu_option for menu %u, id %u has unknown option id %u. Option will not be used" , gMenuItem . MenuId , gMenuItem . OptionIndex , gMenuItem . OptionType );
2009-12-20 13:35:08 +02:00
2011-05-26 23:57:17 +02:00
if ( gMenuItem . ActionPoiId && ! GetPointOfInterest ( gMenuItem . ActionPoiId ))
2009-12-20 13:35:08 +02:00
{
2011-05-26 23:57:17 +02:00
sLog -> outErrorDb ( "Table gossip_menu_option for menu %u, id %u use non-existing action_poi_id %u, ignoring" , gMenuItem . MenuId , gMenuItem . OptionIndex , gMenuItem . ActionPoiId );
gMenuItem . ActionPoiId = 0 ;
2009-12-20 13:35:08 +02:00
}
2011-05-26 23:57:17 +02:00
m_mGossipMenuItemsMap . insert ( GossipMenuItemsMap :: value_type ( gMenuItem . MenuId , gMenuItem ));
2009-12-20 13:35:08 +02:00
++ count ;
}
2010-04-07 19:13:19 +02:00
while ( result -> NextRow ());
2009-12-20 13:35:08 +02:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u gossip_menu_option entries in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-11-05 09:22:56 -06:00
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
void ObjectMgr :: AddVendorItem ( uint32 entry , uint32 item , int32 maxcount , uint32 incrtime , uint32 extendedcost , bool savetodb )
2008-10-11 14:16:25 -05:00
{
VendorItemData & vList = m_mCacheVendorItemMap [ entry ];
2010-07-15 10:12:51 +02:00
vList . AddItem ( item , maxcount , incrtime , extendedcost );
2009-10-17 15:51:44 -07:00
2010-07-15 10:12:51 +02:00
if ( savetodb )
2011-04-29 20:47:02 +02:00
WorldDatabase . PExecute ( "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost) VALUES('%u', '%u', '%u', '%u', '%u')" , entry , item , maxcount , incrtime , extendedcost );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
bool ObjectMgr :: RemoveVendorItem ( uint32 entry , uint32 item , bool savetodb )
2008-10-11 14:16:25 -05:00
{
CacheVendorItemMap :: iterator iter = m_mCacheVendorItemMap . find ( entry );
2010-04-07 19:14:10 +02:00
if ( iter == m_mCacheVendorItemMap . end ())
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2011-06-12 02:30:32 +02:00
if ( ! iter -> second . RemoveItem ( item ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
if ( savetodb ) WorldDatabase . PExecute ( "DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'" , entry , item );
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-07-15 10:12:51 +02:00
bool ObjectMgr :: IsVendorItemValid ( uint32 vendor_entry , uint32 item_id , int32 maxcount , uint32 incrtime , uint32 ExtendedCost , Player * pl , std :: set < uint32 >* skip_vendors , uint32 ORnpcflag ) const
2008-10-11 14:16:25 -05:00
{
2011-04-28 22:57:08 +02:00
CreatureTemplate const * cInfo = sObjectMgr -> GetCreatureTemplate ( vendor_entry );
2010-04-07 19:14:10 +02:00
if ( ! cInfo )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pl )
2008-10-11 14:16:25 -05:00
ChatHandler ( pl ). SendSysMessage ( LANG_COMMAND_VENDORSELECTION );
else
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `(game_event_)npc_vendor` have data for not existed creature template (Entry: %u), ignore" , vendor_entry );
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! (( cInfo -> npcflag | ORnpcflag ) & UNIT_NPC_FLAG_VENDOR ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 23:25:02 +02:00
if ( ! skip_vendors || skip_vendors -> count ( vendor_entry ) == 0 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pl )
2008-10-11 14:16:25 -05:00
ChatHandler ( pl ). SendSysMessage ( LANG_COMMAND_VENDORSELECTION );
else
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `(game_event_)npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore" , vendor_entry );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( skip_vendors )
2008-10-11 14:16:25 -05:00
skip_vendors -> insert ( vendor_entry );
}
return false ;
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
if ( ! sObjectMgr -> GetItemTemplate ( item_id ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pl )
2008-10-11 14:16:25 -05:00
ChatHandler ( pl ). PSendSysMessage ( LANG_ITEM_NOT_FOUND , item_id );
else
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore" , vendor_entry , item_id );
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2010-07-15 10:12:51 +02:00
if ( ExtendedCost && ! sItemExtendedCostStore . LookupEntry ( ExtendedCost ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pl )
2010-07-15 10:12:51 +02:00
ChatHandler ( pl ). PSendSysMessage ( LANG_EXTENDED_COST_NOT_EXIST , ExtendedCost );
2008-10-11 14:16:25 -05:00
else
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore" , item_id , ExtendedCost , vendor_entry );
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( maxcount > 0 && incrtime == 0 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pl )
2010-04-08 08:20:08 +02:00
ChatHandler ( pl ). PSendSysMessage ( "MaxCount != 0 (%u) but IncrTime == 0" , maxcount );
2008-10-11 14:16:25 -05:00
else
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore" , maxcount , item_id , vendor_entry );
2008-10-11 14:16:25 -05:00
return false ;
}
2010-04-07 23:25:02 +02:00
else if ( maxcount == 0 && incrtime > 0 )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pl )
2010-04-07 23:56:35 +02:00
ChatHandler ( pl ). PSendSysMessage ( "MaxCount == 0 but IncrTime<>= 0" );
2008-10-11 14:16:25 -05:00
else
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore" , item_id , vendor_entry );
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
VendorItemData const * vItems = GetNpcVendorItemList ( vendor_entry );
2010-04-07 19:14:10 +02:00
if ( ! vItems )
2008-10-11 14:16:25 -05:00
return true ; // later checks for non-empty lists
2009-10-17 15:51:44 -07:00
2010-06-21 23:41:28 +02:00
if ( vItems -> FindItemCostPair ( item_id , ExtendedCost ))
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pl )
2010-07-15 10:12:51 +02:00
ChatHandler ( pl ). PSendSysMessage ( LANG_ITEM_ALREADY_IN_LIST , item_id , ExtendedCost );
2008-10-11 14:16:25 -05:00
else
2011-06-12 02:30:32 +02:00
sLog -> outErrorDb ( "Table `npc_vendor` has duplicate items %u (with extended cost %u) for vendor (Entry: %u), ignoring" , item_id , ExtendedCost , vendor_entry );
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( vItems -> GetItemCount () >= MAX_VENDOR_ITEMS )
2008-10-11 14:16:25 -05:00
{
2010-04-07 19:14:10 +02:00
if ( pl )
2008-10-11 14:16:25 -05:00
ChatHandler ( pl ). SendSysMessage ( LANG_COMMAND_ADDVENDORITEMITEMS );
else
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignore" , vItems -> GetItemCount (), MAX_VENDOR_ITEMS , vendor_entry );
2008-10-11 14:16:25 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2008-11-20 16:16:57 -06:00
void ObjectMgr :: LoadScriptNames ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2008-11-20 16:16:57 -06:00
m_scriptNames . push_back ( "" );
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query (
2010-08-07 16:48:34 +02:00
"SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
"UNION "
2010-08-06 13:47:17 +02:00
"SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
"UNION "
2008-11-20 16:16:57 -06:00
"SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
"UNION "
2010-07-24 22:41:42 +02:00
"SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
"UNION "
2010-08-06 12:13:13 +02:00
"SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
"UNION "
2010-08-06 16:28:17 +02:00
"SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
"UNION "
2010-08-06 16:33:31 +02:00
"SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
"UNION "
2010-08-06 18:03:09 +02:00
"SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
"UNION "
2008-11-20 16:16:57 -06:00
"SELECT DISTINCT(script) FROM instance_template WHERE script <> ''" );
2009-10-17 15:51:44 -07:00
2010-01-01 14:19:29 -06:00
if ( ! result )
2008-11-20 16:16:57 -06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outString ();
sLog -> outErrorDb ( ">> Loaded empty set of Script Names!" );
2009-01-22 22:44:27 -06:00
return ;
2008-11-20 16:16:57 -06:00
}
2009-10-17 15:51:44 -07:00
2009-09-13 00:01:35 -07:00
uint32 count = 1 ;
2009-10-17 15:51:44 -07:00
2009-01-22 22:44:27 -06:00
do
{
m_scriptNames . push_back (( * result )[ 0 ]. GetString ());
++ count ;
2010-08-06 18:03:09 +02:00
}
while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2008-11-20 16:16:57 -06:00
std :: sort ( m_scriptNames . begin (), m_scriptNames . end ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %d Script Names in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2008-11-20 16:16:57 -06:00
}
2009-10-17 15:51:44 -07:00
2008-11-20 16:16:57 -06:00
uint32 ObjectMgr :: GetScriptId ( const char * name )
{
// use binary search to find the script name in the sorted vector
// assume "" is the first element
2010-04-07 19:14:10 +02:00
if ( ! name ) return 0 ;
2008-11-20 16:16:57 -06:00
ScriptNameMap :: const_iterator itr =
std :: lower_bound ( m_scriptNames . begin (), m_scriptNames . end (), name );
2010-04-07 19:14:10 +02:00
if ( itr == m_scriptNames . end () || * itr != name ) return 0 ;
2010-12-11 20:37:38 +06:00
return uint32 ( itr - m_scriptNames . begin ());
2008-11-20 16:16:57 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-20 12:19:14 +06:00
void ObjectMgr :: CheckScripts ( ScriptsType type , std :: set < int32 >& ids )
2008-11-20 16:16:57 -06:00
{
2010-08-20 12:19:14 +06:00
ScriptMapMap * scripts = GetScriptsMapByType ( type );
if ( ! scripts )
return ;
for ( ScriptMapMap :: const_iterator itrMM = scripts -> begin (); itrMM != scripts -> end (); ++ itrMM )
2008-11-20 16:16:57 -06:00
{
2009-10-17 16:20:24 -07:00
for ( ScriptMap :: const_iterator itrM = itrMM -> second . begin (); itrM != itrMM -> second . end (); ++ itrM )
2008-11-20 16:16:57 -06:00
{
2009-04-17 15:16:19 -05:00
switch ( itrM -> second . command )
2008-11-20 16:16:57 -06:00
{
2009-04-17 15:16:19 -05:00
case SCRIPT_COMMAND_TALK :
{
2010-09-22 18:13:57 +06:00
if ( ! GetTrinityStringLocale ( itrM -> second . Talk . TextID ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `db_script_string` not has string id %u used db script (ID: %u)" , itrM -> second . Talk . TextID , itrMM -> first );
2009-10-17 15:51:44 -07:00
2010-09-22 18:13:57 +06:00
if ( ids . find ( itrM -> second . Talk . TextID ) != ids . end ())
ids . erase ( itrM -> second . Talk . TextID );
2009-04-17 15:16:19 -05:00
}
2010-08-21 20:55:31 +02:00
default :
break ;
2008-11-20 16:16:57 -06:00
}
}
}
}
2009-10-17 15:51:44 -07:00
2008-11-20 16:16:57 -06:00
void ObjectMgr :: LoadDbScriptStrings ()
{
2010-09-02 20:22:19 +02:00
LoadTrinityStrings ( "db_script_string" , MIN_DB_SCRIPT_STRING_ID , MAX_DB_SCRIPT_STRING_ID );
2009-10-17 15:51:44 -07:00
2008-11-20 16:16:57 -06:00
std :: set < int32 > ids ;
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( int32 i = MIN_DB_SCRIPT_STRING_ID ; i < MAX_DB_SCRIPT_STRING_ID ; ++ i )
2010-04-07 19:14:10 +02:00
if ( GetTrinityStringLocale ( i ))
2008-11-20 16:16:57 -06:00
ids . insert ( i );
2009-10-17 15:51:44 -07:00
2010-08-20 12:19:14 +06:00
for ( int type = SCRIPTS_FIRST ; type < SCRIPTS_LAST ; ++ type )
CheckScripts ( ScriptsType ( type ), ids );
2009-10-17 15:51:44 -07:00
2009-10-17 16:20:24 -07:00
for ( std :: set < int32 >:: const_iterator itr = ids . begin (); itr != ids . end (); ++ itr )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Table `db_script_string` has unused string id %u" , * itr );
2008-11-20 16:16:57 -06:00
}
2009-10-17 15:51:44 -07:00
2010-09-02 18:20:59 +02:00
bool LoadTrinityStrings ( char const * table , int32 start_value , int32 end_value )
2008-10-11 14:16:25 -05:00
{
2009-05-15 16:41:36 -05:00
// MAX_DB_SCRIPT_STRING_ID is max allowed negative value for scripts (scrpts can use only more deep negative values
// start/end reversed for negative values
if ( start_value > MAX_DB_SCRIPT_STRING_ID || end_value >= start_value )
2008-10-11 14:16:25 -05:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Table '%s' load attempted with range (%d - %d) reserved by Trinity, strings not loaded." , table , start_value , end_value + 1 );
2009-05-15 16:41:36 -05:00
return false ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-12-22 21:25:23 +01:00
return sObjectMgr -> LoadTrinityStrings ( table , start_value , end_value );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-03-03 02:48:31 +02:00
CreatureBaseStats const * ObjectMgr :: GetCreatureBaseStats ( uint8 level , uint8 unitClass )
2009-12-20 20:23:18 -07:00
{
2011-04-29 20:47:02 +02:00
CreatureBaseStatsMap :: const_iterator it = m_creatureBaseStatsMap . find ( MAKE_PAIR16 ( level , unitClass ));
2009-12-20 20:23:18 -07:00
2010-03-03 04:32:47 +02:00
if ( it != m_creatureBaseStatsMap . end ())
return & ( it -> second );
struct DefaultCreatureBaseStats : public CreatureBaseStats
{
DefaultCreatureBaseStats ()
{
BaseArmor = 1 ;
for ( uint8 j = 0 ; j < MAX_CREATURE_BASE_HP ; ++ j )
BaseHealth [ j ] = 1 ;
BaseMana = 0 ;
}
};
static const DefaultCreatureBaseStats def_stats ;
return & def_stats ;
2009-12-20 20:23:18 -07:00
}
void ObjectMgr :: LoadCreatureClassLevelStats ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor FROM creature_classlevelstats" );
2009-12-20 20:23:18 -07:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 creature base stats. DB table `creature_classlevelstats` is empty." );
sLog -> outString ();
2009-12-20 20:23:18 -07:00
return ;
}
2011-04-28 22:57:08 +02:00
uint32 count = 0 ;
2009-12-20 20:23:18 -07:00
do
{
Field * fields = result -> Fetch ();
2010-03-03 04:32:47 +02:00
2010-08-30 15:25:15 +02:00
uint8 Level = fields [ 0 ]. GetUInt8 ();
2010-03-03 04:32:47 +02:00
uint8 Class = fields [ 1 ]. GetUInt8 ();
CreatureBaseStats stats ;
2011-04-28 22:57:08 +02:00
2010-01-10 22:02:03 +01:00
for ( uint8 i = 0 ; i < MAX_CREATURE_BASE_HP ; ++ i )
stats . BaseHealth [ i ] = fields [ i + 2 ]. GetUInt32 ();
2011-04-28 22:57:08 +02:00
2010-01-10 22:02:03 +01:00
stats . BaseMana = fields [ 5 ]. GetUInt32 ();
stats . BaseArmor = fields [ 6 ]. GetUInt32 ();
2009-12-20 20:23:18 -07:00
2010-03-03 04:32:47 +02:00
if ( ! Class || (( 1 << ( Class - 1 )) & CLASSMASK_ALL_CREATURES ) == 0 )
2011-04-28 22:57:08 +02:00
sLog -> outErrorDb ( "Creature base stats for level %u has invalid class %u" , Level , Class );
2009-12-20 20:23:18 -07:00
2010-01-10 22:02:03 +01:00
for ( uint8 i = 0 ; i < MAX_CREATURE_BASE_HP ; ++ i )
2009-12-20 20:23:18 -07:00
{
2010-01-10 22:02:03 +01:00
if ( stats . BaseHealth [ i ] < 1 )
{
2011-04-28 22:57:08 +02:00
sLog -> outErrorDb ( "Creature base stats for class %u, level %u has invalid zero base HP[%u] - set to 1" , Class , Level , i );
2010-01-10 22:02:03 +01:00
stats . BaseHealth [ i ] = 1 ;
}
2009-12-20 20:23:18 -07:00
}
2010-03-03 04:32:47 +02:00
m_creatureBaseStatsMap [ MAKE_PAIR16 ( Level , Class )] = stats ;
2009-12-20 20:23:18 -07:00
2011-04-28 22:57:08 +02:00
++ count ;
2009-12-20 20:23:18 -07:00
}
while ( result -> NextRow ());
2011-04-28 22:57:08 +02:00
CreatureTemplateContainer const * ctc = sObjectMgr -> GetCreatureTemplates ();
for ( CreatureTemplateContainer :: const_iterator itr = ctc -> begin (); itr != ctc -> end (); ++ itr )
2010-01-11 18:13:21 +01:00
{
2011-04-28 22:57:08 +02:00
for ( uint16 lvl = itr -> second . minlevel ; lvl <= itr -> second . maxlevel ; ++ lvl )
2010-01-11 18:13:21 +01:00
{
2011-04-28 22:57:08 +02:00
if ( m_creatureBaseStatsMap . find ( MAKE_PAIR16 ( lvl , itr -> second . unit_class )) == m_creatureBaseStatsMap . end ())
sLog -> outErrorDb ( "Missing base stats for creature class %u level %u" , itr -> second . unit_class , lvl );
2010-01-11 18:13:21 +01:00
}
}
2011-04-28 22:57:08 +02:00
sLog -> outString ( ">> Loaded %u creature base stats in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2010-12-23 23:25:44 +01:00
sLog -> outString ();
2009-12-20 20:23:18 -07:00
}
2010-09-05 13:12:24 -07:00
void ObjectMgr :: LoadFactionChangeAchievements ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT alliance_id, horde_id FROM player_factionchange_achievement" );
2010-09-05 13:12:24 -07:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 faction change achievement pairs. DB table `player_factionchange_achievement` is empty." );
sLog -> outString ();
2010-09-05 13:12:24 -07:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2010-09-05 13:12:24 -07:00
do
{
Field * fields = result -> Fetch ();
uint32 alliance = fields [ 0 ]. GetUInt32 ();
uint32 horde = fields [ 1 ]. GetUInt32 ();
if ( ! sAchievementStore . LookupEntry ( alliance ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Achievement %u referenced in `player_factionchange_achievement` does not exist, pair skipped!" , alliance );
2010-09-05 13:12:24 -07:00
else if ( ! sAchievementStore . LookupEntry ( horde ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Achievement %u referenced in `player_factionchange_achievement` does not exist, pair skipped!" , horde );
2010-09-05 13:12:24 -07:00
else
factionchange_achievements [ alliance ] = horde ;
2010-12-19 17:06:33 +01:00
++ count ;
2010-09-05 13:12:24 -07:00
}
while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u faction change achievement pairs in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-09-05 13:12:24 -07:00
}
void ObjectMgr :: LoadFactionChangeItems ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT alliance_id, horde_id FROM player_factionchange_items" );
2010-09-05 13:12:24 -07:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 faction change item pairs. DB table `player_factionchange_items` is empty." );
sLog -> outString ();
2010-09-05 13:12:24 -07:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2010-09-05 13:12:24 -07:00
do
{
Field * fields = result -> Fetch ();
uint32 alliance = fields [ 0 ]. GetUInt32 ();
uint32 horde = fields [ 1 ]. GetUInt32 ();
2011-08-04 15:14:15 +02:00
if ( ! GetItemTemplate ( alliance ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item %u referenced in `player_factionchange_items` does not exist, pair skipped!" , alliance );
2011-08-04 15:14:15 +02:00
else if ( ! GetItemTemplate ( horde ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item %u referenced in `player_factionchange_items` does not exist, pair skipped!" , horde );
2010-09-05 13:12:24 -07:00
else
factionchange_items [ alliance ] = horde ;
2010-12-19 17:06:33 +01:00
++ count ;
2010-09-05 13:12:24 -07:00
}
while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u faction change item pairs in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-09-05 13:12:24 -07:00
}
void ObjectMgr :: LoadFactionChangeSpells ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT alliance_id, horde_id FROM player_factionchange_spells" );
2010-09-05 13:12:24 -07:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 faction change spell pairs. DB table `player_factionchange_spells` is empty." );
sLog -> outString ();
2010-09-05 13:12:24 -07:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2010-09-05 13:12:24 -07:00
do
{
Field * fields = result -> Fetch ();
uint32 alliance = fields [ 0 ]. GetUInt32 ();
uint32 horde = fields [ 1 ]. GetUInt32 ();
2011-07-26 23:09:28 +02:00
if ( ! sSpellMgr -> GetSpellInfo ( alliance ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Spell %u referenced in `player_factionchange_spells` does not exist, pair skipped!" , alliance );
2011-07-26 23:09:28 +02:00
else if ( ! sSpellMgr -> GetSpellInfo ( horde ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Spell %u referenced in `player_factionchange_spells` does not exist, pair skipped!" , horde );
2010-09-05 13:12:24 -07:00
else
factionchange_spells [ alliance ] = horde ;
2010-12-19 17:06:33 +01:00
++ count ;
2010-09-05 13:12:24 -07:00
}
while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u faction change spell pairs in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-09-05 13:12:24 -07:00
}
void ObjectMgr :: LoadFactionChangeReputations ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-09-11 21:10:54 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT alliance_id, horde_id FROM player_factionchange_reputations" );
2010-09-05 13:12:24 -07:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded 0 faction change reputation pairs. DB table `player_factionchange_reputations` is empty." );
sLog -> outString ();
2010-09-05 13:12:24 -07:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2010-09-05 13:12:24 -07:00
do
{
Field * fields = result -> Fetch ();
uint32 alliance = fields [ 0 ]. GetUInt32 ();
uint32 horde = fields [ 1 ]. GetUInt32 ();
if ( ! sFactionStore . LookupEntry ( alliance ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Reputation %u referenced in `player_factionchange_reputations` does not exist, pair skipped!" , alliance );
2010-09-05 13:12:24 -07:00
else if ( ! sFactionStore . LookupEntry ( horde ))
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Reputation %u referenced in `player_factionchange_reputations` does not exist, pair skipped!" , horde );
2010-09-05 13:12:24 -07:00
else
factionchange_reputations [ alliance ] = horde ;
2010-12-19 17:06:33 +01:00
++ count ;
2010-09-05 13:12:24 -07:00
}
while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u faction change reputation pairs in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-09-05 13:12:24 -07:00
}
2011-02-22 23:47:32 +01:00
2011-04-28 22:54:30 +02:00
GameObjectTemplate const * ObjectMgr :: GetGameObjectTemplate ( uint32 entry )
{
GameObjectTemplateContainer :: const_iterator itr = GameObjectTemplateStore . find ( entry );
if ( itr != GameObjectTemplateStore . end ())
return & ( itr -> second );
return NULL ;
}
2011-04-28 22:57:08 +02:00
CreatureTemplate const * ObjectMgr :: GetCreatureTemplate ( uint32 entry )
{
CreatureTemplateContainer :: const_iterator itr = CreatureTemplateStore . find ( entry );
if ( itr != CreatureTemplateStore . end ())
return & ( itr -> second );
return NULL ;
}
2011-08-03 12:28:42 +02:00
VehicleAccessoryList const * ObjectMgr :: GetVehicleAccessoryList ( Vehicle * veh ) const
{
if ( Creature * cre = veh -> GetBase () -> ToCreature ())
{
// Give preference to GUID-based accessories
VehicleAccessoryMap :: const_iterator itr = m_VehicleAccessoryMap . find ( cre -> GetDBTableGUIDLow ());
if ( itr != m_VehicleAccessoryMap . end ())
return & itr -> second ;
}
// Otherwise return entry-based
VehicleAccessoryMap :: const_iterator itr = m_VehicleTemplateAccessoryMap . find ( veh -> GetCreatureEntry ());
if ( itr != m_VehicleTemplateAccessoryMap . end ())
return & itr -> second ;
return NULL ;
}