void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; const uint32 DBCFilesCount = 60; barGoLink bar(DBCFilesCount); StoreProblemList bad_dbc_files; uint32 availableDbcLocales = 0xFFFFFFFF; LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaStore, dbcPath,"AreaTable.dbc"); // must be after sAreaStore loading for (uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0 { if (AreaTableEntry const* area = sAreaStore.LookupEntry(i)) { // fill AreaId->DBC records sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag)); // fill MapId->DBC records ( skip sub zones and continents) if (area->zone == 0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag)); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAuctionHouseStore, dbcPath,"AuctionHouse.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCinematicSequencesStore, dbcPath,"CinematicSequences.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesStore, dbcPath,"Emotes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc"); for (uint32 i=0;i<sFactionStore.GetNumRows(); ++i) { FactionEntry const * faction = sFactionStore.LookupEntry(i); if (faction && faction->team) { SimpleFactionsList &flist = sFactionTeamMap[faction->team]; flist.push_back(i); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc"); for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { SpellEntry const * spell = sSpellStore.LookupEntry(i); if (spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view #if OREGON_ENDIAN == OREGON_BIGENDIAN std::swap(*((uint32*)(&spell->SpellFamilyFlags)),*(((uint32*)(&spell->SpellFamilyFlags))+1)); #endif } for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); if (!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); if (spellInfo && (spellInfo->Attributes & 0x1D0) == 0x1D0) { for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if (!cFamily) continue; if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; for (int j = 0; j < 5; j++) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j); } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // fill table by amount of talent ranks and fill sTalentTabBitSizeInInspect // store in with (row,col,talent)->size key for correct sorting by (row,col) typedef std::map<uint32,uint32> TalentBitSize; TalentBitSize sTalentBitSize; for (uint32 i = 1; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab); if (!talentTabInfo) continue; // find talent rank uint32 curtalent_maxrank = 0; for (uint32 k = 5; k > 0; --k) { if (talentInfo->RankID[k-1]) { curtalent_maxrank = k; break; } } sTalentBitSize[(talentInfo->Row<<24) + (talentInfo->Col<<16)+talentInfo->TalentID] = curtalent_maxrank; sTalentTabSizeInInspect[talentInfo->TalentTab] += curtalent_maxrank; } // now have all max ranks (and then bit amount used for store talent ranks in inspect) for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) { TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentTabId); if (!talentTabInfo) continue; // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; // store class talent tab pages uint32 cls = 1; for (uint32 m=1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {} sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; // add total amount bits for first rank starting from talent tab first talent rank pos. uint32 pos = 0; for (TalentBitSize::iterator itr = sTalentBitSize.begin(); itr != sTalentBitSize.end(); ++itr) { uint32 talentId = itr->first & 0xFFFF; TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentId); if (!talentInfo) continue; if (talentInfo->TalentTab != talentTabId) continue; sTalentPosInInspect[talentId] = pos; pos+= itr->second; } } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc"); // Initialize global taxinodes mask memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask)); for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { if (sTaxiNodesStore.LookupEntry(i)) { uint8 field = (uint8)((i - 1) / 32); uint32 submask = 1<<((i-1)%32); sTaxiNodesMask[field] |= submask; } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc"); for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc"); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) ++pathLength[entry->path]; // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay); sTaxiPathNodeStore.Clear(); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWMOAreaTableStore, dbcPath,"WMOAreaTable.dbc"); for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) { if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) { sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); // error checks if (bad_dbc_files.size() >= DBCFilesCount) { sLog.outError("\nIncorrect DataDir value in Oregond.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str()); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",bad_dbc_files.size(),DBCFilesCount,str.c_str()); exit(1); } // check at up-to-date DBC files (53085 is last added spell in 2.4.3) // check at up-to-date DBC files (17514 is last ID in SkillLineAbilities in 2.4.3) // check at up-to-date DBC files (598 is last map added in 2.4.3) // check at up-to-date DBC files (1127 is last gem property added in 2.4.3) // check at up-to-date DBC files (2425 is last item extended cost added in 2.4.3) // check at up-to-date DBC files (71 is last char title added in 2.4.3) // check at up-to-date DBC files (1768 is last area added in 2.4.3) if ( !sSpellStore.LookupEntry(53085) || !sSkillLineAbilityStore.LookupEntry(17514) || !sMapStore.LookupEntry(598) || !sGemPropertiesStore.LookupEntry(1127) || !sItemExtendedCostStore.LookupEntry(2425) || !sCharTitlesStore.LookupEntry(71) || !sAreaStore.LookupEntry(1768)) { sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from 2.4.3 client."); exit(1); } sLog.outString(); sLog.outString(">> Initialized %d data stores", DBCFilesCount); }
void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath + "dbc/"; const uint32 DBCFilesCount = 50; BarGoLink bar(DBCFilesCount); StoreProblemList bad_dbc_files; // bitmask for index of fullLocaleNameList uint32 availableDbcLocales = 0xFFFFFFFF; LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaStore, dbcPath, "AreaTable.dbc"); // must be after sAreaStore loading for (uint32 i = 1; i <= sAreaStore.GetNumRows(); ++i) // areaid numbered from 1 { if (AreaTableEntry const* area = sAreaStore.LookupEntry(i)) { // fill AreaId->DBC records sAreaIDByAreaFlag.insert(AreaIDByAreaFlag::value_type(uint16(area->exploreFlag), area->ID)); // fill MapId->DBC records ( skip sub zones and continents ) if (area->zone == 0 && area->mapid != 0 && area->mapid != 1) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid, area->exploreFlag)); } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc"); for (uint32 i = 0; i < sFactionStore.GetNumRows(); ++i) { FactionEntry const* faction = sFactionStore.LookupEntry(i); if (faction && faction->team) { SimpleFactionsList& flist = sFactionTeamMap[faction->team]; flist.push_back(i); } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemClassStore, dbcPath, "ItemClass.dbc"); // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSkillRaceClassInfoStore, dbcPath, "SkillRaceClassInfo.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc"); for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { SpellEntry const* spell = sSpellStore.LookupEntry(i); if (spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view #if MANGOS_ENDIAN == MANGOS_BIGENDIAN std::swap(*((uint32*)(&spell->SpellFamilyFlags)), *(((uint32*)(&spell->SpellFamilyFlags)) + 1)); #endif } for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); if (!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); if (spellInfo && (spellInfo->Attributes & (SPELL_ATTR_UNK4 | SPELL_ATTR_PASSIVE | SPELL_ATTR_UNK7 | SPELL_ATTR_UNK8)) == (SPELL_ATTR_UNK4 | SPELL_ATTR_PASSIVE | SPELL_ATTR_UNK7 | SPELL_ATTR_UNK8)) { for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if (!cFamily) continue; if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sSpellShapeshiftFormStore, dbcPath, "SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; for (int j = 0; j < 5; ++j) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // fill table by amount of talent ranks and fill sTalentTabBitSizeInInspect // store in with (row,col,talent)->size key for correct sorting by (row,col) typedef std::map<uint32, uint32> TalentBitSize; TalentBitSize sTalentBitSize; for (uint32 i = 1; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); if (!talentTabInfo) continue; // find talent rank uint32 curtalent_maxrank = 0; for (uint32 k = 5; k > 0; --k) { if (talentInfo->RankID[k - 1]) { curtalent_maxrank = k; break; } } sTalentBitSize[(talentInfo->Row << 24) + (talentInfo->Col << 16) + talentInfo->TalentID] = curtalent_maxrank; sTalentTabSizeInInspect[talentInfo->TalentTab] += curtalent_maxrank; } // now have all max ranks (and then bit amount used for store talent ranks in inspect) for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) { TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabId); if (!talentTabInfo) continue; // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; // store class talent tab pages uint32 cls = 1; for (uint32 m = 1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {} sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabId; // add total amount bits for first rank starting from talent tab first talent rank pos. uint32 pos = 0; for (TalentBitSize::iterator itr = sTalentBitSize.begin(); itr != sTalentBitSize.end(); ++itr) { uint32 talentId = itr->first & 0xFFFF; TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId); if (!talentInfo) continue; if (talentInfo->TalentTab != talentTabId) continue; sTalentPosInInspect[talentId] = pos; pos += itr->second; } } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc"); for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures LoadDBC(availableDbcLocales, bar, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc"); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) { if (pathLength[entry->path] < entry->index + 1) pathLength[entry->path] = entry->index + 1; } // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data (pointers to sTaxiPathNodeStore elements for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path].set(entry->index, entry); // Initialize global taxinodes mask // include existing nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) if (SpellEntry const* sInfo = sSpellStore.LookupEntry(i)) for (int j = 0; j < MAX_EFFECT_INDEX; ++j) if (sInfo->Effect[j] == 123 /*SPELL_EFFECT_SEND_TAXI*/) spellPaths.insert(sInfo->EffectMiscValue[j]); memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask)); for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); if (!node) continue; TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i); if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty()) { bool ok = false; for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i) { // not spell path if (spellPaths.find(dest_i->second.ID) == spellPaths.end()) { ok = true; break; } } if (!ok) continue; } // valid taxi network node uint8 field = (uint8)((i - 1) / 32); uint32 submask = 1 << ((i - 1) % 32); sTaxiNodesMask[field] |= submask; } } LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc"); for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) { if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) { sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); } } // LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc"); LoadDBC(availableDbcLocales, bar, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); // error checks if (bad_dbc_files.size() >= DBCFilesCount) { sLog.outError("\nIncorrect DataDir value in mangosd.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFilesCount, dataPath.c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; 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()); Log::WaitBeforeContinueIfNeed(); exit(1); } // Check loaded DBC files proper version if (!sSpellStore.LookupEntry(33392) || !sSkillLineAbilityStore.LookupEntry(15030) || !sMapStore.LookupEntry(533) || !sAreaStore.LookupEntry(3486)) { sLog.outError("\nYou have _outdated_ DBC files. Please re-extract DBC files for one from client build: %s", AcceptableClientBuildsListStr().c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } sLog.outString(">> Initialized %d data stores", DBCFilesCount); sLog.outString(); }
void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; const uint32 DBCFilesCount = 70; barGoLink bar( DBCFilesCount ); StoreProblemList bad_dbc_files; uint32 availableDbcLocales = 0xFFFFFFFF; LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaStore, dbcPath,"AreaTable.dbc"); // must be after sAreaStore loading for(uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0 { if(AreaTableEntry const* area = sAreaStore.LookupEntry(i)) { // fill AreaId->DBC records sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag)); // fill MapId->DBC records ( skip sub zones and continents ) if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571 ) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag)); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionStore, dbcPath,"Faction.dbc"); for (uint32 i=0;i<sFactionStore.GetNumRows(); ++i) { FactionEntry const * faction = sFactionStore.LookupEntry(i); if (faction && faction->team) { SimpleFactionsList &flist = sFactionTeamMap[faction->team]; flist.push_back(i); } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellStore, dbcPath,"Spell.dbc"); for(uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { SpellEntry const * spell = sSpellStore.LookupEntry(i); if(spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); // DBC not support uint64 fields but SpellEntry have SpellFamilyFlags mapped at 2 uint32 fields // uint32 field already converted to bigendian if need, but must be swapped for correct uint64 bigendian view #if MANGOS_ENDIAN == MANGOS_BIGENDIAN std::swap(*((uint32*)(&spell->SpellFamilyFlags)),*(((uint32*)(&spell->SpellFamilyFlags))+1)); #endif } for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); if(!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); if(spellInfo && (spellInfo->Attributes & 0x1D0) == 0x1D0) { for (unsigned int i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if(!cFamily) continue; if(skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; for (int j = 0; j < 5; j++) if(talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j); } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // fill table by amount of talent ranks and fill sTalentTabBitSizeInInspect // store in with (row,col,talent)->size key for correct sorting by (row,col) typedef std::map<uint32,uint32> TalentBitSize; TalentBitSize sTalentBitSize; for(uint32 i = 1; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); if(!talentTabInfo) continue; // find talent rank uint32 curtalent_maxrank = 0; for(uint32 k = 5; k > 0; --k) { if(talentInfo->RankID[k-1]) { curtalent_maxrank = k; break; } } sTalentBitSize[(talentInfo->Row<<24) + (talentInfo->Col<<16)+talentInfo->TalentID] = curtalent_maxrank; sTalentTabSizeInInspect[talentInfo->TalentTab] += curtalent_maxrank; } // now have all max ranks (and then bit amount used for store talent ranks in inspect) for(uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) { TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentTabId ); if(!talentTabInfo) continue; // store class talent tab pages uint32 cls = 1; for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < 12 /*MAX_CLASSES*/;m <<=1, ++cls) {} sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; // add total amount bits for first rank starting from talent tab first talent rank pos. uint32 pos = 0; for(TalentBitSize::iterator itr = sTalentBitSize.begin(); itr != sTalentBitSize.end(); ++itr) { uint32 talentId = itr->first & 0xFFFF; TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentId ); if(!talentInfo) continue; if(talentInfo->TalentTab != talentTabId) continue; sTalentPosInInspect[talentId] = pos; pos+= itr->second; } } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc"); for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc"); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) { if (pathLength[entry->path] < entry->index + 1) pathLength[entry->path] = entry->index + 1; } // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for(uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay); sTaxiPathNodeStore.Clear(); // Initialize global taxinodes mask // include existed nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; for(uint32 i = 1; i < sSpellStore.GetNumRows (); ++i) if(SpellEntry const* sInfo = sSpellStore.LookupEntry (i)) for(int j=0; j < 3; ++j) if(sInfo->Effect[j]==123 /*SPELL_EFFECT_SEND_TAXI*/) spellPaths.insert(sInfo->EffectMiscValue[j]); memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask)); for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { if(!sTaxiNodesStore.LookupEntry(i)) continue; TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i); if(src_i!=sTaxiPathSetBySource.end() && !src_i->second.empty()) { bool ok = false; for(TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin();dest_i != src_i->second.end(); ++dest_i) { // not spell path if(spellPaths.find(dest_i->second.ID)==spellPaths.end()) { ok = true; break; } } if(!ok) continue; } // valid taxi netowrk node uint8 field = (uint8)((i - 1) / 32); uint32 submask = 1<<((i-1)%32); sTaxiNodesMask[field] |= submask; } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc"); // error checks if(bad_dbc_files.size() >= DBCFilesCount ) { sLog.outError("\nIncorrect DataDir value in mangosd.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str()); exit(1); } else if(!bad_dbc_files.empty() ) { std::string str; for(std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",bad_dbc_files.size(),DBCFilesCount,str.c_str()); exit(1); } // Check loaded DBC files proper version if( !sSpellStore.LookupEntry(54909) || // last added spell in 3.0.8a !sSpellStore.LookupEntry(49184) || // last added spell in 3.0.8a sSpellStore.LookupEntry(49184)->RecoveryTime!=5000||// last changed spell in 3.0.8a !sMapStore.LookupEntry(624) || // last map added in 3.0.8a !sGemPropertiesStore.LookupEntry(1557) || // last gem property added in 3.0.8a !sItemExtendedCostStore.LookupEntry(2589) || // last item extended cost added in 3.0.8a !sCharTitlesStore.LookupEntry(144) || // last char title added in 3.0.8a !sAreaStore.LookupEntry(2769) ) // last area (areaflag) added in 3.0.8a { sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } sLog.outString(); sLog.outString( ">> Initialized %d data stores", DBCFilesCount ); }