bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags) { Relocate(x, y, z, ang); // instance id and phaseMask isn't set to values different from std. if (!IsPositionValid()) { sLog->outError("Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, x, y); return false; } Object::_Create(guidlow, 0, HIGHGUID_MO_TRANSPORT); GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry); if (!goinfo) { sLog->outErrorDb("Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f", guidlow, mapid, x, y, z, ang); return false; } m_goInfo = goinfo; SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); //SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); SetUInt32Value(GAMEOBJECT_FLAGS, MAKE_PAIR32(0x28, 0x64)); SetUInt32Value(GAMEOBJECT_LEVEL, m_period); SetEntry(goinfo->entry); SetDisplayId(goinfo->displayId); SetGoState(GO_STATE_READY); SetGoType(GameobjectTypes(goinfo->type)); SetGoAnimProgress(animprogress); if (dynflags) SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags)); SetName(goinfo->name); SetZoneScript(); return true; }
void BattleGround::OnObjectDBLoad(Creature* creature) { const BattleGroundEventIdx eventId = sBattleGroundMgr.GetCreatureEventIndex(creature->GetGUIDLow()); if (eventId.event1 == BG_EVENT_NONE) return; m_EventObjects[MAKE_PAIR32(eventId.event1, eventId.event2)].creatures.push_back(creature->GetObjectGuid()); if (!IsActiveEvent(eventId.event1, eventId.event2)) SpawnBGCreature(creature->GetObjectGuid(), RESPAWN_ONE_DAY); }
bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags) { Relocate(x,y,z,ang); SetMapId(mapid); if(!IsPositionValid()) { sLog.outError("ERROR: Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow,x,y); return false; } Object::_Create(guidlow, 0, HIGHGUID_MO_TRANSPORT); GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(guidlow); if (!goinfo) { sLog.outErrorDb("Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f",guidlow, mapid, x, y, z, ang); return false; } m_goInfo = goinfo; SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); //SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); SetUInt32Value(GAMEOBJECT_FLAGS, MAKE_PAIR32(0x28, 0x64)); SetUInt32Value(GAMEOBJECT_LEVEL, m_period); SetEntry(goinfo->id); SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); SetGoState(1); SetGoType(GameobjectTypes(goinfo->type)); SetGoAnimProgress(animprogress); if(dynflags) SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags)); return true; }
bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags) { Relocate(x, y, z, ang); if (!IsPositionValid()) { sLog->outError("Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, x, y); return false; } Object::_Create(guidlow, 0, HIGHGUID_MO_TRANSPORT); GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry); if (!goinfo) { sLog->outErrorDb("Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f", guidlow, mapid, x, y, z, ang); return false; } m_goInfo = goinfo; TransportTemplate const* tInfo = sTransportMgr->GetTransportTemplate(entry); if (!tInfo) { sLog->outError("Transport %u (name: %s) will not be created, missing `transport_template` entry.", entry, goinfo->name.c_str()); return false; } _transportInfo = tInfo; // initialize waypoints _nextFrame = tInfo->keyFrames.begin(); _currentFrame = _nextFrame++; SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); SetUInt32Value(GAMEOBJECT_LEVEL, tInfo->pathTime); SetEntry(goinfo->entry); SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); SetGoState(GO_STATE_READY); SetGoType(GameobjectTypes(goinfo->type)); SetGoAnimProgress(animprogress); if (dynflags) SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags)); SetName(goinfo->name); return true; }
void BattleGround::SpawnEvent(uint8 event1, uint8 event2, bool spawn) { // stop if we want to spawn something which was already spawned // or despawn something which was already despawned if (event2 == BG_EVENT_NONE || (spawn && m_ActiveEvents[event1] == event2) || (!spawn && m_ActiveEvents[event1] != event2)) return; if (spawn) { // if event gets spawned, the current active event mus get despawned SpawnEvent(event1, m_ActiveEvents[event1], false); m_ActiveEvents[event1] = event2; // set this event to active } else m_ActiveEvents[event1] = BG_EVENT_NONE; // no event active if event2 gets despawned GuidVector::const_iterator itr = m_EventObjects[MAKE_PAIR32(event1, event2)].creatures.begin(); for (; itr != m_EventObjects[MAKE_PAIR32(event1, event2)].creatures.end(); ++itr) SpawnBGCreature(*itr, (spawn) ? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); GuidVector::const_iterator itr2 = m_EventObjects[MAKE_PAIR32(event1, event2)].gameobjects.begin(); for (; itr2 != m_EventObjects[MAKE_PAIR32(event1, event2)].gameobjects.end(); ++itr2) SpawnBGObject(*itr2, (spawn) ? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); }
void BattleGround::OnObjectDBLoad(GameObject* obj) { const BattleGroundEventIdx eventId = sBattleGroundMgr.GetGameObjectEventIndex(obj->GetGUIDLow()); if (eventId.event1 == BG_EVENT_NONE) return; m_EventObjects[MAKE_PAIR32(eventId.event1, eventId.event2)].gameobjects.push_back(obj->GetObjectGuid()); if (!IsActiveEvent(eventId.event1, eventId.event2)) { SpawnBGObject(obj->GetObjectGuid(), RESPAWN_ONE_DAY); } else { // it's possible, that doors aren't spawned anymore (wsg) if (GetStatus() >= STATUS_IN_PROGRESS && IsDoor(eventId.event1, eventId.event2)) DoorOpen(obj->GetObjectGuid()); } }
/* Transport::~Transport() { ASSERT(_passengers.empty()); UnloadStaticPassengers(); } */ bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags) { Relocate(x, y, z, ang); if (!IsPositionValid()) { IC_LOG_ERROR("entities.transport", "Transport (GUID: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, x, y); return false; } Object::_Create(guidlow, 0, HIGHGUID_MO_TRANSPORT); GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry); if (!goinfo) { IC_LOG_ERROR("sql.sql", "Transport not created: entry in `gameobject_template` not found, guidlow: %u map: %u (X: %f Y: %f Z: %f) ang: %f", guidlow, mapid, x, y, z, ang); return false; } m_goInfo = goinfo; SetObjectScale(goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); SetUInt32Value(GAMEOBJECT_LEVEL, m_period); SetEntry(goinfo->entry); SetDisplayId(goinfo->displayId); SetGoState(GO_STATE_READY); SetGoType(GameobjectTypes(goinfo->type)); SetGoAnimProgress(animprogress); if (dynflags) SetUInt32Value(GAMEOBJECT_DYN_FLAGS, MAKE_PAIR32(0, dynflags)); SetName(goinfo->name); SetZoneScript(); return true; }
void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath + "/"; uint32 build = ReadDBCBuild(dbcPath); // Check the expected DBC version if (!IsAcceptableClientBuild(build)) { if (build) std::cerr << "Found DBC files for build " << build << " but expected DBC for one from builds: " << AcceptableClientBuildsListStr() << " Please extract correct DBC files.\n"; else std::cerr << "Incorrect DBC directory or not found build info (outdated DBC files). Required one from builds: " << AcceptableClientBuildsListStr() << " Please extract correct DBC files.\n"; exit(1); } const uint32 DBCFilesCount = 89; StoreProblemList bad_dbc_files; LocalData availableDbcLocales(build); LoadDBC(availableDbcLocales,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,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sAuctionHouseStore, dbcPath,"AuctionHouse.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sChrRacesStore, dbcPath,"ChrRaces.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sCinematicSequencesStore, dbcPath,"CinematicSequences.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sCurrencyTypesStore, dbcPath,"CurrencyTypes.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sEmotesStore, dbcPath,"Emotes.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc"); LoadDBC(availableDbcLocales,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,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGameObjectDisplayInfoStore,dbcPath,"GameObjectDisplayInfo.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtOCTClassCombatRatingScalarStore,dbcPath,"gtOCTClassCombatRatingScalar.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc"); //LoadDBC(availableDbcLocales,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently LoadDBC(availableDbcLocales,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGtRegenMPPerSptStore, dbcPath,"gtRegenMPPerSpt.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sHolidaysStore, dbcPath,"Holidays.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sItemStore, dbcPath,"Item.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sItemBagFamilyStore, dbcPath,"ItemBagFamily.dbc"); //LoadDBC(availableDbcLocales,bad_dbc_files,sItemDisplayInfoStore, dbcPath,"ItemDisplayInfo.dbc"); -- not used currently //LoadDBC(availableDbcLocales,bad_dbc_files,sItemCondExtCostsStore, dbcPath,"ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sItemLimitCategoryStore, dbcPath,"ItemLimitCategory.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sItemRandomPropertiesStore,dbcPath,"ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sItemRandomSuffixStore, dbcPath,"ItemRandomSuffix.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sItemSetStore, dbcPath,"ItemSet.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sMapDifficultyStore, dbcPath,"MapDifficulty.dbc"); // fill data for(uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) if(MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) sMapDifficultyMap[MAKE_PAIR32(entry->MapId,entry->Difficulty)] = MapDifficulty(entry->resetTime,entry->maxPlayers); sMapDifficultyStore.Clear(); LoadDBC(availableDbcLocales,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sQuestXPLevelStore, dbcPath,"QuestXP.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sPvPDifficultyStore, dbcPath,"PvpDifficulty.dbc"); for(uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); LoadDBC(availableDbcLocales,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); LoadDBC(availableDbcLocales,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,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellDifficultyStore, dbcPath,"SpellDifficulty.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellItemEnchantmentStore,dbcPath,"SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); LoadDBC(availableDbcLocales,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 < MAX_TALENT_RANK; j++) if(talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j); } LoadDBC(availableDbcLocales,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // 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; } } LoadDBC(availableDbcLocales,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); // error checks if (bad_dbc_files.size() >= DBCFilesCount ) { std::cerr << "\nIncorrect DBC directory or ALL required *.dbc files (" << DBCFilesCount << ") not found by path: " << dataPath << std::endl; 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"; std::cerr << "\nSome required *.dbc files (" << bad_dbc_files.size() << " from " << DBCFilesCount << ") not found or not compatible:\n" << str << std::endl; exit(1); } // Check loaded DBC files proper version if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.5a !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a !sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.3.5a !sItemStore.LookupEntry(56806) || // last client known item added in 3.3.5a !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a !sMapStore.LookupEntry(724) || // last map added in 3.3.5a !sSpellStore.LookupEntry(80864) ) // last added spell in 3.3.5a { std::cerr << "\nYou have mixed version DBC files. Please re-extract DBC files for one from client build: " << AcceptableClientBuildsListStr() << std::endl; exit(1); } std::cerr << "\n>> Initialized " << DBCFilesCount << " data stores\n"; }
void LoadDBCStores(const std::string& dataPath) { uint32 oldMSTime = getMSTime(); std::string dbcPath = dataPath+"dbc/"; StoreProblemList bad_dbc_files; uint32 availableDbcLocales = 0xFFFFFFFF; LoadDBC(availableDbcLocales, 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, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc", &CustomAchievementfmt, &CustomAchievementIndex); LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAreaPOIStore, dbcPath, "AreaPOI.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath,"CreatureDisplayInfoExtra.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); LoadDBC(availableDbcLocales, 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, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc"); for (uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i) { if (GameObjectDisplayInfoEntry const* info = sGameObjectDisplayInfoStore.LookupEntry(i)) { if (info->maxX < info->minX) std::swap(*(float*)(&info->maxX), *(float*)(&info->minX)); if (info->maxY < info->minY) std::swap(*(float*)(&info->maxY), *(float*)(&info->minY)); if (info->maxZ < info->minZ) std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ)); } } LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc"); //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sGtOCTRegenMPStore, dbcPath, "gtOCTRegenMP.dbc"); -- not used currently LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemStore, dbcPath, "Item.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc"); //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemDisplayInfoStore, dbcPath, "ItemDisplayInfo.dbc"); -- not used currently //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemCondExtCostsStore, dbcPath, "ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemExtendedCostStore, dbcPath, "ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc"); // fill data for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] != '\0'); sMapDifficultyStore.Clear(); LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc"); for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); LoadDBC(availableDbcLocales, bad_dbc_files, sQuestXPStore, dbcPath, "QuestXP.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex); for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { SpellEntry const* spell = sSpellStore.LookupEntry(i); if (spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); } 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_ATTR0_PASSIVE) { for (uint32 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; if (spellInfo->spellLevel) continue; if (skillLine->learnOnGetSkill != ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL) continue; sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftStore, dbcPath, "SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); // Create Spelldifficulty searcher for (uint32 i = 0; i < sSpellDifficultyStore.GetNumRows(); ++i) { SpellDifficultyEntry const* spellDiff = sSpellDifficultyStore.LookupEntry(i); if (!spellDiff) continue; SpellDifficultyEntry newEntry; memset(newEntry.SpellID, 0, 4*sizeof(uint32)); for (int x = 0; x < MAX_DIFFICULTY; ++x) { if (spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x])) { if (spellDiff->SpellID[x] > 0)//don't show error if spell is <= 0, not all modes have spells and there are unknown negative values sLog->outErrorDb("spelldifficulty_dbc: spell %i at field id:%u at spellid%i does not exist in SpellStore (spell.dbc), loaded as 0", spellDiff->SpellID[x], spellDiff->ID, x); newEntry.SpellID[x] = 0;//spell was <= 0 or invalid, set to 0 } else newEntry.SpellID[x] = spellDiff->SpellID[x]; } if (newEntry.SpellID[0] <= 0 || newEntry.SpellID[1] <= 0)//id0-1 must be always set! continue; for (int x = 0; x < MAX_DIFFICULTY; ++x) sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID); } // 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 < MAX_TALENT_RANK; j++) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); } LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // 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; } } LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); LoadDBC(availableDbcLocales, 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, 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].set(entry->index, entry); // 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 < MAX_SPELL_EFFECTS; ++j) if (sInfo->Effect[j] == SPELL_EFFECT_SEND_TAXI) spellPaths.insert(sInfo->EffectMiscValue[j]); memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask)); memset(sOldContinentsNodesMask, 0, sizeof(sOldContinentsNodesMask)); memset(sHordeTaxiNodesMask, 0, sizeof(sHordeTaxiNodesMask)); memset(sAllianceTaxiNodesMask, 0, sizeof(sAllianceTaxiNodesMask)); memset(sDeathKnightTaxiNodesMask, 0, sizeof(sDeathKnightTaxiNodesMask)); 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; if (node->MountCreatureID[0] && node->MountCreatureID[0] != 32981) sHordeTaxiNodesMask[field] |= submask; if (node->MountCreatureID[1] && node->MountCreatureID[1] != 32981) sAllianceTaxiNodesMask[field] |= submask; if (node->MountCreatureID[0] == 32981 || node->MountCreatureID[1] == 32981) sDeathKnightTaxiNodesMask[field] |= submask; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94) sOldContinentsNodesMask[field] |= submask; // fix DK node at Ebon Hold if (i == 315) { ((TaxiNodesEntry*)node)->MountCreatureID[1] = 32981; } } } LoadDBC(availableDbcLocales, bad_dbc_files, sTeamContributionPointsStore, dbcPath, "TeamContributionPoints.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc"); LoadDBC(availableDbcLocales, 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, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); // error checks if (bad_dbc_files.size() >= DBCFileCount) { sLog->outError("Incorrect DataDir value in worldserver.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFileCount, dataPath.c_str()); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (StoreProblemList::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; sLog->outError("Some required *.dbc files (%u from %d) not found or not compatible:\n%s", (uint32)bad_dbc_files.size(), DBCFileCount, str.c_str()); exit(1); } // Check loaded DBC files proper version if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.5a !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a !sGemPropertiesStore.LookupEntry(1629) || // last added spell in 3.3.5a !sItemStore.LookupEntry(56806) || // last gem property added in 3.3.5a !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a !sMapStore.LookupEntry(724) || // last map added in 3.3.5a !sSpellStore.LookupEntry(80864) ) // last client known item added in 3.3.5a { sLog->outError("You have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } sLog->outString(">> Initialized %d data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); }
void LoadDBCStores(const std::string& dataPath) { uint32 oldMSTime = getMSTime(); std::string dbcPath = dataPath + "dbc/"; StoreProblemList bad_dbc_files; uint32 availableDbcLocales = 0xFFFFFFFF; #define LOAD_DBC(store, file) LoadDBC(availableDbcLocales, bad_dbc_files, store, dbcPath, file) LOAD_DBC(sAreaTableStore, "AreaTable.dbc"); LOAD_DBC(sAchievementCriteriaStore, "Achievement_Criteria.dbc"); LOAD_DBC(sAreaTriggerStore, "AreaTrigger.dbc"); LOAD_DBC(sAreaGroupStore, "AreaGroup.dbc"); LOAD_DBC(sAreaPOIStore, "AreaPOI.dbc"); LOAD_DBC(sAuctionHouseStore, "AuctionHouse.dbc"); LOAD_DBC(sBankBagSlotPricesStore, "BankBagSlotPrices.dbc"); LOAD_DBC(sBannedAddOnsStore, "BannedAddOns.dbc"); LOAD_DBC(sBattlemasterListStore, "BattlemasterList.dbc"); LOAD_DBC(sBarberShopStyleStore, "BarberShopStyle.dbc"); LOAD_DBC(sCharacterFacialHairStylesStore, "CharacterFacialHairStyles.dbc"); LOAD_DBC(sCharSectionsStore, "CharSections.dbc"); LOAD_DBC(sCharStartOutfitStore, "CharStartOutfit.dbc"); LOAD_DBC(sCharTitlesStore, "CharTitles.dbc"); LOAD_DBC(sChatChannelsStore, "ChatChannels.dbc"); LOAD_DBC(sChrClassesStore, "ChrClasses.dbc"); LOAD_DBC(sChrRacesStore, "ChrRaces.dbc"); LOAD_DBC(sCinematicCameraStore, "CinematicCamera.dbc"); LOAD_DBC(sCinematicSequencesStore, "CinematicSequences.dbc"); LOAD_DBC(sCreatureDisplayInfoStore, "CreatureDisplayInfo.dbc"); LOAD_DBC(sCreatureDisplayInfoExtraStore, "CreatureDisplayInfoExtra.dbc"); LOAD_DBC(sCreatureFamilyStore, "CreatureFamily.dbc"); LOAD_DBC(sCreatureModelDataStore, "CreatureModelData.dbc"); LOAD_DBC(sCreatureSpellDataStore, "CreatureSpellData.dbc"); LOAD_DBC(sCreatureTypeStore, "CreatureType.dbc"); LOAD_DBC(sCurrencyTypesStore, "CurrencyTypes.dbc"); LOAD_DBC(sDestructibleModelDataStore, "DestructibleModelData.dbc"); LOAD_DBC(sDungeonEncounterStore, "DungeonEncounter.dbc"); LOAD_DBC(sDurabilityCostsStore, "DurabilityCosts.dbc"); LOAD_DBC(sDurabilityQualityStore, "DurabilityQuality.dbc"); LOAD_DBC(sEmotesStore, "Emotes.dbc"); LOAD_DBC(sEmotesTextStore, "EmotesText.dbc"); LOAD_DBC(sEmotesTextSoundStore, "EmotesTextSound.dbc"); LOAD_DBC(sFactionStore, "Faction.dbc"); LOAD_DBC(sFactionTemplateStore, "FactionTemplate.dbc"); LOAD_DBC(sGameObjectDisplayInfoStore, "GameObjectDisplayInfo.dbc"); LOAD_DBC(sGemPropertiesStore, "GemProperties.dbc"); LOAD_DBC(sGlyphPropertiesStore, "GlyphProperties.dbc"); LOAD_DBC(sGlyphSlotStore, "GlyphSlot.dbc"); LOAD_DBC(sGtBarberShopCostBaseStore, "gtBarberShopCostBase.dbc"); LOAD_DBC(sGtCombatRatingsStore, "gtCombatRatings.dbc"); LOAD_DBC(sGtChanceToMeleeCritBaseStore, "gtChanceToMeleeCritBase.dbc"); LOAD_DBC(sGtChanceToMeleeCritStore, "gtChanceToMeleeCrit.dbc"); LOAD_DBC(sGtChanceToSpellCritBaseStore, "gtChanceToSpellCritBase.dbc"); LOAD_DBC(sGtChanceToSpellCritStore, "gtChanceToSpellCrit.dbc"); LOAD_DBC(sGtNPCManaCostScalerStore, "gtNPCManaCostScaler.dbc"); LOAD_DBC(sGtOCTClassCombatRatingScalarStore, "gtOCTClassCombatRatingScalar.dbc"); LOAD_DBC(sGtOCTRegenHPStore, "gtOCTRegenHP.dbc"); //LOAD_DBC(sGtOCTRegenMPStore, "gtOCTRegenMP.dbc"); -- not used currently LOAD_DBC(sGtRegenHPPerSptStore, "gtRegenHPPerSpt.dbc"); LOAD_DBC(sGtRegenMPPerSptStore, "gtRegenMPPerSpt.dbc"); LOAD_DBC(sHolidaysStore, "Holidays.dbc"); LOAD_DBC(sItemStore, "Item.dbc"); LOAD_DBC(sItemBagFamilyStore, "ItemBagFamily.dbc"); //LOAD_DBC(sItemDisplayInfoStore, "ItemDisplayInfo.dbc"); -- not used currently //LOAD_DBC(sItemCondExtCostsStore, "ItemCondExtCosts.dbc"); LOAD_DBC(sItemExtendedCostStore, "ItemExtendedCost.dbc"); LOAD_DBC(sItemLimitCategoryStore, "ItemLimitCategory.dbc"); LOAD_DBC(sItemRandomPropertiesStore, "ItemRandomProperties.dbc"); LOAD_DBC(sItemRandomSuffixStore, "ItemRandomSuffix.dbc"); LOAD_DBC(sItemSetStore, "ItemSet.dbc"); LOAD_DBC(sLFGDungeonStore, "LFGDungeons.dbc"); LOAD_DBC(sLightStore, "Light.dbc"); LOAD_DBC(sLiquidTypeStore, "LiquidType.dbc"); LOAD_DBC(sLockStore, "Lock.dbc"); LOAD_DBC(sMailTemplateStore, "MailTemplate.dbc"); LOAD_DBC(sMapStore, "Map.dbc"); LOAD_DBC(sMapDifficultyStore, "MapDifficulty.dbc"); LOAD_DBC(sMovieStore, "Movie.dbc"); LOAD_DBC(sNamesProfanityStore, "NamesProfanity.dbc"); LOAD_DBC(sNamesReservedStore, "NamesReserved.dbc"); LOAD_DBC(sOverrideSpellDataStore, "OverrideSpellData.dbc"); LOAD_DBC(sPowerDisplayStore, "PowerDisplay.dbc"); LOAD_DBC(sPvPDifficultyStore, "PvpDifficulty.dbc"); LOAD_DBC(sQuestXPStore, "QuestXP.dbc"); LOAD_DBC(sQuestFactionRewardStore, "QuestFactionReward.dbc"); LOAD_DBC(sQuestSortStore, "QuestSort.dbc"); LOAD_DBC(sRandomPropertiesPointsStore, "RandPropPoints.dbc"); LOAD_DBC(sScalingStatDistributionStore, "ScalingStatDistribution.dbc"); LOAD_DBC(sScalingStatValuesStore, "ScalingStatValues.dbc"); LOAD_DBC(sSkillLineStore, "SkillLine.dbc"); LOAD_DBC(sSkillLineAbilityStore, "SkillLineAbility.dbc"); LOAD_DBC(sSkillRaceClassInfoStore, "SkillRaceClassInfo.dbc"); LOAD_DBC(sSkillTiersStore, "SkillTiers.dbc"); LOAD_DBC(sSoundEntriesStore, "SoundEntries.dbc"); LOAD_DBC(sSpellCastTimesStore, "SpellCastTimes.dbc"); LOAD_DBC(sSpellCategoryStore, "SpellCategory.dbc"); LOAD_DBC(sSpellDurationStore, "SpellDuration.dbc"); LOAD_DBC(sSpellFocusObjectStore, "SpellFocusObject.dbc"); LOAD_DBC(sSpellItemEnchantmentStore, "SpellItemEnchantment.dbc"); LOAD_DBC(sSpellItemEnchantmentConditionStore, "SpellItemEnchantmentCondition.dbc"); LOAD_DBC(sSpellRadiusStore, "SpellRadius.dbc"); LOAD_DBC(sSpellRangeStore, "SpellRange.dbc"); LOAD_DBC(sSpellRuneCostStore, "SpellRuneCost.dbc"); LOAD_DBC(sSpellShapeshiftStore, "SpellShapeshiftForm.dbc"); LOAD_DBC(sStableSlotPricesStore, "StableSlotPrices.dbc"); LOAD_DBC(sSummonPropertiesStore, "SummonProperties.dbc"); LOAD_DBC(sTalentStore, "Talent.dbc"); LOAD_DBC(sTalentTabStore, "TalentTab.dbc"); LOAD_DBC(sTaxiNodesStore, "TaxiNodes.dbc"); LOAD_DBC(sTaxiPathStore, "TaxiPath.dbc"); LOAD_DBC(sTaxiPathNodeStore, "TaxiPathNode.dbc"); LOAD_DBC(sTeamContributionPointsStore, "TeamContributionPoints.dbc"); LOAD_DBC(sTotemCategoryStore, "TotemCategory.dbc"); LOAD_DBC(sTransportAnimationStore, "TransportAnimation.dbc"); LOAD_DBC(sTransportRotationStore, "TransportRotation.dbc"); LOAD_DBC(sVehicleStore, "Vehicle.dbc"); LOAD_DBC(sVehicleSeatStore, "VehicleSeat.dbc"); LOAD_DBC(sWMOAreaTableStore, "WMOAreaTable.dbc"); LOAD_DBC(sWorldMapAreaStore, "WorldMapArea.dbc"); LOAD_DBC(sWorldMapOverlayStore, "WorldMapOverlay.dbc"); LOAD_DBC(sWorldSafeLocsStore, "WorldSafeLocs.dbc"); #undef LOAD_DBC #define LOAD_DBC_EXT(store, file, dbtable, dbformat, dbpk) LoadDBC(availableDbcLocales, bad_dbc_files, store, dbcPath, file, dbtable, dbformat, dbpk) LOAD_DBC_EXT(sAchievementStore, "Achievement.dbc", "achievement_dbc", CustomAchievementfmt, CustomAchievementIndex); LOAD_DBC_EXT(sSpellStore, "Spell.dbc", "spell_dbc", CustomSpellEntryfmt, CustomSpellEntryIndex); LOAD_DBC_EXT(sSpellDifficultyStore, "SpellDifficulty.dbc", "spelldifficulty_dbc", CustomSpellDifficultyfmt, CustomSpellDifficultyIndex); #undef LOAD_DBC_EXT for (CharacterFacialHairStylesEntry const* entry : sCharacterFacialHairStylesStore) if (entry->Race && ((1 << (entry->Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0) // ignore nonplayable races sCharFacialHairMap.insert({ entry->Race | (entry->Gender << 8) | (entry->Variation << 16), entry }); for (CharSectionsEntry const* entry : sCharSectionsStore) if (entry->Race && ((1 << (entry->Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0) // ignore nonplayable races sCharSectionMap.insert({ entry->GenType | (entry->Gender << 8) | (entry->Race << 16), entry }); for (CharStartOutfitEntry const* outfit : sCharStartOutfitStore) sCharStartOutfitMap[outfit->Race | (outfit->Class << 8) | (outfit->Gender << 16)] = outfit; for (EmotesTextSoundEntry const* entry : sEmotesTextSoundStore) sEmotesTextSoundMap[EmotesTextSoundKey(entry->EmotesTextId, entry->RaceId, entry->SexId)] = entry; for (FactionEntry const* faction : sFactionStore) { if (faction->team) { SimpleFactionsList& flist = sFactionTeamMap[faction->team]; flist.push_back(faction->ID); } } for (GameObjectDisplayInfoEntry const* info : sGameObjectDisplayInfoStore) { if (info->maxX < info->minX) std::swap(*(float*)(&info->maxX), *(float*)(&info->minX)); if (info->maxY < info->minY) std::swap(*(float*)(&info->maxY), *(float*)(&info->minY)); if (info->maxZ < info->minZ) std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ)); } // fill data for (MapDifficultyEntry const* entry : sMapDifficultyStore) sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] != '\0'); for (NamesProfanityEntry const* namesProfanity : sNamesProfanityStore) { ASSERT(namesProfanity->Language < TOTAL_LOCALES || namesProfanity->Language == -1); std::wstring wname; bool conversionResult = Utf8toWStr(namesProfanity->Name, wname); ASSERT(conversionResult); if (namesProfanity->Language != -1) NamesProfaneValidators[namesProfanity->Language].emplace_back(wname, Trinity::regex::perl | Trinity::regex::icase | Trinity::regex::optimize); else for (uint32 i = 0; i < TOTAL_LOCALES; ++i) NamesProfaneValidators[i].emplace_back(wname, Trinity::regex::perl | Trinity::regex::icase | Trinity::regex::optimize); } for (NamesReservedEntry const* namesReserved : sNamesReservedStore) { ASSERT(namesReserved->Language < TOTAL_LOCALES || namesReserved->Language == -1); std::wstring wname; bool conversionResult = Utf8toWStr(namesReserved->Name, wname); ASSERT(conversionResult); if (namesReserved->Language != -1) NamesReservedValidators[namesReserved->Language].emplace_back(wname, Trinity::regex::perl | Trinity::regex::icase | Trinity::regex::optimize); else for (uint32 i = 0; i < TOTAL_LOCALES; ++i) NamesReservedValidators[i].emplace_back(wname, Trinity::regex::perl | Trinity::regex::icase | Trinity::regex::optimize); } for (PvPDifficultyEntry const* entry : sPvPDifficultyStore) { ASSERT(entry->bracketId < MAX_BATTLEGROUND_BRACKETS, "PvpDifficulty bracket (%d) exceeded max allowed value (%d)", entry->bracketId, MAX_BATTLEGROUND_BRACKETS); } for (SkillRaceClassInfoEntry const* entry : sSkillRaceClassInfoStore) if (sSkillLineStore.LookupEntry(entry->SkillId)) SkillRaceClassInfoBySkill.emplace(entry->SkillId, entry); for (SkillLineAbilityEntry const* skillLine : sSkillLineAbilityStore) { SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); if (spellInfo && spellInfo->Attributes & SPELL_ATTR0_PASSIVE) { for (CreatureFamilyEntry const* cFamily : sCreatureFamilyStore) { if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; if (spellInfo->spellLevel) continue; if (skillLine->AutolearnType != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN) continue; sPetFamilySpellsStore[cFamily->ID].insert(spellInfo->Id); } } } // Create Spelldifficulty searcher for (SpellDifficultyEntry const* spellDiff : sSpellDifficultyStore) { SpellDifficultyEntry newEntry; memset(newEntry.SpellID, 0, 4*sizeof(uint32)); for (uint8 x = 0; x < MAX_DIFFICULTY; ++x) { if (spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x])) { if (spellDiff->SpellID[x] > 0)//don't show error if spell is <= 0, not all modes have spells and there are unknown negative values TC_LOG_ERROR("sql.sql", "spelldifficulty_dbc: spell %i at field id:%u at spellid%i does not exist in SpellStore (spell.dbc), loaded as 0", spellDiff->SpellID[x], spellDiff->ID, x); newEntry.SpellID[x] = 0;//spell was <= 0 or invalid, set to 0 } else newEntry.SpellID[x] = spellDiff->SpellID[x]; } if (newEntry.SpellID[0] <= 0 || newEntry.SpellID[1] <= 0)//id0-1 must be always set! continue; for (uint8 x = 0; x < MAX_DIFFICULTY; ++x) if (newEntry.SpellID[x]) sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID); } // create talent spells set for (TalentEntry const* talentInfo : sTalentStore) { for (uint8 j = 0; j < MAX_TALENT_RANK; ++j) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(talentInfo->TalentID, j); } // prepare fast data access to bit pos of talent ranks for use at inspecting { // now have all max ranks (and then bit amount used for store talent ranks in inspect) for (TalentTabEntry const* talentTabInfo : sTalentTabStore) { // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; // store class talent tab pages for (uint32 cls = 1; cls < MAX_CLASSES; ++cls) if (talentTabInfo->ClassMask & (1 << (cls - 1))) sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabInfo->TalentTabID; } } for (TaxiPathEntry const* entry : sTaxiPathStore) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore) { if (pathLength[entry->PathID] < entry->NodeIndex + 1) pathLength[entry->PathID] = entry->NodeIndex + 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 (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore) sTaxiPathNodesByPath[entry->PathID][entry->NodeIndex] = entry; // Initialize global taxinodes mask // include existed nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; for (SpellEntry const* sInfo : sSpellStore) for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) if (sInfo->Effect[j] == SPELL_EFFECT_SEND_TAXI) spellPaths.insert(sInfo->EffectMiscValue[j]); sTaxiNodesMask.fill(0); sOldContinentsNodesMask.fill(0); sHordeTaxiNodesMask.fill(0); sAllianceTaxiNodesMask.fill(0); sDeathKnightTaxiNodesMask.fill(0); for (TaxiNodesEntry const* node : sTaxiNodesStore) { TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(node->ID); 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 (dest_i->second.price || spellPaths.find(dest_i->second.ID) == spellPaths.end()) { ok = true; break; } } if (!ok) continue; } // valid taxi network node uint8 field = (uint8)((node->ID - 1) / 32); uint32 submask = 1 << ((node->ID - 1) % 32); sTaxiNodesMask[field] |= submask; if (node->MountCreatureID[0] && node->MountCreatureID[0] != 32981) sHordeTaxiNodesMask[field] |= submask; if (node->MountCreatureID[1] && node->MountCreatureID[1] != 32981) sAllianceTaxiNodesMask[field] |= submask; if (node->MountCreatureID[0] == 32981 || node->MountCreatureID[1] == 32981) sDeathKnightTaxiNodesMask[field] |= submask; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) if (node->map_id < 2 || node->ID == 82 || node->ID == 83 || node->ID == 93 || node->ID == 94) sOldContinentsNodesMask[field] |= submask; // fix DK node at Ebon Hold and Shadow Vault flight master if (node->ID == 315 || node->ID == 333) const_cast<TaxiNodesEntry*>(node)->MountCreatureID[1] = 32981; } } for (WMOAreaTableEntry const* entry : sWMOAreaTableStore) sWMOAreaInfoByTripple[WMOAreaTableKey(entry->rootId, entry->adtId, entry->groupId)] = entry; // error checks if (bad_dbc_files.size() >= DBCFileCount) { TC_LOG_ERROR("misc", "Incorrect DataDir value in worldserver.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFileCount, dataPath.c_str()); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (StoreProblemList::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; TC_LOG_ERROR("misc", "Some required *.dbc files (%u from %d) not found or not compatible:\n%s", (uint32)bad_dbc_files.size(), DBCFileCount, str.c_str()); exit(1); } // Check loaded DBC files proper version if (!sAreaTableStore.LookupEntry(4987) || // last area added in 3.3.5a !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a !sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.3.5a !sItemStore.LookupEntry(56806) || // last client known item added in 3.3.5a !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a !sMapStore.LookupEntry(724) || // last map added in 3.3.5a !sSpellStore.LookupEntry(80864) ) // last added spell in 3.3.5a { TC_LOG_ERROR("misc", "You have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } TC_LOG_INFO("server.loading", ">> Initialized %d data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime)); }
void InstanceResetScheduler::LoadResetTimes() { time_t now = time(NULL); time_t today = (now / DAY) * DAY; time_t oldest_reset_time = now; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::pair<uint32 /*PAIR32(map,difficulty)*/, time_t> ResetTimeMapDiffType; typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; InstResetTimeMapDiffType instResetTime; QueryResult *result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance WHERE resettime > 0"); if( result ) { do { if(time_t resettime = time_t((*result)[3].GetUInt64())) { uint32 id = (*result)[0].GetUInt32(); uint32 mapid = (*result)[1].GetUInt32(); uint32 difficulty = (*result)[2].GetUInt32(); instResetTime[id] = ResetTimeMapDiffType(MAKE_PAIR32(mapid,difficulty), resettime); } } while (result->NextRow()); delete result; // update reset time for normal instances with the max creature respawn time + X hours result = CharacterDatabase.Query("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance"); if( result ) { do { Field *fields = result->Fetch(); uint32 instance = fields[1].GetUInt32(); time_t resettime = time_t(fields[0].GetUInt64() + 2 * HOUR); InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if(itr != instResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } while (result->NextRow()); delete result; } // schedule the reset times for(InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if(itr->second.second > now) ScheduleReset(true, itr->second.second, InstanceResetEvent(RESET_EVENT_DUNGEON, PAIR32_LOPART(itr->second.first),Difficulty(PAIR32_HIPART(itr->second.first)),itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld.getConfig(CONFIG_UINT32_INSTANCE_RESET_TIME_HOUR) * HOUR; result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if(result) { do { Field *fields = result->Fetch(); uint32 mapid = fields[0].GetUInt32(); Difficulty difficulty = Difficulty(fields[1].GetUInt32()); uint64 oldresettime = fields[2].GetUInt64(); MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty); if(!mapDiff) { sLog.outError("InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid,difficulty); continue; } // update the reset time if the hour in the configs changes uint32 offset = sMapStore.LookupEntry(mapid)->instanceResetOffset; uint64 start_point = INSTANCE_RESET_SCHEDULE_START_TIME + offset + diff; uint64 newresettime = start_point + uint32((oldresettime - start_point) / DAY) * DAY; if(oldresettime != newresettime) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty = '%u'", newresettime, mapid, difficulty); SetResetTimeFor(mapid,difficulty,newresettime); } while(result->NextRow()); delete result; } // clean expired instances, references to them will be deleted in CleanupInstances // must be done before calculating new reset times m_InstanceSaves._CleanupExpiredInstancesAtTime(now); // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue for(MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { uint32 map_diff_pair = itr->first; uint32 mapid = PAIR32_LOPART(map_diff_pair); Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); MapDifficulty const* mapDiff = &itr->second; // skip mapDiff without global reset time if (!mapDiff->resetTime) continue; uint32 period = GetMaxResetTimeFor(mapDiff); time_t t = GetResetTimeFor(mapid,difficulty); if(!t || t < now) { bool existsInDB = bool(t); uint32 offset = sMapStore.LookupEntry(mapid)->instanceResetOffset; uint64 start_point = INSTANCE_RESET_SCHEDULE_START_TIME + offset + diff; t = start_point + uint32(ceil(float(now - start_point) / period) * period); if(existsInDB) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); else CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','%u','"UI64FMTD"')", mapid, difficulty, (uint64)t); } SetResetTimeFor(mapid,difficulty,t); // schedule the global reset/warning ResetEventType type = RESET_EVENT_INFORM_1; for(; type < RESET_EVENT_INFORM_LAST; type = ResetEventType(type+1)) if(t - resetEventTypeDelay[type] > now) break; ScheduleReset(true, t - resetEventTypeDelay[type], InstanceResetEvent(type, mapid, difficulty, 0)); } }
/** * @name AddMenuItem * @brief Adds a localized gossip menu item from db by menu id and menu item id. * @param menuId Gossip menu id. * @param menuItemId Gossip menu item id. * @param sender Identifier of the current menu. * @param action Custom action given to OnGossipHello. */ void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action) { /// Find items for given menu id. GossipMenuItemsMapBounds bounds = sObjectMgr->GetGossipMenuItemsMapBounds(menuId); /// Return if there are none. if (bounds.first == bounds.second) return; /// Iterate over each of them. for (GossipMenuItemsContainer::const_iterator itr = bounds.first; itr != bounds.second; ++itr) { /// Find the one with the given menu item id. if (itr->second.OptionIndex != menuItemId) continue; /// Store texts for localization. std::string strOptionText = itr->second.OptionText; std::string strBoxText = itr->second.BoxText; /// Check need of localization. if (GetLocale() > LOCALE_enUS) /// Find localizations from database. if (GossipMenuItemsLocale const* no = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, menuItemId))) { /// Translate texts if there are any. ObjectMgr::GetLocaleString(no->OptionText, GetLocale(), strOptionText); ObjectMgr::GetLocaleString(no->BoxText, GetLocale(), strBoxText); } /// Add menu item with existing method. Menu item id -1 is also used in ADD_GOSSIP_ITEM macro. AddMenuItem(-1, itr->second.OptionIcon, strOptionText, sender, action, strBoxText, itr->second.BoxMoney, itr->second.BoxCoded); } }
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty) { MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId,difficulty)); return itr != sMapDifficultyMap.end() ? &itr->second : NULL; }
void InstanceSaveManager::LoadResetTimes() { time_t now = GameTime::GetGameTime(); time_t today = (now / DAY) * DAY; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::pair<uint32 /*PAIR32(map, difficulty)*/, time_t> ResetTimeMapDiffType; typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; InstResetTimeMapDiffType instResetTime; // index instance ids by map/difficulty pairs for fast reset warning send typedef std::multimap<uint32 /*PAIR32(map, difficulty)*/, uint32 /*instanceid*/ > ResetTimeMapDiffInstances; typedef std::pair<ResetTimeMapDiffInstances::const_iterator, ResetTimeMapDiffInstances::const_iterator> ResetTimeMapDiffInstancesBounds; ResetTimeMapDiffInstances mapDiffResetInstances; if (QueryResult result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC")) { do { Field* fields = result->Fetch(); uint32 instanceId = fields[0].GetUInt32(); // Mark instance id as being used sMapMgr->RegisterInstanceId(instanceId); if (time_t resettime = time_t(fields[3].GetUInt64())) { uint32 mapid = fields[1].GetUInt16(); uint32 difficulty = fields[2].GetUInt8(); instResetTime[instanceId] = ResetTimeMapDiffType(MAKE_PAIR32(mapid, difficulty), resettime); mapDiffResetInstances.insert(ResetTimeMapDiffInstances::value_type(MAKE_PAIR32(mapid, difficulty), instanceId)); } } while (result->NextRow()); // schedule the reset times for (InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if (itr->second.second > now) ScheduleReset(true, itr->second.second, InstResetEvent(0, PAIR32_LOPART(itr->second.first), Difficulty(PAIR32_HIPART(itr->second.first)), itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; if (QueryResult result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset")) { do { Field* fields = result->Fetch(); uint32 mapid = fields[0].GetUInt16(); Difficulty difficulty = Difficulty(fields[1].GetUInt8()); uint64 oldresettime = fields[2].GetUInt64(); MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty); if (!mapDiff) { TC_LOG_ERROR("misc", "InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GLOBAL_INSTANCE_RESETTIME); stmt->setUInt16(0, uint16(mapid)); stmt->setUInt8(1, uint8(difficulty)); CharacterDatabase.DirectExecute(stmt); continue; } // update the reset time if the hour in the configs changes uint64 newresettime = (oldresettime / DAY) * DAY + diff; if (oldresettime != newresettime) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME); stmt->setUInt64(0, uint64(newresettime)); stmt->setUInt16(1, uint16(mapid)); stmt->setUInt8(2, uint8(difficulty)); CharacterDatabase.DirectExecute(stmt); } InitializeResetTimeFor(mapid, difficulty, newresettime); } while (result->NextRow()); } // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue for (MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { uint32 map_diff_pair = itr->first; uint32 mapid = PAIR32_LOPART(map_diff_pair); Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); MapDifficulty const* mapDiff = &itr->second; if (!mapDiff->resetTime) continue; // the reset_delay must be at least one day uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME))/DAY) * DAY); if (period < DAY) period = DAY; time_t t = GetResetTimeFor(mapid, difficulty); if (!t) { // initialize the reset time t = today + period + diff; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GLOBAL_INSTANCE_RESETTIME); stmt->setUInt16(0, uint16(mapid)); stmt->setUInt8(1, uint8(difficulty)); stmt->setUInt64(2, uint64(t)); CharacterDatabase.DirectExecute(stmt); } if (t < now) { // assume that expired instances have already been cleaned // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME); stmt->setUInt64(0, uint64(t)); stmt->setUInt16(1, uint16(mapid)); stmt->setUInt8(2, uint8(difficulty)); CharacterDatabase.DirectExecute(stmt); } InitializeResetTimeFor(mapid, difficulty, t); // schedule the global reset/warning uint8 type; for (type = 1; type < 4; ++type) if (t - ResetTimeDelay[type-1] > now) break; ScheduleReset(true, t - ResetTimeDelay[type-1], InstResetEvent(type, mapid, difficulty, 0)); ResetTimeMapDiffInstancesBounds range = mapDiffResetInstances.equal_range(map_diff_pair); for (; range.first != range.second; ++range.first) ScheduleReset(true, t - ResetTimeDelay[type-1], InstResetEvent(type, mapid, difficulty, range.first->second)); } }
void InstanceSaveManager::LoadResetTimes() { time_t now = time(NULL); time_t today = (now / DAY) * DAY; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::pair<uint32 /*PAIR32(map, difficulty)*/, time_t> ResetTimeMapDiffType; typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; InstResetTimeMapDiffType instResetTime; // index instance ids by map/difficulty pairs for fast reset warning send typedef std::multimap<uint32 /*PAIR32(map, difficulty)*/, uint32 /*instanceid*/ > ResetTimeMapDiffInstances; ResetTimeMapDiffInstances mapDiffResetInstances; QueryResult result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC"); if (result) { do { Field* fields = result->Fetch(); uint32 instanceId = fields[0].GetUInt32(); // Instances are pulled in ascending order from db and nextInstanceId is initialized with 1, // so if the instance id is used, increment until we find the first unused one for a potential new instance if (sMapMgr->GetNextInstanceId() == instanceId) sMapMgr->SetNextInstanceId(instanceId + 1); // Mark instance id as being used sMapMgr->RegisterInstanceId(instanceId); if (time_t resettime = time_t(fields[3].GetUInt32())) { uint32 mapid = fields[1].GetUInt16(); uint32 difficulty = fields[2].GetUInt8(); instResetTime[instanceId] = ResetTimeMapDiffType(MAKE_PAIR32(mapid, difficulty), resettime); mapDiffResetInstances.insert(ResetTimeMapDiffInstances::value_type(MAKE_PAIR32(mapid, difficulty), instanceId)); } } while (result->NextRow()); // update reset time for normal instances with the max creature respawn time + X hours if (PreparedQueryResult result2 = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAX_CREATURE_RESPAWNS))) { do { Field* fields = result2->Fetch(); uint32 instance = fields[1].GetUInt32(); time_t resettime = time_t(fields[0].GetUInt32() + 2 * HOUR); InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if (itr != instResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } while (result->NextRow()); } // schedule the reset times for (InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if (itr->second.second > now) ScheduleReset(true, itr->second.second, InstResetEvent(0, PAIR32_LOPART(itr->second.first), Difficulty(PAIR32_HIPART(itr->second.first)), itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if (result) { do { Field* fields = result->Fetch(); uint32 mapid = fields[0].GetUInt16(); Difficulty difficulty = Difficulty(fields[1].GetUInt8()); uint64 oldresettime = fields[2].GetUInt32(); MapDifficulty const* mapDiff = GetMapDifficultyData(mapid, difficulty); if (!mapDiff) { sLog->outError("InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid, difficulty); continue; } // update the reset time if the hour in the configs changes uint64 newresettime = (oldresettime / DAY) * DAY + diff; if (oldresettime != newresettime) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%u' AND difficulty = '%u'", uint32(newresettime), mapid, difficulty); SetResetTimeFor(mapid, difficulty, newresettime); } while (result->NextRow()); } ResetTimeMapDiffInstances::const_iterator in_itr; // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue for (MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { uint32 map_diff_pair = itr->first; uint32 mapid = PAIR32_LOPART(map_diff_pair); Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); MapDifficulty const* mapDiff = &itr->second; if (!mapDiff->resetTime) continue; // the reset_delay must be at least one day uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME))/DAY) * DAY); if (period < DAY) period = DAY; time_t t = GetResetTimeFor(mapid, difficulty); if (!t) { // initialize the reset time t = today + period + diff; CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u', '%u', '%u')", mapid, difficulty, (uint32)t); } if (t < now) { // assume that expired instances have already been cleaned // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); } SetResetTimeFor(mapid, difficulty, t); // schedule the global reset/warning uint8 type; for (type = 1; type < 4; ++type) if (t - ResetTimeDelay[type-1] > now) break; ScheduleReset(true, t - ResetTimeDelay[type-1], InstResetEvent(type, mapid, difficulty, 0)); for (in_itr = mapDiffResetInstances.lower_bound(map_diff_pair); in_itr != mapDiffResetInstances.upper_bound(map_diff_pair); ++in_itr) ScheduleReset(true, t - ResetTimeDelay[type-1], InstResetEvent(type, mapid, difficulty, in_itr->second)); } }
void InstanceSaveManager::SetResetTimeFor(uint32 mapid, Difficulty d, time_t t) { ResetTimeByMapDifficultyMap::iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d)); ASSERT(itr != m_resetTimeByMapDifficulty.end()); itr->second = t; }
void LoadDBCStores(const std::string& dataPath, uint32& availableDbcLocales) { uint32 oldMSTime = getMSTime(); std::string dbcPath = dataPath+"dbc/"; StoreProblemList bad_dbc_files; for (uint8 i = 0 ; i < TOTAL_LOCALES; ++i) availableDbcLocales |= (1 << i); LoadDBC(availableDbcLocales, 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, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc", &CustomAchievementfmt, &CustomAchievementIndex); LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAreaPOIStore, dbcPath, "AreaPOI.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sArmorLocationStore, dbcPath,"ArmorLocation.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); LoadDBC(availableDbcLocales, 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, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc"); for (uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i) { if (GameObjectDisplayInfoEntry const * info = sGameObjectDisplayInfoStore.LookupEntry(i)) { if (info->maxX < info->minX) std::swap(*(float*)(&info->maxX), *(float*)(&info->minX)); if (info->maxY < info->minY) std::swap(*(float*)(&info->maxY), *(float*)(&info->minY)); if (info->maxZ < info->minZ) std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ)); } } LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc"); //LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc"); //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sGtOCTRegenMPStore, dbcPath, "gtOCTRegenMP.dbc"); -- not used currently //LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc"); LoadDBC(availableDbcLocales,bad_dbc_files,sGuildPerksStore, dbcPath,"GuildPerkSpells.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc"); //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemDisplayInfoStore, dbcPath, "ItemDisplayInfo.dbc"); -- not used currently //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemCondExtCostsStore, dbcPath, "ItemCondExtCosts.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemExtendedCostStore, dbcPath, "ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sItemReforgeStore, dbcPath, "ItemReforge.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc"); // fill data for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText > 0); // HACK for map 0, data removed in 4.0 - by LordJZ /// ToDo: Find a way to correctly fix this sMapDifficultyMap[MAKE_PAIR32(0/*map*/, 0/*difficulty*/)] = MapDifficulty(0/*resetTime*/ ,0/*mapPlayers*/, false /*HasErrorMessage*/); sMapDifficultyStore.Clear(); LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMountCapabilityStore, dbcPath, "MountCapability.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sMountTypeStore, dbcPath, "MountType.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc"); for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); LoadDBC(availableDbcLocales, bad_dbc_files, sQuestXPStore, dbcPath, "QuestXP.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellAuraOptionsStore, dbcPath, "SpellAuraOptions.dbc"/*, &CustomSpellAuraOptionsEntryfmt, &CustomSpellAuraOptionsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellAuraRestrictionsStore, dbcPath, "SpellAuraRestrictions.dbc", &CustomSpellAuraRestrictionsEntryfmt, &CustomSpellAuraRestrictionsEntryIndex); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastingRequirementsStore, dbcPath, "SpellCastingRequirements.dbc"/*, &CustomSpellCastingRequirementsEntryfmt, &CustomSpellCastingRequirementsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoriesStore, dbcPath, "SpellCategories.dbc"/*, &CustomSpellCategoriesEntryfmt, &CustomSpellCategoriesEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellClassOptionsStore, dbcPath, "SpellClassOptions.dbc", &CustomSpellClassOptionsEntryfmt, &CustomSpellClassOptionsEntryIndex); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCooldownsStore, dbcPath, "SpellCooldowns.dbc"/*, &CustomSpellCooldownsEntryfmt, &CustomSpellCooldownsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellEffectStore, dbcPath, "SpellEffect.dbc", &CustomSpellEffectEntryfmt, &CustomSpellEffectEntryIndex); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellEquippedItemsStore, dbcPath, "SpellEquippedItems.dbc"/*, &CustomSpellEquippedItemsEntryfmt, &CustomSpellEquippedItemsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellInterruptsStore, dbcPath, "SpellInterrupts.dbc"/*, &CustomSpellInterruptsEntryfmt, &CustomSpellInterruptsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellLevelsStore, dbcPath, "SpellLevels.dbc"/*, &CustomSpellLevelsEntryfmt, &CustomSpellLevelsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellPowerStore, dbcPath, "SpellPower.dbc"/*, &CustomSpellPowerEntryfmt, &CustomSpellPowerEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellReagentsStore, dbcPath, "SpellReagents.dbc"/*, &CustomSpellReagentsEntryfmt, &CustomSpellReagentsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellScalingStore, dbcPath, "SpellScaling.dbc"/*, &CustomSpellScalingEntryfmt, &CustomSpellScalingEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftStore, dbcPath, "SpellShapeshift.dbc"/*, &CustomSpellShapeshiftEntryfmt, &CustomSpellShapeshiftEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellTargetRestrictionsStore, dbcPath, "SpellTargetRestrictions.dbc"/*, &CustomSpellTargetRestrictionsEntryfmt, &CustomSpellTargetRestrictionsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellTotemsStore, dbcPath, "SpellTotems.dbc"/*, &CustomSpellTotemsEntryfmt, &CustomSpellTotemsEntryIndex*/); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftFormStore, dbcPath, "SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); // Create Spelldifficulty searcher for (uint32 i = 0; i < sSpellDifficultyStore.GetNumRows(); ++i) { SpellDifficultyEntry const *spellDiff = sSpellDifficultyStore.LookupEntry(i); if (!spellDiff) continue; SpellDifficultyEntry newEntry; memset(newEntry.SpellID, 0, 4*sizeof(uint32)); for (int x = 0; x < MAX_DIFFICULTY; ++x) { if (spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x])) { if (spellDiff->SpellID[x] > 0)//don't show error if spell is <= 0, not all modes have spells and there are unknown negative values sLog->outErrorDb("spelldifficulty_dbc: spell %i at field id:%u at spellid%i does not exist in SpellStore (spell.dbc), loaded as 0", spellDiff->SpellID[x], spellDiff->ID, x); newEntry.SpellID[x] = 0;//spell was <= 0 or invalid, set to 0 } else newEntry.SpellID[x] = spellDiff->SpellID[x]; } if (newEntry.SpellID[0] <= 0 || newEntry.SpellID[1] <= 0)//id0-1 must be always set! continue; for (int x = 0; x < MAX_DIFFICULTY; ++x) sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID); } // 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 < MAX_TALENT_RANK; j++) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); } LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTreePrimarySpellsStore, dbcPath, "TalentTreePrimarySpells.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // 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; } } LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); LoadDBC(availableDbcLocales, 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, 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].set(entry->index, entry); //LoadDBC(availableDbcLocales, bad_dbc_files, sTeamContributionPointsStore, dbcPath, "TeamContributionPoints.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc"); LoadDBC(availableDbcLocales, 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, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc"); LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); //LoadDBC(availableDbcLocales, bad_dbc_files, sWorldStateStore, dbcPath, "WorldStateUI.dbc"); // error checks if (bad_dbc_files.size() >= DBCFileCount) { sLog->outError("Incorrect DataDir value in worldserver.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFileCount, dataPath.c_str()); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (StoreProblemList::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; sLog->outError("Some required *.dbc files (%u from %d) not found or not compatible:\n%s", (uint32)bad_dbc_files.size(), DBCFileCount, str.c_str()); exit(1); } // Check loaded DBC files proper version if (!sAreaStore.LookupEntry(4445) || // last area (areaflag) added in 4.0.6a !sCharTitlesStore.LookupEntry(229) || // last char title added in 4.0.6a !sGemPropertiesStore.LookupEntry(1858) || // last gem property added in 4.0.6a !sItemExtendedCostStore.LookupEntry(3400) || // last item extended cost added in 4.0.6a !sMapStore.LookupEntry(767) || // last map added in 4.0.6a !sSpellStore.LookupEntry(96539) ) // last added spell in 4.0.6a { sLog->outError("You have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } sLog->outString(">> Initialized %d data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); }
/** * @name AddMenuItem * @brief Adds a localized gossip menu item from db by menu id and menu item id. * @param menuId Gossip menu id. * @param menuItemId Gossip menu item id. * @param sender Identifier of the current menu. * @param action Custom action given to OnGossipHello. */ void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action) { /// Find items for given menu id. GossipMenuItemsMapBounds bounds = sObjectMgr->GetGossipMenuItemsMapBounds(menuId); /// Return if there are none. if (bounds.first == bounds.second) return; /// Iterate over each of them. for (GossipMenuItemsContainer::const_iterator itr = bounds.first; itr != bounds.second; ++itr) { /// Find the one with the given menu item id. if (itr->second.OptionIndex != menuItemId) continue; /// Store texts for localization. std::string strOptionText, strBoxText; BroadcastTextEntry const* optionBroadcastText = sBroadcastTextStore.LookupEntry(itr->second.OptionBroadcastTextId); BroadcastTextEntry const* boxBroadcastText = sBroadcastTextStore.LookupEntry(itr->second.BoxBroadcastTextId); /// OptionText if (optionBroadcastText) strOptionText = DB2Manager::GetBroadcastTextValue(optionBroadcastText, GetLocale()); else strOptionText = itr->second.OptionText; /// BoxText if (boxBroadcastText) strBoxText = DB2Manager::GetBroadcastTextValue(boxBroadcastText, GetLocale()); else strBoxText = itr->second.BoxText; /// Check need of localization. if (GetLocale() != DEFAULT_LOCALE) { if (!optionBroadcastText) { /// Find localizations from database. if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, menuItemId))) ObjectMgr::GetLocaleString(gossipMenuLocale->OptionText, GetLocale(), strOptionText); } if (!boxBroadcastText) { /// Find localizations from database. if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, menuItemId))) ObjectMgr::GetLocaleString(gossipMenuLocale->BoxText, GetLocale(), strBoxText); } } /// Add menu item with existing method. Menu item id -1 is also used in ADD_GOSSIP_ITEM macro. AddMenuItem(-1, itr->second.OptionIcon, strOptionText, sender, action, strBoxText, itr->second.BoxMoney, itr->second.BoxCoded); } }
LFGDungeonExpansionEntry const* GetLFGExpansionEntry(uint32 dungeonId, uint32 expansion) { LFGDungeonExpansionMap::const_iterator itr = sLFGDungeonExpansionMap.find(MAKE_PAIR32(dungeonId,expansion)); return itr != sLFGDungeonExpansionMap.end() ? itr->second : NULL; }
void InstanceResetScheduler::LoadResetTimes() { time_t now = time(NULL); time_t today = (now / DAY) * DAY; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::pair<uint32 /*PAIR32(map,difficulty)*/, time_t> ResetTimeMapDiffType; typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; InstResetTimeMapDiffType instResetTime; // index instance ids by map/difficulty pairs for fast reset warning send typedef std::multimap<uint32 /*PAIR32(map,difficulty)*/, uint32 /*instanceid*/ > ResetTimeMapDiffInstances; ResetTimeMapDiffInstances mapDiffResetInstances; QueryResult *result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance WHERE resettime > 0"); if( result ) { do { if(time_t resettime = time_t((*result)[3].GetUInt64())) { uint32 id = (*result)[0].GetUInt32(); uint32 mapid = (*result)[1].GetUInt32(); uint32 difficulty = (*result)[2].GetUInt32(); instResetTime[id] = ResetTimeMapDiffType(MAKE_PAIR32(mapid,difficulty), resettime); mapDiffResetInstances.insert(ResetTimeMapDiffInstances::value_type(MAKE_PAIR32(mapid,difficulty),id)); } } while (result->NextRow()); delete result; // update reset time for normal instances with the max creature respawn time + X hours result = WorldDatabase.Query("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance"); if( result ) { do { Field *fields = result->Fetch(); uint32 instance = fields[1].GetUInt32(); time_t resettime = time_t(fields[0].GetUInt64() + 2 * HOUR); InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if(itr != instResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } while (result->NextRow()); delete result; } // schedule the reset times for(InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if(itr->second.second > now) ScheduleReset(true, itr->second.second, InstanceResetEvent(0, PAIR32_LOPART(itr->second.first),Difficulty(PAIR32_HIPART(itr->second.first)),itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld.getConfig(CONFIG_UINT32_INSTANCE_RESET_TIME_HOUR) * HOUR; result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if(result) { do { Field *fields = result->Fetch(); uint32 mapid = fields[0].GetUInt32(); Difficulty difficulty = Difficulty(fields[1].GetUInt32()); uint64 oldresettime = fields[2].GetUInt64(); MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty); if(!mapDiff) { sLog.outError("InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid,difficulty); continue; } // update the reset time if the hour in the configs changes uint64 newresettime = (oldresettime / DAY) * DAY + diff; if(oldresettime != newresettime) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty = '%u'", newresettime, mapid, difficulty); SetResetTimeFor(mapid,difficulty,newresettime); } while(result->NextRow()); delete result; } // clean expired instances, references to them will be deleted in CleanupInstances // must be done before calculating new reset times m_InstanceSaves._CleanupExpiredInstancesAtTime(now); // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue for(MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { uint32 map_diff_pair = itr->first; uint32 mapid = PAIR32_LOPART(map_diff_pair); Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); MapDifficulty const* mapDiff = &itr->second; if (!mapDiff->resetTime) continue; // the reset_delay must be at least one day uint32 period = uint32(mapDiff->resetTime / DAY * sWorld.getConfig(CONFIG_FLOAT_RATE_INSTANCE_RESET_TIME)) * DAY; if (period < DAY) period = DAY; time_t t = GetResetTimeFor(mapid,difficulty); if(!t) { // initialize the reset time t = today + period + diff; CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','%u','"UI64FMTD"')", mapid, difficulty, (uint64)t); } if(t < now) { // assume that expired instances have already been cleaned // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); } SetResetTimeFor(mapid,difficulty,t); // schedule the global reset/warning uint8 type = 1; static int tim[4] = {3600, 900, 300, 60}; for(; type < 4; type++) if(t - tim[type-1] > now) break; for(ResetTimeMapDiffInstances::const_iterator in_itr = mapDiffResetInstances.lower_bound(map_diff_pair); in_itr != mapDiffResetInstances.upper_bound(map_diff_pair); ++in_itr) { ScheduleReset(true, t - tim[type-1], InstanceResetEvent(type, mapid, difficulty, in_itr->second)); } } }
void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; LocaleNameStr const* defaultLocaleNameStr = NULL; uint32 build = ReadDBCBuild(dbcPath,defaultLocaleNameStr); // Check the expected DBC version if (!IsAcceptableClientBuild(build)) { if (build) sLog.outError("Found DBC files for build %u but StrawberryWorld expected DBC for one from builds: %s Please extract correct DBC files.", build, AcceptableClientBuildsListStr().c_str()); else sLog.outError("Incorrect DataDir value in StrawberryWorld.conf or not found build info (outdated DBC files). Required one from builds: %s Please extract correct DBC files.",AcceptableClientBuildsListStr().c_str()); Log::WaitBeforeContinueIfNeed(); exit(1); } const uint32 DBCFilesCount = 102; BarGoLink bar(DBCFilesCount); StoreProblemList bad_dbc_files; LocalData availableDbcLocales(build,defaultLocaleNameStr->locale); 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,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,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,sChrPowerTypesStore, dbcPath, "ChrClassesXPowerTypes.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,sDungeonEncounterStore, dbcPath,"DungeonEncounter.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,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,sGtOCTClassCombatRatingScalarStore,dbcPath,"gtOCTClassCombatRatingScalar.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,sHolidaysStore, dbcPath,"Holidays.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.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,sItemExtendedCostStore, dbcPath,"ItemExtendedCost.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemLimitCategoryStore, dbcPath,"ItemLimitCategory.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,sMapDifficultyStore, dbcPath,"MapDifficulty.dbc"); // fill data for(uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) if(MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) sMapDifficultyMap[MAKE_PAIR32(entry->MapId,entry->Difficulty)] = MapDifficulty(entry->resetTime,entry->maxPlayers); sMapDifficultyStore.Clear(); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sOverrideSpellDataStore, dbcPath,"OverrideSpellData.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestXPLevelStore, dbcPath,"QuestXP.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sPvPDifficultyStore, dbcPath,"PvpDifficulty.dbc"); for(uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) STRAWBERRY_ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); 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,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) { if(SpellEntry const * spell = sSpellStore.LookupEntry(i)) { if(SpellCategoriesEntry const* category = spell->GetSpellCategories()) if(uint32 cat = category->Category) sSpellCategoryStore[cat].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 STRAWBERRY_ENDIAN == STRAWBERRY_BIGENDIAN std::swap(*((uint32*)(&spell->SpellFamilyFlags)),*(((uint32*)(&spell->SpellFamilyFlags))+1)); #endif } } LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellAuraOptionsStore, dbcPath,"SpellAuraOptions.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellAuraRestrictionsStore, dbcPath,"SpellAuraRestrictions.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastingRequirementsStore, dbcPath,"SpellCastingRequirements.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCategoriesStore, dbcPath,"SpellCategories.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellClassOptionsStore, dbcPath,"SpellClassOptions.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCooldownsStore, dbcPath,"SpellCooldowns.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellEffectStore, dbcPath,"SpellEffect.dbc"); /*for(uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i) { if(SpellEffectEntry const *spellEffect = sSpellEffectStore.LookupEntry(i)) sSpellEffectMap[spellEffect->EffectSpellId].effects[spellEffect->EffectIndex] = spellEffect; }*/ LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellEquippedItemsStore, dbcPath,"SpellEquippedItems.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellInterruptsStore, dbcPath,"SpellInterrupts.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellLevelsStore, dbcPath,"SpellLevels.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellMiscStore, dbcPath,"SpellMisc.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellPowerStore, dbcPath,"SpellPower.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellReagentsStore, dbcPath,"SpellReagents.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellScalingStore, dbcPath,"SpellScaling.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshift.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellTargetRestrictionsStore, dbcPath,"SpellTargetRestrictions.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellTotemsStore, dbcPath,"SpellTotems.dbc"); for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); if(!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); SpellMiscEntry const* spellMisc = sSpellMiscStore.LookupEntry(skillLine->spellId); if (!spellMisc) continue; if(spellInfo && spellMisc->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,sSpellShapeshiftFormStore, 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 < MAX_TALENT_RANK; 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 { // 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; } } 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(SpellEffectEntry const* effect = sInfo->GetSpellEffect(SpellEffectIndex(j))) if(effect->Effect==123 /*SPELL_EFFECT_SEND_TAXI*/) spellPaths.insert(effect->EffectMiscValue); memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask)); memset(sOldContinentsNodesMask,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; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94) sOldContinentsNodesMask[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,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 StrawberryWorld.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 (!sAreaStore.LookupEntry(4975) || // last area (areaflag) added in 5.0.1 Beta !sCharTitlesStore.LookupEntry(287) || // last char title added in 5.0.1 Beta !sGemPropertiesStore.LookupEntry(2272) || // last gem property added in 5.0.1 Beta !sMapStore.LookupEntry(1051) || // last map added in 5.0.1 Beta !sSpellStore.LookupEntry(122523) ) // last added spell in 5.0.1 Beta { sLog.outError("\nYou have mixed version DBC files. Please re-extract DBC files for one from client build: %s",AcceptableClientBuildsListStr().c_str()); Log::WaitBeforeContinueIfNeed(); 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 = 80; 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,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,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,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,sCreatureTypeStore, dbcPath,"CreatureType.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCurrencyTypesStore, dbcPath,"CurrencyTypes.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,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,sHolidaysStore, dbcPath,"Holidays.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemStore, dbcPath,"Item.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sItemBagFamilyStore, dbcPath,"ItemBagFamily.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,sItemLimitCategoryStore, dbcPath,"ItemLimitCategory.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,sMapDifficultyStore, dbcPath,"MapDifficulty.dbc"); // fill data for(uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) if(MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) sMapDifficultyMap[MAKE_PAIR32(entry->MapId,entry->Difficulty)] = MapDifficulty(entry->resetTime,entry->maxPlayers); sMapDifficultyStore.Clear(); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.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 < MAX_TALENT_RANK; 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 { // 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; } } 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)); memset(sOldContinentsNodesMask,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; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94) sOldContinentsNodesMask[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,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()); 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()); exit(1); } // Check loaded DBC files proper version if( !sSpellStore.LookupEntry(66530) || // last added spell in 3.1.3 !sMapStore.LookupEntry(624) || // last map added in 3.1.3 !sGemPropertiesStore.LookupEntry(1609) || // last gem property added in 3.1.3 !sItemExtendedCostStore.LookupEntry(2671) || // last item extended cost added in 3.1.3 !sCharTitlesStore.LookupEntry(166) || // last char title added in 3.1.3 !sAreaStore.LookupEntry(2905) || // last area (areaflag) added in 3.1.3 !sItemStore.LookupEntry(46894) ) // last client known item added in 3.1.3 { 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 ); }
void InstanceSaveManager::LoadResetTimes() { time_t now = time(NULL); time_t today = (now / DAY) * DAY; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid instances so those are skipped typedef std::pair<uint32, time_t> ResetTimeMapDiffType; typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; InstResetTimeMapDiffType instResetTime; // index instance ids by map pairs for fast reset warning send typedef std::multimap<uint32, uint32 /*instanceid*/ > ResetTimeMapDiffInstances; ResetTimeMapDiffInstances mapDiffResetInstances; QueryResult result = CharacterDatabase.Query("SELECT id, map, resettime FROM instance ORDER BY id ASC"); if (result) { do { Field* fields = result->Fetch(); uint32 instanceId = fields[0].GetUInt32(); // Instances are pulled in ascending order from db and nextInstanceId is initialized with 1, // so if the instance id is used, increment until we find the first unused one for a potential new instance if (sMapMgr->GetNextInstanceId() == instanceId) sMapMgr->SetNextInstanceId(instanceId + 1); // Mark instance id as being used sMapMgr->RegisterInstanceId(instanceId); if (time_t resettime = time_t(fields[3].GetUInt32())) { uint32 mapid = fields[1].GetUInt16(); instResetTime[instanceId] = ResetTimeMapDiffType(MAKE_PAIR32(mapid), resettime); mapDiffResetInstances.insert(ResetTimeMapDiffInstances::value_type(MAKE_PAIR32(mapid), instanceId)); } } while (result->NextRow()); // update reset time for normal instances with the max creature respawn time + X hours if (PreparedQueryResult result2 = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAX_CREATURE_RESPAWNS))) { do { Field* fields = result2->Fetch(); uint32 instance = fields[1].GetUInt32(); time_t resettime = time_t(fields[0].GetUInt32() + 2 * HOUR); InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if (itr != instResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } while (result->NextRow()); } // schedule the reset times for (InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if (itr->second.second > now) ScheduleReset(true, itr->second.second, InstResetEvent(0, PAIR32_LOPART(itr->second.first), itr->first)); } // load the global respawn times for raid instances uint32 diff = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; result = CharacterDatabase.Query("SELECT mapid, resettime FROM instance_reset"); if (result) { do { Field* fields = result->Fetch(); uint32 mapid = fields[0].GetUInt16(); uint64 oldresettime = fields[2].GetUInt32(); // update the reset time if the hour in the configs changes uint64 newresettime = (oldresettime / DAY) * DAY + diff; if (oldresettime != newresettime) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%u'", uint32(newresettime), mapid); SetResetTimeFor(mapid, newresettime); } while (result->NextRow()); } ResetTimeMapDiffInstances::const_iterator in_itr; }
void BattleGroundDS::DespawnEvent(uint8 event1, uint8 event2) { BGObjects::const_iterator itr2 = m_EventObjects[MAKE_PAIR32(event1, event2)].gameobjects.begin(); for(; itr2 != m_EventObjects[MAKE_PAIR32(event1, event2)].gameobjects.end(); ++itr2) DespawnBGObject(*itr2); }
void DungeonResetScheduler::LoadResetTimes() { time_t const now = time(NULL); time_t const today = (now / DAY) * DAY; time_t const nextWeek = today + (7 * DAY); // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped typedef std::pair<uint32 /*PAIR32(map,difficulty)*/, time_t> ResetTimeMapDiffType; typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; InstResetTimeMapDiffType instResetTime; QueryResult *result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance WHERE resettime > 0"); if( result ) { do { if (time_t resettime = time_t((*result)[3].GetUInt64())) { uint32 id = (*result)[0].GetUInt32(); uint32 mapid = (*result)[1].GetUInt32(); uint32 difficulty = (*result)[2].GetUInt32(); MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); MapDifficultyEntry const* mapDiff = GetMapDifficultyData(mapid,Difficulty(difficulty)); if (!mapEntry || !mapEntry->IsDungeon() || !mapDiff) { sMapPersistentStateMgr.DeleteInstanceFromDB(id); continue; } //if in DBC no resettime - sedule resettime from DB if (!mapDiff->resetTime) instResetTime[id] = ResetTimeMapDiffType(MAKE_PAIR32(mapid,difficulty), resettime); } } while (result->NextRow()); delete result; // update reset time for normal instances with the max creature respawn time + X hours result = CharacterDatabase.Query("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance"); if( result ) { do { Field* fields = result->Fetch(); time_t resettime = time_t(fields[0].GetUInt64() + 2 * HOUR); uint32 instance = fields[1].GetUInt32(); InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if(itr != instResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '" UI64FMTD "' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } while (result->NextRow()); delete result; } // schedule the reset times for(InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if(itr->second.second > now) ScheduleReset(true, itr->second.second, DungeonResetEvent(RESET_EVENT_NORMAL_DUNGEON, PAIR32_LOPART(itr->second.first),Difficulty(PAIR32_HIPART(itr->second.first)),itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld.getConfig(CONFIG_UINT32_INSTANCE_RESET_TIME_HOUR) * HOUR; result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if(result) { do { Field* fields = result->Fetch(); time_t oldresettime; uint32 mapid = fields[0].GetUInt32(); Difficulty difficulty = Difficulty(fields[1].GetUInt32()); uint64 _oldresettime = fields[2].GetUInt64(); if (_oldresettime > uint64(time(NULL) + INSTANCE_MAX_RESET_OFFSET)) { MapDifficultyEntry const* mapDiff = GetMapDifficultyData(mapid,Difficulty(difficulty)); oldresettime = DungeonResetScheduler::CalculateNextResetTime(mapDiff); sLog.outErrorDb("Wrong reset time in group_instance corrected to: %ld", oldresettime); } else oldresettime = time_t(_oldresettime); MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); if (!mapEntry || !mapEntry->IsDungeon() || !GetMapDifficultyData(mapid,difficulty)) { sLog.outError("MapPersistentStateManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid,difficulty); continue; } // update the reset time if the hour in the configs changes time_t newresettime = (oldresettime / DAY) * DAY + diff; if(oldresettime != newresettime && newresettime > now) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty = '%u'", (uint64)newresettime, mapid, difficulty); SetResetTimeFor(mapid,difficulty,newresettime); } while(result->NextRow()); delete result; } // clean expired instances, references to them will be deleted in CleanupInstances // must be done before calculating new reset times m_InstanceSaves._CleanupExpiredInstancesAtTime(now); // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue for(MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { uint32 map_diff_pair = itr->first; uint32 mapid = PAIR32_LOPART(map_diff_pair); Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); MapDifficultyEntry const* mapDiff = itr->second; // skip mapDiff without global reset time if (!mapDiff->resetTime) continue; MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); if (!mapEntry || !mapEntry->IsDungeon()) continue; //time_t period = GetMaxResetTimeFor(mapDiff); time_t t = GetResetTimeFor(mapid,difficulty); if (!t || t < now || t > nextWeek) { t = CalculateNextResetTime(mapDiff); CharacterDatabase.DirectPExecute("REPLACE INTO instance_reset VALUES ('%u','%u','" UI64FMTD "')", mapid, difficulty, (uint64)t); } SetResetTimeFor(mapid,difficulty,t); // schedule the global reset/warning ResetEventType type = RESET_EVENT_INFORM_1; for (; type < RESET_EVENT_INFORM_LAST; type = ResetEventType(type + 1)) if (t > time_t(now + resetEventTypeDelay[type])) break; ScheduleReset(true, t - resetEventTypeDelay[type], DungeonResetEvent(type, mapid, difficulty, 0)); } }