1 | /* |
---|
2 | * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> |
---|
3 | * |
---|
4 | * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> |
---|
5 | * |
---|
6 | * This program is free software; you can redistribute it and/or modify |
---|
7 | * it under the terms of the GNU General Public License as published by |
---|
8 | * the Free Software Foundation; either version 2 of the License, or |
---|
9 | * (at your option) any later version. |
---|
10 | * |
---|
11 | * This program is distributed in the hope that it will be useful, |
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | * GNU General Public License for more details. |
---|
15 | * |
---|
16 | * You should have received a copy of the GNU General Public License |
---|
17 | * along with this program; if not, write to the Free Software |
---|
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
19 | */ |
---|
20 | |
---|
21 | #include "DBCStores.h" |
---|
22 | //#include "DataStore.h" |
---|
23 | #include "Policies/SingletonImp.h" |
---|
24 | #include "Log.h" |
---|
25 | #include "ProgressBar.h" |
---|
26 | |
---|
27 | #include "DBCfmt.cpp" |
---|
28 | |
---|
29 | #include <map> |
---|
30 | |
---|
31 | typedef std::map<uint16,uint32> AreaFlagByAreaID; |
---|
32 | typedef std::map<uint32,uint32> AreaFlagByMapID; |
---|
33 | |
---|
34 | DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt); |
---|
35 | static AreaFlagByAreaID sAreaFlagByAreaID; |
---|
36 | static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files |
---|
37 | |
---|
38 | DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt); |
---|
39 | DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt); |
---|
40 | DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt); |
---|
41 | DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt); |
---|
42 | DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt); |
---|
43 | DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt); |
---|
44 | DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt); |
---|
45 | DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt); |
---|
46 | DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt); |
---|
47 | DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt); |
---|
48 | |
---|
49 | DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore(DurabilityQualityfmt); |
---|
50 | DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore(DurabilityCostsfmt); |
---|
51 | |
---|
52 | DBCStorage <EmotesTextEntry> sEmotesTextStore(EmoteEntryfmt); |
---|
53 | |
---|
54 | typedef std::map<uint32,SimpleFactionsList> FactionTeamMap; |
---|
55 | static FactionTeamMap sFactionTeamMap; |
---|
56 | DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt); |
---|
57 | DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt); |
---|
58 | |
---|
59 | DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt); |
---|
60 | |
---|
61 | DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore(GtCombatRatingsfmt); |
---|
62 | DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt); |
---|
63 | DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt); |
---|
64 | DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt); |
---|
65 | DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore(GtChanceToSpellCritfmt); |
---|
66 | DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt); |
---|
67 | //DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently |
---|
68 | DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt); |
---|
69 | DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt); |
---|
70 | DBCStorage <ItemEntry> sItemStore(Itemfmt); |
---|
71 | //DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt); |
---|
72 | //DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently |
---|
73 | DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt); |
---|
74 | DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt); |
---|
75 | DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt); |
---|
76 | DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt); |
---|
77 | |
---|
78 | DBCStorage <LockEntry> sLockStore(LockEntryfmt); |
---|
79 | |
---|
80 | DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt); |
---|
81 | DBCStorage <MapEntry> sMapStore(MapEntryfmt); |
---|
82 | |
---|
83 | DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt); |
---|
84 | |
---|
85 | DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt); |
---|
86 | |
---|
87 | DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt); |
---|
88 | DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt); |
---|
89 | |
---|
90 | DBCStorage <SoundEntriesEntry> sSoundEntriesStore(SoundEntriesfmt); |
---|
91 | |
---|
92 | DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore(SpellItemEnchantmentfmt); |
---|
93 | DBCStorage <SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore(SpellItemEnchantmentConditionfmt); |
---|
94 | DBCStorage <SpellEntry> sSpellStore(SpellEntryfmt); |
---|
95 | SpellCategoryStore sSpellCategoryStore; |
---|
96 | PetFamilySpellsStore sPetFamilySpellsStore; |
---|
97 | |
---|
98 | DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore(SpellCastTimefmt); |
---|
99 | DBCStorage <SpellDurationEntry> sSpellDurationStore(SpellDurationfmt); |
---|
100 | DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt); |
---|
101 | DBCStorage <SpellRadiusEntry> sSpellRadiusStore(SpellRadiusfmt); |
---|
102 | DBCStorage <SpellRangeEntry> sSpellRangeStore(SpellRangefmt); |
---|
103 | DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftfmt); |
---|
104 | DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt); |
---|
105 | DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt); |
---|
106 | TalentSpellPosMap sTalentSpellPosMap; |
---|
107 | DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt); |
---|
108 | |
---|
109 | // store absolute bit position for first rank for talent inspect |
---|
110 | typedef std::map<uint32,uint32> TalentInspectMap; |
---|
111 | static TalentInspectMap sTalentPosInInspect; |
---|
112 | static TalentInspectMap sTalentTabSizeInInspect; |
---|
113 | static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3]; |
---|
114 | |
---|
115 | DBCStorage <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt); |
---|
116 | TaxiMask sTaxiNodesMask; |
---|
117 | |
---|
118 | // DBC used only for initialization sTaxiPathSetBySource at startup. |
---|
119 | TaxiPathSetBySource sTaxiPathSetBySource; |
---|
120 | DBCStorage <TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt); |
---|
121 | |
---|
122 | // DBC used only for initialization sTaxiPathSetBySource at startup. |
---|
123 | TaxiPathNodesByPath sTaxiPathNodesByPath; |
---|
124 | struct TaxiPathNodeEntry |
---|
125 | { |
---|
126 | uint32 path; |
---|
127 | uint32 index; |
---|
128 | uint32 mapid; |
---|
129 | float x; |
---|
130 | float y; |
---|
131 | float z; |
---|
132 | uint32 actionFlag; |
---|
133 | uint32 delay; |
---|
134 | }; |
---|
135 | static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt); |
---|
136 | |
---|
137 | DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt); |
---|
138 | |
---|
139 | DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt); |
---|
140 | DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt); |
---|
141 | |
---|
142 | typedef std::list<std::string> StoreProblemList; |
---|
143 | |
---|
144 | static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, std::string filename) |
---|
145 | { |
---|
146 | sLog.outError("ERROR: Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).",filename.c_str(),fsize,rsize); |
---|
147 | |
---|
148 | // assert must fail after function call |
---|
149 | return false; |
---|
150 | } |
---|
151 | |
---|
152 | template<class T> |
---|
153 | inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage<T>& storage, std::string dbc_path, std::string filename) |
---|
154 | { |
---|
155 | // compatibility format and C++ structure sizes |
---|
156 | assert(DBCFile::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFile::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename)); |
---|
157 | |
---|
158 | std::string dbc_filename = dbc_path + filename; |
---|
159 | if(storage.Load(dbc_filename.c_str())) |
---|
160 | { |
---|
161 | bar.step(); |
---|
162 | for(uint8 i = 0; i < MAX_LOCALE; ++i) |
---|
163 | { |
---|
164 | if(!(availableDbcLocales & (1 << i))) |
---|
165 | continue; |
---|
166 | |
---|
167 | std::string dbc_filename_loc = dbc_path + localeNames[i] + "/" + filename; |
---|
168 | if(!storage.LoadStringsFrom(dbc_filename_loc.c_str())) |
---|
169 | availableDbcLocales &= ~(1<<i); // mark as not available for speedup next checks |
---|
170 | } |
---|
171 | } |
---|
172 | else |
---|
173 | { |
---|
174 | // sort problematic dbc to (1) non compatible and (2) non-existed |
---|
175 | FILE * f=fopen(dbc_filename.c_str(),"rb"); |
---|
176 | if(f) |
---|
177 | { |
---|
178 | char buf[100]; |
---|
179 | snprintf(buf,100," (exist, but have %d fields instead %d) Wrong client version DBC file?",storage.GetFieldCount(),strlen(storage.GetFormat())); |
---|
180 | errlist.push_back(dbc_filename + buf); |
---|
181 | fclose(f); |
---|
182 | } |
---|
183 | else |
---|
184 | errlist.push_back(dbc_filename); |
---|
185 | } |
---|
186 | } |
---|
187 | |
---|
188 | void LoadDBCStores(std::string dataPath) |
---|
189 | { |
---|
190 | std::string dbcPath = dataPath+"dbc/"; |
---|
191 | |
---|
192 | const uint32 DBCFilesCount = 56; |
---|
193 | |
---|
194 | barGoLink bar( DBCFilesCount ); |
---|
195 | |
---|
196 | StoreProblemList bad_dbc_files; |
---|
197 | uint32 availableDbcLocales = 0xFFFFFFFF; |
---|
198 | |
---|
199 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaStore, dbcPath,"AreaTable.dbc"); |
---|
200 | |
---|
201 | // must be after sAreaStore loading |
---|
202 | for(uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0 |
---|
203 | { |
---|
204 | if(AreaTableEntry const* area = sAreaStore.LookupEntry(i)) |
---|
205 | { |
---|
206 | // fill AreaId->DBC records |
---|
207 | sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag)); |
---|
208 | |
---|
209 | // fill MapId->DBC records ( skip sub zones and continents ) |
---|
210 | if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 ) |
---|
211 | sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag)); |
---|
212 | } |
---|
213 | } |
---|
214 | |
---|
215 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); |
---|
216 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); |
---|
217 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); |
---|
218 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); |
---|
219 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); |
---|
220 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); |
---|
221 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc"); |
---|
222 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc"); |
---|
223 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc"); |
---|
224 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc"); |
---|
225 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc"); |
---|
226 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc"); |
---|
227 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc"); |
---|
228 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc"); |
---|
229 | for (uint32 i=0;i<sFactionStore.GetNumRows(); ++i) |
---|
230 | { |
---|
231 | FactionEntry const * faction = sFactionStore.LookupEntry(i); |
---|
232 | if (faction && faction->team) |
---|
233 | { |
---|
234 | SimpleFactionsList &flist = sFactionTeamMap[faction->team]; |
---|
235 | flist.push_back(i); |
---|
236 | } |
---|
237 | } |
---|
238 | |
---|
239 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); |
---|
240 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); |
---|
241 | |
---|
242 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); |
---|
243 | |
---|
244 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); |
---|
245 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc"); |
---|
246 | |
---|
247 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc"); |
---|
248 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc"); |
---|
249 | |
---|
250 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc"); |
---|
251 | //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently |
---|
252 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc"); |
---|
253 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc"); |
---|
254 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.dbc"); |
---|
255 | //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently |
---|
256 | //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); |
---|
257 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc"); |
---|
258 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc"); |
---|
259 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc"); |
---|
260 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc"); |
---|
261 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc"); |
---|
262 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc"); |
---|
263 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); |
---|
264 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); |
---|
265 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); |
---|
266 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); |
---|
267 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); |
---|
268 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); |
---|
269 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc"); |
---|
270 | for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) |
---|
271 | { |
---|
272 | SpellEntry const * spell = sSpellStore.LookupEntry(i); |
---|
273 | if(spell && spell->Category) |
---|
274 | sSpellCategoryStore[spell->Category].insert(i); |
---|
275 | |
---|
276 | // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields |
---|
277 | // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view |
---|
278 | #if TRINITY_ENDIAN == TRINITY_BIGENDIAN |
---|
279 | std::swap(*((uint32*)(&spell->SpellFamilyFlags)),*(((uint32*)(&spell->SpellFamilyFlags))+1)); |
---|
280 | #endif |
---|
281 | } |
---|
282 | |
---|
283 | for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) |
---|
284 | { |
---|
285 | SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); |
---|
286 | |
---|
287 | if(!skillLine) |
---|
288 | continue; |
---|
289 | |
---|
290 | SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); |
---|
291 | |
---|
292 | if(spellInfo && (spellInfo->Attributes & 0x1D0) == 0x1D0) |
---|
293 | { |
---|
294 | for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) |
---|
295 | { |
---|
296 | CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); |
---|
297 | if(!cFamily) |
---|
298 | continue; |
---|
299 | |
---|
300 | if(skillLine->skillId != cFamily->skillLine && skillLine->skillId != cFamily->skillLine2) |
---|
301 | continue; |
---|
302 | |
---|
303 | sPetFamilySpellsStore[i].insert(spellInfo->Id); |
---|
304 | } |
---|
305 | } |
---|
306 | } |
---|
307 | |
---|
308 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc"); |
---|
309 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc"); |
---|
310 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc"); |
---|
311 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc"); |
---|
312 | |
---|
313 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc"); |
---|
314 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc"); |
---|
315 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc"); |
---|
316 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc"); |
---|
317 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); |
---|
318 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); |
---|
319 | |
---|
320 | // create talent spells set |
---|
321 | for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) |
---|
322 | { |
---|
323 | TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); |
---|
324 | if (!talentInfo) continue; |
---|
325 | for (int j = 0; j < 5; j++) |
---|
326 | if(talentInfo->RankID[j]) |
---|
327 | sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j); |
---|
328 | } |
---|
329 | |
---|
330 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc"); |
---|
331 | |
---|
332 | // preper fast data access to bit pos of talent ranks for use at inspecting |
---|
333 | { |
---|
334 | // fill table by amount of talent ranks and fill sTalentTabBitSizeInInspect |
---|
335 | // store in with (row,col,talent)->size key for correct sorting by (row,col) |
---|
336 | typedef std::map<uint32,uint32> TalentBitSize; |
---|
337 | TalentBitSize sTalentBitSize; |
---|
338 | for(uint32 i = 1; i < sTalentStore.GetNumRows(); ++i) |
---|
339 | { |
---|
340 | TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); |
---|
341 | if (!talentInfo) continue; |
---|
342 | |
---|
343 | TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); |
---|
344 | if(!talentTabInfo) |
---|
345 | continue; |
---|
346 | |
---|
347 | // find talent rank |
---|
348 | uint32 curtalent_maxrank = 0; |
---|
349 | for(uint32 k = 5; k > 0; --k) |
---|
350 | { |
---|
351 | if(talentInfo->RankID[k-1]) |
---|
352 | { |
---|
353 | curtalent_maxrank = k; |
---|
354 | break; |
---|
355 | } |
---|
356 | } |
---|
357 | |
---|
358 | sTalentBitSize[(talentInfo->Row<<24) + (talentInfo->Col<<16)+talentInfo->TalentID] = curtalent_maxrank; |
---|
359 | sTalentTabSizeInInspect[talentInfo->TalentTab] += curtalent_maxrank; |
---|
360 | } |
---|
361 | |
---|
362 | // now have all max ranks (and then bit amount used for store talent ranks in inspect) |
---|
363 | for(uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) |
---|
364 | { |
---|
365 | TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentTabId ); |
---|
366 | if(!talentTabInfo) |
---|
367 | continue; |
---|
368 | |
---|
369 | // store class talent tab pages |
---|
370 | uint32 cls = 1; |
---|
371 | for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < 12 /*MAX_CLASSES*/;m <<=1, ++cls) {} |
---|
372 | |
---|
373 | sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; |
---|
374 | |
---|
375 | // add total amount bits for first rank starting from talent tab first talent rank pos. |
---|
376 | uint32 pos = 0; |
---|
377 | for(TalentBitSize::iterator itr = sTalentBitSize.begin(); itr != sTalentBitSize.end(); ++itr) |
---|
378 | { |
---|
379 | uint32 talentId = itr->first & 0xFFFF; |
---|
380 | TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentId ); |
---|
381 | if(!talentInfo) |
---|
382 | continue; |
---|
383 | |
---|
384 | if(talentInfo->TalentTab != talentTabId) |
---|
385 | continue; |
---|
386 | |
---|
387 | sTalentPosInInspect[talentId] = pos; |
---|
388 | pos+= itr->second; |
---|
389 | } |
---|
390 | } |
---|
391 | } |
---|
392 | |
---|
393 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc"); |
---|
394 | |
---|
395 | // Initialize global taxinodes mask |
---|
396 | memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask)); |
---|
397 | for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) |
---|
398 | { |
---|
399 | if(sTaxiNodesStore.LookupEntry(i)) |
---|
400 | { |
---|
401 | uint8 field = (uint8)((i - 1) / 32); |
---|
402 | uint32 submask = 1<<((i-1)%32); |
---|
403 | sTaxiNodesMask[field] |= submask; |
---|
404 | } |
---|
405 | } |
---|
406 | |
---|
407 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc"); |
---|
408 | for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) |
---|
409 | if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) |
---|
410 | sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price); |
---|
411 | uint32 pathCount = sTaxiPathStore.GetNumRows(); |
---|
412 | |
---|
413 | //## TaxiPathNode.dbc ## Loaded only for initialization different structures |
---|
414 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc"); |
---|
415 | // Calculate path nodes count |
---|
416 | std::vector<uint32> pathLength; |
---|
417 | pathLength.resize(pathCount); // 0 and some other indexes not used |
---|
418 | for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) |
---|
419 | if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) |
---|
420 | ++pathLength[entry->path]; |
---|
421 | // Set path length |
---|
422 | sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used |
---|
423 | for(uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) |
---|
424 | sTaxiPathNodesByPath[i].resize(pathLength[i]); |
---|
425 | // fill data |
---|
426 | for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) |
---|
427 | if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) |
---|
428 | sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay); |
---|
429 | sTaxiPathNodeStore.Clear(); |
---|
430 | |
---|
431 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); |
---|
432 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); |
---|
433 | LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); |
---|
434 | |
---|
435 | // error checks |
---|
436 | if(bad_dbc_files.size() >= DBCFilesCount ) |
---|
437 | { |
---|
438 | sLog.outError("\nIncorrect DataDir value in Trinityd.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str()); |
---|
439 | exit(1); |
---|
440 | } |
---|
441 | else if(!bad_dbc_files.empty() ) |
---|
442 | { |
---|
443 | std::string str; |
---|
444 | for(std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) |
---|
445 | str += *i + "\n"; |
---|
446 | |
---|
447 | sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",bad_dbc_files.size(),DBCFilesCount,str.c_str()); |
---|
448 | exit(1); |
---|
449 | } |
---|
450 | |
---|
451 | // check at up-to-date DBC files (53085 is last added spell in 2.4.3) |
---|
452 | // check at up-to-date DBC files (17514 is last ID in SkillLineAbilities in 2.4.3) |
---|
453 | // check at up-to-date DBC files (598 is last map added in 2.4.3) |
---|
454 | // check at up-to-date DBC files (1127 is last gem property added in 2.4.3) |
---|
455 | // check at up-to-date DBC files (2425 is last item extended cost added in 2.4.3) |
---|
456 | // check at up-to-date DBC files (71 is last char title added in 2.4.3) |
---|
457 | // check at up-to-date DBC files (1768 is last area added in 2.4.3) |
---|
458 | if( !sSpellStore.LookupEntry(53085) || |
---|
459 | !sSkillLineAbilityStore.LookupEntry(17514) || |
---|
460 | !sMapStore.LookupEntry(598) || |
---|
461 | !sGemPropertiesStore.LookupEntry(1127) || |
---|
462 | !sItemExtendedCostStore.LookupEntry(2425) || |
---|
463 | !sCharTitlesStore.LookupEntry(71) || |
---|
464 | !sAreaStore.LookupEntry(1768) ) |
---|
465 | { |
---|
466 | sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); |
---|
467 | exit(1); |
---|
468 | } |
---|
469 | |
---|
470 | sLog.outString(); |
---|
471 | sLog.outString( ">> Loaded %d data stores", DBCFilesCount ); |
---|
472 | sLog.outString(); |
---|
473 | } |
---|
474 | |
---|
475 | SimpleFactionsList const* GetFactionTeamList(uint32 faction) |
---|
476 | { |
---|
477 | FactionTeamMap::const_iterator itr = sFactionTeamMap.find(faction); |
---|
478 | if(itr==sFactionTeamMap.end()) |
---|
479 | return NULL; |
---|
480 | return &itr->second; |
---|
481 | } |
---|
482 | |
---|
483 | char* GetPetName(uint32 petfamily, uint32 dbclang) |
---|
484 | { |
---|
485 | if(!petfamily) |
---|
486 | return NULL; |
---|
487 | CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(petfamily); |
---|
488 | if(!pet_family) |
---|
489 | return NULL; |
---|
490 | return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL; |
---|
491 | } |
---|
492 | |
---|
493 | TalentSpellPos const* GetTalentSpellPos(uint32 spellId) |
---|
494 | { |
---|
495 | TalentSpellPosMap::const_iterator itr = sTalentSpellPosMap.find(spellId); |
---|
496 | if(itr==sTalentSpellPosMap.end()) |
---|
497 | return NULL; |
---|
498 | |
---|
499 | return &itr->second; |
---|
500 | } |
---|
501 | |
---|
502 | uint32 GetTalentSpellCost(uint32 spellId) |
---|
503 | { |
---|
504 | if(TalentSpellPos const* pos = GetTalentSpellPos(spellId)) |
---|
505 | return pos->rank+1; |
---|
506 | |
---|
507 | return 0; |
---|
508 | } |
---|
509 | |
---|
510 | AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id) |
---|
511 | { |
---|
512 | AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id); |
---|
513 | if(i == sAreaFlagByAreaID.end()) |
---|
514 | return NULL; |
---|
515 | |
---|
516 | return sAreaStore.LookupEntry(i->second); |
---|
517 | } |
---|
518 | |
---|
519 | AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id) |
---|
520 | { |
---|
521 | if(area_flag) |
---|
522 | return sAreaStore.LookupEntry(area_flag); |
---|
523 | |
---|
524 | if(MapEntry const* mapEntry = sMapStore.LookupEntry(map_id)) |
---|
525 | return GetAreaEntryByAreaID(mapEntry->linked_zone); |
---|
526 | |
---|
527 | return NULL; |
---|
528 | } |
---|
529 | |
---|
530 | uint32 GetAreaFlagByMapId(uint32 mapid) |
---|
531 | { |
---|
532 | AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid); |
---|
533 | if(i == sAreaFlagByMapID.end()) |
---|
534 | return 0; |
---|
535 | else |
---|
536 | return i->second; |
---|
537 | } |
---|
538 | |
---|
539 | uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) |
---|
540 | { |
---|
541 | if(mapid != 530) // speed for most cases |
---|
542 | return mapid; |
---|
543 | |
---|
544 | if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) |
---|
545 | return wma->virtual_map_id >= 0 ? wma->virtual_map_id : wma->map_id; |
---|
546 | |
---|
547 | return mapid; |
---|
548 | } |
---|
549 | |
---|
550 | ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) |
---|
551 | { |
---|
552 | mapid = GetVirtualMapForMapAndZone(mapid,zoneId); |
---|
553 | if(mapid < 2) |
---|
554 | return CONTENT_1_60; |
---|
555 | |
---|
556 | MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); |
---|
557 | if(!mapEntry) |
---|
558 | return CONTENT_1_60; |
---|
559 | |
---|
560 | switch(mapEntry->Expansion()) |
---|
561 | { |
---|
562 | default: return CONTENT_1_60; |
---|
563 | case 1: return CONTENT_61_70; |
---|
564 | case 2: return CONTENT_71_80; |
---|
565 | } |
---|
566 | } |
---|
567 | |
---|
568 | ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id) |
---|
569 | { |
---|
570 | // not sorted, numbering index from 0 |
---|
571 | for(uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) |
---|
572 | { |
---|
573 | ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(i); |
---|
574 | if(ch && ch->ChannelID == channel_id) |
---|
575 | return ch; |
---|
576 | } |
---|
577 | return NULL; |
---|
578 | } |
---|
579 | |
---|
580 | bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) |
---|
581 | { |
---|
582 | if(requiredTotemCategoryId==0) |
---|
583 | return true; |
---|
584 | if(itemTotemCategoryId==0) |
---|
585 | return false; |
---|
586 | |
---|
587 | TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId); |
---|
588 | if(!itemEntry) |
---|
589 | return false; |
---|
590 | TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId); |
---|
591 | if(!reqEntry) |
---|
592 | return false; |
---|
593 | |
---|
594 | if(itemEntry->categoryType!=reqEntry->categoryType) |
---|
595 | return false; |
---|
596 | |
---|
597 | return (itemEntry->categoryMask & reqEntry->categoryMask)==reqEntry->categoryMask; |
---|
598 | } |
---|
599 | |
---|
600 | void Zone2MapCoordinates(float& x,float& y,uint32 zone) |
---|
601 | { |
---|
602 | WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone); |
---|
603 | |
---|
604 | // if not listed then map coordinates (instance) |
---|
605 | if(!maEntry) |
---|
606 | return; |
---|
607 | |
---|
608 | std::swap(x,y); // at client map coords swapped |
---|
609 | x = x*((maEntry->x2-maEntry->x1)/100)+maEntry->x1; |
---|
610 | y = y*((maEntry->y2-maEntry->y1)/100)+maEntry->y1; // client y coord from top to down |
---|
611 | } |
---|
612 | |
---|
613 | void Map2ZoneCoordinates(float& x,float& y,uint32 zone) |
---|
614 | { |
---|
615 | WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone); |
---|
616 | |
---|
617 | // if not listed then map coordinates (instance) |
---|
618 | if(!maEntry) |
---|
619 | return; |
---|
620 | |
---|
621 | x = (x-maEntry->x1)/((maEntry->x2-maEntry->x1)/100); |
---|
622 | y = (y-maEntry->y1)/((maEntry->y2-maEntry->y1)/100); // client y coord from top to down |
---|
623 | std::swap(x,y); // client have map coords swapped |
---|
624 | } |
---|
625 | |
---|
626 | uint32 GetTalentInspectBitPosInTab(uint32 talentId) |
---|
627 | { |
---|
628 | TalentInspectMap::const_iterator itr = sTalentPosInInspect.find(talentId); |
---|
629 | if(itr == sTalentPosInInspect.end()) |
---|
630 | return 0; |
---|
631 | |
---|
632 | return itr->second; |
---|
633 | } |
---|
634 | |
---|
635 | uint32 GetTalentTabInspectBitSize(uint32 talentTabId) |
---|
636 | { |
---|
637 | TalentInspectMap::const_iterator itr = sTalentTabSizeInInspect.find(talentTabId); |
---|
638 | if(itr == sTalentTabSizeInInspect.end()) |
---|
639 | return 0; |
---|
640 | |
---|
641 | return itr->second; |
---|
642 | } |
---|
643 | |
---|
644 | uint32 const* GetTalentTabPages(uint32 cls) |
---|
645 | { |
---|
646 | return sTalentTabPages[cls]; |
---|
647 | } |
---|
648 | |
---|
649 | // script support functions |
---|
650 | TRINITY_DLL_SPEC DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; } |
---|
651 | TRINITY_DLL_SPEC DBCStorage <SpellEntry> const* GetSpellStore() { return &sSpellStore; } |
---|
652 | TRINITY_DLL_SPEC DBCStorage <SpellRangeEntry> const* GetSpellRangeStore() { return &sSpellRangeStore; } |
---|