diff options
| author | Shauren <shauren.trinity@gmail.com> | 2016-01-24 15:56:10 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2016-05-20 23:46:17 +0200 |
| commit | 5c2c9a684f1458da0cea1f3536622add77ef1324 (patch) | |
| tree | d3a2a349e8bed9a31cf417ce93830d508ecea46b /src/server/game | |
| parent | 65c0a0ee4d5c299f3caab04b6cb3fcd7a4a93e2e (diff) | |
Core/DataStores: Updated dbc/db2 to 7.0.1.20810
Diffstat (limited to 'src/server/game')
60 files changed, 2504 insertions, 3057 deletions
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index e60b9776cba..4f2298858ca 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -165,7 +165,7 @@ void ScriptedAI::DoPlaySoundToSet(WorldObject* source, uint32 soundId) if (!source) return; - if (!sSoundEntriesStore.LookupEntry(soundId)) + if (!sSoundKitStore.LookupEntry(soundId)) { TC_LOG_ERROR("scripts", "Invalid soundId %u used in DoPlaySoundToSet (Source: %s)", soundId, source->GetGUID().ToString().c_str()); return; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 85c5e2f017a..c47bbfb3282 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1647,7 +1647,7 @@ class TC_GAME_API SmartAIMgr bool IsSoundValid(SmartScriptHolder const& e, uint32 entry) { - if (!sSoundEntriesStore.LookupEntry(entry)) + if (!sSoundKitStore.LookupEntry(entry)) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Sound entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); return false; diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 642c21e3ff1..f4b51eba6f4 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -924,6 +924,12 @@ CriteriaList const& GuildAchievementMgr::GetCriteriaByType(CriteriaTypes type) c return sCriteriaMgr->GetGuildCriteriaByType(type); } +bool PlayerAchievementMgr::ModifierTreeSatisfied(uint32 modifierTreeId) const +{ + return AdditionalRequirementsSatisfied(sAchievementMgr->GetModifierTree(modifierTreeId), 0, 0, nullptr, _owner); +} + + std::string PlayerAchievementMgr::GetOwnerInfo() const { return Trinity::StringFormat("%s %s", _owner->GetGUID().ToString().c_str(), _owner->GetName().c_str()); diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index b937f2194e2..3e2ec0ef7ff 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -513,7 +513,7 @@ void AuctionHouseMgr::Update() mNeutralAuctions.Update(); } -AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId) +AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId, uint32* houseId) { uint32 houseid = 7; // goblin auction house @@ -550,6 +550,9 @@ AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTem } } + if (houseId) + *houseId = houseid; + return sAuctionHouseStore.LookupEntry(houseid); } @@ -904,7 +907,7 @@ bool AuctionEntry::LoadFromDB(Field* fields) } factionTemplateId = auctioneerInfo->faction; - auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(factionTemplateId); + auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(factionTemplateId, &houseId); if (!auctionHouseEntry) { TC_LOG_ERROR("misc", "Auction %u has auctioneer (GUID : " UI64FMTD " Entry: %u) with wrong faction %u", Id, auctioneer, auctioneerData->id, factionTemplateId); diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index 17b72a24c22..160cab40771 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -79,11 +79,12 @@ struct TC_GAME_API AuctionEntry ObjectGuid::LowType bidder; uint32 deposit; //deposit can be calculated only when creating auction uint32 etime; + uint32 houseId; AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc uint32 factionTemplateId; // helpers - uint32 GetHouseId() const { return auctionHouseEntry->ID; } + uint32 GetHouseId() const { return houseId; } uint32 GetHouseFaction() const { return auctionHouseEntry->FactionID; } uint32 GetAuctionCut() const; uint32 GetAuctionOutBid() const; @@ -188,7 +189,7 @@ class TC_GAME_API AuctionHouseMgr void SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans); static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item* pItem, uint32 count); - static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId); + static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId, uint32* houseId); public: diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp index 8a45d40988d..d7e17b266f3 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp @@ -1026,6 +1026,7 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config) auctionEntry->bidder = UI64LIT(0); auctionEntry->bid = 0; auctionEntry->deposit = sAuctionMgr->GetAuctionDeposit(ahEntry, etime, item, stackCount); + auctionEntry->houseId = houseid; auctionEntry->auctionHouseEntry = ahEntry; auctionEntry->expire_time = time(NULL) + urand(config.GetMinTime(), config.GetMaxTime()) * HOUR; diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp index 3e523cad4fb..c11c25219a5 100644 --- a/src/server/game/Chat/ChatLink.cpp +++ b/src/server/game/Chat/ChatLink.cpp @@ -348,18 +348,23 @@ bool SpellChatLink::ValidateName(char* buffer, const char* context) return false; } - uint32 skillLineNameLength = strlen(skillLine->DisplayName_lang); - if (skillLineNameLength > 0 && strncmp(skillLine->DisplayName_lang, buffer, skillLineNameLength) == 0) + for (uint8 i = 0; i < TOTAL_LOCALES; ++i) { - // found the prefix, remove it to perform spellname validation below - // -2 = strlen(": ") - uint32 spellNameLength = strlen(buffer) - skillLineNameLength - 2; - memmove(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1); + uint32 skillLineNameLength = strlen(skillLine->DisplayName->Str[i]); + if (skillLineNameLength > 0 && strncmp(skillLine->DisplayName->Str[i], buffer, skillLineNameLength) == 0) + { + // found the prefix, remove it to perform spellname validation below + // -2 = strlen(": ") + uint32 spellNameLength = strlen(buffer) - skillLineNameLength - 2; + memmove(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1); + break; + } } } - if (*_spell->SpellName && strcmp(_spell->SpellName, buffer) == 0) - return true; + for (uint8 i = 0; i < TOTAL_LOCALES; ++i) + if (*_spell->SpellName->Str[i] && strcmp(_spell->SpellName->Str[i], buffer) == 0) + return true; TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): linked spell (id: %u) name wasn't found in any localization", context, _spell->Id); return false; diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 2ff7196a2dc..a1ca9bd5f73 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -2621,8 +2621,15 @@ bool ConditionMgr::IsPlayerMeetingCondition(Player* player, PlayerConditionEntry std::array<bool, AuraCount::value> results; results.fill(true); for (std::size_t i = 0; i < AuraCount::value; ++i) + { if (condition->AuraSpellID[i]) - results[i] = player->HasAura(condition->AuraSpellID[i]); + { + if (condition->AuraCount[i]) + results[i] = player->GetAuraCount(condition->AuraSpellID[i]) >= condition->AuraCount[i]; + else + results[i] = player->HasAura(condition->AuraSpellID[i]); + } + } if (!PlayerConditionLogic(condition->AuraSpellLogic, results)) return false; @@ -2728,5 +2735,8 @@ bool ConditionMgr::IsPlayerMeetingCondition(Player* player, PlayerConditionEntry if (condition->MaxAvgEquippedItemLevel && uint32(std::floor(player->GetFloatValue(PLAYER_FIELD_AVG_ITEM_LEVEL + 1))) > condition->MaxAvgEquippedItemLevel) return false; + if (condition->ModifierTreeID && !player->ModifierTreeSatisfied(condition->ModifierTreeID)) + return false; + return true; } diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 2fd9c22b080..ae01936ff0e 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -25,8 +25,11 @@ #include "World.h" DB2Storage<AchievementEntry> sAchievementStore("Achievement.db2", AchievementFormat, HOTFIX_SEL_ACHIEVEMENT); +DB2Storage<AnimKitEntry> sAnimKitStore("AnimKit.db2", AnimKitFormat, HOTFIX_SEL_ANIM_KIT); DB2Storage<AreaGroupMemberEntry> sAreaGroupMemberStore("AreaGroupMember.db2", AreaGroupMemberFormat, HOTFIX_SEL_AREA_GROUP_MEMBER); +DB2Storage<ArmorLocationEntry> sArmorLocationStore("ArmorLocation.db2", ArmorLocationFormat, HOTFIX_SEL_ARMOR_LOCATION); DB2Storage<AuctionHouseEntry> sAuctionHouseStore("AuctionHouse.db2", AuctionHouseFormat, HOTFIX_SEL_AUCTION_HOUSE); +DB2Storage<BankBagSlotPricesEntry> sBankBagSlotPricesStore("BankBagSlotPrices.db2", BankBagSlotPricesFormat, HOTFIX_SEL_BANK_BAG_SLOT_PRICES); DB2Storage<BarberShopStyleEntry> sBarberShopStyleStore("BarberShopStyle.db2", BarberShopStyleFormat, HOTFIX_SEL_BARBER_SHOP_STYLE); DB2Storage<BattlePetBreedQualityEntry> sBattlePetBreedQualityStore("BattlePetBreedQuality.db2", BattlePetBreedQualityFormat, HOTFIX_SEL_BATTLE_PET_BREED_QUALITY); DB2Storage<BattlePetBreedStateEntry> sBattlePetBreedStateStore("BattlePetBreedState.db2", BattlePetBreedStateFormat, HOTFIX_SEL_BATTLE_PET_BREED_STATE); @@ -35,16 +38,21 @@ DB2Storage<BattlePetSpeciesStateEntry> sBattlePetSpeciesStateStore("Bat DB2Storage<BroadcastTextEntry> sBroadcastTextStore("BroadcastText.db2", BroadcastTextFormat, HOTFIX_SEL_BROADCAST_TEXT); DB2Storage<CharStartOutfitEntry> sCharStartOutfitStore("CharStartOutfit.db2", CharStartOutfitFormat, HOTFIX_SEL_CHAR_START_OUTFIT); DB2Storage<ChrClassesXPowerTypesEntry> sChrClassesXPowerTypesStore("ChrClassesXPowerTypes.db2", ChrClassesXPowerTypesFormat, HOTFIX_SEL_CHR_CLASSES_X_POWER_TYPES); +DB2Storage<ChrRacesEntry> sChrRacesStore("ChrRaces.db2", ChrRacesFormat, HOTFIX_SEL_CHR_RACES); DB2Storage<CinematicSequencesEntry> sCinematicSequencesStore("CinematicSequences.db2", CinematicSequencesFormat, HOTFIX_SEL_CINEMATIC_SEQUENCES); DB2Storage<CreatureDisplayInfoEntry> sCreatureDisplayInfoStore("CreatureDisplayInfo.db2", CreatureDisplayInfoFormat, HOTFIX_SEL_CREATURE_DISPLAY_INFO); +DB2Storage<CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore("CreatureDisplayInfoExtra.db2", CreatureDisplayInfoExtraFormat, HOTFIX_SEL_CREATURE_DISPLAY_INFO_EXTRA); DB2Storage<CreatureTypeEntry> sCreatureTypeStore("CreatureType.db2", CreatureTypeFormat, HOTFIX_SEL_CREATURE_TYPE); DB2Storage<CriteriaEntry> sCriteriaStore("Criteria.db2", CriteriaFormat, HOTFIX_SEL_CRITERIA); DB2Storage<CriteriaTreeEntry> sCriteriaTreeStore("CriteriaTree.db2", CriteriaTreeFormat, HOTFIX_SEL_CRITERIA_TREE); DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore("CurrencyTypes.db2", CurrencyTypesFormat, HOTFIX_SEL_CURRENCY_TYPES); DB2Storage<CurvePointEntry> sCurvePointStore("CurvePoint.db2", CurvePointFormat, HOTFIX_SEL_CURVE_POINT); DB2Storage<DestructibleModelDataEntry> sDestructibleModelDataStore("DestructibleModelData.db2", DestructibleModelDataFormat, HOTFIX_SEL_DESTRUCTIBLE_MODEL_DATA); +DB2Storage<DurabilityCostsEntry> sDurabilityCostsStore("DurabilityCosts.db2", DurabilityCostsFormat, HOTFIX_SEL_DURABILITY_COSTS); DB2Storage<DurabilityQualityEntry> sDurabilityQualityStore("DurabilityQuality.db2", DurabilityQualityFormat, HOTFIX_SEL_DURABILITY_QUALITY); +DB2Storage<EmotesTextSoundEntry> sEmotesTextSoundStore("EmotesTextSound.db2", EmotesTextSoundFormat, HOTFIX_SEL_EMOTES_TEXT_SOUND); DB2Storage<GameObjectsEntry> sGameObjectsStore("GameObjects.db2", GameObjectsFormat, HOTFIX_SEL_GAMEOBJECTS); +DB2Storage<GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore("GameObjectDisplayInfo.db2", GameObjectDisplayInfoFormat, HOTFIX_SEL_GAMEOBJECT_DISPLAY_INFO); DB2Storage<GameTablesEntry> sGameTablesStore("GameTables.db2", GameTablesFormat, HOTFIX_SEL_GAME_TABLES); DB2Storage<GarrAbilityEntry> sGarrAbilityStore("GarrAbility.db2", GarrAbilityFormat, HOTFIX_SEL_GARR_ABILITY); DB2Storage<GarrBuildingEntry> sGarrBuildingStore("GarrBuilding.db2", GarrBuildingFormat, HOTFIX_SEL_GARR_BUILDING); @@ -58,6 +66,9 @@ DB2Storage<GarrPlotInstanceEntry> sGarrPlotInstanceStore("GarrPlot DB2Storage<GarrSiteLevelEntry> sGarrSiteLevelStore("GarrSiteLevel.db2", GarrSiteLevelFormat, HOTFIX_SEL_GARR_SITE_LEVEL); DB2Storage<GarrSiteLevelPlotInstEntry> sGarrSiteLevelPlotInstStore("GarrSiteLevelPlotInst.db2", GarrSiteLevelPlotInstFormat, HOTFIX_SEL_GARR_SITE_LEVEL_PLOT_INST); DB2Storage<GlyphSlotEntry> sGlyphSlotStore("GlyphSlot.db2", GlyphSlotFormat, HOTFIX_SEL_GLYPH_SLOT); +DB2Storage<GuildColorBackgroundEntry> sGuildColorBackgroundStore("GuildColorBackground.db2", GuildColorBackgroundFormat, HOTFIX_SEL_GUILD_COLOR_BACKGROUND); +DB2Storage<GuildColorBorderEntry> sGuildColorBorderStore("GuildColorBorder.db2", GuildColorBorderFormat, HOTFIX_SEL_GUILD_COLOR_BORDER); +DB2Storage<GuildColorEmblemEntry> sGuildColorEmblemStore("GuildColorEmblem.db2", GuildColorEmblemFormat, HOTFIX_SEL_GUILD_COLOR_EMBLEM); DB2Storage<GuildPerkSpellsEntry> sGuildPerkSpellsStore("GuildPerkSpells.db2", GuildPerkSpellsFormat, HOTFIX_SEL_GUILD_PERK_SPELLS); DB2Storage<HeirloomEntry> sHeirloomStore("Heirloom.db2", HeirloomFormat, HOTFIX_SEL_HEIRLOOM); DB2Storage<HolidaysEntry> sHolidaysStore("Holidays.db2", HolidaysEntryFormat, HOTFIX_SEL_HOLIDAYS); @@ -66,10 +77,19 @@ DB2Storage<ImportPriceQualityEntry> sImportPriceQualityStore("Import DB2Storage<ImportPriceShieldEntry> sImportPriceShieldStore("ImportPriceShield.db2", ImportPriceShieldFormat, HOTFIX_SEL_IMPORT_PRICE_SHIELD); DB2Storage<ImportPriceWeaponEntry> sImportPriceWeaponStore("ImportPriceWeapon.db2", ImportPriceWeaponFormat, HOTFIX_SEL_IMPORT_PRICE_WEAPON); DB2Storage<ItemAppearanceEntry> sItemAppearanceStore("ItemAppearance.db2", ItemAppearanceFormat, HOTFIX_SEL_ITEM_APPEARANCE); +DB2Storage<ItemArmorQualityEntry> sItemArmorQualityStore("ItemArmorQuality.db2", ItemArmorQualityFormat, HOTFIX_SEL_ITEM_ARMOR_QUALITY); +DB2Storage<ItemArmorShieldEntry> sItemArmorShieldStore("ItemArmorShield.db2", ItemArmorShieldFormat, HOTFIX_SEL_ITEM_ARMOR_SHIELD); +DB2Storage<ItemArmorTotalEntry> sItemArmorTotalStore("ItemArmorTotal.db2", ItemArmorTotalFormat, HOTFIX_SEL_ITEM_ARMOR_TOTAL); +DB2Storage<ItemBagFamilyEntry> sItemBagFamilyStore("ItemBagFamily.db2", ItemBagFamilyFormat, HOTFIX_SEL_ITEM_BAG_FAMILY); DB2Storage<ItemBonusEntry> sItemBonusStore("ItemBonus.db2", ItemBonusFormat, HOTFIX_SEL_ITEM_BONUS); DB2Storage<ItemBonusTreeNodeEntry> sItemBonusTreeNodeStore("ItemBonusTreeNode.db2", ItemBonusTreeNodeFormat, HOTFIX_SEL_ITEM_BONUS_TREE_NODE); DB2Storage<ItemClassEntry> sItemClassStore("ItemClass.db2", ItemClassFormat, HOTFIX_SEL_ITEM_CLASS); DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore("ItemCurrencyCost.db2", ItemCurrencyCostFormat, HOTFIX_SEL_ITEM_CURRENCY_COST); +DB2Storage<ItemDamageAmmoEntry> sItemDamageAmmoStore("ItemDamageAmmo.db2", ItemDamageAmmoFormat, HOTFIX_SEL_ITEM_DAMAGE_AMMO); +DB2Storage<ItemDamageOneHandEntry> sItemDamageOneHandStore("ItemDamageOneHand.db2", ItemDamageOneHandFormat, HOTFIX_SEL_ITEM_DAMAGE_ONE_HAND); +DB2Storage<ItemDamageOneHandCasterEntry> sItemDamageOneHandCasterStore("ItemDamageOneHandCaster.db2", ItemDamageOneHandCasterFormat, HOTFIX_SEL_ITEM_DAMAGE_ONE_HAND_CASTER); +DB2Storage<ItemDamageTwoHandEntry> sItemDamageTwoHandStore("ItemDamageTwoHand.db2", ItemDamageTwoHandFormat, HOTFIX_SEL_ITEM_DAMAGE_TWO_HAND); +DB2Storage<ItemDamageTwoHandCasterEntry> sItemDamageTwoHandCasterStore("ItemDamageTwoHandCaster.db2", ItemDamageTwoHandCasterFormat, HOTFIX_SEL_ITEM_DAMAGE_TWO_HAND_CASTER); DB2Storage<ItemDisenchantLootEntry> sItemDisenchantLootStore("ItemDisenchantLoot.db2", ItemDisenchantLootFormat, HOTFIX_SEL_ITEM_DISENCHANT_LOOT); DB2Storage<ItemEffectEntry> sItemEffectStore("ItemEffect.db2", ItemEffectFormat, HOTFIX_SEL_ITEM_EFFECT); DB2Storage<ItemEntry> sItemStore("Item.db2", ItemFormat, HOTFIX_SEL_ITEM); @@ -79,7 +99,8 @@ DB2Storage<ItemModifiedAppearanceEntry> sItemModifiedAppearanceStore("It DB2Storage<ItemPriceBaseEntry> sItemPriceBaseStore("ItemPriceBase.db2", ItemPriceBaseFormat, HOTFIX_SEL_ITEM_PRICE_BASE); DB2Storage<ItemRandomPropertiesEntry> sItemRandomPropertiesStore("ItemRandomProperties.db2", ItemRandomPropertiesFormat, HOTFIX_SEL_ITEM_RANDOM_PROPERTIES); DB2Storage<ItemRandomSuffixEntry> sItemRandomSuffixStore("ItemRandomSuffix.db2", ItemRandomSuffixFormat, HOTFIX_SEL_ITEM_RANDOM_SUFFIX); -DB2Storage<ItemSparseEntry> sItemSparseStore("Item-sparse.db2", ItemSparseFormat, HOTFIX_SEL_ITEM_SPARSE); +DB2Storage<ItemSetSpellEntry> sItemSetSpellStore("ItemSetSpell.db2", ItemSetSpellFormat, HOTFIX_SEL_ITEM_SET_SPELL); +DB2SparseStorage<ItemSparseEntry> sItemSparseStore("Item-sparse.db2", ItemSparseFormat, HOTFIX_SEL_ITEM_SPARSE); DB2Storage<ItemSpecEntry> sItemSpecStore("ItemSpec.db2", ItemSpecFormat, HOTFIX_SEL_ITEM_SPEC); DB2Storage<ItemSpecOverrideEntry> sItemSpecOverrideStore("ItemSpecOverride.db2", ItemSpecOverrideFormat, HOTFIX_SEL_ITEM_SPEC_OVERRIDE); DB2Storage<ItemToBattlePetSpeciesEntry> sItemToBattlePetSpeciesStore("ItemToBattlePetSpecies.db2", ItemToBattlePetSpeciesFormat, HOTFIX_SEL_ITEM_TO_BATTLE_PET_SPECIES); @@ -90,6 +111,7 @@ DB2Storage<ModifierTreeEntry> sModifierTreeStore("ModifierTree DB2Storage<MountCapabilityEntry> sMountCapabilityStore("MountCapability.db2", MountCapabilityFormat, HOTFIX_SEL_MOUNT_CAPABILITY); DB2Storage<MountEntry> sMountStore("Mount.db2", MountFormat, HOTFIX_SEL_MOUNT); DB2Storage<MountTypeXCapabilityEntry> sMountTypeXCapabilityStore("MountTypeXCapability.db2", MountTypeXCapabilityFormat, HOTFIX_SEL_MOUNT_TYPE_X_CAPABILITY); +DB2Storage<MovieEntry> sMovieStore("Movie.db2", MovieFormat, HOTFIX_SEL_MOVIE); DB2Storage<NameGenEntry> sNameGenStore("NameGen.db2", NameGenFormat, HOTFIX_SEL_NAME_GEN); DB2Storage<NamesProfanityEntry> sNamesProfanityStore("NamesProfanity.db2", NamesProfanityFormat, HOTFIX_SEL_NAMES_PROFANITY); DB2Storage<NamesReservedEntry> sNamesReservedStore("NamesReserved.db2", NamesReservedFormat, HOTFIX_SEL_NAMES_RESERVED); @@ -97,21 +119,38 @@ DB2Storage<NamesReservedLocaleEntry> sNamesReservedLocaleStore("Names DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore("OverrideSpellData.db2", OverrideSpellDataFormat, HOTFIX_SEL_OVERRIDE_SPELL_DATA); DB2Storage<PhaseXPhaseGroupEntry> sPhaseXPhaseGroupStore("PhaseXPhaseGroup.db2", PhaseXPhaseGroupFormat, HOTFIX_SEL_PHASE_X_PHASE_GROUP); DB2Storage<PlayerConditionEntry> sPlayerConditionStore("PlayerCondition.db2", PlayerConditionFormat, HOTFIX_SEL_PLAYER_CONDITION); +DB2Storage<PowerDisplayEntry> sPowerDisplayStore("PowerDisplay.db2", PowerDisplayFormat, HOTFIX_SEL_POWER_DISPLAY); +DB2Storage<QuestFactionRewardEntry> sQuestFactionRewardStore("QuestFactionReward.db2", QuestFactionRewardFormat, HOTFIX_SEL_QUEST_FACTION_REWARD); DB2Storage<QuestMoneyRewardEntry> sQuestMoneyRewardStore("QuestMoneyReward.db2", QuestMoneyRewardFormat, HOTFIX_SEL_QUEST_MONEY_REWARD); -DB2Storage<QuestPackageItemEntry> sQuestPackageItemStore("QuestPackageItem.db2", QuestPackageItemfmt, HOTFIX_SEL_QUEST_PACKAGE_ITEM); +DB2Storage<QuestPackageItemEntry> sQuestPackageItemStore("QuestPackageItem.db2", QuestPackageItemFormat, HOTFIX_SEL_QUEST_PACKAGE_ITEM); DB2Storage<QuestSortEntry> sQuestSortStore("QuestSort.db2", QuestSortFormat, HOTFIX_SEL_QUEST_SORT); DB2Storage<QuestV2Entry> sQuestV2Store("QuestV2.db2", QuestV2Format, HOTFIX_SEL_QUEST_V2); DB2Storage<QuestXPEntry> sQuestXPStore("QuestXP.db2", QuestXPFormat, HOTFIX_SEL_QUEST_XP); +DB2Storage<RandPropPointsEntry> sRandPropPointsStore("RandPropPoints.db2", RandPropPointsFormat, HOTFIX_SEL_RAND_PROP_POINTS); DB2Storage<ScalingStatDistributionEntry> sScalingStatDistributionStore("ScalingStatDistribution.db2", ScalingStatDistributionFormat, HOTFIX_SEL_SCALING_STAT_DISTRIBUTION); -DB2Storage<SoundEntriesEntry> sSoundEntriesStore("SoundEntries.db2", SoundEntriesFormat, HOTFIX_SEL_SOUND_ENTRIES); +DB2Storage<SkillLineEntry> sSkillLineStore("SkillLine.db2", SkillLineFormat, HOTFIX_SEL_SKILL_LINE); +DB2Storage<SkillLineAbilityEntry> sSkillLineAbilityStore("SkillLineAbility.db2", SkillLineAbilityFormat, HOTFIX_SEL_SKILL_LINE_ABILITY); +DB2Storage<SkillRaceClassInfoEntry> sSkillRaceClassInfoStore("SkillRaceClassInfo.db2", SkillRaceClassInfoFormat, HOTFIX_SEL_SKILL_RACE_CLASS_INFO); +DB2Storage<SoundKitEntry> sSoundKitStore("SoundKit.db2", SoundKitFormat, HOTFIX_SEL_SOUND_KIT); DB2Storage<SpecializationSpellsEntry> sSpecializationSpellsStore("SpecializationSpells.db2", SpecializationSpellsFormat, HOTFIX_SEL_SPECIALIZATION_SPELLS); +DB2Storage<SpellEntry> sSpellStore("Spell.db2", SpellFormat, HOTFIX_SEL_SPELL); +DB2Storage<SpellAuraOptionsEntry> sSpellAuraOptionsStore("SpellAuraOptions.db2", SpellAuraOptionsFormat, HOTFIX_SEL_SPELL_AURA_OPTIONS); DB2Storage<SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore("SpellAuraRestrictions.db2", SpellAuraRestrictionsFormat, HOTFIX_SEL_SPELL_AURA_RESTRICTIONS); DB2Storage<SpellCastTimesEntry> sSpellCastTimesStore("SpellCastTimes.db2", SpellCastTimesFormat, HOTFIX_SEL_SPELL_CAST_TIMES); DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore("SpellCastingRequirements.db2", SpellCastingRequirementsFormat, HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS); +DB2Storage<SpellCategoriesEntry> sSpellCategoriesStore("SpellCategories.db2", SpellCategoriesFormat, HOTFIX_SEL_SPELL_CATEGORIES); +DB2Storage<SpellCategoryEntry> sSpellCategoryStore("SpellCategory.db2", SpellCategoryFormat, HOTFIX_SEL_SPELL_CATEGORY); DB2Storage<SpellClassOptionsEntry> sSpellClassOptionsStore("SpellClassOptions.db2", SpellClassOptionsFormat, HOTFIX_SEL_SPELL_CLASS_OPTIONS); +DB2Storage<SpellCooldownsEntry> sSpellCooldownsStore("SpellCooldowns.db2", SpellCooldownsFormat, HOTFIX_SEL_SPELL_COOLDOWNS); DB2Storage<SpellDurationEntry> sSpellDurationStore("SpellDuration.db2", SpellDurationFormat, HOTFIX_SEL_SPELL_DURATION); +DB2Storage<SpellEffectEntry> sSpellEffectStore("SpellEffect.db2", SpellEffectFormat, HOTFIX_SEL_SPELL_EFFECT); +DB2Storage<SpellEffectScalingEntry> sSpellEffectScalingStore("SpellEffectScaling.db2", SpellEffectScalingFormat, HOTFIX_SEL_SPELL_EFFECT_SCALING); +DB2Storage<SpellEquippedItemsEntry> sSpellEquippedItemsStore("SpellEquippedItems.db2", SpellEquippedItemsFormat, HOTFIX_SEL_SPELL_EQUIPPED_ITEMS); +DB2Storage<SpellFocusObjectEntry> sSpellFocusObjectStore("SpellFocusObject.db2", SpellFocusObjectFormat, HOTFIX_SEL_SPELL_FOCUS_OBJECT); +DB2Storage<SpellInterruptsEntry> sSpellInterruptsStore("SpellInterrupts.db2", SpellInterruptsFormat, HOTFIX_SEL_SPELL_INTERRUPTS); DB2Storage<SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore("SpellItemEnchantmentCondition.db2", SpellItemEnchantmentConditionFormat, HOTFIX_SEL_SPELL_ITEM_ENCHANTMENT_CONDITION); DB2Storage<SpellLearnSpellEntry> sSpellLearnSpellStore("SpellLearnSpell.db2", SpellLearnSpellFormat, HOTFIX_SEL_SPELL_LEARN_SPELL); +DB2Storage<SpellLevelsEntry> sSpellLevelsStore("SpellLevels.db2", SpellLevelsFormat, HOTFIX_SEL_SPELL_LEVELS); DB2Storage<SpellMiscEntry> sSpellMiscStore("SpellMisc.db2", SpellMiscFormat, HOTFIX_SEL_SPELL_MISC); DB2Storage<SpellPowerEntry> sSpellPowerStore("SpellPower.db2", SpellPowerFormat, HOTFIX_SEL_SPELL_POWER); DB2Storage<SpellPowerDifficultyEntry> sSpellPowerDifficultyStore("SpellPowerDifficulty.db2", SpellPowerDifficultyFormat, HOTFIX_SEL_SPELL_POWER_DIFFICULTY); @@ -120,7 +159,10 @@ DB2Storage<SpellProcsPerMinuteModEntry> sSpellProcsPerMinuteModStore("Sp DB2Storage<SpellRadiusEntry> sSpellRadiusStore("SpellRadius.db2", SpellRadiusFormat, HOTFIX_SEL_SPELL_RADIUS); DB2Storage<SpellRangeEntry> sSpellRangeStore("SpellRange.db2", SpellRangeFormat, HOTFIX_SEL_SPELL_RANGE); DB2Storage<SpellReagentsEntry> sSpellReagentsStore("SpellReagents.db2", SpellReagentsFormat, HOTFIX_SEL_SPELL_REAGENTS); -DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore("SpellRuneCost.db2", SpellRuneCostFormat, HOTFIX_SEL_SPELL_RUNE_COST); +DB2Storage<SpellScalingEntry> sSpellScalingStore("SpellScaling.db2", SpellScalingFormat, HOTFIX_SEL_SPELL_SCALING); +DB2Storage<SpellShapeshiftEntry> sSpellShapeshiftStore("SpellShapeshift.db2", SpellShapeshiftFormat, HOTFIX_SEL_SPELL_SHAPESHIFT); +DB2Storage<SpellShapeshiftFormEntry> sSpellShapeshiftFormStore("SpellShapeshiftForm.db2", SpellShapeshiftFormFormat, HOTFIX_SEL_SPELL_SHAPESHIFT_FORM); +DB2Storage<SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore("SpellTargetRestrictions.db2", SpellTargetRestrictionsFormat, HOTFIX_SEL_SPELL_TARGET_RESTRICTIONS); DB2Storage<SpellTotemsEntry> sSpellTotemsStore("SpellTotems.db2", SpellTotemsFormat, HOTFIX_SEL_SPELL_TOTEMS); DB2Storage<SpellXSpellVisualEntry> sSpellXSpellVisualStore("SpellXSpellVisual.db2", SpellXSpellVisualFormat, HOTFIX_SEL_SPELL_X_SPELL_VISUAL); DB2Storage<TaxiNodesEntry> sTaxiNodesStore("TaxiNodes.db2", TaxiNodesFormat, HOTFIX_SEL_TAXI_NODES); @@ -132,6 +174,7 @@ DB2Storage<TransportAnimationEntry> sTransportAnimationStore("Transp DB2Storage<TransportRotationEntry> sTransportRotationStore("TransportRotation.db2", TransportRotationFormat, HOTFIX_SEL_TRANSPORT_ROTATION); DB2Storage<UnitPowerBarEntry> sUnitPowerBarStore("UnitPowerBar.db2", UnitPowerBarFormat, HOTFIX_SEL_UNIT_POWER_BAR); DB2Storage<WorldMapOverlayEntry> sWorldMapOverlayStore("WorldMapOverlay.db2", WorldMapOverlayFormat, HOTFIX_SEL_WORLD_MAP_OVERLAY); +DB2Storage<WorldMapTransformsEntry> sWorldMapTransformsStore("WorldMapTransforms.db2", WorldMapTransformsFormat, HOTFIX_SEL_WORLD_MAP_TRANSFORMS); TaxiMask sTaxiNodesMask; TaxiMask sOldContinentsNodesMask; @@ -140,12 +183,12 @@ TaxiMask sAllianceTaxiNodesMask; TaxiPathSetBySource sTaxiPathSetBySource; TaxiPathNodesByPath sTaxiPathNodesByPath; -typedef std::list<std::string> DB2StoreProblemList; +typedef std::vector<std::string> DB2StoreProblemList; uint32 DB2FilesCount = 0; -template<class T> -inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, DB2Manager::StorageMap& stores, DB2Storage<T>* storage, std::string const& db2Path, uint32 defaultLocale) +template<class T, template<class> class DB2> +inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, DB2Manager::StorageMap& stores, DB2StorageBase* storage, std::string const& db2Path, uint32 defaultLocale, DB2<T> const& /*hint*/) { // compatibility format and C++ structure sizes ASSERT(DB2FileLoader::GetFormatRecordSize(storage->GetFormat()) == sizeof(T), @@ -204,10 +247,13 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) DB2StoreProblemList bad_db2_files; uint32 availableDb2Locales = 0xFF; -#define LOAD_DB2(store) LoadDB2(availableDb2Locales, bad_db2_files, _stores, &store, db2Path, defaultLocale) +#define LOAD_DB2(store) LoadDB2(availableDb2Locales, bad_db2_files, _stores, &store, db2Path, defaultLocale, store) LOAD_DB2(sAchievementStore); + LOAD_DB2(sAnimKitStore); + LOAD_DB2(sArmorLocationStore); LOAD_DB2(sAreaGroupMemberStore); + LOAD_DB2(sBankBagSlotPricesStore); LOAD_DB2(sBattlePetBreedQualityStore); LOAD_DB2(sBattlePetBreedStateStore); LOAD_DB2(sAuctionHouseStore); @@ -217,16 +263,21 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) LOAD_DB2(sBroadcastTextStore); LOAD_DB2(sCharStartOutfitStore); LOAD_DB2(sChrClassesXPowerTypesStore); + LOAD_DB2(sChrRacesStore); LOAD_DB2(sCinematicSequencesStore); LOAD_DB2(sCreatureDisplayInfoStore); + LOAD_DB2(sCreatureDisplayInfoExtraStore); LOAD_DB2(sCreatureTypeStore); LOAD_DB2(sCriteriaStore); LOAD_DB2(sCriteriaTreeStore); LOAD_DB2(sCurrencyTypesStore); LOAD_DB2(sCurvePointStore); LOAD_DB2(sDestructibleModelDataStore); + LOAD_DB2(sDurabilityCostsStore); LOAD_DB2(sDurabilityQualityStore); + LOAD_DB2(sEmotesTextSoundStore); LOAD_DB2(sGameObjectsStore); + LOAD_DB2(sGameObjectDisplayInfoStore); LOAD_DB2(sGameTablesStore); LOAD_DB2(sGarrAbilityStore); LOAD_DB2(sGarrBuildingPlotInstStore); @@ -240,6 +291,9 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) LOAD_DB2(sGarrSiteLevelPlotInstStore); LOAD_DB2(sGarrSiteLevelStore); LOAD_DB2(sGlyphSlotStore); + LOAD_DB2(sGuildColorBackgroundStore); + LOAD_DB2(sGuildColorBorderStore); + LOAD_DB2(sGuildColorEmblemStore); LOAD_DB2(sGuildPerkSpellsStore); LOAD_DB2(sHeirloomStore); LOAD_DB2(sHolidaysStore); @@ -248,10 +302,19 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) LOAD_DB2(sImportPriceShieldStore); LOAD_DB2(sImportPriceWeaponStore); LOAD_DB2(sItemAppearanceStore); + LOAD_DB2(sItemArmorQualityStore); + LOAD_DB2(sItemArmorShieldStore); + LOAD_DB2(sItemArmorTotalStore); + LOAD_DB2(sItemBagFamilyStore); LOAD_DB2(sItemBonusStore); LOAD_DB2(sItemBonusTreeNodeStore); LOAD_DB2(sItemClassStore); LOAD_DB2(sItemCurrencyCostStore); + LOAD_DB2(sItemDamageAmmoStore); + LOAD_DB2(sItemDamageOneHandCasterStore); + LOAD_DB2(sItemDamageOneHandStore); + LOAD_DB2(sItemDamageTwoHandCasterStore); + LOAD_DB2(sItemDamageTwoHandStore); LOAD_DB2(sItemDisenchantLootStore); LOAD_DB2(sItemEffectStore); LOAD_DB2(sItemExtendedCostStore); @@ -260,6 +323,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) LOAD_DB2(sItemPriceBaseStore); LOAD_DB2(sItemRandomPropertiesStore); LOAD_DB2(sItemRandomSuffixStore); + LOAD_DB2(sItemSetSpellStore); LOAD_DB2(sItemSparseStore); LOAD_DB2(sItemSpecOverrideStore); LOAD_DB2(sItemSpecStore); @@ -272,6 +336,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) LOAD_DB2(sMountCapabilityStore); LOAD_DB2(sMountStore); LOAD_DB2(sMountTypeXCapabilityStore); + LOAD_DB2(sMovieStore); LOAD_DB2(sNameGenStore); LOAD_DB2(sNamesProfanityStore); LOAD_DB2(sNamesReservedStore); @@ -279,21 +344,37 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) LOAD_DB2(sOverrideSpellDataStore); LOAD_DB2(sPhaseXPhaseGroupStore); LOAD_DB2(sPlayerConditionStore); + LOAD_DB2(sPowerDisplayStore); + LOAD_DB2(sQuestFactionRewardStore); LOAD_DB2(sQuestMoneyRewardStore); LOAD_DB2(sQuestPackageItemStore); LOAD_DB2(sQuestSortStore); LOAD_DB2(sQuestV2Store); LOAD_DB2(sQuestXPStore); LOAD_DB2(sScalingStatDistributionStore); - LOAD_DB2(sSoundEntriesStore); + LOAD_DB2(sSkillLineStore); + LOAD_DB2(sSkillLineAbilityStore); + LOAD_DB2(sSkillRaceClassInfoStore); + LOAD_DB2(sSoundKitStore); LOAD_DB2(sSpecializationSpellsStore); + LOAD_DB2(sSpellStore); + LOAD_DB2(sSpellAuraOptionsStore); LOAD_DB2(sSpellAuraRestrictionsStore); LOAD_DB2(sSpellCastTimesStore); LOAD_DB2(sSpellCastingRequirementsStore); + LOAD_DB2(sSpellCategoriesStore); + LOAD_DB2(sSpellCategoryStore); LOAD_DB2(sSpellClassOptionsStore); + LOAD_DB2(sSpellCooldownsStore); LOAD_DB2(sSpellDurationStore); + LOAD_DB2(sSpellEffectScalingStore); + LOAD_DB2(sSpellEffectStore); + LOAD_DB2(sSpellEquippedItemsStore); + LOAD_DB2(sSpellFocusObjectStore); + LOAD_DB2(sSpellInterruptsStore); LOAD_DB2(sSpellItemEnchantmentConditionStore); LOAD_DB2(sSpellLearnSpellStore); + LOAD_DB2(sSpellLevelsStore); LOAD_DB2(sSpellMiscStore); LOAD_DB2(sSpellPowerStore); LOAD_DB2(sSpellPowerDifficultyStore); @@ -302,7 +383,10 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) LOAD_DB2(sSpellRadiusStore); LOAD_DB2(sSpellRangeStore); LOAD_DB2(sSpellReagentsStore); - LOAD_DB2(sSpellRuneCostStore); + LOAD_DB2(sSpellScalingStore); + LOAD_DB2(sSpellShapeshiftFormStore); + LOAD_DB2(sSpellShapeshiftStore); + LOAD_DB2(sSpellTargetRestrictionsStore); LOAD_DB2(sSpellTotemsStore); LOAD_DB2(sSpellXSpellVisualStore); LOAD_DB2(sTaxiNodesStore); @@ -314,6 +398,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) LOAD_DB2(sTransportRotationStore); LOAD_DB2(sUnitPowerBarStore); LOAD_DB2(sWorldMapOverlayStore); + LOAD_DB2(sWorldMapTransformsStore); #undef LOAD_DB2 @@ -323,21 +408,38 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) for (CharStartOutfitEntry const* outfit : sCharStartOutfitStore) _charStartOutfits[outfit->RaceID | (outfit->ClassID << 8) | (outfit->GenderID << 16)] = outfit; - sChrClassesXPowerTypesStore.Sort(&ChrClassesXPowerTypesEntryComparator::Compare); + std::set<ChrClassesXPowerTypesEntry const*, ChrClassesXPowerTypesEntryComparator> powers; + for (ChrClassesXPowerTypesEntry const* power : sChrClassesXPowerTypesStore) + powers.insert(power); + for (uint32 i = 0; i < MAX_CLASSES; ++i) for (uint32 j = 0; j < MAX_POWERS; ++j) _powersByClass[i][j] = MAX_POWERS; - for (ChrClassesXPowerTypesEntry const* power : sChrClassesXPowerTypesStore) + for (ChrClassesXPowerTypesEntry const* power : powers) { uint32 index = 0; for (uint32 j = 0; j < MAX_POWERS; ++j) if (_powersByClass[power->ClassID][j] != MAX_POWERS) ++index; + ASSERT(power->PowerType < MAX_POWERS); _powersByClass[power->ClassID][power->PowerType] = index; } + for (EmotesTextSoundEntry const* emoteTextSound : sEmotesTextSoundStore) + _emoteTextSounds[EmotesTextSoundContainer::key_type(emoteTextSound->EmotesTextId, emoteTextSound->RaceId, emoteTextSound->SexId, emoteTextSound->ClassId)] = emoteTextSound; + + for (GameObjectDisplayInfoEntry const* gameObjectDisplayInfo : sGameObjectDisplayInfoStore) + { + if (gameObjectDisplayInfo->GeoBoxMax.X < gameObjectDisplayInfo->GeoBoxMin.X) + std::swap(*(float*)(&gameObjectDisplayInfo->GeoBoxMax.X), *(float*)(&gameObjectDisplayInfo->GeoBoxMin.X)); + if (gameObjectDisplayInfo->GeoBoxMax.Y < gameObjectDisplayInfo->GeoBoxMin.Y) + std::swap(*(float*)(&gameObjectDisplayInfo->GeoBoxMax.Y), *(float*)(&gameObjectDisplayInfo->GeoBoxMin.Y)); + if (gameObjectDisplayInfo->GeoBoxMax.Z < gameObjectDisplayInfo->GeoBoxMin.Z) + std::swap(*(float*)(&gameObjectDisplayInfo->GeoBoxMax.Z), *(float*)(&gameObjectDisplayInfo->GeoBoxMin.Z)); + } + for (GlyphSlotEntry const* glyphSlot : sGlyphSlotStore) if (glyphSlot->Type == GLYPH_SLOT_MAJOR || glyphSlot->Type == GLYPH_SLOT_MINOR) _glyphSlots.insert(glyphSlot); @@ -355,10 +457,16 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) } } + for (ItemCurrencyCostEntry const* itemCurrencyCost : sItemCurrencyCostStore) + _itemsWithCurrencyCost.insert(itemCurrencyCost->ItemId); + for (ItemModifiedAppearanceEntry const* appearanceMod : sItemModifiedAppearanceStore) if (ItemAppearanceEntry const* appearance = sItemAppearanceStore.LookupEntry(appearanceMod->AppearanceID)) _itemDisplayIDs[appearanceMod->ItemID | (appearanceMod->AppearanceModID << 24)] = appearance->DisplayID; + for (ItemSetSpellEntry const* entry : sItemSetSpellStore) + _itemSetSpells[entry->ItemSetID].push_back(entry); + for (ItemSpecOverrideEntry const* entry : sItemSpecOverrideStore) _itemSpecOverrides[entry->ItemID].push_back(entry); @@ -424,6 +532,10 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) for (QuestPackageItemEntry const* questPackageItem : sQuestPackageItemStore) _questPackages[questPackageItem->QuestPackageID].push_back(questPackageItem); + for (SkillRaceClassInfoEntry const* entry : sSkillRaceClassInfoStore) + if (sSkillLineStore.LookupEntry(entry->SkillID)) + _skillRaceClassInfoBySkill.insert(SkillRaceClassInfoContainer::value_type(entry->SkillID, entry)); + for (SpecializationSpellsEntry const* specSpells : sSpecializationSpellsStore) _specializationSpellsBySpec[specSpells->SpecID].push_back(specSpells); @@ -459,8 +571,8 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) 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; + if (pathLength[entry->PathID] < entry->NodeIndex + 1u) + pathLength[entry->PathID] = entry->NodeIndex + 1u; // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used @@ -528,7 +640,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) else if (!bad_db2_files.empty()) { std::string str; - for (std::list<std::string>::iterator i = bad_db2_files.begin(); i != bad_db2_files.end(); ++i) + for (auto i = bad_db2_files.begin(); i != bad_db2_files.end(); ++i) str += *i + "\n"; TC_LOG_ERROR("misc", "\nSome required *.db2 files (%u from %d) not found or not compatible:\n%s", (uint32)bad_db2_files.size(), DB2FilesCount, str.c_str()); @@ -536,8 +648,9 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) } // Check loaded DB2 files proper version - if (!sItemStore.LookupEntry(128706) || // last item added in 6.2.0 (20216) - !sItemExtendedCostStore.LookupEntry(5923) ) // last item extended cost added in 6.2.0 (20216) + if (!sItemStore.LookupEntry(136350) || // last item added in 7.0.1 (20810) + !sItemExtendedCostStore.LookupEntry(5951) || // last item extended cost added in 7.0.1 (20810) + !sSpellStore.LookupEntry(207511)) // last spell added in 7.0.1 (20810) { TC_LOG_ERROR("misc", "You have _outdated_ DB2 files. Please extract correct versions from current using client."); exit(1); @@ -644,6 +757,31 @@ uint32 DB2Manager::GetPowerIndexByClass(uint32 powerType, uint32 classId) const return _powersByClass[classId][powerType]; } +char const* DB2Manager::GetChrRaceName(uint8 race, LocaleConstant locale /*= DEFAULT_LOCALE*/) +{ + ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race); + if (!raceEntry) + return ""; + + if (raceEntry->Name->Str[locale][0] != '\0') + return raceEntry->Name->Str[locale]; + + return raceEntry->Name->Str[DEFAULT_LOCALE]; +} + +EmotesTextSoundEntry const* DB2Manager::GetTextSoundEmoteFor(uint32 emote, uint8 race, uint8 gender, uint8 class_) const +{ + auto itr = _emoteTextSounds.find(EmotesTextSoundContainer::key_type(emote, race, gender, class_)); + if (itr != _emoteTextSounds.end()) + return itr->second; + + itr = _emoteTextSounds.find(EmotesTextSoundContainer::key_type(emote, race, gender, 0)); + if (itr != _emoteTextSounds.end()) + return itr->second; + + return nullptr; +} + uint32 DB2Manager::GetHeirloomItemLevel(uint32 curveId, uint32 level) const { // Assuming linear item level scaling for heirlooms @@ -719,6 +857,15 @@ uint32 DB2Manager::GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const return 0; } +std::vector<ItemSetSpellEntry const*> const* DB2Manager::GetItemSetSpells(uint32 itemSetId) const +{ + auto itr = _itemSetSpells.find(itemSetId); + if (itr != _itemSetSpells.end()) + return &itr->second; + + return nullptr; +} + std::vector<ItemSpecOverrideEntry const*> const* DB2Manager::GetItemSpecOverrides(uint32 itemId) const { auto itr = _itemSpecOverrides.find(itemId); @@ -809,6 +956,22 @@ std::set<uint32> DB2Manager::GetPhasesForGroup(uint32 group) const return std::set<uint32>(); } +SkillRaceClassInfoEntry const* DB2Manager::GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_) +{ + auto bounds = _skillRaceClassInfoBySkill.equal_range(skill); + for (auto itr = bounds.first; itr != bounds.second; ++itr) + { + if (itr->second->RaceMask && !(itr->second->RaceMask & (1 << (race - 1)))) + continue; + if (itr->second->ClassMask && !(itr->second->ClassMask & (1 << (class_ - 1)))) + continue; + + return itr->second; + } + + return nullptr; +} + std::vector<SpecializationSpellsEntry const*> const* DB2Manager::GetSpecializationSpells(uint32 specId) const { auto itr = _specializationSpellsBySpec.find(specId); @@ -869,11 +1032,80 @@ std::vector<SpellProcsPerMinuteModEntry const*> DB2Manager::GetSpellProcsPerMinu return std::vector<SpellProcsPerMinuteModEntry const*>(); } +bool DB2Manager::IsTotemCategoryCompatibleWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) +{ + if (requiredTotemCategoryId == 0) + return true; + if (itemTotemCategoryId == 0) + return false; + + TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId); + if (!itemEntry) + return false; + TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId); + if (!reqEntry) + return false; + + if (itemEntry->CategoryType != reqEntry->CategoryType) + return false; + + return (itemEntry->CategoryMask & reqEntry->CategoryMask) == reqEntry->CategoryMask; +} + bool DB2Manager::IsToyItem(uint32 toy) const { return _toys.count(toy) > 0; } +void DB2Manager::DeterminaAlternateMapPosition(uint32 mapId, float x, float y, float z, uint32* newMapId /*= nullptr*/, DBCPosition2D* newPos /*= nullptr*/) +{ + ASSERT(newMapId || newPos); + WorldMapTransformsEntry const* transformation = nullptr; + for (WorldMapTransformsEntry const* transform : sWorldMapTransformsStore) + { + if (transform->MapID != mapId) + continue; + + if (transform->RegionMin.X > x || transform->RegionMax.X < x) + continue; + if (transform->RegionMin.Y > y || transform->RegionMax.Y < y) + continue; + if (transform->RegionMin.Z > z || transform->RegionMax.Z < z) + continue; + + transformation = transform; + break; + } + + if (!transformation) + { + if (newMapId) + *newMapId = mapId; + + if (newPos) + { + newPos->X = x; + newPos->Y = y; + } + return; + } + + if (newMapId) + *newMapId = transformation->NewMapID; + + if (!newPos) + return; + + if (transformation->RegionScale > 0.0f && transformation->RegionScale < 1.0f) + { + x = (x - transformation->RegionMin.X) * transformation->RegionScale + transformation->RegionMin.X; + y = (y - transformation->RegionMin.Y) * transformation->RegionScale + transformation->RegionMin.Y; + } + + newPos->X = x + transformation->RegionOffset.X; + newPos->Y = y + transformation->RegionOffset.Y; +} + bool DB2Manager::ChrClassesXPowerTypesEntryComparator::Compare(ChrClassesXPowerTypesEntry const* left, ChrClassesXPowerTypesEntry const* right) { if (left->ClassID != right->ClassID) @@ -892,5 +1124,5 @@ bool DB2Manager::MountTypeXCapabilityEntryComparator::Compare(MountTypeXCapabili { if (left->MountTypeID == right->MountTypeID) return left->OrderIndex < right->OrderIndex; - return left->ID < right->ID; + return left->MountTypeID < right->MountTypeID; } diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index b42d1dd8bab..4e3f7bdd70b 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -25,7 +25,10 @@ #include <array> TC_GAME_API extern DB2Storage<AchievementEntry> sAchievementStore; +TC_GAME_API extern DB2Storage<AnimKitEntry> sAnimKitStore; +TC_GAME_API extern DB2Storage<ArmorLocationEntry> sArmorLocationStore; TC_GAME_API extern DB2Storage<AuctionHouseEntry> sAuctionHouseStore; +TC_GAME_API extern DB2Storage<BankBagSlotPricesEntry> sBankBagSlotPricesStore; TC_GAME_API extern DB2Storage<BarberShopStyleEntry> sBarberShopStyleStore; TC_GAME_API extern DB2Storage<BattlePetBreedQualityEntry> sBattlePetBreedQualityStore; TC_GAME_API extern DB2Storage<BattlePetBreedStateEntry> sBattlePetBreedStateStore; @@ -33,15 +36,19 @@ TC_GAME_API extern DB2Storage<BattlePetSpeciesEntry> sBattlePetSp TC_GAME_API extern DB2Storage<BattlePetSpeciesStateEntry> sBattlePetSpeciesStateStore; TC_GAME_API extern DB2Storage<BroadcastTextEntry> sBroadcastTextStore; TC_GAME_API extern DB2Storage<CharStartOutfitEntry> sCharStartOutfitStore; +TC_GAME_API extern DB2Storage<ChrRacesEntry> sChrRacesStore; TC_GAME_API extern DB2Storage<CinematicSequencesEntry> sCinematicSequencesStore; TC_GAME_API extern DB2Storage<CreatureDisplayInfoEntry> sCreatureDisplayInfoStore; +TC_GAME_API extern DB2Storage<CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore; TC_GAME_API extern DB2Storage<CreatureTypeEntry> sCreatureTypeStore; TC_GAME_API extern DB2Storage<CriteriaEntry> sCriteriaStore; TC_GAME_API extern DB2Storage<CriteriaTreeEntry> sCriteriaTreeStore; TC_GAME_API extern DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore; TC_GAME_API extern DB2Storage<DestructibleModelDataEntry> sDestructibleModelDataStore; +TC_GAME_API extern DB2Storage<DurabilityCostsEntry> sDurabilityCostsStore; TC_GAME_API extern DB2Storage<DurabilityQualityEntry> sDurabilityQualityStore; TC_GAME_API extern DB2Storage<GameObjectsEntry> sGameObjectsStore; +TC_GAME_API extern DB2Storage<GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore; TC_GAME_API extern DB2Storage<GameTablesEntry> sGameTablesStore; TC_GAME_API extern DB2Storage<GarrAbilityEntry> sGarrAbilityStore; TC_GAME_API extern DB2Storage<GarrBuildingEntry> sGarrBuildingStore; @@ -55,15 +62,25 @@ TC_GAME_API extern DB2Storage<GarrPlotInstanceEntry> sGarrPlotIns TC_GAME_API extern DB2Storage<GarrSiteLevelEntry> sGarrSiteLevelStore; TC_GAME_API extern DB2Storage<GarrSiteLevelPlotInstEntry> sGarrSiteLevelPlotInstStore; TC_GAME_API extern DB2Storage<GlyphSlotEntry> sGlyphSlotStore; +TC_GAME_API extern DB2Storage<GuildColorBackgroundEntry> sGuildColorBackgroundStore; +TC_GAME_API extern DB2Storage<GuildColorBorderEntry> sGuildColorBorderStore; +TC_GAME_API extern DB2Storage<GuildColorEmblemEntry> sGuildColorEmblemStore; TC_GAME_API extern DB2Storage<GuildPerkSpellsEntry> sGuildPerkSpellsStore; -TC_GAME_API extern DB2Storage<HeirloomEntry> sHeirloomStore; TC_GAME_API extern DB2Storage<HolidaysEntry> sHolidaysStore; TC_GAME_API extern DB2Storage<ImportPriceArmorEntry> sImportPriceArmorStore; TC_GAME_API extern DB2Storage<ImportPriceQualityEntry> sImportPriceQualityStore; TC_GAME_API extern DB2Storage<ImportPriceShieldEntry> sImportPriceShieldStore; TC_GAME_API extern DB2Storage<ImportPriceWeaponEntry> sImportPriceWeaponStore; +TC_GAME_API extern DB2Storage<ItemArmorQualityEntry> sItemArmorQualityStore; +TC_GAME_API extern DB2Storage<ItemArmorShieldEntry> sItemArmorShieldStore; +TC_GAME_API extern DB2Storage<ItemArmorTotalEntry> sItemArmorTotalStore; +TC_GAME_API extern DB2Storage<ItemBagFamilyEntry> sItemBagFamilyStore; TC_GAME_API extern DB2Storage<ItemClassEntry> sItemClassStore; -TC_GAME_API extern DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore; +TC_GAME_API extern DB2Storage<ItemDamageAmmoEntry> sItemDamageAmmoStore; +TC_GAME_API extern DB2Storage<ItemDamageOneHandEntry> sItemDamageOneHandStore; +TC_GAME_API extern DB2Storage<ItemDamageOneHandCasterEntry> sItemDamageOneHandCasterStore; +TC_GAME_API extern DB2Storage<ItemDamageTwoHandEntry> sItemDamageTwoHandStore; +TC_GAME_API extern DB2Storage<ItemDamageTwoHandCasterEntry> sItemDamageTwoHandCasterStore; TC_GAME_API extern DB2Storage<ItemDisenchantLootEntry> sItemDisenchantLootStore; TC_GAME_API extern DB2Storage<ItemEffectEntry> sItemEffectStore; TC_GAME_API extern DB2Storage<ItemEntry> sItemStore; @@ -72,40 +89,60 @@ TC_GAME_API extern DB2Storage<ItemLimitCategoryEntry> sItemLimitCa TC_GAME_API extern DB2Storage<ItemPriceBaseEntry> sItemPriceBaseStore; TC_GAME_API extern DB2Storage<ItemRandomPropertiesEntry> sItemRandomPropertiesStore; TC_GAME_API extern DB2Storage<ItemRandomSuffixEntry> sItemRandomSuffixStore; -TC_GAME_API extern DB2Storage<ItemSparseEntry> sItemSparseStore; +TC_GAME_API extern DB2Storage<ItemSetSpellEntry> sItemSetSpellStore; +TC_GAME_API extern DB2SparseStorage<ItemSparseEntry> sItemSparseStore; TC_GAME_API extern DB2Storage<ItemSpecEntry> sItemSpecStore; TC_GAME_API extern DB2Storage<ItemSpecOverrideEntry> sItemSpecOverrideStore; TC_GAME_API extern DB2Storage<ItemToBattlePetSpeciesEntry> sItemToBattlePetSpeciesStore; TC_GAME_API extern DB2Storage<MailTemplateEntry> sMailTemplateStore; TC_GAME_API extern DB2Storage<ModifierTreeEntry> sModifierTreeStore; TC_GAME_API extern DB2Storage<MountCapabilityEntry> sMountCapabilityStore; +TC_GAME_API extern DB2Storage<MovieEntry> sMovieStore; TC_GAME_API extern DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore; TC_GAME_API extern DB2Storage<PlayerConditionEntry> sPlayerConditionStore; +TC_GAME_API extern DB2Storage<PowerDisplayEntry> sPowerDisplayStore; +TC_GAME_API extern DB2Storage<QuestFactionRewardEntry> sQuestFactionRewardStore; TC_GAME_API extern DB2Storage<QuestMoneyRewardEntry> sQuestMoneyRewardStore; TC_GAME_API extern DB2Storage<QuestSortEntry> sQuestSortStore; TC_GAME_API extern DB2Storage<QuestXPEntry> sQuestXPStore; +TC_GAME_API extern DB2Storage<RandPropPointsEntry> sRandPropPointsStore; TC_GAME_API extern DB2Storage<ScalingStatDistributionEntry> sScalingStatDistributionStore; -TC_GAME_API extern DB2Storage<SoundEntriesEntry> sSoundEntriesStore; +TC_GAME_API extern DB2Storage<SkillLineEntry> sSkillLineStore; +TC_GAME_API extern DB2Storage<SkillLineAbilityEntry> sSkillLineAbilityStore; +TC_GAME_API extern DB2Storage<SkillRaceClassInfoEntry> sSkillRaceClassInfoStore; +TC_GAME_API extern DB2Storage<SoundKitEntry> sSoundKitStore; +TC_GAME_API extern DB2Storage<SpellEntry> sSpellStore; +TC_GAME_API extern DB2Storage<SpellAuraOptionsEntry> sSpellAuraOptionsStore; TC_GAME_API extern DB2Storage<SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore; TC_GAME_API extern DB2Storage<SpellCastTimesEntry> sSpellCastTimesStore; TC_GAME_API extern DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore; +TC_GAME_API extern DB2Storage<SpellCategoriesEntry> sSpellCategoriesStore; +TC_GAME_API extern DB2Storage<SpellCategoryEntry> sSpellCategoryStore; TC_GAME_API extern DB2Storage<SpellClassOptionsEntry> sSpellClassOptionsStore; +TC_GAME_API extern DB2Storage<SpellCooldownsEntry> sSpellCooldownsStore; TC_GAME_API extern DB2Storage<SpellDurationEntry> sSpellDurationStore; +TC_GAME_API extern DB2Storage<SpellEffectEntry> sSpellEffectStore; +TC_GAME_API extern DB2Storage<SpellEffectScalingEntry> sSpellEffectScalingStore; +TC_GAME_API extern DB2Storage<SpellEquippedItemsEntry> sSpellEquippedItemsStore; +TC_GAME_API extern DB2Storage<SpellFocusObjectEntry> sSpellFocusObjectStore; +TC_GAME_API extern DB2Storage<SpellInterruptsEntry> sSpellInterruptsStore; TC_GAME_API extern DB2Storage<SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore; TC_GAME_API extern DB2Storage<SpellLearnSpellEntry> sSpellLearnSpellStore; +TC_GAME_API extern DB2Storage<SpellLevelsEntry> sSpellLevelsStore; TC_GAME_API extern DB2Storage<SpellMiscEntry> sSpellMiscStore; TC_GAME_API extern DB2Storage<SpellPowerEntry> sSpellPowerStore; TC_GAME_API extern DB2Storage<SpellProcsPerMinuteEntry> sSpellProcsPerMinuteStore; TC_GAME_API extern DB2Storage<SpellRadiusEntry> sSpellRadiusStore; TC_GAME_API extern DB2Storage<SpellRangeEntry> sSpellRangeStore; TC_GAME_API extern DB2Storage<SpellReagentsEntry> sSpellReagentsStore; -TC_GAME_API extern DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore; +TC_GAME_API extern DB2Storage<SpellScalingEntry> sSpellScalingStore; +TC_GAME_API extern DB2Storage<SpellShapeshiftEntry> sSpellShapeshiftStore; +TC_GAME_API extern DB2Storage<SpellShapeshiftFormEntry> sSpellShapeshiftFormStore; +TC_GAME_API extern DB2Storage<SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore; TC_GAME_API extern DB2Storage<SpellTotemsEntry> sSpellTotemsStore; TC_GAME_API extern DB2Storage<SpellXSpellVisualEntry> sSpellXSpellVisualStore; TC_GAME_API extern DB2Storage<TaxiNodesEntry> sTaxiNodesStore; TC_GAME_API extern DB2Storage<TaxiPathEntry> sTaxiPathStore; -TC_GAME_API extern DB2Storage<TotemCategoryEntry> sTotemCategoryStore; -TC_GAME_API extern DB2Storage<ToyEntry> sToyStore; TC_GAME_API extern DB2Storage<UnitPowerBarEntry> sUnitPowerBarStore; TC_GAME_API extern DB2Storage<WorldMapOverlayEntry> sWorldMapOverlayStore; @@ -142,6 +179,7 @@ public: typedef std::map<uint32 /*hash*/, DB2StorageBase*> StorageMap; typedef std::unordered_map<uint32 /*areaGroupId*/, std::vector<uint32/*areaId*/>> AreaGroupMemberContainer; typedef std::unordered_map<uint32, CharStartOutfitEntry const*> CharStartOutfitContainer; + typedef std::map<std::tuple<uint32, uint8, uint8, uint8>, EmotesTextSoundEntry const*> EmotesTextSoundContainer; typedef std::set<GlyphSlotEntry const*, GlyphSlotEntryComparator> GlyphSlotContainer; typedef std::map<uint32 /*curveID*/, std::map<uint32/*index*/, CurvePointEntry const*, std::greater<uint32>>> HeirloomCurvesContainer; typedef std::unordered_map<uint32, HeirloomEntry const*> HeirloomItemsContainer; @@ -150,6 +188,7 @@ public: typedef std::unordered_multimap<uint32 /*itemId*/, uint32 /*bonusTreeId*/> ItemToBonusTreeContainer; typedef std::unordered_map<uint32 /*itemId | appearanceMod << 24*/, uint32> ItemDisplayIdContainer; typedef std::unordered_map<uint32, std::set<ItemBonusTreeNodeEntry const*>> ItemBonusTreeContainer; + typedef std::unordered_map<uint32, std::vector<ItemSetSpellEntry const*>> ItemSetSpellContainer; typedef std::unordered_map<uint32, std::vector<ItemSpecOverrideEntry const*>> ItemSpecOverridesContainer; typedef std::unordered_map<uint32, MountEntry const*> MountContainer; typedef std::set<MountTypeXCapabilityEntry const*, MountTypeXCapabilityEntryComparator> MountTypeXCapabilitySet; @@ -158,6 +197,7 @@ public: typedef std::array<std::vector<boost::regex>, TOTAL_LOCALES + 1> NameValidationRegexContainer; typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer; typedef std::unordered_map<uint32, std::vector<QuestPackageItemEntry const*>> QuestPackageItemContainer; + typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoContainer; typedef std::unordered_map<uint32, std::vector<SpecializationSpellsEntry const*>> SpecializationSpellsContainer; typedef std::unordered_map<uint32, std::vector<SpellPowerEntry const*>> SpellPowerContainer; typedef std::unordered_map<uint32, std::unordered_map<uint32, std::vector<SpellPowerEntry const*>>> SpellPowerDifficultyContainer; @@ -177,12 +217,16 @@ public: static char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false); CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender) const; uint32 GetPowerIndexByClass(uint32 powerType, uint32 classId) const; + static char const* GetChrRaceName(uint8 race, LocaleConstant locale = DEFAULT_LOCALE); + EmotesTextSoundEntry const* GetTextSoundEmoteFor(uint32 emote, uint8 race, uint8 gender, uint8 class_) const; GlyphSlotContainer const& GetGlyphSlots() const { return _glyphSlots; } uint32 GetHeirloomItemLevel(uint32 curveId, uint32 level) const; HeirloomEntry const* GetHeirloomByItemId(uint32 itemId) const; ItemBonusList const* GetItemBonusList(uint32 bonusListId) const; std::set<uint32> GetItemBonusTree(uint32 itemId, uint32 itemBonusTreeMod) const; + bool HasItemCurrencyCost(uint32 itemId) const { return _itemsWithCurrencyCost.count(itemId) > 0; } uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const; + std::vector<ItemSetSpellEntry const*> const* GetItemSetSpells(uint32 itemSetId) const; std::vector<ItemSpecOverrideEntry const*> const* GetItemSpecOverrides(uint32 itemId) const; std::string GetNameGenEntry(uint8 race, uint8 gender, LocaleConstant locale) const; MountEntry const* GetMount(uint32 spellId) const; @@ -192,10 +236,13 @@ public: std::vector<QuestPackageItemEntry const*> const* GetQuestPackageItems(uint32 questPackageID) const; uint32 GetQuestUniqueBitFlag(uint32 questId); std::set<uint32> GetPhasesForGroup(uint32 group) const; + SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_); std::vector<SpecializationSpellsEntry const*> const* GetSpecializationSpells(uint32 specId) const; std::vector<SpellPowerEntry const*> GetSpellPowers(uint32 spellId, Difficulty difficulty = DIFFICULTY_NONE, bool* hasDifficultyPowers = nullptr) const; std::vector<SpellProcsPerMinuteModEntry const*> GetSpellProcsPerMinuteMods(uint32 spellprocsPerMinuteId) const; + static bool IsTotemCategoryCompatibleWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); bool IsToyItem(uint32 toy) const; + static void DeterminaAlternateMapPosition(uint32 mapId, float x, float y, float z, uint32* newMapId = nullptr, DBCPosition2D* newPos = nullptr); private: StorageMap _stores; @@ -204,13 +251,16 @@ private: AreaGroupMemberContainer _areaGroupMembers; CharStartOutfitContainer _charStartOutfits; uint32 _powersByClass[MAX_CLASSES][MAX_POWERS]; + EmotesTextSoundContainer _emoteTextSounds; GlyphSlotContainer _glyphSlots; HeirloomItemsContainer _heirlooms; HeirloomCurvesContainer _heirloomCurvePoints; ItemBonusListContainer _itemBonusLists; ItemBonusTreeContainer _itemBonusTrees; + std::unordered_set<uint32> _itemsWithCurrencyCost; ItemDisplayIdContainer _itemDisplayIDs; ItemToBonusTreeContainer _itemToBonusTree; + ItemSetSpellContainer _itemSetSpells; ItemSpecOverridesContainer _itemSpecOverrides; MountContainer _mountsBySpellId; MountCapabilitiesByTypeContainer _mountCapabilitiesByType; @@ -218,6 +268,7 @@ private: NameValidationRegexContainer _nameValidators; PhaseGroupContainer _phasesByGroup; QuestPackageItemContainer _questPackages; + SkillRaceClassInfoContainer _skillRaceClassInfoBySkill; SpecializationSpellsContainer _specializationSpellsBySpec; SpellPowerContainer _spellPowers; SpellPowerDifficultyContainer _spellPowerDifficulties; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index daebcf7375f..ff3b9efc9c1 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -26,165 +26,229 @@ struct AchievementEntry { - uint32 ID; // 0 - int32 Faction; // 1 -1=all, 0=horde, 1=alliance - int32 MapID; // 2 -1=none - uint32 Supercedes; // 3 its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin) - LocalizedString* Title; // 4 - LocalizedString* Description; // 5 - uint32 Category; // 6 - uint32 Points; // 7 reward points - uint32 UIOrder; // 8 - uint32 Flags; // 9 - uint32 IconID; // 10 icon (from SpellIcon.dbc) - LocalizedString* Reward; // 11 - uint32 MinimumCriteria; // 12 - need this count of completed criterias (own or referenced achievement criterias) - uint32 SharesCriteria; // 13 - referenced achievement (counting of all completed criterias) - uint32 CriteriaTree; // 14 + uint32 ID; + LocalizedString* Title; + LocalizedString* Description; + uint32 Flags; + LocalizedString* Reward; + int16 MapID; // -1 = none + uint16 Supercedes; // its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin) + uint16 Category; + uint16 UIOrder; + uint16 IconID; + uint16 SharesCriteria; // referenced achievement (counting of all completed criterias) + uint16 CriteriaTree; + int8 Faction; // -1 = all, 0 = horde, 1 = alliance + uint8 Points; + uint8 MinimumCriteria; // need this count of completed criterias (own or referenced achievement criterias) +}; + +struct AnimKitEntry +{ + uint32 OneShotDuration; + uint16 OneShotStopAnimKitID; + uint16 LowDefAnimKitID; }; struct AreaGroupMemberEntry { - uint32 ID; // 0 - uint32 AreaGroupID; // 1 - uint32 AreaID; // 2 + uint16 AreaGroupID; + uint16 AreaID; +}; + +struct ArmorLocationEntry +{ + float Modifier[5]; }; struct AuctionHouseEntry { - uint32 ID; // 0 - uint32 FactionID; // 1 id of faction.dbc for player factions associated with city - uint32 DepositRate; // 2 1/3 from real - uint32 ConsignmentRate; // 3 - LocalizedString* Name; // 4 + LocalizedString* Name; + uint16 FactionID; // id of faction.dbc for player factions associated with city + uint8 DepositRate; + uint8 ConsignmentRate; +}; + +struct BankBagSlotPricesEntry +{ + uint32 Cost; }; struct BarberShopStyleEntry { - uint32 ID; // 0 - uint32 Type; // 1 value 0 -> hair, value 2 -> facialhair - LocalizedString* DisplayName; // 2 - LocalizedString* Description; // 3 - float CostModifier; // 4 - uint32 Race; // 5 - uint32 Sex; // 6 - uint32 Data; // 7 (real ID to hair/facial hair) + uint32 ID; + LocalizedString* DisplayName; + LocalizedString* Description; + float CostModifier; + uint8 Type; // value 0 -> hair, value 2 -> facialhair + uint8 Race; + uint8 Sex; + uint8 Data; // real ID to hair/facial hair }; struct BattlePetBreedQualityEntry { - uint32 ID; // 0 - uint32 Quality; // 1 - float Modifier; // 2 + float Modifier; + uint8 Quality; }; struct BattlePetBreedStateEntry { - uint32 ID; // 0 - uint32 BreedID; // 1 - uint32 State; // 2 - int32 Value; // 3 + uint32 ID; + int16 Value; + uint8 BreedID; + uint8 State; }; struct BattlePetSpeciesEntry { - uint32 ID; // 0 - uint32 CreatureID; // 1 - uint32 IconFileID; // 2 - uint32 SummonSpellID; // 3 - uint32 PetType; // 4 - int32 Source; // 5 - uint32 Flags; // 6 - LocalizedString* SourceText; // 7 - LocalizedString* Description; // 8 + uint32 ID; + uint32 CreatureID; + uint32 IconFileID; + uint32 SummonSpellID; + LocalizedString* SourceText; + LocalizedString* Description; + uint16 Flags; + uint8 PetType; + int8 Source; }; struct BattlePetSpeciesStateEntry { - uint32 ID; // 0 - uint32 SpeciesID; // 1 - uint32 State; // 2 - int32 Value; // 3 + uint32 ID; + int32 Value; + uint16 SpeciesID; + uint8 State; }; #define MAX_BROADCAST_TEXT_EMOTES 3 struct BroadcastTextEntry { - uint32 ID; - int32 Language; LocalizedString* MaleText; LocalizedString* FemaleText; - uint32 EmoteID[MAX_BROADCAST_TEXT_EMOTES]; - uint32 EmoteDelay[MAX_BROADCAST_TEXT_EMOTES]; - uint32 SoundID; - uint32 UnkEmoteID; - uint32 Type; + uint16 EmoteID[MAX_BROADCAST_TEXT_EMOTES]; + uint16 EmoteDelay[MAX_BROADCAST_TEXT_EMOTES]; + uint16 SoundID; + uint16 UnkEmoteID; + uint8 Language; + uint8 Type; }; #define MAX_OUTFIT_ITEMS 24 struct CharStartOutfitEntry { - uint32 ID; // 0 - uint8 RaceID; // 1 - uint8 ClassID; // 2 - uint8 GenderID; // 3 - uint8 OutfitID; // 4 - int32 ItemID[MAX_OUTFIT_ITEMS]; // 5-28 - uint32 PetDisplayID; // 29 Pet Model ID for starting pet - uint32 PetFamilyID; // 30 Pet Family Entry for starting pet + int32 ItemID[MAX_OUTFIT_ITEMS]; + uint32 PetDisplayID; // Pet Model ID for starting pet + uint8 RaceID; + uint8 ClassID; + uint8 GenderID; + uint8 OutfitID; + uint8 PetFamilyID; // Pet Family Entry for starting pet }; struct ChrClassesXPowerTypesEntry { - uint32 ID; // 0 - uint32 ClassID; // 1 - uint32 PowerType; // 2 + uint8 ClassID; + uint8 PowerType; +}; + +struct ChrRacesEntry +{ + uint32 ID; + uint32 Flags; + char const* ClientPrefix; + char const* ClientFileString; + LocalizedString* Name; + LocalizedString* NameFemale; + LocalizedString* NameMale; + char const* FacialHairCustomization[2]; + char const* HairCustomization; + uint32 CreateScreenFileDataID; + uint32 SelectScreenFileDataID; + float MaleCustomizeOffset[3]; + float FemaleCustomizeOffset[3]; + uint32 LowResScreenFileDataID; + uint16 FactionID; + uint16 ExplorationSoundID; + uint16 MaleDisplayID; + uint16 FemaleDisplayID; + uint16 ResSicknessSpellID; + uint16 SplashSoundID; + uint16 CinematicSequenceID; + uint16 UAMaleCreatureSoundDataID; + uint16 UAFemaleCreatureSoundDataID; + uint16 HighResMaleDisplayID; + uint16 HighResFemaleDisplayID; + uint16 Unk; + uint8 BaseLanguage; + uint8 CreatureType; + uint8 TeamID; + uint8 RaceRelated; + uint8 UnalteredVisualRaceID; + uint8 CharComponentTextureLayoutID; + uint8 DefaultClassID; + uint8 NeutralRaceID; + uint8 CharComponentTexLayoutHiResID; }; struct CinematicSequencesEntry { - uint32 ID; // 0 - uint32 SoundID; // 1 - uint32 Camera[8]; // 2-9 + uint16 SoundID; + uint16 Camera[8]; }; struct CreatureDisplayInfoEntry { - uint32 ID; // 0 - uint32 ModelID; // 1 - uint32 SoundID; // 2 - uint32 ExtendedDisplayInfoID; // 3 - float CreatureModelScale; // 4 - float PlayerModelScale; // 5 Used for players if greater than 0, see client's CGUnit_C::GetModelScale - uint32 CreatureModelAlpha; // 6 - LocalizedString* TextureVariation[3]; // 7-9 - LocalizedString* PortraitTextureName; // 10 - uint32 PortraitCreatureDisplayInfoID; // 11 - uint32 SizeClass; // 12 - uint32 BloodID; // 13 - uint32 NPCSoundID; // 14 - uint32 ParticleColorID; // 15 - uint32 CreatureGeosetData; // 16 - uint32 ObjectEffectPackageID; // 17 - uint32 AnimReplacementSetID; // 18 - uint32 Flags; // 19 - int32 Gender; // 20 - uint32 StateSpellVisualKitID; // 21 + uint32 ID; + uint32 ExtendedDisplayInfoID; + float CreatureModelScale; + float PlayerModelScale; + uint32 TextureVariation[3]; + char const* PortraitTextureName; + uint32 PortraitCreatureDisplayInfoID; + uint32 CreatureGeosetData; + uint32 StateSpellVisualKitID; + uint16 ModelID; + uint16 SoundID; + uint16 NPCSoundID; + uint16 ParticleColorID; + uint16 ObjectEffectPackageID; + uint16 AnimReplacementSetID; + uint8 CreatureModelAlpha; + uint8 SizeClass; + uint8 BloodID; + uint8 Flags; + int8 Gender; + int8 Unk700; +}; + +struct CreatureDisplayInfoExtraEntry +{ + uint32 NPCItemDisplay[10]; + uint32 FileDataID; + uint32 HDFileDataID; + uint8 DisplayRaceID; + uint8 DisplaySexID; + uint8 DisplayClassID; + uint8 SkinID; + uint8 FaceID; + uint8 HairStyleID; + uint8 HairColorID; + uint8 FacialHairID; + uint8 CustomDisplayOption[3]; + uint8 Flags; }; struct CreatureTypeEntry { - uint32 ID; // 0 - LocalizedString* Name; // 1 - uint32 Flags; // 2 no exp? critters, non-combat pets, gas cloud. + LocalizedString* Name; + uint8 Flags; // no exp? critters, non-combat pets, gas cloud. }; struct CriteriaEntry { - uint32 ID; // 0 - uint32 Type; // 1 union { uint32 ID; @@ -303,297 +367,319 @@ struct CriteriaEntry // CRITERIA_TYPE_COMPLETE_GARRISON_SHIPMENT = 182 uint32 CharShipmentContainerID; - } Asset; // 2 - uint32 StartEvent; // 3 - uint32 StartAsset; // 4 - uint32 StartTimer; // 5 - uint32 FailEvent; // 6 - uint32 FailAsset; // 7 - uint32 ModifierTreeId; // 8 - uint32 Flags; // 9 - uint32 EligibilityWorldStateID; // 10 - uint32 EligibilityWorldStateValue; // 11 + } Asset; + uint32 StartAsset; + uint32 FailAsset; + uint16 StartTimer; + uint16 ModifierTreeId; + uint16 EligibilityWorldStateID; + uint8 Type; + uint8 StartEvent; + uint8 FailEvent; + uint8 Flags; + uint8 EligibilityWorldStateValue; }; struct CriteriaTreeEntry { - uint32 ID; // 0 - uint32 CriteriaID; // 1 - uint64 Amount; // 2 - uint32 Operator; // 3 - uint32 Parent; // 4 - uint32 Flags; // 5 - LocalizedString* Description; // 6 - uint32 OrderIndex; // 7 + uint32 Amount; + LocalizedString* Description; + uint16 CriteriaID; + uint16 Parent; + uint16 Flags; + uint16 OrderIndex; + uint8 Operator; }; struct CurrencyTypesEntry { - uint32 ID; // 0 - uint32 CategoryID; // 1 - LocalizedString* Name; // 2 - LocalizedString* InventoryIcon[2]; // 3-4 - uint32 SpellWeight; // 5 - uint32 SpellCategory; // 6 - uint32 MaxQty; // 7 - uint32 MaxEarnablePerWeek; // 8 - uint32 Flags; // 9 - uint32 Quality; // 10 - LocalizedString* Description; // 11 + uint32 ID; + LocalizedString* Name; + char const* InventoryIcon[2]; + uint32 MaxQty; + uint32 MaxEarnablePerWeek; + uint32 Flags; + LocalizedString* Description; + uint8 CategoryID; + uint8 SpellWeight; + uint8 SpellCategory; + uint8 Quality; }; struct CurvePointEntry { - uint32 ID; // 0 - uint32 CurveID; // 1 - uint32 Index; // 2 - float X; // 3 - float Y; // 4 + float X; + float Y; + uint16 CurveID; + uint8 Index; }; struct DestructibleModelDataEntry { - uint32 ID; // 0 - struct - { - uint32 DisplayID; // 1 - uint32 ImpactEffectDoodadSet; // 2 - uint32 AmbientDoodadSet; // 3 - uint32 NameSet; // 4 - } StateDamaged; - struct - { - uint32 DisplayID; // 5 - uint32 DestructionDoodadSet; // 6 - uint32 ImpactEffectDoodadSet; // 7 - uint32 AmbientDoodadSet; // 8 - uint32 NameSet; // 9 - } StateDestroyed; - struct - { - uint32 DisplayID; // 10 - uint32 DestructionDoodadSet; // 11 - uint32 ImpactEffectDoodadSet; // 12 - uint32 AmbientDoodadSet; // 13 - uint32 NameSet; // 14 - } StateRebuilding; - struct - { - uint32 DisplayID; // 15 - uint32 InitDoodadSet; // 16 - uint32 AmbientDoodadSet; // 17 - uint32 NameSet; // 18 - } StateSmoke; - uint32 EjectDirection; // 19 - uint32 RepairGroundFx; // 20 - uint32 DoNotHighlight; // 21 - uint32 HealEffect; // 22 - uint32 HealEffectSpeed; // 23 + uint16 StateDamagedDisplayID; + uint16 StateDestroyedDisplayID; + uint16 StateRebuildingDisplayID; + uint16 StateSmokeDisplayID; + uint16 HealEffectSpeed; + uint8 StateDamagedImpactEffectDoodadSet; + uint8 StateDamagedAmbientDoodadSet; + uint8 StateDamagedNameSet; + uint8 StateDestroyedDestructionDoodadSet; + uint8 StateDestroyedImpactEffectDoodadSet; + uint8 StateDestroyedAmbientDoodadSet; + uint8 StateDestroyedNameSet; + uint8 StateRebuildingDestructionDoodadSet; + uint8 StateRebuildingImpactEffectDoodadSet; + uint8 StateRebuildingAmbientDoodadSet; + uint8 StateRebuildingNameSet; + uint8 StateSmokeInitDoodadSet; + uint8 StateSmokeAmbientDoodadSet; + uint8 StateSmokeNameSet; + uint8 EjectDirection; + uint8 DoNotHighlight; + uint8 HealEffect; +}; + +struct DurabilityCostsEntry +{ + uint16 WeaponSubClassCost[21]; + uint16 ArmorSubClassCost[8]; }; struct DurabilityQualityEntry { - uint32 ID; // 0 - float QualityMod; // 1 + float QualityMod; +}; + +struct EmotesTextSoundEntry +{ + uint16 EmotesTextId; + uint16 SoundId; + uint8 RaceId; + uint8 SexId; + uint8 ClassId; }; struct GameObjectsEntry { - uint32 ID; // 0 - uint32 MapID; // 1 - uint32 DisplayID; // 2 - DBCPosition3D Position; // 3-5 - float RotationX; // 6 - float RotationY; // 7 - float RotationZ; // 8 - float RotationW; // 9 - float Size; // 10 - uint32 PhaseUseFlags; // 11 - uint32 PhaseID; // 12 - uint32 PhaseGroupID; // 13 - uint32 Type; // 14 - uint32 Data[8]; // 15-22 - LocalizedString* Name; // 23 + uint32 ID; + DBCPosition3D Position; + float RotationX; + float RotationY; + float RotationZ; + float RotationW; + float Size; + int32 Data[8]; + LocalizedString* Name; + uint16 MapID; + uint16 DisplayID; + uint16 PhaseID; + uint16 PhaseGroupID; + uint8 PhaseUseFlags; + uint8 Type; +}; + +struct GameObjectDisplayInfoEntry +{ + uint32 FileDataID; + DBCPosition3D GeoBoxMin; + DBCPosition3D GeoBoxMax; + float OverrideLootEffectScale; + float OverrideNameScale; + uint16 Sound[10]; + uint16 ObjectEffectPackageID; }; struct GameTablesEntry { - uint32 ID; // 0 - LocalizedString* Name; // 1 - uint32 NumRows; // 2 - uint32 NumColumns; // 3 + LocalizedString* Name; + uint16 NumRows; + uint8 NumColumns; }; struct GarrAbilityEntry { - uint32 ID; // 0 - uint32 Flags; // 1 - LocalizedString* Name; // 2 - LocalizedString* Description; // 3 - uint32 IconFileDataID; // 4 - uint32 OtherFactionGarrAbilityID; // 5 - uint32 GarrAbilityCategoryID; // 6 - uint32 FollowerTypeID; // 7 + uint32 ID; + LocalizedString* Name; + LocalizedString* Description; + uint32 IconFileDataID; + uint16 OtherFactionGarrAbilityID; + uint8 Flags; + uint8 GarrAbilityCategoryID; + uint8 FollowerTypeID; }; struct GarrBuildingEntry { - uint32 ID; // 0 - uint32 HordeGameObjectID; // 1 - uint32 AllianceGameObjectID; // 2 - uint32 Unknown; // 3 - uint32 Type; // 4 - uint32 Level; // 5 - LocalizedString* NameAlliance; // 6 - LocalizedString* NameHorde; // 7 - LocalizedString* Description; // 8 - LocalizedString* Tooltip; // 9 - uint32 BuildDuration; // 10 - uint32 CostCurrencyID; // 11 - int32 CostCurrencyAmount; // 12 - uint32 HordeTexPrefixKitID; // 13 - uint32 AllianceTexPrefixKitID; // 14 - uint32 IconFileDataID; // 15 - uint32 BonusAmount; // 16 - uint32 Flags; // 17 - uint32 AllianceActivationScenePackageID; // 18 - uint32 HordeActivationScenePackageID; // 19 - uint32 MaxShipments; // 20 - uint32 FollowerRequiredGarrAbilityID; // 21 - uint32 FollowerGarrAbilityEffectID; // 22 - int32 CostMoney; // 23 + uint32 HordeGameObjectID; + uint32 AllianceGameObjectID; + LocalizedString* NameAlliance; + LocalizedString* NameHorde; + LocalizedString* Description; + LocalizedString* Tooltip; + uint32 IconFileDataID; + uint16 BuildDuration; + uint16 CostCurrencyID; + int16 CostCurrencyAmount; + uint16 AllianceActivationScenePackageID; + uint16 HordeActivationScenePackageID; + int16 CostMoney; + uint8 Unknown; + uint8 Type; + uint8 Level; + uint8 HordeTexPrefixKitID; + uint8 AllianceTexPrefixKitID; + uint8 BonusAmount; + uint8 Flags; + uint8 MaxShipments; + uint8 FollowerRequiredGarrAbilityID; + uint8 FollowerGarrAbilityEffectID; + uint8 GarrTypeID; }; struct GarrBuildingPlotInstEntry { - uint32 ID; // 0 - uint32 GarrBuildingID; // 1 - uint32 UiTextureAtlasMemberID; // 2 - uint32 GarrSiteLevelPlotInstID; // 3 - DBCPosition2D LandmarkOffset; // 4-5 + uint32 ID; + DBCPosition2D LandmarkOffset; + uint16 UiTextureAtlasMemberID; + uint16 GarrSiteLevelPlotInstID; + uint8 GarrBuildingID; }; struct GarrClassSpecEntry { - uint32 ID; // 0 - LocalizedString* NameMale; // 1 - LocalizedString* NameFemale; // 2 - LocalizedString* NameGenderless; // 3 - uint32 ClassAtlasID; // 4 UiTextureAtlasMember.db2 ref - uint32 GarrFollItemSetID; // 5 + uint32 ID; + LocalizedString* NameMale; + LocalizedString* NameFemale; + LocalizedString* NameGenderless; + uint16 ClassAtlasID; // UiTextureAtlasMember.db2 ref + uint8 GarrFollItemSetID; }; struct GarrFollowerEntry { - uint32 ID; // 0 - uint32 FollowerTypeID; // 1 - uint32 HordeCreatureID; // 2 - uint32 AllianceCreatureID; // 3 - uint32 HordeUiAnimRaceInfoID; // 4 - uint32 AllianceUiAnimRaceInfoID; // 5 - uint32 Quality; // 6 - uint32 HordeGarrClassSpecID; // 7 - uint32 AllianceGarrClassSpecID; // 8 - uint32 HordeGarrFollItemSetID; // 9 - uint32 AllianceGarrFollItemSetID; // 10 - uint32 Level; // 11 - uint32 ItemLevelWeapon; // 12 - uint32 ItemLevelArmor; // 13 - uint32 Unknown1; // 14 - uint32 Flags; // 15 - LocalizedString* HordeSourceText; // 16 - LocalizedString* AllianceSourceText; // 17 - int32 Unknown2; // 18 - int32 Unknown3; // 19 - uint32 HordePortraitIconID; // 20 - uint32 AlliancePortraitIconID; // 21 - uint32 HordeListPortraitTextureKitID; // 22 - uint32 AllianceListPortraitTextureKitID; // 23 + uint32 HordeCreatureID; + uint32 AllianceCreatureID; + LocalizedString* HordeSourceText; + LocalizedString* AllianceSourceText; + uint32 HordePortraitIconID; + uint32 AlliancePortraitIconID; + uint16 ItemLevelWeapon; + uint16 ItemLevelArmor; + uint8 FollowerTypeID; + uint8 HordeUiAnimRaceInfoID; + uint8 AllianceUiAnimRaceInfoID; + uint8 Quality; + uint8 HordeGarrClassSpecID; + uint8 AllianceGarrClassSpecID; + uint8 HordeGarrFollItemSetID; + uint8 AllianceGarrFollItemSetID; + uint8 Level; + uint8 Unknown1; + uint8 Flags; + int8 Unknown2; + int8 Unknown3; + uint8 HordeListPortraitTextureKitID; + uint8 AllianceListPortraitTextureKitID; + uint8 GarrTypeID; }; struct GarrFollowerXAbilityEntry { - uint32 ID; // 0 - uint32 GarrFollowerID; // 1 - uint32 GarrAbilityID; // 2 - uint32 FactionIndex; // 3 + uint16 GarrFollowerID; + uint16 GarrAbilityID; + uint8 FactionIndex; }; struct GarrPlotEntry { - uint32 ID; // 0 - uint32 GarrPlotUICategoryID; // 1 - uint32 PlotType; // 2 - uint32 Flags; // 3 - LocalizedString* Name; // 4 - uint32 MinCount; // 5 - uint32 MaxCount; // 6 - uint32 AllianceConstructionGameObjectID; // 7 - uint32 HordeConstructionGameObjectID; // 8 + LocalizedString* Name; + uint32 AllianceConstructionGameObjectID; + uint32 HordeConstructionGameObjectID; + uint8 GarrPlotUICategoryID; + uint8 PlotType; + uint8 Flags; + uint8 MinCount; + uint8 MaxCount; }; struct GarrPlotBuildingEntry { - uint32 ID; // 0 - uint32 GarrPlotID; // 1 - uint32 GarrBuildingID; // 2 + uint8 GarrPlotID; + uint8 GarrBuildingID; }; struct GarrPlotInstanceEntry { - uint32 ID; // 0 - uint32 GarrPlotID; // 1 - LocalizedString* Name; // 2 + LocalizedString* Name; + uint8 GarrPlotID; }; struct GarrSiteLevelEntry { - uint32 ID; // 0 - uint32 Level; // 1 - uint32 MapID; // 2 - uint32 SiteID; // 3 - uint32 UITextureKitID; // 4 - DBCPosition2D TownHall; // 5-6 - uint32 MovieID; // 7 - uint32 Level2; // 8 - uint32 UpgradeResourceCost; // 9 - uint32 UpgradeMoneyCost; // 10 + DBCPosition2D TownHall; + uint16 MapID; + uint16 UpgradeResourceCost; + uint16 UpgradeMoneyCost; + uint8 Level; + uint8 SiteID; + uint8 UITextureKitID; + uint8 MovieID; + uint8 Level2; }; struct GarrSiteLevelPlotInstEntry { - uint32 ID; // 0 - uint32 GarrSiteLevelID; // 1 - uint32 GarrPlotInstanceID; // 2 - DBCPosition2D Landmark; // 3-4 - uint32 Unknown; // 5 + DBCPosition2D Landmark; + uint16 GarrSiteLevelID; + uint8 GarrPlotInstanceID; + uint8 Unknown; }; struct GlyphSlotEntry { - uint32 ID; // 0 - uint32 Type; // 1 - uint32 Tooltip; // 2 + uint8 Type; + uint8 Tooltip; +}; + +struct GuildColorBackgroundEntry +{ + uint8 Red; + uint8 Green; + uint8 Blue; +}; + +struct GuildColorBorderEntry +{ + uint8 Red; + uint8 Green; + uint8 Blue; +}; + +struct GuildColorEmblemEntry +{ + uint8 Red; + uint8 Green; + uint8 Blue; }; struct GuildPerkSpellsEntry { - uint32 ID; // 0 - uint32 GuildLevel; // 1 - uint32 SpellID; // 2 + uint32 SpellID; + uint8 GuildLevel; }; struct HeirloomEntry { - uint32 ID; // 0 - uint32 ItemID; // 1 - uint32 Flags; // 2 - LocalizedString* SourceText; // 3 - uint32 Source; // 4 - uint32 OldItem[2]; // 5-6 - uint32 NextDifficultyItemID; // 7 - uint32 UpgradeItemID[2]; // 8-9 - uint32 ItemBonusListID[2]; // 10-11 + uint32 ID; + uint32 ItemID; + LocalizedString* SourceText; + uint32 OldItem[2]; + uint32 NextDifficultyItemID; + uint32 UpgradeItemID[2]; + uint16 ItemBonusListID[2]; + uint8 Flags; + uint8 Source; }; #define MAX_HOLIDAY_DURATIONS 10 @@ -602,122 +688,164 @@ struct HeirloomEntry struct HolidaysEntry { - uint32 ID; // 0 - uint32 Duration[MAX_HOLIDAY_DURATIONS]; // 1-10 - uint32 Date[MAX_HOLIDAY_DATES]; // 11-26 (dates in unix time starting at January, 1, 2000) - uint32 Region; // 27 - uint32 Looping; // 28 - uint32 CalendarFlags[MAX_HOLIDAY_FLAGS]; // 29-38 - uint32 HolidayNameID; // 39 HolidayNames.dbc - uint32 HolidayDescriptionID; // 40 HolidayDescriptions.dbc - LocalizedString* TextureFilename; // 41 - uint32 Priority; // 42 - uint32 CalendarFilterType; // 43 (-1 = Fishing Contest, 0 = Unk, 1 = Darkmoon Festival, 2 = Yearly holiday) - uint32 Flags; // 44 (0 = Darkmoon Faire, Fishing Contest and Wotlk Launch, rest is 1) + uint32 Date[MAX_HOLIDAY_DATES]; // dates in unix time starting at January, 1, 2000 + char const* TextureFilename; + uint16 Duration[MAX_HOLIDAY_DURATIONS]; + uint16 Region; + uint8 Looping; + uint8 CalendarFlags[MAX_HOLIDAY_FLAGS]; + uint8 HolidayNameID; + uint8 HolidayDescriptionID; + uint8 Priority; + int8 CalendarFilterType; + uint8 Flags; }; struct ImportPriceArmorEntry { - uint32 ID; // 0 - float ClothFactor; // 1 - float LeatherFactor; // 2 - float MailFactor; // 3 - float PlateFactor; // 4 + float ClothFactor; + float LeatherFactor; + float MailFactor; + float PlateFactor; }; struct ImportPriceQualityEntry { - uint32 ID; // 0 - float Factor; // 1 + float Factor; }; struct ImportPriceShieldEntry { - uint32 ID; // 0 - float Factor; // 1 + float Factor; }; struct ImportPriceWeaponEntry { - uint32 ID; // 0 - float Factor; // 1 + float Factor; +}; + +struct ItemEntry +{ + uint32 FileDataID; + uint8 Class; + uint8 SubClass; + int8 SoundOverrideSubclass; + int8 Material; + uint8 InventoryType; + uint8 Sheath; + uint8 GroupSoundsID; }; struct ItemAppearanceEntry { - uint32 ID; // 0 - uint32 DisplayID; // 1 - uint32 IconFileDataID; // 2 + uint32 DisplayID; + uint32 IconFileDataID; + uint8 ObjectComponentSlot; +}; + +struct ItemArmorQualityEntry +{ + float QualityMod[7]; + uint16 ItemLevel; +}; + +struct ItemArmorShieldEntry +{ + float Quality[7]; + uint16 ItemLevel; +}; + +struct ItemArmorTotalEntry +{ + float Value[4]; + uint16 ItemLevel; +}; + +struct ItemBagFamilyEntry +{ + LocalizedString* Name; }; struct ItemBonusEntry { - uint32 ID; // 0 - uint32 BonusListID; // 1 - uint32 Type; // 2 - int32 Value[2]; // 3-4 - uint32 Index; // 5 + uint32 ID; + int32 Value[2]; + uint16 BonusListID; + uint8 Type; + uint8 Index; }; struct ItemBonusTreeNodeEntry { - uint32 ID; // 0 - uint32 BonusTreeID; // 1 - uint32 BonusTreeModID; // 2 - uint32 SubTreeID; // 3 - uint32 BonusListID; // 4 + uint16 BonusTreeID; + uint16 SubTreeID; + uint16 BonusListID; + uint8 BonusTreeModID; }; struct ItemClassEntry { - uint32 ID; // 0 - uint32 Flags; // 1 - float PriceMod; // 2 - LocalizedString* Name; // 3 + float PriceMod; + LocalizedString* Name; + uint8 Flags; }; struct ItemCurrencyCostEntry { - uint32 ID; // 0 - uint32 ItemId; // 1 + uint32 ItemId; }; -struct ItemDisenchantLootEntry +struct ItemDamageAmmoEntry { - uint32 ID; // 0 - uint32 ItemClass; // 1 - int32 ItemSubClass; // 2 - uint32 ItemQuality; // 3 - uint32 MinItemLevel; // 4 - uint32 MaxItemLevel; // 5 - uint32 RequiredDisenchantSkill; // 6 + float DPS[7]; + uint16 ItemLevel; }; -struct ItemEffectEntry +struct ItemDamageOneHandEntry { - uint32 ID; // 0 - uint32 ItemID; // 1 - uint32 OrderIndex; // 2 - uint32 SpellID; // 3 - uint32 Trigger; // 4 - int32 Charges; // 5 - int32 Cooldown; // 6 - uint32 Category; // 7 - int32 CategoryCooldown; // 8 - uint32 ChrSpecializationID; // 9 + float DPS[7]; + uint16 ItemLevel; }; -struct ItemEntry +struct ItemDamageOneHandCasterEntry +{ + float DPS[7]; + uint16 ItemLevel; +}; + +struct ItemDamageTwoHandEntry +{ + float DPS[7]; + uint16 ItemLevel; +}; + +struct ItemDamageTwoHandCasterEntry +{ + float DPS[7]; + uint16 ItemLevel; +}; + +struct ItemDisenchantLootEntry +{ + uint16 MinItemLevel; + uint16 MaxItemLevel; + uint16 RequiredDisenchantSkill; + uint8 ItemClass; + int8 ItemSubClass; + uint8 ItemQuality; +}; + +struct ItemEffectEntry { - uint32 ID; // 0 - uint32 Class; // 1 - uint32 SubClass; // 2 - int32 SoundOverrideSubclass; // 3 - int32 Material; // 4 - uint32 InventoryType; // 5 - uint32 Sheath; // 6 - uint32 FileDataID; // 7 - uint32 GroupSoundsID; // 8 + uint32 ItemID; + uint32 SpellID; + int32 Cooldown; + int32 CategoryCooldown; + int16 Charges; + uint16 Category; + uint16 ChrSpecializationID; + uint8 OrderIndex; + uint8 Trigger; }; #define MAX_ITEM_EXT_COST_ITEMS 5 @@ -725,64 +853,64 @@ struct ItemEntry struct ItemExtendedCostEntry { - uint32 ID; // 0 extended-cost entry id - uint32 RequiredArenaSlot; // 3 arena slot restrictions (min slot value) - uint32 RequiredItem[MAX_ITEM_EXT_COST_ITEMS]; // 3-6 required item id - uint32 RequiredItemCount[MAX_ITEM_EXT_COST_ITEMS]; // 7-11 required count of 1st item - uint32 RequiredPersonalArenaRating; // 12 required personal arena rating - uint32 ItemPurchaseGroup; // 13 - uint32 RequiredCurrency[MAX_ITEM_EXT_COST_CURRENCIES]; // 14-18 required curency id - uint32 RequiredCurrencyCount[MAX_ITEM_EXT_COST_CURRENCIES]; // 19-23 required curency count - uint32 RequiredFactionId; // 24 - uint32 RequiredFactionStanding; // 25 - uint32 RequirementFlags; // 26 - uint32 RequiredAchievement; // 27 - uint32 RequiredMoney; // 28 + uint32 RequiredItem[MAX_ITEM_EXT_COST_ITEMS]; // required item id + uint32 RequiredCurrencyCount[MAX_ITEM_EXT_COST_CURRENCIES]; // required curency count + uint32 RequiredMoney; + uint16 RequiredItemCount[MAX_ITEM_EXT_COST_ITEMS]; // required count of 1st item + uint16 RequiredPersonalArenaRating; // required personal arena rating + uint16 RequiredCurrency[MAX_ITEM_EXT_COST_CURRENCIES]; // required curency id + uint8 RequiredArenaSlot; // arena slot restrictions (min slot value) + uint8 RequiredFactionId; + uint8 RequiredFactionStanding; + uint8 RequirementFlags; + uint8 RequiredAchievement; }; struct ItemLimitCategoryEntry { - uint32 ID; // 0 - LocalizedString* Name; // 1 - uint32 Quantity; // 2 - uint32 Flags; // 3 + LocalizedString* Name; + uint8 Quantity; + uint8 Flags; }; struct ItemModifiedAppearanceEntry { - uint32 ID; // 0 - uint32 ItemID; // 1 - uint32 AppearanceModID; // 2 - uint32 AppearanceID; // 3 - uint32 IconFileDataID; // 4 - uint32 Index; // 5 + uint32 ID; + uint32 ItemID; + uint16 AppearanceID; + uint8 AppearanceModID; + uint8 Index; }; struct ItemPriceBaseEntry { - uint32 ID; // 0 - uint32 ItemLevel; // 1 Item level (1 - 1000) - float ArmorFactor; // 2 Price factor for armor - float WeaponFactor; // 3 Price factor for weapons + float ArmorFactor; + float WeaponFactor; + uint16 ItemLevel; }; #define MAX_ITEM_RANDOM_PROPERTIES 5 struct ItemRandomPropertiesEntry { - uint32 ID; // 0 - LocalizedString* InternalName; // 1 - uint32 Enchantment[MAX_ITEM_RANDOM_PROPERTIES]; // 2-6 - LocalizedString* Name; // 7 + LocalizedString* Name; + uint16 Enchantment[MAX_ITEM_RANDOM_PROPERTIES]; }; struct ItemRandomSuffixEntry { - uint32 ID; // 0 - LocalizedString* Name; // 1 - LocalizedString* InternalName; // 2 - uint32 Enchantment[MAX_ITEM_RANDOM_PROPERTIES]; // 3-7 - uint32 AllocationPct[MAX_ITEM_RANDOM_PROPERTIES]; // 8-12 + LocalizedString* Name; + LocalizedString* InternalName; + uint16 Enchantment[MAX_ITEM_RANDOM_PROPERTIES]; + uint16 AllocationPct[MAX_ITEM_RANDOM_PROPERTIES]; +}; + +struct ItemSetSpellEntry +{ + uint32 SpellID; + uint16 ItemSetID; + uint16 ChrSpecID; + uint8 Threshold; }; #define MAX_ITEM_PROTO_FLAGS 3 @@ -791,474 +919,650 @@ struct ItemRandomSuffixEntry struct ItemSparseEntry { - uint32 ID; // 0 - uint32 Quality; // 1 - uint32 Flags[MAX_ITEM_PROTO_FLAGS]; // 2-4 - float Unk1; // 5 - float Unk2; // 6 - uint32 BuyCount; // 7 - uint32 BuyPrice; // 8 - uint32 SellPrice; // 9 - uint32 InventoryType; // 10 - int32 AllowableClass; // 11 - int32 AllowableRace; // 12 - uint32 ItemLevel; // 13 - int32 RequiredLevel; // 14 - uint32 RequiredSkill; // 15 - uint32 RequiredSkillRank; // 16 - uint32 RequiredSpell; // 17 - uint32 RequiredHonorRank; // 18 - uint32 RequiredCityRank; // 19 - uint32 RequiredReputationFaction; // 20 - uint32 RequiredReputationRank; // 21 - uint32 MaxCount; // 22 - uint32 Stackable; // 23 - uint32 ContainerSlots; // 24 - int32 ItemStatType[MAX_ITEM_PROTO_STATS]; // 25 - 34 - int32 ItemStatValue[MAX_ITEM_PROTO_STATS]; // 35 - 44 - int32 ItemStatAllocation[MAX_ITEM_PROTO_STATS]; // 45 - 54 - float ItemStatSocketCostMultiplier[MAX_ITEM_PROTO_STATS]; // 55 - 64 - uint32 ScalingStatDistribution; // 65 - uint32 DamageType; // 66 - uint32 Delay; // 67 - float RangedModRange; // 68 - uint32 Bonding; // 69 - LocalizedString* Name; // 70 - LocalizedString* Name2; // 71 - LocalizedString* Name3; // 72 - LocalizedString* Name4; // 73 - LocalizedString* Description; // 74 - uint32 PageText; // 75 - uint32 LanguageID; // 76 - uint32 PageMaterial; // 77 - uint32 StartQuest; // 78 - uint32 LockID; // 79 - int32 Material; // 80 - uint32 Sheath; // 81 - uint32 RandomProperty; // 82 - uint32 RandomSuffix; // 83 - uint32 ItemSet; // 84 - uint32 Area; // 85 - uint32 Map; // 86 - uint32 BagFamily; // 87 - uint32 TotemCategory; // 88 - uint32 SocketColor[MAX_ITEM_PROTO_SOCKETS]; // 89-91 - uint32 SocketBonus; // 92 - uint32 GemProperties; // 93 - float ArmorDamageModifier; // 94 - uint32 Duration; // 95 - uint32 ItemLimitCategory; // 96 - uint32 HolidayID; // 97 - float StatScalingFactor; // 98 - uint32 CurrencySubstitutionID; // 99 - uint32 CurrencySubstitutionCount; // 100 - uint32 ItemNameDescriptionID; // 101 + uint32 Flags[MAX_ITEM_PROTO_FLAGS]; + float Unk1; + float Unk2; + uint32 BuyPrice; + uint32 SellPrice; + int32 AllowableClass; + int32 AllowableRace; + uint32 RequiredSpell; + uint32 MaxCount; + uint32 Stackable; + int32 ItemStatAllocation[MAX_ITEM_PROTO_STATS]; + float ItemStatSocketCostMultiplier[MAX_ITEM_PROTO_STATS]; + float RangedModRange; + LocalizedString* Name; + LocalizedString* Name2; + LocalizedString* Name3; + LocalizedString* Name4; + LocalizedString* Description; + uint32 BagFamily; + float ArmorDamageModifier; + uint32 Duration; + float StatScalingFactor; + uint16 ItemLevel; + uint16 RequiredSkill; + uint16 RequiredSkillRank; + uint16 RequiredReputationFaction; + int16 ItemStatValue[MAX_ITEM_PROTO_STATS]; + uint16 ScalingStatDistribution; + uint16 Delay; + uint16 PageText; + uint16 StartQuest; + uint16 LockID; + uint16 RandomProperty; + uint16 RandomSuffix; + uint16 ItemSet; + uint16 Area; + uint16 Map; + uint16 SocketBonus; + uint16 GemProperties; + uint16 ItemLimitCategory; + uint16 HolidayID; + uint16 ItemNameDescriptionID; + uint8 Quality; + uint8 BuyCount; + uint8 InventoryType; + int8 RequiredLevel; + uint8 RequiredHonorRank; + uint8 RequiredCityRank; + uint8 RequiredReputationRank; + uint8 ContainerSlots; + int8 ItemStatType[MAX_ITEM_PROTO_STATS]; + uint8 DamageType; + uint8 Bonding; + uint8 LanguageID; + uint8 PageMaterial; + int8 Material; + uint8 Sheath; + uint8 TotemCategory; + uint8 SocketColor[MAX_ITEM_PROTO_SOCKETS]; + uint8 CurrencySubstitutionID; + uint8 CurrencySubstitutionCount; + uint8 ArtifactID; }; struct ItemSpecEntry { - uint32 ID; // 0 - uint32 MinLevel; // 1 - uint32 MaxLevel; // 2 - uint32 ItemType; // 3 - uint32 PrimaryStat; // 4 - uint32 SecondaryStat; // 5 - uint32 SpecID; // 6 + uint16 SpecID; + uint8 MinLevel; + uint8 MaxLevel; + uint8 ItemType; + uint8 PrimaryStat; + uint8 SecondaryStat; }; struct ItemSpecOverrideEntry { - uint32 ID; // 0 - uint32 ItemID; // 1 - uint32 SpecID; // 2 + uint32 ItemID; + uint16 SpecID; }; struct ItemToBattlePetSpeciesEntry { - uint32 ID; // 0 - uint32 BattlePetSpeciesID; // 1 + uint16 BattlePetSpeciesID; }; struct ItemXBonusTreeEntry { - uint32 ID; // 0 - uint32 ItemID; // 1 - uint32 BonusTreeID; // 2 + uint32 ItemID; + uint16 BonusTreeID; }; #define KEYCHAIN_SIZE 32 struct KeyChainEntry { - uint32 Id; - uint8 Key[KEYCHAIN_SIZE]; + uint8 Key[KEYCHAIN_SIZE]; }; struct MailTemplateEntry { - uint32 ID; // 0 - LocalizedString* Body; // 1 + LocalizedString* Body; }; struct ModifierTreeEntry { - uint32 ID; // 0 - uint32 Type; // 1 - uint32 Asset[2]; // 2-3 - uint32 Operator; // 4 - uint32 Amount; // 5 - uint32 Parent; // 6 + uint32 Asset[2]; + uint16 Parent; + uint8 Type; + uint8 Unk700; + uint8 Operator; + uint8 Amount; }; struct MountEntry { - uint32 Id; + uint32 ID; uint32 SpellId; - uint32 MountTypeId; uint32 DisplayId; - uint32 Flags; LocalizedString* Name; LocalizedString* Description; LocalizedString* SourceDescription; - uint32 Source; - uint32 PlayerConditionId; + uint16 MountTypeId; + uint16 Flags; + uint16 PlayerConditionId; + uint8 Source; }; struct MountCapabilityEntry { - uint32 ID; // 0 - uint32 Flags; // 1 - uint32 RequiredRidingSkill; // 2 - uint32 RequiredArea; // 3 - uint32 RequiredAura; // 4 - uint32 RequiredSpell; // 5 - uint32 SpeedModSpell; // 6 - int32 RequiredMap; // 7 + uint32 ID; + uint32 RequiredSpell; + uint32 SpeedModSpell; + uint16 RequiredRidingSkill; + uint16 RequiredArea; + int16 RequiredMap; + uint8 Flags; + uint8 RequiredAura; }; struct MountTypeXCapabilityEntry { - uint32 ID; // 0 - uint32 MountTypeID; // 1 - uint32 OrderIndex; // 2 - uint32 MountCapabilityID; // 3 + uint16 MountTypeID; + uint16 MountCapabilityID; + uint8 OrderIndex; +}; + +struct MovieEntry +{ + uint32 AudioFileDataID; + uint32 SubtitleFileDataID; + uint8 Volume; + uint8 KeyID; }; struct NameGenEntry { - uint32 ID; // 0 - LocalizedString* Name; // 1 - uint32 Race; // 2 - uint32 Sex; // 3 + LocalizedString* Name; + uint8 Race; + uint8 Sex; }; struct NamesProfanityEntry { - uint32 ID; // 0 - char const* Name; // 1 - int32 Language; // 2 + char const* Name; + int8 Language; }; struct NamesReservedEntry { - uint32 ID; // 0 - char const* Name; // 1 + char const* Name; }; struct NamesReservedLocaleEntry { - uint32 ID; // 0 - char const* Name; // 1 - uint32 LocaleMask; // 2 + char const* Name; + uint8 LocaleMask; }; #define MAX_OVERRIDE_SPELL 10 struct OverrideSpellDataEntry { - uint32 ID; // 0 - uint32 SpellID[MAX_OVERRIDE_SPELL]; // 1-10 - uint32 Flags; // 11 - uint32 PlayerActionbarFileDataID; // 12 + uint32 SpellID[MAX_OVERRIDE_SPELL]; + uint32 PlayerActionbarFileDataID; + uint8 Flags; }; struct PhaseXPhaseGroupEntry { - uint32 ID; - uint32 PhaseID; - uint32 PhaseGroupID; + uint16 PhaseID; + uint16 PhaseGroupID; }; struct PlayerConditionEntry { - uint32 ID; // 0 - uint32 Flags; // 1 - uint32 MinLevel; // 2 - uint32 MaxLevel; // 3 - uint32 RaceMask; // 4 - uint32 ClassMask; // 5 - int32 Gender; // 6 - int32 NativeGender; // 7 - uint32 SkillID[4]; // 8-11 - int32 MinSkill[4]; // 12-15 - int32 MaxSkill[4]; // 16-19 - uint32 SkillLogic; // 20 - uint32 LanguageID; // 21 - uint32 MinLanguage; // 22 - uint32 MaxLanguage; // 23 - uint32 MinFactionID[3]; // 24-26 - uint32 MaxFactionID; // 27 - uint32 MinReputation[3]; // 28-30 - uint32 MaxReputation; // 31 - uint32 ReputationLogic; // 32 - uint32 Unknown1; // 33 - uint32 MinPVPRank; // 34 - uint32 MaxPVPRank; // 35 - uint32 PvpMedal; // 36 - uint32 PrevQuestLogic; // 37 - uint32 PrevQuestID[4]; // 38-41 - uint32 CurrQuestLogic; // 42 - uint32 CurrQuestID[4]; // 43-46 - uint32 CurrentCompletedQuestLogic; // 47 - uint32 CurrentCompletedQuestID[4]; // 48-51 - uint32 SpellLogic; // 52 - uint32 SpellID[4]; // 53-56 - uint32 ItemLogic; // 57 - uint32 ItemID[4]; // 58-61 - uint32 ItemCount[4]; // 62-65 - uint32 ItemFlags; // 66 - uint32 Explored[2]; // 67-68 - uint32 Time[2]; // 69-70 - uint32 AuraSpellLogic; // 71 - uint32 AuraSpellID[4]; // 72-75 - uint32 WorldStateExpressionID; // 76 - uint32 WeatherID; // 77 - uint32 PartyStatus; // 78 - uint32 LifetimeMaxPVPRank; // 79 - uint32 AchievementLogic; // 80 - uint32 Achievement[4]; // 81-84 - uint32 LfgLogic; // 85 - uint32 LfgStatus[4]; // 86-89 - uint32 LfgCompare[4]; // 90-93 - uint32 LfgValue[4]; // 94-97 - uint32 AreaLogic; // 98 - uint32 AreaID[4]; // 99-102 - uint32 CurrencyLogic; // 103 - uint32 CurrencyID[4]; // 104-107 - uint32 CurrencyCount[4]; // 108-111 - uint32 QuestKillID; // 112 - uint32 QuestKillLogic; // 113 - uint32 QuestKillMonster[4]; // 114-117 - int32 MinExpansionLevel; // 118 - int32 MaxExpansionLevel; // 119 - int32 MinExpansionTier; // 120 - int32 MaxExpansionTier; // 121 - uint32 MinGuildLevel; // 122 - uint32 MaxGuildLevel; // 123 - uint32 PhaseUseFlags; // 124 - uint32 PhaseID; // 125 - uint32 PhaseGroupID; // 126 - uint32 MinAvgItemLevel; // 127 - uint32 MaxAvgItemLevel; // 128 - uint32 MinAvgEquippedItemLevel; // 129 - uint32 MaxAvgEquippedItemLevel; // 130 - int32 ChrSpecializationIndex; // 131 - int32 ChrSpecializationRole; // 132 - LocalizedString* FailureDescription_lang; // 133 - int32 PowerType; // 134 - int32 PowerTypeComp; // 135 - int32 PowerTypeValue; // 136 + uint32 RaceMask; + uint32 SkillLogic; + uint32 ReputationLogic; + uint32 PrevQuestLogic; + uint32 CurrQuestLogic; + uint32 CurrentCompletedQuestLogic; + uint32 SpellLogic; + uint32 SpellID[4]; + uint32 ItemLogic; + uint32 ItemID[4]; + uint32 Time[2]; + uint32 AuraSpellLogic; + uint32 AuraSpellID[4]; + uint32 AchievementLogic; + uint32 AreaLogic; + uint32 QuestKillLogic; + uint32 QuestKillMonster[6]; + LocalizedString* FailureDescription; + uint32 Unknown700_1; + uint32 Unknown700_2; + uint16 MinLevel; + uint16 MaxLevel; + uint16 ClassMask; + uint16 SkillID[4]; + int16 MinSkill[4]; + int16 MaxSkill[4]; + uint16 MinFactionID[3]; + uint16 MaxFactionID; + uint16 PrevQuestID[4]; + uint16 CurrQuestID[4]; + uint16 CurrentCompletedQuestID[4]; + uint16 Explored[2]; + uint16 WorldStateExpressionID; + uint16 Achievement[4]; + uint16 AreaID[4]; + uint16 QuestKillID; + uint16 PhaseID; + uint16 MinAvgItemLevel; + uint16 MaxAvgItemLevel; + uint16 MinAvgEquippedItemLevel; + uint16 MaxAvgEquippedItemLevel; + uint16 ModifierTreeID; + uint8 Flags; + int8 Gender; + int8 NativeGender; + uint8 LanguageID; + uint8 MinLanguage; + uint8 MaxLanguage; + uint8 MinReputation[3]; + uint8 MaxReputation; + uint8 Unknown1; + uint8 MinPVPRank; + uint8 MaxPVPRank; + uint8 PvpMedal; + uint8 ItemCount[4]; + uint8 ItemFlags; + uint8 AuraCount[4]; + uint8 WeatherID; + uint8 PartyStatus; + uint8 LifetimeMaxPVPRank; + uint8 LfgLogic; + uint8 LfgStatus[4]; + uint8 LfgCompare[4]; + uint8 LfgValue[4]; + uint8 CurrencyLogic; + uint8 CurrencyID[4]; + uint8 CurrencyCount[4]; + int8 MinExpansionLevel; + int8 MaxExpansionLevel; + int8 MinExpansionTier; + int8 MaxExpansionTier; + uint8 MinGuildLevel; + uint8 MaxGuildLevel; + uint8 PhaseUseFlags; + uint8 PhaseGroupID; + int8 ChrSpecializationIndex; + int8 ChrSpecializationRole; + int8 PowerType; + int8 PowerTypeComp; + int8 PowerTypeValue; +}; + +struct PowerDisplayEntry +{ + char const* GlobalStringBaseTag; + uint8 PowerType; + uint8 Red; + uint8 Green; + uint8 Blue; +}; + +struct QuestFactionRewardEntry +{ + int16 QuestRewFactionValue[10]; }; struct QuestMoneyRewardEntry { - uint32 Level; // 0 - uint32 Money[10]; // 1 + uint32 Money[10]; }; struct QuestPackageItemEntry { - uint32 ID; // 0 - uint32 QuestPackageID; // 1 - uint32 ItemID; // 2 - uint32 ItemCount; // 3 - uint32 FilterType; // 4 + uint32 ItemID; + uint16 QuestPackageID; + uint8 ItemCount; + uint8 FilterType; }; struct QuestSortEntry { - uint32 ID; // 0 - LocalizedString* SortName; // 1 + LocalizedString* SortName; }; struct QuestV2Entry { - uint32 ID; // 0 - uint32 UniqueBitFlag; // 1 + uint16 UniqueBitFlag; }; struct QuestXPEntry { - uint32 ID; // 0 - uint32 Exp[10]; // 1 + uint16 Exp[10]; +}; + +struct RandPropPointsEntry +{ + uint16 EpicPropertiesPoints[5]; + uint16 RarePropertiesPoints[5]; + uint16 UncommonPropertiesPoints[5]; }; struct ScalingStatDistributionEntry { - uint32 ID; // 0 - uint32 MinLevel; // 1 - uint32 MaxLevel; // 2 - uint32 ItemLevelCurveID; // 3 -}; - -struct SoundEntriesEntry -{ - uint32 ID; // 0 - uint32 SoundType; // 1 - LocalizedString* Name; // 2 - uint32 FileDataID[20]; // 3-22 - uint32 Freq[20]; // 23-42 - float VolumeFloat; // 43 - uint32 Flags; // 44 - float MinDistance; // 45 - float DistanceCutoff; // 46 - uint32 EAXDef; // 47 - uint32 SoundEntriesAdvancedID; // 48 - float VolumeVariationPlus; // 49 - float VolumeVariationMinus; // 50 - float PitchVariationPlus; // 51 - float PitchVariationMinus; // 52 - float PitchAdjust; // 53 - uint32 DialogType; // 54 - uint32 BusOverwriteID; // 55 + uint16 ItemLevelCurveID; + uint8 MinLevel; + uint8 MaxLevel; +}; + +struct SkillLineEntry +{ + LocalizedString* DisplayName; + LocalizedString* Description; + LocalizedString* AlternateVerb; + uint16 SpellIconID; + uint16 Flags; + uint8 CategoryID; + uint8 CanLink; + uint8 ParentSkillLineID; +}; + +struct SkillLineAbilityEntry +{ + uint32 SpellID; + uint32 RaceMask; + uint32 ClassMask; + uint32 SupercedesSpell; + uint16 SkillLine; + uint16 MinSkillLineRank; + uint16 TrivialSkillLineRankHigh; + uint16 TrivialSkillLineRankLow; + uint16 UniqueBit; + uint16 TradeSkillCategoryID; + uint8 AquireMethod; + uint8 NumSkillUps; +}; + +struct SkillRaceClassInfoEntry +{ + int32 RaceMask; + uint16 SkillID; + int16 ClassMask; + uint16 Flags; + uint16 SkillTierID; + uint8 Availability; + uint8 MinLevel; +}; + +struct SoundKitEntry +{ + uint32 ID; + uint8 SoundType; + LocalizedString* Name; + float VolumeFloat; + float MinDistance; + float DistanceCutoff; + float VolumeVariationPlus; + float VolumeVariationMinus; + float PitchVariationPlus; + float PitchVariationMinus; + float PitchAdjust; + uint16 Flags; + uint16 SoundEntriesAdvancedID; + uint8 EAXDef; + uint8 DialogType; + uint8 BusOverwriteID; + uint8 Unk700; }; struct SpecializationSpellsEntry { - uint32 ID; // 0 - uint32 SpecID; // 1 - uint32 OrderIndex; // 2 - uint32 SpellID; // 3 - uint32 OverridesSpellID; // 4 - LocalizedString* Description; // 5 + uint32 ID; + uint32 SpellID; + uint32 OverridesSpellID; + LocalizedString* Description; + uint16 SpecID; + uint8 OrderIndex; +}; + +struct SpellEntry +{ + uint32 ID; + LocalizedString* Name; + LocalizedString* NameSubtext; + LocalizedString* Description; + LocalizedString* AuraDescription; + uint32 MiscID; + uint16 DescriptionVariablesID; +}; + +struct SpellAuraOptionsEntry +{ + uint32 SpellID; + uint32 ProcCharges; + uint32 ProcTypeMask; + uint32 ProcCategoryRecovery; + uint16 CumulativeAura; + uint8 DifficultyID; + uint8 ProcChance; + uint8 SpellProcsPerMinuteID; }; struct SpellAuraRestrictionsEntry { - uint32 ID; // 0 - uint32 CasterAuraState; // 1 - uint32 TargetAuraState; // 2 - uint32 ExcludeCasterAuraState; // 3 - uint32 ExcludeTargetAuraState; // 4 - uint32 CasterAuraSpell; // 5 - uint32 TargetAuraSpell; // 6 - uint32 ExcludeCasterAuraSpell; // 7 - uint32 ExcludeTargetAuraSpell; // 8 + uint32 SpellID; + uint32 CasterAuraSpell; + uint32 TargetAuraSpell; + uint32 ExcludeCasterAuraSpell; + uint32 ExcludeTargetAuraSpell; + uint8 DifficultyID; + uint8 CasterAuraState; + uint8 TargetAuraState; + uint8 ExcludeCasterAuraState; + uint8 ExcludeTargetAuraState; +}; + +struct SpellCastTimesEntry +{ + int32 CastTime; + int32 MinCastTime; + int16 CastTimePerLevel; }; struct SpellCastingRequirementsEntry { - uint32 ID; // 0 - uint32 FacingCasterFlags; // 1 - uint32 MinFactionID; // 1 - uint32 MinReputation; // 3 - uint32 RequiredAreasID; // 4 - uint32 RequiredAuraVision; // 5 - uint32 RequiresSpellFocus; // 6 + uint32 SpellID; + uint16 MinFactionID; + uint16 RequiredAreasID; + uint16 RequiresSpellFocus; + uint8 FacingCasterFlags; + uint8 MinReputation; + uint8 RequiredAuraVision; }; -struct SpellCastTimesEntry +struct SpellCategoriesEntry +{ + uint32 SpellID; + uint16 Category; + uint16 StartRecoveryCategory; + uint16 ChargeCategory; + uint8 DifficultyID; + uint8 DefenseType; + uint8 DispelType; + uint8 Mechanic; + uint8 PreventionType; +}; + +struct SpellCategoryEntry { - uint32 ID; // 0 - int32 CastTime; // 1 - int32 CastTimePerLevel; // 2 - int32 MinCastTime; // 3 + LocalizedString* Name; + int32 ChargeRecoveryTime; + uint8 Flags; + uint8 UsesPerWeek; + uint8 MaxCharges; }; struct SpellClassOptionsEntry { - uint32 ID; // 0 - uint32 ModalNextSpell; // 1 - flag128 SpellClassMask; // 2-5 - uint32 SpellClassSet; // 6 + uint32 SpellID; + flag128 SpellClassMask; + uint16 ModalNextSpell; + uint8 SpellClassSet; +}; + +struct SpellCooldownsEntry +{ + uint32 SpellID; + uint32 CategoryRecoveryTime; + uint32 RecoveryTime; + uint32 StartRecoveryTime; + uint8 DifficultyID; }; struct SpellDurationEntry { - uint32 ID; // 0 - int32 Duration[3]; // 1-3 + int32 Duration; + int32 MaxDuration; + int16 DurationPerLevel; +}; + +struct SpellEffectEntry +{ + uint32 ID; + float EffectAmplitude; + uint32 EffectAuraPeriod; + uint32 EffectBasePoints; + float EffectBonusCoefficient; + float EffectChainAmplitude; + uint32 EffectDieSides; + uint32 EffectItemType; + int32 EffectMiscValue; + int32 EffectMiscValueB; + float EffectPointsPerResource; + float EffectRealPointsPerLevel; + flag128 EffectSpellClassMask; + uint32 EffectTriggerSpell; + float EffectPosFacing; + uint32 SpellID; + uint32 EffectAttributes; + float BonusCoefficientFromAP; + uint16 EffectAura; + uint16 EffectChainTargets; + uint8 DifficultyID; + uint8 Effect; + uint8 EffectMechanic; + uint8 EffectRadiusIndex; + uint8 EffectRadiusMaxIndex; + uint8 ImplicitTarget[2]; + uint8 EffectIndex; +}; + +#define MAX_SPELL_EFFECTS 32 +#define MAX_EFFECT_MASK 0xFFFFFFFF + +struct SpellEffectScalingEntry +{ + float Coefficient; + float Variance; + float ResourceCoefficient; + uint32 SpellEffectID; +}; + +struct SpellEquippedItemsEntry +{ + uint32 SpellID; + int32 EquippedItemInventoryTypeMask; + int32 EquippedItemSubClassMask; + int8 EquippedItemClass; +}; + +struct SpellFocusObjectEntry +{ + LocalizedString* Name; +}; + +struct SpellInterruptsEntry +{ + uint32 SpellID; + uint32 AuraInterruptFlags[2]; + uint32 ChannelInterruptFlags[2]; + uint16 InterruptFlags; + uint8 DifficultyID; }; struct SpellItemEnchantmentConditionEntry { - uint32 ID; // 0 - uint8 LTOperandType[5]; // 1-2 - uint32 LTOperand[5]; // 2-6 - uint8 Operator[5]; // 7-8 - uint8 RTOperandType[5]; // 8-9 - uint32 RTOperand[5]; // 10-14 - uint8 Logic[5]; // 15-16 + uint8 LTOperandType[5]; + uint8 LTOperand[5]; + uint8 Operator[5]; + uint8 RTOperandType[5]; + uint8 RTOperand[5]; + uint8 Logic[5]; }; struct SpellLearnSpellEntry { - uint32 ID; // 0 - uint32 LearnSpellID; // 1 - uint32 SpellID; // 2 - uint32 OverridesSpellID; // 3 + uint32 LearnSpellID; + uint32 SpellID; + uint32 OverridesSpellID; +}; + +struct SpellLevelsEntry +{ + uint32 SpellID; + uint16 BaseLevel; + uint16 MaxLevel; + uint16 SpellLevel; + uint8 DifficultyID; }; struct SpellMiscEntry { - uint32 ID; // 0 - uint32 Attributes; // 1 - uint32 AttributesEx; // 2 - uint32 AttributesExB; // 3 - uint32 AttributesExC; // 4 - uint32 AttributesExD; // 5 - uint32 AttributesExE; // 6 - uint32 AttributesExF; // 7 - uint32 AttributesExG; // 8 - uint32 AttributesExH; // 9 - uint32 AttributesExI; // 10 - uint32 AttributesExJ; // 11 - uint32 AttributesExK; // 12 - uint32 AttributesExL; // 13 - uint32 AttributesExM; // 14 - uint32 CastingTimeIndex; // 15 - uint32 DurationIndex; // 16 - uint32 RangeIndex; // 17 - float Speed; // 18 - uint32 SpellIconID; // 21 - uint32 ActiveIconID; // 22 - uint32 SchoolMask; // 23 - float MultistrikeSpeedMod; // 24 + uint32 Attributes; + uint32 AttributesEx; + uint32 AttributesExB; + uint32 AttributesExC; + uint32 AttributesExD; + uint32 AttributesExE; + uint32 AttributesExF; + uint32 AttributesExG; + uint32 AttributesExH; + uint32 AttributesExI; + uint32 AttributesExJ; + uint32 AttributesExK; + uint32 AttributesExL; + uint32 AttributesExM; + float Speed; + float MultistrikeSpeedMod; + uint16 CastingTimeIndex; + uint16 DurationIndex; + uint16 RangeIndex; + uint16 SpellIconID; + uint16 ActiveIconID; + uint8 SchoolMask; }; struct SpellPowerEntry { - uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 PowerIndex; // 2 - uint32 PowerType; // 3 - uint32 ManaCost; // 4 - uint32 ManaCostPerLevel; // 5 - uint32 ManaCostPerSecond; // 6 - uint32 ManaCostAdditional; // 7 Spell uses [ManaCost, ManaCost+ManaCostAdditional] power - affects tooltip parsing as multiplier on SpellEffectEntry::EffectPointsPerResource + uint32 ID; + uint32 SpellID; + uint32 ManaCost; + float ManaCostPercentage; + float ManaCostPercentagePerSecond; + uint32 RequiredAura; + float HealthCostPercentage; + uint16 ManaCostPerSecond; + uint16 ManaCostAdditional; // Spell uses [ManaCost, ManaCost+ManaCostAdditional] power - affects tooltip parsing as multiplier on SpellEffectEntry::EffectPointsPerResource // only SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_NORMALIZED_WEAPON_DMG - uint32 PowerDisplayID; // 8 - uint32 UnitPowerBarID; // 9 - float ManaCostPercentage; // 10 - float ManaCostPercentagePerSecond; // 11 - uint32 RequiredAura; // 12 - float HealthCostPercentage; // 13 + uint16 PowerDisplayID; + uint16 UnitPowerBarID; + uint8 PowerIndex; + uint8 PowerType; + uint8 ManaCostPerLevel; }; struct SpellPowerDifficultyEntry { - uint32 SpellPowerID; // 0 - uint32 DifficultyID; // 1 - uint32 PowerIndex; // 2 + uint32 SpellPowerID; + uint8 DifficultyID; + uint8 PowerIndex; }; struct SpellProcsPerMinuteEntry @@ -1279,173 +1583,213 @@ struct SpellProcsPerMinuteModEntry struct SpellRadiusEntry { - uint32 ID; // 0 - float Radius; // 1 - float RadiusPerLevel; // 2 - float RadiusMin; // 3 - float RadiusMax; // 4 + float Radius; + float RadiusPerLevel; + float RadiusMin; + float RadiusMax; }; struct SpellRangeEntry { - uint32 ID; // 0 - float MinRangeHostile; // 1 - float MinRangeFriend; // 2 - float MaxRangeHostile; // 3 - float MaxRangeFriend; // 4 - uint32 Flags; // 5 - LocalizedString* DisplayName; // 6 - LocalizedString* DisplayNameShort; // 7 + float MinRangeHostile; + float MinRangeFriend; + float MaxRangeHostile; + float MaxRangeFriend; + LocalizedString* DisplayName; + LocalizedString* DisplayNameShort; + uint8 Flags; }; #define MAX_SPELL_REAGENTS 8 struct SpellReagentsEntry { - uint32 ID; // 0 - int32 Reagent[MAX_SPELL_REAGENTS]; // 1-8 - uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 9-16 + uint32 SpellID; + int32 Reagent[MAX_SPELL_REAGENTS]; + uint16 ReagentCount[MAX_SPELL_REAGENTS]; +}; + +struct SpellScalingEntry +{ + uint32 SpellID; + uint16 ScalesFromItemLevel; + int8 ScalingClass; + uint8 MaxScalingLevel; +}; + +struct SpellShapeshiftEntry +{ + uint32 SpellID; + uint32 ShapeshiftExclude[2]; + uint32 ShapeshiftMask[2]; + uint8 StanceBarOrder; }; -struct SpellRuneCostEntry +#define MAX_SHAPESHIFT_SPELLS 8 + +struct SpellShapeshiftFormEntry { - uint32 ID; // 0 - uint32 RuneCost[4]; // 1-4 (0=blood, 1=unholy, 2=frost, 3=death) - uint32 RunicPower; // 5 + LocalizedString* Name; + float WeaponDamageVariance; + uint32 Flags; + uint16 AttackIconID; + uint16 CombatRoundTime; + uint16 CreatureDisplayID[4]; + uint16 PresetSpellID[MAX_SHAPESHIFT_SPELLS]; + int8 CreatureType; + uint8 MountTypeID; + uint8 BonusActionBar; +}; - bool NoRuneCost() const { return RuneCost[0] == 0 && RuneCost[1] == 0 && RuneCost[2] == 0 && RuneCost[3] == 0; } - bool NoRunicPowerGain() const { return RunicPower == 0; } +struct SpellTargetRestrictionsEntry +{ + uint32 SpellID; + float ConeAngle; + float Width; + uint32 Targets; + uint16 MaxTargetLevel; + uint16 TargetCreatureType; + uint8 DifficultyID; + uint8 MaxAffectedTargets; }; #define MAX_SPELL_TOTEMS 2 struct SpellTotemsEntry { - uint32 ID; // 0 - uint32 RequiredTotemCategoryID[MAX_SPELL_TOTEMS]; // 1 - uint32 Totem[MAX_SPELL_TOTEMS]; // 2 + uint32 SpellID; + uint32 Totem[MAX_SPELL_TOTEMS]; + uint8 RequiredTotemCategoryID[MAX_SPELL_TOTEMS]; }; struct SpellXSpellVisualEntry { - uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 DifficultyID; // 2 - uint32 SpellVisualID[2]; // 3-4 - float Unk620; // 5 - uint32 PlayerConditionID; // 6 - uint32 Flags; // 7 + uint32 ID; + uint32 SpellID; + float Unk620; + uint16 SpellVisualID[2]; + uint16 PlayerConditionID; + uint8 DifficultyID; + uint8 Flags; }; struct TaxiNodesEntry { - uint32 ID; // 0 - uint32 MapID; // 1 - DBCPosition3D Pos; // 2-4 - LocalizedString* Name; // 5 - uint32 MountCreatureID[2]; // 6-7 - uint32 ConditionID; // 8 - uint32 LearnableIndex; // 9 - some kind of index only for learnable nodes - uint32 Flags; // 10 - DBCPosition2D MapOffset; // 11-12 + uint32 ID; + DBCPosition3D Pos; + LocalizedString* Name; + uint32 MountCreatureID[2]; + DBCPosition2D MapOffset; + uint16 MapID; + uint16 ConditionID; + uint16 LearnableIndex; + uint8 Flags; }; struct TaxiPathEntry { - uint32 ID; // 0 - uint32 From; // 1 - uint32 To; // 2 - uint32 Cost; // 3 + uint32 ID; + uint16 From; + uint16 To; + uint16 Cost; }; struct TaxiPathNodeEntry { - uint32 ID; // 0 - uint32 PathID; // 1 - uint32 NodeIndex; // 2 - uint32 MapID; // 3 - DBCPosition3D Loc; // 4-6 - uint32 Flags; // 7 - uint32 Delay; // 8 - uint32 ArrivalEventID; // 9 - uint32 DepartureEventID; // 10 + uint32 ID; + DBCPosition3D Loc; + uint32 Delay; + uint16 PathID; + uint16 MapID; + uint16 ArrivalEventID; + uint16 DepartureEventID; + uint8 NodeIndex; + uint8 Flags; }; struct TotemCategoryEntry { - uint32 ID; // 0 - LocalizedString* Name; // 1 - uint32 CategoryType; // 2 - uint32 CategoryMask; // 3 + LocalizedString* Name; + uint32 CategoryMask; + uint8 CategoryType; }; struct ToyEntry { - uint32 ID; // 0 - uint32 ItemID; // 1 - uint32 Flags; // 2 - LocalizedString* Description; // 3 - uint32 CategoryFilter; // 4 + uint32 ID; + uint32 ItemID; + LocalizedString* Description; + uint8 Flags; + uint8 CategoryFilter; }; struct TransportAnimationEntry { - uint32 ID; // 0 - uint32 TransportID; // 1 - uint32 TimeIndex; // 2 - DBCPosition3D Pos; // 3-5 - uint32 SequenceID; // 6 + uint32 TransportID; + uint32 TimeIndex; + DBCPosition3D Pos; + uint8 SequenceID; }; struct TransportRotationEntry { - uint32 ID; // 0 - uint32 TransportID; // 1 - uint32 TimeIndex; // 2 - float X; // 3 - float Y; // 4 - float Z; // 5 - float W; // 6 + uint32 TransportID; + uint32 TimeIndex; + float X; + float Y; + float Z; + float W; }; struct UnitPowerBarEntry { - uint32 ID; // 0 - uint32 MinPower; // 1 - uint32 MaxPower; // 2 - uint32 StartPower; // 3 - uint32 CenterPower; // 4 - float RegenerationPeace; // 5 - float RegenerationCombat; // 6 - uint32 BarType; // 7 - uint32 FileDataID[6]; // 8-13 - uint32 Color[6]; // 14-19 - uint32 Flags; // 20 - LocalizedString* Name; // 21 - LocalizedString* Cost; // 22 - LocalizedString* OutOfError; // 23 - LocalizedString* ToolTip; // 24 - float StartInset; // 25 - float EndInset; // 26 + uint32 MaxPower; + float RegenerationPeace; + float RegenerationCombat; + uint32 FileDataID[6]; + uint32 Color[6]; + LocalizedString* Name; + LocalizedString* Cost; + LocalizedString* OutOfError; + LocalizedString* ToolTip; + float StartInset; + float EndInset; + uint16 StartPower; + uint16 Flags; + uint8 MinPower; + uint8 CenterPower; + uint8 BarType; }; #define MAX_WORLD_MAP_OVERLAY_AREA_IDX 4 struct WorldMapOverlayEntry { - uint32 ID; // 0 - uint32 MapAreaID; // 1 idx in WorldMapArea.dbc - uint32 AreaID[MAX_WORLD_MAP_OVERLAY_AREA_IDX]; // 2-5 - LocalizedString* TextureName; // 6 - uint32 TextureWidth; // 7 - uint32 TextureHeight; // 8 - uint32 OffsetX; // 9 - uint32 OffsetY; // 10 - uint32 HitRectTop; // 11 - uint32 HitRectLeft; // 12 - uint32 HitRectBottom; // 13 - uint32 HitRectRight; // 14 - uint32 PlayerConditionID; // 15 + char const* TextureName; + uint16 MapAreaID; // idx in WorldMapArea.dbc + uint16 AreaID[MAX_WORLD_MAP_OVERLAY_AREA_IDX]; + uint16 TextureWidth; + uint16 TextureHeight; + uint16 OffsetX; + uint16 OffsetY; + uint16 HitRectTop; + uint16 HitRectLeft; + uint16 HitRectBottom; + uint16 HitRectRight; + uint16 PlayerConditionID; +}; + +struct WorldMapTransformsEntry +{ + DBCPosition3D RegionMin; + DBCPosition3D RegionMax; + DBCPosition2D RegionOffset; + float RegionScale; + uint16 MapID; + uint16 NewMapID; + uint16 NewDungeonMapID; + uint16 NewAreaID; + uint8 Flags; }; #pragma pack(pop) @@ -1465,7 +1809,7 @@ typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource; typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList; typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath; -#define TaxiMaskSize 217 +#define TaxiMaskSize 226 typedef std::array<uint8, TaxiMaskSize> TaxiMask; #endif diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h index 2a64a2d4eb5..1e8c3be57ea 100644 --- a/src/server/game/DataStores/DB2fmt.h +++ b/src/server/game/DataStores/DB2fmt.h @@ -18,113 +18,154 @@ #ifndef TRINITY_DB2SFRM_H #define TRINITY_DB2SFRM_H -char const AchievementFormat[] = "niiissiiiiisiii"; -char const AreaGroupMemberFormat[] = "nii"; -char const AuctionHouseFormat[] = "niiis"; -char const BarberShopStyleFormat[] = "nissfiii"; -char const BattlePetBreedQualityFormat[] = "nif"; -char const BattlePetBreedStateFormat[] = "niii"; -char const BattlePetSpeciesFormat[] = "niiiiiiss"; -char const BattlePetSpeciesStateFormat[] = "niii"; -char const BroadcastTextFormat[] = "nissiiiiiiiii"; -char const CharStartOutfitFormat[] = "nbbbbiiiiiiiiiiiiiiiiiiiiiiiiii"; -char const ChrClassesXPowerTypesFormat[] = "iii"; -char const CinematicSequencesFormat[] = "niiiiiiiii"; -char const CreatureDisplayInfoFormat[] = "niiiffissssiiiiiiiiiii"; -char const CreatureTypeFormat[] = "nsi"; -char const CriteriaFormat[] = "niiiiiiiiiii"; -char const CriteriaTreeFormat[] = "niliiisi"; -char const CurrencyTypesFormat[] = "nisssiiiiiis"; -char const CurvePointFormat[] = "niiff"; -char const DestructibleModelDataFormat[] = "niiiiiiiiiiiiiiiiiiiiiii"; -char const DurabilityQualityFormat[] = "nf"; -char const GameObjectsFormat[] = "niiffffffffiiiiiiiiiiiis"; -char const GameTablesFormat[] = "nsii"; -char const GarrAbilityFormat[] = "nissiiii"; -char const GarrBuildingFormat[] = "niiiiissssiiiiiiiiiiiiii"; -char const GarrBuildingPlotInstFormat[] = "niiiff"; -char const GarrClassSpecFormat[] = "nsssii"; -char const GarrFollowerFormat[] = "niiiiiiiiiiiiiiissiiiiii"; -char const GarrFollowerXAbilityFormat[] = "niii"; -char const GarrPlotBuildingFormat[] = "nii"; -char const GarrPlotFormat[] = "niiisiiii"; -char const GarrPlotInstanceFormat[] = "nis"; -char const GarrSiteLevelFormat[] = "niiiiffiiii"; -char const GarrSiteLevelPlotInstFormat[] = "niiffi"; -char const GlyphSlotFormat[] = "nii"; -char const HeirloomFormat[] = "niisiiiiiiii"; -char const GuildPerkSpellsFormat[] = "nii"; -char const HolidaysEntryFormat[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisiii"; -char const ImportPriceArmorFormat[] = "nffff"; -char const ImportPriceQualityFormat[] = "nf"; -char const ImportPriceShieldFormat[] = "nf"; -char const ImportPriceWeaponFormat[] = "nf"; -char const ItemAppearanceFormat[] = "nii"; -char const ItemBonusFormat[] = "niiiii"; -char const ItemBonusTreeNodeFormat[] = "niiii"; -char const ItemClassFormat[] = "nifs"; -char const ItemCurrencyCostFormat[] = "in"; -char const ItemDisenchantLootFormat[] = "niiiiii"; -char const ItemEffectFormat[] = "niiiiiiiii"; -char const ItemExtendedCostFormat[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiii"; -char const ItemFormat[] = "niiiiiiii"; -char const ItemLimitCategoryFormat[] = "nsii"; -char const ItemModifiedAppearanceFormat[] = "niiiii"; -char const ItemPriceBaseFormat[] = "niff"; -char const ItemRandomPropertiesFormat[] = "nsiiiiis"; -char const ItemRandomSuffixFormat[] = "nssiiiiiiiiii"; -char const ItemSparseFormat[] = "niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffffffiiifisssssiiiiiiiiiiiiiiiiiiifiiifiii"; -char const ItemSpecFormat[] = "niiiiii"; -char const ItemSpecOverrideFormat[] = "nii"; -char const ItemToBattlePetSpeciesFormat[] = "ni"; -char const ItemXBonusTreeFormat[] = "nii"; -char const KeyChainFormat[] = "nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; -char const MailTemplateFormat[] = "ns"; -char const ModifierTreeFormat[] = "niiiiii"; -char const MountCapabilityFormat[] = "niiiiiii"; -char const MountFormat[] = "niiiisssii"; -char const MountTypeXCapabilityFormat[] = "niii"; -char const NameGenFormat[] = "nsii"; -char const NamesProfanityFormat[] = "nSi"; -char const NamesReservedFormat[] = "nS"; -char const NamesReservedLocaleFormat[] = "nSi"; -char const OverrideSpellDataFormat[] = "niiiiiiiiiiii"; -char const PhaseXPhaseGroupFormat[] = "nii"; -char const PlayerConditionFormat[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisiii"; -char const QuestMoneyRewardFormat[] = "niiiiiiiiii"; -char const QuestPackageItemfmt[] = "niiii"; -char const QuestSortFormat[] = "ns"; -char const QuestV2Format[] = "ni"; -char const QuestXPFormat[] = "niiiiiiiiii"; -char const ScalingStatDistributionFormat[] = "niii"; -char const SoundEntriesFormat[] = "nisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiififfiifffffii"; -char const SpecializationSpellsFormat[] = "niiiis"; -char const SpellAuraRestrictionsFormat[] = "niiiiiiii"; -char const SpellCastTimesFormat[] = "niii"; -char const SpellCastingRequirementsFormat[] = "niiiiii"; -char const SpellClassOptionsFormat[] = "niiiiii"; -char const SpellDurationFormat[] = "niii"; -char const SpellItemEnchantmentConditionFormat[] = "nbbbbbiiiiibbbbbbbbbbiiiiibbbbb"; -char const SpellLearnSpellFormat[] = "niii"; -char const SpellMiscFormat[] = "niiiiiiiiiiiiiiiiifiiif"; -char const SpellPowerDifficultyFormat[] = "nii"; -char const SpellPowerFormat[] = "niiiiiiiiiffif"; -char const SpellProcsPerMinuteFormat[] = "nfi"; -char const SpellProcsPerMinuteModFormat[] = "niifi"; -char const SpellRadiusFormat[] = "nffff"; -char const SpellRangeFormat[] = "nffffiss"; -char const SpellReagentsFormat[] = "niiiiiiiiiiiiiiii"; -char const SpellRuneCostFormat[] = "niiiii"; -char const SpellTotemsFormat[] = "niiii"; -char const SpellXSpellVisualFormat[] = "niiiifii"; -char const TaxiNodesFormat[] = "nifffsiiiiiff"; -char const TaxiPathFormat[] = "niii"; -char const TaxiPathNodeFormat[] = "niiifffiiii"; -char const TotemCategoryFormat[] = "nsii"; -char const ToyFormat[] = "niisi"; -char const TransportAnimationFormat[] = "niifffi"; -char const TransportRotationFormat[] = "niiffff"; -char const UnitPowerBarFormat[] = "niiiiffiiiiiiiiiiiiiissssff"; -char const WorldMapOverlayFormat[] = "niiiiisiiiiiiiii"; +char const AchievementFormat[] = "nssishhhhhhhbbb"; +char const AnimKitFormat[] = "dihh"; +char const AreaGroupMemberFormat[] = "dhh"; +char const ArmorLocationFormat[] = "dfffff"; +char const AuctionHouseFormat[] = "dshbb"; +char const BankBagSlotPricesFormat[] = "di"; +char const BarberShopStyleFormat[] = "nssfbbbb"; +char const BattlePetBreedQualityFormat[] = "dfb"; +char const BattlePetBreedStateFormat[] = "nhbb"; +char const BattlePetSpeciesFormat[] = "niiisshbb"; +char const BattlePetSpeciesStateFormat[] = "nihb"; +char const BroadcastTextFormat[] = "dsshhhhhhhhbb"; +char const CharStartOutfitFormat[] = "diiiiiiiiiiiiiiiiiiiiiiiiibbbbb"; +char const ChrClassesXPowerTypesFormat[] = "dbb"; +char const ChrRacesFormat[] = "niSSsssSSSiiffffffihhhhhhhhhhhhbbbbbbbbb"; +char const CinematicSequencesFormat[] = "dhhhhhhhhh"; +char const CreatureDisplayInfoFormat[] = "niffiiiSiiihhhhhhbbbbbb"; +char const CreatureDisplayInfoExtraFormat[] = "diiiiiiiiiiiibbbbbbbbbbbb"; +char const CreatureTypeFormat[] = "dsb"; +char const CriteriaFormat[] = "diiihhhbbbbb"; +char const CriteriaTreeFormat[] = "dishhhhb"; +char const CurrencyTypesFormat[] = "nSSsiiisbbbb"; +char const CurvePointFormat[] = "dffhb"; +char const DestructibleModelDataFormat[] = "dhhhhhbbbbbbbbbbbbbbbbb"; +char const DurabilityCostsFormat[] = "dhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"; +char const DurabilityQualityFormat[] = "df"; +char const EmotesTextSoundFormat[] = "dhhbbb"; +char const GameObjectsFormat[] = "nffffffffiiiiiiiishhhhbb"; +char const GameObjectDisplayInfoFormat[] = "diffffffffhhhhhhhhhhh"; +char const GameTablesFormat[] = "dshb"; +char const GarrAbilityFormat[] = "nssihbbb"; +char const GarrBuildingFormat[] = "diissssihhhhhhbbbbbbbbbbb"; +char const GarrBuildingPlotInstFormat[] = "nffhhb"; +char const GarrClassSpecFormat[] = "nssshb"; +char const GarrFollowerFormat[] = "diissiihhbbbbbbbbbbbbbbbb"; +char const GarrFollowerXAbilityFormat[] = "dhhb"; +char const GarrPlotFormat[] = "dsiibbbbb"; +char const GarrPlotBuildingFormat[] = "dbb"; +char const GarrPlotInstanceFormat[] = "dsb"; +char const GarrSiteLevelFormat[] = "dffhhhbbbbb"; +char const GarrSiteLevelPlotInstFormat[] = "dffhbb"; +char const GlyphSlotFormat[] = "dbb"; +char const GuildColorBackgroundFormat[] = "dbbb"; +char const GuildColorBorderFormat[] = "dbbb"; +char const GuildColorEmblemFormat[] = "dbbb"; +char const GuildPerkSpellsFormat[] = "dib"; +char const HeirloomFormat[] = "nisiiiiihhbb"; +char const HolidaysEntryFormat[] = "diiiiiiiiiiiiiiiiShhhhhhhhhhhbbbbbbbbbbbbbbbb"; +char const ImportPriceArmorFormat[] = "dffff"; +char const ImportPriceQualityFormat[] = "df"; +char const ImportPriceShieldFormat[] = "df"; +char const ImportPriceWeaponFormat[] = "df"; +char const ItemFormat[] = "dibbbbbbb"; +char const ItemAppearanceFormat[] = "diib"; +char const ItemArmorQualityFormat[] = "dfffffffh"; +char const ItemArmorShieldFormat[] = "dfffffffh"; +char const ItemArmorTotalFormat[] = "dffffh"; +char const ItemBagFamilyFormat[] = "ds"; +char const ItemBonusFormat[] = "niihbb"; +char const ItemBonusTreeNodeFormat[] = "dhhhb"; +char const ItemClassFormat[] = "dfsb"; +char const ItemCurrencyCostFormat[] = "di"; +char const ItemDamageAmmoFormat[] = "dfffffffh"; +char const ItemDamageOneHandFormat[] = "dfffffffh"; +char const ItemDamageOneHandCasterFormat[] = "dfffffffh"; +char const ItemDamageTwoHandFormat[] = "dfffffffh"; +char const ItemDamageTwoHandCasterFormat[] = "dfffffffh"; +char const ItemDisenchantLootFormat[] = "dhhhbbb"; +char const ItemEffectFormat[] = "diiiihhhbb"; +char const ItemExtendedCostFormat[] = "diiiiiiiiiiihhhhhhhhhhhbbbbb"; +char const ItemLimitCategoryFormat[] = "dsbb"; +char const ItemModifiedAppearanceFormat[] = "nihbb"; +char const ItemPriceBaseFormat[] = "dffh"; +char const ItemRandomPropertiesFormat[] = "dshhhhh"; +char const ItemRandomSuffixFormat[] = "dsshhhhhhhhhh"; +char const ItemSetSpellFormat[] = "dihhb"; +char const ItemSparseFormat[] = "iiiffiiiiiiiiiiiiiiiiifffffffffffsssssififhhhhhhhhhhhhhhhhhhhhhhhhhhhhhbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +char const ItemSpecFormat[] = "dhbbbbb"; +char const ItemSpecOverrideFormat[] = "dih"; +char const ItemToBattlePetSpeciesFormat[] = "dh"; +char const ItemXBonusTreeFormat[] = "dih"; +char const KeyChainFormat[] = "dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +char const MailTemplateFormat[] = "ds"; +char const ModifierTreeFormat[] = "diihbbbb"; +char const MountFormat[] = "niissshhhb"; +char const MountCapabilityFormat[] = "niihhhbb"; +char const MountTypeXCapabilityFormat[] = "dhhb"; +char const MovieFormat[] = "diibb"; +char const NameGenFormat[] = "dsbb"; +char const NamesProfanityFormat[] = "dSb"; +char const NamesReservedFormat[] = "dS"; +char const NamesReservedLocaleFormat[] = "dSb"; +char const OverrideSpellDataFormat[] = "diiiiiiiiiiib"; +char const PhaseXPhaseGroupFormat[] = "dhh"; +char const PlayerConditionFormat[] = "diiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisiihhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +char const PowerDisplayFormat[] = "dSbbbb"; +char const QuestFactionRewardFormat[] = "dhhhhhhhhhh"; +char const QuestMoneyRewardFormat[] = "diiiiiiiiii"; +char const QuestPackageItemFormat[] = "dihbb"; +char const QuestSortFormat[] = "ds"; +char const QuestV2Format[] = "dh"; +char const QuestXPFormat[] = "dhhhhhhhhhh"; +char const RandPropPointsFormat[] = "dhhhhhhhhhhhhhhh"; +char const ScalingStatDistributionFormat[] = "dhbb"; +char const SkillLineFormat[] = "dssshhbbb"; +char const SkillLineAbilityFormat[] = "diiiihhhhhhbb"; +char const SkillRaceClassInfoFormat[] = "dihhhhbb"; +char const SoundKitFormat[] = "nsffffffffhhbbbbb"; +char const SpecializationSpellsFormat[] = "niishb"; +char const SpellFormat[] = "nssssih"; +char const SpellAuraOptionsFormat[] = "diiiihbbb"; +char const SpellAuraRestrictionsFormat[] = "diiiiibbbbb"; +char const SpellCastTimesFormat[] = "diih"; +char const SpellCastingRequirementsFormat[] = "dihhhbbb"; +char const SpellCategoriesFormat[] = "dihhhbbbbb"; +char const SpellCategoryFormat[] = "dsibbb"; +char const SpellClassOptionsFormat[] = "diiiiihb"; +char const SpellCooldownsFormat[] = "diiiib"; +char const SpellDurationFormat[] = "diih"; +char const SpellEffectFormat[] = "nfiiffiiiiffiiiiifiifhhbbbbbbbb"; +char const SpellEffectScalingFormat[] = "dfffi"; +char const SpellEquippedItemsFormat[] = "diiib"; +char const SpellFocusObjectFormat[] = "ds"; +char const SpellInterruptsFormat[] = "diiiiihb"; +char const SpellItemEnchantmentConditionFormat[] = "dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; +char const SpellLearnSpellFormat[] = "diii"; +char const SpellLevelsFormat[] = "dihhhb"; +char const SpellMiscFormat[] = "diiiiiiiiiiiiiiffhhhhhb"; +char const SpellPowerFormat[] = "niiffifhhhhbbb"; +char const SpellPowerDifficultyFormat[] = "nbb"; +char const SpellRadiusFormat[] = "dffff"; +char const SpellRangeFormat[] = "dffffssb"; +char const SpellReagentsFormat[] = "diiiiiiiiihhhhhhhh"; +char const SpellScalingFormat[] = "dihbb"; +char const SpellShapeshiftFormat[] = "diiiiib"; +char const SpellShapeshiftFormFormat[] = "dsfihhhhhhhhhhhhhhbbb"; +char const SpellTargetRestrictionsFormat[] = "diffihhbb"; +char const SpellTotemsFormat[] = "diiibb"; +char const SpellXSpellVisualFormat[] = "nifhhhbb"; +char const TaxiNodesFormat[] = "nfffsiiffhhhb"; +char const TaxiPathFormat[] = "nhhh"; +char const TaxiPathNodeFormat[] = "nfffihhhhbb"; +char const TotemCategoryFormat[] = "dsib"; +char const ToyFormat[] = "nisbb"; +char const TransportAnimationFormat[] = "diifffb"; +char const TransportRotationFormat[] = "diiffff"; +char const UnitPowerBarFormat[] = "diffiiiiiiiiiiiissssffhhbbb"; +char const WorldMapOverlayFormat[] = "dShhhhhhhhhhhhhh"; +char const WorldMapTransformsFormat[] = "dfffffffffhhhhb"; #endif diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 710e92ca712..739b4ac51a0 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -436,6 +436,7 @@ enum Difficulty : uint8 DIFFICULTY_EVENT_SCENARIO = 20, DIFFICULTY_MYTHIC = 23, DIFFICULTY_TIMEWALKER = 24, + DIFFICULTY_PVP_SCENARIO = 25, MAX_DIFFICULTY }; diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 79c42c4fc7b..0e0375826ce 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -23,10 +23,8 @@ #include "DBCfmt.h" #include "Timer.h" #include "DB2Stores.h" - #include <map> - struct WMOAreaTableTripple { WMOAreaTableTripple(int32 r, int32 a, int32 g) : groupId(g), rootId(r), adtId(a) @@ -48,12 +46,9 @@ typedef std::multimap<uint32, CharSectionsEntry const*> CharSectionsMap; typedef std::map<uint32, std::vector<uint32>> FactionTeamMap; typedef std::map<WMOAreaTableTripple, WMOAreaTableEntry const*> WMOAreaInfoByTripple; -DBCStorage<AnimKitEntry> sAnimKitStore(AnimKitfmt); DBCStorage<AreaTableEntry> sAreaTableStore(AreaTablefmt); DBCStorage<AreaTriggerEntry> sAreaTriggerStore(AreaTriggerfmt); -DBCStorage<ArmorLocationEntry> sArmorLocationStore(ArmorLocationfmt); -DBCStorage<BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesfmt); DBCStorage<BannedAddOnsEntry> sBannedAddOnsStore(BannedAddOnsfmt); DBCStorage<BattlemasterListEntry> sBattlemasterListStore(BattlemasterListfmt); @@ -62,48 +57,24 @@ CharSectionsMap sCharSectionMap; DBCStorage<CharTitlesEntry> sCharTitlesStore(CharTitlesfmt); DBCStorage<ChatChannelsEntry> sChatChannelsStore(ChatChannelsfmt); DBCStorage<ChrClassesEntry> sChrClassesStore(ChrClassesfmt); -DBCStorage<ChrRacesEntry> sChrRacesStore(ChrRacesfmt); DBCStorage<ChrSpecializationEntry> sChrSpecializationStore(ChrSpecializationfmt); ChrSpecializationByIndexArray sChrSpecializationByIndexStore; -DBCStorage<CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt); DBCStorage<CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt); DBCStorage<CreatureModelDataEntry> sCreatureModelDataStore(CreatureModelDatafmt); DBCStorage<DifficultyEntry> sDifficultyStore(DifficultyFmt); DBCStorage<DungeonEncounterEntry> sDungeonEncounterStore(DungeonEncounterfmt); -DBCStorage<DurabilityCostsEntry> sDurabilityCostsStore(DurabilityCostsfmt); DBCStorage<EmotesEntry> sEmotesStore(Emotesfmt); DBCStorage<EmotesTextEntry> sEmotesTextStore(EmotesTextfmt); -typedef std::tuple<uint32, uint32, uint32> EmotesTextSoundKey; -static std::map<EmotesTextSoundKey, EmotesTextSoundEntry const*> sEmotesTextSoundMap; -DBCStorage <EmotesTextSoundEntry> sEmotesTextSoundStore(EmotesTextSoundEntryfmt); DBCStorage<FactionEntry> sFactionStore(Factionfmt); static FactionTeamMap sFactionTeamMap; DBCStorage<FactionTemplateEntry> sFactionTemplateStore(FactionTemplatefmt); -DBCStorage<GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt); DBCStorage<GemPropertiesEntry> sGemPropertiesStore(GemPropertiesfmt); DBCStorage<GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt); -DBCStorage<GuildColorBackgroundEntry> sGuildColorBackgroundStore(GuildColorBackgroundfmt); -DBCStorage<GuildColorBorderEntry> sGuildColorBorderStore(GuildColorBorderfmt); -DBCStorage<GuildColorEmblemEntry> sGuildColorEmblemStore(GuildColorEmblemfmt); -DBCStorage<ItemArmorQualityEntry> sItemArmorQualityStore(ItemArmorQualityfmt); -DBCStorage<ItemArmorShieldEntry> sItemArmorShieldStore(ItemArmorShieldfmt); -DBCStorage<ItemArmorTotalEntry> sItemArmorTotalStore(ItemArmorTotalfmt); -DBCStorage<ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt); -DBCStorage<ItemDamageEntry> sItemDamageAmmoStore(ItemDamagefmt); -DBCStorage<ItemDamageEntry> sItemDamageOneHandCasterStore(ItemDamagefmt); -DBCStorage<ItemDamageEntry> sItemDamageOneHandStore(ItemDamagefmt); -DBCStorage<ItemDamageEntry> sItemDamageRangedStore(ItemDamagefmt); -DBCStorage<ItemDamageEntry> sItemDamageThrownStore(ItemDamagefmt); -DBCStorage<ItemDamageEntry> sItemDamageTwoHandCasterStore(ItemDamagefmt); -DBCStorage<ItemDamageEntry> sItemDamageTwoHandStore(ItemDamagefmt); -DBCStorage<ItemDamageEntry> sItemDamageWandStore(ItemDamagefmt); DBCStorage<ItemSetEntry> sItemSetStore(ItemSetfmt); -DBCStorage<ItemSetSpellEntry> sItemSetSpellStore(ItemSetSpellfmt); -ItemSetSpellsStore sItemSetSpellsStore; DBCStorage<LFGDungeonEntry> sLFGDungeonStore(LFGDungeonfmt); DBCStorage<LightEntry> sLightStore(Lightfmt); @@ -113,37 +84,11 @@ DBCStorage<LockEntry> sLockStore(Lockfmt); DBCStorage<MapEntry> sMapStore(Mapfmt); DBCStorage<MapDifficultyEntry> sMapDifficultyStore(MapDifficultyfmt); // only for loading MapDifficultyMap sMapDifficultyMap; -DBCStorage<MovieEntry> sMovieStore(Moviefmt); DBCStorage<PhaseEntry> sPhaseStore(Phasefmt); -DBCStorage<PowerDisplayEntry> sPowerDisplayStore(PowerDisplayfmt); DBCStorage<PvPDifficultyEntry> sPvpDifficultyStore(PvpDifficultyfmt); -DBCStorage<QuestFactionRewEntry> sQuestFactionRewardStore(QuestFactionRewardfmt); - -DBCStorage<RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandPropPointsfmt); - -DBCStorage<SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt); -DBCStorage<SkillLineEntry> sSkillLineStore(SkillLinefmt); -DBCStorage<SkillRaceClassInfoEntry> sSkillRaceClassInfoStore(SkillRaceClassInfofmt); -SkillRaceClassInfoMap SkillRaceClassInfoBySkill; -DBCStorage<SpellAuraOptionsEntry> sSpellAuraOptionsStore(SpellAuraOptionsfmt); -DBCStorage<SpellCategoriesEntry> sSpellCategoriesStore(SpellCategoriesfmt); -DBCStorage<SpellCategoryEntry> sSpellCategoryStore(SpellCategoryfmt); -DBCStorage<SpellCooldownsEntry> sSpellCooldownsStore(SpellCooldownsfmt); -DBCStorage<SpellEffectEntry> sSpellEffectStore(SpellEffectfmt); -DBCStorage<SpellEffectScalingEntry> sSpellEffectScalingStore(SpellEffectScalingfmt); -SpellEffectScallingByEffectId sSpellEffectScallingByEffectId; -DBCStorage<SpellEntry> sSpellStore(Spellfmt); -DBCStorage<SpellEquippedItemsEntry> sSpellEquippedItemsStore(SpellEquippedItemsfmt); -DBCStorage<SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt); -DBCStorage<SpellInterruptsEntry> sSpellInterruptsStore(SpellInterruptsfmt); DBCStorage<SpellItemEnchantmentEntry> sSpellItemEnchantmentStore(SpellItemEnchantmentfmt); -DBCStorage<SpellLevelsEntry> sSpellLevelsStore(SpellLevelsfmt); -DBCStorage<SpellScalingEntry> sSpellScalingStore(SpellScalingfmt); -DBCStorage<SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftfmt); -DBCStorage<SpellShapeshiftFormEntry> sSpellShapeshiftFormStore(SpellShapeshiftFormfmt); -DBCStorage<SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore(SpellTargetRestrictionsfmt); DBCStorage<SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt); DBCStorage<TalentEntry> sTalentStore(Talentfmt); @@ -155,30 +100,24 @@ DBCStorage<VehicleSeatEntry> sVehicleSeatStore(VehicleSeatfmt); DBCStorage<WMOAreaTableEntry> sWMOAreaTableStore(WMOAreaTablefmt); static WMOAreaInfoByTripple sWMOAreaInfoByTripple; DBCStorage<WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreafmt); -DBCStorage<WorldMapTransformsEntry> sWorldMapTransformsStore(WorldMapTransformsfmt); DBCStorage<WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsfmt); -GameTable<GtArmorMitigationByLvlEntry> sGtArmorMitigationByLvlStore(GtArmorMitigationByLvlfmt); -GameTable<GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt); -GameTable<GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt); -GameTable<GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt); -GameTable<GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt); -GameTable<GtChanceToSpellCritEntry> sGtChanceToSpellCritStore(GtChanceToSpellCritfmt); -GameTable<GtCombatRatingsEntry> sGtCombatRatingsStore(GtCombatRatingsfmt); -GameTable<GtItemSocketCostPerLevelEntry> sGtItemSocketCostPerLevelStore(GtItemSocketCostPerLevelfmt); -GameTable<GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore(GtNPCManaCostScalerfmt); -GameTable<GtNpcTotalHpEntry> sGtNpcTotalHpStore(GtNpcTotalHpfmt); -GameTable<GtNpcTotalHpExp1Entry> sGtNpcTotalHpExp1Store(GtNpcTotalHpExp1fmt); -GameTable<GtNpcTotalHpExp2Entry> sGtNpcTotalHpExp2Store(GtNpcTotalHpExp2fmt); -GameTable<GtNpcTotalHpExp3Entry> sGtNpcTotalHpExp3Store(GtNpcTotalHpExp3fmt); -GameTable<GtNpcTotalHpExp4Entry> sGtNpcTotalHpExp4Store(GtNpcTotalHpExp4fmt); -GameTable<GtNpcTotalHpExp5Entry> sGtNpcTotalHpExp5Store(GtNpcTotalHpExp5fmt); -GameTable<GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore(GtOCTBaseHPByClassfmt); -GameTable<GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore(GtOCTBaseMPByClassfmt); -GameTable<GtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore(GtOCTHpPerStaminafmt); -GameTable<GtOCTLevelExperienceEntry> sGtOCTLevelExperienceStore(GtOCTLevelExperiencefmt); -GameTable<GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt); -GameTable<GtSpellScalingEntry> sGtSpellScalingStore(GtSpellScalingfmt); +GameTable<GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore; +GameTable<GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore; +GameTable<GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore; +GameTable<GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore; +GameTable<GtChanceToSpellCritEntry> sGtChanceToSpellCritStore; +GameTable<GtCombatRatingsEntry> sGtCombatRatingsStore; +GameTable<GtItemSocketCostPerLevelEntry> sGtItemSocketCostPerLevelStore; +GameTable<GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore; +GameTable<GtNpcTotalHpEntry> sGtNpcTotalHpStore[MAX_EXPANSIONS]; +GameTable<GtNpcDamageByClassEntry> sGtNpcDamageByClassStore[MAX_EXPANSIONS]; +GameTable<GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore; +GameTable<GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore; +GameTable<GtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore; +GameTable<GtOCTLevelExperienceEntry> sGtOCTLevelExperienceStore; +GameTable<GtRegenMPPerSptEntry> sGtRegenMPPerSptStore; +GameTable<GtSpellScalingEntry> sGtSpellScalingStore; typedef std::list<std::string> StoreProblemList; @@ -297,88 +236,41 @@ void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale) #define LOAD_DBC(store, file) LoadDBC(availableDbcLocales, bad_dbc_files, store, dbcPath, file, defaultLocale) - LOAD_DBC(sAnimKitStore, "AnimKit.dbc");//20444 - LOAD_DBC(sAreaTableStore, "AreaTable.dbc");//20444 - LOAD_DBC(sAreaTriggerStore, "AreaTrigger.dbc");//20444 - LOAD_DBC(sArmorLocationStore, "ArmorLocation.dbc");//20444 - LOAD_DBC(sBankBagSlotPricesStore, "BankBagSlotPrices.dbc");//20444 - LOAD_DBC(sBannedAddOnsStore, "BannedAddOns.dbc");//20444 - LOAD_DBC(sBattlemasterListStore, "BattlemasterList.dbc");//20444 - LOAD_DBC(sCharSectionsStore, "CharSections.dbc");//20444 - LOAD_DBC(sCharTitlesStore, "CharTitles.dbc");//20444 - LOAD_DBC(sChatChannelsStore, "ChatChannels.dbc");//20444 - LOAD_DBC(sChrClassesStore, "ChrClasses.dbc");//20444 - LOAD_DBC(sChrRacesStore, "ChrRaces.dbc");//20444 - LOAD_DBC(sChrSpecializationStore, "ChrSpecialization.dbc");//20444 - LOAD_DBC(sCreatureDisplayInfoExtraStore, "CreatureDisplayInfoExtra.dbc");//20444 - LOAD_DBC(sCreatureFamilyStore, "CreatureFamily.dbc");//20444 - LOAD_DBC(sCreatureModelDataStore, "CreatureModelData.dbc");//20444 - LOAD_DBC(sDifficultyStore, "Difficulty.dbc");//20444 - LOAD_DBC(sDungeonEncounterStore, "DungeonEncounter.dbc");//20444 - LOAD_DBC(sDurabilityCostsStore, "DurabilityCosts.dbc");//20444 - LOAD_DBC(sEmotesStore, "Emotes.dbc");//20444 - LOAD_DBC(sEmotesTextStore, "EmotesText.dbc");//20444 - LOAD_DBC(sEmotesTextSoundStore, "EmotesTextSound.dbc"); - LOAD_DBC(sFactionStore, "Faction.dbc");//20444 - LOAD_DBC(sFactionTemplateStore, "FactionTemplate.dbc");//20444 - LOAD_DBC(sGameObjectDisplayInfoStore, "GameObjectDisplayInfo.dbc");//20444 - LOAD_DBC(sGemPropertiesStore, "GemProperties.dbc");//20444 - LOAD_DBC(sGlyphPropertiesStore, "GlyphProperties.dbc");//20444 - LOAD_DBC(sGuildColorBackgroundStore, "GuildColorBackground.dbc");//20444 - LOAD_DBC(sGuildColorBorderStore, "GuildColorBorder.dbc"); //20444 - LOAD_DBC(sGuildColorEmblemStore, "GuildColorEmblem.dbc");//20444 - LOAD_DBC(sItemArmorQualityStore, "ItemArmorQuality.dbc");//20444 - LOAD_DBC(sItemArmorShieldStore, "ItemArmorShield.dbc");//20444 - LOAD_DBC(sItemArmorTotalStore, "ItemArmorTotal.dbc");//20444 - LOAD_DBC(sItemBagFamilyStore, "ItemBagFamily.dbc");//20444 - LOAD_DBC(sItemDamageAmmoStore, "ItemDamageAmmo.dbc");//20444 - LOAD_DBC(sItemDamageOneHandCasterStore, "ItemDamageOneHandCaster.dbc");//20444 - LOAD_DBC(sItemDamageOneHandStore, "ItemDamageOneHand.dbc");//20444 - LOAD_DBC(sItemDamageRangedStore, "ItemDamageRanged.dbc");//20444 - LOAD_DBC(sItemDamageThrownStore, "ItemDamageThrown.dbc");//20444 - LOAD_DBC(sItemDamageTwoHandCasterStore, "ItemDamageTwoHandCaster.dbc");//20444 - LOAD_DBC(sItemDamageTwoHandStore, "ItemDamageTwoHand.dbc");//20444 - LOAD_DBC(sItemDamageWandStore, "ItemDamageWand.dbc");//20444 - LOAD_DBC(sItemSetSpellStore, "ItemSetSpell.dbc");//20444 - LOAD_DBC(sItemSetStore, "ItemSet.dbc");//20444 - LOAD_DBC(sLFGDungeonStore, "LfgDungeons.dbc");//20444 - LOAD_DBC(sLightStore, "Light.dbc"); //20444 - LOAD_DBC(sLiquidTypeStore, "LiquidType.dbc");//20444 - LOAD_DBC(sLockStore, "Lock.dbc");//20444 - LOAD_DBC(sMapDifficultyStore, "MapDifficulty.dbc");//20444 - LOAD_DBC(sMapStore, "Map.dbc");//20444 - LOAD_DBC(sMovieStore, "Movie.dbc");//20444 - LOAD_DBC(sPhaseStore, "Phase.dbc"); // 20444 - LOAD_DBC(sPowerDisplayStore, "PowerDisplay.dbc");//20444 - LOAD_DBC(sPvpDifficultyStore, "PvpDifficulty.dbc");//20444 - LOAD_DBC(sQuestFactionRewardStore, "QuestFactionReward.dbc");//20444 - LOAD_DBC(sRandomPropertiesPointsStore, "RandPropPoints.dbc");//20444 - LOAD_DBC(sSkillLineAbilityStore, "SkillLineAbility.dbc");//20444 - LOAD_DBC(sSkillLineStore, "SkillLine.dbc");//20444 - LOAD_DBC(sSkillRaceClassInfoStore, "SkillRaceClassInfo.dbc");//20444 - LOAD_DBC(sSpellAuraOptionsStore, "SpellAuraOptions.dbc");//20444 - LOAD_DBC(sSpellCategoriesStore, "SpellCategories.dbc");//20444 - LOAD_DBC(sSpellCategoryStore, "SpellCategory.dbc");//20444 - LOAD_DBC(sSpellCooldownsStore, "SpellCooldowns.dbc");//20444 - LOAD_DBC(sSpellEffectScalingStore, "SpellEffectScaling.dbc");//20444 - LOAD_DBC(sSpellEffectStore, "SpellEffect.dbc"/*, &CustomSpellEffectfmt, &CustomSpellEffectEntryIndex*/);//20444 - LOAD_DBC(sSpellEquippedItemsStore, "SpellEquippedItems.dbc");//20444 - LOAD_DBC(sSpellFocusObjectStore, "SpellFocusObject.dbc");//20444 - LOAD_DBC(sSpellInterruptsStore, "SpellInterrupts.dbc");//20444 - LOAD_DBC(sSpellItemEnchantmentStore, "SpellItemEnchantment.dbc");//20444 - LOAD_DBC(sSpellLevelsStore, "SpellLevels.dbc");//20444 - LOAD_DBC(sSpellScalingStore, "SpellScaling.dbc");//20444 - LOAD_DBC(sSpellShapeshiftFormStore, "SpellShapeshiftForm.dbc");//20444 - LOAD_DBC(sSpellShapeshiftStore, "SpellShapeshift.dbc");//20444 - LOAD_DBC(sSpellStore, "Spell.dbc"/*, &CustomSpellfmt, &CustomSpellEntryIndex*/);//20444 - LOAD_DBC(sSpellTargetRestrictionsStore, "SpellTargetRestrictions.dbc");//20444 - LOAD_DBC(sSummonPropertiesStore, "SummonProperties.dbc");//20444 - LOAD_DBC(sTalentStore, "Talent.dbc");//20444 - LOAD_DBC(sVehicleSeatStore, "VehicleSeat.dbc");//20444 - LOAD_DBC(sVehicleStore, "Vehicle.dbc");//20444 - LOAD_DBC(sWMOAreaTableStore, "WMOAreaTable.dbc");//20444 + LOAD_DBC(sAreaTableStore, "AreaTable.dbc");//20810 + LOAD_DBC(sAreaTriggerStore, "AreaTrigger.dbc");//20810 + LOAD_DBC(sBannedAddOnsStore, "BannedAddOns.dbc");//20810 + LOAD_DBC(sBattlemasterListStore, "BattlemasterList.dbc");//20810 + LOAD_DBC(sCharSectionsStore, "CharSections.dbc");//20810 + LOAD_DBC(sCharTitlesStore, "CharTitles.dbc");//20810 + LOAD_DBC(sChatChannelsStore, "ChatChannels.dbc");//20810 + LOAD_DBC(sChrClassesStore, "ChrClasses.dbc");//20810 + LOAD_DBC(sChrSpecializationStore, "ChrSpecialization.dbc");//20810 + LOAD_DBC(sCreatureFamilyStore, "CreatureFamily.dbc");//20810 + LOAD_DBC(sCreatureModelDataStore, "CreatureModelData.dbc");//20810 + LOAD_DBC(sDifficultyStore, "Difficulty.dbc");//20810 + LOAD_DBC(sDungeonEncounterStore, "DungeonEncounter.dbc");//20810 + LOAD_DBC(sEmotesStore, "Emotes.dbc");//20810 + LOAD_DBC(sEmotesTextStore, "EmotesText.dbc");//20810 + LOAD_DBC(sFactionStore, "Faction.dbc");//20810 + LOAD_DBC(sFactionTemplateStore, "FactionTemplate.dbc");//20810 + LOAD_DBC(sGemPropertiesStore, "GemProperties.dbc");//20810 + LOAD_DBC(sGlyphPropertiesStore, "GlyphProperties.dbc");//20810 + LOAD_DBC(sItemSetStore, "ItemSet.dbc");//20810 + LOAD_DBC(sLFGDungeonStore, "LfgDungeons.dbc");//20810 + LOAD_DBC(sLightStore, "Light.dbc"); //20810 + LOAD_DBC(sLiquidTypeStore, "LiquidType.dbc");//20810 + LOAD_DBC(sLockStore, "Lock.dbc");//20810 + LOAD_DBC(sMapDifficultyStore, "MapDifficulty.dbc");//20810 + LOAD_DBC(sMapStore, "Map.dbc");//20810 + LOAD_DBC(sPhaseStore, "Phase.dbc");//20810 + LOAD_DBC(sPvpDifficultyStore, "PvpDifficulty.dbc");//20810 + LOAD_DBC(sSpellItemEnchantmentStore, "SpellItemEnchantment.dbc");//20810 + LOAD_DBC(sSummonPropertiesStore, "SummonProperties.dbc");//20810 + LOAD_DBC(sTalentStore, "Talent.dbc");//20810 + LOAD_DBC(sVehicleSeatStore, "VehicleSeat.dbc");//20810 + LOAD_DBC(sVehicleStore, "Vehicle.dbc");//20810 + LOAD_DBC(sWMOAreaTableStore, "WMOAreaTable.dbc");//20810 LOAD_DBC(sWorldMapAreaStore, "WorldMapArea.dbc");//20444 - LOAD_DBC(sWorldMapTransformsStore, "WorldMapTransforms.dbc");//20444 LOAD_DBC(sWorldSafeLocsStore, "WorldSafeLocs.dbc"); // 20444 #undef LOAD_DBC @@ -408,10 +300,6 @@ void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale) "MAX_DIFFICULTY is not large enough to contain all difficulties! (current value %d, required %d)", MAX_DIFFICULTY, sDifficultyStore.GetNumRows()); - for (uint32 i = 0; i < sEmotesTextSoundStore.GetNumRows(); ++i) - if (EmotesTextSoundEntry const* entry = sEmotesTextSoundStore.LookupEntry(i)) - sEmotesTextSoundMap[EmotesTextSoundKey(entry->EmotesTextId, entry->RaceId, entry->SexId)] = entry; - for (uint32 i = 0; i < sFactionStore.GetNumRows(); ++i) { FactionEntry const* faction = sFactionStore.LookupEntry(i); @@ -422,22 +310,6 @@ void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale) } } - for (uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i) - { - if (GameObjectDisplayInfoEntry const* info = sGameObjectDisplayInfoStore.LookupEntry(i)) - { - if (info->GeoBoxMax.X < info->GeoBoxMin.X) - std::swap(*(float*)(&info->GeoBoxMax.X), *(float*)(&info->GeoBoxMin.X)); - if (info->GeoBoxMax.Y < info->GeoBoxMin.Y) - std::swap(*(float*)(&info->GeoBoxMax.Y), *(float*)(&info->GeoBoxMin.Y)); - if (info->GeoBoxMax.Z < info->GeoBoxMin.Z) - std::swap(*(float*)(&info->GeoBoxMax.Z), *(float*)(&info->GeoBoxMin.Z)); - } - } - - for (ItemSetSpellEntry const* entry : sItemSetSpellStore) - sItemSetSpellsStore[entry->ItemSetID].push_back(entry); - // fill data for (uint32 i = 0; i < sMapDifficultyStore.GetNumRows(); ++i) if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) @@ -449,20 +321,6 @@ void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale) if (entry->BracketID > MAX_BATTLEGROUND_BRACKETS) ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); - for (uint32 i = 0; i < sSkillRaceClassInfoStore.GetNumRows(); ++i) - if (SkillRaceClassInfoEntry const* entry = sSkillRaceClassInfoStore.LookupEntry(i)) - if (sSkillLineStore.LookupEntry(entry->SkillID)) - SkillRaceClassInfoBySkill.emplace(entry->SkillID, entry); - - for (uint32 j = 0; j < sSpellEffectScalingStore.GetNumRows(); j++) - { - SpellEffectScalingEntry const* spellEffectScaling = sSpellEffectScalingStore.LookupEntry(j); - if (!spellEffectScaling) - continue; - - sSpellEffectScallingByEffectId.insert(std::make_pair(spellEffectScaling->SpellEffectID, j)); - } - for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) { if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(i)) @@ -496,11 +354,10 @@ void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale) } // Check loaded DBC files proper version - if (!sAreaTableStore.LookupEntry(7941) || // last area added in 6.2.2 (20444) - !sCharTitlesStore.LookupEntry(457) || // last char title added in 6.2.2 (20444) - !sGemPropertiesStore.LookupEntry(2544) || // last gem property added in 6.2.2 (20444) - !sMapStore.LookupEntry(1497) || // last map added in 6.2.2 (20444) - !sSpellStore.LookupEntry(197204) ) // last spell added in 6.2.2 (20444) + if (!sAreaTableStore.LookupEntry(6719) || // last area (areaflag) added in 7.0.1 (20810) + !sCharTitlesStore.LookupEntry(469) || // last char title added in 7.0.1 (20810) + !sGemPropertiesStore.LookupEntry(2952) || // last gem property added in 7.0.1 (20810) + !sMapStore.LookupEntry(1602) ) // last map added in 7.0.1 (20810) { TC_LOG_ERROR("misc", "You have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); @@ -519,27 +376,34 @@ void LoadGameTables(const std::string& dataPath, uint32 defaultLocale) #define LOAD_GT(tableName, store, file) LoadGameTable(bad_dbc_files, tableName, store, dbcPath, file) - LOAD_GT("ArmorMitigationByLvl", sGtArmorMitigationByLvlStore, "gtArmorMitigationByLvl.dbc"); // 21463 - LOAD_GT("BarberShopCostBase", sGtBarberShopCostBaseStore, "gtBarberShopCostBase.dbc"); // 20444 - LOAD_GT("CombatRatings", sGtCombatRatingsStore, "gtCombatRatings.dbc"); // 20444 - LOAD_GT("ChanceToMeleeCritBase", sGtChanceToMeleeCritBaseStore, "gtChanceToMeleeCritBase.dbc"); // 20444 - LOAD_GT("ChanceToMeleeCrit", sGtChanceToMeleeCritStore, "gtChanceToMeleeCrit.dbc"); // 20444 - LOAD_GT("ChanceToSpellCritBase", sGtChanceToSpellCritBaseStore, "gtChanceToSpellCritBase.dbc"); // 20444 - LOAD_GT("ChanceToSpellCrit", sGtChanceToSpellCritStore, "gtChanceToSpellCrit.dbc"); // 20444 - LOAD_GT("ItemSocketCostPerLevel", sGtItemSocketCostPerLevelStore, "gtItemSocketCostPerLevel.dbc"); // 20444 - LOAD_GT("NPCManaCostScaler", sGtNPCManaCostScalerStore, "gtNPCManaCostScaler.dbc"); // 20444 - LOAD_GT("NpcTotalHp", sGtNpcTotalHpStore, "gtNpcTotalHp.dbc"); // 20444 - LOAD_GT("NpcTotalHpExp1", sGtNpcTotalHpExp1Store, "gtNpcTotalHpExp1.dbc"); // 20444 - LOAD_GT("NpcTotalHpExp2", sGtNpcTotalHpExp2Store, "gtNpcTotalHpExp2.dbc"); // 20444 - LOAD_GT("NpcTotalHpExp3", sGtNpcTotalHpExp3Store, "gtNpcTotalHpExp3.dbc"); // 20444 - LOAD_GT("NpcTotalHpExp4", sGtNpcTotalHpExp4Store, "gtNpcTotalHpExp4.dbc"); // 20444 - LOAD_GT("NpcTotalHpExp5", sGtNpcTotalHpExp5Store, "gtNpcTotalHpExp5.dbc"); // 20444 - LOAD_GT("OCTHPPerStamina", sGtOCTHpPerStaminaStore, "gtOCTHpPerStamina.dbc"); // 20444 - LOAD_GT("OCTLevelExperience", sGtOCTLevelExperienceStore, "gtOCTLevelExperience.dbc"); // 20444 - LOAD_GT("RegenMPPerSpt", sGtRegenMPPerSptStore, "gtRegenMPPerSpt.dbc"); // 20444 - LOAD_GT("SpellScaling", sGtSpellScalingStore, "gtSpellScaling.dbc"); // 20444 - LOAD_GT("OCTBaseHPByClass", sGtOCTBaseHPByClassStore, "gtOCTBaseHPByClass.dbc"); // 20444 - LOAD_GT("OCTBaseMPByClass", sGtOCTBaseMPByClassStore, "gtOCTBaseMPByClass.dbc"); // 20444 + LOAD_GT("BarberShopCostBase", sGtBarberShopCostBaseStore, "gtBarberShopCostBase.dbc"); // 20810 + LOAD_GT("CombatRatings", sGtCombatRatingsStore, "gtCombatRatings.dbc"); // 20810 + LOAD_GT("ChanceToMeleeCritBase", sGtChanceToMeleeCritBaseStore, "gtChanceToMeleeCritBase.dbc"); // 20810 + LOAD_GT("ChanceToMeleeCrit", sGtChanceToMeleeCritStore, "gtChanceToMeleeCrit.dbc"); // 20810 + LOAD_GT("ChanceToSpellCritBase", sGtChanceToSpellCritBaseStore, "gtChanceToSpellCritBase.dbc"); // 20810 + LOAD_GT("ChanceToSpellCrit", sGtChanceToSpellCritStore, "gtChanceToSpellCrit.dbc"); // 20810 + LOAD_GT("ItemSocketCostPerLevel", sGtItemSocketCostPerLevelStore, "gtItemSocketCostPerLevel.dbc"); // 20810 + LOAD_GT("NPCManaCostScaler", sGtNPCManaCostScalerStore, "gtNPCManaCostScaler.dbc"); // 20810 + LOAD_GT("NpcTotalHp", sGtNpcTotalHpStore[0], "gtNpcTotalHp.dbc"); // 20810 + LOAD_GT("NpcTotalHpExp1", sGtNpcTotalHpStore[1], "gtNpcTotalHpExp1.dbc"); // 20810 + LOAD_GT("NpcTotalHpExp2", sGtNpcTotalHpStore[2], "gtNpcTotalHpExp2.dbc"); // 20810 + LOAD_GT("NpcTotalHpExp3", sGtNpcTotalHpStore[3], "gtNpcTotalHpExp3.dbc"); // 20810 + LOAD_GT("NpcTotalHpExp4", sGtNpcTotalHpStore[4], "gtNpcTotalHpExp4.dbc"); // 20810 + LOAD_GT("NpcTotalHpExp5", sGtNpcTotalHpStore[5], "gtNpcTotalHpExp5.dbc"); // 20810 + LOAD_GT("NpcTotalHpExp6", sGtNpcTotalHpStore[6], "gtNpcTotalHpExp6.dbc"); // 20810 + LOAD_GT("NpcDamageByClass", sGtNpcDamageByClassStore[0], "gtNpcDamageByClass.dbc"); // 20810 + LOAD_GT("NpcDamageByClassExp1", sGtNpcDamageByClassStore[1], "gtNpcDamageByClassExp1.dbc"); // 20810 + LOAD_GT("NpcDamageByClassExp2", sGtNpcDamageByClassStore[2], "gtNpcDamageByClassExp2.dbc"); // 20810 + LOAD_GT("NpcDamageByClassExp3", sGtNpcDamageByClassStore[3], "gtNpcDamageByClassExp3.dbc"); // 20810 + LOAD_GT("NpcDamageByClassExp4", sGtNpcDamageByClassStore[4], "gtNpcDamageByClassExp4.dbc"); // 20810 + LOAD_GT("NpcDamageByClassExp5", sGtNpcDamageByClassStore[5], "gtNpcDamageByClassExp5.dbc"); // 20810 + LOAD_GT("NpcDamageByClassExp6", sGtNpcDamageByClassStore[6], "gtNpcDamageByClassExp6.dbc"); // 20810 + LOAD_GT("OCTHPPerStamina", sGtOCTHpPerStaminaStore, "gtOCTHpPerStamina.dbc"); // 20810 + LOAD_GT("OCTLevelExperience", sGtOCTLevelExperienceStore, "gtOCTLevelExperience.dbc"); // 20810 + LOAD_GT("RegenMPPerSpt", sGtRegenMPPerSptStore, "gtRegenMPPerSpt.dbc"); // 20810 + LOAD_GT("SpellScaling", sGtSpellScalingStore, "gtSpellScaling.dbc"); // 20810 + LOAD_GT("OCTBaseHPByClass", sGtOCTBaseHPByClassStore, "gtOCTBaseHPByClass.dbc"); // 20810 + LOAD_GT("OCTBaseMPByClass", sGtOCTBaseMPByClassStore, "gtOCTBaseMPByClass.dbc"); // 20810 #undef LOAD_GT @@ -583,12 +447,6 @@ char const* GetCreatureFamilyPetName(uint32 petfamily, uint32 /*locale*/) return pet_family->Name_lang ? pet_family->Name_lang : NULL; } -EmotesTextSoundEntry const* FindTextSoundEmoteFor(uint32 emote, uint32 race, uint32 gender) -{ - auto itr = sEmotesTextSoundMap.find(EmotesTextSoundKey(emote, race, gender)); - return itr != sEmotesTextSoundMap.end() ? itr->second : nullptr; -} - WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid) { WMOAreaInfoByTripple::iterator i = sWMOAreaInfoByTripple.find(WMOAreaTableTripple(rootid, adtid, groupid)); @@ -597,12 +455,6 @@ WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid return i->second; } -char const* GetRaceName(uint8 race, uint8 /*locale*/) -{ - ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race); - return raceEntry ? raceEntry->Name_lang : NULL; -} - char const* GetClassName(uint8 class_, uint8 /*locale*/) { ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); @@ -636,6 +488,8 @@ uint32 GetMaxLevelForExpansion(uint32 expansion) return 90; case EXPANSION_WARLORDS_OF_DRAENOR: return 100; + case EXPANSION_LEGION: + return 110; default: break; } @@ -654,30 +508,12 @@ uint32 GetExpansionForLevel(uint32 level) return EXPANSION_CATACLYSM; else if (level < 90) return EXPANSION_MISTS_OF_PANDARIA; + else if (level < 100) + return EXPANSION_WARLORDS_OF_DRAENOR; else return CURRENT_EXPANSION; } -bool IsTotemCategoryCompatibleWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) -{ - if (requiredTotemCategoryId == 0) - return true; - if (itemTotemCategoryId == 0) - return false; - - TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId); - if (!itemEntry) - return false; - TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId); - if (!reqEntry) - return false; - - if (itemEntry->CategoryType != reqEntry->CategoryType) - return false; - - return (itemEntry->CategoryMask & reqEntry->CategoryMask) == reqEntry->CategoryMask; -} - void Zone2MapCoordinates(float& x, float& y, uint32 worldMapAreaId) { WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(worldMapAreaId); @@ -854,68 +690,3 @@ uint32 GetDefaultMapLight(uint32 mapId) return 0; } - -SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_) -{ - SkillRaceClassInfoBounds bounds = SkillRaceClassInfoBySkill.equal_range(skill); - for (SkillRaceClassInfoMap::iterator itr = bounds.first; itr != bounds.second; ++itr) - { - if (itr->second->RaceMask && !(itr->second->RaceMask & (1 << (race - 1)))) - continue; - if (itr->second->ClassMask && !(itr->second->ClassMask & (1 << (class_ - 1)))) - continue; - - return itr->second; - } - - return NULL; -} - -void DeterminaAlternateMapPosition(uint32 mapId, float x, float y, float z, uint32* newMapId /*= nullptr*/, DBCPosition2D* newPos /*= nullptr*/) -{ - ASSERT(newMapId || newPos); - WorldMapTransformsEntry const* transformation = nullptr; - for (WorldMapTransformsEntry const* transform : sWorldMapTransformsStore) - { - if (transform->MapID != mapId) - continue; - - if (transform->RegionMin.X > x || transform->RegionMax.X < x) - continue; - if (transform->RegionMin.Y > y || transform->RegionMax.Y < y) - continue; - if (transform->RegionMin.Z > z || transform->RegionMax.Z < z) - continue; - - transformation = transform; - break; - } - - if (!transformation) - { - if (newMapId) - *newMapId = mapId; - - if (newPos) - { - newPos->X = x; - newPos->Y = y; - } - return; - } - - if (newMapId) - *newMapId = transformation->NewMapID; - - if (!newPos) - return; - - if (transformation->RegionScale > 0.0f && transformation->RegionScale < 1.0f) - { - x = (x - transformation->RegionMin.X) * transformation->RegionScale + transformation->RegionMin.X; - y = (y - transformation->RegionMin.Y) * transformation->RegionScale + transformation->RegionMin.Y; - } - - newPos->X = x + transformation->RegionOffset.X; - newPos->Y = y + transformation->RegionOffset.Y; -} diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 4ab1769c69f..a1986effa48 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -30,9 +30,6 @@ TC_GAME_API CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSection // ChrClasses TC_GAME_API char const* GetClassName(uint8 class_, uint8 locale); -// ChrRaces -TC_GAME_API char const* GetRaceName(uint8 race, uint8 locale); - // ChrSpecialization #define PET_SPEC_OVERRIDE_CLASS_INDEX MAX_CLASSES typedef ChrSpecializationEntry const* ChrSpecializationByIndexArray[MAX_CLASSES + 1][MAX_SPECIALIZATIONS]; @@ -40,16 +37,9 @@ typedef ChrSpecializationEntry const* ChrSpecializationByIndexArray[MAX_CLASSES // CreatureFamilty TC_GAME_API char const* GetCreatureFamilyPetName(uint32 petfamily, uint32 locale); -// EmotesText -TC_GAME_API EmotesTextSoundEntry const* FindTextSoundEmoteFor(uint32 emote, uint32 race, uint32 gender); - // Faction TC_GAME_API std::vector<uint32> const* GetFactionTeamList(uint32 faction); -// ItemSetSpells -typedef std::vector<ItemSetSpellEntry const*> ItemSetSpells; -typedef std::unordered_map<uint32, ItemSetSpells> ItemSetSpellsStore; - // LfgDungeons TC_GAME_API LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty); @@ -69,20 +59,9 @@ TC_GAME_API MapDifficultyEntry const* GetDownscaledMapDifficultyData(uint32 mapI TC_GAME_API PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level); TC_GAME_API PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id); -// SkillRaceClassInfo -typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap; -typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds; -TC_GAME_API SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_); - -// SpellEffectScaling -typedef std::unordered_map<uint32, uint32> SpellEffectScallingByEffectId; - // Talent typedef std::vector<TalentEntry const*> TalentsByPosition[MAX_CLASSES][MAX_TALENT_TIERS][MAX_TALENT_COLUMNS]; -// TotemCategory -TC_GAME_API bool IsTotemCategoryCompatibleWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); - // WMOAreaTable TC_GAME_API WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid); @@ -91,9 +70,6 @@ TC_GAME_API uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); TC_GAME_API void Zone2MapCoordinates(float &x, float &y, uint32 worldMapAreaId); TC_GAME_API void Map2ZoneCoordinates(float &x, float &y, uint32 worldMapAreaId); -// WorldMapTransforms -TC_GAME_API void DeterminaAlternateMapPosition(uint32 mapId, float x, float y, float z, uint32* newMapId = nullptr, DBCPosition2D* newPos = nullptr); - TC_GAME_API uint32 GetMaxLevelForExpansion(uint32 expansion); TC_GAME_API uint32 GetExpansionForLevel(uint32 level); @@ -101,7 +77,7 @@ template<class T> class GameTable { public: - GameTable(char const* format) : _storage(format), _gtEntry(nullptr) { } + GameTable() : _storage("df"), _gtEntry(nullptr) { } void SetGameTableEntry(GameTablesEntry const* gtEntry) { _gtEntry = gtEntry; } @@ -125,81 +101,34 @@ private: GameTablesEntry const* _gtEntry; }; -TC_GAME_API extern DBCStorage<AnimKitEntry> sAnimKitStore; TC_GAME_API extern DBCStorage<AreaTableEntry> sAreaTableStore; TC_GAME_API extern DBCStorage<AreaTriggerEntry> sAreaTriggerStore; -TC_GAME_API extern DBCStorage<ArmorLocationEntry> sArmorLocationStore; -TC_GAME_API extern DBCStorage<BankBagSlotPricesEntry> sBankBagSlotPricesStore; TC_GAME_API extern DBCStorage<BannedAddOnsEntry> sBannedAddOnsStore; TC_GAME_API extern DBCStorage<BattlemasterListEntry> sBattlemasterListStore; TC_GAME_API extern DBCStorage<CharSectionsEntry> sCharSectionsStore; TC_GAME_API extern DBCStorage<CharTitlesEntry> sCharTitlesStore; TC_GAME_API extern DBCStorage<ChatChannelsEntry> sChatChannelsStore; TC_GAME_API extern DBCStorage<ChrClassesEntry> sChrClassesStore; -TC_GAME_API extern DBCStorage<ChrRacesEntry> sChrRacesStore; TC_GAME_API extern DBCStorage<ChrSpecializationEntry> sChrSpecializationStore; TC_GAME_API extern ChrSpecializationByIndexArray sChrSpecializationByIndexStore; -TC_GAME_API extern DBCStorage<CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore; TC_GAME_API extern DBCStorage<CreatureFamilyEntry> sCreatureFamilyStore; TC_GAME_API extern DBCStorage<CreatureModelDataEntry> sCreatureModelDataStore; TC_GAME_API extern DBCStorage<DifficultyEntry> sDifficultyStore; TC_GAME_API extern DBCStorage<DungeonEncounterEntry> sDungeonEncounterStore; -TC_GAME_API extern DBCStorage<DurabilityCostsEntry> sDurabilityCostsStore; TC_GAME_API extern DBCStorage<EmotesEntry> sEmotesStore; TC_GAME_API extern DBCStorage<EmotesTextEntry> sEmotesTextStore; TC_GAME_API extern DBCStorage<FactionEntry> sFactionStore; TC_GAME_API extern DBCStorage<FactionTemplateEntry> sFactionTemplateStore; -TC_GAME_API extern DBCStorage<GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore; TC_GAME_API extern DBCStorage<GemPropertiesEntry> sGemPropertiesStore; TC_GAME_API extern DBCStorage<GlyphPropertiesEntry> sGlyphPropertiesStore; -TC_GAME_API extern DBCStorage<GuildColorBackgroundEntry> sGuildColorBackgroundStore; -TC_GAME_API extern DBCStorage<GuildColorBorderEntry> sGuildColorBorderStore; -TC_GAME_API extern DBCStorage<GuildColorEmblemEntry> sGuildColorEmblemStore; -TC_GAME_API extern DBCStorage<ItemArmorQualityEntry> sItemArmorQualityStore; -TC_GAME_API extern DBCStorage<ItemArmorShieldEntry> sItemArmorShieldStore; -TC_GAME_API extern DBCStorage<ItemArmorTotalEntry> sItemArmorTotalStore; -TC_GAME_API extern DBCStorage<ItemBagFamilyEntry> sItemBagFamilyStore; -TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageAmmoStore; -TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageOneHandCasterStore; -TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageOneHandStore; -TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageRangedStore; -TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageThrownStore; -TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageTwoHandCasterStore; -TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageTwoHandStore; -TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageWandStore; TC_GAME_API extern DBCStorage<ItemSetEntry> sItemSetStore; -TC_GAME_API extern DBCStorage<ItemSetSpellEntry> sItemSetSpellStore; -TC_GAME_API extern ItemSetSpellsStore sItemSetSpellsStore; TC_GAME_API extern DBCStorage<LFGDungeonEntry> sLFGDungeonStore; TC_GAME_API extern DBCStorage<LiquidTypeEntry> sLiquidTypeStore; TC_GAME_API extern DBCStorage<LockEntry> sLockStore; TC_GAME_API extern DBCStorage<MapEntry> sMapStore; TC_GAME_API extern MapDifficultyMap sMapDifficultyMap; -TC_GAME_API extern DBCStorage<MovieEntry> sMovieStore; TC_GAME_API extern DBCStorage<PhaseEntry> sPhaseStore; -TC_GAME_API extern DBCStorage<PowerDisplayEntry> sPowerDisplayStore; -TC_GAME_API extern DBCStorage<QuestFactionRewEntry> sQuestFactionRewardStore; -TC_GAME_API extern DBCStorage<RandomPropertiesPointsEntry> sRandomPropertiesPointsStore; -TC_GAME_API extern DBCStorage<SkillLineAbilityEntry> sSkillLineAbilityStore; -TC_GAME_API extern DBCStorage<SkillLineEntry> sSkillLineStore; -TC_GAME_API extern DBCStorage<SkillRaceClassInfoEntry> sSkillRaceClassInfoStore; -TC_GAME_API extern DBCStorage<SpellAuraOptionsEntry> sSpellAuraOptionsStore; -TC_GAME_API extern DBCStorage<SpellCategoriesEntry> sSpellCategoriesStore; -TC_GAME_API extern DBCStorage<SpellCategoryEntry> sSpellCategoryStore; -TC_GAME_API extern DBCStorage<SpellCooldownsEntry> sSpellCooldownsStore; -TC_GAME_API extern DBCStorage<SpellEffectEntry> sSpellEffectStore; -TC_GAME_API extern DBCStorage<SpellEffectScalingEntry> sSpellEffectScalingStore; -TC_GAME_API extern SpellEffectScallingByEffectId sSpellEffectScallingByEffectId; -TC_GAME_API extern DBCStorage<SpellEntry> sSpellStore; -TC_GAME_API extern DBCStorage<SpellEquippedItemsEntry> sSpellEquippedItemsStore; -TC_GAME_API extern DBCStorage<SpellFocusObjectEntry> sSpellFocusObjectStore; -TC_GAME_API extern DBCStorage<SpellInterruptsEntry> sSpellInterruptsStore; TC_GAME_API extern DBCStorage<SpellItemEnchantmentEntry> sSpellItemEnchantmentStore; -TC_GAME_API extern DBCStorage<SpellLevelsEntry> sSpellLevelsStore; -TC_GAME_API extern DBCStorage<SpellScalingEntry> sSpellScalingStore; -TC_GAME_API extern DBCStorage<SpellShapeshiftEntry> sSpellShapeshiftStore; -TC_GAME_API extern DBCStorage<SpellShapeshiftFormEntry> sSpellShapeshiftFormStore; -TC_GAME_API extern DBCStorage<SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore; TC_GAME_API extern DBCStorage<SummonPropertiesEntry> sSummonPropertiesStore; TC_GAME_API extern DBCStorage<TalentEntry> sTalentStore; TC_GAME_API extern TalentsByPosition sTalentByPos; @@ -217,12 +146,8 @@ TC_GAME_API extern GameTable<GtChanceToSpellCritEntry> sGtChanceToSpell TC_GAME_API extern GameTable<GtCombatRatingsEntry> sGtCombatRatingsStore; TC_GAME_API extern GameTable<GtItemSocketCostPerLevelEntry> sGtItemSocketCostPerLevelStore; TC_GAME_API extern GameTable<GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore; -TC_GAME_API extern GameTable<GtNpcTotalHpEntry> sGtNpcTotalHpStore; -TC_GAME_API extern GameTable<GtNpcTotalHpExp1Entry> sGtNpcTotalHpExp1Store; -TC_GAME_API extern GameTable<GtNpcTotalHpExp2Entry> sGtNpcTotalHpExp2Store; -TC_GAME_API extern GameTable<GtNpcTotalHpExp3Entry> sGtNpcTotalHpExp3Store; -TC_GAME_API extern GameTable<GtNpcTotalHpExp4Entry> sGtNpcTotalHpExp4Store; -TC_GAME_API extern GameTable<GtNpcTotalHpExp5Entry> sGtNpcTotalHpExp5Store; +TC_GAME_API extern GameTable<GtNpcTotalHpEntry> sGtNpcTotalHpStore[MAX_EXPANSIONS]; +TC_GAME_API extern GameTable<GtNpcDamageByClassEntry> sGtNpcDamageByClassStore[MAX_EXPANSIONS]; TC_GAME_API extern GameTable<GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore; TC_GAME_API extern GameTable<GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore; TC_GAME_API extern GameTable<GtOCTLevelExperienceEntry> sGtOCTLevelExperienceStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 5eed5ca0b6d..30704aaadad 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -26,14 +26,6 @@ // Structures using to access raw DBC data and required packing to portability #pragma pack(push, 1) -struct AnimKitEntry -{ - uint32 ID; // 0 - //uint32 OneShotDuration; // 1 - //uint32 OneShotStopAnimKitID; // 2 - //uint32 LowDefAnimKitID; // 3 -}; - struct AreaTableEntry { uint32 ID; // 0 @@ -56,7 +48,6 @@ struct AreaTableEntry //uint32 UWIntroMusic; // 21 //uint32 UWZoneMusic; // 22 //uint32 UWAmbience; // 23 - //uint32 WorldPvPID; // 24 World_PVP_Area.dbc //uint32 PvPCombastWorldStateID; // 25 //uint32 WildBattlePetLevelMin; // 26 //uint32 WildBattlePetLevelMax; // 27 @@ -90,18 +81,6 @@ struct AreaTriggerEntry //uint32 Flags // 16 }; -struct ArmorLocationEntry -{ - uint32 ID; // 0 - float Modifier[5]; // 1-5 multiplier for armor types (cloth...plate, no armor?) -}; - -struct BankBagSlotPricesEntry -{ - uint32 ID; // 0 - uint32 Cost; // 1 -}; - struct BannedAddOnsEntry { uint32 ID; // 0 @@ -134,7 +113,8 @@ struct BattlemasterListEntry enum CharSectionFlags { SECTION_FLAG_PLAYER = 0x01, - SECTION_FLAG_DEATH_KNIGHT = 0x04 + SECTION_FLAG_DEATH_KNIGHT = 0x04, + SECTION_FLAG_DEMON_HUNTER = 0x40 }; enum CharSectionType @@ -143,7 +123,10 @@ enum CharSectionType SECTION_TYPE_FACE = 1, SECTION_TYPE_FACIAL_HAIR = 2, SECTION_TYPE_HAIR = 3, - SECTION_TYPE_UNDERWEAR = 4 + SECTION_TYPE_UNDERWEAR = 4, + SECTION_TYPE_CUSTOM_DISPLAY_1 = 10, + SECTION_TYPE_CUSTOM_DISPLAY_2 = 12, + SECTION_TYPE_CUSTOM_DISPLAY_3 = 14 }; struct CharSectionsEntry @@ -152,13 +135,12 @@ struct CharSectionsEntry uint32 Race; uint32 Gender; uint32 GenType; - //char* TexturePath[3]; + //uint32 TextureFileDataID[3]; uint32 Flags; uint32 Type; uint32 Color; }; - struct CharTitlesEntry { uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() @@ -201,53 +183,12 @@ struct ChrClassesEntry //uint32 Unk1; // 18 }; -struct ChrRacesEntry -{ - uint32 ID; // 0 - uint32 Flags; // 1 - uint32 FactionID; // 2 faction template id - //uint32 ExplorationSoundID; // 3 - uint32 MaleDisplayID; // 4 - uint32 FemaleDisplayID; // 5 - //char* ClientPrefix; // 6 - //uint32 BaseLanguage; // 7 - //uint32 CreatureType; // 8 - //uint32 ResSicknessSpellID; // 9 - //uint32 SplashSoundID; // 10 - //char* ClientFileString; // 11 - uint32 CinematicSequenceID; // 12 - uint32 TeamID; // 13 m_alliance (0 alliance, 1 horde, 2 neutral) - char* Name_lang; // 14 - //char* NameFemale_lang; // 15 - //char* NameMale_lang; // 16 - //char* FacialHairCustomization[2]; // 17-18 - //char* HairCustomization; // 19 - //uint32 RaceRelated; // 20 - //uint32 UnalteredVisualRaceID; // 21 - //uint32 UAMaleCreatureSoundDataID; // 22 - //uint32 UAFemaleCreatureSoundDataID; // 23 - //uint32 CharComponentTextureLayoutID; // 24 - //uint32 DefaultClassID; // 25 - //uint32 CreateScreenFileDataID; // 26 - //uint32 SelectScreenFileDataID; // 27 - //float MaleCustomizeOffset[3]; // 28-30 - //float FemaleCustomizeOffset[3]; // 31-33 - //uint32 NeutralRaceID; // 34 - //uint32 LowResScreenFileDataID; // 35 - //uint32 HighResMaleDisplayID; // 36 - //uint32 HighResFemaleDisplayID; // 37 - //uint32 CharComponentTexLayoutHiResID; // 38 - //uint32 Unk; // 39 -}; - -#define MAX_MASTERY_SPELLS 2 - struct ChrSpecializationEntry { uint32 ID; // 0 Specialization ID //char* BackgroundFile; // 1 uint32 ClassID; // 2 - uint32 MasterySpellID[MAX_MASTERY_SPELLS]; // 3 + uint32 MasterySpellID; // 3 uint32 OrderIndex; // 4 uint32 PetTalentType; // 5 uint32 Role; // 6 (0 - Tank, 1 - Healer, 2 - DPS) @@ -257,23 +198,8 @@ struct ChrSpecializationEntry //char* Name_lang; // 10 //char* Name2_lang; // 11 Same as name_lang? //char* Description_lang; // 12 - uint32 PrimaryStatOrder[2]; // 13-14 -}; - -struct CreatureDisplayInfoExtraEntry -{ - //uint32 ID; // 0 - uint32 DisplayRaceID; // 1 - //uint32 DisplaySexID; // 2 - //uint32 SkinID; // 3 - //uint32 FaceID; // 4 - //uint32 HairStyleID; // 5 - //uint32 HairColorID; // 6 - //uint32 FacialHairID; // 7 - //uint32 NPCItemDisplay[11]; // 8-18 - //uint32 Flags; // 19 - //uint32 FileDataID; // 20 - //uint32 Unk; // 21 + //uint32 PrimaryStatOrder; // 13 + //uint32 AnimReplacementSetID; // 14 }; struct CreatureFamilyEntry @@ -304,25 +230,27 @@ struct CreatureModelDataEntry //float FootprintTextureWidth; // 8 //float FootprintParticleScale; // 9 //uint32 FoleyMaterialID; // 10 - //uint32 FootstepShakeSize; // 11 - //uint32 DeathThudShakeSize; // 12 - //uint32 SoundID; // 13 - //float CollisionWidth; // 14 - float CollisionHeight; // 15 - float MountHeight; // 16 - //float GeoBoxMin[3]; // 17-19 - //float GeoBoxMax[3]; // 20-22 - //float WorldEffectScale; // 23 - //float AttachedEffectScale; // 24 - //float MissileCollisionRadius; // 25 - //float MissileCollisionPush; // 26 - //float MissileCollisionRaise; // 27 - //float OverrideLootEffectScale; // 28 - //float OverrideNameScale; // 29 - //float OverrideSelectionRadius; // 30 - //float TamedPetBaseScale; // 31 - //uint32 CreatureGeosetDataID; // 32 - //float HoverHeight; // 33 + //uint32 Unk700_1; // 11 + //uint32 Unk700_2; // 12 + //uint32 FootstepShakeSize; // 13 + //uint32 DeathThudShakeSize; // 14 + //uint32 SoundID; // 15 + //float CollisionWidth; // 16 + float CollisionHeight; // 17 + float MountHeight; // 18 + //float GeoBoxMin[3]; // 19-21 + //float GeoBoxMax[3]; // 22-24 + //float WorldEffectScale; // 25 + //float AttachedEffectScale; // 26 + //float MissileCollisionRadius; // 27 + //float MissileCollisionPush; // 28 + //float MissileCollisionRaise; // 29 + //float OverrideLootEffectScale; // 30 + //float OverrideNameScale; // 31 + //float OverrideSelectionRadius; // 32 + //float TamedPetBaseScale; // 33 + //uint32 CreatureGeosetDataID; // 34 + //float HoverHeight; // 35 }; /* not used @@ -366,13 +294,6 @@ struct DungeonEncounterEntry //uint32 Unk; // 8 Flags2? }; -struct DurabilityCostsEntry -{ - uint32 ID; // 0 - uint32 WeaponSubClassCost[21]; // 1-22 - uint32 ArmorSubClassCost[8]; // 23-30 -}; - struct EmotesEntry { uint32 ID; // 0 @@ -393,15 +314,6 @@ struct EmotesTextEntry //uint32 EmoteText[16]; // 3-18 }; -struct EmotesTextSoundEntry -{ - uint32 Id; // 0 - uint32 EmotesTextId; // 1 - uint32 RaceId; // 2 - uint32 SexId; // 3, 0 male / 1 female - uint32 SoundId; // 4 -}; - struct FactionEntry { uint32 ID; // 0 @@ -484,18 +396,6 @@ struct FactionTemplateEntry bool IsContestedGuardFaction() const { return (Flags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD) != 0; } }; -struct GameObjectDisplayInfoEntry -{ - uint32 ID; // 0 - uint32 FileDataID; // 1 - //uint32 Sound[10]; // 2-11 - DBCPosition3D GeoBoxMin; // 12-14 - DBCPosition3D GeoBoxMax; // 15-17 - //uint32 ObjectEffectPackageID; // 18 - //float OverrideLootEffectScale; // 19 - //float OverrideNameScale; // 20 -}; - struct GemPropertiesEntry { uint32 ID; // 0 @@ -560,32 +460,12 @@ struct GtNPCManaCostScalerEntry float ratio; }; -struct GtNpcTotalHpEntry -{ - float HP; -}; - -struct GtNpcTotalHpExp1Entry -{ - float HP; -}; - -struct GtNpcTotalHpExp2Entry -{ - float HP; -}; - -struct GtNpcTotalHpExp3Entry -{ - float HP; -}; - -struct GtNpcTotalHpExp4Entry +struct GtNpcDamageByClassEntry { - float HP; + float Damage; }; -struct GtNpcTotalHpExp5Entry +struct GtNpcTotalHpEntry { float HP; }; @@ -640,76 +520,6 @@ struct GtOCTBaseMPByClassEntry float ratio; }; -// GuildColorBackground.dbc -struct GuildColorBackgroundEntry -{ - uint32 ID; - //uint8 Red; - //uint8 Green; - //uint8 Blue; -}; - -// GuildColorBorder.dbc -struct GuildColorBorderEntry -{ - uint32 ID; - //uint8 Red; - //uint8 Green; - //uint8 Blue; -}; - -// GuildColorEmblem.dbc -struct GuildColorEmblemEntry -{ - uint32 ID; - //uint8 Red; - //uint8 Green; - //uint8 Blue; -}; - -// common struct for: -// ItemDamageAmmo.dbc -// ItemDamageOneHand.dbc -// ItemDamageOneHandCaster.dbc -// ItemDamageRanged.dbc -// ItemDamageThrown.dbc -// ItemDamageTwoHand.dbc -// ItemDamageTwoHandCaster.dbc -// ItemDamageWand.dbc -struct ItemDamageEntry -{ - uint32 ID; // 0 item level - float DPS[7]; // 1-7 multiplier for item quality - uint32 ItemLevel; // 8 item level -}; - -struct ItemArmorQualityEntry -{ - uint32 ID; // 0 item level - float QualityMod[7]; // 1-7 multiplier for item quality - uint32 ItemLevel; // 8 item level -}; - -struct ItemArmorShieldEntry -{ - uint32 ID; // 0 item level - uint32 ItemLevel; // 1 item level - float Quality[7]; // 2-8 quality -}; - -struct ItemArmorTotalEntry -{ - uint32 ID; // 0 item level - uint32 ItemLevel; // 1 item level - float Value[4]; // 2-5 multiplier for armor types (cloth...plate) -}; - -struct ItemBagFamilyEntry -{ - uint32 ID; // 0 - //char* Name_lang; // 1 m_name_lang -}; - struct ItemDisplayInfoEntry { uint32 ID; // 0 @@ -736,15 +546,6 @@ struct ItemSetEntry uint32 RequiredSkillRank; // 20 }; -struct ItemSetSpellEntry -{ - uint32 ID; // 0 - uint32 ItemSetID; // 1 - uint32 SpellID; // 2 - uint32 Threshold; // 3 - uint32 ChrSpecID; // 4 -}; - struct LFGDungeonEntry { uint32 ID; // 0 @@ -910,25 +711,6 @@ struct MinorTalentEntry uint32 OrderIndex; // 3 }; -struct MovieEntry -{ - uint32 ID; // 0 index - //uint32 Volume; // 1 - //uint32 KeyID; // 2 - //uint32 AudioFileDataID; // 3 - //uint32 SubtitleFileDataID; // 4 -}; - -struct PowerDisplayEntry -{ - uint32 ID; // 0 - uint32 PowerType; // 1 - //char* GlobalStringBaseTag; // 2 - //uint8 Red; // 3 - //uint8 Green; // 4 - //uint8 Blue; // 5 -}; - struct PvPDifficultyEntry { //uint32 ID; // 0 @@ -941,280 +723,6 @@ struct PvPDifficultyEntry BattlegroundBracketId GetBracketId() const { return BattlegroundBracketId(BracketID); } }; -struct QuestFactionRewEntry -{ - uint32 ID; // 0 - int32 QuestRewFactionValue[10]; // 1-10 -}; - -struct RandomPropertiesPointsEntry -{ - uint32 ItemLevel; // 0 - uint32 EpicPropertiesPoints[5]; // 1-5 - uint32 RarePropertiesPoints[5]; // 6-10 - uint32 UncommonPropertiesPoints[5]; // 11-15 -}; - -struct SkillLineEntry -{ - uint32 ID; // 0 m_ID - int32 CategoryID; // 1 m_categoryID - char* DisplayName_lang; // 2 m_displayName_lang - //char* Description_lang; // 3 m_description_lang - uint32 SpellIconID; // 4 m_spellIconID - //char* AlternateVerb_lang; // 5 m_alternateVerb_lang - uint32 CanLink; // 6 m_canLink (prof. with recipes) - //uint32 ParentSkillLineID; // 7 - //uint32 Flags; // 8 -}; - -struct SkillLineAbilityEntry -{ - uint32 ID; // 0 - uint32 SkillLine; // 1 - uint32 SpellID; // 2 - uint32 RaceMask; // 3 - uint32 ClassMask; // 4 - uint32 MinSkillLineRank; // 7 - uint32 SupercedesSpell; // 8 - uint32 AquireMethod; // 9 - uint32 TrivialSkillLineRankHigh; // 10 - uint32 TrivialSkillLineRankLow; // 11 - uint32 NumSkillUps; // 12 - uint32 UniqueBit; // 13 - uint32 TradeSkillCategoryID; // 14 -}; - -struct SkillRaceClassInfoEntry -{ - //uint32 ID; // 0 - uint32 SkillID; // 1 - int32 RaceMask; // 2 - int32 ClassMask; // 3 - uint32 Flags; // 4 - uint32 Availability; // 5 - uint32 MinLevel; // 6 - uint32 SkillTierID; // 7 -}; - -// SpellEffect.dbc -struct SpellEffectEntry -{ - uint32 ID; // 0 - uint32 DifficultyID; // 1 - uint32 Effect; // 2 - float EffectAmplitude; // 3 - uint32 EffectAura; // 4 - uint32 EffectAuraPeriod; // 5 - uint32 EffectBasePoints; // 6 - float EffectBonusCoefficient; // 7 - float EffectChainAmplitude; // 8 - uint32 EffectChainTargets; // 9 - uint32 EffectDieSides; // 10 - uint32 EffectItemType; // 11 - uint32 EffectMechanic; // 12 - int32 EffectMiscValue; // 13 - int32 EffectMiscValueB; // 14 - float EffectPointsPerResource; // 15 - uint32 EffectRadiusIndex; // 16 - uint32 EffectRadiusMaxIndex; // 17 - float EffectRealPointsPerLevel; // 18 - flag128 EffectSpellClassMask; // 19-22 - uint32 EffectTriggerSpell; // 23 - float EffectPosFacing; // 24 - uint32 ImplicitTarget[2]; // 25-26 - uint32 SpellID; // 27 - uint32 EffectIndex; // 28 - uint32 EffectAttributes; // 29 - float BonusCoefficientFromAP; // 30 -}; - -#define MAX_SPELL_EFFECTS 32 -#define MAX_EFFECT_MASK 0xFFFFFFFF - -// SpellEffectScaling.dbc -struct SpellEffectScalingEntry -{ - uint32 ID; // 0 - float Coefficient; // 1 - float Variance; // 2 - float ResourceCoefficient; // 3 - uint32 SpellEffectID; // 4 -}; - -// SpellAuraOptions.dbc -struct SpellAuraOptionsEntry -{ - uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 DifficultyID; // 2 - uint32 CumulativeAura; // 3 - uint32 ProcChance; // 4 - uint32 ProcCharges; // 5 - uint32 ProcTypeMask; // 6 - uint32 ProcCategoryRecovery; // 7 - uint32 SpellProcsPerMinuteID; // 8 -}; - -// Spell.dbc -struct SpellEntry -{ - uint32 ID; // 0 - char* Name_lang; // 1 - //char* NameSubtext_lang; // 2 - //char* Description_lang; // 3 - //char* AuraDescription_lang; // 4 - uint32 RuneCostID; // 5 - uint32 SpellMissileID; // 6 - uint32 DescriptionVariablesID; // 7 - uint32 ScalingID; // 8 - uint32 AuraOptionsID; // 9 - uint32 AuraRestrictionsID; // 10 - uint32 CastingRequirementsID; // 11 - uint32 CategoriesID; // 12 - uint32 ClassOptionsID; // 13 - uint32 CooldownsID; // 14 - uint32 EquippedItemsID; // 15 - uint32 InterruptsID; // 16 - uint32 LevelsID; // 17 - uint32 ReagentsID; // 18 - uint32 ShapeshiftID; // 19 - uint32 TargetRestrictionsID; // 20 - uint32 TotemsID; // 21 - uint32 RequiredProjectID; // 22 - uint32 MiscID; // 23 -}; - -// SpellCategories.dbc -struct SpellCategoriesEntry -{ - //uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 DifficultyID; // 2 - uint32 Category; // 3 - uint32 DefenseType; // 4 - uint32 DispelType; // 5 - uint32 Mechanic; // 6 - uint32 PreventionType; // 7 - uint32 StartRecoveryCategory; // 8 - uint32 ChargeCategory; // 9 -}; - -struct SpellCategoryEntry -{ - uint32 ID; // 0 - uint32 Flags; // 1 - //uint8 UsesPerWeek; // 2 - //uint8 Padding[3]; // 2 - //char* Name_lang; // 3 - int32 MaxCharges; // 4 - int32 ChargeRecoveryTime; // 5 -}; - -struct SpellFocusObjectEntry -{ - uint32 ID; // 0 - //char* Name_lang; // 1 -}; - -// SpellEquippedItems.dbc -struct SpellEquippedItemsEntry -{ - //uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 DifficultyID; // 2 - int32 EquippedItemClass; // 3 m_equippedItemClass (value) - int32 EquippedItemInventoryTypeMask; // 4 m_equippedItemInvTypes (mask) - int32 EquippedItemSubClassMask; // 5 m_equippedItemSubclass (mask) -}; - -// SpellCooldowns.dbc -struct SpellCooldownsEntry -{ - //uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 DifficultyID; // 2 - uint32 CategoryRecoveryTime; // 3 - uint32 RecoveryTime; // 4 - uint32 StartRecoveryTime; // 5 -}; - -// SpellInterrupts.dbc -struct SpellInterruptsEntry -{ - //uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 DifficultyID; // 2 - uint32 AuraInterruptFlags[2]; // 3-4 - uint32 ChannelInterruptFlags[2]; // 5-6 - uint32 InterruptFlags; // 7 -}; - -// SpellLevels.dbc -struct SpellLevelsEntry -{ - //uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 DifficultyID; // 2 - uint32 BaseLevel; // 3 - uint32 MaxLevel; // 4 - uint32 SpellLevel; // 5 -}; - -#define MAX_SHAPESHIFT_SPELLS 8 - -struct SpellShapeshiftFormEntry -{ - uint32 ID; // 0 - //uint32 BonusActionBar; // 1 - //char* Name_lang; // 2 - uint32 Flags; // 3 - int32 CreatureType; // 4 <=0 humanoid, other normal creature types - //uint32 AttackIconID; // 5 unused, related to next field - uint32 CombatRoundTime; // 6 - uint32 CreatureDisplayID[4]; // 7-10 (0 - Alliance, 1 - Horde) - uint32 PresetSpellID[MAX_SHAPESHIFT_SPELLS]; // 11-18 spells which appear in the bar after shapeshifting - //uint32 MountTypeID; // 19 - //uint32 ExitSoundEntriesID; // 20 -}; - -// SpellShapeshift.dbc -struct SpellShapeshiftEntry -{ - uint32 ID; // 0 - uint32 ShapeshiftExclude[2]; // 1-2 - uint32 ShapeshiftMask[2]; // 3-4 - //uint32 StanceBarOrder; // 5 -}; - -// SpellTargetRestrictions.dbc -struct SpellTargetRestrictionsEntry -{ - uint32 ID; // 0 - uint32 SpellID; // 1 - uint32 DifficultyID; // 2 - float ConeAngle; // 3 - float Width; // 4 - uint32 MaxAffectedTargets; // 5 - uint32 MaxTargetLevel; // 6 - uint32 TargetCreatureType; // 7 - uint32 Targets; // 8 -}; - -// SpellScaling.dbc -struct SpellScalingEntry -{ - uint32 ID; // 0 - int32 CastTimeMin; // 1 - int32 CastTimeMax; // 2 - uint32 CastTimeMaxLevel; // 3 - int32 ScalingClass; // 4 - float NerfFactor; // 5 - uint32 NerfMaxLevel; // 6 - uint32 MaxScalingLevel; // 7 - uint32 ScalesFromItemLevel; // 8 -}; - #define MAX_ITEM_ENCHANTMENT_EFFECTS 3 struct SpellItemEnchantmentEntry @@ -1227,16 +735,18 @@ struct SpellItemEnchantmentEntry //char* Name_lang // 11 uint32 ItemVisual; // 12 uint32 Flags; // 13 - uint32 SRCItemID; // 14 - uint32 ConditionID; // 15 - uint32 RequiredSkillID; // 16 - uint32 RequiredSkillRank; // 17 - uint32 MinLevel; // 18 - uint32 MaxLevel; // 19 - uint32 ItemLevel; // 20 - int32 ScalingClass; // 21 - int32 ScalingClassRestricted; // 22 - float EffectScalingPoints[MAX_ITEM_ENCHANTMENT_EFFECTS];//23-25 + uint32 ConditionID; // 14 + uint32 RequiredSkillID; // 15 + uint32 RequiredSkillRank; // 16 + uint32 MinLevel; // 17 + uint32 MaxLevel; // 18 + uint32 ItemLevel; // 19 + int32 ScalingClass; // 20 + int32 ScalingClassRestricted; // 21 + float EffectScalingPoints[MAX_ITEM_ENCHANTMENT_EFFECTS];//22-24 + //uint32 PlayerConditionID; // 25 + //uint32 TransmogCost; // 26 + //uint32 TextureFileDataID; // 27 }; struct StableSlotPricesEntry @@ -1423,20 +933,6 @@ struct WorldMapAreaEntry //uint32 LevelRangeMax; // 13 Maximum recommended level displayed on world map }; -struct WorldMapTransformsEntry -{ - //uint32 ID; // 0 - uint32 MapID; // 1 - DBCPosition3D RegionMin; // 2 - DBCPosition3D RegionMax; // 3 - uint32 NewMapID; // 4 - DBCPosition2D RegionOffset; // 5 - //uint32 NewDungeonMapID; // 6 - //uint32 Flags; // 7 - //uint32 NewAreaID; // 8 - float RegionScale; // 9 -}; - struct WorldSafeLocsEntry { uint32 ID; // 0 diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 171eec94266..b85710acae6 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -22,64 +22,27 @@ // x - skip<uint32>, X - skip<uint8>, s - char*, f - float, i - uint32, b - uint8, d - index (not included) // n - index (included), l - uint64, p - field present in sql dbc, a - field absent in sql dbc -char const AnimKitfmt[] = "nxxx"; -char const AreaTablefmt[] = "niiiiixxxxxxisiiiiixxxxxxxxxx"; +char const AreaTablefmt[] = "niiiiixxxxxxisiiiiixxxxxxxxx"; char const AreaTriggerfmt[] = "nifffxxxfffffxxxx"; -char const ArmorLocationfmt[] = "nfffff"; -char const BankBagSlotPricesfmt[] = "ni"; char const BannedAddOnsfmt[] = "nxxxxxxxxxx"; char const BattlemasterListfmt[] = "niiiiiiiiiiiiiiiiixsiiiixxxxxxx"; char const CharSectionsfmt[] = "diiixxxiii"; char const CharTitlesfmt[] = "nxssix"; char const ChatChannelsfmt[] = "nixsx"; char const ChrClassesfmt[] = "nixsxxxixiiiiixxxxx"; -char const ChrRacesfmt[] = "niixiixxxxxxiisxxxxxxxxxxxxxxxxxxxxxxxxx"; -char const ChrSpecializationfmt[] = "nxiiiiiiiiixxxii"; -char const CreatureDisplayInfoExtrafmt[] = "dixxxxxxxxxxxxxxxxxxxx"; +char const ChrSpecializationfmt[] = "nxiiiiiiiixxxxx"; char const CreatureFamilyfmt[] = "nfifiiiiixsx"; -char const CreatureModelDatafmt[] = "niixxxxxxxxxxxxffxxxxxxxxxxxxxxxxx"; +char const CreatureModelDatafmt[] = "niixxxxxxxxxxxxxxffxxxxxxxxxxxxxxxxx"; char const DifficultyFmt[] = "niiiixiixxxxix"; char const DungeonEncounterfmt[] = "niiixsxxx"; -char const DurabilityCostsfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; char const Emotesfmt[] = "nxxiiixx"; char const EmotesTextfmt[] = "nxixxxxxxxxxxxxxxxx"; char const EmotesTextSoundEntryfmt[] = "niiii"; char const Factionfmt[] = "niiiiiiiiiiiiiiiiiiffixsxixx"; char const FactionTemplatefmt[] = "niiiiiiiiiiiii"; -char const GameObjectDisplayInfofmt[] = "nixxxxxxxxxxffffffxxx"; char const GemPropertiesfmt[] = "nixxii"; char const GlyphPropertiesfmt[] = "niiix"; -char const GtArmorMitigationByLvlfmt[] = "xf"; -char const GtBarberShopCostBasefmt[] = "xf"; -char const GtCombatRatingsfmt[] = "xf"; -char const GtOCTHpPerStaminafmt[] = "df"; -char const GtOCTLevelExperiencefmt[] = "xf"; -char const GtChanceToMeleeCritBasefmt[] = "xf"; -char const GtChanceToMeleeCritfmt[] = "xf"; -char const GtChanceToSpellCritBasefmt[] = "xf"; -char const GtChanceToSpellCritfmt[] = "xf"; -char const GtItemSocketCostPerLevelfmt[] = "xf"; -char const GtNPCManaCostScalerfmt[] = "xf"; -char const GtNpcTotalHpfmt[] = "xf"; -char const GtNpcTotalHpExp1fmt[] = "xf"; -char const GtNpcTotalHpExp2fmt[] = "xf"; -char const GtNpcTotalHpExp3fmt[] = "xf"; -char const GtNpcTotalHpExp4fmt[] = "xf"; -char const GtNpcTotalHpExp5fmt[] = "xf"; -char const GtRegenMPPerSptfmt[] = "xf"; -char const GtSpellScalingfmt[] = "df"; -char const GtOCTBaseHPByClassfmt[] = "df"; -char const GtOCTBaseMPByClassfmt[] = "df"; -char const GuildColorBackgroundfmt[] = "nXXX"; -char const GuildColorBorderfmt[] = "nXXX"; -char const GuildColorEmblemfmt[] = "nXXX"; -char const ItemBagFamilyfmt[] = "nx"; -char const ItemArmorQualityfmt[] = "nfffffffi"; -char const ItemArmorShieldfmt[] = "nifffffff"; -char const ItemArmorTotalfmt[] = "niffff"; -char const ItemDamagefmt[] = "nfffffffi"; char const ItemSetfmt[] = "nsiiiiiiiiiiiiiiiiiii"; -char const ItemSetSpellfmt[] = "niiii"; char const LFGDungeonfmt[] = "nsiiixxiiiixxixixxxxxxxxxxxxxx"; char const Lightfmt[] = "nifffxxxxxxxxxx"; char const LiquidTypefmt[] = "nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; @@ -87,42 +50,15 @@ char const Lockfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; char const Mapfmt[] = "nxiixxsixxixiffxiiiiix"; char const MapDifficultyfmt[] = "diisiiii"; char const MinorTalentfmt[] = "niii"; -char const Moviefmt[] = "nxxxx"; char const Phasefmt[] = "ni"; -char const QuestFactionRewardfmt[] = "niiiiiiiiii"; -char const PowerDisplayfmt[] = "nixXXX"; char const PvpDifficultyfmt[] = "diiii"; -char const RandPropPointsfmt[] = "niiiiiiiiiiiiiii"; -char const SkillLinefmt[] = "nisxixixx"; -char const SkillLineAbilityfmt[] = "niiiiiiiiiiii"; -char const SkillRaceClassInfofmt[] = "diiiiiii"; -char const SpellCategoriesfmt[] = "diiiiiiiii"; -char const SpellCategoryfmt[] = "nixxii"; -char const SpellEffectfmt[] = "niifiiiffiiiiiifiifiiiiifiiiiif"; -const std::string CustomSpellEffectfmt = "ppppppppppppppappppppppppp"; -const std::string CustomSpellEffectEntryIndex = "Id"; -char const Spellfmt[] = "nsxxxiiiiiiiiiiiiiiiiiii"; -const std::string CustomSpellfmt = "ppppppppppppppapaaaaaaaaapaaaaaapapppaapppaaapa"; -const std::string CustomSpellEntryIndex = "Id"; -char const SpellEffectScalingfmt[] = "nfffi"; -char const SpellFocusObjectfmt[] = "nx"; -char const SpellItemEnchantmentfmt[] = "niiiiiiiiiixiiiiiiiiiiifff"; -char const SpellScalingfmt[] = "niiiifiii"; -char const SpellTargetRestrictionsfmt[] = "niiffiiii"; -char const SpellInterruptsfmt[] = "diiiiiii"; -char const SpellEquippedItemsfmt[] = "diiiii"; -char const SpellAuraOptionsfmt[] = "niiiiiiii"; -char const SpellCooldownsfmt[] = "diiiii"; -char const SpellLevelsfmt[] = "diiiii"; -char const SpellShapeshiftfmt[] = "niiiix"; -char const SpellShapeshiftFormfmt[] = "nxxiixiiiiiiiiiiiiixx"; +char const SpellItemEnchantmentfmt[] = "niiiiiiiiiixiiiiiiiiiifffxxx"; char const SummonPropertiesfmt[] = "niiiii"; char const Talentfmt[] = "niiiiiiiiix"; char const Vehiclefmt[] = "niiffffiiiiiiiifffffffffffffffxxxxfifiiii"; char const VehicleSeatfmt[] = "niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiffffffffffffiiiiiiiii"; char const WMOAreaTablefmt[] = "niiixxxxxiixxxx"; char const WorldMapAreafmt[] = "xinxffffixxxxx"; -char const WorldMapTransformsfmt[] = "diffffffiffxxxf"; char const WorldSafeLocsfmt[] = "niffffx"; #endif diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 42d7ff404db..9c524413aba 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2052,8 +2052,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* uint32 modelId = m_goInfo->displayId; if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec)) - if (modelData->StateDamaged.DisplayID) - modelId = modelData->StateDamaged.DisplayID; + if (modelData->StateDamagedDisplayID) + modelId = modelData->StateDamagedDisplayID; SetDisplayId(modelId); if (setHealth) @@ -2080,8 +2080,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* uint32 modelId = m_goInfo->displayId; if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec)) - if (modelData->StateDestroyed.DisplayID) - modelId = modelData->StateDestroyed.DisplayID; + if (modelData->StateDestroyedDisplayID) + modelId = modelData->StateDestroyedDisplayID; SetDisplayId(modelId); if (setHealth) @@ -2099,8 +2099,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* uint32 modelId = m_goInfo->displayId; if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->destructibleBuilding.DestructibleModelRec)) - if (modelData->StateRebuilding.DisplayID) - modelId = modelData->StateRebuilding.DisplayID; + if (modelData->StateRebuildingDisplayID) + modelId = modelData->StateRebuildingDisplayID; SetDisplayId(modelId); // restores to full health diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 20f1772ef00..3eba4d58d80 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -78,28 +78,29 @@ void AddItemsSetItem(Player* player, Item* item) ++eff->EquippedItemCount; - ItemSetSpells& spells = sItemSetSpellsStore[setid]; - - for (ItemSetSpellEntry const* itemSetSpell : spells) + if (std::vector<ItemSetSpellEntry const*> const* itemSetSpells = sDB2Manager.GetItemSetSpells(setid)) { - //not enough for spell - if (itemSetSpell->Threshold > eff->EquippedItemCount) - continue; + for (ItemSetSpellEntry const* itemSetSpell : *itemSetSpells) + { + //not enough for spell + if (itemSetSpell->Threshold > eff->EquippedItemCount) + continue; - if (eff->SetBonuses.count(itemSetSpell)) - continue; + if (eff->SetBonuses.count(itemSetSpell)) + continue; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemSetSpell->SpellID); - if (!spellInfo) - { - TC_LOG_ERROR("entities.player.items", "WORLD: unknown spell id %u in items set %u effects", itemSetSpell->SpellID, setid); - continue; - } + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemSetSpell->SpellID); + if (!spellInfo) + { + TC_LOG_ERROR("entities.player.items", "WORLD: unknown spell id %u in items set %u effects", itemSetSpell->SpellID, setid); + continue; + } - eff->SetBonuses.insert(itemSetSpell); - // spell cast only if fit form requirement, in other case will cast at form change - if (!itemSetSpell->ChrSpecID || itemSetSpell->ChrSpecID == player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID)) - player->ApplyEquipSpell(spellInfo, NULL, true); + eff->SetBonuses.insert(itemSetSpell); + // spell cast only if fit form requirement, in other case will cast at form change + if (!itemSetSpell->ChrSpecID || itemSetSpell->ChrSpecID == player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID)) + player->ApplyEquipSpell(spellInfo, NULL, true); + } } } @@ -132,18 +133,20 @@ void RemoveItemsSetItem(Player* player, ItemTemplate const* proto) --eff->EquippedItemCount; - ItemSetSpells const& spells = sItemSetSpellsStore[setid]; - for (ItemSetSpellEntry const* itemSetSpell : spells) + if (std::vector<ItemSetSpellEntry const*> const* itemSetSpells = sDB2Manager.GetItemSetSpells(setid)) { - // enough for spell - if (itemSetSpell->Threshold <= eff->EquippedItemCount) - continue; + for (ItemSetSpellEntry const* itemSetSpell : *itemSetSpells) + { + // enough for spell + if (itemSetSpell->Threshold <= eff->EquippedItemCount) + continue; - if (!eff->SetBonuses.count(itemSetSpell)) - continue; + if (!eff->SetBonuses.count(itemSetSpell)) + continue; - player->ApplyEquipSpell(sSpellMgr->AssertSpellInfo(itemSetSpell->SpellID), nullptr, false); - eff->SetBonuses.erase(itemSetSpell); + player->ApplyEquipSpell(sSpellMgr->AssertSpellInfo(itemSetSpell->SpellID), nullptr, false); + eff->SetBonuses.erase(itemSetSpell); + } } if (!eff->EquippedItemCount) //all items of a set were removed @@ -373,6 +376,21 @@ void Item::SaveToDB(SQLTransaction& trans) stmt->setUInt64(1, GetGUID().GetCounter()); trans->Append(stmt); } + if (!GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).empty()) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_GEMS); + stmt->setUInt64(0, GetGUID().GetCounter()); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_INSTANCE_GEMS); + stmt->setUInt64(0, GetGUID().GetCounter()); + uint32 i = 0; + for (; i < MAX_GEM_SOCKETS && i < GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).size(); ++i) + stmt->setUInt32(1 + i, GetDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, i)); + for (; i < MAX_GEM_SOCKETS; ++i) + stmt->setUInt32(1 + i, 0); + trans->Append(stmt); + } break; } case ITEM_REMOVED: @@ -381,6 +399,10 @@ void Item::SaveToDB(SQLTransaction& trans) stmt->setUInt64(0, GetGUID().GetCounter()); trans->Append(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_GEMS); + stmt->setUInt64(0, GetGUID().GetCounter()); + trans->Append(stmt); + if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); @@ -413,7 +435,9 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie // 0 1 2 3 4 5 6 7 8 9 10 11 12 //result = CharacterDatabase.PQuery("SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, // 13 14 15 16 17 18 19 20 - // transmogrification, upgradeId, enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, bonusListIDs FROM item_instance WHERE guid = '%u'", guid); + // transmogrification, upgradeId, enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, bonusListIDs, + // 21 22 23 + // gemItemId1, gemItemId2, gemItemId3 FROM item_instance WHERE guid = '%u'", guid); // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB @@ -493,6 +517,17 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie SetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL, fields[18].GetUInt16()); SetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID, fields[19].GetUInt32()); + uint32 gemItemIds[3] = { fields[21].GetUInt32(), fields[22].GetUInt32(), fields[23].GetUInt32() }; + if (gemItemIds[0] || gemItemIds[1] || gemItemIds[2]) + { + // gem slots must be preserved, hence funky logic + AddDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, gemItemIds[0]); + if (gemItemIds[1] || gemItemIds[2]) + AddDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, gemItemIds[1]); + if (gemItemIds[2]) + AddDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, gemItemIds[2]); + } + Tokenizer bonusListIDs(fields[20].GetString(), ' '); for (char const* token : bonusListIDs) { @@ -582,27 +617,25 @@ int32 Item::GenerateItemRandomPropertyId(uint32 item_id) if (itemProto->GetRandomProperty()) { uint32 randomPropId = GetItemEnchantMod(itemProto->GetRandomProperty()); - ItemRandomPropertiesEntry const* random_id = sItemRandomPropertiesStore.LookupEntry(randomPropId); - if (!random_id) + if (!sItemRandomPropertiesStore.LookupEntry(randomPropId)) { TC_LOG_ERROR("sql.sql", "Enchantment id #%u used but it doesn't have records in 'ItemRandomProperties.dbc'", randomPropId); return 0; } - return random_id->ID; + return randomPropId; } // RandomSuffix case else { uint32 randomPropId = GetItemEnchantMod(itemProto->GetRandomSuffix()); - ItemRandomSuffixEntry const* random_id = sItemRandomSuffixStore.LookupEntry(randomPropId); - if (!random_id) + if (!sItemRandomSuffixStore.LookupEntry(randomPropId)) { TC_LOG_ERROR("sql.sql", "Enchantment id #%u used but it doesn't have records in sItemRandomSuffixStore.", randomPropId); return 0; } - return -int32(random_id->ID); + return -int32(randomPropId); } } @@ -613,12 +646,12 @@ void Item::SetItemRandomProperties(int32 randomPropId) if (randomPropId > 0) { - ItemRandomPropertiesEntry const* item_rand = sItemRandomPropertiesStore.LookupEntry(randomPropId); - if (item_rand) + ItemRandomPropertiesEntry const* item_rand = sItemRandomPropertiesStore.LookupEntry(-randomPropId); + if (sItemRandomPropertiesStore.LookupEntry(randomPropId)) { - if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != int32(item_rand->ID)) + if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != randomPropId) { - SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, item_rand->ID); + SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, randomPropId); SetState(ITEM_CHANGED, GetOwner()); } for (uint32 i = PROP_ENCHANTMENT_SLOT_1; i < PROP_ENCHANTMENT_SLOT_1 + 3; ++i) @@ -630,10 +663,9 @@ void Item::SetItemRandomProperties(int32 randomPropId) ItemRandomSuffixEntry const* item_rand = sItemRandomSuffixStore.LookupEntry(-randomPropId); if (item_rand) { - if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != -int32(item_rand->ID) || - !GetItemSuffixFactor()) + if (GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID) != randomPropId || !GetItemSuffixFactor()) { - SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, -int32(item_rand->ID)); + SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, randomPropId); UpdateItemSuffixFactor(); SetState(ITEM_CHANGED, GetOwner()); } @@ -924,36 +956,24 @@ void Item::ClearEnchantment(EnchantmentSlot slot) bool Item::GemsFitSockets() const { - for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) + uint32 gemSlot = 0; + for (uint32 gemItemId : GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS)) { - uint8 SocketColor = GetTemplate()->GetSocketColor(enchant_slot - SOCK_ENCHANTMENT_SLOT); - + uint8 SocketColor = GetTemplate()->GetSocketColor(gemSlot); if (!SocketColor) // no socket slot continue; - uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)); - if (!enchant_id) // no gems on this socket - return false; - - SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!enchantEntry) // invalid gem id on this socket - return false; - - uint8 GemColor = 0; + uint32 GemColor = 0; - uint32 gemid = enchantEntry->SRCItemID; - if (gemid) + ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemItemId); + if (gemProto) { - ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemid); - if (gemProto) - { - GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GetGemProperties()); - if (gemProperty) - GemColor = gemProperty->Type; - } + GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GetGemProperties()); + if (gemProperty) + GemColor = gemProperty->Type; } - if (!(GemColor & SocketColor)) // bad gem color on this socket + if (!(GemColor & SocketColorToGemTypeMask[SocketColor])) // bad gem color on this socket return false; } return true; @@ -961,44 +981,22 @@ bool Item::GemsFitSockets() const uint8 Item::GetGemCountWithID(uint32 GemID) const { - uint8 count = 0; - for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) + return std::count_if(GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).begin(), GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).end(), [GemID](uint32 gemItemId) { - uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)); - if (!enchant_id) - continue; - - SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!enchantEntry) - continue; - - if (GemID == enchantEntry->SRCItemID) - ++count; - } - return count; + return gemItemId == GemID; + }); } uint8 Item::GetGemCountWithLimitCategory(uint32 limitCategory) const { - uint8 count = 0; - for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) + return std::count_if(GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).begin(), GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).end(), [limitCategory](uint32 gemItemId) { - uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)); - if (!enchant_id) - continue; - - SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!enchantEntry) - continue; - - ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(enchantEntry->SRCItemID); + ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemItemId); if (!gemProto) - continue; + return false; - if (gemProto->GetItemLimitCategory() == limitCategory) - ++count; - } - return count; + return gemProto->GetItemLimitCategory() == limitCategory; + }); } bool Item::IsLimitedToAnotherMapOrZone(uint32 cur_mapId, uint32 cur_zoneId) const diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp index 7b30480df35..2f82071f66f 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp @@ -178,7 +178,7 @@ TC_GAME_API uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uin return 0; } - RandomPropertiesPointsEntry const* randPropPointsEntry = sRandomPropertiesPointsStore.LookupEntry(itemLevel); + RandPropPointsEntry const* randPropPointsEntry = sRandPropPointsStore.LookupEntry(itemLevel); if (!randPropPointsEntry) return 0; diff --git a/src/server/game/Entities/Item/ItemTemplate.cpp b/src/server/game/Entities/Item/ItemTemplate.cpp index ebed45eaaac..04873bdddcf 100644 --- a/src/server/game/Entities/Item/ItemTemplate.cpp +++ b/src/server/game/Entities/Item/ItemTemplate.cpp @@ -22,6 +22,29 @@ #include "ItemTemplate.h" #include "Player.h" +uint32 const SocketColorToGemTypeMask[19] = +{ + 0, + SOCKET_COLOR_META, + SOCKET_COLOR_RED, + SOCKET_COLOR_YELLOW, + SOCKET_COLOR_BLUE, + SOCKET_COLOR_HYDRAULIC, + SOCKET_COLOR_COGWHEEL, + SOCKET_COLOR_PRISMATIC, + SOCKET_COLOR_RELIC_IRON, + SOCKET_COLOR_RELIC_BLOOD, + SOCKET_COLOR_RELIC_SHADOW, + SOCKET_COLOR_RELIC_FEL, + SOCKET_COLOR_RELIC_ARCANE, + SOCKET_COLOR_RELIC_FROST, + SOCKET_COLOR_RELIC_FIRE, + SOCKET_COLOR_RELIC_WATER, + SOCKET_COLOR_RELIC_LIFE, + SOCKET_COLOR_RELIC_WIND, + SOCKET_COLOR_RELIC_HOLY +}; + char const* ItemTemplate::GetName(LocaleConstant locale) const { if (!strlen(ExtendedData->Name->Str[locale])) @@ -137,21 +160,21 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag if (GetClass() != ITEM_CLASS_WEAPON || quality > ITEM_QUALITY_ARTIFACT) return; - DBCStorage<ItemDamageEntry>* store = NULL; // get the right store here if (GetInventoryType() > INVTYPE_RANGEDRIGHT) return; + float dps = 0.0f; switch (GetInventoryType()) { case INVTYPE_AMMO: - store = &sItemDamageAmmoStore; + dps = sItemDamageAmmoStore.AssertEntry(itemLevel)->DPS[quality]; break; case INVTYPE_2HWEAPON: if (GetFlags2() & ITEM_FLAG2_CASTER_WEAPON) - store = &sItemDamageTwoHandCasterStore; + dps = sItemDamageTwoHandCasterStore.AssertEntry(itemLevel)->DPS[quality]; else - store = &sItemDamageTwoHandStore; + dps = sItemDamageTwoHandStore.AssertEntry(itemLevel)->DPS[quality]; break; case INVTYPE_RANGED: case INVTYPE_THROWN: @@ -159,15 +182,15 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag switch (GetSubClass()) { case ITEM_SUBCLASS_WEAPON_WAND: - store = &sItemDamageWandStore; - break; - case ITEM_SUBCLASS_WEAPON_THROWN: - store = &sItemDamageThrownStore; + dps = sItemDamageOneHandCasterStore.AssertEntry(itemLevel)->DPS[quality]; break; case ITEM_SUBCLASS_WEAPON_BOW: case ITEM_SUBCLASS_WEAPON_GUN: case ITEM_SUBCLASS_WEAPON_CROSSBOW: - store = &sItemDamageRangedStore; + if (GetFlags2() & ITEM_FLAG2_CASTER_WEAPON) + dps = sItemDamageTwoHandCasterStore.AssertEntry(itemLevel)->DPS[quality]; + else + dps = sItemDamageTwoHandStore.AssertEntry(itemLevel)->DPS[quality]; break; default: return; @@ -177,21 +200,14 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag case INVTYPE_WEAPONMAINHAND: case INVTYPE_WEAPONOFFHAND: if (GetFlags2() & ITEM_FLAG2_CASTER_WEAPON) - store = &sItemDamageOneHandCasterStore; + dps = sItemDamageOneHandCasterStore.AssertEntry(itemLevel)->DPS[quality]; else - store = &sItemDamageOneHandStore; + dps = sItemDamageOneHandStore.AssertEntry(itemLevel)->DPS[quality]; break; default: return; } - ASSERT(store); - - ItemDamageEntry const* damageInfo = store->LookupEntry(itemLevel); - if (!damageInfo) - return; - - float dps = damageInfo->DPS[quality]; float avgDamage = dps * GetDelay() * 0.001f; minDamage = (GetStatScalingFactor() * -0.5f + 1.0f) * avgDamage; maxDamage = floor(float(avgDamage * (GetStatScalingFactor() * 0.5f + 1.0f) + 0.5f)); diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index d69f1c88845..38265cc9fed 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -317,15 +317,29 @@ enum BAG_FAMILY_MASK enum SocketColor { - SOCKET_COLOR_META = 1, - SOCKET_COLOR_RED = 2, - SOCKET_COLOR_YELLOW = 4, - SOCKET_COLOR_BLUE = 8, - SOCKET_COLOR_HYDRAULIC = 16, // not used - SOCKET_COLOR_COGWHEEL = 32, -}; - -#define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE | SOCKET_COLOR_COGWHEEL) + SOCKET_COLOR_META = 0x00001, + SOCKET_COLOR_RED = 0x00002, + SOCKET_COLOR_YELLOW = 0x00004, + SOCKET_COLOR_BLUE = 0x00008, + SOCKET_COLOR_HYDRAULIC = 0x00010, // not used + SOCKET_COLOR_COGWHEEL = 0x00020, + SOCKET_COLOR_PRISMATIC = 0x0000E, + SOCKET_COLOR_RELIC_IRON = 0x00040, + SOCKET_COLOR_RELIC_BLOOD = 0x00080, + SOCKET_COLOR_RELIC_SHADOW = 0x00100, + SOCKET_COLOR_RELIC_FEL = 0x00200, + SOCKET_COLOR_RELIC_ARCANE = 0x00400, + SOCKET_COLOR_RELIC_FROST = 0x00800, + SOCKET_COLOR_RELIC_FIRE = 0x01000, + SOCKET_COLOR_RELIC_WATER = 0x02000, + SOCKET_COLOR_RELIC_LIFE = 0x04000, + SOCKET_COLOR_RELIC_WIND = 0x08000, + SOCKET_COLOR_RELIC_HOLY = 0x10000 +}; + +extern uint32 const SocketColorToGemTypeMask[19]; + +#define SOCKET_COLOR_STANDARD (SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE) enum InventoryType { @@ -646,10 +660,11 @@ class Player; struct TC_GAME_API ItemTemplate { + uint32 Id; ItemEntry const* BasicData; ItemSparseEntry const* ExtendedData; - uint32 GetId() const { return BasicData->ID; } + uint32 GetId() const { return Id; } uint32 GetClass() const { return BasicData->Class; } uint32 GetSubClass() const { return BasicData->SubClass; } uint32 GetQuality() const { return ExtendedData->Quality; } @@ -658,7 +673,7 @@ struct TC_GAME_API ItemTemplate uint32 GetFlags3() const { return ExtendedData->Flags[2]; } float GetUnk1() const { return ExtendedData->Unk1; } float GetUnk2() const { return ExtendedData->Unk2; } - uint32 GetBuyCount() const { return std::max(ExtendedData->BuyCount, 1u); } + uint32 GetBuyCount() const { return std::max<uint32>(ExtendedData->BuyCount, 1u); } uint32 GetBuyPrice() const { return ExtendedData->BuyPrice; } uint32 GetSellPrice() const { return ExtendedData->SellPrice; } InventoryType GetInventoryType() const { return InventoryType(ExtendedData->InventoryType); } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index f9fa1b3aeb6..67d8d89cdf6 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1341,6 +1341,13 @@ std::vector<uint32> const& Object::GetDynamicValues(uint16 index) const return _dynamicValues[index]; } +uint32 Object::GetDynamicValue(uint16 index, uint8 offset) const +{ + ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false)); + ASSERT(offset < _dynamicValues[index].size()); + return _dynamicValues[index][offset]; +} + void Object::AddDynamicValue(uint16 index, uint32 value) { ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false)); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 503555037e1..bd31af9363c 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -168,6 +168,7 @@ class TC_GAME_API Object void ApplyModFlag64(uint16 index, uint64 flag, bool apply); std::vector<uint32> const& GetDynamicValues(uint16 index) const; + uint32 GetDynamicValue(uint16 index, uint8 offset) const; void AddDynamicValue(uint16 index, uint32 value); void RemoveDynamicValue(uint16 index, uint32 value); void ClearDynamicValue(uint16 index); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 90f1c829bb9..38a47d999a9 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -421,7 +421,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac return false; } - if (!ValidateAppearance(createInfo->Race, createInfo->Class, createInfo->Sex, createInfo->HairStyle, createInfo->HairColor, createInfo->Face, createInfo->FacialHairStyle, createInfo->Skin, true)) + if (!ValidateAppearance(createInfo->Race, createInfo->Class, createInfo->Sex, createInfo->HairStyle, createInfo->HairColor, createInfo->Face, createInfo->FacialHairStyle, createInfo->Skin, createInfo->CustomDisplay, true)) { TC_LOG_ERROR("entities.player", "Player::Create: Possible hacking-attempt: Account %u tried creating a character named '%s' with invalid appearance attributes - refusing to do so", GetSession()->GetAccountId(), m_name.c_str()); @@ -1805,20 +1805,21 @@ void Player::RegenerateAll() // Runes act as cooldowns, and they don't need to send any data if (getClass() == CLASS_DEATH_KNIGHT) { - for (uint8 i = 0; i < MAX_RUNES; i += 2) + uint32 regeneratedRunes = 0; + uint32 regenIndex = 0; + while (regeneratedRunes < MAX_RECHARGING_RUNES && !m_runes->CooldownOrder.empty()) { - uint8 runeToRegen = i; - uint32 cd = GetRuneCooldown(i); - uint32 secondRuneCd = GetRuneCooldown(i + 1); - // Regenerate second rune of the same type only after first rune is off the cooldown - if (secondRuneCd && (cd > secondRuneCd || !cd)) + uint8 runeToRegen = m_runes->CooldownOrder[regenIndex++]; + uint32 runeCooldown = GetRuneCooldown(runeToRegen); + if (runeCooldown > m_regenTimer) { - runeToRegen = i + 1; - cd = secondRuneCd; + SetRuneCooldown(runeToRegen, runeCooldown - m_regenTimer); + ++regenIndex; } + else + SetRuneCooldown(runeCooldown, 0); - if (cd) - SetRuneCooldown(runeToRegen, (cd > m_regenTimer) ? cd - m_regenTimer : 0); + ++regeneratedRunes; } } @@ -2055,8 +2056,8 @@ void Player::ResetAllPowers() case POWER_RUNIC_POWER: SetPower(POWER_RUNIC_POWER, 0); break; - case POWER_ECLIPSE: - SetPower(POWER_ECLIPSE, 0); + case POWER_LUNAR_POWER: + SetPower(POWER_LUNAR_POWER, 0); break; default: break; @@ -3142,12 +3143,12 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent if (!pSkill) continue; - if (pSkill->ID == fromSkill) + if (_spell_idx->second->SkillLine == fromSkill) continue; // Runeforging special case - if ((_spell_idx->second->AquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(pSkill->ID)) || ((pSkill->ID == SKILL_RUNEFORGING_2) && _spell_idx->second->TrivialSkillLineRankHigh == 0)) - if (SkillRaceClassInfoEntry const* rcInfo = GetSkillRaceClassInfo(pSkill->ID, getRace(), getClass())) + if ((_spell_idx->second->AquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(_spell_idx->second->SkillLine)) || ((_spell_idx->second->SkillLine == SKILL_RUNEFORGING_2) && _spell_idx->second->TrivialSkillLineRankHigh == 0)) + if (SkillRaceClassInfoEntry const* rcInfo = sDB2Manager.GetSkillRaceClassInfo(_spell_idx->second->SkillLine, getRace(), getClass())) LearnDefaultSkill(rcInfo); } } @@ -3230,7 +3231,7 @@ bool Player::IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const bool Player::IsCurrentSpecMasterySpell(SpellInfo const* spellInfo) const { if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetSpecId(GetActiveTalentGroup()))) - return spellInfo->Id == chrSpec->MasterySpellID[0] || spellInfo->Id == chrSpec->MasterySpellID[1]; + return spellInfo->Id == chrSpec->MasterySpellID; return false; } @@ -3968,6 +3969,10 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe stmt->setUInt64(0, guid); trans->Append(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_GEMS_BY_OWNER); + stmt->setUInt64(0, guid); + trans->Append(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER); stmt->setUInt64(0, guid); trans->Append(stmt); @@ -4217,7 +4222,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) SetPower(POWER_RAGE, 0); SetPower(POWER_ENERGY, uint32(GetMaxPower(POWER_ENERGY)*restore_percent)); SetPower(POWER_FOCUS, uint32(GetMaxPower(POWER_FOCUS)*restore_percent)); - SetPower(POWER_ECLIPSE, 0); + SetPower(POWER_LUNAR_POWER, 0); } // trigger update zone for alive state zone updates @@ -5326,7 +5331,7 @@ void Player::UpdateSkillsForLevel() continue; uint32 pskill = itr->first; - SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(pskill, getRace(), getClass()); + SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(pskill, getRace(), getClass()); if (!rcEntry) continue; @@ -5363,7 +5368,7 @@ void Player::UpdateSkillsToMaxSkillsForLevel() continue; uint32 pskill = itr->first; - SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(pskill, getRace(), getClass()); + SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(pskill, getRace(), getClass()); if (!rcEntry) continue; @@ -6129,7 +6134,7 @@ void Player::RewardReputation(Quest const* quest) else { uint32 row = ((quest->RewardFactionValue[i] < 0) ? 1 : 0) + 1; - if (QuestFactionRewEntry const* questFactionRewEntry = sQuestFactionRewardStore.LookupEntry(row)) + if (QuestFactionRewardEntry const* questFactionRewEntry = sQuestFactionRewardStore.LookupEntry(row)) { uint32 field = abs(quest->RewardFactionValue[i]); rep = questFactionRewEntry->QuestRewFactionValue[field]; @@ -9764,7 +9769,7 @@ bool Player::HasItemTotemCategory(uint32 TotemCategory) const for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i) { item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i); - if (item && IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory)) + if (item && DB2Manager::IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory)) return true; } @@ -9777,7 +9782,7 @@ bool Player::HasItemTotemCategory(uint32 TotemCategory) const for (uint32 j = 0; j < bag->GetBagSize(); ++j) { item = GetUseableItemByPos(i, j); - if (item && IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory)) + if (item && DB2Manager::IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory)) return true; } } @@ -12763,20 +12768,23 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool if (pEnchant->RequiredSkillID > 0 && pEnchant->RequiredSkillRank > GetSkillValue(pEnchant->RequiredSkillID)) return; - // Cogwheel gems dont have requirement data set in SpellItemEnchantment.dbc, but they do have it in Item-sparse.db2 - if (ItemTemplate const* gem = sObjectMgr->GetItemTemplate(pEnchant->SRCItemID)) - if (gem->GetRequiredSkill() && GetSkillValue(gem->GetRequiredSkill()) < gem->GetRequiredSkillRank()) - return; // If we're dealing with a gem inside a prismatic socket we need to check the prismatic socket requirements // rather than the gem requirements itself. If the socket has no color it is a prismatic socket. - if ((slot == SOCK_ENCHANTMENT_SLOT || slot == SOCK_ENCHANTMENT_SLOT_2 || slot == SOCK_ENCHANTMENT_SLOT_3) - && !item->GetSocketColor(slot - SOCK_ENCHANTMENT_SLOT)) + if ((slot == SOCK_ENCHANTMENT_SLOT || slot == SOCK_ENCHANTMENT_SLOT_2 || slot == SOCK_ENCHANTMENT_SLOT_3)) { - // Check if the requirements for the prismatic socket are met before applying the gem stats - SpellItemEnchantmentEntry const* pPrismaticEnchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT)); - if (!pPrismaticEnchant || (pPrismaticEnchant->RequiredSkillID > 0 && pPrismaticEnchant->RequiredSkillRank > GetSkillValue(pPrismaticEnchant->RequiredSkillID))) - return; + if (!item->GetSocketColor(slot - SOCK_ENCHANTMENT_SLOT)) + { + // Check if the requirements for the prismatic socket are met before applying the gem stats + SpellItemEnchantmentEntry const* pPrismaticEnchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT)); + if (!pPrismaticEnchant || (pPrismaticEnchant->RequiredSkillID > 0 && pPrismaticEnchant->RequiredSkillRank > GetSkillValue(pPrismaticEnchant->RequiredSkillID))) + return; + } + + // Cogwheel gems dont have requirement data set in SpellItemEnchantment.dbc, but they do have it in Item-sparse.db2 + if (ItemTemplate const* gem = sObjectMgr->GetItemTemplate(item->GetDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, uint32(slot - SOCK_ENCHANTMENT_SLOT)))) + if (gem->GetRequiredSkill() && GetSkillValue(gem->GetRequiredSkill()) < gem->GetRequiredSkillRank()) + return; } if (!item->IsBroken()) @@ -16357,7 +16365,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_HAIR_COLOR_ID), GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID), GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE), - GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID))) + GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID), + std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE>{ fields[14].GetUInt8(), fields[15].GetUInt8(), fields[16].GetUInt8() })) { TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong Appearance values (Hair/Skin/Color), can't load.", guid.ToString().c_str()); return false; @@ -16922,7 +16931,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) for (; loadedPowers < MAX_POWERS_PER_CLASS; ++loadedPowers) SetUInt32Value(UNIT_FIELD_POWER + loadedPowers, 0); - SetPower(POWER_ECLIPSE, 0); + SetPower(POWER_LUNAR_POWER, 0); TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: The value of player '%s' after load item and aura is: ", m_name.c_str()); outDebugValues(); @@ -17265,8 +17274,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // SELECT ii.guid, ii.itemEntry, ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomPropertyId, ii.durability, ii.playedTime, ii.text, ii.transmogrification, ii.upgradeId - // 15 16 17 18 19 20 21 22 - // ii.enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, ii.bonusListIDs, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot + // 15 16 17 18 19 20 21 22 23 24 25 + // ii.enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, ii.bonusListIDs, ig.gemItemId1, ig.gemItemId2, ig.gemItemId3, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot //NOTE: the "order by `bag`" is important because it makes sure //the bagMap is filled before items in the bags are loaded //NOTE2: the "order by `slot`" is needed because mainhand weapons are (wrongly?) @@ -17288,8 +17297,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) Field* fields = result->Fetch(); if (Item* item = _LoadItem(trans, zoneId, timeDiff, fields)) { - ObjectGuid bagGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[21].GetUInt64()) : ObjectGuid::Empty; - uint8 slot = fields[22].GetUInt8(); + ObjectGuid bagGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[24].GetUInt64()) : ObjectGuid::Empty; + uint8 slot = fields[25].GetUInt8(); GetSession()->GetCollectionMgr()->CheckHeirloomUpgrades(item); @@ -21560,23 +21569,11 @@ bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) if (i == slot) continue; Item* pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem2 && !pItem2->IsBroken() && pItem2->GetTemplate()->GetSocketColor(0)) + if (pItem2 && !pItem2->IsBroken()) { - for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + for (uint32 gemItemId : pItem2->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS)) { - uint32 enchant_id = pItem2->GetEnchantmentId(EnchantmentSlot(enchant_slot)); - if (!enchant_id) - continue; - - SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!enchantEntry) - continue; - - uint32 gemid = enchantEntry->SRCItemID; - if (!gemid) - continue; - - ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemid); + ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemItemId); if (!gemProto) continue; @@ -21584,13 +21581,11 @@ bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot) if (!gemProperty) continue; - uint8 GemColor = gemProperty->Type; + uint32 GemColor = gemProperty->Type; for (uint8 b = 0, tmpcolormask = 1; b < 4; b++, tmpcolormask <<= 1) - { if (tmpcolormask & GemColor) ++curcount[b]; - } } } } @@ -23498,7 +23493,7 @@ void Player::ResurrectUsingRequestDataImpl() SetPower(POWER_RAGE, 0); SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY)); SetPower(POWER_FOCUS, GetMaxPower(POWER_FOCUS)); - SetPower(POWER_ECLIPSE, 0); + SetPower(POWER_LUNAR_POWER, 0); if (uint32 aura = _resurrectionData->Aura) CastSpell(this, aura, true, nullptr, nullptr, _resurrectionData->GUID); @@ -24005,16 +24000,16 @@ uint32 Player::GetBarberShopCost(BarberShopStyleEntry const* newHairStyle, uint8 void Player::InitGlyphsForLevel() { - uint32 slotMask = 0; - uint8 slot = 0; - uint8 level = getLevel(); - for (GlyphSlotEntry const* gs : sDB2Manager.GetGlyphSlots()) - { - if (level >= ((gs->Tooltip + 1) * 25)) - slotMask |= 1 << slot; + //uint32 slotMask = 0; + //uint8 slot = 0; + //uint8 level = getLevel(); + //for (GlyphSlotEntry const* gs : sDB2Manager.GetGlyphSlots()) + //{ + // if (level >= ((gs->Tooltip + 1) * 25)) + // slotMask |= 1 << slot; - SetGlyphSlot(slot++, gs->ID); - } + // SetGlyphSlot(slot++, gs->ID); + //} } void Player::SetGlyph(uint8 slot, uint32 glyph) @@ -24095,7 +24090,7 @@ bool Player::isTotalImmunity() const return false; } -uint32 Player::GetRuneTypeBaseCooldown() const +uint32 Player::GetRuneBaseCooldown() const { float cooldown = RUNE_BASE_COOLDOWN; @@ -24133,72 +24128,33 @@ void Player::SetRuneCooldown(uint8 index, uint32 cooldown, bool casted /*= false SetRuneTimer(index, 0); } - m_runes->runes[index].Cooldown = cooldown; + m_runes->Cooldown[index] = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); } -void Player::SetRuneConvertAura(uint8 index, AuraEffect const* aura) -{ - m_runes->runes[index].ConvertAura = aura; -} - -void Player::AddRuneByAuraEffect(uint8 index, RuneType newType, AuraEffect const* aura) +void Runes::SetRuneState(uint8 index, bool set /*= true*/) { - SetRuneConvertAura(index, aura); ConvertRune(index, newType); -} - -void Player::RemoveRunesByAuraEffect(AuraEffect const* aura) -{ - for (uint8 i = 0; i < MAX_RUNES; ++i) + auto itr = std::find(CooldownOrder.begin(), CooldownOrder.end(), index); + if (set) { - if (m_runes->runes[i].ConvertAura == aura) - { - ConvertRune(i, GetBaseRune(i)); - SetRuneConvertAura(i, nullptr); - } + RuneState |= (1 << index); // usable + if (itr == CooldownOrder.end()) + CooldownOrder.push_back(index); } -} - -void Player::RestoreBaseRune(uint8 index) -{ - AuraEffect const* aura = m_runes->runes[index].ConvertAura; - // If rune was converted by a non-passive aura that still active we should keep it converted - if (aura && !(aura->GetSpellInfo()->Attributes & SPELL_ATTR0_PASSIVE)) - return; - ConvertRune(index, GetBaseRune(index)); - SetRuneConvertAura(index, nullptr); - // Don't drop passive talents providing rune convertion - if (!aura || aura->GetAuraType() != SPELL_AURA_CONVERT_RUNE) - return; - for (uint8 i = 0; i < MAX_RUNES; ++i) + else { - if (aura == m_runes->runes[i].ConvertAura) - return; + RuneState &= ~(1 << index); // on cooldown + if (itr != CooldownOrder.end()) + CooldownOrder.erase(itr); } - aura->GetBase()->Remove(); -} - -void Player::ConvertRune(uint8 index, RuneType newType) -{ - SetCurrentRune(index, newType); - - WorldPackets::Spells::ConvertRune data; - data.Index = index; - data.Rune = newType; - GetSession()->SendPacket(data.Write()); } -void Player::ResyncRunes(uint8 count) const +void Player::ResyncRunes() const { - WorldPackets::Spells::ResyncRunes data(count); + WorldPackets::Spells::ResyncRunes data(MAX_RUNES); + for (uint32 i = 0; i < MAX_RUNES; ++i) + data.Runes.push_back(uint8(255 - (GetRuneCooldown(i) * 51))); - for (uint32 i = 0; i < count; ++i) - { - WorldPackets::Spells::ResyncRunes::ResyncRune rune; - rune.RuneType = GetCurrentRune(i); // rune type - rune.Cooldown = uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255) - data.Runes.push_back(rune); - } GetSession()->SendPacket(data.Write()); } @@ -24209,16 +24165,6 @@ void Player::AddRunePower(uint8 index) const GetSession()->SendPacket(&data); } -static RuneType runeSlotTypes[MAX_RUNES] = -{ - /*0*/ RUNE_BLOOD, - /*1*/ RUNE_BLOOD, - /*2*/ RUNE_UNHOLY, - /*3*/ RUNE_UNHOLY, - /*4*/ RUNE_FROST, - /*5*/ RUNE_FROST -}; - void Player::InitRunes() { if (getClass() != CLASS_DEATH_KNIGHT) @@ -24228,20 +24174,14 @@ void Player::InitRunes() if (runeIndex == MAX_POWERS) return; - m_runes = new Runes; - - m_runes->runeState = 0; - m_runes->lastUsedRune = RUNE_BLOOD; + m_runes = new Runes(); + m_runes->RuneState = 0; for (uint8 i = 0; i < MAX_RUNES; ++i) { - SetBaseRune(i, runeSlotTypes[i]); // init base types - SetCurrentRune(i, runeSlotTypes[i]); // init current types SetRuneCooldown(i, 0); // reset cooldowns SetRuneTimer(i, 0xFFFFFFFF); // Reset rune flags SetLastRuneGraceTimer(i, 0); - SetRuneConvertAura(i, nullptr); - m_runes->SetRuneState(i); } // set a base regen timer equal to 10 sec @@ -24249,15 +24189,6 @@ void Player::InitRunes() SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + runeIndex, 0.1f); } -bool Player::IsBaseRuneSlotsOnCooldown(RuneType runeType) const -{ - for (uint8 i = 0; i < MAX_RUNES; ++i) - if (GetBaseRune(i) == runeType && GetRuneCooldown(i) == 0) - return false; - - return true; -} - void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast) { Loot loot; @@ -24400,7 +24331,7 @@ void Player::_LoadSkills(PreparedQueryResult result) uint16 value = fields[1].GetUInt16(); uint16 max = fields[2].GetUInt16(); - SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skill, getRace(), getClass()); + SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(skill, getRace(), getClass()); if (!rcEntry) { TC_LOG_ERROR("entities.player", "Player::_LoadSkills: Player '%s' (%s, Race: %u, Class: %u) has forbidden skill %u for his race/class combination", @@ -24512,16 +24443,9 @@ InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limi return res; // check unique-equipped on gems - for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) + for (uint32 gemItemId : pItem->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS)) { - uint32 enchant_id = pItem->GetEnchantmentId(EnchantmentSlot(enchant_slot)); - if (!enchant_id) - continue; - SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!enchantEntry) - continue; - - ItemTemplate const* pGem = sObjectMgr->GetItemTemplate(enchantEntry->SRCItemID); + ItemTemplate const* pGem = sObjectMgr->GetItemTemplate(gemItemId); if (!pGem) continue; @@ -24679,6 +24603,11 @@ void Player::CompletedAchievement(AchievementEntry const* entry) m_achievementMgr->CompletedAchievement(entry, this); } +bool Player::ModifierTreeSatisfied(uint32 modifierTreeId) const +{ + return m_achievementMgr->ModifierTreeSatisfied(modifierTreeId); +} + bool Player::LearnTalent(uint32 talentId) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId); @@ -25306,9 +25235,8 @@ void Player::ActivateTalentGroup(uint8 spec) if (CanUseMastery()) if (ChrSpecializationEntry const* specialization = sChrSpecializationStore.LookupEntry(GetSpecId(GetActiveTalentGroup()))) - for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i) - if (uint32 mastery = specialization->MasterySpellID[i]) - LearnSpell(mastery, false); + if (uint32 mastery = specialization->MasterySpellID) + LearnSpell(mastery, false); // set glyphs for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot) @@ -26088,7 +26016,19 @@ void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const uint32 Player::CalculateTalentsTiers() const { - uint32 const* rowLevels = (getClass() != CLASS_DEATH_KNIGHT) ? DefaultTalentRowLevels : DKTalentRowLevels; + uint32 const* rowLevels; + switch (getClass()) + { + case CLASS_DEATH_KNIGHT: + rowLevels = DKTalentRowLevels; + break; + case CLASS_DEMON_HUNTER: + rowLevels = DHTalentRowLevels; + default: + rowLevels = DefaultTalentRowLevels; + break; + } + for (uint32 i = MAX_TALENT_TIERS; i; --i) if (getLevel() >= rowLevels[i - 1]) return i; @@ -26219,9 +26159,8 @@ void Player::RemoveSpecializationSpells() } } - for (uint32 j = 0; j < MAX_MASTERY_SPELLS; ++j) - if (uint32 mastery = specialization->MasterySpellID[j]) - RemoveAurasDueToSpell(mastery); + if (uint32 mastery = specialization->MasterySpellID) + RemoveAurasDueToSpell(mastery); } } } @@ -26232,8 +26171,21 @@ void Player::RemoveSocial() m_social = nullptr; } -// TODO: check demon hunter custom display sections -bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, bool create /*=false*/) +bool IsSectionFlagValid(CharSectionsEntry const* entry, uint8 class_, bool create) +{ + if (create && !(entry->Flags & SECTION_FLAG_PLAYER)) + return false; + + if (class_ != CLASS_DEATH_KNIGHT && (entry->Flags & SECTION_FLAG_DEATH_KNIGHT)) + return false; + + if (class_ != CLASS_DEMON_HUNTER && (entry->Flags & SECTION_FLAG_DEMON_HUNTER)) + return false; + + return true; +} + +bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> const& customDisplay, bool create /*= false*/) { // Check skin color // For Skin type is always 0 @@ -26241,10 +26193,9 @@ bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 ha { // Skin Color defined as Face color, too, we check skin & face in one pass if (CharSectionsEntry const* entry2 = GetCharSectionEntry(race, SECTION_TYPE_FACE, gender, faceID, skinColor)) { - // Check DeathKnight exclusive - if (((entry->Flags & SECTION_FLAG_DEATH_KNIGHT) || (entry2->Flags & SECTION_FLAG_DEATH_KNIGHT)) && class_ != CLASS_DEATH_KNIGHT) + if (!IsSectionFlagValid(entry, class_, create)) return false; - if (create && !((entry->Flags & SECTION_FLAG_PLAYER) && (entry2->Flags & SECTION_FLAG_PLAYER))) + if (!IsSectionFlagValid(entry2, class_, create)) return false; } else @@ -26259,18 +26210,14 @@ bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 ha // Check Hair if (CharSectionsEntry const* entry = GetCharSectionEntry(race, SECTION_TYPE_HAIR, gender, hairID, hairColor)) { - if ((entry->Flags & SECTION_FLAG_DEATH_KNIGHT) && class_ != CLASS_DEATH_KNIGHT) - return false; - if (create && !(entry->Flags & SECTION_FLAG_PLAYER)) + if (!IsSectionFlagValid(entry, class_, create)) return false; if (!excludeCheck) { if (CharSectionsEntry const* entry2 = GetCharSectionEntry(race, SECTION_TYPE_FACIAL_HAIR, gender, facialHair, hairColor)) { - if ((entry2->Flags & SECTION_FLAG_DEATH_KNIGHT) && class_ != CLASS_DEATH_KNIGHT) - return false; - if (create && !(entry2->Flags & SECTION_FLAG_PLAYER)) + if (!IsSectionFlagValid(entry2, class_, create)) return false; } else @@ -26285,6 +26232,11 @@ bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 ha else return false; + for (uint32 i = 0; i < PLAYER_CUSTOM_DISPLAY_SIZE; ++i) + if (CharSectionsEntry const* entry = GetCharSectionEntry(race, CharSectionType(SECTION_TYPE_CUSTOM_DISPLAY_1 + i * 2), gender, customDisplay[i], 0)) + if (!IsSectionFlagValid(entry, class_, create)) + return false; + return true; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index aa1f1d0697e..b538bbbe05c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -447,7 +447,8 @@ struct Areas float y2; }; -#define MAX_RUNES 6 +#define MAX_RUNES 7 +#define MAX_RECHARGING_RUNES 3 enum RuneCooldowns { @@ -455,36 +456,13 @@ enum RuneCooldowns RUNE_MISS_COOLDOWN = 1500 // cooldown applied on runes when the spell misses }; -enum RuneType : uint8 -{ - RUNE_BLOOD = 0, - RUNE_UNHOLY = 1, - RUNE_FROST = 2, - RUNE_DEATH = 3, - NUM_RUNE_TYPES = 4 -}; - -struct RuneInfo -{ - RuneType BaseRune; - RuneType CurrentRune; - uint32 Cooldown; - AuraEffect const* ConvertAura; -}; - struct Runes { - RuneInfo runes[MAX_RUNES]; - uint8 runeState; // mask of available runes - RuneType lastUsedRune; + std::deque<uint8> CooldownOrder; + uint32 Cooldown[MAX_RUNES]; + uint8 RuneState; // mask of available runes - void SetRuneState(uint8 index, bool set = true) - { - if (set) - runeState |= (1 << index); // usable - else - runeState &= ~(1 << index); // on cooldown - } + void SetRuneState(uint8 index, bool set = true); }; struct EnchantDuration @@ -1162,6 +1140,7 @@ struct ResurrectionData static uint32 const DefaultTalentRowLevels[MAX_TALENT_TIERS] = { 15, 30, 45, 60, 75, 90, 100 }; static uint32 const DKTalentRowLevels[MAX_TALENT_TIERS] = { 57, 58, 59, 60, 75, 90, 100 }; +static uint32 const DHTalentRowLevels[MAX_TALENT_TIERS] = { 99, 100, 102, 104, 106, 108, 110 }; struct TC_GAME_API PlayerTalentInfo { @@ -1652,7 +1631,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE; } static bool IsValidClass(uint8 Class) { return ((1 << (Class - 1)) & CLASSMASK_ALL_PLAYABLE) != 0; } static bool IsValidRace(uint8 Race) { return ((1 << (Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0; } - static bool ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, bool create = false); + static bool ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> const& customDisplay, bool create = false); /*********************************************************/ /*** SAVE SYSTEM ***/ @@ -2424,24 +2403,11 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool isAllowedToLoot(const Creature* creature); DeclinedName const* GetDeclinedNames() const { return m_declinedname; } - uint8 GetRunesState() const { return m_runes->runeState; } - RuneType GetBaseRune(uint8 index) const { return RuneType(m_runes->runes[index].BaseRune); } - RuneType GetCurrentRune(uint8 index) const { return RuneType(m_runes->runes[index].CurrentRune); } - uint32 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; } - uint32 GetRuneBaseCooldown(uint8 index) const { return GetRuneTypeBaseCooldown(); } - uint32 GetRuneTypeBaseCooldown() const; - bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const; - RuneType GetLastUsedRune() const { return m_runes->lastUsedRune; } - void SetLastUsedRune(RuneType type) { m_runes->lastUsedRune = type; } - void SetBaseRune(uint8 index, RuneType baseRune) { m_runes->runes[index].BaseRune = baseRune; } - void SetCurrentRune(uint8 index, RuneType currentRune) { m_runes->runes[index].CurrentRune = currentRune; } + uint8 GetRunesState() const { return m_runes->RuneState; } + uint32 GetRuneCooldown(uint8 index) const { return m_runes->Cooldown[index]; } + uint32 GetRuneBaseCooldown() const; void SetRuneCooldown(uint8 index, uint32 cooldown, bool casted = false); - void SetRuneConvertAura(uint8 index, AuraEffect const* aura); - void AddRuneByAuraEffect(uint8 index, RuneType newType, AuraEffect const* aura); - void RemoveRunesByAuraEffect(AuraEffect const* aura); - void RestoreBaseRune(uint8 index); - void ConvertRune(uint8 index, RuneType newType); - void ResyncRunes(uint8 count) const; + void ResyncRunes() const; void AddRunePower(uint8 index) const; void InitRunes(); @@ -2454,6 +2420,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void StartCriteriaTimer(CriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0); void RemoveCriteriaTimer(CriteriaTimedTypes type, uint32 entry); void CompletedAchievement(AchievementEntry const* entry); + bool ModifierTreeSatisfied(uint32 modifierTreeId) const; bool HasTitle(uint32 bitIndex) const; bool HasTitle(CharTitlesEntry const* title) const { return HasTitle(title->MaskID); } diff --git a/src/server/game/Entities/Taxi/TaxiPathGraph.cpp b/src/server/game/Entities/Taxi/TaxiPathGraph.cpp index 6617267be6a..22af722d592 100644 --- a/src/server/game/Entities/Taxi/TaxiPathGraph.cpp +++ b/src/server/game/Entities/Taxi/TaxiPathGraph.cpp @@ -108,8 +108,8 @@ void TaxiPathGraph::AddVerticeAndEdgeFromNodeInfo(TaxiNodesEntry const* from, Ta uint32 map1, map2; DBCPosition2D pos1, pos2; - DeterminaAlternateMapPosition(nodes[i - 1]->MapID, nodes[i - 1]->Loc.X, nodes[i - 1]->Loc.Y, nodes[i - 1]->Loc.Z, &map1, &pos1); - DeterminaAlternateMapPosition(nodes[i]->MapID, nodes[i]->Loc.X, nodes[i]->Loc.Y, nodes[i]->Loc.Z, &map2, &pos2); + DB2Manager::DeterminaAlternateMapPosition(nodes[i - 1]->MapID, nodes[i - 1]->Loc.X, nodes[i - 1]->Loc.Y, nodes[i - 1]->Loc.Z, &map1, &pos1); + DB2Manager::DeterminaAlternateMapPosition(nodes[i]->MapID, nodes[i]->Loc.X, nodes[i]->Loc.Y, nodes[i]->Loc.Z, &map2, &pos2); if (map1 != map2) continue; diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index deb163fde7e..f9ba83c19ca 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -539,24 +539,21 @@ void Player::UpdateMastery() if (!chrSpec) return; - for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i) - { - if (!chrSpec->MasterySpellID[i]) - continue; + if (!chrSpec->MasterySpellID) + return; - if (Aura* aura = GetAura(chrSpec->MasterySpellID[i])) + if (Aura* aura = GetAura(chrSpec->MasterySpellID)) + { + for (SpellEffectInfo const* effect : aura->GetSpellEffectInfos()) { - for (SpellEffectInfo const* effect : aura->GetSpellEffectInfos()) - { - if (!effect) - continue; + if (!effect) + continue; - float mult = effect->BonusCoefficient; - if (G3D::fuzzyEq(mult, 0.0f)) - continue; + float mult = effect->BonusCoefficient; + if (G3D::fuzzyEq(mult, 0.0f)) + continue; - aura->GetEffect(effect->EffectIndex)->ChangeAmount(int32(value * effect->BonusCoefficient)); - } + aura->GetEffect(effect->EffectIndex)->ChangeAmount(int32(value * effect->BonusCoefficient)); } } } @@ -780,7 +777,7 @@ void Player::UpdateAllRunesRegen() if (runeIndex == MAX_POWERS) return; - uint32 cooldown = GetRuneTypeBaseCooldown(); + uint32 cooldown = GetRuneBaseCooldown(); SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER + runeIndex, float(1 * IN_MILLISECONDS) / float(cooldown)); SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + runeIndex, float(1 * IN_MILLISECONDS) / float(cooldown)); } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 271b84364de..2bf8d161798 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6056,78 +6056,6 @@ bool Unit::HandleAuraProc(Unit* /*victim*/, uint32 /*damage*/, Aura* triggeredBy } case SPELLFAMILY_DEATHKNIGHT: { - // Blood of the North - // Reaping - // Death Rune Mastery - /// @todo move those to spell scripts - if (dummySpell->SpellIconID == 3041 || (dummySpell->SpellIconID == 22 && dummySpell->Id != 62459) || dummySpell->SpellIconID == 2622) - { - *handled = true; - // Convert recently used Blood Rune to Death Rune - if (Player* player = ToPlayer()) - { - if (player->getClass() != CLASS_DEATH_KNIGHT) - return false; - - RuneType rune = ToPlayer()->GetLastUsedRune(); - // can't proc from death rune use - if (rune == RUNE_DEATH) - return false; - AuraEffect* aurEff = triggeredByAura->GetEffect(EFFECT_0); - if (!aurEff) - return false; - - // Reset amplitude - set death rune remove timer to 30s - aurEff->ResetPeriodic(true); - uint32 runesLeft; - - if (dummySpell->SpellIconID == 2622) - runesLeft = 2; - else - runesLeft = 1; - - for (uint8 i = 0; i < MAX_RUNES && runesLeft; ++i) - { - if (dummySpell->SpellIconID == 2622) - { - if (player->GetCurrentRune(i) == RUNE_DEATH || - player->GetBaseRune(i) == RUNE_BLOOD) - continue; - } - else - { - if (player->GetCurrentRune(i) == RUNE_DEATH || - player->GetBaseRune(i) != RUNE_BLOOD) - continue; - } - if (player->GetRuneCooldown(i) != (player->GetRuneBaseCooldown(i) - player->GetLastRuneGraceTimer(i))) - continue; - - --runesLeft; - // Mark aura as used - player->AddRuneByAuraEffect(i, RUNE_DEATH, aurEff); - } - return true; - } - return false; - } - - switch (dummySpell->Id) - { - // Bone Shield cooldown - case 49222: - { - *handled = true; - if (cooldown && GetTypeId() == TYPEID_PLAYER) - { - if (GetSpellHistory()->HasCooldown(100000)) - return false; - - GetSpellHistory()->AddCooldown(100000, 0, std::chrono::milliseconds(cooldown)); - } - return true; - } - } break; } case SPELLFAMILY_WARRIOR: @@ -11153,16 +11081,16 @@ int32 Unit::GetCreatePowers(Powers power) const case POWER_RUNIC_POWER: return 1000; case POWER_RUNES: - return 0; + return 6; case POWER_SOUL_SHARDS: return 400; - case POWER_ECLIPSE: + case POWER_LUNAR_POWER: return 100; case POWER_HOLY_POWER: return 3; case POWER_CHI: return 4; - case POWER_SHADOW_ORBS: + case POWER_INSANITY: return 3; case POWER_BURNING_EMBERS: return 40; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 415c46afa5d..5ba84c271be 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1446,7 +1446,7 @@ class TC_GAME_API Unit : public WorldObject Powers getPowerType() const { return Powers(GetUInt32Value(UNIT_FIELD_DISPLAY_POWER)); } void setPowerType(Powers power); int32 GetPower(Powers power) const; - int32 GetMinPower(Powers power) const { return power == POWER_ECLIPSE ? -100 : 0; } + int32 GetMinPower(Powers power) const { return power == POWER_LUNAR_POWER ? -100 : 0; } int32 GetMaxPower(Powers power) const; float GetPowerPct(Powers power) const { return GetMaxPower(power) ? 100.f * GetPower(power) / GetMaxPower(power) : 0.0f; } int32 CountPctFromMaxPower(Powers power, int32 pct) const { return CalculatePct(GetMaxPower(power), pct); } diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp index 56cbb9ad58e..33bf14d4c15 100644 --- a/src/server/game/Garrison/Garrison.cpp +++ b/src/server/game/Garrison/Garrison.cpp @@ -23,7 +23,7 @@ #include "ObjectMgr.h" #include "VehicleDefines.h" -Garrison::Garrison(Player* owner) : _owner(owner), _siteLevel(nullptr), _followerActivationsRemainingToday(1) +Garrison::Garrison(Player* owner) : _owner(owner), _siteLevelId(0), _siteLevel(nullptr), _followerActivationsRemainingToday(1) { } @@ -34,7 +34,8 @@ bool Garrison::LoadFromDB(PreparedQueryResult garrison, PreparedQueryResult blue return false; Field* fields = garrison->Fetch(); - _siteLevel = sGarrSiteLevelStore.LookupEntry(fields[0].GetUInt32()); + _siteLevelId = fields[0].GetUInt32(); + _siteLevel = sGarrSiteLevelStore.LookupEntry(_siteLevelId); _followerActivationsRemainingToday = fields[1].GetUInt32(); if (!_siteLevel) return false; @@ -47,7 +48,7 @@ bool Garrison::LoadFromDB(PreparedQueryResult garrison, PreparedQueryResult blue { fields = blueprints->Fetch(); if (GarrBuildingEntry const* building = sGarrBuildingStore.LookupEntry(fields[0].GetUInt32())) - _knownBuildings.insert(building->ID); + _knownBuildings.insert(fields[0].GetUInt32()); } while (blueprints->NextRow()); } @@ -141,7 +142,7 @@ void Garrison::SaveToDB(SQLTransaction trans) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_GARRISON); stmt->setUInt64(0, _owner->GetGUID().GetCounter()); - stmt->setUInt32(1, _siteLevel->ID); + stmt->setUInt32(1, _siteLevelId); stmt->setUInt32(2, _followerActivationsRemainingToday); trans->Append(stmt); @@ -219,14 +220,17 @@ void Garrison::DeleteFromDB(ObjectGuid::LowType ownerGuid, SQLTransaction trans) bool Garrison::Create(uint32 garrSiteId) { - _siteLevel = sGarrisonMgr.GetGarrSiteLevelEntry(garrSiteId, 1); - if (!_siteLevel) + DBStorageIterator<GarrSiteLevelEntry> siteLevelItr = sGarrisonMgr.GetGarrSiteLevelEntry(garrSiteId, 1); + if (siteLevelItr == sGarrSiteLevelStore.end()) return false; + _siteLevelId = siteLevelItr.Key(); + _siteLevel = siteLevelItr.Value(); + InitializePlots(); WorldPackets::Garrison::GarrisonCreateResult garrisonCreateResult; - garrisonCreateResult.GarrSiteLevelID = _siteLevel->ID; + garrisonCreateResult.GarrSiteLevelID = _siteLevelId; _owner->SendDirectMessage(garrisonCreateResult.Write()); _owner->SendUpdatePhasing(); SendRemoteInfo(); @@ -247,11 +251,11 @@ void Garrison::Delete() void Garrison::InitializePlots() { - if (std::vector<GarrSiteLevelPlotInstEntry const*> const* plots = sGarrisonMgr.GetGarrPlotInstForSiteLevel(_siteLevel->ID)) + if (std::vector<std::pair<uint32, GarrSiteLevelPlotInstEntry const*>> const* plots = sGarrisonMgr.GetGarrPlotInstForSiteLevel(_siteLevelId)) { for (std::size_t i = 0; i < plots->size(); ++i) { - uint32 garrPlotInstanceId = plots->at(i)->GarrPlotInstanceID; + uint32 garrPlotInstanceId = plots->at(i).second->GarrPlotInstanceID; GarrPlotInstanceEntry const* plotInstance = sGarrPlotInstanceStore.LookupEntry(garrPlotInstanceId); GameObjectsEntry const* gameObject = sGarrisonMgr.GetPlotGameObject(_siteLevel->MapID, garrPlotInstanceId); if (!plotInstance || !gameObject) @@ -266,7 +270,7 @@ void Garrison::InitializePlots() plotInfo.PacketInfo.PlotPos.Relocate(gameObject->Position.X, gameObject->Position.Y, gameObject->Position.Z, 2 * std::acos(gameObject->RotationW)); plotInfo.PacketInfo.PlotType = plot->PlotType; plotInfo.EmptyGameObjectId = gameObject->ID; - plotInfo.GarrSiteLevelPlotInstId = plots->at(i)->ID; + plotInfo.GarrSiteLevelPlotInstId = plots->at(i).first; } } } @@ -439,13 +443,13 @@ void Garrison::CancelBuildingConstruction(uint32 garrPlotInstanceId) if (constructing->Level > 1) { // Restore previous level building - GarrBuildingEntry const* restored = sGarrisonMgr.GetPreviousLevelBuilding(constructing->Type, constructing->Level); + uint32 restored = sGarrisonMgr.GetPreviousLevelBuildingId(constructing->Type, constructing->Level); ASSERT(restored); WorldPackets::Garrison::GarrisonPlaceBuildingResult placeBuildingResult; placeBuildingResult.Result = GARRISON_SUCCESS; placeBuildingResult.BuildingInfo.GarrPlotInstanceID = garrPlotInstanceId; - placeBuildingResult.BuildingInfo.GarrBuildingID = restored->ID; + placeBuildingResult.BuildingInfo.GarrBuildingID = restored; placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr); placeBuildingResult.BuildingInfo.Active = true; @@ -505,7 +509,7 @@ void Garrison::AddFollower(uint32 garrFollowerId) follower.PacketInfo.Xp = 0; follower.PacketInfo.CurrentBuildingID = 0; follower.PacketInfo.CurrentMissionID = 0; - follower.PacketInfo.AbilityID = sGarrisonMgr.RollFollowerAbilities(followerEntry, follower.PacketInfo.Quality, GetFaction(), true); + follower.PacketInfo.AbilityID = sGarrisonMgr.RollFollowerAbilities(garrFollowerId, followerEntry, follower.PacketInfo.Quality, GetFaction(), true); follower.PacketInfo.FollowerStatus = 0; addFollowerResult.Follower = follower.PacketInfo; @@ -527,7 +531,7 @@ void Garrison::SendInfo() { WorldPackets::Garrison::GetGarrisonInfoResult garrisonInfo; garrisonInfo.GarrSiteID = _siteLevel->SiteID; - garrisonInfo.GarrSiteLevelID = _siteLevel->ID; + garrisonInfo.GarrSiteLevelID = _siteLevelId; garrisonInfo.FactionIndex = GetFaction(); garrisonInfo.NumFollowerActivationsRemaining = _followerActivationsRemainingToday; for (auto& p : _plots) @@ -554,7 +558,7 @@ void Garrison::SendRemoteInfo() const remoteInfo.Sites.resize(1); WorldPackets::Garrison::GarrisonRemoteSiteInfo& remoteSiteInfo = remoteInfo.Sites[0]; - remoteSiteInfo.GarrSiteLevelID = _siteLevel->ID; + remoteSiteInfo.GarrSiteLevelID = _siteLevelId; for (auto const& p : _plots) if (p.second.BuildingInfo.PacketInfo) remoteSiteInfo.Buildings.emplace_back(p.first, p.second.BuildingInfo.PacketInfo->GarrBuildingID); diff --git a/src/server/game/Garrison/Garrison.h b/src/server/game/Garrison/Garrison.h index 2aa38ee6ad3..68ebbc4c0b9 100644 --- a/src/server/game/Garrison/Garrison.h +++ b/src/server/game/Garrison/Garrison.h @@ -157,6 +157,7 @@ private: GarrisonError CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 garrBuildingId) const; GarrisonError CheckBuildingRemoval(uint32 garrPlotInstanceId) const; Player* _owner; + uint32 _siteLevelId; GarrSiteLevelEntry const* _siteLevel; uint32 _followerActivationsRemainingToday; diff --git a/src/server/game/Garrison/GarrisonMgr.cpp b/src/server/game/Garrison/GarrisonMgr.cpp index 5c9bef62fc3..e2cba691910 100644 --- a/src/server/game/Garrison/GarrisonMgr.cpp +++ b/src/server/game/Garrison/GarrisonMgr.cpp @@ -32,8 +32,8 @@ GarrisonMgr& GarrisonMgr::Instance() void GarrisonMgr::Initialize() { - for (GarrSiteLevelPlotInstEntry const* plotInstance : sGarrSiteLevelPlotInstStore) - _garrisonPlotInstBySiteLevel[plotInstance->GarrSiteLevelID].push_back(plotInstance); + for (auto itr = sGarrSiteLevelPlotInstStore.begin(); itr != sGarrSiteLevelPlotInstStore.end(); ++itr) + _garrisonPlotInstBySiteLevel[itr->GarrSiteLevelID].push_back(std::make_pair(itr.Key(), itr.Value())); for (GameObjectsEntry const* gameObject : sGameObjectsStore) if (gameObject->Type == GAMEOBJECT_TYPE_GARRISON_PLOT) @@ -45,8 +45,8 @@ void GarrisonMgr::Initialize() for (GarrBuildingPlotInstEntry const* buildingPlotInst : sGarrBuildingPlotInstStore) _garrisonBuildingPlotInstances[MAKE_PAIR64(buildingPlotInst->GarrBuildingID, buildingPlotInst->GarrSiteLevelPlotInstID)] = buildingPlotInst->ID; - for (GarrBuildingEntry const* building : sGarrBuildingStore) - _garrisonBuildingsByType[building->Type].push_back(building); + for (auto itr = sGarrBuildingStore.begin(); itr != sGarrBuildingStore.end(); ++itr) + _garrisonBuildingsByType[itr->Type].push_back(itr.Key()); for (GarrFollowerXAbilityEntry const* followerAbility : sGarrFollowerXAbilityStore) { @@ -73,16 +73,16 @@ void GarrisonMgr::Initialize() LoadFollowerClassSpecAbilities(); } -GarrSiteLevelEntry const* GarrisonMgr::GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const +DBStorageIterator<GarrSiteLevelEntry> GarrisonMgr::GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const { - for (GarrSiteLevelEntry const* garrSiteLevel : sGarrSiteLevelStore) - if (garrSiteLevel->SiteID == garrSiteId && garrSiteLevel->Level == level) - return garrSiteLevel; + for (auto itr = sGarrSiteLevelStore.begin(); itr != sGarrSiteLevelStore.end(); ++itr) + if (itr->SiteID == garrSiteId && itr->Level == level) + return itr; - return nullptr; + return sGarrSiteLevelStore.end(); } -std::vector<GarrSiteLevelPlotInstEntry const*> const* GarrisonMgr::GetGarrPlotInstForSiteLevel(uint32 garrSiteLevelId) const +std::vector<std::pair<uint32, GarrSiteLevelPlotInstEntry const*>> const* GarrisonMgr::GetGarrPlotInstForSiteLevel(uint32 garrSiteLevelId) const { auto itr = _garrisonPlotInstBySiteLevel.find(garrSiteLevelId); if (itr != _garrisonPlotInstBySiteLevel.end()) @@ -122,15 +122,15 @@ uint32 GarrisonMgr::GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSi return 0; } -GarrBuildingEntry const* GarrisonMgr::GetPreviousLevelBuilding(uint32 buildingType, uint32 currentLevel) const +uint32 GarrisonMgr::GetPreviousLevelBuildingId(uint32 buildingType, uint32 currentLevel) const { auto itr = _garrisonBuildingsByType.find(buildingType); if (itr != _garrisonBuildingsByType.end()) - for (GarrBuildingEntry const* building : itr->second) - if (building->Level == currentLevel - 1) - return building; + for (uint32 buildingId : itr->second) + if (sGarrBuildingStore.AssertEntry(buildingId)->Level == currentLevel - 1) + return buildingId; - return nullptr; + return 0; } FinalizeGarrisonPlotGOInfo const* GarrisonMgr::GetPlotFinalizeGOInfo(uint32 garrPlotInstanceID) const @@ -164,7 +164,7 @@ uint32 const AbilitiesForQuality[][2] = { 2, 3 } // Legendary }; -std::list<GarrAbilityEntry const*> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const +std::list<GarrAbilityEntry const*> GarrisonMgr::RollFollowerAbilities(uint32 garrFollowerId, GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const { ASSERT(faction < 2); @@ -173,7 +173,7 @@ std::list<GarrAbilityEntry const*> GarrisonMgr::RollFollowerAbilities(GarrFollow uint32 slots[2] = { AbilitiesForQuality[quality][0], AbilitiesForQuality[quality][1] }; GarrAbilities const* abilities = nullptr; - auto itr = _garrisonFollowerAbilities[faction].find(follower->ID); + auto itr = _garrisonFollowerAbilities[faction].find(garrFollowerId); if (itr != _garrisonFollowerAbilities[faction].end()) abilities = &itr->second; diff --git a/src/server/game/Garrison/GarrisonMgr.h b/src/server/game/Garrison/GarrisonMgr.h index 6130fd67b25..7a93941d59b 100644 --- a/src/server/game/Garrison/GarrisonMgr.h +++ b/src/server/game/Garrison/GarrisonMgr.h @@ -45,15 +45,15 @@ public: void Initialize(); - GarrSiteLevelEntry const* GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const; - std::vector<GarrSiteLevelPlotInstEntry const*> const* GetGarrPlotInstForSiteLevel(uint32 garrSiteLevelId) const; + DBStorageIterator<GarrSiteLevelEntry> GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const; + std::vector<std::pair<uint32, GarrSiteLevelPlotInstEntry const*>> const* GetGarrPlotInstForSiteLevel(uint32 garrSiteLevelId) const; GameObjectsEntry const* GetPlotGameObject(uint32 mapId, uint32 garrPlotInstanceId) const; bool IsPlotMatchingBuilding(uint32 garrPlotId, uint32 garrBuildingId) const; uint32 GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSiteLevelPlotInstId) const; - GarrBuildingEntry const* GetPreviousLevelBuilding(uint32 buildingType, uint32 currentLevel) const; + uint32 GetPreviousLevelBuildingId(uint32 buildingType, uint32 currentLevel) const; FinalizeGarrisonPlotGOInfo const* GetPlotFinalizeGOInfo(uint32 garrPlotInstanceID) const; uint64 GenerateFollowerDbId(); - std::list<GarrAbilityEntry const*> RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const; + std::list<GarrAbilityEntry const*> RollFollowerAbilities(uint32 garrFollowerId, GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const; std::list<GarrAbilityEntry const*> GetClassSpecAbilities(GarrFollowerEntry const* follower, uint32 faction) const; private: @@ -61,11 +61,11 @@ private: void LoadPlotFinalizeGOInfo(); void LoadFollowerClassSpecAbilities(); - std::unordered_map<uint32 /*garrSiteId*/, std::vector<GarrSiteLevelPlotInstEntry const*>> _garrisonPlotInstBySiteLevel; + std::unordered_map<uint32 /*garrSiteId*/, std::vector<std::pair<uint32, GarrSiteLevelPlotInstEntry const*>>> _garrisonPlotInstBySiteLevel; std::unordered_map<uint32 /*mapId*/, std::unordered_map<uint32 /*garrPlotId*/, GameObjectsEntry const*>> _garrisonPlots; std::unordered_map<uint32 /*garrPlotId*/, std::unordered_set<uint32/*garrBuildingId*/>> _garrisonBuildingsByPlot; std::unordered_map<uint64 /*garrBuildingId | garrSiteLevelPlotInstId << 32*/, uint32 /*garrBuildingPlotInstId*/> _garrisonBuildingPlotInstances; - std::unordered_map<uint32 /*buildingType*/, std::vector<GarrBuildingEntry const*>> _garrisonBuildingsByType; + std::unordered_map<uint32 /*buildingType*/, std::vector<uint32>> _garrisonBuildingsByType; std::unordered_map<uint32 /*garrPlotInstanceId*/, FinalizeGarrisonPlotGOInfo> _finalizePlotGOInfo; std::unordered_map<uint32 /*garrFollowerId*/, GarrAbilities> _garrisonFollowerAbilities[2]; std::unordered_map<uint32 /*classSpecId*/, std::list<GarrAbilityEntry const*>> _garrisonFollowerClassSpecAbilities; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 96936a82d08..c52622bd966 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2410,7 +2410,7 @@ void FillDisenchantFields(uint32* disenchantID, uint32* requiredDisenchantSkill, itemTemplate.GetMaxStackSize() > 1 || itemTemplate.GetQuality() < ITEM_QUALITY_UNCOMMON || itemTemplate.GetQuality() > ITEM_QUALITY_EPIC || !(itemTemplate.GetClass() == ITEM_CLASS_ARMOR || itemTemplate.GetClass() == ITEM_CLASS_WEAPON) || - !(Item::GetSpecialPrice(&itemTemplate) || sItemCurrencyCostStore.LookupEntry(itemTemplate.GetId()))) + !(Item::GetSpecialPrice(&itemTemplate) || sDB2Manager.HasItemCurrencyCost(itemTemplate.GetId()))) return; for (uint32 i = 0; i < sItemDisenchantLootStore.GetNumRows(); ++i) @@ -2424,18 +2424,18 @@ void FillDisenchantFields(uint32* disenchantID, uint32* requiredDisenchantSkill, disenchant->MinItemLevel <= itemTemplate.GetBaseItemLevel() && disenchant->MaxItemLevel >= itemTemplate.GetBaseItemLevel()) { - if (disenchant->ID == 60 || disenchant->ID == 61) // epic item disenchant ilvl range 66-99 (classic) + if (i == 60 || i == 61) // epic item disenchant ilvl range 66-99 (classic) { if (itemTemplate.GetBaseRequiredLevel() > 60 || itemTemplate.GetRequiredSkillRank() > 300) continue; // skip to epic item disenchant ilvl range 90-199 (TBC) } - else if (disenchant->ID == 66 || disenchant->ID == 67) // epic item disenchant ilvl range 90-199 (TBC) + else if (i == 66 || i == 67) // epic item disenchant ilvl range 90-199 (TBC) { if (itemTemplate.GetBaseRequiredLevel() <= 60 || (itemTemplate.GetRequiredSkill() && itemTemplate.GetRequiredSkillRank() <= 300)) continue; } - *disenchantID = disenchant->ID; + *disenchantID = i; *requiredDisenchantSkill = disenchant->RequiredDisenchantSkill; return; } @@ -2624,13 +2624,15 @@ void ObjectMgr::LoadItemTemplates() uint32 oldMSTime = getMSTime(); uint32 sparseCount = 0; - for (ItemSparseEntry const* sparse : sItemSparseStore) + for (auto itr = sItemSparseStore.begin(); itr != sItemSparseStore.end(); ++itr) { - ItemEntry const* db2Data = sItemStore.LookupEntry(sparse->ID); + ItemSparseEntry const* sparse = itr->second; + ItemEntry const* db2Data = sItemStore.LookupEntry(itr->first); if (!db2Data) continue; - ItemTemplate& itemTemplate = _itemTemplateStore[sparse->ID]; + ItemTemplate& itemTemplate = _itemTemplateStore[itr->first]; + itemTemplate.Id = itr->first; itemTemplate.BasicData = db2Data; itemTemplate.ExtendedData = sparse; @@ -2644,7 +2646,7 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.FlagsCu = 0; itemTemplate.SpellPPMRate = 0.0f; - if (std::vector<ItemSpecOverrideEntry const*> const* itemSpecOverrides = sDB2Manager.GetItemSpecOverrides(sparse->ID)) + if (std::vector<ItemSpecOverrideEntry const*> const* itemSpecOverrides = sDB2Manager.GetItemSpecOverrides(itemTemplate.Id)) { for (ItemSpecOverrideEntry const* itemSpecOverride : *itemSpecOverrides) itemTemplate.Specializations[0].insert(itemSpecOverride->SpecID); @@ -3448,6 +3450,12 @@ void ObjectMgr::LoadPlayerInfo() if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_CATACLYSM && (race == RACE_GOBLIN || race == RACE_WORGEN)) continue; + if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_MISTS_OF_PANDARIA && (race == RACE_PANDAREN_NEUTRAL || race == RACE_PANDAREN_HORDE || race == RACE_PANDAREN_ALLIANCE)) + continue; + + if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_LEGION && class_ == CLASS_DEMON_HUNTER) + continue; + // fatal error if no level 1 data if (!info->levelInfo || info->levelInfo[0].stats[0] == 0) { @@ -4388,7 +4396,7 @@ void ObjectMgr::LoadQuests() if (qinfo->SoundAccept) { - if (!sSoundEntriesStore.LookupEntry(qinfo->SoundAccept)) + if (!sSoundKitStore.LookupEntry(qinfo->SoundAccept)) { TC_LOG_ERROR("sql.sql", "Quest %u has `SoundAccept` = %u but sound %u does not exist, set to 0.", qinfo->GetQuestId(), qinfo->SoundAccept, qinfo->SoundAccept); @@ -4398,7 +4406,7 @@ void ObjectMgr::LoadQuests() if (qinfo->SoundTurnIn) { - if (!sSoundEntriesStore.LookupEntry(qinfo->SoundTurnIn)) + if (!sSoundKitStore.LookupEntry(qinfo->SoundTurnIn)) { TC_LOG_ERROR("sql.sql", "Quest %u has `SoundTurnIn` = %u but sound %u does not exist, set to 0.", qinfo->GetQuestId(), qinfo->SoundTurnIn, qinfo->SoundTurnIn); @@ -8703,25 +8711,12 @@ void ObjectMgr::LoadCreatureClassLevelStats() if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0) TC_LOG_ERROR("sql.sql", "Creature base stats for level %u has invalid class %u", Level, Class); - GtNpcTotalHpEntry const* HpExp0 = sGtNpcTotalHpStore.EvaluateTable(Level - 1, Class - 1); - GtNpcTotalHpExp1Entry const* HpExp1 = sGtNpcTotalHpExp1Store.EvaluateTable(Level - 1, Class - 1); - GtNpcTotalHpExp2Entry const* HpExp2 = sGtNpcTotalHpExp2Store.EvaluateTable(Level - 1, Class - 1); - GtNpcTotalHpExp3Entry const* HpExp3 = sGtNpcTotalHpExp3Store.EvaluateTable(Level - 1, Class - 1); - GtNpcTotalHpExp4Entry const* HpExp4 = sGtNpcTotalHpExp4Store.EvaluateTable(Level - 1, Class - 1); - GtNpcTotalHpExp5Entry const* HpExp5 = sGtNpcTotalHpExp5Store.EvaluateTable(Level - 1, Class - 1); - CreatureBaseStats stats; - stats.BaseHealth[0] = uint32(HpExp0->HP); - stats.BaseHealth[1] = uint32(HpExp1->HP); - stats.BaseHealth[2] = uint32(HpExp2->HP); - stats.BaseHealth[3] = uint32(HpExp3->HP); - stats.BaseHealth[4] = uint32(HpExp4->HP); - stats.BaseHealth[5] = uint32(HpExp5->HP); - for (uint8 i = 0; i < MAX_EXPANSIONS; ++i) { - stats.BaseDamage[i] = fields[6 + i].GetFloat(); + stats.BaseHealth[0] = sGtNpcTotalHpStore[i].EvaluateTable(Level - 1, Class - 1)->HP; + stats.BaseDamage[0] = sGtNpcDamageByClassStore[i].EvaluateTable(Level - 1, Class - 1)->Damage; if (stats.BaseDamage[i] < 0.0f) { TC_LOG_ERROR("sql.sql", "Creature base stats for class %u, level %u has invalid negative base damage[%u] - set to 0.0", Class, Level, i); diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 86a59f04f23..e0d15e8def0 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -368,7 +368,7 @@ void Guild::BankTab::LoadFromDB(Field* fields) bool Guild::BankTab::LoadItemFromDB(Field* fields) { - uint8 slotId = fields[23].GetUInt8(); + uint8 slotId = fields[26].GetUInt8(); ObjectGuid::LowType itemGuid = fields[0].GetUInt64(); uint32 itemEntry = fields[1].GetUInt32(); if (slotId >= GUILD_BANK_MAX_SLOTS) @@ -2395,7 +2395,7 @@ void Guild::LoadBankTabFromDB(Field* fields) bool Guild::LoadBankItemFromDB(Field* fields) { - uint8 tabId = fields[22].GetUInt8(); + uint8 tabId = fields[25].GetUInt8(); if (tabId >= _GetPurchasedTabsSize()) { TC_LOG_ERROR("guild", "Invalid tab for item (GUID: %u, id: #%u) in guild bank, skipped.", diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index 6af809dcedb..20cbf22d40e 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -403,8 +403,8 @@ void GuildMgr::LoadGuilds() // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, transmogrification, upgradeId, enchantIllusion, - // 17 18 19 20 21 22 23 - // battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid + // 17 18 19 20 21 22 23 24 25 26 + // battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, ig.gemItemId1, ig.gemItemId2, ig.gemItemId3, guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEMS)); if (!result) @@ -417,7 +417,7 @@ void GuildMgr::LoadGuilds() do { Field* fields = result->Fetch(); - uint64 guildId = fields[21].GetUInt64(); + uint64 guildId = fields[24].GetUInt64(); if (Guild* guild = GetGuildById(guildId)) guild->LoadBankItemFromDB(fields); diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 43a0baa75a7..1fa50f1493e 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -55,7 +55,7 @@ void WorldSession::SendAuctionHello(ObjectGuid guid, Creature* unit) return; } - AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction()); + AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction(), nullptr); if (!ahEntry) return; @@ -139,7 +139,8 @@ void WorldSession::HandleAuctionSellItem(WorldPackets::AuctionHouse::AuctionSell return; } - AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->getFaction()); + uint32 houseId = 0; + AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->getFaction(), &houseId); if (!auctionHouseEntry) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) has wrong faction.", packet.Auctioneer.ToString().c_str()); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 07507392cef..95a99736563 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -280,7 +280,7 @@ void WorldSession::HandleCharEnum(PreparedQueryResult result) TC_LOG_INFO("network", "Loading char guid %s from account %u.", charInfo.Guid.ToString().c_str(), GetAccountId()); - if (!Player::ValidateAppearance(charInfo.Race, charInfo.Class, charInfo.Sex, charInfo.HairStyle, charInfo.HairColor, charInfo.Face, charInfo.FacialHair, charInfo.Skin)) + if (!Player::ValidateAppearance(charInfo.Race, charInfo.Class, charInfo.Sex, charInfo.HairStyle, charInfo.HairColor, charInfo.Face, charInfo.FacialHair, charInfo.Skin, charInfo.CustomDisplay)) { TC_LOG_ERROR("entities.player.loading", "Player %s has wrong Appearance values (Hair/Skin/Color), forcing recustomize", charInfo.Guid.ToString().c_str()); @@ -1432,7 +1432,8 @@ void WorldSession::HandleAlterAppearance(WorldPackets::Character::AlterApperance packet.NewHairColor, bs_face ? bs_face->Data : _player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_FACE_ID), bs_facialHair->Data, - bs_skinColor ? bs_skinColor->Data : _player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID))) + bs_skinColor ? bs_skinColor->Data : _player->GetByteValue(PLAYER_BYTES, PLAYER_BYTES_OFFSET_SKIN_ID), + std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE>{0, 0, 0})) return; GameObject* go = _player->FindNearestGameObjectOfType(GAMEOBJECT_TYPE_BARBER_CHAIR, 5.0f); @@ -1534,7 +1535,8 @@ void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, World uint8 plrGender = fields[3].GetUInt8(); uint16 atLoginFlags = fields[4].GetUInt16(); - if (!Player::ValidateAppearance(plrRace, plrClass, plrGender, customizeInfo->HairStyleID, customizeInfo->HairColorID, customizeInfo->FaceID, customizeInfo->FacialHairStyleID, customizeInfo->SkinID, true)) + if (!Player::ValidateAppearance(plrRace, plrClass, plrGender, customizeInfo->HairStyleID, customizeInfo->HairColorID, customizeInfo->FaceID, + customizeInfo->FacialHairStyleID, customizeInfo->SkinID, customizeInfo->CustomDisplay, true)) { SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo); return; diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 8c7f8190e09..80ee0918616 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -901,29 +901,21 @@ void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems) return; } - // tried to put normal gem in meta socket - if (itemTarget->GetSocketColor(i) == SOCKET_COLOR_META && GemProps[i]->Type != SOCKET_COLOR_META) - return; - - // tried to put meta gem in normal socket - if (itemTarget->GetSocketColor(i) != SOCKET_COLOR_META && GemProps[i]->Type == SOCKET_COLOR_META) - return; - - // tried to put normal gem in cogwheel socket - if (itemTarget->GetSocketColor(i) == SOCKET_COLOR_COGWHEEL && GemProps[i]->Type != SOCKET_COLOR_COGWHEEL) - return; - - // tried to put cogwheel gem in normal socket - if (itemTarget->GetSocketColor(i) != SOCKET_COLOR_COGWHEEL && GemProps[i]->Type == SOCKET_COLOR_COGWHEEL) - return; + // Gem must match socket color + if (SocketColorToGemTypeMask[itemTarget->GetSocketColor(i)] != GemProps[i]->Type) + { + // unless its red, blue, yellow or prismatic + if (!(SocketColorToGemTypeMask[itemTarget->GetSocketColor(i)] & SOCKET_COLOR_PRISMATIC) || !(GemProps[i]->Type & SOCKET_COLOR_PRISMATIC)) + return; + } } uint32 GemEnchants[MAX_GEM_SOCKETS]; - uint32 OldEnchants[MAX_GEM_SOCKETS]; + uint32 oldGemItemIds[MAX_GEM_SOCKETS]; for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments { GemEnchants[i] = (GemProps[i]) ? GemProps[i]->EnchantID : 0; - OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i)); + oldGemItemIds[i] = itemTarget->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).size() > i ? itemTarget->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS)[i] : 0; } // check unique-equipped conditions @@ -951,15 +943,12 @@ void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems) return; } } - else if (OldEnchants[j]) + else if (oldGemItemIds[j]) { - if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j])) + if (iGemProto->GetId() == oldGemItemIds[j]) { - if (iGemProto->GetId() == enchantEntry->SRCItemID) - { - _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL); - return; - } + _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL); + return; } } } @@ -980,13 +969,12 @@ void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems) if (iGemProto->GetItemLimitCategory() == Gems[j]->GetTemplate()->GetItemLimitCategory()) ++limit_newcount; } - else if (OldEnchants[j]) + else if (oldGemItemIds[j]) { // existing gem - if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j])) - if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(enchantEntry->SRCItemID)) - if (iGemProto->GetItemLimitCategory() == jProto->GetItemLimitCategory()) - ++limit_newcount; + if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(oldGemItemIds[j])) + if (iGemProto->GetItemLimitCategory() == jProto->GetItemLimitCategory()) + ++limit_newcount; } } @@ -1018,16 +1006,25 @@ void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems) for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot) _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false); + uint32 reqGemSlots = 0; + for (uint32 i = 0; i < MAX_GEM_SOCKETS; ++i) + if (Gems[i]) + reqGemSlots = i + 1; + + while (itemTarget->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).size() < reqGemSlots) + itemTarget->AddDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, 0); + for (int i = 0; i < MAX_GEM_SOCKETS; ++i) { - if (GemEnchants[i]) + if (Item* guidItem = _player->GetItemByGuid(socketGems.GemItem[i])) { - itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i], 0, 0, _player->GetGUID()); - if (Item* guidItem = _player->GetItemByGuid(socketGems.GemItem[i])) - { - uint32 gemCount = 1; - _player->DestroyItemCount(guidItem, gemCount, true); - } + itemTarget->SetDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, i, guidItem->GetEntry()); + + if (GemEnchants[i]) + itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i], 0, 0, _player->GetGUID()); + + uint32 gemCount = 1; + _player->DestroyItemCount(guidItem, gemCount, true); } } diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index 2060468a41a..d6e1b35de6e 100644 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -71,7 +71,7 @@ void WorldSession::HandleConfirmRespecWipeOpcode(WorldPackets::Talent::ConfirmRe void WorldSession::HandleUnlearnSkillOpcode(WorldPackets::Spells::UnlearnSkill& packet) { - SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(packet.SkillLine, GetPlayer()->getRace(), GetPlayer()->getClass()); + SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(packet.SkillLine, GetPlayer()->getRace(), GetPlayer()->getClass()); if (!rcEntry || !(rcEntry->Flags & SKILL_FLAG_UNLEARNABLE)) return; diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index a7e11e81970..be4f71e8b71 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -1557,7 +1557,7 @@ void LoadLootTemplates_Disenchant() if (!disenchant) continue; - uint32 lootid = disenchant->ID; + uint32 lootid = i; if (lootIdSet.find(lootid) == lootIdSet.end()) LootTemplates_Disenchant.ReportNonExistingId(lootid); else diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 63079904a67..1ef2e7b0ed9 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -82,10 +82,11 @@ enum Expansions EXPANSION_CATACLYSM = 3, EXPANSION_MISTS_OF_PANDARIA = 4, EXPANSION_WARLORDS_OF_DRAENOR = 5, - MAX_EXPANSIONS = 6 + EXPANSION_LEGION = 6, + MAX_EXPANSIONS }; -#define CURRENT_EXPANSION EXPANSION_WARLORDS_OF_DRAENOR +#define CURRENT_EXPANSION EXPANSION_LEGION enum Gender { @@ -174,11 +175,12 @@ enum Classes CLASS_MAGE = 8, CLASS_WARLOCK = 9, CLASS_MONK = 10, - CLASS_DRUID = 11 + CLASS_DRUID = 11, + CLASS_DEMON_HUNTER = 12 }; // max+1 for player class -#define MAX_CLASSES 12 +#define MAX_CLASSES 13 #define CLASSMASK_ALL_PLAYABLE \ ((1<<(CLASS_WARRIOR-1)) | \ @@ -191,7 +193,8 @@ enum Classes (1<<(CLASS_MAGE-1)) | \ (1<<(CLASS_WARLOCK-1)) | \ (1<<(CLASS_MONK-1)) | \ - (1<<(CLASS_DRUID-1))) + (1<<(CLASS_DRUID-1)) | \ + (1<<(CLASS_DEMON_HUNTER-1))) // valid classes for creature_template.unit_class enum UnitClass @@ -253,16 +256,18 @@ enum Powers // (6.0) POWER_RUNES = 5, POWER_RUNIC_POWER = 6, POWER_SOUL_SHARDS = 7, - POWER_ECLIPSE = 8, + POWER_LUNAR_POWER = 8, POWER_HOLY_POWER = 9, POWER_ALTERNATE_POWER = 10, // Used in some quests - POWER_DARK_FORCE = 11, + POWER_MAELSTROM = 11, POWER_CHI = 12, - POWER_SHADOW_ORBS = 13, + POWER_INSANITY = 13, POWER_BURNING_EMBERS = 14, POWER_DEMONIC_FURY = 15, POWER_ARCANE_CHARGES = 16, - MAX_POWERS = 17, + POWER_FURY = 17, + POWER_PAIN = 18, + MAX_POWERS = 19, POWER_ALL = 127, // default for class? POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) }; @@ -725,7 +730,7 @@ enum SpellAttr10 SPELL_ATTR10_UNK9 = 0x00000200, // 9 SPELL_ATTR10_UNK10 = 0x00000400, // 10 SPELL_ATTR10_HERB_GATHERING_MINING = 0x00000800, // 11 Only Herb Gathering and Mining - SPELL_ATTR10_UNK12 = 0x00001000, // 12 + SPELL_ATTR10_USE_SPELL_BASE_LEVEL_FOR_SCALING = 0x00001000, // 12 SPELL_ATTR10_UNK13 = 0x00002000, // 13 SPELL_ATTR10_UNK14 = 0x00004000, // 14 SPELL_ATTR10_UNK15 = 0x00008000, // 15 @@ -756,7 +761,7 @@ enum SpellAttr11 SPELL_ATTR11_UNK4 = 0x00000010, // 4 SPELL_ATTR11_UNK5 = 0x00000020, // 5 SPELL_ATTR11_UNK6 = 0x00000040, // 6 - SPELL_ATTR11_NO_RANK = 0x00000080, // 7 Spell_C_GetSpellRank returns 0 instead of 5 * std::min(SpellLevels->MaxLevel, caster->Level) + SPELL_ATTR11_RANK_IGNORES_CASTER_LEVEL = 0x00000080, // 7 Spell_C_GetSpellRank returns SpellLevels->MaxLevel * 5 instead of std::min(SpellLevels->MaxLevel, caster->Level) * 5 SPELL_ATTR11_UNK8 = 0x00000100, // 8 SPELL_ATTR11_UNK9 = 0x00000200, // 9 SPELL_ATTR11_UNK10 = 0x00000400, // 10 diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index aa78cae6deb..53800dbb726 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -780,22 +780,11 @@ void WorldPackets::Spells::SpellClick::Read() TryAutoDismount = _worldPacket.ReadBit(); } -WorldPacket const* WorldPackets::Spells::ConvertRune::Write() -{ - _worldPacket << uint8(Index); - _worldPacket << uint8(Rune); - - return &_worldPacket; -} - WorldPacket const* WorldPackets::Spells::ResyncRunes::Write() { _worldPacket << uint32(Runes.size()); - for (auto const& rune : Runes) - { - _worldPacket << uint8(rune.RuneType); - _worldPacket << uint8(rune.Cooldown); - } + if (!Runes.empty()) + _worldPacket.append(Runes.data(), Runes.size()); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index b1cb39251de..0680405eeb2 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -799,31 +799,14 @@ namespace WorldPackets bool TryAutoDismount = false; }; - class ConvertRune final : public ServerPacket - { - public: - ConvertRune() : ServerPacket(SMSG_CONVERT_RUNE, 1 + 1) { } - - WorldPacket const* Write() override; - - uint8 Index = 0; - uint8 Rune = 0; - }; - class ResyncRunes final : public ServerPacket { public: - struct ResyncRune - { - uint8 RuneType = 0; - uint8 Cooldown = 0; - }; - ResyncRunes(size_t size) : ServerPacket(SMSG_RESYNC_RUNES, 4 + 2 * size) { } WorldPacket const* Write() override; - std::vector<ResyncRune> Runes; + std::vector<uint8> Runes; }; class MissileTrajectoryCollision final : public ClientPacket diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index b7159ea08ae..900092c126b 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1001,7 +1001,6 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONSOLE_WRITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTROL_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONVERT_RUNE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_LOCATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 8027f49db0d..715799294de 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1668,7 +1668,6 @@ enum OpcodeServer : uint32 SMSG_BF_MGR_ENTRY_INVITE = 0xBADD, SMSG_BF_MGR_QUEUE_INVITE = 0xBADD, SMSG_BF_MGR_QUEUE_REQUEST_RESPONSE = 0xBADD, - SMSG_CONVERT_RUNE = 0xBADD, }; inline bool IsInstanceOnlyOpcode(uint32 opcode) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index c86e20a53ad..e529990cccd 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -308,7 +308,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK implemented in Spell::EffectApplyAura &AuraEffect::HandleAuraCloneCaster, //247 SPELL_AURA_CLONE_CASTER &AuraEffect::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst - &AuraEffect::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE + &AuraEffect::HandleNULL, //249 SPELL_AURA_CONVERT_RUNE deprecated &AuraEffect::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2 &AuraEffect::HandleNoImmediateEffect, //251 SPELL_AURA_MOD_ENEMY_DODGE &AuraEffect::HandleModCombatSpeedPct, //252 SPELL_AURA_252 Is there any difference between this and SPELL_AURA_MELEE_SLOW ? maybe not stacking mod? @@ -5250,39 +5250,6 @@ void AuraEffect::HandleComprehendLanguage(AuraApplication const* aurApp, uint8 m } } -void AuraEffect::HandleAuraConvertRune(AuraApplication const* aurApp, uint8 mode, bool apply) const -{ - if (!(mode & AURA_EFFECT_HANDLE_REAL)) - return; - - Unit* target = aurApp->GetTarget(); - - Player* player = target->ToPlayer(); - if (!player) - return; - - if (player->getClass() != CLASS_DEATH_KNIGHT) - return; - - uint32 runes = m_amount; - // convert number of runes specified in aura amount of rune type in miscvalue to runetype in miscvalueb - if (apply) - { - for (uint32 i = 0; i < MAX_RUNES && runes; ++i) - { - if (GetMiscValue() != player->GetCurrentRune(i)) - continue; - if (!player->GetRuneCooldown(i)) - { - player->AddRuneByAuraEffect(i, RuneType(GetMiscValueB()), this); - --runes; - } - } - } - else - player->RemoveRunesByAuraEffect(this); -} - void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, bool apply) const { Unit* target = aurApp->GetTarget(); @@ -5575,19 +5542,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const target->DealDamage(target, damage, NULL, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); break; } - // Blood of the North - // Reaping - // Death Rune Mastery - if (GetSpellInfo()->SpellIconID == 3041 || GetSpellInfo()->SpellIconID == 22 || GetSpellInfo()->SpellIconID == 2622) - { - if (target->GetTypeId() != TYPEID_PLAYER) - return; - if (target->ToPlayer()->getClass() != CLASS_DEATH_KNIGHT) - return; - - // timer expired - remove death runes - target->ToPlayer()->RemoveRunesByAuraEffect(this); - } break; default: break; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 0d907e4148c..46a0ccdabc6 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -294,7 +294,6 @@ class TC_GAME_API AuraEffect void HandleAuraEmpathy(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleAuraModFaction(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleComprehendLanguage(AuraApplication const* aurApp, uint8 mode, bool apply) const; - void HandleAuraConvertRune(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleAuraOpenStable(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleAuraModFakeInebriation(AuraApplication const* aurApp, uint8 mode, bool apply) const; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 521abd26e7b..af22d2fa496 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1517,21 +1517,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b target->RemoveAura(61988); break; case SPELLFAMILY_DEATHKNIGHT: - // Blood of the North - // Reaping - // Death Rune Mastery - if (GetSpellInfo()->SpellIconID == 3041 || GetSpellInfo()->SpellIconID == 22 || GetSpellInfo()->SpellIconID == 2622) - { - if (!GetEffect(0) || GetEffect(0)->GetAuraType() != SPELL_AURA_PERIODIC_DUMMY) - break; - if (target->GetTypeId() != TYPEID_PLAYER) - break; - if (target->ToPlayer()->getClass() != CLASS_DEATH_KNIGHT) - break; - - // aura removed - remove death runes - target->ToPlayer()->RemoveRunesByAuraEffect(GetEffect(0)); - } break; case SPELLFAMILY_HUNTER: // Glyph of Freezing Trap diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index dac9b82549c..cf35e643a02 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3340,7 +3340,7 @@ void Spell::cast(bool skipCheck) if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) { m_caster->GetSpellHistory()->ResetCooldown(m_spellInfo->Id, true); - m_caster->GetSpellHistory()->RestoreCharge(m_spellInfo->ChargeCategoryEntry); + m_caster->GetSpellHistory()->RestoreCharge(m_spellInfo->ChargeCategoryId); } } @@ -3892,8 +3892,7 @@ void Spell::SendSpellStart() && std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellInfo::CostData const& cost) { return cost.Power != POWER_HEALTH; }) != m_powerCost.end()) castFlags |= CAST_FLAG_POWER_LEFT_SELF; - if (m_spellInfo->RuneCostID && - std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellInfo::CostData const& cost) { return cost.Power == POWER_RUNES; }) != m_powerCost.end()) + if (std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellInfo::CostData const& cost) { return cost.Power == POWER_RUNES; }) != m_powerCost.end()) castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it WorldPackets::Spells::SpellStart packet; @@ -3938,7 +3937,7 @@ void Spell::SendSpellStart() for (uint8 i = 0; i < MAX_RUNES; ++i) { // float casts ensure the division is performed on floats as we need float result - float baseCd = float(player->GetRuneBaseCooldown(i)); + float baseCd = float(player->GetRuneBaseCooldown()); castData.RemainingRunes->Cooldowns.push_back((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed } } @@ -3995,7 +3994,6 @@ void Spell::SendSpellGo() if ((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) - && m_spellInfo->RuneCostID && std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellInfo::CostData const& cost) { return cost.Power == POWER_RUNES; }) != m_powerCost.end() && !(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)) { @@ -4056,7 +4054,7 @@ void Spell::SendSpellGo() for (uint8 i = 0; i < MAX_RUNES; ++i) { // float casts ensure the division is performed on floats as we need float result - float baseCd = float(player->GetRuneBaseCooldown(i)); + float baseCd = float(player->GetRuneBaseCooldown()); castData.RemainingRunes->Cooldowns.push_back((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed } } @@ -4544,9 +4542,10 @@ void Spell::TakePower() } } -SpellCastResult Spell::CheckRuneCost(uint32 runeCostID) +SpellCastResult Spell::CheckRuneCost() { - if (std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellInfo::CostData const& cost) { return cost.Power == POWER_RUNES; }) == m_powerCost.end() || !runeCostID) + auto runeCost = std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellInfo::CostData const& cost) { return cost.Power == POWER_RUNES; }); + if (runeCost == m_powerCost.end()) return SPELL_CAST_OK; Player* player = m_caster->ToPlayer(); @@ -4556,36 +4555,12 @@ SpellCastResult Spell::CheckRuneCost(uint32 runeCostID) if (player->getClass() != CLASS_DEATH_KNIGHT) return SPELL_CAST_OK; - SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(runeCostID); - if (!src) - return SPELL_CAST_OK; - - if (src->NoRuneCost()) - return SPELL_CAST_OK; - - int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death - - for (uint32 i = 0; i < NUM_RUNE_TYPES; ++i) - { - runeCost[i] = src->RuneCost[i]; - if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this); - } - - runeCost[RUNE_DEATH] += MAX_RUNES; - - for (uint32 i = 0; i < MAX_RUNES; ++i) - { - RuneType rune = player->GetCurrentRune(i); - if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0)) - runeCost[rune]--; - } - - for (uint32 i = 0; i < RUNE_DEATH; ++i) - if (runeCost[i] > 0) - runeCost[RUNE_DEATH] += runeCost[i]; + int32 readyRunes = 0; + for (uint32 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i) + if (player->GetRuneCooldown(i) == 0) + ++readyRunes; - if (runeCost[RUNE_DEATH] > MAX_RUNES) + if (readyRunes < runeCost->Amount) return SPELL_FAILED_NO_POWER; // not sure if result code is correct return SPELL_CAST_OK; @@ -4596,95 +4571,24 @@ void Spell::TakeRunePower(bool didHit) if (m_caster->GetTypeId() != TYPEID_PLAYER || m_caster->getClass() != CLASS_DEATH_KNIGHT) return; - SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID); - if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain())) - return; - Player* player = m_caster->ToPlayer(); m_runesState = player->GetRunesState(); // store previous state - int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death - - for (uint32 i = 0; i < NUM_RUNE_TYPES; ++i) + int32 runeCost = std::find_if(m_powerCost.begin(), m_powerCost.end(), [](SpellInfo::CostData const& cost) { - runeCost[i] = runeCostData->RuneCost[i]; - if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this); - } + return cost.Power == POWER_RUNES; + })->Amount; - bool convertUsedRunes = false; - for (AuraEffect const* convertConsumedRuneAuras : m_caster->GetAuraEffectsByType(SPELL_AURA_CONVERT_CONSUMED_RUNE)) - if (convertConsumedRuneAuras->IsAffectingSpell(m_spellInfo)) - convertUsedRunes = true; - - // Let's say we use a skill that requires a Frost rune. This is the order: - // - Frost rune - // - Death rune, originally a Frost rune - // - Death rune, any kind - for (uint32 i = 0; i < MAX_RUNES; ++i) + for (uint32 i = 0; i < player->GetMaxPower(POWER_RUNES); ++i) { - RuneType rune = player->GetCurrentRune(i); - if (!player->GetRuneCooldown(i) && runeCost[rune] > 0) + if (!player->GetRuneCooldown(i) && runeCost > 0) { - player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i) : uint32(RUNE_MISS_COOLDOWN), true); - player->SetLastUsedRune(rune); - runeCost[rune]--; + player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown() : uint32(RUNE_MISS_COOLDOWN), true); + --runeCost; if (convertUsedRunes) player->ConvertRune(i, RUNE_DEATH); } } - - // Find a Death rune where the base rune matches the one we need - runeCost[RUNE_DEATH] += runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST]; - if (runeCost[RUNE_DEATH] > 0) - { - for (uint32 i = 0; i < MAX_RUNES; ++i) - { - RuneType rune = player->GetCurrentRune(i); - RuneType baseRune = player->GetBaseRune(i); - if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && runeCost[baseRune] > 0) - { - player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i) : uint32(RUNE_MISS_COOLDOWN), true); - player->SetLastUsedRune(rune); - runeCost[baseRune]--; - runeCost[rune]--; - - // keep Death Rune type if missed - if (didHit && !convertUsedRunes) - player->RestoreBaseRune(i); - - if (runeCost[RUNE_DEATH] == 0) - break; - } - } - } - - // Grab any Death rune - if (runeCost[RUNE_DEATH] > 0) - { - for (uint32 i = 0; i < MAX_RUNES; ++i) - { - RuneType rune = player->GetCurrentRune(i); - if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH) - { - player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i) : uint32(RUNE_MISS_COOLDOWN), true); - player->SetLastUsedRune(rune); - runeCost[rune]--; - - // keep Death Rune type if missed - if (didHit && !convertUsedRunes) - player->RestoreBaseRune(i); - - if (runeCost[RUNE_DEATH] == 0) - break; - } - } - } - - // you can gain some runic power when use runes - if (didHit) - if (int32 rp = int32(runeCostData->RunicPower * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME))) - player->ModifyPower(POWER_RUNIC_POWER, int32(rp)); } void Spell::TakeReagents() @@ -5952,7 +5856,7 @@ SpellCastResult Spell::CheckRange(bool strict) { // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range // these are triggered by other spells - possibly we should omit range check in that case? - if (m_spellInfo->RangeEntry->ID == 1) + if (m_spellInfo->RangeIndex == 1) return SPELL_CAST_OK; range_type = m_spellInfo->RangeEntry->Flags; @@ -6025,7 +5929,7 @@ SpellCastResult Spell::CheckPower() //check rune cost only if a spell has PowerType == POWER_RUNES if (cost.Power == POWER_RUNES) { - SpellCastResult failReason = CheckRuneCost(m_spellInfo->RuneCostID); + SpellCastResult failReason = CheckRuneCost(); if (failReason != SPELL_CAST_OK) return failReason; } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 192ed942ce0..2be8c001ae7 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -501,7 +501,7 @@ class TC_GAME_API Spell SpellCastResult CheckItems(); SpellCastResult CheckRange(bool strict); SpellCastResult CheckPower(); - SpellCastResult CheckRuneCost(uint32 runeCostID); + SpellCastResult CheckRuneCost(); SpellCastResult CheckCasterAuras() const; SpellCastResult CheckArenaAndRatedBattlegroundCastRules(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index d605e1d8679..b174454225d 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1618,7 +1618,7 @@ void Spell::EffectEnergize(SpellEffIndex /*effIndex*/) if (level_diff > 0) damage -= level_multiplier * level_diff; - if (damage < 0 && power != POWER_ECLIPSE) + if (damage < 0 && power != POWER_LUNAR_POWER) return; m_caster->EnergizeBySpell(unitTarget, m_spellInfo->Id, damage, power); @@ -2435,7 +2435,7 @@ void Spell::EffectLearnSkill(SpellEffIndex /*effIndex*/) return; uint32 skillid = effectInfo->MiscValue; - SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skillid, unitTarget->getRace(), unitTarget->getClass()); + SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(skillid, unitTarget->getRace(), unitTarget->getClass()); if (!rcEntry) return; @@ -5192,52 +5192,24 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex) m_runesState = m_caster->ToPlayer()->GetRunesState(); uint32 count = damage; - if (count == 0) count = 1; - for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j) + if (count == 0) + count = 1; + + // first restore fully depleted runes + for (uint32 j = 0; j < player->GetMaxPower(POWER_RUNES) && count > 0; ++j) { - if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(effectInfo->MiscValue)) + if (player->GetRuneCooldown(j) == player->GetRuneBaseCooldown()) { - if (m_spellInfo->Id == 45529) - if (player->GetBaseRune(j) != RuneType(effectInfo->MiscValueB)) - continue; player->SetRuneCooldown(j, 0); --count; } } - // Blood Tap - if (m_spellInfo->Id == 45529 && count > 0) - { - for (uint32 l = 0; l + 1 < MAX_RUNES && count > 0; ++l) - { - // Check if both runes are on cd as that is the only time when this needs to come into effect - if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(effectInfo->MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(effectInfo->MiscValueB))) - { - // Should always update the rune with the lowest cd - if (l + 1 < MAX_RUNES && player->GetRuneCooldown(l) >= player->GetRuneCooldown(l+1)) - l++; - player->SetRuneCooldown(l, 0); - --count; - // is needed to push through to the client that the rune is active - player->ResyncRunes(MAX_RUNES); - } - else - break; - } - } - - // Empower rune weapon - if (m_spellInfo->Id == 47568) + // then the rest if we still got something left + for (uint32 j = 0; j < player->GetMaxPower(POWER_RUNES) && count > 0; ++j) { - // Need to do this just once - if (effIndex != 0) - return; - - for (uint32 i = 0; i < MAX_RUNES; ++i) - { - if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH)) - player->SetRuneCooldown(i, 0); - } + player->SetRuneCooldown(j, 0); + --count; } } @@ -5435,7 +5407,7 @@ void Spell::EffectPlayMusic(SpellEffIndex /*effIndex*/) uint32 soundid = effectInfo->MiscValue; - if (!sSoundEntriesStore.LookupEntry(soundid)) + if (!sSoundKitStore.LookupEntry(soundid)) { TC_LOG_ERROR("spells", "EffectPlayMusic: Sound (Id: %u) does not exist in spell %u.", soundid, m_spellInfo->Id); return; @@ -5489,7 +5461,7 @@ void Spell::EffectPlaySound(SpellEffIndex /*effIndex*/) uint32 soundId = effectInfo->MiscValue; - if (!sSoundEntriesStore.LookupEntry(soundId)) + if (!sSoundKitStore.LookupEntry(soundId)) { TC_LOG_ERROR("spells", "EffectPlaySound: Sound (Id: %u) does not exist in spell %u.", soundId, m_spellInfo->Id); return; diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 7de2c2a9d46..bb991b66cf9 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -237,7 +237,7 @@ void SpellHistory::HandleCooldowns(SpellInfo const* spellInfo, Item const* item, void SpellHistory::HandleCooldowns(SpellInfo const* spellInfo, uint32 itemID, Spell* spell /*= nullptr*/) { - if (ConsumeCharge(spellInfo->ChargeCategoryEntry)) + if (ConsumeCharge(spellInfo->ChargeCategoryId)) return; if (Player* player = _owner->ToPlayer()) @@ -268,7 +268,7 @@ bool SpellHistory::IsReady(SpellInfo const* spellInfo, uint32 itemId /*= 0*/, bo if (HasCooldown(spellInfo->Id, itemId, ignoreCategoryCooldown)) return false; - if (!HasCharge(spellInfo->ChargeCategoryEntry)) + if (!HasCharge(spellInfo->ChargeCategoryId)) return false; return true; @@ -696,16 +696,16 @@ bool SpellHistory::IsSchoolLocked(SpellSchoolMask schoolMask) const return false; } -bool SpellHistory::ConsumeCharge(SpellCategoryEntry const* chargeCategoryEntry) +bool SpellHistory::ConsumeCharge(uint32 chargeCategoryId) { - if (!chargeCategoryEntry) + if (!sSpellCategoryStore.LookupEntry(chargeCategoryId)) return false; - int32 chargeRecovery = GetChargeRecoveryTime(chargeCategoryEntry); - if (chargeRecovery > 0 && GetMaxCharges(chargeCategoryEntry) > 0) + int32 chargeRecovery = GetChargeRecoveryTime(chargeCategoryId); + if (chargeRecovery > 0 && GetMaxCharges(chargeCategoryId) > 0) { Clock::time_point recoveryStart; - std::deque<ChargeEntry>& charges = _categoryCharges[chargeCategoryEntry->ID]; + std::deque<ChargeEntry>& charges = _categoryCharges[chargeCategoryId]; if (charges.empty()) recoveryStart = Clock::now(); else @@ -718,12 +718,9 @@ bool SpellHistory::ConsumeCharge(SpellCategoryEntry const* chargeCategoryEntry) return false; } -void SpellHistory::RestoreCharge(SpellCategoryEntry const* chargeCategoryEntry) +void SpellHistory::RestoreCharge(uint32 chargeCategoryId) { - if (!chargeCategoryEntry) - return; - - auto itr = _categoryCharges.find(chargeCategoryEntry->ID); + auto itr = _categoryCharges.find(chargeCategoryId); if (itr != _categoryCharges.end() && !itr->second.empty()) { itr->second.pop_back(); @@ -731,7 +728,7 @@ void SpellHistory::RestoreCharge(SpellCategoryEntry const* chargeCategoryEntry) if (Player* player = GetPlayerOwner()) { WorldPackets::Spells::SetSpellCharges setSpellCharges; - setSpellCharges.Category = chargeCategoryEntry->ID; + setSpellCharges.Category = chargeCategoryId; if (!itr->second.empty()) setSpellCharges.NextRecoveryTime = uint32(std::chrono::duration_cast<std::chrono::milliseconds>(itr->second.front().RechargeEnd - Clock::now()).count()); setSpellCharges.ConsumedCharges = itr->second.size(); @@ -742,12 +739,9 @@ void SpellHistory::RestoreCharge(SpellCategoryEntry const* chargeCategoryEntry) } } -void SpellHistory::ResetCharges(SpellCategoryEntry const* chargeCategoryEntry) +void SpellHistory::ResetCharges(uint32 chargeCategoryId) { - if (!chargeCategoryEntry) - return; - - auto itr = _categoryCharges.find(chargeCategoryEntry->ID); + auto itr = _categoryCharges.find(chargeCategoryId); if (itr != _categoryCharges.end()) { _categoryCharges.erase(itr); @@ -756,7 +750,7 @@ void SpellHistory::ResetCharges(SpellCategoryEntry const* chargeCategoryEntry) { WorldPackets::Spells::ClearSpellCharges clearSpellCharges; clearSpellCharges.IsPet = _owner != player; - clearSpellCharges.Category = chargeCategoryEntry->ID; + clearSpellCharges.Category = chargeCategoryId; player->SendDirectMessage(clearSpellCharges.Write()); } } @@ -774,40 +768,42 @@ void SpellHistory::ResetAllCharges() } } -bool SpellHistory::HasCharge(SpellCategoryEntry const* chargeCategoryEntry) const +bool SpellHistory::HasCharge(uint32 chargeCategoryId) const { - if (!chargeCategoryEntry) + if (!sSpellCategoryStore.LookupEntry(chargeCategoryId)) return true; // Check if the spell is currently using charges (untalented warlock Dark Soul) - int32 maxCharges = GetMaxCharges(chargeCategoryEntry); + int32 maxCharges = GetMaxCharges(chargeCategoryId); if (maxCharges <= 0) return true; - auto itr = _categoryCharges.find(chargeCategoryEntry->ID); + auto itr = _categoryCharges.find(chargeCategoryId); return itr == _categoryCharges.end() || int32(itr->second.size()) < maxCharges; } -int32 SpellHistory::GetMaxCharges(SpellCategoryEntry const* chargeCategoryEntry) const +int32 SpellHistory::GetMaxCharges(uint32 chargeCategoryId) const { + SpellCategoryEntry const* chargeCategoryEntry = sSpellCategoryStore.LookupEntry(chargeCategoryId); if (!chargeCategoryEntry) return 0; uint32 charges = chargeCategoryEntry->MaxCharges; - charges += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MAX_CHARGES, chargeCategoryEntry->ID); + charges += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MAX_CHARGES, chargeCategoryId); return charges; } -int32 SpellHistory::GetChargeRecoveryTime(SpellCategoryEntry const* chargeCategoryEntry) const +int32 SpellHistory::GetChargeRecoveryTime(uint32 chargeCategoryId) const { + SpellCategoryEntry const* chargeCategoryEntry = sSpellCategoryStore.LookupEntry(chargeCategoryId); if (!chargeCategoryEntry) return 0; int32 recoveryTime = chargeCategoryEntry->ChargeRecoveryTime; - recoveryTime += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MOD, chargeCategoryEntry->ID); + recoveryTime += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MOD, chargeCategoryId); float recoveryTimeF = recoveryTime; - recoveryTimeF *= _owner->GetTotalAuraMultiplierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER, chargeCategoryEntry->ID); + recoveryTimeF *= _owner->GetTotalAuraMultiplierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER, chargeCategoryId); if (_owner->HasAuraType(SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE)) recoveryTimeF *= _owner->GetFloatValue(UNIT_MOD_CAST_HASTE); diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index f2a3d346fdf..51b22c7e38a 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -132,13 +132,13 @@ public: bool IsSchoolLocked(SpellSchoolMask schoolMask) const; // Charges - bool ConsumeCharge(SpellCategoryEntry const* chargeCategoryEntry); - void RestoreCharge(SpellCategoryEntry const* chargeCategoryEntry); - void ResetCharges(SpellCategoryEntry const* chargeCategoryEntry); + bool ConsumeCharge(uint32 chargeCategoryId); + void RestoreCharge(uint32 chargeCategoryId); + void ResetCharges(uint32 chargeCategoryId); void ResetAllCharges(); - bool HasCharge(SpellCategoryEntry const* chargeCategoryEntry) const; - int32 GetMaxCharges(SpellCategoryEntry const* chargeCategoryEntry) const; - int32 GetChargeRecoveryTime(SpellCategoryEntry const* chargeCategoryEntry) const; + bool HasCharge(uint32 chargeCategoryId) const; + int32 GetMaxCharges(uint32 chargeCategoryId) const; + int32 GetChargeRecoveryTime(uint32 chargeCategoryId) const; // Global cooldown bool HasGlobalCooldown(SpellInfo const* spellInfo) const; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 28ac49fde1f..5b820f02c02 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -360,7 +360,7 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 147 }; -SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* _effect) +SpellEffectInfo::SpellEffectInfo(SpellEffectScalingEntry const* spellEffectScaling, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* _effect) { _spellInfo = spellInfo; EffectIndex = _effect ? _effect->EffectIndex : effIndex; @@ -389,12 +389,9 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo con BonusCoefficientFromAP = _effect ? _effect->BonusCoefficientFromAP : 0.0f; ImplicitTargetConditions = NULL; - uint32 _effectScalingId = _effect ? sSpellEffectScallingByEffectId.find(_effect->ID) != sSpellEffectScallingByEffectId.end() ? sSpellEffectScallingByEffectId[_effect->ID] : 0 : 0; - SpellEffectScalingEntry const* _effectScalingEntry = sSpellEffectScalingStore.LookupEntry(_effectScalingId); - - Scaling.Coefficient = _effectScalingEntry ? _effectScalingEntry->Coefficient : 0.0f; - Scaling.Variance = _effectScalingEntry ? _effectScalingEntry->Variance : 0.0f; - Scaling.ResourceCoefficient = _effectScalingEntry ? _effectScalingEntry->ResourceCoefficient : 0.0f; + Scaling.Coefficient = spellEffectScaling ? spellEffectScaling->Coefficient : 0.0f; + Scaling.Variance = spellEffectScaling ? spellEffectScaling->Variance : 0.0f; + Scaling.ResourceCoefficient = spellEffectScaling ? spellEffectScaling->ResourceCoefficient : 0.0f; } bool SpellEffectInfo::IsEffect() const @@ -468,7 +465,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const* else if (caster) level = caster->getLevel(); - if (!_spellInfo->HasAttribute(SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL) && _spellInfo->HasAttribute(SPELL_ATTR10_UNK12)) + if (!_spellInfo->HasAttribute(SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL) && _spellInfo->HasAttribute(SPELL_ATTR10_USE_SPELL_BASE_LEVEL_FOR_SCALING)) level = _spellInfo->BaseLevel; if (_spellInfo->Scaling.MaxScalingLevel && _spellInfo->Scaling.MaxScalingLevel < level) @@ -492,12 +489,6 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const* } else value = GetRandomPropertyPoints(_spellInfo->Scaling.ScalesFromItemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0); - - if (level < _spellInfo->Scaling.CastTimeMaxLevel && _spellInfo->Scaling.CastTimeMax) - value *= float(_spellInfo->Scaling.CastTimeMin + (level - 1) * (_spellInfo->Scaling.CastTimeMax - _spellInfo->Scaling.CastTimeMin) / (_spellInfo->Scaling.CastTimeMaxLevel - 1)) / float(_spellInfo->Scaling.CastTimeMax); - - if (level < _spellInfo->Scaling.NerfMaxLevel) - value *= ((((1.0f - _spellInfo->Scaling.NerfFactor) * (level - 1)) / (_spellInfo->Scaling.NerfMaxLevel - 1)) + _spellInfo->Scaling.NerfFactor); } value *= Scaling.Coefficient; @@ -976,10 +967,11 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 251 SPELL_EFFECT_SET_GARRISON_CACHE_SIZE }; -SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& effectsMap, SpellVisualMap&& visuals) +SpellInfo::SpellInfo(SpellInfoLoadHelper const& data, SpellEffectEntryMap const& effectsMap, SpellVisualMap&& visuals, + std::unordered_map<uint32, SpellEffectScalingEntry const*> const& effectScaling) : _hasPowerDifficultyData(false) { - Id = spellEntry->ID; + Id = data.Entry->ID; // SpellDifficultyEntry for (SpellEffectEntryMap::value_type const& itr : effectsMap) @@ -990,31 +982,17 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& ef for (size_t i = 0; i < effects.size(); ++i) { if (SpellEffectEntry const* effect = effects[i]) - _effects[itr.first][effect->EffectIndex] = new SpellEffectInfo(spellEntry, this, effect->EffectIndex, effect); + { + auto scalingItr = effectScaling.find(effect->ID); + _effects[itr.first][effect->EffectIndex] = new SpellEffectInfo(scalingItr != effectScaling.end() ? scalingItr->second : nullptr, this, effect->EffectIndex, effect); + } } } - SpellName = spellEntry->Name_lang; - RuneCostID = spellEntry->RuneCostID; - SpellDifficultyId = 0; - SpellScalingId = spellEntry->ScalingID; - SpellAuraOptionsId = spellEntry->AuraOptionsID; - SpellAuraRestrictionsId = spellEntry->AuraRestrictionsID; - SpellCastingRequirementsId = spellEntry->CastingRequirementsID; - SpellCategoriesId = spellEntry->CategoriesID; - SpellClassOptionsId = spellEntry->ClassOptionsID; - SpellCooldownsId = spellEntry->CooldownsID; - SpellEquippedItemsId = spellEntry->EquippedItemsID; - SpellInterruptsId = spellEntry->InterruptsID; - SpellLevelsId = spellEntry->LevelsID; - SpellReagentsId = spellEntry->ReagentsID; - SpellShapeshiftId = spellEntry->ShapeshiftID; - SpellTargetRestrictionsId = spellEntry->TargetRestrictionsID; - SpellTotemsId = spellEntry->TotemsID; - SpellMiscId = spellEntry->MiscID; + SpellName = data.Entry->Name; // SpellMiscEntry - SpellMiscEntry const* _misc = GetSpellMisc(); + SpellMiscEntry const* _misc = data.Misc; Attributes = _misc ? _misc->Attributes : 0; AttributesEx = _misc ? _misc->AttributesEx : 0; AttributesEx2 = _misc ? _misc->AttributesExB : 0; @@ -1031,6 +1009,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& ef AttributesEx13 = _misc ? _misc->AttributesExM : 0; CastTimeEntry = _misc ? (_misc->CastingTimeIndex ? sSpellCastTimesStore.LookupEntry(_misc->CastingTimeIndex) : NULL) : NULL; DurationEntry = _misc ? (_misc->DurationIndex ? sSpellDurationStore.LookupEntry(_misc->DurationIndex) : NULL) : NULL; + RangeIndex = _misc ? _misc->RangeIndex : 0; RangeEntry = _misc ? (_misc->RangeIndex ? sSpellRangeStore.LookupEntry(_misc->RangeIndex) : NULL) : NULL; Speed = _misc ? _misc->Speed : 0; SchoolMask = _misc ? _misc->SchoolMask : 0; @@ -1041,18 +1020,13 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& ef _visuals = std::move(visuals); // SpellScalingEntry - SpellScalingEntry const* _scaling = GetSpellScaling(); - Scaling.CastTimeMin = _scaling ? _scaling->CastTimeMin : 0; - Scaling.CastTimeMax = _scaling ?_scaling->CastTimeMax : 0; - Scaling.CastTimeMaxLevel = _scaling ? _scaling->CastTimeMaxLevel : 0; + SpellScalingEntry const* _scaling = data.Scaling; Scaling.Class = _scaling ? _scaling->ScalingClass : 0; - Scaling.NerfFactor = _scaling ? _scaling->NerfFactor : 0; - Scaling.NerfMaxLevel = _scaling ? _scaling->NerfMaxLevel : 0; Scaling.MaxScalingLevel = _scaling ? _scaling->MaxScalingLevel : 0; Scaling.ScalesFromItemLevel = _scaling ? _scaling->ScalesFromItemLevel : 0; // SpellAuraOptionsEntry - SpellAuraOptionsEntry const* _options = GetSpellAuraOptions(); + SpellAuraOptionsEntry const* _options = data.AuraOptions; SpellProcsPerMinuteEntry const* _ppm = _options ? sSpellProcsPerMinuteStore.LookupEntry(_options->SpellProcsPerMinuteID) : nullptr; ProcFlags = _options ? _options->ProcTypeMask : 0; ProcChance = _options ? _options->ProcChance : 0; @@ -1064,7 +1038,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& ef StackAmount = _options ? _options->CumulativeAura : 0; // SpellAuraRestrictionsEntry - SpellAuraRestrictionsEntry const* _aura = GetSpellAuraRestrictions(); + SpellAuraRestrictionsEntry const* _aura = data.AuraRestrictions; CasterAuraState = _aura ? _aura->CasterAuraState : 0; TargetAuraState = _aura ? _aura->TargetAuraState : 0; ExcludeCasterAuraState = _aura ? _aura->ExcludeCasterAuraState : 0; @@ -1075,47 +1049,47 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& ef ExcludeTargetAuraSpell = _aura ? _aura->ExcludeTargetAuraSpell : 0; // SpellCastingRequirementsEntry - SpellCastingRequirementsEntry const* _castreq = GetSpellCastingRequirements(); + SpellCastingRequirementsEntry const* _castreq = data.CastingRequirements; RequiresSpellFocus = _castreq ? _castreq->RequiresSpellFocus : 0; FacingCasterFlags = _castreq ? _castreq->FacingCasterFlags : 0; RequiredAreasID = _castreq ? _castreq->RequiredAreasID : -1; // SpellCategoriesEntry - SpellCategoriesEntry const* _categorie = GetSpellCategories(); - CategoryEntry = _categorie ? sSpellCategoryStore.LookupEntry(_categorie->Category) : NULL; + SpellCategoriesEntry const* _categorie = data.Categories; + CategoryId = _categorie ? _categorie->Category : 0; Dispel = _categorie ? _categorie->DispelType : 0; Mechanic = _categorie ? _categorie->Mechanic : 0; StartRecoveryCategory = _categorie ? _categorie->StartRecoveryCategory : 0; DmgClass = _categorie ? _categorie->DefenseType : 0; PreventionType = _categorie ? _categorie->PreventionType : 0; - ChargeCategoryEntry = _categorie ? sSpellCategoryStore.LookupEntry(_categorie->ChargeCategory) : 0; + ChargeCategoryId = _categorie ? _categorie->ChargeCategory : 0; // SpellClassOptionsEntry - SpellClassOptionsEntry const* _class = GetSpellClassOptions(); + SpellClassOptionsEntry const* _class = data.ClassOptions; SpellFamilyName = _class ? _class->SpellClassSet : 0; SpellFamilyFlags = _class ? _class->SpellClassMask : flag128(); // SpellCooldownsEntry - SpellCooldownsEntry const* _cooldowns = GetSpellCooldowns(); + SpellCooldownsEntry const* _cooldowns = data.Cooldowns; RecoveryTime = _cooldowns ? _cooldowns->RecoveryTime : 0; CategoryRecoveryTime = _cooldowns ? _cooldowns->CategoryRecoveryTime : 0; StartRecoveryTime = _cooldowns ? _cooldowns->StartRecoveryTime : 0; // SpellEquippedItemsEntry - SpellEquippedItemsEntry const* _equipped = GetSpellEquippedItems(); + SpellEquippedItemsEntry const* _equipped = data.EquippedItems; EquippedItemClass = _equipped ? _equipped->EquippedItemClass : -1; EquippedItemSubClassMask = _equipped ?_equipped->EquippedItemSubClassMask : -1; EquippedItemInventoryTypeMask = _equipped ? _equipped->EquippedItemInventoryTypeMask : -1; // SpellInterruptsEntry - SpellInterruptsEntry const* _interrupt = GetSpellInterrupts(); + SpellInterruptsEntry const* _interrupt = data.Interrupts; InterruptFlags = _interrupt ? _interrupt->InterruptFlags : 0; // TODO: 6.x these flags have 2 parts AuraInterruptFlags = _interrupt ? _interrupt->AuraInterruptFlags[0] : 0; ChannelInterruptFlags = _interrupt ? _interrupt->ChannelInterruptFlags[0] : 0; // SpellLevelsEntry - SpellLevelsEntry const* _levels = GetSpellLevels(); + SpellLevelsEntry const* _levels = data.Levels; MaxLevel = _levels ? _levels->MaxLevel : 0; BaseLevel = _levels ? _levels->BaseLevel : 0; SpellLevel = _levels ? _levels->SpellLevel : 0; @@ -1124,26 +1098,26 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& ef PowerCosts = sDB2Manager.GetSpellPowers(Id, DIFFICULTY_NONE, &_hasPowerDifficultyData); // SpellReagentsEntry - SpellReagentsEntry const* _reagents = GetSpellReagents(); + SpellReagentsEntry const* _reagents = data.Reagents; for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i) Reagent[i] = _reagents ? _reagents->Reagent[i] : 0; for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i) ReagentCount[i] = _reagents ? _reagents->ReagentCount[i] : 0; // SpellShapeshiftEntry - SpellShapeshiftEntry const* _shapeshift = GetSpellShapeshift(); + SpellShapeshiftEntry const* _shapeshift = data.Shapeshift; Stances = _shapeshift ? MAKE_PAIR64(_shapeshift->ShapeshiftMask[0], _shapeshift->ShapeshiftMask[1]) : 0; StancesNot = _shapeshift ? MAKE_PAIR64(_shapeshift->ShapeshiftExclude[0], _shapeshift->ShapeshiftExclude[1]) : 0; // SpellTargetRestrictionsEntry - SpellTargetRestrictionsEntry const* _target = GetSpellTargetRestrictions(); + SpellTargetRestrictionsEntry const* _target = data.TargetRestrictions; Targets = _target ? _target->Targets : 0; TargetCreatureType = _target ? _target->TargetCreatureType : 0; MaxAffectedTargets = _target ? _target->MaxAffectedTargets : 0; MaxTargetLevel = _target ? _target->MaxTargetLevel : 0; // SpellTotemsEntry - SpellTotemsEntry const* _totem = GetSpellTotems(); + SpellTotemsEntry const* _totem = data.Totems; for (uint8 i = 0; i < 2; ++i) TotemCategory[i] = _totem ? _totem->RequiredTotemCategoryID[i] : 0; for (uint8 i = 0; i < 2; ++i) @@ -1169,7 +1143,7 @@ void SpellInfo::_UnloadSpellEffects() uint32 SpellInfo::GetCategory() const { - return CategoryEntry ? CategoryEntry->ID : 0; + return CategoryId; } bool SpellInfo::HasEffect(uint32 difficulty, SpellEffectName effect) const @@ -1475,7 +1449,11 @@ bool SpellInfo::IsStackableOnOneSlotWithDifferentCasters() const bool SpellInfo::IsCooldownStartedOnEvent() const { - return Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE || (CategoryEntry && CategoryEntry->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT); + if (Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE) + return true; + + SpellCategoryEntry const* category = sSpellCategoryStore.LookupEntry(CategoryId); + return category && category->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT; } bool SpellInfo::IsDeathPersistent() const @@ -2505,33 +2483,43 @@ int32 SpellInfo::GetDuration() const { if (!DurationEntry) return 0; - return (DurationEntry->Duration[0] == -1) ? -1 : abs(DurationEntry->Duration[0]); + return (DurationEntry->Duration == -1) ? -1 : abs(DurationEntry->Duration); } int32 SpellInfo::GetMaxDuration() const { if (!DurationEntry) return 0; - return (DurationEntry->Duration[2] == -1) ? -1 : abs(DurationEntry->Duration[2]); + return (DurationEntry->MaxDuration == -1) ? -1 : abs(DurationEntry->MaxDuration); } uint32 SpellInfo::CalcCastTime(uint8 level, Spell* spell /*= NULL*/) const { int32 castTime = 0; - if (!level && spell) - level = spell->GetCaster()->getLevel(); - - // not all spells have cast time index and this is all is pasiive abilities - if (level && Scaling.CastTimeMax > 0) + if (CastTimeEntry) { - castTime = Scaling.CastTimeMax; - if (Scaling.CastTimeMaxLevel > level) - castTime = Scaling.CastTimeMin + int32(level - 1) * (Scaling.CastTimeMax - Scaling.CastTimeMin) / (Scaling.CastTimeMaxLevel - 1); + int32 calcLevel = spell ? spell->GetCaster()->getLevel() : 0; + if (MaxLevel && uint32(calcLevel) > MaxLevel) + calcLevel = MaxLevel; + + if (HasAttribute(SPELL_ATTR13_UNK17)) + calcLevel *= 5; + + if (MaxLevel && uint32(calcLevel) > MaxLevel) + calcLevel = MaxLevel; + + if (BaseLevel) + calcLevel -= BaseLevel; + + if (calcLevel < 0) + calcLevel = 0; + + castTime = CastTimeEntry->CastTime + CastTimeEntry->CastTimePerLevel * level; + if (castTime < CastTimeEntry->MinCastTime) + castTime = CastTimeEntry->MinCastTime; } - else if (CastTimeEntry) - castTime = CastTimeEntry->CastTime; - if (!castTime) + if (castTime <= 0) return 0; if (spell) @@ -3344,81 +3332,6 @@ bool SpellInfo::_IsPositiveTarget(uint32 targetA, uint32 targetB) return true; } -SpellTargetRestrictionsEntry const* SpellInfo::GetSpellTargetRestrictions() const -{ - return SpellTargetRestrictionsId ? sSpellTargetRestrictionsStore.LookupEntry(SpellTargetRestrictionsId) : NULL; -} - -SpellEquippedItemsEntry const* SpellInfo::GetSpellEquippedItems() const -{ - return SpellEquippedItemsId ? sSpellEquippedItemsStore.LookupEntry(SpellEquippedItemsId) : NULL; -} - -SpellInterruptsEntry const* SpellInfo::GetSpellInterrupts() const -{ - return SpellInterruptsId ? sSpellInterruptsStore.LookupEntry(SpellInterruptsId) : NULL; -} - -SpellLevelsEntry const* SpellInfo::GetSpellLevels() const -{ - return SpellLevelsId ? sSpellLevelsStore.LookupEntry(SpellLevelsId) : NULL; -} - -SpellReagentsEntry const* SpellInfo::GetSpellReagents() const -{ - return SpellReagentsId ? sSpellReagentsStore.LookupEntry(SpellReagentsId) : NULL; -} - -SpellScalingEntry const* SpellInfo::GetSpellScaling() const -{ - return SpellScalingId ? sSpellScalingStore.LookupEntry(SpellScalingId) : NULL; -} - -SpellShapeshiftEntry const* SpellInfo::GetSpellShapeshift() const -{ - return SpellShapeshiftId ? sSpellShapeshiftStore.LookupEntry(SpellShapeshiftId) : NULL; -} - -SpellTotemsEntry const* SpellInfo::GetSpellTotems() const -{ - return SpellTotemsId ? sSpellTotemsStore.LookupEntry(SpellTotemsId) : NULL; -} - -SpellMiscEntry const* SpellInfo::GetSpellMisc() const -{ - return SpellMiscId ? sSpellMiscStore.LookupEntry(SpellMiscId) : NULL; -} - -SpellAuraOptionsEntry const* SpellInfo::GetSpellAuraOptions() const -{ - return SpellAuraOptionsId ? sSpellAuraOptionsStore.LookupEntry(SpellAuraOptionsId) : NULL; -} - -SpellAuraRestrictionsEntry const* SpellInfo::GetSpellAuraRestrictions() const -{ - return SpellAuraRestrictionsId ? sSpellAuraRestrictionsStore.LookupEntry(SpellAuraRestrictionsId) : NULL; -} - -SpellCastingRequirementsEntry const* SpellInfo::GetSpellCastingRequirements() const -{ - return SpellCastingRequirementsId ? sSpellCastingRequirementsStore.LookupEntry(SpellCastingRequirementsId) : NULL; -} - -SpellCategoriesEntry const* SpellInfo::GetSpellCategories() const -{ - return SpellCategoriesId ? sSpellCategoriesStore.LookupEntry(SpellCategoriesId) : NULL; -} - -SpellClassOptionsEntry const* SpellInfo::GetSpellClassOptions() const -{ - return SpellClassOptionsId ? sSpellClassOptionsStore.LookupEntry(SpellClassOptionsId) : NULL; -} - -SpellCooldownsEntry const* SpellInfo::GetSpellCooldowns() const -{ - return SpellCooldownsId ? sSpellCooldownsStore.LookupEntry(SpellCooldownsId) : NULL; -} - void SpellInfo::_UnloadImplicitTargetConditionLists() { // find the same instances of ConditionList and delete them. diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 4faf98a0791..764760ddffa 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -277,7 +277,7 @@ public: RealPointsPerLevel(0), BasePoints(0), PointsPerResource(0), Amplitude(0), ChainAmplitude(0), BonusCoefficient(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), PositionFacing(0), RadiusEntry(NULL), ChainTargets(0), ItemType(0), TriggerSpell(0), BonusCoefficientFromAP(0.0f), ImplicitTargetConditions(NULL) { } - SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* effect); + SpellEffectInfo(SpellEffectScalingEntry const* spellEffectScaling, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* effect); bool IsEffect() const; bool IsEffect(SpellEffectName effectName) const; @@ -324,11 +324,13 @@ typedef std::unordered_map<uint32, SpellVisualVector> SpellVisualMap; typedef std::vector<AuraEffect*> AuraEffectVector; +struct SpellInfoLoadHelper; + class TC_GAME_API SpellInfo { public: uint32 Id; - SpellCategoryEntry const* CategoryEntry; + uint32 CategoryId; uint32 Dispel; uint32 Mechanic; uint32 Attributes; @@ -379,7 +381,7 @@ public: uint32 SpellLevel; SpellDurationEntry const* DurationEntry; std::vector<SpellPowerEntry const*> PowerCosts; - uint32 RuneCostID; + uint32 RangeIndex; SpellRangeEntry const* RangeEntry; float Speed; uint32 StackAmount; @@ -393,7 +395,7 @@ public: uint32 SpellVisual[2]; uint32 SpellIconID; uint32 ActiveIconID; - char* SpellName; + LocalizedString const* SpellName; uint32 MaxTargetLevel; uint32 MaxAffectedTargets; uint32 SpellFamilyName; @@ -402,32 +404,11 @@ public: uint32 PreventionType; int32 RequiredAreasID; uint32 SchoolMask; - SpellCategoryEntry const* ChargeCategoryEntry; - uint32 SpellDifficultyId; - uint32 SpellScalingId; - uint32 SpellAuraOptionsId; - uint32 SpellAuraRestrictionsId; - uint32 SpellCastingRequirementsId; - uint32 SpellCategoriesId; - uint32 SpellClassOptionsId; - uint32 SpellCooldownsId; - uint32 SpellEquippedItemsId; - uint32 SpellInterruptsId; - uint32 SpellLevelsId; - uint32 SpellReagentsId; - uint32 SpellShapeshiftId; - uint32 SpellTargetRestrictionsId; - uint32 SpellTotemsId; - uint32 SpellMiscId; + uint32 ChargeCategoryId; // SpellScalingEntry struct ScalingInfo { - int32 CastTimeMin; - int32 CastTimeMax; - uint32 CastTimeMaxLevel; int32 Class; - float NerfFactor; - uint32 NerfMaxLevel; uint32 MaxScalingLevel; uint32 ScalesFromItemLevel; } Scaling; @@ -435,24 +416,8 @@ public: uint32 ExplicitTargetMask; SpellChainNode const* ChainEntry; - // struct access functions - SpellTargetRestrictionsEntry const* GetSpellTargetRestrictions() const; - SpellAuraOptionsEntry const* GetSpellAuraOptions() const; - SpellAuraRestrictionsEntry const* GetSpellAuraRestrictions() const; - SpellCastingRequirementsEntry const* GetSpellCastingRequirements() const; - SpellCategoriesEntry const* GetSpellCategories() const; - SpellClassOptionsEntry const* GetSpellClassOptions() const; - SpellCooldownsEntry const* GetSpellCooldowns() const; - SpellEquippedItemsEntry const* GetSpellEquippedItems() const; - SpellInterruptsEntry const* GetSpellInterrupts() const; - SpellLevelsEntry const* GetSpellLevels() const; - SpellReagentsEntry const* GetSpellReagents() const; - SpellScalingEntry const* GetSpellScaling() const; - SpellShapeshiftEntry const* GetSpellShapeshift() const; - SpellTotemsEntry const* GetSpellTotems() const; - SpellMiscEntry const* GetSpellMisc() const; - - SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap const& effectsMap, SpellVisualMap&& visuals); + SpellInfo(SpellInfoLoadHelper const& data, SpellEffectEntryMap const& effectsMap, SpellVisualMap&& visuals, + std::unordered_map<uint32, SpellEffectScalingEntry const*> const& effectScaling); ~SpellInfo(); uint32 GetCategory() const; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index beeb1109dce..d5f3c0c5d77 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2690,9 +2690,11 @@ void SpellMgr::LoadSpellInfoStore() UnloadSpellInfoStore(); mSpellInfoMap.resize(sSpellStore.GetNumRows(), NULL); + std::unordered_map<uint32, SpellInfoLoadHelper> loadData; std::unordered_map<uint32, SpellEffectEntryMap> effectsBySpell; std::unordered_map<uint32, SpellVisualMap> visualsBySpell; + std::unordered_map<uint32, SpellEffectScalingEntry const*> spellEffectScallingByEffectId; for (SpellEffectEntry const* effect : sSpellEffectStore) { @@ -2709,12 +2711,70 @@ void SpellMgr::LoadSpellInfoStore() effectsForDifficulty[effect->EffectIndex] = effect; } + for (SpellAuraOptionsEntry const* auraOptions : sSpellAuraOptionsStore) + if (!auraOptions->DifficultyID) // TODO: implement + loadData[auraOptions->SpellID].AuraOptions = auraOptions; + + for (SpellAuraRestrictionsEntry const* auraRestrictions : sSpellAuraRestrictionsStore) + if (!auraRestrictions->DifficultyID) // TODO: implement + loadData[auraRestrictions->SpellID].AuraRestrictions = auraRestrictions; + + for (SpellCastingRequirementsEntry const* castingRequirements : sSpellCastingRequirementsStore) + loadData[castingRequirements->SpellID].CastingRequirements = castingRequirements; + + for (SpellCategoriesEntry const* categories : sSpellCategoriesStore) + if (!categories->DifficultyID) // TODO: implement + loadData[categories->SpellID].Categories = categories; + + for (SpellClassOptionsEntry const* classOptions : sSpellClassOptionsStore) + loadData[classOptions->SpellID].ClassOptions = classOptions; + + for (SpellCooldownsEntry const* cooldowns : sSpellCooldownsStore) + if (!cooldowns->DifficultyID) // TODO: implement + loadData[cooldowns->SpellID].Cooldowns = cooldowns; + + for (SpellEffectScalingEntry const* spellEffectScaling : sSpellEffectScalingStore) + spellEffectScallingByEffectId[spellEffectScaling->SpellEffectID] = spellEffectScaling; + + for (SpellEquippedItemsEntry const* equippedItems : sSpellEquippedItemsStore) + loadData[equippedItems->SpellID].EquippedItems = equippedItems; + + for (SpellInterruptsEntry const* interrupts : sSpellInterruptsStore) + if (!interrupts->DifficultyID) // TODO: implement + loadData[interrupts->SpellID].Interrupts = interrupts; + + for (SpellLevelsEntry const* levels : sSpellLevelsStore) + if (!levels->DifficultyID) // TODO: implement + loadData[levels->SpellID].Levels = levels; + + for (SpellReagentsEntry const* reagents : sSpellReagentsStore) + loadData[reagents->SpellID].Reagents = reagents; + + for (SpellScalingEntry const* scaling : sSpellScalingStore) + loadData[scaling->SpellID].Scaling = scaling; + + for (SpellShapeshiftEntry const* shapeshift : sSpellShapeshiftStore) + loadData[shapeshift->SpellID].Shapeshift = shapeshift; + + for (SpellTargetRestrictionsEntry const* targetRestrictions : sSpellTargetRestrictionsStore) + if (!targetRestrictions->DifficultyID) // TODO: implement + loadData[targetRestrictions->SpellID].TargetRestrictions = targetRestrictions; + + for (SpellTotemsEntry const* totems : sSpellTotemsStore) + loadData[totems->SpellID].Totems = totems; + for (SpellXSpellVisualEntry const* visual : sSpellXSpellVisualStore) visualsBySpell[visual->SpellID][visual->DifficultyID].push_back(visual); for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i) + { if (SpellEntry const* spellEntry = sSpellStore.LookupEntry(i)) - mSpellInfoMap[i] = new SpellInfo(spellEntry, effectsBySpell[i], std::move(visualsBySpell[i])); + { + loadData[i].Entry = spellEntry; + loadData[i].Misc = sSpellMiscStore.LookupEntry(spellEntry->MiscID); + mSpellInfoMap[i] = new SpellInfo(loadData[i], effectsBySpell[i], std::move(visualsBySpell[i]), spellEffectScallingByEffectId); + } + } TC_LOG_INFO("server.loading", ">> Loaded SpellInfo store in %u ms", GetMSTimeDiffToNow(oldMSTime)); } @@ -3115,12 +3175,6 @@ void SpellMgr::LoadSpellInfoCorrections() case 6474: // Earthbind Totem (instant pulse) spellInfo->AttributesEx5 |= SPELL_ATTR5_START_PERIODIC_AT_APPLY; break; - case 5176: // Wrath - case 2912: // Starfire - //case 78674: // Starsurge 6.x effect 1 is no more - const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->Effect = SPELL_EFFECT_DUMMY; - const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->TargetA = TARGET_UNIT_CASTER; - break; case 70728: // Exploit Weakness (needs target selection script) case 70840: // Devious Minds (needs target selection script) const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER); @@ -3467,6 +3521,11 @@ void SpellMgr::LoadSpellInfoCorrections() void SpellMgr::LoadPetFamilySpellsStore() { + std::unordered_map<uint32, SpellLevelsEntry const*> levelsBySpell; + for (SpellLevelsEntry const* levels : sSpellLevelsStore) + if (!levels->DifficultyID) + levelsBySpell[levels->SpellID] = levels; + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); @@ -3477,8 +3536,8 @@ void SpellMgr::LoadPetFamilySpellsStore() if (!spellInfo) continue; - SpellLevelsEntry const* levels = sSpellLevelsStore.LookupEntry(spellInfo->LevelsID); - if (spellInfo->LevelsID && (!levels || levels->SpellLevel)) + auto levels = levelsBySpell.find(skillLine->SpellID); + if (levels != levelsBySpell.end() && levels->second->SpellLevel) continue; if (SpellMiscEntry const* spellMisc = sSpellMiscStore.LookupEntry(spellInfo->MiscID)) diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 79721235c17..e9488d8ecbb 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -597,6 +597,27 @@ TC_GAME_API int32 GetDiminishingReturnsLimitDuration(SpellInfo const* spellproto TC_GAME_API extern PetFamilySpellsStore sPetFamilySpellsStore; +struct SpellInfoLoadHelper +{ + SpellEntry const* Entry = nullptr; + + SpellAuraOptionsEntry const* AuraOptions = nullptr; + SpellAuraRestrictionsEntry const* AuraRestrictions = nullptr; + SpellCastingRequirementsEntry const* CastingRequirements = nullptr; + SpellCategoriesEntry const* Categories = nullptr; + SpellClassOptionsEntry const* ClassOptions = nullptr; + SpellCooldownsEntry const* Cooldowns = nullptr; + SpellEquippedItemsEntry const* EquippedItems = nullptr; + SpellInterruptsEntry const* Interrupts = nullptr; + SpellLevelsEntry const* Levels = nullptr; + SpellMiscEntry const* Misc = nullptr; + SpellReagentsEntry const* Reagents = nullptr; + SpellScalingEntry const* Scaling = nullptr; + SpellShapeshiftEntry const* Shapeshift = nullptr; + SpellTargetRestrictionsEntry const* TargetRestrictions = nullptr; + SpellTotemsEntry const* Totems = nullptr; +}; + class TC_GAME_API SpellMgr { // Constructors diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index f4bc3f7fcba..8aa1c1a4dc8 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -121,7 +121,7 @@ void CreatureTextMgr::LoadCreatureTexts() if (temp.sound) { - if (!sSoundEntriesStore.LookupEntry(temp.sound)) + if (!sSoundKitStore.LookupEntry(temp.sound)) { TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Sound %u but sound does not exist.", temp.entry, temp.group, temp.sound); temp.sound = 0; |
