2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "DBCStores.h"
20 #include "Policies/SingletonImp.h"
22 #include "ProgressBar.h"
23 #include "SharedDefines.h"
24 #include "ObjectDefines.h"
30 typedef std::map
<uint16
,uint32
> AreaFlagByAreaID
;
31 typedef std::map
<uint32
,uint32
> AreaFlagByMapID
;
33 DBCStorage
<AreaTableEntry
> sAreaStore(AreaTableEntryfmt
);
34 DBCStorage
<AreaGroupEntry
> sAreaGroupStore(AreaGroupEntryfmt
);
35 static AreaFlagByAreaID sAreaFlagByAreaID
;
36 static AreaFlagByMapID sAreaFlagByMapID
; // for instances without generated *.map files
38 DBCStorage
<AchievementEntry
> sAchievementStore(Achievementfmt
);
39 DBCStorage
<AchievementCriteriaEntry
> sAchievementCriteriaStore(AchievementCriteriafmt
);
40 DBCStorage
<AreaTriggerEntry
> sAreaTriggerStore(AreaTriggerEntryfmt
);
41 DBCStorage
<AuctionHouseEntry
> sAuctionHouseStore(AuctionHouseEntryfmt
);
42 DBCStorage
<BankBagSlotPricesEntry
> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt
);
43 DBCStorage
<BattlemasterListEntry
> sBattlemasterListStore(BattlemasterListEntryfmt
);
44 DBCStorage
<BarberShopStyleEntry
> sBarberShopStyleStore(BarberShopStyleEntryfmt
);
45 DBCStorage
<CharStartOutfitEntry
> sCharStartOutfitStore(CharStartOutfitEntryfmt
);
46 DBCStorage
<CharTitlesEntry
> sCharTitlesStore(CharTitlesEntryfmt
);
47 DBCStorage
<ChatChannelsEntry
> sChatChannelsStore(ChatChannelsEntryfmt
);
48 DBCStorage
<ChrClassesEntry
> sChrClassesStore(ChrClassesEntryfmt
);
49 DBCStorage
<ChrRacesEntry
> sChrRacesStore(ChrRacesEntryfmt
);
50 DBCStorage
<CinematicSequencesEntry
> sCinematicSequencesStore(CinematicSequencesEntryfmt
);
51 DBCStorage
<CreatureDisplayInfoEntry
> sCreatureDisplayInfoStore(CreatureDisplayInfofmt
);
52 DBCStorage
<CreatureFamilyEntry
> sCreatureFamilyStore(CreatureFamilyfmt
);
53 DBCStorage
<CreatureSpellDataEntry
> sCreatureSpellDataStore(CreatureSpellDatafmt
);
54 DBCStorage
<CreatureTypeEntry
> sCreatureTypeStore(CreatureTypefmt
);
55 DBCStorage
<CurrencyTypesEntry
> sCurrencyTypesStore(CurrencyTypesfmt
);
57 DBCStorage
<DurabilityQualityEntry
> sDurabilityQualityStore(DurabilityQualityfmt
);
58 DBCStorage
<DurabilityCostsEntry
> sDurabilityCostsStore(DurabilityCostsfmt
);
60 DBCStorage
<EmotesEntry
> sEmotesStore(EmotesEntryfmt
);
61 DBCStorage
<EmotesTextEntry
> sEmotesTextStore(EmotesTextEntryfmt
);
63 typedef std::map
<uint32
,SimpleFactionsList
> FactionTeamMap
;
64 static FactionTeamMap sFactionTeamMap
;
65 DBCStorage
<FactionEntry
> sFactionStore(FactionEntryfmt
);
66 DBCStorage
<FactionTemplateEntry
> sFactionTemplateStore(FactionTemplateEntryfmt
);
68 DBCStorage
<GameObjectDisplayInfoEntry
> sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt
);
69 DBCStorage
<GemPropertiesEntry
> sGemPropertiesStore(GemPropertiesEntryfmt
);
70 DBCStorage
<GlyphPropertiesEntry
> sGlyphPropertiesStore(GlyphPropertiesfmt
);
71 DBCStorage
<GlyphSlotEntry
> sGlyphSlotStore(GlyphSlotfmt
);
73 DBCStorage
<GtBarberShopCostBaseEntry
> sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt
);
74 DBCStorage
<GtCombatRatingsEntry
> sGtCombatRatingsStore(GtCombatRatingsfmt
);
75 DBCStorage
<GtChanceToMeleeCritBaseEntry
> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt
);
76 DBCStorage
<GtChanceToMeleeCritEntry
> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt
);
77 DBCStorage
<GtChanceToSpellCritBaseEntry
> sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt
);
78 DBCStorage
<GtChanceToSpellCritEntry
> sGtChanceToSpellCritStore(GtChanceToSpellCritfmt
);
79 DBCStorage
<GtOCTRegenHPEntry
> sGtOCTRegenHPStore(GtOCTRegenHPfmt
);
80 //DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
81 DBCStorage
<GtRegenHPPerSptEntry
> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt
);
82 DBCStorage
<GtRegenMPPerSptEntry
> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt
);
84 DBCStorage
<HolidaysEntry
> sHolidaysStore(Holidaysfmt
);
86 DBCStorage
<ItemEntry
> sItemStore(Itemfmt
);
87 DBCStorage
<ItemBagFamilyEntry
> sItemBagFamilyStore(ItemBagFamilyfmt
);
88 //DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt);
89 //DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently
90 DBCStorage
<ItemExtendedCostEntry
> sItemExtendedCostStore(ItemExtendedCostEntryfmt
);
91 DBCStorage
<ItemLimitCategoryEntry
> sItemLimitCategoryStore(ItemLimitCategoryEntryfmt
);
92 DBCStorage
<ItemRandomPropertiesEntry
> sItemRandomPropertiesStore(ItemRandomPropertiesfmt
);
93 DBCStorage
<ItemRandomSuffixEntry
> sItemRandomSuffixStore(ItemRandomSuffixfmt
);
94 DBCStorage
<ItemSetEntry
> sItemSetStore(ItemSetEntryfmt
);
96 DBCStorage
<LockEntry
> sLockStore(LockEntryfmt
);
98 DBCStorage
<MailTemplateEntry
> sMailTemplateStore(MailTemplateEntryfmt
);
99 DBCStorage
<MapEntry
> sMapStore(MapEntryfmt
);
101 // DBC used only for initialization sMapDifficultyMap at startup.
102 DBCStorage
<MapDifficultyEntry
> sMapDifficultyStore(MapDifficultyEntryfmt
); // only for loading
103 MapDifficultyMap sMapDifficultyMap
;
105 DBCStorage
<MovieEntry
> sMovieStore(MovieEntryfmt
);
107 DBCStorage
<QuestFactionRewardEntry
> sQuestFactionRewardStore(QuestFactionRewardfmt
);
108 DBCStorage
<QuestSortEntry
> sQuestSortStore(QuestSortEntryfmt
);
109 DBCStorage
<QuestXPLevel
> sQuestXPLevelStore(QuestXPLevelfmt
);
111 DBCStorage
<PvPDifficultyEntry
> sPvPDifficultyStore(PvPDifficultyfmt
);
113 DBCStorage
<RandomPropertiesPointsEntry
> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt
);
114 DBCStorage
<ScalingStatDistributionEntry
> sScalingStatDistributionStore(ScalingStatDistributionfmt
);
115 DBCStorage
<ScalingStatValuesEntry
> sScalingStatValuesStore(ScalingStatValuesfmt
);
117 DBCStorage
<SkillLineEntry
> sSkillLineStore(SkillLinefmt
);
118 DBCStorage
<SkillLineAbilityEntry
> sSkillLineAbilityStore(SkillLineAbilityfmt
);
120 DBCStorage
<SoundEntriesEntry
> sSoundEntriesStore(SoundEntriesfmt
);
122 DBCStorage
<SpellItemEnchantmentEntry
> sSpellItemEnchantmentStore(SpellItemEnchantmentfmt
);
123 DBCStorage
<SpellItemEnchantmentConditionEntry
> sSpellItemEnchantmentConditionStore(SpellItemEnchantmentConditionfmt
);
124 DBCStorage
<SpellEntry
> sSpellStore(SpellEntryfmt
);
125 SpellCategoryStore sSpellCategoryStore
;
126 PetFamilySpellsStore sPetFamilySpellsStore
;
128 DBCStorage
<SpellCastTimesEntry
> sSpellCastTimesStore(SpellCastTimefmt
);
129 DBCStorage
<SpellDurationEntry
> sSpellDurationStore(SpellDurationfmt
);
130 DBCStorage
<SpellFocusObjectEntry
> sSpellFocusObjectStore(SpellFocusObjectfmt
);
131 DBCStorage
<SpellRadiusEntry
> sSpellRadiusStore(SpellRadiusfmt
);
132 DBCStorage
<SpellRangeEntry
> sSpellRangeStore(SpellRangefmt
);
133 DBCStorage
<SpellRuneCostEntry
> sSpellRuneCostStore(SpellRuneCostfmt
);
134 DBCStorage
<SpellShapeshiftEntry
> sSpellShapeshiftStore(SpellShapeshiftfmt
);
135 DBCStorage
<StableSlotPricesEntry
> sStableSlotPricesStore(StableSlotPricesfmt
);
136 DBCStorage
<SummonPropertiesEntry
> sSummonPropertiesStore(SummonPropertiesfmt
);
137 DBCStorage
<TalentEntry
> sTalentStore(TalentEntryfmt
);
138 TalentSpellPosMap sTalentSpellPosMap
;
139 DBCStorage
<TalentTabEntry
> sTalentTabStore(TalentTabEntryfmt
);
141 // store absolute bit position for first rank for talent inspect
142 static uint32 sTalentTabPages
[MAX_CLASSES
][3];
144 DBCStorage
<TaxiNodesEntry
> sTaxiNodesStore(TaxiNodesEntryfmt
);
145 TaxiMask sTaxiNodesMask
;
146 TaxiMask sOldContinentsNodesMask
;
148 // DBC used only for initialization sTaxiPathSetBySource at startup.
149 TaxiPathSetBySource sTaxiPathSetBySource
;
150 DBCStorage
<TaxiPathEntry
> sTaxiPathStore(TaxiPathEntryfmt
);
152 // DBC used only for initialization sTaxiPathNodeStore at startup.
153 TaxiPathNodesByPath sTaxiPathNodesByPath
;
154 static DBCStorage
<TaxiPathNodeEntry
> sTaxiPathNodeStore(TaxiPathNodeEntryfmt
);
156 DBCStorage
<TotemCategoryEntry
> sTotemCategoryStore(TotemCategoryEntryfmt
);
157 DBCStorage
<VehicleEntry
> sVehicleStore(VehicleEntryfmt
);
158 DBCStorage
<VehicleSeatEntry
> sVehicleSeatStore(VehicleSeatEntryfmt
);
159 DBCStorage
<WorldMapAreaEntry
> sWorldMapAreaStore(WorldMapAreaEntryfmt
);
160 DBCStorage
<WorldMapOverlayEntry
> sWorldMapOverlayStore(WorldMapOverlayEntryfmt
);
161 DBCStorage
<WorldSafeLocsEntry
> sWorldSafeLocsStore(WorldSafeLocsEntryfmt
);
163 typedef std::list
<std::string
> StoreProblemList
;
165 bool IsAcceptableClientBuild(uint32 build
)
167 int accepted_versions
[] = EXPECTED_MANGOSD_CLIENT_BUILD
;
168 for(int i
= 0; accepted_versions
[i
]; ++i
)
169 if(build
== accepted_versions
[i
])
175 std::string
AcceptableClientBuildsListStr()
177 std::ostringstream data
;
178 int accepted_versions
[] = EXPECTED_MANGOSD_CLIENT_BUILD
;
179 for(int i
= 0; accepted_versions
[i
]; ++i
)
180 data
<< accepted_versions
[i
] << " ";
184 static bool ReadDBCBuildFileText(const std::string
& dbc_path
, char const* localeName
, std::string
& text
)
186 std::string filename
= dbc_path
+ "component.wow-" + localeName
+ ".txt";
188 if(FILE* file
= fopen(filename
.c_str(),"rb"))
191 fread(buf
,1,100-1,file
);
201 static uint32
ReadDBCBuild(const std::string
& dbc_path
, char const* localeName
= NULL
)
207 for(LocaleNameStr
* itr
= &fullLocaleNameList
[0]; itr
->name
; ++itr
)
208 if (ReadDBCBuildFileText(dbc_path
,itr
->name
,text
))
212 ReadDBCBuildFileText(dbc_path
,localeName
,text
);
217 size_t pos
= text
.find("version=\"");
218 size_t pos1
= pos
+ strlen("version=\"");
219 size_t pos2
= text
.find("\"",pos1
);
220 if (pos
== text
.npos
|| pos2
== text
.npos
|| pos1
>= pos2
)
223 std::string build_str
= text
.substr(pos1
,pos2
-pos1
);
225 int build
= atoi(build_str
.c_str());
232 static bool LoadDBC_assert_print(uint32 fsize
,uint32 rsize
, const std::string
& filename
)
234 sLog
.outError("ERROR: Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).",filename
.c_str(),fsize
,rsize
);
236 // assert must fail after function call
242 explicit LocalData(uint32 build
) : main_build(build
), availableDbcLocales(0xFFFFFFFF),checkedDbcLocaleBuilds(0) {}
245 // bitmasks for index of fullLocaleNameList
246 uint32 availableDbcLocales
;
247 uint32 checkedDbcLocaleBuilds
;
251 inline void LoadDBC(LocalData
& localeData
,barGoLink
& bar
, StoreProblemList
& errlist
, DBCStorage
<T
>& storage
, const std::string
& dbc_path
, const std::string
& filename
)
253 // compatibility format and C++ structure sizes
254 assert(DBCFileLoader::GetFormatRecordSize(storage
.GetFormat()) == sizeof(T
) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage
.GetFormat()),sizeof(T
),filename
));
256 std::string dbc_filename
= dbc_path
+ filename
;
257 if(storage
.Load(dbc_filename
.c_str()))
260 for(uint8 i
= 0; fullLocaleNameList
[i
].name
; ++i
)
262 if (!(localeData
.availableDbcLocales
& (1 << i
)))
265 std::string dbc_dir_loc
= dbc_path
+ fullLocaleNameList
[i
].name
+ "/";
267 if (!(localeData
.checkedDbcLocaleBuilds
& (1 << i
)))
269 localeData
.checkedDbcLocaleBuilds
|= (1<<i
);// mark as checked for speedup next checks
271 uint32 build_loc
= ReadDBCBuild(dbc_dir_loc
,fullLocaleNameList
[i
].name
);
272 if(localeData
.main_build
!= build_loc
)
274 localeData
.availableDbcLocales
&= ~(1<<i
); // mark as not available for speedup next checks
276 // exist but wrong build
279 std::string dbc_filename_loc
= dbc_path
+ fullLocaleNameList
[i
].name
+ "/" + filename
;
281 snprintf(buf
,200," (exist, but DBC locale subdir %s have DBCs for build %u instead expected build %u, it and other DBC from subdir skipped)",fullLocaleNameList
[i
].name
,build_loc
,localeData
.main_build
);
282 errlist
.push_back(dbc_filename_loc
+ buf
);
289 std::string dbc_filename_loc
= dbc_path
+ fullLocaleNameList
[i
].name
+ "/" + filename
;
290 if(!storage
.LoadStringsFrom(dbc_filename_loc
.c_str()))
291 localeData
.availableDbcLocales
&= ~(1<<i
); // mark as not available for speedup next checks
296 // sort problematic dbc to (1) non compatible and (2) non-existed
297 FILE * f
=fopen(dbc_filename
.c_str(),"rb");
301 snprintf(buf
,100," (exist, but have %d fields instead " SIZEFMTD
") Wrong client version DBC file?",storage
.GetFieldCount(),strlen(storage
.GetFormat()));
302 errlist
.push_back(dbc_filename
+ buf
);
306 errlist
.push_back(dbc_filename
);
310 void LoadDBCStores(const std::string
& dataPath
)
312 std::string dbcPath
= dataPath
+"dbc/";
314 uint32 build
= ReadDBCBuild(dbcPath
);
316 // Check the expected DBC version
317 if (!IsAcceptableClientBuild(build
))
320 sLog
.outError("Found DBC files for build %u but mangosd expected DBC for one from builds: %s Please extract correct DBC files.", build
, AcceptableClientBuildsListStr().c_str());
322 sLog
.outError("Incorrect DataDir value in mangosd.conf or not found build info (outdated DBC files). Required one from builds: %s Please extract correct DBC files.",AcceptableClientBuildsListStr().c_str());
326 const uint32 DBCFilesCount
= 84;
328 barGoLink
bar( (int)DBCFilesCount
);
330 StoreProblemList bad_dbc_files
;
332 LocalData
availableDbcLocales(build
);
334 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sAreaStore
, dbcPath
,"AreaTable.dbc");
336 // must be after sAreaStore loading
337 for(uint32 i
= 0; i
< sAreaStore
.GetNumRows(); ++i
) // areaflag numbered from 0
339 if(AreaTableEntry
const* area
= sAreaStore
.LookupEntry(i
))
341 // fill AreaId->DBC records
342 sAreaFlagByAreaID
.insert(AreaFlagByAreaID::value_type(uint16(area
->ID
),area
->exploreFlag
));
344 // fill MapId->DBC records ( skip sub zones and continents )
345 if(area
->zone
==0 && area
->mapid
!= 0 && area
->mapid
!= 1 && area
->mapid
!= 530 && area
->mapid
!= 571 )
346 sAreaFlagByMapID
.insert(AreaFlagByMapID::value_type(area
->mapid
,area
->exploreFlag
));
350 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sAchievementStore
, dbcPath
,"Achievement.dbc");
351 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sAchievementCriteriaStore
, dbcPath
,"Achievement_Criteria.dbc");
352 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sAreaTriggerStore
, dbcPath
,"AreaTrigger.dbc");
353 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sAreaGroupStore
, dbcPath
,"AreaGroup.dbc");
354 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sAuctionHouseStore
, dbcPath
,"AuctionHouse.dbc");
355 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sBankBagSlotPricesStore
, dbcPath
,"BankBagSlotPrices.dbc");
356 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sBattlemasterListStore
, dbcPath
,"BattlemasterList.dbc");
357 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sBarberShopStyleStore
, dbcPath
,"BarberShopStyle.dbc");
358 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sCharStartOutfitStore
, dbcPath
,"CharStartOutfit.dbc");
359 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sCharTitlesStore
, dbcPath
,"CharTitles.dbc");
360 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sChatChannelsStore
, dbcPath
,"ChatChannels.dbc");
361 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sChrClassesStore
, dbcPath
,"ChrClasses.dbc");
362 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sChrRacesStore
, dbcPath
,"ChrRaces.dbc");
363 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sCinematicSequencesStore
, dbcPath
,"CinematicSequences.dbc");
364 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sCreatureDisplayInfoStore
, dbcPath
,"CreatureDisplayInfo.dbc");
365 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sCreatureFamilyStore
, dbcPath
,"CreatureFamily.dbc");
366 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sCreatureSpellDataStore
, dbcPath
,"CreatureSpellData.dbc");
367 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sCreatureTypeStore
, dbcPath
,"CreatureType.dbc");
368 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sCurrencyTypesStore
, dbcPath
,"CurrencyTypes.dbc");
369 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sDurabilityCostsStore
, dbcPath
,"DurabilityCosts.dbc");
370 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sDurabilityQualityStore
, dbcPath
,"DurabilityQuality.dbc");
371 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sEmotesStore
, dbcPath
,"Emotes.dbc");
372 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sEmotesTextStore
, dbcPath
,"EmotesText.dbc");
373 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sFactionStore
, dbcPath
,"Faction.dbc");
374 for (uint32 i
=0;i
<sFactionStore
.GetNumRows(); ++i
)
376 FactionEntry
const * faction
= sFactionStore
.LookupEntry(i
);
377 if (faction
&& faction
->team
)
379 SimpleFactionsList
&flist
= sFactionTeamMap
[faction
->team
];
384 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sFactionTemplateStore
, dbcPath
,"FactionTemplate.dbc");
385 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGameObjectDisplayInfoStore
,dbcPath
,"GameObjectDisplayInfo.dbc");
386 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGemPropertiesStore
, dbcPath
,"GemProperties.dbc");
387 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGlyphPropertiesStore
, dbcPath
,"GlyphProperties.dbc");
388 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGlyphSlotStore
, dbcPath
,"GlyphSlot.dbc");
390 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtBarberShopCostBaseStore
,dbcPath
,"gtBarberShopCostBase.dbc");
391 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtCombatRatingsStore
, dbcPath
,"gtCombatRatings.dbc");
393 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtChanceToMeleeCritBaseStore
, dbcPath
,"gtChanceToMeleeCritBase.dbc");
394 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtChanceToMeleeCritStore
, dbcPath
,"gtChanceToMeleeCrit.dbc");
396 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtChanceToSpellCritBaseStore
, dbcPath
,"gtChanceToSpellCritBase.dbc");
397 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtChanceToSpellCritStore
, dbcPath
,"gtChanceToSpellCrit.dbc");
399 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtOCTRegenHPStore
, dbcPath
,"gtOCTRegenHP.dbc");
400 //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently
401 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtRegenHPPerSptStore
, dbcPath
,"gtRegenHPPerSpt.dbc");
402 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sGtRegenMPPerSptStore
, dbcPath
,"gtRegenMPPerSpt.dbc");
403 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sHolidaysStore
, dbcPath
,"Holidays.dbc");
404 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sItemStore
, dbcPath
,"Item.dbc");
405 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sItemBagFamilyStore
, dbcPath
,"ItemBagFamily.dbc");
406 //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently
407 //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc");
408 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sItemExtendedCostStore
, dbcPath
,"ItemExtendedCost.dbc");
409 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sItemLimitCategoryStore
, dbcPath
,"ItemLimitCategory.dbc");
410 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sItemRandomPropertiesStore
,dbcPath
,"ItemRandomProperties.dbc");
411 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sItemRandomSuffixStore
, dbcPath
,"ItemRandomSuffix.dbc");
412 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sItemSetStore
, dbcPath
,"ItemSet.dbc");
413 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sLockStore
, dbcPath
,"Lock.dbc");
414 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sMailTemplateStore
, dbcPath
,"MailTemplate.dbc");
415 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sMapStore
, dbcPath
,"Map.dbc");
417 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sMapDifficultyStore
, dbcPath
,"MapDifficulty.dbc");
419 for(uint32 i
= 1; i
< sMapDifficultyStore
.GetNumRows(); ++i
)
420 if(MapDifficultyEntry
const* entry
= sMapDifficultyStore
.LookupEntry(i
))
421 sMapDifficultyMap
[MAKE_PAIR32(entry
->MapId
,entry
->Difficulty
)] = MapDifficulty(entry
->resetTime
,entry
->maxPlayers
);
422 sMapDifficultyStore
.Clear();
424 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sMovieStore
, dbcPath
,"Movie.dbc");
425 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sQuestFactionRewardStore
, dbcPath
,"QuestFactionReward.dbc");
426 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sQuestSortStore
, dbcPath
,"QuestSort.dbc");
427 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sQuestXPLevelStore
, dbcPath
,"QuestXP.dbc");
428 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sPvPDifficultyStore
, dbcPath
,"PvpDifficulty.dbc");
429 for(uint32 i
= 0; i
< sPvPDifficultyStore
.GetNumRows(); ++i
)
430 if (PvPDifficultyEntry
const* entry
= sPvPDifficultyStore
.LookupEntry(i
))
431 if (entry
->bracketId
> MAX_BATTLEGROUND_BRACKETS
)
432 assert(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data");
434 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sRandomPropertiesPointsStore
, dbcPath
,"RandPropPoints.dbc");
435 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sScalingStatDistributionStore
, dbcPath
,"ScalingStatDistribution.dbc");
436 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sScalingStatValuesStore
, dbcPath
,"ScalingStatValues.dbc");
437 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSkillLineStore
, dbcPath
,"SkillLine.dbc");
438 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSkillLineAbilityStore
, dbcPath
,"SkillLineAbility.dbc");
439 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSoundEntriesStore
, dbcPath
,"SoundEntries.dbc");
440 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellStore
, dbcPath
,"Spell.dbc");
441 for(uint32 i
= 1; i
< sSpellStore
.GetNumRows(); ++i
)
443 SpellEntry
const * spell
= sSpellStore
.LookupEntry(i
);
444 if(spell
&& spell
->Category
)
445 sSpellCategoryStore
[spell
->Category
].insert(i
);
447 // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields
448 // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view
449 #if MANGOS_ENDIAN == MANGOS_BIGENDIAN
450 std::swap(*((uint32
*)(&spell
->SpellFamilyFlags
)),*(((uint32
*)(&spell
->SpellFamilyFlags
))+1));
454 for (uint32 j
= 0; j
< sSkillLineAbilityStore
.GetNumRows(); ++j
)
456 SkillLineAbilityEntry
const *skillLine
= sSkillLineAbilityStore
.LookupEntry(j
);
461 SpellEntry
const* spellInfo
= sSpellStore
.LookupEntry(skillLine
->spellId
);
463 if(spellInfo
&& (spellInfo
->Attributes
& 0x1D0) == 0x1D0)
465 for (unsigned int i
= 1; i
< sCreatureFamilyStore
.GetNumRows(); ++i
)
467 CreatureFamilyEntry
const* cFamily
= sCreatureFamilyStore
.LookupEntry(i
);
471 if(skillLine
->skillId
!= cFamily
->skillLine
[0] && skillLine
->skillId
!= cFamily
->skillLine
[1])
474 sPetFamilySpellsStore
[i
].insert(spellInfo
->Id
);
479 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellCastTimesStore
, dbcPath
,"SpellCastTimes.dbc");
480 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellDurationStore
, dbcPath
,"SpellDuration.dbc");
481 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellFocusObjectStore
, dbcPath
,"SpellFocusObject.dbc");
482 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellItemEnchantmentStore
,dbcPath
,"SpellItemEnchantment.dbc");
483 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellItemEnchantmentConditionStore
,dbcPath
,"SpellItemEnchantmentCondition.dbc");
484 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellRadiusStore
, dbcPath
,"SpellRadius.dbc");
485 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellRangeStore
, dbcPath
,"SpellRange.dbc");
486 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellRuneCostStore
, dbcPath
,"SpellRuneCost.dbc");
487 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSpellShapeshiftStore
, dbcPath
,"SpellShapeshiftForm.dbc");
488 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sStableSlotPricesStore
, dbcPath
,"StableSlotPrices.dbc");
489 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sSummonPropertiesStore
, dbcPath
,"SummonProperties.dbc");
490 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sTalentStore
, dbcPath
,"Talent.dbc");
492 // create talent spells set
493 for (unsigned int i
= 0; i
< sTalentStore
.GetNumRows(); ++i
)
495 TalentEntry
const *talentInfo
= sTalentStore
.LookupEntry(i
);
496 if (!talentInfo
) continue;
497 for (int j
= 0; j
< MAX_TALENT_RANK
; j
++)
498 if(talentInfo
->RankID
[j
])
499 sTalentSpellPosMap
[talentInfo
->RankID
[j
]] = TalentSpellPos(i
,j
);
502 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sTalentTabStore
, dbcPath
,"TalentTab.dbc");
504 // prepare fast data access to bit pos of talent ranks for use at inspecting
506 // now have all max ranks (and then bit amount used for store talent ranks in inspect)
507 for(uint32 talentTabId
= 1; talentTabId
< sTalentTabStore
.GetNumRows(); ++talentTabId
)
509 TalentTabEntry
const *talentTabInfo
= sTalentTabStore
.LookupEntry( talentTabId
);
513 // prevent memory corruption; otherwise cls will become 12 below
514 if ((talentTabInfo
->ClassMask
& CLASSMASK_ALL_PLAYABLE
)==0)
517 // store class talent tab pages
519 for(uint32 m
=1;!(m
& talentTabInfo
->ClassMask
) && cls
< MAX_CLASSES
;m
<<=1, ++cls
) {}
521 sTalentTabPages
[cls
][talentTabInfo
->tabpage
]=talentTabId
;
525 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sTaxiNodesStore
, dbcPath
,"TaxiNodes.dbc");
527 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sTaxiPathStore
, dbcPath
,"TaxiPath.dbc");
528 for(uint32 i
= 1; i
< sTaxiPathStore
.GetNumRows(); ++i
)
529 if(TaxiPathEntry
const* entry
= sTaxiPathStore
.LookupEntry(i
))
530 sTaxiPathSetBySource
[entry
->from
][entry
->to
] = TaxiPathBySourceAndDestination(entry
->ID
,entry
->price
);
531 uint32 pathCount
= sTaxiPathStore
.GetNumRows();
533 //## TaxiPathNode.dbc ## Loaded only for initialization different structures
534 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sTaxiPathNodeStore
, dbcPath
,"TaxiPathNode.dbc");
535 // Calculate path nodes count
536 std::vector
<uint32
> pathLength
;
537 pathLength
.resize(pathCount
); // 0 and some other indexes not used
538 for(uint32 i
= 1; i
< sTaxiPathNodeStore
.GetNumRows(); ++i
)
539 if(TaxiPathNodeEntry
const* entry
= sTaxiPathNodeStore
.LookupEntry(i
))
541 if (pathLength
[entry
->path
] < entry
->index
+ 1)
542 pathLength
[entry
->path
] = entry
->index
+ 1;
545 sTaxiPathNodesByPath
.resize(pathCount
); // 0 and some other indexes not used
546 for(uint32 i
= 1; i
< sTaxiPathNodesByPath
.size(); ++i
)
547 sTaxiPathNodesByPath
[i
].resize(pathLength
[i
]);
549 for(uint32 i
= 1; i
< sTaxiPathNodeStore
.GetNumRows(); ++i
)
550 if(TaxiPathNodeEntry
const* entry
= sTaxiPathNodeStore
.LookupEntry(i
))
551 sTaxiPathNodesByPath
[entry
->path
][entry
->index
] = TaxiPathNode(entry
->mapid
,entry
->x
,entry
->y
,entry
->z
,entry
->actionFlag
,entry
->delay
);
552 sTaxiPathNodeStore
.Clear();
554 // Initialize global taxinodes mask
555 // include existed nodes that have at least single not spell base (scripted) path
557 std::set
<uint32
> spellPaths
;
558 for(uint32 i
= 1; i
< sSpellStore
.GetNumRows (); ++i
)
559 if(SpellEntry
const* sInfo
= sSpellStore
.LookupEntry (i
))
560 for(int j
=0; j
< MAX_EFFECT_INDEX
; ++j
)
561 if(sInfo
->Effect
[j
]==123 /*SPELL_EFFECT_SEND_TAXI*/)
562 spellPaths
.insert(sInfo
->EffectMiscValue
[j
]);
564 memset(sTaxiNodesMask
,0,sizeof(sTaxiNodesMask
));
565 memset(sOldContinentsNodesMask
,0,sizeof(sTaxiNodesMask
));
566 for(uint32 i
= 1; i
< sTaxiNodesStore
.GetNumRows(); ++i
)
568 TaxiNodesEntry
const* node
= sTaxiNodesStore
.LookupEntry(i
);
572 TaxiPathSetBySource::const_iterator src_i
= sTaxiPathSetBySource
.find(i
);
573 if(src_i
!=sTaxiPathSetBySource
.end() && !src_i
->second
.empty())
576 for(TaxiPathSetForSource::const_iterator dest_i
= src_i
->second
.begin();dest_i
!= src_i
->second
.end(); ++dest_i
)
579 if(spellPaths
.find(dest_i
->second
.ID
)==spellPaths
.end())
590 // valid taxi network node
591 uint8 field
= (uint8
)((i
- 1) / 32);
592 uint32 submask
= 1<<((i
-1)%32);
593 sTaxiNodesMask
[field
] |= submask
;
595 // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info)
596 if (node
->map_id
< 2 || i
== 82 || i
== 83 || i
== 93 || i
== 94)
597 sOldContinentsNodesMask
[field
] |= submask
;
601 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sTotemCategoryStore
, dbcPath
,"TotemCategory.dbc");
602 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sVehicleStore
, dbcPath
,"Vehicle.dbc");
603 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sVehicleSeatStore
, dbcPath
,"VehicleSeat.dbc");
604 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sWorldMapAreaStore
, dbcPath
,"WorldMapArea.dbc");
605 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sWorldMapOverlayStore
, dbcPath
,"WorldMapOverlay.dbc");
606 LoadDBC(availableDbcLocales
,bar
,bad_dbc_files
,sWorldSafeLocsStore
, dbcPath
,"WorldSafeLocs.dbc");
609 if(bad_dbc_files
.size() >= DBCFilesCount
)
611 sLog
.outError("\nIncorrect DataDir value in mangosd.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount
,dataPath
.c_str());
614 else if(!bad_dbc_files
.empty() )
617 for(std::list
<std::string
>::iterator i
= bad_dbc_files
.begin(); i
!= bad_dbc_files
.end(); ++i
)
620 sLog
.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",(uint32
)bad_dbc_files
.size(),DBCFilesCount
,str
.c_str());
624 // Check loaded DBC files proper version
625 if( !sSpellStore
.LookupEntry(74445) || // last added spell in 3.3.2
626 !sMapStore
.LookupEntry(718) || // last map added in 3.3.2
627 !sGemPropertiesStore
.LookupEntry(1629) || // last gem property added in 3.3.2
628 !sItemExtendedCostStore
.LookupEntry(2982) || // last item extended cost added in 3.3.2
629 !sCharTitlesStore
.LookupEntry(177) || // last char title added in 3.3.2
630 !sAreaStore
.LookupEntry(3461) || // last area (areaflag) added in 3.3.2
631 !sItemStore
.LookupEntry(52686) ) // last client known item added in 3.3.2
633 sLog
.outError("\nYou have mixed version DBC files. Please re-extract DBC files for one from client build: %s",AcceptableClientBuildsListStr().c_str());
638 sLog
.outString( ">> Initialized %d data stores", DBCFilesCount
);
641 SimpleFactionsList
const* GetFactionTeamList(uint32 faction
)
643 FactionTeamMap::const_iterator itr
= sFactionTeamMap
.find(faction
);
644 if(itr
==sFactionTeamMap
.end())
649 char* GetPetName(uint32 petfamily
, uint32 dbclang
)
653 CreatureFamilyEntry
const *pet_family
= sCreatureFamilyStore
.LookupEntry(petfamily
);
656 return pet_family
->Name
[dbclang
]?pet_family
->Name
[dbclang
]:NULL
;
659 TalentSpellPos
const* GetTalentSpellPos(uint32 spellId
)
661 TalentSpellPosMap::const_iterator itr
= sTalentSpellPosMap
.find(spellId
);
662 if(itr
==sTalentSpellPosMap
.end())
668 uint32
GetTalentSpellCost(uint32 spellId
)
670 if(TalentSpellPos
const* pos
= GetTalentSpellPos(spellId
))
676 int32
GetAreaFlagByAreaID(uint32 area_id
)
678 AreaFlagByAreaID::iterator i
= sAreaFlagByAreaID
.find(area_id
);
679 if(i
== sAreaFlagByAreaID
.end())
685 AreaTableEntry
const* GetAreaEntryByAreaID(uint32 area_id
)
687 int32 areaflag
= GetAreaFlagByAreaID(area_id
);
691 return sAreaStore
.LookupEntry(areaflag
);
694 AreaTableEntry
const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag
,uint32 map_id
)
697 return sAreaStore
.LookupEntry(area_flag
);
699 if(MapEntry
const* mapEntry
= sMapStore
.LookupEntry(map_id
))
700 return GetAreaEntryByAreaID(mapEntry
->linked_zone
);
705 uint32
GetAreaFlagByMapId(uint32 mapid
)
707 AreaFlagByMapID::iterator i
= sAreaFlagByMapID
.find(mapid
);
708 if(i
== sAreaFlagByMapID
.end())
714 uint32
GetVirtualMapForMapAndZone(uint32 mapid
, uint32 zoneId
)
716 if(mapid
!= 530 && mapid
!= 571) // speed for most cases
719 if(WorldMapAreaEntry
const* wma
= sWorldMapAreaStore
.LookupEntry(zoneId
))
720 return wma
->virtual_map_id
>= 0 ? wma
->virtual_map_id
: wma
->map_id
;
725 ContentLevels
GetContentLevelsForMapAndZone(uint32 mapid
, uint32 zoneId
)
727 mapid
= GetVirtualMapForMapAndZone(mapid
,zoneId
);
731 MapEntry
const* mapEntry
= sMapStore
.LookupEntry(mapid
);
735 switch(mapEntry
->Expansion())
737 default: return CONTENT_1_60
;
738 case 1: return CONTENT_61_70
;
739 case 2: return CONTENT_71_80
;
743 ChatChannelsEntry
const* GetChannelEntryFor(uint32 channel_id
)
745 // not sorted, numbering index from 0
746 for(uint32 i
= 0; i
< sChatChannelsStore
.GetNumRows(); ++i
)
748 ChatChannelsEntry
const* ch
= sChatChannelsStore
.LookupEntry(i
);
749 if(ch
&& ch
->ChannelID
== channel_id
)
755 bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId
, uint32 requiredTotemCategoryId
)
757 if(requiredTotemCategoryId
==0)
759 if(itemTotemCategoryId
==0)
762 TotemCategoryEntry
const* itemEntry
= sTotemCategoryStore
.LookupEntry(itemTotemCategoryId
);
765 TotemCategoryEntry
const* reqEntry
= sTotemCategoryStore
.LookupEntry(requiredTotemCategoryId
);
769 if(itemEntry
->categoryType
!=reqEntry
->categoryType
)
772 return (itemEntry
->categoryMask
& reqEntry
->categoryMask
)==reqEntry
->categoryMask
;
775 bool Zone2MapCoordinates(float& x
,float& y
,uint32 zone
)
777 WorldMapAreaEntry
const* maEntry
= sWorldMapAreaStore
.LookupEntry(zone
);
779 // if not listed then map coordinates (instance)
780 if (!maEntry
|| maEntry
->x2
== maEntry
->x1
|| maEntry
->y2
== maEntry
->y1
)
783 std::swap(x
,y
); // at client map coords swapped
784 x
= x
*((maEntry
->x2
-maEntry
->x1
)/100)+maEntry
->x1
;
785 y
= y
*((maEntry
->y2
-maEntry
->y1
)/100)+maEntry
->y1
; // client y coord from top to down
790 bool Map2ZoneCoordinates(float& x
,float& y
,uint32 zone
)
792 WorldMapAreaEntry
const* maEntry
= sWorldMapAreaStore
.LookupEntry(zone
);
794 // if not listed then map coordinates (instance)
795 if (!maEntry
|| maEntry
->x2
== maEntry
->x1
|| maEntry
->y2
== maEntry
->y1
)
798 x
= (x
-maEntry
->x1
)/((maEntry
->x2
-maEntry
->x1
)/100);
799 y
= (y
-maEntry
->y1
)/((maEntry
->y2
-maEntry
->y1
)/100); // client y coord from top to down
800 std::swap(x
,y
); // client have map coords swapped
805 MapDifficulty
const* GetMapDifficultyData(uint32 mapId
, Difficulty difficulty
)
807 MapDifficultyMap::const_iterator itr
= sMapDifficultyMap
.find(MAKE_PAIR32(mapId
,difficulty
));
808 return itr
!= sMapDifficultyMap
.end() ? &itr
->second
: NULL
;
811 PvPDifficultyEntry
const* GetBattlegroundBracketByLevel( uint32 mapid
, uint32 level
)
813 // prevent out-of-range levels for dbc data
814 if (level
> DEFAULT_MAX_LEVEL
)
815 level
= DEFAULT_MAX_LEVEL
;
817 for(uint32 i
= 0; i
< sPvPDifficultyStore
.GetNumRows(); ++i
)
818 if (PvPDifficultyEntry
const* entry
= sPvPDifficultyStore
.LookupEntry(i
))
819 if (entry
->mapId
== mapid
&& entry
->minLevel
<= level
&& entry
->maxLevel
>= level
)
825 PvPDifficultyEntry
const* GetBattlegroundBracketById(uint32 mapid
, BattleGroundBracketId id
)
827 for(uint32 i
= 0; i
< sPvPDifficultyStore
.GetNumRows(); ++i
)
828 if (PvPDifficultyEntry
const* entry
= sPvPDifficultyStore
.LookupEntry(i
))
829 if (entry
->mapId
== mapid
&& entry
->GetBracketId() == id
)
835 uint32
const* GetTalentTabPages(uint32 cls
)
837 return sTalentTabPages
[cls
];
840 // script support functions
841 MANGOS_DLL_SPEC DBCStorage
<SoundEntriesEntry
> const* GetSoundEntriesStore() { return &sSoundEntriesStore
; }
842 MANGOS_DLL_SPEC DBCStorage
<SpellEntry
> const* GetSpellStore() { return &sSpellStore
; }
843 MANGOS_DLL_SPEC DBCStorage
<SpellRangeEntry
> const* GetSpellRangeStore() { return &sSpellRangeStore
; }
844 MANGOS_DLL_SPEC DBCStorage
<FactionEntry
> const* GetFactionStore() { return &sFactionStore
; }
845 MANGOS_DLL_SPEC DBCStorage
<ItemEntry
> const* GetItemDisplayStore() { return &sItemStore
; }
846 MANGOS_DLL_SPEC DBCStorage
<CreatureDisplayInfoEntry
> const* GetCreatureDisplayStore() { return &sCreatureDisplayInfoStore
; }
847 MANGOS_DLL_SPEC DBCStorage
<EmotesEntry
> const* GetEmotesStore() { return &sEmotesStore
; }
848 MANGOS_DLL_SPEC DBCStorage
<EmotesTextEntry
> const* GetEmotesTextStore() { return &sEmotesTextStore
; }